videoparsers: adjust to modified baseparse API
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Mon, 13 Feb 2012 17:44:01 +0000 (18:44 +0100)
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Mon, 13 Feb 2012 17:44:01 +0000 (18:44 +0100)
gst/videoparsers/gstdiracparse.c
gst/videoparsers/gsth263parse.c
gst/videoparsers/gsth264parse.c
gst/videoparsers/gstmpeg4videoparse.c
gst/videoparsers/gstmpegvideoparse.c

index 7725c97..3327700 100644 (file)
@@ -56,10 +56,8 @@ static gboolean gst_dirac_parse_set_sink_caps (GstBaseParse * parse,
     GstCaps * caps);
 static GstCaps *gst_dirac_parse_get_sink_caps (GstBaseParse * parse,
     GstCaps * filter);
-static gboolean gst_dirac_parse_check_valid_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame, guint * framesize, gint * skipsize);
-static GstFlowReturn gst_dirac_parse_parse_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame);
+static GstFlowReturn gst_dirac_parse_handle_frame (GstBaseParse * parse,
+    GstBaseParseFrame * frame, gint * skipsize);
 static gboolean gst_dirac_parse_convert (GstBaseParse * parse,
     GstFormat src_format, gint64 src_value, GstFormat dest_format,
     gint64 * dest_value);
@@ -127,10 +125,8 @@ gst_dirac_parse_class_init (GstDiracParseClass * klass)
       GST_DEBUG_FUNCPTR (gst_dirac_parse_set_sink_caps);
   base_parse_class->get_sink_caps =
       GST_DEBUG_FUNCPTR (gst_dirac_parse_get_sink_caps);
-  base_parse_class->check_valid_frame =
-      GST_DEBUG_FUNCPTR (gst_dirac_parse_check_valid_frame);
-  base_parse_class->parse_frame =
-      GST_DEBUG_FUNCPTR (gst_dirac_parse_parse_frame);
+  base_parse_class->handle_frame =
+      GST_DEBUG_FUNCPTR (gst_dirac_parse_handle_frame);
   base_parse_class->convert = GST_DEBUG_FUNCPTR (gst_dirac_parse_convert);
   base_parse_class->event = GST_DEBUG_FUNCPTR (gst_dirac_parse_event);
   base_parse_class->src_event = GST_DEBUG_FUNCPTR (gst_dirac_parse_src_event);
@@ -213,9 +209,9 @@ gst_dirac_parse_set_sink_caps (GstBaseParse * parse, GstCaps * caps)
   return TRUE;
 }
 
