RELEASE: GStreamer FFmpeg Plug-ins 0.10.12 "A year in hell"

Edward Hervey bilboed at gmail.com
Thu Aug 11 02:30:57 PDT 2011


Hi,

On Thu, 2011-08-11 at 10:02 +0100, Tvrtko Ursulin wrote:
> On Wednesday 20 Jul 2011 12:02:00 Edward Hervey wrote:
[...]
> I see that multi-threaded decoding is disabled by default in gstffmpegdec. Is this
> because of known issues and how serious are they?

  The support for it was only dropped a month before release. The reason
why I set the default back to only using one thread was:
  * Lots of warnings from the libav side on some formats
  * Reports of segfaulting in some situations
  * Critical basic MT-safety patches landing the day I was going to do
the release.

  That being said, the multi-threading support in gst-ffmpeg hasn't been
removed/disabled. It's just that I've re-setted the default number of
threads to 1 (instead of 0 which is automatic numbers).
  So you can still force the number of threads you want manually.

  Hopefully everything will be more stable soon and we'll be able to do
a new gst-ffmpeg release with the default multi-threading enabled within
a couple of months.

> 
> With regards to ffdeinterlace - I did a pretty mechanical (not understading GStreamer
> internals and code base that well) patch  porting the mode property from good plugins
> deinterlace because having this control and automatic mode is quite convenient for us.
> 
> Would something like this be acceptable for merging upstream? At least in principle, I realize patch might have issues. :)
> 

  Put that patch in a new bug report on bugzilla.gnome.org . It'll be
handled there like all patches. I have no objections per-se.

    Edward

