Update the code for sync with SPIN 2.4 (Muxer) 14/45614/1 submit/tizen/20150811.021742
authorJoungkook Seo <jk7704.seo@samsung.com>
Mon, 10 Aug 2015 01:48:42 +0000 (10:48 +0900)
committerJoungkook Seo <jk7704.seo@samsung.com>
Mon, 10 Aug 2015 01:48:49 +0000 (10:48 +0900)
Change-Id: I0c673e63606be12bef08c90345d9e8b65bd44cb7
Signed-off-by: Joungkook Seo <jk7704.seo@samsung.com>
doc/mediamuxer_doc.h
include/mediamuxer.h
include/mediamuxer_port.h
src/mediamuxer.c
src/mediamuxer_port.c
src/port_gst/mediamuxer_port_gst.c
test/mediamuxer_test.c

index d955b47..91e2e9e 100755 (executable)
@@ -43,6 +43,7 @@
  * mediamuxer_set_data_sink()
  * mediamuxer_add_track(1)
  * mediamuxer_add_track(2)     [add more tracks, if needed]
+ * mediamuxer_prepare()
  * mediamuxer_start()
  * while()
  *     if (is_track(1)_data_available)
@@ -54,6 +55,7 @@
  *     else
  *             mediamuxer_close_track(2)
  * mediamuxer_stop()
+ * mediamuxer_unprepare()
  * mediamuxer_destroy()
  */
 
index 0a382b1..6b601b8 100755 (executable)
@@ -145,13 +145,13 @@ int mediamuxer_set_data_sink(mediamuxer_h muxer, char *path, mediamuxer_output_f
  * @pre The media muxer state must be set to #MEDIAMUXER_STATE_IDLE.
  * @see #media_format_h
  * @see mediamuxer_create()
- * @see mediamuxer_start()
+ * @see mediamuxer_prepare()
  * */
 int mediamuxer_add_track(mediamuxer_h muxer, media_format_h media_format, int *track_index);
 
 /**
- * @brief Starts the media muxer.
- * @remarks Initiates the necessary parameters, and keeps the muxer ready for writing data.
+ * @brief Prepares the media muxer.
+ * @remarks Initiates the necessary parameters.
  * @since_tizen 3.0
  * @param[in] muxer     The media muxer handle
  * @return @c 0 on success, otherwise a negative error value
@@ -161,6 +161,22 @@ int mediamuxer_add_track(mediamuxer_h muxer, media_format_h media_format, int *t
  * @pre The media muxer state must be set to #MEDIAMUXER_STATE_IDLE.
  * @post The media muxer state will be #MEDIAMUXER_STATE_READY.
  * @see mediamuxer_create()
+ * @see mediamuxer_unprepare()
+ * */
+int mediamuxer_prepare(mediamuxer_h muxer);
+
+/**
+ * @brief Starts the media muxer.
+ * @remarks Keeps the muxer ready for writing data.
+ * @since_tizen 3.0
+ * @param[in] muxer     The media muxer handle
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIAMUXER_ERROR_NONE Successful
+ * @retval #MEDIAMUXER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIAMUXER_ERROR_INVALID_STATE Invalid state
+ * @pre The media muxer state must be set to #MEDIAMUXER_STATE_READY.
+ * @post The media muxer state will be #MEDIAMUXER_STATE_MUXING.
+ * @see mediamuxer_prepare()
  * @see mediamuxer_stop()
  * */
 int mediamuxer_start(mediamuxer_h muxer);
@@ -175,10 +191,10 @@ int mediamuxer_start(mediamuxer_h muxer);
  * @retval #MEDIAMUXER_ERROR_NONE Successful
  * @retval #MEDIAMUXER_ERROR_INVALID_PARAMETER Invalid parameter
  * @retval #MEDIAMUXER_ERROR_INVALID_STATE Invalid state
- * @pre The media muxer state must be set to #MEDIAMUXER_STATE_READY by calling mediamuxer_start() or
+ * @pre The media muxer state must be set to #MEDIAMUXER_STATE_READY by calling mediamuxer_prepare() or
  *      set to #MEDIAMUXER_STATE_PAUSED by calling mediamuxer_pause().
  * @post The media muxer state will be #MEDIAMUXER_STATE_MUXING.
- * @see mediamuxer_start()
+ * @see mediamuxer_prepare()
  * @see mediamuxer_close_track()
  * @see mediamuxer_pause()
  * @see #media_packet_h
@@ -197,7 +213,7 @@ int mediamuxer_write_sample(mediamuxer_h muxer, int track_index, media_packet_h
  * @pre The media muxer state must be set to #MEDIAMUXER_STATE_MUXING.
  * @see mediamuxer_write_sample()
  * @see mediamuxer_pause()
- * @see mediamuxer_stop()
+ * @see mediamuxer_unprepare()
  * @see #mediamuxer_error_e
  * */
 int mediamuxer_close_track(mediamuxer_h muxer, int track_index);
@@ -237,21 +253,38 @@ int mediamuxer_resume(mediamuxer_h muxer);
 
 /**
  * @brief Stops the media muxer.
- * @remarks Unrefs the variables created after calling mediamuxer_start().
+ * @remarks Keeps the muxer ready for writing data.
+ * @since_tizen 3.0
+ * @param[in] muxer     The media muxer handle
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIAMUXER_ERROR_NONE Successful
+ * @retval #MEDIAMUXER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MEDIAMUXER_ERROR_INVALID_STATE Invalid state
+ * @pre The media muxer state must be set to #MEDIAMUXER_STATE_MUXING
+ *     or #MEDIAMUXER_STATE_PAUSED.
+ * @post The media muxer state will be #MEDIAMUXER_STATE_READY.
+ * @see mediamuxer_start()
+ * @see mediamuxer_unprepare()
+ * */
+int mediamuxer_stop(mediamuxer_h muxer);
+
+/**
+ * @brief Unprepares the media muxer.
+ * @remarks Unrefs the variables created after calling mediamuxer_prepare().
  * @since_tizen 3.0
  * @param[in] muxer     The media muxer handle
  * @return @c 0 on success, otherwise a negative error value
  * @retval #MEDIAMUXER_ERROR_NONE Successful
  * @retval #MEDIAMUXER_ERROR_INVALID_PARAMETER Invalid parameter
  * @retval #MEDIAMUXER_ERROR_INVALID_STATE Invalid state
- * @pre The media muxer state must be set to #MEDIAMUXER_STATE_MUXING by calling mediamuxer_start() or
+ * @pre The media muxer state must be set to #MEDIAMUXER_STATE_READY or
  *      set to #MEDIAMUXER_STATE_PAUSED by calling mediamuxer_pause().
  * @post The media muxer state will be #MEDIAMUXER_STATE_IDLE.
  * @see mediamuxer_write_sample()
  * @see mediamuxer_pause()
  * @see mediamuxer_destroy()
  * */
-int mediamuxer_stop(mediamuxer_h muxer);
+int mediamuxer_unprepare(mediamuxer_h muxer);
 
 /**
  * @brief Removes the instance of media muxer and clear all its context memory.
index 191aaf7..93396fb 100755 (executable)
@@ -64,7 +64,7 @@ extern "C" {
 
     @par
     Most of functions which change muxer state work as synchronous. But,
-    mx_start() should be used asynchronously. Both mx_pause() and mx__resume()
+    mx_prepare() should be used asynchronously. Both mx_pause() and mx__resume()
     should also be used asynchronously in the case of streaming data.
     So, application have to confirm the result of those APIs through message
     callback function.
@@ -332,11 +332,13 @@ typedef struct _media_port_muxer_ops {
        /* Add new ops at the end of structure, no order change */
        int (*set_data_sink)(MMHandleType pHandle, char *uri, mediamuxer_output_format_e format);
        int (*add_track)(MMHandleType pHandle, media_format_h media_format, int *track_index);
+       int (*prepare)(MMHandleType pHandle);
        int (*start)(MMHandleType pHandle);
        int (*write_sample)(MMHandleType pHandle, int track_index, media_packet_h inbuf);
        int (*close_track)(MMHandleType pHandle, int track_index);
        int (*pause)(MMHandleType pHandle);
        int (*resume)(MMHandleType pHandle);
+       int (*unprepare)(MMHandleType pHandle);
        int (*stop)(MMHandleType pHandle);
        int (*destroy)(MMHandleType pHandle);
        int (*set_error_cb)(MMHandleType pHandle, mx_error_cb callback, void* user_data);
@@ -422,6 +424,26 @@ int mx_destroy(MMHandleType muxer);
  *
  * @par Example
  * @code
+if (mx_prepare(g_muxer) != MX_ERROR_NONE)
+{
+    MX_E("failed to prepare muxer\n");
+}
+ * @endcode
+ */
+int mx_prepare(MMHandleType muxer);
+
+/**
+ * This function starts the muxer object. \n
+ * For GST-port, this function sets the pipeline to playing
+ *
+ * @param   muxer     [in]    Handle of muxer
+ *
+ * @return  This function returns zero on success, or negative value with error
+               code.
+ * @see     mx_stop
+ *
+ * @par Example
+ * @code
 if (mx_start(g_muxer) != MX_ERROR_NONE)
 {
     MX_E("failed to start muxer\n");
@@ -481,7 +503,7 @@ int mx_write_sample(MMHandleType mediamuxer, int track_index, media_packet_h inb
  *
  * @return  This function returns zero on success, or negative value with error
                 code.
- * @see     mx_stop
+ * @see     mx_unprepare
  *
  * @par Example
  * @code
@@ -494,14 +516,14 @@ if (mx_close_track(g_muxer,1) != MX_ERROR_NONE)
 int mx_close_track(MMHandleType mediamuxer, int track_index);
 
 /**
- * This function stops/un-prepares the muxer object. \n
- * For GST-port, this function unrefs necessary gst elemetns
+ * This function stops the muxer object. \n
+ * For GST-port, this function sets the pipeline to ready
  *
  * @param   muxer     [in]    Handle of muxer
  *
  * @return  This function returns zero on success, or negative value with error
                code.
- * @see     mx_stop
+ * @see     mx_start
  *
  * @par Example
  * @code
@@ -514,6 +536,26 @@ if (mx_stop(g_muxer) != MX_ERROR_NONE)
 int mx_stop(MMHandleType mediamuxer);
 
 /**
+ * This function stops/un-prepares the muxer object. \n
+ * For GST-port, this function unrefs necessary gst elemetns
+ *
+ * @param   muxer     [in]    Handle of muxer
+ *
+ * @return  This function returns zero on success, or negative value with error
+               code.
+ * @see     mx_unprepare
+ *
+ * @par Example
+ * @code
+if (mx_unprepare(g_muxer) != MX_ERROR_NONE)
+{
+    MX_E("failed to unprepare muxer\n");
+}
+ * @endcode
+ */
+int mx_unprepare(MMHandleType mediamuxer);
+
+/**
  * This function pauses the muxing operation. \n
  * For GST-port, this function pauses the pipeline
  *
index aa75887..6618f5b 100644 (file)
@@ -64,7 +64,8 @@ int mediamuxer_create(mediamuxer_h *muxer)
 
                /* set callback */
                mx_set_error_cb(handle->mx_handle, (mediamuxer_error_cb)_mediamuxer_error_cb, handle);
-               handle->muxer_state = MEDIAMUXER_STATE_IDLE;
+               if (ret == MEDIAMUXER_ERROR_NONE)
+                       handle->muxer_state = MEDIAMUXER_STATE_IDLE;
                return MEDIAMUXER_ERROR_NONE;
        }
 }
