From: Gilbok Lee Date: Mon, 12 Jun 2017 10:43:29 +0000 (+0900) Subject: Implement new api for set/unset eos callback X-Git-Tag: accepted/tizen/unified/20170703.064214^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ff98bad46c83850f68d0bfe5f2f5f1e4bfd1d1ce;p=platform%2Fcore%2Fapi%2Fmediamuxer.git Implement new api for set/unset eos callback [Version] 0.1.10 [Profile] Common [Issue Type] Add new APIs Change-Id: I9555587ec36ae1e3e419511b43e6835bb735c59a --- diff --git a/include/mediamuxer_port.h b/include/mediamuxer_port.h index cbc4b00..90e7dbb 100755 --- a/include/mediamuxer_port.h +++ b/include/mediamuxer_port.h @@ -324,6 +324,18 @@ extern "C" { typedef void (*mx_error_cb)(mediamuxer_error_e error, void *user_data); /** + * @brief Called when eos occurs in media muxer. + * @since_tizen 4.0 + * @param[in] user_data The user data passed from the code where + * mediamuxer_set_eos_cb() was invoked + * This data will be accessible from @a mediamuxer_eos_cb + * @pre Create media demuxer handle by calling mediamuxer_create() function. + * @see mediamuxer_set_eos_cb() + * @see mediamuxer_unset_eos_cb() + */ +typedef void (*mx_eos_cb)(void *user_data); + +/** * Attribute validity structure */ typedef struct _media_port_muxer_ops { @@ -342,6 +354,7 @@ typedef struct _media_port_muxer_ops { int (*stop)(MMHandleType pHandle); int (*destroy)(MMHandleType pHandle); int (*set_error_cb)(MMHandleType pHandle, mx_error_cb callback, void* user_data); + int (*set_eos_cb)(MMHandleType pHandle, mx_eos_cb callback, void *user_data); } media_port_muxer_ops; /* ============================================================================ @@ -606,6 +619,17 @@ int mx_resume(MMHandleType mediamuxer); */ int mx_set_error_cb(MMHandleType muxer, mediamuxer_error_cb callback, void* user_data); +/** + * This function is to set eos call back function + * + * @param muxer [in] Handle of muxer + * @param callback [in] call back function pointer + * @param user_data [in] user specific data pointer + * + * @return This function returns zero on success, or negative value with error code. + */ +int mx_set_eos_cb(MMHandleType muxer, mediamuxer_eos_cb callback, void *user_data); + #ifdef __cplusplus } #endif diff --git a/include/mediamuxer_private.h b/include/mediamuxer_private.h index 06779cc..73277b9 100755 --- a/include/mediamuxer_private.h +++ b/include/mediamuxer_private.h @@ -86,6 +86,8 @@ typedef struct _mediamuxer_s { mediamuxer_error_cb error_cb; void* error_cb_userdata; mediamuxer_state_e muxer_state; + mediamuxer_eos_cb eos_cb; + void* eos_cb_userdata; } mediamuxer_s; typedef struct { diff --git a/include/port_gst/mediamuxer_port_gst.h b/include/port_gst/mediamuxer_port_gst.h index c1a2646..24de8f6 100755 --- a/include/port_gst/mediamuxer_port_gst.h +++ b/include/port_gst/mediamuxer_port_gst.h @@ -94,6 +94,17 @@ typedef struct _mxgst_handle_t { */ typedef void (*gst_muxer_error_cb)(mediamuxer_error_e error, void *user_data); +/** + * @brief Called when the eos has occured. + * @since_tizen 4.0 + * @details It will be invoked when the eos has occured. + * @param[in] user_data The user data passed from the callback registration function + * @pre It will be invoked when the eos has occured if user register this callback using mediamuxer_set_eos_cb(). + * @see mediamuxer_set_eos_cb() + * @see mediamuxer_unset_eos_cb() + */ +typedef void (*gst_muxer_eos_cb)(void *user_data); + #ifdef __cplusplus } #endif diff --git a/src/mediamuxer.c b/src/mediamuxer.c index 50344c1..44f2315 100644 --- a/src/mediamuxer.c +++ b/src/mediamuxer.c @@ -31,6 +31,7 @@ * Public Implementation */ static gboolean _mediamuxer_error_cb(mediamuxer_error_e error, void *user_data); +static gboolean _mediamuxer_eos_cb(void *user_data); int mediamuxer_create(mediamuxer_h *muxer) { @@ -63,6 +64,7 @@ int mediamuxer_create(mediamuxer_h *muxer) /* set callback */ mx_set_error_cb(handle->mx_handle, (mediamuxer_error_cb)_mediamuxer_error_cb, handle); + mx_set_eos_cb(handle->mx_handle, (mediamuxer_eos_cb)_mediamuxer_eos_cb, handle); if (ret == MEDIAMUXER_ERROR_NONE) handle->muxer_state = MEDIAMUXER_STATE_IDLE; return MEDIAMUXER_ERROR_NONE; @@ -442,3 +444,47 @@ static gboolean _mediamuxer_error_cb(mediamuxer_error_e error, void *user_data) return 0; } + +static gboolean _mediamuxer_eos_cb(void *user_data) +{ + if (user_data == NULL) { + MX_I("_mediamuxer_eos_cb: EOS to report. But call back is not set"); + return 0; + } + mediamuxer_s *handle = (mediamuxer_s *)user_data; + if (handle->muxer_state != MEDIAMUXER_STATE_MUXING) + return MEDIAMUXER_ERROR_INVALID_STATE; + if (handle->eos_cb) + ((mediamuxer_eos_cb)handle->eos_cb)(handle->eos_cb_userdata); + else + MX_I("_mediamuxer_eos_cb: EOS to report. But call back is not set"); + return 0; +} + +int mediamuxer_set_eos_cb(mediamuxer_h muxer, + mediamuxer_eos_cb callback, void *user_data) +{ + MUXER_INSTANCE_CHECK(muxer); + mediamuxer_s *handle; + handle = (mediamuxer_s *)muxer; + if (handle->muxer_state != MEDIAMUXER_STATE_IDLE) + return MEDIAMUXER_ERROR_INVALID_STATE; + handle->eos_cb = callback; + handle->eos_cb_userdata = user_data; + MX_I("set eos_cb(%p)", callback); + return MEDIAMUXER_ERROR_NONE; +} + +int mediamuxer_unset_eos_cb(mediamuxer_h muxer) +{ + MUXER_INSTANCE_CHECK(muxer); + mediamuxer_s *handle; + handle = (mediamuxer_s *)muxer; + if (handle->muxer_state != MEDIAMUXER_STATE_IDLE) + return MEDIAMUXER_ERROR_INVALID_STATE; + handle->eos_cb = NULL; + handle->eos_cb_userdata = NULL; + MX_I("mediamuxer_unset_eos_cb"); + return MEDIAMUXER_ERROR_NONE; +} + diff --git a/src/mediamuxer_port.c b/src/mediamuxer_port.c index 942fe35..22da57a 100644 --- a/src/mediamuxer_port.c +++ b/src/mediamuxer_port.c @@ -274,3 +274,19 @@ int mx_set_error_cb(MMHandleType muxer, MEDIAMUXER_FLEAVE(); return result; } + +int mx_set_eos_cb(MMHandleType muxer, + mediamuxer_eos_cb callback, void* user_data) +{ + MEDIAMUXER_FENTER(); + int result = MX_ERROR_NONE; + mx_handle_t *mx_handle = (mx_handle_t *) muxer; + MEDIAMUXER_CHECK_NULL(mx_handle); + media_port_muxer_ops *pOps = mx_handle->muxer_ops; + MEDIAMUXER_CHECK_NULL(pOps); + result = pOps->set_eos_cb(mx_handle->mxport_handle, callback, user_data); + MEDIAMUXER_CHECK_SET_AND_PRINT(result, MX_ERROR_NONE, result, + MX_ERROR, "error while setting eos call back"); + MEDIAMUXER_FLEAVE(); + return result; +} diff --git a/src/port_gst/mediamuxer_port_gst.c b/src/port_gst/mediamuxer_port_gst.c index 97c6e09..eca4635 100755 --- a/src/port_gst/mediamuxer_port_gst.c +++ b/src/port_gst/mediamuxer_port_gst.c @@ -43,6 +43,10 @@ static int gst_muxer_destroy(MMHandleType pHandle); static int gst_muxer_set_error_cb(MMHandleType pHandle, gst_muxer_error_cb callback, void* user_data); +static int __gst_eos_callback(void *user_data); +static int gst_muxer_set_eos_cb(MMHandleType pHandle, + gst_muxer_eos_cb callback, void* user_data); + /* Media Muxer API common */ static media_port_muxer_ops def_mux_ops = { .n_size = 0, @@ -59,6 +63,7 @@ static media_port_muxer_ops def_mux_ops = { .unprepare = gst_muxer_unprepare, .destroy = gst_muxer_destroy, .set_error_cb = gst_muxer_set_error_cb, + .set_eos_cb = gst_muxer_set_eos_cb, }; int gst_mediamuxer_port_register(media_port_muxer_ops *pOps) @@ -596,6 +601,7 @@ static gboolean _mx_gst_bus_call(GstBus *bus, GstMessage *msg, gpointer data) switch (GST_MESSAGE_TYPE(msg)) { case GST_MESSAGE_EOS: MX_I("End of stream"); + __gst_eos_callback(data); break; case GST_MESSAGE_ERROR: { gchar *debug; @@ -1511,3 +1517,45 @@ ERROR: MEDIAMUXER_FLEAVE(); return ret; } + +int gst_muxer_set_eos_cb(MMHandleType pHandle, gst_muxer_eos_cb callback, void* user_data) +{ + MEDIAMUXER_FENTER(); + int ret = MX_ERROR_NONE; + MEDIAMUXER_CHECK_NULL(pHandle); + mxgst_handle_t *gst_handle = (mxgst_handle_t *) pHandle; + + if (gst_handle->user_cb[_GST_EVENT_TYPE_EOS]) { + MX_E("Already set mediamuxer_error_cb"); + ret = MX_ERROR_INVALID_ARGUMENT; + goto ERROR; + } else { + if (!callback) { + ret = MX_ERROR_INVALID_ARGUMENT; + goto ERROR; + } + } + + MX_I("Set event handler callback(cb = %p, data = %p)", callback, user_data); + gst_handle->user_cb[_GST_EVENT_TYPE_EOS] = (gst_muxer_eos_cb) callback; + gst_handle->user_data[_GST_EVENT_TYPE_EOS] = user_data; + MEDIAMUXER_FLEAVE(); + return MX_ERROR_NONE; +ERROR: + MEDIAMUXER_FLEAVE(); + return ret; +} + +static int __gst_eos_callback(void* user_data) +{ + if (user_data == NULL) { + MX_E("Invalid argument"); + return MX_ERROR; + } + mxgst_handle_t *gst_handle = (mxgst_handle_t *)user_data; + if (gst_handle->user_cb[_GST_EVENT_TYPE_EOS]) + ((gst_muxer_eos_cb)gst_handle->user_cb[_GST_EVENT_TYPE_EOS])(gst_handle->user_data[_GST_EVENT_TYPE_EOS]); + else + MX_E("EOS received, but callback is not set!!!"); + return MX_ERROR_NONE; +} diff --git a/test/mediamuxer_test.c b/test/mediamuxer_test.c index 6761dc4..7b4aa73 100644 --- a/test/mediamuxer_test.c +++ b/test/mediamuxer_test.c @@ -450,6 +450,12 @@ void app_err_cb(mediamuxer_error_e error, void *user_data) g_print("Got Error %d: %s from mediamuxer\n", error, (char *)user_data); } +void app_eos_cb(void *user_data) +{ + g_print("Got EOS from mediamuxer\n"); +} + + int test_mediamuxer_set_error_cb() { int ret = 0; @@ -458,6 +464,14 @@ int test_mediamuxer_set_error_cb() return ret; } +int test_mediamuxer_set_eos_cb() +{ + int ret = 0; + g_print("test_mediamuxer_set_eos_cb\n"); + ret = mediamuxer_set_eos_cb(myMuxer, app_eos_cb, myMuxer); + return ret; +} + int test_mediamuxer_with_demuxer_prepare() { int tracks_num = 0; @@ -580,27 +594,33 @@ void _interpret_main_menu(char *cmd) test_mediamuxer_pause(); } else if (strncmp(cmd, "r", 1) == 0) { test_mediamuxer_resume(); - } else if (strncmp(cmd, "b", 1) == 0) { - test_mediamuxer_set_error_cb(); } else if (strncmp(cmd, "q", 1) == 0) { quit_testApp(); } else { g_print("unknown menu command. Please try again\n"); } - } else if (len == 2 && validate_with_codec) { - if (strncmp(cmd, "cv", 2) == 0) - g_menu_state = CURRENT_STATUS_RAW_VIDEO_FILENAME; - else if (strncmp(cmd, "ve", 2) == 0) - g_menu_state = CURRENT_STATUS_SET_VENC_INFO; - else if (strncmp(cmd, "ca", 2) == 0) - g_menu_state = CURRENT_STATUS_RAW_AUDIO_FILENAME; - else if (strncmp(cmd, "ae", 2) == 0) - g_menu_state = CURRENT_STATUS_SET_AENC_INFO; - } else if (len == 2 && validate_with_demux) { - if (strncmp(cmd, "mp", 2) == 0) - g_menu_state = CURRENT_STATUS_FILENAME; - else if (strncmp(cmd, "pr", 2) == 0) - test_mediamuxer_with_demuxer_prepare(); + } else if (len == 2) { + if (strncmp(cmd, "er", 2) == 0) { + test_mediamuxer_set_error_cb(); + } else if (strncmp(cmd, "eo", 2) == 0) { + test_mediamuxer_set_eos_cb(); + } else if (validate_with_codec) { + if (strncmp(cmd, "cv", 2) == 0) + g_menu_state = CURRENT_STATUS_RAW_VIDEO_FILENAME; + else if (strncmp(cmd, "ve", 2) == 0) + g_menu_state = CURRENT_STATUS_SET_VENC_INFO; + else if (strncmp(cmd, "ca", 2) == 0) + g_menu_state = CURRENT_STATUS_RAW_AUDIO_FILENAME; + else if (strncmp(cmd, "ae", 2) == 0) + g_menu_state = CURRENT_STATUS_SET_AENC_INFO; + } else if (validate_with_demux) { + if (strncmp(cmd, "mp", 2) == 0) + g_menu_state = CURRENT_STATUS_FILENAME; + else if (strncmp(cmd, "pr", 2) == 0) + test_mediamuxer_with_demuxer_prepare(); + } else { + g_print("unknown menu command. Please try again\n"); + } } else { g_print("unknown menu command. Please try again\n"); } @@ -651,32 +671,32 @@ static void interpret(char *cmd) { switch (g_menu_state) { case CURRENT_STATUS_MAINMENU: { - _interpret_main_menu(cmd); - break; - } + _interpret_main_menu(cmd); + break; + } case CURRENT_STATUS_MP4_FILENAME: { - input_filepath(cmd); - strncpy(media_file, cmd, MAX_INPUT_SIZE - 1); - g_menu_state = CURRENT_STATUS_MAINMENU; - break; - } + input_filepath(cmd); + strncpy(media_file, cmd, MAX_INPUT_SIZE - 1); + g_menu_state = CURRENT_STATUS_MAINMENU; + break; + } case CURRENT_STATUS_DATA_SINK: { - strncpy(data_sink, cmd, MAX_INPUT_SIZE - 1); - test_mediamuxer_set_data_sink(); - g_menu_state = CURRENT_STATUS_MAINMENU; - break; - } + strncpy(data_sink, cmd, MAX_INPUT_SIZE - 1); + test_mediamuxer_set_data_sink(); + g_menu_state = CURRENT_STATUS_MAINMENU; + break; + } case CURRENT_STATUS_RAW_VIDEO_FILENAME: { /* "cv" */ - use_video = 1; - static int codecid = 0; - input_raw_filepath(cmd); - use_encoder = 1; - codecid = 0x2030; /* video */ - mediacodec_config_set_codec(codecid, 5); - reset_menu_state(); - g_menu_state = CURRENT_STATUS_MAINMENU; - break; - } + use_video = 1; + static int codecid = 0; + input_raw_filepath(cmd); + use_encoder = 1; + codecid = 0x2030; /* video */ + mediacodec_config_set_codec(codecid, 5); + reset_menu_state(); + g_menu_state = CURRENT_STATUS_MAINMENU; + break; + } case CURRENT_STATUS_SET_VENC_INFO: /* "ve" */ { static int cnt = 0; @@ -697,61 +717,62 @@ static void interpret(char *cmd) target_bits = atoi(cmd); g_print("width = %d, height = %d, fps = %f, target_bits = %d\n", width, height, fps, target_bits); mediacodec_config_set_venc_info(width, height, fps, target_bits); - mediacodec_config_prepare(); + mediacodec_config_prepare(); reset_menu_state(); cnt = 0; break; default: break; } + break; } case CURRENT_STATUS_RAW_AUDIO_FILENAME: - { /* "ca" */ - use_video = 0; - static int codecid = 0; - input_raw_filepath(cmd); - use_encoder = 1; - codecid = 0x1060; /* audio */ - mediacodec_config_set_codec(codecid, 9); - reset_menu_state(); - g_menu_state = CURRENT_STATUS_MAINMENU; - break; - } + { /* "ca" */ + use_video = 0; + static int codecid = 0; + input_raw_filepath(cmd); + use_encoder = 1; + codecid = 0x1060; /* audio */ + mediacodec_config_set_codec(codecid, 9); + reset_menu_state(); + g_menu_state = CURRENT_STATUS_MAINMENU; + break; + } case CURRENT_STATUS_SET_AENC_INFO: /* ae */ - { - static int cnt = 0; - switch (cnt) { - case 0: - samplerate = atoi(cmd); - cnt++; - break; - case 1: - channel = atoi(cmd); - cnt++; - break; - case 2: - bit = atoi(cmd); - cnt++; - break; - case 3: - bitrate = atoi(cmd); - mediacodec_config_set_aenc_info(samplerate, channel, bit, bitrate); - mediacodec_config_prepare(); - reset_menu_state(); - cnt = 0; - break; - default: - break; - } - } - break; - case CURRENT_STATUS_FILENAME: { /* mp */ - input_filepath(cmd); - strncpy(media_file, cmd, MAX_INPUT_SIZE - 1); - g_menu_state = CURRENT_STATUS_MAINMENU; + { + static int cnt = 0; + switch (cnt) { + case 0: + samplerate = atoi(cmd); + cnt++; + break; + case 1: + channel = atoi(cmd); + cnt++; + break; + case 2: + bit = atoi(cmd); + cnt++; + break; + case 3: + bitrate = atoi(cmd); + mediacodec_config_set_aenc_info(samplerate, channel, bit, bitrate); + mediacodec_config_prepare(); + reset_menu_state(); + cnt = 0; + break; + default: break; } + } + break; + case CURRENT_STATUS_FILENAME: { /* mp */ + input_filepath(cmd); + strncpy(media_file, cmd, MAX_INPUT_SIZE - 1); + g_menu_state = CURRENT_STATUS_MAINMENU; + break; + } default: break; } @@ -785,8 +806,9 @@ static void display_sub_basic() g_print("s. Start \n"); g_print("m. StartMuxing \n"); g_print("p. PauseMuxing \t"); - g_print("r. ResumeMuxing \t"); - g_print("b. Set error callback \n"); + g_print("r. ResumeMuxing \n"); + g_print("er. Set error callback \t"); + g_print("eo. Set eos callback \n"); g_print("t. Stop \t"); g_print("u. UnPrepare \t"); g_print("d. Destroy \n");