> Thanks,
> 
> Tvrtko
> 
> 
> diff -uprN a/gst-ffmpeg-0.10.12/ext/ffmpeg/gstffmpegdeinterlace.c b/gst-ffmpeg-0.10.12/ext/ffmpeg/gstffmpegdeinterlace.c
> --- a/gst-ffmpeg-0.10.12/ext/ffmpeg/gstffmpegdeinterlace.c	2011-07-13 10:07:28.000000000 +0100
> +++ b/gst-ffmpeg-0.10.12/ext/ffmpeg/gstffmpegdeinterlace.c	2011-08-04 11:11:30.542756021 +0100
> @@ -37,6 +37,44 @@
>  #include "gstffmpegcodecmap.h"
>  #include "gstffmpegutils.h"
>  
> +
> +/* Properties */
> +
> +#define DEFAULT_MODE            GST_FFMPEGDEINTERLACE_MODE_AUTO
> +
> +enum
> +{
> +  PROP_0,
> +  PROP_MODE,
> +  PROP_LAST
> +};
> +
> +typedef enum {
> +  GST_FFMPEGDEINTERLACE_MODE_AUTO,
> +  GST_FFMPEGDEINTERLACE_MODE_INTERLACED,
> +  GST_FFMPEGDEINTERLACE_MODE_DISABLED
> +} GstFFMpegDeinterlaceMode;
> +
> +#define GST_TYPE_FFMPEGDEINTERLACE_MODES (gst_ffmpegdeinterlace_modes_get_type ())
> +static GType
> +gst_ffmpegdeinterlace_modes_get_type (void)
> +{
> +  static GType deinterlace_modes_type = 0;
> +
> +  static const GEnumValue modes_types[] = {
> +    {GST_FFMPEGDEINTERLACE_MODE_AUTO, "Auto detection", "auto"},
> +    {GST_FFMPEGDEINTERLACE_MODE_INTERLACED, "Force deinterlacing", "interlaced"},
> +    {GST_FFMPEGDEINTERLACE_MODE_DISABLED, "Run in passthrough mode", "disabled"},
> +    {0, NULL, NULL},
> +  };
> +
> +  if (!deinterlace_modes_type) {
> +    deinterlace_modes_type =
> +        g_enum_register_static ("GstFFMpegDeinterlaceModes", modes_types);
> +  }
> +  return deinterlace_modes_type;
> +}
> +
>  typedef struct _GstFFMpegDeinterlace
>  {
>    GstElement element;
> @@ -46,6 +84,14 @@ typedef struct _GstFFMpegDeinterlace
>    gint width, height;
>    gint to_size;
>  
> +  GstFFMpegDeinterlaceMode mode;
> +  
> +  gboolean interlaced; /* is input interlaced? */
> +  gboolean passthrough;
> +  
> +  gboolean reconfigure;
> +  GstFFMpegDeinterlaceMode new_mode;
> +  
>    enum PixelFormat pixfmt;
>    AVPicture from_frame, to_frame;
>  } GstFFMpegDeinterlace;
> @@ -68,6 +114,11 @@ typedef struct _GstFFMpegDeinterlaceClas
>  
>  GType gst_ffmpegdeinterlace_get_type (void);
>  
> +static void gst_ffmpegdeinterlace_set_property (GObject * self, guint prop_id,
> +    const GValue * value, GParamSpec * pspec);
> +static void gst_ffmpegdeinterlace_get_property (GObject * self, guint prop_id,
> +    GValue * value, GParamSpec * pspec);
> +
>  static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
>      GST_PAD_SRC,
>      GST_PAD_ALWAYS,
> @@ -103,6 +154,34 @@ gst_ffmpegdeinterlace_base_init (gpointe
>  static void
>  gst_ffmpegdeinterlace_class_init (GstFFMpegDeinterlaceClass * klass)
>  {
> +  GObjectClass *gobject_class = (GObjectClass *) klass;
> +
> +  gobject_class->set_property = gst_ffmpegdeinterlace_set_property;
> +  gobject_class->get_property = gst_ffmpegdeinterlace_get_property;
> +
> +  /**
> +   * GstDeinterlace:mode
> +   * 
> +   * This selects whether the deinterlacing methods should
> +   * always be applied or if they should only be applied
> +   * on content that has the "interlaced" flag on the caps.
> +   *
> +   */
> +  g_object_class_install_property (gobject_class, PROP_MODE,
> +      g_param_spec_enum ("mode",
> +          "Mode",
> +          "Deinterlace Mode",
> +          GST_TYPE_FFMPEGDEINTERLACE_MODES,
> +          DEFAULT_MODE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
> +      );
> +}
> +
> +static void
> +gst_ffmpegdeinterlace_update_passthrough (GstFFMpegDeinterlace * deinterlace)
> +{
> +  deinterlace->passthrough = (deinterlace->mode == GST_FFMPEGDEINTERLACE_MODE_DISABLED
> +      || (!deinterlace->interlaced && deinterlace->mode != GST_FFMPEGDEINTERLACE_MODE_INTERLACED));
> +  GST_DEBUG_OBJECT (deinterlace, "Passthrough: %d", deinterlace->passthrough);
>  }
>  
>  static gboolean
> @@ -120,6 +199,10 @@ gst_ffmpegdeinterlace_sink_setcaps (GstP
>    if (!gst_structure_get_int (structure, "height", &deinterlace->height))
>      return FALSE;
>  
> +  deinterlace->interlaced = FALSE;
> +  gst_structure_get_boolean (structure, "interlaced", &deinterlace->interlaced);
> +  gst_ffmpegdeinterlace_update_passthrough (deinterlace);
> +
>    ctx = avcodec_alloc_context ();
>    ctx->width = deinterlace->width;
>    ctx->height = deinterlace->height;
> @@ -138,10 +221,10 @@ gst_ffmpegdeinterlace_sink_setcaps (GstP
>        avpicture_get_size (deinterlace->pixfmt, deinterlace->width,
>        deinterlace->height);
>  
> -  src_caps = gst_caps_copy (caps);
> -  gst_caps_set_simple (src_caps, "interlaced", G_TYPE_BOOLEAN, FALSE, NULL);
> -  ret = gst_pad_set_caps (deinterlace->srcpad, src_caps);
> -  gst_caps_unref (src_caps);
> +  src_caps = gst_caps_copy (caps);
> +  gst_caps_set_simple (src_caps, "interlaced", G_TYPE_BOOLEAN, deinterlace->interlaced, NULL);
> +  ret = gst_pad_set_caps (deinterlace->srcpad, src_caps);
> +  gst_caps_unref (src_caps);
>  
>    return ret;
>  }
> @@ -162,6 +245,12 @@ gst_ffmpegdeinterlace_init (GstFFMpegDei
>    gst_element_add_pad (GST_ELEMENT (deinterlace), deinterlace->srcpad);
>  
>    deinterlace->pixfmt = PIX_FMT_NB;
> +
> +  deinterlace->interlaced = FALSE;
> +  deinterlace->passthrough = FALSE;
> +  deinterlace->reconfigure = FALSE;
> +  deinterlace->mode = DEFAULT_MODE;
> +  deinterlace->new_mode = -1;
>  }
>  
>  static GstFlowReturn
> @@ -172,6 +261,23 @@ gst_ffmpegdeinterlace_chain (GstPad * pa
>    GstBuffer *outbuf = NULL;
>    GstFlowReturn result;
>  
> +  GST_OBJECT_LOCK (deinterlace);
> +  if (deinterlace->reconfigure) {
> +    if (deinterlace->new_mode != -1)
> +      deinterlace->mode = deinterlace->new_mode;
> +    deinterlace->new_mode = -1;
> +
> +    deinterlace->reconfigure = FALSE;
> +    GST_OBJECT_UNLOCK (deinterlace);
> +    if (GST_PAD_CAPS (deinterlace->srcpad))
> +      gst_ffmpegdeinterlace_sink_setcaps (deinterlace->sinkpad, GST_PAD_CAPS (deinterlace->sinkpad));
> +  } else {
> +    GST_OBJECT_UNLOCK (deinterlace);
> +  }
> +  
> +  if (deinterlace->passthrough)
> +      return gst_pad_push (deinterlace->srcpad, inbuf);
> +
>    result =
>        gst_pad_alloc_buffer (deinterlace->srcpad, GST_BUFFER_OFFSET_NONE,
>        deinterlace->to_size, GST_PAD_CAPS (deinterlace->srcpad), &outbuf);
> @@ -202,3 +308,53 @@ gst_ffmpegdeinterlace_register (GstPlugi
>    return gst_element_register (plugin, "ffdeinterlace",
>        GST_RANK_NONE, GST_TYPE_FFMPEGDEINTERLACE);
>  }
> +
> +static void
> +gst_ffmpegdeinterlace_set_property (GObject * object, guint prop_id,
> +    const GValue * value, GParamSpec * pspec)
> +{
> +  GstFFMpegDeinterlace *self;
> +
> +  g_return_if_fail (GST_IS_FFMPEGDEINTERLACE (object));
> +  self = GST_FFMPEGDEINTERLACE (object);
> +
> +  switch (prop_id) {
> +    case PROP_MODE:{
> +      gint new_mode;
> +
> +      GST_OBJECT_LOCK (self);
> +      new_mode = g_value_get_enum (value);
> +      if (self->mode != new_mode && GST_PAD_CAPS (self->srcpad)) {
> +        self->reconfigure = TRUE;
> +        self->new_mode = new_mode;
> +      } else {
> +        self->mode = new_mode;
> +        gst_ffmpegdeinterlace_update_passthrough (self);
> +      }
> +      GST_OBJECT_UNLOCK (self);
> +      break;
> +    }
> +    default:
> +      G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec);
> +  }
> +
> +}
> +
> +static void
> +gst_ffmpegdeinterlace_get_property (GObject * object, guint prop_id,
> +    GValue * value, GParamSpec * pspec)
> +{
> +  GstFFMpegDeinterlace *self;
> +
> +  g_return_if_fail (GST_IS_FFMPEGDEINTERLACE (object));
> +  self = GST_FFMPEGDEINTERLACE (object);
> +
> +  switch (prop_id) {
> +    case PROP_MODE:
> +      g_value_set_enum (value, self->mode);
> +      break;
> +    default:
> +      G_OBJECT_WARN_INVALID_PROPERTY_ID (self, prop_id, pspec);
> +  }
> +}
> +




More information about the gstreamer-devel mailing list