@@ -129,13 +130,39 @@ int mediamuxer_add_track(mediamuxer_h muxer, media_format_h media_format, int *t
        return ret;
 }
 
+int mediamuxer_prepare(mediamuxer_h muxer)
+{
+       MX_I("mediamuxer_prepare\n");
+       int ret = MEDIAMUXER_ERROR_NONE;
+       MUXER_INSTANCE_CHECK(muxer);
+       mediamuxer_s *handle = (mediamuxer_s *)(muxer);
+       if (handle->muxer_state == MEDIAMUXER_STATE_IDLE) {
+               ret = mx_prepare(handle->mx_handle);
+               if (ret != MEDIAMUXER_ERROR_NONE) {
+                       MX_E("[CoreAPI][%s] MUXER_ERROR_INVALID_OPERATION(0x%08x)",
+                            __FUNCTION__, MEDIAMUXER_ERROR_INVALID_OPERATION);
+                       ret = MEDIAMUXER_ERROR_INVALID_OPERATION;
+               } else {
+                       MX_I("[CoreAPI][%s] prepare successful, handle : %p",
+                            __FUNCTION__, handle);
+               }
+       } else {
+               MX_E("[CoreAPI][%s] MEDIAMUXER_ERROR_INVALID_STATE(0x%08x)",
+                    __FUNCTION__, MEDIAMUXER_ERROR_INVALID_STATE);
+               return MEDIAMUXER_ERROR_INVALID_STATE;
+       }
+       if (ret == MEDIAMUXER_ERROR_NONE)
+               handle->muxer_state = MEDIAMUXER_STATE_READY;
+       return ret;
+}
+
 int mediamuxer_start(mediamuxer_h muxer)
 {
        MX_I("mediamuxer_start\n");
        int ret = MEDIAMUXER_ERROR_NONE;
        MUXER_INSTANCE_CHECK(muxer);
        mediamuxer_s *handle = (mediamuxer_s *)(muxer);
-       if (handle->muxer_state == MEDIAMUXER_STATE_IDLE) {
+       if (handle->muxer_state == MEDIAMUXER_STATE_READY) {
                ret = mx_start(handle->mx_handle);
                if (ret != MEDIAMUXER_ERROR_NONE) {
                        MX_E("[CoreAPI][%s] MUXER_ERROR_INVALID_OPERATION(0x%08x)",
@@ -150,7 +177,8 @@ int mediamuxer_start(mediamuxer_h muxer)
                     __FUNCTION__, MEDIAMUXER_ERROR_INVALID_STATE);
                return MEDIAMUXER_ERROR_INVALID_STATE;
        }
-       handle->muxer_state = MEDIAMUXER_STATE_READY;
+       if (ret == MEDIAMUXER_ERROR_NONE)
+               handle->muxer_state = MEDIAMUXER_STATE_MUXING;
        return ret;
 }
 
@@ -180,7 +208,8 @@ int mediamuxer_write_sample(mediamuxer_h muxer, int track_index, media_packet_h
                     __FUNCTION__, MEDIAMUXER_ERROR_INVALID_STATE);
                return MEDIAMUXER_ERROR_INVALID_STATE;
        }
-       handle->muxer_state = MEDIAMUXER_STATE_MUXING;
+       if (ret == MEDIAMUXER_ERROR_NONE)
+               handle->muxer_state = MEDIAMUXER_STATE_MUXING;
        return ret;
 }
 
@@ -237,7 +266,8 @@ int mediamuxer_pause(mediamuxer_h muxer)
                     __FUNCTION__, MEDIAMUXER_ERROR_INVALID_STATE);
                return MEDIAMUXER_ERROR_INVALID_STATE;
        }
-       handle->muxer_state = MEDIAMUXER_STATE_PAUSED;
+       if (ret == MEDIAMUXER_ERROR_NONE)
+               handle->muxer_state = MEDIAMUXER_STATE_PAUSED;
        return ret;
 }
 
@@ -263,7 +293,8 @@ int mediamuxer_resume(mediamuxer_h muxer)
                     __FUNCTION__, MEDIAMUXER_ERROR_INVALID_STATE);
                return MEDIAMUXER_ERROR_INVALID_STATE;
        }
-       handle->muxer_state = MEDIAMUXER_STATE_MUXING;
+       if (ret == MEDIAMUXER_ERROR_NONE)
+               handle->muxer_state = MEDIAMUXER_STATE_MUXING;
        return ret;
 }
 
@@ -273,17 +304,44 @@ int mediamuxer_stop(mediamuxer_h muxer)
        int ret = MEDIAMUXER_ERROR_NONE;
        MUXER_INSTANCE_CHECK(muxer);
        mediamuxer_s *handle = (mediamuxer_s *)(muxer);
+       if (handle->muxer_state == MEDIAMUXER_STATE_MUXING
+               || handle->muxer_state == MEDIAMUXER_STATE_PAUSED) {
+               ret = mx_stop(handle->mx_handle);
+               if (ret != MEDIAMUXER_ERROR_NONE) {
+                       MX_E("[CoreAPI][%s] MUXER_ERROR_INVALID_OPERATION(0x%08x)",
+                            __FUNCTION__, MEDIAMUXER_ERROR_INVALID_OPERATION);
+                       ret = MEDIAMUXER_ERROR_INVALID_OPERATION;
+               } else {
+                       MX_I("[CoreAPI][%s] stop successful, handle : %p",
+                            __FUNCTION__, handle);
+               }
+       } else {
+               MX_E("[CoreAPI][%s] MEDIAMUXER_ERROR_INVALID_STATE(0x%08x)",
+                    __FUNCTION__, MEDIAMUXER_ERROR_INVALID_STATE);
+               return MEDIAMUXER_ERROR_INVALID_STATE;
+       }
+       if (ret == MEDIAMUXER_ERROR_NONE)
+               handle->muxer_state = MEDIAMUXER_STATE_READY;
+       return ret;
+}
+
+int mediamuxer_unprepare(mediamuxer_h muxer)
+{
+       MX_I("mediamuxer_unprepare\n");
+       int ret = MEDIAMUXER_ERROR_NONE;
+       MUXER_INSTANCE_CHECK(muxer);
+       mediamuxer_s *handle = (mediamuxer_s *)(muxer);
        if (handle->muxer_state == MEDIAMUXER_STATE_READY
                || handle->muxer_state == MEDIAMUXER_STATE_MUXING
                || handle->muxer_state == MEDIAMUXER_STATE_PAUSED) {
-               ret = mx_stop(handle->mx_handle);
+               ret = mx_unprepare(handle->mx_handle);
                if (ret != MEDIAMUXER_ERROR_NONE) {
                        MX_E
                        ("[CoreAPI][%s] MUXER_ERROR_INVALID_OPERATION(0x%08x)",
                         __FUNCTION__, MEDIAMUXER_ERROR_INVALID_OPERATION);
                        ret = MEDIAMUXER_ERROR_INVALID_OPERATION;
                } else {
-                       MX_I("[CoreAPI][%s] stop successful, handle : %p",
+                       MX_I("[CoreAPI][%s] unprepare successful, handle : %p",
                             __FUNCTION__, handle);
                }
        } else {
@@ -291,7 +349,8 @@ int mediamuxer_stop(mediamuxer_h muxer)
                     __FUNCTION__, MEDIAMUXER_ERROR_INVALID_STATE);
                return MEDIAMUXER_ERROR_INVALID_STATE;
        }
-       handle->muxer_state = MEDIAMUXER_STATE_IDLE;
+       if (ret == MEDIAMUXER_ERROR_NONE)
+               handle->muxer_state = MEDIAMUXER_STATE_IDLE;
        return ret;
 }
 