-static gboolean
-gst_dirac_parse_check_valid_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
+static GstFlowReturn
+gst_dirac_parse_handle_frame (GstBaseParse * parse,
+    GstBaseParseFrame * frame, gint * skipsize)
 {
   int off;
   guint32 next_header;
@@ -224,13 +220,16 @@ gst_dirac_parse_check_valid_frame (GstBaseParse * parse,
   gsize size;
   gboolean have_picture = FALSE;
   int offset;
+  guint framesize = 0;
 
   gst_buffer_map (frame->buffer, &map, GST_MAP_READ);
   data = map.data;
   size = map.size;
 
-  if (G_UNLIKELY (size < 13))
+  if (G_UNLIKELY (size < 13)) {
+    *skipsize = 1;
     goto out;
+  }
 
   GST_DEBUG ("%" G_GSIZE_FORMAT ": %02x %02x %02x %02x", size, data[0], data[1],
       data[2], data[3]);
@@ -261,7 +260,7 @@ gst_dirac_parse_check_valid_frame (GstBaseParse * parse,
     GST_DEBUG ("offset %d:", offset);
 
     if (offset + 13 >= size) {
-      *framesize = offset + 13;
+      framesize = offset + 13;
       goto out;
     }
 
@@ -284,43 +283,21 @@ gst_dirac_parse_check_valid_frame (GstBaseParse * parse,
 
     offset += next_header;
     if (offset >= size) {
-      *framesize = offset;
+      framesize = offset;
       goto out;
     }
   }
 
   gst_buffer_unmap (frame->buffer, &map);
 
-  *framesize = offset;
-  GST_DEBUG ("framesize %d", *framesize);
+  framesize = offset;
+  GST_DEBUG ("framesize %d", framesize);
 
-  return TRUE;
-
-out:
-  gst_buffer_unmap (frame->buffer, &map);
-  return FALSE;
-}
-
-static GstFlowReturn
-gst_dirac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
-{
-  GstDiracParse *diracparse = GST_DIRAC_PARSE (parse);
-  GstMapInfo map;
-  guint8 *data;
-  gsize size;
-
-  /* Called when processing incoming buffers.  Function should parse
-     a checked frame. */
-  /* MUST implement */
-
-  gst_buffer_map (frame->buffer, &map, GST_MAP_READ);
-  data = map.data;
-  size = map.size;
-
-  //GST_ERROR("got here %d", size);
+  g_assert (framesize <= size);
 
   if (data[4] == SCHRO_PARSE_CODE_SEQUENCE_HEADER) {
     GstCaps *caps;
+    GstDiracParse *diracparse = GST_DIRAC_PARSE (parse);
     DiracSequenceHeader sequence_header;
     int ret;
 
@@ -349,10 +326,14 @@ gst_dirac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
     }
   }
 
-  gst_buffer_unmap (frame->buffer, &map);
-
   gst_base_parse_set_min_frame_size (parse, 13);
 
+  return gst_base_parse_finish_frame (parse, frame, framesize);
+
+out:
+  gst_buffer_unmap (frame->buffer, &map);
+  if (framesize)
+    gst_base_parse_set_min_frame_size (parse, framesize);
   return GST_FLOW_OK;
 }
 
index bff6866..3d749b2 100644 (file)
@@ -32,6 +32,8 @@
 #include <gst/base/gstbytereader.h>
 #include "gsth263parse.h"
 
+#include <string.h>
+
 GST_DEBUG_CATEGORY (h263_parse_debug);
 #define GST_CAT_DEFAULT h263_parse_debug
 
@@ -54,10 +56,8 @@ static gboolean gst_h263_parse_start (GstBaseParse * parse);
 static gboolean gst_h263_parse_stop (GstBaseParse * parse);
 static gboolean gst_h263_parse_sink_event (GstBaseParse * parse,
     GstEvent * event);
-static gboolean gst_h263_parse_check_valid_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame, guint * framesize, gint * skipsize);
-static GstFlowReturn gst_h263_parse_parse_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame);
+static GstFlowReturn gst_h263_parse_handle_frame (GstBaseParse * parse,
+    GstBaseParseFrame * frame, gint * skipsize);
 static GstCaps *gst_h263_parse_get_sink_caps (GstBaseParse * parse,
     GstCaps * filter);
 
@@ -83,9 +83,7 @@ gst_h263_parse_class_init (GstH263ParseClass * klass)
   parse_class->start = GST_DEBUG_FUNCPTR (gst_h263_parse_start);
   parse_class->stop = GST_DEBUG_FUNCPTR (gst_h263_parse_stop);
   parse_class->event = GST_DEBUG_FUNCPTR (gst_h263_parse_sink_event);
-  parse_class->check_valid_frame =
-      GST_DEBUG_FUNCPTR (gst_h263_parse_check_valid_frame);
-  parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_h263_parse_parse_frame);
+  parse_class->handle_frame = GST_DEBUG_FUNCPTR (gst_h263_parse_handle_frame);
   parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_h263_parse_get_sink_caps);
 }
 
@@ -256,21 +254,25 @@ gst_h263_parse_set_src_caps (GstH263Parse * h263parse,
   gst_caps_unref (caps);
 }
 
