From 62d36ebdac0e40b4623309e3e939e665fdfba870 Mon Sep 17 00:00:00 2001 From: Deepak Srivastava Date: Mon, 7 Dec 2015 16:05:15 +0530 Subject: [PATCH 01/16] Sync with 2.4 [Implemented EOS callback functionality.] [1] Fixed ACR-461 Review comments Change-Id: Ib4167bab71c958dc85f0154c7a5731368db3cde4 Signed-off-by: Deepak Srivastava Signed-off-by: Seo Joungkook --- include/mediademuxer.h | 48 +++++++++++++++++++++++-- include/mediademuxer_port.h | 26 ++++++++++++++ include/mediademuxer_private.h | 2 ++ include/port_gst/mediademuxer_port_gst.h | 12 +++++++ src/mediademuxer.c | 48 +++++++++++++++++++++++++ src/mediademuxer_port.c | 22 +++++++++++- src/port_gst/mediademuxer_port_gst.c | 61 ++++++++++++++++++++++++++++++-- test/mediademuxer_test.c | 50 ++++++++++++++++++-------- 8 files changed, 248 insertions(+), 21 deletions(-) mode change 100644 => 100755 include/mediademuxer.h diff --git a/include/mediademuxer.h b/include/mediademuxer.h old mode 100644 new mode 100755 index f43515f..1f52589 --- a/include/mediademuxer.h +++ b/include/mediademuxer.h @@ -88,7 +88,7 @@ typedef enum { * @param[in] error The error that occurred in media demuxer * @param[in] user_data The user data passed from the code where * mediademuxer_set_error_cb() was invoked - * This data will be accessible from @a mediademuxer_error_cb + * This data will be accessible from mediademuxer_error_cb() * @pre Create media demuxer handle by calling mediademuxer_create() function. * @see mediademuxer_set_error_cb() * @see mediademuxer_unset_error_cb() @@ -96,6 +96,19 @@ typedef enum { typedef void (*mediademuxer_error_cb) (mediademuxer_error_e error, void *user_data); /** + * @brief Called when end of stream occurs in media demuxer. + * @since_tizen 3.0 + * @param[in] track_num The track_num which indicate eos for which track number occured + * @param[in] user_data The user data passed from the code where + * mediademuxer_set_eos_cb() was invoked + * This data will be accessible from mediademuxer_eos_cb() + * @pre Create media demuxer handle by calling mediademuxer_create() function. + * @see mediademuxer_set_eos_cb() + * @see mediademuxer_unset_eos_cb() + */ +typedef void (*mediademuxer_eos_cb) (int track_num, void *user_data); + +/** * @brief Creates a media demuxer handle for demuxing. * @since_tizen 3.0 * @remarks You must release @a demuxer using mediademuxer_destroy() function. @@ -324,7 +337,7 @@ int mediademuxer_destroy(mediademuxer_h demuxer); int mediademuxer_get_state(mediademuxer_h demuxer, mediademuxer_state *state); /** - * @brief Registers a error callback function to be invoked when an error occurs. + * @brief Registers an error callback function to be invoked when an error occurs. * @details Following error codes can be delivered. * #MEDIADEMUXER_ERROR_INVALID_OPERATION, * #MEDIADEMUXER_ERROR_NOT_SUPPORTED, @@ -337,7 +350,7 @@ int mediademuxer_get_state(mediademuxer_h demuxer, mediademuxer_state *state); * @param[in] callback Callback function pointer * @param[in] user_data The user data passed from the code where * mediademuxer_set_error_cb() was invoked - * This data will be accessible from @a mediademuxer_error_cb + * This data will be accessible from mediademuxer_error_cb() * @return @c 0 on success, otherwise a negative error value * @retval #MEDIADEMUXER_ERROR_NONE Successful * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter @@ -360,6 +373,35 @@ int mediademuxer_set_error_cb(mediademuxer_h demuxer, mediademuxer_error_cb call int mediademuxer_unset_error_cb(mediademuxer_h demuxer); /** + * @brief Registers an eos callback function to be invoked when an eos occurs. + * @since_tizen 3.0 + * @param[in] demuxer The media demuxer handle + * @param[in] callback Callback function pointer + * @param[in] user_data The user data passed from the code where + * mediademuxer_set_eos_cb() was invoked + * This data will be accessible from mediademuxer_eos_cb() + * @return @c 0 on success, otherwise a negative error value + * @retval #MEDIADEMUXER_ERROR_NONE Successful + * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter + * @pre Create a media demuxer handle by calling mediademuxer_create() function. + * @post mediademuxer_eos_cb() will be invoked. + * @see mediademuxer_unset_eos_cb() + * @see mediademuxer_eos_cb() + * */ +int mediademuxer_set_eos_cb(mediademuxer_h demuxer, mediademuxer_eos_cb callback, void *user_data); + +/** + * @brief Unregisters the eos callback function. + * @since_tizen 3.0 + * @param[in] demuxer The media demuxer handle + * @return @c 0 on success, otherwise a negative error value + * @retval #MEDIADEMUXER_ERROR_NONE Successful + * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter + * @see mediademuxer_eos_cb() + * */ +int mediademuxer_unset_eos_cb(mediademuxer_h demuxer); + +/** * @} */ diff --git a/include/mediademuxer_port.h b/include/mediademuxer_port.h index 9b53291..1d671ce 100755 --- a/include/mediademuxer_port.h +++ b/include/mediademuxer_port.h @@ -325,6 +325,20 @@ extern "C" { * @see mediademuxer_unset_error_cb() */ typedef void (*md_error_cb)(mediademuxer_error_e error, void *user_data); + +/** + * @brief Called when eos occurs in media demuxer. + * @since_tizen 3.0 + * @param[in] track_num The track_num which indicate eos has occurred in which track numbe + * @param[in] user_data The user data passed from the code where + * mediademuxer_set_eos_cb() was invoked + * This data will be accessible from @a mediademuxer_eos_cb + * @pre Create media demuxer handle by calling mediademuxer_create() function. + * @see mediademuxer_set_eos_cb() + * @see mediademuxer_unset_eos_cb() + */ +typedef void (*md_eos_cb)(int track_num, void *user_data); + /** * Enumerations of demuxer state. */ @@ -346,6 +360,7 @@ typedef struct _media_port_demuxer_ops { int (*unprepare)(MMHandleType pHandle); int (*destroy)(MMHandleType pHandle); int (*set_error_cb)(MMHandleType demuxer, md_error_cb callback, void* user_data); + int (*set_eos_cb)(MMHandleType demuxer, md_eos_cb callback, void* user_data); int (*get_data)(MMHandleType pHandle, char *buffer); } media_port_demuxer_ops; @@ -557,6 +572,17 @@ int md_seek(MMHandleType demuxer, int64_t pos); */ int md_set_error_cb(MMHandleType demuxer, md_error_cb callback, void *user_data); +/** + * This function is to set eos call back function + * + * @param demuxer [in] Handle of demuxer + * @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 md_set_eos_cb(MMHandleType demuxer, md_eos_cb callback, void *user_data); + #ifdef __cplusplus } #endif diff --git a/include/mediademuxer_private.h b/include/mediademuxer_private.h index 9a70511..5e9a99e 100755 --- a/include/mediademuxer_private.h +++ b/include/mediademuxer_private.h @@ -71,6 +71,8 @@ typedef struct _mediademuxer_s { pthread_t prepare_async_thread; mediademuxer_error_cb error_cb; void* error_cb_userdata; + mediademuxer_eos_cb eos_cb; + void* eos_cb_userdata; mediademuxer_state demux_state; } mediademuxer_s; diff --git a/include/port_gst/mediademuxer_port_gst.h b/include/port_gst/mediademuxer_port_gst.h index 0499c39..8928813 100755 --- a/include/port_gst/mediademuxer_port_gst.h +++ b/include/port_gst/mediademuxer_port_gst.h @@ -113,6 +113,18 @@ typedef struct _mdgst_handle_t { */ typedef void (*gst_error_cb)(mediademuxer_error_e error, void *user_data); +/** + * @brief Called when the eos has occured. + * @since_tizen 3.0 + * @details It will be invoked when the eos has occured. + * @param[in] track_num track number to indicate eos + * @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 mediademuxer_set_eos_cb(). + * @see mediademuxer_set_eos_cb() + * @see mediademuxer_unset_eos_cb() + */ +typedef void (*gst_eos_cb)(int track_num, void *user_data); + #ifdef __cplusplus } #endif diff --git a/src/mediademuxer.c b/src/mediademuxer.c index 5788249..887755d 100755 --- a/src/mediademuxer.c +++ b/src/mediademuxer.c @@ -33,6 +33,7 @@ * Public Implementation */ static gboolean _mediademuxer_error_cb(mediademuxer_error_e error, void *user_data); +static gboolean _mediademuxer_eos_cb(int track_num, void *user_data); int mediademuxer_create(mediademuxer_h *demuxer) { @@ -73,6 +74,10 @@ int mediademuxer_create(mediademuxer_h *demuxer) md_set_error_cb(handle->md_handle, (mediademuxer_error_cb) _mediademuxer_error_cb, handle); + md_set_eos_cb(handle->md_handle, + (mediademuxer_eos_cb) _mediademuxer_eos_cb, + handle); + handle->demux_state = MEDIADEMUXER_IDLE; return MEDIADEMUXER_ERROR_NONE; } @@ -394,3 +399,46 @@ static gboolean _mediademuxer_error_cb(mediademuxer_error_e error, void *user_da MD_I("_mediademuxer_error_cb: ERROR %d to report. But call back is not set\n", error); return 0; } + +int mediademuxer_set_eos_cb(mediademuxer_h demuxer, + mediademuxer_eos_cb callback, void *user_data) +{ + DEMUXER_INSTANCE_CHECK(demuxer); + mediademuxer_s *handle; + handle = (mediademuxer_s *)(demuxer); + if (handle->demux_state != MEDIADEMUXER_IDLE) + return MEDIADEMUXER_ERROR_INVALID_STATE; + handle->eos_cb = callback; + handle->eos_cb_userdata = user_data; + MD_I("set eos_cb(%p)", callback); + return MEDIADEMUXER_ERROR_NONE; +} + +int mediademuxer_unset_eos_cb(mediademuxer_h demuxer) +{ + DEMUXER_INSTANCE_CHECK(demuxer); + mediademuxer_s *handle; + handle = (mediademuxer_s *)(demuxer); + if (handle->demux_state != MEDIADEMUXER_IDLE) + return MEDIADEMUXER_ERROR_INVALID_STATE; + handle->eos_cb = NULL; + handle->eos_cb_userdata = NULL; + MD_I("mediademuxer_unset_eos_cb\n"); + return MEDIADEMUXER_ERROR_NONE; +} + +static gboolean _mediademuxer_eos_cb(int track_num, void *user_data) +{ + if (user_data == NULL) { + MD_I("_mediademuxer_eos_cb: EOS to report. But call back is not set\n"); + return 0; + } + mediademuxer_s *handle = (mediademuxer_s *)user_data; + if (handle->demux_state != MEDIADEMUXER_DEMUXING) + return MEDIADEMUXER_ERROR_INVALID_STATE; + if (handle->eos_cb) + ((mediademuxer_eos_cb)handle->eos_cb)(track_num, handle->eos_cb_userdata); + else + MD_I("_mediademuxer_eos_cb: EOS %d to report. But call back is not set\n", track_num); + return 0; +} diff --git a/src/mediademuxer_port.c b/src/mediademuxer_port.c index fe5385e..d1f79ab 100755 --- a/src/mediademuxer_port.c +++ b/src/mediademuxer_port.c @@ -398,7 +398,7 @@ int md_read_sample(MMHandleType demuxer, int track_indx, media_packet_h *outbuf) media_port_demuxer_ops *pOps = md_handle->demuxer_ops; MEDIADEMUXER_CHECK_NULL(pOps); result = pOps->read_sample(md_handle->mdport_handle, outbuf, track_indx); - if (result == MD_EOS || result == MD_ERROR_NONE) { + if (result == MD_ERROR_NONE) { MEDIADEMUXER_FLEAVE(); return result; } else { @@ -540,3 +540,23 @@ ERROR: MEDIADEMUXER_FLEAVE(); return result; } + +int md_set_eos_cb(MMHandleType demuxer, + mediademuxer_eos_cb callback, void *user_data) +{ + MEDIADEMUXER_FENTER(); + int result = MD_ERROR_NONE; + md_handle_t *md_handle = (md_handle_t *) demuxer; + MEDIADEMUXER_CHECK_NULL(md_handle); + media_port_demuxer_ops *pOps = md_handle->demuxer_ops; + MEDIADEMUXER_CHECK_NULL(pOps); + result = pOps->set_eos_cb(md_handle->mdport_handle, callback, user_data); + MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, result, + MD_ERROR, "error while setting eos call back"); + MEDIADEMUXER_FLEAVE(); + return result; +ERROR: + result = MD_ERROR_INVALID_ARGUMENT; + MEDIADEMUXER_FLEAVE(); + return result; +} diff --git a/src/port_gst/mediademuxer_port_gst.c b/src/port_gst/mediademuxer_port_gst.c index 2c0b1d9..74f96cb 100755 --- a/src/port_gst/mediademuxer_port_gst.c +++ b/src/port_gst/mediademuxer_port_gst.c @@ -43,6 +43,9 @@ static int gst_demuxer_unprepare(MMHandleType pHandle); static int gst_demuxer_destroy(MMHandleType pHandle); static int gst_set_error_cb(MMHandleType pHandle, gst_error_cb callback, void* user_data); +static int gst_set_eos_cb(MMHandleType pHandle, + gst_eos_cb callback, void *user_data); +static int __gst_eos_callback(int track_num, void* user_data); /* Media Demuxer API common */ static media_port_demuxer_ops def_demux_ops = { @@ -60,6 +63,7 @@ static media_port_demuxer_ops def_demux_ops = { .unprepare = gst_demuxer_unprepare, .destroy = gst_demuxer_destroy, .set_error_cb = gst_set_error_cb, + .set_eos_cb = gst_set_eos_cb, }; int gst_port_register(media_port_demuxer_ops *pOps) @@ -1232,9 +1236,10 @@ static int gst_demuxer_read_sample(MMHandleType pHandle, sample = gst_app_sink_pull_sample((GstAppSink *) sink); if (sample == NULL) { if (gst_app_sink_is_eos((GstAppSink *) sink)) { - MD_W("End of stream (EOS) reached\n"); - ret = MD_EOS; - goto ERROR; + MD_W("End of stream (EOS) reached, triggering the eos callback\n"); + ret = MD_ERROR_NONE; + __gst_eos_callback(track_indx, demuxer); + return ret; } else { MD_E("gst_demuxer_read_sample failed\n"); ret = MD_ERROR_UNKNOWN; @@ -1511,3 +1516,53 @@ ERROR: MEDIADEMUXER_FLEAVE(); return ret; } + +int gst_set_eos_cb(MMHandleType pHandle, gst_eos_cb callback, void *user_data) +{ + MEDIADEMUXER_FENTER(); + int ret = MD_ERROR_NONE; + MEDIADEMUXER_CHECK_NULL(pHandle); + mdgst_handle_t *gst_handle = (mdgst_handle_t *) pHandle; + + if (!gst_handle) { + MD_E("fail invaild param (gst_handle)\n"); + ret = MD_INVALID_ARG; + goto ERROR; + } + + if (gst_handle->user_cb[_GST_EVENT_TYPE_EOS]) { + MD_E("Already set mediademuxer_eos_cb\n"); + ret = MD_ERROR_INVALID_ARGUMENT; + goto ERROR; + } else { + if (!callback) { + MD_E("fail invaild argument (callback)\n"); + ret = MD_ERROR_INVALID_ARGUMENT; + goto ERROR; + } + } + + MD_I("Set event handler callback(cb = %p, data = %p)\n", callback, user_data); + gst_handle->user_cb[_GST_EVENT_TYPE_EOS] = (gst_eos_cb) callback; + gst_handle->user_data[_GST_EVENT_TYPE_EOS] = user_data; + MEDIADEMUXER_FLEAVE(); + return MD_ERROR_NONE; +ERROR: + MEDIADEMUXER_FLEAVE(); + return ret; +} + +static int __gst_eos_callback(int track_num, void* user_data) +{ + if (user_data == NULL) { + MD_E("Invalid argument"); + return MD_ERROR; + } + mdgst_handle_t *gst_handle = (mdgst_handle_t *) user_data; + if (gst_handle->user_cb[_GST_EVENT_TYPE_EOS]) + ((gst_eos_cb)gst_handle->user_cb[_GST_EVENT_TYPE_EOS])(track_num, + gst_handle->user_data[_GST_EVENT_TYPE_EOS]); + else + MD_E("EOS received, but callback is not set!!!"); + return MD_ERROR_NONE; +} diff --git a/test/mediademuxer_test.c b/test/mediademuxer_test.c index b7c8bb1..5c85e97 100755 --- a/test/mediademuxer_test.c +++ b/test/mediademuxer_test.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -60,6 +59,8 @@ int channel = 0; int samplerate = 0; int bit = 0; bool is_adts = 0; +bool vid_eos_track = 0; +bool aud_eos_track = 0; /*----------------------------------------------------------------------- | DEBUG DEFINITIONS | @@ -76,7 +77,7 @@ bool is_adts = 0; do {\ int ret = 0; \ ret = expr; \ - if (ret != MD_ERROR_NONE) {\ + if (ret != MEDIADEMUXER_ERROR_NONE) {\ printf("[%s:%d] error code : %x \n", __func__, __LINE__, ret); \ return; \ } \ @@ -387,7 +388,7 @@ static void mediacodec_process_audio_pkt(media_packet_h in_buf) void *_fetch_audio_data(void *ptr) { - int ret = MD_ERROR_NONE; + int ret = MEDIADEMUXER_ERROR_NONE; int *status = (int *)g_malloc(sizeof(int) * 1); media_packet_h audbuf; int count = 0; @@ -432,13 +433,12 @@ void *_fetch_audio_data(void *ptr) while (1) { ret = mediademuxer_read_sample(demuxer, aud_track, &audbuf); - if (ret == MD_EOS) { - g_print("EOS return of mediademuxer_read_sample()\n"); - pthread_exit(NULL); - } else if (ret != MD_ERROR_NONE) { + if (ret != MEDIADEMUXER_ERROR_NONE) { g_print("Error (%d) return of mediademuxer_read_sample()\n", ret); pthread_exit(NULL); } + if (aud_eos_track) + break; count++; media_packet_get_buffer_size(audbuf, &buf_size); media_packet_get_buffer_data_ptr(audbuf, &data); @@ -475,6 +475,7 @@ void *_fetch_audio_data(void *ptr) media_packet_destroy(audbuf); } + g_print("EOS return of mediademuxer_read_sample() for audio\n"); *status = 0; if (validate_with_codec) mediacodec_finish(g_media_codec, fp_out_codec_audio); @@ -580,7 +581,7 @@ static void _local_media_packet_get_codec_data(media_packet_h pkt) void *_fetch_video_data(void *ptr) { - int ret = MD_ERROR_NONE; + int ret = MEDIADEMUXER_ERROR_NONE; int *status = (int *)g_malloc(sizeof(int) * 1); media_packet_h vidbuf; int count = 0; @@ -608,13 +609,12 @@ void *_fetch_video_data(void *ptr) } while (1) { ret = mediademuxer_read_sample(demuxer, vid_track, &vidbuf); - if (ret == MD_EOS) { - g_print("EOS return of mediademuxer_read_sample()\n"); - pthread_exit(NULL); - } else if (ret != MD_ERROR_NONE) { + if (ret != MEDIADEMUXER_ERROR_NONE) { g_print("Error (%d) return of mediademuxer_read_sample()\n", ret); pthread_exit(NULL); } + if (vid_eos_track) + break; count++; media_packet_get_buffer_size(vidbuf, &buf_size); media_packet_get_buffer_data_ptr(vidbuf, &data); @@ -637,6 +637,7 @@ void *_fetch_video_data(void *ptr) else media_packet_destroy(vidbuf); } + g_print("EOS return of mediademuxer_read_sample() for video\n"); *status = 0; if (validate_with_codec) mediacodec_finish(g_media_codec_1, fp_out_codec_video); @@ -739,6 +740,17 @@ void app_err_cb(mediademuxer_error_e error, void *user_data) printf("Got Error %d from Mediademuxer\n", error); } +void app_eos_cb(int track_index, void *user_data) +{ + printf("Got EOS for track -- %d from Mediademuxer\n", track_index); + if (track_index == vid_track) + vid_eos_track = true; + else if (track_index == aud_track) + aud_eos_track = true; + else + g_print("EOS for invalid track number\n"); +} + int test_mediademuxer_set_error_cb() { int ret = 0; @@ -747,6 +759,13 @@ int test_mediademuxer_set_error_cb() return ret; } +int test_mediademuxer_set_eos_cb() +{ + int ret = 0; + g_print("test_mediademuxer_set_eos_cb\n"); + ret = mediademuxer_set_eos_cb(demuxer, app_eos_cb, demuxer); + return ret; +} /*----------------------------------------------------------------------- | EXTRA FUNCTION | @@ -811,6 +830,7 @@ static void display_sub_basic() g_print("---------------------------------------------------------------------------\n"); g_print("c. Create \t"); g_print("s. Set callback \t"); + g_print("e. Set eos callback \t"); g_print("p. Path \t"); g_print("d. Destroy \t"); g_print("q. Quit \n"); @@ -829,6 +849,8 @@ void _interpret_main_menu(char *cmd) test_mediademuxer_create(); } else if (strncmp(cmd, "s", 1) == 0) { test_mediademuxer_set_error_cb(); + } else if (strncmp(cmd, "e", 1) == 0) { + test_mediademuxer_set_eos_cb(); } else if (strncmp(cmd, "p", 1) == 0) { g_menu_state = CURRENT_STATUS_FILENAME; } else if (strncmp(cmd, "d", 1) == 0) { @@ -901,9 +923,9 @@ static void interpret(char *cmd) case CURRENT_STATUS_FILENAME: { int ret = 0; ret = test_mediademuxer_set_data_source(demuxer, cmd); - if (ret != MD_ERROR_INVALID_ARGUMENT) { + if (ret != MEDIADEMUXER_ERROR_INVALID_PARAMETER) { ret = test_mediademuxer_prepare(); - if (ret != MD_ERROR_INVALID_ARGUMENT) { + if (ret != MEDIADEMUXER_ERROR_INVALID_PARAMETER) { g_menu_state = CURRENT_STATUS_SET_DATA; } else { g_print("test_mediademuxer_prepare failed \n"); -- 2.7.4 From ac2ac3c3c522330d8a16e87623281e9511cf9475 Mon Sep 17 00:00:00 2001 From: Gilbok Lee Date: Fri, 18 Dec 2015 15:00:09 +0900 Subject: [PATCH 02/16] Removed libprivileage-control dependency Change-Id: I275f671602c803bae635cf7da47b4dd81eb1d492 Signed-off-by: Gilbok Lee --- packaging/capi-mediademuxer.spec | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packaging/capi-mediademuxer.spec b/packaging/capi-mediademuxer.spec index 73e5ae6..3d25e86 100755 --- a/packaging/capi-mediademuxer.spec +++ b/packaging/capi-mediademuxer.spec @@ -19,10 +19,6 @@ BuildRequires: pkgconfig(gstreamer-video-1.0) BuildRequires: pkgconfig(gstreamer-app-1.0) BuildRequires: pkgconfig(iniparser) -Requires(post): /sbin/ldconfig -Requires(post): libprivilege-control -Requires(postun): /sbin/ldconfig - %description %package devel -- 2.7.4 From e35658f07c620f626b5f49ef268b0ddbb64e0087 Mon Sep 17 00:00:00 2001 From: Akshay Gaikwad Date: Fri, 18 Dec 2015 14:36:31 +0530 Subject: [PATCH 03/16] Sync with 2.4 [Fixed cyclomatic complexity issue.] [1] Added break, if polling interval exceed. Also corrected the state change in test application. [2] Code cleanup. [3] Error handling done for invalid file path. [4] Added frame rate for video format Change-Id: I2658aeeb0359c539d9a9cf02535b724c5a2773b1 Signed-off-by: Akshay Gaikwad --- src/mediademuxer.c | 9 +- src/mediademuxer_port.c | 4 +- src/port_gst/mediademuxer_port_gst.c | 286 ++++++++++++----------------------- test/mediademuxer_test.c | 4 +- 4 files changed, 107 insertions(+), 196 deletions(-) diff --git a/src/mediademuxer.c b/src/mediademuxer.c index 887755d..334e182 100755 --- a/src/mediademuxer.c +++ b/src/mediademuxer.c @@ -91,6 +91,11 @@ int mediademuxer_set_data_source(mediademuxer_h demuxer, const char *path) handle = (mediademuxer_s *)(demuxer); if (handle && path && handle->demux_state == MEDIADEMUXER_IDLE) { ret = md_set_data_source((MMHandleType) (handle->md_handle), path); + if (ret != MEDIADEMUXER_ERROR_NONE) { + MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", __FUNCTION__, + MEDIADEMUXER_ERROR_INVALID_PATH); + return MEDIADEMUXER_ERROR_INVALID_PATH; + } } else { if (!path) { MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", @@ -110,7 +115,7 @@ int mediademuxer_set_data_source(mediademuxer_h demuxer, const char *path) int mediademuxer_prepare(mediademuxer_h demuxer) { MD_I("mediademuxer_prepare\n"); - mediademuxer_error_e ret; + mediademuxer_error_e ret = MEDIADEMUXER_ERROR_NONE; DEMUXER_INSTANCE_CHECK(demuxer); mediademuxer_s *handle; handle = (mediademuxer_s *)(demuxer); @@ -344,7 +349,7 @@ int mediademuxer_destroy(mediademuxer_h demuxer) int mediademuxer_get_state(mediademuxer_h demuxer, mediademuxer_state *state) { MD_I("mediademuxer_get_state\n"); - int ret = MEDIADEMUXER_ERROR_NONE; + mediademuxer_error_e ret = MEDIADEMUXER_ERROR_NONE; DEMUXER_INSTANCE_CHECK(demuxer); mediademuxer_s *handle = (mediademuxer_s *)(demuxer); if (state != NULL) { diff --git a/src/mediademuxer_port.c b/src/mediademuxer_port.c index d1f79ab..d2bee30 100755 --- a/src/mediademuxer_port.c +++ b/src/mediademuxer_port.c @@ -184,7 +184,8 @@ mediademuxer_src_type __md_util_media_type(char **uri) } return MD_ERROR_NONE; } else { - MD_E("could access %s.\n", path); + MD_E("could not access %s.\n", path); + goto ERROR; } } else if ((path = strstr(*uri, "rtsp://"))) { if (strlen(path)) { @@ -300,6 +301,7 @@ int md_prepare(MMHandleType demuxer) MEDIADEMUXER_CHECK_NULL(md_handle); media_port_demuxer_ops *pOps = md_handle->demuxer_ops; MEDIADEMUXER_CHECK_NULL(pOps); + MEDIADEMUXER_CHECK_NULL(md_handle->uri_src); result = pOps->prepare(md_handle->mdport_handle, md_handle->uri_src); MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, result, MD_ERROR, "error while doing prepare"); diff --git a/src/port_gst/mediademuxer_port_gst.c b/src/port_gst/mediademuxer_port_gst.c index 74f96cb..d2c7401 100755 --- a/src/port_gst/mediademuxer_port_gst.c +++ b/src/port_gst/mediademuxer_port_gst.c @@ -393,32 +393,6 @@ static int __gst_create_audio_only_pipeline(gpointer data, GstCaps *caps) goto ERROR; } gst_pad_unlink(pad, fake_pad); - if (strstr(type, "adif")) { - adif_queue = gst_element_factory_make("queue", NULL); - if (!adif_queue) { - MD_E("factory not able to make queue in case of adif aac\n"); - goto ERROR; - } - /* Add this queue to the pipeline */ - gst_bin_add_many(GST_BIN(gst_handle->pipeline), adif_queue, NULL); - queue_srcpad = gst_element_get_static_pad(adif_queue, "src"); - if (!queue_srcpad) { - MD_E("fail to get queue src pad for adif aac.\n"); - goto ERROR; - } - queue_sinkpad = gst_element_get_static_pad(adif_queue, "sink"); - if (!queue_sinkpad) { - MD_E("fail to get queue sink pad for adif aac.\n"); - goto ERROR; - } - /* link typefind with queue */ - MEDIADEMUXER_LINK_PAD(pad, queue_sinkpad, ERROR); - /* link queue with aacparse */ - MEDIADEMUXER_LINK_PAD(queue_srcpad, aud_pad, ERROR); - } else { - MEDIADEMUXER_LINK_PAD(pad, aud_pad, ERROR); - } - if (!id3tag) { MEDIADEMUXER_SET_STATE(gst_handle->demux, GST_STATE_PAUSED, ERROR); @@ -428,20 +402,6 @@ static int __gst_create_audio_only_pipeline(gpointer data, GstCaps *caps) GST_STATE_PAUSED, ERROR); gst_element_link(id3tag, gst_handle->demux); } - - if (adif_queue) - MEDIADEMUXER_SET_STATE(adif_queue, GST_STATE_PAUSED, ERROR); - - if (pad) - gst_object_unref(pad); - if (aud_pad) - gst_object_unref(aud_pad); - if (fake_pad) - gst_object_unref(fake_pad); - if (queue_sinkpad) - gst_object_unref(queue_sinkpad); - if (queue_srcpad) - gst_object_unref(queue_srcpad); } /* calling "on_pad_added" function to set the caps */ @@ -462,6 +422,43 @@ static int __gst_create_audio_only_pipeline(gpointer data, GstCaps *caps) __gst_free_stuct(&(head_track->head)); goto ERROR; } + if (strstr(type, "adif")) { + adif_queue = gst_element_factory_make("queue", NULL); + if (!adif_queue) { + MD_E("factory not able to make queue in case of adif aac\n"); + goto ERROR; + } + /* Add this queue to the pipeline */ + gst_bin_add_many(GST_BIN(gst_handle->pipeline), adif_queue, NULL); + queue_srcpad = gst_element_get_static_pad(adif_queue, "src"); + if (!queue_srcpad) { + MD_E("fail to get queue src pad for adif aac.\n"); + goto ERROR; + } + queue_sinkpad = gst_element_get_static_pad(adif_queue, "sink"); + if (!queue_sinkpad) { + MD_E("fail to get queue sink pad for adif aac.\n"); + goto ERROR; + } + /* link typefind with queue */ + MEDIADEMUXER_LINK_PAD(pad, queue_sinkpad, ERROR); + /* link queue with aacparse */ + MEDIADEMUXER_LINK_PAD(queue_srcpad, aud_pad, ERROR); + } else { + MEDIADEMUXER_LINK_PAD(pad, aud_pad, ERROR); + } + if (adif_queue) + MEDIADEMUXER_SET_STATE(adif_queue, GST_STATE_PAUSED, ERROR); + if (pad) + gst_object_unref(pad); + if (aud_pad) + gst_object_unref(aud_pad); + if (fake_pad) + gst_object_unref(fake_pad); + if (queue_sinkpad) + gst_object_unref(queue_sinkpad); + if (queue_srcpad) + gst_object_unref(queue_srcpad); if (aud_srcpad) gst_object_unref(aud_srcpad); @@ -674,6 +671,7 @@ static int _gst_create_pipeline(mdgst_handle_t *gst_handle, char *uri) if (count > POLLING_INTERVAL) { MD_E("Error occure\n"); ret = MD_ERROR; + break; } } @@ -815,6 +813,9 @@ int _set_mime_video(media_format_h format, track *head) GstStructure *struc = NULL; int src_width; int src_height; + int frame_rate_numerator = 0; + int frame_rate_denominator = 0; + media_format_mimetype_e mime_type = MEDIA_FORMAT_MAX; struc = gst_caps_get_structure(head->caps, 0); if (!struc) { MD_E("cannot get structure from caps.\n"); @@ -822,27 +823,31 @@ int _set_mime_video(media_format_h format, track *head) } if (gst_structure_has_name(struc, "video/x-h264")) { const gchar *version = gst_structure_get_string(struc, "stream-format"); - if (strncmp(version, "avc", 3) == 0) { - gst_structure_get_int(struc, "width", &src_width); - gst_structure_get_int(struc, "height", &src_height); - if (media_format_set_video_mime(format, MEDIA_FORMAT_H264_SP)) - goto ERROR; - if (media_format_set_video_width(format, src_width)) - goto ERROR; - if (media_format_set_video_height(format, src_height)) - goto ERROR; + if (strncmp(version, "avc", 3) == 0) + mime_type = MEDIA_FORMAT_H264_SP; + else { + MD_W("Video mime (%s) not supported so far\n", gst_structure_get_name(struc)); + goto ERROR; } } else if (gst_structure_has_name(struc, "video/x-h263")) { - gst_structure_get_int(struc, "width", &src_width); - gst_structure_get_int(struc, "height", &src_height); - if (media_format_set_video_mime(format, MEDIA_FORMAT_H263)) - goto ERROR; - if (media_format_set_video_width(format, src_width)) - goto ERROR; - if (media_format_set_video_height(format, src_height)) - goto ERROR; + mime_type = MEDIA_FORMAT_H263; } else { - MD_I("Video mime not supported so far\n"); + MD_W("Video mime (%s) not supported so far\n", gst_structure_get_name(struc)); + goto ERROR; + } + if (media_format_set_video_mime(format, mime_type)) { + MD_E("Unable to set video mime type (%x)\n", mime_type); + goto ERROR; + } + gst_structure_get_int(struc, "width", &src_width); + gst_structure_get_int(struc, "height", &src_height); + if (media_format_set_video_width(format, src_width)) + goto ERROR; + if (media_format_set_video_height(format, src_height)) + goto ERROR; + gst_structure_get_fraction(struc, "framerate", &frame_rate_numerator, &frame_rate_denominator); + if (media_format_set_video_frame_rate(format, frame_rate_numerator)) { + MD_E("Unable to set video frame rate\n"); goto ERROR; } MEDIADEMUXER_FLEAVE(); @@ -862,6 +867,7 @@ int _set_mime_audio(media_format_h format, track *head) int channels = 0; int id3_flag = 0; const gchar *stream_format; + media_format_mimetype_e mime_type = MEDIA_FORMAT_MAX; struc = gst_caps_get_structure(head->caps, 0); if (!struc) { @@ -876,49 +882,16 @@ int _set_mime_audio(media_format_h format, track *head) int layer; gst_structure_get_int(struc, "mpegversion", &mpegversion); if (mpegversion == 4 || mpegversion == 2) { - gst_structure_get_int(struc, "channels", &channels); - gst_structure_get_int(struc, "rate", &rate); - gst_structure_get_int(struc, "bit", &bit); + mime_type = MEDIA_FORMAT_AAC_LC; stream_format = gst_structure_get_string(struc, "stream-format"); - if (media_format_set_audio_mime(format, MEDIA_FORMAT_AAC_LC)) - goto ERROR; - if (channels == 0) - channels = 2; /* default */ - if (media_format_set_audio_channel(format, channels)) - goto ERROR; - if (rate == 0) - rate = 44100; /* default */ - if (media_format_set_audio_samplerate(format, rate)) - goto ERROR; - if (bit == 0) - bit = 16; /* default */ - if (media_format_set_audio_bit(format, bit)) - goto ERROR; if (strncmp(stream_format, "adts", 4) == 0) media_format_set_audio_aac_type(format, 1); else media_format_set_audio_aac_type(format, 0); - } - if (mpegversion == 1 || id3_flag) { + } else if (mpegversion == 1 || id3_flag) { gst_structure_get_int(struc, "layer", &layer); if ((layer == 3) || (id3_flag == 1)) { - gst_structure_get_int(struc, "channels", &channels); - gst_structure_get_int(struc, "rate", &rate); - gst_structure_get_int(struc, "bit", &bit); - if (media_format_set_audio_mime(format, MEDIA_FORMAT_MP3)) - goto ERROR; - if (channels == 0) - channels = 2; /* default */ - if (media_format_set_audio_channel(format, channels)) - goto ERROR; - if (rate == 0) - rate = 44100; /* default */ - if (bit == 0) - bit = 16; /* default */ - if (media_format_set_audio_samplerate(format, rate)) - goto ERROR; - if (media_format_set_audio_bit(format, bit)) - goto ERROR; + mime_type = MEDIA_FORMAT_MP3; } else { MD_I("No Support for MPEG%d Layer %d media\n", mpegversion, layer); goto ERROR; @@ -926,9 +899,6 @@ int _set_mime_audio(media_format_h format, track *head) } } else if (gst_structure_has_name(struc, "audio/x-amr-nb-sh") || gst_structure_has_name(struc, "audio/x-amr-wb-sh")) { - media_format_mimetype_e mime_type; - gst_structure_get_int(struc, "channels", &channels); - gst_structure_get_int(struc, "rate", &rate); if (gst_structure_has_name(struc, "audio/x-amr-nb-sh")) { mime_type = MEDIA_FORMAT_AMR_NB; rate = 8000; @@ -936,108 +906,42 @@ int _set_mime_audio(media_format_h format, track *head) mime_type = MEDIA_FORMAT_AMR_WB; rate = 16000; } - if (media_format_set_audio_mime(format, mime_type)) - goto ERROR; - if (channels == 0) - channels = 1; /* default */ - if (bit == 0) - bit = 16; /* default */ - if (media_format_set_audio_channel(format, channels)) - goto ERROR; - if (media_format_set_audio_samplerate(format, rate)) - goto ERROR; - if (media_format_set_audio_bit(format, bit)) - goto ERROR; } else if (gst_structure_has_name(struc, "audio/AMR")) { - gst_structure_get_int(struc, "channels", &channels); - gst_structure_get_int(struc, "rate", &rate); - gst_structure_get_int(struc, "bit", &bit); - if (media_format_set_audio_mime(format, MEDIA_FORMAT_AMR_NB)) - goto ERROR; - if (channels == 0) - channels = 1; /* default */ - if (media_format_set_audio_channel(format, channels)) - goto ERROR; - if (media_format_set_audio_samplerate(format, rate)) - goto ERROR; - if (bit == 0) - bit = 16; /* default */ - if (media_format_set_audio_bit(format, bit)) - goto ERROR; + mime_type = MEDIA_FORMAT_AMR_NB; } else if (gst_structure_has_name(struc, "audio/AMR-WB")) { - gst_structure_get_int(struc, "channels", &channels); - gst_structure_get_int(struc, "rate", &rate); - gst_structure_get_int(struc, "bit", &bit); - if (media_format_set_audio_mime(format, MEDIA_FORMAT_AMR_WB)) - goto ERROR; - if (channels == 0) - channels = 1; /* default */ - if (media_format_set_audio_channel(format, channels)) - goto ERROR; - if (media_format_set_audio_samplerate(format, rate)) - goto ERROR; - if (bit == 0) - bit = 16; /* default */ - if (media_format_set_audio_bit(format, bit)) - goto ERROR; + mime_type = MEDIA_FORMAT_AMR_WB; } else if (gst_structure_has_name(struc, "audio/x-wav")) { - gst_structure_get_int(struc, "channels", &channels); - gst_structure_get_int(struc, "rate", &rate); - gst_structure_get_int(struc, "bit", &bit); - if (media_format_set_audio_mime(format, MEDIA_FORMAT_PCM)) - goto ERROR; - if (channels == 0) - channels = 2; /* default */ - if (media_format_set_audio_channel(format, channels)) - goto ERROR; - if (rate == 0) - rate = 44100; /* default */ - if (media_format_set_audio_samplerate(format, rate)) - goto ERROR; - if (bit == 0) - bit = 16; /* default */ - if (media_format_set_audio_bit(format, bit)) - goto ERROR; + mime_type = MEDIA_FORMAT_PCM; } else if (gst_structure_has_name(struc, "audio/x-flac")) { - gst_structure_get_int(struc, "channels", &channels); - gst_structure_get_int(struc, "rate", &rate); - gst_structure_get_int(struc, "bit", &bit); - if (media_format_set_audio_mime(format, MEDIA_FORMAT_FLAC)) - goto ERROR; - if (channels == 0) - channels = 2; /* default */ - if (media_format_set_audio_channel(format, channels)) - goto ERROR; - if (rate == 0) - rate = 44100; /* default */ - if (media_format_set_audio_samplerate(format, rate)) - goto ERROR; - if (bit == 0) - bit = 16; /* default */ - if (media_format_set_audio_bit(format, bit)) - goto ERROR; + mime_type = MEDIA_FORMAT_FLAC; } else if (gst_structure_has_name(struc, "audio/x-vorbis")) { - gst_structure_get_int(struc, "channels", &channels); - gst_structure_get_int(struc, "rate", &rate); - gst_structure_get_int(struc, "bit", &bit); - if (media_format_set_audio_mime(format, MEDIA_FORMAT_VORBIS)) - goto ERROR; - if (channels == 0) - channels = 2; /* default */ - if (media_format_set_audio_channel(format, channels)) - goto ERROR; - if (rate == 0) - rate = 44100; /* default */ - if (media_format_set_audio_samplerate(format, rate)) - goto ERROR; - if (bit == 0) - bit = 16; /* default */ - if (media_format_set_audio_bit(format, bit)) - goto ERROR; + mime_type = MEDIA_FORMAT_VORBIS; } else { - MD_I("Audio mime not supported so far\n"); + MD_W("Audio mime (%s) not supported so far\n", gst_structure_get_name(struc)); goto ERROR; } + if (media_format_set_audio_mime(format, mime_type)) + goto ERROR; + gst_structure_get_int(struc, "channels", &channels); + if (channels == 0) { /* default */ + if (mime_type == MEDIA_FORMAT_AMR_NB || mime_type == MEDIA_FORMAT_AMR_WB) + channels = 1; + else + channels = 2; + } + if (media_format_set_audio_channel(format, channels)) + goto ERROR; + if (rate == 0) + gst_structure_get_int(struc, "rate", &rate); + if (rate == 0) + rate = 44100; /* default */ + if (media_format_set_audio_samplerate(format, rate)) + goto ERROR; + gst_structure_get_int(struc, "bit", &bit); + if (bit == 0) + bit = 16; /* default */ + if (media_format_set_audio_bit(format, bit)) + goto ERROR; MEDIADEMUXER_FLEAVE(); return ret; ERROR: diff --git a/test/mediademuxer_test.c b/test/mediademuxer_test.c index 5c85e97..de4faea 100755 --- a/test/mediademuxer_test.c +++ b/test/mediademuxer_test.c @@ -923,9 +923,9 @@ static void interpret(char *cmd) case CURRENT_STATUS_FILENAME: { int ret = 0; ret = test_mediademuxer_set_data_source(demuxer, cmd); - if (ret != MEDIADEMUXER_ERROR_INVALID_PARAMETER) { + if (ret == MEDIADEMUXER_ERROR_NONE) { ret = test_mediademuxer_prepare(); - if (ret != MEDIADEMUXER_ERROR_INVALID_PARAMETER) { + if (ret == MEDIADEMUXER_ERROR_NONE) { g_menu_state = CURRENT_STATUS_SET_DATA; } else { g_print("test_mediademuxer_prepare failed \n"); -- 2.7.4 From 95a7600ad699711018128c55e07f6c7851607905 Mon Sep 17 00:00:00 2001 From: Gilbok Lee Date: Mon, 28 Dec 2015 10:53:38 +0900 Subject: [PATCH 04/16] Fix svace issue (WGID:25363) Change-Id: I4a0dba22adfb94bb67276106aa1863e7ba1d748f Signed-off-by: Gilbok Lee --- src/mediademuxer_port.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mediademuxer_port.c b/src/mediademuxer_port.c index d1f79ab..c692c68 100755 --- a/src/mediademuxer_port.c +++ b/src/mediademuxer_port.c @@ -213,7 +213,11 @@ mediademuxer_src_type __md_util_media_type(char **uri) strncpy(old_uristr, *uri, len_uri + 1); /* need to added 7 char for file:// + 1 for '\0'+ uri len */ new_uristr = (char *)realloc(*uri, (7 + len_uri + 1) * sizeof(char)); - MEDIADEMUXER_CHECK_NULL(new_uristr); + if (!new_uristr) { + free(old_uristr); + old_uristr = NULL; + return MD_ERROR_INVALID_ARGUMENT; + } MD_L("reallocating uri[%p] to new_uristr[%p] \n", *uri, new_uristr); *uri = new_uristr; g_snprintf(*uri, 7 + len_uri + 1, "file://%s", old_uristr); -- 2.7.4 From 1b2c7a195fb86e76c078c7a563a3157216fb12f2 Mon Sep 17 00:00:00 2001 From: Deepak Srivastava Date: Tue, 29 Dec 2015 12:57:21 +0530 Subject: [PATCH 05/16] Applied Error handling guidelines. Change-Id: I0def588aa5cec7f9a663e31106d44c206c43049f Signed-off-by: Deepak Srivastava --- include/mediademuxer.h | 30 ++++++++++++++++----------- src/mediademuxer.c | 56 ++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 68 insertions(+), 18 deletions(-) diff --git a/include/mediademuxer.h b/include/mediademuxer.h index 1f52589..33b9d3e 100755 --- a/include/mediademuxer.h +++ b/include/mediademuxer.h @@ -26,10 +26,6 @@ extern "C" { #endif /* __cplusplus */ -#ifndef TIZEN_ERROR_MEDIA_DEMUXER -#define TIZEN_ERROR_MEDIA_DEMUXER -0x04000000 -#endif - /** * @file mediademuxer.h * @brief This file contains the capi media demuxer API. @@ -115,6 +111,8 @@ typedef void (*mediademuxer_eos_cb) (int track_num, void *user_data); * @param[out] demuxer A new handle to media demuxer * @return @c 0 on success, otherwise a negative error value * @retval #MEDIADEMUXER_ERROR_NONE Successful + * @retval #MEDIADEMUXER_ERROR_INVALID_OPERATION Invalid Operation + * @retval #MEDIADEMUXER_ERROR_OUT_OF_MEMORY Out of memory * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter * @post The media demuxer state will be #MEDIADEMUXER_STATE_IDLE. * @see mediademuxer_destroy() @@ -133,7 +131,7 @@ int mediademuxer_create(mediademuxer_h *demuxer); * @retval #MEDIADEMUXER_ERROR_NONE Successful * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #MEDIADEMUXER_ERROR_INVALID_STATE Invalid state - * @retval #MEDIADEMUXER_ERROR_PERMISSION_DENIED Permission denied + * @retval #MEDIADEMUXER_ERROR_INVALID_OPERATION Invalid Operation * @retval #MEDIADEMUXER_ERROR_INVALID_PATH Invalid path * @pre The media muxer state will be #MEDIADEMUXER_STATE_IDLE by calling mediademuxer_create() function. * */ @@ -148,6 +146,7 @@ int mediademuxer_set_data_source(mediademuxer_h demuxer, const char *path); * @retval #MEDIADEMUXER_ERROR_NONE Successful * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #MEDIADEMUXER_ERROR_INVALID_STATE Invalid state + * @retval #MEDIADEMUXER_ERROR_INVALID_OPERATION Invalid Operation * @pre The media demuxer state should be #MEDIADEMUXER_STATE_IDLE. * @post The media demuxer state will be #MEDIADEMUXER_STATE_READY. * @see mediademuxer_set_data_source() @@ -163,6 +162,7 @@ int mediademuxer_prepare(mediademuxer_h demuxer); * @retval #MEDIADEMUXER_ERROR_NONE Successful * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #MEDIADEMUXER_ERROR_INVALID_STATE Invalid state + * @retval #MEDIADEMUXER_ERROR_INVALID_OPERATION Invalid Operation * @pre The media demuxer state should be #MEDIADEMUXER_STATE_READY. * @see mediademuxer_prepare() * @see mediademuxer_select_track() @@ -178,6 +178,7 @@ int mediademuxer_get_track_count(mediademuxer_h demuxer, int *count); * @retval #MEDIADEMUXER_ERROR_NONE Successful * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #MEDIADEMUXER_ERROR_INVALID_STATE Invalid state + * @retval #MEDIADEMUXER_ERROR_INVALID_OPERATION Invalid Operation * @pre The media demuxer state should be #MEDIADEMUXER_STATE_READY. * @see mediademuxer_get_track_count() * @see mediademuxer_start() @@ -193,6 +194,7 @@ int mediademuxer_select_track(mediademuxer_h demuxer, int track_index); * @retval #MEDIADEMUXER_ERROR_NONE Successful * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #MEDIADEMUXER_ERROR_INVALID_STATE Invalid state + * @retval #MEDIADEMUXER_ERROR_INVALID_OPERATION Invalid Operation * @pre The media demuxer state should be #MEDIADEMUXER_STATE_READY. * @post The media demuxer state will be #MEDIADEMUXER_STATE_DEMUXING. * @see mediademuxer_prepare() @@ -213,6 +215,7 @@ int mediademuxer_start(mediademuxer_h demuxer); * @retval #MEDIADEMUXER_ERROR_NONE Successful * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #MEDIADEMUXER_ERROR_INVALID_STATE Invalid state + * @retval #MEDIADEMUXER_ERROR_INVALID_OPERATION Invalid Operation * @pre The media demuxer state must be set to #MEDIADEMUXER_STATE_DEMUXING by calling * mediademuxer_start() or set to #MEDIADEMUXER_STATE_READY by calling mediademuxer_prepare(). * @see mediademuxer_get_track_count() @@ -235,6 +238,7 @@ int mediademuxer_get_track_info(mediademuxer_h demuxer, int track_index, media_f * @retval #MEDIADEMUXER_ERROR_NONE Successful * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #MEDIADEMUXER_ERROR_INVALID_STATE Invalid state + * @retval #MEDIADEMUXER_ERROR_INVALID_OPERATION Invalid Operation * @pre The media demuxer state should be #MEDIADEMUXER_STATE_DEMUXING. * @see mediademuxer_start() * @see mediademuxer_get_track_info() @@ -255,6 +259,7 @@ int mediademuxer_read_sample(mediademuxer_h demuxer, int track_index, media_pack * @retval #MEDIADEMUXER_ERROR_NONE Successful * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #MEDIADEMUXER_ERROR_INVALID_STATE Invalid state + * @retval #MEDIADEMUXER_ERROR_INVALID_OPERATION Invalid Operation * @pre The media demuxer state should be #MEDIADEMUXER_STATE_DEMUXING. * @see mediademuxer_read_sample() * @see mediademuxer_stop() @@ -270,6 +275,7 @@ int mediademuxer_seek(mediademuxer_h demuxer, int64_t pos); * @retval #MEDIADEMUXER_ERROR_NONE Successful * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #MEDIADEMUXER_ERROR_INVALID_STATE Invalid state + * @retval #MEDIADEMUXER_ERROR_INVALID_OPERATION Invalid Operation * @pre The media demuxer state must be set to #MEDIADEMUXER_STATE_DEMUXING by calling * mediademuxer_read_sample() or set to #MEDIADEMUXER_STATE_READY by calling mediademuxer_select_track(). * @see mediademuxer_select_track() @@ -286,6 +292,7 @@ int mediademuxer_unselect_track(mediademuxer_h demuxer, int track_index); * @retval #MEDIADEMUXER_ERROR_NONE Successful * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #MEDIADEMUXER_ERROR_INVALID_STATE Invalid state + * @retval #MEDIADEMUXER_ERROR_INVALID_OPERATION Invalid Operation * @pre The media demuxer state must be set to #MEDIADEMUXER_STATE_DEMUXING. * @post The media demuxer state will be in #MEDIADEMUXER_READY. * @see mediademuxer_start() @@ -302,6 +309,7 @@ int mediademuxer_stop(mediademuxer_h demuxer); * @retval #MEDIADEMUXER_ERROR_NONE Successful * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #MEDIADEMUXER_ERROR_INVALID_STATE Invalid state + * @retval #MEDIADEMUXER_ERROR_INVALID_OPERATION Invalid Operation * @pre The media demuxer state should be #MEDIADEMUXER_STATE_READY. * @post The media demuxer state will be #MEDIADEMUXER_STATE_IDLE. * @see mediademuxer_prepare() @@ -316,6 +324,7 @@ int mediademuxer_unprepare(mediademuxer_h demuxer); * @retval #MEDIADEMUXER_ERROR_NONE Successful * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter * @retval #MEDIADEMUXER_ERROR_INVALID_STATE Invalid state + * @retval #MEDIADEMUXER_ERROR_INVALID_OPERATION Invalid Operation * @pre Create a media demuxer handle by calling mediademuxer_create() function. * @post The media demuxer state will be #MEDIADEMUXER_STATE_NONE. * @see mediademuxer_create() @@ -338,13 +347,6 @@ int mediademuxer_get_state(mediademuxer_h demuxer, mediademuxer_state *state); /** * @brief Registers an error callback function to be invoked when an error occurs. - * @details Following error codes can be delivered. - * #MEDIADEMUXER_ERROR_INVALID_OPERATION, - * #MEDIADEMUXER_ERROR_NOT_SUPPORTED, - * #MEDIADEMUXER_ERROR_INVALID_PATH, - * #MEDIADEMUXER_ERROR_RESOURCE_LIMIT, - * #MEDIADEMUXER_ERROR_SEEK_FAILED, - * #MEDIADEMUXER_ERROR_DRM_NOT_PERMITTED * @since_tizen 3.0 * @param[in] demuxer The media demuxer handle * @param[in] callback Callback function pointer @@ -354,6 +356,7 @@ int mediademuxer_get_state(mediademuxer_h demuxer, mediademuxer_state *state); * @return @c 0 on success, otherwise a negative error value * @retval #MEDIADEMUXER_ERROR_NONE Successful * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIADEMUXER_ERROR_INVALID_STATE Invalid state * @pre Create a media demuxer handle by calling mediademuxer_create() function. * @post mediademuxer_error_cb() will be invoked. * @see mediademuxer_unset_error_cb() @@ -368,6 +371,7 @@ int mediademuxer_set_error_cb(mediademuxer_h demuxer, mediademuxer_error_cb call * @return @c 0 on success, otherwise a negative error value * @retval #MEDIADEMUXER_ERROR_NONE Successful * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIADEMUXER_ERROR_INVALID_STATE Invalid state * @see mediademuxer_error_cb() * */ int mediademuxer_unset_error_cb(mediademuxer_h demuxer); @@ -383,6 +387,7 @@ int mediademuxer_unset_error_cb(mediademuxer_h demuxer); * @return @c 0 on success, otherwise a negative error value * @retval #MEDIADEMUXER_ERROR_NONE Successful * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIADEMUXER_ERROR_INVALID_STATE Invalid state * @pre Create a media demuxer handle by calling mediademuxer_create() function. * @post mediademuxer_eos_cb() will be invoked. * @see mediademuxer_unset_eos_cb() @@ -397,6 +402,7 @@ int mediademuxer_set_eos_cb(mediademuxer_h demuxer, mediademuxer_eos_cb callback * @return @c 0 on success, otherwise a negative error value * @retval #MEDIADEMUXER_ERROR_NONE Successful * @retval #MEDIADEMUXER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIADEMUXER_ERROR_INVALID_STATE Invalid state * @see mediademuxer_eos_cb() * */ int mediademuxer_unset_eos_cb(mediademuxer_h demuxer); diff --git a/src/mediademuxer.c b/src/mediademuxer.c index 334e182..a48a649 100755 --- a/src/mediademuxer.c +++ b/src/mediademuxer.c @@ -18,8 +18,6 @@ #include #include #include -#include -#include #include #include @@ -121,7 +119,11 @@ int mediademuxer_prepare(mediademuxer_h demuxer) handle = (mediademuxer_s *)(demuxer); if (handle && handle->demux_state == MEDIADEMUXER_IDLE) { ret = md_prepare((MMHandleType) (handle->md_handle)); - if (ret == MEDIADEMUXER_ERROR_NONE) + if (ret != MEDIADEMUXER_ERROR_NONE) { + MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + return MEDIADEMUXER_ERROR_INVALID_OPERATION; + } else handle->demux_state = MEDIADEMUXER_READY; } else { if (handle->demux_state != MEDIADEMUXER_IDLE) @@ -142,6 +144,11 @@ int mediademuxer_get_track_count(mediademuxer_h demuxer, int *count) handle = (mediademuxer_s *)(demuxer); if (handle && handle->demux_state == MEDIADEMUXER_READY) { ret = md_get_track_count((MMHandleType) (handle->md_handle), count); + if (ret != MEDIADEMUXER_ERROR_NONE) { + MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + return MEDIADEMUXER_ERROR_INVALID_OPERATION; + } } else { if (handle->demux_state != MEDIADEMUXER_READY) return MEDIADEMUXER_ERROR_INVALID_STATE; @@ -161,6 +168,11 @@ int mediademuxer_select_track(mediademuxer_h demuxer, int track_index) handle = (mediademuxer_s *)(demuxer); if (handle && handle->demux_state == MEDIADEMUXER_READY) { ret = md_select_track((MMHandleType) (handle->md_handle), track_index); + if (ret != MEDIADEMUXER_ERROR_NONE) { + MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + return MEDIADEMUXER_ERROR_INVALID_OPERATION; + } } else { if (handle->demux_state != MEDIADEMUXER_READY) return MEDIADEMUXER_ERROR_INVALID_STATE; @@ -180,7 +192,11 @@ int mediademuxer_start(mediademuxer_h demuxer) handle = (mediademuxer_s *)(demuxer); if (handle && handle->demux_state == MEDIADEMUXER_READY) { ret = md_start((MMHandleType) (handle->md_handle)); - if (ret == MEDIADEMUXER_ERROR_NONE) + if (ret != MEDIADEMUXER_ERROR_NONE) { + MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + return MEDIADEMUXER_ERROR_INVALID_OPERATION; + } else handle->demux_state = MEDIADEMUXER_DEMUXING; } else { if (handle->demux_state != MEDIADEMUXER_READY) @@ -207,6 +223,11 @@ int mediademuxer_get_track_info(mediademuxer_h demuxer, int track_index, if (handle && (handle->demux_state == MEDIADEMUXER_READY || handle->demux_state == MEDIADEMUXER_DEMUXING)) { ret = md_get_track_info((MMHandleType) (handle->md_handle), track_index, format); + if (ret != MEDIADEMUXER_ERROR_NONE) { + MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + return MEDIADEMUXER_ERROR_INVALID_OPERATION; + } } else { if (handle->demux_state != MEDIADEMUXER_READY) return MEDIADEMUXER_ERROR_INVALID_STATE; @@ -229,6 +250,11 @@ int mediademuxer_read_sample(mediademuxer_h demuxer, int track_index, return MEDIADEMUXER_ERROR_INVALID_PARAMETER; if (handle && handle->demux_state == MEDIADEMUXER_DEMUXING) { ret = md_read_sample((MMHandleType) (handle->md_handle), track_index, outbuf); + if (ret != MEDIADEMUXER_ERROR_NONE) { + MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + return MEDIADEMUXER_ERROR_INVALID_OPERATION; + } } else { if (handle->demux_state != MEDIADEMUXER_DEMUXING) return MEDIADEMUXER_ERROR_INVALID_STATE; @@ -248,6 +274,11 @@ int mediademuxer_seek(mediademuxer_h demuxer, int64_t pos) handle = (mediademuxer_s *)(demuxer); if (handle && handle->demux_state == MEDIADEMUXER_DEMUXING) { ret = md_seek((MMHandleType) (handle->md_handle), pos); + if (ret != MEDIADEMUXER_ERROR_NONE) { + MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + return MEDIADEMUXER_ERROR_INVALID_OPERATION; + } } else { if (handle->demux_state != MEDIADEMUXER_DEMUXING) return MEDIADEMUXER_ERROR_INVALID_STATE; @@ -268,6 +299,11 @@ int mediademuxer_unselect_track(mediademuxer_h demuxer, int track_index) if (handle && (handle->demux_state == MEDIADEMUXER_READY || handle->demux_state == MEDIADEMUXER_DEMUXING)) { ret = md_unselect_track((MMHandleType) (handle->md_handle), track_index); + if (ret != MEDIADEMUXER_ERROR_NONE) { + MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + return MEDIADEMUXER_ERROR_INVALID_OPERATION; + } } else { if (handle->demux_state != MEDIADEMUXER_READY) return MEDIADEMUXER_ERROR_INVALID_STATE; @@ -287,7 +323,11 @@ int mediademuxer_stop(mediademuxer_h demuxer) handle = (mediademuxer_s *)(demuxer); if (handle && handle->demux_state == MEDIADEMUXER_DEMUXING) { ret = md_stop((MMHandleType) (handle->md_handle)); - if (ret == MEDIADEMUXER_ERROR_NONE) + if (ret != MEDIADEMUXER_ERROR_NONE) { + MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + return MEDIADEMUXER_ERROR_INVALID_OPERATION; + } else handle->demux_state = MEDIADEMUXER_READY; } else { if (handle->demux_state != MEDIADEMUXER_DEMUXING) @@ -308,7 +348,11 @@ int mediademuxer_unprepare(mediademuxer_h demuxer) handle = (mediademuxer_s *)(demuxer); if (handle && handle->demux_state == MEDIADEMUXER_READY) { ret = md_unprepare((MMHandleType) (handle->md_handle)); - if (ret == MEDIADEMUXER_ERROR_NONE) + if (ret != MEDIADEMUXER_ERROR_NONE) { + MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", + __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); + return MEDIADEMUXER_ERROR_INVALID_OPERATION; + } else handle->demux_state = MEDIADEMUXER_IDLE; } else { if (handle->demux_state != MEDIADEMUXER_READY) -- 2.7.4 From a6d5cf25f6c27a6ad64acc8aad58f2ee2dcb3339 Mon Sep 17 00:00:00 2001 From: DEEPAK SRIVASTAVA Date: Wed, 6 Jan 2016 16:39:53 +0530 Subject: [PATCH 06/16] Sync with 2.4 [Setting default property of appsink equivalent to fakesink]. Change-Id: I8155182548a7a87fa965aceda319f1eda640ce26 Signed-off-by: DEEPAK SRIVASTAVA --- src/port_gst/mediademuxer_port_gst.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/port_gst/mediademuxer_port_gst.c b/src/port_gst/mediademuxer_port_gst.c index d2c7401..613ff51 100755 --- a/src/port_gst/mediademuxer_port_gst.c +++ b/src/port_gst/mediademuxer_port_gst.c @@ -238,7 +238,8 @@ int __gst_add_track_info(GstPad *pad, gchar *name, track **head, return MD_ERROR; } gst_bin_add_many(GST_BIN(pipeline), temp->appsink, NULL); - gst_app_sink_set_max_buffers((GstAppSink *) temp->appsink, MAX_APP_BUFFER); + gst_app_sink_set_max_buffers((GstAppSink *) temp->appsink, (guint) 0); + gst_app_sink_set_drop((GstAppSink *) temp->appsink, true); MEDIADEMUXER_SET_STATE(temp->appsink, GST_STATE_PAUSED, ERROR); apppad = gst_element_get_static_pad(temp->appsink, "sink"); if (!apppad) { -- 2.7.4 From ca2a42329b4fda661a5bc9b8d5261bf713dbe99a Mon Sep 17 00:00:00 2001 From: Deepak Srivastava Date: Tue, 19 Jan 2016 09:21:11 +0530 Subject: [PATCH 07/16] Sync with 2.4 (Error handling when eos not set.) [1] Added description of test main menu('e') in display_sub_basic() Change-Id: I90ba549185efdb3f0fe4a298ba01a56613ad57f4 Signed-off-by: Deepak Srivastava --- src/mediademuxer.c | 4 +++- test/mediademuxer_test.c | 7 +++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/mediademuxer.c b/src/mediademuxer.c index a48a649..e46e287 100755 --- a/src/mediademuxer.c +++ b/src/mediademuxer.c @@ -117,7 +117,7 @@ int mediademuxer_prepare(mediademuxer_h demuxer) DEMUXER_INSTANCE_CHECK(demuxer); mediademuxer_s *handle; handle = (mediademuxer_s *)(demuxer); - if (handle && handle->demux_state == MEDIADEMUXER_IDLE) { + if (handle && handle->demux_state == MEDIADEMUXER_IDLE && handle->eos_cb != NULL) { ret = md_prepare((MMHandleType) (handle->md_handle)); if (ret != MEDIADEMUXER_ERROR_NONE) { MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", @@ -128,6 +128,8 @@ int mediademuxer_prepare(mediademuxer_h demuxer) } else { if (handle->demux_state != MEDIADEMUXER_IDLE) return MEDIADEMUXER_ERROR_INVALID_STATE; + if (handle->eos_cb == NULL) + MD_E("EOS callback is not set\n"); MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); return MEDIADEMUXER_ERROR_INVALID_OPERATION; diff --git a/test/mediademuxer_test.c b/test/mediademuxer_test.c index de4faea..ec7b89a 100755 --- a/test/mediademuxer_test.c +++ b/test/mediademuxer_test.c @@ -826,7 +826,7 @@ static void display_sub_basic() g_print("\n"); g_print("===========================================================================\n"); g_print(" media demuxer test\n"); - g_print(" SELECT : c -> (s) -> p -> (goto submenu) -> d -> q \n"); + g_print(" SELECT : c -> (s) -> e -> p -> (goto submenu) -> d -> q \n"); g_print("---------------------------------------------------------------------------\n"); g_print("c. Create \t"); g_print("s. Set callback \t"); @@ -929,7 +929,10 @@ static void interpret(char *cmd) g_menu_state = CURRENT_STATUS_SET_DATA; } else { g_print("test_mediademuxer_prepare failed \n"); - g_menu_state = CURRENT_STATUS_FILENAME; + if (ret == MEDIADEMUXER_ERROR_INVALID_OPERATION) + g_menu_state = CURRENT_STATUS_MAINMENU; + else + g_menu_state = CURRENT_STATUS_FILENAME; } } else { g_menu_state = CURRENT_STATUS_FILENAME; -- 2.7.4 From 3a7e6cf7e891f260bf04bd21ab10a3f0076b5c59 Mon Sep 17 00:00:00 2001 From: Deepak Srivastava Date: Fri, 22 Jan 2016 14:13:18 +0530 Subject: [PATCH 08/16] Sync with 2.4 (Corrected get track info). [1] Corrected enum values. Change-Id: Ib250d9fcf61fe46493b279e60c663498331a8579 Signed-off-by: Deepak Srivastava --- include/mediademuxer_error.h | 2 +- src/port_gst/mediademuxer_port_gst.c | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/include/mediademuxer_error.h b/include/mediademuxer_error.h index 86a46da..12bb402 100755 --- a/include/mediademuxer_error.h +++ b/include/mediademuxer_error.h @@ -40,7 +40,7 @@ typedef enum { MD_MEMORY_ALLOCED = -16, /**< codec has got memory and can decode one frame */ MD_COURRPTED_INI = -17, /**< value in the ini file is not valid */ MD_ERROR_FILE_NOT_FOUND = -18, - MD_EOS, /** read sample reached end of stream */ + MD_EOS = -19, /** read sample reached end of stream */ } md_ret_e; #define MD_ERROR_CLASS 0x80000000 /**< Definition of number describing error group */ diff --git a/src/port_gst/mediademuxer_port_gst.c b/src/port_gst/mediademuxer_port_gst.c index 613ff51..514c81b 100755 --- a/src/port_gst/mediademuxer_port_gst.c +++ b/src/port_gst/mediademuxer_port_gst.c @@ -231,6 +231,7 @@ int __gst_add_track_info(GstPad *pad, gchar *name, track **head, temp->name = name; temp->caps_string = gst_caps_to_string(temp->caps); temp->next = NULL; + temp->format = NULL; temp->appsink = gst_element_factory_make("appsink", NULL); if (!temp->appsink) { MD_E("factory not able to make appsink"); @@ -976,7 +977,23 @@ static int gst_demuxer_get_track_info(MMHandleType pHandle, temp = temp->next; count++; } - + if (temp->format != NULL) { + ret = media_format_ref(temp->format); + if (ret != MEDIA_FORMAT_ERROR_NONE) { + MD_E("Mediaformat reference count increment failed. returned %d\n", ret); + ret = MD_INTERNAL_ERROR; + goto ERROR; + } + ret = media_format_make_writable(temp->format, format); /* copy the content */ + if (ret != MEDIA_FORMAT_ERROR_NONE) { + MD_E("Mediaformat create copy failed. returned %d\n", ret); + media_format_unref(temp->format); + ret = MD_INTERNAL_ERROR; + goto ERROR; + } + MEDIADEMUXER_FLEAVE(); + return ret; + } ret = media_format_create(&(temp->format)); if (ret != MEDIA_FORMAT_ERROR_NONE) { MD_E("Mediaformat creation failed. returned %d\n", ret); -- 2.7.4 From fab8fb330492b04ae7116915a77a6e6a5551fae0 Mon Sep 17 00:00:00 2001 From: "satheesan.en" Date: Wed, 3 Feb 2016 11:26:22 +0530 Subject: [PATCH 09/16] Added one pre-condition detail in the header comment of mediademuxer_prepare() Change-Id: I93f62a485e7cf538e8999bc99755ed8409aaea1c Signed-off-by: satheesan.en --- include/mediademuxer.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/mediademuxer.h b/include/mediademuxer.h index 33b9d3e..b358bcc 100755 --- a/include/mediademuxer.h +++ b/include/mediademuxer.h @@ -148,6 +148,7 @@ int mediademuxer_set_data_source(mediademuxer_h demuxer, const char *path); * @retval #MEDIADEMUXER_ERROR_INVALID_STATE Invalid state * @retval #MEDIADEMUXER_ERROR_INVALID_OPERATION Invalid Operation * @pre The media demuxer state should be #MEDIADEMUXER_STATE_IDLE. + * @pre mediademuxer_set_error_cb should be called before mediademuxer_prepare(). * @post The media demuxer state will be #MEDIADEMUXER_STATE_READY. * @see mediademuxer_set_data_source() * @see mediademuxer_unprepare() -- 2.7.4 From 1be247417c000d559960805b77b371a9b353c915 Mon Sep 17 00:00:00 2001 From: Gilbok Lee Date: Fri, 29 Apr 2016 10:11:05 +0900 Subject: [PATCH 10/16] Add build option to mediademuxer test excute files for applying ASLR Change-Id: Ie2e3e0e03ada1d7c6add1940c808c261ac8bf89a Signed-off-by: Gilbok Lee --- test/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index d5feaa9..9110bd2 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -10,7 +10,7 @@ FOREACH(flag ${${fw_test}_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") ENDFOREACH(flag) -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -pie") aux_source_directory(. sources) -- 2.7.4 From d9981b192ba7c101f276baa95fb8b655cc878514 Mon Sep 17 00:00:00 2001 From: Gilbok Lee Date: Wed, 15 Jun 2016 16:43:00 +0900 Subject: [PATCH 11/16] Fix memory leak issue Change-Id: Ic849df19b9d71c135522fe959b861b8c975d0841 Signed-off-by: Gilbok Lee --- include/port_gst/mediademuxer_port_gst.h | 3 +- src/mediademuxer.c | 14 ++++--- src/mediademuxer_port.c | 7 +++- src/port_gst/mediademuxer_port_gst.c | 67 ++++++++++++++++++++++---------- test/mediademuxer_test.c | 8 ++++ 5 files changed, 70 insertions(+), 29 deletions(-) diff --git a/include/port_gst/mediademuxer_port_gst.h b/include/port_gst/mediademuxer_port_gst.h index 8928813..8bda13a 100755 --- a/include/port_gst/mediademuxer_port_gst.h +++ b/include/port_gst/mediademuxer_port_gst.h @@ -87,8 +87,9 @@ typedef struct _mdgst_handle_t { GstElement *typefind; GstElement *demux; GstElement *fakesink; + GMainContext *thread_default; gulong signal_handoff; - gint bus_whatch_id; + guint bus_watch_id; bool is_valid_container; track_info info; int state_change_timeout; diff --git a/src/mediademuxer.c b/src/mediademuxer.c index e46e287..e2c67c1 100755 --- a/src/mediademuxer.c +++ b/src/mediademuxer.c @@ -123,8 +123,9 @@ int mediademuxer_prepare(mediademuxer_h demuxer) MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); return MEDIADEMUXER_ERROR_INVALID_OPERATION; - } else + } else { handle->demux_state = MEDIADEMUXER_READY; + } } else { if (handle->demux_state != MEDIADEMUXER_IDLE) return MEDIADEMUXER_ERROR_INVALID_STATE; @@ -198,8 +199,9 @@ int mediademuxer_start(mediademuxer_h demuxer) MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); return MEDIADEMUXER_ERROR_INVALID_OPERATION; - } else + } else { handle->demux_state = MEDIADEMUXER_DEMUXING; + } } else { if (handle->demux_state != MEDIADEMUXER_READY) return MEDIADEMUXER_ERROR_INVALID_STATE; @@ -380,21 +382,21 @@ int mediademuxer_destroy(mediademuxer_h demuxer) __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); return MEDIADEMUXER_ERROR_INVALID_OPERATION; } else { - MD_E("[CoreAPI][%s] destroy handle : %p", __FUNCTION__, - handle); + MD_E("[CoreAPI][%s] destroy handle : %p", __FUNCTION__, handle); + handle->demux_state = MEDIADEMUXER_NONE; + g_free(handle); + handle = NULL; } } else { MD_E("[CoreAPI][%s] DEMUXER_ERROR_INVALID_OPERATION(0x%08x)", __FUNCTION__, MEDIADEMUXER_ERROR_INVALID_OPERATION); return MEDIADEMUXER_ERROR_INVALID_OPERATION; } - handle->demux_state = MEDIADEMUXER_NONE; return MEDIADEMUXER_ERROR_NONE; } int mediademuxer_get_state(mediademuxer_h demuxer, mediademuxer_state *state) { - MD_I("mediademuxer_get_state\n"); mediademuxer_error_e ret = MEDIADEMUXER_ERROR_NONE; DEMUXER_INSTANCE_CHECK(demuxer); mediademuxer_s *handle = (mediademuxer_s *)(demuxer); diff --git a/src/mediademuxer_port.c b/src/mediademuxer_port.c index cacc760..409d94b 100755 --- a/src/mediademuxer_port.c +++ b/src/mediademuxer_port.c @@ -259,17 +259,20 @@ int _md_util_parse(MMHandleType demuxer, const char *type) /*Set media_type depending upon the header of string else consider using file protocol */ if (new_demuxer->uri_src) { MD_L("new_demuxer->uri_src deallocating %p\n", new_demuxer->uri_src); - free(new_demuxer->uri_src); + g_free(new_demuxer->uri_src); + new_demuxer->uri_src = NULL; } new_demuxer->uri_src_media_type = __md_util_media_type(&media_type_string); if (new_demuxer->uri_src_media_type != MEDIADEMUXER_SRC_INVALID) { + if (new_demuxer->uri_src) + g_free(new_demuxer->uri_src); new_demuxer->uri_src = media_type_string; MD_L("uri:%s\n uri_type:%d\n", new_demuxer->uri_src, new_demuxer->uri_src_media_type); } else { MD_E("Error while setiing source\n"); MD_E("deallocating media_type_string %p\n", media_type_string); - free(media_type_string); + g_free(media_type_string); goto ERROR; } MEDIADEMUXER_FLEAVE(); diff --git a/src/port_gst/mediademuxer_port_gst.c b/src/port_gst/mediademuxer_port_gst.c index 514c81b..3a9e4c2 100755 --- a/src/port_gst/mediademuxer_port_gst.c +++ b/src/port_gst/mediademuxer_port_gst.c @@ -180,6 +180,10 @@ void __gst_free_stuct(track **head) MD_I("deallocate GST_PAD %p\n", temp->pad); gst_object_unref(temp->pad); } */ + if (temp->caps) { + MD_I("deallocate GST_PAD caps_ %p\n", temp->caps); + gst_caps_unref(temp->caps); + } if (temp->name) { MD_I("deallocate GST_PAD name %p\n", temp->name); g_free(temp->name); @@ -189,11 +193,10 @@ void __gst_free_stuct(track **head) temp->caps_string); g_free(temp->caps_string); } - if (temp->caps) { - MD_I("deallocate GST_PAD caps_ %p\n", temp->caps); - gst_caps_unref(temp->caps); + if (temp->format) { + MD_I("unref media_format %p\n", temp->format); + media_format_unref(temp->format); } - if (temp->next) { track *next = temp->next; MD_I("deallocate memory %p\n", temp); @@ -286,12 +289,17 @@ int __gst_add_track_info(GstPad *pad, gchar *name, track **head, prev = prev->next; prev->next = temp; } - gst_object_unref(apppad); + if (apppad) + gst_object_unref(apppad); + if (parse_sink_pad) + gst_object_unref(parse_sink_pad); MEDIADEMUXER_FLEAVE(); return MD_ERROR_NONE; ERROR: if (apppad) gst_object_unref(apppad); + if (parse_sink_pad) + gst_object_unref(parse_sink_pad); __gst_free_stuct(head); MEDIADEMUXER_FLEAVE(); return MD_ERROR; @@ -447,10 +455,31 @@ static int __gst_create_audio_only_pipeline(gpointer data, GstCaps *caps) /* link queue with aacparse */ MEDIADEMUXER_LINK_PAD(queue_srcpad, aud_pad, ERROR); } else { - MEDIADEMUXER_LINK_PAD(pad, aud_pad, ERROR); + MEDIADEMUXER_LINK_PAD(pad, aud_pad, ERROR); } if (adif_queue) MEDIADEMUXER_SET_STATE(adif_queue, GST_STATE_PAUSED, ERROR); + + trck = head_track->head; + while (trck != NULL && aud_srcpad != trck->pad) + trck = trck->next; + + if (trck != NULL) { + if (trck->caps) + gst_caps_unref(trck->caps); + trck->caps = caps; + if (trck->caps_string) + g_free(trck->caps_string); + trck->caps_string = gst_caps_to_string(trck->caps); + MD_I("caps set to %s\n", trck->caps_string); + if (trck->name) + g_free(trck->name); + g_strlcpy(name, "audio", strlen(name)); + trck->name = name; + } + (head_track->num_audio_track)++; + + /* unref pads */ if (pad) gst_object_unref(pad); if (aud_pad) @@ -464,17 +493,6 @@ static int __gst_create_audio_only_pipeline(gpointer data, GstCaps *caps) if (aud_srcpad) gst_object_unref(aud_srcpad); - trck = head_track->head; - while (trck != NULL && aud_srcpad != trck->pad) - trck = trck->next; - if (trck != NULL) { - trck->caps = caps; - trck->caps_string = gst_caps_to_string(trck->caps); - MD_I("caps set to %s\n", trck->caps_string); - g_strlcpy(name, "audio", strlen(name)); - trck->name = name; - } - (head_track->num_audio_track)++; __gst_no_more_pad(gst_handle->demux, data); g_free(type); MEDIADEMUXER_FLEAVE(); @@ -659,8 +677,9 @@ static int _gst_create_pipeline(mdgst_handle_t *gst_handle, char *uri) /* connect signals, bus watcher */ bus = gst_pipeline_get_bus(GST_PIPELINE(gst_handle->pipeline)); - gst_handle->bus_whatch_id = gst_bus_add_watch(bus, __gst_bus_call, gst_handle); - gst_object_unref(bus); + gst_handle->bus_watch_id = gst_bus_add_watch(bus, __gst_bus_call, gst_handle); + gst_handle->thread_default = g_main_context_get_thread_default(); + gst_object_unref(GST_OBJECT(bus)); /* set pipeline state to PAUSED */ MEDIADEMUXER_SET_STATE(gst_handle->pipeline, GST_STATE_PAUSED, ERROR); @@ -1025,7 +1044,6 @@ static int gst_demuxer_get_track_info(MMHandleType pHandle, ret = MD_INTERNAL_ERROR; goto ERROR; } - MEDIADEMUXER_FLEAVE(); return ret; ERROR: @@ -1376,6 +1394,15 @@ static int gst_demuxer_unprepare(MMHandleType pHandle) mdgst_handle_t *gst_handle = (mdgst_handle_t *) pHandle; _gst_clear_struct(gst_handle); + if (gst_handle->bus_watch_id) { + GSource *source = NULL; + source = g_main_context_find_source_by_id(gst_handle->thread_default, gst_handle->bus_watch_id); + if (source) { + g_source_destroy(source); + LOGD("Deallocation bus watch id"); + } + } + MD_I("gst_demuxer_stop pipeine %p\n", gst_handle->pipeline); if (_md_gst_destroy_pipeline(gst_handle->pipeline) != MD_ERROR_NONE) { ret = MD_ERROR; diff --git a/test/mediademuxer_test.c b/test/mediademuxer_test.c index ec7b89a..37ec468 100755 --- a/test/mediademuxer_test.c +++ b/test/mediademuxer_test.c @@ -390,6 +390,10 @@ void *_fetch_audio_data(void *ptr) { int ret = MEDIADEMUXER_ERROR_NONE; int *status = (int *)g_malloc(sizeof(int) * 1); + if (!status) { + g_print("Fail malloc fetch audio data retur status value\n"); + return NULL; + } media_packet_h audbuf; int count = 0; uint64_t buf_size = 0; @@ -583,6 +587,10 @@ void *_fetch_video_data(void *ptr) { int ret = MEDIADEMUXER_ERROR_NONE; int *status = (int *)g_malloc(sizeof(int) * 1); + if (!status) { + g_print("Fail malloc fetch video data retur status value\n"); + return NULL; + } media_packet_h vidbuf; int count = 0; uint64_t buf_size = 0; -- 2.7.4 From 61162ef16e9ee068cd20b345ca27ac478182dbc4 Mon Sep 17 00:00:00 2001 From: Gilbok Lee Date: Thu, 30 Jun 2016 14:10:53 +0900 Subject: [PATCH 12/16] Sync with 2.4 1. Added support for extracting Text track. 2. Link queue element after demux 3. To fix EOS issue when one single channel data alone is retreived Change-Id: I3c0c7e3571050d70b19a497d99097efd95c60e70 Signed-off-by: Gilbok Lee --- packaging/capi-mediademuxer.spec | 2 +- src/port_gst/mediademuxer_port_gst.c | 162 ++++++++++++++++++++++++++++++----- test/mediademuxer_test.c | 81 +++++++++++++++--- 3 files changed, 212 insertions(+), 33 deletions(-) diff --git a/packaging/capi-mediademuxer.spec b/packaging/capi-mediademuxer.spec index 3d25e86..71d394a 100755 --- a/packaging/capi-mediademuxer.spec +++ b/packaging/capi-mediademuxer.spec @@ -1,6 +1,6 @@ Name: capi-mediademuxer Summary: A Media Demuxer library in Tizen Native API -Version: 0.1.1 +Version: 0.1.2 Release: 1 Group: Multimedia/API License: Apache-2.0 diff --git a/src/port_gst/mediademuxer_port_gst.c b/src/port_gst/mediademuxer_port_gst.c index 3a9e4c2..1401628 100755 --- a/src/port_gst/mediademuxer_port_gst.c +++ b/src/port_gst/mediademuxer_port_gst.c @@ -217,6 +217,8 @@ int __gst_add_track_info(GstPad *pad, gchar *name, track **head, { MEDIADEMUXER_FENTER(); GstPad *apppad = NULL; + GstPad *queue_sink_pad = NULL; + GstPad *queue_src_pad = NULL; GstCaps *outcaps = NULL; GstPad *parse_sink_pad = NULL; GstElement *parse_element = NULL; @@ -235,50 +237,78 @@ int __gst_add_track_info(GstPad *pad, gchar *name, track **head, temp->caps_string = gst_caps_to_string(temp->caps); temp->next = NULL; temp->format = NULL; + + /* Link demuxer - queue */ + temp->queue = gst_element_factory_make("queue", NULL); + if (!temp->queue) { + MD_E("factory not able to make queue"); + goto ERROR; + } + + if (!gst_bin_add(GST_BIN(pipeline), temp->queue)) { + MD_E("fail add queue in pipeline"); + goto ERROR; + } + + queue_sink_pad = gst_element_get_static_pad(temp->queue, "sink"); + if (!queue_sink_pad) { + MD_E("queue_sink_pad of appsink not avaible"); + goto ERROR; + } + + MEDIADEMUXER_SET_STATE(temp->queue, GST_STATE_PAUSED, ERROR); + MEDIADEMUXER_LINK_PAD(pad, queue_sink_pad, ERROR); + temp->appsink = gst_element_factory_make("appsink", NULL); if (!temp->appsink) { MD_E("factory not able to make appsink"); - __gst_free_stuct(head); - return MD_ERROR; + goto ERROR; + } + + if (!gst_bin_add(GST_BIN(pipeline), temp->appsink)) { + MD_E("fail add queue in pipeline"); + goto ERROR; } - gst_bin_add_many(GST_BIN(pipeline), temp->appsink, NULL); + gst_app_sink_set_max_buffers((GstAppSink *) temp->appsink, (guint) 0); gst_app_sink_set_drop((GstAppSink *) temp->appsink, true); MEDIADEMUXER_SET_STATE(temp->appsink, GST_STATE_PAUSED, ERROR); + + queue_src_pad = gst_element_get_static_pad(temp->queue, "src"); + if (!queue_src_pad) { + MD_E("queue_src_pad of appsink not avaible"); + goto ERROR; + } apppad = gst_element_get_static_pad(temp->appsink, "sink"); if (!apppad) { MD_E("sink pad of appsink not avaible"); - __gst_free_stuct(head); - return MD_ERROR; + goto ERROR; } /* Check for type video and it should be h264 */ if (strstr(name, "video") && strstr(temp->caps_string, "h264")) { parse_element = gst_element_factory_make("h264parse", NULL); if (!parse_element) { MD_E("factory not able to make h264parse"); - __gst_free_stuct(head); - gst_object_unref(apppad); - return MD_ERROR; + goto ERROR; } gst_bin_add_many(GST_BIN(pipeline), parse_element, NULL); - MEDIADEMUXER_SET_STATE(parse_element, GST_STATE_PAUSED, ERROR); - parse_sink_pad = gst_element_get_static_pad(parse_element, "sink"); if (!parse_sink_pad) { + gst_object_unref(parse_element); MD_E("sink pad of h264parse not available"); - __gst_free_stuct(head); - gst_object_unref(apppad); - return MD_ERROR; + goto ERROR; } + MEDIADEMUXER_SET_STATE(parse_element, GST_STATE_PAUSED, ERROR); + /* Link demuxer pad with sink pad of parse element */ - MEDIADEMUXER_LINK_PAD(pad, parse_sink_pad, ERROR); + MEDIADEMUXER_LINK_PAD(queue_src_pad, parse_sink_pad, ERROR); outcaps = gst_caps_new_simple("video/x-h264", "stream-format", G_TYPE_STRING, "byte-stream", NULL); gst_element_link_filtered(parse_element, temp->appsink, outcaps); gst_caps_unref(outcaps); } else { - MEDIADEMUXER_LINK_PAD(pad, apppad, ERROR); + MEDIADEMUXER_LINK_PAD(queue_src_pad, apppad, ERROR); } /* gst_pad_link(pad, fpad) */ if (*head == NULL) { @@ -289,13 +319,30 @@ int __gst_add_track_info(GstPad *pad, gchar *name, track **head, prev = prev->next; prev->next = temp; } + if (queue_sink_pad) + gst_object_unref(queue_sink_pad); + if (queue_src_pad) + gst_object_unref(queue_src_pad); if (apppad) gst_object_unref(apppad); if (parse_sink_pad) gst_object_unref(parse_sink_pad); MEDIADEMUXER_FLEAVE(); return MD_ERROR_NONE; + ERROR: + if (temp->caps) + gst_object_unref(temp->caps); + if (temp->caps_string) + g_free(temp->caps_string); + if (temp->queue) + gst_object_unref(temp->queue); + if (temp->appsink) + gst_object_unref(temp->appsink); + if (queue_sink_pad) + gst_object_unref(queue_sink_pad); + if (queue_src_pad) + gst_object_unref(queue_src_pad); if (apppad) gst_object_unref(apppad); if (parse_sink_pad) @@ -327,6 +374,11 @@ static void __gst_on_pad_added(GstElement *element, GstPad *pad, gpointer data) tmp = head_track->head; while (tmp->next) tmp = tmp->next; + if (!tmp || !tmp->caps_string) { + MD_I("trak or trak caps_string is NULL\n"); + MEDIADEMUXER_FLEAVE(); + return; + } if (tmp->caps_string[0] == 'v') { MD_I("found Video Pad\n"); (head_track->num_video_track)++; @@ -777,6 +829,29 @@ ERROR: return ret; } +static int _gst_unlink_unselected_track(track *temp, int index) +{ + MEDIADEMUXER_FENTER(); + int ret = MD_ERROR_NONE; + int count = 0; + GstPad *queue_sink_pad = NULL; + while (count != index) { + temp = temp->next; + count++; + } + queue_sink_pad = gst_element_get_static_pad(temp->queue, "sink"); + if (!queue_sink_pad) { + MD_E("queue_sink_pad of appsink not avaible\n"); + return MD_ERROR; + } + if (gst_pad_unlink(temp->pad, queue_sink_pad) != TRUE) + MD_W("demuxer is already unlinked from queue for track %d\n", index); + + gst_object_unref(queue_sink_pad); + MEDIADEMUXER_FLEAVE(); + return ret; +} + static int gst_demuxer_start(MMHandleType pHandle) { MEDIADEMUXER_FENTER(); @@ -792,6 +867,14 @@ static int gst_demuxer_start(MMHandleType pHandle) if (gst_handle->selected_tracks[indx] == false) _gst_demuxer_unset(pHandle, indx); */ + if (gst_handle->selected_tracks[indx] != true) { + if (_gst_unlink_unselected_track((((mdgst_handle_t *) pHandle)->info).head, indx) != MD_ERROR_NONE) { + MD_E("Failed to unlink unselected tracks\n"); + ret = MD_INTERNAL_ERROR; + goto ERROR; + } + } + } track_info *head_track = &(gst_handle->info); @@ -827,6 +910,31 @@ ERROR: return ret; } +int _set_mime_text(media_format_h format, track *head) +{ + MEDIADEMUXER_FENTER(); + int ret = MD_ERROR_NONE; + GstStructure *struc = NULL; + struc = gst_caps_get_structure(head->caps, 0); + if (!struc) { + MD_E("cannot get structure from caps.\n"); + goto ERROR; + } + if (gst_structure_has_name(struc, "text/x-raw")) { + if (media_format_set_text_mime(format, MEDIA_FORMAT_TEXT_MP4)) + goto ERROR; + } else { + MD_I("Text mime not supported so far\n"); + goto ERROR; + } + + MEDIADEMUXER_FLEAVE(); + return ret; +ERROR: + MEDIADEMUXER_FLEAVE(); + return MD_ERROR; +} + int _set_mime_video(media_format_h format, track *head) { MEDIADEMUXER_FENTER(); @@ -844,14 +952,16 @@ int _set_mime_video(media_format_h format, track *head) } if (gst_structure_has_name(struc, "video/x-h264")) { const gchar *version = gst_structure_get_string(struc, "stream-format"); - if (strncmp(version, "avc", 3) == 0) + if (strncmp(version, "avc", 3) == 0) { mime_type = MEDIA_FORMAT_H264_SP; - else { + } else { MD_W("Video mime (%s) not supported so far\n", gst_structure_get_name(struc)); goto ERROR; } } else if (gst_structure_has_name(struc, "video/x-h263")) { mime_type = MEDIA_FORMAT_H263; + } else if (gst_structure_has_name(struc, "video/mpeg")) { + mime_type = MEDIA_FORMAT_MPEG4_SP; } else { MD_W("Video mime (%s) not supported so far\n", gst_structure_get_name(struc)); goto ERROR; @@ -862,10 +972,14 @@ int _set_mime_video(media_format_h format, track *head) } gst_structure_get_int(struc, "width", &src_width); gst_structure_get_int(struc, "height", &src_height); - if (media_format_set_video_width(format, src_width)) + if (media_format_set_video_width(format, src_width)) { + MD_E("Unable to set video width\n"); goto ERROR; - if (media_format_set_video_height(format, src_height)) - goto ERROR; + } + if (media_format_set_video_height(format, src_height)) { + MD_E("Unable to set video height\n"); + goto ERROR; + } gst_structure_get_fraction(struc, "framerate", &frame_rate_numerator, &frame_rate_denominator); if (media_format_set_video_frame_rate(format, frame_rate_numerator)) { MD_E("Unable to set video frame rate\n"); @@ -1028,8 +1142,12 @@ static int gst_demuxer_get_track_info(MMHandleType pHandle, } else if (temp->caps_string[0] == 'v') { MD_I("Setting for Video \n"); _set_mime_video(temp->format, temp); - } else - MD_W("Not supported so far (except audio and video)\n"); + } else if (temp->caps_string[0] == 't') { + MD_I("Setting for Subtitle\n"); + _set_mime_text(temp->format, temp); + } else { + MD_W("Not supported so far (except audio, video and subtitle)\n"); + } ret = media_format_ref(temp->format); /* increment the ref to retain the original content */ if (ret != MEDIA_FORMAT_ERROR_NONE) { diff --git a/test/mediademuxer_test.c b/test/mediademuxer_test.c index 37ec468..6b10666 100755 --- a/test/mediademuxer_test.c +++ b/test/mediademuxer_test.c @@ -49,10 +49,13 @@ enum { mediademuxer_h demuxer = NULL; media_format_mimetype_e v_mime; media_format_mimetype_e a_mime; +media_format_mimetype_e t_mime; +media_format_text_type_e t_type; int g_menu_state = CURRENT_STATUS_MAINMENU; int num_tracks = 0; int aud_track = -1; int vid_track = -1; +int txt_track = -1; int w; int h; int channel = 0; @@ -61,6 +64,7 @@ int bit = 0; bool is_adts = 0; bool vid_eos_track = 0; bool aud_eos_track = 0; +bool text_eos_track = 0; /*----------------------------------------------------------------------- | DEBUG DEFINITIONS | @@ -112,6 +116,7 @@ bool aud_eos_track = 0; #if DEMUXER_OUTPUT_DUMP FILE *fp_audio_out = NULL; FILE *fp_video_out = NULL; +FILE *fp_text_out = NULL; bool validate_dump = false; #define ADTS_HEADER_SIZE 7 @@ -166,16 +171,14 @@ void generate_header_aac_adts(unsigned char *buffer, int packetLen) /* Make ADTS header */ buffer[0] = (char)0xFF; buffer[1] = (char)0xF1; - buffer[2] = (char)(((profile-1)<<6) + (freqIdx<<2) +(chanCfg>>2)); - buffer[3] = (char)(((chanCfg&3)<<6) + (packetLen>>11)); - buffer[4] = (char)((packetLen&0x7FF) >> 3); - buffer[5] = (char)(((packetLen&7)<<5) + 0x1F); + buffer[2] = (char)(((profile - 1) << 6) + (freqIdx << 2) + (chanCfg >> 2)); + buffer[3] = (char)(((chanCfg & 3) << 6) + (packetLen >> 11)); + buffer[4] = (char)((packetLen & 0x7FF) >> 3); + buffer[5] = (char)(((packetLen & 7) << 5) + 0x1F); buffer[6] = (char)0xFC; } #endif - - /*----------------------------------------------------------------------- | LOCAL FUNCTION | -----------------------------------------------------------------------*/ @@ -198,8 +201,10 @@ int test_mediademuxer_set_data_source(mediademuxer_h demuxer, const char *path) if (fp_audio_out != NULL) { validate_dump = true; fp_video_out = fopen("/opt/usr/dump_video.out", "wb"); - } else + fp_text_out = fopen("/opt/usr/dump_text.out", "wb"); + } else { g_print("Error - Cannot open file for file dump, Please chek root\n"); + } #endif ret = mediademuxer_set_data_source(demuxer, path); @@ -268,6 +273,10 @@ int test_mediademuxer_get_track_info() if (a_mime == MEDIA_FORMAT_AAC_LC) media_format_get_audio_aac_type(g_media_format, &is_adts); aud_track = track; + } else if (media_format_get_text_info(g_media_format, &t_mime, &t_type) == MEDIA_FORMAT_ERROR_NONE) { + g_print("media_format_get_text_info is sucess!\n"); + g_print("\t\t[media_format_get_text]mime:%x, type:%x\n", t_mime, t_type); + txt_track = track; } else { g_print("Not Supported YET\n"); } @@ -653,9 +662,51 @@ void *_fetch_video_data(void *ptr) return (void *)status; } +void *_fetch_text_data(void *ptr) +{ + int ret = MEDIADEMUXER_ERROR_NONE; + int *status = (int *)g_malloc(sizeof(int) * 1); + if (!status) { + g_print("Fail malloc fetch video data retur status value\n"); + return NULL; + } + media_packet_h txtbuf; + int count = 0; + uint64_t buf_size = 0; + void *data = NULL; + + *status = -1; + g_print("text Data function\n"); + g_print("Text track number is :%d\n", txt_track); + while (1) { + ret = mediademuxer_read_sample(demuxer, txt_track, &txtbuf); + if (ret != MEDIADEMUXER_ERROR_NONE) { + g_print("Error (%d) return of mediademuxer_read_sample()\n", ret); + pthread_exit(NULL); + } + if (text_eos_track) + break; + count++; + media_packet_get_buffer_size(txtbuf, &buf_size); + media_packet_get_buffer_data_ptr(txtbuf, &data); + g_print("Text Read Count::[%4d] frame - get_buffer_size = %"PRIu64"\n", count, buf_size); +#if DEMUXER_OUTPUT_DUMP + if (validate_dump) { + if (data != NULL) + fwrite(data, 1, buf_size, fp_text_out); + else + g_print("DUMP : write(text data) fail for NULL\n"); + } +#endif + } + g_print("EOS return of mediademuxer_read_sample()\n"); + *status = 0; + return (void *)status; +} + int test_mediademuxer_read_sample() { - pthread_t thread[2]; + pthread_t thread[3]; pthread_attr_t attr; /* Initialize and set thread detached attribute */ pthread_attr_init(&attr); @@ -668,6 +719,10 @@ int test_mediademuxer_read_sample() g_print("In main: creating thread for audio\n"); pthread_create(&thread[1], &attr, _fetch_audio_data, NULL); } + if (txt_track != -1) { + g_print("In main: creating thread for text\n"); + pthread_create(&thread[2], &attr, _fetch_text_data, NULL); + } pthread_attr_destroy(&attr); return 0; } @@ -738,8 +793,9 @@ int test_mediademuxer_get_state() g_print("Mediademuxer_state = DEMUXING\n"); else g_print("Mediademuxer_state = NOT SUPPORT STATE\n"); - } else + } else { g_print("Mediademuxer_state call failed\n"); + } return 0; } @@ -755,6 +811,8 @@ void app_eos_cb(int track_index, void *user_data) vid_eos_track = true; else if (track_index == aud_track) aud_eos_track = true; + else if (track_index == txt_track) + text_eos_track = true; else g_print("EOS for invalid track number\n"); } @@ -943,6 +1001,8 @@ static void interpret(char *cmd) g_menu_state = CURRENT_STATUS_FILENAME; } } else { + if (ret == MEDIADEMUXER_ERROR_INVALID_PATH) + g_print("Invalid path, file does not exist\n"); g_menu_state = CURRENT_STATUS_FILENAME; } break; @@ -989,8 +1049,9 @@ static void interpret(char *cmd) g_print("UNKNOW COMMAND\n"); else g_print("UNKNOW COMMAND\n"); - } else + } else { g_print("UNKNOW COMMAND\n"); + } break; } default: -- 2.7.4 From 7c3f0c7e7fb4f9224d22b73e0e23ddb7a210433e Mon Sep 17 00:00:00 2001 From: Gilbok Lee Date: Thu, 7 Jul 2016 19:52:31 +0900 Subject: [PATCH 13/16] Fix memory leak Change-Id: Id9fc121363e45bc89c22cfd3c0f147d210522fdf Signed-off-by: Gilbok Lee --- packaging/capi-mediademuxer.spec | 2 +- src/port_gst/mediademuxer_port_gst.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packaging/capi-mediademuxer.spec b/packaging/capi-mediademuxer.spec index 71d394a..3b40c83 100755 --- a/packaging/capi-mediademuxer.spec +++ b/packaging/capi-mediademuxer.spec @@ -1,6 +1,6 @@ Name: capi-mediademuxer Summary: A Media Demuxer library in Tizen Native API -Version: 0.1.2 +Version: 0.1.3 Release: 1 Group: Multimedia/API License: Apache-2.0 diff --git a/src/port_gst/mediademuxer_port_gst.c b/src/port_gst/mediademuxer_port_gst.c index 1401628..91fcc0e 100755 --- a/src/port_gst/mediademuxer_port_gst.c +++ b/src/port_gst/mediademuxer_port_gst.c @@ -1495,6 +1495,8 @@ int _md_gst_destroy_pipeline(GstElement *pipeline) int ret = MD_ERROR_NONE; if (pipeline) MEDIADEMUXER_SET_STATE(pipeline, GST_STATE_NULL, ERROR); + if (pipeline) + gst_object_unref(GST_OBJECT(pipeline)); MEDIADEMUXER_FLEAVE(); return ret; ERROR: -- 2.7.4 From 73ad39e7bec500798df70987a101dc971126c0f1 Mon Sep 17 00:00:00 2001 From: Gilbok Lee Date: Mon, 18 Jul 2016 16:49:03 +0900 Subject: [PATCH 14/16] Fix bug for read_sample function return buffer (when EOS state, read_sample retured garbage buffer) Change-Id: Ie8a598da01f8bb9ef36ebfc740be775538ac19ba --- packaging/capi-mediademuxer.spec | 2 +- src/port_gst/mediademuxer_port_gst.c | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/packaging/capi-mediademuxer.spec b/packaging/capi-mediademuxer.spec index 3b40c83..471b8c7 100755 --- a/packaging/capi-mediademuxer.spec +++ b/packaging/capi-mediademuxer.spec @@ -1,6 +1,6 @@ Name: capi-mediademuxer Summary: A Media Demuxer library in Tizen Native API -Version: 0.1.3 +Version: 0.1.4 Release: 1 Group: Multimedia/API License: Apache-2.0 diff --git a/src/port_gst/mediademuxer_port_gst.c b/src/port_gst/mediademuxer_port_gst.c index 91fcc0e..31214ed 100755 --- a/src/port_gst/mediademuxer_port_gst.c +++ b/src/port_gst/mediademuxer_port_gst.c @@ -1277,12 +1277,6 @@ static int gst_demuxer_read_sample(MMHandleType pHandle, goto ERROR; } - if (media_packet_create_alloc(atrack->format, NULL, NULL, &mediabuf)) { - MD_E("media_packet_create_alloc failed\n"); - ret = MD_ERROR; - goto ERROR; - } - if (indx != track_indx) { MD_E("Invalid track Index\n"); ret = MD_ERROR_INVALID_ARGUMENT; @@ -1296,14 +1290,23 @@ static int gst_demuxer_read_sample(MMHandleType pHandle, if (gst_app_sink_is_eos((GstAppSink *) sink)) { MD_W("End of stream (EOS) reached, triggering the eos callback\n"); ret = MD_ERROR_NONE; + *outbuf = NULL; __gst_eos_callback(track_indx, demuxer); return ret; } else { MD_E("gst_demuxer_read_sample failed\n"); + *outbuf = NULL; ret = MD_ERROR_UNKNOWN; + return ret; } } + if (media_packet_create_alloc(atrack->format, NULL, NULL, &mediabuf)) { + MD_E("media_packet_create_alloc failed\n"); + ret = MD_ERROR; + goto ERROR; + } + GstBuffer *buffer = gst_sample_get_buffer(sample); if (buffer == NULL) { MD_E("gst_sample_get_buffer returned NULL pointer\n"); @@ -1337,6 +1340,9 @@ static int gst_demuxer_read_sample(MMHandleType pHandle, MEDIADEMUXER_FLEAVE(); return ret; ERROR: + if (mediabuf) + media_packet_destroy(mediabuf); + *outbuf = NULL; MEDIADEMUXER_FLEAVE(); return ret; } -- 2.7.4 From 89d36c3809e70211e921b1767c0e915c0862dbd9 Mon Sep 17 00:00:00 2001 From: Gilbok Lee Date: Fri, 29 Jul 2016 11:13:12 +0900 Subject: [PATCH 15/16] Add mpeg4video parser, because decoding has to be possible with the output packet. Change-Id: I3b9ecb2fe05e5a185866fa552599a04cb48989ad --- packaging/capi-mediademuxer.spec | 2 +- src/port_gst/mediademuxer_port_gst.c | 29 ++++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/packaging/capi-mediademuxer.spec b/packaging/capi-mediademuxer.spec index 471b8c7..d1a54db 100755 --- a/packaging/capi-mediademuxer.spec +++ b/packaging/capi-mediademuxer.spec @@ -1,6 +1,6 @@ Name: capi-mediademuxer Summary: A Media Demuxer library in Tizen Native API -Version: 0.1.4 +Version: 0.1.5 Release: 1 Group: Multimedia/API License: Apache-2.0 diff --git a/src/port_gst/mediademuxer_port_gst.c b/src/port_gst/mediademuxer_port_gst.c index 31214ed..2214f2d 100755 --- a/src/port_gst/mediademuxer_port_gst.c +++ b/src/port_gst/mediademuxer_port_gst.c @@ -291,7 +291,10 @@ int __gst_add_track_info(GstPad *pad, gchar *name, track **head, MD_E("factory not able to make h264parse"); goto ERROR; } - gst_bin_add_many(GST_BIN(pipeline), parse_element, NULL); + if (!gst_bin_add(GST_BIN(pipeline), parse_element)) { + MD_E("fail add h264parse in pipeline"); + goto ERROR; + } parse_sink_pad = gst_element_get_static_pad(parse_element, "sink"); if (!parse_sink_pad) { gst_object_unref(parse_element); @@ -307,6 +310,30 @@ int __gst_add_track_info(GstPad *pad, gchar *name, track **head, outcaps = gst_caps_new_simple("video/x-h264", "stream-format", G_TYPE_STRING, "byte-stream", NULL); gst_element_link_filtered(parse_element, temp->appsink, outcaps); gst_caps_unref(outcaps); + } else if (strstr(name, "video") && strstr(temp->caps_string, "mpeg")) { + parse_element = gst_element_factory_make("mpeg4videoparse", NULL); + if (!parse_element) { + MD_E("factory not able to make mpeg4videoparse"); + goto ERROR; + } + if (!gst_bin_add(GST_BIN(pipeline), parse_element)) { + MD_E("fail add mpeg4videoparse in pipeline"); + goto ERROR; + } + parse_sink_pad = gst_element_get_static_pad(parse_element, "sink"); + if (!parse_sink_pad) { + gst_object_unref(parse_element); + MD_E("sink pad of mpeg4videoparse not available"); + goto ERROR; + } + + g_object_set(G_OBJECT(parse_element), "config-interval", 1, NULL); + + MEDIADEMUXER_SET_STATE(parse_element, GST_STATE_PAUSED, ERROR); + + /* Link demuxer pad with sink pad of parse element */ + MEDIADEMUXER_LINK_PAD(queue_src_pad, parse_sink_pad, ERROR); + gst_element_link(parse_element, temp->appsink); } else { MEDIADEMUXER_LINK_PAD(queue_src_pad, apppad, ERROR); } -- 2.7.4 From 56c61052dc7608e12dd97e52499719b1ded82192 Mon Sep 17 00:00:00 2001 From: Gilbok Lee Date: Fri, 29 Jul 2016 19:13:32 +0900 Subject: [PATCH 16/16] Changed the function name to conflict of symbol link Change-Id: If4ee0e2b7ff960dd7b142b58fe2da14e1ea3005b --- packaging/capi-mediademuxer.spec | 2 +- src/mediademuxer_port.c | 18 +++++++++--------- src/port_custom/mediademuxer_port_custom.c | 2 +- src/port_ffmpeg/mediademuxer_port_ffmpeg.c | 2 +- src/port_gst/mediademuxer_port_gst.c | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/packaging/capi-mediademuxer.spec b/packaging/capi-mediademuxer.spec index d1a54db..d09180c 100755 --- a/packaging/capi-mediademuxer.spec +++ b/packaging/capi-mediademuxer.spec @@ -1,6 +1,6 @@ Name: capi-mediademuxer Summary: A Media Demuxer library in Tizen Native API -Version: 0.1.5 +Version: 0.1.6 Release: 1 Group: Multimedia/API License: Apache-2.0 diff --git a/src/mediademuxer_port.c b/src/mediademuxer_port.c index 409d94b..7abee84 100755 --- a/src/mediademuxer_port.c +++ b/src/mediademuxer_port.c @@ -36,9 +36,9 @@ #define MAX_ERR_LEN 256 /* function type */ -extern int gst_port_register(media_port_demuxer_ops *pOps); -extern int ffmpeg_port_register(media_port_demuxer_ops *pOps); -extern int custom_port_register(media_port_demuxer_ops *pOps); +extern int gst_mediademxer_port_register(media_port_demuxer_ops *pOps); +extern int ffmpeg_mediademxer_port_register(media_port_demuxer_ops *pOps); +extern int custom_mediademxer_port_register(media_port_demuxer_ops *pOps); int __md_util_exist_file_path(const char *file_path); bool __md_util_is_sdp_file(const char *path); mediademuxer_src_type __md_util_media_type(char **uri); @@ -48,11 +48,11 @@ int _md_util_parse(MMHandleType demuxer, const char *type); * Sequence of functions should be same as the port enumeration * "port_mode" in mm_demuxer_ini.h file */ -typedef int (*register_port)(media_port_demuxer_ops *); -register_port register_port_func[] = { - &gst_port_register, - &ffmpeg_port_register, - &custom_port_register +typedef int (*register_port_demuxer)(media_port_demuxer_ops *); +register_port_demuxer register_port_demuxer_func[] = { + &gst_mediademxer_port_register, + &ffmpeg_mediademxer_port_register, + &custom_mediademxer_port_register }; int md_create(MMHandleType *demuxer) @@ -82,7 +82,7 @@ int md_create(MMHandleType *demuxer) MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, result, MD_COURRPTED_INI, "can't load ini"); - register_port_func[new_demuxer->ini.port_type](pOps); + register_port_demuxer_func[new_demuxer->ini.port_type](pOps); result = pOps->init(&new_demuxer->mdport_handle); MEDIADEMUXER_CHECK_SET_AND_PRINT(result, MD_ERROR_NONE, result, MD_NOT_INITIALIZED, "md_create failed"); diff --git a/src/port_custom/mediademuxer_port_custom.c b/src/port_custom/mediademuxer_port_custom.c index 171d70c..78a6a7b 100755 --- a/src/port_custom/mediademuxer_port_custom.c +++ b/src/port_custom/mediademuxer_port_custom.c @@ -43,7 +43,7 @@ static media_port_demuxer_ops def_demux_ops = { .get_data = custom_demuxer_get_data, }; -int custom_port_register(media_port_demuxer_ops *pOps) +int custom_mediademxer_port_register(media_port_demuxer_ops *pOps) { int ret = MD_ERROR_NONE; MEDIADEMUXER_FENTER(); diff --git a/src/port_ffmpeg/mediademuxer_port_ffmpeg.c b/src/port_ffmpeg/mediademuxer_port_ffmpeg.c index 352c385..4405359 100755 --- a/src/port_ffmpeg/mediademuxer_port_ffmpeg.c +++ b/src/port_ffmpeg/mediademuxer_port_ffmpeg.c @@ -43,7 +43,7 @@ static media_port_demuxer_ops def_demux_ops = { .get_data = ffmpeg_demuxer_get_data, }; -int ffmpeg_port_register(media_port_demuxer_ops *pOps) +int ffmpeg_mediademxer_port_register(media_port_demuxer_ops *pOps) { int ret = MD_ERROR_NONE; MEDIADEMUXER_FENTER(); diff --git a/src/port_gst/mediademuxer_port_gst.c b/src/port_gst/mediademuxer_port_gst.c index 2214f2d..9205e35 100755 --- a/src/port_gst/mediademuxer_port_gst.c +++ b/src/port_gst/mediademuxer_port_gst.c @@ -66,7 +66,7 @@ static media_port_demuxer_ops def_demux_ops = { .set_eos_cb = gst_set_eos_cb, }; -int gst_port_register(media_port_demuxer_ops *pOps) +int gst_mediademxer_port_register(media_port_demuxer_ops *pOps) { MEDIADEMUXER_FENTER(); int ret = MD_ERROR_NONE; -- 2.7.4