@@ -317,7 +376,8 @@ int mediamuxer_destroy(mediamuxer_h muxer)
                     __FUNCTION__, MEDIAMUXER_ERROR_INVALID_STATE);
                return MEDIAMUXER_ERROR_INVALID_STATE;
        }
-       handle->muxer_state = MEDIAMUXER_STATE_NONE;
+       if (ret == MEDIAMUXER_ERROR_NONE)
+               handle->muxer_state = MEDIAMUXER_STATE_NONE;
        return ret;
 }
 
@@ -345,9 +405,7 @@ int mediamuxer_set_error_cb(mediamuxer_h muxer, mediamuxer_error_cb callback, vo
 
        handle->error_cb = callback;
        handle->error_cb_userdata = user_data;
-
        MX_I("set error_cb(%p)", callback);
-
        return MEDIAMUXER_ERROR_NONE;
 }
 
index 81bc5cc..1b46378 100644 (file)
@@ -55,7 +55,7 @@ int mx_create(MMHandleType *muxer)
        MEDIAMUXER_CHECK_NULL(pOps);
 
        new_muxer->muxer_ops = pOps;
-       MX_I("mx_create allocating new_demuxer->demuxer_ops %p:\n",
+       MX_I("mx_create allocating new_muxer->muxer_ops %p:\n",
             new_muxer->muxer_ops);
        pOps->n_size = sizeof(media_port_muxer_ops);
        /* load ini files */
@@ -115,6 +115,24 @@ ERROR:
        return ret;
 }
 
+int mx_prepare(MMHandleType mediamuxer)
+{
+       int ret = MX_ERROR_NONE;
+       mx_handle_t *mx_handle = (mx_handle_t *)(mediamuxer);
+       MEDIAMUXER_FENTER();
+       MEDIAMUXER_CHECK_NULL(mx_handle);
+       media_port_muxer_ops *pOps = mx_handle->muxer_ops;
+       MEDIAMUXER_CHECK_NULL(pOps);
+       ret = pOps->prepare(mx_handle->mxport_handle);
+       MEDIAMUXER_CHECK_SET_AND_PRINT(ret, MX_ERROR_NONE, ret, MX_ERROR,
+                                      "error while preparing");
+       MEDIAMUXER_FLEAVE();
+       return ret;
+ERROR:
+       MEDIAMUXER_FLEAVE();
+       return ret;
+}
+
 int mx_start(MMHandleType mediamuxer)
 {
        int ret = MX_ERROR_NONE;
@@ -215,6 +233,24 @@ int mx_stop(MMHandleType mediamuxer)
        MEDIAMUXER_CHECK_NULL(pOps);
        ret = pOps->stop(mx_handle->mxport_handle);
        MEDIAMUXER_CHECK_SET_AND_PRINT(ret, MX_ERROR_NONE, ret, MX_ERROR,
+                                      "error while stopping");
+       MEDIAMUXER_FLEAVE();
+       return ret;
+ERROR:
+       MEDIAMUXER_FLEAVE();
+       return ret;
+}
+
+int mx_unprepare(MMHandleType mediamuxer)
+{
+       int ret = MX_ERROR_NONE;
+       mx_handle_t *mx_handle = (mx_handle_t *)(mediamuxer);
+       MEDIAMUXER_FENTER();
+       MEDIAMUXER_CHECK_NULL(mx_handle);
+       media_port_muxer_ops *pOps = mx_handle->muxer_ops;
+       MEDIAMUXER_CHECK_NULL(pOps);
+       ret = pOps->unprepare(mx_handle->mxport_handle);
+       MEDIAMUXER_CHECK_SET_AND_PRINT(ret, MX_ERROR_NONE, ret, MX_ERROR,
                                       "error while destroying");
        MEDIAMUXER_FLEAVE();
        return ret;
index 98b2344..7ef56ff 100644 (file)
@@ -30,6 +30,7 @@ static int gst_muxer_set_data_sink(MMHandleType pHandle, char *uri,
                        mediamuxer_output_format_e format);
 static int gst_muxer_add_track(MMHandleType pHandle,
                        media_format_h media_format, int *track_index);
+static int gst_muxer_prepare(MMHandleType pHandle);
 static int gst_muxer_start(MMHandleType pHandle);
 static int gst_muxer_write_sample(MMHandleType pHandle, int track_index,
                        media_packet_h inbuf);
@@ -37,6 +38,7 @@ static int gst_muxer_close_track(MMHandleType pHandle, int track_index);
 static int gst_muxer_pause(MMHandleType pHandle);
 static int gst_muxer_resume(MMHandleType pHandle);
 static int gst_muxer_stop(MMHandleType pHandle);
+static int gst_muxer_unprepare(MMHandleType pHandle);
 static int gst_muxer_destroy(MMHandleType pHandle);
 static int gst_set_error_cb(MMHandleType pHandle,
                        gst_error_cb callback, void* user_data);
@@ -47,12 +49,14 @@ static media_port_muxer_ops def_mux_ops = {
        .init = gst_muxer_init,
        .set_data_sink = gst_muxer_set_data_sink,
        .add_track = gst_muxer_add_track,
+       .prepare = gst_muxer_prepare,
        .start = gst_muxer_start,
        .write_sample = gst_muxer_write_sample,
        .close_track = gst_muxer_close_track,
        .pause = gst_muxer_pause,
        .resume = gst_muxer_resume,
        .stop = gst_muxer_stop,
+       .unprepare = gst_muxer_unprepare,
        .destroy = gst_muxer_destroy,
        .set_error_cb = gst_set_error_cb,
 };
@@ -489,9 +493,9 @@ mx_ret_e _gst_create_pipeline(mxgst_handle_t *gst_handle)
        gst_handle->bus_watch_id = gst_bus_add_watch(bus, _mx_gst_bus_call, gst_handle);
        gst_object_unref(bus);
 
-       /* set pipeline state to PLAYING */
+       /* set pipeline state to READY */
        MEDIAMUXER_ELEMENT_SET_STATE(GST_ELEMENT_CAST(gst_handle->pipeline),
-                                    GST_STATE_PLAYING);
+                                    GST_STATE_READY);
        return MX_ERROR_NONE;
 
 STATE_CHANGE_FAILED:
@@ -524,14 +528,14 @@ ERROR:
        return ret;
 }
 
-static int gst_muxer_start(MMHandleType pHandle)
+static int gst_muxer_prepare(MMHandleType pHandle)
 {
        MEDIAMUXER_FENTER();
        int ret = MX_ERROR_NONE;
        MEDIAMUXER_CHECK_NULL(pHandle);
        mxgst_handle_t *new_mediamuxer = (mxgst_handle_t *) pHandle;
 
-       MX_I("__gst_muxer_start adding elements to the pipeline:%p\n", new_mediamuxer);
+       MX_I("__gst_muxer_prepare adding elements to the pipeline:%p\n", new_mediamuxer);
        ret = _gst_create_pipeline(new_mediamuxer);
        MEDIAMUXER_FLEAVE();
        return ret;
@@ -542,6 +546,34 @@ ERROR:
        return ret;
 }
 