-static gboolean
-gst_h263_parse_check_valid_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
+static GstFlowReturn
+gst_h263_parse_handle_frame (GstBaseParse * parse,
+    GstBaseParseFrame * frame, gint * skipsize)
 {
   GstH263Parse *h263parse;
   GstBuffer *buffer;
   guint psc_pos, next_psc_pos;
   gsize size;
+  H263Params params = { 0, };
+  GstFlowReturn res = GST_FLOW_OK;
 
   h263parse = GST_H263_PARSE (parse);
   buffer = frame->buffer;
   size = gst_buffer_get_size (buffer);
 
-  if (size < 3)
-    return FALSE;
+  if (size < 3) {
+    *skipsize = 1;
+    return GST_FLOW_OK;
+  }
 
   psc_pos = find_psc (buffer, 0);
 
@@ -283,6 +285,10 @@ gst_h263_parse_check_valid_frame (GstBaseParse * parse,
     goto more;
   }
 
+  /* need to skip */
+  if (psc_pos > 0)
+    goto more;
+
   /* Found the start of the frame, now try to find the end */
   next_psc_pos = psc_pos + 3;
   next_psc_pos = find_psc (buffer, next_psc_pos);
@@ -299,9 +305,6 @@ gst_h263_parse_check_valid_frame (GstBaseParse * parse,
 
   /* If this is the first frame, parse and set srcpad caps */
   if (h263parse->state == PARSING) {
-    H263Params params = { 0, };
-    GstFlowReturn res;
-
     res = gst_h263_parse_get_params (&params, buffer, FALSE, &h263parse->state);
     if (res != GST_FLOW_OK || h263parse->state != GOT_HEADER) {
       GST_WARNING ("Couldn't parse header - setting passthrough mode");
@@ -311,42 +314,18 @@ gst_h263_parse_check_valid_frame (GstBaseParse * parse,
       gst_h263_parse_set_src_caps (h263parse, &params);
       gst_base_parse_set_passthrough (parse, FALSE);
     }
+    memset (&params, 0, sizeof (params));
   }
 
-  *skipsize = psc_pos;
-  *framesize = next_psc_pos - psc_pos;
-
   /* XXX: After getting a keyframe, should we adjust min_frame_size to
    * something smaller so we don't end up collecting too many non-keyframes? */
 
-  GST_DEBUG_OBJECT (h263parse, "found a frame of size %d at pos %d",
-      *framesize, *skipsize);
-
-  return TRUE;
-
-more:
-  /* ask for best next available */
-  *framesize = G_MAXUINT;
-
-  *skipsize = psc_pos;
-
-  return FALSE;
-}
-
-static GstFlowReturn
-gst_h263_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
-{
-  GstH263Parse *h263parse;
-  GstBuffer *buffer;
-  GstFlowReturn res;
-  H263Params params = { 0, };
-
-  h263parse = GST_H263_PARSE (parse);
-  buffer = frame->buffer;
+  GST_DEBUG_OBJECT (h263parse, "found a frame of size %u at pos %u",
+      next_psc_pos, psc_pos);
 
   res = gst_h263_parse_get_params (&params, buffer, TRUE, &h263parse->state);
   if (res != GST_FLOW_OK)
-    goto out;
+    goto more;
 
   if (h263parse->state == PASSTHROUGH || h263parse->state == PARSING) {
     /* There's a feature we don't support, or we didn't have enough data to
@@ -354,17 +333,18 @@ gst_h263_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
      * passthrough mode and let downstream handle it if it can. */
     GST_WARNING ("Couldn't parse header - setting passthrough mode");
     gst_base_parse_set_passthrough (parse, TRUE);
-    goto out;
+    goto more;
   }
 
-  /* h263parse->state is now GOT_HEADER */
-
   if (gst_h263_parse_is_delta_unit (&params))
     GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
   else
     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
 
-out:
+  return gst_base_parse_finish_frame (parse, frame, next_psc_pos);
+
+more:
+  *skipsize = psc_pos;
 
   return res;
 }
index 0118822..c4a0ece 100644 (file)
@@ -79,8 +79,8 @@ static void gst_h264_parse_finalize (GObject * object);
 
 static gboolean gst_h264_parse_start (GstBaseParse * parse);
 static gboolean gst_h264_parse_stop (GstBaseParse * parse);
-static gboolean gst_h264_parse_check_valid_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame, guint * framesize, gint * skipsize);
+static GstFlowReturn gst_h264_parse_handle_frame (GstBaseParse * parse,
+    GstBaseParseFrame * frame, gint * skipsize);
 static GstFlowReturn gst_h264_parse_parse_frame (GstBaseParse * parse,
     GstBaseParseFrame * frame);
 static GstFlowReturn gst_h264_parse_pre_push_frame (GstBaseParse * parse,
@@ -124,9 +124,7 @@ gst_h264_parse_class_init (GstH264ParseClass * klass)
   /* Override BaseParse vfuncs */
   parse_class->start = GST_DEBUG_FUNCPTR (gst_h264_parse_start);
   parse_class->stop = GST_DEBUG_FUNCPTR (gst_h264_parse_stop);
-  parse_class->check_valid_frame =
-      GST_DEBUG_FUNCPTR (gst_h264_parse_check_valid_frame);
-  parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_h264_parse_parse_frame);
+  parse_class->handle_frame = GST_DEBUG_FUNCPTR (gst_h264_parse_handle_frame);
   parse_class->pre_push_frame =
       GST_DEBUG_FUNCPTR (gst_h264_parse_pre_push_frame);
   parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_h264_parse_set_caps);
