From 2b5ff1e1ee365b801a1e5baa44ba825f6893a556 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Mon, 4 Sep 2017 18:13:53 +0900 Subject: [PATCH 01/16] Removed TM1 kernel dependency Change-Id: Ie02972ac83881534744efd2e51e811348d5709f6 --- include/media_codec_port_gst.h | 9 ----- packaging/capi-media-codec.spec | 90 +---------------------------------------- src/media_codec_port_gst.c | 69 ------------------------------- 3 files changed, 2 insertions(+), 166 deletions(-) mode change 100644 => 100755 packaging/capi-media-codec.spec diff --git a/include/media_codec_port_gst.h b/include/media_codec_port_gst.h index 626f9ad..4373b7b 100644 --- a/include/media_codec_port_gst.h +++ b/include/media_codec_port_gst.h @@ -71,15 +71,6 @@ typedef enum { BUF_SHARE_METHOD_FLUSH_BUFFER } buf_share_method_t; -#ifdef TIZEN_PROFILE_LITE -struct _ion_mmu_data_t { - gint master_id; - gint fd_buffer; - unsigned long iova_addr; - size_t iova_size; -}; -#endif - struct _mc_gst_port_t { mc_gst_core_t *core; guint num_buffers; diff --git a/packaging/capi-media-codec.spec b/packaging/capi-media-codec.spec old mode 100644 new mode 100755 index ff08340..d1871f2 --- a/packaging/capi-media-codec.spec +++ b/packaging/capi-media-codec.spec @@ -29,21 +29,7 @@ BuildRequires: pkgconfig(iniparser) %description A Media Codec library in Tizen Native API -%ifarch %{arm} -# This is for backward-compatibility. This does not deteriorate 4.0 Configurability -# if mobile || "undefined" -%if "%{?profile}" != "wearable" && "%{?profile}" != "tv" && "%{?profile}" != "ivi" && "%{?profile}" != "common" -%package extension-TM1 -Summary: Extension for mobile TM1 -Requires: %{name} = %{version}-%{release} -#!BuildIgnore: kernel-headers -BuildConflicts: linux-glibc-devel -BuildRequires: kernel-headers-3.10-sc7730 - -%description extension-TM1 -A Media Codec library in Tizen Native API Extension for mobile TM1 -%endif -%endif + %package devel @@ -59,40 +45,8 @@ Requires: %{name} = %{version}-%{release} %build -%if 0%{?sec_build_binary_debug_enable} -export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE" -export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE" -export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE" -%endif -%ifarch %{arm} -export CFLAGS="$CFLAGS -DENABLE_FFMPEG_CODEC" -%endif export CFLAGS="$CFLAGS -DSYSCONFDIR=\\\"%{_sysconfdir}\\\"" -export CFLAGS_DEFAULT="$CFLAGS" - -%ifarch %{arm} -# This is for backward-compatibility. This does not deteriorate 4.0 Configurability -# if mobile || "undefined" -%if "%{?profile}" != "wearable" && "%{?profile}" != "tv" && "%{?profile}" != "ivi" && "%{?profile}" != "common" -# extension-TM1 -export CFLAGS="$CFLAGS_DEFAULT -DTIZEN_PROFILE_LITE" - -MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` -%cmake . -DCMAKE_INSTALL_PREFIX=/usr -DFULLVER=%{version} -DMAJORVER=${MAJORVER} - -make %{?jobs:-j%jobs} - -mkdir -p tm1 - -%make_install -ls -al %{buildroot}%{_libdir}/libcapi-media-codec.so.* -cp -a %{buildroot}%{_libdir}/libcapi-media-codec.so.* tm1/ - -%endif -%endif -# common -export CFLAGS="$CFLAGS_DEFAULT" MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` %cmake . -DCMAKE_INSTALL_PREFIX=/usr -DFULLVER=%{version} -DMAJORVER=${MAJORVER} @@ -106,44 +60,6 @@ cp test/media_codec_test %{buildroot}/usr/bin %make_install - -%ifarch %{arm} -# This is for backward-compatibility. This does not deteriorate 4.0 Configurability -# if mobile || "undefined" -%if "%{?profile}" != "wearable" && "%{?profile}" != "tv" && "%{?profile}" != "ivi" && "%{?profile}" != "common" -# extension-TM1 -pushd tm1 -for FILE in libcapi-media-codec.so.*; do mv "$FILE" "%{buildroot}%{_libdir}/$FILE.tm1"; done -popd - -%post extension-TM1 -pushd %{_libdir} -for FILE in libcapi-media-codec.so.*.tm1; do mv "$FILE" "${FILE%.tm1}"; done -popd -/sbin/ldconfig - -%preun extension-TM1 -case "$1" in - 0) - # This is an un-installation. - pushd %{_libdir} - for FILE in libcapi-media-codec.so.*; do mv "$FILE" "${FILE%.tm1}"; done - popd - /sbin/ldconfig - ;; - 1) - # This is an upgrade. - # Do nothing. - : - ;; -esac - -%files extension-TM1 -%manifest capi-media-codec.manifest -%{_libdir}/libcapi-media-codec.so.*.tm1 -%endif -%endif - %post /sbin/ldconfig @@ -153,9 +69,7 @@ esac %files %manifest capi-media-codec.manifest %{_libdir}/libcapi-media-codec.so.* -%ifarch %{arm} -%exclude %{_libdir}/libcapi-media-codec.so.*.tm1 -%endif + %license LICENSE.APLv2 /usr/bin/* #%{_bindir}/* diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index c639c02..27663cf 100644 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -28,12 +28,6 @@ #include #include -#ifdef TIZEN_PROFILE_LITE -#include -#include -#include -#endif - /* * Internal Implementation */ @@ -75,9 +69,6 @@ static const gchar * _mc_bit_to_string(int bit); static int _mc_get_support_bit_from_format(media_format_mimetype_e format); static int _mc_link_vtable(mc_gst_core_t *core, mediacodec_codec_type_e id, gboolean is_encoder, gboolean is_hw); -#ifdef TIZEN_PROFILE_LITE -static int __tbm_get_physical_addr_bo(tbm_bo_handle tbm_bo_handle_fd_t, int *phy_addr, int *phy_size); -#endif static int _mc_gst_flush_buffers(mc_gst_core_t *core); static void _mc_gst_set_flush_input(mc_gst_core_t *core); static void _mc_gst_set_flush_output(mc_gst_core_t *core); @@ -1558,9 +1549,7 @@ static int _mc_link_vtable(mc_gst_core_t *core, mediacodec_codec_type_e id, gboo if (encoder) { core->vtable = is_hw ? venc_h264_hw_vtable : venc_vtable; core->caps = gst_caps_new_empty_simple("video/x-raw"); -#ifdef TIZEN_PROFILE_LITE g_object_set(GST_OBJECT(core->codec), "byte-stream", TRUE, NULL); -#endif } else { if (is_hw) { core->vtable = vdec_h264_hw_vtable; @@ -2617,21 +2606,6 @@ static MMVideoBuffer *__mc_gst_make_tbm_buffer(mc_gst_core_t *core, media_packet tbm_bo_unmap(mm_vbuffer->handle.bo[i]); } -#ifdef TIZEN_PROFILE_LITE - gint phy_addr = 0; - gint phy_size = 0; - tbm_bo_handle handle_fd = tbm_bo_get_handle(mm_vbuffer->handle.bo[0], TBM_DEVICE_MM); - if (handle_fd.ptr == NULL) { - LOGE("Invaild bo handle"); - return NULL; - } - - if (__tbm_get_physical_addr_bo(handle_fd, &phy_addr, &phy_size) == 0) { - mm_vbuffer->handle.paddr[0] = (void *)phy_addr; - LOGD("mm_vbuffer->paddr : %p", mm_vbuffer->handle.paddr[0]); - } -#endif - mm_vbuffer->type = MM_VIDEO_BUFFER_TYPE_TBM_BO; mm_vbuffer->width[0] = surface_info.width; mm_vbuffer->height[0] = surface_info.height; @@ -2952,49 +2926,6 @@ static void _mc_gst_set_flush_output(mc_gst_core_t *core) MEDIACODEC_FLEAVE(); } -#ifdef TIZEN_PROFILE_LITE -gint __tbm_get_physical_addr_bo(tbm_bo_handle handle_bo, int *phy_addr, int *phy_size) -{ - gint ret = 0; - gint open_flags = O_RDWR; - gint ion_fd = -1; - - ion_mmu_data_t mmu_data; - struct ion_custom_data custom_data; - - memset(&mmu_data, 0x0, sizeof(ion_mmu_data_t)); - - mmu_data.fd_buffer = handle_bo.u32; - custom_data.cmd = 4; - custom_data.arg = (unsigned long)&mmu_data; - - ion_fd = open("/dev/ion", open_flags); - if (ion_fd < 0) - LOGE("[tbm_get_physical_addr_bo] ion_fd open device failed"); - - if (ioctl(ion_fd, ION_IOC_CUSTOM, &custom_data) < 0) { - LOGE("[tbm_get_physical_addr_bo] ION_IOC_CUSTOM failed"); - ret = -1; - } - - if (!ret) { - *phy_addr = mmu_data.iova_addr; - *phy_size = mmu_data.iova_size; - } else { - *phy_addr = 0; - *phy_size = 0; - LOGW("[tbm_get_physical_addr_bo] getting physical address is failed. phy_addr = 0"); - } - - if (ion_fd != -1) { - close(ion_fd); - ion_fd = -1; - } - - return 0; -} -#endif - #if TIZEN_EXYNOS_SPECIFIC /* * Get tiled address of position(x,y) -- 2.7.4 From 8965728c33f40275cc605a0bf4f866a155541eed Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Tue, 12 Sep 2017 20:11:30 +0900 Subject: [PATCH 02/16] Applying and modifying the tizen coding rule Change-Id: I9c6d51fb0ae8a62184111a2424df8b977288b031 --- include/media_codec_util.h | 2 +- packaging/capi-media-codec.spec | 2 +- src/media_codec_port.c | 3 +-- src/media_codec_port_gst.c | 12 ++++-------- 4 files changed, 7 insertions(+), 12 deletions(-) diff --git a/include/media_codec_util.h b/include/media_codec_util.h index 5dde410..4808b86 100644 --- a/include/media_codec_util.h +++ b/include/media_codec_util.h @@ -60,7 +60,7 @@ void mc_hex_dump(char *desc, void *addr, int len); if (x) \ g_free(x); \ x = NULL; \ - } while(0) + } while (0) #ifdef __cplusplus } diff --git a/packaging/capi-media-codec.spec b/packaging/capi-media-codec.spec index d1871f2..99af600 100755 --- a/packaging/capi-media-codec.spec +++ b/packaging/capi-media-codec.spec @@ -5,7 +5,7 @@ Name: capi-media-codec Summary: A Media Codec library in Tizen Native API Version: 0.5.7 -Release: 0 +Release: 2 Group: Multimedia/API License: Apache-2.0 Source0: %{name}-%{version}.tar.gz diff --git a/src/media_codec_port.c b/src/media_codec_port.c index 4edb261..238c492 100644 --- a/src/media_codec_port.c +++ b/src/media_codec_port.c @@ -810,9 +810,8 @@ int _mediacodec_foreach_supported_codec(mediacodec_supported_codec_cb callback, for (i = 0; i < CODEC_NR_ITEMS; i++) { if (codec[i]) { index = simple_to_codec_type_enumeration(i); - if (!callback(index, user_data)) { + if (!callback(index, user_data)) goto CALLBACK_ERROR; - } } } diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index 27663cf..50a24b6 100644 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -1150,9 +1150,8 @@ static int _mc_gst_update_caps(mc_gst_core_t *core, GstMCBuffer *mcbuffer, bool NULL); ret = __mc_set_caps_codecdata(core, mcbuffer, CODECDATA_NOT_USE); - if (ret != MC_ERROR_NONE) { + if (ret != MC_ERROR_NONE) LOGW("__mc_set_caps_codecdata failed"); - } } } else { if (core->encoder) { @@ -1178,25 +1177,22 @@ static int _mc_gst_update_caps(mc_gst_core_t *core, GstMCBuffer *mcbuffer, bool case MEDIACODEC_AAC_HE: case MEDIACODEC_AAC_HE_PS: ret = __mc_set_caps_codecdata(core, mcbuffer, AAC_CODECDATA_SIZE); - if (ret != MC_ERROR_NONE) { + if (ret != MC_ERROR_NONE) LOGW("__mc_set_caps_codecdata failed"); - } break; case MEDIACODEC_WMAV1: case MEDIACODEC_WMAV2: case MEDIACODEC_WMAPRO: case MEDIACODEC_WMALSL: ret = __mc_set_caps_codecdata(core, mcbuffer, WMA_CODECDATA_SIZE); - if (ret != MC_ERROR_NONE) { + if (ret != MC_ERROR_NONE) LOGW("__mc_set_caps_codecdata failed"); - } break; case MEDIACODEC_VORBIS: case MEDIACODEC_FLAC: ret = __mc_set_caps_streamheader(core, mcbuffer, VORBIS_CODECDATA_SIZE); - if (ret != MC_ERROR_NONE) { + if (ret != MC_ERROR_NONE) LOGW("__mc_set_caps_streamheader failed"); - } break; default: LOGD("doesn't need to set codecdata"); -- 2.7.4 From 6af61a679a22604928b8f3758823a3b4637e717f Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Wed, 27 Sep 2017 15:46:50 +0900 Subject: [PATCH 03/16] removed dependency of appcore-efl Change-Id: I5cf0903944e587f3108b76ee43e4eaba92c7e405 --- CMakeLists.txt | 2 +- packaging/capi-media-codec.spec | 1 - src/media_codec_ini.c | 2 +- test/CMakeLists.txt | 3 +-- test/media_codec_test.c | 36 +++--------------------------------- 5 files changed, 6 insertions(+), 38 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b80b61c..52b72df 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ SET(PREFIX ${CMAKE_INSTALL_PREFIX}) SET(INC_DIR include) INCLUDE_DIRECTORIES(${INC_DIR}) -SET(dependents "dlog glib-2.0 mm-common libtbm capi-media-tool gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 capi-system-info" ) +SET(dependents "dlog glib-2.0 mm-common libtbm capi-media-tool iniparser gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 capi-system-info" ) SET(pc_dependents "capi-base-common capi-media-tool gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0" ) INCLUDE(FindPkgConfig) diff --git a/packaging/capi-media-codec.spec b/packaging/capi-media-codec.spec index 99af600..5437140 100755 --- a/packaging/capi-media-codec.spec +++ b/packaging/capi-media-codec.spec @@ -14,7 +14,6 @@ BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(mm-common) BuildRequires: pkgconfig(capi-base-common) -BuildRequires: pkgconfig(appcore-efl) BuildRequires: pkgconfig(capi-media-tool) BuildRequires: pkgconfig(libtbm) BuildRequires: pkgconfig(gstreamer-1.0) diff --git a/src/media_codec_ini.c b/src/media_codec_ini.c index 676ae83..b9d4d14 100644 --- a/src/media_codec_ini.c +++ b/src/media_codec_ini.c @@ -23,7 +23,7 @@ #include #include #include -#include "iniparser.h" +#include #include #include diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index de10cdc..5d65e75 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -6,8 +6,7 @@ INCLUDE_DIRECTORIES(../include/headers) link_directories(${CMAKE_SOURCE_DIR}/../) INCLUDE(FindPkgConfig) -pkg_check_modules(${fw_test} REQUIRED appcore-efl elementary) -#pkg_check_modules(${fw_test} REQUIRED appcore-efl elementary capi-media-camera capi-mediademuxer capi-mediamuxer) +#pkg_check_modules(${fw_test} REQUIRED capi-media-camera capi-mediademuxer capi-mediamuxer) FOREACH(flag ${${fw_test}_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") ENDFOREACH(flag) diff --git a/test/media_codec_test.c b/test/media_codec_test.c index 64491d5..a542c46 100644 --- a/test/media_codec_test.c +++ b/test/media_codec_test.c @@ -17,8 +17,6 @@ #include #include #include -#include -#include #include #include @@ -184,10 +182,7 @@ struct _App { /* Render */ guint w; guint h; - Evas_Object *win; - Evas_Object *img; media_packet_h packet; - Ecore_Pipe *pipe; GList *packet_list; GMutex lock; @@ -203,8 +198,6 @@ media_format_h fmt = NULL; media_packet_pool_h pkt_pool = NULL; /* Internal Functions */ -gint _create_app(void *data); -gint _terminate_app(void *data); void displaymenu(void); void display_sub_basic(); @@ -223,30 +216,6 @@ void (*extractor)(App *app, guint8** data, gint *size, gboolean *have_frame, gbo gint g_menu_state = CURRENT_STATUS_MAINMENU; -gint _create_app(void *data) -{ - g_print("My app is going alive!\n"); - App *app = (App*)data; - - g_mutex_init(&app->lock); - return 0; -} - -gint _terminate_app(void *data) -{ - g_print("My app is going gone!\n"); - App *app = (App*)data; - - g_mutex_clear(&app->lock); - return 0; -} - - -struct appcore_ops ops = { - .create = _create_app, - .terminate = _terminate_app, -}; - static const guint mp3types_bitrates[2][3][16] = { { {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,}, @@ -1941,6 +1910,7 @@ void input_filepath(char *filename, App *app) void quit_program(App *app) { + g_mutex_clear(&app->lock); media_format_unref(fmt); g_main_loop_quit(app->loop); exit(0); @@ -2579,12 +2549,12 @@ int main(int argc, char *argv[]) App *app = &s_app; + g_mutex_init(&app->lock); displaymenu(); app->loop = g_main_loop_new(NULL, TRUE); app->timer = g_timer_new(); g_main_loop_run(app->loop); - ops.data = app; - return appcore_efl_main(PACKAGE, &argc, &argv, &ops); + return 0; } -- 2.7.4 From aa2db44687c535e8402d3998b5eb5ab6de82c1bd Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Thu, 12 Oct 2017 10:54:49 +0900 Subject: [PATCH 04/16] fixed coverity issues Change-Id: Id8fbe562674bf38057cee10d50870516b4be7b05 --- include/media_codec_bitstream.h | 2 +- include/media_codec_port.h | 4 ++-- include/media_codec_private.h | 1 + src/media_codec_bitstream.c | 24 ++++++++++-------------- src/media_codec_port.c | 12 ++++++------ src/media_codec_port_gst.c | 19 ++++++++++++++++--- test/media_codec_test.c | 17 ++--------------- 7 files changed, 38 insertions(+), 41 deletions(-) diff --git a/include/media_codec_bitstream.h b/include/media_codec_bitstream.h index 2898146..416c9b3 100644 --- a/include/media_codec_bitstream.h +++ b/include/media_codec_bitstream.h @@ -18,7 +18,7 @@ #define __TIZEN_MEDIA_CODEC_BITSTREAM_H__ #include -#include +#include typedef struct _mc_bitstream_t mc_bitstream_t; diff --git a/include/media_codec_port.h b/include/media_codec_port.h index f704059..f1c3fca 100644 --- a/include/media_codec_port.h +++ b/include/media_codec_port.h @@ -288,8 +288,8 @@ void _mc_create_codec_map_from_ini_static(mc_ini_t *ini, mc_codec_spec_t *spec_e void _mc_create_decoder_map_from_ini(mc_handle_t *mc_handle); void _mc_create_encoder_map_from_ini(mc_handle_t *mc_handle); -const int simple_to_codec_type_enumeration(codec_type_e codec_id); -const int codec_type_to_simple_enumeration(mediacodec_codec_type_e media_codec_id); +const codec_type_e simple_to_codec_type_enumeration(codec_type_e codec_id); +const codec_type_e codec_type_to_simple_enumeration(mediacodec_codec_type_e media_codec_id); #ifdef __cplusplus } diff --git a/include/media_codec_private.h b/include/media_codec_private.h index dc5d663..6f50a49 100644 --- a/include/media_codec_private.h +++ b/include/media_codec_private.h @@ -19,6 +19,7 @@ #include #include +#include #include diff --git a/src/media_codec_bitstream.c b/src/media_codec_bitstream.c index 373da79..da6d3b7 100644 --- a/src/media_codec_bitstream.c +++ b/src/media_codec_bitstream.c @@ -162,7 +162,7 @@ unsigned int __mc_bytestream_to_nal(unsigned char *data, int size) int __mc_decode_sps(mc_bitstream_t *pstream, int *width, int *height) { - int ret = MC_ERROR_NONE; + int ret = 0; unsigned int tmp = 0; int profile_idc = 0; @@ -177,7 +177,7 @@ int __mc_decode_sps(mc_bitstream_t *pstream, int *width, int *height) profile_idc = tmp; if (profile_idc > 51) - ret = MC_INVALID_IN_BUF; + ret = -1; /*TODO parse width, height, etc...*/ @@ -220,7 +220,7 @@ int _mc_check_h264_bytestream(unsigned char *nal, int byte_length, bool port, bo switch (syntax & 0x1F) { case NAL_SEQUENCE_PARAMETER_SET: LOGD("nal_unit_type : SPS"); - if ((ret = __mc_decode_sps(&pstream, NULL, NULL)) != MC_ERROR_NONE) + if ((ret = __mc_decode_sps(&pstream, NULL, NULL)) != -1) return ret; state |= MC_EXIST_SPS; codec_length += nal_length; @@ -264,7 +264,7 @@ int _mc_check_h264_bytestream(unsigned char *nal, int byte_length, bool port, bo /* input port */ if (!port && !CHECK_VALID_PACKET(state, MC_VALID_FIRST_SLICE)) - return MC_INVALID_IN_BUF; + return -1; /* output port */ if (port) { @@ -289,9 +289,9 @@ int _mc_check_valid_h263_frame(unsigned char *p, int size) } while (count == 1 && p < end); if (count != 1) - return MC_INVALID_IN_BUF; /* frame boundary violated */ + return -1; /* frame boundary violated */ - return MC_ERROR_NONE; + return 0; } bool _mc_is_voss(unsigned char *buf, int size, int *codec_size) @@ -352,8 +352,6 @@ bool _mc_is_vop(unsigned char *p, int size, int pos) int _mc_check_mpeg4_out_bytestream(unsigned char *buf, int buf_length, bool* need_codec_data, bool *need_sync_flag) { int codec_data_size = 0; - g_return_val_if_fail(need_codec_data != NULL, MC_PARAM_ERROR); - g_return_val_if_fail(need_sync_flag != NULL, MC_PARAM_ERROR); *need_codec_data = FALSE; *need_sync_flag = FALSE; @@ -368,8 +366,6 @@ int _mc_check_mpeg4_out_bytestream(unsigned char *buf, int buf_length, bool* nee bool _mc_check_h263_out_bytestream(unsigned char *p, int buf_length, bool* need_sync_flag) { - g_return_val_if_fail(need_sync_flag != NULL, MC_PARAM_ERROR); - *need_sync_flag = FALSE; /* PSC not present */ @@ -402,7 +398,7 @@ int _mc_get_h264_codecdata_size(guint8 *data, int size) data_size = _mc_check_h264_bytestream(data, size, 0, NULL, NULL, NULL); if (data_size <= 0) { LOGE("No valid SPS/PPS ..."); - return MC_INVALID_IN_BUF; + return -1; } return data_size; } else { @@ -417,12 +413,12 @@ int _mc_get_h264_codecdata_size(guint8 *data, int size) /* parse the avcC data */ if (size < 7) { /* when numSPS==0 and numPPS==0, length is 7 bytes */ LOGE("If contains codec_data, size should over 7 bytes ..."); - return MC_INVALID_IN_BUF; + return -1; } /* parse the version, this must be 1 */ if (data[0] != 1) { LOGE("If contains codec_data, first byte must be 1 ..."); - return MC_INVALID_IN_BUF; + return -1; } num_sps = data[5] & 0x1f; @@ -451,7 +447,7 @@ int _mc_get_h264_codecdata_size(guint8 *data, int size) return offset; } - return MC_INVALID_IN_BUF; + return -1; } } diff --git a/src/media_codec_port.c b/src/media_codec_port.c index 238c492..3584dd5 100644 --- a/src/media_codec_port.c +++ b/src/media_codec_port.c @@ -79,7 +79,7 @@ int mc_create(MMHandleType *mediacodec) return ret; ERROR: - + g_free(new_mediacodec); return MC_INVALID_ARG; } @@ -798,18 +798,18 @@ int _mediacodec_foreach_supported_codec(mediacodec_supported_codec_cb callback, { int ret = MEDIACODEC_NONE; int i; - int index = 0; + int index; gboolean codec[CODEC_NR_ITEMS] = {0,}; for (i = 0; i < mc_ini.num_supported_codecs; i++) { - index = codec_type_to_simple_enumeration(spec_emul[i].codec_id); + index = (int)codec_type_to_simple_enumeration(spec_emul[i].codec_id); codec[index] = TRUE; } for (i = 0; i < CODEC_NR_ITEMS; i++) { if (codec[i]) { - index = simple_to_codec_type_enumeration(i); + index = (int)simple_to_codec_type_enumeration(i); if (!callback(index, user_data)) goto CALLBACK_ERROR; } @@ -988,7 +988,7 @@ void _mc_create_codec_map_from_ini_static(mc_ini_t *ini, mc_codec_spec_t *spec_e return; } -const int codec_type_to_simple_enumeration(mediacodec_codec_type_e media_codec_id) +const codec_type_e codec_type_to_simple_enumeration(mediacodec_codec_type_e media_codec_id) { guint media_codec_id_u = (guint)media_codec_id; @@ -1052,7 +1052,7 @@ const int codec_type_to_simple_enumeration(mediacodec_codec_type_e media_codec_i } } -const int simple_to_codec_type_enumeration(codec_type_e codec_id) +const codec_type_e simple_to_codec_type_enumeration(codec_type_e codec_id) { guint codec_id_u = (guint)codec_id; diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index 50a24b6..5bf33cf 100644 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -14,7 +14,6 @@ * limitations under the License. * */ -#include #include #include #include @@ -516,6 +515,7 @@ int __mc_fill_packet_with_output_buffer(mc_gst_core_t *core, void *data, int siz ret = media_packet_create_from_external_memory(core->output_fmt, ext_mem, mem_size, __mc_output_buffer_finalize_cb, mcbuffer, &packet); if (ret != MEDIA_PACKET_ERROR_NONE) { LOGW("media_packet_create_alloc failed"); + g_free(ext_mem); return MC_ERROR; } mcbuffer->packet = packet; @@ -536,6 +536,7 @@ int __mc_fill_venc_packet_with_output_buffer(mc_gst_core_t *core, void *data, in bool slice = FALSE; gint mem_size = 0; gchar *ext_mem = NULL; + gint data_size = 0; void *packet_data = NULL; media_packet_h packet = NULL; @@ -545,7 +546,12 @@ int __mc_fill_venc_packet_with_output_buffer(mc_gst_core_t *core, void *data, in case MEDIA_FORMAT_H264_SP: case MEDIA_FORMAT_H264_MP: case MEDIA_FORMAT_H264_HP: - ret = _mc_check_h264_bytestream((unsigned char *)data, size, 1, &codec_config, &sync_flag, &slice); + data_size = _mc_check_h264_bytestream((unsigned char *)data, size, 1, &codec_config, &sync_flag, &slice); + + if (data_size <= 0) { + LOGE("No valid SPS/PPS ..."); + return MC_INVALID_IN_BUF; + } break; case MEDIA_FORMAT_MPEG4_SP: case MEDIA_FORMAT_MPEG4_ASP: @@ -567,6 +573,7 @@ int __mc_fill_venc_packet_with_output_buffer(mc_gst_core_t *core, void *data, in ret = media_packet_create_from_external_memory(core->output_fmt, ext_mem, mem_size, __mc_output_buffer_finalize_cb, mcbuffer, &packet); if (ret != MEDIA_PACKET_ERROR_NONE) { LOGW("media_packet_create_alloc failed"); + g_free(ext_mem); return MC_ERROR; } mcbuffer->packet = packet; @@ -607,6 +614,7 @@ int __mc_fill_aenc_packet_with_output_buffer(mc_gst_core_t *core, void *data, in ret = media_packet_create_from_external_memory(core->output_fmt, ext_mem, mem_size, __mc_output_buffer_finalize_cb, mcbuffer, &packet); if (ret != MEDIA_PACKET_ERROR_NONE) { LOGW("media_packet_create_alloc failed"); + g_free(ext_mem); return MC_ERROR; } mcbuffer->packet = packet; @@ -641,7 +649,12 @@ int __mc_fill_aenc_packet_with_output_buffer(mc_gst_core_t *core, void *data, in gst_buffer_map(core->codec_data, &map, GST_MAP_READ); ptr = map.data; len = map.size; - media_packet_set_codec_data(packet, ptr, len); + ret = media_packet_set_codec_data(packet, ptr, len); + if (ret != MEDIA_PACKET_ERROR_NONE) { + LOGW("media_packet_set_codec_data failed"); + gst_buffer_unmap(core->codec_data, &map); + return MC_ERROR; + } gst_buffer_unmap(core->codec_data, &map); } diff --git a/test/media_codec_test.c b/test/media_codec_test.c index a542c46..5b592f5 100644 --- a/test/media_codec_test.c +++ b/test/media_codec_test.c @@ -832,8 +832,6 @@ void _mediacodec_process_input(App *app) media_packet_h pkt = NULL; guint8 *tmp; gint read; - gint size; - gint offset; gint stride_width; gboolean codec_config = FALSE; @@ -869,7 +867,6 @@ void _mediacodec_process_input(App *app) /* Y */ media_packet_get_video_plane_data_ptr(pkt, 0, (void **)&buf_data_ptr); media_packet_get_video_stride_width(pkt, 0, &stride_width); - offset = app->width*app->height; for (j = 0; j < app->height; j++) { memcpy(buf_data_ptr, tmp, app->width); @@ -880,7 +877,6 @@ void _mediacodec_process_input(App *app) if (app->hardware == TRUE) { media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&buf_data_ptr); media_packet_get_video_stride_width(pkt, 1, &stride_width); - size = app->width * app->height / 2; for (j = 0; j < app->height / 2; j++) { memcpy(buf_data_ptr, tmp, app->width); @@ -891,7 +887,6 @@ void _mediacodec_process_input(App *app) /* U */ media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&buf_data_ptr); media_packet_get_video_stride_width(pkt, 1, &stride_width); - size = (app->width>>1) * (app->height>>1); for (j = 0; j < app->height/2; j++) { memcpy(buf_data_ptr, tmp, app->width/2); @@ -902,7 +897,6 @@ void _mediacodec_process_input(App *app) /* V */ media_packet_get_video_plane_data_ptr(pkt, 2, (void **)&buf_data_ptr); media_packet_get_video_stride_width(pkt, 2, &stride_width); - offset += size; for (j = 0; j < app->height/2; j++) { memcpy(buf_data_ptr, tmp, app->width/2); @@ -935,8 +929,6 @@ gboolean read_data(App *app) guint8 *tmp; gint i; gint read; - gint size; - gint offset; gint stride_width; if (app->offset == 0) { @@ -990,7 +982,6 @@ gboolean read_data(App *app) /* Y */ media_packet_get_video_plane_data_ptr(pkt, 0, (void **)&buf_data_ptr); media_packet_get_video_stride_width(pkt, 0, &stride_width); - offset = app->width*app->height; for (i = 0; i < app->height; i++) { memcpy(buf_data_ptr, tmp, app->width); @@ -1001,7 +992,6 @@ gboolean read_data(App *app) if (app->hardware == TRUE) { media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&buf_data_ptr); media_packet_get_video_stride_width(pkt, 1, &stride_width); - size = app->width * app->height>>1; for (i = 0; i < app->height>>1; i++) { memcpy(buf_data_ptr, tmp, app->width); @@ -1013,7 +1003,6 @@ gboolean read_data(App *app) /* U */ media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&buf_data_ptr); media_packet_get_video_stride_width(pkt, 1, &stride_width); - size = (app->width>>1) * (app->height>>1); for (i = 0; i < app->height/2; i++) { memcpy(buf_data_ptr, tmp, app->width>>1); @@ -1024,7 +1013,6 @@ gboolean read_data(App *app) /* V */ media_packet_get_video_plane_data_ptr(pkt, 2, (void **)&buf_data_ptr); media_packet_get_video_stride_width(pkt, 2, &stride_width); - offset += size; for (i = 0; i < app->height/2; i++) { memcpy(buf_data_ptr, tmp, app->width>>1); @@ -2359,7 +2347,7 @@ void decoder_output_dump(App *app, media_packet_h pkt) guint8 *temp; int i = 0; int stride_width, stride_height; - gchar filename[100] = {0}; + gchar filename[256] = {0, }; FILE *fp = NULL; int ret = 0; @@ -2445,7 +2433,7 @@ void output_dump(App *app, media_packet_h pkt) { void *temp; uint64_t buf_size; - gchar filename[100] = {0}; + gchar filename[256] = {0, }; FILE *fp = NULL; int ret = 0; char adts[100] = {0, }; @@ -2537,7 +2525,6 @@ const char* codec_type_to_string(mediacodec_codec_type_e media_codec_id) default: return "NONE"; } - return "NONE"; } int main(int argc, char *argv[]) -- 2.7.4 From e89ab99f6380d1419c2fca0443556b436b92a8ab Mon Sep 17 00:00:00 2001 From: Vadym Sachenko Date: Fri, 17 Nov 2017 15:29:03 +0200 Subject: [PATCH 05/16] mm-resource-manager integration patch Change-Id: I411252643810ee1e07977d384aadf6b227548cea Signed-off-by: Vadym Sachenko --- CMakeLists.txt | 4 +- include/media_codec_private.h | 2 + packaging/capi-media-codec.spec | 3 +- src/media_codec.c | 126 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 132 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 52b72df..dc41164 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,8 +10,8 @@ SET(PREFIX ${CMAKE_INSTALL_PREFIX}) SET(INC_DIR include) INCLUDE_DIRECTORIES(${INC_DIR}) -SET(dependents "dlog glib-2.0 mm-common libtbm capi-media-tool iniparser gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 capi-system-info" ) -SET(pc_dependents "capi-base-common capi-media-tool gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0" ) +SET(dependents "dlog glib-2.0 mm-common libtbm capi-media-tool iniparser gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 capi-system-info mm-resource-manager" ) +SET(pc_dependents "capi-base-common capi-media-tool gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 mm-resource-manager" ) INCLUDE(FindPkgConfig) pkg_check_modules(${fw_name} REQUIRED ${dependents}) diff --git a/include/media_codec_private.h b/include/media_codec_private.h index 6f50a49..c574563 100644 --- a/include/media_codec_private.h +++ b/include/media_codec_private.h @@ -24,6 +24,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { @@ -101,6 +102,7 @@ typedef struct _mediacodec_s { int state; bool is_omx; char *m_mime; + mm_resource_manager_res_h codec_resource; mediacodec_input_buffer_used_cb empty_buffer_cb; void* empty_buffer_cb_userdata; diff --git a/packaging/capi-media-codec.spec b/packaging/capi-media-codec.spec index 5437140..9f9ee77 100755 --- a/packaging/capi-media-codec.spec +++ b/packaging/capi-media-codec.spec @@ -4,7 +4,7 @@ Name: capi-media-codec Summary: A Media Codec library in Tizen Native API -Version: 0.5.7 +Version: 0.5.8 Release: 2 Group: Multimedia/API License: Apache-2.0 @@ -21,6 +21,7 @@ BuildRequires: pkgconfig(gstreamer-plugins-base-1.0) BuildRequires: pkgconfig(gstreamer-app-1.0) BuildRequires: pkgconfig(capi-system-info) BuildRequires: pkgconfig(iniparser) +BuildRequires: pkgconfig(mm-resource-manager) #BuildRequires: pkgconfig(capi-media-camera) #BuildRequires: pkgconfig(capi-mediademuxer) #BuildRequires: pkgconfig(capi-mediamuxer) diff --git a/src/media_codec.c b/src/media_codec.c index 2d8c848..88784ba 100644 --- a/src/media_codec.c +++ b/src/media_codec.c @@ -24,12 +24,22 @@ #include +#define MC_PREALLOCATED_HANDLE_ARRAY_SIZE 16 + +static mm_resource_manager_h resource_manager; +static GPtrArray *mediacodec_handles; +static GMutex mediacodec_handles_lock; + static gboolean __mediacodec_empty_buffer_cb(media_packet_h pkt, void *user_data); static gboolean __mediacodec_fill_buffer_cb(media_packet_h pkt, void *user_data); static gboolean __mediacodec_error_cb(mediacodec_error_e error, void *user_data); static gboolean __mediacodec_eos_cb(void *user_data); static gboolean __mediacodec_supported_codec_cb(mediacodec_codec_type_e codec_type, void *user_data); static gboolean __mediacodec_buffer_status_cb(mediacodec_status_e status, void *user_data); +static void __mediacodec_init_lib() __attribute__((constructor)); +static void __mediacodec_deinit_lib() __attribute__((destructor)); +static int __mediacodec_resource_release_cb(mm_resource_manager_h rm, + mm_resource_manager_res_h resource_h, void *user_data); /* * Internal Implementation @@ -121,6 +131,9 @@ int mediacodec_create(mediacodec_h *mediacodec) LOGD("mediacodec_create.."); + if (resource_manager == NULL) + return MEDIACODEC_ERROR_INTERNAL; + handle = (mediacodec_s *)malloc(sizeof(mediacodec_s)); if (handle != NULL) { memset(handle, 0 , sizeof(mediacodec_s)); @@ -151,6 +164,10 @@ int mediacodec_create(mediacodec_h *mediacodec) mc_set_buffer_status_cb(handle->mc_handle, (mediacodec_buffer_status_cb)__mediacodec_buffer_status_cb, handle); mc_set_supported_codec_cb(handle->mc_handle, (mediacodec_supported_codec_cb)__mediacodec_supported_codec_cb, handle); + g_mutex_lock(&mediacodec_handles_lock); + g_ptr_array_insert(mediacodec_handles, -1, *mediacodec); + g_mutex_unlock(&mediacodec_handles_lock); + return MEDIACODEC_ERROR_NONE; } @@ -166,6 +183,10 @@ int mediacodec_destroy(mediacodec_h mediacodec) LOGD("MEDIACODEC_ERROR_INVALID_OPERATION(0x%08x)", MEDIACODEC_ERROR_INVALID_OPERATION); return MEDIACODEC_ERROR_INVALID_OPERATION; } else { + g_mutex_lock(&mediacodec_handles_lock); + g_ptr_array_remove_fast(mediacodec_handles, mediacodec); + g_mutex_unlock(&mediacodec_handles_lock); + handle->state = MEDIACODEC_STATE_NONE; free(handle); handle = NULL; @@ -273,8 +294,61 @@ int mediacodec_prepare(mediacodec_h mediacodec) { MEDIACODEC_INSTANCE_CHECK(mediacodec); mediacodec_s *handle = (mediacodec_s *)mediacodec; + mc_handle_t *mc_handle = (mc_handle_t *) handle->mc_handle; + int rm_ret = MM_RESOURCE_MANAGER_ERROR_NONE; + mm_resource_manager_res_h resource; MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE); + if (mc_handle->is_hw && mc_handle->is_video) { + + if (handle->codec_resource) { + LOGE("Codec resource is tried to be acquired twice\n"); + return MC_INTERNAL_ERROR; + } + + /* + * TODO + * Currently volume of requested resource is set to 1. Default + * capacity for video encoder/decoder is 1 too. The actual capacity + * should be set in mmfw-sysconf > mmfw_resource_manager.ini. + * If different encode/decode operation needs different volume of + * video encoder/decoder, '1' in the following + * mm_resource_manager_mark_for_acquire function should be set to + * corresponding value. + * If that value depends on platform where it's executed, + * MM_RESOURCE_MANAGER_RES_TYPE_COND_* and + * mm_resource_manager_get_res_type_volume() can be used. + * Additional info can be found in doxygen comments of mm_resource_manager.h + */ + rm_ret = mm_resource_manager_mark_for_acquire(resource_manager, + mc_handle->is_encoder ? + MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_ENCODER : + MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_DECODER, + 1, &resource); + if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) + switch (rm_ret) { + case MM_RESOURCE_MANAGER_ERROR_NOT_SUPPORTED: + return MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE; + case MM_RESOURCE_MANAGER_ERROR_NOT_ENOUGH: + return MEDIACODEC_ERROR_RESOURCE_OVERLOADED; + default: + return MEDIACODEC_ERROR_INTERNAL; + } + + rm_ret = mm_resource_manager_commit(resource_manager); + if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) { + mm_resource_manager_mark_for_release(resource_manager, resource); + switch (rm_ret) { + case MM_RESOURCE_MANAGER_ERROR_LOW_PRIORITY: + return MEDIACODEC_ERROR_RESOURCE_OVERLOADED; + default: + return MEDIACODEC_ERROR_INTERNAL; + } + } + + handle->codec_resource = resource; + } + int ret = mc_prepare(handle->mc_handle); if (ret != MEDIACODEC_ERROR_NONE) { @@ -295,6 +369,15 @@ int mediacodec_unprepare(mediacodec_h mediacodec) if (ret != MEDIACODEC_ERROR_NONE) { return __convert_error_code(ret, (char *)__FUNCTION__); } else { + if (handle->codec_resource != NULL) { + mm_resource_manager_mark_for_release(resource_manager, + handle->codec_resource); + handle->codec_resource = NULL; + mm_resource_manager_commit(resource_manager); + } else { + LOGD("No codec resource to release. Probably resource release cb called\n"); + } + handle->state = MEDIACODEC_STATE_IDLE; return MEDIACODEC_ERROR_NONE; } @@ -597,3 +680,46 @@ static gboolean __mediacodec_buffer_status_cb(mediacodec_status_e status, void * return 1; } + + +static int __mediacodec_resource_release_cb(mm_resource_manager_h rm, + mm_resource_manager_res_h resource_h, void *user_data) +{ + int i; + mediacodec_s *handle; + + g_mutex_lock(&mediacodec_handles_lock); + for (i = 0; i < mediacodec_handles->len; i++) { + handle = g_ptr_array_index(mediacodec_handles, i); + if (handle->codec_resource == resource_h) { + /* + * TODO + * The resource release cb is asynchronous, so mediacodec_unprepare might be + * called in this thread and in the main thread at the same time. + * Mutex lock/unlock should be added in the body of mediacodec_unprepare() to + * avoid the race condition. + */ + handle->codec_resource = NULL; + mediacodec_unprepare((mediacodec_h)handle); + __mediacodec_error_cb(MEDIACODEC_ERROR_RESOURCE_OVERLOADED, handle); + break; + } + } + g_mutex_unlock(&mediacodec_handles_lock); + + return FALSE; +} + +static void __mediacodec_init_lib() +{ + mediacodec_handles = g_ptr_array_sized_new(MC_PREALLOCATED_HANDLE_ARRAY_SIZE); + mm_resource_manager_create(MM_RESOURCE_MANAGER_APP_CLASS_MEDIA, + __mediacodec_resource_release_cb, NULL, &resource_manager); +} + +static void __mediacodec_deinit_lib() +{ + if (resource_manager != NULL) + mm_resource_manager_destroy(resource_manager); + g_ptr_array_unref(mediacodec_handles); +} -- 2.7.4 From 357ee30a38b2f2fe67fc76832c62e31ffa12bcd1 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Wed, 7 Mar 2018 13:16:18 +0900 Subject: [PATCH 06/16] fixed typo Change-Id: Ic7e83fed94caf9334278c48b018aface598bf27d --- doc/media_codec_doc.h | 2 +- include/media_codec.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/media_codec_doc.h b/doc/media_codec_doc.h index 03bed18..5899e57 100644 --- a/doc/media_codec_doc.h +++ b/doc/media_codec_doc.h @@ -25,7 +25,7 @@ /** * @defgroup CAPI_MEDIA_CODEC_MODULE Media Codec - * @brief The @ref CAPI_MEDIA_CODEC_MODULE APIs provides functions for encodinging and decoding using media data + * @brief The @ref CAPI_MEDIA_CODEC_MODULE APIs provides functions for encoding and decoding using media data * @ingroup CAPI_MEDIA_FRAMEWORK * * @section CAPI_MEDIA_CODEC_MODULE_HEADER Required Header diff --git a/include/media_codec.h b/include/media_codec.h index 8e6aa3c..5899592 100644 --- a/include/media_codec.h +++ b/include/media_codec.h @@ -601,7 +601,7 @@ int mediacodec_get_supported_type(mediacodec_h mediacodec, mediacodec_codec_type /** * @brief Gets the media packet pool allocated for recycling media packets. * @details The user can get the pool allocated with the number of packets are required to be used in codecs.\n - * It is recomended to use media packet pool for better stability and performance. + * It is recommended to use media packet pool for better stability and performance. * @since_tizen 3.0 * @remarks The @a pool should be released using media_packet_pool_deallocate() and destroyed using media_packet_pool_destroy(). * @param[in] mediacodec The mediacodec handle -- 2.7.4 From 851569d522d4b4f4159f8888da5296569a8ed149 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Thu, 15 Mar 2018 15:07:08 +0900 Subject: [PATCH 07/16] fixed coverity issues Change-Id: I564f3d25eaa051c5792e7f9afb7fd61683950523 --- src/media_codec.c | 20 +++++++++++++++++--- src/media_codec_port_gst.c | 12 ++++++++++-- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/media_codec.c b/src/media_codec.c index 88784ba..445b069 100644 --- a/src/media_codec.c +++ b/src/media_codec.c @@ -363,6 +363,7 @@ int mediacodec_unprepare(mediacodec_h mediacodec) { MEDIACODEC_INSTANCE_CHECK(mediacodec); mediacodec_s *handle = (mediacodec_s *)mediacodec; + int rm_ret = MM_RESOURCE_MANAGER_ERROR_NONE; int ret = mc_unprepare(handle->mc_handle); @@ -373,7 +374,16 @@ int mediacodec_unprepare(mediacodec_h mediacodec) mm_resource_manager_mark_for_release(resource_manager, handle->codec_resource); handle->codec_resource = NULL; - mm_resource_manager_commit(resource_manager); + rm_ret = mm_resource_manager_commit(resource_manager); + if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) { + mm_resource_manager_mark_for_release(resource_manager, resource); + switch (rm_ret) { + case MM_RESOURCE_MANAGER_ERROR_LOW_PRIORITY: + return MEDIACODEC_ERROR_RESOURCE_OVERLOADED; + default: + return MEDIACODEC_ERROR_INTERNAL; + } + } } else { LOGD("No codec resource to release. Probably resource release cb called\n"); } @@ -713,8 +723,12 @@ static int __mediacodec_resource_release_cb(mm_resource_manager_h rm, static void __mediacodec_init_lib() { mediacodec_handles = g_ptr_array_sized_new(MC_PREALLOCATED_HANDLE_ARRAY_SIZE); - mm_resource_manager_create(MM_RESOURCE_MANAGER_APP_CLASS_MEDIA, - __mediacodec_resource_release_cb, NULL, &resource_manager); + + if (MM_RESOURCE_MANAGER_ERROR_NONE != mm_resource_manager_create(MM_RESOURCE_MANAGER_APP_CLASS_MEDIA, + __mediacodec_resource_release_cb, NULL, &resource_manager)) { + LOGE("Failed to initialize resource manager"); + g_ptr_array_unref(mediacodec_handles); + } } static void __mediacodec_deinit_lib() diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index 5bf33cf..c787b0c 100644 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -2582,6 +2582,8 @@ static MMVideoBuffer *__mc_gst_make_tbm_buffer(mc_gst_core_t *core, media_packet { gint i; gint num_bos; + gint err; + int ret = MEDIA_PACKET_ERROR_NONE; tbm_surface_h surface = NULL; tbm_surface_info_s surface_info; tbm_bo_handle handle_bo; @@ -2599,9 +2601,15 @@ static MMVideoBuffer *__mc_gst_make_tbm_buffer(mc_gst_core_t *core, media_packet } memset(mm_vbuffer, 0x00, sizeof(MMVideoBuffer)); - media_packet_get_tbm_surface(packet, &surface); + ret = media_packet_get_tbm_surface(packet, &surface); + if (ret != MEDIA_PACKET_ERROR_NONE) { + LOGE("Failed to get tbm surface"); + free(mm_vbuffer); + return NULL; + } + num_bos = tbm_surface_internal_get_num_bos(surface); - gint err = tbm_surface_get_info((tbm_surface_h)surface, &surface_info); + err = tbm_surface_get_info((tbm_surface_h)surface, &surface_info); if (err != TBM_SURFACE_ERROR_NONE) { LOGE("get tbm surface is failed"); free(mm_vbuffer); -- 2.7.4 From b980cabf5130a8b89202680861c82e3f87d9b9f7 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Thu, 15 Mar 2018 17:39:32 +0900 Subject: [PATCH 08/16] fixed building error Change-Id: Ic4e66099736465a86d6e8e50dab78ad67172af4a --- src/media_codec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/media_codec.c b/src/media_codec.c index 445b069..526c1b3 100644 --- a/src/media_codec.c +++ b/src/media_codec.c @@ -376,7 +376,7 @@ int mediacodec_unprepare(mediacodec_h mediacodec) handle->codec_resource = NULL; rm_ret = mm_resource_manager_commit(resource_manager); if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) { - mm_resource_manager_mark_for_release(resource_manager, resource); + mm_resource_manager_mark_for_release(resource_manager, handle->codec_resource); switch (rm_ret) { case MM_RESOURCE_MANAGER_ERROR_LOW_PRIORITY: return MEDIACODEC_ERROR_RESOURCE_OVERLOADED; -- 2.7.4 From 12969757c2d1c63c3fce7a663402841cfe6d1092 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Mon, 26 Mar 2018 14:39:08 +0900 Subject: [PATCH 09/16] fixed svace issues Change-Id: I8c76d1e63d51b7c5a14edd737b06be4b23668e8e --- src/media_codec_port_gst.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index c787b0c..771e632 100644 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -1669,7 +1669,8 @@ mc_ret_e mc_gst_prepare(mc_handle_t *mc_handle) LOGD("factory name : %s, output_fmt : %x", factory_name, out_mime); /* create media_packet for output fmt */ - if ((ret = _mc_output_media_packet_new(new_core, video, encoder, out_mime)) != MC_ERROR_NONE) { + ret = _mc_output_media_packet_new(new_core, video, encoder, out_mime); + if (ret != MC_ERROR_NONE) { LOGE("Failed to create output pakcet"); return ret; } @@ -1686,13 +1687,15 @@ mc_ret_e mc_gst_prepare(mc_handle_t *mc_handle) mc_handle->core = new_core; /* create basic core elements */ - if ((ret = _mc_gst_create_pipeline(mc_handle->core, factory_name) != MC_ERROR_NONE)) { + ret = _mc_gst_create_pipeline(mc_handle->core, factory_name); + if (ret != MC_ERROR_NONE) { LOGE("failed to create pipeline"); return ret; } /* link vtable */ - if ((ret = _mc_link_vtable(mc_handle->core, id, encoder, hardware)) != MC_ERROR_NONE) { + ret = _mc_link_vtable(mc_handle->core, id, encoder, hardware); + if (ret != MC_ERROR_NONE) { LOGE("vtable link failed"); return ret; } -- 2.7.4 From 673705926faaf5a3abd1aefc7f47d890220a50ff Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Fri, 23 Mar 2018 10:05:12 +0900 Subject: [PATCH 10/16] Add audioresample for supporting various samplerates Change-Id: Ic41c21a21cf5ea621b047917ac5b2045712d1a4c --- include/media_codec_port.h | 55 +-- include/media_codec_port_gst.h | 29 +- src/media_codec_port.c | 52 +-- src/media_codec_port_gst.c | 740 +++++++++++++++++++++++------------------ test/media_codec_test.c | 156 ++++----- 5 files changed, 546 insertions(+), 486 deletions(-) mode change 100644 => 100755 include/media_codec_port_gst.h diff --git a/include/media_codec_port.h b/include/media_codec_port.h index f1c3fca..f2a732c 100644 --- a/include/media_codec_port.h +++ b/include/media_codec_port.h @@ -163,41 +163,21 @@ typedef enum _mc_codec_port_type_e { CODEC_PORT_TYPE_MAX, } mc_codec_port_type_e; -typedef enum _mc_vendor_e { - MC_VENDOR_DEFAULT, - MC_VENDOR_SLSI_SEC, - MC_VENDOR_SLSI_EXYNOS, - MC_VENDOR_QCT, - MC_VENDOR_SPRD -} mc_vendor_e; - -struct _mc_decoder_info_t { - int width; - int height; - int actwidth; - int actheight; - - int samplerate; - int channel; - int bit; -}; - -struct _mc_encoder_info_t { - int width; - int height; - int bitrate; - int format; - int fps; - int qp_min; - int qp_max; - int vbvbuffer_size; - int level; - int profile; - - int samplerate; - int channel; - int bit; -}; +typedef struct mc_audio_port_definition_t { + gint samplerate; + gint channel; + gint bit_depth; + gint bitrate; +} mc_audio_port_definition_t; + +typedef struct mc_video_port_definition_t { + gchar *format; + gint width; + gint height; + gint stride; + gint bitrate; + gint framerate; +} mc_video_port_definition_t; /* Codec Private data */ struct _mc_handle_t { @@ -209,14 +189,13 @@ struct _mc_handle_t { mediacodec_port_type_e port_type; mediacodec_codec_type_e codec_id; - mc_vendor_e vendor; void *ports[2]; void *core; union { - mc_decoder_info_t decoder; - mc_encoder_info_t encoder; + mc_audio_port_definition_t audio; + mc_video_port_definition_t video; } info; /* for process done cb */ diff --git a/include/media_codec_port_gst.h b/include/media_codec_port_gst.h old mode 100644 new mode 100755 index 4373b7b..4d9198f --- a/include/media_codec_port_gst.h +++ b/include/media_codec_port_gst.h @@ -59,17 +59,26 @@ extern "C" { #define THRESHOLD_QNUM 5 /* gst port layer */ +typedef struct _mc_gst_port_def_t mc_gst_port_def_t; typedef struct _mc_gst_port_t mc_gst_port_t; typedef struct _mc_gst_core_t mc_gst_core_t; typedef struct _GstMCBuffer GstMCBuffer; -typedef struct _ion_mmu_data_t ion_mmu_data_t; + typedef enum { - BUF_SHARE_METHOD_PADDR = 0, - BUF_SHARE_METHOD_FD, - BUF_SHARE_METHOD_TIZEN_BUFFER, - BUF_SHARE_METHOD_FLUSH_BUFFER -} buf_share_method_t; + in_port_index = 0, + out_port_index +} port_index_e; + + +struct _mc_gst_port_def_t { + gchar *mime_type; + media_format_mimetype_e coding_type; + union { + mc_audio_port_definition_t audio; + mc_video_port_definition_t video; + } info; +}; struct _mc_gst_port_t { mc_gst_core_t *core; @@ -77,19 +86,21 @@ struct _mc_gst_port_t { guint buffer_size; guint index; gboolean is_allocated; - media_packet_h *buffers; GQueue *queue; GMutex mutex; GCond buffer_cond; + mc_gst_port_def_t port_def; }; struct _mc_gst_core_t { gint(**vtable)(); const gchar *mime; - gchar *format; GstElement *pipeline; GstElement *appsrc; GstElement *audioconvert; + GstElement *audioresample; + GstElement *videoscale; + GstElement *videoconvert; GstElement *capsfilter; GstElement *parser; GstElement *fakesink; @@ -137,8 +148,8 @@ struct _mc_gst_core_t { mc_aqueue_t *available_queue; GQueue *output_queue; - void *codec_info; GstBuffer *codec_data; + GstCaps* (*mc_caps_new)(mc_gst_core_t *, mediacodec_codec_type_e, gint); void* user_cb[_MEDIACODEC_EVENT_TYPE_NUM]; void* user_data[_MEDIACODEC_EVENT_TYPE_NUM]; diff --git a/src/media_codec_port.c b/src/media_codec_port.c index 3584dd5..cf6843a 100644 --- a/src/media_codec_port.c +++ b/src/media_codec_port.c @@ -174,8 +174,8 @@ int mc_set_vdec_info(MMHandleType mediacodec, int width, int height) MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && mc_handle->is_video && !mc_handle->is_encoder, MC_INVALID_ARG, "MEDIACODEC_ERROR_INVALID_PARAMETER"); - mc_handle->info.decoder.width = width; - mc_handle->info.decoder.height = height; + mc_handle->info.video.width = width; + mc_handle->info.video.height = height; mc_handle->is_prepared = true; @@ -198,10 +198,10 @@ int mc_set_venc_info(MMHandleType mediacodec, int width, int height, int fps, in MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && mc_handle->is_video && mc_handle->is_encoder, MC_INVALID_ARG, "MEDIACODEC_ERROR_INVALID_PARAMETER"); - mc_handle->info.encoder.width = width; - mc_handle->info.encoder.height = height; - mc_handle->info.encoder.fps = fps; - mc_handle->info.encoder.bitrate = target_bits * 1000; + mc_handle->info.video.width = width; + mc_handle->info.video.height = height; + mc_handle->info.video.framerate = fps; + mc_handle->info.video.bitrate = target_bits * 1000; mc_handle->is_prepared = true; return ret; @@ -223,9 +223,9 @@ int mc_set_adec_info(MMHandleType mediacodec, int samplerate, int channel, int b MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && !mc_handle->is_video && !mc_handle->is_encoder, MC_INVALID_ARG, "MEDIACODEC_ERROR_INVALID_PARAMETER"); - mc_handle->info.decoder.samplerate = samplerate; - mc_handle->info.decoder.channel = channel; - mc_handle->info.decoder.bit = bit; + mc_handle->info.audio.samplerate = samplerate; + mc_handle->info.audio.channel = channel; + mc_handle->info.audio.bit_depth = bit; mc_handle->is_prepared = true; return ret; @@ -247,10 +247,10 @@ int mc_set_aenc_info(MMHandleType mediacodec, int samplerate, int channel, int b MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && !mc_handle->is_video && mc_handle->is_encoder, MC_INVALID_ARG, "MEDIACODEC_ERROR_INVALID_PARAMETER"); - mc_handle->info.encoder.samplerate = samplerate; - mc_handle->info.encoder.channel = channel; - mc_handle->info.encoder.bit = bit; - mc_handle->info.encoder.bitrate = bitrate * 1000; + mc_handle->info.audio.samplerate = samplerate; + mc_handle->info.audio.channel = channel; + mc_handle->info.audio.bit_depth = bit; + mc_handle->info.audio.bitrate = bitrate * 1000; mc_handle->is_prepared = true; @@ -294,19 +294,19 @@ int mc_configure(MMHandleType mediacodec, media_format_h format, int flags) return MC_PARAM_ERROR; } - mc_handle->info.encoder.samplerate = samplerate; - mc_handle->info.encoder.channel = channel; - mc_handle->info.encoder.bit = bit; - mc_handle->info.encoder.bitrate = bitrate * 1000; + mc_handle->info.audio.samplerate = samplerate; + mc_handle->info.audio.channel = channel; + mc_handle->info.audio.bit_depth = bit; + mc_handle->info.audio.bitrate = bitrate * 1000; } else if (GET_IS_DECODER(flags)) { if ((samplerate <= 0) || (channel <= 0) || (bit <= 0)) { LOGE("invalid pram is set : samplerate : %d, channel : %d, bit : %d", samplerate, channel, bit); return MC_PARAM_ERROR; } - mc_handle->info.decoder.samplerate = samplerate; - mc_handle->info.decoder.channel = channel; - mc_handle->info.decoder.bit = bit; + mc_handle->info.audio.samplerate = samplerate; + mc_handle->info.audio.channel = channel; + mc_handle->info.audio.bit_depth = bit; } else { LOGE("either an encoder or a decoder must be set"); return MC_PARAM_ERROR; @@ -322,10 +322,10 @@ int mc_configure(MMHandleType mediacodec, media_format_h format, int flags) return MC_PARAM_ERROR; } - mc_handle->info.encoder.width = width; - mc_handle->info.encoder.height = height; - mc_handle->info.encoder.fps = fps; - mc_handle->info.encoder.bitrate = bitrate * 1000; + mc_handle->info.video.width = width; + mc_handle->info.video.height = height; + mc_handle->info.video.framerate = fps; + mc_handle->info.video.bitrate = bitrate * 1000; } else if (GET_IS_DECODER(flags)) { if ((width <= 0) || (height <= 0)) { LOGE("invalid pram is set : width : %d, height : %d", @@ -333,8 +333,8 @@ int mc_configure(MMHandleType mediacodec, media_format_h format, int flags) return MC_PARAM_ERROR; } - mc_handle->info.decoder.width = width; - mc_handle->info.decoder.height = height; + mc_handle->info.video.width = width; + mc_handle->info.video.height = height; } else { LOGE("either an encoder or a decoder must be set"); return MC_PARAM_ERROR; diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index 771e632..6d32a7b 100644 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -41,11 +41,10 @@ static mc_ret_e _mc_gst_create_pipeline(mc_gst_core_t *core, gchar *factory_name static mc_ret_e _mc_gst_destroy_pipeline(mc_gst_core_t *core); static void __mc_gst_buffer_add(GstElement *element, GstBuffer *buffer, GstPad *pad, gpointer data); static int __mc_output_buffer_finalize_cb(media_packet_h packet, int error_code, void *user_data); -static int _mc_gst_update_caps(mc_gst_core_t *core, GstMCBuffer *mcbuffer, bool codec_config); -static gboolean _mc_update_packet_info(mc_gst_core_t *core, media_format_h fmt); +static gboolean _mc_update_packet_info(mc_gst_core_t *core, media_format_h format); static GstMCBuffer *_mc_gst_media_packet_to_gstbuffer(mc_gst_core_t *core, media_packet_h packet, bool codec_config); static int _mc_gst_gstbuffer_to_appsrc(mc_gst_core_t *core, GstMCBuffer *mcbuffer); -static gchar *__mc_get_gst_input_format(media_packet_h packet, bool is_hw); +static gchar *__mc_get_gst_input_format(media_format_mimetype_e mimetype, bool is_hw); static GstMCBuffer *__mc_gst_make_media_packet(mc_gst_core_t *core, GstBuffer *buffer); static gboolean __mc_gst_bus_callback(GstBus *bus, GstMessage *msg, gpointer data); static GstBusSyncReply __mc_gst_bus_sync_callback(GstBus *bus, GstMessage *msg, gpointer data); @@ -82,6 +81,9 @@ static void __csc_tiled_to_linear_crop(unsigned char *yuv420_dest, static void _mc_send_eos_signal(mc_gst_core_t *core); static void _mc_wait_for_eos(mc_gst_core_t *core); static int _mc_get_mime(mc_gst_core_t *core); +static int _mc_set_codec_data(mc_gst_core_t *core, GstMCBuffer *mcbuffer); +GstCaps *_mc_gst_vid_caps_new(mc_gst_core_t *core, mediacodec_codec_type_e codec_id, gint index); +GstCaps *_mc_gst_aud_caps_new(mc_gst_core_t *core, mediacodec_codec_type_e codec_id, gint index); /* video vtable */ int(*vdec_vtable[])() = {&__mc_fill_input_buffer_with_packet, &__mc_fill_packet_with_output_buffer}; @@ -287,10 +289,10 @@ int __mc_fill_input_buffer_with_venc_packet(mc_gst_core_t *core, media_packet_h uint32_t plane_num; guint8 *planes[2]; - mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info; + mc_gst_port_def_t *port_def = &core->ports[in_port_index]->port_def; - width = enc_info->width; - height = enc_info->height; + width = port_def->info.video.width; + height = port_def->info.video.height; ret = media_packet_get_number_of_video_planes(packet, &plane_num); if (ret != MEDIA_PACKET_ERROR_NONE) { @@ -402,11 +404,11 @@ int __mc_fill_vdec_packet_with_output_buffer(mc_gst_core_t *core, void *data, in g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); - mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; + mc_gst_port_def_t *port_def = &core->ports[out_port_index]->port_def; if (!core->is_hw) { - width = dec_info->width; - height = dec_info->height; + width = port_def->info.video.width; + height = port_def->info.video.height; stride_width = GST_ROUND_UP_4(width); stride_height = height; buf_size = stride_width * stride_height * 3 / 2; @@ -419,8 +421,8 @@ int __mc_fill_vdec_packet_with_output_buffer(mc_gst_core_t *core, void *data, in return MC_ERROR; } - tsurf_info.width = dec_info->width; - tsurf_info.height = dec_info->height; + tsurf_info.width = port_def->info.video.width; + tsurf_info.height = port_def->info.video.height; tsurf_info.format = TBM_FORMAT_YVU420; tsurf_info.bpp = tbm_surface_internal_get_bpp(TBM_FORMAT_YVU420); tsurf_info.num_planes = tbm_surface_internal_get_num_planes(TBM_FORMAT_YVU420); @@ -463,8 +465,8 @@ int __mc_fill_vdec_packet_with_output_buffer(mc_gst_core_t *core, void *data, in } if (bo_num > 0) { - tsurf_info.width = dec_info->width; - tsurf_info.height = dec_info->height; + tsurf_info.width = port_def->info.video.width; + tsurf_info.height = port_def->info.video.height; tsurf_info.format = TBM_FORMAT_NV12; /* bo_format */ tsurf_info.bpp = tbm_surface_internal_get_bpp(TBM_FORMAT_NV12); tsurf_info.num_planes = tbm_surface_internal_get_num_planes(TBM_FORMAT_NV12); @@ -542,13 +544,13 @@ int __mc_fill_venc_packet_with_output_buffer(mc_gst_core_t *core, void *data, in g_return_val_if_fail(core != NULL, MC_PARAM_ERROR); - switch (core->out_mime) { + switch (core->ports[out_port_index]->port_def.coding_type) { case MEDIA_FORMAT_H264_SP: case MEDIA_FORMAT_H264_MP: case MEDIA_FORMAT_H264_HP: data_size = _mc_check_h264_bytestream((unsigned char *)data, size, 1, &codec_config, &sync_flag, &slice); - if (data_size <= 0) { + if (data_size < 0) { LOGE("No valid SPS/PPS ..."); return MC_INVALID_IN_BUF; } @@ -904,41 +906,36 @@ int _mc_output_media_packet_new(mc_gst_core_t *core, bool video, bool encoder, m LOGE("media format create failed"); return MC_ERROR; } + mc_gst_port_def_t *port_def = &core->ports[out_port_index]->port_def; if (encoder) { - mc_encoder_info_t *info; - - info = (mc_encoder_info_t *)core->codec_info; if (video) { media_format_set_video_mime(core->output_fmt, out_mime); - media_format_set_video_width(core->output_fmt, info->width); - media_format_set_video_height(core->output_fmt, info->height); - media_format_set_video_avg_bps(core->output_fmt, info->bitrate); + media_format_set_video_width(core->output_fmt, port_def->info.video.width); + media_format_set_video_height(core->output_fmt, port_def->info.video.height); + media_format_set_video_avg_bps(core->output_fmt, port_def->info.video.bitrate); } else { int support_bit = 0; support_bit = _mc_get_support_bit_from_format(out_mime); media_format_set_audio_mime(core->output_fmt, out_mime); - media_format_set_audio_channel(core->output_fmt, info->channel); - media_format_set_audio_samplerate(core->output_fmt, info->samplerate); + media_format_set_audio_channel(core->output_fmt, port_def->info.audio.channel); + media_format_set_audio_samplerate(core->output_fmt, port_def->info.audio.samplerate); media_format_set_audio_bit(core->output_fmt, support_bit); - media_format_set_audio_avg_bps(core->output_fmt, info->bitrate); + media_format_set_audio_avg_bps(core->output_fmt, port_def->info.audio.bitrate); } } else { - mc_decoder_info_t *info; - - info = (mc_decoder_info_t *)core->codec_info; if (video) { media_format_set_video_mime(core->output_fmt, out_mime); - media_format_set_video_width(core->output_fmt, info->width); - media_format_set_video_height(core->output_fmt, info->height); + media_format_set_video_width(core->output_fmt, port_def->info.video.width); + media_format_set_video_height(core->output_fmt, port_def->info.video.height); } else { media_format_set_audio_mime(core->output_fmt, out_mime); - media_format_set_audio_channel(core->output_fmt, info->channel); - media_format_set_audio_samplerate(core->output_fmt, info->samplerate); - media_format_set_audio_bit(core->output_fmt, info->bit); + media_format_set_audio_channel(core->output_fmt, port_def->info.audio.channel); + media_format_set_audio_samplerate(core->output_fmt, port_def->info.audio.samplerate); + media_format_set_audio_bit(core->output_fmt, port_def->info.audio.bit_depth); } } return MC_ERROR_NONE; @@ -956,7 +953,8 @@ mc_gst_core_t *mc_gst_core_new() core = g_new0(mc_gst_core_t, 1); /* 0 : input, 1 : output */ - core->ports[0] = NULL; + core->ports[0] = mc_gst_port_new(core); + core->ports[0]->index = 0; core->ports[1] = mc_gst_port_new(core); core->ports[1]->index = 1; @@ -1018,6 +1016,11 @@ void mc_gst_core_free(mc_gst_core_t *core) if (core->codec_data) gst_buffer_unref(core->codec_data); + if (core->ports[0] != NULL) { + mc_gst_port_free(core->ports[0]); + core->ports[0] = NULL; + } + if (core->ports[1] != NULL) { mc_gst_port_free(core->ports[1]); core->ports[1] = NULL; @@ -1043,7 +1046,6 @@ mc_gst_port_t *mc_gst_port_new(mc_gst_core_t *core) port->num_buffers = -1; port->buffer_size = 0; port->is_allocated = 0; - port->buffers = NULL; g_mutex_init(&port->mutex); port->queue = g_queue_new(); @@ -1069,33 +1071,43 @@ void mc_gst_port_free(mc_gst_port_t *port) return; } -gboolean _mc_update_packet_info(mc_gst_core_t *core, media_format_h fmt) +gboolean _mc_update_packet_info(mc_gst_core_t *core, media_format_h format) { - gboolean is_updated = FALSE; + gboolean is_format_change = FALSE; - mc_decoder_info_t *codec_info = (mc_decoder_info_t *)core->codec_info; + mc_gst_port_def_t *input_port_def = &core->ports[in_port_index]->port_def; if (core->video) { gint width = 0; gint height = 0; gint bitrate = 0; + gint framerate = 0; + gchar *sformat = NULL; + media_format_mimetype_e mimetype = 0; - media_format_get_video_info(fmt, NULL, &width, &height, &bitrate, NULL); + media_format_get_video_info(format, &mimetype, &width, &height, &bitrate, NULL); + media_format_get_video_frame_rate(format, &framerate); - if ((codec_info->width != width) || (codec_info->height != height)) { - LOGD("Resolution changed : %dx%d -> %dx%d", codec_info->width, codec_info->height, width, height); - codec_info->width = width; - codec_info->height = height; - is_updated = TRUE; + is_format_change |= input_port_def->info.video.width != width; + is_format_change |= input_port_def->info.video.height != height; + is_format_change |= (input_port_def->info.video.framerate != framerate) && (framerate != 0); + if (is_format_change) { + LOGD("Format changed : resolution %dx%d -> %dx%d, framerate %d -> %d", + input_port_def->info.video.width, input_port_def->info.video.height, width, height, + input_port_def->info.video.framerate, framerate); + input_port_def->info.video.width = width; + input_port_def->info.video.height = height; } if (core->encoder) { - mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info; - - if (bitrate != 0 && enc_info->bitrate != bitrate * 1000) { - LOGD("Bitrate changed : %d -> %d", enc_info->bitrate, bitrate); - enc_info->bitrate = bitrate * 1000; - is_updated = TRUE; + sformat = __mc_get_gst_input_format(mimetype, core->is_hw); + is_format_change |= input_port_def->info.video.bitrate != bitrate * 1000; + is_format_change |= g_strcmp0(input_port_def->info.video.format, sformat); + if (is_format_change) { + LOGD("Bitrate changed : %d -> %d", input_port_def->info.video.bitrate, bitrate); + LOGD("Format changed : %s -> %s", input_port_def->info.video.format, sformat); + input_port_def->info.video.bitrate = bitrate * 1000; + input_port_def->info.video.format = g_strdup(sformat); } } } else { @@ -1104,31 +1116,34 @@ gboolean _mc_update_packet_info(mc_gst_core_t *core, media_format_h fmt) gint bit; gint bitrate; - media_format_get_audio_info(fmt, NULL, &channel, &samplerate, &bit, &bitrate); + media_format_get_audio_info(format, NULL, &channel, &samplerate, &bit, &bitrate); - if ((codec_info->channel != channel) || (codec_info->samplerate != samplerate) || (codec_info->bit != bit)) { - LOGD("Audio info. changed : %d -> %d, %d -> %d, %d -> %d", codec_info->channel, channel, codec_info->samplerate, samplerate, codec_info->bit, bit); - codec_info->channel = channel; - codec_info->samplerate = samplerate; - codec_info->bit = bit; - is_updated = TRUE; + is_format_change |= input_port_def->info.audio.channel != channel; + is_format_change |= input_port_def->info.audio.samplerate != samplerate; + is_format_change |= input_port_def->info.audio.bit_depth != bit; + if (is_format_change) { + LOGD("Audio info. changed : %d -> %d, %d -> %d, %d -> %d", + input_port_def->info.audio.channel, channel, + input_port_def->info.audio.samplerate, samplerate, + input_port_def->info.audio.bit_depth, bit); + input_port_def->info.audio.channel = channel; + input_port_def->info.audio.samplerate = samplerate; + input_port_def->info.audio.bit_depth = bit; } if (core->encoder) { - mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info; - - if (bitrate != 0 && enc_info->bitrate != bitrate * 1000) { - LOGD("Bitrate changed : %d -> %d", enc_info->bitrate, bitrate); - enc_info->bitrate = bitrate * 1000; - is_updated = TRUE; + is_format_change |= input_port_def->info.audio.bitrate != bitrate * 1000; + if (is_format_change) { + LOGD("Bitrate changed : %d -> %d", input_port_def->info.audio.bitrate, bitrate); + input_port_def->info.audio.bitrate = bitrate * 1000; } } } - return is_updated; + return is_format_change; } -static int _mc_gst_update_caps(mc_gst_core_t *core, GstMCBuffer *mcbuffer, bool codec_config) +static int _mc_set_codec_data(mc_gst_core_t *core, GstMCBuffer *mcbuffer) { MEDIACODEC_FENTER(); @@ -1137,88 +1152,43 @@ static int _mc_gst_update_caps(mc_gst_core_t *core, GstMCBuffer *mcbuffer, bool int ret = MC_ERROR_NONE; - if (core->video) { - if (core->encoder) { - mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info; - - core->format = __mc_get_gst_input_format(mcbuffer->packet, core->is_hw); - gst_caps_set_simple(core->caps, - "format", G_TYPE_STRING, core->format, - "width", G_TYPE_INT, enc_info->width, - "height", G_TYPE_INT, enc_info->height, - "framerate", GST_TYPE_FRACTION, enc_info->fps, 1, - NULL); - - if (g_object_class_find_property(G_OBJECT_GET_CLASS(core->codec), "bitrate")) - g_object_set(GST_OBJECT(core->codec), "bitrate", enc_info->bitrate, NULL); - else - g_object_set(GST_OBJECT(core->codec), "target-bitrate", enc_info->bitrate, NULL); - LOGD("set bitrate = %d.", enc_info->bitrate); - } else { - mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; - - gst_caps_set_simple(core->caps, - "width", G_TYPE_INT, dec_info->width, - "height", G_TYPE_INT, dec_info->height, - NULL); - - ret = __mc_set_caps_codecdata(core, mcbuffer, CODECDATA_NOT_USE); - if (ret != MC_ERROR_NONE) - LOGW("__mc_set_caps_codecdata failed"); - } - } else { - if (core->encoder) { - mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info; - - gst_caps_set_simple(core->caps, - "format", G_TYPE_STRING, _mc_bit_to_string(enc_info->bit), - "rate", G_TYPE_INT, enc_info->samplerate, - "channels", G_TYPE_INT, enc_info->channel, - NULL); - g_object_set(GST_OBJECT(core->codec), "bitrate", enc_info->bitrate, NULL); - } else { - mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; - - gst_caps_set_simple(core->caps, - "rate", G_TYPE_INT, dec_info->samplerate, - "channels", G_TYPE_INT, dec_info->channel, - NULL); - - if (codec_config) { - switch (core->codec_id) { - case MEDIACODEC_AAC: - case MEDIACODEC_AAC_HE: - case MEDIACODEC_AAC_HE_PS: - ret = __mc_set_caps_codecdata(core, mcbuffer, AAC_CODECDATA_SIZE); - if (ret != MC_ERROR_NONE) - LOGW("__mc_set_caps_codecdata failed"); - break; - case MEDIACODEC_WMAV1: - case MEDIACODEC_WMAV2: - case MEDIACODEC_WMAPRO: - case MEDIACODEC_WMALSL: - ret = __mc_set_caps_codecdata(core, mcbuffer, WMA_CODECDATA_SIZE); - if (ret != MC_ERROR_NONE) - LOGW("__mc_set_caps_codecdata failed"); - break; - case MEDIACODEC_VORBIS: - case MEDIACODEC_FLAC: - ret = __mc_set_caps_streamheader(core, mcbuffer, VORBIS_CODECDATA_SIZE); - if (ret != MC_ERROR_NONE) - LOGW("__mc_set_caps_streamheader failed"); - break; - default: - LOGD("doesn't need to set codecdata"); - break; - - } - } - } + switch (core->codec_id) { + case MEDIACODEC_AAC: + case MEDIACODEC_AAC_HE: + case MEDIACODEC_AAC_HE_PS: + ret = __mc_set_caps_codecdata(core, mcbuffer, AAC_CODECDATA_SIZE); + if (ret != MC_ERROR_NONE) + LOGW("__mc_set_caps_codecdata failed"); + break; + case MEDIACODEC_WMAV1: + case MEDIACODEC_WMAV2: + case MEDIACODEC_WMAPRO: + case MEDIACODEC_WMALSL: + ret = __mc_set_caps_codecdata(core, mcbuffer, WMA_CODECDATA_SIZE); + if (ret != MC_ERROR_NONE) + LOGW("__mc_set_caps_codecdata failed"); + break; + case MEDIACODEC_VORBIS: + case MEDIACODEC_FLAC: + ret = __mc_set_caps_streamheader(core, mcbuffer, VORBIS_CODECDATA_SIZE); + if (ret != MC_ERROR_NONE) + LOGW("__mc_set_caps_streamheader failed"); + break; + case MEDIACODEC_H264: + case MEDIACODEC_MPEG4: + ret = __mc_set_caps_codecdata(core, mcbuffer, CODECDATA_NOT_USE); + if (ret != MC_ERROR_NONE) + LOGW("__mc_set_caps_codecdata failed"); + break; + default: + LOGD("doesn't need to set codecdata"); + break; } - g_object_set(core->appsrc, "caps", core->caps, NULL); MEDIACODEC_FLEAVE(); return ret; + + } static gpointer feed_task(gpointer data) @@ -1227,8 +1197,9 @@ static gpointer feed_task(gpointer data) bool codec_config = FALSE; bool eos = FALSE; bool initiative = TRUE; - media_format_h fmt = NULL; - media_packet_h in_buf = NULL; + bool is_format_change = FALSE; + media_format_h format = NULL; + media_packet_h input_buffer = NULL; GstMCBuffer *mcbuffer = NULL; MEDIACODEC_FENTER(); @@ -1237,23 +1208,23 @@ static gpointer feed_task(gpointer data) while (g_atomic_int_get(&core->available_queue->running)) { LOGD("waiting for next input...."); - in_buf = _mc_get_input_buffer(core); - if (!in_buf) + input_buffer = _mc_get_input_buffer(core); + if (!input_buffer) goto LEAVE; - media_packet_get_format(in_buf, &fmt); - if (fmt) { - if (_mc_update_packet_info(core, fmt)) - initiative = TRUE; - media_format_unref(fmt); + media_packet_get_format(input_buffer, &format); + if (format) { + if (_mc_update_packet_info(core, format)) + is_format_change = TRUE; + media_format_unref(format); } - if (media_packet_is_codec_config(in_buf, &codec_config) != MEDIA_PACKET_ERROR_NONE) { + if (media_packet_is_codec_config(input_buffer, &codec_config) != MEDIA_PACKET_ERROR_NONE) { LOGE("media_packet_is_codec_config failed"); goto ERROR; } - if (media_packet_is_end_of_stream(in_buf, &eos) != MEDIA_PACKET_ERROR_NONE) { + if (media_packet_is_end_of_stream(input_buffer, &eos) != MEDIA_PACKET_ERROR_NONE) { LOGE("media_packet_is_end_of_stream failed"); goto ERROR; } @@ -1265,41 +1236,43 @@ static gpointer feed_task(gpointer data) LOGD("end of stream"); gst_app_src_end_of_stream(GST_APP_SRC(core->appsrc)); _mc_wait_for_eos(core); - initiative = true; + initiative = TRUE; - _mc_gst_handle_input_buffer_used(core, in_buf); + _mc_gst_handle_input_buffer_used(core, input_buffer); goto LEAVE; } - mcbuffer = _mc_gst_media_packet_to_gstbuffer(core, in_buf, codec_config); + mcbuffer = _mc_gst_media_packet_to_gstbuffer(core, input_buffer, codec_config); if (!mcbuffer) { LOGW("gstbuffer can't make"); goto ERROR; } - /* mcbuffer took the ownership of the in_buf, so set in_buf to NULL to aviod double unref */ - in_buf = NULL; + /* mcbuffer took the ownership of the input_buffer, so set input_buffer to NULL to aviod double unref */ + input_buffer = NULL; - if (codec_config) - initiative = TRUE; - - if (initiative) { + if (codec_config || initiative) { GstPad *pad; - - ret = _mc_gst_update_caps(core, mcbuffer, codec_config); + ret = _mc_set_codec_data(core, mcbuffer); if (ret != MC_ERROR_NONE) { - LOGE("failed to update caps"); - /* unref mcbuff->buffer will invoke the finalize() of GstMcBuffer */ + LOGE("failed to set codec data"); gst_buffer_unref(mcbuffer->buffer); goto ERROR; } - pad = gst_element_get_static_pad(core->appsrc, "src"); gst_pad_push_event(pad, gst_event_new_stream_start("start")); gst_object_unref(pad); + initiative = FALSE; + } + if (is_format_change) { + GstCaps *caps; + caps = core->mc_caps_new(core, core->codec_id, in_port_index); + g_object_set(core->appsrc, "caps", caps, NULL); + gst_caps_unref(caps); LOGD("caps updated"); } + /* inject buffer */ ret = _mc_gst_gstbuffer_to_appsrc(core, mcbuffer); if (ret != GST_FLOW_OK) { @@ -1307,12 +1280,10 @@ static gpointer feed_task(gpointer data) goto ERROR; } - initiative = false; - continue; ERROR: - if (in_buf) - _mc_gst_handle_input_buffer_used(core, in_buf); + if (input_buffer) + _mc_gst_handle_input_buffer_used(core, input_buffer); _mc_gst_set_flush_input(core); @@ -1323,13 +1294,13 @@ ERROR: continue; LEAVE: - /*LOGE("status : in_buf : %p, codec_config : %d, eos : %d, encoder : %d in feed_task", in_buf, codec_config, eos, core->encoder);*/ + /*LOGE("status : input_buffer : %p, codec_config : %d, eos : %d, encoder : %d in feed_task", input_buffer, codec_config, eos, core->encoder);*/ continue; } - LOGI("status : in_buf : %p, codec_config : %d, eos : %d, video : %d, encoder : %d in feed_task", - in_buf, codec_config, eos, core->video, core->encoder); + LOGI("status : input_buffer : %p, codec_config : %d, eos : %d, video : %d, encoder : %d in feed_task", + input_buffer, codec_config, eos, core->video, core->encoder); LOGD("feed task finished %p v(%d)e(%d)", core, core->video, core->encoder); MEDIACODEC_FLEAVE(); @@ -1360,6 +1331,210 @@ static void __mc_gst_start_feed(GstElement *pipeline, guint size, gpointer data) } } +GstCaps *_mc_gst_aud_caps_new(mc_gst_core_t *core, mediacodec_codec_type_e codec_id, gint index) +{ + GstCaps *caps = NULL; + mc_gst_port_def_t *port_def = &core->ports[index]->port_def; + + caps = gst_caps_new_simple(core->mime, + "rate", G_TYPE_INT, port_def->info.audio.samplerate, + "channels", G_TYPE_INT, port_def->info.audio.channel, NULL); + + switch (codec_id) { + case MEDIACODEC_AAC: + if (core->encoder) { + gst_caps_set_simple(caps, + "layout", G_TYPE_STRING, "interleaved", NULL); + g_object_set(GST_OBJECT(core->codec), "compliance", -2, NULL); + } else { + gst_caps_set_simple(caps, + "framed", G_TYPE_BOOLEAN, TRUE, + "mpegversion", G_TYPE_INT, 4, + "stream-format", G_TYPE_STRING, "adts", + NULL); + LOGD("CAPS for codec_id (MEDIACODEC_AAC_LC - normal ADTS)"); + } + break; + case MEDIACODEC_AAC_HE: + case MEDIACODEC_AAC_HE_PS: + if (core->encoder) { + LOGD("[MC_NOT_SUPPORTED] he-aac-v12 encoder is not supported yet!!!"); + return NULL; + } else { + gst_caps_set_simple(caps, + "mpegversion", G_TYPE_INT, 4, + "framed", G_TYPE_BOOLEAN, TRUE, + "stream-format", G_TYPE_STRING, "raw", + NULL); + LOGD("CAPS for codec_id (MEDIACODEC_AAC_HE)"); + } + break; + case MEDIACODEC_MP3: + if (core->encoder) { + LOGD("[MC_NOT_SUPPORTED] mp3 encoder is not supported yet!!!"); + return NULL; + } else { + gst_caps_set_simple(caps, + "framed", G_TYPE_BOOLEAN, TRUE, + "mpegversion", G_TYPE_INT, 1, /* To-Do : plz check */ + "mpegaudioversion", G_TYPE_INT, 1, /* To-Do : plz check */ + "layer", G_TYPE_INT, 3, /* To-Do : plz check */ + NULL); + LOGD("CAPS for codec_id (MEDIACODEC_MP3)"); + } + break; + case MEDIACODEC_AMR_NB: + if (core->encoder) { + gst_caps_set_simple(caps, + "format", G_TYPE_STRING, _mc_bit_to_string(port_def->info.audio.bit_depth), + "layout", G_TYPE_STRING, "interleaved", + NULL); + LOGD("CAPS for codec_id (MEDIACODEC_AMR_NB)"); + } else { + gst_caps_set_simple(caps, + "rate", G_TYPE_INT, 8000, + NULL); + } + break; + case MEDIACODEC_AMR_WB: + if (core->encoder) { + LOGD("[MC_NOT_SUPPORTED] amr-wb encoder is not supported yet!!!"); + return NULL; + } else { + gst_caps_set_simple(caps, + "rate", G_TYPE_INT, 16000, + NULL); + } + break; + case MEDIACODEC_VORBIS: + if (core->encoder) { + LOGD("[MC_NOT_SUPPORTED] vorbis encoder is not supported yet!!!"); + return NULL; + } else { + } + break; + case MEDIACODEC_FLAC: + if (core->encoder) { + LOGD("[MC_NOT_SUPPORTED] flac encoder is not supported yet!!!"); + return NULL; + } else { + gst_caps_set_simple(caps, + "framed", G_TYPE_BOOLEAN, TRUE, + /* FIXME - Insert More Info */ + NULL); + } + break; + case MEDIACODEC_WMAV1: + case MEDIACODEC_WMAV2: + case MEDIACODEC_WMAPRO: + case MEDIACODEC_WMALSL: + if (core->encoder) { + LOGD("[MC_NOT_SUPPORTED] wma encoder is not supported yet!!!"); + return NULL; + } else { + /* + * Need to extract from Stream Type Specific ... or + * Need to get Demuxer's Caps from Stream Type Specific + */ + guint16 format_tag = 0; + gint wma_version = 0; + gint block_align = 1024; /*FIXME : Need checking */ + gint bitrate = 128000; /*FIXME : Need checking */ + + LOGD(" ----- WMA Need Additional Caps -----------"); + if (core->codec_id == MEDIACODEC_WMAV1) { + format_tag = 352; /* 0x160 */ + wma_version = 1; + } else if (core->codec_id == MEDIACODEC_WMAV2) { + format_tag = 353; /* 0x161 */ + wma_version = 2; + } else if (core->codec_id == MEDIACODEC_WMAPRO) { + format_tag = 354; /* 0x162 */ + wma_version = 3; + } else if (core->codec_id == MEDIACODEC_WMALSL) { + format_tag = 355; /* 0x163 */ + wma_version = 3; + } else { + LOGE("Not support WMA format"); + } + + gst_caps_set_simple(caps, + "bitrate", G_TYPE_INT, bitrate, + "depth", G_TYPE_INT, port_def->info.audio.bit_depth, + /* FIXME - Need More Info */ + "wmaversion", G_TYPE_INT, wma_version, + "format_tag", G_TYPE_INT, format_tag, + "block_align", G_TYPE_INT, block_align, + NULL); + } + break; + default: + break; + } + return caps; +} + +GstCaps *_mc_gst_vid_caps_new(mc_gst_core_t *core, mediacodec_codec_type_e codec_id, gint index) +{ + GstCaps *caps = NULL; + mc_gst_port_def_t *port_def = &core->ports[index]->port_def; + + caps = gst_caps_new_simple(core->mime, + "width", G_TYPE_INT, port_def->info.video.width, + "height", G_TYPE_INT, port_def->info.video.height, + "framerate", GST_TYPE_FRACTION, port_def->info.video.framerate, 1, + NULL); + + switch (codec_id) { + case MEDIACODEC_H263: + if (core->encoder) { + gst_caps_set_simple(caps, + "format", G_TYPE_STRING, port_def->info.video.format, + NULL); + } else { + gst_caps_set_simple(caps, + "mpegversion", G_TYPE_INT, 4, + "framerate", GST_TYPE_FRACTION, 30, 1, + NULL); + } + break; + case MEDIACODEC_MPEG4: + if (core->encoder) { + gst_caps_set_simple(caps, + "format", G_TYPE_STRING, port_def->info.video.format, + NULL); + } else { + gst_caps_set_simple(caps, + "mpegversion", G_TYPE_INT, 4, + "systemstream", G_TYPE_BOOLEAN, false, + "parsed", G_TYPE_BOOLEAN, TRUE, + "framerate", GST_TYPE_FRACTION, 30, 1, + NULL); + } + break; + case MEDIACODEC_H264: + if (core->encoder) { + gst_caps_set_simple(caps, + "format", G_TYPE_STRING, port_def->info.video.format, + NULL); + g_object_set(GST_OBJECT(core->codec), "byte-stream", TRUE, NULL); + LOGE("format : %s", port_def->info.video.format); + } else { + gst_caps_set_simple(caps, + "parsed", G_TYPE_BOOLEAN, TRUE, /* FIXME different from sw */ + "alignment", G_TYPE_STRING, "au", + "stream-format", G_TYPE_STRING, "byte-stream", + "framerate", GST_TYPE_FRACTION, 30, 1, + NULL); + } + break; + default: + break; + } + + return caps; +} + static int _mc_link_vtable(mc_gst_core_t *core, mediacodec_codec_type_e id, gboolean encoder, gboolean is_hw) { MEDIACODEC_FENTER(); @@ -1368,69 +1543,35 @@ static int _mc_link_vtable(mc_gst_core_t *core, mediacodec_codec_type_e id, gboo switch (id) { case MEDIACODEC_AAC: - /* if set to 'CODEC_CONFIG', then It is also available case of MEDIA_FORMAT_AAC_LC (RAW) */ - LOGD("aac lc (adts) vtable"); if (encoder) { core->vtable = aenc_aac_vtable; - core->caps = gst_caps_new_simple(core->mime, - "layout", G_TYPE_STRING, "interleaved", NULL); - g_object_set(GST_OBJECT(core->codec), "compliance", -2, NULL); } else { - LOGD("CAPS for codec_id (MEDIACODEC_AAC_LC - normal ADTS)"); - core->vtable = adec_aac_vtable; - core->caps = gst_caps_new_simple(core->mime, - "framed", G_TYPE_BOOLEAN, TRUE, - "mpegversion", G_TYPE_INT, 4, - "stream-format", G_TYPE_STRING, "adts", - NULL); } break; case MEDIACODEC_AAC_HE: case MEDIACODEC_AAC_HE_PS: - LOGD("aac he v12 vtable"); if (encoder) { LOGD("[MC_NOT_SUPPORTED] he-aac-v12 encoder is not supported yet!!!"); return MC_NOT_SUPPORTED; } else { - LOGD("CAPS for codec_id (MEDIACODEC_AAC_HE and _PS - MP4/M4A case)"); core->vtable = adec_aacv12_vtable; - core->caps = gst_caps_new_simple(core->mime, - "mpegversion", G_TYPE_INT, 4, /*TODO : need adding version /profile*/ - "framed", G_TYPE_BOOLEAN, TRUE, - "stream-format", G_TYPE_STRING, "raw", - NULL); } break; case MEDIACODEC_MP3: - LOGD("mp3 vtable - Only support decoder"); if (encoder) { LOGD("[MC_NOT_SUPPORTED] mp3 encoder is not supported yet!!!"); return MC_NOT_SUPPORTED; } else { core->vtable = adec_mp3_vtable; - core->caps = gst_caps_new_simple(core->mime, - "framed", G_TYPE_BOOLEAN, TRUE, - "mpegversion", G_TYPE_INT, 1, /* To-Do : plz check */ - "mpegaudioversion", G_TYPE_INT, 1, /* To-Do : plz check */ - "layer", G_TYPE_INT, 3, /* To-Do : plz check */ - NULL); } break; case MEDIACODEC_AMR_NB: LOGD("amrnb vtable"); if (encoder) { core->vtable = aenc_amrnb_vtable; - core->caps = gst_caps_new_simple(core->mime, - "format", G_TYPE_STRING, "S16LE", - "layout", G_TYPE_STRING, "interleaved", - NULL); - } else { core->vtable = adec_amrnb_vtable; - core->caps = gst_caps_new_simple(core->mime, - "rate", G_TYPE_INT, 8000, - NULL); } break; case MEDIACODEC_AMR_WB: @@ -1440,9 +1581,6 @@ static int _mc_link_vtable(mc_gst_core_t *core, mediacodec_codec_type_e id, gboo return MC_NOT_SUPPORTED; } else { core->vtable = adec_amrwb_vtable; - core->caps = gst_caps_new_simple(core->mime, - "rate", G_TYPE_INT, 16000, - NULL); } break; case MEDIACODEC_VORBIS: @@ -1452,7 +1590,6 @@ static int _mc_link_vtable(mc_gst_core_t *core, mediacodec_codec_type_e id, gboo return MC_NOT_SUPPORTED; } else { core->vtable = adec_vorbis_vtable; - core->caps = gst_caps_new_empty_simple("audio/x-vorbis"); } break; case MEDIACODEC_FLAC: @@ -1462,10 +1599,6 @@ static int _mc_link_vtable(mc_gst_core_t *core, mediacodec_codec_type_e id, gboo return MC_NOT_SUPPORTED; } else { core->vtable = adec_flac_vtable; - core->caps = gst_caps_new_simple(core->mime, - "framed", G_TYPE_BOOLEAN, TRUE, - /* FIXME - Insert More Info */ - NULL); } break; case MEDIACODEC_WMAV1: @@ -1477,64 +1610,18 @@ static int _mc_link_vtable(mc_gst_core_t *core, mediacodec_codec_type_e id, gboo LOGD("[MC_NOT_SUPPORTED] wma encoder is not supported yet!!!"); return MC_NOT_SUPPORTED; } else { - mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info; - core->vtable = adec_wma_vtable; - - /* - * Need to extract from Stream Type Specific ... or - * Need to get Demuxer's Caps from Stream Type Specific - */ - guint16 format_tag = 0; - gint wma_version = 0; - gint block_align = 1024; /*FIXME : Need checking */ - gint bitrate = 128000; /*FIXME : Need checking */ - - LOGD(" ----- WMA Need Additional Caps -----------"); - if (core->codec_id == MEDIACODEC_WMAV1) { - format_tag = 352; /* 0x160 */ - wma_version = 1; - } else if (core->codec_id == MEDIACODEC_WMAV2) { - format_tag = 353; /* 0x161 */ - wma_version = 2; - } else if (core->codec_id == MEDIACODEC_WMAPRO) { - format_tag = 354; /* 0x162 */ - wma_version = 3; - } else if (core->codec_id == MEDIACODEC_WMALSL) { - format_tag = 355; /* 0x163 */ - wma_version = 3; - } else { - LOGE("Not support WMA format"); - } - - core->caps = gst_caps_new_simple(core->mime, - "bitrate", G_TYPE_INT, bitrate, - "depth", G_TYPE_INT, dec_info->bit, - /* FIXME - Need More Info */ - "wmaversion", G_TYPE_INT, wma_version, - "format_tag", G_TYPE_INT, format_tag, - "block_align", G_TYPE_INT, block_align, - NULL); } break; case MEDIACODEC_H263: LOGD("h263 vtable"); if (encoder) { core->vtable = is_hw ? venc_h263_hw_vtable : venc_h263_sw_vtable; - core->caps = gst_caps_new_empty_simple("video/x-raw"); } else { if (is_hw) { core->vtable = vdec_h263_hw_vtable; - core->caps = gst_caps_new_simple(core->mime, - "mpegversion", G_TYPE_INT, 4, - "framerate", GST_TYPE_FRACTION, 30, 1, - NULL); } else { core->vtable = vdec_h263_sw_vtable; - core->caps = gst_caps_new_simple(core->mime, - "variant", G_TYPE_STRING, "itu", - "framerate", GST_TYPE_FRACTION, 30, 1, - NULL); } } break; @@ -1542,47 +1629,25 @@ static int _mc_link_vtable(mc_gst_core_t *core, mediacodec_codec_type_e id, gboo LOGD("mpeg4 vtable"); if (encoder) { core->vtable = is_hw ? venc_mpeg4_hw_vtable : venc_mpeg4_sw_vtable; - core->caps = gst_caps_new_empty_simple("video/x-raw"); } else { core->vtable = is_hw ? vdec_mpeg4_hw_vtable : vdec_mpeg4_sw_vtable; - core->caps = gst_caps_new_simple(core->mime, - "mpegversion", G_TYPE_INT, 4, - "systemstream", G_TYPE_BOOLEAN, false, - "parsed", G_TYPE_BOOLEAN, TRUE, - "framerate", GST_TYPE_FRACTION, 30, 1, - NULL); } break; case MEDIACODEC_H264: LOGD("h264 vtable"); if (encoder) { core->vtable = is_hw ? venc_h264_hw_vtable : venc_vtable; - core->caps = gst_caps_new_empty_simple("video/x-raw"); - g_object_set(GST_OBJECT(core->codec), "byte-stream", TRUE, NULL); } else { if (is_hw) { core->vtable = vdec_h264_hw_vtable; - core->caps = gst_caps_new_simple(core->mime, - "parsed", G_TYPE_BOOLEAN, TRUE, - "alignment", G_TYPE_STRING, "au", - "stream-format", G_TYPE_STRING, "byte-stream", - "framerate", GST_TYPE_FRACTION, 30, 1, - NULL); } else { core->vtable = vdec_h264_sw_vtable; - core->caps = gst_caps_new_simple(core->mime, - "alignment", G_TYPE_STRING, "au", - "stream-format", G_TYPE_STRING, "byte-stream", - "framerate", GST_TYPE_FRACTION, 30, 1, - NULL); } } break; default: break; } - /* set caps */ - g_object_set(core->appsrc, "caps", core->caps, NULL); MEDIACODEC_FLEAVE(); @@ -1618,6 +1683,7 @@ mc_ret_e mc_gst_prepare(mc_handle_t *mc_handle) media_format_mimetype_e out_mime; int num_supported_codec = 0; int i = 0; + GstCaps *caps = NULL; if (!mc_handle) return MC_PARAM_ERROR; @@ -1655,9 +1721,11 @@ mc_ret_e mc_gst_prepare(mc_handle_t *mc_handle) new_core->eos = false; new_core->encoder = encoder; new_core->video = video; - new_core->codec_info = encoder ? (void *)&mc_handle->info.encoder : (void *)&mc_handle->info.decoder; - new_core->out_mime = codec_map[i].type.out_format; + memcpy(&new_core->ports[in_port_index]->port_def.info, &mc_handle->info, sizeof(mc_handle->info)); + memcpy(&new_core->ports[out_port_index]->port_def.info, &mc_handle->info, sizeof(mc_handle->info)); + new_core->ports[out_port_index]->port_def.coding_type = out_mime; new_core->codec_id = id; + new_core->mc_caps_new = video ? &_mc_gst_vid_caps_new : &_mc_gst_aud_caps_new; new_core->bufmgr = tbm_bufmgr_init(new_core->drm_fd); if (new_core->bufmgr == NULL) { @@ -1684,8 +1752,6 @@ mc_ret_e mc_gst_prepare(mc_handle_t *mc_handle) } } - mc_handle->core = new_core; - /* create basic core elements */ ret = _mc_gst_create_pipeline(mc_handle->core, factory_name); if (ret != MC_ERROR_NONE) { @@ -1700,6 +1766,22 @@ mc_ret_e mc_gst_prepare(mc_handle_t *mc_handle) return ret; } + /* set caps in capsfilter as default*/ + caps = new_core->mc_caps_new(new_core, id, out_port_index); + + /* FIXME will parse input format from ini. format is needed when linking elements*/ + if (new_core->video && new_core->encoder) { + gchar *format = NULL; + + format = new_core->is_hw ? "SN12" : "I420"; + gst_caps_set_simple(caps, + "format", G_TYPE_STRING, format, + NULL); + } + g_object_set(new_core->capsfilter, "caps", caps, NULL); + gst_caps_unref(caps); + + mc_handle->core = new_core; LOGD("initialized... %d", ret); MEDIACODEC_FLEAVE(); @@ -2009,6 +2091,28 @@ mc_ret_e _mc_gst_create_pipeline(mc_gst_core_t *core, gchar *factory_name) LOGE("capsfilter can't create"); goto ERROR; } + + core->audioresample = gst_element_factory_make("audioresample", NULL); + + if (!core->audioresample) { + LOGE("capsfilter can't create"); + goto ERROR; + } + } + + if (core->video && core->encoder) { + core->videoconvert = gst_element_factory_make("videoconvert", NULL); + + if (!core->videoconvert) { + LOGE("videoconvert can't create"); + goto ERROR; + } + + core->videoscale = gst_element_factory_make("videoscale", NULL); + if (!core->videoscale) { + LOGE("videoscale can't create"); + goto ERROR; + } } core->capsfilter = gst_element_factory_make("capsfilter", NULL); @@ -2028,10 +2132,18 @@ mc_ret_e _mc_gst_create_pipeline(mc_gst_core_t *core, gchar *factory_name) /*__mc_link_elements(core);*/ if (!core->video && core->encoder) { - gst_bin_add_many(GST_BIN(core->pipeline), core->appsrc, core->capsfilter, core->audioconvert, core->codec, core->fakesink, NULL); + gst_bin_add_many(GST_BIN(core->pipeline), core->appsrc, core->audioresample, core->audioconvert, core->capsfilter, core->codec, core->fakesink, NULL); /* link elements */ - if (!(gst_element_link_many(core->appsrc, core->capsfilter, core->audioconvert, core->codec, core->fakesink, NULL))) { + if (!(gst_element_link_many(core->appsrc, core->audioresample, core->audioconvert, core->capsfilter, core->codec, core->fakesink, NULL))) { + LOGE("gst_element_link_many is failed"); + goto ERROR; + } + } else if (core->video && core->encoder) { + gst_bin_add_many(GST_BIN(core->pipeline), core->appsrc, core->capsfilter, core->codec, core->fakesink, NULL); + + /* link elements */ + if (!(gst_element_link_many(core->appsrc, core->codec, core->fakesink, NULL))) { LOGE("gst_element_link_many is failed"); goto ERROR; } @@ -2089,6 +2201,15 @@ ERROR: if (core->capsfilter) gst_object_unref(GST_OBJECT(core->capsfilter)); + if (core->audioresample) + gst_object_unref(GST_OBJECT(core->audioresample)); + + if (core->videoscale) + gst_object_unref(GST_OBJECT(core->videoscale)); + + if (core->videoconvert) + gst_object_unref(GST_OBJECT(core->videoconvert)); + if (core->audioconvert) gst_object_unref(GST_OBJECT(core->audioconvert)); @@ -2263,16 +2384,9 @@ int __mc_output_buffer_finalize_cb(media_packet_h packet, int error_code, void * return MEDIA_PACKET_FINALIZE; } -gchar *__mc_get_gst_input_format(media_packet_h packet, bool is_hw) +gchar *__mc_get_gst_input_format(media_format_mimetype_e mimetype, bool is_hw) { gchar *format = NULL; - media_format_h fmt = NULL; - media_format_mimetype_e mimetype = 0; - - media_packet_get_format(packet, &fmt); - media_format_get_video_info(fmt, &mimetype, NULL, NULL, NULL, NULL); - media_format_unref(fmt); - LOGD("input packet mimetype : %x", mimetype); switch (mimetype) { case MEDIA_FORMAT_I420: @@ -3409,29 +3523,19 @@ mc_ret_e mc_gst_get_packet_pool(mc_handle_t *mc_handle, media_packet_pool_h *pac mime_format = _mc_get_mime(core); if (core->video) { - if (core->encoder) { - media_format_set_video_mime(fmt_handle, mime_format); - media_format_set_video_width(fmt_handle, mc_handle->info.encoder.width); - media_format_set_video_height(fmt_handle, mc_handle->info.encoder.height); - media_format_set_video_avg_bps(fmt_handle, mc_handle->info.encoder.bitrate); - } else { - media_format_set_video_mime(fmt_handle, mime_format); - media_format_set_video_width(fmt_handle, mc_handle->info.decoder.width); - media_format_set_video_height(fmt_handle, mc_handle->info.decoder.height); - } + media_format_set_video_mime(fmt_handle, mime_format); + media_format_set_video_width(fmt_handle, mc_handle->info.video.width); + media_format_set_video_height(fmt_handle, mc_handle->info.video.height); + if (core->encoder) + media_format_set_video_avg_bps(fmt_handle, mc_handle->info.video.bitrate); } else { - if (core->encoder) { media_format_set_audio_mime(fmt_handle, mime_format); - media_format_set_audio_channel(fmt_handle, mc_handle->info.encoder.channel); - media_format_set_audio_samplerate(fmt_handle, mc_handle->info.encoder.samplerate); - media_format_set_audio_bit(fmt_handle, mc_handle->info.encoder.bit); - } else { - media_format_set_audio_mime(fmt_handle, mime_format); - media_format_set_audio_channel(fmt_handle, mc_handle->info.decoder.channel); - media_format_set_audio_samplerate(fmt_handle, mc_handle->info.decoder.samplerate); - media_format_set_audio_bit(fmt_handle, mc_handle->info.decoder.bit); - } + media_format_set_audio_channel(fmt_handle, mc_handle->info.audio.channel); + media_format_set_audio_samplerate(fmt_handle, mc_handle->info.audio.samplerate); + media_format_set_audio_bit(fmt_handle, mc_handle->info.audio.bit_depth); + if (core->encoder) + media_format_set_audio_avg_bps(fmt_handle, mc_handle->info.audio.bitrate); } ret = media_packet_pool_set_media_format(pool, fmt_handle); diff --git a/test/media_codec_test.c b/test/media_codec_test.c index 5b592f5..dc46195 100644 --- a/test/media_codec_test.c +++ b/test/media_codec_test.c @@ -799,6 +799,7 @@ int _configure(App *app, int codecid, int flag, gboolean *hardware, media_forma if (encoder) { extractor = amrenc_extractor; mime = MEDIA_FORMAT_PCM_F32LE; /* FIXME need to check according to verdor */ + *codec_mime = MEDIA_FORMAT_AMR_NB; app->is_amr_nb = TRUE; } else { extractor = amrdec_extractor; @@ -1408,6 +1409,7 @@ void _mediacodec_prepare(App *app, gboolean frame_all) media_format_set_video_width(fmt, app->width); media_format_set_video_height(fmt, app->height); media_format_set_video_avg_bps(fmt, app->target_bits); + media_format_set_video_frame_rate(fmt, app->fps); media_format_create(&codec_format); media_format_set_video_mime(codec_format, codec_mime); @@ -1985,30 +1987,33 @@ void displaymenu(void) g_print("*** input mediapath.\n"); } else if (g_menu_state == CURRENT_STATUS_SET_CODEC) { g_print("*** Codec id : Select Codec ID Numbe (e.g. AAC_LC = 96)\n"); - g_print(" L16 = 16 (0x10)\n"); - g_print(" ALAW = 32 (0x20)\n"); - g_print(" ULAW = 48 (0x30)\n"); - g_print(" AMR_NB = 64 (0x40)\n"); - g_print(" AMR_WB = 65 (0x41)\n"); - g_print(" G729 = 80 (0x50)\n"); - g_print(" AAC_LC = 96 (0x60)\n"); - g_print(" AAC_HE = 97 (0x61)\n"); - g_print(" AAC_PS = 98 (0x62)\n"); - g_print(" MP3 = 112 (0x70)\n"); - g_print(" VORBIS = 128 (0x80)\n"); - g_print(" FLAC = 144 (0x90)\n"); - g_print(" WMAV1 = 160 (0xA0)\n"); - g_print(" WMAV2 = 161 (0xA1)\n"); - g_print(" WMAPRO = 162 (0xA2)\n"); - g_print(" WMALSL = 163 (0xA3)\n"); + g_print(" L16 = 0\n"); + g_print(" ALAW = 1\n"); + g_print(" ULAW = 2\n"); + g_print(" AMR_NB = 3\n"); + g_print(" AMR_WB = 4\n"); + g_print(" G729 = 5\n"); + g_print(" AAC_LC = 6\n"); + g_print(" AAC_HE = 7\n"); + g_print(" AAC_PS = 8\n"); + g_print(" MP3 = 9\n"); + g_print(" VORBIS = 10\n"); + g_print(" FLAC = 11\n"); + g_print(" WMAV1 = 12\n"); + g_print(" WMAV2 = 13\n"); + g_print(" WMAPRO = 14\n"); + g_print(" WMALSL = 15\n"); g_print(" -------------------\n"); - g_print(" H261 = 101\n"); - g_print(" H263 = 102\n"); - g_print(" H264 = 103\n"); - g_print(" MJPEG = 104\n"); - g_print(" MPEG1 = 105\n"); - g_print(" MPEG2 = 106\n"); - g_print(" MPEG4 = 107\n"); + g_print(" H261 = 16\n"); + g_print(" H263 = 17\n"); + g_print(" H264 = 18\n"); + g_print(" MJPEG = 19\n"); + g_print(" MPEG1 = 20\n"); + g_print(" MPEG2 = 21\n"); + g_print(" MPEG4 = 22\n"); + g_print(" HEVC = 23\n"); + g_print(" VP8 = 24\n"); + g_print(" VP9 = 25\n"); g_print(" -------------------\n"); g_print("*** Flags : Select Combination Number (e.g. DEOCDER + TYPE_SW = 10)\n"); g_print(" CODEC : ENCODER = 1 DECODER = 2\n"); @@ -2046,6 +2051,7 @@ void interpret(char *cmd) { App *app = &s_app; gint tmp = 0; + static gint cnt = 0; switch (g_menu_state) { case CURRENT_STATUS_MAINMENU: @@ -2057,111 +2063,83 @@ void interpret(char *cmd) break; case CURRENT_STATUS_SET_CODEC: { - static gint cnt = 0; - gchar **ptr = NULL; - switch (cnt) { - case 0: - tmp = atoi(cmd); + gint ids[] = { 0x1010, 0x1020, 0x1030, 0x1040, 0x1041, 0x1050, 0x1060, 0x1061, 0x1062, + 0x1070, 0x1080, 0x1090, 0x10A0, 0x10A1, 0x10A2, 0x10A3, 0x2010, 0x2020, + 0x2030, 0x2040, 0x2050, 0x2060, 0x2070, 0x2080, 0x2090, 0x20A0, 0x20B0 }; - if (tmp > 100 && - (tmp != 112) && - (tmp != 128) && - (tmp != 144) && - (tmp != 160) && (tmp != 161) && (tmp != 162) && (tmp != 163)) { - tmp = strtol(cmd, ptr, 16); - app->codecid = 0x2000 + ((tmp & 0xFF) << 4); - } else - app->codecid = 0x1000 + tmp; + if (cnt == 0) { + gint n_sizes = G_N_ELEMENTS(ids); + tmp = atoi(cmd); + if (tmp < 0 || tmp >= n_sizes - 1) { + cnt = 0; + g_print("Invalid value\n"); + reset_menu_state(); + break; + } + app->codecid = ids[tmp]; cnt++; - break; - case 1: + } else if (cnt == 1) { app->flag = atoi(cmd); cnt = 0; reset_menu_state(); - break; - default: - break; } } break; case CURRENT_STATUS_SET_VDEC_INFO: { - static gint cnt = 0; - switch (cnt) { - case 0: + if (cnt == 0) { app->width = atoi(cmd); cnt++; - break; - case 1: + } else if (cnt == 1) { app->height = atoi(cmd); app->type = VIDEO_DEC; reset_menu_state(); cnt = 0; - break; - default: - break; } } break; case CURRENT_STATUS_SET_VENC_INFO: { - static gint cnt = 0; - switch (cnt) { - case 0: - app->width = atoi(cmd); + if (cnt == 0) { + app->width = atol(cmd); cnt++; - break; - case 1: - app->height = atoi(cmd); + } else if (cnt == 1) { + app->height = atol(cmd); cnt++; - break; - case 2: + } else if (cnt == 2) { app->fps = atol(cmd); cnt++; - break; - case 3: - app->target_bits = atoi(cmd); + } else if (cnt == 3) { + app->target_bits = atol(cmd); app->type = VIDEO_ENC; reset_menu_state(); cnt = 0; - break; - default: - break; } } break; case CURRENT_STATUS_SET_ADEC_INFO: { - static gint cnt = 0; - switch (cnt) { - case 0: + if (cnt == 0) { app->samplerate = atoi(cmd); cnt++; - break; - case 1: + } else if (cnt == 1) { app->channel = atoi(cmd); cnt++; - break; - case 2: + } else if (cnt == 2) { app->bit = atoi(cmd); app->type = AUDIO_DEC; reset_menu_state(); cnt = 0; - break; - default: - break; } } break; case CURRENT_STATUS_SET_AENC_INFO: { - static int cnt = 0; - switch (cnt) { - case 0: + if (cnt == 0) { tmp = atoi(cmd); if (tmp <= 0 || tmp > 96000) { @@ -2171,8 +2149,7 @@ void interpret(char *cmd) } app->samplerate = tmp; cnt++; - break; - case 1: + } else if (cnt == 1) { tmp = atoi(cmd); if (tmp <= 0 || tmp > 6) { @@ -2182,8 +2159,7 @@ void interpret(char *cmd) } app->channel = tmp; cnt++; - break; - case 2: + } else if (cnt == 2) { tmp = atoi(cmd); if (tmp <= 0 || tmp > 32) { @@ -2193,8 +2169,7 @@ void interpret(char *cmd) } app->bit = tmp; cnt++; - break; - case 3: + } else if (cnt == 3) { tmp = atoi(cmd); if (tmp <= 0 || tmp >= INT_MAX) { @@ -2207,9 +2182,6 @@ void interpret(char *cmd) reset_menu_state(); cnt = 0; - break; - default: - break; } } break; @@ -2237,22 +2209,16 @@ void interpret(char *cmd) case CURRENT_STATUS_AUTO_TEST: { int len; - static int cnt = 0; - switch (cnt) { - case 0: + if (cnt == 0) { len = strlen(cmd); strncpy(app->filepath, cmd, len + 1); g_print("%s, %d\n", app->filepath, len); cnt++; - break; - case 1: + } else if (cnt == 1) { app->is_video = atoi(cmd) ? 1 : 0; _mediacodec_auto_test(app, app->filepath); reset_menu_state(); cnt = 0; - break; - default: - break; } } break; -- 2.7.4 From 6e514281315352dff296762d447854f25c624030 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Thu, 29 Mar 2018 16:53:23 +0900 Subject: [PATCH 11/16] Sync with tizen 4.0 Change-Id: I4e77a485916bb78806c28484ea4e6a980ad53525 --- doc/media_codec_doc.h | 12 +++ include/media_codec.h | 26 +++++++ include/media_codec_port.h | 4 +- packaging/capi-media-codec.spec | 4 +- src/media_codec_port.c | 161 +++++++++++++++++++++++++++++++++++++--- src/media_codec_port_gst.c | 89 +++++----------------- 6 files changed, 211 insertions(+), 85 deletions(-) mode change 100644 => 100755 doc/media_codec_doc.h mode change 100644 => 100755 include/media_codec.h mode change 100644 => 100755 include/media_codec_port.h mode change 100644 => 100755 src/media_codec_port.c mode change 100644 => 100755 src/media_codec_port_gst.c diff --git a/doc/media_codec_doc.h b/doc/media_codec_doc.h old mode 100644 new mode 100755 index 5899e57..36a1586 --- a/doc/media_codec_doc.h +++ b/doc/media_codec_doc.h @@ -33,6 +33,18 @@ * * @section CAPI_MEDIA_CODEC_MODULE_OVERVIEW Overview * + * @section CAPI_MEDIA_CODEC_FEATURE Related Features + * This API is related with the following features:\n + * - %http://tizen.org/feature/multimedia.media_codec:\n + * + * It is recommended to design feature related codes in your application for reliability.\n + * + * You can check if a device supports the related features for this API by using @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of your application.\n + * + * To ensure your application is only running on the device with specific features, please define the features in your manifest file using the manifest editor in the SDK.\n + * + * More details on featuring your application can be found from Feature Element. + * * MEDIA CODEC API allows : * The API allows you to direct access to the media codec on device. It operates on "raw" data, so any file headers * must be stripped off. media_packet is used for zero-copy. diff --git a/include/media_codec.h b/include/media_codec.h old mode 100644 new mode 100755 index 5899592..835cbec --- a/include/media_codec.h +++ b/include/media_codec.h @@ -212,6 +212,7 @@ typedef bool (*mediacodec_supported_codec_cb)(mediacodec_codec_type_e codec_type * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #MEDIACODEC_ERROR_OUT_OF_MEMORY Out of memory * @retval #MEDIACODEC_ERROR_INVALID_OPERATION Invalid operation + * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) */ int mediacodec_create(mediacodec_h *mediacodec); @@ -227,6 +228,7 @@ int mediacodec_create(mediacodec_h *mediacodec); * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #MEDIACODEC_ERROR_OUT_OF_MEMORY Out of memory * @retval #MEDIACODEC_ERROR_INVALID_OPERATION Invalid operation + * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) */ int mediacodec_destroy(mediacodec_h mediacodec); @@ -246,6 +248,7 @@ int mediacodec_destroy(mediacodec_h mediacodec); * @retval #MEDIACODEC_ERROR_OUT_OF_MEMORY Out of memory * @retval #MEDIACODEC_ERROR_INVALID_OPERATION Invalid operation * @retval #MEDIACODEC_ERROR_CODEC_NOT_FOUND Codec not found + * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) */ int mediacodec_set_codec(mediacodec_h mediacodec, mediacodec_codec_type_e codec_type, int flags); @@ -260,6 +263,7 @@ int mediacodec_set_codec(mediacodec_h mediacodec, mediacodec_codec_type_e codec_ * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #MEDIACODEC_ERROR_OUT_OF_MEMORY Out of memory * @retval #MEDIACODEC_ERROR_INVALID_OPERATION Invalid operation + * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) */ int mediacodec_set_vdec_info(mediacodec_h mediacodec, int width, int height); @@ -278,6 +282,7 @@ int mediacodec_set_vdec_info(mediacodec_h mediacodec, int width, int height); * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #MEDIACODEC_ERROR_OUT_OF_MEMORY Out of memory * @retval #MEDIACODEC_ERROR_INVALID_OPERATION Invalid operation + * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) */ int mediacodec_set_venc_info(mediacodec_h mediacodec, int width, int height, int fps, int target_bits); @@ -293,6 +298,7 @@ int mediacodec_set_venc_info(mediacodec_h mediacodec, int width, int height, int * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #MEDIACODEC_ERROR_OUT_OF_MEMORY Out of memory * @retval #MEDIACODEC_ERROR_INVALID_OPERATION Invalid operation + * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) */ int mediacodec_set_adec_info(mediacodec_h mediacodec, int samplerate, int channel, int bit); @@ -309,6 +315,7 @@ int mediacodec_set_adec_info(mediacodec_h mediacodec, int samplerate, int channe * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #MEDIACODEC_ERROR_OUT_OF_MEMORY Out of memory * @retval #MEDIACODEC_ERROR_INVALID_OPERATION Invalid operation + * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) */ int mediacodec_set_aenc_info(mediacodec_h mediacodec, int samplerate, int channel, int bit, int bitrate); @@ -336,6 +343,7 @@ int mediacodec_set_aenc_info(mediacodec_h mediacodec, int samplerate, int channe * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #MEDIACODEC_ERROR_CODEC_NOT_FOUND Unsupported codec + * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) * @pre The media format has been created and the required values for configuration have been set. * @see media_format_set_video_mime() * @see media_format_set_audio_mime() @@ -359,6 +367,7 @@ int mediacodec_configure_from_media_format(mediacodec_h mediacodec, media_format * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #MEDIACODEC_ERROR_OUT_OF_MEMORY Out of memory * @retval #MEDIACODEC_ERROR_INVALID_OPERATION Invalid operation + * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) * @pre The mediacodec should call mediacodec_set_codec()and mediacodec_set_vdec_info()/mediacodec_set_venc_info() before calling mediacodec_prepare() * If the decoder is set by mediacodec_set_codec(), mediacodec_set_vdec_info() should be called. If the encoder is set by * mediacodec_set_codec(), mediacodec_set_venc_info() should be called. @@ -374,6 +383,7 @@ int mediacodec_prepare(mediacodec_h mediacodec); * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #MEDIACODEC_ERROR_OUT_OF_MEMORY Out of memory * @retval #MEDIACODEC_ERROR_INVALID_OPERATION Invalid operation + * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) */ int mediacodec_unprepare(mediacodec_h mediacodec); @@ -391,6 +401,7 @@ int mediacodec_unprepare(mediacodec_h mediacodec); * @retval #MEDIACODEC_ERROR_OUT_OF_MEMORY Out of memory * @retval #MEDIACODEC_ERROR_INVALID_OPERATION Invalid operation * @retval #MEDIACODEC_ERROR_OVERFLOW_INBUFFER Overflow inputbuffer + * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) */ int mediacodec_process_input(mediacodec_h mediacodec, media_packet_h inbuf, uint64_t timeOutUs); @@ -407,6 +418,7 @@ int mediacodec_process_input(mediacodec_h mediacodec, media_packet_h inbuf, uint * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #MEDIACODEC_ERROR_OUT_OF_MEMORY Out of memory * @retval #MEDIACODEC_ERROR_INVALID_OPERATION Invalid operation + * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) */ int mediacodec_get_output(mediacodec_h mediacodec, media_packet_h *outbuf, uint64_t timeOutUs); @@ -417,6 +429,7 @@ int mediacodec_get_output(mediacodec_h mediacodec, media_packet_h *outbuf, uint6 * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) */ int mediacodec_flush_buffers(mediacodec_h mediacodec); @@ -429,6 +442,7 @@ int mediacodec_flush_buffers(mediacodec_h mediacodec); * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) * @pre mediacodec_set_input_buffer_used_cb should be called before mediacodec_preare(). * @post mediacodec_input_buffer_used_cb will be invoked. * @see mediacodec_set_input_buffer_used_cb() @@ -443,6 +457,7 @@ int mediacodec_set_input_buffer_used_cb(mediacodec_h mediacodec, mediacodec_inpu * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) * @see mediacodec_set_input_buffer_used_cb() */ int mediacodec_unset_input_buffer_used_cb(mediacodec_h mediacodec); @@ -456,6 +471,7 @@ int mediacodec_unset_input_buffer_used_cb(mediacodec_h mediacodec); * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) * @pre mediacodec_set_output_buffer_available_cb should be called before mediacodec_preare(). * @post mediacodec_output_buffer_available_cb will be invoked. * @see mediacodec_set_output_buffer_available_cb() @@ -470,6 +486,7 @@ int mediacodec_set_output_buffer_available_cb(mediacodec_h mediacodec, mediacode * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) * @see mediacodec_set_output_buffer_available_cb() */ int mediacodec_unset_output_buffer_available_cb(mediacodec_h mediacodec); @@ -483,6 +500,7 @@ int mediacodec_unset_output_buffer_available_cb(mediacodec_h mediacodec); * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) * @pre mediacodec_set_error_cb should be called before mediacodec_preare(). * @post mediacodec_error_cb will be invoked. * @see mediacodec_set_error_cb() @@ -497,6 +515,7 @@ int mediacodec_set_error_cb(mediacodec_h mediacodec, mediacodec_error_cb callbac * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) * @see mediacodec_set_error_cb() */ int mediacodec_unset_error_cb(mediacodec_h mediacodec); @@ -510,6 +529,7 @@ int mediacodec_unset_error_cb(mediacodec_h mediacodec); * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) * @pre mediacodec_set_eos_cb should be called before mediacodec_preare(). * @post mediacodec_eos_cb will be invoked. * @see mediacodec_set_eos_cb() @@ -524,6 +544,7 @@ int mediacodec_set_eos_cb(mediacodec_h mediacodec, mediacodec_eos_cb callback, v * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) * @see mediacodec_set_event_handler_cb() */ int mediacodec_unset_eos_cb(mediacodec_h mediacodec); @@ -537,6 +558,7 @@ int mediacodec_unset_eos_cb(mediacodec_h mediacodec); * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) * @pre mediacodec_set_buffer_status_cb should be called before mediacodec_preare(). * @post mediacodec_buffer_status_cb will be invoked. * @see mediacodec_set_buffer_status_cb() @@ -551,6 +573,7 @@ int mediacodec_set_buffer_status_cb(mediacodec_h mediacodec, mediacodec_buffer_s * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) */ int mediacodec_unset_buffer_status_cb(mediacodec_h mediacodec); @@ -563,6 +586,7 @@ int mediacodec_unset_buffer_status_cb(mediacodec_h mediacodec); * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) * @see mediacodec_foreach_supported_codec() */ int mediacodec_foreach_supported_codec(mediacodec_h mediacodec, mediacodec_supported_codec_cb callback, void *user_data); @@ -577,6 +601,7 @@ int mediacodec_foreach_supported_codec(mediacodec_h mediacodec, mediacodec_suppo * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) @code #include mediacodec_h mediacodec; @@ -611,6 +636,7 @@ int mediacodec_get_supported_type(mediacodec_h mediacodec, mediacodec_codec_type * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #MEDIACODEC_ERROR_OUT_OF_MEMORY Out of memory * @retval #MEDIACODEC_ERROR_INVALID_OPERATION The user calls mediacodec_get_packet_pool() before calling mediacodec_prepare(). + * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) * @pre mediacodec_get_packet_pool() should be called after calling mediacodec_prepare(). * @post If the pool is used, media_packet_pool_deallocate() and media_packet_pool_destroy() should be called. * @see media_packet_pool_acquire_packet() diff --git a/include/media_codec_port.h b/include/media_codec_port.h old mode 100644 new mode 100755 index f2a732c..986bdd3 --- a/include/media_codec_port.h +++ b/include/media_codec_port.h @@ -267,8 +267,8 @@ void _mc_create_codec_map_from_ini_static(mc_ini_t *ini, mc_codec_spec_t *spec_e void _mc_create_decoder_map_from_ini(mc_handle_t *mc_handle); void _mc_create_encoder_map_from_ini(mc_handle_t *mc_handle); -const codec_type_e simple_to_codec_type_enumeration(codec_type_e codec_id); -const codec_type_e codec_type_to_simple_enumeration(mediacodec_codec_type_e media_codec_id); +mediacodec_codec_type_e simple_to_codec_type_enumeration(codec_type_e codec_id); +codec_type_e codec_type_to_simple_enumeration(mediacodec_codec_type_e media_codec_id); #ifdef __cplusplus } diff --git a/packaging/capi-media-codec.spec b/packaging/capi-media-codec.spec index 9f9ee77..0d2a3bb 100755 --- a/packaging/capi-media-codec.spec +++ b/packaging/capi-media-codec.spec @@ -4,8 +4,8 @@ Name: capi-media-codec Summary: A Media Codec library in Tizen Native API -Version: 0.5.8 -Release: 2 +Version: 0.5.10 +Release: 0 Group: Multimedia/API License: Apache-2.0 Source0: %{name}-%{version}.tar.gz diff --git a/src/media_codec_port.c b/src/media_codec_port.c old mode 100644 new mode 100755 index cf6843a..804a7cb --- a/src/media_codec_port.c +++ b/src/media_codec_port.c @@ -27,6 +27,9 @@ #include #include +static gboolean _check_support_audio_info(mediacodec_codec_type_e codec_id, int samplerate, int channel, int bit_depth); +static gboolean _check_support_video_info(mediacodec_codec_type_e codec_id, int width, int height); + int mc_create(MMHandleType *mediacodec) { mc_handle_t *new_mediacodec = NULL; @@ -168,7 +171,7 @@ int mc_set_vdec_info(MMHandleType mediacodec, int width, int height) return MC_INVALID_ARG; } - if ((width <= 0) || (height <= 0)) + if (!_check_support_video_info(mc_handle->codec_id, width, height)) return MC_PARAM_ERROR; MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && mc_handle->is_video && !mc_handle->is_encoder, @@ -192,7 +195,7 @@ int mc_set_venc_info(MMHandleType mediacodec, int width, int height, int fps, in return MC_INVALID_ARG; } - if ((width <= 0) || (height <= 0)) + if (!_check_support_video_info(mc_handle->codec_id, width, height) || fps < 0 || target_bits < 0) return MC_PARAM_ERROR; MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && mc_handle->is_video && mc_handle->is_encoder, @@ -217,7 +220,7 @@ int mc_set_adec_info(MMHandleType mediacodec, int samplerate, int channel, int b return MC_INVALID_ARG; } - if ((samplerate <= 0) || (channel <= 0) || (bit <= 0)) + if (!_check_support_audio_info(mc_handle->codec_id, samplerate, channel, bit)) return MC_PARAM_ERROR; MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && !mc_handle->is_video && !mc_handle->is_encoder, @@ -241,7 +244,7 @@ int mc_set_aenc_info(MMHandleType mediacodec, int samplerate, int channel, int b return MC_INVALID_ARG; } - if ((samplerate <= 0) || (channel <= 0) || (bit <= 0)) + if (!_check_support_audio_info(mc_handle->codec_id, samplerate, channel, bit)) return MC_PARAM_ERROR; MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && !mc_handle->is_video && mc_handle->is_encoder, @@ -287,8 +290,10 @@ int mc_configure(MMHandleType mediacodec, media_format_h format, int flags) if (type == MEDIA_FORMAT_AUDIO) { media_format_get_audio_info(format, &mimetype, &channel, &samplerate, &bit, &bitrate); + codec_id = mimetype & codec_mask; + if (GET_IS_ENCODER(flags)) { - if ((samplerate <= 0) || (channel <= 0) || (bit <= 0) || (bitrate <= 0)) { + if (!_check_support_audio_info(codec_id, samplerate, channel, bit)) { LOGE("invalid pram is set : samplerate : %d, channel : %d, bit : %d, bitrate : %d", samplerate, channel, bit, bitrate); return MC_PARAM_ERROR; @@ -299,7 +304,7 @@ int mc_configure(MMHandleType mediacodec, media_format_h format, int flags) mc_handle->info.audio.bit_depth = bit; mc_handle->info.audio.bitrate = bitrate * 1000; } else if (GET_IS_DECODER(flags)) { - if ((samplerate <= 0) || (channel <= 0) || (bit <= 0)) { + if (!_check_support_audio_info(codec_id, samplerate, channel, bit)) { LOGE("invalid pram is set : samplerate : %d, channel : %d, bit : %d", samplerate, channel, bit); return MC_PARAM_ERROR; @@ -314,9 +319,10 @@ int mc_configure(MMHandleType mediacodec, media_format_h format, int flags) } else if (type == MEDIA_FORMAT_VIDEO) { media_format_get_video_info(format, &mimetype, &width, &height, &bitrate, NULL); media_format_get_video_frame_rate(format, &fps); + codec_id = mimetype & codec_mask; if (GET_IS_ENCODER(flags)) { - if ((width <= 0) || (height <= 0) || (bitrate <= 0) || (fps <= 0)) { + if (!_check_support_video_info(codec_id, width, height) || fps <= 0 || bitrate <= 0) { LOGE("invalid pram is set : width : %d, height : %d, bitrate : %d, fps : %d", width, height, bitrate, fps); return MC_PARAM_ERROR; @@ -327,7 +333,7 @@ int mc_configure(MMHandleType mediacodec, media_format_h format, int flags) mc_handle->info.video.framerate = fps; mc_handle->info.video.bitrate = bitrate * 1000; } else if (GET_IS_DECODER(flags)) { - if ((width <= 0) || (height <= 0)) { + if (!_check_support_video_info(codec_id, width, height)) { LOGE("invalid pram is set : width : %d, height : %d", width, height); return MC_PARAM_ERROR; @@ -347,8 +353,6 @@ int mc_configure(MMHandleType mediacodec, media_format_h format, int flags) if (!GET_IS_HW(flags) && !GET_IS_SW(flags)) flags |= MEDIACODEC_SUPPORT_TYPE_SW; - codec_id = mimetype & codec_mask; - for (i = 0; i < mc_handle->ini->num_supported_codecs; i++) { if ((codec_id == spec_emul[i].codec_id) && (flags == spec_emul[i].codec_type)) break; @@ -988,7 +992,7 @@ void _mc_create_codec_map_from_ini_static(mc_ini_t *ini, mc_codec_spec_t *spec_e return; } -const codec_type_e codec_type_to_simple_enumeration(mediacodec_codec_type_e media_codec_id) +codec_type_e codec_type_to_simple_enumeration(mediacodec_codec_type_e media_codec_id) { guint media_codec_id_u = (guint)media_codec_id; @@ -1052,7 +1056,7 @@ const codec_type_e codec_type_to_simple_enumeration(mediacodec_codec_type_e medi } } -const codec_type_e simple_to_codec_type_enumeration(codec_type_e codec_id) +mediacodec_codec_type_e simple_to_codec_type_enumeration(codec_type_e codec_id) { guint codec_id_u = (guint)codec_id; @@ -1115,3 +1119,136 @@ const codec_type_e simple_to_codec_type_enumeration(codec_type_e codec_id) return NONE; } } + +gboolean _check_support_audio_info(mediacodec_codec_type_e codec_id, int samplerate, int channel, int bit_depth) +{ + gint i = 0; + gint maxchannels = 2; + gint n_rates = 0; + gint s_bit_depth = 32; + + switch (codec_id) { + case MEDIACODEC_AMR_NB: + { + const static gint l_rates[] = { 8000 }; + maxchannels = 1; + n_rates = G_N_ELEMENTS(l_rates); + s_bit_depth = 16; /* NOTE: amrnbenc/amrnbdec surpports S16LE as format*/ + + while (i < n_rates) { + if (l_rates[i] == samplerate) + break; + i++; + } + + if (i == n_rates) { + LOGE("Invalid samplerate set"); + return false; + } + break; + } + case MEDIACODEC_AAC_LC: + case MEDIACODEC_AAC_HE: + { + const static gint l_rates[] = { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350 }; + maxchannels = 6; + n_rates = G_N_ELEMENTS(l_rates); + s_bit_depth = 32; /* NOTE: avdec_aac/avenc_aac surpports S32LE as format*/ + + while (i < n_rates) { + if (l_rates[i] == samplerate) + break; + i++; + } + + if (i == n_rates) { + LOGE("Invalid samplerate set"); + return false; + } + break; + } + case MEDIACODEC_MP3: + { + s_bit_depth = 16; /* NOTE: amrenc/amrnbdec surpports S16LE as format*/ + break; + } + case MEDIACODEC_VORBIS: + { + s_bit_depth = 32; /* NOTE: vorbisenc/vorbisdec surpports S32LE as format */ + break; + } + case MEDIACODEC_FLAC: + { + s_bit_depth = 32; /* NOTE: avdec_flac surpports S32LE as format */ + break; + } + default: + break; + } + + if (channel < 0 || channel > maxchannels) { + LOGE("Invalid channel set"); + return false; + } + + if (bit_depth != s_bit_depth) { + LOGE("Invalid bit set"); + return false; + } + + return true; +} + +gboolean _check_support_video_info(mediacodec_codec_type_e codec_id, int width, int height) +{ + gint i = 0; + gint n_sizes = 0; + + if (width <= 0 || height <= 0) { + LOGE("Invalid resolution set"); + return false; + } + + switch (codec_id) { + case MEDIACODEC_H261: + { + const static gint widths[] = { 352, 176 }; + const static gint heights[] = { 288, 144 }; + n_sizes = G_N_ELEMENTS(widths); + + while (i < n_sizes) { + if ((widths[i] == width) && (heights[i] == height)) + break; + i++; + } + + if (i == n_sizes) { + LOGE("Invalid resolution set"); + return false; + } + break; + } + case MEDIACODEC_H263: + { + const static gint widths[] = { 352, 704, 176, 1408, 128 }; + const static gint heights[] = { 288, 576, 144, 1152, 96 }; + n_sizes = G_N_ELEMENTS(widths); + + while (i < n_sizes) { + if ((widths[i] == width) && (heights[i] == height)) + break; + i++; + } + + if (i == n_sizes) { + LOGE("Invalid resolution set"); + return false; + } + break; + } + default: + break; + } + + return true; +} diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c old mode 100644 new mode 100755 index 6d32a7b..753b309 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -64,7 +64,6 @@ static gint __gst_handle_library_error(mc_gst_core_t *core, int code); static gint __gst_handle_core_error(mc_gst_core_t *core, int code); static const gchar * _mc_error_to_string(mc_ret_e err); static const gchar * _mc_bit_to_string(int bit); -static int _mc_get_support_bit_from_format(media_format_mimetype_e format); static int _mc_link_vtable(mc_gst_core_t *core, mediacodec_codec_type_e id, gboolean is_encoder, gboolean is_hw); static int _mc_gst_flush_buffers(mc_gst_core_t *core); @@ -908,36 +907,23 @@ int _mc_output_media_packet_new(mc_gst_core_t *core, bool video, bool encoder, m } mc_gst_port_def_t *port_def = &core->ports[out_port_index]->port_def; - if (encoder) { + if (video) { + media_format_set_video_mime(core->output_fmt, out_mime); + media_format_set_video_width(core->output_fmt, port_def->info.video.width); + media_format_set_video_height(core->output_fmt, port_def->info.video.height); - if (video) { - media_format_set_video_mime(core->output_fmt, out_mime); - media_format_set_video_width(core->output_fmt, port_def->info.video.width); - media_format_set_video_height(core->output_fmt, port_def->info.video.height); + if (encoder) media_format_set_video_avg_bps(core->output_fmt, port_def->info.video.bitrate); - } else { - int support_bit = 0; - support_bit = _mc_get_support_bit_from_format(out_mime); - - media_format_set_audio_mime(core->output_fmt, out_mime); - media_format_set_audio_channel(core->output_fmt, port_def->info.audio.channel); - media_format_set_audio_samplerate(core->output_fmt, port_def->info.audio.samplerate); - media_format_set_audio_bit(core->output_fmt, support_bit); - media_format_set_audio_avg_bps(core->output_fmt, port_def->info.audio.bitrate); - } } else { + media_format_set_audio_mime(core->output_fmt, out_mime); + media_format_set_audio_channel(core->output_fmt, port_def->info.audio.channel); + media_format_set_audio_samplerate(core->output_fmt, port_def->info.audio.samplerate); + media_format_set_audio_bit(core->output_fmt, port_def->info.audio.bit_depth); - if (video) { - media_format_set_video_mime(core->output_fmt, out_mime); - media_format_set_video_width(core->output_fmt, port_def->info.video.width); - media_format_set_video_height(core->output_fmt, port_def->info.video.height); - } else { - media_format_set_audio_mime(core->output_fmt, out_mime); - media_format_set_audio_channel(core->output_fmt, port_def->info.audio.channel); - media_format_set_audio_samplerate(core->output_fmt, port_def->info.audio.samplerate); - media_format_set_audio_bit(core->output_fmt, port_def->info.audio.bit_depth); - } + if (encoder) + media_format_set_audio_avg_bps(core->output_fmt, port_def->info.audio.bitrate); } + return MC_ERROR_NONE; } @@ -1090,7 +1076,7 @@ gboolean _mc_update_packet_info(mc_gst_core_t *core, media_format_h format) is_format_change |= input_port_def->info.video.width != width; is_format_change |= input_port_def->info.video.height != height; - is_format_change |= (input_port_def->info.video.framerate != framerate) && (framerate != 0); + is_format_change |= ((input_port_def->info.video.framerate != framerate) && (framerate != 0)); if (is_format_change) { LOGD("Format changed : resolution %dx%d -> %dx%d, framerate %d -> %d", input_port_def->info.video.width, input_port_def->info.video.height, width, height, @@ -1101,7 +1087,7 @@ gboolean _mc_update_packet_info(mc_gst_core_t *core, media_format_h format) if (core->encoder) { sformat = __mc_get_gst_input_format(mimetype, core->is_hw); - is_format_change |= input_port_def->info.video.bitrate != bitrate * 1000; + is_format_change |= ((input_port_def->info.video.bitrate != bitrate * 1000) && (bitrate != 0)); is_format_change |= g_strcmp0(input_port_def->info.video.format, sformat); if (is_format_change) { LOGD("Bitrate changed : %d -> %d", input_port_def->info.video.bitrate, bitrate); @@ -1132,7 +1118,7 @@ gboolean _mc_update_packet_info(mc_gst_core_t *core, media_format_h format) } if (core->encoder) { - is_format_change |= input_port_def->info.audio.bitrate != bitrate * 1000; + is_format_change |= ((input_port_def->info.audio.bitrate != bitrate * 1000) && (bitrate != 0)); if (is_format_change) { LOGD("Bitrate changed : %d -> %d", input_port_def->info.audio.bitrate, bitrate); input_port_def->info.audio.bitrate = bitrate * 1000; @@ -1261,6 +1247,7 @@ static gpointer feed_task(gpointer data) pad = gst_element_get_static_pad(core->appsrc, "src"); gst_pad_push_event(pad, gst_event_new_stream_start("start")); gst_object_unref(pad); + is_format_change = TRUE; initiative = FALSE; } @@ -1344,6 +1331,7 @@ GstCaps *_mc_gst_aud_caps_new(mc_gst_core_t *core, mediacodec_codec_type_e codec case MEDIACODEC_AAC: if (core->encoder) { gst_caps_set_simple(caps, + "format", G_TYPE_STRING, _mc_bit_to_string(port_def->info.audio.bit_depth), "layout", G_TYPE_STRING, "interleaved", NULL); g_object_set(GST_OBJECT(core->codec), "compliance", -2, NULL); } else { @@ -1656,17 +1644,7 @@ static int _mc_link_vtable(mc_gst_core_t *core, mediacodec_codec_type_e id, gboo static gint _mc_gst_gstbuffer_to_appsrc(mc_gst_core_t *core, GstMCBuffer *mcbuffer) { - gint ret = MC_ERROR_NONE; - - MEDIACODEC_FENTER(); - - ret = gst_app_src_push_buffer(GST_APP_SRC(core->appsrc), mcbuffer->buffer); - LOGD("pushed buffer to appsrc : %p, buffer of size %" G_GSIZE_FORMAT "", - mcbuffer->buffer, gst_buffer_get_size(mcbuffer->buffer)); - - MEDIACODEC_FLEAVE(); - - return ret; + return gst_app_src_push_buffer(GST_APP_SRC(core->appsrc), mcbuffer->buffer); } media_packet_h _mc_get_input_buffer(mc_gst_core_t *core) @@ -1753,14 +1731,14 @@ mc_ret_e mc_gst_prepare(mc_handle_t *mc_handle) } /* create basic core elements */ - ret = _mc_gst_create_pipeline(mc_handle->core, factory_name); + ret = _mc_gst_create_pipeline(new_core, factory_name); if (ret != MC_ERROR_NONE) { LOGE("failed to create pipeline"); return ret; } /* link vtable */ - ret = _mc_link_vtable(mc_handle->core, id, encoder, hardware); + ret = _mc_link_vtable(new_core, id, encoder, hardware); if (ret != MC_ERROR_NONE) { LOGE("vtable link failed"); return ret; @@ -3397,33 +3375,6 @@ const gchar * _mc_bit_to_string(int bit) } } -int _mc_get_support_bit_from_format(media_format_mimetype_e format) -{ - gint bit = 0; - - switch (format) { - case MEDIA_FORMAT_PCM_S16LE: - case MEDIA_FORMAT_PCM_S16BE: - case MEDIA_FORMAT_PCM_U16LE: - case MEDIA_FORMAT_PCM_U16BE: - bit = 16; - break; - case MEDIA_FORMAT_PCM_S32LE: - case MEDIA_FORMAT_PCM_S32BE: - case MEDIA_FORMAT_PCM_U32LE: - case MEDIA_FORMAT_PCM_U32BE: - case MEDIA_FORMAT_PCM_F32LE: - case MEDIA_FORMAT_PCM_F32BE: - bit = 32; - break; - default: - LOGE("NOT SUPPORTED!!!!"); - break; - } - - return bit; -} - int _mc_get_mime(mc_gst_core_t *core) { media_format_mimetype_e mime = MEDIA_FORMAT_MAX; -- 2.7.4 From 06263b0fe5c2e3e5485e6c6ab4a3d4dca6e7a846 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Fri, 6 Apr 2018 16:21:32 +0900 Subject: [PATCH 12/16] Fixed a problem when packet with codec config flag queued Change-Id: I1051324d90fc2ba1125b51b706f2ab25a37e82c8 --- packaging/capi-media-codec.spec | 2 +- src/media_codec_port_gst.c | 44 +++++++++++++++++++++++++---------------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/packaging/capi-media-codec.spec b/packaging/capi-media-codec.spec index 0d2a3bb..88d1a85 100755 --- a/packaging/capi-media-codec.spec +++ b/packaging/capi-media-codec.spec @@ -4,7 +4,7 @@ Name: capi-media-codec Summary: A Media Codec library in Tizen Native API -Version: 0.5.10 +Version: 0.5.11 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index 753b309..a9ea98a 100755 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -80,7 +80,7 @@ static void __csc_tiled_to_linear_crop(unsigned char *yuv420_dest, static void _mc_send_eos_signal(mc_gst_core_t *core); static void _mc_wait_for_eos(mc_gst_core_t *core); static int _mc_get_mime(mc_gst_core_t *core); -static int _mc_set_codec_data(mc_gst_core_t *core, GstMCBuffer *mcbuffer); +static int _mc_set_codec_data(mc_gst_core_t *core, GstMCBuffer *mcbuffer, bool codec_config); GstCaps *_mc_gst_vid_caps_new(mc_gst_core_t *core, mediacodec_codec_type_e codec_id, gint index); GstCaps *_mc_gst_aud_caps_new(mc_gst_core_t *core, mediacodec_codec_type_e codec_id, gint index); @@ -1129,7 +1129,7 @@ gboolean _mc_update_packet_info(mc_gst_core_t *core, media_format_h format) return is_format_change; } -static int _mc_set_codec_data(mc_gst_core_t *core, GstMCBuffer *mcbuffer) +static int _mc_set_codec_data(mc_gst_core_t *core, GstMCBuffer *mcbuffer, bool codec_config) { MEDIACODEC_FENTER(); @@ -1142,23 +1142,29 @@ static int _mc_set_codec_data(mc_gst_core_t *core, GstMCBuffer *mcbuffer) case MEDIACODEC_AAC: case MEDIACODEC_AAC_HE: case MEDIACODEC_AAC_HE_PS: - ret = __mc_set_caps_codecdata(core, mcbuffer, AAC_CODECDATA_SIZE); - if (ret != MC_ERROR_NONE) - LOGW("__mc_set_caps_codecdata failed"); + if (codec_config) { + ret = __mc_set_caps_codecdata(core, mcbuffer, AAC_CODECDATA_SIZE); + if (ret != MC_ERROR_NONE) + LOGW("__mc_set_caps_codecdata failed"); + } break; case MEDIACODEC_WMAV1: case MEDIACODEC_WMAV2: case MEDIACODEC_WMAPRO: case MEDIACODEC_WMALSL: - ret = __mc_set_caps_codecdata(core, mcbuffer, WMA_CODECDATA_SIZE); - if (ret != MC_ERROR_NONE) - LOGW("__mc_set_caps_codecdata failed"); + if (codec_config) { + ret = __mc_set_caps_codecdata(core, mcbuffer, WMA_CODECDATA_SIZE); + if (ret != MC_ERROR_NONE) + LOGW("__mc_set_caps_codecdata failed"); + } break; case MEDIACODEC_VORBIS: case MEDIACODEC_FLAC: - ret = __mc_set_caps_streamheader(core, mcbuffer, VORBIS_CODECDATA_SIZE); - if (ret != MC_ERROR_NONE) - LOGW("__mc_set_caps_streamheader failed"); + if (codec_config) { + ret = __mc_set_caps_streamheader(core, mcbuffer, VORBIS_CODECDATA_SIZE); + if (ret != MC_ERROR_NONE) + LOGW("__mc_set_caps_streamheader failed"); + } break; case MEDIACODEC_H264: case MEDIACODEC_MPEG4: @@ -1237,12 +1243,14 @@ static gpointer feed_task(gpointer data) input_buffer = NULL; if (codec_config || initiative) { - GstPad *pad; - ret = _mc_set_codec_data(core, mcbuffer); - if (ret != MC_ERROR_NONE) { - LOGE("failed to set codec data"); - gst_buffer_unref(mcbuffer->buffer); - goto ERROR; + GstPad *pad = NULL; + if (!core->encoder) { + ret = _mc_set_codec_data(core, mcbuffer, codec_config); + if (ret != MC_ERROR_NONE) { + LOGE("failed to set codec data"); + gst_buffer_unref(mcbuffer->buffer); + goto ERROR; + } } pad = gst_element_get_static_pad(core->appsrc, "src"); gst_pad_push_event(pad, gst_event_new_stream_start("start")); @@ -1257,6 +1265,7 @@ static gpointer feed_task(gpointer data) g_object_set(core->appsrc, "caps", caps, NULL); gst_caps_unref(caps); LOGD("caps updated"); + is_format_change = FALSE; } @@ -1747,6 +1756,7 @@ mc_ret_e mc_gst_prepare(mc_handle_t *mc_handle) /* set caps in capsfilter as default*/ caps = new_core->mc_caps_new(new_core, id, out_port_index); + new_core->caps = caps; /* FIXME will parse input format from ini. format is needed when linking elements*/ if (new_core->video && new_core->encoder) { gchar *format = NULL; -- 2.7.4 From 7840c0abe4e500193d266a8265a2e6ef7688a510 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Thu, 12 Apr 2018 10:49:55 +0900 Subject: [PATCH 13/16] Added offset to check for discontinuity when timestamp is not available Change-Id: Ia09e5a8c92630e6035e178fd42b6a665c8b766bd --- include/media_codec_port_gst.h | 1 + packaging/capi-media-codec.spec | 2 +- src/media_codec_port_gst.c | 6 ++++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/media_codec_port_gst.h b/include/media_codec_port_gst.h index 4d9198f..2888192 100755 --- a/include/media_codec_port_gst.h +++ b/include/media_codec_port_gst.h @@ -138,6 +138,7 @@ struct _mc_gst_core_t { guint prepare_count; guint num_live_buffers; guint etb_count; + gint64 offset; mediacodec_codec_type_e codec_id; media_format_mimetype_e out_mime; diff --git a/packaging/capi-media-codec.spec b/packaging/capi-media-codec.spec index 88d1a85..5c09524 100755 --- a/packaging/capi-media-codec.spec +++ b/packaging/capi-media-codec.spec @@ -4,7 +4,7 @@ Name: capi-media-codec Summary: A Media Codec library in Tizen Native API -Version: 0.5.11 +Version: 0.5.12 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index a9ea98a..5036d3e 100755 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -1257,6 +1257,7 @@ static gpointer feed_task(gpointer data) gst_object_unref(pad); is_format_change = TRUE; initiative = FALSE; + core->offset = GST_BUFFER_OFFSET_NONE; } if (is_format_change) { @@ -2450,6 +2451,11 @@ GstMCBuffer *_mc_gst_media_packet_to_gstbuffer(mc_gst_core_t *core, media_packet media_packet_get_duration(packet, &dur); GST_BUFFER_DURATION(mcbuffer->buffer) = dur; + GST_BUFFER_OFFSET(mcbuffer->buffer) = core->offset; + + core->offset += buf_size; + GST_BUFFER_OFFSET_END(mcbuffer->buffer) = core->offset; + return mcbuffer; } -- 2.7.4 From 41162f9d3827a7fa06a976ebbe0eca32e9354a70 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Thu, 3 May 2018 10:51:41 +0900 Subject: [PATCH 14/16] [ACR-1217] Added enum for resource conflict Change-Id: I5029960a6024f9b4710928808a555012f38476eb --- doc/media_codec_doc.h | 2 +- include/media_codec.h | 106 ++++++++++++++++++++++------------------ packaging/capi-media-codec.spec | 2 +- src/media_codec.c | 11 ++--- 4 files changed, 65 insertions(+), 56 deletions(-) diff --git a/doc/media_codec_doc.h b/doc/media_codec_doc.h index 36a1586..1c41347 100755 --- a/doc/media_codec_doc.h +++ b/doc/media_codec_doc.h @@ -35,7 +35,7 @@ * * @section CAPI_MEDIA_CODEC_FEATURE Related Features * This API is related with the following features:\n - * - %http://tizen.org/feature/multimedia.media_codec:\n + * - %http://tizen.org/feature/multimedia.media_codec\n * * It is recommended to design feature related codes in your application for reliability.\n * diff --git a/include/media_codec.h b/include/media_codec.h index 835cbec..5626215 100755 --- a/include/media_codec.h +++ b/include/media_codec.h @@ -43,7 +43,7 @@ extern "C" { typedef struct mediacodec_s *mediacodec_h; /** - * @brief Enumeration of media codec support type + * @brief Enumeration of media codec support type. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @remarks If this codec is to be used as an encoder or decoder, the codec flag must be set to #MEDIACODEC_ENCODER or * #MEDIACODEC_DECODER. If user doesn't set optional flag, default flags will be set to #MEDIACODEC_SUPPORT_TYPE_SW. @@ -56,7 +56,7 @@ typedef enum { } mediacodec_support_type_e; /** - * @brief Enumerations of media codec type + * @brief Enumerations of media codec type. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif */ typedef enum { @@ -94,7 +94,7 @@ typedef enum { } mediacodec_codec_type_e; /** - * @brief Enumeration of media codec error + * @brief Enumeration of media codec error. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif */ typedef enum { @@ -118,46 +118,54 @@ typedef enum { MEDIACODEC_ERROR_BUFFER_NOT_AVAILABLE = TIZEN_ERROR_MEDIACODEC | 0x0c, /**< Not available buffer */ MEDIACODEC_ERROR_OVERFLOW_INBUFFER = TIZEN_ERROR_MEDIACODEC | 0x0d, /**< Overflow input buffer (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ MEDIACODEC_ERROR_RESOURCE_OVERLOADED = TIZEN_ERROR_MEDIACODEC | 0x0e, /**< Exceed the instance limits (Since @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif)*/ + MEDIACODEC_ERROR_RESOURCE_CONFLICT = TIZEN_ERROR_MEDIACODEC | 0x0f, /**< Interrupted by a resource conflict (Since 5.0)*/ } mediacodec_error_e; /** - * @brief Enumeration of buffer status + * @brief Enumeration of buffer status. * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif */ typedef enum { - MEDIACODEC_NEED_DATA, - MEDIACODEC_ENOUGH_DATA + MEDIACODEC_NEED_DATA, /**< The internal queue is running out of data */ + MEDIACODEC_ENOUGH_DATA /**< The internal queue is full */ } mediacodec_status_e; /** - * @brief Called when the input buffer(pkt) used up. - * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @brief Called when the input buffer(packet) used up. * @details It will be invoked when mediacodec has used input buffer. - * @param[in] pkt The media packet handle + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks The @a packet should be released using media_packet_destroy(). + * @param[in] packet The media packet handle * @param[in] user_data The user data passed from the callback registration function * @pre It will be invoked when input buffer process completed if you register this callback using mediacodec_set_input_buffer_used_cb(). * @see mediacodec_set_input_buffer_used_cb() * @see mediacodec_unset_input_buffer_used_cb() */ -typedef void (*mediacodec_input_buffer_used_cb)(media_packet_h pkt, void *user_data); +typedef void (*mediacodec_input_buffer_used_cb)(media_packet_h packet, void *user_data); /** * @brief Called when the output buffer is available. - * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @details It will be invoked when mediacodec has output buffer. - * @param[in] pkt The media packet handle + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks The @a packet should be released using media_packet_destroy(). + * @param[in] packet The media packet handle * @param[in] user_data The user data passed from the callback registration function * @pre It will be invoked when mediacodec process completed(had output buffer) if you register this callback using mediacodec_set_fill_buffer_cb(). * @see mediacodec_set_output_buffer_available_cb() * @see mediacodec_unset_output_buffer_available_cb() */ -typedef void (*mediacodec_output_buffer_available_cb)(media_packet_h pkt, void *user_data); +typedef void (*mediacodec_output_buffer_available_cb)(media_packet_h packet, void *user_data); /** - * @brief Called when the error has occured - * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @brief Called when the error has occured. * @details It will be invoked when the error has occured. - * @param[in] error_code The error code + * Following error codes can be delivered. + * #MEDIACODEC_ERROR_INTERNAL, + * #MEDIACODEC_ERROR_INVALID_STREAM, + * #MEDIACODEC_ERROR_NOT_SUPPORTED_FORMAT, + * #MEDIACODEC_ERROR_RESOURCE_CONFLICT + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @param[in] error The error code * @param[in] user_data The user data passed from the callback registration function * @pre It will be invoked when the error has occured if you register this callback using mediacodec_set_error_cb(). * @see mediacodec_set_error_cb() @@ -166,9 +174,9 @@ typedef void (*mediacodec_output_buffer_available_cb)(media_packet_h pkt, void * typedef void (*mediacodec_error_cb)(mediacodec_error_e error, void *user_data); /** - * @brief Called when there is no data to decode/encode - * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @brief Called when there is no data to decode/encode. * @details It will be invoked when the end-of-stream is reached. + * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] user_data The user data passed from the callback registration function * @pre It will be invoked when the eos event generate if you register this callback using mediacodec_set_eos_cb(). * @see mediacodec_set_eos_cb() @@ -178,9 +186,10 @@ typedef void (*mediacodec_eos_cb)(void *user_data); /** * @brief Called when the mediacodec needs more data or has enough data. + * @details It is recommended that the application stops calling mediacodec_process_input() when #MEDIACODEC_ENOUGH_DATA * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif - * @details It is recommended that the application stops calling mediacodec_process_input() when MEDIACODEC_ENOUGH_DATA * is invoked. + * @param[in] status The state of the buffer * @param[in] user_data The user data passed from the callback registration function * @see mediacodec_set_buffer_status_cb() * @see mediacodec_unset_buffer_status_cb() @@ -199,7 +208,7 @@ typedef void (*mediacodec_buffer_status_cb)(mediacodec_status_e status, void *us typedef bool (*mediacodec_supported_codec_cb)(mediacodec_codec_type_e codec_type, void *user_data); /** - * @brief Creates a mediacodec handle for decoding/encoding + * @brief Creates a mediacodec handle for decoding/encoding. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @remarks you must release @a mediacodec using mediacodec_destroy().\n * Although you can create multiple mediacodec handles at the same time, @@ -253,7 +262,7 @@ int mediacodec_destroy(mediacodec_h mediacodec); int mediacodec_set_codec(mediacodec_h mediacodec, mediacodec_codec_type_e codec_type, int flags); /** - * @brief Sets the default info for the video decoder + * @brief Sets the default info for the video decoder. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] mediacodec The handle to mediacodec * @param[in] width The width for video decoding. @@ -268,7 +277,7 @@ int mediacodec_set_codec(mediacodec_h mediacodec, mediacodec_codec_type_e codec_ int mediacodec_set_vdec_info(mediacodec_h mediacodec, int width, int height); /** - * @brief Sets the default info for the video encoder + * @brief Sets the default info for the video encoder. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @remarks The frame rate is the speed of recording and the speed of playback. * If user wants the default setting for ratecontrol, set @a target_bits to @c 0. @@ -287,7 +296,7 @@ int mediacodec_set_vdec_info(mediacodec_h mediacodec, int width, int height); int mediacodec_set_venc_info(mediacodec_h mediacodec, int width, int height, int fps, int target_bits); /** - * @brief Sets the default info for the audio decoder + * @brief Sets the default info for the audio decoder. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] mediacodec The handle to mediacodec * @param[in] samplerate The samplerate for audio decoding. @@ -303,7 +312,7 @@ int mediacodec_set_venc_info(mediacodec_h mediacodec, int width, int height, int int mediacodec_set_adec_info(mediacodec_h mediacodec, int samplerate, int channel, int bit); /** - * @brief Sets the default info for the audio encoder + * @brief Sets the default info for the audio encoder. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] mediacodec The handle to mediacodec * @param[in] samplerate The samplerate for audio encoding. @@ -368,6 +377,8 @@ int mediacodec_configure_from_media_format(mediacodec_h mediacodec, media_format * @retval #MEDIACODEC_ERROR_OUT_OF_MEMORY Out of memory * @retval #MEDIACODEC_ERROR_INVALID_OPERATION Invalid operation * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) + * @retval #MEDIACODEC_ERROR_RESOURCE_OVERLOADED Exceed the instance limits (Since 5.0) + * @retval #MEDIACODEC_ERROR_INTERNAL Internal error (Since 5.0) * @pre The mediacodec should call mediacodec_set_codec()and mediacodec_set_vdec_info()/mediacodec_set_venc_info() before calling mediacodec_prepare() * If the decoder is set by mediacodec_set_codec(), mediacodec_set_vdec_info() should be called. If the encoder is set by * mediacodec_set_codec(), mediacodec_set_venc_info() should be called. @@ -408,8 +419,9 @@ int mediacodec_process_input(mediacodec_h mediacodec, media_packet_h inbuf, uint /** * @brief Gets the decoded or encoded packet from the output queue. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif + * @remarks The @a packet should be released using media_packet_destroy(). * @param[in] mediacodec The handle to mediacodec - * @param[out] outbuf The current output of the decoder/encoder. + * @param[out] packet The current output of the decoder/encoder. * this function passed decoded/encoded frame to output queue. * @param[in] timeOutUs The timeout in microseconds. \n * The input buffer wait up to "timeOutUs" microseconds. @@ -420,7 +432,7 @@ int mediacodec_process_input(mediacodec_h mediacodec, media_packet_h inbuf, uint * @retval #MEDIACODEC_ERROR_INVALID_OPERATION Invalid operation * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) */ -int mediacodec_get_output(mediacodec_h mediacodec, media_packet_h *outbuf, uint64_t timeOutUs); +int mediacodec_get_output(mediacodec_h mediacodec, media_packet_h *packet, uint64_t timeOutUs); /** * @brief Flushes both input and output buffers. @@ -434,7 +446,7 @@ int mediacodec_get_output(mediacodec_h mediacodec, media_packet_h *outbuf, uint6 int mediacodec_flush_buffers(mediacodec_h mediacodec); /** - * @brief set empty buffer callback the media codec for process, asynchronously. + * @brief Sets empty buffer callback the media codec for process, asynchronously. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] mediacodec The handle to mediacodec * @param[in] callback The callback function to register @@ -443,15 +455,15 @@ int mediacodec_flush_buffers(mediacodec_h mediacodec); * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) - * @pre mediacodec_set_input_buffer_used_cb should be called before mediacodec_preare(). - * @post mediacodec_input_buffer_used_cb will be invoked. + * @pre mediacodec_set_input_buffer_used_cb() should be called before mediacodec_preare(). + * @post mediacodec_input_buffer_used_cb() will be invoked. * @see mediacodec_set_input_buffer_used_cb() * @see mediacodec_unset_input_buffer_used_cb() */ int mediacodec_set_input_buffer_used_cb(mediacodec_h mediacodec, mediacodec_input_buffer_used_cb callback, void* user_data); /** - * @brief unset input buffer used callback the media codec for process, asynchronously. + * @brief Unsets input buffer used callback the media codec for process, asynchronously. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] mediacodec The handle to mediacodec * @return @c 0 on success, otherwise a negative error value @@ -463,7 +475,7 @@ int mediacodec_set_input_buffer_used_cb(mediacodec_h mediacodec, mediacodec_inpu int mediacodec_unset_input_buffer_used_cb(mediacodec_h mediacodec); /** - * @brief set output buffer available callback the media codec for process, asynchronously. + * @brief Sets output buffer available callback the media codec for process, asynchronously. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] mediacodec The handle to mediacodec * @param[in] callback The callback function to register @@ -472,15 +484,15 @@ int mediacodec_unset_input_buffer_used_cb(mediacodec_h mediacodec); * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) - * @pre mediacodec_set_output_buffer_available_cb should be called before mediacodec_preare(). - * @post mediacodec_output_buffer_available_cb will be invoked. + * @pre mediacodec_set_output_buffer_available_cb() should be called before mediacodec_preare(). + * @post mediacodec_output_buffer_available_cb() will be invoked. * @see mediacodec_set_output_buffer_available_cb() * @see mediacodec_unset_output_buffer_available_cb() */ int mediacodec_set_output_buffer_available_cb(mediacodec_h mediacodec, mediacodec_output_buffer_available_cb callback, void* user_data); /** - * @brief unset output buffer available callback the media codec for process, asynchronously. + * @brief unsets output buffer available callback the media codec for process, asynchronously. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] mediacodec The handle to mediacodec * @return @c 0 on success, otherwise a negative error value @@ -492,7 +504,7 @@ int mediacodec_set_output_buffer_available_cb(mediacodec_h mediacodec, mediacode int mediacodec_unset_output_buffer_available_cb(mediacodec_h mediacodec); /** - * @brief set error callback the media codec for process, asynchronously. + * @brief Sets error callback the media codec for process, asynchronously. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] mediacodec The handle to mediacodec * @param[in] callback The callback function to register @@ -501,15 +513,15 @@ int mediacodec_unset_output_buffer_available_cb(mediacodec_h mediacodec); * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) - * @pre mediacodec_set_error_cb should be called before mediacodec_preare(). - * @post mediacodec_error_cb will be invoked. + * @pre mediacodec_set_error_cb() should be called before mediacodec_preare(). + * @post mediacodec_error_cb() will be invoked. * @see mediacodec_set_error_cb() * @see mediacodec_unset_error_cb() */ int mediacodec_set_error_cb(mediacodec_h mediacodec, mediacodec_error_cb callback, void* user_data); /** - * @brief unset error callback the media codec for process, asynchronously. + * @brief Unsets error callback the media codec for process, asynchronously. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] mediacodec The handle to mediacodec * @return @c 0 on success, otherwise a negative error value @@ -521,7 +533,7 @@ int mediacodec_set_error_cb(mediacodec_h mediacodec, mediacodec_error_cb callbac int mediacodec_unset_error_cb(mediacodec_h mediacodec); /** - * @brief set eos callback the media codec for process, asynchronously. + * @brief Sets eos callback the media codec for process, asynchronously. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] mediacodec The handle to mediacodec * @param[in] callback The callback function to register @@ -530,15 +542,15 @@ int mediacodec_unset_error_cb(mediacodec_h mediacodec); * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) - * @pre mediacodec_set_eos_cb should be called before mediacodec_preare(). - * @post mediacodec_eos_cb will be invoked. + * @pre mediacodec_set_eos_cb() should be called before mediacodec_preare(). + * @post mediacodec_eos_cb() will be invoked. * @see mediacodec_set_eos_cb() * @see mediacodec_unset_eos_cb() */ int mediacodec_set_eos_cb(mediacodec_h mediacodec, mediacodec_eos_cb callback, void* user_data); /** - * @brief unset eos callback the media codec for process, asynchronously. + * @brief unsets eos callback the media codec for process, asynchronously. * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif * @param[in] mediacodec The handle to mediacodec * @return @c 0 on success, otherwise a negative error value @@ -550,7 +562,7 @@ int mediacodec_set_eos_cb(mediacodec_h mediacodec, mediacodec_eos_cb callback, v int mediacodec_unset_eos_cb(mediacodec_h mediacodec); /** - * @brief Registers a callback function to be invoked when the mediacodec needs more data or has enough data. + * @brief Sets a callback function to be invoked when the mediacodec needs more data or has enough data. * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif * @param[in] mediacodec The handle to mediacodec * @param[in] callback The callback function to register @@ -559,15 +571,15 @@ int mediacodec_unset_eos_cb(mediacodec_h mediacodec); * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE Not supported on device (Since 4.0) - * @pre mediacodec_set_buffer_status_cb should be called before mediacodec_preare(). - * @post mediacodec_buffer_status_cb will be invoked. + * @pre mediacodec_set_buffer_status_cb() should be called before mediacodec_preare(). + * @post mediacodec_buffer_status_cb() will be invoked. * @see mediacodec_set_buffer_status_cb() * @see mediacodec_unset_buffer_status_cb() */ int mediacodec_set_buffer_status_cb(mediacodec_h mediacodec, mediacodec_buffer_status_cb callback, void* user_data); /** - * @brief Unregisters the callback function. + * @brief Unsets the callback function. * @since_tizen @if MOBILE 2.4 @elseif WEARABLE 3.0 @endif * @param[in] mediacodec The handle to mediacodec * @return @c 0 on success, otherwise a negative error value @@ -597,7 +609,7 @@ int mediacodec_foreach_supported_codec(mediacodec_h mediacodec, mediacodec_suppo * @param[in] mediacodec The handle to mediacodec * @param[in] codec_type The identifier of the codec type of the encoder. * @param[in] encoder Whether the encoder or decoder : (@c true = encoder, @c false = decoder). - * @param[out] support_type (@c MEDIACODEC_SUPPORT_TYPE_HW = mediacodec can be performed with hardware codec, @c MEDIACODEC_SUPPORT_TYPE_SW = mediacodec can be performed with software codec) + * @param[out] support_type (@c #MEDIACODEC_SUPPORT_TYPE_HW = mediacodec can be performed with hardware codec, @c #MEDIACODEC_SUPPORT_TYPE_SW = mediacodec can be performed with software codec) * @return @c 0 on success, otherwise a negative error value * @retval #MEDIACODEC_ERROR_NONE Successful * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter diff --git a/packaging/capi-media-codec.spec b/packaging/capi-media-codec.spec index 5c09524..daabadd 100755 --- a/packaging/capi-media-codec.spec +++ b/packaging/capi-media-codec.spec @@ -4,7 +4,7 @@ Name: capi-media-codec Summary: A Media Codec library in Tizen Native API -Version: 0.5.12 +Version: 0.5.13 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/media_codec.c b/src/media_codec.c index 526c1b3..b76269a 100644 --- a/src/media_codec.c +++ b/src/media_codec.c @@ -327,6 +327,7 @@ int mediacodec_prepare(mediacodec_h mediacodec) 1, &resource); if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) switch (rm_ret) { + LOGE("Failed to acquire resource manager %x", rm_ret); case MM_RESOURCE_MANAGER_ERROR_NOT_SUPPORTED: return MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE; case MM_RESOURCE_MANAGER_ERROR_NOT_ENOUGH: @@ -338,12 +339,8 @@ int mediacodec_prepare(mediacodec_h mediacodec) rm_ret = mm_resource_manager_commit(resource_manager); if (rm_ret != MM_RESOURCE_MANAGER_ERROR_NONE) { mm_resource_manager_mark_for_release(resource_manager, resource); - switch (rm_ret) { - case MM_RESOURCE_MANAGER_ERROR_LOW_PRIORITY: - return MEDIACODEC_ERROR_RESOURCE_OVERLOADED; - default: - return MEDIACODEC_ERROR_INTERNAL; - } + LOGE("Failed to commit resource manager : %x", rm_ret); + return MEDIACODEC_ERROR_INTERNAL; } handle->codec_resource = resource; @@ -711,7 +708,7 @@ static int __mediacodec_resource_release_cb(mm_resource_manager_h rm, */ handle->codec_resource = NULL; mediacodec_unprepare((mediacodec_h)handle); - __mediacodec_error_cb(MEDIACODEC_ERROR_RESOURCE_OVERLOADED, handle); + __mediacodec_error_cb(MEDIACODEC_ERROR_RESOURCE_CONFLICT, handle); break; } } -- 2.7.4 From 40784902baada12295340f66f82df0d2397d53a3 Mon Sep 17 00:00:00 2001 From: Sejun Park Date: Tue, 21 Aug 2018 17:58:03 +0900 Subject: [PATCH 15/16] Apply tizen allocator to mediacodec Change-Id: I4304b314d499fb53d694b330eaf391cccbc54c98 --- CMakeLists.txt | 4 +- include/media_codec_port_gst.h | 2 + packaging/capi-media-codec.spec | 2 +- src/media_codec_port_gst.c | 214 ++++++++++------------------------------ 4 files changed, 55 insertions(+), 167 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dc41164..217ee07 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,8 +10,8 @@ SET(PREFIX ${CMAKE_INSTALL_PREFIX}) SET(INC_DIR include) INCLUDE_DIRECTORIES(${INC_DIR}) -SET(dependents "dlog glib-2.0 mm-common libtbm capi-media-tool iniparser gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 capi-system-info mm-resource-manager" ) -SET(pc_dependents "capi-base-common capi-media-tool gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 mm-resource-manager" ) +SET(dependents "dlog glib-2.0 mm-common libtbm capi-media-tool iniparser gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 capi-system-info mm-resource-manager gstreamer-allocators-1.0" ) +SET(pc_dependents "capi-base-common capi-media-tool gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0 mm-resource-manager gstreamer-allocators-1.0" ) INCLUDE(FindPkgConfig) pkg_check_modules(${fw_name} REQUIRED ${dependents}) diff --git a/include/media_codec_port_gst.h b/include/media_codec_port_gst.h index 2888192..18010d4 100755 --- a/include/media_codec_port_gst.h +++ b/include/media_codec_port_gst.h @@ -30,6 +30,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -151,6 +152,7 @@ struct _mc_gst_core_t { GstBuffer *codec_data; GstCaps* (*mc_caps_new)(mc_gst_core_t *, mediacodec_codec_type_e, gint); + GstAllocator *allocator; void* user_cb[_MEDIACODEC_EVENT_TYPE_NUM]; void* user_data[_MEDIACODEC_EVENT_TYPE_NUM]; diff --git a/packaging/capi-media-codec.spec b/packaging/capi-media-codec.spec index daabadd..6f405a3 100755 --- a/packaging/capi-media-codec.spec +++ b/packaging/capi-media-codec.spec @@ -4,7 +4,7 @@ Name: capi-media-codec Summary: A Media Codec library in Tizen Native API -Version: 0.5.13 +Version: 0.6.0 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c index 5036d3e..5d09f4b 100755 --- a/src/media_codec_port_gst.c +++ b/src/media_codec_port_gst.c @@ -48,7 +48,7 @@ static gchar *__mc_get_gst_input_format(media_format_mimetype_e mimetype, bool i static GstMCBuffer *__mc_gst_make_media_packet(mc_gst_core_t *core, GstBuffer *buffer); static gboolean __mc_gst_bus_callback(GstBus *bus, GstMessage *msg, gpointer data); static GstBusSyncReply __mc_gst_bus_sync_callback(GstBus *bus, GstMessage *msg, gpointer data); -static MMVideoBuffer *__mc_gst_make_tbm_buffer(mc_gst_core_t *core, media_packet_h packet); +static GstMemory *__mc_gst_make_tbm_buffer(mc_gst_core_t *core, GstMCBuffer *mcbuffer); static GstMCBuffer *gst_mediacodec_buffer_new(mc_gst_core_t *core, media_packet_h packet, uint64_t size); static void __mc_input_buffer_finalize_cb(GstMCBuffer *buffer); static int __mc_set_caps_streamheader(mc_gst_core_t *core, GstMCBuffer *mcbuffer, guint streamheader_size); @@ -168,7 +168,7 @@ int __mc_fill_inbuf_with_mm_video_buffer(mc_gst_core_t *core, media_packet_h pac { gint ret = MC_ERROR_NONE; uint64_t buf_size = 0; - MMVideoBuffer *mm_vbuffer = NULL; + GstMemory *mem; void *buf_data = NULL; ret = media_packet_get_buffer_size(packet, &buf_size); @@ -183,21 +183,15 @@ int __mc_fill_inbuf_with_mm_video_buffer(mc_gst_core_t *core, media_packet_h pac return MC_ERROR; } - mm_vbuffer = __mc_gst_make_tbm_buffer(core, mcbuffer->packet); - - if (mm_vbuffer != NULL) { - gst_buffer_prepend_memory(mcbuffer->buffer, - gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, mm_vbuffer, sizeof(*mm_vbuffer), 0, - sizeof(*mm_vbuffer), mm_vbuffer, free)); - LOGD("mm_vbuffer appended, %d, %d", sizeof(*mm_vbuffer), gst_buffer_n_memory(mcbuffer->buffer)); + mem = __mc_gst_make_tbm_buffer(core, mcbuffer); + if (mem == NULL) { + LOGW("Failed to make tizen memory"); + return MC_ERROR; } - if (buf_data != NULL) { - gst_buffer_prepend_memory(mcbuffer->buffer, - gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, buf_data, buf_size, 0, - buf_size, mcbuffer, (GDestroyNotify)__mc_input_buffer_finalize_cb)); - LOGD("packet data apended, %d, %d", buf_size, gst_buffer_n_memory(mcbuffer->buffer)); - } + gst_buffer_append_memory(mcbuffer->buffer, mem); + LOGD("tizen memory appended"); + return ret; } @@ -359,21 +353,17 @@ int __mc_fill_input_buffer_with_venc_packet(mc_gst_core_t *core, media_packet_h } } } else { - MMVideoBuffer *mm_video_buffer = NULL; - - mm_video_buffer = __mc_gst_make_tbm_buffer(core, packet); + GstMemory *mem = NULL; - gst_buffer_prepend_memory(mcbuffer->buffer, - gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, mm_video_buffer, sizeof(MMVideoBuffer), 0, - sizeof(MMVideoBuffer), mm_video_buffer, free)); + mem = __mc_gst_make_tbm_buffer(core, mcbuffer); + if (mem == NULL) { + LOGW("Failed to make tizen memory"); + return MC_ERROR; + } - LOGD("mm_video_buffer appended, %d, %d", sizeof(MMVideoBuffer), gst_buffer_n_memory(mcbuffer->buffer)); + gst_buffer_append_memory(mcbuffer->buffer, mem); + LOGD("tizen memory appended"); } - - gst_buffer_prepend_memory(mcbuffer->buffer, - gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, planes[0], mcbuffer->buf_size, 0, - mcbuffer->buf_size, mcbuffer, (GDestroyNotify)__mc_input_buffer_finalize_cb)); - return ret; } @@ -447,45 +437,7 @@ int __mc_fill_vdec_packet_with_output_buffer(mc_gst_core_t *core, void *data, in tsurf = tbm_surface_internal_create_with_bos(&tsurf_info, bo, 1); } else { - int bo_num = 0; - MMVideoBuffer *mm_vbuffer = NULL; - mm_vbuffer = (MMVideoBuffer *)data; - - if (mm_vbuffer->type == MM_VIDEO_BUFFER_TYPE_TBM_BO) { - tbm_surface_info_s tsurf_info; - memset(&tsurf_info, 0x0, sizeof(tbm_surface_info_s)); - - /* create tbm surface */ - for (i = 0; i < MM_VIDEO_BUFFER_PLANE_MAX; i++) { - if (mm_vbuffer->handle.bo[i]) { - bo_num++; - tsurf_info.planes[i].stride = mm_vbuffer->stride_width[i]; - } - } - - if (bo_num > 0) { - tsurf_info.width = port_def->info.video.width; - tsurf_info.height = port_def->info.video.height; - tsurf_info.format = TBM_FORMAT_NV12; /* bo_format */ - tsurf_info.bpp = tbm_surface_internal_get_bpp(TBM_FORMAT_NV12); - tsurf_info.num_planes = tbm_surface_internal_get_num_planes(TBM_FORMAT_NV12); - tsurf_info.size = 0; - - for (i = 0; i < tsurf_info.num_planes; i++) { - tsurf_info.planes[i].stride = mm_vbuffer->stride_width[i]; - tsurf_info.planes[i].size = mm_vbuffer->stride_width[i] * mm_vbuffer->stride_height[i]; - - if (i < bo_num) - tsurf_info.planes[i].offset = 0; - else - tsurf_info.planes[i].offset = tsurf_info.planes[i-1].offset + tsurf_info.planes[i - 1].size; - - tsurf_info.size += tsurf_info.planes[i].size; - LOGD("%d plane stride : %d, size : %d", i, tsurf_info.planes[i].stride, tsurf_info.planes[i].size); - } - tsurf = tbm_surface_internal_create_with_bos(&tsurf_info, (tbm_bo *)mm_vbuffer->handle.bo, bo_num); - } - } + tsurf = (tbm_surface_h)data; } if (tsurf) { @@ -966,6 +918,7 @@ mc_gst_core_t *mc_gst_core_new() g_atomic_int_set(&core->available_queue->running, 1); core->available_queue->thread = g_thread_new("feed thread", &feed_task, core); + core->allocator = gst_tizen_allocator_new(); core->bufmgr = NULL; core->drm_fd = -1; @@ -999,6 +952,11 @@ void mc_gst_core_free(mc_gst_core_t *core) mc_async_queue_free(async_queue->input); g_free(async_queue); + if (core->allocator) { + gst_object_unref(core->allocator); + core->allocator = NULL; + } + if (core->codec_data) gst_buffer_unref(core->codec_data); @@ -2328,36 +2286,11 @@ void __mc_gst_buffer_add(GstElement *element, GstBuffer *buffer, GstPad *pad, gp int __mc_output_buffer_finalize_cb(media_packet_h packet, int error_code, void *user_data) { - int i = 0; - guint n; - GstMemory *mem; - GstMapInfo map = GST_MAP_INFO_INIT; - MMVideoBuffer *mm_video_buf = NULL; - MEDIACODEC_FENTER(); GstMCBuffer *mcbuffer = (GstMCBuffer *)user_data; - if (mcbuffer->buffer) { - n = gst_buffer_n_memory(mcbuffer->buffer); - - if (n > 1) { - mem = gst_buffer_peek_memory(mcbuffer->buffer, n-1); - gst_memory_map(mem, &map, GST_MAP_READ); - mm_video_buf = (MMVideoBuffer *)map.data; - - if (!mm_video_buf) { - LOGW("gstbuffer map.data is null"); - } else { - for (i = 0; i < MM_VIDEO_BUFFER_PLANE_MAX; i++) { - if (mm_video_buf->handle.bo[i]) - tbm_bo_unref(mm_video_buf->handle.bo[i]); - } - } - gst_memory_unmap(mem, &map); - } - gst_buffer_unref((GstBuffer *)mcbuffer->buffer); - } + gst_buffer_unref((GstBuffer *)mcbuffer->buffer); if (mcbuffer->ext_mem) { g_free(mcbuffer->ext_mem); @@ -2462,10 +2395,12 @@ GstMCBuffer *_mc_gst_media_packet_to_gstbuffer(mc_gst_core_t *core, media_packet GstMCBuffer *__mc_gst_make_media_packet(mc_gst_core_t *core, GstBuffer *buffer) { gint ret = MEDIA_PACKET_ERROR_NONE; - guint n; GstMemory *mem; GstMapInfo map = GST_MAP_INFO_INIT; GstMCBuffer *mcbuffer = NULL; + void *data = NULL; + gint size = 0; + mcbuffer = (GstMCBuffer *)g_malloc0(sizeof(*mcbuffer)); @@ -2474,24 +2409,27 @@ GstMCBuffer *__mc_gst_make_media_packet(mc_gst_core_t *core, GstBuffer *buffer) return NULL; } - n = gst_buffer_n_memory(buffer); + mem = gst_buffer_peek_memory(buffer, 0); - mem = gst_buffer_peek_memory(buffer, n-1); - - gst_memory_map(mem, &map, GST_MAP_READ); + if (gst_is_tizen_memory(mem)) { + data = (void *)gst_tizen_memory_get_surface(mem); + size = tbm_surface_internal_get_size((tbm_surface_h)data); + } else { + gst_memory_map(mem, &map, GST_MAP_READ); + data = map.data; + size = map.size; + gst_memory_unmap(mem, &map); + } mcbuffer->buffer = buffer; mcbuffer->core = core; - mcbuffer->buf_size = map.size; + mcbuffer->buf_size = size; - LOGD("n : %d, map.data : %p, map.size : %d", n, map.data, map.size); - ret = __mc_fill_output_buffer(core, map.data, map.size, mcbuffer); + ret = __mc_fill_output_buffer(core, data, mcbuffer->buf_size, mcbuffer); if (ret != MC_ERROR_NONE) { LOGW("failed to fill outbuf: %s (ox%08x)", _mc_error_to_string(ret), ret); - gst_memory_unmap(mem, &map); return NULL; } - gst_memory_unmap(mem, &map); return mcbuffer; } @@ -2689,85 +2627,33 @@ static GstBusSyncReply __mc_gst_bus_sync_callback(GstBus *bus, GstMessage *msg, return reply; } -static MMVideoBuffer *__mc_gst_make_tbm_buffer(mc_gst_core_t *core, media_packet_h packet) +static GstMemory *__mc_gst_make_tbm_buffer(mc_gst_core_t *core, GstMCBuffer *mcbuffer) { - gint i; - gint num_bos; - gint err; int ret = MEDIA_PACKET_ERROR_NONE; tbm_surface_h surface = NULL; - tbm_surface_info_s surface_info; - tbm_bo_handle handle_bo; + GstVideoInfo vinfo; + GstMemory *mem = NULL; - if (!packet) { + if (!mcbuffer->packet) { LOGE("output is null"); return NULL; } - MMVideoBuffer *mm_vbuffer = NULL; - mm_vbuffer = (MMVideoBuffer *)malloc(sizeof(MMVideoBuffer)); - if (!mm_vbuffer) { - LOGE("Failed to alloc MMVideoBuffer"); - return NULL; - } - memset(mm_vbuffer, 0x00, sizeof(MMVideoBuffer)); - - ret = media_packet_get_tbm_surface(packet, &surface); + ret = media_packet_get_tbm_surface(mcbuffer->packet, &surface); if (ret != MEDIA_PACKET_ERROR_NONE) { LOGE("Failed to get tbm surface"); - free(mm_vbuffer); return NULL; } - num_bos = tbm_surface_internal_get_num_bos(surface); - err = tbm_surface_get_info((tbm_surface_h)surface, &surface_info); - if (err != TBM_SURFACE_ERROR_NONE) { - LOGE("get tbm surface is failed"); - free(mm_vbuffer); + if (!gst_video_info_from_caps(&vinfo, core->caps)) { + LOGE("Failed to get video info"); return NULL; } - for (i = 0; i < num_bos; i++) { - mm_vbuffer->handle.bo[i] = tbm_surface_internal_get_bo(surface, i); - LOGD("mm_vbuffer->handle.bo[%d] : %p", i, mm_vbuffer->handle.bo[i]); - tbm_bo_map(mm_vbuffer->handle.bo[i], TBM_DEVICE_CPU, TBM_OPTION_READ); - tbm_bo_unmap(mm_vbuffer->handle.bo[i]); - } - - mm_vbuffer->type = MM_VIDEO_BUFFER_TYPE_TBM_BO; - mm_vbuffer->width[0] = surface_info.width; - mm_vbuffer->height[0] = surface_info.height; - mm_vbuffer->width[1] = surface_info.width; - mm_vbuffer->height[1] = surface_info.height>>1; - mm_vbuffer->size[0] = surface_info.planes[0].size; - mm_vbuffer->size[1] = surface_info.planes[1].size; - mm_vbuffer->stride_width[0] = surface_info.planes[0].stride; - mm_vbuffer->stride_height[0] = surface_info.planes[0].size / surface_info.planes[0].stride; - mm_vbuffer->stride_width[1] = surface_info.planes[1].stride; - mm_vbuffer->stride_height[1] = surface_info.planes[1].size / surface_info.planes[1].stride; - - if (mm_vbuffer->handle.bo[0]) { - handle_bo = tbm_bo_get_handle(mm_vbuffer->handle.bo[0], TBM_DEVICE_CPU); - mm_vbuffer->data[0] = handle_bo.ptr; - - handle_bo = tbm_bo_get_handle(mm_vbuffer->handle.bo[0], TBM_DEVICE_MM); - mm_vbuffer->handle.dmabuf_fd[0] = handle_bo.u32; - } - - if (mm_vbuffer->handle.bo[1]) { - handle_bo = tbm_bo_get_handle(mm_vbuffer->handle.bo[1], TBM_DEVICE_CPU); - mm_vbuffer->data[1] = handle_bo.ptr; - - handle_bo = tbm_bo_get_handle(mm_vbuffer->handle.bo[1], TBM_DEVICE_MM); - mm_vbuffer->handle.dmabuf_fd[1] = handle_bo.u32; - } else { - mm_vbuffer->data[1] = mm_vbuffer->data[0] + mm_vbuffer->stride_width[0] * mm_vbuffer->stride_height[0]; - } - mm_vbuffer->plane_num = 2; - - LOGD("size[0] : %d, size[1] : %d, bo[0] :%p, bo[1] :%p", mm_vbuffer->size[0], mm_vbuffer->size[1], mm_vbuffer->handle.bo[0], mm_vbuffer->handle.bo[1]); + mem = gst_tizen_allocator_alloc_surface(core->allocator, + &vinfo, surface, mcbuffer, (GDestroyNotify)__mc_input_buffer_finalize_cb); - return mm_vbuffer; + return mem; } static void __mc_input_buffer_finalize_cb(GstMCBuffer *mcbuffer) -- 2.7.4 From e5dd80e572cb291e38f157d85208ef7f9f9c84fa Mon Sep 17 00:00:00 2001 From: SeokHoon Lee Date: Tue, 18 Sep 2018 17:09:02 +0900 Subject: [PATCH 16/16] Add gcov environment Signed-off-by: SeokHoon Lee Change-Id: I22f77c8cffa0ad72d5d377fa5cb1db43dc143e9b --- packaging/capi-media-codec.spec | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packaging/capi-media-codec.spec b/packaging/capi-media-codec.spec index 6f405a3..f74b8b7 100755 --- a/packaging/capi-media-codec.spec +++ b/packaging/capi-media-codec.spec @@ -47,6 +47,12 @@ Requires: %{name} = %{version}-%{release} export CFLAGS="$CFLAGS -DSYSCONFDIR=\\\"%{_sysconfdir}\\\"" +%if 0%{?gcov:1} +export CFLAGS+=" -fprofile-arcs -ftest-coverage" +export CXXFLAGS+=" -fprofile-arcs -ftest-coverage" +export LDFLAGS+=" -lgcov" +%endif + MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` %cmake . -DCMAKE_INSTALL_PREFIX=/usr -DFULLVER=%{version} -DMAJORVER=${MAJORVER} -- 2.7.4