+static int gst_muxer_start(MMHandleType pHandle)
+{
+       MEDIAMUXER_FENTER();
+       int ret = MX_ERROR_NONE;
+       MEDIAMUXER_CHECK_NULL(pHandle);
+       mxgst_handle_t *gst_handle = (mxgst_handle_t *) pHandle;
+
+       MX_I("__gst_muxer_start making pipeline to playing:%p\n", gst_handle);
+
+       /* set pipeline state to PLAYING */
+       MEDIAMUXER_ELEMENT_SET_STATE(GST_ELEMENT_CAST(gst_handle->pipeline),
+                                    GST_STATE_PLAYING);
+
+       MEDIAMUXER_FLEAVE();
+       return ret;
+
+STATE_CHANGE_FAILED:
+       MX_E("muxer state change failed, returning \n");
+       ret = MX_ERROR_INVALID_ARGUMENT;
+       MEDIAMUXER_FLEAVE();
+       return ret;
+ERROR:
+       MX_E("muxer handle NULL, returning \n");
+       ret = MX_ERROR_INVALID_ARGUMENT;
+       MEDIAMUXER_FLEAVE();
+       return ret;
+}
+
 int __gst_codec_specific_caps(GstCaps *new_cap,
                               media_format_mimetype_e mimetype)
 {
@@ -1056,8 +1088,8 @@ ERROR:
 static int gst_muxer_resume(MMHandleType pHandle)
 {
        MEDIAMUXER_FENTER();
-       MEDIAMUXER_CHECK_NULL(pHandle);
        int ret = MX_ERROR_NONE;
+       MEDIAMUXER_CHECK_NULL(pHandle);
        mxgst_handle_t *gst_handle = (mxgst_handle_t *) pHandle;
 
        MX_I("gst_muxer_resume setting pipeline to playing");
@@ -1074,6 +1106,31 @@ ERROR:
        return ret;
 }
 
+static int gst_muxer_stop(MMHandleType pHandle)
+{
+       MEDIAMUXER_FENTER();
+       int ret = MX_ERROR_NONE;
+       MEDIAMUXER_CHECK_NULL(pHandle);
+       mxgst_handle_t *gst_handle = (mxgst_handle_t *) pHandle;
+
+       MX_I("gst_muxer_stop making pipeline to ready:%p\n", gst_handle);
+       /* set pipeline state to READY */
+       MEDIAMUXER_ELEMENT_SET_STATE(GST_ELEMENT_CAST(gst_handle->pipeline),
+                                    GST_STATE_READY);
+       MEDIAMUXER_FLEAVE();
+       return ret;
+STATE_CHANGE_FAILED:
+       MX_E("muxer state change failed, returning \n");
+       ret = MX_ERROR_INVALID_ARGUMENT;
+       MEDIAMUXER_FLEAVE();
+       return ret;
+ERROR:
+       MX_E("muxer handle NULL, returning \n");
+       ret = MX_ERROR_INVALID_ARGUMENT;
+       MEDIAMUXER_FLEAVE();
+       return ret;
+}
+
 mx_ret_e _gst_destroy_pipeline(mxgst_handle_t *gst_handle)
 {
        gint ret = MX_ERROR_NONE;
@@ -1115,14 +1172,14 @@ mx_ret_e _gst_destroy_pipeline(mxgst_handle_t *gst_handle)
        return ret;
 }
 
-static int gst_muxer_stop(MMHandleType pHandle)
+static int gst_muxer_unprepare(MMHandleType pHandle)
 {
        MEDIAMUXER_FENTER();
        int ret = MX_ERROR_NONE;
        MEDIAMUXER_CHECK_NULL(pHandle);
        mxgst_handle_t *gst_handle = (mxgst_handle_t *) pHandle;
 
-       MX_I("__gst_muxer_stop setting eos to sources:%p\n", gst_handle);
+       MX_I("gst_muxer_unprepare setting eos to sources:%p\n", gst_handle);
        ret = _gst_destroy_pipeline(gst_handle);
        MEDIAMUXER_FLEAVE();
        return ret;
index 52efcfe..9ce398e 100644 (file)
 #include <sys/time.h>
 #include <stdlib.h>
 #include <stdio.h>
-
+#include <gst/gst.h>
+#include <inttypes.h>
 #include <mm_error.h>
 #include <mm_debug.h>
 #include "../include/mediamuxer_port.h"
 #include <mediamuxer.h>
 #include <mediamuxer_private.h>
 #include <media_packet_internal.h>
-/* Read encoded medial files locally: encoded A/V files along with info & caps */
-#define H264_FILE video_data
-#define H264_INFO video_extra_info
-#define AAC_FILE audio_data
-#define AAC_INFO  audio_extra_info
 
 /*-----------------------------------------------------------------------
 |    GLOBAL VARIABLE DEFINITIONS:                                       |
@@ -49,22 +45,451 @@ media_format_h media_format_a = NULL;
 
 bool aud_eos = 0;
 bool vid_eos = 0;
-char audio_extra_info[1000];
-char audio_data[1000];
-char video_extra_info[1000];
-char video_data[1000];
+char *aud_caps, *vid_caps;
+char file_mp4[1000];
+bool have_mp4 = false;
+int track_index_vid, track_index_aud;
+
+/* demuxer sturcture */
+typedef struct _CustomData
+{
+       GstElement *pipeline;
+       GstElement *source;
+       GstElement *demuxer;
+       GstElement *audioqueue;
+       GstElement *videoqueue;
+
+       GstElement *audio_appsink;      /* o/p of demuxer */
+       GstElement *video_appsink;
+       GstElement *dummysink;
+
+       char *saveLocation_audio;       /* aac stream */
+       char *saveLocation_video;       /* h264 stream */
+       GMainLoop *loop;
+
+       GTimer *timer;
+} CustomData;
+
+
+/* demuxer helper functions */
+static void _video_app_sink_callback(GstElement *sink, CustomData *data);
+static void _video_app_sink_eos_callback(GstElement *sink, CustomData *data);
+static void _audio_app_sink_eos_callback(GstElement *sink, CustomData *data);
+static void _on_pad_added(GstElement *element, GstPad *pad, CustomData *data);
+static gboolean _bus_call(GstBus *bus, GstMessage *msg, gpointer data);
+
+/* Demuxer audio-appsink buffer receive callback*/
+static void _audio_app_sink_callback(GstElement *sink, CustomData *data)
+{
+       GstBuffer *buffer;
+       media_format_h audfmt;
+       media_packet_h aud_pkt;
+       track_index_aud = 2;    /* track_index=2 for audio */
+       guint8 *dptr;
+       static int count = 0;
+       if (count == 0)
+               g_print("\ngst-1.0 audio\n");
+       GstSample *sample;
+       uint64_t ns;
+       int key;
+       GstMapInfo map;
+       g_signal_emit_by_name(sink, "pull-sample", &sample);
+       buffer = gst_sample_get_buffer(sample);
+       if (buffer) {
+               /* Print a * to indicate a received buffer */
+               g_print("\na%d: ",++count);
+
+               if (gst_buffer_map(buffer, &map, GST_MAP_READ)) {
+                       if (!GST_BUFFER_FLAG_IS_SET(buffer,GST_BUFFER_FLAG_DELTA_UNIT)) {
+                               /* g_print( "  Key Frame  \n"); */
+                               key = 1;
+                       } else {
+                               /* g_print( "  NOT a Key Frame  \n"); */
+                               key = 0;
+                       }
+
+                       if (media_format_create(&audfmt)) {
+                               g_print("media_format_create failed\n");
+                               return;
+                       }
+
+                       if (media_format_set_audio_mime(audfmt, MEDIA_FORMAT_AAC)) {
+                               g_print("media_format_set_audio_mime failed\n");
+                               return;
+                       }
+
+                       if (media_packet_create(audfmt, NULL, NULL, &aud_pkt)) {
+                               g_print("create audio media_packet failed\n");
+                               return;
+                       }
+
+                       if (media_packet_alloc(aud_pkt)) {
+                               g_print("audio media_packet alloc failed\n");
+                               return;
+                       }
+
+                       media_packet_get_buffer_data_ptr(aud_pkt, (void **)&dptr);
+                       memcpy((char*)dptr, map.data, map.size);
+
+                       if (media_packet_set_buffer_size(aud_pkt, (uint64_t)(map.size))) {
+                               g_print("audio set_buffer_size failed\n");
+                               return;
+                       }
+
+                       if (media_packet_get_buffer_size(aud_pkt, &ns)) {
+                               g_print("unable to set the buffer size actual =%u, fixed %"PRIu64"\n",map.size,ns);
+                               return;
+                       }
+
+                       g_print(" fixed size %"PRIu64"\n", ns);
+
+                       if (media_packet_set_pts(aud_pkt, buffer->pts)) {
+                               g_print("unable to set the pts\n");
+                               return;
+                       }
+
+                       if (media_packet_set_dts(aud_pkt, buffer->dts)) {
+                               g_print("unable to set the pts\n");
+                               return;
+                       }
+
+                       if (media_packet_set_duration(aud_pkt, buffer->duration)) {
+                               g_print("unable to set the pts\n");
+                               return;
+                       }
+
+                       if (media_packet_set_flags(aud_pkt, key)) {
+                               g_print("unable to set the flag size\n");
+                               return;
+                       }
+
+                       if (media_packet_set_codec_data(aud_pkt, aud_caps, strlen(aud_caps)+1)) {
+                               g_print("unable to set the audio codec data e\n");
+                               return;
+                       }
+
+                       g_print("A write sample call. packet add:%p\n", aud_pkt);
+                       mediamuxer_write_sample(myMuxer, track_index_aud, aud_pkt);
+
+                       media_packet_destroy(aud_pkt);
+               }
+       }
+}
+
+/* Demuxer video-appsink buffer receive callback*/
+static void _video_app_sink_callback(GstElement *sink, CustomData *data)
+{
+       GstBuffer *buffer;
+       media_format_h vidfmt;
+       media_packet_h vid_pkt;
+       track_index_vid = 1; /* track_index=1 for video */
+       uint64_t ns;
+       static int count = 0;
+       unsigned int vsize;
+       int key;
+       guint8 *dptr;
+       GstMapInfo map;
+       if (count == 0)
+               g_print("\ngst-1.0 Video\n");
+       GstSample *sample;
+       g_signal_emit_by_name(sink, "pull-sample", &sample);
+       buffer = gst_sample_get_buffer(sample);
+
+       if (buffer) {
+               /* Print a * to indicate a received buffer */
+               g_print("v%d: ", ++count);
+
+               g_print("PTS=%llu\n", buffer->pts);
+
+               if (gst_buffer_map(buffer, &map, GST_MAP_READ)) {
+                       if (media_format_create(&vidfmt)) {
+                               g_print("media_format_create failed\n");
+                               return;
+                       }
+
+                       if (media_format_set_video_mime(vidfmt, MEDIA_FORMAT_H264_SP)) {
+                               g_print("media_format_set_vidio_mime failed\n");
+                               return;
+                       }
+
+                       if (!GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DELTA_UNIT)) {
+                               /* g_print("Key Frame\n"); */
+                               key = 1;
+                       } else {
+                               /* g_print("NOT a Key Frame\n"); */
+                               key = 0;
+                       }
+
+                       vsize = map.size;
+                       media_format_set_video_width(vidfmt, vsize/2+1);
+                       media_format_set_video_height(vidfmt, vsize/2+1);
+                       /*frame rate is came from the caps filter of demuxer*/
+                       if (media_format_set_video_frame_rate(vidfmt, 30)) {
+                               g_print("media_format_set_video_frame_rate failed\n");
+                               return;
+                       }
+
+                       if (media_packet_create(vidfmt, NULL, NULL, &vid_pkt)) {
+                               g_print("create video media_packet failed\n");
+                               return;
+                       }
+
+                       if (media_packet_alloc(vid_pkt)) {
+                               g_print("video media_packet alloc failed\n");
+                               return;
+                       }
+
+                       media_packet_get_buffer_data_ptr(vid_pkt, (void**)&dptr);
+                       media_packet_get_buffer_size(vid_pkt, &ns);
+                       g_print("set v buf size as %"PRIu64", data size=%d\n", ns, vsize);
+                       memcpy((char*)dptr, map.data,map.size);
+
+                       if (media_packet_set_buffer_size(vid_pkt, (uint64_t)(map.size))) {
+                               g_print("video set_buffer_size failed\n");
+                               return;
+                       }
+
+                       if (media_packet_get_buffer_size(vid_pkt, &ns)) {
+                               g_print("unable to set the buffer size actual =%d, fixed %"PRIu64"\n", map.size, ns);
+                               return;
+                       }
+
+                       g_print("fixed size %"PRIu64"\n",ns);
+
+                       if (media_packet_set_pts(vid_pkt, buffer->pts)) {
+                               g_print("unable to set the pts\n");
+                               return;
+                       }
+
+                       if (media_packet_set_dts(vid_pkt, buffer->dts)) {
+                               g_print("unable to set the pts\n");
+                               return;
+                       }
+
+                       if (media_packet_set_duration(vid_pkt, buffer->duration)) {
+                               g_print("unable to set the pts\n");
+                               return;
+                       }
+
+                       if (media_packet_set_flags(vid_pkt, key)) {
+                               g_print("unable to set the flag size\n");
+                               return;
+                       }
+                       if (media_packet_set_codec_data(vid_pkt, vid_caps, strlen(vid_caps)+1)) {
+                               g_print("unable to set the video codec data e\n");
+                               return;
+                       }
+
+                       g_print("A write sample call. packet add:%p\n", vid_pkt);
+                       mediamuxer_write_sample(myMuxer, track_index_vid, vid_pkt);
+                       media_packet_destroy(vid_pkt);
+               }
+       }
+
+}
+
+/* demuxer video appsink eos callback */
+static void _video_app_sink_eos_callback(GstElement *sink, CustomData *data)
+{
+       mediamuxer_close_track(myMuxer, track_index_vid);
+       g_print("\n video h264 eos reached \n");
+       vid_eos = 1;
+       if (aud_eos == 1)
+               g_main_loop_quit(data->loop);
+}
+
+/* demuxer audio appsink eos callback */
+static void _audio_app_sink_eos_callback(GstElement *sink, CustomData *data)
+{
+       mediamuxer_close_track(myMuxer, track_index_aud);
+       g_print("\n audio AAC eos reached \n");
+       aud_eos = 1;
+       if (vid_eos == 1)
+               g_main_loop_quit(data->loop);
+}
+
+/* demuxer on_pad callback */
+static void _on_pad_added(GstElement *element, GstPad *pad, CustomData *data)
+{
+       GstPadLinkReturn ret;
+       GstPad *sink_pad_audioqueue = gst_element_get_static_pad(data->audioqueue, "sink");
+       GstPad *sink_pad_videoqueue = gst_element_get_static_pad(data->videoqueue, "sink");
+       GstCaps *new_pad_aud_caps = NULL;
+       GstCaps *new_pad_vid_caps = NULL;
+       GstCaps *new_pad_caps = NULL;
+       GstStructure *new_pad_struct = NULL;
+       const gchar *new_pad_type = NULL;
+       char *caps;
+       g_print("Received new pad '%s' from '%s':\n", GST_PAD_NAME(pad), GST_ELEMENT_NAME(element));
+
+       new_pad_caps = gst_pad_get_current_caps(pad);
+       new_pad_struct = gst_caps_get_structure(new_pad_caps, 0);
+       new_pad_type = gst_structure_get_name(new_pad_struct);
+
+       if (g_str_has_prefix(new_pad_type, "audio/mpeg")) {
+               new_pad_aud_caps = gst_pad_get_current_caps(pad);
+               caps = gst_caps_to_string(new_pad_aud_caps);
+               g_print("Aud caps:%s\n", caps);
+               aud_caps = caps;
+
+               /* Link demuxer to audioqueue */
+               ret = gst_pad_link(pad, sink_pad_audioqueue);
+               if (GST_PAD_LINK_FAILED(ret))
+                       g_print(" Type is but link failed.\n %s", new_pad_type);
+               else
+                       g_print(" Link succeeded  (type '%s').\n", new_pad_type);
+
+               gst_element_link(data->audioqueue, data->audio_appsink);
+               g_object_set(data->audio_appsink, "emit-signals", TRUE, NULL);
+               g_signal_connect(data->audio_appsink, "new-sample", G_CALLBACK(_audio_app_sink_callback), data);
+               g_signal_connect(data->audio_appsink, "eos", G_CALLBACK(_audio_app_sink_eos_callback), data);
+
+               /* Link audioqueue->audio_appsink and save/Give to appsrc of muxer */
+               gst_element_set_state(data->audio_appsink, GST_STATE_PLAYING);
+               /* one has to set the newly added element to the same state as the rest of the elements. */
+       } else if (g_str_has_prefix(new_pad_type, "video/x-h264")) {
+               new_pad_vid_caps = gst_pad_get_current_caps(pad);
+               caps = gst_caps_to_string(new_pad_vid_caps);
+               g_print("Video:%s\n",caps);
+               vid_caps = caps;
+
+               /* link demuxer with videoqueue */
+               ret = gst_pad_link(pad, sink_pad_videoqueue);
+               if (GST_PAD_LINK_FAILED(ret))
+                       g_print("Type is '%s' but link failed.\n", new_pad_type);
+               else
+                       g_print("Link succeeded (type '%s').\n", new_pad_type);
+               gst_element_link(data->videoqueue, data->video_appsink);
+               g_object_set(data->video_appsink, "emit-signals", TRUE, NULL);
+               g_signal_connect(data->video_appsink, "new-sample", G_CALLBACK(_video_app_sink_callback), data);
+               g_signal_connect(data->video_appsink, "eos", G_CALLBACK(_video_app_sink_eos_callback), data);
+               gst_element_set_state(data->video_appsink, GST_STATE_PLAYING);
+               /* one has to set the newly added element to the same state as the rest of the elements. */
+       } else {
+               g_print(" It has type '%s' which is not raw A/V. Ignoring.\n", new_pad_type);
+               goto exit;
+       }
+
+exit:
+       if (new_pad_caps != NULL)
+               gst_caps_unref(new_pad_caps);
+
+       gst_object_unref(sink_pad_audioqueue);
+       gst_object_unref(sink_pad_videoqueue);
+}
+
+/* Demuxer bus_call */
+static gboolean _bus_call(GstBus *bus, GstMessage *mesg, gpointer data)
+{
+       GMainLoop *dmxr_loop = (GMainLoop*)data;
+
+       switch (GST_MESSAGE_TYPE(mesg))
+       {
+               case GST_MESSAGE_EOS:
+                       g_print("End of stream\n");
+                       g_main_loop_quit(dmxr_loop);
+                       break;
+
+               case GST_MESSAGE_ERROR:
+               {
+                       gchar *dbg;
+                       GError *err;
+                       gst_message_parse_error(mesg, &err, &dbg);
+                       g_free(dbg);
+                       g_printerr("Demuxer-Error:%s \n", err->message);
+                       g_error_free(err);
+                       g_main_loop_quit(dmxr_loop);
+                       break;
+               }
+               default:
+                       break;
+       }
+       return TRUE;
+}
+
+/* Demux an mp4 file and generate encoded streams and extra data  */
+int demux_mp4()
+{
+       CustomData data;
+       GMainLoop *loop_dmx;
+       GstBus *bus;
+       guint watch_id_for_bus;
+
+       if (access(file_mp4, F_OK) == -1) {
+               /* mp4 file doesn't exist */
+               g_print("mp4 Invalid file path.");
+               return -1;
+       }
+
+       gst_init(NULL,NULL);
+       loop_dmx = g_main_loop_new(NULL, FALSE);
+       data.loop = loop_dmx;
+
+       /* Create gstreamer elements for demuxer*/
+       data.pipeline = gst_pipeline_new("DemuxerPipeline");
+       data.source = gst_element_factory_make("filesrc", "file-source");
+       data.demuxer = gst_element_factory_make("qtdemux", "mp4-demuxer");
+       data.audioqueue = gst_element_factory_make("queue", "audio-queue");
+       data.videoqueue = gst_element_factory_make("queue", "video-queue");
+
+       data.dummysink = gst_element_factory_make("fakesink", "fakesink");
+       data.video_appsink = gst_element_factory_make("appsink", "video (h264) appsink");
+       data.audio_appsink = gst_element_factory_make("appsink", "audio (AAC) appsink");
+
+       if (!data.pipeline || !data.source || !data.demuxer || !data.audioqueue
+               || !data.dummysink || !data.videoqueue || !data.audio_appsink || !data.video_appsink) {
+               g_print("Test-Suite: One gst-element can't be created. Exiting\n");
+               return -1;
+       }
+
+       /* Add msg-handler */
+       bus = gst_pipeline_get_bus(GST_PIPELINE(data.pipeline));
+       watch_id_for_bus = gst_bus_add_watch(bus, _bus_call, loop_dmx);
+       gst_object_unref(bus);
+
+       /* Add gstreamer-elements into gst-pipeline */
+       gst_bin_add_many(GST_BIN(data.pipeline), data.source, data.demuxer, data.dummysink, \
+                     data.audioqueue, data.videoqueue,data.audio_appsink, data.video_appsink, NULL);
+
+       /* we set the input filename to the source element */
+       g_object_set(G_OBJECT(data.source), "location", file_mp4, NULL);
+
+       /* we link the elements together */
+       gst_element_link(data.source, data.demuxer);
+
+       /* Register demuxer callback */
+       g_signal_connect(data.demuxer, "pad-added", G_CALLBACK(_on_pad_added), &data);
+
+       /* play the pipeline */
+       g_print("Now playing: %s\n", file_mp4);
+       gst_element_set_state(data.pipeline, GST_STATE_PLAYING);
+
+       /* Run the loop till quit */
+       g_print("gst-pipeline-Running...\n");
+       g_main_loop_run(loop_dmx);
+
+       /* Done with gst-loop. Free resources */
+       gst_element_set_state(data.pipeline, GST_STATE_NULL);
+
+       g_print("Unreferencing the gst-pipeline\n");
+       gst_object_unref(GST_OBJECT(data.pipeline));
+       g_source_remove(watch_id_for_bus);
+       g_main_loop_unref(loop_dmx);
+       return 0;
+}
+
 
 int test_mediamuxer_create()
 {
        g_print("test_mediamuxer_create\n");
        g_print("%p", myMuxer);
 
-       if (mediamuxer_create(&myMuxer)
-           != MEDIAMUXER_ERROR_NONE) {
+       if (mediamuxer_create(&myMuxer) != MEDIAMUXER_ERROR_NONE) {
                g_print("mediamuxer create is failed\n");
        }
+
        g_print("\n Muxer->mx_handle created successfully with address=%p",
-               (void *)((mediamuxer_s *) myMuxer)->mx_handle);
+               (void *)((mediamuxer_s *)myMuxer)->mx_handle);
        g_print("\n Muxer handle created successfully with address=%p",
                myMuxer);
 
@@ -90,6 +515,13 @@ int test_mediamuxer_destroy()
        return ret;
 }
 
+int test_mediamuxer_prepare()
+{
+       g_print("mediamuxer_prepare completed \n");
+       mediamuxer_prepare(myMuxer);
+       return 0;
+}
+
 int test_mediamuxer_start()
 {
        g_print("mediamuxer_start completed \n");
@@ -114,18 +546,18 @@ int test_mediamuxer_add_track_video()
 
        media_format_set_video_width(media_format, 640);
        media_format_set_video_height(media_format, 480);
-       media_format_set_video_avg_bps(media_format, 10);
-       media_format_set_video_max_bps(media_format, 10);
+       media_format_set_video_avg_bps(media_format, 256000);
+       media_format_set_video_max_bps(media_format, 256000);
 
        media_format_get_video_info(media_format, &mimetype, &width, &height, &avg_bps, &max_bps);
 
-       g_print("\n Video Mime trying to set: %x   %x\n", (int)(mimetype), (int)(MEDIA_FORMAT_H264_SP));
+       g_print("\n Video Mime trying to set: %x   %x\n",(int)(mimetype),(int)(MEDIA_FORMAT_H264_SP));
        g_print("\n Video param trying to set: (width, height, avg_bps, max_bps): %d %d %d %d  \n",
                width, height, avg_bps, max_bps);
 
        /* To add video track */
        mediamuxer_add_track(myMuxer, media_format, &track_index_vid);
-       g_print("audio track index returned is: %d", track_index_vid);
+       g_print("video track index returned is: %d", track_index_vid);
        return 0;
 }
 
@@ -147,9 +579,9 @@ int test_mediamuxer_add_track_audio()
 
        if (media_format_set_audio_channel(media_format_a, 2) == MEDIA_FORMAT_ERROR_INVALID_OPERATION)
                g_print("Problem during media_format_set_audio_channel operation");
-       media_format_set_audio_samplerate(media_format_a, 44000);
-       media_format_set_audio_bit(media_format_a, 1);
-       media_format_set_audio_avg_bps(media_format_a, 10);
+       media_format_set_audio_samplerate(media_format_a, 44100);
+       media_format_set_audio_bit(media_format_a, 32);
+       media_format_set_audio_avg_bps(media_format_a, 128000);
        media_format_set_audio_aac_type(media_format_a, true);
 
        media_format_get_audio_info(media_format_a, &mimetype, &channel, &samplerate, &bit, &avg_bps);
@@ -177,313 +609,10 @@ int test_mediamuxer_set_error_cb()
        return ret;
 }
 