@@ -645,9 +643,9 @@ gst_h264_parse_collect_nal (GstH264Parse * h264parse, const guint8 * data,
  * see https://bugzilla.gnome.org/show_bug.cgi?id=650093 */
 #define GST_BASE_PARSE_FRAME_FLAG_PARSING   0x10000
 
-static gboolean
-gst_h264_parse_check_valid_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
+static GstFlowReturn
+gst_h264_parse_handle_frame (GstBaseParse * parse,
+    GstBaseParseFrame * frame, gint * skipsize)
 {
   GstH264Parse *h264parse = GST_H264_PARSE (parse);
   GstBuffer *buffer = frame->buffer;
@@ -659,6 +657,7 @@ gst_h264_parse_check_valid_frame (GstBaseParse * parse,
   GstH264NalParser *nalparser = h264parse->nalparser;
   GstH264NalUnit nalu;
   GstH264ParserResult pres;
+  gint framesize;
 
   gst_buffer_map (buffer, &map, GST_MAP_READ);
   data = map.data;
@@ -667,7 +666,8 @@ gst_h264_parse_check_valid_frame (GstBaseParse * parse,
   /* expect at least 3 bytes startcode == sc, and 2 bytes NALU payload */
   if (G_UNLIKELY (size < 5)) {
     gst_buffer_unmap (buffer, &map);
-    return FALSE;
+    *skipsize = 1;
+    return GST_FLOW_OK;
   }
 
   /* need to configure aggregation */
@@ -820,14 +820,15 @@ gst_h264_parse_check_valid_frame (GstBaseParse * parse,
   }
 
 end:
-  *framesize = nalu.offset + nalu.size;
+  framesize = nalu.offset + nalu.size;
 
   gst_buffer_unmap (buffer, &map);
-  return TRUE;
+
+  gst_h264_parse_parse_frame (parse, frame);
+
+  return gst_base_parse_finish_frame (parse, frame, framesize);
 
 more:
-  /* ask for best next available */
-  *framesize = G_MAXUINT;
   *skipsize = 0;
 
   /* Restart parsing from here next time */
@@ -837,7 +838,7 @@ more:
   /* Fall-through. */
 out:
   gst_buffer_unmap (buffer, &map);
-  return FALSE;
+  return GST_FLOW_OK;
 
 skip:
   GST_DEBUG_OBJECT (h264parse, "skipping %d", *skipsize);
@@ -1321,7 +1322,7 @@ gst_h264_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
 
     buf = gst_adapter_take_buffer (h264parse->frame_out, av);
     gst_buffer_copy_into (buf, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
-    gst_buffer_replace (&frame->buffer, buf);
+    gst_buffer_replace (&frame->out_buffer, buf);
     gst_buffer_unref (buf);
   }
 
@@ -1541,7 +1542,7 @@ gst_h264_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
           /* should already be keyframe/IDR, but it may not have been,
            * so mark it as such to avoid being discarded by picky decoder */
           GST_BUFFER_FLAG_UNSET (new_buf, GST_BUFFER_FLAG_DELTA_UNIT);
-          gst_buffer_replace (&frame->buffer, new_buf);
+          gst_buffer_replace (&frame->out_buffer, new_buf);
           gst_buffer_unref (new_buf);
         }
       }
index f043516..72bf9e6 100644 (file)
@@ -70,8 +70,8 @@ G_DEFINE_TYPE (GstMpeg4VParse, gst_mpeg4vparse, GST_TYPE_BASE_PARSE);
 
 static gboolean gst_mpeg4vparse_start (GstBaseParse * parse);
 static gboolean gst_mpeg4vparse_stop (GstBaseParse * parse);
-static gboolean gst_mpeg4vparse_check_valid_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame, guint * framesize, gint * skipsize);
+static GstFlowReturn gst_mpeg4vparse_handle_frame (GstBaseParse * parse,
+    GstBaseParseFrame * frame, gint * skipsize);
 static GstFlowReturn gst_mpeg4vparse_parse_frame (GstBaseParse * parse,
     GstBaseParseFrame * frame);
 static GstFlowReturn gst_mpeg4vparse_pre_push_frame (GstBaseParse * parse,
@@ -166,9 +166,7 @@ gst_mpeg4vparse_class_init (GstMpeg4VParseClass * klass)
   /* Override BaseParse vfuncs */
   parse_class->start = GST_DEBUG_FUNCPTR (gst_mpeg4vparse_start);
   parse_class->stop = GST_DEBUG_FUNCPTR (gst_mpeg4vparse_stop);
-  parse_class->check_valid_frame =
-      GST_DEBUG_FUNCPTR (gst_mpeg4vparse_check_valid_frame);
-  parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_mpeg4vparse_parse_frame);
+  parse_class->handle_frame = GST_DEBUG_FUNCPTR (gst_mpeg4vparse_handle_frame);
   parse_class->pre_push_frame =
       GST_DEBUG_FUNCPTR (gst_mpeg4vparse_pre_push_frame);
   parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_mpeg4vparse_set_caps);
