omxvideo: start sharing more code between video decoder and encoder
authorChristian König <christian.koenig@amd.com>
Mon, 3 Mar 2014 15:15:24 +0000 (16:15 +0100)
committerSebastian Dröge <sebastian@centricular.com>
Wed, 12 Mar 2014 11:47:09 +0000 (12:47 +0100)
Identical functionality spread of two different components.
We can't use a common base class because of different inheritance,
but let's try to share the code anyway.

https://bugzilla.gnome.org/show_bug.cgi?id=726024

omx/Makefile.am
omx/gstomxvideo.c [new file with mode: 0644]
omx/gstomxvideo.h [new file with mode: 0644]
omx/gstomxvideodec.c
omx/gstomxvideoenc.c

index 9006214..bcdd60c 100644 (file)
@@ -13,6 +13,7 @@ endif
 libgstomx_la_SOURCES = \
        gstomx.c \
        gstomxbufferpool.c \
+       gstomxvideo.c \
        gstomxvideodec.c \
        gstomxvideoenc.c \
        gstomxaudioenc.c \
@@ -31,6 +32,7 @@ libgstomx_la_SOURCES = \
 
 noinst_HEADERS = \
        gstomx.h \
+       gstomxvideo.h \
        gstomxvideodec.h \
        gstomxvideoenc.h \
        gstomxaudioenc.h \
