Implement new api for set/unset eos callback 67/133467/5 accepted/tizen/unified/20170703.064214 submit/tizen/20170630.020714
authorGilbok Lee <gilbok.lee@samsung.com>
Mon, 12 Jun 2017 10:43:29 +0000 (19:43 +0900)
committerGilbok Lee <gilbok.lee@samsung.com>
Mon, 12 Jun 2017 12:25:01 +0000 (12:25 +0000)
[Version] 0.1.10
[Profile] Common
[Issue Type] Add new APIs

Change-Id: I9555587ec36ae1e3e419511b43e6835bb735c59a

include/mediamuxer_port.h
include/mediamuxer_private.h
include/port_gst/mediamuxer_port_gst.h
src/mediamuxer.c
src/mediamuxer_port.c
src/port_gst/mediamuxer_port_gst.c
test/mediamuxer_test.c

index cbc4b00..90e7dbb 100755 (executable)
@@ -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
index 06779cc..73277b9 100755 (executable)
@@ -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 {
index c1a2646..24de8f6 100755 (executable)
@@ -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
index 50344c1..44f2315 100644 (file)
@@ -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;
+}
+
index 942fe35..22da57a 100644 (file)
@@ -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;
+}
index 97c6e09..eca4635 100755 (executable)
@@ -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;
+}
index 6761dc4..7b4aa73 100644 (file)
@@ -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");