Merge tizen patch based on 1.12.2
[platform/upstream/gstreamer.git] / omx / gstomxvideoenc.c
old mode 100644 (file)
new mode 100755 (executable)
index 5c1d7fc..0c84e6f
 #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)
 {
@@ -110,6 +116,7 @@ enum
 #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 \
@@ -204,12 +211,42 @@ gst_omx_video_enc_init (GstOMXVideoEnc * self)
 
   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)
 {
@@ -259,6 +296,7 @@ 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;
 
@@ -354,12 +392,42 @@ gst_omx_video_enc_open (GstVideoEncoder * encoder)
       }
     }
   }
-#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;
 }
@@ -524,9 +592,6 @@ gst_omx_video_enc_change_state (GstElement * element, GstStateChange transition)
       break;
   }
 
-  if (ret == GST_STATE_CHANGE_FAILURE)
-    return ret;
-
   ret =
       GST_ELEMENT_CLASS (gst_omx_video_enc_parent_class)->change_state (element,
       transition);
@@ -582,11 +647,20 @@ gst_omx_video_enc_handle_output_frame (GstOMXVideoEnc * self, GstOMXPort * port,
         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;
@@ -720,9 +794,8 @@ gst_omx_video_enc_loop (GstOMXVideoEnc * self)
       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
@@ -802,9 +875,15 @@ component_error:
 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;
   }
 
@@ -853,8 +932,14 @@ flow_error:
       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;
@@ -1024,6 +1109,9 @@ gst_omx_video_enc_set_format (GstVideoEncoder * encoder,
       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));
@@ -1044,15 +1132,23 @@ gst_omx_video_enc_set_format (GstVideoEncoder * encoder,
   }
 
   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:
@@ -1072,7 +1168,7 @@ gst_omx_video_enc_set_format (GstVideoEncoder * encoder,
 
     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;
@@ -1095,6 +1191,17 @@ gst_omx_video_enc_set_format (GstVideoEncoder * encoder,
           &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 */
   {
@@ -1164,9 +1271,9 @@ gst_omx_video_enc_set_format (GstVideoEncoder * encoder,
   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)
@@ -1212,18 +1319,18 @@ gst_omx_video_enc_set_format (GstVideoEncoder * encoder,
         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
@@ -1318,7 +1425,7 @@ gst_omx_video_enc_fill_buffer (GstOMXVideoEnc * self, GstBuffer * inbuf,
     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) {
@@ -1330,7 +1437,7 @@ gst_omx_video_enc_fill_buffer (GstOMXVideoEnc * self, GstBuffer * inbuf,
     ret = TRUE;
     goto done;
   }
-
+#endif
   /* Different strides */
 
   switch (info->finfo->format) {
@@ -1457,44 +1564,44 @@ gst_omx_video_enc_fill_buffer (GstOMXVideoEnc * self, GstBuffer * inbuf,
       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");
@@ -1576,9 +1683,8 @@ gst_omx_video_enc_handle_frame (GstVideoEncoder * encoder,
         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