diff --git a/omx/gstomxvideo.c b/omx/gstomxvideo.c
new file mode 100644 (file)
index 0000000..c282fd2
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ *   Author: Christian König <christian.koenig@amd.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gstomxvideo.h"
+
+GST_DEBUG_CATEGORY_STATIC (gst_omx_video_debug_category);
+#define GST_CAT_DEFAULT gst_omx_video_debug_category
+
+GList *
+gst_omx_video_get_supported_colorformats (GstOMXPort * port,
+    GstVideoCodecState * state)
+{
+  GstOMXComponent *comp = port->comp;
+  OMX_VIDEO_PARAM_PORTFORMATTYPE param;
+  OMX_ERRORTYPE err;
+  GList *negotiation_map = NULL;
+  gint old_index;
+  GstOMXVideoNegotiationMap *m;
+
+  GST_OMX_INIT_STRUCT (&param);
+  param.nPortIndex = port->index;
+  param.nIndex = 0;
+  if (!state || state->info.fps_n == 0)
+    param.xFramerate = 0;
+  else
+    param.xFramerate = (state->info.fps_n << 16) / (state->info.fps_d);
+
+  old_index = -1;
+  do {
+    err =
+        gst_omx_component_get_parameter (comp,
+        OMX_IndexParamVideoPortFormat, &param);
+
+    /* FIXME: Workaround for Bellagio that simply always
+     * returns the same value regardless of nIndex and
+     * never returns OMX_ErrorNoMore
+     */
+    if (old_index == param.nIndex)
+      break;
+
+    if (err == OMX_ErrorNone || err == OMX_ErrorNoMore) {
+      switch (param.eColorFormat) {
+        case OMX_COLOR_FormatYUV420Planar:
+        case OMX_COLOR_FormatYUV420PackedPlanar:
+          m = g_slice_new (GstOMXVideoNegotiationMap);
+          m->format = GST_VIDEO_FORMAT_I420;
+          m->type = param.eColorFormat;
+          negotiation_map = g_list_append (negotiation_map, m);
+          GST_DEBUG_OBJECT (comp->parent,
+              "Component supports I420 (%d) at index %u",
+              param.eColorFormat, (guint) param.nIndex);
+          break;
+        case OMX_COLOR_FormatYUV420SemiPlanar:
+          m = g_slice_new (GstOMXVideoNegotiationMap);
+          m->format = GST_VIDEO_FORMAT_NV12;
+          m->type = param.eColorFormat;
+          negotiation_map = g_list_append (negotiation_map, m);
+          GST_DEBUG_OBJECT (comp->parent,
+              "Component supports NV12 (%d) at index %u",
+              param.eColorFormat, (guint) param.nIndex);
+          break;
+        default:
+          GST_DEBUG_OBJECT (comp->parent,
+              "Component supports unsupported color format %d at index %u",
+              param.eColorFormat, (guint) param.nIndex);
+          break;
+      }
+    }
+    old_index = param.nIndex++;
+  } while (err == OMX_ErrorNone);
+
+  return negotiation_map;
+}
+
+GstCaps *
+gst_omx_video_get_caps_4_map (GList * map)
+{
+  GstCaps *caps = gst_caps_new_empty ();
+  GList *l;
+
+  for (l = map; l; l = l->next) {
+    GstOMXVideoNegotiationMap *entry = l->data;
+
+    gst_caps_append_structure (caps,
+        gst_structure_new ("video/x-raw",
+            "format", G_TYPE_STRING,
+            gst_video_format_to_string (entry->format), NULL));
+  }
+  return caps;
+}
+
+void
+gst_omx_video_negotiation_map_free (GstOMXVideoNegotiationMap * m)
+{
+  g_slice_free (GstOMXVideoNegotiationMap, m);
+}
+
+GstVideoCodecFrame *
+gst_omx_video_find_nearest_frame (GstOMXBuffer * buf, GList * frames)
+{
+  GstVideoCodecFrame *best = NULL;
+  GstClockTimeDiff best_diff = G_MAXINT64;
+  GstClockTime timestamp;
+  GList *l;
+
+  timestamp =
+      gst_util_uint64_scale (buf->omx_buf->nTimeStamp, GST_SECOND,
+      OMX_TICKS_PER_SECOND);
+
+  for (l = frames; l; l = l->next) {
+    GstVideoCodecFrame *tmp = l->data;
+    GstClockTimeDiff diff = ABS (GST_CLOCK_DIFF (timestamp, tmp->pts));
+
+    if (diff < best_diff) {
+      best = tmp;
+      best_diff = diff;
+
+      if (diff == 0)
+        break;
+    }
+  }
+
+  if (best)
+    gst_video_codec_frame_ref (best);
+
+  g_list_foreach (frames, (GFunc) gst_video_codec_frame_unref, NULL);
+  g_list_free (frames);
+
+  return best;
+}
diff --git a/omx/gstomxvideo.h b/omx/gstomxvideo.h
new file mode 100644 (file)
index 0000000..df81654
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2014 Advanced Micro Devices, Inc.
+ *   Author: Christian König <christian.koenig@amd.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ */
+
+#ifndef __GST_OMX_VIDEO_H__
+#define __GST_OMX_VIDEO_H__
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gst/gst.h>
+#include <gst/video/video.h>
+
+#include "gstomx.h"
+
+G_BEGIN_DECLS
+
+typedef struct
+{
+  GstVideoFormat format;
+  OMX_COLOR_FORMATTYPE type;
+} GstOMXVideoNegotiationMap;
+
+GList *
+gst_omx_video_get_supported_colorformats (GstOMXPort * port,
+    GstVideoCodecState * state);
+
+GstCaps * gst_omx_video_get_caps_4_map(GList * map);
+
+void
+gst_omx_video_negotiation_map_free (GstOMXVideoNegotiationMap * m);
+
+GstVideoCodecFrame *
+gst_omx_video_find_nearest_frame (GstOMXBuffer * buf, GList * frames);
+
+G_END_DECLS
+
+#endif /* __GST_OMX_VIDEO_H__ */
index 3b6605a..af93aba 100644 (file)
@@ -48,6 +48,7 @@
 #include <string.h>
 
 #include "gstomxbufferpool.h"
+#include "gstomxvideo.h"
 #include "gstomxvideodec.h"
 
 GST_DEBUG_CATEGORY_STATIC (gst_omx_video_dec_debug_category);
@@ -402,43 +403,6 @@ gst_omx_video_dec_change_state (GstElement * element, GstStateChange transition)
   return ret;
 }
 