@@ -363,9 +361,9 @@ gst_mpeg4vparse_process_sc (GstMpeg4VParse * mp4vparse, GstMpeg4Packet * packet,
  * see https://bugzilla.gnome.org/show_bug.cgi?id=650093 */
 #define GST_BASE_PARSE_FRAME_FLAG_PARSING   0x10000
 
-static gboolean
-gst_mpeg4vparse_check_valid_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
+static GstFlowReturn
+gst_mpeg4vparse_handle_frame (GstBaseParse * parse,
+    GstBaseParseFrame * frame, gint * skipsize)
 {
   GstMpeg4VParse *mp4vparse = GST_MPEG4VIDEO_PARSE (parse);
   GstMpeg4Packet packet;
@@ -374,6 +372,7 @@ gst_mpeg4vparse_check_valid_frame (GstBaseParse * parse,
   gsize size;
   gint off = 0;
   gboolean ret = FALSE;
+  guint framesize;
 
   gst_buffer_map (frame->buffer, &map, GST_MAP_READ);
   data = map.data;
@@ -381,8 +380,10 @@ gst_mpeg4vparse_check_valid_frame (GstBaseParse * parse,
 
 retry:
   /* at least start code and subsequent byte */
-  if (G_UNLIKELY (size - off < 5))
+  if (G_UNLIKELY (size - off < 5)) {
+    *skipsize = 1;
     goto out;
+  }
 
   /* avoid stale cached parsing state */
   if (!(frame->flags & GST_BASE_PARSE_FRAME_FLAG_PARSING)) {
@@ -453,13 +454,11 @@ next:
     case (GST_MPEG4_PARSER_ERROR):
       /* if draining, take all */
       if (GST_BASE_PARSE_DRAINING (parse)) {
-        *framesize = size;
+        framesize = size;
         ret = TRUE;
       } else {
         /* resume scan where we left it */
         mp4vparse->last_sc = size - 3;
-        /* request best next available */
-        *framesize = G_MAXUINT;
       }
       goto out;
       break;
@@ -472,14 +471,25 @@ next:
   off = packet.offset;
 
   if (ret) {
-    *framesize = off - 3;
+    framesize = off - 3;
   } else {
     goto next;
   }
 
 out:
   gst_buffer_unmap (frame->buffer, &map);
-  return ret;
+
+  if (ret) {
+    GstFlowReturn res;
+
+    g_assert (framesize <= map.size);
+    res = gst_mpeg4vparse_parse_frame (parse, frame);
+    if (res == GST_BASE_PARSE_FLOW_DROPPED)
+      frame->flags |= GST_BASE_PARSE_FRAME_FLAG_DROP;
+    return gst_base_parse_finish_frame (parse, frame, framesize);
+  }
+
+  return GST_FLOW_OK;
 }
 
 static void
@@ -694,7 +704,7 @@ gst_mpeg4vparse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
           superbuf = gst_buffer_merge (mp4vparse->config, buffer);
           gst_buffer_copy_into (superbuf, buffer, GST_BUFFER_COPY_METADATA, 0,
               csize);
-          gst_buffer_replace (&frame->buffer, superbuf);
+          gst_buffer_replace (&frame->out_buffer, superbuf);
           gst_buffer_unref (superbuf);
         } else {
           GST_INFO_OBJECT (parse, "... but avoiding duplication");
index 37a13cc..dca3df5 100644 (file)
@@ -66,8 +66,8 @@ G_DEFINE_TYPE (GstMpegvParse, gst_mpegv_parse, GST_TYPE_BASE_PARSE);
 
 static gboolean gst_mpegv_parse_start (GstBaseParse * parse);
 static gboolean gst_mpegv_parse_stop (GstBaseParse * parse);
-static gboolean gst_mpegv_parse_check_valid_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame, guint * framesize, gint * skipsize);
+static GstFlowReturn gst_mpegv_parse_handle_frame (GstBaseParse * parse,
+    GstBaseParseFrame * frame, gint * skipsize);
 static GstFlowReturn gst_mpegv_parse_parse_frame (GstBaseParse * parse,
     GstBaseParseFrame * frame);
 static gboolean gst_mpegv_parse_set_caps (GstBaseParse * parse, GstCaps * caps);
@@ -159,9 +159,7 @@ gst_mpegv_parse_class_init (GstMpegvParseClass * klass)
   /* Override BaseParse vfuncs */
   parse_class->start = GST_DEBUG_FUNCPTR (gst_mpegv_parse_start);
   parse_class->stop = GST_DEBUG_FUNCPTR (gst_mpegv_parse_stop);
-  parse_class->check_valid_frame =
-      GST_DEBUG_FUNCPTR (gst_mpegv_parse_check_valid_frame);
-  parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_mpegv_parse_parse_frame);
+  parse_class->handle_frame = GST_DEBUG_FUNCPTR (gst_mpegv_parse_handle_frame);
   parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_mpegv_parse_set_caps);
   parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_mpegv_parse_get_caps);
   parse_class->pre_push_frame =
