summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjk7744.park <jk7744.park@samsung.com>2015-10-24 16:24:05 +0900
committerjk7744.park <jk7744.park@samsung.com>2015-10-24 16:24:05 +0900
commit7a70cadf0d29290af314cb8852108d900efff74d (patch)
tree292c8ed343896ef66648d5f3a17b81ea0c93f152
parent76414ed7332777509a4c804fe5ea97a6400ee181 (diff)
downloadmediacodec-accepted/tizen_2.4_mobile.tar.gz
mediacodec-accepted/tizen_2.4_mobile.tar.bz2
mediacodec-accepted/tizen_2.4_mobile.zip
-rw-r--r--AUTHORS3
-rw-r--r--[-rwxr-xr-x]CMakeLists.txt6
-rw-r--r--capi-media-codec.manifest2
-rwxr-xr-xinclude/media_codec.h326
-rwxr-xr-xinclude/media_codec_bitstream.h113
-rwxr-xr-xinclude/media_codec_ini.h103
-rwxr-xr-xinclude/media_codec_port.h62
-rwxr-xr-xinclude/media_codec_port_gst.h163
-rwxr-xr-xinclude/media_codec_private.h6
-rwxr-xr-xinclude/media_codec_queue.h2
-rwxr-xr-xinclude/media_codec_spec_emul.h32
-rwxr-xr-xinclude/media_codec_util.h13
-rwxr-xr-xpackaging/capi-media-codec.spec25
-rwxr-xr-xsrc/media_codec.c310
-rwxr-xr-xsrc/media_codec_bitstream.c372
-rwxr-xr-xsrc/media_codec_ini.c571
-rwxr-xr-xsrc/media_codec_port.c683
-rwxr-xr-xsrc/media_codec_port_gst.c3018
-rwxr-xr-xsrc/media_codec_queue.c80
-rwxr-xr-xsrc/media_codec_util.c26
-rw-r--r--test/CMakeLists.txt1
-rwxr-xr-xtest/media_codec_test.c1245
-rw-r--r--test/test_samples/sample_mpeg4/00000bin0 -> 556 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00001bin0 -> 53 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00002bin0 -> 129 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00003bin0 -> 139 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00004bin0 -> 143 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00005bin0 -> 156 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00006bin0 -> 32 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00007bin0 -> 38 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00008bin0 -> 43 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00009bin0 -> 37 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00010bin0 -> 36 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00011bin0 -> 30 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00012bin0 -> 166 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00013bin0 -> 101 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00014bin0 -> 123 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00015bin0 -> 763 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00016bin0 -> 112 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00017bin0 -> 106 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00018bin0 -> 112 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00019bin0 -> 105 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00020bin0 -> 95 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00021bin0 -> 126 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00022bin0 -> 141 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00023bin0 -> 70 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00024bin0 -> 123 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00025bin0 -> 118 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00026bin0 -> 243 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00027bin0 -> 279 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00028bin0 -> 253 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00029bin0 -> 188 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00030bin0 -> 736 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00031bin0 -> 105 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00032bin0 -> 168 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00033bin0 -> 201 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00034bin0 -> 183 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00035bin0 -> 211 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00036bin0 -> 221 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00037bin0 -> 275 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00038bin0 -> 262 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00039bin0 -> 266 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00040bin0 -> 364 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00041bin0 -> 446 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00042bin0 -> 578 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00043bin0 -> 643 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00044bin0 -> 726 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00045bin0 -> 1856 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00046bin0 -> 815 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00047bin0 -> 947 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00048bin0 -> 974 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00049bin0 -> 1124 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00050bin0 -> 1290 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00051bin0 -> 1341 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00052bin0 -> 1347 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00053bin0 -> 1616 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00054bin0 -> 1591 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00055bin0 -> 1769 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00056bin0 -> 1778 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00057bin0 -> 1676 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00058bin0 -> 1801 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00059bin0 -> 1992 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00060bin0 -> 3145 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00061bin0 -> 3051 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00062bin0 -> 2365 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00063bin0 -> 2327 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00064bin0 -> 2276 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00065bin0 -> 1769 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00066bin0 -> 2678 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00067bin0 -> 1919 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00068bin0 -> 2062 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00069bin0 -> 2134 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00070bin0 -> 2084 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00071bin0 -> 2190 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00072bin0 -> 2125 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00073bin0 -> 2315 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00074bin0 -> 2282 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00075bin0 -> 7781 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00076bin0 -> 2581 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00077bin0 -> 2977 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00078bin0 -> 3269 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00079bin0 -> 3460 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00080bin0 -> 3535 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00081bin0 -> 3424 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00082bin0 -> 3273 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00083bin0 -> 3144 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00084bin0 -> 3057 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00085bin0 -> 2826 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00086bin0 -> 2756 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00087bin0 -> 2721 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00088bin0 -> 2492 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00089bin0 -> 2211 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00090bin0 -> 5118 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00091bin0 -> 5548 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00092bin0 -> 1854 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00093bin0 -> 1187 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00094bin0 -> 1322 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00095bin0 -> 1453 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00096bin0 -> 1194 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00097bin0 -> 1112 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00098bin0 -> 709 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00099bin0 -> 602 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00100bin0 -> 632 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00101bin0 -> 491 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00102bin0 -> 327 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00103bin0 -> 1269 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00104bin0 -> 173 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00105bin0 -> 12197 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00106bin0 -> 65 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00107bin0 -> 157 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00108bin0 -> 173 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00109bin0 -> 145 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00110bin0 -> 148 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00111bin0 -> 148 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00112bin0 -> 138 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00113bin0 -> 143 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00114bin0 -> 210 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00115bin0 -> 220 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00116bin0 -> 191 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00117bin0 -> 187 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00118bin0 -> 180 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00119bin0 -> 182 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00120bin0 -> 7504 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00121bin0 -> 4604 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00122bin0 -> 2444 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00123bin0 -> 1516 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00124bin0 -> 1039 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00125bin0 -> 658 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00126bin0 -> 401 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00127bin0 -> 432 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00128bin0 -> 375 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00129bin0 -> 1220 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00130bin0 -> 142 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00131bin0 -> 244 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00132bin0 -> 366 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00133bin0 -> 253 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00134bin0 -> 301 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00135bin0 -> 12322 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00136bin0 -> 68 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00137bin0 -> 138 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00138bin0 -> 170 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00139bin0 -> 174 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00140bin0 -> 159 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00141bin0 -> 185 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00142bin0 -> 152 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00143bin0 -> 159 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00144bin0 -> 203 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00145bin0 -> 140 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00146bin0 -> 132 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00147bin0 -> 162 bytes
-rw-r--r--test/test_samples/sample_mpeg4/00148bin0 -> 151 bytes
171 files changed, 5416 insertions, 1746 deletions
diff --git a/AUTHORS b/AUTHORS
index b01c60f..30471e6 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,2 +1 @@
-Kangho Hur <kanho.hur@samsung.com>
-Seungkeun Lee <sngn.lee@samsung.com>
+Sejun Park <sejun79.park@samsung.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e0daaf3..5b4b584 100755..100644
--- 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 capi-media-tool libtbm libdri2 gstreamer-0.10 gstreamer-plugins-base-0.10 gstreamer-app-0.10" )
-SET(pc_dependents "capi-base-common capi-media-tool gstreamer-0.10 gstreamer-plugins-base-0.10 gstreamer-app-0.10" )
+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(pc_dependents "capi-base-common capi-media-tool gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-app-1.0" )
INCLUDE(FindPkgConfig)
pkg_check_modules(${fw_name} REQUIRED ${dependents})
@@ -19,7 +19,7 @@ FOREACH(flag ${${fw_name}_CFLAGS})
SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
ENDFOREACH(flag)
-SET(CMAKE_C_FLAGS "-I./include -I./include/headers ${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -Werror")
+SET(CMAKE_C_FLAGS "-I./include -I./include/headers ${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall")
SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
IF("${ARCH}" STREQUAL "arm")
diff --git a/capi-media-codec.manifest b/capi-media-codec.manifest
index e3deed8..0ee3ca6 100644
--- a/capi-media-codec.manifest
+++ b/capi-media-codec.manifest
@@ -3,6 +3,6 @@
<domain name="_" />
</request>
<assign>
- <filesystem path="/usr/bin/player_test" label="_" exec_label="none" />
+ <filesystem path="/usr/bin/media_codec_test" label="_" exec_label="none" />
</assign>
</manifest>
diff --git a/include/media_codec.h b/include/media_codec.h
index 678123e..c5161b9 100755
--- a/include/media_codec.h
+++ b/include/media_codec.h
@@ -37,15 +37,15 @@ extern "C" {
/**
* @brief Media Codec type handle.
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @since_tizen 2.3
*/
typedef struct mediacodec_s *mediacodec_h;
/**
* @brief Enumeration of media codec support type
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @since_tizen 2.3
* @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_HW.
+ * #MEDIACODEC_DECODER. If user doesn't set optional flag, default flags will be set to #MEDIACODEC_SUPPORT_TYPE_SW.
*/
typedef enum
{
@@ -57,31 +57,46 @@ typedef enum
/**
* @brief Enumerations of media codec type
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @since_tizen 2.3
*/
typedef enum
{
- MEDIACODEC_NONE = 0x0, /**< NONE*/
- MEDIACODEC_L16 = 0x1010, /**< L16*/
- MEDIACODEC_ALAW = 0x1020, /**< ALAW*/
- MEDIACODEC_ULAW = 0x1030, /**< ULAW*/
- MEDIACODEC_AMR = 0x1040, /**< AMR*/
- MEDIACODEC_G729 = 0x1050, /**< G729*/
- MEDIACODEC_AAC = 0x1060, /**< AAC*/
- MEDIACODEC_MP3 = 0x1070, /**< MP3*/
-
- MEDIACODEC_H261 = 0x2010, /**< H.261*/
- MEDIACODEC_H263 = 0x2020, /**< H.263*/
- MEDIACODEC_H264 = 0x2030, /**< H.264*/
- MEDIACODEC_MJPEG = 0x2040, /**< MJPEG*/
- MEDIACODEC_MPEG1 = 0x2050, /**< MPEG1*/
- MEDIACODEC_MPEG2 = 0x2060, /**< MPEG2*/
- MEDIACODEC_MPEG4 = 0x2070, /**< MPEG4*/
+ MEDIACODEC_NONE = 0x0, /**< NONE*/
+ MEDIACODEC_L16 = 0x1010, /**< L16*/
+ MEDIACODEC_ALAW = 0x1020, /**< ALAW*/
+ MEDIACODEC_ULAW = 0x1030, /**< ULAW*/
+ MEDIACODEC_AMR = 0x1040, /**< MEDIACDEC_AMR indicates AMR-NB (Since 2.4)*/
+ MEDIACODEC_AMR_NB = 0x1040, /**< AMR-NB (Since 2.4)*/
+ MEDIACODEC_AMR_WB = 0x1041, /**< AMR-WB (Since 2.4)*/
+ MEDIACODEC_G729 = 0x1050, /**< G729*/
+ MEDIACODEC_AAC = 0x1060, /**< MEDIACDEC_AAC indicates AAC-LC (Since 2.4)*/
+ MEDIACODEC_AAC_LC = 0x1060, /**< AAC-LC (Since 2.4)*/
+ MEDIACODEC_AAC_HE = 0x1061, /**< HE-AAC (Since 2.4)*/
+ MEDIACODEC_AAC_HE_PS = 0x1062, /**< HE-AAC-PS (Since 2.4)*/
+ MEDIACODEC_MP3 = 0x1070, /**< MP3*/
+ MEDIACODEC_VORBIS = 0x1080, /**< VORBIS (Since 2.4)*/
+ MEDIACODEC_FLAC = 0x1090, /**< FLAC (Since 2.4)*/
+ MEDIACODEC_WMAV1 = 0x10A0, /**< WMA version 1 (Since 2.4)*/
+ MEDIACODEC_WMAV2 = 0x10A1, /**< WMA version 2 (Since 2.4)*/
+ MEDIACODEC_WMAPRO = 0x10A2, /**< WMA Professional (Since 2.4)*/
+ MEDIACODEC_WMALSL = 0x10A3, /**< WMA Lossless (Since 2.4)*/
+
+ MEDIACODEC_H261 = 0x2010, /**< H.261*/
+ MEDIACODEC_H263 = 0x2020, /**< H.263*/
+ MEDIACODEC_H264 = 0x2030, /**< H.264*/
+ MEDIACODEC_MJPEG = 0x2040, /**< MJPEG*/
+ MEDIACODEC_MPEG1 = 0x2050, /**< MPEG1*/
+ MEDIACODEC_MPEG2 = 0x2060, /**< MPEG2*/
+ MEDIACODEC_MPEG4 = 0x2070, /**< MPEG4*/
+ MEDIACODEC_HEVC = 0x2080, /**< HEVC (Since 2.4)*/
+ MEDIACODEC_VP8 = 0x2090, /**< VP8 (Since 2.4)*/
+ MEDIACODEC_VP9 = 0x20A0, /**< VP9 (Since 2.4)*/
+ MEDIACODEC_VC1 = 0x20B0, /**< VC1 (Since 2.4)*/
} mediacodec_codec_type_e;
/**
* @brief Enumeration of media codec error
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @since_tizen 2.3
*/
typedef enum
{
@@ -103,11 +118,23 @@ typedef enum
MEDIACODEC_ERROR_STREAM_NOT_FOUND = TIZEN_ERROR_MEDIACODEC | 0x0a, /**< Cannot find stream */
MEDIACODEC_ERROR_NOT_SUPPORTED_FORMAT = TIZEN_ERROR_MEDIACODEC | 0x0b, /**< Not supported format */
MEDIACODEC_ERROR_BUFFER_NOT_AVAILABLE = TIZEN_ERROR_MEDIACODEC | 0x0c, /**< Not available buffer */
+ MEDIACODEC_ERROR_OVERFLOW_INBUFFER = TIZEN_ERROR_MEDIACODEC | 0x0d, /**< Overflow input buffer (Since 2.4)*/
+ MEDIACODEC_ERROR_RESOURCE_OVERLOADED = TIZEN_ERROR_MEDIACODEC | 0x0e, /**< Exceed the instance limits (Since 2.4)*/
} mediacodec_error_e;
/**
+ * @brief Enumeration of buffer status
+ * @since_tizen 2.4
+ */
+typedef enum
+{
+ MEDIACODEC_NEED_DATA,
+ MEDIACODEC_ENOUGH_DATA
+} mediacodec_status_e;
+
+/**
* @brief Called when the input buffer(pkt) used up.
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @since_tizen 2.3
* @details It will be invoked when mediacodec has used input buffer.
* @param[in] pkt The media packet handle
* @param[in] user_data The user data passed from the callback registration function
@@ -119,7 +146,7 @@ typedef void (*mediacodec_input_buffer_used_cb)(media_packet_h pkt, void *user_d
/**
* @brief Called when the output buffer is available.
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @since_tizen 2.3
* @details It will be invoked when mediacodec has output buffer.
* @param[in] pkt The media packet handle
* @param[in] user_data The user data passed from the callback registration function
@@ -131,7 +158,7 @@ typedef void (*mediacodec_output_buffer_available_cb)(media_packet_h pkt, void *
/**
* @brief Called when the error has occured
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @since_tizen 2.3
* @details It will be invoked when the error has occured.
* @param[in] error_code The error code
* @param[in] user_data The user data passed from the callback registration function
@@ -143,7 +170,7 @@ 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
+ * @since_tizen 2.3
* @details It will be invoked when the end-of-stream is reached.
* @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().
@@ -153,8 +180,30 @@ typedef void (*mediacodec_error_cb)(mediacodec_error_e error, void *user_data);
typedef void (*mediacodec_eos_cb)(void *user_data);
/**
+ * @brief Called when the mediacodec needs more data or has enough data.
+ * @since_tizen 2.4
+ * @details It is recommended that the application stops calling mediacodec_process_input() when MEDIACODEC_ENOUGH_DATA
+ * is invoked.
+ * @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()
+ */
+typedef void (*mediacodec_buffer_status_cb)(mediacodec_status_e status, void *user_data);
+
+/**
+ * @brief Called once for each supported codec types.
+ * @since_tizen 2.4
+ * @param[in] codec_type The codec type
+ * @param[in] user_data The user data passed from the foreach function
+ * @return @c true to continue with the next iteration of the loop, @c false to break out of the loop.
+ * @pre mediacodec_foreach_supported_codec() will invoke this callback.
+ * @see mediacodec_foreach_supported_codec()
+ */
+typedef bool (*mediacodec_supported_codec_cb)(mediacodec_codec_type_e codec_type, void *user_data);
+
+/**
* @brief Creates a mediacodec handle for decoding/encoding
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @since_tizen 2.3
* @remarks you must release @a mediacodec using mediacodec_destroy().\n
* Although you can create multiple mediacodec handles at the same time,
* the mediacodec cannot guarantee proper operation because of limited resources, like
@@ -171,7 +220,7 @@ int mediacodec_create(mediacodec_h *mediacodec);
/**
* @brief Destroys the mediacodec handle and releases all its resources.
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @since_tizen 2.3
* @remarks To completely shutdown the mediacodec operation, call this function with a valid player handle from any
* mediacodec
*
@@ -181,18 +230,24 @@ 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
+ @code
+ #include <media_codec.h>
+ mediacodec_h mediacodec;
+
+ mediacodec_create(&mediacodec);
+ @endcode
*/
int mediacodec_destroy(mediacodec_h mediacodec);
/**
* @brief Sets the codec type and decoder/encoder.
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @since_tizen 2.3
* @remarks If this codec is to be used as a decoder, pass the #MEDIACODEC_DECODER flag.
* If this codec is to be used as an encoder, pass the #MEDIACODEC_ENCODER flag.
- * By default, It is used hardware default setting. If user want software setting, pass the
+ * By default, It is used software default setting. If user want software setting, pass the
* #MEDIACODEC_SUPPORT_TYPE_SW flags.
* @param[in] mediacodec The handle of mediacodec
- * @param[in] codec_id The identifier of the codec type of the decoder/encoder
+ * @param[in] codec_type The identifier of the codec type of the decoder/encoder
* @param[in] flags The encoding/decoding scheme.
* @return @c 0 on success, otherwise a negative error value
* @retval #MEDIACODEC_ERROR_NONE Successful
@@ -200,12 +255,19 @@ 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
+ @code
+ #include <media_codec.h>
+ mediacodec_h mediacodec;
+
+ mediacodec_create(&mediacodec);
+ mediacodec_destroy(mediacodec);
+ @endcode
*/
-int mediacodec_set_codec(mediacodec_h mediacodec, mediacodec_codec_type_e codec_id, mediacodec_support_type_e flags);
+int mediacodec_set_codec(mediacodec_h mediacodec, mediacodec_codec_type_e codec_type, mediacodec_support_type_e flags);
/**
* @brief Sets the default info for the video decoder
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @since_tizen 2.3
* @param[in] mediacodec The handle to mediacodec
* @param[in] width The width for video decoding.
* @param[in] height The height for video decoding.
@@ -214,12 +276,19 @@ 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
+ @code
+ #include <media_codec.h>
+ mediacodec_h mediacodec;
+
+ mediacodec_create(&mediacodec);
+ mediacodec_set_codec(mediacodec, MEDIACODEC_H264, MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_HW);
+ @endcode
*/
int mediacodec_set_vdec_info(mediacodec_h mediacodec, int width, int height);
/**
* @brief Sets the default info for the video encoder
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @since_tizen 2.3
* @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.
* @param[in] mediacodec The handle to mediacodec
@@ -232,12 +301,20 @@ 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
+ @code
+ #include <media_codec.h>
+ mediacodec_h mediacodec;
+
+ mediacodec_create(&mediacodec);
+ mediacodec_set_codec(mediacodec, MEDIACODEC_H264, MEDIACODEC_ENCODER | MEDIACODEC_SUPPORT_TYPE_HW);
+ mediacodec_set_venc_info(mediacodec, 640, 480, 30, 1000);
+ @endcode
*/
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
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @since_tizen 2.3
* @param[in] mediacodec The handle to mediacodec
* @param[in] samplerate The samplerate for audio decoding.
* @param[in] channel The channels for audio decoding.
@@ -247,28 +324,44 @@ 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
+ @code
+ #include <media_codec.h>
+ mediacodec_h mediacodec;
+
+ mediacodec_create(&mediacodec);
+ mediacodec_set_codec(mediacodec, MEDIACODEC_AAC, MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_SW);
+ mediacodec_set_adec_info(mediacodec, 44100, 2, 16);
+ @endcode
*/
int mediacodec_set_adec_info(mediacodec_h mediacodec, int samplerate, int channel, int bit);
/**
* @brief Sets the default info for the audio encdoer
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @since_tizen 2.3
* @param[in] mediacodec The handle to mediacodec
* @param[in] samplerate The samplerate for audio encoding.
* @param[in] channel The channels for audio encoding.
- * @param[in] bit The bits resolution for audio encoding.
- * @param[in] bitrate The bitrate for audio encoding.
+ * @param[in] bit The bits resolution for audio encoding.
+ * @param[in] bitrate The bitrate for audio encoding.
* @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_OUT_OF_MEMORY Out of memory
* @retval #MEDIACODEC_ERROR_INVALID_OPERATION Invalid operation
+ @code
+ #include <media_codec.h>
+ mediacodec_h mediacodec;
+
+ mediacodec_create(&mediacodec);
+ mediacodec_set_codec(mediacodec, MEDIACODEC_AAC, MEDIACODEC_ENCODER | MEDIACODEC_SUPPORT_TYPE_SW);
+ mediacodec_set_aenc_info(mediacodec, 44100, 2, 16, 128);
+ @endcode
*/
int mediacodec_set_aenc_info(mediacodec_h mediacodec, int samplerate, int channel, int bit, int bitrate);
/**
* @brief Prepares @a mediacodec for encoding/decoding.
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @since_tizen 2.3
* @param[in] mediacodec The handle to mediacodec
* @return @c 0 on success, otherwise a negative error value
* @retval #MEDIACODEC_ERROR_NONE Successful
@@ -278,25 +371,42 @@ int mediacodec_set_aenc_info(mediacodec_h mediacodec, int samplerate, int channe
* @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.
+ @code
+ #include <media_codec.h>
+ mediacodec_h mediacodec;
+
+ mediacodec_create(&mediacodec);
+ mediacodec_set_codec(mediacodec, MEDIACODEC_H264, MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_HW);
+ mediacodec_prepare(mediacodec);
+ @endcode
*/
int mediacodec_prepare(mediacodec_h mediacodec);
/**
* @brief Unprepares @a mediacodec for encoding/decoding.
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @since_tizen 2.3
* @param[in] mediacodec The handle to 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_OUT_OF_MEMORY Out of memory
* @retval #MEDIACODEC_ERROR_INVALID_OPERATION Invalid operation
+ @code
+ #include <media_codec.h>
+ mediacodec_h mediacodec;
+
+ mediacodec_create(&mediacodec);
+ mediacodec_set_codec(mediacodec, MEDIACODEC_H264, MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_HW);
+ mediacodec_prepare(mediacodec);
+ mediacodec_unprepare(mediacodec);
+ @endcode
*/
int mediacodec_unprepare(mediacodec_h mediacodec);
/**
* @brief Decodes/Encodes a packet. The function passed undecoded/unencoded packet to the input queue and decode/encode a
* frame sequentially.
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @since_tizen 2.3
* @param[in] mediacodec The handle to mediacodec
* @param[in] inbuf The current input format for the decoder/encoder
* @param[in] timeOutUs The timeout in microseconds. \n
@@ -306,14 +416,25 @@ int mediacodec_unprepare(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_OVERFLOW_INBUFFER Overflow inputbuffer
+ @code
+ #include <media_codec.h>
+ mediacodec_h mediacodec;
+ media_packet_h pkt;
+
+ mediacodec_create(&mediacodec);
+ mediacodec_set_codec(mediacodec, MEDIACODEC_H264, MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_HW);
+ mediacodec_prepare(mediacodec);
+ mediacodec_process_input(pkt);
+ @endcode
*/
int mediacodec_process_input (mediacodec_h mediacodec, media_packet_h inbuf, uint64_t timeOutUs);
/**
* @brief Gets the decoded or encoded packet from the output queue.
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @since_tizen 2.3
* @param[in] mediacodec The handle to mediacodec
- * @param[in] outbuf The current output of the decoder/encoder. this function passed decoded/encoded frame to output
+ * @param[out] outbuf 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.
@@ -322,12 +443,46 @@ int mediacodec_process_input (mediacodec_h mediacodec, media_packet_h inbuf, uin
* @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter
* @retval #MEDIACODEC_ERROR_OUT_OF_MEMORY Out of memory
* @retval #MEDIACODEC_ERROR_INVALID_OPERATION Invalid operation
+ @code
+ #include <media_codec.h>
+ mediacodec_h mediacodec;
+ media_packet_h pkt;
+ media_packet_h out_pkt;
+
+ mediacodec_create(&mediacodec);
+ mediacodec_set_codec(mediacodec, MEDIACODEC_H264, MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_HW);
+ mediacodec_prepare(mediacodec);
+ mediacodec_process_input(pkt);
+ mediacodec_get_output(mediacodec, &out_pkt, 1000);
+ @endcode
*/
int mediacodec_get_output (mediacodec_h mediacodec, media_packet_h *outbuf, uint64_t timeOutUs);
/**
+ * @brief Flushes both input and output buffers.
+ * @since_tizen 2.4
+ * @param[in] mediacodec The handle to mediacodec
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIACODEC_ERROR_NONE Successful
+ * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter
+ @code
+ #include <media_codec.h>
+ mediacodec_h mediacodec;
+ media_packet_h pkt;
+ media_packet_h out_pkt;
+
+ mediacodec_create(&mediacodec);
+ mediacodec_set_codec(mediacodec, MEDIACODEC_H264, MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_HW);
+ mediacodec_prepare(mediacodec);
+ mediacodec_process_input(pkt);
+ mediacodec_flush_buffers(mediacodec);
+ @endcode
+ */
+int mediacodec_flush_buffers (mediacodec_h mediacodec);
+
+/**
* @brief set empty buffer callback the media codec for process, asynchronously.
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @since_tizen 2.3
* @param[in] mediacodec The handle to mediacodec
* @param[in] callback The callback function to register
* @param[in] user_data The user data to be passed to the callback function
@@ -343,7 +498,7 @@ int mediacodec_set_input_buffer_used_cb(mediacodec_h mediacodec, mediacodec_inpu
/**
* @brief unset input buffer used callback the media codec for process, asynchronously.
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @since_tizen 2.3
* @param[in] mediacodec The handle to mediacodec
* @return @c 0 on success, otherwise a negative error value
* @retval #MEDIACODEC_ERROR_NONE Successful
@@ -354,7 +509,7 @@ int mediacodec_unset_input_buffer_used_cb(mediacodec_h mediacodec);
/**
* @brief set output buffer available callback the media codec for process, asynchronously.
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @since_tizen 2.3
* @param[in] mediacodec The handle to mediacodec
* @param[in] callback The callback function to register
* @param[in] user_data The user data to be passed to the callback function
@@ -370,7 +525,7 @@ int mediacodec_set_output_buffer_available_cb(mediacodec_h mediacodec, mediacode
/**
* @brief unset output buffer available callback the media codec for process, asynchronously.
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @since_tizen 2.3
* @param[in] mediacodec The handle to mediacodec
* @return @c 0 on success, otherwise a negative error value
* @retval #MEDIACODEC_ERROR_NONE Successful
@@ -381,7 +536,7 @@ int mediacodec_unset_output_buffer_available_cb(mediacodec_h mediacodec);
/**
* @brief set error callback the media codec for process, asynchronously.
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @since_tizen 2.3
* @param[in] mediacodec The handle to mediacodec
* @param[in] callback The callback function to register
* @param[in] user_data The user data to be passed to the callback function
@@ -397,7 +552,7 @@ int mediacodec_set_error_cb(mediacodec_h mediacodec, mediacodec_error_cb callbac
/**
* @brief unset error callback the media codec for process, asynchronously.
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @since_tizen 2.3
* @param[in] mediacodec The handle to mediacodec
* @return @c 0 on success, otherwise a negative error value
* @retval #MEDIACODEC_ERROR_NONE Successful
@@ -408,7 +563,7 @@ int mediacodec_unset_error_cb(mediacodec_h mediacodec);
/**
* @brief set eos callback the media codec for process, asynchronously.
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @since_tizen 2.3
* @param[in] mediacodec The handle to mediacodec
* @param[in] callback The callback function to register
* @param[in] user_data The user data to be passed to the callback function
@@ -424,7 +579,7 @@ int mediacodec_set_eos_cb(mediacodec_h mediacodec, mediacodec_eos_cb callback, v
/**
* @brief unset eos callback the media codec for process, asynchronously.
- * @since_tizen @if MOBILE 2.3 @elseif WEARABLE 2.3.1 @endif
+ * @since_tizen 2.3
* @param[in] mediacodec The handle to mediacodec
* @return @c 0 on success, otherwise a negative error value
* @retval #MEDIACODEC_ERROR_NONE Successful
@@ -434,6 +589,77 @@ 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.
+ * @since_tizen 2.4
+ * @param[in] mediacodec The handle to mediacodec
+ * @param[in] callback The callback function to register
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIACODEC_ERROR_NONE Successful
+ * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter
+ * @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.
+ * @since_tizen 2.4
+ * @param[in] mediacodec The handle to mediacodec
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIACODEC_ERROR_NONE Successful
+ * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter
+ */
+int mediacodec_unset_buffer_status_cb(mediacodec_h mediacodec);
+
+/**
+ * @brief Retrieves all supported codecs by invoking callback function once for each supported codecs.
+ * @since_tizen 2.4
+ * @param[in] mediacodec The handle to mediacodec
+ * @param[in] callback The callback function to invoke
+ * @param[in] user_data The user data to be passed to the callback function
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIACODEC_ERROR_NONE Successful
+ * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter
+ * @see mediacodec_foreach_supported_codec()
+ */
+int mediacodec_foreach_supported_codec(mediacodec_h mediacodec, mediacodec_supported_codec_cb callback, void *user_data);
+
+/**
+ * @brief Verifies whether encoding can be performed with codec_type or not.
+ * @since_tizen 2.4
+ * @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)
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #MEDIACODEC_ERROR_NONE Successful
+ * @retval #MEDIACODEC_ERROR_INVALID_PARAMETER Invalid parameter
+ @code
+ #include <media_codec.h>
+ mediacodec_h mediacodec;
+ mediacodec_support_type_e type;
+ mediacodec_codec_type_e codec_type = MEDIACODEC_H264;
+
+ mediacodec_create(&mediacodec);
+ mediacodec_get_supported_type(mediacodec, codec_type, 1, &type);
+
+ if(type == MEDIACODEC_SUPPORT_TYPE_HW)
+ // only h/w supported
+ else if (type == MEDIACODEC_SUPPORT_TYPE_SW)
+ // only s/w supported
+ else if (type == (MEDIACODEC_SUPPORT_TYPE_HW|MEDIACODEC_SUPPORT_TYPE_SW)
+ // both supported
+
+ mediacodec_set_codec(mediacodec, codec_type, MEDIACODEC_ENCODER | MEDIACODEC_SUPPORT_TYPE_HW);
+ @endcode
+ */
+int mediacodec_get_supported_type(mediacodec_h mediacodec, mediacodec_codec_type_e codec_type, bool encoder, int *support_type);
+
+
+/**
* @}
*/
diff --git a/include/media_codec_bitstream.h b/include/media_codec_bitstream.h
new file mode 100755
index 0000000..44329ba
--- /dev/null
+++ b/include/media_codec_bitstream.h
@@ -0,0 +1,113 @@
+/*
+* Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef __TIZEN_MEDIA_CODEC_BITSTREAM_H__
+#define __TIZEN_MEDIA_CODEC_BITSTREAM_H__
+
+#include <tizen.h>
+#include <media_codec_port.h>
+
+typedef struct _mc_bitstream_t mc_bitstream_t;
+
+typedef enum
+{
+ NAL_SLICE_NO_PARTITIONING = 1,
+ NAL_SLICE_PART_A,
+ NAL_SLICE_PART_B,
+ NAL_SLICE_PART_C,
+ NAL_SLICE_IDR,
+ NAL_SEI,
+ NAL_SEQUENCE_PARAMETER_SET,
+ NAL_PICTURE_PARAMETER_SET,
+ NAL_PICTURE_DELIMITER,
+ NAL_END_OF_SEQUENCE,
+ NAL_END_OF_STREAM,
+ NAL_FILLER_DATA,
+ NAL_PREFIX_SVC = 14
+} mc_nal_unit_type_e;
+
+enum
+{
+ MC_EXIST_SPS = 1 << 0,
+ MC_EXIST_PPS = 1 << 1,
+ MC_EXIST_IDR = 1 << 2,
+ MC_EXIST_SLICE = 1 << 3,
+
+ MC_VALID_HEADER = ( MC_EXIST_SPS | MC_EXIST_PPS ),
+ MC_VALID_FIRST_SLICE = ( MC_EXIST_SPS | MC_EXIST_PPS | MC_EXIST_IDR )
+};
+
+#define CHECK_VALID_PACKET(state, expected_state) \
+ ((state & (expected_state)) == (expected_state))
+
+static const unsigned int mask[33] =
+{
+ 0x00000000, 0x00000001, 0x00000003, 0x00000007,
+ 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
+ 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
+ 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
+ 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
+ 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
+ 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
+ 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
+ 0xffffffff
+};
+
+struct _mc_bitstream_t
+{
+ unsigned char *data;
+ unsigned int numBytes;
+ unsigned int bytePos;
+ unsigned int buffer;
+ unsigned int dataBitPos;
+ unsigned int bitcnt;
+};
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MC_READ16B(x) ((((const unsigned char*)(x))[0] << 8) | ((const unsigned char*)(x))[1])
+
+#define MC_READ32B(x) ((((const unsigned char*)(x))[0] << 24) | \
+ (((const unsigned char*)(x))[1] << 16) | \
+ (((const unsigned char*)(x))[2] << 8) | \
+ ((const unsigned char*)(x))[3])
+
+void mc_init_bits(mc_bitstream_t *stream, unsigned char *data, int size);
+short mc_show_bits(mc_bitstream_t *stream, unsigned char nbits, unsigned int *pulOutData);
+short mc_read_bits( mc_bitstream_t *stream, unsigned char nbits, unsigned int *pulOutData );
+short mc_byte_align( mc_bitstream_t *stream );
+
+bool _mc_is_voss(unsigned char *buf, int size, int *codec_size);
+bool _mc_is_ivop(unsigned char *p, int size, int pos);
+bool _mc_is_vop(unsigned char *p, int size, int pos);
+
+
+int __mc_decode_sps(mc_bitstream_t *pstream, int *width, int *height);
+unsigned int __mc_bytestream_to_nal( unsigned char* data, int size );
+int _mc_check_h264_bytestream ( unsigned char *nal, int byte_length, bool port, bool *codec_config, bool *sync_flag, bool *slice);
+int _mc_check_valid_h263_frame(unsigned char *p, int size);
+bool _mc_check_h263_out_bytestream(unsigned char *p, int buf_length, bool* need_sync_flag);
+int _mc_check_mpeg4_out_bytestream(unsigned char *buf, int buf_length, bool* need_codec_data, bool *need_sync_flag);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_MEDIA_CODEC_BITSTREAM_H__ */
diff --git a/include/media_codec_ini.h b/include/media_codec_ini.h
new file mode 100755
index 0000000..daca4e7
--- /dev/null
+++ b/include/media_codec_ini.h
@@ -0,0 +1,103 @@
+/*
+* Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef __TIZEN_MEDIA_CODEC_INI_H__
+#define __TIZEN_MEDIA_CODEC_INI_H__
+
+#include <glib.h>
+#include <mm_types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MEDIA_CODEC_INI_DEFAULT_PATH "/usr/etc/mmfw_media_codec.ini"
+#define MEDIA_CODEC_INI_MAX_STRLEN 256
+#define DEFAULT_PORT "GST_PORT"
+#define MEDIA_CODEC_MAX_CODEC_TYPE 100
+#define MEDIA_CODEC_MAX_CODEC_ROLE 4
+
+#define MEDICODEC_INI_MAX_ELEMENT 10
+#define MEDIA_CODEC_MAX_VIDEO_CODEC 100
+#define MEDIA_CODEC_MAX_AUDIO_CODEC 100
+
+
+typedef enum {
+ GST_PORT = 0,
+ FFMPEG_PORT,
+ CUSTOM_PORT,
+} port_mode;
+
+typedef struct {
+ gchar name[MEDIA_CODEC_INI_MAX_STRLEN];
+ gchar mime[MEDIA_CODEC_INI_MAX_STRLEN];
+ gchar format[MEDIA_CODEC_INI_MAX_STRLEN];
+} codec_info_t;
+
+typedef struct {
+ gint codec_id;
+ codec_info_t codec_info[MEDIA_CODEC_MAX_CODEC_ROLE];
+} codec_t;
+
+
+/* @ mark means the item has tested */
+typedef struct __mc_ini {
+ port_mode port_type;
+ /* general */
+ gchar port_name[MEDIA_CODEC_INI_MAX_STRLEN];
+ codec_t codec[MEDIA_CODEC_MAX_CODEC_TYPE];
+} mc_ini_t;
+
+/*Default sink ini values*/
+/* General*/
+
+/* NOTE : following content should be same with above default values */
+/* FIXIT : need smarter way to generate default ini file. */
+/* FIXIT : finally, it should be an external file */
+#define MEDIA_CODEC_DEFAULT_INI \
+ "\
+[general] \n\
+\n\
+;Add general config parameters here\n\
+\n\
+\n\
+\n\
+[port_in_use] \n\
+\n\
+;media_codec_port = GST_PORT \n\
+;media_codec_port = FFMPEG_PORT \n\
+;media_codec_port = CUSTOM_PORT \n\
+media_codec_port = GST_PORT \n\
+\n\
+[gst_port] \n\
+\n\
+;Add gst port specific config paramters here\n\
+\n\
+\n\
+[custom_port] \n\
+\n\
+;Add custom port specific config paramters here\n\
+\n\
+\n\
+\n\
+"
+
+int mc_ini_load(mc_ini_t *ini);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*__TIZEN_MEDIA_CODEC_INI_H__*/
diff --git a/include/media_codec_port.h b/include/media_codec_port.h
index 92d80f2..cd6d76f 100755
--- a/include/media_codec_port.h
+++ b/include/media_codec_port.h
@@ -24,7 +24,9 @@
#include <media_codec.h>
#include <media_codec_queue.h>
+#include <media_codec_bitstream.h>
#include <media_codec_spec_emul.h>
+#include <media_codec_ini.h>
/*===========================================================================================
@@ -36,7 +38,6 @@
/*---------------------------------------------------------------------------
| GLOBAL #defines: |
---------------------------------------------------------------------------*/
-#define OUT_BUF_SIZE 9000000
#define CHECK_BIT(x, y) (((x) >> (y)) & 0x01)
#define GET_IS_ENCODER(x) CHECK_BIT(x, 0)
#define GET_IS_DECODER(x) CHECK_BIT(x, 1)
@@ -46,6 +47,13 @@
//#define GET_IS_OMX(x) CHECK_BIT(x, 4)
//#define GET_IS_GEN(x) CHECK_BIT(x, 5)
+#if 1
+#define MEDIACODEC_FENTER();
+#define MEDIACODEC_FLEAVE();
+#else
+#define MEDIACODEC_FENTER(); LOGW("%s Enter",__FUNCTION__);
+#define MEDIACODEC_FLEAVE(); LOGW("%s Exit",__FUNCTION__);
+#endif
/*---------------------------------------------------------------------------
| GLOBAL CONSTANT DEFINITIONS: |
@@ -74,6 +82,7 @@ typedef enum
MC_OUTPUT_BUFFER_EMPTY = -16,
MC_OUTPUT_BUFFER_OVERFLOW = -17, /**< codec output buffer is overflow */
MC_MEMORY_ALLOCED = -18, /**< codec has got memory and can decode one frame */
+ MC_COURRPTED_INI = -19,
} mc_ret_e;
/*---------------------------------------------------------------------------
@@ -88,18 +97,25 @@ typedef enum
* @see mediacodec_unset_dequeue_input_buffer_cb()
*/
+
typedef struct _mc_decoder_info_t mc_decoder_info_t;
typedef struct _mc_encoder_info_t mc_encoder_info_t;
typedef struct _mc_handle_t mc_handle_t;
-#define MEDIACODEC_CMD_LOCK(x_mediacodec) g_mutex_lock(&((mc_handle_t*)x_mediacodec)->cmd_lock )
-#define MEDIACODEC_CMD_UNLOCK(x_mediacodec) g_mutex_unlock( &((mc_handle_t*)x_mediacodec)->cmd_lock )
-
typedef void (*mc_dequeue_input_buffer_cb)(media_packet_h pkt, void *user_data);
typedef void (*mc_empty_buffer_cb)(media_packet_h pkt, void *user_data);
typedef void (*mc_fill_buffer_cb)(media_packet_h pkt, void *user_data);
typedef void (*mc_error_cb)(mediacodec_error_e error, void *user_data);
typedef void (*mc_eos_cb)(void *user_data);
+typedef void (*mc_buffer_status_cb)(mediacodec_status_e status, void *user_data);
+typedef void (*mc_supported_codec_cb)(mediacodec_codec_type_e codec_type, void *user_data);
+
+int (*mc_sniff_bitstream)(mc_handle_t *handle, media_packet_h pkt);
+
+int mc_sniff_h264_bitstream(mc_handle_t *handle, media_packet_h pkt);
+int mc_sniff_mpeg4_bitstream(mc_handle_t *handle, media_packet_h pkt);
+int mc_sniff_h263_bitstream(mc_handle_t *handle, media_packet_h pkt);
+int mc_sniff_yuv(mc_handle_t *handle, media_packet_h pkt);
typedef enum {
_MEDIACODEC_EVENT_TYPE_COMPLETE,
@@ -107,19 +123,30 @@ typedef enum {
_MEDIACODEC_EVENT_TYPE_FILLBUFFER,
_MEDIACODEC_EVENT_TYPE_ERROR,
_MEDIACODEC_EVENT_TYPE_EOS,
+ _MEDIACODEC_EVENT_TYPE_BUFFER_STATUS,
_MEDIACODEC_EVENT_TYPE_INTERNAL_FILLBUFFER,
+ _MEDIACODEC_EVENT_TYPE_SUPPORTED_CODEC,
_MEDIACODEC_EVENT_TYPE_NUM
} _mediacodec_event_e;
typedef enum _mc_codec_port_type_e
{
- CODEC_PORT_TYPE_GENERAL,
- CODEC_PORT_TYPE_OMX,
- CODEC_PORT_TYPE_GST,
- CODEC_PORT_TYPE_MAX,
+ CODEC_PORT_TYPE_GENERAL,
+ CODEC_PORT_TYPE_OMX,
+ CODEC_PORT_TYPE_GST,
+ 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;
@@ -150,7 +177,6 @@ struct _mc_encoder_info_t
int bit;
};
-
/* Codec Private data */
struct _mc_handle_t
{
@@ -160,9 +186,10 @@ struct _mc_handle_t
bool is_hw;
bool is_prepared;
- GMutex cmd_lock;
+ GList *supported_codecs;
mediacodec_port_type_e port_type;
mediacodec_codec_type_e codec_id;
+ mc_vendor_e vendor;
void *ports[2];
void *core;
@@ -177,6 +204,14 @@ struct _mc_handle_t
void* user_cb[_MEDIACODEC_EVENT_TYPE_NUM];
void* user_data[_MEDIACODEC_EVENT_TYPE_NUM];
+ mc_codec_map_t encoder_map[MEDIA_CODEC_MAX_CODEC_TYPE];
+ mc_codec_map_t decoder_map[MEDIA_CODEC_MAX_CODEC_TYPE];
+
+ int num_supported_codecs;
+ int num_supported_decoder;
+ int num_supported_encoder;
+
+ mc_ini_t ini;
};
/*===========================================================================================
@@ -206,6 +241,9 @@ int mc_unprepare(MMHandleType mediacodec);
int mc_process_input(MMHandleType mediacodec, media_packet_h inbuf, uint64_t timeOutUs);
int mc_get_output(MMHandleType mediacodec, media_packet_h *outbuf, uint64_t timeOutUs);
+int mc_flush_buffers(MMHandleType mediacodec);
+int mc_get_supported_type(MMHandleType mediacodec, mediacodec_codec_type_e codec_type, bool encoder, int *support_type);
+
int mc_set_empty_buffer_cb(MMHandleType mediacodec, mediacodec_input_buffer_used_cb callback, void* user_data);
int mc_unset_empty_buffer_cb(MMHandleType mediacodec);
@@ -218,6 +256,10 @@ int mc_unset_error_cb(MMHandleType mediacodec);
int mc_set_eos_cb(MMHandleType mediacodec, mediacodec_eos_cb callback, void* user_data);
int mc_unset_eos_cb(MMHandleType mediacodec);
+int mc_set_buffer_status_cb(MMHandleType mediacodec, mediacodec_buffer_status_cb callback, void* user_data);
+int mc_unset_buffer_status_cb(MMHandleType mediacodec);
+
+
#ifdef __cplusplus
}
#endif
diff --git a/include/media_codec_port_gst.h b/include/media_codec_port_gst.h
index 4a3dd5c..1908081 100755
--- a/include/media_codec_port_gst.h
+++ b/include/media_codec_port_gst.h
@@ -23,42 +23,38 @@
#include <media_codec.h>
#include <media_codec_private.h>
#include <media_codec_port.h>
+#include <media_codec_bitstream.h>
#include <tbm_type.h>
#include <tbm_surface.h>
#include <tbm_bufmgr.h>
#include <tbm_surface_internal.h>
+#include <gst/video/video-format.h>
#ifdef __cplusplus
extern "C" {
#endif
-#if 0
-#define MMPLAYER_FENTER(); debug_fenter();
-#define MMPLAYER_FLEAVE(); debug_fleave();
-#else
-#define MMPLAYER_FENTER(); LOGW("%s Enter",__FUNCTION__);
-#define MMPLAYER_FLEAVE(); LOGW("%s Exit",__FUNCTION__);
-#endif
-
-
#define GST_INIT_STRUCTURE(param) \
memset(&(param), 0, sizeof(param));
-#define MEDIACODEC_ELEMENT_SET_STATE( x_element, x_state ) \
-LOGD("setting state [%s:%d] to [%s]\n", #x_state, x_state, GST_ELEMENT_NAME( x_element ) ); \
-if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state ( x_element, x_state) ) \
-{ \
- LOGE("failed to set state %s to %s\n", #x_state, GST_ELEMENT_NAME( x_element )); \
- goto STATE_CHANGE_FAILED; \
-}
+#define MEDIACODEC_ELEMENT_SET_STATE( x_element, x_state ) \
+ do { \
+ LOGD("setting state [%s:%d] to [%s]\n", #x_state, x_state, GST_ELEMENT_NAME( x_element ) ); \
+ if ( GST_STATE_CHANGE_FAILURE == gst_element_set_state ( x_element, x_state) ) \
+ { \
+ LOGE("failed to set state %s to %s\n", #x_state, GST_ELEMENT_NAME( x_element )); \
+ goto STATE_CHANGE_FAILED; \
+ } \
+ } while (0)
#define SCMN_IMGB_MAX_PLANE 4
-#define TBM_API_CHANGE //this need for temporary test - tbm_surface_internal_create_with_bos() API change
+#define TBM_API_CHANGE
+
/* gst port layer */
typedef struct _mc_gst_port_t mc_gst_port_t;
typedef struct _mc_gst_core_t mc_gst_core_t;
-typedef struct _mc_gst_buffer_t mc_gst_buffer_t;
+typedef struct _GstMCBuffer GstMCBuffer;
typedef enum {
BUF_SHARE_METHOD_PADDR = 0,
@@ -69,37 +65,13 @@ typedef enum {
#ifdef TIZEN_PROFILE_LITE
struct ion_mmu_data {
- int fd_buffer;
- unsigned long iova_addr;
- size_t iova_size;
+ int master_id;
+ int fd_buffer;
+ unsigned long iova_addr;
+ size_t iova_size;
};
#endif
-typedef struct
-{
- int w[SCMN_IMGB_MAX_PLANE]; /* width of each image plane */
- int h[SCMN_IMGB_MAX_PLANE]; /* height of each image plane */
- int s[SCMN_IMGB_MAX_PLANE]; /* stride of each image plane */
- int e[SCMN_IMGB_MAX_PLANE]; /* elevation of each image plane */
- void *a[SCMN_IMGB_MAX_PLANE]; /* user space address of each image plane */
- void *p[SCMN_IMGB_MAX_PLANE]; /* physical address of each image plane, if needs */
- int cs; /* color space type of image */
- int x; /* left postion, if needs */
- int y; /* top position, if needs */
- int __dummy2; /* to align memory */
- int data[16]; /* arbitrary data */
- int dma_buf_fd[SCMN_IMGB_MAX_PLANE]; /* DMABUF fd of each image plane */
- /* buffer share method */
- int buf_share_method; /* will be 2(BUF_SHARE_METHOD_TIZEN_BUFFER)*/
- int y_size; /* Y plane size in case of ST12 */
- /* UV plane size in case of ST12 */
- int uv_size; /* UV plane size in case of ST12 */
- tbm_bo bo[SCMN_IMGB_MAX_PLANE]; /* Tizen buffer object of each image plane */
- void *jpeg_data; /* JPEG data */
- int jpeg_size; /* JPEG size */
- int tz_enable; /* TZ memory buffer */
-} SCMN_IMGB;
-
struct _mc_gst_port_t
{
mc_gst_core_t *core;
@@ -118,12 +90,17 @@ struct _mc_gst_core_t
{
int(**vtable)();
const char *mime;
- int format;
+ //int format;
+ gchar *format;
GstElement* pipeline;
GstElement* appsrc;
+ GstElement* capsfilter;
+ GstElement* parser;
GstElement* fakesink;
GstElement* codec;
- SCMN_IMGB *psimgb;
+ MMVideoBuffer *psimgb;
+ tbm_bufmgr bufmgr;
+ int drm_fd;
GMainContext *thread_default;
gulong signal_handoff;
@@ -132,12 +109,10 @@ struct _mc_gst_core_t
GMutex eos_mutex;
GMutex eos_wait_mutex;
- GMutex drain_mutex;
GMutex prepare_lock;
+ GMutex drain_lock;
GCond eos_cond;
GCond eos_waiting_cond;
- //mc_sem_t *push_sem;
- //mc_sem_t *pop_sem;
GstState state;
bool output_allocated;
@@ -148,49 +123,91 @@ struct _mc_gst_core_t
bool eos_waiting;
bool codec_config;
bool need_feed;
- int prepare_count;
- int num_live_buffers;
+ bool need_codec_data;
+ bool need_sync_flag;
+ bool unprepare_flag;
+ unsigned int prepare_count;
+ unsigned int num_live_buffers;
+ unsigned int queued_count;
+ unsigned int dequeued_count;
+
mediacodec_codec_type_e codec_id;
+ media_format_mimetype_e out_mime;
media_format_h output_fmt;
mc_gst_port_t *ports[2];
+ mc_bitstream_t bits;
mc_aqueue_t *available_queue;
GQueue *output_queue;
void *codec_info;
+ unsigned char codec_data[100];
+ int codec_data_size;
void* user_cb[_MEDIACODEC_EVENT_TYPE_NUM];
void* user_data[_MEDIACODEC_EVENT_TYPE_NUM];
};
-struct _mc_gst_buffer_t
+struct _GstMCBuffer
{
- GstBuffer buffer;
+ GstBuffer *buffer;
+ int buf_size;
mc_gst_core_t* core;
media_packet_h pkt;
+ bool has_imgb;
};
enum { fill_inbuf, fill_outbuf, create_caps };
-int __mc_fill_input_buffer(mc_gst_core_t *core, mc_gst_buffer_t *buff);
-int __mc_fill_output_buffer(mc_gst_core_t *core, GstBuffer *buff, media_packet_h *out_pkt);
-int __mc_create_caps(mc_gst_core_t *core, GstCaps **caps);
-
-int __mc_fill_inbuf_with_bo(mc_gst_core_t *core, mc_gst_buffer_t *buff);
-int __mc_fill_inbuf_with_packet(mc_gst_core_t *core, mc_gst_buffer_t *buff);
-
-int __mc_fill_outbuf_with_bo(mc_gst_core_t *core, GstBuffer *buff, media_packet_h *out_pkt);
-int __mc_fill_outbuf_with_packet(mc_gst_core_t *core, GstBuffer *buff, media_packet_h *out_pkt);
-
-int __mc_venc_caps(mc_gst_core_t *core, GstCaps **caps);
-int __mc_vdec_caps(mc_gst_core_t *core, GstCaps **caps);
-int __mc_aenc_caps(mc_gst_core_t *core, GstCaps **caps);
-int __mc_adec_caps(mc_gst_core_t *core, GstCaps **caps);
-int __mc_mp3dec_caps(mc_gst_core_t *core, GstCaps **caps);
-int __mc_h263enc_caps(mc_gst_core_t *core, GstCaps **caps);
-
+//int __mc_link_elements(mc_gst_core_t *core);
+int __mc_fill_input_buffer(mc_gst_core_t *core, media_packet_h pkt, GstMCBuffer *buff);
+int __mc_fill_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_pkt);
+int __mc_create_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config);
+
+//int __mc_venc_link(mc_gst_core_t *core);
+//int __mc_general_link(mc_gst_core_t *core);
+
+int __mc_fill_inbuf_with_mm_video_buffer(mc_gst_core_t *core, media_packet_h pkt, GstMCBuffer *buff);
+int __mc_fill_inbuf_with_packet(mc_gst_core_t *core, media_packet_h pkt, GstMCBuffer *buff);
+int __mc_fill_inbuf_with_venc_packet(mc_gst_core_t *core, media_packet_h pkt, GstMCBuffer *mc_buffer);
+
+int __mc_fill_packet_with_outbuf(mc_gst_core_t *core, void *data, int size, media_packet_h *out_pkt);
+int __mc_fill_venc_packet_with_outbuf(mc_gst_core_t *core, void *data, int size, media_packet_h *out_pkt);
+int __mc_fill_video_packet_with_mm_video_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_pkt);
+int __mc_fill_vdec_packet_with_outbuf(mc_gst_core_t *core, void *data, int size, media_packet_h *pkt);
+
+int __mc_vdec_h264_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config);
+int __mc_venc_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config);
+int __mc_vdec_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config);
+int __mc_vdec_h263_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config);
+int __mc_vdec_mpeg4_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config);
+int __mc_h264dec_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config);
+int __mc_sprddec_mpeg4_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config);
+int __mc_sprddec_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config);
+int __mc_sprdenc_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config);
+int __mc_sprdenc_mpeg4_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config);
+int __mc_aenc_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config);
+int __mc_adec_aac_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config);
+int __mc_aenc_aac_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config);
+int __mc_adec_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config);
+int __mc_adec_aacv12_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config);
+int __mc_adec_mp3_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config);
+int __mc_adec_amrnb_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config);
+int __mc_adec_amrwb_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config);
+int __mc_aenc_amrnb_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config);
+int __mc_adec_vorbis_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config);
+int __mc_adec_flac_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config);
+int __mc_adec_wma_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config);
+bool _mc_is_voss (unsigned char *p, int size, int *codec_size);
+bool _mc_is_ivop (unsigned char *p, int size, int pos);
+bool _mc_is_vop (unsigned char *p, int size, int pos);
+
+
+void _mc_create_codec_map_from_ini(mc_handle_t *mc_handle, mc_codec_spec_t *spec_emul);
+void _mc_create_decoder_map_from_ini(mc_handle_t *mc_handle);
+void _mc_create_encoder_map_from_ini(mc_handle_t *mc_handle);
mc_gst_core_t *mc_gst_core_new();
void mc_gst_core_free(mc_gst_core_t *core);
@@ -203,6 +220,8 @@ mc_ret_e mc_gst_unprepare(mc_handle_t *mc_handle);
mc_ret_e mc_gst_process_input(mc_handle_t *mc_handle, media_packet_h inbuf, uint64_t timeOutUs);
mc_ret_e mc_gst_get_output(mc_handle_t *mc_handle, media_packet_h *outbuf, uint64_t timeOutUs);
+mc_ret_e mc_gst_flush_buffers(mc_handle_t *mc_handle);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/media_codec_private.h b/include/media_codec_private.h
index 7bc76fc..c703087 100755
--- a/include/media_codec_private.h
+++ b/include/media_codec_private.h
@@ -47,6 +47,8 @@ extern "C" {
#define MEDIACODEC_NULL_ARG_CHECK(arg) \
MEDIACODEC_CHECK_CONDITION(arg != NULL,MEDIACODEC_ERROR_INVALID_PARAMETER,"MEDIACODEC_ERROR_INVALID_PARAMETER")
+#define MEDIACODEC_SUPPORT_CHECK(arg) \
+ MEDIACODEC_CHECK_CONDITION(arg != false, MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE, "MEDIACODEC_ERROR_NOT_SUPPORTED_ON_DEVICE")
/**
* @brief Enumeration of media codec state
* @since_tizen 2.3
@@ -110,6 +112,10 @@ typedef struct _mediacodec_s {
void* error_cb_userdata;
mediacodec_eos_cb eos_cb;
void* eos_cb_userdata;
+ mediacodec_buffer_status_cb buffer_status_cb;
+ void* buffer_status_cb_userdata;
+ mediacodec_supported_codec_cb supported_codec_cb;
+ void* supported_codec_cb_userdata;
} mediacodec_s;
diff --git a/include/media_codec_queue.h b/include/media_codec_queue.h
index 428a53c..5242997 100755
--- a/include/media_codec_queue.h
+++ b/include/media_codec_queue.h
@@ -55,6 +55,8 @@ void mc_async_queue_enable (async_queue_t *async_queue);
void mc_async_queue_flush(async_queue_t *async_queue);
+gboolean mc_async_queue_is_empty(async_queue_t *async_queue);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/media_codec_spec_emul.h b/include/media_codec_spec_emul.h
index 597d4b0..3ba2129 100755
--- a/include/media_codec_spec_emul.h
+++ b/include/media_codec_spec_emul.h
@@ -51,38 +51,6 @@ struct _mc_codec_map_t
mc_codec_type_t type;
};
-static const mc_codec_spec_t spec_emul[] =
-{
- {MEDIACODEC_H264, MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_SW, MEDIACODEC_PORT_TYPE_GST},
- {MEDIACODEC_H263, MEDIACODEC_ENCODER | MEDIACODEC_SUPPORT_TYPE_SW, MEDIACODEC_PORT_TYPE_GST},
- {MEDIACODEC_AAC, MEDIACODEC_ENCODER | MEDIACODEC_SUPPORT_TYPE_SW, MEDIACODEC_PORT_TYPE_GST},
- {MEDIACODEC_AAC, MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_SW, MEDIACODEC_PORT_TYPE_GST},
- {MEDIACODEC_MP3, MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_SW, MEDIACODEC_PORT_TYPE_GST}
-};
-
-static const mc_codec_map_t encoder_map[] =
-{
-#ifdef ENABLE_FFMPEG_CODEC
- {MEDIACODEC_H263, SOFTWARE, {"ffenc_h263", "video/x-raw-yuv", MEDIA_FORMAT_H263P }},
- {MEDIACODEC_AAC, SOFTWARE, {"ffenc_aac", "audio/x-raw-int", MEDIA_FORMAT_AAC}}
-#else
- {MEDIACODEC_H263, SOFTWARE, {"maru_h263enc", "video/x-raw-yuv", MEDIA_FORMAT_H263P}},
- {MEDIACODEC_AAC, SOFTWARE, {"maru_aacenc", "audio/x-raw-int", MEDIA_FORMAT_AAC}}
-#endif
-};
-
-static const mc_codec_map_t decoder_map[] =
-{
-#ifdef ENABLE_FFMPEG_CODEC
- {MEDIACODEC_H264, SOFTWARE, {"ffdec_h264", "video/x-h264", MEDIA_FORMAT_I420}},
- {MEDIACODEC_AAC, SOFTWARE, {"ffdec_aac", "audio/mpeg", MEDIA_FORMAT_PCM}},
- {MEDIACODEC_MP3, SOFTWARE, {"ffdec_mp3", "audio/mpeg", MEDIA_FORMAT_PCM}}
-#else
- {MEDIACODEC_H264, SOFTWARE, {"maru_h264dec", "video/x-h264", MEDIA_FORMAT_I420}},
- {MEDIACODEC_AAC, SOFTWARE, {"maru_aacdec", "audio/mpeg", MEDIA_FORMAT_PCM}},
- {MEDIACODEC_MP3, SOFTWARE, {"maru_mp3dec", "audio/mpeg", MEDIA_FORMAT_PCM}}
-#endif
-};
#ifdef __cplusplus
}
diff --git a/include/media_codec_util.h b/include/media_codec_util.h
index 5acf139..2142b1d 100755
--- a/include/media_codec_util.h
+++ b/include/media_codec_util.h
@@ -27,15 +27,6 @@
extern "C" {
#endif
-#if 1
-#define MEDIACODEC_FENTER(); LOGI("%s Enter",__FUNCTION__);
-#define MEDIACODEC_FLEAVE(); LOGI("%s Exit",__FUNCTION__);
-#else
-#define MEDIACODEC_FENTER(); LOGD("%s Enter",__FUNCTION__);
-#define MEDIACODEC_FLEAVE(); LOGD("%s Exit",__FUNCTION__);
-#endif
-
-
typedef enum
{
CODEC_RET_SUCCESS = 0,
@@ -67,6 +58,7 @@ mc_sem_t *mc_sem_new();
void mc_sem_free(mc_sem_t *sem);
void mc_sem_down(mc_sem_t *sem);
void mc_sem_up(mc_sem_t *sem);
+
void mc_hex_dump(char *desc, void *addr, int len);
#define MC_FREEIF(x) \
@@ -74,9 +66,6 @@ if ( x ) \
g_free( x ); \
x = NULL;
-
-
-
#ifdef __cplusplus
}
#endif
diff --git a/packaging/capi-media-codec.spec b/packaging/capi-media-codec.spec
index d6c1027..542839d 100755
--- a/packaging/capi-media-codec.spec
+++ b/packaging/capi-media-codec.spec
@@ -1,6 +1,6 @@
Name: capi-media-codec
Summary: A Media Codec library in Tizen Native API
-Version: 0.1.2
+Version: 0.4.2
Release: 0
Group: Multimedia/API
License: Apache-2.0
@@ -13,11 +13,16 @@ BuildRequires: pkgconfig(capi-base-common)
BuildRequires: pkgconfig(appcore-efl)
BuildRequires: pkgconfig(capi-media-tool)
BuildRequires: pkgconfig(libtbm)
-BuildRequires: pkgconfig(gstreamer-0.10)
-BuildRequires: pkgconfig(gstreamer-plugins-base-0.10)
-BuildRequires: pkgconfig(gstreamer-app-0.10)
-BuildRequires: pkgconfig(libdri2)
-
+BuildRequires: pkgconfig(gstreamer-1.0)
+BuildRequires: pkgconfig(gstreamer-plugins-base-1.0)
+BuildRequires: pkgconfig(gstreamer-app-1.0)
+BuildRequires: pkgconfig(capi-system-info)
+BuildRequires: pkgconfig(iniparser)
+%if "%{tizen_target_name}" == "Z130H" || "%{?tizen_target_name}" == "Z300H"
+#!BuildIgnore: kernel-headers
+BuildConflicts: linux-glibc-devel
+BuildRequires: kernel-headers-tizen-dev
+%endif
Requires(post): /sbin/ldconfig
Requires(post): libprivilege-control
Requires(postun): /sbin/ldconfig
@@ -27,7 +32,7 @@ Requires(postun): /sbin/ldconfig
%package devel
Summary: A Media Player library in Tizen Native API (Development)
-Group: Multimedia/API
+Group: TO_BE/FILLED_IN
Requires: %{name} = %{version}-%{release}
%description devel
@@ -37,6 +42,9 @@ Requires: %{name} = %{version}-%{release}
%build
+%if "%{tizen_target_name}" == "Z130H" || "%{?tizen_target_name}" == "Z300H"
+export CFLAGS="$CFLAGS -DTIZEN_PROFILE_LITE"
+%endif
%if 0%{?sec_build_binary_debug_enable}
export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE"
export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE"
@@ -56,8 +64,9 @@ make %{?jobs:-j%jobs}
rm -rf %{buildroot}
mkdir -p %{buildroot}/usr/share/license
mkdir -p %{buildroot}/usr/bin
-cp LICENSE.APLv2 %{buildroot}/usr/share/license/%{name}
cp test/media_codec_test %{buildroot}/usr/bin
+cp LICENSE.APLv2 %{buildroot}/usr/share/license/%{name}
+
%make_install
%post
diff --git a/src/media_codec.c b/src/media_codec.c
index 75988a3..efd6591 100755
--- a/src/media_codec.c
+++ b/src/media_codec.c
@@ -20,6 +20,7 @@
#include <media_codec.h>
#include <media_codec_private.h>
#include <media_codec_port.h>
+#include <system_info.h>
#include <dlog.h>
@@ -27,16 +28,19 @@ static gboolean __mediacodec_empty_buffer_cb(media_packet_h pkt, void *user_dat
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);
+
/*
* Internal Implementation
*/
-int __convert_error_code(int code, char* func_name)
+int __convert_error_code(int code, char *func_name)
{
int ret = MEDIACODEC_ERROR_INVALID_OPERATION;
- char* msg = "MEDIACOODEC_INVALID_OPERATION";
- switch(code)
- {
+ char *msg = "MEDIACOODEC_INVALID_OPERATION";
+
+ switch (code) {
case MC_ERROR_NONE:
ret = MEDIACODEC_ERROR_NONE;
msg = "MEDIACODEC_ERROR_NONE";
@@ -102,15 +106,9 @@ int __convert_error_code(int code, char* func_name)
return ret;
}
-bool __mediacodec_state_validate(mediacodec_h mediacodec, mediacodec_state_e threshold)
-{
- mediacodec_s * handle = (mediacodec_s *) mediacodec;
-
- if(handle->state < threshold)
- return FALSE;
- return TRUE;
-}
-
+/*
+ * Public Implementation
+ */
int mediacodec_create(mediacodec_h *mediacodec)
{
@@ -118,31 +116,25 @@ int mediacodec_create(mediacodec_h *mediacodec)
mediacodec_s *handle;
int ret;
- LOGD ("mediacodec_create..\n");
+ LOGD("mediacodec_create..");
- handle = (mediacodec_s*)malloc( sizeof(mediacodec_s));
- if (handle != NULL)
- {
+ handle = (mediacodec_s *)malloc(sizeof(mediacodec_s));
+ if (handle != NULL) {
memset(handle, 0 , sizeof(mediacodec_s));
- }
- else
- {
+ } else {
LOGE("MEDIACODEC_ERROR_OUT_OF_MEMORY(0x%08x)", MEDIACODEC_ERROR_OUT_OF_MEMORY);
return MEDIACODEC_ERROR_OUT_OF_MEMORY;
}
ret = mc_create(&handle->mc_handle);
- if (ret != MEDIACODEC_ERROR_NONE)
- {
+ if (ret != MEDIACODEC_ERROR_NONE) {
LOGE("MEDIACODEC_ERROR_INVALID_OPERATION(0x%08x)", MEDIACODEC_ERROR_INVALID_OPERATION);
handle->state = MEDIACODEC_STATE_NONE;
free(handle);
handle = NULL;
return MEDIACODEC_ERROR_INVALID_OPERATION;
- }
- else
- {
- *mediacodec = (mediacodec_h) handle;
+ } else {
+ *mediacodec = (mediacodec_h)handle;
handle->state = MEDIACODEC_STATE_IDLE;
LOGD("new handle : %p", *mediacodec);
}
@@ -152,6 +144,8 @@ int mediacodec_create(mediacodec_h *mediacodec)
mc_set_fill_buffer_cb(handle->mc_handle, (mediacodec_output_buffer_available_cb)__mediacodec_fill_buffer_cb, handle);
mc_set_error_cb(handle->mc_handle, (mediacodec_error_cb)__mediacodec_error_cb, handle);
mc_set_eos_cb(handle->mc_handle, (mediacodec_eos_cb)__mediacodec_eos_cb, handle);
+ 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);
return MEDIACODEC_ERROR_NONE;
@@ -159,17 +153,15 @@ int mediacodec_create(mediacodec_h *mediacodec)
int mediacodec_destroy(mediacodec_h mediacodec)
{
- LOGD ("[%s] Start, handle to destroy : %p", __FUNCTION__, mediacodec);
+ LOGD("[%s] Start, handle to destroy : %p", __FUNCTION__, mediacodec);
MEDIACODEC_INSTANCE_CHECK(mediacodec);
- mediacodec_s * handle = (mediacodec_s *) mediacodec;
+ mediacodec_s *handle = (mediacodec_s *)mediacodec;
int ret = mc_destroy(handle->mc_handle);
if (ret != MEDIACODEC_ERROR_NONE) {
LOGD("MEDIACODEC_ERROR_INVALID_OPERATION(0x%08x)", MEDIACODEC_ERROR_INVALID_OPERATION);
return MEDIACODEC_ERROR_INVALID_OPERATION;
- }
- else
- {
+ } else {
handle->state = MEDIACODEC_STATE_NONE;
free(handle);
handle = NULL;
@@ -180,17 +172,14 @@ int mediacodec_destroy(mediacodec_h mediacodec)
int mediacodec_set_codec(mediacodec_h mediacodec, mediacodec_codec_type_e codec_id, mediacodec_support_type_e flags)
{
MEDIACODEC_INSTANCE_CHECK(mediacodec);
- mediacodec_s * handle = (mediacodec_s *) mediacodec;
+ mediacodec_s *handle = (mediacodec_s *)mediacodec;
MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
int ret = mc_set_codec(handle->mc_handle, codec_id, flags);
- if (ret != MEDIACODEC_ERROR_NONE)
- {
- return __convert_error_code(ret,(char*)__FUNCTION__);
- }
- else
- {
+ if (ret != MEDIACODEC_ERROR_NONE) {
+ return __convert_error_code(ret, (char *)__FUNCTION__);
+ } else {
handle->state = MEDIACODEC_STATE_IDLE;
return MEDIACODEC_ERROR_NONE;
}
@@ -199,17 +188,14 @@ int mediacodec_set_codec(mediacodec_h mediacodec, mediacodec_codec_type_e codec_
int mediacodec_set_vdec_info(mediacodec_h mediacodec, int width, int height)
{
MEDIACODEC_INSTANCE_CHECK(mediacodec);
- mediacodec_s * handle = (mediacodec_s *) mediacodec;
+ mediacodec_s *handle = (mediacodec_s *)mediacodec;
MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
int ret = mc_set_vdec_info(handle->mc_handle, width, height);
- if (ret != MEDIACODEC_ERROR_NONE)
- {
- return __convert_error_code(ret,(char*)__FUNCTION__);
- }
- else
- {
+ if (ret != MEDIACODEC_ERROR_NONE) {
+ return __convert_error_code(ret, (char *)__FUNCTION__);
+ } else {
handle->state = MEDIACODEC_STATE_IDLE;
return MEDIACODEC_ERROR_NONE;
}
@@ -218,17 +204,14 @@ 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)
{
MEDIACODEC_INSTANCE_CHECK(mediacodec);
- mediacodec_s * handle = (mediacodec_s *) mediacodec;
+ mediacodec_s *handle = (mediacodec_s *)mediacodec;
MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
int ret = mc_set_venc_info(handle->mc_handle, width, height, fps, target_bits);
- if (ret != MEDIACODEC_ERROR_NONE)
- {
- return __convert_error_code(ret,(char*)__FUNCTION__);
- }
- else
- {
+ if (ret != MEDIACODEC_ERROR_NONE) {
+ return __convert_error_code(ret, (char *)__FUNCTION__);
+ } else {
handle->state = MEDIACODEC_STATE_IDLE;
return MEDIACODEC_ERROR_NONE;
}
@@ -237,17 +220,14 @@ 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)
{
MEDIACODEC_INSTANCE_CHECK(mediacodec);
- mediacodec_s * handle = (mediacodec_s *) mediacodec;
+ mediacodec_s *handle = (mediacodec_s *)mediacodec;
MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
int ret = mc_set_adec_info(handle->mc_handle, samplerate, channel, bit);
- if (ret != MEDIACODEC_ERROR_NONE)
- {
- return __convert_error_code(ret,(char*)__FUNCTION__);
- }
- else
- {
+ if (ret != MEDIACODEC_ERROR_NONE) {
+ return __convert_error_code(ret, (char *)__FUNCTION__);
+ } else {
handle->state = MEDIACODEC_STATE_IDLE;
return MEDIACODEC_ERROR_NONE;
}
@@ -256,17 +236,14 @@ int mediacodec_set_adec_info(mediacodec_h mediacodec, int samplerate, int channe
int mediacodec_set_aenc_info(mediacodec_h mediacodec, int samplerate, int channel, int bit, int bitrate)
{
MEDIACODEC_INSTANCE_CHECK(mediacodec);
- mediacodec_s * handle = (mediacodec_s *) mediacodec;
+ mediacodec_s *handle = (mediacodec_s *)mediacodec;
MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
int ret = mc_set_aenc_info(handle->mc_handle, samplerate, channel, bit, bitrate);
- if (ret != MEDIACODEC_ERROR_NONE)
- {
- return __convert_error_code(ret,(char*)__FUNCTION__);
- }
- else
- {
+ if (ret != MEDIACODEC_ERROR_NONE) {
+ return __convert_error_code(ret, (char *)__FUNCTION__);
+ } else {
handle->state = MEDIACODEC_STATE_IDLE;
return MEDIACODEC_ERROR_NONE;
}
@@ -275,17 +252,14 @@ int mediacodec_set_aenc_info(mediacodec_h mediacodec, int samplerate, int channe
int mediacodec_prepare(mediacodec_h mediacodec)
{
MEDIACODEC_INSTANCE_CHECK(mediacodec);
- mediacodec_s * handle = (mediacodec_s *) mediacodec;
+ mediacodec_s *handle = (mediacodec_s *)mediacodec;
MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
int ret = mc_prepare(handle->mc_handle);
- if (ret != MEDIACODEC_ERROR_NONE)
- {
- return __convert_error_code(ret,(char*)__FUNCTION__);
- }
- else
- {
+ if (ret != MEDIACODEC_ERROR_NONE) {
+ return __convert_error_code(ret, (char *)__FUNCTION__);
+ } else {
handle->state = MEDIACODEC_STATE_READY;
return MEDIACODEC_ERROR_NONE;
}
@@ -294,16 +268,13 @@ int mediacodec_prepare(mediacodec_h mediacodec)
int mediacodec_unprepare(mediacodec_h mediacodec)
{
MEDIACODEC_INSTANCE_CHECK(mediacodec);
- mediacodec_s * handle = (mediacodec_s *) mediacodec;
+ mediacodec_s *handle = (mediacodec_s *)mediacodec;
int ret = mc_unprepare(handle->mc_handle);
- if (ret != MEDIACODEC_ERROR_NONE)
- {
- return __convert_error_code(ret,(char*)__FUNCTION__);
- }
- else
- {
+ if (ret != MEDIACODEC_ERROR_NONE) {
+ return __convert_error_code(ret, (char *)__FUNCTION__);
+ } else {
handle->state = MEDIACODEC_STATE_IDLE;
return MEDIACODEC_ERROR_NONE;
}
@@ -312,18 +283,14 @@ int mediacodec_unprepare(mediacodec_h mediacodec)
int mediacodec_process_input(mediacodec_h mediacodec, media_packet_h inbuf, uint64_t timeOutUs)
{
MEDIACODEC_INSTANCE_CHECK(mediacodec);
- mediacodec_s * handle = (mediacodec_s *) mediacodec;
+ mediacodec_s *handle = (mediacodec_s *)mediacodec;
MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_READY);
int ret = mc_process_input(handle->mc_handle, inbuf, timeOutUs);
- if (ret != MEDIACODEC_ERROR_NONE)
- {
- return __convert_error_code(ret,(char*)__FUNCTION__);
- }
- else
- {
- //handle->state = MEDIACODEC_STATE_EXCUTE;
+ if (ret != MEDIACODEC_ERROR_NONE) {
+ return __convert_error_code(ret, (char *)__FUNCTION__);
+ } else {
return MEDIACODEC_ERROR_NONE;
}
}
@@ -331,26 +298,52 @@ int mediacodec_process_input(mediacodec_h mediacodec, media_packet_h inbuf, uint
int mediacodec_get_output(mediacodec_h mediacodec, media_packet_h *outbuf, uint64_t timeOutUs)
{
MEDIACODEC_INSTANCE_CHECK(mediacodec);
- mediacodec_s * handle = (mediacodec_s *) mediacodec;
+ mediacodec_s *handle = (mediacodec_s *)mediacodec;
MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_READY);
int ret = mc_get_output(handle->mc_handle, outbuf, timeOutUs);
- if (ret != MEDIACODEC_ERROR_NONE)
- {
- return __convert_error_code(ret,(char*)__FUNCTION__);
+ if (ret != MEDIACODEC_ERROR_NONE) {
+ return __convert_error_code(ret, (char *)__FUNCTION__);
+ } else {
+ return MEDIACODEC_ERROR_NONE;
}
- else
- {
- //handle->state = MEDIACODEC_STATE_EXCUTE;
+}
+
+int mediacodec_flush_buffers(mediacodec_h mediacodec)
+{
+ MEDIACODEC_INSTANCE_CHECK(mediacodec);
+ mediacodec_s *handle = (mediacodec_s *)mediacodec;
+
+ int ret = mc_flush_buffers(handle->mc_handle);
+
+ if (ret != MEDIACODEC_ERROR_NONE) {
+ return __convert_error_code(ret, (char *)__FUNCTION__);
+ } else {
+ return MEDIACODEC_ERROR_NONE;
+ }
+}
+
+int mediacodec_get_supported_type(mediacodec_h mediacodec, mediacodec_codec_type_e codec_type, bool encoder, int *support_type)
+{
+ MEDIACODEC_INSTANCE_CHECK(mediacodec);
+ mediacodec_s *handle = (mediacodec_s *)mediacodec;
+ MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
+
+ int ret = mc_get_supported_type(handle->mc_handle, codec_type, encoder, support_type);
+
+ if (ret != MEDIACODEC_ERROR_NONE) {
+ return __convert_error_code(ret, (char *)__FUNCTION__);
+ } else {
+ handle->state = MEDIACODEC_STATE_IDLE;
return MEDIACODEC_ERROR_NONE;
}
}
-int mediacodec_set_input_buffer_used_cb(mediacodec_h mediacodec, mediacodec_input_buffer_used_cb callback, void* user_data)
+int mediacodec_set_input_buffer_used_cb(mediacodec_h mediacodec, mediacodec_input_buffer_used_cb callback, void *user_data)
{
MEDIACODEC_INSTANCE_CHECK(mediacodec);
- mediacodec_s * handle = (mediacodec_s *) mediacodec;
+ mediacodec_s *handle = (mediacodec_s *)mediacodec;
MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
handle->empty_buffer_cb = callback;
@@ -364,7 +357,7 @@ int mediacodec_set_input_buffer_used_cb(mediacodec_h mediacodec, mediacodec_inpu
int mediacodec_unset_input_buffer_used_cb(mediacodec_h mediacodec)
{
MEDIACODEC_INSTANCE_CHECK(mediacodec);
- mediacodec_s * handle = (mediacodec_s *) mediacodec;
+ mediacodec_s *handle = (mediacodec_s *)mediacodec;
handle->empty_buffer_cb = NULL;
handle->empty_buffer_cb_userdata = NULL;
@@ -373,10 +366,10 @@ int mediacodec_unset_input_buffer_used_cb(mediacodec_h mediacodec)
}
-int mediacodec_set_output_buffer_available_cb(mediacodec_h mediacodec, mediacodec_output_buffer_available_cb callback, void* user_data)
+int mediacodec_set_output_buffer_available_cb(mediacodec_h mediacodec, mediacodec_output_buffer_available_cb callback, void *user_data)
{
MEDIACODEC_INSTANCE_CHECK(mediacodec);
- mediacodec_s * handle = (mediacodec_s *) mediacodec;
+ mediacodec_s *handle = (mediacodec_s *)mediacodec;
MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
handle->fill_buffer_cb = callback;
@@ -391,7 +384,7 @@ int mediacodec_set_output_buffer_available_cb(mediacodec_h mediacodec, mediacode
int mediacodec_unset_output_buffer_available_cb(mediacodec_h mediacodec)
{
MEDIACODEC_INSTANCE_CHECK(mediacodec);
- mediacodec_s * handle = (mediacodec_s *) mediacodec;
+ mediacodec_s *handle = (mediacodec_s *)mediacodec;
handle->fill_buffer_cb = NULL;
handle->fill_buffer_cb_userdata = NULL;
@@ -399,10 +392,10 @@ int mediacodec_unset_output_buffer_available_cb(mediacodec_h mediacodec)
return MEDIACODEC_ERROR_NONE;
}
-int mediacodec_set_error_cb(mediacodec_h mediacodec, mediacodec_error_cb callback, void* user_data)
+int mediacodec_set_error_cb(mediacodec_h mediacodec, mediacodec_error_cb callback, void *user_data)
{
MEDIACODEC_INSTANCE_CHECK(mediacodec);
- mediacodec_s * handle = (mediacodec_s *) mediacodec;
+ mediacodec_s *handle = (mediacodec_s *)mediacodec;
MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
handle->error_cb = callback;
@@ -417,7 +410,7 @@ int mediacodec_set_error_cb(mediacodec_h mediacodec, mediacodec_error_cb callbac
int mediacodec_unset_error_cb(mediacodec_h mediacodec)
{
MEDIACODEC_INSTANCE_CHECK(mediacodec);
- mediacodec_s * handle = (mediacodec_s *) mediacodec;
+ mediacodec_s *handle = (mediacodec_s *)mediacodec;
handle->error_cb = NULL;
handle->error_cb_userdata = NULL;
@@ -425,10 +418,10 @@ int mediacodec_unset_error_cb(mediacodec_h mediacodec)
return MEDIACODEC_ERROR_NONE;
}
-int mediacodec_set_eos_cb(mediacodec_h mediacodec, mediacodec_eos_cb callback, void* user_data)
+int mediacodec_set_eos_cb(mediacodec_h mediacodec, mediacodec_eos_cb callback, void *user_data)
{
MEDIACODEC_INSTANCE_CHECK(mediacodec);
- mediacodec_s * handle = (mediacodec_s *) mediacodec;
+ mediacodec_s *handle = (mediacodec_s *)mediacodec;
MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
handle->eos_cb = callback;
@@ -443,7 +436,7 @@ int mediacodec_set_eos_cb(mediacodec_h mediacodec, mediacodec_eos_cb callback, v
int mediacodec_unset_eos_cb(mediacodec_h mediacodec)
{
MEDIACODEC_INSTANCE_CHECK(mediacodec);
- mediacodec_s * handle = (mediacodec_s *) mediacodec;
+ mediacodec_s *handle = (mediacodec_s *)mediacodec;
handle->eos_cb = NULL;
handle->eos_cb_userdata = NULL;
@@ -451,15 +444,61 @@ int mediacodec_unset_eos_cb(mediacodec_h mediacodec)
return MEDIACODEC_ERROR_NONE;
}
+int mediacodec_set_buffer_status_cb(mediacodec_h mediacodec, mediacodec_buffer_status_cb callback, void *user_data)
+{
+ MEDIACODEC_INSTANCE_CHECK(mediacodec);
+ mediacodec_s *handle = (mediacodec_s *)mediacodec;
+ MEDIACODEC_STATE_CHECK(handle, MEDIACODEC_STATE_IDLE);
+
+ handle->buffer_status_cb = callback;
+ handle->buffer_status_cb_userdata = user_data;
+
+ LOGD("set buffer_status_cb(%p)", callback);
+
+ return MEDIACODEC_ERROR_NONE;
+
+}
+
+int mediacodec_unset_buffer_status_cb(mediacodec_h mediacodec)
+{
+ MEDIACODEC_INSTANCE_CHECK(mediacodec);
+ mediacodec_s *handle = (mediacodec_s *)mediacodec;
+
+ handle->buffer_status_cb = NULL;
+ handle->buffer_status_cb_userdata = NULL;
+
+ return MEDIACODEC_ERROR_NONE;
+}
+
+int mediacodec_foreach_supported_codec(mediacodec_h mediacodec, mediacodec_supported_codec_cb callback, void *user_data)
+{
+ MEDIACODEC_INSTANCE_CHECK(mediacodec);
+ mediacodec_s *handle = (mediacodec_s *)mediacodec;
+
+ handle->supported_codec_cb = callback;
+ handle->supported_codec_cb_userdata = user_data;
+
+ LOGD("set supported_codec_cb(%p)", callback);
+ int ret = _mediacodec_foreach_supported_codec(handle->mc_handle, callback, handle);
+
+ if (ret != MEDIACODEC_ERROR_NONE) {
+ return __convert_error_code(ret, (char *)__FUNCTION__);
+ } else {
+ return MEDIACODEC_ERROR_NONE;
+ }
+
+ return MEDIACODEC_ERROR_NONE;
+
+}
+
static gboolean __mediacodec_empty_buffer_cb(media_packet_h pkt, void *user_data)
{
- if(user_data == NULL || pkt == NULL)
+ if (user_data == NULL || pkt == NULL)
return 0;
- mediacodec_s * handle = (mediacodec_s *) user_data;
+ mediacodec_s *handle = (mediacodec_s *)user_data;
- if ( handle->empty_buffer_cb )
- {
+ if (handle->empty_buffer_cb) {
((mediacodec_input_buffer_used_cb)handle->empty_buffer_cb)(pkt, handle->empty_buffer_cb_userdata);
}
@@ -468,13 +507,12 @@ 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)
{
- if(user_data == NULL || pkt == NULL)
+ if (user_data == NULL || pkt == NULL)
return 0;
- mediacodec_s * handle = (mediacodec_s *) user_data;
+ mediacodec_s *handle = (mediacodec_s *)user_data;
- if ( handle->fill_buffer_cb )
- {
+ if (handle->fill_buffer_cb) {
((mediacodec_output_buffer_available_cb)handle->fill_buffer_cb)(pkt, handle->fill_buffer_cb_userdata);
}
@@ -483,13 +521,12 @@ 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)
{
- if(user_data == NULL)
+ if (user_data == NULL)
return 0;
- mediacodec_s * handle = (mediacodec_s *) user_data;
+ mediacodec_s *handle = (mediacodec_s *)user_data;
- if ( handle->error_cb )
- {
+ if (handle->error_cb) {
((mediacodec_error_cb)handle->error_cb)(error, handle->error_cb_userdata);
}
@@ -498,15 +535,42 @@ static gboolean __mediacodec_error_cb(mediacodec_error_e error, void *user_data)
static gboolean __mediacodec_eos_cb(void *user_data)
{
- if(user_data == NULL)
+ if (user_data == NULL)
return 0;
- mediacodec_s * handle = (mediacodec_s *) user_data;
+ mediacodec_s *handle = (mediacodec_s *)user_data;
- if ( handle->eos_cb )
- {
+ if (handle->eos_cb) {
((mediacodec_eos_cb)handle->eos_cb)(handle->eos_cb_userdata);
}
return 1;
}
+
+static gboolean __mediacodec_supported_codec_cb(mediacodec_codec_type_e codec_type, void *user_data)
+{
+ if (user_data == NULL)
+ return 0;
+
+ mediacodec_s *handle = (mediacodec_s *)user_data;
+
+ if (handle->supported_codec_cb) {
+ return ((mediacodec_supported_codec_cb)handle->supported_codec_cb)(codec_type, handle->supported_codec_cb_userdata);
+ }
+ return false;
+}
+
+static gboolean __mediacodec_buffer_status_cb(mediacodec_status_e status, void *user_data)
+{
+ if (user_data == NULL)
+ return 0;
+
+ mediacodec_s *handle = (mediacodec_s *)user_data;
+
+ if (handle->buffer_status_cb) {
+ ((mediacodec_buffer_status_cb)handle->buffer_status_cb)(status, handle->buffer_status_cb_userdata);
+ }
+
+ return 1;
+}
+
diff --git a/src/media_codec_bitstream.c b/src/media_codec_bitstream.c
new file mode 100755
index 0000000..7e08491
--- /dev/null
+++ b/src/media_codec_bitstream.c
@@ -0,0 +1,372 @@
+/*
+* Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+ *
+ */
+#include <stdio.h>
+#include <dlog.h>
+#include <media_codec_bitstream.h>
+
+void mc_init_bits(mc_bitstream_t *stream, unsigned char *data, int size)
+{
+ stream->data = data;
+ stream->numBytes = size;
+ stream->bitcnt = 32;
+ stream->bytePos = 0;
+ stream->dataBitPos = 0;
+ stream->buffer = 0;
+}
+
+short mc_show_bits(mc_bitstream_t *stream, unsigned char nbits, unsigned int *pulOutData)
+{
+ unsigned char *bits;
+ unsigned int dataBitPos = stream->dataBitPos;
+ unsigned int bitcnt = stream->bitcnt;
+ unsigned int dataBytePos;
+ unsigned int i;
+
+ if (nbits > (32 - bitcnt)) {
+ dataBytePos = dataBitPos >> 3;
+ bitcnt = dataBitPos & 7;
+ if (dataBytePos > stream->numBytes - 4) {
+ stream->buffer = 0;
+ for (i = 0; i < stream->numBytes - dataBytePos; i++) {
+ stream->buffer |= stream->data[dataBytePos + i];
+ stream->buffer <<= 8;
+ }
+ stream->buffer <<= 8 * (3 - i);
+ } else {
+ bits = &stream->data[dataBytePos];
+ stream->buffer = (bits[0] << 24) | (bits[1] << 16) | (bits[2] << 8) | bits[3];
+ }
+ stream->bitcnt = bitcnt;
+ }
+ bitcnt += nbits;
+
+ *pulOutData = (stream->buffer >> (32 - bitcnt)) & mask[(unsigned short)nbits];
+
+ return 0;
+}
+
+short mc_read_bits(mc_bitstream_t *stream, unsigned char nbits, unsigned int *pulOutData)
+{
+ unsigned char *bits;
+ unsigned int dataBitPos = stream->dataBitPos;
+ unsigned int bitcnt = stream->bitcnt;
+ unsigned int dataBytePos;
+
+ if ((dataBitPos + nbits) > (stream->numBytes << 3)) {
+ *pulOutData = 0;
+ return -1;
+ }
+
+ if (nbits > (32 - bitcnt)) {
+ dataBytePos = dataBitPos >> 3;
+ bitcnt = dataBitPos & 7;
+ bits = &stream->data[dataBytePos];
+ stream->buffer = (bits[0] << 24) | (bits[1] << 16) | (bits[2] << 8) | bits[3];
+ }
+
+
+ stream->dataBitPos += nbits;
+ stream->bitcnt = (unsigned char)(bitcnt + nbits);
+
+
+ *pulOutData = (stream->buffer >> (32 - stream->bitcnt)) & mask[(unsigned short)nbits];
+
+ return 0;
+}
+
+short mc_byte_align(mc_bitstream_t *stream)
+{
+ unsigned char *bits;
+ unsigned int dataBitPos = stream->dataBitPos;
+ unsigned int bitcnt = stream->bitcnt;
+ unsigned int dataBytePos;
+ unsigned int leftBits;
+
+ leftBits = 8 - (dataBitPos & 0x7);
+ if (leftBits == 8) {
+ if ((dataBitPos + 8) > (unsigned int)(stream->numBytes << 3))
+ return (-1);
+ dataBitPos += 8;
+ bitcnt += 8;
+ } else {
+ dataBytePos = dataBitPos >> 3;
+ dataBitPos += leftBits;
+ bitcnt += leftBits;
+ }
+
+ if (bitcnt > 32) {
+ dataBytePos = dataBitPos >> 3;
+ bits = &stream->data[dataBytePos];
+ stream->buffer = (bits[0] << 24) | (bits[1] << 16) | (bits[2] << 8) | bits[3];
+ }
+
+
+ stream->dataBitPos = dataBitPos;
+ stream->bitcnt = bitcnt;
+
+ return 0;
+}
+unsigned int __mc_bytestream_to_nal(unsigned char *data, int size)
+{
+ unsigned char val, zero_count;
+ unsigned char *pNal = data;
+ int index = 0;
+
+ zero_count = 0;
+
+ val = pNal[index++];
+ while (!val) {
+ zero_count++;
+ val = pNal[index++];
+ }
+
+ zero_count = 0;
+
+ while (1) {
+ if (index >= size)
+ return (index - 1);
+
+ val = pNal[index++];
+
+ if (!val)
+ zero_count++;
+ else {
+ if ((zero_count >= 2) && (val == 1))
+ break;
+ else {
+ zero_count = 0;
+ }
+ }
+ }
+
+ if (zero_count > 3)
+ zero_count = 3;
+
+ return (index - zero_count - 1);
+}
+
+int __mc_decode_sps(mc_bitstream_t *pstream, int *width, int *height)
+{
+ int ret = MC_ERROR_NONE;
+ unsigned int tmp = 0;
+
+ int profile_idc = 0;
+
+ mc_read_bits(pstream, 8, &tmp);
+ mc_read_bits(pstream, 1, &tmp);
+ mc_read_bits(pstream, 1, &tmp);
+ mc_read_bits(pstream, 1, &tmp);
+ mc_read_bits(pstream, 5, &tmp);
+ mc_read_bits(pstream, 8, &tmp);
+
+ profile_idc = tmp;
+
+ if (profile_idc > 51)
+ ret = MC_INVALID_IN_BUF;
+
+ /*TODO parse width, height, etc...*/
+
+ return ret;
+}
+
+int _mc_check_h264_bytestream(unsigned char *nal, int byte_length, bool port, bool *codec_config, bool *sync_flag, bool *slice)
+{
+ int ret = MC_ERROR_NONE;
+ int stacked_length = 0;
+ int nal_length = 0;
+ unsigned int syntax = 0;
+ unsigned int state = 0;
+ int count = 0;
+ int nal_unit_type = 0;
+
+ mc_bitstream_t pstream;
+
+ nal_unit_type = nal[2] == 1 ? (nal[3] & 0x1F) : (nal[4] & 0x1F);
+
+ if (nal_unit_type == 0x7 || nal_unit_type == 0x8 || nal_unit_type == 0x9) {
+
+ while (1) {
+ nal_length = __mc_bytestream_to_nal(nal + stacked_length, byte_length - stacked_length);
+
+ mc_init_bits(&pstream, nal + stacked_length, byte_length - stacked_length);
+ mc_read_bits(&pstream, 32, &syntax);
+ mc_read_bits(&pstream, 8, &syntax);
+
+ switch (syntax & 0x1F) {
+ case NAL_SEQUENCE_PARAMETER_SET:
+ LOGD("nal_unit_type : SPS");
+ if ((ret = __mc_decode_sps(&pstream, NULL, NULL)) != MC_ERROR_NONE)
+ return ret;
+ state |= MC_EXIST_SPS;
+ break;
+ case NAL_PICTURE_PARAMETER_SET:
+ LOGD("nal_unit_type : PPS");
+ state |= MC_EXIST_PPS;
+ break;
+ case NAL_SLICE_IDR:
+ LOGD("nal_unit_type : IDR");
+ state |= MC_EXIST_IDR;
+ break;
+ default:
+ state |= MC_EXIST_SLICE;
+ LOGD("nal_unit_type : %x", syntax & 0x1F);
+ break;
+ }
+
+ LOGD("stacked_length : %d, nal_length : %d, byte_length : %d", stacked_length, nal_length, byte_length);
+
+ stacked_length += nal_length;
+ count++;
+
+ if ((stacked_length >= byte_length) || count > 5)
+ break;
+ }
+ } else if (nal_unit_type == 0x5) {
+ state |= MC_EXIST_IDR;
+ LOGD("nal_unit_type is IDR");
+ } else if (nal_unit_type == 0x01 || nal_unit_type == 0x02 || nal_unit_type == 0x03 || nal_unit_type == 0x04) {
+ state |= MC_EXIST_SLICE;
+ LOGD("nal_unit_type : %x", nal_unit_type);
+ } else {
+ LOGD("Non VCL");
+ }
+
+ LOGD("for debug state :%d, %d", state, MC_VALID_FIRST_SLICE);
+
+ /* input port */
+ if (!port && !CHECK_VALID_PACKET(state, MC_VALID_FIRST_SLICE))
+ return MC_INVALID_IN_BUF;
+
+ /* output port */
+ if (port) {
+ *codec_config = CHECK_VALID_PACKET(state, MC_VALID_HEADER) ? 1 : 0;
+ *sync_flag = CHECK_VALID_PACKET(state, MC_EXIST_IDR) ? 1 : 0;
+ *slice = CHECK_VALID_PACKET(state, MC_EXIST_SLICE) ? 1 : 0;
+ }
+
+ return ret;
+}
+
+int _mc_check_valid_h263_frame(unsigned char *p, int size)
+{
+ unsigned char *end = p + size - 3;
+ int count = 0;
+
+ do {
+ /* Found the start of the frame, now try to find the end */
+ if ((p[0] == 0x00) && (p[1] == 0x00) && ((p[2]&0xFC) == 0x80))
+ count++;
+ p++;
+ } while (count == 1 && p < end);
+
+ if (count != 1)
+ return MC_INVALID_IN_BUF; /* frame boundary violated */
+
+ return MC_ERROR_NONE;
+}
+
+bool _mc_is_voss(unsigned char *buf, int size, int *codec_size)
+{
+ unsigned char *p = buf;
+ unsigned char *end = p + size - 3;
+ if (size < 4)
+ return false;
+
+ if (!((p[0] == 0x00) && (p[1] == 0x00) && (p[2] == 0x01) && (p[3] == 0xB0)))
+ return false;
+
+ if (codec_size) {
+ for (; p < end ; p++) {
+ if ((p[0] == 0x00) && (p[1] == 0x00) && (p[2] == 0x01) && (p[3] == 0xB6)) {
+ *codec_size = p-buf;
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool _mc_is_ivop(unsigned char *p, int size, int pos)
+{
+ if (size < (pos + 5))
+ return false;
+
+ p = p + pos;
+
+ if ((p[0] == 0x00) && (p[1] == 0x00) && (p[2] == 0x01) && (p[3] == 0xB6)) {
+ /* VOP_CODING_TYPE (binary) Coding method
+ // 00 intra-coded (I)
+ // 01 predictive-coded (P)
+ // 10 bidirectionally-predictive-coded (B)
+ // 11 sprite (S)
+ */
+ if ((p[4] & 0xC0) == 0x0) /*I-VOP */
+ return true;
+ }
+ return false;
+}
+
+bool _mc_is_vop(unsigned char *p, int size, int pos)
+{
+ if (size < (pos + 4))
+ return false;
+
+ p = p + pos;
+
+ if ((p[0] == 0x00) && (p[1] == 0x00) && (p[2] == 0x01) && (p[3] == 0xB6))
+ return true;
+
+ return false;
+}
+
+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;
+
+ if (_mc_is_voss(buf, buf_length, &codec_data_size))
+ *need_codec_data = TRUE;
+ if (_mc_is_ivop(buf, buf_length, codec_data_size))
+ *need_sync_flag = TRUE;
+
+ return codec_data_size;
+}
+
+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 */
+ if ((p[0] != 0x00) || (p[1] != 0x00) || ((p[2]&0xFC) != 0x80)) {
+ return false;
+ }
+
+ /* PTYPE Field, Bit 9: Picture Coding Type, "0" INTRA (I-picture), "1" INTER (P-picture) */
+ if (!(p[4] & 0x2)) {
+ *need_sync_flag = TRUE;
+ }
+
+ return TRUE;
+}
+
diff --git a/src/media_codec_ini.c b/src/media_codec_ini.c
new file mode 100755
index 0000000..dd79ebc
--- /dev/null
+++ b/src/media_codec_ini.c
@@ -0,0 +1,571 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __MEDIA_CODEC_INI_C__
+#define __MEDIA_CODEC_INI_C__
+
+/* includes here */
+#include <glib.h>
+#include <stdlib.h>
+#include <glib/gstdio.h>
+#include <mm_debug.h>
+#include <mm_error.h>
+#include "iniparser.h"
+#include <media_codec_ini.h>
+#include <media_codec_port.h>
+
+#define DEFAULT_VALUE ""
+
+#define DEFAULT_HW_DECODER_NAME ""
+#define DEFAULT_HW_DECODER_MIME ""
+#define DEFAULT_HW_DECODER_FORMAT ""
+
+#define DEFAULT_HW_ENCODER_NAME ""
+#define DEFAULT_HW_ENCODER_MIME ""
+#define DEFAULT_HW_ENCODER_FORMAT ""
+
+#define DEFAULT_SW_DECODER_NAME ""
+#define DEFAULT_SW_DECODER_MIME ""
+#define DEFAULT_SW_DECODER_FORMAT ""
+
+#define DEFAULT_SW_ENCODER_NAME ""
+#define DEFAULT_SW_ENCODER_MIME ""
+#define DEFAULT_SW_ENCODER_FORMAT ""
+
+
+#define CNAME_SIZE 512
+
+typedef struct {
+ gchar cname[MEDIA_CODEC_INI_MAX_STRLEN];
+ mediacodec_codec_type_e ctype;
+}codec_list_t;
+
+static codec_list_t general_codec_list[]={
+ {"h261", MEDIACODEC_H261},
+ {"h263", MEDIACODEC_H263},
+ {"h264", MEDIACODEC_H264},
+ {"mjpeg", MEDIACODEC_MJPEG},
+ {"mpeg1", MEDIACODEC_MPEG1},
+ {"mpeg2", MEDIACODEC_MPEG2},
+ {"mpeg4", MEDIACODEC_MPEG4},
+ {"hevc", MEDIACODEC_HEVC},
+ {"vp8", MEDIACODEC_VP8},
+ {"vp9", MEDIACODEC_VP9},
+ {"vc1", MEDIACODEC_VC1},
+ {"aac_lc", MEDIACODEC_AAC_LC},
+ {"aac_he", MEDIACODEC_AAC_HE},
+ {"aac_he_ps", MEDIACODEC_AAC_HE_PS},
+ {"mp3", MEDIACODEC_MP3},
+ {"amr_nb", MEDIACODEC_AMR_NB},
+ {"amr_wb", MEDIACODEC_AMR_WB},
+ {"vorbis", MEDIACODEC_VORBIS},
+ {"flac", MEDIACODEC_FLAC},
+ {"wmav1", MEDIACODEC_WMAV1},
+ {"wmav2", MEDIACODEC_WMAV2},
+ {"wmapro", MEDIACODEC_WMAPRO},
+};
+
+/* internal functions, macros here */
+#ifdef MEDIA_CODEC_DEFAULT_INI
+static gboolean _generate_default_ini(void);
+#endif
+
+static void _mc_ini_check_ini_status(void);
+
+/* macro */
+#define MEDIA_CODEC_INI_GET_STRING( x_dict, x_item, x_ini, x_default ) \
+ do \
+{ \
+ gchar* str = iniparser_getstring(x_dict, x_ini, x_default); \
+ \
+ if ( str && \
+ ( strlen( str ) > 0 ) && \
+ ( strlen( str ) < MEDIA_CODEC_INI_MAX_STRLEN ) ) \
+ { \
+ strncpy ( x_item, str, strlen(str)+1 ); \
+ } \
+ else \
+ { \
+ strncpy ( x_item, x_default, strlen(x_default)+1 ); \
+ } \
+}while(0)
+
+#define MEDIA_CODEC_INI_GET_STRING_FROM_LIST( x_dict, x_list, x_ini, x_default ) \
+ do \
+{ \
+ char *token = NULL; \
+ char *usr_ptr = NULL; \
+ int index = 0; \
+ const char *delimiters = " ,"; \
+ gchar temp_arr[MEDIA_CODEC_INI_MAX_STRLEN] = {0}; \
+ MEDIA_CODEC_INI_GET_STRING(x_dict, temp_arr, x_ini, x_default); \
+ token = strtok_r( temp_arr, delimiters, &usr_ptr ); \
+ while (token) \
+ { \
+ if (index == 0) \
+ strncpy(x_list.name,token, MEDIA_CODEC_INI_MAX_STRLEN-1 );\
+ else if (index == 1) \
+ strncpy(x_list.mime,token, MEDIA_CODEC_INI_MAX_STRLEN-1 );\
+ else if (index == 2) \
+ strncpy(x_list.format,token, MEDIA_CODEC_INI_MAX_STRLEN-1 );\
+ index++;\
+ token = strtok_r( NULL, delimiters, &usr_ptr ); \
+ } \
+}while(0)
+
+#define MEDIA_CODEC_INI_GET_COLOR( x_dict, x_item, x_ini, x_default ) \
+ do \
+{ \
+ gchar* str = iniparser_getstring(x_dict, x_ini, x_default); \
+ \
+ if ( str && \
+ ( strlen( str ) > 0 ) && \
+ ( strlen( str ) < MEDIA_CODEC_INI_MAX_STRLEN ) ) \
+ { \
+ x_item = (guint) strtoul(str, NULL, 16); \
+ } \
+ else \
+ { \
+ x_item = (guint) strtoul(x_default, NULL, 16); \
+ } \
+}while(0)
+
+/* x_ini is the list of index to set TRUE at x_list[index] */
+#define MEDIA_CODEC_INI_GET_BOOLEAN_FROM_LIST( x_dict, x_list, x_list_max, x_ini, x_default ) \
+ do \
+{ \
+ int index = 0; \
+ const char *delimiters = " ,"; \
+ char *usr_ptr = NULL; \
+ char *token = NULL; \
+ gchar temp_arr[MEDIA_CODEC_INI_MAX_STRLEN] = {0}; \
+ MEDIA_CODEC_INI_GET_STRING( x_dict, temp_arr, x_ini, x_default); \
+ token = strtok_r( temp_arr, delimiters, &usr_ptr ); \
+ while (token) \
+ { \
+ index = atoi(token); \
+ if (index < 0 || index > x_list_max -1) \
+ { \
+ LOGW("%d is not valid index\n", index); \
+ } \
+ else \
+ { \
+ x_list[index] = TRUE; \
+ } \
+ token = strtok_r( NULL, delimiters, &usr_ptr ); \
+ } \
+}while(0)
+
+/* x_ini is the list of value to be set at x_list[index] */
+#define MEDIA_CODEC_INI_GET_INT_FROM_LIST( x_dict, x_list, x_list_max, x_ini, x_default ) \
+ do \
+{ \
+ int index = 0; \
+ int value = 0; \
+ const char *delimiters = " ,"; \
+ char *usr_ptr = NULL; \
+ char *token = NULL; \
+ gchar temp_arr[MEDIA_CODEC_INI_MAX_STRLEN] = {0}; \
+ MEDIA_CODEC_INI_GET_STRING(x_dict, temp_arr, x_ini, x_default); \
+ token = strtok_r( temp_arr, delimiters, &usr_ptr ); \
+ while (token) \
+ { \
+ if ( index > x_list_max -1) \
+ { \
+ LOGE("%d is not valid index\n", index); \
+ break; \
+ } \
+ else \
+ { \
+ value = atoi(token); \
+ x_list[index] = value; \
+ index++; \
+ } \
+ token = strtok_r( NULL, delimiters, &usr_ptr ); \
+ } \
+}while(0)
+
+#define MEDIA_CODEC_GET_DEFAULT_LIST( x_list, x_default ) \
+ do \
+{ \
+ strncpy( x_list, x_default, MEDIA_CODEC_INI_MAX_STRLEN - 1);\
+}while(0)
+#define MEDIA_CODEC_PRINT_LIST( x_list, x_message ) \
+ do \
+{ \
+ codec_info_t codec_list= x_list;\
+ printf("%s =", x_message);\
+ printf("%s %s %s\n", codec_list.name, codec_list.mime, codec_list.format);\
+}while(0)
+
+media_format_mimetype_e _mc_convert_media_format_str_to_int(char *sformat )
+{
+
+ media_format_mimetype_e iformat = MEDIA_FORMAT_I420;
+ if (!strcmp(sformat,"I420")) {
+ iformat = MEDIA_FORMAT_I420;
+ goto endf;
+ } else if (!strcmp(sformat,"NV12")) {
+ iformat = MEDIA_FORMAT_NV12;
+ goto endf;
+ } else if (!strcmp(sformat,"NV12T")) {
+ iformat = MEDIA_FORMAT_NV12T;
+ goto endf;
+ } else if (!strcmp(sformat,"YV12")) {
+ iformat = MEDIA_FORMAT_YV12;
+ goto endf;
+ } else if (!strcmp(sformat,"NV21")) {
+ iformat = MEDIA_FORMAT_NV21;
+ goto endf;
+ } else if (!strcmp(sformat,"NV16")) {
+ iformat = MEDIA_FORMAT_NV16;
+ } else if (!strcmp(sformat,"YUYV")) {
+ iformat = MEDIA_FORMAT_YUYV;
+ goto endf;
+ } else if (!strcmp(sformat,"UYVY")) {
+ iformat = MEDIA_FORMAT_UYVY;
+ goto endf;
+ } else if (!strcmp(sformat,"422P")) {
+ iformat = MEDIA_FORMAT_422P;
+ goto endf;
+ } else if (!strcmp(sformat,"RGB565")) {
+ iformat = MEDIA_FORMAT_RGB565;
+ goto endf;
+ } else if (!strcmp(sformat,"RGB888")) {
+ iformat = MEDIA_FORMAT_RGB888;
+ goto endf;
+ } else if (!strcmp(sformat,"RGBA")) {
+ iformat = MEDIA_FORMAT_RGBA;
+ goto endf;
+ } else if (!strcmp(sformat,"ARGB")) {
+ iformat = MEDIA_FORMAT_ARGB;
+ goto endf;
+ } else if (!strcmp(sformat,"PCM")) {
+ iformat = MEDIA_FORMAT_PCM;
+ goto endf;
+ } else if (!strcmp(sformat,"H261")) {
+ iformat = MEDIA_FORMAT_H261;
+ goto endf;
+ } else if (!strcmp(sformat,"H263")) {
+ iformat = MEDIA_FORMAT_H263;
+ goto endf;
+ } else if (!strcmp(sformat,"H263P")) {
+ iformat = MEDIA_FORMAT_H263P;
+ goto endf;
+ } else if (!strcmp(sformat,"H264_SP")) {
+ iformat = MEDIA_FORMAT_H264_SP;
+ goto endf;
+ } else if (!strcmp(sformat,"H264_MP")) {
+ iformat = MEDIA_FORMAT_H264_MP;
+ goto endf;
+ } else if (!strcmp(sformat,"H264_HP")) {
+ iformat = MEDIA_FORMAT_H264_HP;
+ goto endf;
+ } else if (!strcmp(sformat,"MPEG4_SP")) {
+ iformat = MEDIA_FORMAT_MPEG4_SP;
+ goto endf;
+ } else if (!strcmp(sformat,"MPEG4_ASP")) {
+ iformat = MEDIA_FORMAT_MPEG4_ASP;
+ goto endf;
+ } else if (!strcmp(sformat,"AMR_NB")) {
+ iformat = MEDIA_FORMAT_AMR_NB;
+ goto endf;
+ } else if (!strcmp(sformat,"AMR_WB")) {
+ iformat = MEDIA_FORMAT_AMR_WB;
+ goto endf;
+ } else if (!strcmp(sformat,"AAC_LC")) {
+ iformat = MEDIA_FORMAT_AAC_LC;
+ goto endf;
+ } else if (!strcmp(sformat,"AAC_HE")) {
+ iformat = MEDIA_FORMAT_AAC_HE;
+ goto endf;
+ } else if (!strcmp(sformat,"AAC_HE_PS")) {
+ iformat = MEDIA_FORMAT_AAC_HE_PS;
+ goto endf;
+ } else if (!strcmp(sformat,"MP3")) {
+ iformat = MEDIA_FORMAT_MP3;
+ goto endf;
+ } else if (!strcmp(sformat,"VORBIS")) {
+ iformat = MEDIA_FORMAT_VORBIS;
+ goto endf;
+ } else if (!strcmp(sformat,"FLAC")) {
+ iformat = MEDIA_FORMAT_FLAC;
+ goto endf;
+ } else if (!strcmp(sformat,"WMAV1")) {
+ iformat = MEDIA_FORMAT_WMAV1;
+ goto endf;
+ } else if (!strcmp(sformat,"WMAV2")) {
+ iformat = MEDIA_FORMAT_WMAV2;
+ goto endf;
+ } else if (!strcmp(sformat,"WMAPRO")) {
+ iformat = MEDIA_FORMAT_WMAPRO;
+ goto endf;
+ }
+
+endf:
+ LOGD("sformat : %x", iformat);
+ return iformat;
+}
+
+int mc_ini_load(mc_ini_t *ini)
+{
+ gchar cname[CNAME_SIZE];
+ int i = 0;
+ dictionary *dict = NULL;
+
+ static const int codec_list = sizeof(general_codec_list) / sizeof(general_codec_list[0]);
+
+ _mc_ini_check_ini_status();
+
+ /* first, try to load existing ini file */
+ dict = iniparser_load(MEDIA_CODEC_INI_DEFAULT_PATH);
+
+ /* if no file exists. create one with set of default values */
+ if (!dict) {
+#ifdef MEDIA_CODEC_DEFAULT_INI
+ LOGD("No inifile found. codec will create default inifile.\n");
+ if (FALSE == _generate_default_ini()) {
+ LOGW("Creating default inifile failed. Media Codec will use default values.\n");
+ } else {
+ /* load default ini */
+ dict = iniparser_load(MEDIA_CODEC_INI_DEFAULT_PATH);
+ }
+#else
+ LOGD("No ini file found. \n");
+ return LOGERROR_FILE_NOT_FOUND;
+#endif
+ }
+
+ /* get ini values */
+ memset(ini, 0, sizeof(mc_ini_t));
+
+ if (dict) {/* if dict is available */
+ /* general */
+ MEDIA_CODEC_INI_GET_STRING( dict, ini->port_name, "port_in_use:media_codec_port",DEFAULT_PORT);
+ /* codec */
+ for (i = 0; i < codec_list; i++) {
+ memset(cname, 0x00, CNAME_SIZE);
+ snprintf(cname, CNAME_SIZE, "%s", general_codec_list[i].cname);
+ int len = strlen(cname);
+
+ ini->codec[i].codec_id = general_codec_list[i].ctype;
+ snprintf(cname+len, CNAME_SIZE-len, "%s", ":hw_decoder");
+ MEDIA_CODEC_INI_GET_STRING_FROM_LIST( dict, ini->codec[i].codec_info[0], cname, DEFAULT_VALUE);
+ snprintf(cname+len, CNAME_SIZE-len, "%s",":hw_encoder");
+ MEDIA_CODEC_INI_GET_STRING_FROM_LIST( dict, ini->codec[i].codec_info[1], cname, DEFAULT_VALUE);
+ snprintf(cname+len, CNAME_SIZE-len, "%s",":sw_decoder");
+ MEDIA_CODEC_INI_GET_STRING_FROM_LIST( dict, ini->codec[i].codec_info[2], cname, DEFAULT_VALUE);
+ snprintf(cname+len, CNAME_SIZE-len, "%s",":sw_encoder");
+ MEDIA_CODEC_INI_GET_STRING_FROM_LIST( dict, ini->codec[i].codec_info[3], cname, DEFAULT_VALUE);
+ }
+ } else {/* if dict is not available just fill the structure with default value */
+
+ LOGW("failed to load ini. using hardcoded default\n");
+ /* general */
+ snprintf(ini->port_name, sizeof(ini->port_name), "%s", DEFAULT_PORT);
+ for (i = 0;i < codec_list; i++) {
+ MEDIA_CODEC_GET_DEFAULT_LIST( ini->codec[i].codec_info[0].name, DEFAULT_HW_DECODER_NAME);
+ MEDIA_CODEC_GET_DEFAULT_LIST( ini->codec[i].codec_info[0].mime, DEFAULT_HW_DECODER_MIME);
+ MEDIA_CODEC_GET_DEFAULT_LIST( ini->codec[i].codec_info[0].format, DEFAULT_HW_DECODER_FORMAT);
+
+ MEDIA_CODEC_GET_DEFAULT_LIST( ini->codec[i].codec_info[1].name, DEFAULT_HW_ENCODER_NAME);
+ MEDIA_CODEC_GET_DEFAULT_LIST( ini->codec[i].codec_info[1].mime, DEFAULT_HW_ENCODER_MIME);
+ MEDIA_CODEC_GET_DEFAULT_LIST( ini->codec[i].codec_info[1].format, DEFAULT_HW_ENCODER_FORMAT);
+
+ MEDIA_CODEC_GET_DEFAULT_LIST( ini->codec[i].codec_info[2].name, DEFAULT_SW_DECODER_NAME);
+ MEDIA_CODEC_GET_DEFAULT_LIST( ini->codec[i].codec_info[2].mime, DEFAULT_SW_DECODER_MIME);
+ MEDIA_CODEC_GET_DEFAULT_LIST( ini->codec[i].codec_info[2].format, DEFAULT_SW_DECODER_FORMAT);
+
+ MEDIA_CODEC_GET_DEFAULT_LIST( ini->codec[i].codec_info[3].name, DEFAULT_SW_ENCODER_NAME);
+ MEDIA_CODEC_GET_DEFAULT_LIST( ini->codec[i].codec_info[3].mime, DEFAULT_SW_ENCODER_MIME);
+ MEDIA_CODEC_GET_DEFAULT_LIST( ini->codec[i].codec_info[3].format, DEFAULT_SW_ENCODER_FORMAT);
+ }
+ }
+
+ if (0 == strcmp(ini->port_name, "GST_PORT"))
+ ini->port_type = GST_PORT;
+ else {
+ LOGE("Invalid port is set to [%s] [%d]\n", ini->port_name,ini->port_type);
+ iniparser_freedict(dict);
+ goto ERROR;
+ }
+ LOGD("The port is set to [%s] [%d]\n", ini->port_name, ini->port_type);
+
+ for (i = 0;i < codec_list; i++) {
+ memset(cname, 0x00, CNAME_SIZE);
+ snprintf(cname, CNAME_SIZE, "%s", general_codec_list[i].cname);
+ int len = strlen(cname);
+
+ snprintf(cname+len, CNAME_SIZE-len, "%s",":hw_decoder");
+ MEDIA_CODEC_PRINT_LIST(ini->codec[i].codec_info[0],cname);
+ snprintf(cname+len, CNAME_SIZE-len, "%s",":hw_encoder");
+ MEDIA_CODEC_PRINT_LIST(ini->codec[i].codec_info[1],cname);
+ snprintf(cname+len, CNAME_SIZE-len, "%s",":sw_decoder");
+ MEDIA_CODEC_PRINT_LIST(ini->codec[i].codec_info[2],cname);
+ snprintf(cname+len, CNAME_SIZE-len, "%s",":sw_encoder");
+ MEDIA_CODEC_PRINT_LIST(ini->codec[i].codec_info[3],cname);
+ }
+
+ /* free dict as we got our own structure */
+ iniparser_freedict(dict);
+
+ /* dump structure */
+ LOGD("codec settings -----------------------------------\n");
+
+ /* general */
+ LOGD("port_name: %s\n", ini->port_name);
+ LOGD("port_type : %d\n", ini->port_type);
+
+ return MC_ERROR_NONE;
+ERROR:
+ return MC_COURRPTED_INI;
+
+}
+
+static void _mc_ini_check_ini_status(void)
+{
+ struct stat ini_buff;
+
+ if (g_stat(MEDIA_CODEC_INI_DEFAULT_PATH, &ini_buff) < 0) {
+ LOGW("failed to get codec ini status\n");
+ } else {
+ if (ini_buff.st_size < 5) {
+ LOGW("codec.ini file size=%d, Corrupted! So, Removed\n", (int)ini_buff.st_size);
+
+ if (g_remove(MEDIA_CODEC_INI_DEFAULT_PATH) == -1) {
+ LOGE("failed to delete corrupted ini");
+ }
+ }
+ }
+}
+
+#ifdef MEDIA_CODEC_DEFAULT_INI
+static gboolean _generate_default_ini(void)
+{
+ FILE *fp = NULL;
+ gchar *default_ini = MEDIA_CODEC_DEFAULT_INI;
+
+ /* create new file */
+ fp = fopen(MEDIA_CODEC_INI_DEFAULT_PATH, "wt");
+
+ if (!fp) {
+ return FALSE;
+ }
+
+ /* writing default ini file */
+ if (strlen(default_ini) !=
+ fwrite(default_ini, 1, strlen(default_ini), fp)) {
+ fclose(fp);
+ return FALSE;
+ }
+
+ fclose(fp);
+ return TRUE;
+}
+#endif
+
+void _mc_create_decoder_map_from_ini(mc_handle_t *mediacodec)
+{
+ int indx = 0, count = 0;
+ int codec_list = sizeof(general_codec_list) / sizeof(general_codec_list[0]);
+ for (indx=0;indx <codec_list;indx++) {
+ if (strcmp(mediacodec->ini.codec[indx].codec_info[0].name, "")) {
+ mediacodec->decoder_map[count].id = mediacodec->ini.codec[indx].codec_id;
+ mediacodec->decoder_map[count].hardware = 1; // hardware
+ mediacodec->decoder_map[count].type.factory_name = mediacodec->ini.codec[indx].codec_info[0].name;
+ mediacodec->decoder_map[count].type.mime = mediacodec->ini.codec[indx].codec_info[0].mime;
+ mediacodec->decoder_map[count].type.out_format= _mc_convert_media_format_str_to_int(mediacodec->ini.codec[indx].codec_info[0].format);
+ count++;
+ }
+
+ if (strcmp(mediacodec->ini.codec[indx].codec_info[2].name, "")) {
+ mediacodec->decoder_map[count].id = mediacodec->ini.codec[indx].codec_id;
+ mediacodec->decoder_map[count].hardware = 0; // software
+ mediacodec->decoder_map[count].type.factory_name = mediacodec->ini.codec[indx].codec_info[2].name;
+ mediacodec->decoder_map[count].type.mime = mediacodec->ini.codec[indx].codec_info[2].mime;
+ mediacodec->decoder_map[count].type.out_format= _mc_convert_media_format_str_to_int(mediacodec->ini.codec[indx].codec_info[2].format);
+ count++;
+ }
+ }
+ mediacodec->num_supported_decoder = count;
+ return;
+
+}
+
+void _mc_create_encoder_map_from_ini(mc_handle_t *mediacodec)
+{
+ int indx = 0, count = 0;
+ int codec_list = sizeof(general_codec_list) / sizeof(general_codec_list[0]);
+
+ for (indx=0;indx <codec_list;indx++) {
+ if (strcmp(mediacodec->ini.codec[indx].codec_info[1].name, "")) {
+ mediacodec->encoder_map[count].id = mediacodec->ini.codec[indx].codec_id;
+ mediacodec->encoder_map[count].hardware = 1;
+ mediacodec->encoder_map[count].type.factory_name = mediacodec->ini.codec[indx].codec_info[1].name;
+ mediacodec->encoder_map[count].type.mime = mediacodec->ini.codec[indx].codec_info[1].mime;
+ mediacodec->encoder_map[count].type.out_format= _mc_convert_media_format_str_to_int(mediacodec->ini.codec[indx].codec_info[1].format);
+ count++;
+ }
+
+ if (strcmp(mediacodec->ini.codec[indx].codec_info[3].name, "")) {
+ mediacodec->encoder_map[count].id = mediacodec->ini.codec[indx].codec_id;
+ mediacodec->encoder_map[count].hardware = 0;
+ mediacodec->encoder_map[count].type.factory_name = mediacodec->ini.codec[indx].codec_info[3].name;
+ mediacodec->encoder_map[count].type.mime = mediacodec->ini.codec[indx].codec_info[3].mime;
+ mediacodec->encoder_map[count].type.out_format= _mc_convert_media_format_str_to_int(mediacodec->ini.codec[indx].codec_info[3].format);
+ count++;
+ }
+ }
+ mediacodec->num_supported_encoder = count;
+ return;
+
+}
+void _mc_create_codec_map_from_ini(mc_handle_t *mediacodec, mc_codec_spec_t *spec_emul)
+{
+ int indx = 0, count = 0;
+ int codec_list = sizeof(general_codec_list) / sizeof(general_codec_list[0]);
+ for (indx=0;indx <codec_list;indx++) {
+ if (strcmp(mediacodec->ini.codec[indx].codec_info[0].name, "")) {
+ spec_emul[count].codec_id = mediacodec->ini.codec[indx].codec_id;
+ spec_emul[count].codec_type = MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_HW;
+ spec_emul[count].port_type = MEDIACODEC_PORT_TYPE_GST;
+ count++;
+ }
+ if (strcmp(mediacodec->ini.codec[indx].codec_info[1].name, "")) {
+ spec_emul[count].codec_id = mediacodec->ini.codec[indx].codec_id;
+ spec_emul[count].codec_type = MEDIACODEC_ENCODER | MEDIACODEC_SUPPORT_TYPE_HW;
+ spec_emul[count].port_type = MEDIACODEC_PORT_TYPE_GST;
+ count++;
+ }
+ if (strcmp(mediacodec->ini.codec[indx].codec_info[2].name, "")) {
+ spec_emul[count].codec_id = mediacodec->ini.codec[indx].codec_id;
+ spec_emul[count].codec_type = MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_SW;
+ spec_emul[count].port_type = MEDIACODEC_PORT_TYPE_GST;
+ count++;
+ }
+ if (strcmp(mediacodec->ini.codec[indx].codec_info[3].name, "")) {
+ spec_emul[count].codec_id = mediacodec->ini.codec[indx].codec_id;
+ spec_emul[count].codec_type = MEDIACODEC_ENCODER | MEDIACODEC_SUPPORT_TYPE_SW;
+ spec_emul[count].port_type = MEDIACODEC_PORT_TYPE_GST;
+ count++;
+ }
+ }
+
+ mediacodec->num_supported_codecs = count;
+ return;
+}
+
+#endif /* #ifdef _MEDIA_CODEC_INI_C_ */
diff --git a/src/media_codec_port.c b/src/media_codec_port.c
index 112b788..0cda9ab 100755
--- a/src/media_codec_port.c
+++ b/src/media_codec_port.c
@@ -27,22 +27,25 @@
#include <media_codec_spec_emul.h>
-//static gboolean _mc_check_is_supported(mc_handle_t* mc_handle, mediacodec_codec_type_e codec_id, mediacodec_support_type_e flags);
+static mc_codec_spec_t spec_emul[MEDIA_CODEC_MAX_CODEC_TYPE];
int mc_create(MMHandleType *mediacodec)
{
- mc_handle_t* new_mediacodec = NULL;
+ mc_handle_t *new_mediacodec = NULL;
int ret = MC_ERROR_NONE;
+ int i;
+ int support_list = sizeof(spec_emul) / sizeof(spec_emul[0]);
/* alloc mediacodec structure */
- new_mediacodec = (mc_handle_t*)g_malloc(sizeof(mc_handle_t));
- if ( ! new_mediacodec )
- {
- LOGE("Cannot allocate memory for player\n");
+ new_mediacodec = (mc_handle_t *)g_malloc(sizeof(mc_handle_t));
+
+ if (!new_mediacodec) {
+ LOGE("Cannot allocate memory for mediacodec");
ret = MC_ERROR;
goto ERROR;
}
memset(new_mediacodec, 0, sizeof(mc_handle_t));
+ memset(spec_emul, 0, sizeof(mc_codec_spec_t)*MEDIA_CODEC_MAX_CODEC_TYPE);
new_mediacodec->is_encoder = false;
new_mediacodec->is_video = false;
@@ -53,102 +56,95 @@ int mc_create(MMHandleType *mediacodec)
new_mediacodec->ports[0] = NULL;
new_mediacodec->ports[1] = NULL;
+ new_mediacodec->num_supported_codecs = 0;
+ new_mediacodec->num_supported_decoder = 0;
+ new_mediacodec->num_supported_encoder = 0;
+
new_mediacodec->core = NULL;
- g_mutex_init(&new_mediacodec->cmd_lock);
- /*
- if(!new_mediacodec->cmd_lock)
- {
- LOGE("failed to create cmd_lock");
+ /* load ini files */
+ ret = mc_ini_load(&new_mediacodec->ini);
+ if(ret != MC_ERROR_NONE)
goto ERROR;
+ _mc_create_codec_map_from_ini(new_mediacodec, spec_emul);
+
+ for (i = 0; i < new_mediacodec->num_supported_codecs; i++) {
+ new_mediacodec->supported_codecs =
+ g_list_append(new_mediacodec->supported_codecs, GINT_TO_POINTER(spec_emul[i].codec_id));
}
- */
+
+ /* create decoder map from ini */
+ _mc_create_decoder_map_from_ini(new_mediacodec);
+
+ /* create encoder map from ini */
+ _mc_create_encoder_map_from_ini(new_mediacodec);
+
*mediacodec = (MMHandleType)new_mediacodec;
return ret;
- // TO DO
ERROR:
- // TO DO
- // If we need destroy and release for others (cmd, mutex..)
- g_mutex_clear(&new_mediacodec->cmd_lock);
- free(new_mediacodec);
- new_mediacodec = NULL;
- return MC_INVALID_ARG;
- return ret;
+ return MC_INVALID_ARG;
}
int mc_destroy(MMHandleType mediacodec)
{
int ret = MC_ERROR_NONE;
- mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
+ mc_handle_t *mc_handle = (mc_handle_t *) mediacodec;
- if (!mc_handle)
- {
+ if (!mc_handle) {
LOGE("fail invaild param\n");
return MC_INVALID_ARG;
}
- MEDIACODEC_CMD_LOCK( mediacodec );
-
LOGD("mediacodec : %p", mediacodec);
- if(mc_handle->core != NULL)
- {
- if(mc_gst_unprepare(mc_handle) != MC_ERROR_NONE)
- {
+ if (mc_handle->core != NULL) {
+ if (mc_gst_unprepare(mc_handle) != MC_ERROR_NONE) {
LOGE("mc_gst_unprepare() failed");
return MC_ERROR;
}
}
mc_handle->is_prepared = false;
-
- MEDIACODEC_CMD_UNLOCK( mediacodec );
+ g_list_free(mc_handle->supported_codecs);
/* free mediacodec structure */
- if(mc_handle) {
- g_free( (void*)mc_handle );
+ if (mc_handle) {
+ g_free((void *)mc_handle);
mc_handle = NULL;
}
+
return ret;
}
int mc_set_codec(MMHandleType mediacodec, mediacodec_codec_type_e codec_id, mediacodec_support_type_e flags)
{
int ret = MC_ERROR_NONE;
- mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
- static const int support_list = sizeof(spec_emul) / sizeof(spec_emul[0]);
+ mc_handle_t *mc_handle = (mc_handle_t *) mediacodec;
int i;
- if (!mc_handle)
- {
- LOGE("fail invaild param\n");
+ if (!mc_handle) {
+ LOGE("fail invaild param");
return MC_INVALID_ARG;
}
- // Mandatory setting
- if ( !GET_IS_ENCODER(flags) && !GET_IS_DECODER(flags) )
- {
- LOGE("should be encoder or decoder\n");
+ /* Mandatory setting */
+ if (!GET_IS_ENCODER(flags) && !GET_IS_DECODER(flags)) {
+ LOGE("should be encoder or decoder");
return MC_PARAM_ERROR;
}
-/*
- if(!_mc_check_is_supported(mc_handle, codec_id, flags))
- return MC_NOT_SUPPORTED;
-*/
- for(i = 0; i < support_list; i++)
- {
- if((codec_id == spec_emul[i].codec_id) && (flags == spec_emul[i].codec_type))
- {
+
+
+ for (i = 0; i < mc_handle->num_supported_codecs; i++) {
+ if ((codec_id == spec_emul[i].codec_id) && (flags == spec_emul[i].codec_type)) {
break;
}
}
+ LOGD("support_list : %d, i : %d", mc_handle->num_supported_codecs, i);
- LOGD("support_list : %d, i : %d", support_list, i);
-
- if(i == support_list)
+ if (i == mc_handle->num_supported_codecs)
return MC_NOT_SUPPORTED;
mc_handle->port_type = spec_emul[i].port_type;
@@ -162,66 +158,16 @@ int mc_set_codec(MMHandleType mediacodec, mediacodec_codec_type_e codec_id, medi
LOGD("encoder : %d, hardware : %d, codec_id : %x, video : %d",
mc_handle->is_encoder, mc_handle->is_hw, mc_handle->codec_id, mc_handle->is_video);
-#if 0
- // mc_handle->is_omx = use_omx;
- // !!!! make it dynamic
- mc_handle->port_type = MEDIACODEC_PORT_TYPE_GST;
-
- // !!!! only gst case is here. expend it to all.
- if (encoder)
- {
- switch(codec_id)
- {
- case MEDIACODEC_H264:
- mc_handle->supported_codec = GST_ENCODE_H264;
- mc_handle->mimetype = MEDIA_FORMAT_H264_HP;
- mc_handle->is_video = 1;
- break;
- case MEDIACODEC_AAC:
- mc_handle->supported_codec = GST_ENCODE_AAC;
- mc_handle->mimetype = MEDIA_FORMAT_AAC;
- mc_handle->is_video = 0;
- break;
- default:
- LOGE("NOT SUPPORTED!!!!");
- break;
- }
- mc_handle->is_encoder = true;
- }
- else
- {
- switch(codec_id)
- {
- case MEDIACODEC_H264:
- mc_handle->supported_codec = GST_DECODE_H264;
- mc_handle->mimetype = MEDIA_FORMAT_NV12;
- mc_handle->is_video = 1;
- break;
- case MEDIACODEC_AAC:
- mc_handle->supported_codec = GST_DECODE_AAC;
- mc_handle->mimetype = MEDIA_FORMAT_PCM;
- mc_handle->is_video = 0;
- break;
- default:
- LOGE("NOT SUPPORTED!!!!");
- break;
- }
-
- // !!!! check if need to be dynamic
- mc_handle->is_encoder = false;
- }
-#endif
return ret;
}
int mc_set_vdec_info(MMHandleType mediacodec, int width, int height)
{
int ret = MC_ERROR_NONE;
- mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
+ mc_handle_t* mc_handle = (mc_handle_t *)mediacodec;
- if (!mc_handle)
- {
+ if (!mc_handle) {
LOGE("fail invaild param\n");
return MC_INVALID_ARG;
}
@@ -230,23 +176,38 @@ int mc_set_vdec_info(MMHandleType mediacodec, int width, int height)
return MC_PARAM_ERROR;
MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && mc_handle->is_video && !mc_handle->is_encoder,
- MEDIACODEC_ERROR_INVALID_PARAMETER,"MEDIACODEC_ERROR_INVALID_PARAMETER");
+ MEDIACODEC_ERROR_INVALID_PARAMETER, "MEDIACODEC_ERROR_INVALID_PARAMETER");
mc_handle->info.decoder.width = width;
mc_handle->info.decoder.height = height;
mc_handle->is_prepared = true;
+ switch (mc_handle->codec_id) {
+ case MEDIACODEC_H264:
+ mc_sniff_bitstream = mc_sniff_h264_bitstream;
+ LOGD("mc_sniff_h264_bitstream");
+ break;
+ case MEDIACODEC_MPEG4:
+ mc_sniff_bitstream = mc_sniff_mpeg4_bitstream;
+ break;
+ case MEDIACODEC_H263:
+ mc_sniff_bitstream = mc_sniff_h263_bitstream;
+ break;
+ default:
+ LOGE("NOT SUPPORTED!!!!");
+ break;
+ }
+
return ret;
}
int mc_set_venc_info(MMHandleType mediacodec, int width, int height, int fps, int target_bits)
{
int ret = MC_ERROR_NONE;
- mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
+ mc_handle_t *mc_handle = (mc_handle_t *) mediacodec;
- if (!mc_handle)
- {
+ if (!mc_handle) {
LOGE("fail invaild param\n");
return MC_INVALID_ARG;
}
@@ -255,14 +216,14 @@ int mc_set_venc_info(MMHandleType mediacodec, int width, int height, int fps, in
return MC_PARAM_ERROR;
MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && mc_handle->is_video && mc_handle->is_encoder,
- MEDIACODEC_ERROR_INVALID_PARAMETER, "MEDIACODEC_ERROR_INVALID_PARAMETER");
+ MEDIACODEC_ERROR_INVALID_PARAMETER, "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;
-
mc_handle->is_prepared = true;
+ mc_sniff_bitstream = mc_sniff_yuv;
return ret;
}
@@ -270,10 +231,9 @@ int mc_set_venc_info(MMHandleType mediacodec, int width, int height, int fps, in
int mc_set_adec_info(MMHandleType mediacodec, int samplerate, int channel, int bit)
{
int ret = MC_ERROR_NONE;
- mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
+ mc_handle_t *mc_handle = (mc_handle_t *) mediacodec;
- if (!mc_handle)
- {
+ if (!mc_handle) {
LOGE("fail invaild param\n");
return MC_INVALID_ARG;
}
@@ -282,24 +242,22 @@ int mc_set_adec_info(MMHandleType mediacodec, int samplerate, int channel, int b
return MC_PARAM_ERROR;
MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && !mc_handle->is_video && !mc_handle->is_encoder,
- MEDIACODEC_ERROR_INVALID_PARAMETER, "MEDIACODEC_ERROR_INVALID_PARAMETER");
+ MEDIACODEC_ERROR_INVALID_PARAMETER, "MEDIACODEC_ERROR_INVALID_PARAMETER");
mc_handle->info.decoder.samplerate = samplerate;
mc_handle->info.decoder.channel = channel;
mc_handle->info.decoder.bit = bit;
-
mc_handle->is_prepared = true;
return ret;
}
-int mc_set_aenc_info(MMHandleType mediacodec, int samplerate, int channel, int bit, int bitrate)
+int mc_set_aenc_info(MMHandleType mediacodec, int samplerate, int channel, int bit, int bitrate)
{
int ret = MC_ERROR_NONE;
- mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
+ mc_handle_t * mc_handle = (mc_handle_t *) mediacodec;
- if (!mc_handle)
- {
+ if (!mc_handle) {
LOGE("fail invaild param\n");
return MC_INVALID_ARG;
}
@@ -308,7 +266,7 @@ int mc_set_aenc_info(MMHandleType mediacodec, int samplerate, int channel, int b
return MC_PARAM_ERROR;
MEDIACODEC_CHECK_CONDITION(mc_handle->codec_id && !mc_handle->is_video && mc_handle->is_encoder,
- MEDIACODEC_ERROR_INVALID_PARAMETER, "MEDIACODEC_ERROR_INVALID_PARAMETER");
+ MEDIACODEC_ERROR_INVALID_PARAMETER, "MEDIACODEC_ERROR_INVALID_PARAMETER");
mc_handle->info.encoder.samplerate = samplerate;
mc_handle->info.encoder.channel = channel;
@@ -323,22 +281,18 @@ int mc_set_aenc_info(MMHandleType mediacodec, int samplerate, int channel, int b
int mc_prepare(MMHandleType mediacodec)
{
int ret = MC_ERROR_NONE;
- mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
+ mc_handle_t *mc_handle = (mc_handle_t *) mediacodec;
- if (!mc_handle)
- {
+ if (!mc_handle) {
LOGE("fail invaild param\n");
return MC_INVALID_ARG;
}
- if(!mc_handle->is_prepared)
+ if (!mc_handle->is_prepared)
return MC_NOT_INITIALIZED;
- MEDIACODEC_CMD_LOCK( mediacodec );
-
/* setting core details */
- switch ( mc_handle->port_type )
- {
+ switch (mc_handle->port_type) {
case MEDIACODEC_PORT_TYPE_GENERAL:
{
}
@@ -359,27 +313,21 @@ int mc_prepare(MMHandleType mediacodec)
break;
}
- MEDIACODEC_CMD_UNLOCK( mediacodec );
-
return ret;
}
int mc_unprepare(MMHandleType mediacodec)
{
int ret = MC_ERROR_NONE;
- mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
+ mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
- if (!mc_handle)
- {
+ if (!mc_handle) {
LOGE("fail invaild param\n");
return MC_INVALID_ARG;
}
- MEDIACODEC_CMD_LOCK( mediacodec );
-
/* deinit core details */
- switch ( mc_handle->port_type )
- {
+ switch (mc_handle->port_type) {
case MEDIACODEC_PORT_TYPE_GENERAL:
{
}
@@ -400,76 +348,67 @@ int mc_unprepare(MMHandleType mediacodec)
break;
}
- MEDIACODEC_CMD_UNLOCK( mediacodec );
-
return ret;
}
-int mc_process_input(MMHandleType mediacodec, media_packet_h inbuf, uint64_t timeOutUs )
+int mc_process_input(MMHandleType mediacodec, media_packet_h inbuf, uint64_t timeOutUs)
{
int ret = MC_ERROR_NONE;
- uint64_t buf_size = 0;
- void *buf_data = NULL;
- bool eos = false;
- mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
+ mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
-
- if (!mc_handle)
- {
- LOGE("fail invaild param\n");
+ if (!mc_handle) {
+ LOGE("fail invaild param");
return MC_INVALID_ARG;
}
- ret = media_packet_get_buffer_size(inbuf, &buf_size);
- if (ret != MEDIA_PACKET_ERROR_NONE)
- {
- LOGE("invaild input buffer");
- return MC_INVALID_IN_BUF;
+ if (mc_handle->is_video) {
+ if ((ret = mc_sniff_bitstream(mc_handle, inbuf)) != MC_ERROR_NONE) {
+ return MC_INVALID_IN_BUF;
+ }
}
- ret = media_packet_get_buffer_data_ptr(inbuf, &buf_data);
- if (ret != MEDIA_PACKET_ERROR_NONE)
- {
- LOGE("invaild input buffer");
- return MC_INVALID_IN_BUF;
- }
+ switch (mc_handle->port_type) {
+ case MEDIACODEC_PORT_TYPE_GENERAL:
+ break;
- ret = media_packet_is_end_of_stream(inbuf, &eos);
- if (ret != MEDIA_PACKET_ERROR_NONE)
- {
- LOGE("invaild input buffer");
- return MC_INVALID_IN_BUF;
- }
+ case MEDIACODEC_PORT_TYPE_OMX:
+ break;
- if(!eos)
- {
- if((buf_data == NULL) || (buf_size == 0))
+ case MEDIACODEC_PORT_TYPE_GST:
{
- LOGE("invaild input buffer");
- return MC_INVALID_IN_BUF;
+ ret = mc_gst_process_input(mc_handle, inbuf, timeOutUs);
}
+ break;
+
+ default:
+ break;
}
- MEDIACODEC_CMD_LOCK( mediacodec );
+ return ret;
+}
- switch ( mc_handle->port_type )
- {
+int mc_get_output(MMHandleType mediacodec, media_packet_h *outbuf, uint64_t timeOutUs)
+{
+ int ret = MC_ERROR_NONE;
+ mc_handle_t *mc_handle = (mc_handle_t *) mediacodec;
+
+ if (!mc_handle) {
+ LOGE("fail invaild param\n");
+ return MC_INVALID_ARG;
+ }
+
+ /* setting core details */
+ switch (mc_handle->port_type) {
case MEDIACODEC_PORT_TYPE_GENERAL:
- {
- //ret = mc_general_process_input(mc_handle->gen_core, inbuf, timeOutUs);
- }
break;
case MEDIACODEC_PORT_TYPE_OMX:
- {
- //ret = mc_omx_process_input(mc_handle, inbuf, timeOutUs);
- }
break;
case MEDIACODEC_PORT_TYPE_GST:
{
- ret = mc_gst_process_input(mc_handle, inbuf, timeOutUs);
+ ret = mc_gst_get_output(mc_handle, outbuf, timeOutUs);
}
break;
@@ -477,42 +416,30 @@ int mc_process_input(MMHandleType mediacodec, media_packet_h inbuf, uint64_t tim
break;
}
- MEDIACODEC_CMD_UNLOCK( mediacodec );
-
return ret;
}
-int mc_get_output(MMHandleType mediacodec, media_packet_h *outbuf, uint64_t timeOutUs)
+int mc_flush_buffers(MMHandleType mediacodec)
{
int ret = MC_ERROR_NONE;
- mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
+ mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
- if (!mc_handle)
- {
+ if (!mc_handle) {
LOGE("fail invaild param\n");
return MC_INVALID_ARG;
}
- MEDIACODEC_CMD_LOCK( mediacodec );
-
/* setting core details */
- switch ( mc_handle->port_type )
- {
+ switch (mc_handle->port_type) {
case MEDIACODEC_PORT_TYPE_GENERAL:
- {
- //ret= mc_general_get_output(mc_handle->gen_core, outbuf, timeOutUs);
- }
break;
case MEDIACODEC_PORT_TYPE_OMX:
- {
- //ret = mc_omx_get_output(mc_handle, outbuf, timeOutUs);
- }
break;
case MEDIACODEC_PORT_TYPE_GST:
{
- ret = mc_gst_get_output(mc_handle, outbuf, timeOutUs);
+ ret = mc_gst_flush_buffers(mc_handle);
}
break;
@@ -520,49 +447,76 @@ int mc_get_output(MMHandleType mediacodec, media_packet_h *outbuf, uint64_t time
break;
}
- MEDIACODEC_CMD_UNLOCK( mediacodec );
-
return ret;
}
-int mc_set_empty_buffer_cb(MMHandleType mediacodec, mediacodec_input_buffer_used_cb callback, void* user_data)
+int mc_get_supported_type(MMHandleType mediacodec, mediacodec_codec_type_e codec_type, bool encoder, int *support_type)
{
int ret = MC_ERROR_NONE;
- mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
+ mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
+ mc_codec_map_t *codec_map;
+ int num_supported_codec = 0;
+ int i;
- if (!mc_handle)
- {
+ *support_type = 0;
+
+ if (!mc_handle) {
LOGE("fail invaild param\n");
return MC_INVALID_ARG;
}
+ codec_map = encoder ? mc_handle->encoder_map : mc_handle->decoder_map;
+ num_supported_codec = encoder ? mc_handle->num_supported_encoder : mc_handle->num_supported_decoder;
- if(mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER])
- {
- LOGE("Already set mediacodec_empty_buffer_cb\n");
- return MC_PARAM_ERROR;
- }
- else
+ for (i = 0; i < num_supported_codec; i++)
{
- if (!callback)
+ if (codec_map[i].id == codec_type)
{
+ if (codec_map[i].hardware)
+ *support_type |= MEDIACODEC_SUPPORT_TYPE_HW;
+ else
+ *support_type |= MEDIACODEC_SUPPORT_TYPE_SW;
+ break;
+ }
+
+ }
+
+ return ret;
+}
+
+int mc_set_empty_buffer_cb(MMHandleType mediacodec, mediacodec_input_buffer_used_cb callback, void *user_data)
+{
+ int ret = MC_ERROR_NONE;
+ mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
+
+ if (!mc_handle) {
+ LOGE("fail invaild param\n");
+ return MC_INVALID_ARG;
+ }
+
+ if (mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER]) {
+ LOGE("Already set mediacodec_empty_buffer_cb");
+ return MC_PARAM_ERROR;
+ } else {
+ if (!callback) {
return MC_INVALID_ARG;
}
- LOGD("Set empty buffer callback(cb = %p, data = %p)\n", callback, user_data);
+ LOGD("Set empty buffer callback(cb = %p, data = %p)", callback, user_data);
mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER] = (mc_empty_buffer_cb) callback;
mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER] = user_data;
+
return MC_ERROR_NONE;
}
return ret;
}
+
int mc_unset_empty_buffer_cb(MMHandleType mediacodec)
{
- mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
+ mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
- if (!mc_handle)
- {
+ if (!mc_handle) {
LOGE("fail invaild param\n");
return MC_INVALID_ARG;
}
@@ -573,29 +527,25 @@ int mc_unset_empty_buffer_cb(MMHandleType mediacodec)
return MC_ERROR_NONE;
}
-int mc_set_fill_buffer_cb(MMHandleType mediacodec, mediacodec_output_buffer_available_cb callback, void* user_data)
+int mc_set_fill_buffer_cb(MMHandleType mediacodec, mediacodec_output_buffer_available_cb callback, void *user_data)
{
int ret = MC_ERROR_NONE;
- mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
+ mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
- if (!mc_handle)
- {
+ if (!mc_handle) {
LOGE("fail invaild param\n");
return MC_INVALID_ARG;
}
- if(mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_FILLBUFFER])
- {
- LOGE("Already set mediacodec_fill_buffer_cb\n");
+ if (mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_FILLBUFFER]) {
+ LOGE("Already set mediacodec_fill_buffer_cb");
return MC_PARAM_ERROR;
- }
- else
- {
+ } else {
if (!callback) {
return MC_INVALID_ARG;
}
- LOGD("Set fill buffer callback(cb = %p, data = %p)\n", callback, user_data);
+ LOGD("Set fill buffer callback(cb = %p, data = %p)", callback, user_data);
mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_FILLBUFFER] = (mc_fill_buffer_cb) callback;
mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_FILLBUFFER] = user_data;
@@ -604,12 +554,12 @@ int mc_set_fill_buffer_cb(MMHandleType mediacodec, mediacodec_output_buffer_avai
return ret;
}
+
int mc_unset_fill_buffer_cb(MMHandleType mediacodec)
{
- mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
+ mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
- if (!mc_handle)
- {
+ if (!mc_handle) {
LOGE("fail invaild param\n");
return MC_INVALID_ARG;
}
@@ -620,24 +570,20 @@ int mc_unset_fill_buffer_cb(MMHandleType mediacodec)
return MC_ERROR_NONE;
}
-int mc_set_error_cb(MMHandleType mediacodec, mediacodec_error_cb callback, void* user_data)
+int mc_set_error_cb(MMHandleType mediacodec, mediacodec_error_cb callback, void *user_data)
{
int ret = MC_ERROR_NONE;
- mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
+ mc_handle_t *mc_handle = (mc_handle_t *) mediacodec;
- if (!mc_handle)
- {
+ if (!mc_handle) {
LOGE("fail invaild param\n");
return MC_INVALID_ARG;
}
- if(mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR])
- {
+ if (mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR]) {
LOGE("Already set mediacodec_fill_buffer_cb\n");
return MC_PARAM_ERROR;
- }
- else
- {
+ } else {
if (!callback) {
return MC_INVALID_ARG;
}
@@ -654,11 +600,10 @@ int mc_set_error_cb(MMHandleType mediacodec, mediacodec_error_cb callback, void*
int mc_unset_error_cb(MMHandleType mediacodec)
{
- mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
+ mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
- if (!mc_handle)
- {
- LOGE("fail invaild param\n");
+ if (!mc_handle) {
+ LOGE("fail invaild param");
return MC_INVALID_ARG;
}
@@ -668,24 +613,20 @@ int mc_unset_error_cb(MMHandleType mediacodec)
return MC_ERROR_NONE;
}
-int mc_set_eos_cb(MMHandleType mediacodec, mediacodec_eos_cb callback, void* user_data)
+int mc_set_eos_cb(MMHandleType mediacodec, mediacodec_eos_cb callback, void *user_data)
{
int ret = MC_ERROR_NONE;
- mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
+ mc_handle_t *mc_handle = (mc_handle_t *) mediacodec;
- if (!mc_handle)
- {
+ if (!mc_handle) {
LOGE("fail invaild param\n");
return MC_INVALID_ARG;
}
- if(mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_EOS])
- {
- LOGE("Already set mediacodec_fill_buffer_cb\n");
+ if (mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_EOS]) {
+ LOGE("Already set mediacodec_fill_buffer_cb");
return MC_PARAM_ERROR;
- }
- else
- {
+ } else {
if (!callback) {
return MC_INVALID_ARG;
}
@@ -702,10 +643,9 @@ int mc_set_eos_cb(MMHandleType mediacodec, mediacodec_eos_cb callback, void* use
int mc_unset_eos_cb(MMHandleType mediacodec)
{
- mc_handle_t* mc_handle = (mc_handle_t*) mediacodec;
+ mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
- if (!mc_handle)
- {
+ if (!mc_handle) {
LOGE("fail invaild param\n");
return MC_INVALID_ARG;
}
@@ -715,34 +655,229 @@ int mc_unset_eos_cb(MMHandleType mediacodec)
return MC_ERROR_NONE;
}
-/*
-gboolean _mc_check_is_supported(mc_handle_t* mc_handle, mediacodec_codec_type_e codec_id, mediacodec_support_type_e flags)
+
+int mc_set_buffer_status_cb(MMHandleType mediacodec, mediacodec_buffer_status_cb callback, void *user_data)
{
- int i=0;
+ int ret = MC_ERROR_NONE;
+ mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
- if (!mc_handle)
- {
+ if (!mc_handle) {
LOGE("fail invaild param\n");
- return FALSE;
+ return MC_INVALID_ARG;
}
- for (i = 0; i < MC_MAX_NUM_CODEC; i++)
- {
- if (mc_handle->g_media_codec_spec_emul[i].mime == codec_id)
- {
- if (mc_handle->g_media_codec_spec_emul[i].codec_type & (flags & 0x3))
- {
- if (mc_handle->g_media_codec_spec_emul[i].support_type & (flags & 0xC))
- {
- mc_handle->port_type = mc_handle->g_media_codec_spec_emul[i].port_type;
- LOGD("port type : %d", mc_handle->port_type);
- return TRUE;
+ if (mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS]) {
+ LOGE("Already set mediacodec_need_data_cb\n");
+ return MC_PARAM_ERROR;
+ } else {
+ if (!callback) {
+ return MC_INVALID_ARG;
+ }
+
+ LOGD("Set start feed callback(cb = %p, data = %p)\n", callback, user_data);
+
+ mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS] = (mc_buffer_status_cb) callback;
+ mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS] = user_data;
+ return MC_ERROR_NONE;
+ }
+
+ return ret;
+}
+
+int mc_unset_buffer_status_cb(MMHandleType mediacodec)
+{
+ mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
+
+ if (!mc_handle) {
+ LOGE("fail invaild param\n");
+ return MC_INVALID_ARG;
+ }
+
+ mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS] = NULL;
+ mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS] = NULL;
+
+ return MC_ERROR_NONE;
+}
+
+int mc_set_supported_codec_cb(MMHandleType mediacodec, mediacodec_supported_codec_cb callback, void *user_data)
+{
+ int ret = MC_ERROR_NONE;
+ mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
+
+ if (!mc_handle) {
+ LOGE("fail invaild param\n");
+ return MC_INVALID_ARG;
+ }
+
+ if (mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_SUPPORTED_CODEC]) {
+ LOGE("Already set mediacodec_supported_codec_cb\n");
+ return MC_PARAM_ERROR;
+ } else {
+ if (!callback) {
+ return MC_INVALID_ARG;
+ }
+
+ LOGD("Set event handler callback(cb = %p, data = %p)", callback, user_data);
+
+ mc_handle->user_cb[_MEDIACODEC_EVENT_TYPE_SUPPORTED_CODEC] = (mc_supported_codec_cb) callback;
+ mc_handle->user_data[_MEDIACODEC_EVENT_TYPE_SUPPORTED_CODEC] = user_data;
+ return MC_ERROR_NONE;
+ }
+
+ return ret;
+}
+
+int _mediacodec_foreach_supported_codec(MMHandleType mediacodec, mediacodec_supported_codec_cb callback, void *user_data)
+{
+ int ret = MC_ERROR_NONE;
+ mc_handle_t *mc_handle = (mc_handle_t *)mediacodec;
+ int codecs_num;
+ gpointer tmp;
+
+ if (!mc_handle) {
+ LOGE("fail invaild param\n");
+ return MC_INVALID_ARG;
+ }
+
+ if (mc_handle->supported_codecs) {
+ codecs_num = g_list_length(mc_handle->supported_codecs);
+ LOGD("supported_codecs : %d", codecs_num);
+
+ while (codecs_num) {
+ tmp = g_list_nth_data(mc_handle->supported_codecs, codecs_num - 1);
+ if (tmp) {
+ if (!callback(GPOINTER_TO_INT(tmp), user_data)) {
+ ret = MEDIACODEC_ERROR_INTERNAL;
+ goto CALLBACK_ERROR;
}
}
+ codecs_num--;
+ }
+
+ if (!callback(-1, user_data)) {
+ ret = MEDIACODEC_ERROR_INTERNAL;
+ goto CALLBACK_ERROR;
+ }
+ }
+
+CALLBACK_ERROR:
+ LOGD("foreach callback returned error");
+ return ret;
+}
+
+int mc_sniff_h264_bitstream(mc_handle_t *handle, media_packet_h pkt)
+{
+ int ret = MC_ERROR_NONE;
+ void *buf_data = NULL;
+ void *codec_data = NULL;
+ unsigned int codec_data_size = 0;
+ uint64_t buf_size = 0;
+ bool eos = false;
+ bool codec_config = false;
+
+ media_packet_get_buffer_size(pkt, &buf_size);
+ media_packet_get_buffer_data_ptr(pkt, &buf_data);
+ media_packet_get_codec_data(pkt, &codec_data, &codec_data_size);
+ media_packet_is_end_of_stream(pkt, &eos);
+ media_packet_is_codec_config(pkt, &codec_config);
+
+ LOGD("codec_data_size : %d, buf_size : %d, codec_config : %d, eos : %d",
+ codec_data_size, (int)buf_size, codec_config, eos);
+
+ if (codec_config) {
+ if (codec_data_size == 0)
+ ret = _mc_check_h264_bytestream(buf_data, (int)buf_size, 0, NULL, NULL, NULL);
+ }
+
+ return ret;
+}
+int mc_sniff_mpeg4_bitstream(mc_handle_t *handle, media_packet_h pkt)
+{
+ uint64_t buf_size = 0;
+ unsigned char *buf_data = NULL;
+ void *codec_data = NULL;
+ int codec_data_size = 0, voss_size = 0;
+ bool eos = false;
+ bool codec_config = false;
+ bool sync_frame = false;
+
+ media_packet_get_buffer_size(pkt, &buf_size);
+ media_packet_get_buffer_data_ptr(pkt, (void *)&buf_data);
+ media_packet_get_codec_data(pkt, &codec_data, &codec_data_size);
+ media_packet_is_end_of_stream(pkt, &eos);
+ media_packet_is_codec_config(pkt, &codec_config);
+ media_packet_is_sync_frame(pkt, &sync_frame);
+
+ LOGD("codec_data_size : %d, buff_size : %d, codec_config : %d, sync_frame : %d, eos : %d",
+ codec_data_size, (int)buf_size, codec_config, sync_frame, eos);
+
+ if (eos)
+ return MC_ERROR_NONE;
+
+ if (codec_config) {
+ if (codec_data) {
+ if (!_mc_is_voss(codec_data, codec_data_size, NULL))/*voss not in codec data */
+ return MC_INVALID_IN_BUF;
+ }
+ /* Codec data + I-frame in buffer */
+ if (_mc_is_voss(buf_data, buf_size, &voss_size)) {
+ if (_mc_is_ivop(buf_data, buf_size, voss_size)) /* IVOP after codec_data */
+ return MC_ERROR_NONE;
+ } else {
+ if (_mc_is_ivop(buf_data, buf_size, 0)) /* IVOP at the start */
+ return MC_ERROR_NONE;
}
+ } else if (_mc_is_vop(buf_data, buf_size, 0))
+ return MC_ERROR_NONE;
+
+ return MC_INVALID_IN_BUF;
+}
+
+int mc_sniff_h263_bitstream(mc_handle_t *handle, media_packet_h pkt)
+{
+ void *buf_data = NULL;
+ uint64_t buf_size = 0;
+ bool eos = false;
+
+ media_packet_get_buffer_size(pkt, &buf_size);
+ media_packet_get_buffer_data_ptr(pkt, &buf_data);
+ media_packet_is_end_of_stream(pkt, &eos);
+
+ if (eos)
+ return MC_ERROR_NONE;
+
+ return _mc_check_valid_h263_frame((unsigned char *)buf_data, (int)buf_size);
+}
+
+int mc_sniff_yuv(mc_handle_t *handle, media_packet_h pkt)
+{
+ int ret = MC_ERROR_NONE;
+
+#if 0 /* libtbm, media-tool should be updated */
+ uint64_t buf_size = 0;
+ int plane_num = 0;
+ int padded_width = 0;
+ int padded_height = 0;
+ int allocated_buffer = 0;
+ int index;
+
+ media_packet_get_buffer_size(pkt, &buf_size);
+ media_packet_get_video_number_of_planes(pkt, &plane_num);
+
+ for (index = 0; index < plane_num; index++) {
+ media_packet_get_video_stride_width(pkt, index, &padded_width);
+ media_packet_get_video_stride_height(pkt, index, &padded_height);
+ allocated_buffer += padded_width * padded_height;
+
+ LOGD("%d plane size : %d", padded_width * padded_height);
}
- return FALSE;
+ if (buf_size > allocated_buffer) {
+ LOGE("Buffer exceeds maximum size [buf_size: %d, allocated_size :%d", (int)buf_size, allocated_buffer);
+ ret = MC_INVALID_IN_BUF;
+ }
+#endif
+ return ret;
}
-*/
+
diff --git a/src/media_codec_port_gst.c b/src/media_codec_port_gst.c
index 170b45b..8da277e 100755
--- a/src/media_codec_port_gst.c
+++ b/src/media_codec_port_gst.c
@@ -33,461 +33,1330 @@
#include <linux/ion.h>
#endif
-#define GST_MC_EVENT_CODEC_DATA "GstEventCodecData"
+#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
/*
* Internal Implementation
*/
static gpointer feed_task(gpointer data);
+static void __mc_gst_stop_feed(GstElement *pipeline, gpointer data);
+static void __mc_gst_start_feed(GstElement *pipeline, guint size, gpointer data);
static media_packet_h _mc_get_input_buffer(mc_gst_core_t *core);
static gboolean __mc_gst_init_gstreamer();
static int _mc_output_media_packet_new(mc_gst_core_t *core, bool video, bool encoder, media_format_mimetype_e out_mime);
-static mc_ret_e _mc_gst_create_pipeline(mc_gst_core_t* core, gchar *factory_name);
+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 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_output_packet_buffer_finalize_cb(media_packet_h packet, int error_code, void *user_data);
-
-static void _mc_gst_update_caps(mc_gst_core_t *core, media_packet_h pkt, GstCaps **caps);
-static mc_gst_buffer_t* _mc_gst_media_packet_to_gstbuffer(mc_gst_core_t* core, GstCaps **caps, media_packet_h pkt, bool codec_config);
-static int _mc_gst_gstbuffer_to_appsrc(mc_gst_core_t *core, mc_gst_buffer_t *buff);
-static guint32 __mc_get_gst_input_format(media_packet_h packet, bool is_hw);
-static media_packet_h __mc_gst_gstbuffer_to_media_packet(mc_gst_core_t* core, GstBuffer* buffer);
+static void _mc_gst_update_caps(mc_gst_core_t *core, media_packet_h pkt, GstCaps **caps, GstMCBuffer* buff, bool codec_config);
+static GstMCBuffer *_mc_gst_media_packet_to_gstbuffer(mc_gst_core_t *core, GstCaps **caps, media_packet_h pkt, bool codec_config);
+static int _mc_gst_gstbuffer_to_appsrc(mc_gst_core_t *core, GstMCBuffer *buff);
+static gchar *__mc_get_gst_input_format(media_packet_h packet, bool is_hw);
+static media_packet_h __mc_gst_make_media_packet(mc_gst_core_t *core, unsigned char *data, int size);
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 SCMN_IMGB* __mc_gst_make_tbm_buffer(mc_gst_core_t* core, media_packet_h pkt);
-static gboolean event_probe_cb(GstPad *pad, GstEvent *event, gpointer user_data);
-static GType __mc_gst_buffer_get_type(void);
-static void __mc_gst_buffer_class_init(gpointer g_class, gpointer class_data);
-static mc_gst_buffer_t* __mc_gst_buffer_new(mc_gst_core_t* core);
-static void __mc_gst_buffer_finalize(mc_gst_buffer_t *buffer);
-
-static gint __gst_handle_stream_error(mc_gst_core_t* core, GError* error, GstMessage * message);
-static gint __gst_transform_gsterror( mc_gst_core_t *core, GstMessage * message, GError* error );
-static gint __gst_handle_resource_error(mc_gst_core_t* core, int code );
-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 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 pkt);
+static GstMCBuffer *gst_mediacodec_buffer_new(mc_gst_core_t* core, media_packet_h pkt, uint64_t size);
+static void gst_mediacodec_buffer_finalize(GstMCBuffer *buffer);
+static int __mc_set_caps_streamheader(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer*buff, guint streamheader_size);
+static int __mc_set_caps_codecdata(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer*buff, guint codecdata_size);
+
+static gint __gst_handle_stream_error(mc_gst_core_t *core, GError *error, GstMessage *message);
+static gint __gst_transform_gsterror(mc_gst_core_t *core, GstMessage *message, GError *error);
+static gint __gst_handle_resource_error(mc_gst_core_t *core, int code);
+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 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);
+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);
-static GstBufferClass *mc_gst_buffer_parent_class = NULL;
-
-#define GST_TYPE_MC_BUFFER (__mc_gst_buffer_get_type())
+static int __tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos);
+static void __csc_tiled_to_linear_crop(unsigned char *yuv420_dest,
+ unsigned char *nv12t_src, int yuv420_width, int yuv420_height,
+ int left, int top, int right, int buttom);
+
+static void _mc_send_eos_signal(mc_gst_core_t *core);
+static void _mc_wait_for_eos(mc_gst_core_t *core);
+
+/* video vtable */
+int(*vdec_vtable[])() = {&__mc_fill_inbuf_with_packet, &__mc_fill_vdec_packet_with_outbuf, &__mc_vdec_caps};
+int(*venc_vtable[])() = {&__mc_fill_inbuf_with_packet, &__mc_fill_venc_packet_with_outbuf, &__mc_venc_caps};
+
+
+int(*vdec_h264_sw_vtable[])() = {&__mc_fill_inbuf_with_packet, /* FFMPEG H.264 Decoder Vtable */
+ &__mc_fill_vdec_packet_with_outbuf,
+ &__mc_vdec_caps};
+int(*vdec_h264_hw_vtable[])() = {&__mc_fill_inbuf_with_packet, /* SPRD H.264 Decoder Vtable */
+ &__mc_fill_video_packet_with_mm_video_buffer,
+ &__mc_sprddec_caps};
+int(*venc_h264_hw_vtable[])() = {&__mc_fill_inbuf_with_mm_video_buffer, /* SPRD H.264 Encoder Vtable */
+ &__mc_fill_venc_packet_with_outbuf,
+ &__mc_sprdenc_caps};
+int(*vdec_mpeg4_sw_vtable[])() = {&__mc_fill_inbuf_with_packet, /* FFMPEG MPEG4 Decoder Vtable */
+ &__mc_fill_vdec_packet_with_outbuf,
+ &__mc_vdec_mpeg4_caps};
+int(*vdec_mpeg4_hw_vtable[])() = {&__mc_fill_inbuf_with_packet, /* SPRD MPEG4 Decoder Vtable */
+ &__mc_fill_video_packet_with_mm_video_buffer,
+ &__mc_sprddec_mpeg4_caps};
+int(*venc_mpeg4_sw_vtable[])() = {&__mc_fill_inbuf_with_venc_packet, /* SPRD MPEG4 Encoder Vtable */
+ &__mc_fill_venc_packet_with_outbuf,
+ &__mc_venc_caps};
+int(*venc_mpeg4_hw_vtable[])() = {&__mc_fill_inbuf_with_mm_video_buffer, /* SPRD MPEG4 Encoder Vtable */
+ &__mc_fill_venc_packet_with_outbuf,
+ &__mc_sprdenc_mpeg4_caps};
+int(*vdec_h263_sw_vtable[])() = {&__mc_fill_inbuf_with_packet, /* FFMPEG MPEG4 Decoder Vtable */
+ &__mc_fill_vdec_packet_with_outbuf,
+ &__mc_vdec_h263_caps};
+int(*vdec_h263_hw_vtable[])() = {&__mc_fill_inbuf_with_packet, /* SPRD MPEG4 Decoder Vtable */
+ &__mc_fill_video_packet_with_mm_video_buffer,
+ &__mc_sprddec_mpeg4_caps};
+int(*venc_h263_sw_vtable[])() = {&__mc_fill_inbuf_with_venc_packet, /* SPRD MPEG4 Encoder Vtable */
+ &__mc_fill_venc_packet_with_outbuf,
+ &__mc_venc_caps};
+int(*venc_h263_hw_vtable[])() = {&__mc_fill_inbuf_with_mm_video_buffer, /* SPRD MPEG4 Encoder Vtable */
+ &__mc_fill_venc_packet_with_outbuf,
+ &__mc_sprdenc_mpeg4_caps};
+
+/* audio vtable */
+int(*aenc_vtable[])() = {&__mc_fill_inbuf_with_packet, &__mc_fill_packet_with_outbuf, &__mc_aenc_caps};
+int(*adec_vtable[])() = {&__mc_fill_inbuf_with_packet, &__mc_fill_packet_with_outbuf, &__mc_adec_caps};
+
+int(*aenc_aac_vtable[])() = {&__mc_fill_inbuf_with_packet, /* AAC LC Encoder vtable */
+ &__mc_fill_packet_with_outbuf,
+ &__mc_aenc_aac_caps};
+int(*adec_aac_vtable[])() = {&__mc_fill_inbuf_with_packet, /* AAC LC Decoder Vtable */
+ &__mc_fill_packet_with_outbuf,
+ &__mc_adec_aac_caps};
+int(*adec_aacv12_vtable[])() = {&__mc_fill_inbuf_with_packet, /* AAC HE Decoder Vtable */
+ &__mc_fill_packet_with_outbuf,
+ &__mc_adec_aacv12_caps};
+int(*adec_mp3_vtable[])() = {&__mc_fill_inbuf_with_packet, /* MP3 Decoder Vtable */
+ &__mc_fill_packet_with_outbuf,
+ &__mc_adec_mp3_caps};
+int(*adec_amrnb_vtable[])() = {&__mc_fill_inbuf_with_packet, /* AMR-NB Decoder Vtable */
+ &__mc_fill_packet_with_outbuf,
+ &__mc_adec_amrnb_caps};
+int(*adec_amrwb_vtable[])() = {&__mc_fill_inbuf_with_packet, /* AMR-WB Decoder Vtable */
+ &__mc_fill_packet_with_outbuf,
+ &__mc_adec_amrwb_caps};
+int(*aenc_amrnb_vtable[])() = {&__mc_fill_inbuf_with_packet, /* AMR-NB Encoder Vtable */
+ &__mc_fill_packet_with_outbuf,
+ &__mc_aenc_amrnb_caps};
+int(*adec_vorbis_vtable[])() = {&__mc_fill_inbuf_with_packet, /* VORBIS Decoder Vtable */
+ &__mc_fill_packet_with_outbuf,
+ &__mc_adec_vorbis_caps};
+int(*adec_flac_vtable[])() = {&__mc_fill_inbuf_with_packet, /* FLAC Decoder Vtable */
+ &__mc_fill_packet_with_outbuf,
+ &__mc_adec_flac_caps};
+int(*adec_wma_vtable[])() = {&__mc_fill_inbuf_with_packet, /* WMA Decoder Vtable */
+ &__mc_fill_packet_with_outbuf,
+ &__mc_adec_wma_caps};
-//static uint64_t wait_until = g_get_monotonic_time() + G_TIME_SPAN_SECOND / 2;
-
-int(*vdec_vtable[])() = {&__mc_fill_inbuf_with_packet, &__mc_fill_outbuf_with_packet, &__mc_vdec_caps};
-int(*venc_vtable[])() = {&__mc_fill_inbuf_with_packet, &__mc_fill_outbuf_with_packet, &__mc_venc_caps};
-int(*adec_vtable[])() = {&__mc_fill_inbuf_with_packet, &__mc_fill_outbuf_with_packet, &__mc_adec_caps};
-int(*aenc_vtable[])() = {&__mc_fill_inbuf_with_packet, &__mc_fill_outbuf_with_packet, &__mc_aenc_caps};
-int(*mp3dec_vtable[])() = {&__mc_fill_inbuf_with_packet, &__mc_fill_outbuf_with_packet, &__mc_mp3dec_caps};
-int(*h264dec_vtable[])() = {&__mc_fill_inbuf_with_packet, &__mc_fill_outbuf_with_bo, &__mc_vdec_caps};
-int(*h264enc_vtable[])() = {&__mc_fill_inbuf_with_bo, &__mc_fill_outbuf_with_packet, &__mc_venc_caps};
-int(*h263dec_vtable[])() = {&__mc_fill_inbuf_with_packet, &__mc_fill_outbuf_with_bo, &__mc_vdec_caps};
-int(*h263enc_vtable[])() = {&__mc_fill_inbuf_with_bo, &__mc_fill_outbuf_with_packet, &__mc_h263enc_caps};
/*
- * mc_gst_object functions
+ * fill_inbuf virtual functions
*/
-int __mc_fill_input_buffer(mc_gst_core_t *core, mc_gst_buffer_t *buff)
-{
- return core->vtable[fill_inbuf](core, buff);
-}
-
-int __mc_fill_output_buffer(mc_gst_core_t *core, GstBuffer* buff, media_packet_h *out_pkt)
-{
- return core->vtable[fill_outbuf](core, buff, out_pkt);
-}
-
-int __mc_create_caps(mc_gst_core_t *core, GstCaps **caps)
+int __mc_fill_input_buffer(mc_gst_core_t *core, media_packet_h pkt, GstMCBuffer *buff)
{
- return core->vtable[create_caps](core, caps);
+ return core->vtable[fill_inbuf](core, pkt, buff);
}
-int __mc_fill_inbuf_with_bo(mc_gst_core_t *core, mc_gst_buffer_t *buff)
+int __mc_fill_inbuf_with_mm_video_buffer(mc_gst_core_t *core, media_packet_h pkt, GstMCBuffer *mc_buffer)
{
int ret = MC_ERROR_NONE;
- void* buf_data = NULL;
- uint64_t buf_size = 0;
- MEDIACODEC_FENTER();
+ MMVideoBuffer *mm_vbuffer = NULL;
+ void *buf_data = NULL;
+ uint64_t buf_size = 0;
- if (!buff->pkt)
- {
- LOGE("output is null");
- return MC_INTERNAL_ERROR;
+ ret = media_packet_get_buffer_size(pkt, &buf_size);
+ if (ret != MEDIA_PACKET_ERROR_NONE) {
+ LOGW("buffer size get fail");
+ return MC_ERROR;
}
- /* copy media_packet to new gstbuffer */
- ret = media_packet_get_buffer_size(buff->pkt, &buf_size);
- if (ret != MEDIA_PACKET_ERROR_NONE)
- {
+ ret = media_packet_get_buffer_data_ptr(pkt, &buf_data);
+ if (ret != MEDIA_PACKET_ERROR_NONE) {
LOGW("buffer size get fail");
+ return MC_ERROR;
}
- ret = media_packet_get_buffer_data_ptr(buff->pkt, &buf_data);
- if (ret != MEDIA_PACKET_ERROR_NONE)
- {
- LOGW("buffer size get fail");
- return MC_INTERNAL_ERROR;
+ mm_vbuffer = __mc_gst_make_tbm_buffer(core, mc_buffer->pkt);
+
+ if (mm_vbuffer != NULL) {
+ gst_buffer_prepend_memory(mc_buffer->buffer,
+ gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, mm_vbuffer, sizeof(*mm_vbuffer), 0,
+ sizeof(*mm_vbuffer), mm_vbuffer, free));
+ LOGD("scmn_mm_vbuffer is appended, %d, %d", sizeof(*mm_vbuffer), gst_buffer_n_memory(mc_buffer->buffer));
}
- SCMN_IMGB *imgb = NULL;
- GST_BUFFER_DATA(buff) = buf_data;
- GST_BUFFER_SIZE (buff) = buf_size;
- imgb = __mc_gst_make_tbm_buffer(core, buff->pkt);
+ if (buf_data != NULL) {
+ gst_buffer_prepend_memory(mc_buffer->buffer,
+ gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, buf_data, buf_size, 0,
+ buf_size, mc_buffer, (GDestroyNotify)gst_mediacodec_buffer_finalize));
+ LOGD("packet data is apended, %d, %d", buf_size, gst_buffer_n_memory(mc_buffer->buffer));
+ }
+ return ret;
+}
- if (!imgb)
- {
- LOGE("get imgb failed");
- return MC_INTERNAL_ERROR;
+int __mc_fill_inbuf_with_packet(mc_gst_core_t *core, media_packet_h pkt, GstMCBuffer *mc_buffer)
+{
+ int ret = MC_ERROR_NONE;
+ void *buf_data = NULL;
+ uint64_t buf_size = 0;
+
+ ret = media_packet_get_buffer_size(pkt, &buf_size);
+ if (ret != MEDIA_PACKET_ERROR_NONE) {
+ LOGW("buffer size get fail");
+ return MC_ERROR;
}
- GST_BUFFER_MALLOCDATA(buff) = (guint8 *)imgb;
- LOGD("__mc_fill_inbuf_with_bo :%llu", buf_size);
+ ret = media_packet_get_buffer_data_ptr(pkt, &buf_data);
+ if (ret != MEDIA_PACKET_ERROR_NONE) {
+ LOGW("buffer size get fail");
+ return MC_ERROR;
+ }
- MEDIACODEC_FLEAVE();
+ if (buf_data != NULL) {
+ gst_buffer_append_memory(mc_buffer->buffer,
+ gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, buf_data, buf_size, 0,
+ buf_size, mc_buffer, (GDestroyNotify)gst_mediacodec_buffer_finalize));
+ LOGD("packet data is apended");
+ }
return ret;
}
-int __mc_fill_inbuf_with_packet(mc_gst_core_t *core, mc_gst_buffer_t *buff)
+int __mc_fill_inbuf_with_venc_packet(mc_gst_core_t *core, media_packet_h pkt, GstMCBuffer *mc_buffer)
{
- int ret = MEDIA_PACKET_ERROR_NONE;
- void* buf_data = NULL;
- uint64_t buf_size = 0;
+ int ret = MC_ERROR_NONE;
+ void *uv_ptr = NULL;
+ void *y_ptr = NULL;
+ int buf_size = 0;
+ int stride_width;
+ int stride_height;
+ int width;
+ int height;
+ uint32_t plane_num;
+ int i;
+ int j;
+ int stride = 0;
- g_return_val_if_fail (core != NULL, MC_PARAM_ERROR);
+ mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info;
- MEDIACODEC_FENTER();
+ width = enc_info->width;
+ height = enc_info->height;
- /* copy media_packet to new gstbuffer */
- ret = media_packet_get_buffer_size(buff->pkt, &buf_size);
- if (ret != MEDIA_PACKET_ERROR_NONE)
- {
- LOGW("buffer size get fail");
- return ret;
+ ret = media_packet_get_number_of_video_planes(pkt, &plane_num);
+ if (ret != MEDIA_PACKET_ERROR_NONE) {
+ LOGW("media_packet_get_number_of_video_planes failed");
+ return MC_ERROR;
}
- ret = media_packet_get_buffer_data_ptr(buff->pkt, &buf_data);
- if (ret != MEDIA_PACKET_ERROR_NONE)
- {
- LOGW("buffer size get fail");
- return ret;
+ ret = media_packet_get_video_plane_data_ptr(pkt, 0, &y_ptr);
+ if (ret != MEDIA_PACKET_ERROR_NONE) {
+ LOGW("media_packet_get_video_plane_data_ptr failed");
+ return MC_ERROR;
}
- //mc_hex_dump("nal", buf_data, 8);
- GST_BUFFER_DATA(buff) = buf_data;
- GST_BUFFER_SIZE (buff) = buf_size;
+ ret = media_packet_get_video_stride_width(pkt, 0, &stride_width);
+ if (ret != MEDIA_PACKET_ERROR_NONE) {
+ LOGW("media_packet_get_video_stride_width failed");
+ return MC_ERROR;
+ }
- LOGD("filled with packet,%d, %p", (int)buf_size, buf_data);
- MEDIACODEC_FLEAVE();
+ ret = media_packet_get_video_stride_height(pkt, 0, &stride_height);
+ if (ret != MEDIA_PACKET_ERROR_NONE) {
+ LOGW("media_packet_get_video_stride_width failed");
+ return MC_ERROR;
+ }
+
+ if (width == stride_width) {
+ mc_buffer->buf_size += stride_width * stride_height;
+
+ for (i = 1; i < plane_num; i++) {
+ media_packet_get_video_plane_data_ptr(pkt, i, &uv_ptr);
+ media_packet_get_video_stride_width(pkt, i, &stride_width);
+ media_packet_get_video_stride_height(pkt, i, &stride_height);
+
+ buf_size = stride_width * stride_height;
+
+ memcpy(y_ptr + mc_buffer->buf_size, uv_ptr, buf_size);
+ LOGD("width is same with stride");
+ LOGD("plane : %d, buf_size : %d, total : %d", i, buf_size, mc_buffer->buf_size);
+ mc_buffer->buf_size += buf_size;
+
+ }
+ } else {
+
+ for (j = 0; j < height; j++) {
+ memcpy(y_ptr + mc_buffer->buf_size, y_ptr + stride, width);
+ mc_buffer->buf_size += width;
+ stride += stride_width;
+ }
+
+ stride = 0;
+
+ for (i = 1; i < plane_num; i++) {
+ media_packet_get_video_plane_data_ptr(pkt, i, &uv_ptr);
+ media_packet_get_video_stride_width(pkt, i, &stride_width);
+ media_packet_get_video_stride_height(pkt, i, &stride_height);
+
+ for (j = 0; j < height>>1; j++) {
+ memcpy(y_ptr + mc_buffer->buf_size, uv_ptr + stride, width>>1);
+ mc_buffer->buf_size += width>>1;
+ stride += stride_width;
+ }
+
+ memcpy(y_ptr + mc_buffer->buf_size, uv_ptr, buf_size);
+ LOGD("plane : %d, buf_size : %d, total : %d", i, buf_size, mc_buffer->buf_size);
+ mc_buffer->buf_size += buf_size;
+ }
+ }
+
+ if (y_ptr != NULL) {
+ gst_buffer_append_memory(mc_buffer->buffer,
+ gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, y_ptr, mc_buffer->buf_size, 0,
+ mc_buffer->buf_size, mc_buffer, (GDestroyNotify)gst_mediacodec_buffer_finalize));
+ LOGD("%d plane data apended : width : %d, height : %d, size : %d",
+ i, stride_width, stride_height, mc_buffer->buf_size);
+ }
return ret;
}
-int __mc_fill_outbuf_with_bo(mc_gst_core_t *core, GstBuffer *buff, media_packet_h* out_pkt)
-{
- int i = 0;;
- int bo_num = 0;
- g_return_val_if_fail (core != NULL, MC_PARAM_ERROR);
- g_return_val_if_fail (buff != NULL, MC_PARAM_ERROR);
+/*
+ * fill_outbuf virtual functions
+*/
- MEDIACODEC_FENTER();
+int __mc_fill_output_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_pkt)
+{
+ return core->vtable[fill_outbuf](core, data, size, out_pkt);
+}
- SCMN_IMGB *psimgb = NULL;
+int __mc_fill_vdec_packet_with_outbuf(mc_gst_core_t *core, void *data, int size, media_packet_h *pkt)
+{
+ int i;
+ int stride_width;
+ int stride_height;
+ uint32_t width;
+ uint32_t height;
+ uint32_t plane_num;
+ uint32_t buf_size;
+ uint32_t plane_size;
+ int ret = MC_ERROR_NONE;
+ void *pkt_data = NULL;
tbm_surface_h tsurf = NULL;
- psimgb = (SCMN_IMGB*)GST_BUFFER_MALLOCDATA(buff);
- mc_decoder_info_t *codec_info = (mc_decoder_info_t *)core->codec_info;
-#ifdef TBM_API_CHANGE
tbm_surface_info_s tsurf_info;
+ tbm_bo bo[MM_VIDEO_BUFFER_PLANE_MAX];
+ tbm_bo_handle thandle;
+
+ g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
+
+ mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
+
+ width = dec_info->width;
+ height = dec_info->height;
+ stride_width = ALIGN(width, 4);
+ stride_height = ALIGN(height, 4);
+ buf_size = stride_width * stride_height * 3 / 2;
+
+ if (buf_size > size)
+ return MC_ERROR;
+
memset(&tsurf_info, 0x0, sizeof(tbm_surface_info_s));
-#endif
- /* create tbm surface */
- for (i = 0; i < SCMN_IMGB_MAX_PLANE; i++)
- {
- if (psimgb->bo[i])
- {
- bo_num++;
-#ifdef TBM_API_CHANGE
- tsurf_info.planes[i].stride = psimgb->s[i];
-#endif
- }
+ bo[0] = tbm_bo_alloc(core->bufmgr, buf_size, TBM_BO_WC);
+ if (!bo[0]) {
+ LOGE("bo allocation failed");
+ return MC_ERROR;
}
- if (bo_num > 0)
- {
-#ifdef TBM_API_CHANGE
- tsurf_info.width = codec_info->width;
- tsurf_info.height = codec_info->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 = psimgb->s[i];
- tsurf_info.planes[i].size = psimgb->s[i] * psimgb->e[i];
-
- if(i < bo_num)
- tsurf_info.planes[i].offset = 0;
- else
- tsurf_info.planes[i].offset = tsurf_info.planes[i - 1].size;
+ tsurf_info.width = dec_info->width;
+ tsurf_info.height = dec_info->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);
+ tsurf_info.size = 0;
+
+ for (i = 0; i < tsurf_info.num_planes; i++) {
+ if (i == 0) {
+ tsurf_info.planes[i].stride = stride_width;
+ tsurf_info.planes[i].size = stride_width * stride_height;
+ tsurf_info.planes[i].offset = 0;
+ tsurf_info.size = tsurf_info.planes[i].size;
+ } else {
+ tsurf_info.planes[i].stride = stride_width>>1;
+ tsurf_info.planes[i].size = (stride_width>>1) * (stride_height>>1);
+ 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;
}
-
- tsurf = tbm_surface_internal_create_with_bos(&tsurf_info, (tbm_bo *)psimgb->bo, bo_num);
- LOGD("[NEW API] tbm surface %p", tsurf);
-#else
- tsurf = tbm_surface_internal_create_with_bos(codec_info->width, codec_info->height, TBM_FORMAT_NV12, (tbm_bo *)psimgb->bo, bo_num);
- LOGD("[OLD API] tbm surface %p", tsurf);
-#endif
}
- if (tsurf)
- {
- media_packet_create_from_tbm_surface(core->output_fmt, tsurf, (media_packet_finalize_cb)__mc_output_buffer_finalize_cb, core, out_pkt);
- LOGD("output pkt = %p", *out_pkt);
- media_packet_set_extra(*out_pkt, buff);
- media_packet_set_buffer_size(*out_pkt, GST_BUFFER_SIZE(buff));
- media_packet_set_pts(*out_pkt, GST_BUFFER_TIMESTAMP(buff));
- }
+ thandle = tbm_bo_map(bo[0], TBM_DEVICE_CPU, TBM_OPTION_WRITE);
+ memcpy(thandle.ptr, data, tsurf_info.size);
+ tbm_bo_unmap(bo[0]);
- MEDIACODEC_FLEAVE();
+ tsurf = tbm_surface_internal_create_with_bos(&tsurf_info, bo, 1);
+
+ if (tsurf) {
+ media_packet_create_from_tbm_surface(core->output_fmt, tsurf,
+ (media_packet_finalize_cb)__mc_output_buffer_finalize_cb, core, pkt);
+ }
return MC_ERROR_NONE;
}
-
-int __mc_fill_outbuf_with_packet(mc_gst_core_t *core, GstBuffer *buff, media_packet_h *out_pkt)
+int __mc_fill_video_packet_with_mm_video_buffer(mc_gst_core_t *core, void *data, int size, media_packet_h *out_pkt)
{
- void* pkt_data = NULL;
+ void *pkt_data = NULL;
+ MMVideoBuffer *mm_vbuffer = NULL;
+ int i;
+ int bo_num = 0;
- g_return_val_if_fail (core != NULL, MC_PARAM_ERROR);
- g_return_val_if_fail (buff != NULL, MC_PARAM_ERROR);
+ g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
- MEDIACODEC_FENTER();
+ mc_decoder_info_t *codec_info = (mc_decoder_info_t *)core->codec_info;
+ mm_vbuffer = (MMVideoBuffer *)data;
+
+ LOGD("buf_share_method %d", mm_vbuffer->type);
+
+ LOGD("a[0] : %p, a[1] : %p, p[0] : %p, p[1] : %p",
+ mm_vbuffer->data[0], mm_vbuffer->data[1], mm_vbuffer->handle.paddr[0], mm_vbuffer->handle.paddr[1]);
+ LOGD("s[0]:%d, e[0]:%d, w[0]:%d, h[0]:%d",
+ mm_vbuffer->stride_width[0], mm_vbuffer->stride_height[0], mm_vbuffer->width[0], mm_vbuffer->height[0]);
+
+ if (mm_vbuffer->type == MM_VIDEO_BUFFER_TYPE_PHYSICAL_ADDRESS) {
+ media_packet_set_buffer_size(*out_pkt, mm_vbuffer->width[0]*mm_vbuffer->height[0]*3/2);
+ media_packet_get_buffer_data_ptr(*out_pkt, &pkt_data);
+
+ __csc_tiled_to_linear_crop(pkt_data, mm_vbuffer->data[0],
+ mm_vbuffer->stride_width[0], mm_vbuffer->stride_height[0], 0, 0, 0, 0);
+ __csc_tiled_to_linear_crop(pkt_data+mm_vbuffer->stride_width[0]*mm_vbuffer->stride_height[0],
+ mm_vbuffer->data[1], mm_vbuffer->stride_width[0], mm_vbuffer->stride_height[0]/2, 0, 0, 0, 0);
+ } else if (mm_vbuffer->type == MM_VIDEO_BUFFER_TYPE_DMABUF_FD) {
+ LOGD("FD type");
+ } else if (mm_vbuffer->type == MM_VIDEO_BUFFER_TYPE_TBM_BO) {
+ tbm_surface_h tsurf = NULL;
+ 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];
+ }
+ }
- media_packet_create_alloc(core->output_fmt, __mc_output_packet_buffer_finalize_cb, core, out_pkt);
+ if (bo_num > 0) {
+ tsurf_info.width = codec_info->width;
+ tsurf_info.height = codec_info->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;
- if (!out_pkt)
- {
- LOGE("out_pkt is null");
- return MC_MEMORY_ERROR;
+ 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",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);
+ }
+
+ if (tsurf) {
+ media_packet_create_from_tbm_surface(core->output_fmt, tsurf,
+ (media_packet_finalize_cb)__mc_output_buffer_finalize_cb, core, out_pkt);
+ }
}
- media_packet_set_extra(*out_pkt, buff);
- LOGI("create_gst_buffer = %p", buff);
- LOGI("gstbuffer refcount %d", GST_MINI_OBJECT_REFCOUNT_VALUE(buff));
+ return MC_ERROR_NONE;
+}
+
+int __mc_fill_packet_with_outbuf(mc_gst_core_t *core, void *data, int size, media_packet_h *out_pkt)
+{
+ void *pkt_data = NULL;
+ int ret = MC_ERROR_NONE;
+ g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
- // !!!! this time do memcpy because no way to set data ptr to media packet.
- media_packet_set_buffer_size(*out_pkt, GST_BUFFER_SIZE(buff));
+ ret = media_packet_create_alloc(core->output_fmt, __mc_output_buffer_finalize_cb, core, out_pkt);
+ if (ret != MEDIA_PACKET_ERROR_NONE) {
+ LOGW("media_packet_create_alloc failed");
+ return MC_ERROR;
+ }
+
+ media_packet_set_buffer_size(*out_pkt, size);
media_packet_get_buffer_data_ptr(*out_pkt, &pkt_data);
+ memcpy(pkt_data, data, size);
- if (!pkt_data)
- {
- media_packet_destroy(*out_pkt);
- return MC_OUTPUT_BUFFER_EMPTY;
+ return MC_ERROR_NONE;
+}
+
+int __mc_fill_venc_packet_with_outbuf(mc_gst_core_t *core, void *data, int size, media_packet_h *out_pkt)
+{
+ void *pkt_data = NULL;
+ bool codec_config = FALSE;
+ bool sync_flag = FALSE;
+ bool slice = FALSE;
+ int codec_data_size = 0;
+ int ret = MC_ERROR_NONE;
+
+ g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
+
+ switch (core->out_mime) {
+ 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);
+ break;
+ case MEDIA_FORMAT_MPEG4_SP:
+ case MEDIA_FORMAT_MPEG4_ASP:
+ codec_data_size = _mc_check_mpeg4_out_bytestream((unsigned char *)data, size, &codec_config, &sync_flag);
+ break;
+ case MEDIA_FORMAT_H263:
+ case MEDIA_FORMAT_H263P:
+ if (!_mc_check_h263_out_bytestream((unsigned char *)data, size, &sync_flag))
+ return MC_INVALID_IN_BUF;
+ break;
+ default:
+ return MC_INVALID_IN_BUF;
}
+ LOGD("codec_config : %d, sync_flag : %d, slice : %d", codec_config, sync_flag, slice);
- memcpy(pkt_data, GST_BUFFER_DATA(buff), GST_BUFFER_SIZE(buff));
- media_packet_set_pts(*out_pkt, GST_BUFFER_TIMESTAMP(buff));
+ ret = media_packet_create_alloc(core->output_fmt, __mc_output_buffer_finalize_cb, core, out_pkt);
+ if (ret != MEDIA_PACKET_ERROR_NONE) {
+ LOGW("media_packet_create_alloc failed");
+ return MC_ERROR;
+ }
- MEDIACODEC_FLEAVE();
+ media_packet_set_buffer_size(*out_pkt, size);
+ media_packet_get_buffer_data_ptr(*out_pkt, &pkt_data);
+ memcpy(pkt_data, data, size);
- return MC_ERROR_NONE;
+ core->need_sync_flag = sync_flag ? 1 : 0;
+ core->need_codec_data = codec_config ? 1 : 0;
+
+ return ret;
}
-int __mc_venc_caps(mc_gst_core_t *core, GstCaps **caps)
+/*
+ * create_caps virtual functions
+*/
+
+int __mc_create_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
{
- g_return_val_if_fail (core != NULL, MC_PARAM_ERROR);
+ return core->vtable[create_caps](core, caps, buff, codec_config);
+}
- MEDIACODEC_FENTER();
+int __mc_venc_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
+{
+ g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
+
+ mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info;
- mc_encoder_info_t *enc_info = (mc_encoder_info_t*)core->codec_info;
+ *caps = gst_caps_new_simple("video/x-raw",
+ "format", G_TYPE_STRING, "I420",
+ "width", G_TYPE_INT, enc_info->width,
+ "height", G_TYPE_INT, enc_info->height,
+ "framerate", GST_TYPE_FRACTION, enc_info->fps, 1,
+ NULL);
+
+ LOGD("%d, %d, %d", enc_info->width, enc_info->height, enc_info->fps);
+
+ return MC_ERROR_NONE;
+}
+
+int __mc_sprdenc_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
+{
+ g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
+
+ mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info;
*caps = gst_caps_new_simple(core->mime,
- "format", GST_TYPE_FOURCC, 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);
+ "format", G_TYPE_STRING, "SN12",
+ "width", G_TYPE_INT, enc_info->width,
+ "height", G_TYPE_INT, enc_info->height,
+ "framerate", GST_TYPE_FRACTION, enc_info->fps, 1, NULL);
- g_object_set (GST_OBJECT(core->codec), "byte-stream", TRUE, NULL);
- g_object_set (GST_OBJECT(core->codec), "bitrate", enc_info->bitrate*1000, NULL);
+ g_object_set(GST_OBJECT(core->codec), "byte-stream", TRUE, NULL);
+ g_object_set(GST_OBJECT(core->codec), "bitrate", enc_info->bitrate*1000, NULL);
- LOGD("%d, %d, %d, %d", core->format, enc_info->width, enc_info->height, enc_info->fps);
+ LOGD("%s, %d, %d, %d", core->format, enc_info->width, enc_info->height, enc_info->fps);
- MEDIACODEC_FLEAVE();
return MC_ERROR_NONE;
}
-int __mc_h263enc_caps(mc_gst_core_t *core, GstCaps **caps)
+int __mc_sprdenc_mpeg4_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *buff, bool codec_config)
{
- g_return_val_if_fail (core != NULL, MC_PARAM_ERROR);
+ g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
- mc_encoder_info_t *enc_info = (mc_encoder_info_t*)core->codec_info;
+ mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info;
- MEDIACODEC_FENTER();
+ *caps = gst_caps_new_simple("video/x-raw",
+ "format", G_TYPE_STRING, "SN12",
+ "width", G_TYPE_INT, enc_info->width,
+ "height", G_TYPE_INT, enc_info->height,
+ "framerate", GST_TYPE_FRACTION, enc_info->fps, 1, NULL);
- *caps = gst_caps_new_simple(core->mime,
- "format", GST_TYPE_FOURCC, 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);
+ g_object_set(GST_OBJECT(core->codec), "bitrate", enc_info->bitrate*1000, NULL);
- g_object_set (GST_OBJECT(core->codec), "bitrate", enc_info->bitrate*1000, NULL);
+ LOGD("%s, %d, %d, %d", core->format, enc_info->width, enc_info->height, enc_info->fps);
- LOGD("%d, %d, %d, %d", core->format, enc_info->width, enc_info->height, enc_info->fps);
- MEDIACODEC_FLEAVE();
+ return MC_ERROR_NONE;
+}
+
+int __mc_h264dec_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
+{
+ g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
+
+ mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
+ LOGD("%d, %d, ", dec_info->width, dec_info->height);
+ *caps = gst_caps_new_simple(core->mime,
+ "parsed", G_TYPE_BOOLEAN, TRUE,
+ "alignment", G_TYPE_STRING, "au",
+ "stream-format", G_TYPE_STRING, "byte-stream",
+ "width", G_TYPE_INT, dec_info->width,
+ "height", G_TYPE_INT, dec_info->height, NULL);
+
+ LOGD("mime : %s, widht :%d, height : %d", core->mime, dec_info->width, dec_info->height);
return MC_ERROR_NONE;
}
-int __mc_mp3dec_caps(mc_gst_core_t *core, GstCaps **caps)
+int __mc_sprddec_mpeg4_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
{
- g_return_val_if_fail (core != NULL, MC_PARAM_ERROR);
+ g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
- MEDIACODEC_FENTER();
- mc_decoder_info_t *dec_info = (mc_decoder_info_t*)core->codec_info;
+ mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
+
+ LOGD("%d, %d, ", dec_info->width, dec_info->height);
*caps = gst_caps_new_simple(core->mime,
- "mpegversion", G_TYPE_INT, 1,
- "layer", G_TYPE_INT, 3,
- "channels", G_TYPE_INT, dec_info->channel,
- "rate", G_TYPE_INT, dec_info->samplerate,
- NULL);
+ "mpegversion", G_TYPE_INT, 4,
+ "width", G_TYPE_INT, dec_info->width,
+ "height", G_TYPE_INT, dec_info->height,
+ "framerate", GST_TYPE_FRACTION, 30, 1,
+ NULL);
- MEDIACODEC_FLEAVE();
+ LOGD("mime : %s, widht :%d, height : %d", core->mime, dec_info->width, dec_info->height);
return MC_ERROR_NONE;
}
-int __mc_vdec_caps(mc_gst_core_t *core, GstCaps **caps)
+int __mc_sprddec_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
{
- g_return_val_if_fail (core != NULL, MC_PARAM_ERROR);
+ g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
- MEDIACODEC_FENTER();
- mc_decoder_info_t *dec_info = (mc_decoder_info_t*)core->codec_info;
+ mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
LOGD("%d, %d, ", dec_info->width, dec_info->height);
*caps = gst_caps_new_simple(core->mime,
- "width", G_TYPE_INT, dec_info->width,
- "height", G_TYPE_INT, dec_info->height,
- "framerate", GST_TYPE_FRACTION, 30, 1, NULL);
+ "width", G_TYPE_INT, dec_info->width,
+ "height", G_TYPE_INT, dec_info->height,
+ "framerate", GST_TYPE_FRACTION, 30, 1,
+ "alignment", G_TYPE_STRING, "au",
+ "stream-format", G_TYPE_STRING, "byte-stream", NULL);
LOGD("mime : %s, widht :%d, height : %d", core->mime, dec_info->width, dec_info->height);
- MEDIACODEC_FLEAVE();
+ return MC_ERROR_NONE;
+}
+
+int __mc_vdec_h263_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
+{
+ g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
+
+ mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
+
+ *caps = gst_caps_new_simple(core->mime,
+ "variant", G_TYPE_STRING, "itu", NULL);
+ LOGD("mime : %s, widht :%d, height : %d", core->mime, dec_info->width, dec_info->height);
return MC_ERROR_NONE;
}
-int __mc_aenc_caps(mc_gst_core_t *core, GstCaps **caps)
+int __mc_vdec_mpeg4_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
{
- g_return_val_if_fail (core != NULL, MC_PARAM_ERROR);
+ g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
- mc_encoder_info_t *enc_info = (mc_encoder_info_t*)core->codec_info;
+ mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
- MEDIACODEC_FENTER();
+ *caps = gst_caps_new_simple(core->mime,
+ "mpegversion", G_TYPE_INT, 4,
+ "systemstream", G_TYPE_BOOLEAN, false, NULL);
+
+ LOGD("mime : %s, widht :%d, height : %d", core->mime, dec_info->width, dec_info->height);
+ return MC_ERROR_NONE;
+}
+
+int __mc_vdec_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
+{
+ g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
+
+ mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
*caps = gst_caps_new_simple(core->mime,
- "signed", G_TYPE_BOOLEAN, TRUE,
- "width", G_TYPE_INT, enc_info->bit,
- "depth", G_TYPE_INT, enc_info->bit,
- "endianness", G_TYPE_INT, G_BYTE_ORDER,
- "channels", G_TYPE_INT, enc_info->channel,
- "rate", G_TYPE_INT, enc_info->samplerate, NULL);
+ "alignment", G_TYPE_STRING, "au",
+ "stream-format", G_TYPE_STRING, "byte-stream", NULL);
- MEDIACODEC_FLEAVE();
+ LOGD("mime : %s, widht :%d, height : %d", core->mime, dec_info->width, dec_info->height);
+ return MC_ERROR_NONE;
+}
+
+int __mc_vdec_h264_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
+{
+ g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
+
+ mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
+ *caps = gst_caps_new_simple(core->mime,
+ "alignment", G_TYPE_STRING, "au",
+ "stream-format", G_TYPE_STRING, "byte-stream", NULL);
+
+ LOGD("mime : %s, widht :%d, height : %d", core->mime, dec_info->width, dec_info->height);
return MC_ERROR_NONE;
}
-int __mc_adec_caps(mc_gst_core_t *core, GstCaps **caps)
+int __mc_aenc_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
{
- g_return_val_if_fail (core != NULL, MC_PARAM_ERROR);
+ g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
- mc_decoder_info_t *dec_info = (mc_decoder_info_t*)core->codec_info;
+ mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info;
- MEDIACODEC_FENTER();
+ *caps = gst_caps_new_simple(core->mime,
+ "rate", G_TYPE_INT, enc_info->samplerate,
+ "channels", G_TYPE_INT, enc_info->channel,
+ "format", G_TYPE_STRING, "F32LE",
+ "layout", G_TYPE_STRING, "interleaved", NULL);
+
+/*
++----GstAudioEncoder
+ +----avenc_aac
+
+Element Properties:
+ compliance : Adherence of the encoder to the specifications
+ flags: readable, writable
+ Enum "GstFFMpegCompliance" Default: 0, "normal"
+ (2): verystrict - Strictly conform to older spec
+ (1): strict - Strictly conform to current spec
+ (0): normal - Normal behavior
+ (-1): unofficial - Allow unofficial extensions
+ (-2): experimental - Allow nonstandardized experimental things
+*/
+ g_object_set(GST_OBJECT(core->codec), "compliance", -2, NULL);
+
+ LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, enc_info->samplerate, enc_info->channel);
+
+ return MC_ERROR_NONE;
+}
+
+int __mc_aenc_aac_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
+{
+ g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
+
+ mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info;
*caps = gst_caps_new_simple(core->mime,
- "mpegversion", G_TYPE_INT, 4,
- "channels", G_TYPE_INT, dec_info->channel,
- "rate", G_TYPE_INT, dec_info->samplerate,
- NULL);
+ "rate", G_TYPE_INT, enc_info->samplerate,
+ "channels", G_TYPE_INT, enc_info->channel,
+ "format", G_TYPE_STRING, "F32LE",
+ "layout", G_TYPE_STRING, "interleaved", NULL);
- MEDIACODEC_FLEAVE();
+ g_object_set(GST_OBJECT(core->codec), "compliance", -2, NULL);
+
+ LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, enc_info->samplerate, enc_info->channel);
return MC_ERROR_NONE;
}
-int _mc_output_media_packet_new(mc_gst_core_t *core, bool video, bool encoder, media_format_mimetype_e out_mime)
+int __mc_aenc_amrnb_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
{
- MEDIACODEC_FENTER();
+ g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
- if(media_format_create(&core->output_fmt) != MEDIA_FORMAT_ERROR_NONE)
- {
+ mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info;
+
+ *caps = gst_caps_new_simple(core->mime,
+ "rate", G_TYPE_INT, enc_info->samplerate,
+ "channels", G_TYPE_INT, enc_info->channel,
+ "format", G_TYPE_STRING, "S16LE",
+ "layout", G_TYPE_STRING, "interleaved",
+ NULL);
+
+ LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, enc_info->samplerate, enc_info->channel);
+
+ return MC_ERROR_NONE;
+}
+
+int __mc_adec_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
+{
+ int ret = MC_ERROR_NONE;
+ g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
+
+ mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
+
+ LOGD("CAPS for codec_id (MEDIACODEC_AAC_LC - normal ADTS)");
+ *caps = gst_caps_new_simple(core->mime,
+ "framed", G_TYPE_BOOLEAN, TRUE,
+ "mpegversion", G_TYPE_INT, 4,
+ "stream-format", G_TYPE_STRING, "adts",
+ "rate", G_TYPE_INT, dec_info->samplerate,
+ "channels", G_TYPE_INT, dec_info->channel,
+ NULL);
+
+ if (codec_config && (!core->encoder)) {
+ guint codecdata_size = 16; /*AAC_CODECDATA_SIZE = 16 (in testsuit)*/
+ ret = __mc_set_caps_codecdata(core, caps, buff, codecdata_size);
+ if (ret != MC_ERROR_NONE) {
+ LOGW("__mc_set_caps_codecdata failed");
+ return ret;
+ }
+ }
+
+ LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, dec_info->samplerate, dec_info->channel);
+
+ return ret;
+}
+
+int __mc_adec_aac_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
+{
+ int ret = MC_ERROR_NONE;
+ g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
+
+ mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
+
+ LOGD("CAPS for codec_id (MEDIACODEC_AAC_LC - normal ADTS)");
+ *caps = gst_caps_new_simple(core->mime,
+ "framed", G_TYPE_BOOLEAN, TRUE,
+ "mpegversion", G_TYPE_INT, 4,
+ "stream-format", G_TYPE_STRING, "adts",
+ "rate", G_TYPE_INT, dec_info->samplerate,
+ "channels", G_TYPE_INT, dec_info->channel,
+ NULL);
+
+ if (codec_config && (!core->encoder)) {
+ guint codecdata_size = 16; /*AAC_CODECDATA_SIZE = 16 (in testsuit)*/
+ ret = __mc_set_caps_codecdata(core, caps, buff, codecdata_size);
+ if (ret != MC_ERROR_NONE) {
+ LOGW("__mc_set_caps_codecdata failed");
+ return ret;
+ }
+ }
+
+ LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, dec_info->samplerate, dec_info->channel);
+
+ return ret;
+}
+
+int __mc_adec_aacv12_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *buff, bool codec_config)
+{
+ int ret = MC_ERROR_NONE;
+ g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
+
+ mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
+
+ LOGD("CAPS for codec_id (MEDIACODEC_AAC_HE and _PS - MP4/M4A case)");
+ *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",
+ "channels", G_TYPE_INT, dec_info->channel,
+ "rate", G_TYPE_INT, dec_info->samplerate,
+ NULL);
+
+ if (codec_config && (!core->encoder)) {
+ guint codecdata_size = 16; /*AAC_CODECDATA_SIZE = 16 (in testsuit)*/
+ ret = __mc_set_caps_codecdata(core, caps, buff, codecdata_size);
+ if (ret != MC_ERROR_NONE) {
+ LOGW("__mc_set_caps_codecdata failed");
+ return ret;
+ }
+ }
+
+ LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, dec_info->samplerate, dec_info->channel);
+
+ return ret;
+}
+
+int __mc_adec_mp3_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *buff, bool codec_config)
+{
+ g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
+
+ mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
+
+ *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 */
+ "rate", G_TYPE_INT, dec_info->samplerate,
+ "channels", G_TYPE_INT, dec_info->channel,
+ NULL);
+
+ LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, dec_info->samplerate, dec_info->channel);
+
+ return MC_ERROR_NONE;
+}
+
+int __mc_adec_amrnb_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *buff, bool codec_config)
+{
+ g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
+
+ mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
+
+ *caps = gst_caps_new_simple(core->mime,
+ "rate", G_TYPE_INT, 8000,
+ "channels", G_TYPE_INT, dec_info->channel, /* FIXME - by 1 */
+ NULL);
+
+ LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, dec_info->samplerate, dec_info->channel);
+
+ return MC_ERROR_NONE;
+}
+
+int __mc_adec_amrwb_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *buff, bool codec_config)
+{
+ g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
+
+ mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
+
+ *caps = gst_caps_new_simple(core->mime,
+ "rate", G_TYPE_INT, 16000,
+ "channels", G_TYPE_INT, dec_info->channel, /* FIXME - by 1 */
+ NULL);
+
+ LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, dec_info->samplerate, dec_info->channel);
+
+ return MC_ERROR_NONE;
+}
+
+int __mc_adec_vorbis_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *buff, bool codec_config)
+{
+ g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
+
+ mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
+ int ret = MC_ERROR_NONE;
+
+ *caps = gst_caps_new_simple(core->mime,
+ "channels", G_TYPE_INT, dec_info->channel,
+ "rate", G_TYPE_INT, dec_info->samplerate,
+ /* FIXME - Insert 'Stream Header' */
+ NULL);
+
+ LOGD(" ----- VORBIS Need Additional Caps -----------");
+ /*
+ * Need to extract from each Stream header ... or
+ * Need to get Demuxer's Caps from each Stream heade
+ */
+ if (codec_config && (!core->encoder)) {
+ guint streamheader_size = 4096; /* VORBIS_CODECDATA_SIZE = 4096 */
+ ret = __mc_set_caps_streamheader(core, caps, buff, streamheader_size);
+ if (ret != MC_ERROR_NONE) {
+ LOGW("__mc_set_caps_streamheader failed");
+ return ret;
+ }
+ }
+
+ LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, dec_info->samplerate, dec_info->channel);
+
+ return ret;
+}
+
+int __mc_adec_flac_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *buff, bool codec_config)
+{
+ g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
+
+ mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
+ int ret = MC_ERROR_NONE;
+
+ *caps = gst_caps_new_simple(core->mime,
+ "channels", G_TYPE_INT, dec_info->channel,
+ "rate", G_TYPE_INT, dec_info->samplerate,
+ "framed", G_TYPE_BOOLEAN, TRUE,
+ /* FIXME - Insert More Info */
+ NULL);
+
+ LOGD(" ----- FLAC Need Additional Caps -----------");
+ /*
+ * Need to extract from each Stream header ... or
+ * Need to get Demuxer's Caps from each Stream heade
+ */
+ if (codec_config && (!core->encoder)) {
+ guint streamheader_size = 4096; /* FLAC_CODECDATA_SIZE = 4096 */
+ ret = __mc_set_caps_streamheader(core, caps, buff, streamheader_size);
+ if (ret != MC_ERROR_NONE) {
+ LOGW("__mc_set_caps_streamheader failed");
+ return ret;
+ }
+ }
+
+ LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, dec_info->samplerate, dec_info->channel);
+
+ return ret;
+}
+
+int __mc_adec_wma_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *buff, bool codec_config)
+{
+ int ret = MC_ERROR_NONE;
+ g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
+
+ mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
+
+ /*
+ * 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_WMAPRO) {
+ format_tag = 355; /* 0x163 */
+ wma_version = 3;
+ } else {
+ LOGE("Not support WMA format");
+ }
+
+ *caps = gst_caps_new_simple(core->mime,
+ "rate", G_TYPE_INT, dec_info->samplerate,
+ "channels", G_TYPE_INT, dec_info->channel,
+ "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);
+
+ if (codec_config && (!core->encoder)) {
+ guint codecdata_size = 64; /* WMA_CODECDATA_SIZE = 64 */
+ ret = __mc_set_caps_codecdata(core, caps, buff, codecdata_size);
+ if (ret != MC_ERROR_NONE) {
+ LOGW("__mc_set_caps_codecdata failed");
+ return ret;
+ }
+ }
+
+ LOGD("mime : %s, samplerate :%d, channel : %d", core->mime, dec_info->samplerate, dec_info->channel);
+
+ return ret;
+}
+
+/**
+ * _gst_caps_set_buffer_array:
+ * @caps: a #GstCaps
+ * @field: field in caps to set
+ * @buf: header buffers
+ *
+ * Adds given buffers to an array of buffers set as the given @field
+ * on the given @caps. List of buffer arguments must be NULL-terminated.
+ *
+ * Returns: input caps with a streamheader field added, or NULL if some error
+ */
+static GstCaps *__mc_gst_caps_set_buffer_array(GstCaps * caps, const gchar * field, GstBuffer * buf, ...)
+{
+ GstStructure *structure = NULL;
+ va_list va;
+ GValue array = { 0 };
+ GValue value = { 0 };
+
+ g_return_val_if_fail(caps != NULL, NULL);
+ g_return_val_if_fail(gst_caps_is_fixed(caps), NULL);
+ g_return_val_if_fail(field != NULL, NULL);
+
+ caps = gst_caps_make_writable(caps);
+ structure = gst_caps_get_structure(caps, 0);
+
+ g_value_init(&array, GST_TYPE_ARRAY);
+
+ va_start(va, buf);
+ /* put buffers in a fixed list */
+ while (buf) {
+ g_value_init(&value, GST_TYPE_BUFFER);
+ gst_value_set_buffer(&value, buf);
+ gst_value_array_append_value(&array, &value);
+ g_value_unset(&value);
+
+ buf = va_arg(va, GstBuffer *);
+ }
+ va_end(va);
+
+ gst_structure_take_value(structure, field, &array);
+
+ return caps;
+}
+
+
+int __mc_set_caps_streamheader(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer*buff, guint streamheader_size)
+{
+ int ret = MEDIA_PACKET_ERROR_NONE;
+ void *buf_data = NULL;
+ uint64_t buf_size = 0;
+ GstBuffer *header1, *header2, *header3;
+ guint hsize1, hsize2, hsize3;
+ GstBuffer *tmp_header;
+ guint8 *tmp_buf = NULL;
+ GstMapInfo map;
+
+ ret = media_packet_get_buffer_size(buff->pkt, &buf_size);
+ if (ret != MEDIA_PACKET_ERROR_NONE) {
+ LOGW("buffer size get fail");
+ return ret;
+ }
+
+ ret = media_packet_get_buffer_data_ptr(buff->pkt, &buf_data);
+ if (ret != MEDIA_PACKET_ERROR_NONE) {
+ LOGW("buffer size get fail");
+ return ret;
+ }
+
+ LOGD("Set caps for streamheader in mime : %s and codec_id (0x%x)", core->mime, core->codec_id);
+
+ if (core->codec_id == MEDIACODEC_VORBIS) {
+ /*
+ * hsize1 : Identification Header (packet type 1) - fixed 30 byte
+ * hsize2 : Comment Header (packet type 3) - variable byte (need calculate)
+ * hsize3 : Setup Header (packet type 5) - variable byte (Used remained bytes)
+ */
+
+ /* First of all, Need to fins and calculate size of hsize2 */
+ tmp_header = gst_buffer_new_and_alloc(streamheader_size);
+ gst_buffer_fill(tmp_header, 0, buf_data, streamheader_size);
+ gst_buffer_map(tmp_header, &map, GST_MAP_READ);
+ tmp_buf = map.data;
+ tmp_buf += (30 + 7); /* hsize1 + '0x03' + 'vorbis'*/
+ hsize2 = (7 + 4);
+ hsize2 += GST_READ_UINT32_LE(tmp_buf);
+ hsize2 += (4 + 1);
+ LOGD("Find streamheader hsize2(%d)", hsize2);
+ gst_buffer_unmap(tmp_header, &map);
+ gst_buffer_unref(tmp_header);
+
+ /* hsize1 : Identification Header (packet type 1) - fixed 30 byte */
+ hsize1 = 30;
+ header1 = gst_buffer_new_and_alloc(hsize1);
+ gst_buffer_fill(header1, 0, buf_data, hsize1);
+ gst_buffer_map(header1, &map, GST_MAP_READ);
+ tmp_buf = map.data;
+ /* '0x01' + 'vorbis' */
+ if (*tmp_buf != 0x01) {
+ LOGE("[ERROR] Invalid Caps of Stream header1");
+ gst_buffer_unmap(header1, &map);
+ return MEDIA_PACKET_ERROR_INVALID_PARAMETER;
+ }
+ gst_buffer_unmap(header1, &map);
+
+ /* hsize2 : Comment Header (packet type 3) - variable byte */
+ header2 = gst_buffer_new_and_alloc(hsize2);
+ gst_buffer_fill(header2, 0, (buf_data + (hsize1)), hsize2);
+ gst_buffer_map(header2, &map, GST_MAP_READ);
+ tmp_buf = map.data;
+ /* '0x03' + 'vorbis' */
+ if (*tmp_buf != 0x03) {
+ LOGE("[ERROR] Invalid Caps of Stream header2");
+ gst_buffer_unmap(header2, &map);
+ return MEDIA_PACKET_ERROR_INVALID_PARAMETER;
+ }
+ gst_buffer_unmap(header2, &map);
+
+ /* hsize3 : Setup Header (packet type 5) - variable byte */
+ hsize3 = streamheader_size - (hsize1 + hsize2);
+ header3 = gst_buffer_new_and_alloc(hsize3);
+ gst_buffer_fill(header3, 0, (buf_data + (hsize1 + hsize2)), hsize3);
+ gst_buffer_map(header3, &map, GST_MAP_READ);
+ tmp_buf = map.data;
+ /* '0x05' + 'vorbis' */
+ if (*tmp_buf != 0x05) {
+ LOGE("[ERROR] Invalid Caps of Stream header3");
+ gst_buffer_unmap(header3, &map);
+ return MEDIA_PACKET_ERROR_INVALID_PARAMETER;
+ }
+ gst_buffer_unmap(header3, &map);
+
+ LOGD("[vorbis] streamheader hsize1 (%d) + hsize2 (%d) + hsize3 (%d) = Total (%d)",
+ hsize1, hsize2, hsize3, (hsize1 + hsize2 + hsize3));
+
+ __mc_gst_caps_set_buffer_array(*caps, "streamheader", header1, header2, header3, NULL);
+
+ gst_buffer_unref(header1);
+ gst_buffer_unref(header2);
+ gst_buffer_unref(header3);
+ } else if (core->codec_id == MEDIACODEC_FLAC) {
+ /*
+ * hsize1 : Stream Info (type 0) - fixed 51 byte
+ * hsize2 : Stream Comment (type 4) - variable byte (need calculate)
+ */
+
+ /* First of all, Need to fins and calculate size of hsize2 */
+ tmp_header = gst_buffer_new_and_alloc(streamheader_size);
+ gst_buffer_fill(tmp_header, 0, buf_data, streamheader_size);
+ gst_buffer_map(tmp_header, &map, GST_MAP_READ);
+ tmp_buf = map.data;
+ hsize2 = 4 + ((tmp_buf[52] << 16) | (tmp_buf[53] << 8) | (tmp_buf[54]));
+ LOGD("Find streamheader hsize2(%d)", hsize2);
+ gst_buffer_unmap(tmp_header, &map);
+ gst_buffer_unref(tmp_header);
+
+ /* hsize1 : Stream Info (type 0) - fixed 51 byte */
+ hsize1 = 51;
+ header1 = gst_buffer_new_and_alloc(hsize1);
+ gst_buffer_fill(header1, 0, buf_data, hsize1);
+ gst_buffer_map(header1, &map, GST_MAP_READ);
+ tmp_buf = map.data;
+ /* '0x7f' + 'FLAC' */
+ if (*tmp_buf != 0x07f) {
+ LOGE("[ERROR] Invalid Caps of Stream header1 (Info)");
+ gst_buffer_unmap(header1, &map);
+ gst_buffer_unref(header1);
+ return MEDIA_PACKET_ERROR_INVALID_PARAMETER;
+ }
+ gst_buffer_unmap(header1, &map);
+
+ /* hsize2 : Stream Comment (type 4) - variable byte (need calculate) */
+ header2 = gst_buffer_new_and_alloc(hsize2);
+ gst_buffer_fill(header2, 0, (buf_data + (hsize1)), hsize2);
+ gst_buffer_map(header2, &map, GST_MAP_READ);
+ tmp_buf = map.data;
+ /* '0x84' */
+ if (*tmp_buf != 0x84) {
+ LOGE("[ERROR] Invalid Caps of Stream header2 (Comment)");
+ gst_buffer_unmap(header2, &map);
+ gst_buffer_unref(header1);
+ gst_buffer_unref(header2);
+ return MEDIA_PACKET_ERROR_INVALID_PARAMETER;
+ }
+ gst_buffer_unmap(header2, &map);
+
+ LOGD("[flac] streamheader hsize1 (%d) + hsize2 (%d) = Total (%d)", hsize1, hsize2, (hsize1 + hsize2));
+ __mc_gst_caps_set_buffer_array(*caps, "streamheader", header1, header2, NULL);
+ gst_buffer_unref(header1);
+ gst_buffer_unref(header2);
+ } else {
+ LOGE("Not support case of Stream header Caps");
+ }
+
+ /* Update gstbuffer's data ptr and size for using previous streamheader.*/
+ LOGD("BEFORE : buff->buffer of size %" G_GSIZE_FORMAT "", gst_buffer_get_size(buff->buffer));
+ gst_buffer_remove_memory_range(buff->buffer, streamheader_size, -1);
+ gst_buffer_set_size(buff->buffer, buf_size - streamheader_size);
+ LOGD("AFTER : buff->buffer of size %" G_GSIZE_FORMAT "", gst_buffer_get_size(buff->buffer));
+
+ return ret;
+}
+
+
+
+int __mc_set_caps_codecdata(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer *buff, guint codecdata_size)
+{
+ int ret = MEDIA_PACKET_ERROR_NONE;
+ void *buf_data = NULL;
+ uint64_t buf_size = 0;
+ GstBuffer *codecdata_buffer;
+
+ ret = media_packet_get_buffer_size(buff->pkt, &buf_size);
+ if (ret != MEDIA_PACKET_ERROR_NONE) {
+ LOGW("buffer size get fail");
+ return ret;
+ }
+
+ ret = media_packet_get_buffer_data_ptr(buff->pkt, &buf_data);
+ if (ret != MEDIA_PACKET_ERROR_NONE) {
+ LOGW("buffer size get fail");
+ return ret;
+ }
+
+ LOGD("Set caps for codec_data in mime : %s and codec_id (0x%x)", core->mime, core->codec_id);
+
+ /* Add the codec_data attribute to caps, if we have it */
+ codecdata_buffer = gst_buffer_new();
+ gst_buffer_copy_into(codecdata_buffer, buff->buffer, GST_BUFFER_COPY_MEMORY,0, codecdata_size);
+ gst_buffer_ref(codecdata_buffer);
+ LOGD("setting codec_data from (packet) buf_data used codecdata_size (%d)", codecdata_size);
+
+ gst_caps_set_simple(*caps, "codec_data", GST_TYPE_BUFFER, codecdata_buffer, NULL);
+ gst_buffer_unref(codecdata_buffer);
+
+ /* Update gstbuffer's data ptr and size for using previous codec_data..*/
+ LOGD("BEFORE : buff->buffer of size %" G_GSIZE_FORMAT "", gst_buffer_get_size(buff->buffer));
+
+ gst_buffer_replace_memory(buff->buffer, 0,
+ gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, buf_data + codecdata_size , buf_size - codecdata_size, 0,
+ buf_size - codecdata_size, buff, (GDestroyNotify)gst_mediacodec_buffer_finalize));
+
+ LOGD("AFTER : buff->buffer of size %" G_GSIZE_FORMAT "", gst_buffer_get_size(buff->buffer));
+
+ return ret;
+}
+
+
+int _mc_output_media_packet_new(mc_gst_core_t *core, bool video, bool encoder, media_format_mimetype_e out_mime)
+{
+ if (media_format_create(&core->output_fmt) != MEDIA_FORMAT_ERROR_NONE) {
LOGE("media format create failed");
return MC_ERROR;
}
- if(encoder)
- {
+ if (encoder) {
mc_encoder_info_t *info;
- info = (mc_encoder_info_t*)core->codec_info;
+ info = (mc_encoder_info_t *)core->codec_info;
- if (video)
- {
+ 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);
- }
- else
- {
+ } 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_avg_bps(core->output_fmt, info->bitrate);
}
- }
- else
- {
+ } else {
mc_decoder_info_t *info;
- info = (mc_decoder_info_t*)core->codec_info;
+ info = (mc_decoder_info_t *)core->codec_info;
- if (video)
- {
+ 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);
- }
- else
- {
+ } 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);
}
}
-
- MEDIACODEC_FLEAVE();
-
return MC_ERROR_NONE;
}
@@ -510,31 +1379,27 @@ mc_gst_core_t *mc_gst_core_new()
core->available_queue = g_new0(mc_aqueue_t, 1);
core->available_queue->input = mc_async_queue_new();
- //core->eos_mutex = g_mutex_new();
g_mutex_init(&core->eos_mutex);
- //core->eos_wait_mutex = g_mutex_new();
- g_mutex_init(&core->eos_wait_mutex);
- //core->drain_mutex = g_mutex_new();
- g_mutex_init(&core->drain_mutex);
- //core->eos_cond = g_cond_new();
g_cond_init(&core->eos_cond);
- //core->eos_waiting_cond = g_cond_new();
- g_cond_init(&core->eos_waiting_cond);
- //core->prepare_lock = g_mutex_new();
g_mutex_init(&core->prepare_lock);
- //core->push_sem = mc_sem_new();
- //core->pop_sem = mc_sem_new();
+ g_mutex_init(&core->drain_lock);
core->need_feed = false;
core->eos = false;
- core->eos_waiting = false;
+ core->need_codec_data = false;
+ core->need_sync_flag = false;
+ core->unprepare_flag = false;
core->prepare_count = 0;
- //g_atomic_int_set(&core->num_live_buffers, 0);
+ core->queued_count = 0;
+ core->dequeued_count = 0;
g_atomic_int_set(&core->available_queue->running, 1);
- //core->available_queue->thread = g_thread_create(feed_task, core, TRUE, NULL);
core->available_queue->thread = g_thread_new("feed thread", &feed_task, core);
+ core->bufmgr = NULL;
+ core->drm_fd = -1;
+ LOGD("gst_core(%p) is created", core);
+
MEDIACODEC_FLEAVE();
return core;
@@ -542,46 +1407,31 @@ mc_gst_core_t *mc_gst_core_new()
void mc_gst_core_free(mc_gst_core_t *core)
{
- mc_aqueue_t *async_queue;
-
MEDIACODEC_FENTER();
+ mc_aqueue_t *async_queue;
+
async_queue = core->available_queue;
- _mc_gst_set_flush_input(core);
mc_async_queue_disable(async_queue->input);
- //mc_async_queue_flush(async_queue->input);
g_atomic_int_set(&async_queue->running, 0);
g_thread_join(async_queue->thread);
- LOGD("@%p g_thread_join", core);
- //mc_sem_free(core->push_sem);
- //mc_sem_free(core->pop_sem);
- //g_mutex_free(core->drain_mutex);
- g_mutex_clear(&core->drain_mutex);
- //g_mutex_free(core->eos_mutex);
g_mutex_clear(&core->eos_mutex);
- //g_mutex_free(core->eos_wait_mutex);
- g_mutex_clear(&core->eos_wait_mutex);
- //g_mutex_free(core->prepare_lock);
g_mutex_clear(&core->prepare_lock);
- //g_cond_free(core->eos_cond);
+ g_mutex_clear(&core->drain_lock);
g_cond_clear(&core->eos_cond);
- //g_cond_free(core->eos_waiting_cond);
- g_cond_clear(&core->eos_waiting_cond);
-
mc_async_queue_free(async_queue->input);
- //mc_async_queue_free(async_queue->output);
- //g_queue_free(core->output_queue);
+ g_free(async_queue);
- if(core->ports[1] != NULL)
- {
+ if (core->ports[1] != NULL) {
mc_gst_port_free(core->ports[1]);
core->ports[1] = NULL;
}
+ LOGD("gst_core(%p) is destroyed", core);
g_free(core);
MEDIACODEC_FLEAVE();
@@ -592,10 +1442,10 @@ void mc_gst_core_free(mc_gst_core_t *core)
*/
mc_gst_port_t *mc_gst_port_new(mc_gst_core_t *core)
{
- mc_gst_port_t *port;
-
MEDIACODEC_FENTER();
+ mc_gst_port_t *port;
+
port = g_new0(mc_gst_port_t, 1);
port->core = core;
port->num_buffers = -1;
@@ -603,14 +1453,13 @@ mc_gst_port_t *mc_gst_port_new(mc_gst_core_t *core)
port->is_allocated = 0;
port->buffers = NULL;
- //port->mutex = g_mutex_new();
g_mutex_init(&port->mutex);
- //port->buffer_cond = g_cond_new();
g_cond_init(&port->buffer_cond);
port->queue = g_queue_new();
- MEDIACODEC_FLEAVE();
+ LOGD("gst_port(%p) is created", port);
+ MEDIACODEC_FLEAVE();
return port;
}
@@ -622,7 +1471,7 @@ void mc_gst_port_free(mc_gst_port_t *port)
g_cond_clear(&port->buffer_cond);
g_queue_free(port->queue);
- //destroy buffers
+ LOGD("gst_port(%p) is freed", port);
g_free(port);
MEDIACODEC_FLEAVE();
@@ -630,323 +1479,246 @@ void mc_gst_port_free(mc_gst_port_t *port)
return;
}
-static void _mc_gst_update_caps(mc_gst_core_t *core, media_packet_h pkt, GstCaps **caps)
+static void _mc_gst_update_caps(mc_gst_core_t *core, media_packet_h pkt, GstCaps **caps, GstMCBuffer* buff, bool codec_config)
{
- //TODO remove is_hw param
+ /*TODO remove is_hw param*/
core->format = __mc_get_gst_input_format(pkt, core->is_hw);
- __mc_create_caps(core, caps);
-}
-
-static gboolean event_probe_cb(GstPad *pad, GstEvent *event, gpointer user_data)
-{
- mc_gst_core_t *core = (mc_gst_core_t*)user_data;
- const GstStructure *s;
- gboolean codec_config = false;
- //uint64_t wait_until = g_get_monotonic_time() + G_TIME_SPAN_SECOND / 2;
-
- switch(GST_EVENT_TYPE (event))
- {
- case GST_EVENT_CUSTOM_DOWNSTREAM:
- {
- s = gst_event_get_structure (event);
- if(gst_structure_has_name (s, GST_MC_EVENT_CODEC_DATA))
- {
- gst_structure_get_boolean (s, "codec_config", &codec_config);
- core->codec_config = codec_config;
- LOGD("codec_config : %d", codec_config);
- }
- break;
- }
-#if 0
- case GST_EVENT_EOS:
- {
- g_mutex_lock(core->eos_mutex);
-
- core->eos = true;
- g_cond_signal(core->eos_cond);
- LOGD("send eos signal");
-
- g_mutex_unlock(core->eos_mutex);
- LOGD ("End of stream\n");
- if (core->user_cb[_MEDIACODEC_EVENT_TYPE_EOS])
- {
- ((mc_eos_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_EOS])(core->user_data[_MEDIACODEC_EVENT_TYPE_EOS]);
- }
- g_mutex_lock(core->eos_mutex);
-/*
- while(!core->eos)
- {
- LOGD("waiting for eos signal...");
- //g_cond_wait(core->eos_cond, core->eos_mutex);
- if(!g_cond_wait_until(core->eos_cond, core->eos_mutex, wait_until))
- {
- core->eos = true;
- LOGD("time out");
-
- if (core->user_cb[_MEDIACODEC_EVENT_TYPE_EOS])
- {
- ((mc_eos_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_EOS])(core->user_data[_MEDIACODEC_EVENT_TYPE_EOS]);
- }
-
- }
- else
- LOGD("recevied signal");
- }
+ GstPad *pad = NULL;
+ GstCaps *template_caps;
- //_mc_gst_set_flush_input(core);
- core->eos = false;
- LOGD("eos flag set to false");
+ pad = gst_element_get_static_pad(core->codec, "src");
+ template_caps = gst_pad_get_pad_template_caps(pad);
- g_mutex_unlock(core->eos_mutex);
-*/
- break;
+ __mc_create_caps(core, caps, buff, codec_config);
+ g_object_set(core->appsrc, "caps", *caps, NULL);
- }
-#endif
- default:
- break;
+ if (gst_caps_is_subset(*caps, template_caps)) {
+ LOGD("new caps is subset of template caps");
}
- return true;
+ gst_object_unref(pad);
}
static gpointer feed_task(gpointer data)
{
- mc_gst_core_t *core = (mc_gst_core_t*)data;
+ mc_gst_core_t *core = (mc_gst_core_t *)data;
int ret = MC_ERROR_NONE;
bool codec_config = FALSE;
bool eos = FALSE;
media_packet_h in_buf = NULL;
- mc_gst_buffer_t* buff = NULL;
+ GstMCBuffer *buff = NULL;
GstCaps *new_caps = NULL;
bool initiative = true;
- //uint64_t wait_until = g_get_monotonic_time() + G_TIME_SPAN_SECOND / 2;
+
MEDIACODEC_FENTER();
- while(g_atomic_int_get(&core->available_queue->running))
- {
+ while (g_atomic_int_get(&core->available_queue->running)) {
LOGD("waiting for next input....");
in_buf = _mc_get_input_buffer(core);
- if(!in_buf)
+ if (!in_buf)
goto LEAVE;
- if(media_packet_is_codec_config(in_buf, &codec_config) != MEDIA_PACKET_ERROR_NONE)
- {
+ if (media_packet_is_codec_config(in_buf, &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(in_buf, &eos) != MEDIA_PACKET_ERROR_NONE) {
LOGE("media_packet_is_end_of_stream failed");
goto ERROR;
}
- if(codec_config)
- initiative = true;
-
- if(eos)
- {
- g_mutex_lock(&core->eos_wait_mutex);
- core->eos_waiting = true;
- g_mutex_unlock(&core->eos_wait_mutex);
+ buff = _mc_gst_media_packet_to_gstbuffer(core, &new_caps, in_buf, codec_config);
+ if (!buff) {
+ LOGW("gstbuffer can't make");
+ goto ERROR;
}
- if(initiative)
- {
- GstStructure *s;
- GstEvent *event;
+ if (codec_config)
+ initiative = true;
+
+ if (initiative) {
GstPad *pad;
- _mc_gst_update_caps(core, in_buf, &new_caps);
- gst_app_src_set_caps(GST_APP_SRC(core->appsrc), new_caps);
+ _mc_gst_update_caps(core, in_buf, &new_caps, buff, codec_config);
pad = gst_element_get_static_pad(core->appsrc, "src");
- s = gst_structure_new (GST_MC_EVENT_CODEC_DATA,
- "codec_config", G_TYPE_BOOLEAN, true, NULL);
- event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s);
- gst_pad_push_event (pad,event);
+ gst_pad_push_event(pad, gst_event_new_stream_start("sejun"));
gst_object_unref(pad);
LOGD("caps updated");
}
- buff = _mc_gst_media_packet_to_gstbuffer(core, &new_caps, in_buf, codec_config);
- if (!buff)
- {
- LOGW("gstbuffer can't make");
- goto ERROR;
- }
- LOGD("gstbuffer refcount %d", GST_MINI_OBJECT_REFCOUNT_VALUE(buff));
-
- g_mutex_lock(&core->drain_mutex);
/* inject buffer */
ret = _mc_gst_gstbuffer_to_appsrc(core, buff);
- if(ret != GST_FLOW_OK)
- {
+ if (ret != GST_FLOW_OK) {
LOGE("Failed to push gst buffer");
- g_mutex_unlock(&core->drain_mutex);
goto ERROR;
}
- LOGD("after refcount %d", GST_MINI_OBJECT_REFCOUNT_VALUE(buff));
initiative = false;
- g_mutex_unlock(&core->drain_mutex);
-#if 1
- if (eos)
- {
+ if (eos) {
LOGD("end of stream");
- //goto EOS;
-
- uint64_t wait_until = g_get_monotonic_time() + G_TIME_SPAN_SECOND / 2;
-
- g_signal_emit_by_name(core->appsrc, "end-of-stream", &ret);
-
- while(!core->eos)
- {
- LOGD("waiting for eos signal...");
- if(!g_cond_wait_until(&core->eos_cond, &core->eos_mutex, wait_until))
- {
- core->eos = true;
- LOGD("time out");
- }
- else
- LOGD("recevied signal");
- }
-
- if (core->user_cb[_MEDIACODEC_EVENT_TYPE_EOS])
- {
- LOGD("eos callback invoked");
- ((mc_eos_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_EOS])(core->user_data[_MEDIACODEC_EVENT_TYPE_EOS]);
- }
-#if 1
- core->eos = false;
- core->eos_waiting = false;
- initiative = true;
- g_cond_signal(&core->eos_waiting_cond);
- LOGD("eos flag set to false");
-#endif
-/*
-
- core->eos = true;
- _mc_gst_set_flush_input(core);
-
-
- g_mutex_lock(core->eos_mutex);
-
- core->eos = false;
+ gst_app_src_end_of_stream(GST_APP_SRC(core->appsrc));
+ _mc_wait_for_eos(core);
initiative = true;
+ }
- g_mutex_unlock(core->eos_mutex);
-
- if (core->user_cb[_MEDIACODEC_EVENT_TYPE_EOS])
- {
- ((mc_eos_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_EOS])(core->user_data[_MEDIACODEC_EVENT_TYPE_EOS]);
- LOGD("send eos callback");
- }
- //g_signal_emit_by_name(core->appsrc, "end-of-stream", &ret);
-*/
- }
-#endif
continue;
ERROR:
-
- g_mutex_lock(&core->drain_mutex);
_mc_gst_set_flush_input(core);
- g_mutex_unlock(&core->drain_mutex);
-
- if (core->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR])
- {
- ((mc_error_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR])(MC_INTERNAL_ERROR, core->user_data[_MEDIACODEC_EVENT_TYPE_ERROR]);
- }
-
- continue;
-/*
-EOS:
-
- g_signal_emit_by_name(core->appsrc, "end-of-stream", &ret);
-
- while(!core->eos)
- {
- LOGD("waiting for eos signal...");
- //g_cond_wait(core->eos_cond, core->eos_mutex);
- if(!g_cond_wait_until(core->eos_cond, core->eos_mutex, wait_until))
- {
- core->eos = true;
- LOGD("time out");
-
- }
- else
- LOGD("recevied signal");
- if (core->user_cb[_MEDIACODEC_EVENT_TYPE_EOS])
- {
- LOGD("eos callback invoked");
- ((mc_eos_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_EOS])(core->user_data[_MEDIACODEC_EVENT_TYPE_EOS]);
- }
+ if (core->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR]) {
+ ((mc_error_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR])
+ (MC_INTERNAL_ERROR, core->user_data[_MEDIACODEC_EVENT_TYPE_ERROR]);
}
- core->eos = false;
- core->eos_waiting = false;
- g_cond_signal(core->eos_waiting_cond);
- initiative = true;
- LOGD("eos flag set to false");
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 : in_buf : %p, codec_config : %d, eos : %d, encoder : %d in feed_task", in_buf, codec_config, eos, core->encoder);*/
continue;
}
- if(new_caps)
- {
+ if (new_caps) {
gst_caps_unref(new_caps);
}
- 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 : in_buf : %p, codec_config : %d, eos : %d, video : %d, encoder : %d in feed_task",
+ in_buf, codec_config, eos, core->video, core->encoder);
LOGD("feed task finished %p v(%d)e(%d)", core, core->video, core->encoder);
+
MEDIACODEC_FLEAVE();
return NULL;
}
+static void __mc_gst_stop_feed(GstElement *pipeline, gpointer data)
+{
+ mc_gst_core_t *core = (mc_gst_core_t *)data;
+
+ LOGI("stop_feed called");
+ if (core->user_cb[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS]) {
+ ((mc_buffer_status_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS])
+ (MEDIACODEC_ENOUGH_DATA, core->user_data[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS]);
+ }
+}
+
+static void __mc_gst_start_feed(GstElement *pipeline, guint size, gpointer data)
+{
+ mc_gst_core_t *core = (mc_gst_core_t *)data;
+
+ LOGI("start_feed called");
+
+ if (core->user_cb[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS]) {
+ ((mc_buffer_status_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS])
+ (MEDIACODEC_NEED_DATA, core->user_data[_MEDIACODEC_EVENT_TYPE_BUFFER_STATUS]);
+ }
+}
+
static int _mc_link_vtable(mc_gst_core_t *core, mediacodec_codec_type_e id, gboolean encoder, gboolean is_hw)
{
- g_return_val_if_fail (core != NULL, MC_PARAM_ERROR);
+ MEDIACODEC_FENTER();
- switch (id)
- {
+ g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
+
+ switch (id) {
case MEDIACODEC_AAC:
{
- LOGD("aac vtable");
- core->vtable = encoder ? aenc_vtable : adec_vtable;
+ /* if set to 'CODEC_CONFIG', then It is also available case of MEDIA_FORMAT_AAC_LC (RAW) */
+ LOGD("aac lc (adts) vtable");
+ core->vtable = encoder ? aenc_aac_vtable : adec_aac_vtable;
+ break;
+ }
+ case MEDIACODEC_AAC_HE:
+ case MEDIACODEC_AAC_HE_PS:
+ {
+ LOGD("aac he v12 vtable");
+ core->vtable = encoder ? aenc_aac_vtable : adec_aacv12_vtable;
+ if (encoder) {
+ LOGD("[MC_NOT_SUPPORTED] he-aac-v12 encoder is not supported yet!!!");
+ return MC_NOT_SUPPORTED;
+ }
break;
}
case MEDIACODEC_MP3:
{
- LOGD("mp3 vtable");
- core->vtable = encoder ? aenc_vtable :mp3dec_vtable;
+ LOGD("mp3 vtable - Only support decoder");
+ core->vtable = encoder ? aenc_vtable : adec_mp3_vtable;
+ if (encoder) {
+ LOGD("[MC_NOT_SUPPORTED] mp3 encoder is not supported yet!!!");
+ return MC_NOT_SUPPORTED;
+ }
+ break;
+ }
+ case MEDIACODEC_AMR_NB:
+ {
+ LOGD("amrnb vtable");
+ core->vtable = encoder ? aenc_amrnb_vtable : adec_amrnb_vtable;
+ break;
+ }
+ case MEDIACODEC_AMR_WB:
+ {
+ LOGD("amrwb vtable - Only support decoder");
+ core->vtable = encoder ? aenc_vtable : adec_amrwb_vtable;
+ if (encoder) {
+ LOGD("[MC_NOT_SUPPORTED] amr-wb encoder is not supported yet!!!");
+ return MC_NOT_SUPPORTED;
+ }
+ break;
+ }
+ case MEDIACODEC_VORBIS:
+ {
+ LOGD("vorbis vtable");
+ core->vtable = encoder ? aenc_vtable : adec_vorbis_vtable;
+ if (encoder) {
+ LOGD("[MC_NOT_SUPPORTED] vorbis encoder is not supported yet!!!");
+ return MC_NOT_SUPPORTED;
+ }
+ break;
+ }
+ case MEDIACODEC_FLAC:
+ {
+ LOGD("flac vtable");
+ core->vtable = encoder ? aenc_vtable : adec_flac_vtable;
+ if (encoder) {
+ LOGD("[MC_NOT_SUPPORTED] flac encoder is not supported yet!!!");
+ return MC_NOT_SUPPORTED;
+ }
+ break;
+ }
+ case MEDIACODEC_WMAV1:
+ case MEDIACODEC_WMAV2:
+ case MEDIACODEC_WMAPRO:
+ case MEDIACODEC_WMALSL:
+ {
+ LOGD("wma(V1 / V2 / LSL / PRO) vtable");
+ core->vtable = encoder ? aenc_vtable : adec_wma_vtable;
+ if (encoder) {
+ LOGD("[MC_NOT_SUPPORTED] wma encoder is not supported yet!!!");
+ return MC_NOT_SUPPORTED;
+ }
break;
}
case MEDIACODEC_H263:
{
LOGD("h263 vtable");
- if(is_hw)
- core->vtable = encoder ? h263enc_vtable : h263dec_vtable;
- else
- core->vtable = encoder ? venc_vtable : vdec_vtable;
+ core->vtable = encoder ? (is_hw ? venc_h263_hw_vtable : venc_h263_sw_vtable) : is_hw ? vdec_h263_hw_vtable : vdec_h263_sw_vtable;
+ break;
+ }
+ case MEDIACODEC_MPEG4:
+ {
+ LOGD("mpeg4 vtable");
+ core->vtable = encoder ? (is_hw ? venc_mpeg4_hw_vtable : venc_mpeg4_sw_vtable) : is_hw ? vdec_mpeg4_hw_vtable : vdec_mpeg4_sw_vtable;
+
break;
}
case MEDIACODEC_H264:
{
LOGD("h264 vtable");
- if(is_hw)
- core->vtable = encoder ? h264enc_vtable : h264dec_vtable;
- else
- core->vtable = encoder ? venc_vtable : vdec_vtable;
+ core->vtable = encoder ? (is_hw ? venc_h264_hw_vtable : venc_vtable) : is_hw ? vdec_h264_hw_vtable : vdec_h264_sw_vtable;
break;
}
default:
@@ -956,14 +1728,16 @@ static int _mc_link_vtable(mc_gst_core_t *core, mediacodec_codec_type_e id, gboo
return MC_ERROR_NONE;
}
-static int _mc_gst_gstbuffer_to_appsrc(mc_gst_core_t *core, mc_gst_buffer_t *buff)
+static int _mc_gst_gstbuffer_to_appsrc(mc_gst_core_t *core, GstMCBuffer *buff)
{
- int ret = MC_ERROR_NONE;
MEDIACODEC_FENTER();
- ret = gst_app_src_push_buffer(GST_APP_SRC(core->appsrc), (GstBuffer*)buff);
+ int ret = MC_ERROR_NONE;
- MEDIACODEC_FLEAVE();
+ LOGD("pushed buffer to appsrc : %p, buffer of size %" G_GSIZE_FORMAT "",
+ buff->buffer, gst_buffer_get_size(buff->buffer));
+
+ ret = gst_app_src_push_buffer(GST_APP_SRC(core->appsrc), buff->buffer);
return ret;
}
@@ -976,8 +1750,11 @@ media_packet_h _mc_get_input_buffer(mc_gst_core_t *core)
mc_ret_e mc_gst_prepare(mc_handle_t *mc_handle)
{
+ MEDIACODEC_FENTER();
+
int ret = MC_ERROR_NONE;
media_format_mimetype_e out_mime;
+ int num_supported_codec=0;
int i = 0;
if (!mc_handle)
@@ -988,64 +1765,62 @@ mc_ret_e mc_gst_prepare(mc_handle_t *mc_handle)
bool encoder;
bool hardware;
gchar *factory_name = NULL;
- static const mc_codec_map_t *codec_map;
- //media_packet_h out_pkt = NULL;
-
- MEDIACODEC_FENTER();
+ mc_codec_map_t *codec_map;
id = mc_handle->codec_id;
video = mc_handle->is_video;
encoder = mc_handle->is_encoder;
hardware = mc_handle->is_hw;
+ codec_map = encoder ? mc_handle->encoder_map : mc_handle->decoder_map;
+ num_supported_codec = encoder ? mc_handle->num_supported_encoder : mc_handle->num_supported_decoder;
- const int codec_list = encoder ? (sizeof(encoder_map) / sizeof(encoder_map[0])) : (sizeof(decoder_map) / sizeof(decoder_map[0]));
-
- codec_map = encoder ? encoder_map : decoder_map;
-
- for(i = 0; i < codec_list; i++)
- {
- if((id == codec_map[i].id) && (hardware == codec_map[i].hardware))
+ for (i = 0; i < num_supported_codec; i++){
+ if ((id == codec_map[i].id) && (hardware == codec_map[i].hardware))
break;
}
- if( i == codec_list )
+ if (i == num_supported_codec)
return MC_NOT_SUPPORTED;
factory_name = codec_map[i].type.factory_name;
out_mime = codec_map[i].type.out_format;
/* gst_core create */
- mc_gst_core_t* new_core = mc_gst_core_new();
+ mc_gst_core_t *new_core = mc_gst_core_new();
new_core->mime = codec_map[i].type.mime;
new_core->is_hw = hardware;
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->codec_info = encoder ? (void *)&mc_handle->info.encoder : (void *)&mc_handle->info.decoder;
+ new_core->out_mime = codec_map[i].type.out_format;
+ new_core->codec_id = id;
+
+ new_core->bufmgr = tbm_bufmgr_init(new_core->drm_fd);
+ if (new_core->bufmgr == NULL) {
+ LOGE("TBM initialization failed");
+ return MC_ERROR;
+ }
LOGD("@%p(%p) core is initializing...v(%d)e(%d)", mc_handle, new_core, new_core->video, new_core->encoder);
- LOGD("factory name : %s, output_fmt : %x, mime %s", factory_name, out_mime, new_core->mime);
+ 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)
- {
+ if ((ret = _mc_output_media_packet_new(new_core, video, encoder, out_mime)) != MC_ERROR_NONE) {
LOGE("Failed to create output pakcet");
return ret;
}
/* link vtable */
- if((ret = _mc_link_vtable(new_core, id, encoder, hardware)) != MC_ERROR_NONE)
- {
+ if ((ret = _mc_link_vtable(new_core, id, encoder, hardware)) != MC_ERROR_NONE) {
LOGE("vtable link failed");
return ret;
}
- for (i = 0; i < _MEDIACODEC_EVENT_TYPE_INTERNAL_FILLBUFFER ; i++)
- {
+ for (i = 0; i < _MEDIACODEC_EVENT_TYPE_INTERNAL_FILLBUFFER ; i++) {
LOGD("copy cb function [%d]", i);
- if (mc_handle->user_cb[i])
- {
+ if (mc_handle->user_cb[i]) {
new_core->user_cb[i] = mc_handle->user_cb[i];
new_core->user_data[i] = mc_handle->user_data[i];
LOGD("user_cb[%d] %p, %p", i, new_core->user_cb[i], mc_handle->user_cb[i]);
@@ -1057,107 +1832,105 @@ 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);
- MEDIACODEC_FLEAVE();
-
+ LOGD("initialized... %d", ret);
return ret;
}
mc_ret_e mc_gst_unprepare(mc_handle_t *mc_handle)
{
+ MEDIACODEC_FENTER();
+
int i;
int ret = MC_ERROR_NONE;
mc_gst_core_t *core = NULL;
- uint64_t wait_until = g_get_monotonic_time() + G_TIME_SPAN_SECOND / 2;
-
- MEDIACODEC_FENTER();
if (!mc_handle)
return MC_PARAM_ERROR;
- core = (mc_gst_core_t*)mc_handle->core;
+ core = (mc_gst_core_t *)mc_handle->core;
- if(core)
- {
- LOGD("@%p(%p) core is uninitializing... v(%d)e(%d)",mc_handle, core, core->video, core->encoder);
+ if (core) {
+ LOGD("@%p(%p) core is uninitializing... v(%d)e(%d)", mc_handle, core, core->video, core->encoder);
- g_mutex_lock(&core->eos_wait_mutex);
-
- if(core->eos_waiting)
- {
- LOGD("waiting for eos is finished");
- if(!g_cond_wait_until(&core->eos_waiting_cond, &core->eos_wait_mutex, wait_until))
- {
- core->eos_waiting = false;
- LOGD("time out");
- }
- else
- {
- LOGD("recevied signal from feed_task");
- }
+ g_mutex_lock(&core->drain_lock);
+ core->unprepare_flag = TRUE;
+ g_mutex_unlock(&core->drain_lock);
+ if (core->eos) {
+ _mc_send_eos_signal(core);
}
- g_mutex_unlock(&core->eos_wait_mutex);
-
-
- LOGD("%p/%p(%d) input flush", mc_handle, core, core->encoder);
- g_mutex_lock(&core->drain_mutex);
_mc_gst_set_flush_input(core);
- g_mutex_unlock(&core->drain_mutex);
-
-
-
- _mc_gst_set_flush_output(core);
-
+ ret = _mc_gst_destroy_pipeline(core);
/* unset callback */
- for (i = 0; i < _MEDIACODEC_EVENT_TYPE_INTERNAL_FILLBUFFER ; i++)
- {
+ for (i = 0; i < _MEDIACODEC_EVENT_TYPE_INTERNAL_FILLBUFFER; i++) {
LOGD("unset cb function [%d]", i);
- if (mc_handle->user_cb[i])
- {
+ if (mc_handle->user_cb[i]) {
core->user_cb[i] = NULL;
core->user_data[i] = NULL;
LOGD("user_cb[%d] %p, %p", i, core->user_cb[i], mc_handle->user_cb[i]);
}
}
- ret = _mc_gst_destroy_pipeline(core);
+ media_format_unref(core->output_fmt);
- if(core != NULL)
- {
+ if (core->bufmgr != NULL) {
+ tbm_bufmgr_deinit(core->bufmgr);
+ core->bufmgr = NULL;
+ }
+
+ if(core->drm_fd != -1) {
+ close(core->drm_fd);
+ LOGD("close drm_fd");
+ }
+
+ if (core != NULL) {
mc_gst_core_free(core);
mc_handle->core = NULL;
}
}
- MEDIACODEC_FLEAVE();
-
return ret;
}
mc_ret_e mc_gst_process_input(mc_handle_t *mc_handle, media_packet_h inbuf, uint64_t timeOutUs)
{
+ MEDIACODEC_FENTER();
+
int ret = MC_ERROR_NONE;
mc_gst_core_t *core = NULL;
+ GTimeVal nowtv;
if (!mc_handle)
return MC_PARAM_ERROR;
- core = (mc_gst_core_t*)mc_handle->core;
- LOGI("@%p v(%d)e(%d)process_input", core, core->video, core->encoder);
+ core = (mc_gst_core_t *)mc_handle->core;
- MEDIACODEC_FENTER();
+ g_get_current_time(&nowtv);
+ g_time_val_add(&nowtv, 500 * 1000); /* usec */
+/*
+ if (!g_cond_timed_wait(&nowtv)) {
+ }
+*/
- g_mutex_lock(&core->eos_mutex);
+ if (core->prepare_count == 0)
+ return MEDIACODEC_ERROR_INVALID_STATE;
- if(!core->eos)
+ g_mutex_lock(&core->drain_lock);
+
+ if (!core->eos || !core->unprepare_flag) {
mc_async_queue_push(core->available_queue->input, inbuf);
- else
+
+ } else {
ret = MC_INVALID_IN_BUF;
+ return ret;
+ }
- g_mutex_unlock(&core->eos_mutex);
+ g_mutex_unlock(&core->drain_lock);
+ LOGI("@v(%d)e(%d)process_input(%d): %p", core->video, core->encoder, core->queued_count, inbuf);
+ core->queued_count++;
MEDIACODEC_FLEAVE();
@@ -1166,6 +1939,8 @@ mc_ret_e mc_gst_process_input(mc_handle_t *mc_handle, media_packet_h inbuf, uint
mc_ret_e mc_gst_get_output(mc_handle_t *mc_handle, media_packet_h *outbuf, uint64_t timeOutUs)
{
+ MEDIACODEC_FENTER();
+
int ret = MC_ERROR_NONE;
mc_gst_core_t *core = NULL;
media_packet_h out_pkt = NULL;
@@ -1173,20 +1948,15 @@ mc_ret_e mc_gst_get_output(mc_handle_t *mc_handle, media_packet_h *outbuf, uint6
if (!mc_handle)
return MC_PARAM_ERROR;
- MEDIACODEC_FENTER();
-
- core = (mc_gst_core_t*)mc_handle->core;
+ core = (mc_gst_core_t *)mc_handle->core;
LOGI("@%p v(%d)e(%d) get_output", core, core->video, core->encoder);
g_mutex_lock(&core->ports[1]->mutex);
- if(!g_queue_is_empty(core->ports[1]->queue))
- {
+ if (!g_queue_is_empty(core->ports[1]->queue)) {
out_pkt = g_queue_pop_head(core->ports[1]->queue);
LOGD("pop from output_queue : %p", out_pkt);
- }
- else
- {
+ } else {
ret = MC_OUTPUT_BUFFER_EMPTY;
LOGD("output_queue is empty");
}
@@ -1201,19 +1971,18 @@ mc_ret_e mc_gst_get_output(mc_handle_t *mc_handle, media_packet_h *outbuf, uint6
mc_ret_e mc_gst_flush_buffers(mc_handle_t *mc_handle)
{
+ MEDIACODEC_FENTER();
+
int ret = MC_ERROR_NONE;
mc_gst_core_t *core = NULL;
if (!mc_handle)
return MC_PARAM_ERROR;
- MEDIACODEC_FENTER();
-
- core = (mc_gst_core_t*)mc_handle->core;
- LOGI("@%p v(%d)e(%d) get_output", core, core->video, core->encoder);
+ core = (mc_gst_core_t *)mc_handle->core;
+ LOGI("@%p v(%d)e(%d) flush_buffers", core, core->video, core->encoder);
- _mc_gst_set_flush_input(core);
- _mc_gst_set_flush_output(core);
+ ret = _mc_gst_flush_buffers(core);
MEDIACODEC_FLEAVE();
@@ -1222,37 +1991,36 @@ mc_ret_e mc_gst_flush_buffers(mc_handle_t *mc_handle)
static gboolean __mc_gst_init_gstreamer()
{
+ MEDIACODEC_FENTER();
+
static gboolean initialized = FALSE;
static const int max_argc = 50;
- gint* argc = NULL;
- gchar** argv = NULL;
- gchar** argv2 = NULL;
+ gint *argc = NULL;
+ gchar **argv = NULL;
+ gchar **argv2 = NULL;
GError *err = NULL;
int i = 0;
int arg_count = 0;
- MEDIACODEC_FENTER();
-
- if ( initialized )
- {
+ if (initialized) {
LOGD("gstreamer already initialized.\n");
return TRUE;
}
/* alloc */
- argc = malloc( sizeof(int) );
- argv = malloc( sizeof(gchar*) * max_argc );
- argv2 = malloc( sizeof(gchar*) * max_argc );
+ argc = malloc(sizeof(int));
+ argv = malloc(sizeof(gchar *) *max_argc);
+ argv2 = malloc(sizeof(gchar *) *max_argc);
- if ( !argc || !argv || !argv2 )
+ if (!argc || !argv || !argv2)
goto ERROR;
- memset( argv, 0, sizeof(gchar*) * max_argc );
- memset( argv2, 0, sizeof(gchar*) * max_argc );
+ memset(argv, 0, sizeof(gchar *) *max_argc);
+ memset(argv2, 0, sizeof(gchar *) *max_argc);
/* add initial */
*argc = 1;
- argv[0] = g_strdup( "media codec" );
+ argv[0] = g_strdup("media codec");
/* we would not do fork for scanning plugins */
argv[*argc] = g_strdup("--gst-disable-registry-fork");
@@ -1270,80 +2038,69 @@ static gboolean __mc_gst_init_gstreamer()
LOGD("argc : %d\n", *argc);
arg_count = *argc;
- for ( i = 0; i < arg_count; i++ )
- {
+ for (i = 0; i < arg_count; i++) {
argv2[i] = argv[i];
LOGD("argv[%d] : %s\n", i, argv2[i]);
}
/* initializing gstreamer */
- if ( ! gst_init_check (argc, &argv, &err))
- {
+ if (!gst_init_check(argc, &argv, &err)) {
LOGE("Could not initialize GStreamer: %s\n", err ? err->message : "unknown error occurred");
- if (err)
- {
- g_error_free (err);
+ if (err) {
+ g_error_free(err);
}
goto ERROR;
}
/* release */
- for ( i = 0; i < arg_count; i++ )
- {
- //debug_log("release - argv[%d] : %s\n", i, argv2[i]);
- MC_FREEIF( argv2[i] );
+ for (i = 0; i < arg_count; i++) {
+ MC_FREEIF(argv2[i]);
}
- MC_FREEIF( argv );
- MC_FREEIF( argv2 );
- MC_FREEIF( argc );
+ MC_FREEIF(argv);
+ MC_FREEIF(argv2);
+ MC_FREEIF(argc);
/* done */
initialized = TRUE;
MEDIACODEC_FLEAVE();
-
return TRUE;
ERROR:
/* release */
- for ( i = 0; i < arg_count; i++ )
- {
+ for (i = 0; i < arg_count; i++) {
LOGD("free[%d] : %s\n", i, argv2[i]);
- MC_FREEIF( argv2[i] );
+ MC_FREEIF(argv2[i]);
}
- MC_FREEIF( argv );
- MC_FREEIF( argv2 );
- MC_FREEIF( argc );
+ MC_FREEIF(argv);
+ MC_FREEIF(argv2);
+ MC_FREEIF(argc);
return FALSE;
}
-mc_ret_e _mc_gst_create_pipeline(mc_gst_core_t* core, gchar *factory_name)
+mc_ret_e _mc_gst_create_pipeline(mc_gst_core_t *core, gchar *factory_name)
{
GstBus *bus = NULL;
- GstPad *pad = NULL;
MEDIACODEC_FENTER();
g_mutex_lock(&core->prepare_lock);
- if(core->prepare_count == 0)
- {
+ if (core->prepare_count == 0) {
- if (!__mc_gst_init_gstreamer())
- {
- LOGE ("gstreamer initialize fail");
+ if (!__mc_gst_init_gstreamer()) {
+ LOGE("gstreamer initialize fail");
g_mutex_unlock(&core->prepare_lock);
return MC_NOT_INITIALIZED;
}
core->codec = gst_element_factory_make(factory_name, NULL);
- if(!core->codec)
- {
- LOGE ("codec element create fail");
+ if (!core->codec) {
+ LOGE("codec element create fail");
goto ERROR;
}
@@ -1353,65 +2110,63 @@ mc_ret_e _mc_gst_create_pipeline(mc_gst_core_t* core, gchar *factory_name)
/* create common elements */
core->pipeline = gst_pipeline_new(NULL);
- if (!core->pipeline)
- {
- LOGE ("pipeline create fail");
+ if (!core->pipeline) {
+ LOGE("pipeline create fail");
goto ERROR;
}
core->appsrc = gst_element_factory_make("appsrc", NULL);
- if (!core->appsrc)
- {
- LOGE ("appsrc can't create");
+ if (!core->appsrc) {
+ LOGE("appsrc can't create");
+ goto ERROR;
+ }
+
+ core->capsfilter = gst_element_factory_make("capsfilter", NULL);
+
+ if (!core->capsfilter) {
+ LOGE("capsfilter can't create");
goto ERROR;
}
core->fakesink = gst_element_factory_make("fakesink", NULL);
- if (!core->fakesink)
- {
- LOGE ("fakesink create fail");
+ if (!core->fakesink) {
+ LOGE("fakesink create fail");
goto ERROR;
}
- g_object_set(core->fakesink, "enable-last-buffer", FALSE, NULL);
+ g_object_set(core->fakesink, "enable-last-sample", FALSE, NULL);
- //__mc_link_elements(core);
- gst_bin_add_many(GST_BIN(core->pipeline), core->appsrc, core->codec, core->fakesink, NULL);
+ /*__mc_link_elements(core);*/
+ gst_bin_add_many(GST_BIN(core->pipeline), core->appsrc, core->capsfilter, core->codec, core->fakesink, NULL);
/* link elements */
- gst_element_link_many(core->appsrc, core->codec, core->fakesink, NULL);
+ if (!(gst_element_link_many(core->appsrc, core->capsfilter, core->codec, core->fakesink, NULL)))
+ {
+ LOGE("gst_element_link_many is failed");
+ goto ERROR;
+ }
/* connect signals, bus watcher */
-
- bus = gst_pipeline_get_bus (GST_PIPELINE (core->pipeline));
- core->bus_whatch_id = gst_bus_add_watch (bus, __mc_gst_bus_callback, core);
+ bus = gst_pipeline_get_bus(GST_PIPELINE(core->pipeline));
+ core->bus_whatch_id = gst_bus_add_watch(bus, __mc_gst_bus_callback, core);
core->thread_default = g_main_context_get_thread_default();
/* set sync handler to get tag synchronously */
- gst_bus_set_sync_handler(bus, __mc_gst_bus_sync_callback, core);
-
- gst_object_unref (GST_OBJECT(bus));
+ gst_bus_set_sync_handler(bus, __mc_gst_bus_sync_callback, core, NULL);
+ gst_object_unref(GST_OBJECT(bus));
- /* add pad probe */
- pad = gst_element_get_static_pad(core->fakesink, "sink");
- core->probe_id = gst_pad_add_event_probe(pad, G_CALLBACK(event_probe_cb), core);
- gst_object_unref (pad);
+ /* app src */
+ g_signal_connect(core->appsrc, "need-data", G_CALLBACK(__mc_gst_start_feed), core);
+ g_signal_connect(core->appsrc, "enough-data", G_CALLBACK(__mc_gst_stop_feed), core);
/* connect handoff */
- g_object_set (GST_OBJECT(core->fakesink), "signal-handoffs", TRUE, NULL);
+ g_object_set(GST_OBJECT(core->fakesink), "signal-handoffs", TRUE, NULL);
core->signal_handoff = g_signal_connect(core->fakesink, "handoff", G_CALLBACK(__mc_gst_buffer_add), core);
- /*
- __mc_create_caps(core, &caps);
- gst_app_src_set_caps(GST_APP_SRC(core->appsrc), caps);
- gst_caps_unref(caps);
- */
/* set state PLAYING */
MEDIACODEC_ELEMENT_SET_STATE(GST_ELEMENT_CAST(core->pipeline), GST_STATE_PLAYING);
- //g_mutex_unlock(core->prepare_lock);
-
}
core->prepare_count++;
g_mutex_unlock(&core->prepare_lock);
@@ -1423,16 +2178,19 @@ mc_ret_e _mc_gst_create_pipeline(mc_gst_core_t* core, gchar *factory_name)
STATE_CHANGE_FAILED:
ERROR:
- if(core->codec)
+ if (core->codec)
gst_object_unref(GST_OBJECT(core->codec));
- if(core->pipeline)
+ if (core->pipeline)
gst_object_unref(GST_OBJECT(core->pipeline));
- if(core->appsrc)
+ if (core->appsrc)
gst_object_unref(GST_OBJECT(core->appsrc));
- if(core->fakesink)
+ if (core->capsfilter)
+ gst_object_unref(GST_OBJECT(core->capsfilter));
+
+ if (core->fakesink)
gst_object_unref(GST_OBJECT(core->fakesink));
g_mutex_unlock(&core->prepare_lock);
@@ -1443,40 +2201,29 @@ ERROR:
mc_ret_e _mc_gst_destroy_pipeline(mc_gst_core_t *core)
{
int ret = MC_ERROR_NONE;
- GstPad *pad = NULL;
MEDIACODEC_FENTER();
g_mutex_lock(&core->prepare_lock);
core->prepare_count--;
- if(core->prepare_count == 0)
- {
+ if (core->prepare_count == 0) {
- if(core->pipeline)
- {
+ if (core->pipeline) {
/* disconnect signal */
- if(core->fakesink && GST_IS_ELEMENT(core->fakesink))
- {
- if(g_signal_handler_is_connected(core->fakesink, core->signal_handoff))
- {
+ if (core->fakesink && GST_IS_ELEMENT(core->fakesink)) {
+ if (g_signal_handler_is_connected(core->fakesink, core->signal_handoff)) {
g_signal_handler_disconnect(core->fakesink, core->signal_handoff);
LOGD("handoff signal destroy");
}
}
- if(core->bus_whatch_id)
- {
+ if (core->bus_whatch_id) {
GSource *source = NULL;
- source = g_main_context_find_source_by_id (core->thread_default, core->bus_whatch_id);
+ source = g_main_context_find_source_by_id(core->thread_default, core->bus_whatch_id);
g_source_destroy(source);
- //g_source_remove(core->bus_whatch_id);
LOGD("bus_whatch_id destroy");
}
- pad = gst_element_get_static_pad(core->fakesink, "sink");
- gst_pad_remove_event_probe(pad, core->probe_id);
- g_object_unref(pad);
-
MEDIACODEC_ELEMENT_SET_STATE(core->pipeline, GST_STATE_NULL);
gst_object_unref(GST_OBJECT(core->pipeline));
@@ -1491,7 +2238,7 @@ mc_ret_e _mc_gst_destroy_pipeline(mc_gst_core_t *core)
return ret;
STATE_CHANGE_FAILED:
- if(core->pipeline)
+ if (core->pipeline)
gst_object_unref(GST_OBJECT(core->pipeline));
LOGD("@%p v(%d)e(%d) destroy_pipeline failed", core, core->video, core->encoder);
@@ -1500,237 +2247,243 @@ STATE_CHANGE_FAILED:
return MC_ERROR;
}
-void __mc_gst_buffer_add (GstElement *element, GstBuffer *buffer, GstPad *pad, gpointer data)
+void __mc_gst_buffer_add(GstElement *element, GstBuffer *buffer, GstPad *pad, gpointer data)
{
- mc_gst_core_t* core = (mc_gst_core_t*) data;
-
+ guint n;
+ GstMemory *mem;
+ GstMapInfo map = GST_MAP_INFO_INIT;
media_packet_h out_pkt = NULL;
MEDIACODEC_FENTER();
- //g_atomic_int_int(&core->num_live_buffers);
- LOGI("@%p(%d)", core, core->encoder);
+ mc_gst_core_t *core = (mc_gst_core_t *)data;
- out_pkt = __mc_gst_gstbuffer_to_media_packet(core, buffer);
- if (out_pkt == NULL)
- {
- LOGE("out_pkt create failed.");
- return;
- }
+ gst_buffer_ref(buffer);
- if(core->encoder && core->codec_config)
- {
- media_packet_set_flags(out_pkt, MEDIA_PACKET_CODEC_CONFIG);
- LOGD("set the codec data %p", buffer);
- }
- core->codec_config = false;
+ n = gst_buffer_n_memory(buffer);
- g_mutex_lock(&core->ports[1]->mutex);
- /* push it to output buffer queue */
- //g_queue_push_tail(core->output_queue, out_pkt);
- g_queue_push_tail(core->ports[1]->queue, out_pkt);
+ mem = gst_buffer_peek_memory(buffer, n-1);
- g_mutex_unlock(&core->ports[1]->mutex);
+ gst_memory_map(mem, &map, GST_MAP_READ);
+ LOGD("n : %d, map.data : %p, map.size : %d", n, map.data, map.size);
- if (core->user_cb[_MEDIACODEC_EVENT_TYPE_FILLBUFFER])
- {
- ((mc_fill_buffer_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_FILLBUFFER])(out_pkt, core->user_data[_MEDIACODEC_EVENT_TYPE_FILLBUFFER]);
- }
+ out_pkt = __mc_gst_make_media_packet(core, map.data, map.size);
- MEDIACODEC_FLEAVE();
-}
+ LOGI("@%p(%d) out_pkt : %p", core, core->encoder, out_pkt);
+ gst_memory_unmap(mem, &map);
-static int __mc_output_packet_buffer_finalize_cb(media_packet_h packet, int error_code, void *user_data)
-{
- void* buffer = NULL;
- MEDIACODEC_FENTER();
+ if (out_pkt) {
+ media_packet_set_extra(out_pkt, buffer);
+ media_packet_set_pts(out_pkt, GST_BUFFER_TIMESTAMP(buffer));
- LOGD("packet finalized: %p", packet);
- media_packet_get_extra(packet, &buffer);
- gst_buffer_unref((GstBuffer*)buffer);
+ if (core->need_codec_data) {
+ media_packet_set_flags(out_pkt, MEDIA_PACKET_CODEC_CONFIG);
+ core->need_codec_data = false;
+ }
+
+ if (core->need_sync_flag) {
+ media_packet_set_flags(out_pkt, MEDIA_PACKET_SYNC_FRAME);
+ core->need_sync_flag = false;
+ }
+
+ g_mutex_lock(&core->ports[1]->mutex);
+ /* push it to output buffer queue */
+ g_queue_push_tail(core->ports[1]->queue, out_pkt);
+
+ core->dequeued_count++;
+ LOGD("dequeued : %d", core->dequeued_count);
+
+ g_mutex_unlock(&core->ports[1]->mutex);
+
+ if (core->user_cb[_MEDIACODEC_EVENT_TYPE_FILLBUFFER]) {
+ ((mc_fill_buffer_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_FILLBUFFER])
+ (out_pkt, core->user_data[_MEDIACODEC_EVENT_TYPE_FILLBUFFER]);
+ }
+ }
MEDIACODEC_FLEAVE();
- return MEDIA_PACKET_FINALIZE;
+ return;
}
int __mc_output_buffer_finalize_cb(media_packet_h packet, int error_code, void *user_data)
{
- void* buffer = NULL;
- SCMN_IMGB *imgb = NULL;
- tbm_surface_h surface = NULL;
- bool has_tbm_surface = false;
-
- MEDIACODEC_FENTER();
+ void *buffer = NULL;
+ int i = 0;
+ guint n;
+ GstMemory *mem;
+ GstMapInfo map = GST_MAP_INFO_INIT;
+ MMVideoBuffer *mm_video_buf = NULL;
+ mc_gst_core_t *core = NULL;
- media_packet_has_tbm_surface_buffer(packet, &has_tbm_surface);
- LOGI("has_tbm_surface : %d", has_tbm_surface);
+ core = (mc_gst_core_t*)user_data;
- if(has_tbm_surface)
- {
- LOGI("destroy tbm surface");
- media_packet_get_tbm_surface(packet, &surface);
- tbm_surface_destroy(surface);
- }
+ LOGD("packet finalized: %p", packet);
media_packet_get_extra(packet, &buffer);
- LOGD("finalized_gst_buffer = %p", buffer);
- LOGI("gstbuffer refcount %d", GST_MINI_OBJECT_REFCOUNT_VALUE(buffer));
- if (GST_BUFFER_MALLOCDATA(buffer))
- {
- imgb = (SCMN_IMGB *)GST_BUFFER_MALLOCDATA(buffer);
- if (imgb)
- {
- LOGI("imgb is destroyed");
- free(imgb);
- imgb = NULL;
- GST_BUFFER_MALLOCDATA(buffer) = NULL;
+
+ n = gst_buffer_n_memory(buffer);
+
+ if (n > 1) {
+ mem = gst_buffer_peek_memory(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 *)buffer);
- //GST_BUFFER_DATA(buffer) = NULL;
- gst_buffer_unref((GstBuffer*)buffer);
-
- MEDIACODEC_FLEAVE();
return MEDIA_PACKET_FINALIZE;
}
-guint32 __mc_get_gst_input_format(media_packet_h packet, bool is_hw)
+gchar *__mc_get_gst_input_format(media_packet_h packet, bool is_hw)
{
- guint32 format = 0;
+ 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)
- {
+ switch (mimetype) {
case MEDIA_FORMAT_I420:
- format = GST_MAKE_FOURCC ('I', '4', '2', '0');
+ format = "I420";
break;
case MEDIA_FORMAT_NV12:
if (is_hw)
- format = GST_MAKE_FOURCC ('S', 'N', '1', '2');
+ format = "SN12";
else
- format = GST_MAKE_FOURCC ('N', 'V', '1', '2');
+ format = "NV12";
+ break;
+ case MEDIA_FORMAT_ARGB:
+ format = "ARGB";
break;
default:
break;
}
+ LOGD("input packet format : %s", format);
return format;
}
-
-mc_gst_buffer_t* _mc_gst_media_packet_to_gstbuffer(mc_gst_core_t* core, GstCaps **caps, media_packet_h pkt, bool codec_config)
+GstMCBuffer *_mc_gst_media_packet_to_gstbuffer(mc_gst_core_t* core, GstCaps **caps, media_packet_h pkt, bool codec_config)
{
- mc_gst_buffer_t* buff = NULL;
- uint64_t pts = 0, dur = 0;
+ int ret = MEDIA_PACKET_ERROR_NONE;
+ GstMCBuffer *mc_buffer = NULL;
+ void *buf_data = NULL;
+ uint64_t buf_size = 0;
+ uint64_t pts = 0;
+ uint64_t dur = 0;
+
+ ret = media_packet_get_buffer_size(pkt, &buf_size);
+ if (ret != MEDIA_PACKET_ERROR_NONE) {
+ LOGW("buffer size get fail");
+ return NULL;
+ }
+
+ ret = media_packet_get_buffer_data_ptr(pkt, &buf_data);
+ if (ret != MEDIA_PACKET_ERROR_NONE) {
+ LOGW("buffer size get fail");
+ return NULL;
+ }
- buff = __mc_gst_buffer_new(core);
- buff->pkt = pkt;
+ mc_buffer = gst_mediacodec_buffer_new(core, pkt, buf_size);
+ if (mc_buffer == NULL) {
+ LOGW("failed to create inbuf");
+ return NULL;
+ }
- //mc_hex_dump("nal", pkt, 8);
+ LOGD("pkt : %p, buf_size : %d", pkt, (int)buf_size);
- __mc_fill_input_buffer(core, buff);
+ ret = __mc_fill_input_buffer(core, pkt, mc_buffer);
+ if (ret != MC_ERROR_NONE) {
+ LOGW("failed to fill inbuf");
+ return NULL;
+ }
/* pts */
media_packet_get_pts(pkt, &pts);
- GST_BUFFER_TIMESTAMP(buff) = (GstClockTime) pts;
- LOGD("GST_BUFFER_TIMESTAMP = %"GST_TIME_FORMAT, GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(buff)));
- LOGD("PTS = %llu", pts);
+ GST_BUFFER_PTS(mc_buffer->buffer) = pts;
/* duration */
media_packet_get_duration(pkt, &dur);
- GST_BUFFER_DURATION(buff) = dur;
-
- GST_BUFFER_CAPS(buff) = gst_caps_copy(*caps);
+ GST_BUFFER_DURATION(mc_buffer->buffer) = dur;
- return buff;
+ return mc_buffer;
}
-media_packet_h __mc_gst_gstbuffer_to_media_packet(mc_gst_core_t* core, GstBuffer* buff)
+media_packet_h __mc_gst_make_media_packet(mc_gst_core_t *core, unsigned char *data, int size)
{
- media_packet_h out_pkt = NULL;
- mc_ret_e ret = MC_ERROR_NONE;
- if (!buff)
- return NULL;
+ media_packet_h pkt = NULL;
- ret = __mc_fill_output_buffer(core, buff, &out_pkt);
- if (ret != MC_ERROR_NONE)
- {
- gst_buffer_ref(buff);
- return NULL;
- }
+ __mc_fill_output_buffer(core, data, size, &pkt);
- gst_buffer_ref(buff);
- return out_pkt;
+ return pkt;
}
-gboolean __mc_gst_bus_callback (GstBus *bus, GstMessage *msg, gpointer data)
+gboolean __mc_gst_bus_callback(GstBus *bus, GstMessage *msg, gpointer data)
{
int ret = MC_ERROR_NONE;
- mc_gst_core_t *core = (mc_gst_core_t*)data;
+ mc_gst_core_t *core = (mc_gst_core_t *)data;
LOGD("@%p v(%d)e(%d)", core, core->video, core->encoder);
- switch (GST_MESSAGE_TYPE (msg)) {
+ switch (GST_MESSAGE_TYPE(msg)) {
case GST_MESSAGE_EOS:
{
- core->eos = true;
- g_cond_signal(&core->eos_cond);
- LOGD("send eos signal");
+ _mc_send_eos_signal(core);
- LOGD ("End of stream\n");
-/*
- if (core->user_cb[_MEDIACODEC_EVENT_TYPE_EOS])
- {
+ if (core->user_cb[_MEDIACODEC_EVENT_TYPE_EOS]) {
+ LOGD("eos callback invoked");
((mc_eos_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_EOS])(core->user_data[_MEDIACODEC_EVENT_TYPE_EOS]);
}
-*/
+
+ LOGD("End of stream\n");
}
break;
case GST_MESSAGE_ERROR:
{
- GError* error = NULL;
+ GError *error = NULL;
- gst_message_parse_error (msg, &error, NULL);
+ gst_message_parse_error(msg, &error, NULL);
- if (!error)
- {
+ if (!error) {
LOGW("GST error message parsing failed");
break;
}
- LOGW ("Error: %s\n", error->message);
+ LOGW("Error: %s\n", error->message);
- if(error)
- {
- if(error->domain == GST_STREAM_ERROR)
- {
+ if (error) {
+ if (error->domain == GST_STREAM_ERROR) {
ret = __gst_handle_stream_error(core, error, msg);
- }
- else if (error->domain == GST_RESOURCE_ERROR)
- {
+ } else if (error->domain == GST_RESOURCE_ERROR) {
ret = __gst_handle_resource_error(core, error->code);
- }
- else if (error->domain == GST_LIBRARY_ERROR)
- {
+ } else if (error->domain == GST_LIBRARY_ERROR) {
ret = __gst_handle_library_error(core, error->code);
- }
- else if (error->domain == GST_CORE_ERROR)
- {
+ } else if (error->domain == GST_CORE_ERROR) {
ret = __gst_handle_core_error(core, error->code);
- }
- else
- {
+ } else {
LOGW("Unexpected error has occured");
}
+
+ if (core->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR]) {
+ ((mc_error_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR])
+ (ret, core->user_data[_MEDIACODEC_EVENT_TYPE_ERROR]);
+ }
}
- g_error_free (error);
+ g_error_free(error);
}
break;
@@ -1738,27 +2491,19 @@ gboolean __mc_gst_bus_callback (GstBus *bus, GstMessage *msg, gpointer data)
break;
}
- if (core->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR])
- {
- ((mc_error_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR])(ret, core->user_data[_MEDIACODEC_EVENT_TYPE_ERROR]);
- }
-
return TRUE;
}
-static gboolean
-__mc_gst_check_useful_message(mc_gst_core_t *core, GstMessage *msg)
+static gboolean __mc_gst_check_useful_message(mc_gst_core_t *core, GstMessage *msg)
{
gboolean retval = false;
- if(!core->pipeline)
- {
+ if (!core->pipeline) {
LOGE("mediacodec pipeline handle is null");
return true;
}
- switch (GST_MESSAGE_TYPE (msg))
- {
+ switch (GST_MESSAGE_TYPE(msg)) {
case GST_MESSAGE_TAG:
case GST_MESSAGE_EOS:
case GST_MESSAGE_ERROR:
@@ -1773,29 +2518,27 @@ __mc_gst_check_useful_message(mc_gst_core_t *core, GstMessage *msg)
return retval;
}
-static GstBusSyncReply
-__mc_gst_bus_sync_callback(GstBus *bus, GstMessage *msg, gpointer data)
+static GstBusSyncReply __mc_gst_bus_sync_callback(GstBus *bus, GstMessage *msg, gpointer data)
{
- mc_gst_core_t *core = (mc_gst_core_t*)data;
+ mc_gst_core_t *core = (mc_gst_core_t *)data;
GstBusSyncReply reply = GST_BUS_DROP;
- if(!core->pipeline)
- {
+ LOGD("__mc_gst_bus_sync_callback is called");
+
+ if (!core->pipeline) {
LOGE("mediacodec pipeline handle is null");
return GST_BUS_PASS;
}
- if(!__mc_gst_check_useful_message(core, msg))
- {
+ if (!__mc_gst_check_useful_message(core, msg)) {
gst_message_unref(msg);
return GST_BUS_DROP;
}
- switch (GST_MESSAGE_TYPE (msg))
- {
- case GST_MESSAGE_STATE_CHANGED:
+ switch (GST_MESSAGE_TYPE(msg)) {
+ case GST_MESSAGE_EOS:
+ case GST_MESSAGE_ERROR:
__mc_gst_bus_callback(NULL, msg, core);
- //__mediacodec_gst_callback(NULL, msg, core);
reply = GST_BUS_DROP;
break;
@@ -1804,141 +2547,113 @@ __mc_gst_bus_sync_callback(GstBus *bus, GstMessage *msg, gpointer data)
break;
}
- if( reply == GST_BUS_DROP )
+ if (reply == GST_BUS_DROP)
gst_message_unref(msg);
return reply;
}
-static SCMN_IMGB * __mc_gst_make_tbm_buffer(mc_gst_core_t* core, media_packet_h pkt)
+static MMVideoBuffer *__mc_gst_make_tbm_buffer(mc_gst_core_t* core, media_packet_h pkt)
{
tbm_surface_h surface = NULL;
tbm_bo bo = NULL;
- mc_encoder_info_t *enc_info = (mc_encoder_info_t*)core->codec_info;
+ mc_encoder_info_t *enc_info = (mc_encoder_info_t *)core->codec_info;
if (!pkt) {
LOGE("output is null");
return NULL;
}
- SCMN_IMGB *psimgb = NULL;
- psimgb = (SCMN_IMGB *)malloc(sizeof(SCMN_IMGB));
- if (!psimgb) {
- LOGE("Failed to alloc SCMN_IMGB");
+ MMVideoBuffer *mm_vbuffer = NULL;
+ mm_vbuffer = (MMVideoBuffer *)malloc(sizeof(MMVideoBuffer));
+ if (!mm_vbuffer) {
+ LOGE("Failed to alloc MMVideoBuffer");
return NULL;
}
- memset(psimgb, 0x00, sizeof(SCMN_IMGB));
+ memset(mm_vbuffer, 0x00, sizeof(MMVideoBuffer));
- media_packet_get_tbm_surface(pkt, &surface);
+ if (media_packet_get_tbm_surface(pkt, &surface) != MEDIA_PACKET_ERROR_NONE)
+ {
+ LOGE("get tbm surface is failed");
+ free(mm_vbuffer);
+ return NULL;
+ }
bo = tbm_surface_internal_get_bo(surface, 0);
+ tbm_bo_map(bo, TBM_DEVICE_MM, TBM_OPTION_READ);
+ tbm_bo_unmap(bo);
+
tbm_bo_handle handle = tbm_bo_get_handle(bo, TBM_DEVICE_CPU);
#ifdef TIZEN_PROFILE_LITE
int phy_addr = 0;
int phy_size = 0;
tbm_bo_handle handle_fd = tbm_bo_get_handle(bo, TBM_DEVICE_MM);
- if (__tbm_get_physical_addr_bo(handle_fd, &phy_addr, &phy_size) == 0)
- {
- psimgb->p[0] = (void*)phy_addr;
+ 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]);
}
+ LOGD("paddr : %p", phy_addr);
#endif
- psimgb->buf_share_method = BUF_SHARE_METHOD_TIZEN_BUFFER;
- psimgb->bo[0] = bo;
- psimgb->a[0] = handle.ptr;
- psimgb->w[0] = enc_info->width;
- psimgb->h[0] = enc_info->height;
- psimgb->s[0] = psimgb->w[0];
- psimgb->e[0] = psimgb->h[0];
+ mm_vbuffer->type = MM_VIDEO_BUFFER_TYPE_TBM_BO;
+ mm_vbuffer->handle.bo[0] = bo;
+ mm_vbuffer->data[0] = handle.ptr;
+ mm_vbuffer->width[0] = enc_info->width;
+ mm_vbuffer->height[0] = enc_info->height;
+ mm_vbuffer->stride_width[0] = mm_vbuffer->width[0];
+ mm_vbuffer->stride_height[0] = mm_vbuffer->height[0];
- return psimgb;
+ return mm_vbuffer;
}
-static GType __mc_gst_buffer_get_type(void)
+static void gst_mediacodec_buffer_finalize(GstMCBuffer *mc_buffer)
{
- static GType _mc_gst_buffer_type;
+ if (!mc_buffer)
+ return;
- if (G_UNLIKELY(_mc_gst_buffer_type == 0)) {
- static const GTypeInfo mc_gst_buffer_info = {
- sizeof (GstBufferClass),
- NULL,
- NULL,
- __mc_gst_buffer_class_init,
- NULL,
- NULL,
- sizeof (mc_gst_buffer_t),
- 0,
- NULL,
- NULL
- };
+ mc_gst_core_t *core = (mc_gst_core_t *)mc_buffer->core;
- _mc_gst_buffer_type = g_type_register_static(GST_TYPE_BUFFER,
- "McGstBuffer",
- &mc_gst_buffer_info,
- 0);
+ if (core->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER]) {
+ ((mc_empty_buffer_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER])
+ (mc_buffer->pkt, core->user_data[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER]);
}
- return _mc_gst_buffer_type;
-}
+ LOGD("%p(%p) buffer finalized...", mc_buffer, mc_buffer->pkt);
+ free(mc_buffer);
+ mc_buffer = NULL;
-static void __mc_gst_buffer_class_init(gpointer g_class, gpointer class_data)
-{
- GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS(g_class);
- mc_gst_buffer_parent_class = g_type_class_peek_parent(g_class);
- mini_object_class->finalize = (GstMiniObjectFinalizeFunction)__mc_gst_buffer_finalize;
+ return;
}
-static mc_gst_buffer_t* __mc_gst_buffer_new(mc_gst_core_t* core)
+static GstMCBuffer *gst_mediacodec_buffer_new(mc_gst_core_t* core, media_packet_h pkt, uint64_t size)
{
- mc_gst_buffer_t *ret = NULL;
- ret = (mc_gst_buffer_t *)gst_mini_object_new(GST_TYPE_MC_BUFFER);
- LOGD("creating buffer : %p", ret);
- ret->core = core;
- return ret;
-}
+ GstMCBuffer *mc_buffer = NULL;
-static void __mc_gst_buffer_finalize(mc_gst_buffer_t *buffer)
-{
- SCMN_IMGB *imgb = NULL;
- mc_gst_core_t *core = buffer->core;
+ mc_buffer = (GstMCBuffer *)malloc(sizeof(*mc_buffer));
- LOGD("__mc_gst_buffer_finalize() is called");
- if (GST_BUFFER_MALLOCDATA(buffer))
- {
- imgb = (SCMN_IMGB *)GST_BUFFER_MALLOCDATA(buffer);
- if (imgb)
- {
- LOGI("imgb is destroyed");
- free(imgb);
- imgb = NULL;
- GST_BUFFER_MALLOCDATA(buffer) = NULL;
- }
+ if (mc_buffer == NULL) {
+ LOGE("malloc fail");
+ return NULL;
}
- //GST_BUFFER_DATA(buffer) = NULL;
+ mc_buffer->buffer = gst_buffer_new();
+ mc_buffer->buf_size = 0;
- if (GST_MINI_OBJECT_CLASS (mc_gst_buffer_parent_class)->finalize) {
- GST_MINI_OBJECT_CLASS (mc_gst_buffer_parent_class)->finalize (GST_MINI_OBJECT(buffer));
- }
-
- if (core->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER])
- {
- ((mc_empty_buffer_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER])(buffer->pkt, core->user_data[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER]);
- LOGD("finalize, pkt : %p, buffer : %p", buffer->pkt, buffer);
- }
+ LOGD("creating buffer : %p, %p", mc_buffer, mc_buffer->buffer);
+ mc_buffer->core = core;
+ mc_buffer->pkt = pkt;
- return;
+ return mc_buffer;
}
-static gint __gst_handle_core_error(mc_gst_core_t* core, int code )
+static gint __gst_handle_core_error(mc_gst_core_t *core, int code)
{
gint trans_err = MEDIACODEC_ERROR_NONE;
g_return_val_if_fail(core, MC_PARAM_ERROR);
- switch ( code )
- {
+ switch (code) {
case GST_CORE_ERROR_MISSING_PLUGIN:
return MEDIACODEC_ERROR_NOT_SUPPORTED_FORMAT;
case GST_CORE_ERROR_STATE_CHANGE:
@@ -1962,14 +2677,13 @@ static gint __gst_handle_core_error(mc_gst_core_t* core, int code )
return trans_err;
}
-static gint __gst_handle_library_error(mc_gst_core_t* core, int code)
+static gint __gst_handle_library_error(mc_gst_core_t *core, int code)
{
gint trans_err = MEDIACODEC_ERROR_NONE;
g_return_val_if_fail(core, MC_PARAM_ERROR);
- switch ( code )
- {
+ switch (code) {
case GST_LIBRARY_ERROR_FAILED:
case GST_LIBRARY_ERROR_TOO_LAZY:
case GST_LIBRARY_ERROR_INIT:
@@ -1985,14 +2699,13 @@ static gint __gst_handle_library_error(mc_gst_core_t* core, int code)
}
-static gint __gst_handle_resource_error(mc_gst_core_t* core, int code )
+static gint __gst_handle_resource_error(mc_gst_core_t *core, int code)
{
gint trans_err = MEDIACODEC_ERROR_NONE;
g_return_val_if_fail(core, MC_PARAM_ERROR);
- switch ( code )
- {
+ switch (code) {
case GST_RESOURCE_ERROR_NO_SPACE_LEFT:
trans_err = MEDIACODEC_ERROR_NO_FREE_SPACE;
break;
@@ -2014,16 +2727,15 @@ static gint __gst_handle_resource_error(mc_gst_core_t* core, int code )
return trans_err;
}
-static gint __gst_handle_stream_error(mc_gst_core_t* core, GError* error, GstMessage * message)
+static gint __gst_handle_stream_error(mc_gst_core_t *core, GError* error, GstMessage * message)
{
gint trans_err = MEDIACODEC_ERROR_NONE;
g_return_val_if_fail(core, MC_PARAM_ERROR);
g_return_val_if_fail(error, MC_PARAM_ERROR);
- g_return_val_if_fail (message, MC_PARAM_ERROR);
+ g_return_val_if_fail(message, MC_PARAM_ERROR);
- switch ( error->code )
- {
+ switch (error->code) {
case GST_STREAM_ERROR_FAILED:
case GST_STREAM_ERROR_TYPE_NOT_FOUND:
case GST_STREAM_ERROR_DECODE:
@@ -2031,7 +2743,7 @@ static gint __gst_handle_stream_error(mc_gst_core_t* core, GError* error, GstMes
case GST_STREAM_ERROR_DECRYPT:
case GST_STREAM_ERROR_DECRYPT_NOKEY:
case GST_STREAM_ERROR_CODEC_NOT_FOUND:
- trans_err = __gst_transform_gsterror( core, message, error );
+ trans_err = __gst_transform_gsterror(core, message, error);
break;
case GST_STREAM_ERROR_NOT_IMPLEMENTED:
@@ -2048,35 +2760,34 @@ static gint __gst_handle_stream_error(mc_gst_core_t* core, GError* error, GstMes
return trans_err;
}
-static gint __gst_transform_gsterror( mc_gst_core_t *core, GstMessage * message, GError* error )
+static gint __gst_transform_gsterror(mc_gst_core_t *core, GstMessage * message, GError* error)
{
gchar *src_element_name = NULL;
GstElement *src_element = NULL;
GstElementFactory *factory = NULL;
- const gchar* klass = NULL;
+ const gchar *klass = NULL;
src_element = GST_ELEMENT_CAST(message->src);
- if ( !src_element )
+ if (!src_element)
goto INTERNAL_ERROR;
src_element_name = GST_ELEMENT_NAME(src_element);
- if ( !src_element_name )
+ if (!src_element_name)
goto INTERNAL_ERROR;
factory = gst_element_get_factory(src_element);
- if ( !factory )
+ if (!factory)
goto INTERNAL_ERROR;
klass = gst_element_factory_get_klass(factory);
- if ( !klass )
+ if (!klass)
goto INTERNAL_ERROR;
LOGD("error code=%d, msg=%s, src element=%s, class=%s\n",
error->code, error->message, src_element_name, klass);
- switch ( error->code )
- {
+ switch (error->code) {
case GST_STREAM_ERROR_DECODE:
return MEDIACODEC_ERROR_INVALID_STREAM;
break;
@@ -2101,49 +2812,80 @@ INTERNAL_ERROR:
return MEDIACODEC_ERROR_INTERNAL;
}
+static int _mc_gst_flush_buffers(mc_gst_core_t *core)
+{
+ gboolean ret = FALSE;
+ GstEvent *event = NULL;
+
+ MEDIACODEC_FENTER();
+
+ _mc_gst_set_flush_input(core);
+
+ event = gst_event_new_seek(1.0, GST_FORMAT_BYTES, GST_SEEK_FLAG_FLUSH,
+ GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_NONE, -1);
+
+ ret = gst_element_send_event(core->appsrc, event);
+ if (ret != TRUE) {
+ LOGE("failed to send seek event");
+ return MC_ERROR;
+ }
+
+ _mc_gst_set_flush_output(core);
+
+ MEDIACODEC_FLEAVE();
+
+ return MC_ERROR_NONE;
+}
+
+
static void _mc_gst_set_flush_input(mc_gst_core_t *core)
{
media_packet_h pkt = NULL;
LOGI("_mc_gst_set_flush_input is called");
- while( pkt != mc_async_queue_pop_forced(core->available_queue->input) )
+
+ while (!mc_async_queue_is_empty(core->available_queue->input))
{
- LOGD("%p pkt is poped");
- if (core->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER])
- {
+ pkt = mc_async_queue_pop_forced(core->available_queue->input);
+
+ if (core->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER]) {
((mc_empty_buffer_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER])
(pkt, core->user_data[_MEDIACODEC_EVENT_TYPE_EMPTYBUFFER]);
}
}
mc_async_queue_flush(core->available_queue->input);
+ core->queued_count = 0;
}
static void _mc_gst_set_flush_output(mc_gst_core_t *core)
{
media_packet_h pkt = NULL;
- LOGI("_mc_gst_set_flush_output is called");
+ MEDIACODEC_FENTER();
g_mutex_lock(&core->ports[1]->mutex);
- if(!g_queue_is_empty(core->ports[1]->queue))
+ while(!g_queue_is_empty(core->ports[1]->queue))
{
- while(pkt != g_queue_pop_head(core->ports[1]->queue))
- {
- LOGD("outpkt in output_queue : %p", pkt);
+ pkt = g_queue_pop_head(core->ports[1]->queue);
+ LOGD("outpkt in output_queue : %p", pkt);
+ if (pkt) {
media_packet_destroy(pkt);
+ LOGD("outpkt destroyed");
+ pkt = NULL;
}
}
-
+ core->dequeued_count = 0;
g_mutex_unlock(&core->ports[1]->mutex);
+ MEDIACODEC_FLEAVE();
}
#ifdef TIZEN_PROFILE_LITE
-int __tbm_get_physical_addr_bo(tbm_bo_handle tbm_bo_handle_fd_t, int* phy_addr, int* phy_size)
+int __tbm_get_physical_addr_bo(tbm_bo_handle tbm_bo_handle_fd_t, int *phy_addr, int *phy_size)
{
int tbm_bo_handle_fd;
- int ret=0;
+ int ret = 0;
tbm_bo_handle_fd = tbm_bo_handle_fd_t.u32;
@@ -2157,36 +2899,302 @@ int __tbm_get_physical_addr_bo(tbm_bo_handle tbm_bo_handle_fd_t, int* phy_addr,
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");
+ 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 fails %d %s",errno,strerror(errno));
- ret=-1;
+ if (ioctl(ion_fd, ION_IOC_CUSTOM, &custom_data) < 0) {
+ LOGE("[tbm_get_physical_addr_bo] ION_IOC_CUSTOM failed");
+ ret = -1;
}
- if (!ret)
- {
+ if (!ret) {
*phy_addr = mmu_data.iova_addr;
*phy_size = mmu_data.iova_size;
- }
- else
- {
+ } else {
*phy_addr = 0;
*phy_size = 0;
- LOGW ("[tbm_get_physical_addr_bo] getting physical address is failed. phy_addr = 0");
+ LOGW("[tbm_get_physical_addr_bo] getting physical address is failed. phy_addr = 0");
}
- if (ion_fd != -1)
- {
- close (ion_fd);
+ if (ion_fd != -1) {
+ close(ion_fd);
ion_fd = -1;
}
return 0;
}
#endif
+
+/*
+ * Get tiled address of position(x,y)
+ *
+ * @param x_size
+ * width of tiled[in]
+ *
+ * @param y_size
+ * height of tiled[in]
+ *
+ * @param x_pos
+ * x position of tield[in]
+ *
+ * @param src_size
+ * y position of tield[in]
+ *
+ * @return
+ * address of tiled data
+ */
+static int __tile_4x2_read(int x_size, int y_size, int x_pos, int y_pos)
+{
+ int pixel_x_m1, pixel_y_m1;
+ int roundup_x;
+ int linear_addr0, linear_addr1, bank_addr ;
+ int x_addr;
+ int trans_addr;
+
+ pixel_x_m1 = x_size - 1;
+ pixel_y_m1 = y_size - 1;
+
+ roundup_x = ((pixel_x_m1 >> 7) + 1);
+
+ x_addr = x_pos >> 2;
+
+ if ((y_size <= y_pos+32) && (y_pos < y_size) &&
+ (((pixel_y_m1 >> 5) & 0x1) == 0) && (((y_pos >> 5) & 0x1) == 0)) {
+ linear_addr0 = (((y_pos & 0x1f) << 4) | (x_addr & 0xf));
+ linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 6) & 0x3f));
+
+ if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1))
+ bank_addr = ((x_addr >> 4) & 0x1);
+ else
+ bank_addr = 0x2 | ((x_addr >> 4) & 0x1);
+ } else {
+ linear_addr0 = (((y_pos & 0x1f) << 4) | (x_addr & 0xf));
+ linear_addr1 = (((y_pos >> 6) & 0xff) * roundup_x + ((x_addr >> 5) & 0x7f));
+
+ if (((x_addr >> 5) & 0x1) == ((y_pos >> 5) & 0x1))
+ bank_addr = ((x_addr >> 4) & 0x1);
+ else
+ bank_addr = 0x2 | ((x_addr >> 4) & 0x1);
+ }
+
+ linear_addr0 = linear_addr0 << 2;
+ trans_addr = (linear_addr1 << 13) | (bank_addr << 11) | linear_addr0;
+
+ return trans_addr;
+}
+
+/*
+ * Converts tiled data to linear
+ * Crops left, top, right, buttom
+ * 1. Y of NV12T to Y of YUV420P
+ * 2. Y of NV12T to Y of YUV420S
+ * 3. UV of NV12T to UV of YUV420S
+ *
+ * @param yuv420_dest
+ * Y or UV plane address of YUV420[out]
+ *
+ * @param nv12t_src
+ * Y or UV plane address of NV12T[in]
+ *
+ * @param yuv420_width
+ * Width of YUV420[in]
+ *
+ * @param yuv420_height
+ * Y: Height of YUV420, UV: Height/2 of YUV420[in]
+ *
+ * @param left
+ * Crop size of left
+ *
+ * @param top
+ * Crop size of top
+ *
+ * @param right
+ * Crop size of right
+ *
+ * @param buttom
+ * Crop size of buttom
+ */
+static void __csc_tiled_to_linear_crop(unsigned char *yuv420_dest, unsigned char *nv12t_src,
+ int yuv420_width, int yuv420_height,
+ int left, int top, int right, int buttom)
+{
+ int i, j;
+ int tiled_offset = 0, tiled_offset1 = 0;
+ int linear_offset = 0;
+ int temp1 = 0, temp2 = 0, temp3 = 0, temp4 = 0;
+
+ temp3 = yuv420_width-right;
+ temp1 = temp3-left;
+ /* real width is greater than or equal 256 */
+ if (temp1 >= 256) {
+ for (i = top; i < yuv420_height-buttom; i += 1) {
+ j = left;
+ temp3 = (j>>8)<<8;
+ temp3 = temp3>>6;
+ temp4 = i>>5;
+ if (temp4 & 0x1) {
+ /* odd fomula: 2+x+(x>>2)<<2+x_block_num*(y-1) */
+ tiled_offset = temp4-1;
+ temp1 = ((yuv420_width+127)>>7)<<7;
+ tiled_offset = tiled_offset*(temp1>>6);
+ tiled_offset = tiled_offset+temp3;
+ tiled_offset = tiled_offset+2;
+ temp1 = (temp3>>2)<<2;
+ tiled_offset = tiled_offset+temp1;
+ tiled_offset = tiled_offset<<11;
+ tiled_offset1 = tiled_offset+2048*2;
+ temp4 = 8;
+ } else {
+ temp2 = ((yuv420_height+31)>>5)<<5;
+ if ((i + 32) < temp2) {
+ /* even1 fomula: x+((x+2)>>2)<<2+x_block_num*y */
+ temp1 = temp3+2;
+ temp1 = (temp1>>2)<<2;
+ tiled_offset = temp3+temp1;
+ temp1 = ((yuv420_width+127)>>7)<<7;
+ tiled_offset = tiled_offset+temp4*(temp1>>6);
+ tiled_offset = tiled_offset<<11;
+ tiled_offset1 = tiled_offset + 2048 * 6;
+ temp4 = 8;
+ } else {
+ /* even2 fomula: x+x_block_num*y */
+ temp1 = ((yuv420_width+127)>>7)<<7;
+ tiled_offset = temp4*(temp1>>6);
+ tiled_offset = tiled_offset+temp3;
+ tiled_offset = tiled_offset<<11;
+ tiled_offset1 = tiled_offset+2048*2;
+ temp4 = 4;
+ }
+ }
+
+ temp1 = i&0x1F;
+ tiled_offset = tiled_offset+64*(temp1);
+ tiled_offset1 = tiled_offset1+64*(temp1);
+ temp2 = yuv420_width-left-right;
+ linear_offset = temp2*(i-top);
+ temp3 = ((j+256)>>8)<<8;
+ temp3 = temp3-j;
+ temp1 = left&0x3F;
+ if (temp3 > 192) {
+ memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset+temp1, 64-temp1);
+ temp2 = ((left+63)>>6)<<6;
+ temp3 = ((yuv420_width-right)>>6)<<6;
+ if (temp2 == temp3) {
+ temp2 = yuv420_width-right-(64-temp1);
+ }
+ memcpy(yuv420_dest+linear_offset+64-temp1, nv12t_src+tiled_offset+2048, 64);
+ memcpy(yuv420_dest+linear_offset+128-temp1, nv12t_src+tiled_offset1, 64);
+ memcpy(yuv420_dest+linear_offset+192-temp1, nv12t_src+tiled_offset1+2048, 64);
+ linear_offset = linear_offset+256-temp1;
+ } else if (temp3 > 128) {
+ memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset+2048+temp1, 64-temp1);
+ memcpy(yuv420_dest+linear_offset+64-temp1, nv12t_src+tiled_offset1, 64);
+ memcpy(yuv420_dest+linear_offset+128-temp1, nv12t_src+tiled_offset1+2048, 64);
+ linear_offset = linear_offset+192-temp1;
+ } else if (temp3 > 64) {
+ memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset1+temp1, 64-temp1);
+ memcpy(yuv420_dest+linear_offset+64-temp1, nv12t_src+tiled_offset1+2048, 64);
+ linear_offset = linear_offset+128-temp1;
+ } else if (temp3 > 0) {
+ memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset1+2048+temp1, 64-temp1);
+ linear_offset = linear_offset+64-temp1;
+ }
+
+ tiled_offset = tiled_offset+temp4*2048;
+ j = (left>>8)<<8;
+ j = j + 256;
+ temp2 = yuv420_width-right-256;
+ for (; j <= temp2; j += 256) {
+ memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
+ tiled_offset1 = tiled_offset1+temp4*2048;
+ memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, 64);
+ memcpy(yuv420_dest+linear_offset+128, nv12t_src+tiled_offset1, 64);
+ tiled_offset = tiled_offset+temp4*2048;
+ memcpy(yuv420_dest+linear_offset+192, nv12t_src+tiled_offset1+2048, 64);
+ linear_offset = linear_offset+256;
+ }
+
+ tiled_offset1 = tiled_offset1+temp4*2048;
+ temp2 = yuv420_width-right-j;
+ if (temp2 > 192) {
+ memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
+ memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, 64);
+ memcpy(yuv420_dest+linear_offset+128, nv12t_src+tiled_offset1, 64);
+ memcpy(yuv420_dest+linear_offset+192, nv12t_src+tiled_offset1+2048, temp2-192);
+ } else if (temp2 > 128) {
+ memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
+ memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, 64);
+ memcpy(yuv420_dest+linear_offset+128, nv12t_src+tiled_offset1, temp2-128);
+ } else if (temp2 > 64) {
+ memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
+ memcpy(yuv420_dest+linear_offset+64, nv12t_src+tiled_offset+2048, temp2-64);
+ } else {
+ memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, temp2);
+ }
+ }
+ } else if (temp1 >= 64) {
+ for (i = top; i < (yuv420_height-buttom); i += 1) {
+ j = left;
+ tiled_offset = __tile_4x2_read(yuv420_width, yuv420_height, j, i);
+ temp2 = ((j+64)>>6)<<6;
+ temp2 = temp2-j;
+ linear_offset = temp1*(i-top);
+ temp4 = j&0x3;
+ tiled_offset = tiled_offset+temp4;
+ memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, temp2);
+ linear_offset = linear_offset+temp2;
+ j = j+temp2;
+ if ((j+64) <= temp3) {
+ tiled_offset = __tile_4x2_read(yuv420_width, yuv420_height, j, i);
+ memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
+ linear_offset = linear_offset+64;
+ j = j+64;
+ }
+ if ((j+64) <= temp3) {
+ tiled_offset = __tile_4x2_read(yuv420_width, yuv420_height, j, i);
+ memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 64);
+ linear_offset = linear_offset+64;
+ j = j+64;
+ }
+ if (j < temp3) {
+ tiled_offset = __tile_4x2_read(yuv420_width, yuv420_height, j, i);
+ temp2 = temp3-j;
+ memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, temp2);
+ }
+ }
+ } else {
+ for (i = top; i < (yuv420_height-buttom); i += 1) {
+ linear_offset = temp1*(i-top);
+ for (j = left; j < (yuv420_width - right); j += 2) {
+ tiled_offset = __tile_4x2_read(yuv420_width, yuv420_height, j, i);
+ temp4 = j&0x3;
+ tiled_offset = tiled_offset+temp4;
+ memcpy(yuv420_dest+linear_offset, nv12t_src+tiled_offset, 2);
+ linear_offset = linear_offset+2;
+ }
+ }
+ }
+}
+
+void _mc_send_eos_signal(mc_gst_core_t *core)
+{
+ g_mutex_lock(&core->eos_mutex);
+ core->eos = FALSE;
+ g_cond_broadcast(&core->eos_cond);
+ g_mutex_unlock(&core->eos_mutex);
+ LOGD("send EOS signal");
+}
+
+void _mc_wait_for_eos(mc_gst_core_t *core)
+{
+ g_mutex_lock(&core->eos_mutex);
+ core->eos = TRUE;
+ LOGD("waiting for EOS");
+ while (core->eos) {
+ g_cond_wait(&core->eos_cond, &core->eos_mutex);
+ }
+ LOGD("received EOS");
+ g_mutex_unlock(&core->eos_mutex);
+}
diff --git a/src/media_codec_queue.c b/src/media_codec_queue.c
index c719bf3..9713601 100755
--- a/src/media_codec_queue.c
+++ b/src/media_codec_queue.c
@@ -1,54 +1,55 @@
#include <media_codec_queue.h>
+#include <dlog.h>
-async_queue_t *mc_async_queue_new (void)
+async_queue_t *mc_async_queue_new(void)
{
async_queue_t *async_queue;
- async_queue = g_slice_new0 (async_queue_t);
+ async_queue = g_slice_new0(async_queue_t);
+ if (async_queue == NULL) {
+ LOGE("async_queue initialization failed");
+ return NULL;
+ }
- //async_queue->condition = g_cond_new ();
- g_cond_init (&async_queue->condition);
- //async_queue->mutex = g_mutex_new ();
+ g_cond_init(&async_queue->condition);
g_mutex_init(&async_queue->mutex);
async_queue->enabled = TRUE;
return async_queue;
}
-void mc_async_queue_free (async_queue_t * async_queue)
+void mc_async_queue_free(async_queue_t *async_queue)
{
- //g_cond_free (async_queue->condition);
- g_cond_clear (&async_queue->condition);
- //g_mutex_free (async_queue->mutex);
- g_mutex_clear (&async_queue->mutex);
+ g_cond_clear(&async_queue->condition);
+ g_mutex_clear(&async_queue->mutex);
- g_list_free (async_queue->head);
- g_slice_free (async_queue_t, async_queue);
+ g_list_free(async_queue->head);
+ g_slice_free(async_queue_t, async_queue);
}
-void mc_async_queue_push (async_queue_t * async_queue, gpointer data)
+void mc_async_queue_push(async_queue_t *async_queue, gpointer data)
{
- g_mutex_lock (&async_queue->mutex);
+ g_mutex_lock(&async_queue->mutex);
async_queue->tail = g_list_append(async_queue->tail, data);
- if(async_queue->tail && async_queue->tail->next)
+ if (async_queue->tail->next)
async_queue->tail = async_queue->tail->next;
else
async_queue->head = async_queue->tail;
async_queue->length++;
- g_cond_signal (&async_queue->condition);
- //LOGD("queue pushed : %p, %d, %p",queue, async_queue->length, data);
+ g_cond_signal(&async_queue->condition);
+ /*LOGD("queue pushed : %p, %d, %p",queue, async_queue->length, data);*/
- g_mutex_unlock (&async_queue->mutex);
+ g_mutex_unlock(&async_queue->mutex);
}
-gpointer mc_async_queue_pop (async_queue_t * async_queue)
+gpointer mc_async_queue_pop(async_queue_t *async_queue)
{
gpointer data = NULL;
- g_mutex_lock (&async_queue->mutex);
+ g_mutex_lock(&async_queue->mutex);
if (!async_queue->enabled) {
/* g_warning ("not enabled!"); */
@@ -56,7 +57,7 @@ gpointer mc_async_queue_pop (async_queue_t * async_queue)
}
if (!async_queue->head) {
- g_cond_wait (&async_queue->condition, &async_queue->mutex);
+ g_cond_wait(&async_queue->condition, &async_queue->mutex);
}
if (async_queue->head) {
@@ -64,26 +65,27 @@ gpointer mc_async_queue_pop (async_queue_t * async_queue)
data = node->data;
async_queue->head = node->next;
+
if (async_queue->head)
async_queue->head->prev = NULL;
else
async_queue->tail = NULL;
async_queue->length--;
- //LOGD("async queue poped : %p, %d, %p",queue, async_queue->length, data);
- g_list_free_1 (node);
+ /*LOGD("async queue poped : %p, %d, %p",queue, async_queue->length, data);*/
+ g_list_free_1(node);
}
leave:
- g_mutex_unlock (&async_queue->mutex);
+ g_mutex_unlock(&async_queue->mutex);
return data;
}
-gpointer mc_async_queue_pop_forced (async_queue_t * async_queue)
+gpointer mc_async_queue_pop_forced(async_queue_t *async_queue)
{
gpointer data = NULL;
- g_mutex_lock (&async_queue->mutex);
+ g_mutex_lock(&async_queue->mutex);
if (async_queue->head) {
GList *node = async_queue->head;
@@ -95,28 +97,28 @@ gpointer mc_async_queue_pop_forced (async_queue_t * async_queue)
else
async_queue->tail = NULL;
async_queue->length--;
- //LOGD("async queue poped : %p, %d, %p",queue, async_queue->length, data);
- g_list_free_1 (node);
+ /*LOGD("async queue poped : %p, %d, %p",queue, async_queue->length, data);*/
+ g_list_free_1(node);
}
- g_mutex_unlock (&async_queue->mutex);
+ g_mutex_unlock(&async_queue->mutex);
return data;
}
-void mc_async_queue_disable (async_queue_t * async_queue)
+void mc_async_queue_disable(async_queue_t *async_queue)
{
- g_mutex_lock (&async_queue->mutex);
+ g_mutex_lock(&async_queue->mutex);
async_queue->enabled = FALSE;
- g_cond_broadcast (&async_queue->condition);
- g_mutex_unlock (&async_queue->mutex);
+ g_cond_broadcast(&async_queue->condition);
+ g_mutex_unlock(&async_queue->mutex);
}
-void mc_async_queue_enable (async_queue_t * async_queue)
+void mc_async_queue_enable(async_queue_t *async_queue)
{
- g_mutex_lock (&async_queue->mutex);
+ g_mutex_lock(&async_queue->mutex);
async_queue->enabled = TRUE;
- g_mutex_unlock (&async_queue->mutex);
+ g_mutex_unlock(&async_queue->mutex);
}
void mc_async_queue_flush(async_queue_t *async_queue)
@@ -129,3 +131,9 @@ void mc_async_queue_flush(async_queue_t *async_queue)
g_mutex_unlock(&async_queue->mutex);
}
+
+gboolean mc_async_queue_is_empty(async_queue_t *async_queue)
+{
+ return async_queue->head == NULL;
+}
+
diff --git a/src/media_codec_util.c b/src/media_codec_util.c
index 71d8262..ee16f7f 100755
--- a/src/media_codec_util.c
+++ b/src/media_codec_util.c
@@ -5,16 +5,15 @@ void *mc_aligned_malloc(int size, int alignment)
unsigned char *pMem;
unsigned char *tmp;
- if((tmp = (unsigned char *)malloc(size + alignment)) != NULL)
- {
- pMem = (unsigned char*)((unsigned int)(tmp + alignment - 1) & (~(unsigned int)(alignment -1)));
+ if ((tmp = (unsigned char *)malloc(size + alignment)) != NULL) {
+ pMem = (unsigned char *)((unsigned int)(tmp + alignment - 1) & (~(unsigned int)(alignment - 1)));
- if(pMem == tmp)
+ if (pMem == tmp)
pMem += alignment;
*(pMem - 1) = (unsigned int)(pMem - tmp);
- return ((void*) pMem);
+ return ((void *) pMem);
}
return NULL;
}
@@ -23,7 +22,7 @@ void mc_aligned_free(void *mem)
{
unsigned char *ptr;
- if(mem == NULL)
+ if (mem == NULL)
return;
ptr = mem;
@@ -36,9 +35,7 @@ mc_sem_t *mc_sem_new()
{
mc_sem_t *sem;
sem = g_new(mc_sem_t, 1);
- //sem->cond = g_cond_new();
g_cond_init(&sem->cond);
- //sem->mutex = g_mutex_new();
g_mutex_init(&sem->mutex);
sem->counter = 0;
@@ -47,9 +44,7 @@ mc_sem_t *mc_sem_new()
void mc_sem_free(mc_sem_t *sem)
{
- //g_cond_free(sem->cond);
g_cond_clear(&sem->cond);
- //g_mutex_free(sem->mutex);
g_mutex_clear(&sem->mutex);
g_free(sem);
}
@@ -58,7 +53,7 @@ void mc_sem_down(mc_sem_t *sem)
{
g_mutex_lock(&sem->mutex);
- while(sem->counter == 0)
+ while (sem->counter == 0)
g_cond_wait(&sem->cond, &sem->mutex);
sem->counter--;
@@ -80,16 +75,14 @@ void mc_hex_dump(char *desc, void *addr, int len)
{
int i;
unsigned char buff[17];
- unsigned char *pc = (unsigned char*)addr;
+ unsigned char *pc = (unsigned char *)addr;
if (desc != NULL)
printf("%s:\n", desc);
- for (i = 0; i < len; i++)
- {
+ for (i = 0; i < len; i++) {
- if ((i % 16) == 0)
- {
+ if ((i % 16) == 0) {
if (i != 0)
printf(" %s\n", buff);
@@ -111,4 +104,3 @@ void mc_hex_dump(char *desc, void *addr, int len)
}
printf(" %s\n", buff);
}
-
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 7b7990e..e9400f4 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -20,4 +20,3 @@ FOREACH(src ${sources})
ADD_EXECUTABLE(${src_name} ${src})
TARGET_LINK_LIBRARIES(${src_name} capi-media-codec ${${fw_test}_LDFLAGS})
ENDFOREACH()
-
diff --git a/test/media_codec_test.c b/test/media_codec_test.c
index e0a0690..b390c8e 100755
--- a/test/media_codec_test.c
+++ b/test/media_codec_test.c
@@ -46,6 +46,19 @@
#define DEFAULT_SAMPLEBYTE 1024
#define ADTS_HEADER_SIZE 7
+/*
+ * 0 (disable) : used in (*.aac_lc, adts)
+ * 1 (enable) : used in (*.m4a, mp4), Need "codec_data"
+ * TODO : AAC_CODECDATA_SIZE is temporal size (16 byte) for codec_data
+ * TODO : WMA_CODECDATA_SIZE is temporal size (64 byte) for codec_data
+ */
+#if 1
+ #define AAC_CODECDATA_SIZE 16
+ #define WMA_CODECDATA_SIZE 64 /*MAX sizeof(WMAUDIO3WAVEFORMAT)*/
+ #define VORBIS_CODECDATA_SIZE 4096
+ #define FLAC_CODECDATA_SIZE 4096 /* MAX sizeof(2^24) */
+#endif
+
#define DUMP_OUTBUF 1
#define MAX_INPUT_BUF_NUM 20
#define USE_INPUT_QUEUE 1
@@ -80,17 +93,18 @@ int g_menu_state = CURRENT_STATUS_MAINMENU;
int g_handle_num = 1;
static mediacodec_h g_media_codec[MAX_HANDLE] = {0};
char g_uri[MAX_STRING_LEN];
+int g_len,bMultipleFiles;
FILE *fp_src = NULL;
media_format_h input_fmt = NULL;
#if USE_INPUT_QUEUE
-media_packet_h *input_buf = NULL;
+//media_packet_h *input_buf = NULL;
+media_packet_h input_buf[MAX_INPUT_BUF_NUM];
#else
media_packet_h in_buf = NULL;
#endif
media_packet_h output_buf = NULL;
-async_queue_t *input_avaliable = NULL;
-
-//static GThread *thread;
+//async_queue_t *input_avaliable = NULL;
+GQueue input_available;
uint64_t pts = 0;
@@ -106,6 +120,11 @@ static int bitrate = DEFAULT_BITRATE;
static int samplebyte = DEFAULT_SAMPLEBYTE;
unsigned char buf_adts[ADTS_HEADER_SIZE];
+unsigned char sps[100];
+unsigned char pps[100];
+unsigned char tmp_buf[1000000];
+static int sps_len, pps_len;
+
media_format_mimetype_e mimetype;
int use_video = 0;
@@ -113,6 +132,7 @@ int use_encoder = 0;
int frame_count = 0;
#if DUMP_OUTBUF
+int g_OutFileCtr;
FILE *fp_out = NULL;
#endif
//static gpointer _feed_pa(gpointer data);
@@ -146,16 +166,19 @@ unsigned int bytestream2nalunit(FILE *fd, unsigned char* nal)
int read_size = 1;
unsigned char buffer[1000000];
unsigned char val, zero_count, i;
+ int nal_unit_type;
+ int init;
zero_count = 0;
if (feof(fd))
- return 0;
+ return -1;
result = fread(buffer, 1, read_size, fd);
if(result != read_size)
{
- exit(1);
+ //exit(1);
+ return -1;
}
val = buffer[0];
while (!val)
@@ -178,6 +201,7 @@ unsigned int bytestream2nalunit(FILE *fd, unsigned char* nal)
nal[nal_length++] = 0;
nal[nal_length++] = 1;
zero_count = 0;
+ init = 1;
while(1)
{
if (feof(fd))
@@ -190,6 +214,10 @@ unsigned int bytestream2nalunit(FILE *fd, unsigned char* nal)
}
val = buffer[0];
+ if(init) {
+ nal_unit_type = val & 0xf;
+ init = 0;
+ }
if (!val)
{
zero_count++;
@@ -214,6 +242,27 @@ unsigned int bytestream2nalunit(FILE *fd, unsigned char* nal)
fseek(fd, -(zero_count + 1), SEEK_CUR);
+ if (nal_unit_type == 0x7)
+ {
+ sps_len = nal_length;
+ memcpy(sps, nal, nal_length);
+ return 0;
+ }
+ else if (nal_unit_type == 0x8)
+ {
+ pps_len = nal_length;
+ memcpy(pps, nal, nal_length);
+ return 0;
+ }
+ else if (nal_unit_type == 0x5)
+ {
+ memcpy(tmp_buf, nal, nal_length);
+ memcpy(nal, sps, sps_len);
+ memcpy(nal + sps_len, pps, pps_len);
+ memcpy(nal + sps_len + pps_len, tmp_buf, nal_length);
+ nal_length += sps_len + pps_len;
+ }
+
return nal_length;
}
@@ -231,7 +280,8 @@ unsigned int bytestream2yuv420(FILE *fd, unsigned char* yuv)
result = fread(buffer, 1,read_size, fd);
if(result != read_size)
{
- exit(1);
+ //exit(1);
+ return -1;
}
memcpy(yuv, buffer, width*height*3/2);
@@ -239,6 +289,121 @@ unsigned int bytestream2yuv420(FILE *fd, unsigned char* yuv)
return width*height*3/2;
}
+int bytestream2h263unit(FILE *fd, unsigned char* p)
+{
+ int len = 0;
+ size_t result;
+ int read_size = 1, state = 1, bStart = 0;
+ unsigned char val;
+
+ if (feof(fd))
+ return -1;
+
+ while(1)
+ {
+ if(fread(&val, 1, read_size, fd) != read_size)
+ return -1;
+ p[len] = val;
+ len += read_size;
+
+ switch(state)
+ {
+ case 1:
+ if(val==0x00)
+ state++;
+ break;
+ case 2:
+ if(val==0x00)
+ state++;
+ else
+ state = 1;
+ break;
+ case 3:
+ state = 1;
+ if((val&0xFC)==0x80)
+ {
+ if(bStart)
+ {
+ // Got next PSC
+ fseek(fd, -3, SEEK_CUR);
+ return len - 3;
+ }
+ else
+ {
+ bStart = 1;
+ // Flush header
+ len = 3;
+ p[0] = p[1] = 0;
+ p[2] = 0x80;
+ }
+ }
+ break;
+ }
+ }
+}
+
+int bytestream2mpeg4unit(FILE *fd, unsigned char* p,int* is_voss)
+{
+ int len = 0;
+ size_t result;
+ int read_size = 1, state = 1, bType=0;
+ unsigned char val;
+
+ if (feof(fd))
+ return -1;
+
+ while(1)
+ {
+ if(fread(&val, 1, read_size, fd) != read_size)
+ return -1;
+ p[len] = val;
+ len += read_size;
+
+ switch(state)
+ {
+ case 1:
+ if(val==0x00)
+ state++;
+ break;
+ case 2:
+ if(val==0x00)
+ state++;
+ else
+ state = 1;
+ break;
+ case 3:
+ if(val==0x01)
+ state++;
+ else
+ state = 1;
+ break;
+ case 4:
+ state = 1;
+ if(val==0xB0 || val==0xB6)
+ {
+ if(bType == 0xB6)
+ {
+ // Got next VOSS/IVOP
+ fseek(fd, -4, SEEK_CUR);
+ return len - 4;
+ }
+ if(!bType)
+ {
+ // Flush header
+ len = 4;
+ p[0] = p[1] = 0x00;
+ p[2] = 0x01;
+ p[3] = val;
+ if(is_voss && val==0xB0)
+ *is_voss = 1;
+ }
+ bType = val;
+ }
+ break;
+ }
+ }
+}
+
/**
* Extract Input data for MP3 decoder
@@ -274,6 +439,12 @@ unsigned int extract_input_mp3dec(FILE *fd, unsigned char* mp3data)
guint padding, bitrate, lsf, layer, mpg25;
guint hdr_bitrate, sf;
+ /*
+ * It is not support skip logicif ID3 Tag and Xing Header.
+ * So It MUST start as mp3 valid frame sequence.
+ * Testsuit that are not guaranteed to be available on functionality of all General DEMUXER/PARSER.
+ */
+
if (feof(fd))
return 0;
@@ -372,35 +543,525 @@ unsigned int extract_input_mp3dec(FILE *fd, unsigned char* mp3data)
/**
* Extract Input data for AAC decoder
* (case of (LC profile) ADTS format)
+ * codec_data : Don't need
**/
unsigned int extract_input_aacdec(FILE *fd, unsigned char* aacdata)
{
int readsize;
size_t result;
+ unsigned int header_size = ADTS_HEADER_SIZE;
+ unsigned char buffer[1000000];
+
+ if (feof(fd))
+ return 0;
+
+ result = fread(buffer, 1, header_size, fd); //adts header
+ if(result != header_size)
+ {
+ return -1;
+ }
+
+ if ((buffer != NULL) && (buffer[0] == 0xff) && ((buffer[1] & 0xf6) == 0xf0)) {
+ readsize = ((buffer[3] & 0x03) << 11) | (buffer[4] << 3) | ((buffer[5] & 0xe0) >> 5);
+ result = fread(buffer + header_size, 1,(readsize - header_size), fd);
+ memcpy(aacdata, buffer, readsize);
+ } else {
+ readsize = 0;
+ g_print("[FAIL] Not found aac frame sync.....\n");
+ }
+
+ return readsize;
+}
+
+/**
+ * Extract Input data for AAC decoder
+ * (case of (AAC+/EAAC+ profile) RAW format)
+ * codec_data : Need
+ * profile : AAC_LC(2) AAC_HE(5), AAC_HE_PS (29)
+ **/
+unsigned int extract_input_aacdec_m4a_test(FILE *fd, unsigned char* aacdata)
+{
+ int readsize = 0;
+ size_t result;
+ unsigned int header_size = ADTS_HEADER_SIZE;
unsigned char buffer[1000000];
+ unsigned char codecdata[AAC_CODECDATA_SIZE] = {0,};
+
+ /*
+ * It is not support full parsing MP4 container box.
+ * So It MUST start as RAW valid frame sequence.
+ * Testsuit that are not guaranteed to be available on functionality of all General DEMUXER/PARSER.
+ */
if (feof(fd))
return 0;
- result = fread(buffer, 1, 6, fd); //adts header
- if(result != 6)
+ if (frame_count == 0)
+ {
+ /*
+ * CAUTION : Codec data is needed only once in first time
+ * Codec data is made(or extracted) by MP4 demuxer in 'esds' box.
+ * So I use this data (byte) as hard coding for temporary our testing.
+ */
+#if 1
+ /*
+ * The codec_data data is according to AudioSpecificConfig,
+ * ISO/IEC 14496-3, 1.6.2.1
+ *
+ * below example is test for using "test.aac" or "TestSample-AAC-LC.m4a"
+ * case : M4A - LC profile
+ * codec_data=(buffer)119056e5000000000000000000000000
+ * savs aac decoder get codec_data. size: 16 (Tag size : 5 byte)
+ * - codec data: profile : 2
+ * - codec data: samplrate: 48000
+ * - codec data: channels : 2
+ */
+ /* 2 bytes are mandatory */
+ codecdata[0] = 0x11; //ex) (5bit) 2 (LC) / (4bit) 3 (48khz)
+ codecdata[1] = 0x90; //ex) (4bit) 2 (2ch)
+ /* othter bytes are (optional) epconfig information */
+ codecdata[2] = 0x56;
+ codecdata[3] = 0xE5;
+ codecdata[4] = 0x00;
+#else
+ /*
+ * below example is test for using "TestSample-EAAC+.m4a"
+ *
+ * case : M4A - HE-AAC v1 and v2 profile
+ * codec_data=(buffer)138856e5a54880000000000000000000
+ * savs aac decoder get codec_data. size: 16 (Tag size : 7 byte)
+ * - codec data: profile : 2
+ * - codec data: samplrate: 22050
+ * - codec data: channels : 1
+ */
+ /* 2 bytes are mandatory */
+ codecdata[0] = 0x13; //ex) (5bit) 2 (LC) / (4bit) 9 (22khz)
+ codecdata[1] = 0x88; //ex) (4bit) 1 (1ch)
+ /* othter bytes are (optional) epconfig information */
+ codecdata[2] = 0x56;
+ codecdata[3] = 0xE5;
+ codecdata[4] = 0xA5;
+ codecdata[5] = 0x48;
+ codecdata[6] = 0x80;
+#endif
+
+ memcpy(aacdata, codecdata, AAC_CODECDATA_SIZE);
+
+ result = fread(buffer, 1, header_size, fd); //adts header
+ if(result != header_size)
+ {
+ return -1;
+ }
+
+ if ((buffer != NULL) && (buffer[0] == 0xff) && ((buffer[1] & 0xf6) == 0xf0)) {
+ readsize = ((buffer[3] & 0x03) << 11) | (buffer[4] << 3) | ((buffer[5] & 0xe0) >> 5);
+ readsize = readsize -header_size;
+ result = fread(buffer, 1, readsize, fd); //Make only RAW data, so exclude header 7 bytes
+ memcpy(aacdata+AAC_CODECDATA_SIZE, buffer, readsize);
+ }
+
+ g_print( "[example] Insert 'codec_data' in 1st frame buffer size (%d)\n", readsize+AAC_CODECDATA_SIZE);
+ return (readsize + AAC_CODECDATA_SIZE); //return combination of (codec_data + raw_data)
+ }
+
+ result = fread(buffer, 1, header_size, fd); //adts header
+ if(result != header_size)
{
exit(1);
}
if ((buffer != NULL) && (buffer[0] == 0xff) && ((buffer[1] & 0xf6) == 0xf0)) {
readsize = ((buffer[3] & 0x03) << 11) | (buffer[4] << 3) | ((buffer[5] & 0xe0) >> 5);
- result = fread(buffer+6, 1,(readsize - 6), fd);
- memcpy(aacdata, buffer,readsize);
+ readsize = readsize -header_size;
+ result = fread(buffer, 1, readsize, fd); //Make only RAW data, so exclude header 7 bytes
+ memcpy(aacdata, buffer, readsize);
} else {
readsize = 0;
g_print("[FAIL] Not found aac frame sync.....\n");
}
+ return readsize; //return only raw_data
+}
+
+/**
+ * Extract Input data for AMR-NB/WB decoder
+ * - AMR-NB : mime type ("audio/AMR") / 8Khz / 1 ch / 16 bits
+ * - AMR-WB : mime type ("audio/AMR-WB") / 16Khz / 1 ch / 16 bits
+ **/
+static const char AMR_header [] = "#!AMR\n";
+static const char AMRWB_header [] = "#!AMR-WB\n";
+#define AMR_NB_MIME_HDR_SIZE 6
+#define AMR_WB_MIME_HDR_SIZE 9
+static const int block_size_nb[16] = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 };
+static const int block_size_wb[16] = { 17, 23, 32, 36, 40, 46, 50, 58, 60, 5, -1, -1, -1, -1, 0, 0 };
+int *blocksize_tbl;
+
+unsigned int extract_input_amrdec(FILE *fd, unsigned char* amrdata)
+{
+ int readsize = 0;
+ size_t result;
+ unsigned int mime_size = AMR_NB_MIME_HDR_SIZE;
+ unsigned char buffer[1000000];
+ unsigned int fsize, mode;
+
+ if (feof(fd))
+ return 0;
+
+ if (frame_count == 0)
+ {
+ /* Check if the given data contains an AMR mime header. */
+ result = fread(buffer, 1, mime_size, fd); //amr-nb header
+ if(result != mime_size)
+ return -1;
+
+ if ( !memcmp (buffer, AMR_header, AMR_NB_MIME_HDR_SIZE))
+ {
+ blocksize_tbl = (int *)block_size_nb;
+ g_print("[----AMR-NB mime header detected----]\n");
+ }
+ else
+ {
+ result = fread(buffer + mime_size, 1, 3, fd); //need more (3) bytes for checking amr-wb mime header
+ if (!memcmp (buffer, AMRWB_header, AMR_WB_MIME_HDR_SIZE))
+ {
+ mime_size = AMR_WB_MIME_HDR_SIZE;
+ blocksize_tbl = (int *)block_size_wb;
+ g_print("[----AMR-WB mime header detected----]\n");
+ }
+ else
+ {
+ g_print("[ERROR] AMR-NB/WB don't detected..\n");
+ return 0;
+ }
+ }
+ }
+
+ result = fread(buffer, 1, 1, fd); /* mode byte check */
+ if(result != 1)
+ return -1;
+ if ((buffer[0] & 0x83) == 0)
+ {
+ mode = (buffer[0] >> 3) & 0x0F; /* Yep. Retrieve the frame size */
+ fsize = blocksize_tbl[mode];
+
+ result = fread(buffer+1, 1, fsize, fd); /* +1 for the previous mode byte */
+ if(result != fsize)
+ return -1;
+ memcpy(amrdata, buffer, fsize);
+ readsize = fsize + 1;
+ } else {
+ readsize = 0;
+ g_print("[FAIL] Not found amr frame sync.....\n");
+ }
+
return readsize;
}
/**
+ * Extract Input data for WMA decoder
+ * codec_data : Need
+ * format : WMAV1, WMAV2, WMAPRO, WMALSL
+ **/
+ #if 1
+unsigned int extract_input_wmadec_test(FILE *fd, unsigned char* wmadata)
+{
+ int readsize = 0;
+ size_t result = 0;
+ unsigned char buffer[1000000];
+ unsigned char codecdata[WMA_CODECDATA_SIZE] = {0,};
+
+ /*
+ * It is not support full parsing ASF container.
+ * So It MUST start as each Payload sequence.
+ * Testsuit that are not guaranteed to be available on functionality of all General DEMUXER/PARSER.
+ */
+ if (feof(fd))
+ return 0;
+
+ if (frame_count == 0)
+ {
+ /* FIXME : temp test ONLY using case of 'test_t1.wma' that Generates a file for testing purposes
+ * This file is consist of
+ * - Only ES : each payload data (total = (16EA * 1024) bytes)
+ * Stream Format is (Codec_data(64 bytes) + ES) + ES + ES + ES ..
+ */
+ codecdata[0] = 0x00;
+ codecdata[1] = 0x00;
+ codecdata[2] = 0x00;
+ codecdata[3] = 0x00;
+ codecdata[4] = 0x01;
+ codecdata[5] = 0x00;
+ codecdata[6] = 0x00;
+ codecdata[7] = 0x00;
+ codecdata[8] = 0x00;
+ codecdata[9] = 0x00;
+
+ memcpy(wmadata, codecdata, WMA_CODECDATA_SIZE);
+
+ readsize = 1024; /* payload size */
+ result = fread(buffer, 1, readsize, fd);
+ if(result != readsize)
+ return -1;
+ memcpy(wmadata+WMA_CODECDATA_SIZE, buffer, readsize);
+
+ g_print( "[Info] Insert 'stream header (%d)' and 1st readsize (%d) in 1st frame buffer size (%d)\n",
+ WMA_CODECDATA_SIZE, readsize, readsize+WMA_CODECDATA_SIZE);
+ return ( WMA_CODECDATA_SIZE + readsize); //return combination of (codec_data + raw_data)
+
+ }
+
+ readsize = 1024; /* payload size */
+ result = fread(buffer, 1, readsize, fd);
+ if(result != readsize)
+ return -1;
+ memcpy(wmadata, buffer, readsize);
+
+ return readsize; //return only raw_data
+}
+#else
+unsigned int extract_input_wmadec_test_1(FILE *fd, unsigned char* wmadata)
+{
+ int readsize = 0;
+ size_t result = 0;
+ unsigned char buffer[1000000];
+ unsigned char codecdata[WMA_CODECDATA_SIZE] = {0,};
+
+ if (feof(fd))
+ return 0;
+
+ if (frame_count == 0)
+ {
+ /* FIXME : temp test ONLY using case of 'test_t1_2.wma'
+ * This file is consist of
+ * - Codec_data : 'Stream Type Specific(28 bytes)' in Stream Properties Object(ObjectID : B7DC0791-A9B7-11CF-8EE6-00C00C205365)
+ * -> 18 bytes (Stream Type Specific data) + 10 bytes (Extra data)
+ * -> 18 bytes is used for Caps
+ * -> 10 bytes is used for real codec_data
+ * - ES : each payload data (total = (16EA * 1024) bytes)
+ *
+ * Stream Format is (Codec_data(28 bytes) + ES) + ES + ES + ES ..
+ */
+ readsize = 28; /* Stream Type Specific size */
+ result = fread(codecdata, 1, readsize, fd);
+ memcpy(wmadata, codecdata, WMA_CODECDATA_SIZE);
+
+ readsize = 1024; /* 1st payload size */
+ result = fread(buffer, 1, readsize, fd);
+ if(result != readsize)
+ exit(1);
+ memcpy(wmadata+WMA_CODECDATA_SIZE, buffer, readsize);
+
+ g_print( "[example] Insert 'codec_data' in 1st frame buffer size (%d)\n", readsize+WMA_CODECDATA_SIZE);
+ return ( WMA_CODECDATA_SIZE + readsize); //return combination of (codec_data + raw_data)
+
+ }
+
+ readsize = 1024; /* payload size */
+ result = fread(buffer, 1, readsize, fd);
+ memcpy(wmadata, buffer, readsize);
+
+ return readsize; //return only raw_data
+}
+#endif
+
+/**
+ * Extract Input data for VORBIS decoder
+ * codec_data : Need as stream header pattern
+ * format : audio/x-vorbis
+ **/
+static const int Key0_t1_segment_size_tbl[12] = { 1, 1, 1, 47, 45, 99, 73, 74, 91,146, 1 }; /* Only Used for key0_t1.ogg */
+static const int Key0_t2_segment_size_tbl[15] = {30, 45, 3776, 1, 1, 1, 47, 45, 99, 73, 74, 91,146, 1 }; /* Only Used for key0_t1.ogg */
+int *psize_tbl;
+unsigned int extract_input_vorbisdec_test(FILE *fd, unsigned char* vorbisdata)
+{
+ int readsize = 0;
+ size_t result = 0;
+ unsigned char buffer[1000000];
+ unsigned char codecdata[VORBIS_CODECDATA_SIZE] = {0,};
+
+ /*
+ * It is not support full parsing OGG container.
+ * So It MUST start as each Segment sequence.
+ * Testsuit that are not guaranteed to be available on functionality of all General DEMUXER/PARSER.
+ */
+ if (feof(fd)) {
+ g_print("%s - [WARN][EOF] at frame_count (%4d)\n",__func__, frame_count);
+ return 0;
+ }
+
+ if (frame_count == 0)
+ {
+ /* FIXME : temp test ONLY using case of 'key0_t1.ogg' that Generates a file for testing purposes
+ * This file is consist of
+ * - Codec_data : 'vorbis header(3851 bytes)' in evey packet starts with a packet type byte(0x01, 0x03,0x05) and the 6 byte indentification string "vorbis"
+ * -> 30 bytes is used for Identifcation Header
+ * -> 45 bytes is used for Comment Header
+ * -> 3776 bytes is used for Setup Header
+ * - Only ES : each Segment data (total = 579 bytes for 10 frames)
+ * Stream Format is (Codec_data(4096 bytes) + ES) + ES + ES + ES ..
+ */
+
+ readsize = 3851; /* stream header size */
+ result = fread(codecdata, sizeof(char), readsize, fd);
+ if(result != readsize) {
+ g_print("%s - [ERROR] fread fail : readsize (%4d) at frame_count (%4d) \n",__func__, readsize, frame_count);
+ return -1;
+ }
+ memcpy(vorbisdata, codecdata, VORBIS_CODECDATA_SIZE);
+
+#if 0
+ psize_tbl = (int *)Key0_t1_segment_size_tbl;
+#else
+ fseek(fd, 0, SEEK_SET);
+ psize_tbl = (int *)Key0_t2_segment_size_tbl;
+#endif
+
+ readsize = psize_tbl[frame_count]; /* 1st segment size */
+ result = fread(buffer, 1, readsize, fd);
+ if(result != readsize) {
+ g_print("%s - [ERROR] fread fail : readsize (%4d) at frame_count (%4d) \n",__func__, readsize, frame_count);
+ return -1;
+ }
+ memcpy(vorbisdata+VORBIS_CODECDATA_SIZE, buffer, readsize);
+
+ g_print( "[Info] Insert 'stream header (%d)' and 1st readsize (%d) in 1st frame buffer size (%d)\n",
+ VORBIS_CODECDATA_SIZE, readsize, readsize+VORBIS_CODECDATA_SIZE);
+ return (VORBIS_CODECDATA_SIZE + readsize); //return combination of (codec_data + raw_data)
+
+ }
+
+ readsize = psize_tbl[frame_count]; /* next segment size */
+ result = fread(buffer, 1, readsize, fd);
+ if(result != readsize) {
+ g_print("%s - [ERROR] fread fail : readsize (%4d) at frame_count (%4d) \n",__func__, readsize, frame_count);
+ return -1;
+ }
+ memcpy(vorbisdata, buffer, readsize);
+
+ return readsize; //return only raw_data
+}
+
+/**
+ * Extract Input data for FLAC decoder
+ * codec_data : Need as stream header pattern
+ * format : audio/x-flac
+ **/
+static const int key0_segment_size_tbl[3+3] = { 4, 38, 44, 1940, 774 }; /* Only Used for key0.flac */
+static const int test_segment_size_tbl[3+11] = { 4, 38, 151, 6314, 5769, 6294, 5780, 6597, 9718, 8691, 8180, 7443, 7953, }; /* Only Used for test.flac */
+int *flac_psize_tbl;
+unsigned int extract_input_flacdec_test(FILE *fd, unsigned char* flacdata)
+{
+ int readsize = 0;
+ size_t result = 0;
+ unsigned char buffer[1000000];
+ unsigned char codecdata[FLAC_CODECDATA_SIZE] = {0,};
+ int codecdata_size = 0;
+ guint readsize1 = 0;
+ guint readsize2 = 0;
+
+ /*
+ * It is not support full parsing FLAC container.
+ * So It MUST start as each valid flac stream sequence.
+ * Testsuit that are not guaranteed to be available on functionality of all General FLAC PARSER.
+ */
+ if (feof(fd)) {
+ g_print("%s - [WARN][EOF] at frame_count (%4d)\n",__func__, frame_count);
+ return 0;
+ }
+
+ if (frame_count == 0)
+ {
+ /* FIXME : temp test ONLY using case of 'key0.flac' that original file for testing purposes
+ * This file is consist of
+ * - Stream: METADATA_BLOCK (INFO + COMMRNT) + FRAME (two frame (1940 + 774) bytes)
+ * Stream Format is (Codec_data(51 bytes) + ES) + ES..
+ */
+
+ /* Pre-append : add marker is madatory */
+ codecdata[0] = 0x7f;
+ codecdata[1] = 0x46; /* F */
+ codecdata[2] = 0x4c; /* L*/
+ codecdata[3] = 0x41; /* A */
+ codecdata[4] = 0x43; /* C */
+ codecdata[5] = 0x01; /* mapping version major */
+ codecdata[6] = 0x00; /* mapping version minor */
+ codecdata[7] = 0x00;
+ codecdata[8] = 0x02;
+
+ codecdata_size = 9;
+ memcpy(flacdata, codecdata, codecdata_size);
+
+ /* case1 : using fixed method of codec data size */
+ /* For 1st stream header */
+ readsize1 = 42; /* 'fLaC' + STREAMINFO (38) */
+ result = fread(codecdata + codecdata_size, 1, readsize1, fd);
+ if(result != readsize1) {
+ g_print("%s - [ERROR] fread fail : readsize1 (%4d) at frame_count (%4d) \n",__func__, readsize1, frame_count);
+ return -1;
+ }
+
+ /* For check valid marker */
+ if ((codecdata[9] == 0x66) && (codecdata[10] == 0x4c) && (codecdata[11] == 0x61) && (codecdata[12] == 0x43))
+ {
+ codecdata_size += readsize1;
+ } else {
+ g_print ("[ERROR] invalid maker\n");
+ return 0;
+ }
+
+ /* For 2nd stream header */
+ readsize2 = 4;
+ result = fread(codecdata + codecdata_size, 1, readsize2, fd);
+ if(result != readsize2) {
+ g_print("%s - [ERROR] fread fail : readsize (%4d) at frame_count (%4d) \n",__func__, readsize2, frame_count);
+ return -1;
+ }
+ if ((codecdata[51] & 0x7f) == 4)
+ {
+ codecdata_size += readsize2;
+ /* For size of 2nd stream header */
+ readsize2 = ((codecdata[52] << 16) | (codecdata[53] << 8) | (codecdata[54]));
+ result = fread(codecdata + codecdata_size, 1, readsize2, fd);
+ codecdata_size += readsize2;
+ if(result != readsize2) {
+ g_print("%s - [ERROR] fread fail : readsize (%4d) at frame_count (%4d) \n",__func__, readsize2, frame_count);
+ return -1;
+ }
+ memcpy(flacdata, codecdata, FLAC_CODECDATA_SIZE);
+ } else {
+ g_print ("[ERROR] invalid type(4) of vorbis comment \n");
+ return 0;
+ }
+
+ /* codec plugins don't used streamheader, So It want to fead direct file sequence */
+ fseek(fd, 0, SEEK_SET);
+ flac_psize_tbl = (int *)key0_segment_size_tbl;
+
+ readsize = flac_psize_tbl[frame_count]; /* 1st segment size */
+ result = fread(buffer, 1, readsize, fd);
+ if(result != readsize) {
+ g_print("%s - [ERROR] fread fail : readsize (%4d) at frame_count (%4d) \n",__func__, readsize, frame_count);
+ return -1;
+ }
+ memcpy(flacdata + FLAC_CODECDATA_SIZE, buffer, readsize);
+
+ g_print( "[Info] Insert 'stream header (%d)' and 1st readsize (%d) in 1st frame buffer size (%d)\n",
+ FLAC_CODECDATA_SIZE, readsize, readsize+FLAC_CODECDATA_SIZE);
+ return ( FLAC_CODECDATA_SIZE + readsize); //return combination of (codec_data + raw_data)
+ }
+
+ readsize = flac_psize_tbl[frame_count]; /* next segment size */
+ result = fread(buffer, 1, readsize, fd);
+ if(result != readsize) {
+ g_print("%s - [ERROR] fread fail : readsize (%4d) at frame_count (%4d) \n",__func__, readsize, frame_count);
+ return -1;
+ }
+ memcpy(flacdata, buffer, readsize);
+
+ return readsize; //return only raw_data
+}
+
+/**
* Extract Input data for AAC encoder
**/
unsigned int extract_input_aacenc(FILE *fd, unsigned char* rawdata)
@@ -416,7 +1077,7 @@ unsigned int extract_input_aacenc(FILE *fd, unsigned char* rawdata)
result = fread(buffer, 1, readsize, fd);
if(result != readsize)
{
- exit(1);
+ return -1;
}
memcpy(rawdata, buffer,readsize);
@@ -460,6 +1121,46 @@ void add_adts_header_for_aacenc(unsigned char *buffer, int packetLen) {
buffer[6] = (char)0xFC;
}
+
+/**
+ * Extract Input data for AMR-NB/WB encoder
+ * But, WB encoder is not support because we don't have WB decoder for reference.
+ **/
+#define AMRNB_PCM_INPUT_SIZE 320
+#define AMRWB_PCM_INPUT_SIZE 640
+#define AMRNB_ENC_TEST 1 /* 1: AMR-NB , 0: AMR-WB*/
+int write_amr_header = 1; /* write magic number for AMR Header at one time */
+unsigned int extract_input_amrenc(FILE *fd, unsigned char* rawdata, int is_amr_nb)
+{
+ int readsize;
+ size_t result;
+ unsigned char buffer[1000000];
+
+ if (feof(fd))
+ return 0;
+
+ if (is_amr_nb)
+ readsize = AMRNB_PCM_INPUT_SIZE;
+ else
+ readsize = AMRWB_PCM_INPUT_SIZE;
+
+ result = fread(buffer, 1, readsize, fd);
+ if(result != readsize)
+ {
+ return -1;
+ }
+
+ memcpy(rawdata, buffer,readsize);
+
+ if (frame_count == 0)
+ {
+ g_print("amr encoder input size (%d) - NB(320) / WB(640)\n", readsize);
+ }
+
+ return readsize;
+}
+
+
static void input_filepath(char *filename)
{
int len = strlen(filename);
@@ -488,9 +1189,15 @@ static void input_filepath(char *filename)
#if DUMP_OUTBUF
fp_out = fopen("/opt/usr/media/codec_dump.out", "wb");
+ g_OutFileCtr = 0;
#endif
strncpy (g_uri, filename, len);
+ g_len = len;
+
+ bMultipleFiles = 0;
+ if(g_uri[g_len-1] == '/')
+ bMultipleFiles = 1;
return;
}
@@ -501,14 +1208,15 @@ void _allocate_buf(void)
int i = 0;
// !!!! remove dependency on internal headers.
- input_avaliable = mc_async_queue_new();
- input_buf = (media_packet_h *)malloc(sizeof(media_packet_h)*MAX_INPUT_BUF_NUM);
+ //input_avaliable = mc_async_queue_new();
+ //input_buf = (media_packet_h *)malloc(sizeof(media_packet_h)*MAX_INPUT_BUF_NUM);
for (i = 0; i < MAX_INPUT_BUF_NUM; i++)
{
media_packet_create_alloc(input_fmt, NULL, NULL, &input_buf[i]);
g_print("input queue buf = %p\n", input_buf[i]);
- mc_async_queue_push(input_avaliable, input_buf[i]);
+ //mc_async_queue_push(input_avaliable, input_buf[i]);
+ g_queue_push_tail(&input_available, input_buf[i]);
}
#else
media_packet_create_alloc(input_fmt, NULL, NULL, &in_buf);
@@ -523,8 +1231,7 @@ void _free_buf(void)
{
int i = 0;
- if (input_avaliable)
- mc_async_queue_free(input_avaliable);
+ //mc_async_queue_free(input_avaliable);
if (input_buf)
{
@@ -537,9 +1244,10 @@ void _free_buf(void)
}
media_format_unref(input_fmt);
input_fmt = NULL;
- free(input_buf);
- input_buf = NULL;
+ //free(input_buf);
+ //input_buf = NULL;
}
+ g_queue_clear(&input_available);
return;
}
#endif
@@ -550,7 +1258,8 @@ static void _mediacodec_empty_buffer_cb(media_packet_h pkt, void *user_data)
{
#if USE_INPUT_QUEUE
media_packet_unset_flags(pkt, MEDIA_PACKET_CODEC_CONFIG);
- mc_async_queue_push(input_avaliable, pkt);
+ //mc_async_queue_push(input_avaliable, pkt);
+ g_queue_push_tail(&input_available, pkt);
g_print("availablebuf = %p\n", pkt);
#else
g_print("Used input buffer = %p\n", pkt);
@@ -574,6 +1283,13 @@ static void _mediacodec_eos_cb(void *user_data)
g_print("event : eos\n");
}
+static bool _mcdiacodec_supported_cb(mediacodec_codec_type_e type, void *user_data)
+{
+ if(type != -1)
+ g_printf("type : %x\n", type);
+ return true;
+}
+
void _mediacodec_destroy(void)
{
int i = 0;
@@ -604,7 +1320,7 @@ void _mediacodec_set_codec(int codecid, int flag)
{
int encoder = 0;
g_print("_mediacodec_configure\n");
- g_print("codecid = %x, flag = %d\n", codecid, flag);
+ g_print("codecid = 0x%x, flag = %d\n", codecid, flag);
if (g_media_codec[0] != NULL)
{
mediacodec_set_codec(g_media_codec[0], (mediacodec_codec_type_e)codecid, flag);
@@ -614,15 +1330,19 @@ void _mediacodec_set_codec(int codecid, int flag)
if (encoder)
{
//input_fmt->mimetype |= MEDIA_FORMAT_RAW;
- //input_fmt->mimetype |= MEDIA_FORMAT_NV12;
- mimetype |= MEDIA_FORMAT_RAW;
mimetype |= MEDIA_FORMAT_NV12;
+ mimetype |= MEDIA_FORMAT_RAW;
//mimetype |= MEDIA_FORMAT_I420;
}
else
{
//input_fmt->mimetype |= MEDIA_FORMAT_H264_SP;
- mimetype |= MEDIA_FORMAT_H264_SP;
+ if(codecid == MEDIACODEC_MPEG4)
+ mimetype |= MEDIA_FORMAT_MPEG4_SP;
+ else if(codecid == MEDIACODEC_H263)
+ mimetype |= MEDIA_FORMAT_H263;
+ else
+ mimetype |= MEDIA_FORMAT_H264_SP;
}
mimetype |= MEDIA_FORMAT_VIDEO;
}
@@ -635,13 +1355,33 @@ void _mediacodec_set_codec(int codecid, int flag)
}
else
{
- if (codecid == MEDIACODEC_AAC)
- mimetype |= MEDIA_FORMAT_AAC; /* MPEG-2 : (*.aac, adts) */
+ if (codecid == MEDIACODEC_AAC) /* same as MEDIACODEC_AAC_LC */
+ mimetype |= MEDIA_FORMAT_AAC; /* MPEG-2/4 : (*.aac, adts), need adts header */
+ else if (codecid == MEDIACODEC_AAC_HE)
+ mimetype |= MEDIA_FORMAT_AAC_HE; /* MPEG-4 : (*.m4a, mp4) */
+ else if (codecid == MEDIACODEC_AAC_HE_PS)
+ mimetype |= MEDIA_FORMAT_AAC_HE_PS; /* MPEG-4 : (*.m4a, mp4) */
else if (codecid == MEDIACODEC_MP3)
mimetype |= MEDIA_FORMAT_MP3;
+ else if (codecid == MEDIACODEC_AMR_NB)
+ mimetype |= MEDIA_FORMAT_AMR_NB;
+ else if (codecid == MEDIACODEC_AMR_WB)
+ mimetype |= MEDIA_FORMAT_AMR_WB;
+ else if (codecid == MEDIACODEC_VORBIS)
+ mimetype |= MEDIA_FORMAT_VORBIS;
+ else if (codecid == MEDIACODEC_FLAC)
+ mimetype |= MEDIA_FORMAT_FLAC;
+ else if (codecid == MEDIACODEC_WMAV1)
+ mimetype |= MEDIA_FORMAT_WMAV1;
+ else if (codecid == MEDIACODEC_WMAV2)
+ mimetype |= MEDIA_FORMAT_WMAV2;
+ else if (codecid == MEDIACODEC_WMAPRO)
+ mimetype |= MEDIA_FORMAT_WMAPRO;
+ else if (codecid == MEDIACODEC_WMALSL)
+ mimetype |= MEDIA_FORMAT_WMALSL;
}
mimetype |= MEDIA_FORMAT_AUDIO;
- g_print(" [audio test] mimetype (0x%x)\n", mimetype);
+ g_print("[audio test] mimetype (0x%x)\n", mimetype);
}
}
else
@@ -743,6 +1483,8 @@ void _mediacodec_prepare(void)
mediacodec_set_output_buffer_available_cb(g_media_codec[i], _mediacodec_fill_buffer_cb, g_media_codec[i]);
mediacodec_set_eos_cb(g_media_codec[i], _mediacodec_eos_cb, g_media_codec[i]);
+ mediacodec_foreach_supported_codec(g_media_codec[i], _mcdiacodec_supported_cb, g_media_codec[i]);
+
err = mediacodec_prepare(g_media_codec[i]);
if (err != MEDIACODEC_ERROR_NONE)
@@ -762,36 +1504,8 @@ void _mediacodec_prepare(void)
return;
}
-/*
-static gpointer
-feed_thread(gpointer data)
-{
- int i;
- int err = 0;
-
- for (i=0; i < g_handle_num; i++)
- {
- if(g_media_codec[i] != NULL)
- {
- mediacodec_unset_input_buffer_used_cb(g_media_codec[i]);
- mediacodec_unset_output_buffer_available_cb(g_media_codec[i]);
- err = mediacodec_unprepare(g_media_codec[i]);
- if (err != MEDIACODEC_ERROR_NONE)
- {
- g_print("mediacodec_unprepare failed error = %d \n", err);
- }
- }
- else
- {
- g_print("mediacodec handle is not created\n");
- }
- }
- g_print("mediacodec unprepare is called");
- return NULL;
-}
-*/
void _mediacodec_unprepare(void)
{
@@ -818,29 +1532,49 @@ void _mediacodec_unprepare(void)
}
}
frame_count = 0;
-
- //thread = g_thread_create(feed_thread, sejun, TRUE, NULL);
return;
}
+int extract_input_per_frame (FILE *fp, unsigned char *rawdata)
+{
+ int readsize=0;
+ size_t result = 0;
+ while (!feof(fp))
+ readsize += fread(rawdata+readsize, 1, 1, fp);
+ return readsize;
+}
int _mediacodec_process_input(void)
{
- g_print("_mediacodec_process_input\n");
- unsigned int buf_size = 0;
+// g_print("_mediacodec_process_input (frame_count :%d)\n", frame_count);
+ int buf_size = 0;
#if USE_INPUT_QUEUE
media_packet_h in_buf = NULL;
#endif
void *data = NULL;
- int ret = 0;
+ int ret = 0, codec_config=0;
+ mediacodec_s * handle = NULL;
+ mc_handle_t* mc_handle = NULL;
+ int err = MEDIACODEC_ERROR_NONE;
if (g_media_codec[0] == NULL)
{
g_print("mediacodec handle is not created\n");
return MEDIACODEC_ERROR_INVALID_PARAMETER;
}
+ else
+ {
+ handle = (mediacodec_s *) g_media_codec[0];
+ mc_handle = (mc_handle_t*) handle->mc_handle;
+ }
if (fp_src == NULL)
{
+ if (bMultipleFiles)
+ {
+ if(g_uri[g_len-1] != '/')
+ g_uri[g_len++] = '/';
+ sprintf(g_uri+g_len, "%05d", frame_count);
+ }
fp_src = fopen(g_uri, "r");
if (fp_src == NULL)
{
@@ -849,12 +1583,12 @@ int _mediacodec_process_input(void)
}
}
#if USE_INPUT_QUEUE
- in_buf = mc_async_queue_pop(input_avaliable);
+ //in_buf = mc_async_queue_pop(input_avaliable);
+ in_buf = g_queue_pop_head(&input_available);
#else
_allocate_buf();
#endif
-
if (in_buf != NULL)
{
media_packet_get_buffer_data_ptr(in_buf, &data);
@@ -865,7 +1599,25 @@ int _mediacodec_process_input(void)
{
if (use_video)
{
- buf_size = bytestream2yuv420(fp_src, data);
+ /*
+ * Video Encoder
+ */
+ if (bMultipleFiles)
+ {
+ buf_size = extract_input_per_frame(fp_src, data);
+ fclose(fp_src);
+ sprintf(g_uri+g_len, "%05d", frame_count+1);
+ fp_src = fopen(g_uri, "r");
+ if (fp_src == NULL)
+ {
+ media_packet_set_flags(in_buf, MEDIA_PACKET_END_OF_STREAM);
+ err = MEDIACODEC_ERROR_INVALID_INBUFFER;
+ }
+ }
+ else
+ {
+ buf_size = bytestream2yuv420(fp_src, data);
+ }
media_packet_set_pts (in_buf, pts);
g_print("input pts = %llu\n", pts);
if (fps != 0)
@@ -875,12 +1627,29 @@ int _mediacodec_process_input(void)
}
else
{
- buf_size = extract_input_aacenc(fp_src, data);
- media_packet_set_pts (in_buf, pts);
- g_print("input pts = %llu\n", pts);
- if (samplerate != 0)
+ /*
+ * Aduio Encoder - AAC /AMR-NB
+ */
+ if (mc_handle->codec_id == MEDIACODEC_AAC_LC)
+ {
+ buf_size = extract_input_aacenc(fp_src, data);
+ media_packet_set_pts (in_buf, pts);
+ g_print("input pts = %llu\n", pts);
+ if (samplerate != 0)
+ {
+ pts += ((GST_SECOND / samplerate) * samplebyte);
+ }
+ }
+ else if(mc_handle->codec_id == MEDIACODEC_AMR_NB)
+ {
+ buf_size = extract_input_amrenc(fp_src, data, 1);
+ media_packet_set_pts (in_buf, pts);
+ g_print("input pts = %llu\n", pts);
+ pts += (GST_SECOND / 50); /* (20ms/frame) AMR_FRAMES_PER_SECOND = 50 */
+ }
+ else
{
- pts += ((GST_SECOND / samplerate) * samplebyte);
+ g_print(" [Input process] Not Suppor Audio Encodert!!!!! - mimetype (0x%x) codecid (0x%x)\n", mimetype, mc_handle->codec_id);
}
}
}
@@ -888,38 +1657,184 @@ int _mediacodec_process_input(void)
{
if (use_video)
{
- if(frame_count == 0)
- ret = media_packet_set_flags(in_buf, MEDIA_PACKET_CODEC_CONFIG);
- else if(frame_count == 300)
- ret = media_packet_set_flags(in_buf, MEDIA_PACKET_END_OF_STREAM);
+ /*
+ * Video Decoder
+ */
+ //else if(frame_count == 150)
+ // ret = media_packet_set_flags(in_buf, MEDIA_PACKET_END_OF_STREAM);
+ switch(mimetype)
+ {
+ case MEDIA_FORMAT_H264_SP:
+ case MEDIA_FORMAT_H264_MP:
+ case MEDIA_FORMAT_H264_HP:
+ {
+ buf_size = bytestream2nalunit(fp_src, data);
+
+ if(frame_count == 2)
+ ret = media_packet_set_flags(in_buf, MEDIA_PACKET_CODEC_CONFIG);
+ }
+ break;
+
+ case MEDIA_FORMAT_MPEG4_SP:
+ case MEDIA_FORMAT_MPEG4_ASP:
+ codec_config = 0;
+ if(bMultipleFiles)
+ {
+ buf_size = extract_input_per_frame(fp_src, data);
+ /* check for voss for setting codec_data flag 0x000001B0 */
+ if(*(int*)data==0xb0010000)
+ codec_config = 1;
+ fclose(fp_src);
+ sprintf(g_uri+g_len, "%05d", frame_count+1);
+ fp_src = fopen(g_uri, "r");
+
+ if (fp_src == NULL)
+ {
+ media_packet_set_flags(in_buf, MEDIA_PACKET_END_OF_STREAM);
+ err = MEDIACODEC_ERROR_INVALID_INBUFFER;
+ }
+ }
+ else
+ {
+ buf_size = bytestream2mpeg4unit(fp_src,data,&codec_config);
+ }
+ if(codec_config)
+ {
+ ret = media_packet_set_flags(in_buf, MEDIA_PACKET_CODEC_CONFIG);
+ g_print("%s MPEG4 frame Set Codec Config\n",__func__);
+ }
+ break;
- buf_size = bytestream2nalunit(fp_src, data);
+ case MEDIA_FORMAT_H263:
+ case MEDIA_FORMAT_H263P:
+ if(bMultipleFiles)
+ {
+ buf_size = extract_input_per_frame(fp_src, data);
+ fclose(fp_src);
+ sprintf(g_uri+g_len, "%05d", frame_count+1);
+ fp_src = fopen(g_uri, "r");
+ if (fp_src == NULL)
+ {
+ media_packet_set_flags(in_buf, MEDIA_PACKET_END_OF_STREAM);
+ err = MEDIACODEC_ERROR_INVALID_INBUFFER;
+ }
+ }
+ else
+ {
+ buf_size = bytestream2h263unit(fp_src,data);
+ }
+ break;
+
+ default:
+ g_print("packet feeding not support for this codec type\n",__func__);
+ break;
+ }
+//mc_hex_dump("nal",data, 16);
}
else
{
- if (mimetype == MEDIA_FORMAT_AAC)
+ /*
+ * Audio Decoder - MP3
+ * - AAC_LC (adts)
+ * - AAC_LC (raw) / AAC_HE (v1) / AAC_HE_PS (v2)
+ * - AMR-NB / AMR-WB
+ */
+ if (mimetype == MEDIA_FORMAT_AAC_LC)
{
- buf_size = extract_input_aacdec(fp_src, data);
+#if 1 /* ORG */
+ /* It is available case of MEDIA_FORMAT_AAC_LC (ADTS) */
+ buf_size = extract_input_aacdec(fp_src, data);
+#else /* temp TEST (aac-lc raw) using codec data */
+ /* It is also available case of MEDIA_FORMAT_AAC_LC (RAW) */
+ if(frame_count[i] == 0) {
+ g_print("%s -[LEO] Enable 'AAC_LC_RAW' for *.mp4 or *.m4a case\n",__func__);
+ ret = media_packet_set_flags(in_buf, MEDIA_PACKET_CODEC_CONFIG);
+ //To-Do for inserting codec_data
+ }
+ buf_size = extract_input_aacdec_m4a_test(fp_src, data, i);
+#endif
+ }
+ else if (mimetype == MEDIA_FORMAT_AAC_HE || mimetype == MEDIA_FORMAT_AAC_HE_PS)
+ {
+ if(frame_count == 0) {
+ g_print("%s -Enable 'HE_AAC_V12_ENABLE' for *.mp4 or *.m4a case\n",__func__);
+ ret = media_packet_set_flags(in_buf, MEDIA_PACKET_CODEC_CONFIG);
+ //To-Do for inserting codec_data
+ }
+ buf_size = extract_input_aacdec_m4a_test(fp_src, data);
}
else if (mimetype == MEDIA_FORMAT_MP3)
{
buf_size = extract_input_mp3dec(fp_src, data);
}
+ else if (mimetype == MEDIA_FORMAT_AMR_NB || mimetype == MEDIA_FORMAT_AMR_WB)
+ {
+ buf_size = extract_input_amrdec(fp_src, data);
+ }
+ else if (mimetype == MEDIA_FORMAT_WMAV1 || mimetype == MEDIA_FORMAT_WMAV2 ||
+ mimetype == MEDIA_FORMAT_WMAPRO || mimetype == MEDIA_FORMAT_WMALSL)
+ {
+ if (frame_count == 0) {
+ g_print("%s -Enable 'MEDIA_PACKET_CODEC_CONFIG' for *.wma case\n",__func__);
+ ret = media_packet_set_flags(in_buf, MEDIA_PACKET_CODEC_CONFIG);
+ //Need 'To-Do' for inserting codec_data
+ }
+ buf_size = extract_input_wmadec_test(fp_src, data);
+ }
+ else if (mimetype == MEDIA_FORMAT_VORBIS)
+ {
+ if (frame_count == 0) {
+ g_print("%s -Enable 'MEDIA_PACKET_CODEC_CONFIG' for *.ogg case\n",__func__);
+ ret = media_packet_set_flags(in_buf, MEDIA_PACKET_CODEC_CONFIG);
+ //Need 'To-Do' for inserting streamheader
+ }
+ buf_size = extract_input_vorbisdec_test(fp_src, data);
+ }
+ else if (mimetype == MEDIA_FORMAT_FLAC)
+ {
+ if (frame_count == 0) {
+ g_print("%s -Enable 'MEDIA_PACKET_CODEC_CONFIG' for *.flac case\n",__func__);
+ ret = media_packet_set_flags(in_buf, MEDIA_PACKET_CODEC_CONFIG);
+ //Need 'To-Do' for inserting streamheader
+ }
+ buf_size = extract_input_flacdec_test(fp_src, data);
+ }
+ else
+ {
+ g_print(" [Input process] Not Suppor Audio Decodert!!!!! - mimetype (0x%x) codecid (0x%x)\n", mimetype, mc_handle->codec_id);
+ }
}
}
- if (buf_size == 0)
+ if (buf_size >= 0)
{
- g_print("input file read failed\n");
- return MEDIACODEC_ERROR_INVALID_PARAMETER;
- }
+ if (use_video && buf_size == 4)
+ {
+ media_packet_set_flags(in_buf, MEDIA_PACKET_END_OF_STREAM);
+ media_packet_set_buffer_size(in_buf, 4);
+ mediacodec_process_input (g_media_codec[0], in_buf, 0);
+ g_printf("eos packet is sent\n");
+
+ return MEDIACODEC_ERROR_INVALID_INBUFFER;
+ }
+ media_packet_set_buffer_size(in_buf, buf_size);
+ g_print("%s - input_buf size = %4d (0x%x) at %4d frame, %p\n",__func__, buf_size, buf_size, frame_count, in_buf);
- media_packet_set_buffer_size(in_buf, buf_size);
- g_print("%s - input_buf size = %d (0x%x), frame_count : %d\n",__func__, buf_size, buf_size, frame_count);
- ret = mediacodec_process_input (g_media_codec[0], in_buf, 0);
- if(frame_count == 300)
+ ret = mediacodec_process_input (g_media_codec[0], in_buf, 0);
+ if (use_video && buf_size == -1)
+ {
+ g_print("%s - END : input_buf size = %d frame_count : %d\n",__func__, buf_size, frame_count);
+ return MEDIACODEC_ERROR_INVALID_INBUFFER;
+ }
+ }
+ else
+ {
+ g_print("%s - [WARN] Check to input buf_size = %4d at %4d frame, %p\n",__func__, buf_size, frame_count, in_buf);
return MEDIACODEC_ERROR_INVALID_INBUFFER;
+ }
+
frame_count++;
+
return ret;
}
@@ -931,32 +1846,78 @@ int _mediacodec_get_output(void)
int err = 0;
uint64_t buf_size = 0;
void *data = NULL;
+ mediacodec_s * handle = NULL;
+ mc_handle_t* mc_handle = NULL;
+
g_print("_mediacodec_get_output\n");
if (g_media_codec[0] == NULL)
{
g_print("mediacodec handle is not created\n");
return MEDIACODEC_ERROR_INVALID_PARAMETER;
}
+ else
+ {
+ handle = (mediacodec_s *) g_media_codec[0];
+ mc_handle = (mc_handle_t*) handle->mc_handle;
+ }
err = mediacodec_get_output(g_media_codec[0], &output_buf, 0);
if( err == MEDIACODEC_ERROR_NONE)
{
media_packet_get_buffer_size(output_buf, &buf_size);
- g_print("%s - output_buf size =%p, %lld\n",__func__, output_buf, buf_size);
+ g_print("%s - output_buf size = %lld\n",__func__, buf_size);
#if DUMP_OUTBUF
media_packet_get_buffer_data_ptr(output_buf, &data);
+
if ((!use_video) && (use_encoder))
{
- if (buf_size > 0)
+ /*
+ * Prepend Header For Aduio Encoder of AAC(adts) and AMR-NB
+ */
+ if (mc_handle->codec_id == MEDIACODEC_AAC_LC)
{
- /* This is used only AAC encoder case for adding each ADTS frame header */
- add_adts_header_for_aacenc(buf_adts, (buf_size+ADTS_HEADER_SIZE));
- fwrite(&buf_adts[0], 1, ADTS_HEADER_SIZE, fp_out);
+ if (buf_size > 0)
+ {
+ /* This is used only AAC encoder case for adding each ADTS frame header */
+ add_adts_header_for_aacenc(buf_adts, (buf_size+ADTS_HEADER_SIZE));
+ fwrite(&buf_adts[0], 1, ADTS_HEADER_SIZE, fp_out);
+ }
+ }
+ else if (mc_handle->codec_id == MEDIACODEC_AMR_NB)
+ {
+ if ((buf_size > 0) && (write_amr_header == 1))
+ {
+ /* This is used only AMR encoder case for adding AMR masic header in only first frame */
+ g_print("%s - AMR_header write in first frame\n",__func__);
+ fwrite(&AMR_header[0], 1, sizeof(AMR_header) - 1, fp_out); /* AMR-NB magic number */
+ write_amr_header = 0;
+ }
}
}
if (data != NULL)
+ {
fwrite(data, 1, buf_size, fp_out);
+
+ // if g_OutFileCtr is set to 1 by developer, dump the output frame by frame in specified output folder
+ if(g_OutFileCtr)
+ {
+ FILE* fp;
+ char str[200];
+ sprintf(str,"/media/frames/%05d", g_OutFileCtr-1);
+ fp = fopen(str,"wb");
+ if(fp)
+ {
+ g_OutFileCtr++;
+ fwrite(data, 1, buf_size, fp);
+ fclose(fp);
+ }
+ else
+ {
+ g_OutFileCtr = 0; // Avoid trying to open file next time
+ }
+ }
+ }
#endif
// printf("%s - output_buf : %p\n",__func__, output_buf);
// mediacodec_reset_output_buffer(g_media_codec[0], &output_buf);
@@ -1015,20 +1976,58 @@ void _mediacodec_get_output_n(int num)
}
return;
}
+static gpointer vdec_task(gpointer data)
+{
+ int i;
+ //TODO extract packets from MediaDemuxer
+ /*
+ for(i=0; demuxer->get_track_count; i++)
+ {
+ }
+ */
+ return NULL;
+}
void _mediacodec_process_all(void)
{
g_print("_mediacodec_process_all\n");
int ret = MEDIACODEC_ERROR_NONE;
+ GThread *vdec_thread, *venc_thread, *adec_thread, *aenc_thread;
while(1)
{
ret = _mediacodec_process_input();
- if(ret != MEDIACODEC_ERROR_NONE)
+ if(ret != MEDIACODEC_ERROR_NONE) {
+ g_print ("_mediacodec_process_input ret = %d\n", ret);
break;
+ }
+ }
+
+/*
+ if(use_encoder)
+ {
+ if(use_video)
+ {
+ }
+ else
+ {
+ }
}
+ else
+ {
+ if(use_video)
+ {
+ vdec_thread = g_thread_create(vdec_task, NULL, TRUE, NULL);
+
+ g_thread_join(vdec_thread);
+ }
+ else
+ {
+ }
+ }
+*/
return;
}
@@ -1147,6 +2146,39 @@ static void displaymenu(void)
}
else if (g_menu_state == CURRENT_STATUS_SET_CODEC)
{
+#if 1 //NEW
+ g_print("*** Codec id : Select Codec ID Number (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(" -------------------\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(" -------------------\n");
+ g_print("*** Flags : Select Combination Number (e.g. DEOCDER + TYPE_SW = 10)\n");
+ g_print(" CODEC : ENCODER = 1 DECODER = 2\n");
+ g_print(" TYPE : HW = 4 SW = 8\n");
+ g_print(" TYPE : OMX = 16 GEN = 32\n");
+ g_print("*** input codec id, flags.\n");
+#else
g_print("*** Codec id : L16 = 1 Flags : MEDIACODEC_ENCODER = 1\n");
g_print(" ALAW = 2 MEDIACODEC_DECODER = 2\n");
g_print(" ULAW = 3 MEDIACODEC_SUPPORT_TYPE_HW = 4,\n");
@@ -1161,7 +2193,8 @@ static void displaymenu(void)
g_print(" MPEG1 = 105\n");
g_print(" MPEG2 = 106\n");
g_print(" MPEG4 = 107\n");
- g_print("*** input codec id, flags.\n");
+ g_print("*** input codec id, falgs.\n");
+#endif
}
else if (g_menu_state == CURRENT_STATUS_SET_VDEC_INFO)
{
@@ -1173,11 +2206,11 @@ static void displaymenu(void)
}
else if (g_menu_state == CURRENT_STATUS_SET_ADEC_INFO)
{
- g_print("*** input audio decode configure.(samplerate, channel, bit)\n");
+ g_print("*** input audio decode configure.(samplerate, channel, bit (e.g. 48000, 2, 16))\n");
}
else if (g_menu_state == CURRENT_STATUS_SET_AENC_INFO)
{
- g_print("*** input audio encode configure.(samplerate, channel, bit, bitrate)\n");
+ g_print("*** input audio encode configure.(samplerate, channel, bit, bitrate (e.g. 48000, 2, 16, 128000))\n");
}
else if (g_menu_state == CURRENT_STATUS_PROCESS_INPUT)
{
@@ -1230,7 +2263,15 @@ static void interpret (char *cmd)
case 0:
tmp = atoi(cmd);
- if(tmp > 100)
+#if 1 //NEW - ToDo : TEST for case of MP3 (112 = 0x70), VORBIS(128), FLAC(144), WMA(160~163)
+ if(tmp > 100 &&
+ (tmp != 112) &&
+ (tmp != 128) &&
+ (tmp != 144) &&
+ (tmp != 160) && (tmp != 161) && (tmp != 162) && (tmp != 163)) //Temporary
+#else
+ if(tmp > 100) //orginal
+#endif
{
tmp = strtol(cmd, ptr, 16);
codecid = 0x2000 + ((tmp & 0xFF) << 4);
@@ -1238,7 +2279,11 @@ static void interpret (char *cmd)
}
else
{
+#if 1 //NEW
+ codecid = 0x1000 + tmp;
+#else
codecid = 0x1000 + (tmp<<4);
+#endif
}
cnt++;
break;
@@ -1385,18 +2430,18 @@ static void display_sub_basic()
g_print("=========================================================================================\n");
g_print(" media codec test\n");
g_print("-----------------------------------------------------------------------------------------\n");
- g_print("a. Create \t");
- g_print("sc. Set codec \t\t");
- g_print("vd. Set vdec info w, h\t");
+ g_print("a. Create \t\t");
+ g_print("sc. Set codec \n");
+ g_print("vd. Set vdec info \t");
g_print("ve. Set venc info \n");
- g_print("ad. Set adec info s, c, b\t");
+ g_print("ad. Set adec info \t");
g_print("ae. Set aenc info \n");
- g_print("pr. Prepare \t");
- g_print("pi. Process input \t");
+ g_print("pr. Prepare \t\t");
+ g_print("pi. Process input \n");
g_print("o. Get output \t\t");
g_print("rb. Reset output buffer \n");
g_print("pa. Process all frames \n");
- g_print("un. Unprepare \t");
+ g_print("un. Unprepare \t\t");
g_print("dt. Destroy \t\t");
g_print("q. quite test suite \t");
g_print("\n");
diff --git a/test/test_samples/sample_mpeg4/00000 b/test/test_samples/sample_mpeg4/00000
new file mode 100644
index 0000000..9fe87ee
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00000
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00001 b/test/test_samples/sample_mpeg4/00001
new file mode 100644
index 0000000..2bb3c75
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00001
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00002 b/test/test_samples/sample_mpeg4/00002
new file mode 100644
index 0000000..c87335c
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00002
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00003 b/test/test_samples/sample_mpeg4/00003
new file mode 100644
index 0000000..b847bd8
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00003
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00004 b/test/test_samples/sample_mpeg4/00004
new file mode 100644
index 0000000..0ce410b
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00004
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00005 b/test/test_samples/sample_mpeg4/00005
new file mode 100644
index 0000000..68a2b92
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00005
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00006 b/test/test_samples/sample_mpeg4/00006
new file mode 100644
index 0000000..2c8b4d3
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00006
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00007 b/test/test_samples/sample_mpeg4/00007
new file mode 100644
index 0000000..2d37adf
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00007
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00008 b/test/test_samples/sample_mpeg4/00008
new file mode 100644
index 0000000..55be446
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00008
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00009 b/test/test_samples/sample_mpeg4/00009
new file mode 100644
index 0000000..302ba22
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00009
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00010 b/test/test_samples/sample_mpeg4/00010
new file mode 100644
index 0000000..d5c4561
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00010
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00011 b/test/test_samples/sample_mpeg4/00011
new file mode 100644
index 0000000..4d85436
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00011
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00012 b/test/test_samples/sample_mpeg4/00012
new file mode 100644
index 0000000..bdb2245
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00012
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00013 b/test/test_samples/sample_mpeg4/00013
new file mode 100644
index 0000000..29dc6b5
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00013
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00014 b/test/test_samples/sample_mpeg4/00014
new file mode 100644
index 0000000..64cafd0
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00014
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00015 b/test/test_samples/sample_mpeg4/00015
new file mode 100644
index 0000000..00feaca
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00015
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00016 b/test/test_samples/sample_mpeg4/00016
new file mode 100644
index 0000000..f9e9a0f
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00016
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00017 b/test/test_samples/sample_mpeg4/00017
new file mode 100644
index 0000000..9a2d75f
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00017
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00018 b/test/test_samples/sample_mpeg4/00018
new file mode 100644
index 0000000..decf4a0
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00018
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00019 b/test/test_samples/sample_mpeg4/00019
new file mode 100644
index 0000000..8c05bca
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00019
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00020 b/test/test_samples/sample_mpeg4/00020
new file mode 100644
index 0000000..1e0591e
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00020
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00021 b/test/test_samples/sample_mpeg4/00021
new file mode 100644
index 0000000..e01d631
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00021
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00022 b/test/test_samples/sample_mpeg4/00022
new file mode 100644
index 0000000..5a1eec2
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00022
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00023 b/test/test_samples/sample_mpeg4/00023
new file mode 100644
index 0000000..472b97f
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00023
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00024 b/test/test_samples/sample_mpeg4/00024
new file mode 100644
index 0000000..bfd7017
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00024
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00025 b/test/test_samples/sample_mpeg4/00025
new file mode 100644
index 0000000..046a5ed
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00025
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00026 b/test/test_samples/sample_mpeg4/00026
new file mode 100644
index 0000000..3679c9a
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00026
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00027 b/test/test_samples/sample_mpeg4/00027
new file mode 100644
index 0000000..6cf1066
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00027
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00028 b/test/test_samples/sample_mpeg4/00028
new file mode 100644
index 0000000..c386c14
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00028
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00029 b/test/test_samples/sample_mpeg4/00029
new file mode 100644
index 0000000..609452d
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00029
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00030 b/test/test_samples/sample_mpeg4/00030
new file mode 100644
index 0000000..629ecce
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00030
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00031 b/test/test_samples/sample_mpeg4/00031
new file mode 100644
index 0000000..69bb74a
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00031
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00032 b/test/test_samples/sample_mpeg4/00032
new file mode 100644
index 0000000..fd494b5
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00032
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00033 b/test/test_samples/sample_mpeg4/00033
new file mode 100644
index 0000000..dcd15a5
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00033
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00034 b/test/test_samples/sample_mpeg4/00034
new file mode 100644
index 0000000..70b100a
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00034
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00035 b/test/test_samples/sample_mpeg4/00035
new file mode 100644
index 0000000..f677dad
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00035
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00036 b/test/test_samples/sample_mpeg4/00036
new file mode 100644
index 0000000..ec1a7e8
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00036
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00037 b/test/test_samples/sample_mpeg4/00037
new file mode 100644
index 0000000..e3a97c0
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00037
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00038 b/test/test_samples/sample_mpeg4/00038
new file mode 100644
index 0000000..f4e0e36
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00038
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00039 b/test/test_samples/sample_mpeg4/00039
new file mode 100644
index 0000000..ab306d1
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00039
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00040 b/test/test_samples/sample_mpeg4/00040
new file mode 100644
index 0000000..9654862
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00040
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00041 b/test/test_samples/sample_mpeg4/00041
new file mode 100644
index 0000000..494199d
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00041
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00042 b/test/test_samples/sample_mpeg4/00042
new file mode 100644
index 0000000..d587d9b
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00042
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00043 b/test/test_samples/sample_mpeg4/00043
new file mode 100644
index 0000000..fb95f36
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00043
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00044 b/test/test_samples/sample_mpeg4/00044
new file mode 100644
index 0000000..b3c0924
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00044
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00045 b/test/test_samples/sample_mpeg4/00045
new file mode 100644
index 0000000..f126cc1
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00045
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00046 b/test/test_samples/sample_mpeg4/00046
new file mode 100644
index 0000000..667e973
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00046
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00047 b/test/test_samples/sample_mpeg4/00047
new file mode 100644
index 0000000..164b22a
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00047
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00048 b/test/test_samples/sample_mpeg4/00048
new file mode 100644
index 0000000..159be6a
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00048
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00049 b/test/test_samples/sample_mpeg4/00049
new file mode 100644
index 0000000..765b9e7
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00049
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00050 b/test/test_samples/sample_mpeg4/00050
new file mode 100644
index 0000000..1ff4292
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00050
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00051 b/test/test_samples/sample_mpeg4/00051
new file mode 100644
index 0000000..080e5b6
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00051
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00052 b/test/test_samples/sample_mpeg4/00052
new file mode 100644
index 0000000..0328527
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00052
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00053 b/test/test_samples/sample_mpeg4/00053
new file mode 100644
index 0000000..aa47e71
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00053
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00054 b/test/test_samples/sample_mpeg4/00054
new file mode 100644
index 0000000..f7b0ea7
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00054
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00055 b/test/test_samples/sample_mpeg4/00055
new file mode 100644
index 0000000..bc58546
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00055
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00056 b/test/test_samples/sample_mpeg4/00056
new file mode 100644
index 0000000..0938c91
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00056
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00057 b/test/test_samples/sample_mpeg4/00057
new file mode 100644
index 0000000..a28a399
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00057
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00058 b/test/test_samples/sample_mpeg4/00058
new file mode 100644
index 0000000..7962b94
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00058
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00059 b/test/test_samples/sample_mpeg4/00059
new file mode 100644
index 0000000..ba9c8c8
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00059
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00060 b/test/test_samples/sample_mpeg4/00060
new file mode 100644
index 0000000..8d1e482
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00060
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00061 b/test/test_samples/sample_mpeg4/00061
new file mode 100644
index 0000000..bdbd18f
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00061
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00062 b/test/test_samples/sample_mpeg4/00062
new file mode 100644
index 0000000..0ed6743
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00062
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00063 b/test/test_samples/sample_mpeg4/00063
new file mode 100644
index 0000000..742c36d
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00063
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00064 b/test/test_samples/sample_mpeg4/00064
new file mode 100644
index 0000000..07310d0
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00064
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00065 b/test/test_samples/sample_mpeg4/00065
new file mode 100644
index 0000000..c89ba06
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00065
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00066 b/test/test_samples/sample_mpeg4/00066
new file mode 100644
index 0000000..b9fa77b
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00066
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00067 b/test/test_samples/sample_mpeg4/00067
new file mode 100644
index 0000000..c688e67
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00067
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00068 b/test/test_samples/sample_mpeg4/00068
new file mode 100644
index 0000000..8994657
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00068
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00069 b/test/test_samples/sample_mpeg4/00069
new file mode 100644
index 0000000..31be525
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00069
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00070 b/test/test_samples/sample_mpeg4/00070
new file mode 100644
index 0000000..fcd920f
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00070
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00071 b/test/test_samples/sample_mpeg4/00071
new file mode 100644
index 0000000..544849d
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00071
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00072 b/test/test_samples/sample_mpeg4/00072
new file mode 100644
index 0000000..e28d543
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00072
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00073 b/test/test_samples/sample_mpeg4/00073
new file mode 100644
index 0000000..607a281
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00073
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00074 b/test/test_samples/sample_mpeg4/00074
new file mode 100644
index 0000000..6fcdb61
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00074
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00075 b/test/test_samples/sample_mpeg4/00075
new file mode 100644
index 0000000..f9943b1
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00075
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00076 b/test/test_samples/sample_mpeg4/00076
new file mode 100644
index 0000000..8637bbe
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00076
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00077 b/test/test_samples/sample_mpeg4/00077
new file mode 100644
index 0000000..c2f1dd6
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00077
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00078 b/test/test_samples/sample_mpeg4/00078
new file mode 100644
index 0000000..9753748
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00078
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00079 b/test/test_samples/sample_mpeg4/00079
new file mode 100644
index 0000000..298cc66
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00079
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00080 b/test/test_samples/sample_mpeg4/00080
new file mode 100644
index 0000000..c8d61e0
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00080
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00081 b/test/test_samples/sample_mpeg4/00081
new file mode 100644
index 0000000..c8f52a1
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00081
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00082 b/test/test_samples/sample_mpeg4/00082
new file mode 100644
index 0000000..f61ee32
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00082
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00083 b/test/test_samples/sample_mpeg4/00083
new file mode 100644
index 0000000..907fe02
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00083
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00084 b/test/test_samples/sample_mpeg4/00084
new file mode 100644
index 0000000..fc82703
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00084
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00085 b/test/test_samples/sample_mpeg4/00085
new file mode 100644
index 0000000..51d7c9e
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00085
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00086 b/test/test_samples/sample_mpeg4/00086
new file mode 100644
index 0000000..17820ea
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00086
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00087 b/test/test_samples/sample_mpeg4/00087
new file mode 100644
index 0000000..c54c572
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00087
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00088 b/test/test_samples/sample_mpeg4/00088
new file mode 100644
index 0000000..02b774b
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00088
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00089 b/test/test_samples/sample_mpeg4/00089
new file mode 100644
index 0000000..ea59f67
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00089
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00090 b/test/test_samples/sample_mpeg4/00090
new file mode 100644
index 0000000..8f73e5f
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00090
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00091 b/test/test_samples/sample_mpeg4/00091
new file mode 100644
index 0000000..c59ba0e
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00091
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00092 b/test/test_samples/sample_mpeg4/00092
new file mode 100644
index 0000000..1e235a1
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00092
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00093 b/test/test_samples/sample_mpeg4/00093
new file mode 100644
index 0000000..8d2ed0a
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00093
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00094 b/test/test_samples/sample_mpeg4/00094
new file mode 100644
index 0000000..4ca9256
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00094
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00095 b/test/test_samples/sample_mpeg4/00095
new file mode 100644
index 0000000..1501237
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00095
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00096 b/test/test_samples/sample_mpeg4/00096
new file mode 100644
index 0000000..a553d5a
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00096
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00097 b/test/test_samples/sample_mpeg4/00097
new file mode 100644
index 0000000..d3d9d7a
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00097
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00098 b/test/test_samples/sample_mpeg4/00098
new file mode 100644
index 0000000..3912121
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00098
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00099 b/test/test_samples/sample_mpeg4/00099
new file mode 100644
index 0000000..b270029
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00099
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00100 b/test/test_samples/sample_mpeg4/00100
new file mode 100644
index 0000000..c4710db
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00100
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00101 b/test/test_samples/sample_mpeg4/00101
new file mode 100644
index 0000000..ca19426
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00101
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00102 b/test/test_samples/sample_mpeg4/00102
new file mode 100644
index 0000000..091b7b8
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00102
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00103 b/test/test_samples/sample_mpeg4/00103
new file mode 100644
index 0000000..674a2eb
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00103
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00104 b/test/test_samples/sample_mpeg4/00104
new file mode 100644
index 0000000..1f561ec
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00104
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00105 b/test/test_samples/sample_mpeg4/00105
new file mode 100644
index 0000000..2e4823f
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00105
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00106 b/test/test_samples/sample_mpeg4/00106
new file mode 100644
index 0000000..98878ef
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00106
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00107 b/test/test_samples/sample_mpeg4/00107
new file mode 100644
index 0000000..937cedc
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00107
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00108 b/test/test_samples/sample_mpeg4/00108
new file mode 100644
index 0000000..4970beb
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00108
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00109 b/test/test_samples/sample_mpeg4/00109
new file mode 100644
index 0000000..4c43d2e
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00109
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00110 b/test/test_samples/sample_mpeg4/00110
new file mode 100644
index 0000000..e99e35c
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00110
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00111 b/test/test_samples/sample_mpeg4/00111
new file mode 100644
index 0000000..8f7e6e4
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00111
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00112 b/test/test_samples/sample_mpeg4/00112
new file mode 100644
index 0000000..073d7bb
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00112
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00113 b/test/test_samples/sample_mpeg4/00113
new file mode 100644
index 0000000..f34e20c
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00113
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00114 b/test/test_samples/sample_mpeg4/00114
new file mode 100644
index 0000000..ce64abc
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00114
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00115 b/test/test_samples/sample_mpeg4/00115
new file mode 100644
index 0000000..d844164
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00115
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00116 b/test/test_samples/sample_mpeg4/00116
new file mode 100644
index 0000000..bba3338
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00116
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00117 b/test/test_samples/sample_mpeg4/00117
new file mode 100644
index 0000000..ae22d23
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00117
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00118 b/test/test_samples/sample_mpeg4/00118
new file mode 100644
index 0000000..eb397fc
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00118
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00119 b/test/test_samples/sample_mpeg4/00119
new file mode 100644
index 0000000..cafae96
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00119
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00120 b/test/test_samples/sample_mpeg4/00120
new file mode 100644
index 0000000..d06a53a
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00120
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00121 b/test/test_samples/sample_mpeg4/00121
new file mode 100644
index 0000000..13b606f
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00121
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00122 b/test/test_samples/sample_mpeg4/00122
new file mode 100644
index 0000000..aaa1220
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00122
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00123 b/test/test_samples/sample_mpeg4/00123
new file mode 100644
index 0000000..a515ab1
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00123
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00124 b/test/test_samples/sample_mpeg4/00124
new file mode 100644
index 0000000..b56a8d6
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00124
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00125 b/test/test_samples/sample_mpeg4/00125
new file mode 100644
index 0000000..79998e4
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00125
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00126 b/test/test_samples/sample_mpeg4/00126
new file mode 100644
index 0000000..1977791
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00126
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00127 b/test/test_samples/sample_mpeg4/00127
new file mode 100644
index 0000000..1308e04
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00127
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00128 b/test/test_samples/sample_mpeg4/00128
new file mode 100644
index 0000000..5df6e5a
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00128
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00129 b/test/test_samples/sample_mpeg4/00129
new file mode 100644
index 0000000..f8d428e
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00129
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00130 b/test/test_samples/sample_mpeg4/00130
new file mode 100644
index 0000000..5c3be66
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00130
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00131 b/test/test_samples/sample_mpeg4/00131
new file mode 100644
index 0000000..3727828
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00131
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00132 b/test/test_samples/sample_mpeg4/00132
new file mode 100644
index 0000000..3bdf862
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00132
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00133 b/test/test_samples/sample_mpeg4/00133
new file mode 100644
index 0000000..f41909b
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00133
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00134 b/test/test_samples/sample_mpeg4/00134
new file mode 100644
index 0000000..f7b25ec
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00134
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00135 b/test/test_samples/sample_mpeg4/00135
new file mode 100644
index 0000000..6f33d05
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00135
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00136 b/test/test_samples/sample_mpeg4/00136
new file mode 100644
index 0000000..6ad916f
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00136
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00137 b/test/test_samples/sample_mpeg4/00137
new file mode 100644
index 0000000..bd83431
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00137
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00138 b/test/test_samples/sample_mpeg4/00138
new file mode 100644
index 0000000..df51024
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00138
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00139 b/test/test_samples/sample_mpeg4/00139
new file mode 100644
index 0000000..a3556d7
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00139
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00140 b/test/test_samples/sample_mpeg4/00140
new file mode 100644
index 0000000..30fe669
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00140
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00141 b/test/test_samples/sample_mpeg4/00141
new file mode 100644
index 0000000..9bc3b16
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00141
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00142 b/test/test_samples/sample_mpeg4/00142
new file mode 100644
index 0000000..911ad85
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00142
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00143 b/test/test_samples/sample_mpeg4/00143
new file mode 100644
index 0000000..26f7f25
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00143
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00144 b/test/test_samples/sample_mpeg4/00144
new file mode 100644
index 0000000..ffbc95b
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00144
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00145 b/test/test_samples/sample_mpeg4/00145
new file mode 100644
index 0000000..bb99f41
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00145
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00146 b/test/test_samples/sample_mpeg4/00146
new file mode 100644
index 0000000..d2fc6be
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00146
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00147 b/test/test_samples/sample_mpeg4/00147
new file mode 100644
index 0000000..83b0129
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00147
Binary files differ
diff --git a/test/test_samples/sample_mpeg4/00148 b/test/test_samples/sample_mpeg4/00148
new file mode 100644
index 0000000..d208ad4
--- /dev/null
+++ b/test/test_samples/sample_mpeg4/00148
Binary files differ