ducativideodec: add a max-reorder-frames decoder property
authorVincent Penquerc'h <vincent.penquerch@collabora.co.uk>
Fri, 19 Oct 2012 09:37:09 +0000 (10:37 +0100)
committerVincent Penquerc'h <vincent.penquerch@collabora.co.uk>
Fri, 19 Oct 2012 09:37:09 +0000 (10:37 +0100)
It allows giving a default high bound for the number of
previous frames to buffer in order to do reordering, for
those codecs with B frames. This will be used instead of
the default high bound of 16 if a stream limit can not
be found, allowing latency to be kept in check.

src/gstducatih264dec.c
src/gstducatimpeg2dec.c
src/gstducatividdec.c
src/gstducatividdec.h

index e5eeba07a49321db6115cf3afd0cfa3bf9634c4e..f65a2ee393ea51f712fe4e2fffc883f1696809f5 100644 (file)
@@ -246,20 +246,20 @@ gst_ducati_h264dec_get_max_dpb_size (GstDucatiVidDec * self, GstCaps * caps)
 
   structure = gst_caps_get_structure (caps, 0);
   if (!structure)
-    return 16;
+    return -1;
 
   level = gst_structure_get_string (structure, "level");
   if (!level)
-    return 16;
+    return -1;
 
   max_dpb = gst_ducati_h264dec_find_max_dpb_from_level (self, level);
   if (max_dpb < 0)
-    return 16;
+    return -1;
 
   max_dpb_size =
       lrint (ceil (1024 * max_dpb / (wmb * hmb * 256 * chroma_factor)));
-  if (max_dpb_size > 16)
-    max_dpb_size = 16;
+  if (max_dpb_size > MAX_BACKLOG_FRAMES)
+    max_dpb_size = MAX_BACKLOG_FRAMES;
 
   return max_dpb_size;
 }
@@ -342,6 +342,8 @@ gst_ducati_h264dec_set_sink_caps (GstDucatiVidDec * self, GstCaps * caps)
   /* If not present, use the spec forumula for a bound */
   if (self->backlog_maxframes < 0) {
     self->backlog_maxframes = gst_ducati_h264dec_get_max_dpb_size (self, caps);
+    if (self->backlog_maxframes < 0)
+      self->backlog_maxframes = self->backlog_default_maxframes;
     GST_WARNING_OBJECT (self,
         "num-reorder-frames not found on caps, defaulting to %d",
         self->backlog_maxframes);
index faf367a0018b60a34e82e716f05066f9d4e717f3..f8085154a6408f71b2db2685797116ea6c39bc07 100644 (file)
@@ -126,7 +126,7 @@ gst_ducati_mpeg2dec_set_sink_caps (GstDucatiVidDec * self, GstCaps * caps)
   profile = gst_structure_get_string (structure, "profile");
   if (!profile || strcmp (profile, "simple")) {
     /* TODO: can a better bound be found from stream headers ? */
-    self->backlog_maxframes = MAX_BACKLOG_FRAMES;
+    self->backlog_maxframes = self->backlog_default_maxframes;
   }
 
   return TRUE;
index ab3147dd4fb54cea58833c8dfefad6c4adf38278..a641b36c559814a89d7824cf9af4a9483e1bb471 100644 (file)
@@ -38,6 +38,7 @@ enum
 {
   PROP_0,
   PROP_VERSION,
+  PROP_MAX_REORDER_FRAMES,
 };
 
 /* helper functions */
@@ -1405,6 +1406,26 @@ gst_ducati_viddec_get_property (GObject * obj,
 
       break;
     }
+    case PROP_MAX_REORDER_FRAMES:
+      g_value_set_int (value, self->backlog_default_maxframes);
+      break;
+    default:{
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+      break;
+    }
+  }
+}
+
+static void
+gst_ducati_viddec_set_property (GObject * obj,
+    guint prop_id, const GValue * value, GParamSpec * pspec)
+{
+  GstDucatiVidDec *self = GST_DUCATIVIDDEC (obj);
+
+  switch (prop_id) {
+    case PROP_MAX_REORDER_FRAMES:
+      self->backlog_default_maxframes = g_value_get_int (value);
+      break;
     default:{
       G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
       break;
@@ -1447,6 +1468,8 @@ gst_ducati_viddec_class_init (GstDucatiVidDecClass * klass)
 
   gobject_class->get_property =
       GST_DEBUG_FUNCPTR (gst_ducati_viddec_get_property);
+  gobject_class->set_property =
+      GST_DEBUG_FUNCPTR (gst_ducati_viddec_set_property);
   gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_ducati_viddec_finalize);
   gstelement_class->change_state =
       GST_DEBUG_FUNCPTR (gst_ducati_viddec_change_state);
@@ -1466,6 +1489,17 @@ gst_ducati_viddec_class_init (GstDucatiVidDecClass * klass)
       g_param_spec_string ("version", "Version",
           "The codec version string", "",
           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+  g_object_class_install_property (gobject_class, PROP_MAX_REORDER_FRAMES,
+      g_param_spec_int ("max-reorder-frames",
+          "Maximum number of frames needed for reordering",
+          "The maximum number of frames needed for reordering output frames. "
+          "Only meaningful for codecs with B frames. 0 means no reordering. "
+          "This value will be used if the correct value cannot be inferred "
+          "from the stream. Too low a value may cause misordering, too high "
+          "will cause extra latency.",
+          0, MAX_BACKLOG_FRAMES, MAX_BACKLOG_FRAMES,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 }
 
 static void
@@ -1530,6 +1564,7 @@ gst_ducati_viddec_init (GstDucatiVidDec * self, GstDucatiVidDecClass * klass)
 
   self->backlog_maxframes = 0;
   self->backlog_nframes = 0;
+  self->backlog_default_maxframes = MAX_BACKLOG_FRAMES;
 
   self->passed_in_bufs = g_hash_table_new_full (g_direct_hash, g_direct_equal,
       NULL, (GDestroyNotify) gst_buffer_unref);
index def8247a4dbad57f8f06952a60f4f968a63086b3..3d481f42ba16160a1547035efa7558f9e46b8715 100644 (file)
@@ -142,6 +142,7 @@ struct _GstDucatiVidDec
   GstBuffer *backlog_frames[MAX_BACKLOG_FRAMES + 1];
   gint backlog_maxframes;
   gint backlog_nframes;
+  gint backlog_default_maxframes;
 };
 
 struct _GstDucatiVidDecClass