basevideodecoder: add capture pattern handling
authorDavid Schleef <ds@schleef.org>
Sun, 19 Sep 2010 02:21:47 +0000 (19:21 -0700)
committerDavid Schleef <ds@schleef.org>
Sun, 19 Sep 2010 02:27:07 +0000 (19:27 -0700)
Move typical scan_for_sync() usage into base class, which just
calls gst_adapter_masked_scan_uint32().

ext/schroedinger/gstschrodec.c
gst-libs/gst/video/gstbasevideodecoder.c
gst-libs/gst/video/gstbasevideodecoder.h

index b5b768face7c857ef78fbe1dad68af67113ec352..cfde8cd66157886df737cb5a1ad1354b3a6f3e8b 100644 (file)
@@ -90,8 +90,6 @@ static gboolean gst_schro_dec_stop (GstBaseVideoDecoder * dec);
 static gboolean gst_schro_dec_reset (GstBaseVideoDecoder * dec);
 static GstFlowReturn gst_schro_dec_parse_data (GstBaseVideoDecoder *
     base_video_decoder, gboolean at_eos);
-static int gst_schro_dec_scan_for_sync (GstBaseVideoDecoder *
-    base_video_decoder, gboolean at_eos, int offset, int n);
 static GstFlowReturn gst_schro_dec_handle_frame (GstBaseVideoDecoder * decoder,
     GstVideoFrame * frame);
 static gboolean gst_schro_dec_finish (GstBaseVideoDecoder * base_video_decoder);
@@ -150,11 +148,12 @@ gst_schro_dec_class_init (GstSchroDecClass * klass)
   base_video_decoder_class->reset = GST_DEBUG_FUNCPTR (gst_schro_dec_reset);
   base_video_decoder_class->parse_data =
       GST_DEBUG_FUNCPTR (gst_schro_dec_parse_data);
-  base_video_decoder_class->scan_for_sync =
-      GST_DEBUG_FUNCPTR (gst_schro_dec_scan_for_sync);
   base_video_decoder_class->handle_frame =
       GST_DEBUG_FUNCPTR (gst_schro_dec_handle_frame);
   base_video_decoder_class->finish = GST_DEBUG_FUNCPTR (gst_schro_dec_finish);
+
+  gst_base_video_decoder_class_set_capture_pattern (base_video_decoder_class,
+      0xffffffff, 0x42424344);
 }
 
 static void
@@ -536,35 +535,6 @@ gst_schro_dec_parse_data (GstBaseVideoDecoder * base_video_decoder,
   return GST_FLOW_OK;
 }
 
-static int
-gst_schro_dec_scan_for_sync (GstBaseVideoDecoder * base_video_decoder,
-    gboolean at_eos, int offset, int n)
-{
-  GstAdapter *adapter = base_video_decoder->input_adapter;
-  int n_available;
-  int ret;
-
-  n_available = gst_adapter_available (adapter) - offset;
-
-  if (n_available < 4) {
-    if (at_eos) {
-      return n_available;
-    } else {
-      return 0;
-    }
-  }
-
-  n = MIN (n, n_available - 3);
-
-  ret = gst_adapter_masked_scan_uint32 (adapter, 0xffffffff, 0x42424344,
-      offset, n);
-  if (ret == -1) {
-    return n;
-  }
-  return ret;
-}
-
-
 static void
 gst_schrodec_send_tags (GstSchroDec * schro_dec)
 {
index 198b3a8861f6f1ef52028d2ab4aba9c06834e5e3..42e7b11bc320e17c1fae4e9ce397d70588f0fdbb 100644 (file)
@@ -862,32 +862,36 @@ gst_base_video_decoder_chain (GstPad * pad, GstBuffer * buf)
       GST_DEBUG ("no sync, scanning");
 
       n = gst_adapter_available (base_video_decoder->input_adapter);
-      m = klass->scan_for_sync (base_video_decoder, FALSE, 0, n);
+      if (klass->capture_mask != 0) {
+        m = gst_adapter_masked_scan_uint32 (base_video_decoder->input_adapter,
+            klass->capture_mask, klass->capture_pattern, 0, n - 3);
+      } else if (klass->scan_for_sync) {
+        m = klass->scan_for_sync (base_video_decoder, FALSE, 0, n);
+      } else {
+        m = 0;
+      }
       if (m == -1) {
+        GST_ERROR ("scan returned no sync");
+        gst_adapter_flush (base_video_decoder->input_adapter, n - 3);
+
         gst_object_unref (base_video_decoder);
         return GST_FLOW_OK;
-      }
-
-      if (m < 0) {
-        g_warning ("subclass returned negative scan %d", m);
-      }
-
-      if (m >= n) {
-        GST_ERROR ("subclass scanned past end %d >= %d", m, n);
-      }
+      } else {
+        if (m > 0) {
+          if (m >= n) {
+            GST_ERROR ("subclass scanned past end %d >= %d", m, n);
+          }
 
-      gst_adapter_flush (base_video_decoder->input_adapter, m);
+          gst_adapter_flush (base_video_decoder->input_adapter, m);
 
-      if (m < n) {
-        GST_DEBUG ("found possible sync after %d bytes (of %d)", m, n);
+          if (m < n) {
+            GST_DEBUG ("found possible sync after %d bytes (of %d)", m, n);
 
-        /* this is only "maybe" sync */
-        base_video_decoder->have_sync = TRUE;
-      }
+            /* this is only "maybe" sync */
+            base_video_decoder->have_sync = TRUE;
+          }
+        }
 
-      if (!base_video_decoder->have_sync) {
-        gst_object_unref (base_video_decoder);
-        return GST_FLOW_OK;
       }
     }
 
@@ -1496,3 +1500,13 @@ gst_base_video_decoder_get_max_decode_time (GstBaseVideoDecoder *
 
   return deadline;
 }
+
+void
+gst_base_video_decoder_class_set_capture_pattern (GstBaseVideoDecoderClass *
+    base_video_decoder_class, guint32 mask, guint32 pattern)
+{
+  g_return_if_fail (((~mask) & pattern) == 0);
+
+  base_video_decoder_class->capture_mask = mask;
+  base_video_decoder_class->capture_pattern = pattern;
+}
index 6bc606d9c7ea6ff8b1a207e4210f592b8cbdc4cf..f996a587ec2fc85cd4a9f370dc9ca5aa0cf998b0 100644 (file)
@@ -137,10 +137,15 @@ struct _GstBaseVideoDecoderClass
   GstFlowReturn (*shape_output) (GstBaseVideoDecoder *coder, GstVideoFrame *frame);
   GstCaps *(*get_caps) (GstBaseVideoDecoder *coder);
 
+  guint32 capture_mask;
+  guint32 capture_pattern;
 };
 
 GType gst_base_video_decoder_get_type (void);
 
+void gst_base_video_decoder_class_set_capture_pattern (GstBaseVideoDecoderClass *klass,
+    guint32 mask, guint32 pattern);
+
 int gst_base_video_decoder_get_width (GstBaseVideoDecoder *coder);
 int gst_base_video_decoder_get_height (GstBaseVideoDecoder *coder);