gst/audioconvert/gstaudioconvert.c: Lower debug, use g_assert in _get_unit_size
[platform/upstream/gstreamer.git] / gst / ffmpegcolorspace / gstffmpegcolorspace.c
index ca6ff13..b3a0b72 100644 (file)
 #include "gstffmpegcolorspace.h"
 #include "gstffmpegcodecmap.h"
 
-GST_DEBUG_CATEGORY (ffmpegcolorspace_debug);
+GST_DEBUG_CATEGORY_STATIC (ffmpegcolorspace_debug);
 #define GST_CAT_DEFAULT ffmpegcolorspace_debug
 
 /* elementfactory information */
-static GstElementDetails ffmpegcsp_details = {
-  "FFMPEG Colorspace converter",
-  "Filter/Converter/Video",
-  "Converts video from one colorspace to another",
-  "Ronald Bultje <rbultje@ronald.bitfreak.net>",
-};
+static const GstElementDetails ffmpegcsp_details =
+GST_ELEMENT_DETAILS ("FFMPEG Colorspace converter",
+    "Filter/Converter/Video",
+    "Converts video from one colorspace to another",
+    "Ronald Bultje <rbultje@ronald.bitfreak.net>");
 
 
 /* Stereo signals and args */
@@ -108,6 +107,7 @@ gst_ffmpegcsp_caps_remove_format_info (GstCaps * caps)
     gst_structure_remove_field (structure, "green_mask");
     gst_structure_remove_field (structure, "blue_mask");
     gst_structure_remove_field (structure, "alpha_mask");
+    gst_structure_remove_field (structure, "palette_data");
   }
 
   gst_caps_do_simplify (caps);
@@ -147,11 +147,13 @@ gst_ffmpegcsp_transform_caps (GstBaseTransform * btrans,
 
   template = gst_ffmpegcsp_codectype_to_caps (CODEC_TYPE_VIDEO, NULL);
   result = gst_caps_intersect (caps, template);
+  gst_caps_unref (template);
 
   gst_caps_append (result, gst_ffmpegcsp_caps_remove_format_info (caps));
 
   GST_DEBUG_OBJECT (btrans, "transformed %" GST_PTR_FORMAT " into %"
       GST_PTR_FORMAT, caps, result);
+
   return result;
 }
 
@@ -163,7 +165,8 @@ gst_ffmpegcsp_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
   GstStructure *structure;
   gint in_height, in_width;
   gint out_height, out_width;
-  gdouble in_framerate, out_framerate;
+  const GValue *in_framerate = NULL;
+  const GValue *out_framerate = NULL;
   const GValue *in_par = NULL;
   const GValue *out_par = NULL;
   AVCodecContext *ctx;
@@ -177,10 +180,14 @@ gst_ffmpegcsp_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
   /* we have to have width and height */
   res = gst_structure_get_int (structure, "width", &in_width);
   res &= gst_structure_get_int (structure, "height", &in_height);
-  res &= gst_structure_get_double (structure, "framerate", &in_framerate);
   if (!res)
     goto no_width_height;
 
+  /* and framerate */
+  in_framerate = gst_structure_get_value (structure, "framerate");
+  if (in_framerate == NULL || !GST_VALUE_HOLDS_FRACTION (in_framerate))
+    goto no_framerate;
+
   /* this is optional */
   in_par = gst_structure_get_value (structure, "pixel-aspect-ratio");
 
@@ -189,16 +196,20 @@ gst_ffmpegcsp_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
   /* we have to have width and height */
   res = gst_structure_get_int (structure, "width", &out_width);
   res &= gst_structure_get_int (structure, "height", &out_height);
-  res &= gst_structure_get_double (structure, "framerate", &out_framerate);
   if (!res)
     goto no_width_height;
 
+  /* and framerate */
+  out_framerate = gst_structure_get_value (structure, "framerate");
+  if (out_framerate == NULL || !GST_VALUE_HOLDS_FRACTION (out_framerate))
+    goto no_framerate;
+
   /* this is optional */
   out_par = gst_structure_get_value (structure, "pixel-aspect-ratio");
 
   /* these must match */
   if (in_width != out_width || in_height != out_height ||
-      in_framerate != out_framerate)
+      gst_value_compare (in_framerate, out_framerate) != GST_VALUE_EQUAL)
     goto format_mismatch;
 
   /* if present, these must match too */
@@ -222,6 +233,7 @@ gst_ffmpegcsp_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
   if (space->palette)
     av_free (space->palette);
   space->palette = ctx->palctrl;
+  ctx->palctrl = NULL;
 
   /* get to format */
   ctx->pix_fmt = PIX_FMT_NB;
