y4m: port some more
authorWim Taymans <wim.taymans@collabora.co.uk>
Sun, 10 Jul 2011 11:44:49 +0000 (13:44 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Sun, 10 Jul 2011 11:48:54 +0000 (13:48 +0200)
Use video helpers.

gst/y4m/gsty4mencode.c
gst/y4m/gsty4mencode.h

index 7f0677c..d007a1d 100644 (file)
@@ -138,79 +138,54 @@ gst_y4m_encode_init (GstY4mEncode * filter)
 static void
 gst_y4m_encode_reset (GstY4mEncode * filter)
 {
-  filter->width = filter->height = -1;
-  filter->fps_num = filter->fps_den = 1;
-  filter->par_num = filter->par_den = 1;
-  filter->colorspace = "unknown";
+  filter->negotiated = FALSE;
 }
 
 static gboolean
 gst_y4m_encode_setcaps (GstPad * pad, GstCaps * vscaps)
 {
+  gboolean ret;
   GstY4mEncode *filter;
-  GstStructure *structure;
-  gboolean res;
-  gint w, h;
-  guint32 fourcc;
-  const GValue *fps, *par, *interlaced;
+  GstVideoInfo info;
 
   filter = GST_Y4M_ENCODE (GST_PAD_PARENT (pad));
 
-  structure = gst_caps_get_structure (vscaps, 0);
+  if (!gst_video_info_from_caps (&info, vscaps))
+    goto invalid_format;
 
-  res = gst_structure_get_int (structure, "width", &w);
-  res &= gst_structure_get_int (structure, "height", &h);
-  res &= ((fps = gst_structure_get_value (structure, "framerate")) != NULL);
-  res &= gst_structure_get_fourcc (structure, "format", &fourcc);
+  filter->info = info;
 
-  switch (fourcc) {             /* Translate fourcc to Y4M colorspace code */
-    case GST_MAKE_FOURCC ('I', '4', '2', '0'):
-    case GST_MAKE_FOURCC ('I', 'Y', 'U', 'V'):
+  switch (GST_VIDEO_INFO_FORMAT (&filter->info)) {
+    case GST_VIDEO_FORMAT_I420:
       filter->colorspace = "420";
       break;
-    case GST_MAKE_FOURCC ('Y', '4', '2', 'B'):
+    case GST_VIDEO_FORMAT_Y42B:
       filter->colorspace = "422";
       break;
-    case GST_MAKE_FOURCC ('Y', '4', '1', 'B'):
+    case GST_VIDEO_FORMAT_Y41B:
       filter->colorspace = "411";
       break;
-    case GST_MAKE_FOURCC ('Y', '4', '4', '4'):
+    case GST_VIDEO_FORMAT_Y444:
       filter->colorspace = "444";
       break;
     default:
-      res = FALSE;
-      break;
+      goto invalid_format;
   }
 
-  if (!res || w <= 0 || h <= 0 || !GST_VALUE_HOLDS_FRACTION (fps))
-    return FALSE;
-
-  /* optional interlaced info */
-  interlaced = gst_structure_get_value (structure, "interlaced");
-
-  /* optional par info */
-  par = gst_structure_get_value (structure, "pixel-aspect-ratio");
-
-  filter->width = w;
-  filter->height = h;
-  filter->fps_num = gst_value_get_fraction_numerator (fps);
-  filter->fps_den = gst_value_get_fraction_denominator (fps);
-  if ((par != NULL) && GST_VALUE_HOLDS_FRACTION (par)) {
-    filter->par_num = gst_value_get_fraction_numerator (par);
-    filter->par_den = gst_value_get_fraction_denominator (par);
-  } else {                      /* indicates unknown */
-    filter->par_num = 0;
-    filter->par_den = 0;
-  }
-  if ((interlaced != NULL) && G_VALUE_HOLDS (interlaced, G_TYPE_BOOLEAN)) {
-    filter->interlaced = g_value_get_boolean (interlaced);
-  } else {
-    /* assume progressive if no interlaced property in caps */
-    filter->interlaced = FALSE;
-  }
   /* the template caps will do for the src pad, should always accept */
-  return gst_pad_set_caps (filter->srcpad,
+  ret = gst_pad_set_caps (filter->srcpad,
       gst_static_pad_template_get_caps (&y4mencode_src_factory));
+
+  filter->negotiated = ret;
+
+  return ret;
+
+  /* ERRORS */
+invalid_format:
+  {
+    GST_ERROR_OBJECT (filter, "got invalid caps");
+    return FALSE;
+  }
 }
 
 static gboolean
@@ -236,23 +211,29 @@ gst_y4m_encode_sink_event (GstPad * pad, GstEvent * event)
 }
 
 static inline GstBuffer *
-gst_y4m_encode_get_stream_header (GstY4mEncode * filter)
+gst_y4m_encode_get_stream_header (GstY4mEncode * filter, gboolean tff)
 {
   gpointer header;
   GstBuffer *buf;
   gchar interlaced;
   gsize len;
 
-  interlaced = 'p';
-
-  if (filter->interlaced && filter->top_field_first)
-    interlaced = 't';
-  else if (filter->interlaced)
-    interlaced = 'b';
+  if (filter->info.flags & GST_VIDEO_FLAG_INTERLACED) {
+    if (tff)
+      interlaced = 't';
+    else
+      interlaced = 'b';
+  } else {
+    interlaced = 'p';
+  }
 
   header = g_strdup_printf ("YUV4MPEG2 C%s W%d H%d I%c F%d:%d A%d:%d\n",
-      filter->colorspace, filter->width, filter->height, interlaced,
-      filter->fps_num, filter->fps_den, filter->par_num, filter->par_den);
+      filter->colorspace, GST_VIDEO_INFO_WIDTH (&filter->info),
+      GST_VIDEO_INFO_HEIGHT (&filter->info), interlaced,
+      GST_VIDEO_INFO_FPS_N (&filter->info),
+      GST_VIDEO_INFO_FPS_D (&filter->info),
+      GST_VIDEO_INFO_PAR_N (&filter->info),
+      GST_VIDEO_INFO_PAR_D (&filter->info));
   len = strlen (header);
 
   buf = gst_buffer_new ();
@@ -287,30 +268,24 @@ gst_y4m_encode_chain (GstPad * pad, GstBuffer * buf)
   GstClockTime timestamp;
 
   /* check we got some decent info from caps */
-  if (filter->width < 0) {
-    GST_ELEMENT_ERROR ("filter", CORE, NEGOTIATION, (NULL),
-        ("format wasn't negotiated before chain function"));
-    gst_buffer_unref (buf);
-    return GST_FLOW_NOT_NEGOTIATED;
-  }
+  if (GST_VIDEO_INFO_FORMAT (&filter->info) != GST_VIDEO_FORMAT_UNKNOWN)
+    goto not_negotiated;
 
   timestamp = GST_BUFFER_TIMESTAMP (buf);
 
   if (G_UNLIKELY (!filter->header)) {
-    if (filter->interlaced == TRUE) {
-      if (GST_BUFFER_FLAG_IS_SET (buf, GST_VIDEO_BUFFER_TFF)) {
-        filter->top_field_first = TRUE;
-      } else {
-        filter->top_field_first = FALSE;
-      }
+    gboolean tff;
+
+    if (filter->info.flags & GST_VIDEO_FLAG_INTERLACED) {
+      tff = GST_BUFFER_FLAG_IS_SET (buf, GST_VIDEO_BUFFER_TFF);
     }
-    outbuf = gst_y4m_encode_get_stream_header (filter);
+    outbuf = gst_y4m_encode_get_stream_header (filter, tff);
     filter->header = TRUE;
     outbuf = gst_buffer_join (outbuf, gst_y4m_encode_get_frame_header (filter));
   } else {
     outbuf = gst_y4m_encode_get_frame_header (filter);
   }
-  /* join with data */
+  /* join with data, FIXME, strides are all wrong etc */
   outbuf = gst_buffer_join (outbuf, buf);
   /* decorate */
   outbuf = gst_buffer_make_writable (outbuf);
@@ -318,6 +293,15 @@ gst_y4m_encode_chain (GstPad * pad, GstBuffer * buf)
   GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
 
   return gst_pad_push (filter->srcpad, outbuf);
+
+  /* ERRORS */
+not_negotiated:
+  {
+    GST_ELEMENT_ERROR ("filter", CORE, NEGOTIATION, (NULL),
+        ("format wasn't negotiated before chain function"));
+    gst_buffer_unref (buf);
+    return GST_FLOW_NOT_NEGOTIATED;
+  }
 }
 
 static void
index 624ab37..9eb820e 100644 (file)
@@ -48,11 +48,9 @@ struct _GstY4mEncode {
   GstPad *sinkpad,*srcpad;
 
   /* caps information */
-  gint width, height;
-  gint fps_num, fps_den;
-  gint par_num, par_den;
-  gboolean interlaced;
-  gboolean top_field_first;
+  GstVideoInfo info;
+  gboolean negotiated;
+
   const gchar *colorspace;
   /* state information */
   gboolean header;