-void *_write_video_data()
-{
-       FILE *pvFile;
-       FILE *pvFileInfo;
-       unsigned int size;
-       unsigned int vsize;
-       unsigned int is_video_readable = 1;
-       unsigned int is_video_pts_readable;
-       unsigned int is_video_dts_readable;
-       unsigned int is_video_duration_readable;
-       unsigned int is_video_flag_readable;
-       unsigned int is_video_key_readable;
-       unsigned long long int pts_vid;
-       unsigned long long int dts_vid;
-       unsigned long long int duration_vid;
-       int flg_vid;
-       int *status = (int *)g_malloc(sizeof(int) * 1);
-       *status = -1;
-       int track_index_vid = 1; /* track_index=2 for video */
-       int vcount = 0;
-       guint8 *ptr_vid;
-       int key_vid;
-       char *vid_caps;
-       int ret_scan;
-       media_packet_h vid_pkt;
-       media_format_h vidfmt;
-       unsigned int vcap_size;
-
-       pvFile = fopen(H264_FILE, "rb");
-       pvFileInfo = fopen(H264_INFO, "rt");
-
-       if (pvFile == NULL || pvFileInfo == NULL) {
-               g_print("\nOne of the files (info/data) cant be loaded...\n");
-               return (void *)status;
-       }
-
-       ret_scan = fscanf(pvFileInfo, "%d\n", &size);
-       vid_caps = (char *)malloc(size + 1);
-       ret_scan = fscanf(pvFileInfo, "%[^\n]s\n", vid_caps);
-       g_print("\nV_Caps = %s\n", vid_caps);
-       vcap_size = size + 1;
-
-       if (!ret_scan) { /* ToDo: repeat the same for every scanf */
-               g_print("\nscan failed");
-               return (void *)status;
-       }
-
-       while (is_video_readable == 1) {
-               /* Read encoded video data */
-               is_video_readable = fscanf(pvFileInfo, "%d\n", &vsize);
-               is_video_pts_readable = fscanf(pvFileInfo, "%llu\n", &pts_vid);
-               is_video_dts_readable = fscanf(pvFileInfo, "%llu\n", &dts_vid);
-               is_video_duration_readable = fscanf(pvFileInfo, "%llu\n", &duration_vid);
-               is_video_flag_readable = fscanf(pvFileInfo, "%u\n", &flg_vid);
-               is_video_key_readable = fscanf(pvFileInfo, "%d\n", &key_vid);
-
-               if (is_video_readable == 1 && is_video_pts_readable == 1 && is_video_dts_readable == 1
-                   && is_video_duration_readable == 1 && is_video_flag_readable == 1
-                   && is_video_key_readable == 1) {
-                       g_print("\nv%d: ", ++vcount);
-                       g_print("\nv_Size: %d, v_pts: %llu, v_dts: %llu v_duration: %llu, v_flag: %d",
-                               vsize, pts_vid, dts_vid, duration_vid, key_vid);
-                       ptr_vid = g_malloc(vsize);
-                       g_assert(ptr_vid);
-                       vsize = fread(ptr_vid, 1, vsize, pvFile);
-
-                       if (media_format_create(&vidfmt)) {
-                               g_print("media_format_create failed\n");
-                               return (void *)status;
-                       }
-                       if (media_format_set_video_mime(vidfmt, MEDIA_FORMAT_H264_SP)) {
-                               g_print("media_format_set_audio_mime failed\n");
-                               return (void *)status;
-                       }
-                       media_format_set_video_width(vidfmt, vsize / 2 + 1);
-                       media_format_set_video_height(vidfmt, vsize / 2 + 1);
-                       /*frame rate is came from the caps filter of demuxer*/
-                       if (media_format_set_video_frame_rate(vidfmt, 30)) {
-                               g_print("media_format_set_video_frame_rate failed\n");
-                               return (void *)status;
-                       }
-
-                       uint64_t ns;
-                       guint8 *dptr;
-
-                       if (media_packet_create(vidfmt, NULL, NULL, &vid_pkt)) {
-                               g_print("\ncreate v media packet failed tc\n");
-                               return (void *)status;
-                       }
-
-                       if (media_packet_alloc(vid_pkt)) {
-                               g_print(" v media packet alloc failed\n");
-                               return (void *)status;
-                       }
-                       media_packet_get_buffer_data_ptr(vid_pkt, (void **)&dptr);
-                       media_packet_get_buffer_size(vid_pkt, &ns);
-                       g_print("set v buf size as %d, data size=%d\n", (int)ns, vsize);
-
-                       memcpy((char *)dptr, ptr_vid, vsize);
-                       if (media_packet_set_buffer_size(vid_pkt, vsize)) {
-                               g_print("set v buf size failed\n");
-                               return (void *)status;
-                       }
-
-
-                       if (media_packet_get_buffer_size(vid_pkt, &ns)) {
-                               g_print("unable to set the v buffer size actual =%d, fixed %d\n", size, (int)ns);
-                               return (void *)status;
-                       }
-                       g_print(" fixed size %d\n", (int)ns);
-
-                       if (media_packet_set_pts(vid_pkt, pts_vid)) {
-                               g_print("unable to set the pts\n");
-                               return (void *)status;
-                       }
-                       if (media_packet_set_dts(vid_pkt, dts_vid)) {
-                               g_print("unable to set the pts\n");
-                               return (void *)status;
-                       }
-                       if (media_packet_set_duration(vid_pkt, duration_vid)) {
-                               g_print("unable to set the pts\n");
-                               return (void *)status;
-                       }
-
-                       if (media_packet_set_flags(vid_pkt, flg_vid)) {
-                               g_print("unable to set the flag size\n");
-                               return (void *)status;
-                       }
-                       if (media_packet_set_codec_data(vid_pkt, vid_caps, vcap_size)) {
-                               g_print("unable to set the flag size\n");
-                               return (void *)status;
-                       }
-
-                       mediamuxer_write_sample(myMuxer, track_index_vid, vid_pkt);
-
-                       media_packet_destroy(vid_pkt);
-               } else {
-                       g_print("\nVideo while done in the test suite");
-                       mediamuxer_close_track(myMuxer, track_index_vid);
-               }
-       }
-       g_print("\n\n\n ******* Out of while loop ****** \n\n\n");
-       fclose(pvFile);
-       fclose(pvFileInfo);
-       *status = 0;
-       return (void *)status;
-}
-
-void *_write_audio_data()
-{
-       FILE *paFile;
-       FILE *paFileInfo;
-       unsigned int size;
-       unsigned int is_audio_readable = 1;
-       unsigned int is_audio_pts_readable;
-       unsigned int is_audio_dts_readable;
-       unsigned int is_audio_duration_readable;
-       unsigned int is_audio_flag_readable;
-       unsigned int is_audio_key_readable;
-       unsigned char *ptr1;
-       unsigned long long int pts;
-       unsigned long long int dts;
-       unsigned long long int duration;
-       int flg;
-
-       int key;
-       int acount = 0;
-       int track_index_aud = 2; /* track_index=2 for audio */
-       char *aud_caps;
-       int ret_scan;
-       media_packet_h aud_pkt;
-       media_format_h audfmt;
-       unsigned int acap_size;
-       int *status = (int *)g_malloc(sizeof(int) * 1);
-       *status = -1;
-
-       paFileInfo = fopen(AAC_INFO, "rt");
-       paFile = fopen(AAC_FILE, "rb");
-
-       if (paFile == NULL || paFileInfo == NULL) {
-               g_print("\nOne of the files (info/data) cant be loaded...\n");
-               return (void *)status;
-       }
-
-       ret_scan = fscanf(paFileInfo, "%d\n", &size);
-       aud_caps = (char *)malloc(1 + size);
-       ret_scan = fscanf(paFileInfo, "%[^\n]s\n", aud_caps);
-       g_print("\nA_Caps = %s\n", aud_caps);
-       acap_size = size + 1;
-
-       if (!ret_scan) { /* ToDo: repeat the same for every scanf */
-               g_print("\nscan failed");
-               return (void *)status;
-       }
-
-       while (is_audio_readable == 1) {
-
-               /* Read encoded audio data */
-               is_audio_readable = fscanf(paFileInfo, "%d\n", &size);
-               is_audio_pts_readable = fscanf(paFileInfo, "%llu\n", &pts);
-               is_audio_dts_readable = fscanf(paFileInfo, "%llu\n", &dts);
-               is_audio_duration_readable = fscanf(paFileInfo, "%llu\n", &duration);
-               is_audio_flag_readable = fscanf(paFileInfo, "%u\n", &flg);
-               is_audio_key_readable = fscanf(paFileInfo, "%d\n", &key);
-
-               if (is_audio_readable == 1 && is_audio_pts_readable == 1
-                   && is_audio_dts_readable == 1 && is_audio_duration_readable == 1
-                   && is_audio_flag_readable == 1 && is_audio_key_readable == 1) {
-                       g_print("\na%d: ", ++acount);
-                       g_print("\nSize: %d, a_pts: %llu, a_dts: %llu, a_duration: %llu, a_flag:%d, a_key:%d",
-                               size, pts, dts, duration, flg, key);
-
-                       if (media_format_create(&audfmt)) {
-                               g_print("media_format_create failed\n");
-                               return (void *)status;
-                       }
-                       if (media_format_set_audio_mime(audfmt, MEDIA_FORMAT_AAC)) {
-                               g_print("media_format_set_audio_mime failed\n");
-                               return (void *)status;
-                       }
-
-                       ptr1 = g_malloc(size);
-                       g_assert(ptr1);
-
-                       size = fread(ptr1, 1, size, paFile);
-
-                       /* To create media_pkt */
-                       uint64_t ns;
-                       guint8 *dptr;
-
-                       if (media_packet_create(audfmt, NULL, NULL, &aud_pkt)) {
-                               g_print("create audio media_packet failed\n");
-                               return (void *)status;
-                       }
-
-                       if (media_packet_alloc(aud_pkt)) {
-                               g_print("audio media_packet alloc failed\n");
-                               return (void *)status;
-                       }
-                       media_packet_get_buffer_data_ptr(aud_pkt, (void **)&dptr);
-                       memcpy((char *)dptr, ptr1, size);
-
-                       if (media_packet_set_buffer_size(aud_pkt, (uint64_t)size)) {
-                               g_print("audio set_buffer_size failed\n");
-                               return (void *)status;
-                       }
-
-                       if (media_packet_get_buffer_size(aud_pkt, &ns)) {
-                               g_print("unable to set the buffer size actual =%d, fixed %d\n", size, (int)ns);
-                               return (void *)status;
-                       }
-
-                       g_print(" fixed size %d\n", (int)ns);
-
-                       if (media_packet_set_pts(aud_pkt, pts)) {
-                               g_print("unable to set the pts\n");
-                               return (void *)status;
-                       }
-
-                       if (media_packet_set_dts(aud_pkt, dts)) {
-                               g_print("unable to set the pts\n");
-                               return (void *)status;
-                       }
-
-                       if (media_packet_set_duration(aud_pkt, duration)) {
-                               g_print("unable to set the pts\n");
-                               return (void *)status;
-                       }
-
-                       if (media_packet_set_flags(aud_pkt, key)) {
-                               g_print("unable to set the flag size\n");
-                               return (void *)status;
-                       }
-                       if (media_packet_set_codec_data(aud_pkt, aud_caps, acap_size)) {
-                               g_print("unable to set the audio codec data e\n");
-                               return (void *)status;
-                       }
-
-                       mediamuxer_write_sample(myMuxer, track_index_aud, aud_pkt);
-
-                       media_packet_destroy(aud_pkt);
-               } else {
-                       g_print("\nAudio while done in the test suite");
-                       mediamuxer_close_track(myMuxer, track_index_aud);
-               }
-
-       }
-       g_print("\n\n\n ******* Out of while loop ****** \n\n\n");
-
-       fclose(paFile);
-       fclose(paFileInfo);
-       *status = 0;
-       return (void *)status;
-}
-
 
 int test_mediamuxer_write_sample()
 {
-       pthread_t thread[2];
-       pthread_attr_t attr;
-       /* Initialize and set thread detached attribute */
-       pthread_attr_init(&attr);
-       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-       g_print("In main: creating thread  for audio\n");
-       pthread_create(&thread[0], &attr, _write_video_data, NULL);
-       pthread_create(&thread[1], &attr, _write_audio_data, NULL);
-       pthread_attr_destroy(&attr);
+       demux_mp4();
        return 0;
 }
 