-static GstVideoCodecFrame *
-gst_omx_video_dec_find_nearest_frame (GstOMXVideoDec * self, GstOMXBuffer * buf)
-{
-  GstVideoCodecFrame *best = NULL;
-  GstClockTimeDiff best_diff = G_MAXINT64;
-  GstClockTime timestamp;
-  GList *frames;
-  GList *l;
-
-  timestamp =
-      gst_util_uint64_scale (buf->omx_buf->nTimeStamp, GST_SECOND,
-      OMX_TICKS_PER_SECOND);
-
-  frames = gst_video_decoder_get_frames (GST_VIDEO_DECODER (self));
-
-  for (l = frames; l; l = l->next) {
-    GstVideoCodecFrame *tmp = l->data;
-    GstClockTimeDiff diff = ABS (GST_CLOCK_DIFF (timestamp, tmp->pts));
-
-    if (diff < best_diff) {
-      best = tmp;
-      best_diff = diff;
-
-      if (diff == 0)
-        break;
-    }
-  }
-
-  if (best)
-    gst_video_codec_frame_ref (best);
-
-  g_list_foreach (frames, (GFunc) gst_video_codec_frame_unref, NULL);
-  g_list_free (frames);
-
-  return best;
-}
-
 static gboolean
 gst_omx_video_dec_fill_buffer (GstOMXVideoDec * self,
     GstOMXBuffer * inbuf, GstBuffer * outbuf)
@@ -1328,7 +1292,8 @@ gst_omx_video_dec_loop (GstOMXVideoDec * self)
       (guint) buf->omx_buf->nFlags, (guint64) buf->omx_buf->nTimeStamp);
 
   GST_VIDEO_DECODER_STREAM_LOCK (self);
