From 40fb5dccea05c14a81c06f84e9504328c0163d2a Mon Sep 17 00:00:00 2001 From: Gilbok Lee Date: Thu, 2 Mar 2023 17:42:24 +0900 Subject: [PATCH] [0.3.155][test] Add audio es push test case - exclude lcov about internal APIs Change-Id: I448b67cda18c812fa0d7b43ef2595abc3b11a95e --- packaging/capi-media-player.spec | 2 +- src/player.c | 3 +- test/player_es_push_test.c | 741 +++++++++++++++++++++++++++------------ 3 files changed, 529 insertions(+), 217 deletions(-) diff --git a/packaging/capi-media-player.spec b/packaging/capi-media-player.spec index fb55b42..d3b0a1e 100644 --- a/packaging/capi-media-player.spec +++ b/packaging/capi-media-player.spec @@ -1,6 +1,6 @@ Name: capi-media-player Summary: A Media Player API -Version: 0.3.154 +Version: 0.3.155 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/player.c b/src/player.c index 9863db8..1e3968f 100644 --- a/src/player.c +++ b/src/player.c @@ -1202,6 +1202,7 @@ static void __media_stream_audio_buffer_cb_handler(callback_cb_info_s *cb_info, } +//LCOV_EXCL_START static void __media_stream_video_buffer_cb_handler_ex(callback_cb_info_s *cb_info, _player_recv_data *recv_data) { /* player_media_stream_buffer_status_e status; */ @@ -1236,8 +1237,8 @@ static void __media_stream_audio_buffer_cb_handler_ex(callback_cb_info_s *cb_inf cb_info->user_cb[MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_AUDIO_BUFFER_STATUS_WITH_INFO]) ((player_media_stream_buffer_status_e) status, bytes, cb_info->user_data[MUSE_PLAYER_EVENT_TYPE_MEDIA_STREAM_AUDIO_BUFFER_STATUS_WITH_INFO]); } - } +//LCOV_EXCL_STOP static void __media_stream_video_seek_cb_handler(callback_cb_info_s *cb_info, _player_recv_data *recv_data) { diff --git a/test/player_es_push_test.c b/test/player_es_push_test.c index 6b27c40..6d04d17 100644 --- a/test/player_es_push_test.c +++ b/test/player_es_push_test.c @@ -23,17 +23,26 @@ #include #include -#define KEY_END "XF86Stop" +#define MAX_STRING_LEN 2048 + +#define ES_DEFAULT_H264_VIDEO_PATH "/home/owner/test.h264" +#define ES_DEFAULT_AAC_AUDIO_PATH "/home/owner/test.aac" -#define ES_DEFAULT_DIR_PATH "/home/owner/" -#define ES_DEFAULT_H264_VIDEO_PATH ES_DEFAULT_DIR_PATH"test.h264" #define ES_DEFAULT_VIDEO_FORMAT_TYPE MEDIA_FORMAT_H264_SP -#define ES_DEFAULT_VIDEO_FORMAT_WIDTH 1280 -#define ES_DEFAULT_VIDEO_FORMAT_HEIGHT 544 +#define ES_DEFAULT_VIDEO_FORMAT_WIDTH 640 +#define ES_DEFAULT_VIDEO_FORMAT_HEIGHT 480 #define ES_DEFAULT_VIDEO_PTS_OFFSET 33000000 -#define ES_DEFAULT_VIDEO_FPS 30 -#define ES_DEFAULT_NUMBER_OF_FEED 2000 -#define USE_EVAS_DISPLAY 0 +#define ES_DEFAULT_VIDEO_FPS 30 +#define ES_DEFAULT_NUMBER_OF_FEED 2000 + +#define ES_DEFAULT_AUDIO_FORMAT_TYPE MEDIA_FORMAT_AAC_LC +#define ES_DEFAULT_AUDIO_SAMPLE_RATE 44100 +#define ES_DEFAULT_AUDIO_CHANNELS 2 +#define ES_DEFAULT_AUDIO_PTS_OFFSET 22676 + +#define ES_SECOND 1000000000 + +#define USE_EVAS_DISPLAY 0 #ifdef PACKAGE #undef PACKAGE @@ -46,9 +55,6 @@ #define LOG_TAG "PLAYER_TEST" static int app_create(void *data); -static int app_reset(bundle *b, void *data); -static int app_resume(void *data); -static int app_pause(void *data); static int app_terminate(void *data); typedef enum { @@ -70,45 +76,49 @@ typedef enum { struct appcore_ops ops = { .create = app_create, .terminate = app_terminate, - .pause = app_pause, - .resume = app_resume, - .reset = app_reset, }; -typedef struct appdata { +typedef struct { Evas_Object *win; Evas_Object *rect; - player_h player_handle; - media_packet_h video_pkt; - media_format_h video_fmt; - FILE *file_src; - pthread_t feeding_thread_id; -} appdata_s; +} appdata; -static void win_delete_request_cb(void *data, Evas_Object *obj, void *event_info) -{ - elm_exit(); -} +static appdata ad; -static Eina_Bool keydown_cb(void *data, int type, void *event) -{ - /* appdata_s *ad = data; */ - Ecore_Event_Key *ev = event; +enum { + CURRENT_STATUS_MAINMENU, + CURRENT_STATUS_AUDIO_FILENAME, + CURRENT_STATUS_VIDEO_FILENAME, + CURRENT_STATUS_AUDIO_FORMAT, + CURRENT_STATUS_VIDEO_FORMAT, +}; - LOGD("start"); +int g_menu_state = CURRENT_STATUS_MAINMENU; - if (!strcmp(ev->keyname, KEY_END)) { - /* Let window go to hide state. */ - /* elm_win_lower(ad->win); */ - LOGD("elm exit"); - elm_exit(); +enum { + INFO_AUDIO, + INFO_VIDEO, + INFO_MAX +}; - return ECORE_CALLBACK_DONE; - } +typedef struct contents_info { + FILE *contents_file; + media_format_h format; + pthread_t feeding_thread_id; + guint pts_offset; +} contents_info_s; - LOGD("done"); +static Evas_Object *g_win_id; +static player_h g_player_handle; +static bool g_thread_end = false; +contents_info_s g_content[INFO_MAX] = {0, }; + +static void _player_destroy(); +void quit_program(); - return ECORE_CALLBACK_PASS_ON; +static void win_delete_request_cb(void *data, Evas_Object *obj, void *event_info) +{ + elm_exit(); } static void win_del(void *data, Evas_Object *obj, void *event) @@ -160,7 +170,7 @@ static Evas_Object *create_render_rect(Evas_Object *pParent) } -static void create_base_gui(appdata_s *ad) +static void create_base_gui(appdata *ad) { /* Enable GLES Backend */ elm_config_accel_preference_set("opengl"); @@ -169,6 +179,7 @@ static void create_base_gui(appdata_s *ad) /* elm_win_util_standard_add(PACKAGE, PACKAGE); */ ad->win = create_win(PACKAGE); ad->rect = create_render_rect(ad->win); + g_win_id = ad->win; #if USE_EVAS_DISPLAY evas_object_image_size_set(ad->rect, 500, 500); evas_object_image_fill_set(ad->rect, 0, 0, 500, 500); @@ -193,26 +204,21 @@ static int app_create(void *data) Initialize UI resources and application's data If this function returns true, the main loop of application starts If this function returns false, the application is terminated */ - appdata_s *ad = data; + appdata *ad = data; LOGD("start"); create_base_gui(ad); - ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, keydown_cb, NULL); - - /* open test file */ - ad->file_src = fopen(ES_DEFAULT_H264_VIDEO_PATH, "r"); LOGD("done"); return 0; } -static int app_pause(void *data) +static int app_terminate(void *data) { - /* Take necessary actions when application becomes invisible. */ - appdata_s *ad = (appdata_s *)data; - int ret = PLAYER_ERROR_NONE; + /* Release all resources. */ + appdata *ad = (appdata *)data; LOGD("start"); @@ -221,50 +227,12 @@ static int app_pause(void *data) return -1; } - if (ad->player_handle == NULL) { + if (g_player_handle == NULL) { g_print("player_handle is NULL"); return -1; } - if (ad->feeding_thread_id) { - pthread_join(ad->feeding_thread_id, NULL); - ad->feeding_thread_id = 0; - } - - player_unset_media_stream_buffer_status_cb_ex(ad->player_handle, PLAYER_STREAM_TYPE_VIDEO); - player_unset_media_stream_buffer_status_cb_ex(ad->player_handle, PLAYER_STREAM_TYPE_AUDIO); - player_unset_media_stream_seek_cb(ad->player_handle, PLAYER_STREAM_TYPE_VIDEO); - player_unset_media_stream_seek_cb(ad->player_handle, PLAYER_STREAM_TYPE_AUDIO); - - ret = player_unprepare(ad->player_handle); - if (ret != PLAYER_ERROR_NONE) { - g_print("player_unprepare failed : 0x%x", ret); - return false; - } - - /* unref media format */ - if (ad->video_fmt) - media_format_unref(ad->video_fmt); - - fclose(ad->file_src); - - /* destroy player handle */ - ret = player_destroy(ad->player_handle); - if (ret != PLAYER_ERROR_NONE) { - g_print("player_destroy failed : 0x%x", ret); - return false; - } - - ad->player_handle = NULL; - - LOGD("done"); - - return 0; -} - -static int app_resume(void *data) -{ - LOGD("start"); + quit_program(); LOGD("done"); @@ -273,12 +241,9 @@ static int app_resume(void *data) static void _player_prepared_cb(void *user_data) { - int ret = PLAYER_ERROR_NONE; - appdata_s *ad = (appdata_s *)user_data; - - LOGD("prepared"); - - ret = player_start(ad->player_handle); + int ret; + g_print("prepared\n"); + ret = player_start(g_player_handle); if (ret != PLAYER_ERROR_NONE) LOGE("player start failed : 0x%x", ret); @@ -363,105 +328,213 @@ int bytestream2nalunit(FILE *fd, unsigned char *nal) return nal_length; } -static void feed_eos_data(appdata_s *appdata) +static void feed_eos_data(contents_info_s* pinfo) { - appdata_s *ad = appdata; + media_packet_h media_pkt; + media_format_h media_format; + + if (!pinfo) + return; + + media_format = pinfo->format; + if (!media_format) + return; LOGD("push EOS"); - if (media_packet_create(ad->video_fmt, NULL, NULL, &ad->video_pkt) != MEDIA_PACKET_ERROR_NONE) { + if (media_packet_create(media_format, NULL, NULL, &media_pkt) != MEDIA_PACKET_ERROR_NONE) { LOGE("media_packet_create_alloc failed\n"); return; } - media_packet_set_flags(ad->video_pkt, MEDIA_PACKET_END_OF_STREAM); - if (player_push_media_stream(ad->player_handle, ad->video_pkt) != PLAYER_ERROR_NONE) + media_packet_set_flags(media_pkt, MEDIA_PACKET_END_OF_STREAM); + if (player_push_media_stream(g_player_handle, media_pkt) != PLAYER_ERROR_NONE) LOGE("fail to push media packet\n"); - media_packet_destroy(ad->video_pkt); - ad->video_pkt = NULL; - + media_packet_destroy(media_pkt); return; } -static bool feed_video_data(appdata_s *appdata) +static bool feed_video_data() { - bool ret = FALSE; + bool ret = false; int read = 0; - static guint64 pts = 0L; + static guint64 video_pts = 0L; void *buf_data_ptr = NULL; - appdata_s *ad = appdata; + media_packet_h video_pkt; - if (media_packet_create_alloc(ad->video_fmt, NULL, NULL, &ad->video_pkt) != MEDIA_PACKET_ERROR_NONE) { - LOGE("media_packet_create_alloc failed\n"); - return FALSE; + if (media_packet_new_alloc(g_content[INFO_VIDEO].format, NULL, NULL, &video_pkt) != MEDIA_PACKET_ERROR_NONE) { + LOGE("media_packet_new_alloc failed\n"); + return false; } - if (media_packet_get_buffer_data_ptr(ad->video_pkt, &buf_data_ptr) != MEDIA_PACKET_ERROR_NONE) { + if (media_packet_get_buffer_data_ptr(video_pkt, &buf_data_ptr) != MEDIA_PACKET_ERROR_NONE) { LOGE("media_packet_get_buffer_data_ptr failed\n"); - goto ERROR; + goto CLEANUP; } - if (media_packet_set_pts(ad->video_pkt, (uint64_t)pts) != MEDIA_PACKET_ERROR_NONE) { + if (media_packet_set_pts(video_pkt, (uint64_t)video_pts) != MEDIA_PACKET_ERROR_NONE) { LOGE("media_packet_set_pts failed\n"); - goto ERROR; + goto CLEANUP; } /* NOTE: In case of H.264 video, stream format for feeding is NAL unit. * And, SPS(0x67) and PPS(0x68) should be located before IDR.(0x65). */ - read = bytestream2nalunit(ad->file_src, buf_data_ptr); + read = bytestream2nalunit(g_content[INFO_VIDEO].contents_file, buf_data_ptr); LOGD("real length = %d\n", read); if (read == 0) { LOGE("input file read failed\n"); - ret = TRUE; - goto ERROR; + ret = true; + goto CLEANUP; } else if (read < 0) { LOGD("push EOS"); - media_packet_destroy(ad->video_pkt); - ad->video_pkt = NULL; + media_packet_set_flags(video_pkt, MEDIA_PACKET_END_OF_STREAM); + if (player_push_media_stream(g_player_handle, video_pkt) != PLAYER_ERROR_NONE) + LOGE("fail to push media packet\n"); + goto CLEANUP; + } + + if (media_packet_set_buffer_size(video_pkt, (uint64_t)read) != MEDIA_PACKET_ERROR_NONE) { + LOGE("media_packet_set_buffer_size failed\n"); + goto CLEANUP; + } - if (media_packet_create(ad->video_fmt, NULL, NULL, &ad->video_pkt) != MEDIA_PACKET_ERROR_NONE) { - LOGE("media_packet_create failed\n"); - goto ERROR; + /* push media packet */ + player_push_media_stream(g_player_handle, video_pkt); + video_pts += g_content[INFO_VIDEO].pts_offset; + ret = true; + +CLEANUP: + /* destroy media packet after use */ + media_packet_destroy(video_pkt); + video_pkt = NULL; + return ret; +} + +static void feed_video_data_thread_func() +{ + int video_frame_count = 0; + + if (!g_content[INFO_VIDEO].contents_file) { + g_print("Not open contents files\n"); + return; + } + + while (!g_thread_end) { + if (video_frame_count == ES_DEFAULT_NUMBER_OF_FEED) { + feed_eos_data(&g_content[INFO_VIDEO]); + break; } - media_packet_set_flags(ad->video_pkt, MEDIA_PACKET_END_OF_STREAM); - if (player_push_media_stream(ad->player_handle, ad->video_pkt) != PLAYER_ERROR_NONE) + + if (!feed_video_data()) + break; + + video_frame_count++; + } +} + +int audiobytestream2nalunit(FILE *fd, unsigned char *nal) +{ + const int HEADER_SIZE = 7; + size_t result; + int nal_length = 0; + unsigned char buffer[1000000]; + int audio_data_length = 0; + + if (feof(fd)) + return -1; + + result = fread(buffer, 1, HEADER_SIZE, fd); + nal_length = (int)(((buffer[4] << 3) & 0x7ff) + + (((buffer[5] - 0x1f) >> 5) & 0x7)); + + audio_data_length = nal_length - HEADER_SIZE; + + if (feof(fd)) + return -1; + + result = fread(buffer + HEADER_SIZE, 1, audio_data_length, fd); + memcpy(nal, buffer, result + HEADER_SIZE); + + return result + HEADER_SIZE; +} + +static bool feed_audio_data() +{ + bool ret = false; + int read = 0; + static guint64 audio_pts = 0L; + void *buf_data_ptr = NULL; + media_packet_h audio_pkt; + + if (media_packet_new_alloc(g_content[INFO_AUDIO].format, NULL, NULL, &audio_pkt) != MEDIA_PACKET_ERROR_NONE) { + LOGE("media_packet_new_alloc failed\n"); + return false; + } + + if (media_packet_get_buffer_data_ptr(audio_pkt, &buf_data_ptr) != MEDIA_PACKET_ERROR_NONE) { + LOGE("media_packet_get_buffer_data_ptr failed\n"); + goto CLEANUP; + } + + if (media_packet_set_pts(audio_pkt, (uint64_t)audio_pts) != MEDIA_PACKET_ERROR_NONE) { + LOGE("media_packet_set_pts failed\n"); + goto CLEANUP; + } + + /* NOTE: In case of H.264 video, stream format for feeding is NAL unit. + * And, SPS(0x67) and PPS(0x68) should be located before IDR.(0x65). + */ + read = audiobytestream2nalunit(g_content[INFO_AUDIO].contents_file, buf_data_ptr); + LOGD("real length = %d\n", read); + if (read == 0) { + LOGE("input file read failed\n"); + ret = true; + goto CLEANUP; + } else if (read < 0) { + LOGD("push EOS"); + media_packet_set_flags(audio_pkt, MEDIA_PACKET_END_OF_STREAM); + if (player_push_media_stream(g_player_handle, audio_pkt) != PLAYER_ERROR_NONE) LOGE("fail to push media packet\n"); - goto ERROR; + goto CLEANUP; } - if (media_packet_set_buffer_size(ad->video_pkt, (uint64_t)read) != MEDIA_PACKET_ERROR_NONE) { + if (media_packet_set_buffer_size(audio_pkt, (uint64_t)read) != MEDIA_PACKET_ERROR_NONE) { LOGE("media_packet_set_buffer_size failed\n"); - goto ERROR; + goto CLEANUP; } /* push media packet */ - player_push_media_stream(ad->player_handle, ad->video_pkt); - pts += ES_DEFAULT_VIDEO_PTS_OFFSET; - ret = TRUE; + player_push_media_stream(g_player_handle, audio_pkt); + audio_pts += g_content[INFO_AUDIO].pts_offset; + ret = true; -ERROR: +CLEANUP: /* destroy media packet after use */ - media_packet_destroy(ad->video_pkt); - ad->video_pkt = NULL; + media_packet_destroy(audio_pkt); return ret; } -static void feed_video_data_thread_func(void *data) +static void feed_audio_data_thread_func() { - appdata_s *ad = (appdata_s *)data; + int audio_frame_count = 0; - while (TRUE) { - static int frame_count = 0; - if (frame_count < ES_DEFAULT_NUMBER_OF_FEED) { - if (!feed_video_data(ad)) - break; - frame_count++; - } else { - feed_eos_data(ad); + if (!g_content[INFO_AUDIO].contents_file) { + g_print("Not open contents files\n"); + return; + } + + while (!g_thread_end) { + if (audio_frame_count == ES_DEFAULT_NUMBER_OF_FEED) { + feed_eos_data(&g_content[INFO_AUDIO]); break; } + + if (!feed_audio_data()) + break; + + audio_frame_count++; } } @@ -497,134 +570,372 @@ static bool _supported_media_format_cb(media_format_mimetype_e format, void *use return true; } -static int app_reset(bundle *b, void *data) +static void _stop_thread() { - /* Take necessary actions when application becomes visible. */ - appdata_s *ad = (appdata_s *)data; - int ret = PLAYER_ERROR_NONE; - - LOGD("start"); - - if (ad == NULL) { - LOGE("appdata is NULL"); - return -1; + int i = 0; + g_thread_end = TRUE; + for (i = 0; i < INFO_MAX; i++) { + if (g_content[i].feeding_thread_id) { + pthread_join(g_content[i].feeding_thread_id, NULL); + g_content[i].feeding_thread_id = 0; + } } +} - ret = player_create(&ad->player_handle); - if (ret != PLAYER_ERROR_NONE) { - LOGE("player_create failed : 0x%x", ret); - return -1; - } +static void _player_create() +{ + int ret = 0; -#if USE_EVAS_DISPLAY - ret = player_set_display(ad->player_handle, PLAYER_DISPLAY_TYPE_EVAS, GET_DISPLAY(ad->rect)); -#else - ret = player_set_display(ad->player_handle, PLAYER_DISPLAY_TYPE_OVERLAY, GET_DISPLAY(ad->win)); -#endif - if (ret != PLAYER_ERROR_NONE) { - LOGE("player_set_display failed : 0x%x", ret); - goto FAILED; - } + if (g_player_handle) + player_destroy(g_player_handle); - /* get media format format */ - ret = media_format_create(&ad->video_fmt); - if (ret != MEDIA_FORMAT_ERROR_NONE) { - LOGE("media_format_create : 0x%x", ret); - goto FAILED; - } + ret = player_create(&g_player_handle); + g_print("player_create returned : 0x%x\n", ret); +} - /* set video format */ - media_format_set_video_mime(ad->video_fmt, ES_DEFAULT_VIDEO_FORMAT_TYPE); - media_format_set_video_width(ad->video_fmt, ES_DEFAULT_VIDEO_FORMAT_WIDTH); - media_format_set_video_height(ad->video_fmt, ES_DEFAULT_VIDEO_FORMAT_HEIGHT); - media_format_set_video_frame_rate(ad->video_fmt, ES_DEFAULT_VIDEO_FPS); +static void _player_play() +{ + int ret = 0; + #if USE_EVAS_DISPLAY + ret = player_set_display(g_player_handle, PLAYER_DISPLAY_TYPE_EVAS, GET_DISPLAY(g_win_id)); + #else + ret = player_set_display(g_player_handle, PLAYER_DISPLAY_TYPE_OVERLAY, GET_DISPLAY(g_win_id)); + #endif - player_set_media_stream_buffer_max_size(ad->player_handle, PLAYER_STREAM_TYPE_VIDEO, (unsigned long long)3 * 1024 * 1024); - player_set_media_stream_buffer_min_threshold(ad->player_handle, PLAYER_STREAM_TYPE_VIDEO, 50); + player_set_media_stream_buffer_max_size(g_player_handle, PLAYER_STREAM_TYPE_VIDEO, (unsigned long long)3 * 1024 * 1024); + player_set_media_stream_buffer_max_size(g_player_handle, PLAYER_STREAM_TYPE_AUDIO, (unsigned long long)1024 * 1024); - ret = player_set_media_stream_buffer_status_cb_ex(ad->player_handle, PLAYER_STREAM_TYPE_VIDEO, _video_buffer_status_cb_ex, (void *)ad); + player_set_media_stream_buffer_min_threshold(g_player_handle, PLAYER_STREAM_TYPE_VIDEO, 50); + player_set_media_stream_buffer_min_threshold(g_player_handle, PLAYER_STREAM_TYPE_AUDIO, 50); + + ret = player_set_media_stream_buffer_status_cb_ex(g_player_handle, PLAYER_STREAM_TYPE_VIDEO, _video_buffer_status_cb_ex, NULL); if (ret != PLAYER_ERROR_NONE) { LOGE("player set video buffer status cb failed : 0x%x", ret); goto FAILED; } - ret = player_set_media_stream_buffer_status_cb_ex(ad->player_handle, PLAYER_STREAM_TYPE_AUDIO, _audio_buffer_status_cb_ex, (void *)ad); + ret = player_set_media_stream_buffer_status_cb_ex(g_player_handle, PLAYER_STREAM_TYPE_AUDIO, _audio_buffer_status_cb_ex, NULL); if (ret != PLAYER_ERROR_NONE) { LOGE("player set audio buffer status cb failed : 0x%x", ret); goto FAILED; } - ret = player_set_media_stream_seek_cb(ad->player_handle, PLAYER_STREAM_TYPE_VIDEO, _video_seek_data_cb, (void *)ad); + ret = player_set_media_stream_seek_cb(g_player_handle, PLAYER_STREAM_TYPE_VIDEO, _video_seek_data_cb, NULL); if (ret != PLAYER_ERROR_NONE) { LOGE("player set seek data cb for video failed : 0x%x", ret); goto FAILED; } - ret = player_set_media_stream_seek_cb(ad->player_handle, PLAYER_STREAM_TYPE_AUDIO, _audio_seek_data_cb, (void *)ad); + ret = player_set_media_stream_seek_cb(g_player_handle, PLAYER_STREAM_TYPE_AUDIO, _audio_seek_data_cb, NULL); if (ret != PLAYER_ERROR_NONE) { LOGE("player set seek data cb for audio failed : 0x%x", ret); goto FAILED; } - player_foreach_media_stream_supported_format(ad->player_handle, _supported_media_format_cb, ad->player_handle); + player_foreach_media_stream_supported_format(g_player_handle, _supported_media_format_cb, g_player_handle); + + if (g_content[INFO_AUDIO].format) + player_set_media_stream_info(g_player_handle, PLAYER_STREAM_TYPE_AUDIO, g_content[INFO_AUDIO].format); - /* send media packet to player */ - player_set_media_stream_info(ad->player_handle, PLAYER_STREAM_TYPE_VIDEO, ad->video_fmt); + if (g_content[INFO_VIDEO].format) + player_set_media_stream_info(g_player_handle, PLAYER_STREAM_TYPE_VIDEO, g_content[INFO_VIDEO].format); - ret = player_prepare_async(ad->player_handle, _player_prepared_cb, (void *)ad); + ret = player_prepare_async(g_player_handle, _player_prepared_cb, NULL); if (ret != PLAYER_ERROR_NONE) { LOGE("player prepare failed : 0x%x", ret); goto FAILED; } - pthread_create(&ad->feeding_thread_id, NULL, (void *)feed_video_data_thread_func, (void *)ad); + if (g_content[INFO_AUDIO].format) + pthread_create(&g_content[INFO_AUDIO].feeding_thread_id, NULL, (void *)feed_audio_data_thread_func, NULL); - LOGD("done"); + if (g_content[INFO_VIDEO].format) + pthread_create(&g_content[INFO_VIDEO].feeding_thread_id, NULL, (void *)feed_video_data_thread_func, NULL); - return 0; + return; FAILED: - if (ad->player_handle) { - player_destroy(ad->player_handle); - ad->player_handle = NULL; + if (g_player_handle) { + player_destroy(g_player_handle); + g_player_handle = NULL; } +} - return -1; +static void _player_stop() +{ + int ret = player_stop(g_player_handle); + g_print("player_stop returned : 0x%x\n", ret); + _stop_thread(); } -static int app_terminate(void *data) +static void _player_pause() { - /* Release all resources. */ - appdata_s *ad = (appdata_s *)data; + int ret = player_pause(g_player_handle); + g_print("player_pause returned : 0x%x\n", ret); +} - LOGD("start"); +static void _player_unprepare() +{ + int ret = 0; + _stop_thread(); + ret = player_unprepare(g_player_handle); + g_print("_player_unprepare returned : 0x%x\n", ret); +} - if (ad == NULL) { - LOGE("appdata is NULL"); - return -1; +static void _player_destroy() +{ + int ret = 0; + _player_unprepare(); + ret = player_destroy(g_player_handle); + g_player_handle = NULL; + g_print("player_destroy returned : 0x%x\n", ret); +} + +static void _input_file_name(char *filename, bool is_audio) +{ + int len = 0; + const char *media_path = NULL; + + if (!filename || filename[0] == '\0') + media_path = is_audio ? ES_DEFAULT_AAC_AUDIO_PATH : ES_DEFAULT_H264_VIDEO_PATH; + else + media_path = (const char *)filename; + + g_print("input media path = %s \n", media_path); + + len = strlen(media_path); + if (len < 0 || len > MAX_STRING_LEN - 1) + return; + + if (is_audio) { + g_content[INFO_AUDIO].contents_file = fopen(media_path, "r"); + g_menu_state = CURRENT_STATUS_AUDIO_FORMAT; + } else { + g_content[INFO_VIDEO].contents_file = fopen(media_path, "r"); + g_menu_state = CURRENT_STATUS_VIDEO_FORMAT; + } +} + +void _interpret_main_menu(char *cmd) +{ + int len = strlen(cmd); + if (len == 1) { + if (strncmp(cmd, "a", 1) == 0) { + _player_create(); + } else if (strncmp(cmd, "b", 1) == 0) { + _player_play(); + } else if (strncmp(cmd, "c", 1) == 0) { + _player_stop(); + } else if (strncmp(cmd, "e", 1) == 0) { + _player_pause(); + } else if (strncmp(cmd, "q", 1) == 0) { + quit_program(); + } else { + g_print("unknown menu \n"); + } + } else if (len == 2) { + if (strncmp(cmd, "af", 2) == 0) { + g_menu_state = CURRENT_STATUS_AUDIO_FILENAME; + } else if (strncmp(cmd, "vf", 2) == 0) { + g_menu_state = CURRENT_STATUS_VIDEO_FILENAME; + } else { + g_print("unknown menu \n"); + } + } else { + g_print("unknown menu \n"); } +} - app_pause(data); +void display_sub_basic() +{ + g_print("\n"); + g_print("=========================================================================================\n"); + g_print(" Player ES Test (press q to quit) \n"); + g_print(" ex) a -> af/vf -> b --------------------------------------------------------------------\n"); + g_print("a. Create\t"); + g_print("b. Play \t"); + g_print("c. Stop \t"); + g_print("d. Resume\t"); + g_print("e. Pause \n"); + g_print("un. Unprepare \t"); + g_print("dt. Destroy \n"); + g_print("af. Set audio file \t"); + g_print("vf. Set Video file \n"); + g_print("q. Quit \n"); + g_print("=========================================================================================\n"); +} - LOGD("done"); +static void displaymenu() +{ + if (g_menu_state == CURRENT_STATUS_MAINMENU) { + display_sub_basic(); + } else if (g_menu_state == CURRENT_STATUS_AUDIO_FILENAME) { + g_print("*** input audio media path.\n"); + } else if (g_menu_state == CURRENT_STATUS_VIDEO_FILENAME) { + g_print("*** input video media path.\n"); + } else if (g_menu_state == CURRENT_STATUS_AUDIO_FORMAT) { + g_print("*** input audio format(aac only)(sample_rate, channel)\n"); + } else if (g_menu_state == CURRENT_STATUS_VIDEO_FORMAT) { + g_print("*** input video format(h264 only)(width, height, fps)\n"); + } else { + g_print("*** unknown status.\n"); + quit_program(); + } + g_print(" >>> "); +} - return 0; + +void quit_program() +{ + if (g_player_handle == NULL) { + g_print("player_handle is NULL"); + return; + } + + player_unset_media_stream_buffer_status_cb_ex(g_player_handle, PLAYER_STREAM_TYPE_VIDEO); + player_unset_media_stream_buffer_status_cb_ex(g_player_handle, PLAYER_STREAM_TYPE_AUDIO); + player_unset_media_stream_seek_cb(g_player_handle, PLAYER_STREAM_TYPE_VIDEO); + player_unset_media_stream_seek_cb(g_player_handle, PLAYER_STREAM_TYPE_AUDIO); + + _player_destroy(); + + /* unref media format */ + for (int i = 0; i < INFO_MAX; i++) { + if (g_content[i].format) { + media_format_unref(g_content[i].format); + g_content[i].format = NULL; + } + + if (g_content[i].contents_file) { + fclose(g_content[i].contents_file); + g_content[i].contents_file = NULL; + } + } + + elm_exit(); } -int main(int argc, char *argv[]) +gboolean timeout_quit_program(void *data) { - int ret = 0; - static appdata_s ad = { 0, }; + quit_program(); + return FALSE; +} - LOGD("start"); +void reset_menu_state(void) +{ + g_menu_state = CURRENT_STATUS_MAINMENU; +} - memset(&ad, 0x0, sizeof(appdata_s)); +gboolean timeout_menu_display(void *data) +{ + displaymenu(); + return FALSE; +} - LOGD("call appcore_efl_main"); +static void interpret(char *cmd) +{ + static int value1 = 0; - ops.data = &ad; + switch (g_menu_state) { + case CURRENT_STATUS_MAINMENU: + { + _interpret_main_menu(cmd); + } + break; + case CURRENT_STATUS_AUDIO_FILENAME: + { + _input_file_name(cmd, TRUE); + } + break; + case CURRENT_STATUS_VIDEO_FILENAME: + { + _input_file_name(cmd, FALSE); + } + break; + case CURRENT_STATUS_AUDIO_FORMAT: + { + value1 = atoi(cmd); + static int cnt = 0; + static int sample_rate = 0; + static int channels = 0; + switch (cnt) { + case 0: + sample_rate = value1 ? value1 : ES_DEFAULT_AUDIO_SAMPLE_RATE; + cnt++; + break; + case 1: + channels = value1 ? value1 : ES_DEFAULT_AUDIO_CHANNELS; + cnt = 0; + media_format_create(&g_content[INFO_AUDIO].format); + media_format_set_audio_mime(g_content[INFO_AUDIO].format, ES_DEFAULT_AUDIO_FORMAT_TYPE); + media_format_set_audio_samplerate(g_content[INFO_AUDIO].format, sample_rate); + media_format_set_audio_channel(g_content[INFO_AUDIO].format, channels); + g_content[INFO_AUDIO].pts_offset = ES_SECOND / sample_rate; + sample_rate = channels = 0; + reset_menu_state(); + break; + } + } + break; + case CURRENT_STATUS_VIDEO_FORMAT: + { + value1 = atoi(cmd); + static int cnt = 0; + static int width = 0; + static int height = 0; + static int fps = 0; + switch (cnt) { + case 0: + width = value1 ? value1 : ES_DEFAULT_VIDEO_FORMAT_WIDTH; + cnt++; + break; + case 1: + height = value1 ? value1 : ES_DEFAULT_VIDEO_FORMAT_HEIGHT; + cnt++; + break; + case 2: + fps = value1 ? value1 : ES_DEFAULT_VIDEO_FPS; + cnt = 0; + media_format_create(&g_content[INFO_VIDEO].format); + media_format_set_video_mime(g_content[INFO_VIDEO].format, ES_DEFAULT_VIDEO_FORMAT_TYPE); + media_format_set_video_width(g_content[INFO_VIDEO].format, width); + media_format_set_video_height(g_content[INFO_VIDEO].format, height); + media_format_set_video_frame_rate(g_content[INFO_VIDEO].format, fps); + g_content[INFO_VIDEO].pts_offset = ES_SECOND / fps; + width = height = fps = 0; + reset_menu_state(); + } + break; + } + break; + + } + g_timeout_add(100, timeout_menu_display, 0); +} - ret = appcore_efl_main(PACKAGE, &argc, &argv, &ops); +gboolean input(GIOChannel *channel) +{ + gchar buf[MAX_STRING_LEN]; + gsize read; + GError *error = NULL; - LOGD("appcore_efl_main() ret = 0x%x", ret); + g_io_channel_read_chars(channel, buf, MAX_STRING_LEN, &read, &error); + buf[read] = '\0'; + g_strstrip(buf); + interpret(buf); - return ret; + return TRUE; +} + +int main(int argc, char *argv[]) +{ + + GIOChannel *stdin_channel; + stdin_channel = g_io_channel_unix_new(0); + g_io_channel_set_flags(stdin_channel, G_IO_FLAG_NONBLOCK, NULL); + g_io_add_watch(stdin_channel, G_IO_IN, (GIOFunc)input, NULL); + + displaymenu(); + memset(&ad, 0x0, sizeof(appdata)); + ops.data = &ad; + + return appcore_efl_main(PACKAGE, &argc, &argv, &ops); } -- 2.7.4