* Copyright (C) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ijkplayer_napi_proxy.h"
static IjkMediaPlayer *GLOBAL_IJKMP = nullptr;
static void (*post_event)(void *weak_this, int what, int arg1, int arg2, char *obj);
void IJKPlayerNapiProxy::message_loop_callback(void (*pe)(void *weak_this, int what, int arg1, int arg2, char *obj)) {
post_event = pe;
}
static void message_loop_n(IjkMediaPlayer *mp) {
LOGI("napi_proxy-->message_loop_n");
void *weak_thiz = ijkmp_get_weak_thiz(mp);
while (1) {
AVMessage msg;
LOGI("napi_proxy-->message_loop_n-->go");
int retval = ijkmp_get_msg(mp, &msg, 1);
if (retval < 0)
break;
assert(retval > 0);
switch (msg.what) {
LOGI("napi_proxy-->message_loop_n-->go-->msg:%d", msg.what);
case FFP_MSG_FLUSH:
MPTRACE("FFP_MSG_FLUSH:\n");
post_event(weak_thiz, MEDIA_NOP, 0, 0, NULL);
break;
case FFP_MSG_ERROR:
MPTRACE("FFP_MSG_ERROR: %d\n", msg.arg1);
post_event(weak_thiz, MEDIA_ERROR, MEDIA_ERROR_IJK_PLAYER, msg.arg1, NULL);
break;
case FFP_MSG_PREPARED:
MPTRACE("FFP_MSG_PREPARED:\n");
post_event(weak_thiz, MEDIA_PREPARED, 0, 0, NULL);
break;
case FFP_MSG_COMPLETED:
MPTRACE("FFP_MSG_COMPLETED:\n");
post_event(weak_thiz, MEDIA_PLAYBACK_COMPLETE, 0, 0, NULL);
break;
case FFP_MSG_VIDEO_SIZE_CHANGED:
MPTRACE("FFP_MSG_VIDEO_SIZE_CHANGED: %d, %d\n", msg.arg1, msg.arg2);
post_event(weak_thiz, MEDIA_SET_VIDEO_SIZE, msg.arg1, msg.arg2, NULL);
break;
case FFP_MSG_SAR_CHANGED:
MPTRACE("FFP_MSG_SAR_CHANGED: %d, %d\n", msg.arg1, msg.arg2);
post_event(weak_thiz, MEDIA_SET_VIDEO_SAR, msg.arg1, msg.arg2, NULL);
break;
case FFP_MSG_VIDEO_RENDERING_START:
MPTRACE("FFP_MSG_VIDEO_RENDERING_START:\n");
post_event(weak_thiz, MEDIA_INFO, MEDIA_INFO_VIDEO_RENDERING_START, 0, NULL);
break;
case FFP_MSG_AUDIO_RENDERING_START:
MPTRACE("FFP_MSG_AUDIO_RENDERING_START:\n");
post_event(weak_thiz, MEDIA_INFO, MEDIA_INFO_AUDIO_RENDERING_START, 0, NULL);
break;
case FFP_MSG_VIDEO_ROTATION_CHANGED:
MPTRACE("FFP_MSG_VIDEO_ROTATION_CHANGED: %d\n", msg.arg1);
post_event(weak_thiz, MEDIA_INFO, MEDIA_INFO_VIDEO_ROTATION_CHANGED, msg.arg1, NULL);
break;
case FFP_MSG_AUDIO_DECODED_START:
MPTRACE("FFP_MSG_AUDIO_DECODED_START:\n");
post_event(weak_thiz, MEDIA_INFO, MEDIA_INFO_AUDIO_DECODED_START, 0, NULL);
break;
case FFP_MSG_VIDEO_DECODED_START:
MPTRACE("FFP_MSG_VIDEO_DECODED_START:\n");
post_event(weak_thiz, MEDIA_INFO, MEDIA_INFO_VIDEO_DECODED_START, 0, NULL);
break;
case FFP_MSG_OPEN_INPUT:
MPTRACE("FFP_MSG_OPEN_INPUT:\n");
post_event(weak_thiz, MEDIA_INFO, MEDIA_INFO_OPEN_INPUT, 0, NULL);
break;
case FFP_MSG_FIND_STREAM_INFO:
MPTRACE("FFP_MSG_FIND_STREAM_INFO:\n");
post_event(weak_thiz, MEDIA_INFO, MEDIA_INFO_FIND_STREAM_INFO, 0, NULL);
break;
case FFP_MSG_COMPONENT_OPEN:
MPTRACE("FFP_MSG_COMPONENT_OPEN:\n");
post_event(weak_thiz, MEDIA_INFO, MEDIA_INFO_COMPONENT_OPEN, 0, NULL);
break;
case FFP_MSG_BUFFERING_START:
MPTRACE("FFP_MSG_BUFFERING_START:\n");
post_event(weak_thiz, MEDIA_INFO, MEDIA_INFO_BUFFERING_START, msg.arg1, NULL);
break;
case FFP_MSG_BUFFERING_END:
MPTRACE("FFP_MSG_BUFFERING_END:\n");
post_event(weak_thiz, MEDIA_INFO, MEDIA_INFO_BUFFERING_END, msg.arg1, NULL);
break;
case FFP_MSG_BUFFERING_UPDATE:
post_event(weak_thiz, MEDIA_BUFFERING_UPDATE, msg.arg1, msg.arg2, NULL);
break;
case FFP_MSG_BUFFERING_BYTES_UPDATE:
break;
case FFP_MSG_BUFFERING_TIME_UPDATE:
break;
case FFP_MSG_SEEK_COMPLETE:
MPTRACE("FFP_MSG_SEEK_COMPLETE:\n");
post_event(weak_thiz, MEDIA_SEEK_COMPLETE, 0, 0, NULL);
break;
case FFP_MSG_ACCURATE_SEEK_COMPLETE:
MPTRACE("FFP_MSG_ACCURATE_SEEK_COMPLETE:\n");
post_event(weak_thiz, MEDIA_INFO, MEDIA_INFO_MEDIA_ACCURATE_SEEK_COMPLETE, msg.arg1, NULL);
break;
case FFP_MSG_PLAYBACK_STATE_CHANGED:
break;
case FFP_MSG_TIMED_TEXT:
if (msg.obj) {
post_event(weak_thiz, MEDIA_TIMED_TEXT, 0, 0, (char *)msg.obj);
} else {
post_event(weak_thiz, MEDIA_TIMED_TEXT, 0, 0, NULL);
}
break;
case FFP_MSG_GET_IMG_STATE:
if (msg.obj) {
post_event(weak_thiz, MEDIA_GET_IMG_STATE, msg.arg1, msg.arg2, (char *)msg.obj);
} else {
post_event(weak_thiz, MEDIA_GET_IMG_STATE, msg.arg1, msg.arg2, NULL);
}
break;
case FFP_MSG_VIDEO_SEEK_RENDERING_START:
MPTRACE("FFP_MSG_VIDEO_SEEK_RENDERING_START:\n");
post_event(weak_thiz, MEDIA_INFO, MEDIA_INFO_VIDEO_SEEK_RENDERING_START, msg.arg1, NULL);
break;
case FFP_MSG_AUDIO_SEEK_RENDERING_START:
MPTRACE("FFP_MSG_AUDIO_SEEK_RENDERING_START:\n");
post_event(weak_thiz, MEDIA_INFO, MEDIA_INFO_AUDIO_SEEK_RENDERING_START, msg.arg1, NULL);
break;
default:
ALOGE("unknown FFP_MSG_xxx(%d)\n", msg.what);
break;
}
msg_free_res(&msg);
}
}
static int message_loop(void *arg);
static int message_loop(void *arg) {
LOGI("napi_proxy-->message_loop");
IjkMediaPlayer *mp = (IjkMediaPlayer *)arg;
message_loop_n(mp);
return 0;
}
IjkMediaPlayer *IJKPlayerNapiProxy::IJKPlayerNapiProxy::get_media_player() {
LOGI("napi_proxy-->get_media_player");
IjkMediaPlayer *mp = GLOBAL_IJKMP;
if (mp) {
ijkmp_inc_ref(mp);
}
return mp;
}
IjkMediaPlayer *IJKPlayerNapiProxy::set_media_player(IjkMediaPlayer *mp) {
LOGI("napi_proxy-->set_media_player");
if (mp) {
ijkmp_inc_ref(mp);
}
GLOBAL_IJKMP = mp;
return mp;
}
void IJKPlayerNapiProxy::IjkMediaPlayer_native_setup(void *weak_this, void *native_window) {
LOGI("napi_proxy-->IjkMediaPlayer_native_setup");
if (!IJKMP_GLOABL_INIT) {
ijkmp_global_init();
}
IJKMP_GLOABL_INIT = true;
GLOBAL_NATIVE_WINDOW = native_window;
IjkMediaPlayer *mp = ijkmp_android_create(message_loop);
IJKPlayerNapiProxy::set_media_player(mp);
ijkmp_android_set_surface(mp, native_window);
ijkmp_set_weak_thiz(mp, weak_this);
ijkmp_set_inject_opaque(mp, ijkmp_get_weak_thiz(mp));
ijkmp_set_ijkio_inject_opaque(mp, ijkmp_get_weak_thiz(mp));
}
void IJKPlayerNapiProxy::IjkMediaPlayer_setDataSource(char *url) {
IjkMediaPlayer *mp = IJKPlayerNapiProxy::get_media_player();
ijkmp_set_data_source(mp, url);
}
void IJKPlayerNapiProxy::IjkMediaPlayer_setOption(int category, char *name, char *value) {
IjkMediaPlayer *mp = IJKPlayerNapiProxy::get_media_player();
ijkmp_set_option(mp, category, name, value);
}
void IJKPlayerNapiProxy::IjkMediaPlayer_setOptionLong(int category, char *name, int64_t value) {
IjkMediaPlayer *mp = IJKPlayerNapiProxy::get_media_player();
ijkmp_set_option_int(mp, category, name, value);
}
void IJKPlayerNapiProxy::IjkMediaPlayer_prepareAsync() {
IjkMediaPlayer *mp = IJKPlayerNapiProxy::get_media_player();
ijkmp_prepare_async(mp);
}
void IJKPlayerNapiProxy::IjkMediaPlayer_start() {
IjkMediaPlayer *mp = IJKPlayerNapiProxy::get_media_player();
ijkmp_start(mp);
}
void IJKPlayerNapiProxy::IjkMediaPlayer_pause() {
IjkMediaPlayer *mp = IJKPlayerNapiProxy::get_media_player();
ijkmp_pause(mp);
}
void IJKPlayerNapiProxy::IjkMediaPlayer_seekTo(int64_t msec) {
IjkMediaPlayer *mp = IJKPlayerNapiProxy::get_media_player();
ijkmp_seek_to(mp, msec);
}
bool IJKPlayerNapiProxy::IjkMediaPlayer_isPlaying() {
IjkMediaPlayer *mp = IJKPlayerNapiProxy::get_media_player();
return ijkmp_is_playing(mp) ? true : false;
}
int IJKPlayerNapiProxy::IjkMediaPlayer_getCurrentPosition() {
int retval = 0;
IjkMediaPlayer *mp = IJKPlayerNapiProxy::get_media_player();
retval = ijkmp_get_current_position(mp);
return retval;
}
int IJKPlayerNapiProxy::IjkMediaPlayer_getDuration() {
int retval = 0;
IjkMediaPlayer *mp = IJKPlayerNapiProxy::get_media_player();
retval = ijkmp_get_duration(mp);
return retval;
}
void IJKPlayerNapiProxy::IjkMediaPlayer_stop() {
IjkMediaPlayer *mp = IJKPlayerNapiProxy::get_media_player();
ijkmp_stop(mp);
}
void IJKPlayerNapiProxy::IjkMediaPlayer_release() {
IjkMediaPlayer *mp = IJKPlayerNapiProxy::get_media_player();
if (!mp)
return;
ijkmp_shutdown(mp);
ijkmp_dec_ref_p(&mp);
}
void IJKPlayerNapiProxy::IjkMediaPlayer_reset() {
IjkMediaPlayer *mp = IJKPlayerNapiProxy::get_media_player();
if (!mp)
return;
ijkmp_android_set_surface(mp, NULL);
void *weak_thiz = ijkmp_set_weak_thiz(mp, NULL);
IjkMediaPlayer_release();
LOGI("napi_proxy-->IjkMediaPlayer_reset");
ijkmp_dec_ref_p(&mp);
}
void IJKPlayerNapiProxy::IjkMediaPlayer_setVolume(float leftVolume, float rightVolume) {
IjkMediaPlayer *mp = IJKPlayerNapiProxy::get_media_player();
ijkmp_android_set_volume(mp, leftVolume, rightVolume);
}
void IJKPlayerNapiProxy::ijkMediaPlayer_setPropertyFloat(int id, float value) {
IjkMediaPlayer *mp = IJKPlayerNapiProxy::get_media_player();
ijkmp_set_property_float(mp, id, value);
}
float IJKPlayerNapiProxy::ijkMediaPlayer_getPropertyFloat(int id, float default_value) {
IjkMediaPlayer *mp = IJKPlayerNapiProxy::get_media_player();
return ijkmp_get_property_float(mp, id, default_value);
}
void IJKPlayerNapiProxy::ijkMediaPlayer_setPropertyLong(int id, long value) {
IjkMediaPlayer *mp = IJKPlayerNapiProxy::get_media_player();
ijkmp_set_property_int64(mp, id, value);
}
long IJKPlayerNapiProxy::ijkMediaPlayer_getPropertyLong(int id, long default_value) {
IjkMediaPlayer *mp = IJKPlayerNapiProxy::get_media_player();
return ijkmp_get_property_int64(mp, id, default_value);
}
int IJKPlayerNapiProxy::IjkMediaPlayer_getAudioSessionId() {
int audio_session_id = 0;
IjkMediaPlayer *mp = IJKPlayerNapiProxy::get_media_player();
audio_session_id = ijkmp_android_get_audio_session_id(mp);
return audio_session_id;
}
void IJKPlayerNapiProxy::IjkMediaPlayer_setLoopCount(int loop_count) {
IjkMediaPlayer *mp = IJKPlayerNapiProxy::get_media_player();
ijkmp_set_loop(mp, loop_count);
}
int IJKPlayerNapiProxy::IjkMediaPlayer_getLoopCount() {
IjkMediaPlayer *mp = IJKPlayerNapiProxy::get_media_player();
int loop_count = ijkmp_get_loop(mp);
return loop_count;
}
char *IJKPlayerNapiProxy::IjkMediaPlayer_getVideoCodecInfo() {
char *codec_info = NULL;
IjkMediaPlayer *mp = IJKPlayerNapiProxy::get_media_player();
ijkmp_get_video_codec_info(mp, &codec_info);
return codec_info;
}
char *IJKPlayerNapiProxy::IjkMediaPlayer_getAudioCodecInfo() {
MPTRACE("%s\n", __func__);
char *codec_info = NULL;
IjkMediaPlayer *mp = IJKPlayerNapiProxy::get_media_player();
ijkmp_get_audio_codec_info(mp, &codec_info);
return codec_info;
}
void IJKPlayerNapiProxy::ijkMediaPlayer_setStreamSelected(int stream, bool selected) {
IjkMediaPlayer *mp = IJKPlayerNapiProxy::get_media_player();
int ret = 0;
ret = ijkmp_set_stream_selected(mp, stream, selected);
if (ret < 0) {
LOGI("failed to %s %d", selected ? "select" : "deselect", stream);
ijkmp_dec_ref_p(&mp);
}
}
const char *getFromMediaMetaByKey(IjkMediaMeta *meta, char *key) {
const char *value = ijkmeta_get_string_l(meta, key);
return value;
}
HashMap IJKPlayerNapiProxy::IjkMediaPlayer_getMediaMeta() {
IjkMediaPlayer *mp = IJKPlayerNapiProxy::get_media_player();
IjkMediaMeta *meta = ijkmp_get_meta_l(mp);
size_t count = ijkmeta_get_children_count_l(meta);
HashMap map = hashmap_create();
for (size_t i = 0; i < count; ++i) {
IjkMediaMeta *streamRawMeta = ijkmeta_get_child_l(meta, i);
if (streamRawMeta) {
map->put(map, (void *)IJKM_KEY_TYPE, (void *)getFromMediaMetaByKey(streamRawMeta, IJKM_KEY_TYPE));
map->put(map, (void *)IJKM_KEY_TYPE, (void *)getFromMediaMetaByKey(streamRawMeta, IJKM_KEY_TYPE));
map->put(map, (void *)IJKM_KEY_LANGUAGE, (void *)getFromMediaMetaByKey(streamRawMeta, IJKM_KEY_LANGUAGE));
const char *type = ijkmeta_get_string_l(streamRawMeta, IJKM_KEY_TYPE);
if (type) {
map->put(map, (void *)IJKM_KEY_CODEC_NAME, (void *)getFromMediaMetaByKey(streamRawMeta, IJKM_KEY_CODEC_NAME));
map->put(map, (void *)IJKM_KEY_CODEC_PROFILE, (void *)getFromMediaMetaByKey(streamRawMeta, IJKM_KEY_CODEC_PROFILE));
map->put(map, (void *)IJKM_KEY_CODEC_LEVEL, (void *)getFromMediaMetaByKey(streamRawMeta, IJKM_KEY_CODEC_LEVEL));
map->put(map, (void *)IJKM_KEY_CODEC_LONG_NAME, (void *)getFromMediaMetaByKey(streamRawMeta, IJKM_KEY_CODEC_LONG_NAME));
map->put(map, (void *)IJKM_KEY_CODEC_PIXEL_FORMAT, (void *)getFromMediaMetaByKey(streamRawMeta, IJKM_KEY_CODEC_PIXEL_FORMAT));
map->put(map, (void *)IJKM_KEY_BITRATE, (void *)getFromMediaMetaByKey(streamRawMeta, IJKM_KEY_BITRATE));
map->put(map, (void *)IJKM_KEY_CODEC_PROFILE_ID, (void *)getFromMediaMetaByKey(streamRawMeta, IJKM_KEY_CODEC_PROFILE_ID));
if (0 == strcmp(type, IJKM_VAL_TYPE__VIDEO)) {
map->put(map, (void *)IJKM_KEY_WIDTH, (void *)getFromMediaMetaByKey(streamRawMeta, IJKM_KEY_WIDTH));
map->put(map, (void *)IJKM_KEY_HEIGHT, (void *)getFromMediaMetaByKey(streamRawMeta, IJKM_KEY_HEIGHT));
map->put(map, (void *)IJKM_KEY_FPS_NUM, (void *)getFromMediaMetaByKey(streamRawMeta, IJKM_KEY_FPS_NUM));
map->put(map, (void *)IJKM_KEY_TBR_NUM, (void *)getFromMediaMetaByKey(streamRawMeta, IJKM_KEY_TBR_NUM));
map->put(map, (void *)IJKM_KEY_TBR_DEN, (void *)getFromMediaMetaByKey(streamRawMeta, IJKM_KEY_TBR_DEN));
map->put(map, (void *)IJKM_KEY_SAR_NUM, (void *)getFromMediaMetaByKey(streamRawMeta, IJKM_KEY_SAR_NUM));
map->put(map, (void *)IJKM_KEY_SAR_DEN, (void *)getFromMediaMetaByKey(streamRawMeta, IJKM_KEY_SAR_DEN));
} else if (0 == strcmp(type, IJKM_VAL_TYPE__AUDIO)) {
map->put(map, (void *)IJKM_KEY_SAMPLE_RATE, (void *)getFromMediaMetaByKey(streamRawMeta, IJKM_KEY_SAMPLE_RATE));
map->put(map, (void *)IJKM_KEY_CHANNEL_LAYOUT, (void *)getFromMediaMetaByKey(streamRawMeta, IJKM_KEY_CHANNEL_LAYOUT));
}
}
}
}
return map;
}
void IJKPlayerNapiProxy::IjkMediaPlayer_native_openlog() {
OHOS_LOG_ON = true;
open_custom_ffmpeg_log_print();
}