@@ -491,6 +620,14 @@ int test_mediamuxer_stop()
 {
        g_print("test_mediamuxer_stop\n");
        mediamuxer_stop(myMuxer);
+       return 0;
+}
+
+
+int test_mediamuxer_unprepare()
+{
+       g_print("test_mediamuxer_unprepare\n");
+       mediamuxer_unprepare(myMuxer);
        media_format_unref(media_format_a);
        media_format_unref(media_format);
        return 0;
@@ -529,10 +666,7 @@ void quit_testApp(void)
 
 enum {
        CURRENT_STATUS_MAINMENU,
-       CURRENT_STATUS_AUDIO_FILENAME,
-       CURRENT_STATUS_AUDIO_INFONAME,
-       CURRENT_STATUS_VIDEO_FILENAME,
-       CURRENT_STATUS_VIDEO_INFONAME,
+       CURRENT_STATUS_MP4_FILENAME
 };
 
 int g_menu_state = CURRENT_STATUS_MAINMENU;
@@ -560,16 +694,28 @@ void _interpret_main_menu(char *cmd)
                        test_mediamuxer_set_data_sink();
                } else if (strncmp(cmd, "d", 1) == 0) {
                        test_mediamuxer_destroy();
+               } else if (strncmp(cmd, "e", 1) == 0) {
+                       test_mediamuxer_prepare();
                } else if (strncmp(cmd, "s", 1) == 0) {
                        test_mediamuxer_start();
                } else if (strncmp(cmd, "a", 1) == 0) {
-                       g_menu_state = CURRENT_STATUS_AUDIO_FILENAME;
+                       if (have_mp4 == false) {
+                               g_menu_state = CURRENT_STATUS_MP4_FILENAME;
+                               have_mp4 = true;
+                       }
+                       test_mediamuxer_add_track_audio();
                } else if (strncmp(cmd, "v", 1) == 0) {
-                       g_menu_state = CURRENT_STATUS_VIDEO_FILENAME;
+                       if (have_mp4 == false) {
+                               g_menu_state = CURRENT_STATUS_MP4_FILENAME;
+                               have_mp4 = true;
+                       }
+                       test_mediamuxer_add_track_video();
                } else if (strncmp(cmd, "m", 1) == 0) {
                        test_mediamuxer_write_sample();
-               } else if (strncmp(cmd, "e", 1) == 0) {
+               } else if (strncmp(cmd, "t", 1) == 0) {
                        test_mediamuxer_stop();
+               } else if (strncmp(cmd, "u", 1) == 0) {
+                       test_mediamuxer_unprepare();
                } else if (strncmp(cmd, "p", 1) == 0) {
                        test_mediamuxer_pause();
                } else if (strncmp(cmd, "r", 1) == 0) {
@@ -592,20 +738,9 @@ static void displaymenu(void)
 {
        if (g_menu_state == CURRENT_STATUS_MAINMENU) {
                display_sub_basic();
-       } else if (g_menu_state == CURRENT_STATUS_AUDIO_FILENAME) {
-               g_print("*** input encoded audio_data path:\n");
-               g_print("[This is the raw encoded audio file to be muxed]:");
-       } else if (g_menu_state == CURRENT_STATUS_AUDIO_INFONAME) {
-               g_print("*** input encoded audio info (extra data) path\n");
-               g_print("[This is the extra-information needed to mux.");
-               g_print("This includes gst-caps too]:");
-       } else if (g_menu_state == CURRENT_STATUS_VIDEO_FILENAME) {
-               g_print("*** input encoded video path\n");
-               g_print("[This is the raw encoded video file to be muxed]:");
-       } else if (g_menu_state == CURRENT_STATUS_VIDEO_INFONAME) {
-               g_print("*** input encoded video info (extra data) path\n");
-               g_print("[This is the extra-information needed to mux.");
-               g_print("This includes gst-caps too]:");
+       } else if (g_menu_state == CURRENT_STATUS_MP4_FILENAME) {
+               g_print("*** input mp4 file path:\n");
+               g_print("[This is the file from where demuxed data is fed to muxer]:");
        } else {
                g_print("*** unknown status.\n");
                exit(0);
@@ -627,30 +762,9 @@ static void interpret(char *cmd)
                                _interpret_main_menu(cmd);
                                break;
                        }
-               case CURRENT_STATUS_AUDIO_FILENAME: {
-                               input_filepath(cmd);
-                               strcpy(audio_data, cmd);
-                               g_menu_state = CURRENT_STATUS_AUDIO_INFONAME;
-                               break;
-                       }
-               case CURRENT_STATUS_AUDIO_INFONAME: {
-                               input_filepath(cmd);
-                               strcpy(audio_extra_info, cmd);
-                               test_mediamuxer_add_track_audio();
-                               g_menu_state = CURRENT_STATUS_MAINMENU;
-
-                               break;
-                       }
-               case CURRENT_STATUS_VIDEO_FILENAME: {
-                               input_filepath(cmd);
-                               strcpy(video_data, cmd);
-                               g_menu_state = CURRENT_STATUS_VIDEO_INFONAME;
-                               break;
-                       }
-               case CURRENT_STATUS_VIDEO_INFONAME: {
+               case CURRENT_STATUS_MP4_FILENAME: {
                                input_filepath(cmd);
-                               strcpy(video_extra_info, cmd);
-                               test_mediamuxer_add_track_video();
+                               strcpy(file_mp4, cmd);
                                g_menu_state = CURRENT_STATUS_MAINMENU;
                                break;
                        }
@@ -670,12 +784,14 @@ static void display_sub_basic()
        g_print("o. Set Data Sink \t");
        g_print("a. AddAudioTrack \t");
        g_print("v. AddVideoTrack \t");
-       g_print("s. Start \t");
-       g_print("m. StartMuxing \t");
+       g_print("e. prepare \t");
+       g_print("s. start \t");
+       g_print("m. startMuxing \t");
        g_print("p. PauseMuxing \t");
        g_print("r. ResumeMuxing \t");
        g_print("b. set error callback \t");
-       g_print("e. Stop (eos) \n");
+       g_print("t. stop \t");
+       g_print("u. UnPrepare \t");
        g_print("d. destroy \t");
        g_print("q. quit \t");
        g_print("\n");
@@ -718,7 +834,7 @@ int main(int argc, char *argv[])
        GMainLoop *loop = g_main_loop_new(NULL, 0);
        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);
+       g_io_add_watch(stdin_channel, G_IO_IN, (GIOFunc)input, NULL);
 
        displaymenu();
        /* g_print("RUN main loop\n"); */