-  frame = gst_omx_video_dec_find_nearest_frame (self, buf);
+  frame = gst_omx_video_find_nearest_frame (buf,
+      gst_video_decoder_get_frames (GST_VIDEO_DECODER (self)));
 
   if (frame
       && (deadline = gst_video_decoder_get_max_decode_time
@@ -1643,86 +1608,6 @@ gst_omx_video_dec_stop (GstVideoDecoder * decoder)
   return TRUE;
 }
 
-typedef struct
-{
-  GstVideoFormat format;
-  OMX_COLOR_FORMATTYPE type;
-} VideoNegotiationMap;
-
-static void
-video_negotiation_map_free (VideoNegotiationMap * m)
-{
-  g_slice_free (VideoNegotiationMap, m);
-}
-
-static GList *
-gst_omx_video_dec_get_supported_colorformats (GstOMXVideoDec * self)
-{
-  GstOMXComponent *comp;
-  GstOMXPort *port;
-  GstVideoCodecState *state = self->input_state;
-  OMX_VIDEO_PARAM_PORTFORMATTYPE param;
-  OMX_ERRORTYPE err;
-  GList *negotiation_map = NULL;
-  gint old_index;
-  VideoNegotiationMap *m;
-
-  port = self->dec_out_port;
-  comp = self->dec;
-
-  GST_OMX_INIT_STRUCT (&param);
-  param.nPortIndex = port->index;
-  param.nIndex = 0;
-  if (!state || state->info.fps_n == 0)
-    param.xFramerate = 0;
-  else
-    param.xFramerate = (state->info.fps_n << 16) / (state->info.fps_d);
-
-  old_index = -1;
-  do {
-    err =
-        gst_omx_component_get_parameter (comp,
-        OMX_IndexParamVideoPortFormat, &param);
-
-    /* FIXME: Workaround for Bellagio that simply always
-     * returns the same value regardless of nIndex and
-     * never returns OMX_ErrorNoMore
-     */
-    if (old_index == param.nIndex)
-      break;
-
-    if (err == OMX_ErrorNone || err == OMX_ErrorNoMore) {
-      switch (param.eColorFormat) {
-        case OMX_COLOR_FormatYUV420Planar:
-        case OMX_COLOR_FormatYUV420PackedPlanar:
-          m = g_slice_new (VideoNegotiationMap);
-          m->format = GST_VIDEO_FORMAT_I420;
-          m->type = param.eColorFormat;
-          negotiation_map = g_list_append (negotiation_map, m);
-          GST_DEBUG_OBJECT (self, "Component supports I420 (%d) at index %u",
-              param.eColorFormat, (guint) param.nIndex);
-          break;
-        case OMX_COLOR_FormatYUV420SemiPlanar:
-          m = g_slice_new (VideoNegotiationMap);
-          m->format = GST_VIDEO_FORMAT_NV12;
-          m->type = param.eColorFormat;
-          negotiation_map = g_list_append (negotiation_map, m);
-          GST_DEBUG_OBJECT (self, "Component supports NV12 (%d) at index %u",
-              param.eColorFormat, (guint) param.nIndex);
-          break;
-        default:
-          GST_DEBUG_OBJECT (self,
-              "Component supports unsupported color format %d at index %u",
-              param.eColorFormat, (guint) param.nIndex);
-          break;
-      }
-    }
-    old_index = param.nIndex++;
-  } while (err == OMX_ErrorNone);
-
-  return negotiation_map;
-}
-
 static gboolean
 gst_omx_video_dec_negotiate (GstOMXVideoDec * self)
 {
@@ -1745,16 +1630,11 @@ gst_omx_video_dec_negotiate (GstOMXVideoDec * self)
   GST_DEBUG_OBJECT (self, "Allowed downstream caps: %" GST_PTR_FORMAT,
       intersection);
 
-  negotiation_map = gst_omx_video_dec_get_supported_colorformats (self);
-  comp_supported_caps = gst_caps_new_empty ();
-  for (l = negotiation_map; l; l = l->next) {
-    VideoNegotiationMap *map = l->data;
+  negotiation_map =
+      gst_omx_video_get_supported_colorformats (self->dec_out_port,
+      self->input_state);
 
-    gst_caps_append_structure (comp_supported_caps,
-        gst_structure_new ("video/x-raw",
-            "format", G_TYPE_STRING,
-            gst_video_format_to_string (map->format), NULL));
-  }
+  comp_supported_caps = gst_omx_video_get_caps_4_map (negotiation_map);
 
   if (!gst_caps_is_empty (comp_supported_caps)) {
     GstCaps *tmp;
@@ -1769,7 +1649,7 @@ gst_omx_video_dec_negotiate (GstOMXVideoDec * self)
     gst_caps_unref (intersection);
     GST_ERROR_OBJECT (self, "Empty caps");
     g_list_free_full (negotiation_map,
-        (GDestroyNotify) video_negotiation_map_free);
+        (GDestroyNotify) gst_omx_video_negotiation_map_free);
     return FALSE;
   }
 
@@ -1785,7 +1665,7 @@ gst_omx_video_dec_negotiate (GstOMXVideoDec * self)
     GST_ERROR_OBJECT (self, "Invalid caps: %" GST_PTR_FORMAT, intersection);
     gst_caps_unref (intersection);
     g_list_free_full (negotiation_map,
-        (GDestroyNotify) video_negotiation_map_free);
+        (GDestroyNotify) gst_omx_video_negotiation_map_free);
     return FALSE;
   }
   gst_caps_unref (intersection);
