summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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
7 files changed, 3605 insertions, 1455 deletions
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);
}
-