@@ -239,21 +251,28 @@ gst_ffmpegcsp_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
   /* ERRORS */
 no_width_height:
   {
-    GST_DEBUG ("did not specify width or height");
+    GST_DEBUG_OBJECT (space, "did not specify width or height");
+    space->from_pixfmt = PIX_FMT_NB;
+    space->to_pixfmt = PIX_FMT_NB;
+    return FALSE;
+  }
+no_framerate:
+  {
+    GST_DEBUG_OBJECT (space, "did not specify framerate");
     space->from_pixfmt = PIX_FMT_NB;
     space->to_pixfmt = PIX_FMT_NB;
     return FALSE;
   }
 format_mismatch:
   {
-    GST_DEBUG ("input and output formats do not match");
+    GST_DEBUG_OBJECT (space, "input and output formats do not match");
     space->from_pixfmt = PIX_FMT_NB;
     space->to_pixfmt = PIX_FMT_NB;
     return FALSE;
   }
 invalid_in_caps:
   {
-    GST_DEBUG ("could not configure context for input format");
+    GST_DEBUG_OBJECT (space, "could not configure context for input format");
     av_free (ctx);
     space->from_pixfmt = PIX_FMT_NB;
     space->to_pixfmt = PIX_FMT_NB;
@@ -261,7 +280,7 @@ invalid_in_caps:
   }
 invalid_out_caps:
   {
-    GST_DEBUG ("could not configure context for output format");
+    GST_DEBUG_OBJECT (space, "could not configure context for output format");
     av_free (ctx);
     space->from_pixfmt = PIX_FMT_NB;
     space->to_pixfmt = PIX_FMT_NB;
@@ -288,7 +307,7 @@ gst_ffmpegcsp_get_type (void)
     };
 
     ffmpegcsp_type = g_type_register_static (GST_TYPE_BASE_TRANSFORM,
-        "GstFFMpegColorspace", &ffmpegcsp_info, 0);
+        "GstFFMpegCsp", &ffmpegcsp_info, 0);
   }
 
   return ffmpegcsp_type;
@@ -305,6 +324,17 @@ gst_ffmpegcsp_base_init (GstFFMpegCspClass * klass)
 }
 
 static void
+gst_ffmpegcsp_finalize (GObject * obj)
+{
+  GstFFMpegCsp *space = GST_FFMPEGCSP (obj);
+
+  if (space->palette)
+    av_free (space->palette);
+
+  G_OBJECT_CLASS (parent_class)->finalize (obj);
+}
+
+static void
 gst_ffmpegcsp_class_init (GstFFMpegCspClass * klass)
 {
   GObjectClass *gobject_class;
@@ -315,7 +345,9 @@ gst_ffmpegcsp_class_init (GstFFMpegCspClass * klass)
   gstelement_class = (GstElementClass *) klass;
   gstbasetransform_class = (GstBaseTransformClass *) klass;
 
-  parent_class = g_type_class_ref (GST_TYPE_BASE_TRANSFORM);
+  parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_ffmpegcsp_finalize);
 
   gstbasetransform_class->transform_caps =
       GST_DEBUG_FUNCPTR (gst_ffmpegcsp_transform_caps);
@@ -338,6 +370,7 @@ gst_ffmpegcsp_class_init (GstFFMpegCspClass * klass)
 static void
 gst_ffmpegcsp_init (GstFFMpegCsp * space)
 {
+  gst_base_transform_set_qos_enabled (GST_BASE_TRANSFORM (space), TRUE);
   space->from_pixfmt = space->to_pixfmt = PIX_FMT_NB;
   space->palette = NULL;
 }
@@ -351,7 +384,7 @@ gst_ffmpegcsp_get_unit_size (GstBaseTransform * btrans, GstCaps * caps,
   AVCodecContext *ctx = NULL;
   gint width, height;
 
-  g_return_val_if_fail (size, FALSE);
+  g_assert (size);
 
   space = GST_FFMPEGCSP (btrans);
 
@@ -367,9 +400,16 @@ gst_ffmpegcsp_get_unit_size (GstBaseTransform * btrans, GstCaps * caps,
 
   *size = avpicture_get_size (ctx->pix_fmt, width, height);
 
-  if (space->palette)
-    *size -= 4 * 256;
+  /* ffmpeg frames have the palette after the frame data, whereas
+   * GStreamer currently puts it into the caps as 'palette_data' field,
+   * so for paletted data the frame size avpicture_get_size() returns is
+   * 1024 bytes larger than what GStreamer expects. */
+  if (gst_structure_has_field (structure, "palette_data")) {
+    *size -= 4 * 256;           /* = AVPALETTE_SIZE */
+  }
 
+  if (ctx->palctrl)
+    av_free (ctx->palctrl);
   av_free (ctx);
 
   return TRUE;
@@ -390,6 +430,7 @@ gst_ffmpegcsp_transform (GstBaseTransform * btrans, GstBuffer * inbuf,
     GstBuffer * outbuf)
 {
   GstFFMpegCsp *space;
+  gint result;
 
   space = GST_FFMPEGCSP (btrans);
 
@@ -410,8 +451,10 @@ gst_ffmpegcsp_transform (GstBaseTransform * btrans, GstBuffer * inbuf,
       GST_BUFFER_DATA (outbuf), space->to_pixfmt, space->width, space->height);
 
   /* and convert */
-  img_convert (&space->to_frame, space->to_pixfmt,
+  result = img_convert (&space->to_frame, space->to_pixfmt,
       &space->from_frame, space->from_pixfmt, space->width, space->height);
+  if (result == -1)
+    goto not_supported;
 
   /* copy timestamps */
   gst_buffer_stamp (outbuf, inbuf);
@@ -426,6 +469,12 @@ unknown_format:
         ("attempting to convert colorspaces between unknown formats"));
     return GST_FLOW_NOT_NEGOTIATED;
   }
+not_supported:
+  {
+    GST_ELEMENT_ERROR (space, CORE, NOT_IMPLEMENTED, (NULL),
+        ("cannot convert between formats"));
+    return GST_FLOW_NOT_SUPPORTED;
+  }
 }
 
 gboolean