@@ -1794,7 +1674,7 @@ gst_omx_video_dec_negotiate (GstOMXVideoDec * self)
   param.nPortIndex = self->dec_out_port->index;
 
   for (l = negotiation_map; l; l = l->next) {
-    VideoNegotiationMap *m = l->data;
+    GstOMXVideoNegotiationMap *m = l->data;
 
     if (m->format == format) {
       param.eColorFormat = m->type;
@@ -1808,7 +1688,7 @@ gst_omx_video_dec_negotiate (GstOMXVideoDec * self)
   /* We must find something here */
   g_assert (l != NULL);
   g_list_free_full (negotiation_map,
-      (GDestroyNotify) video_negotiation_map_free);
+      (GDestroyNotify) gst_omx_video_negotiation_map_free);
 
   err =
       gst_omx_component_set_parameter (self->dec,
index 07c9d77..9dcbbd1 100644 (file)
@@ -26,6 +26,7 @@
 #include <gst/video/gstvideometa.h>
 #include <string.h>
 
+#include "gstomxvideo.h"
 #include "gstomxvideoenc.h"
 
 GST_DEBUG_CATEGORY_STATIC (gst_omx_video_enc_debug_category);
@@ -539,43 +540,6 @@ gst_omx_video_enc_change_state (GstElement * element, GstStateChange transition)
   return ret;
 }
 
-static GstVideoCodecFrame *
-gst_omx_video_enc_find_nearest_frame (GstOMXVideoEnc * self, GstOMXBuffer * buf)
-{
-  GstVideoCodecFrame *best = NULL;
-  GstClockTimeDiff best_diff = G_MAXINT64;
-  GstClockTime timestamp;
-  GList *frames;
-  GList *l;
-
-  timestamp =
-      gst_util_uint64_scale (buf->omx_buf->nTimeStamp, GST_SECOND,
-      OMX_TICKS_PER_SECOND);
-
-  frames = gst_video_encoder_get_frames (GST_VIDEO_ENCODER (self));
-
-  for (l = frames; l; l = l->next) {
-    GstVideoCodecFrame *tmp = l->data;
-    GstClockTimeDiff diff = ABS (GST_CLOCK_DIFF (timestamp, tmp->pts));
-
-    if (diff < best_diff) {
-      best = tmp;
-      best_diff = diff;
-
-      if (diff == 0)
-        break;
-    }
-  }
-
-  if (best)
-    gst_video_codec_frame_ref (best);
-
-  g_list_foreach (frames, (GFunc) gst_video_codec_frame_unref, NULL);
-  g_list_free (frames);
-
-  return best;
-}
-
 static GstFlowReturn
 gst_omx_video_enc_handle_output_frame (GstOMXVideoEnc * self, GstOMXPort * port,
     GstOMXBuffer * buf, GstVideoCodecFrame * frame)
@@ -782,7 +746,8 @@ gst_omx_video_enc_loop (GstOMXVideoEnc * self)
       (guint) buf->omx_buf->nFlags, (guint64) buf->omx_buf->nTimeStamp);
 
   GST_VIDEO_ENCODER_STREAM_LOCK (self);
-  frame = gst_omx_video_enc_find_nearest_frame (self, buf);
+  frame = gst_omx_video_find_nearest_frame (buf,
+      gst_video_encoder_get_frames (GST_VIDEO_ENCODER (self)));
 
   g_assert (klass->handle_output_frame);
   flow_ret = klass->handle_output_frame (self, self->enc_out_port, buf, frame);
@@ -958,83 +923,6 @@ gst_omx_video_enc_stop (GstVideoEncoder * encoder)
   return TRUE;
 }
 
-typedef struct
-{
-  GstVideoFormat format;
-  OMX_COLOR_FORMATTYPE type;
-} VideoNegotiationMap;
-
-static void
-video_negotiation_map_free (VideoNegotiationMap * m)
-{
-  g_slice_free (VideoNegotiationMap, m);
-}
-
-static GList *
-gst_omx_video_enc_get_supported_colorformats (GstOMXVideoEnc * self)
-{
-  GstOMXPort *port = self->enc_in_port;
-  GstVideoCodecState *state = self->input_state;
-  OMX_VIDEO_PARAM_PORTFORMATTYPE param;
-  OMX_ERRORTYPE err;
-  GList *negotiation_map = NULL;
-  gint old_index;
-
-  GST_OMX_INIT_STRUCT (&param);
-  param.nPortIndex = port->index;
-  param.nIndex = 0;
-  if (!state || state->info.fps_n == 0)
-    param.xFramerate = 0;
-  else
-    param.xFramerate = (state->info.fps_n << 16) / (state->info.fps_d);
-
-  old_index = -1;
-  do {
-    VideoNegotiationMap *m;
-
-    err =
-        gst_omx_component_get_parameter (self->enc,
-        OMX_IndexParamVideoPortFormat, &param);
-
-    /* FIXME: Workaround for Bellagio that simply always
-     * returns the same value regardless of nIndex and
-     * never returns OMX_ErrorNoMore
-     */
-    if (old_index == param.nIndex)
-      break;
-
-    if (err == OMX_ErrorNone || err == OMX_ErrorNoMore) {
-      switch (param.eColorFormat) {
-        case OMX_COLOR_FormatYUV420Planar:
-        case OMX_COLOR_FormatYUV420PackedPlanar:
-          m = g_slice_new (VideoNegotiationMap);
-          m->format = GST_VIDEO_FORMAT_I420;
-          m->type = param.eColorFormat;
-          negotiation_map = g_list_append (negotiation_map, m);
-          GST_DEBUG_OBJECT (self, "Component supports I420 (%d) at index %u",
-              param.eColorFormat, (guint) param.nIndex);
-          break;
-        case OMX_COLOR_FormatYUV420SemiPlanar:
-          m = g_slice_new (VideoNegotiationMap);
-          m->format = GST_VIDEO_FORMAT_NV12;
-          m->type = param.eColorFormat;
-          negotiation_map = g_list_append (negotiation_map, m);
-          GST_DEBUG_OBJECT (self, "Component supports NV12 (%d) at index %u",
-              param.eColorFormat, (guint) param.nIndex);
-          break;
-        default:
-          GST_DEBUG_OBJECT (self,
-              "Component supports unsupported color format %d at index %u",
-              param.eColorFormat, (guint) param.nIndex);
-          break;
-      }
-    }
-    old_index = param.nIndex++;
-  } while (err == OMX_ErrorNone);
-
-  return negotiation_map;
-}
-
 static gboolean
 gst_omx_video_enc_set_format (GstVideoEncoder * encoder,
     GstVideoCodecState * state)
