#include <OMX_Index.h>
#endif
+//#define CODEC_ENC_INPUT_DUMP
GST_DEBUG_CATEGORY_STATIC (gst_omx_video_enc_debug_category);
#define GST_CAT_DEFAULT gst_omx_video_enc_debug_category
#define GST_TYPE_OMX_VIDEO_ENC_CONTROL_RATE (gst_omx_video_enc_control_rate_get_type ())
+
+#ifdef CODEC_ENC_INPUT_DUMP
+#include <stdio.h>
+#endif
+
static GType
gst_omx_video_enc_control_rate_get_type (void)
{
#define GST_OMX_VIDEO_ENC_QUANT_P_FRAMES_DEFAULT (0xffffffff)
#define GST_OMX_VIDEO_ENC_QUANT_B_FRAMES_DEFAULT (0xffffffff)
+
/* class initialization */
#define DEBUG_INIT \
g_mutex_init (&self->drain_lock);
g_cond_init (&self->drain_cond);
-#ifdef GST_TIZEN_MODIFICATION
- self->hTBMBufMgr = NULL;
+#ifdef TIZEN_FEATURE_OMX
+ self->bufmgr = NULL;
self->drm_fd = -1;
#endif
}
+#ifdef CODEC_ENC_INPUT_DUMP
+static inline void
+gst_omx_video_enc_input_dump (MMVideoBuffer *inbuf)
+{
+ char *temp = (char *)inbuf->data[0];
+ int i = 0;
+ char filename[100]={0};
+ FILE *fp = NULL;
+
+ GST_WARNING ("codec enc input dump start. w = %d, h = %d", inbuf->width[0], inbuf->height[0]);
+
+ sprintf(filename, "/tmp/enc_input_dump_%d_%d.yuv", inbuf->width[0], inbuf->height[0]);
+ fp = fopen(filename, "ab");
+
+ for (i = 0; i < inbuf->height[0]; i++) {
+ fwrite(temp, inbuf->width[0], 1, fp);
+ temp += inbuf->stride_width[0];
+ }
+
+ temp = (char*)inbuf->data[1];
+
+ for(i = 0; i < inbuf->height[1] ; i++) {
+ fwrite(temp, inbuf->width[1], 1, fp);
+ temp += inbuf->stride_width[1];
+ }
+ GST_WARNING ("codec encoder input dumped!!");
+ fclose(fp);
+}
+#endif
+
static gboolean
gst_omx_video_enc_open (GstVideoEncoder * encoder)
{
self->enc_in_port = gst_omx_component_add_port (self->enc, in_port_index);
self->enc_out_port = gst_omx_component_add_port (self->enc, out_port_index);
+
if (!self->enc_in_port || !self->enc_out_port)
return FALSE;
}
}
}
-#ifdef GST_TIZEN_MODIFICATION
- self->hTBMBufMgr = tbm_bufmgr_init(self->drm_fd);
- if(self->hTBMBufMgr == NULL){
+#ifdef TIZEN_FEATURE_OMX
+ self->bufmgr = tbm_bufmgr_init (self->drm_fd);
+ if (self->bufmgr == NULL){
GST_ERROR_OBJECT (self, "TBM initialization failed.");
return FALSE;
}
+
+ self->enc_in_port->use_buffer = klass->cdata.in_port_usebuffer;
+ self->enc_out_port->use_buffer = klass->cdata.out_port_usebuffer;
+
+ /* get extension index and set platform specific buffer enable */
+#if defined(USE_OMX_TARGET_EXYNOS) || defined(USE_OMX_TARGET_EXYNOS64)
+ {
+ OMX_ERRORTYPE err;
+ OMX_INDEXTYPE index = OMX_IndexComponentStartUnused;
+ EnableGemBuffersParams gem_param;
+
+ err = gst_omx_component_get_extension_index (self->enc, (OMX_STRING) EXYNOS_INDEX_PARAM_STORE_METADATA_BUFFER, &index);
+ if (err != OMX_ErrorNone) {
+ GST_WARNING_OBJECT (self, "Failed to get extension index : %s (0x%08x)",
+ gst_omx_error_to_string (err), err);
+ }
+
+ OMX_INIT_PARAM (gem_param);
+ gem_param.enable = OMX_TRUE;
+ gem_param.nPortIndex = 0;
+
+
+ err = gst_omx_component_set_parameter (self->enc, index, &gem_param);
+ if (err != OMX_ErrorNone) {
+ GST_ERROR_OBJECT (self, "Failed to set platform specific buffer: %s (0x%08x)",
+ gst_omx_error_to_string (err), err);
+ }
+
+ }
+#endif
#endif
return TRUE;
}
break;
}
- if (ret == GST_STATE_CHANGE_FAILURE)
- return ret;
-
ret =
GST_ELEMENT_CLASS (gst_omx_video_enc_parent_class)->change_state (element,
transition);
self->input_state);
state->codec_data = codec_data;
gst_video_codec_state_unref (state);
+#ifdef TIZEN_FEATURE_OMX
+ /*Modification : codec data already set_caps, so unref frame whenever negotiate ok or not*/
+ if (!gst_video_encoder_negotiate (GST_VIDEO_ENCODER (self)))
+ flow_ret = GST_FLOW_NOT_NEGOTIATED;
+ else
+ flow_ret = GST_FLOW_OK;
+ gst_video_codec_frame_unref (frame);
+#else
if (!gst_video_encoder_negotiate (GST_VIDEO_ENCODER (self))) {
gst_video_codec_frame_unref (frame);
return GST_FLOW_NOT_NEGOTIATED;
}
flow_ret = GST_FLOW_OK;
+#endif
} else if (buf->omx_buf->nFilledLen > 0) {
GstBuffer *outbuf;
GstMapInfo map = GST_MAP_INFO_INIT;
err = gst_omx_port_set_enabled (port, TRUE);
if (err != OMX_ErrorNone)
goto reconfigure_error;
-#ifdef GST_TIZEN_MODIFICATION
- err = gst_omx_port_tbm_allocate_enc_buffers(port, self->hTBMBufMgr,
- self->enc_in_port->port_def.format.video.eCompressionFormat);
+#ifdef TIZEN_FEATURE_OMX
+ err = gst_omx_port_tbm_allocate_enc_buffers(port, self->bufmgr, port->use_buffer);
#else
err = gst_omx_port_allocate_buffers (port);
#endif
flushing:
{
GST_DEBUG_OBJECT (self, "Flushing -- stopping task");
+ g_mutex_lock (&self->drain_lock);
+ if (self->draining) {
+ self->draining = FALSE;
+ g_cond_broadcast (&self->drain_cond);
+ }
gst_pad_pause_task (GST_VIDEO_ENCODER_SRC_PAD (self));
self->downstream_flow_ret = GST_FLOW_FLUSHING;
self->started = FALSE;
+ g_mutex_unlock (&self->drain_lock);
return;
}
self->started = FALSE;
} else if (flow_ret == GST_FLOW_FLUSHING) {
GST_DEBUG_OBJECT (self, "Flushing -- stopping task");
+ g_mutex_lock (&self->drain_lock);
+ if (self->draining) {
+ self->draining = FALSE;
+ g_cond_broadcast (&self->drain_cond);
+ }
gst_pad_pause_task (GST_VIDEO_ENCODER_SRC_PAD (self));
self->started = FALSE;
+ g_mutex_unlock (&self->drain_lock);
}
GST_VIDEO_ENCODER_STREAM_UNLOCK (self);
return;
case GST_VIDEO_FORMAT_NV12:
port_def.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
break;
+ case GST_VIDEO_FORMAT_SN12:
+ port_def.format.video.eColorFormat = OMX_EXT_COLOR_FormatNV12LPhysicalAddress;
+ break;
default:
GST_ERROR_OBJECT (self, "Unsupported format %s",
gst_video_format_to_string (info->finfo->format));
}
port_def.format.video.nFrameWidth = info->width;
+#ifdef TIZEN_FEATURE_OMX
+ port_def.format.video.nStride = ALIGN(info->width, 16);
+#else
if (port_def.nBufferAlignment)
port_def.format.video.nStride =
(info->width + port_def.nBufferAlignment - 1) &
(~(port_def.nBufferAlignment - 1));
else
port_def.format.video.nStride = GST_ROUND_UP_4 (info->width); /* safe (?) default */
+#endif
port_def.format.video.nFrameHeight = info->height;
+#ifdef TIZEN_FEATURE_OMX
+ port_def.format.video.nSliceHeight = ALIGN(info->width, 16);
+#else
port_def.format.video.nSliceHeight = info->height;
+#endif
switch (port_def.format.video.eColorFormat) {
case OMX_COLOR_FormatYUV420Planar:
case OMX_EXT_COLOR_FormatNV12LPhysicalAddress: /* FALL THROUGH */
case OMX_EXT_COLOR_FormatNV12TPhysicalAddress:
-#ifdef GST_TIZEN_MODIFICATION
+#ifdef TIZEN_FEATURE_OMX
port_def.nBufferSize = sizeof(MMVideoBuffer);
#endif
break;
&port_def) != OMX_ErrorNone)
return FALSE;
+#ifdef TIZEN_FEATURE_OMX
+ GST_DEBUG_OBJECT (self, "Updating outport port definition");
+ gst_omx_port_get_port_definition (self->enc_out_port, &port_def);
+
+ port_def.format.video.nFrameWidth = info->width;
+ port_def.format.video.nFrameHeight = info->height;
+
+ if (gst_omx_port_update_port_definition (self->enc_out_port, &port_def) != OMX_ErrorNone)
+ return FALSE;
+#endif
+
#ifdef USE_OMX_TARGET_RPI
/* aspect ratio */
{
if (needs_disable) {
if (gst_omx_port_set_enabled (self->enc_in_port, TRUE) != OMX_ErrorNone)
return FALSE;
-#ifdef GST_TIZEN_MODIFICATION
- if(gst_omx_port_tbm_allocate_enc_buffers(self->enc_in_port, self->hTBMBufMgr,
- self->enc_in_port->port_def.format.video.eCompressionFormat) != OMX_ErrorNone)
+#ifdef TIZEN_FEATURE_OMX
+ if (gst_omx_port_tbm_allocate_enc_buffers (self->enc_in_port, self->bufmgr,
+ self->enc_in_port->use_buffer) != OMX_ErrorNone)
return FALSE;
#else
if (gst_omx_port_allocate_buffers (self->enc_in_port) != OMX_ErrorNone)
return FALSE;
/* Need to allocate buffers to reach Idle state */
-#ifdef GST_TIZEN_MODIFICATION
- if(gst_omx_port_tbm_allocate_enc_buffers(self->enc_in_port, self->hTBMBufMgr,
- self->enc_in_port->port_def.format.video.eCompressionFormat) != OMX_ErrorNone)
+#ifdef TIZEN_FEATURE_OMX
+ if (gst_omx_port_tbm_allocate_enc_buffers(self->enc_in_port, self->bufmgr,
+ self->enc_in_port->use_buffer) != OMX_ErrorNone)
return FALSE;
#else
if (gst_omx_port_allocate_buffers (self->enc_in_port) != OMX_ErrorNone)
return FALSE;
#endif
-#ifdef GST_TIZEN_MODIFICATION
- if(gst_omx_port_tbm_allocate_enc_buffers(self->enc_out_port, self->hTBMBufMgr,
- self->enc_out_port->port_def.format.video.eCompressionFormat) != OMX_ErrorNone)
+#ifdef TIZEN_FEATURE_OMX
+ if (gst_omx_port_tbm_allocate_enc_buffers(self->enc_out_port, self->bufmgr,
+ self->enc_out_port->use_buffer) != OMX_ErrorNone)
#else
if (gst_omx_port_allocate_buffers (self->enc_out_port) != OMX_ErrorNone)
#endif
GST_ERROR_OBJECT (self, "Width or height do not match");
goto done;
}
-
+#ifndef TIZEN_FEATURE_OMX
/* Same strides and everything */
if (gst_buffer_get_size (inbuf) ==
outbuf->omx_buf->nAllocLen - outbuf->omx_buf->nOffset) {
ret = TRUE;
goto done;
}
-
+#endif
/* Different strides */
switch (info->finfo->format) {
break;
}
case GST_VIDEO_FORMAT_ST12:
- case GST_VIDEO_FORMAT_SN12:{
- GstMemory* ext_memory = gst_buffer_peek_memory(inbuf, 1);
- GstMapInfo ext_info = GST_MAP_INFO_INIT;
- MMVideoBuffer *ext_buf = NULL;
-
- if (!ext_memory) {
- GST_WARNING_OBJECT (self, "null MMVideoBuffer pointer in hw color format. skip this.");
- goto done;
- }
-
- gst_memory_map(ext_memory, &ext_info, GST_MAP_READ);
- ext_buf = (MMVideoBuffer*)ext_info.data;
- gst_memory_unmap(ext_memory, &ext_info);
+ case GST_VIDEO_FORMAT_SN12:
+ {
+ GstMemory* ext_memory = gst_buffer_peek_memory(inbuf, 1);
+ GstMapInfo ext_info = GST_MAP_INFO_INIT;
+ MMVideoBuffer *mm_vbuffer = NULL;
+
+ if (!ext_memory) {
+ GST_WARNING_OBJECT (self, "null MMVideoBuffer pointer in hw color format. skip this.");
+ goto done;
+ }
- if (ext_buf != NULL && ext_buf->type == MM_VIDEO_BUFFER_TYPE_TBM_BO) {
+ gst_memory_map(ext_memory, &ext_info, GST_MAP_READ);
+ mm_vbuffer = (MMVideoBuffer*)ext_info.data;
+ gst_memory_unmap(ext_memory, &ext_info);
- if (ext_buf->handle.dmabuf_fd[0] == NULL)
- gst_omx_tbm_get_bo_fd(ext_buf->handle.bo[0]);
+ if (mm_vbuffer != NULL && mm_vbuffer->type == MM_VIDEO_BUFFER_TYPE_TBM_BO) {
+ mm_vbuffer->handle.dmabuf_fd[0] = tbm_bo_get_handle (mm_vbuffer->handle.bo[0], TBM_DEVICE_MM).u32;
+ mm_vbuffer->handle.dmabuf_fd[1] = tbm_bo_get_handle (mm_vbuffer->handle.bo[1], TBM_DEVICE_MM).u32;
+ mm_vbuffer->data[0] = tbm_bo_get_handle (mm_vbuffer->handle.bo[0], TBM_DEVICE_CPU).ptr;
+ mm_vbuffer->data[1] = tbm_bo_get_handle (mm_vbuffer->handle.bo[1], TBM_DEVICE_CPU).ptr;
- if (ext_buf->handle.dmabuf_fd[1] == NULL)
- gst_omx_tbm_get_bo_fd(ext_buf->handle.bo[1]);
+ GST_LOG_OBJECT (self, "enc. fd[0]:%d fd[1]:%d a[0]:%p, a[1]:%p, w[0]:%d h[0]:%d %d, %d, buf_share_method:%d",
+ mm_vbuffer->handle.dmabuf_fd[0], mm_vbuffer->handle.dmabuf_fd[1], mm_vbuffer->data[0], mm_vbuffer->data[1],
+ mm_vbuffer->width[0], mm_vbuffer->height[0], mm_vbuffer->width[1], mm_vbuffer->height[1], mm_vbuffer->type);
- GST_LOG_OBJECT (self, "enc. fd[0]:%d fd[1]:%d fd[2]:%d w[0]:%d h[0]:%d buf_share_method:%d",
- ext_buf->handle.dmabuf_fd[0], ext_buf->handle.dmabuf_fd[1], ext_buf->handle.dmabuf_fd[2], ext_buf->width[0], ext_buf->height[0], ext_buf->type);
- } else {
- GST_WARNING_OBJECT (self, "enc input buf has wrong buf_share_method[%d]", ext_buf->type);
- }
-
- outbuf->omx_buf->nAllocLen = sizeof(MMVideoBuffer);
- outbuf->omx_buf->nFilledLen = sizeof(MMVideoBuffer);
- memcpy (outbuf->omx_buf->pBuffer, ext_buf, sizeof(MMVideoBuffer));
+ outbuf->omx_buf->nAllocLen = sizeof (MMVideoBuffer);
+ outbuf->omx_buf->nFilledLen = sizeof (MMVideoBuffer);
+ memcpy (outbuf->omx_buf->pBuffer, mm_vbuffer, sizeof (MMVideoBuffer));
+ } else {
+ GST_WARNING_OBJECT (self, "enc input has wrong buf");
+ }
#ifdef CODEC_ENC_INPUT_DUMP
- gst_omx_video_enc_input_dump(ext_buf);
+ gst_omx_video_enc_input_dump(mm_vbuffer);
#endif
- ret = TRUE;
- break;
+ ret = TRUE;
+ break;
}
default:
GST_ERROR_OBJECT (self, "Unsupported format");
GST_VIDEO_ENCODER_STREAM_LOCK (self);
goto reconfigure_error;
}
-#ifdef GST_TIZEN_MODIFICATION
- err = gst_omx_port_tbm_allocate_enc_buffers(port, self->hTBMBufMgr,
- self->enc_in_port->port_def.format.video.eCompressionFormat);
+#ifdef TIZEN_FEATURE_OMX
+ err = gst_omx_port_tbm_allocate_enc_buffers (port, self->bufmgr, port->use_buffer);
#else
err = gst_omx_port_allocate_buffers (port);
#endif