@@ -493,9 +491,9 @@ update_frame_parsing_status (GstMpegvParse * mpvparse,
 }
 
 
-static gboolean
-gst_mpegv_parse_check_valid_frame (GstBaseParse * parse,
-    GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
+static GstFlowReturn
+gst_mpegv_parse_handle_frame (GstBaseParse * parse,
+    GstBaseParseFrame * frame, gint * skipsize)
 {
   GstMpegvParse *mpvparse = GST_MPEGVIDEO_PARSE (parse);
   GstBuffer *buf = frame->buffer;
@@ -547,10 +545,9 @@ gst_mpegv_parse_check_valid_frame (GstBaseParse * parse,
 
 end:
   if (fsize > 0) {
-    *framesize = fsize;
     ret = TRUE;
   } else if (GST_BASE_PARSE_DRAINING (parse)) {
-    *framesize = buf_size;
+    fsize = buf_size;
     ret = TRUE;
 
   } else {
@@ -562,8 +559,6 @@ end:
     else
       *skipsize = 0;
 
-    /* request best next available */
-    *framesize = G_MAXUINT;
     ret = FALSE;
   }
 
@@ -571,7 +566,18 @@ end:
   g_list_free (mpvparse->typeoffsize);
   mpvparse->typeoffsize = NULL;
 
-  return ret;
+  if (ret) {
+    GstFlowReturn res;
+
+    *skipsize = 0;
+    g_assert (fsize <= buf_size);
+    res = gst_mpegv_parse_parse_frame (parse, frame);
+    if (res == GST_BASE_PARSE_FLOW_DROPPED)
+      frame->flags |= GST_BASE_PARSE_FRAME_FLAG_DROP;
+    return gst_base_parse_finish_frame (parse, frame, fsize);
+  }
+
+  return GST_FLOW_OK;
 }
 
 static void