@@ -1097,7 +985,9 @@ gst_omx_video_enc_set_format (GstVideoEncoder * encoder,
     GST_DEBUG_OBJECT (self, "Encoder drained and disabled");
   }
 
-  negotiation_map = gst_omx_video_enc_get_supported_colorformats (self);
+  negotiation_map =
+      gst_omx_video_get_supported_colorformats (self->enc_in_port,
+      self->input_state);
   if (!negotiation_map) {
     /* Fallback */
     switch (info->finfo->format) {
@@ -1115,7 +1005,7 @@ gst_omx_video_enc_set_format (GstVideoEncoder * encoder,
     }
   } else {
     for (l = negotiation_map; l; l = l->next) {
-      VideoNegotiationMap *m = l->data;
+      GstOMXVideoNegotiationMap *m = l->data;
 
       if (m->format == info->finfo->format) {
         port_def.format.video.eColorFormat = m->type;
@@ -1123,7 +1013,7 @@ gst_omx_video_enc_set_format (GstVideoEncoder * encoder,
       }
     }
     g_list_free_full (negotiation_map,
-        (GDestroyNotify) video_negotiation_map_free);
+        (GDestroyNotify) gst_omx_video_negotiation_map_free);
   }
 
   port_def.format.video.nFrameWidth = info->width;
@@ -1781,24 +1671,18 @@ static GstCaps *
 gst_omx_video_enc_getcaps (GstVideoEncoder * encoder, GstCaps * filter)
 {
   GstOMXVideoEnc *self = GST_OMX_VIDEO_ENC (encoder);
-  GList *negotiation_map = NULL, *l;
+  GList *negotiation_map = NULL;
   GstCaps *comp_supported_caps;
 
   if (!self->enc)
     return gst_video_encoder_proxy_getcaps (encoder, NULL, filter);
 
-  negotiation_map = gst_omx_video_enc_get_supported_colorformats (self);
-  comp_supported_caps = gst_caps_new_empty ();
-  for (l = negotiation_map; l; l = l->next) {
-    VideoNegotiationMap *map = l->data;
-
-    gst_caps_append_structure (comp_supported_caps,
-        gst_structure_new ("video/x-raw",
-            "format", G_TYPE_STRING,
-            gst_video_format_to_string (map->format), NULL));
-  }
+  negotiation_map =
+      gst_omx_video_get_supported_colorformats (self->enc_in_port,
+      self->input_state);
+  comp_supported_caps = gst_omx_video_get_caps_4_map (negotiation_map);
   g_list_free_full (negotiation_map,
-      (GDestroyNotify) video_negotiation_map_free);
+      (GDestroyNotify) gst_omx_video_negotiation_map_free);
 
   if (!gst_caps_is_empty (comp_supported_caps)) {
     GstCaps *ret =