h264parse: disable optimized packetized processing for reverse playback
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Wed, 1 Feb 2012 11:47:56 +0000 (12:47 +0100)
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Wed, 1 Feb 2012 12:53:17 +0000 (13:53 +0100)
... as baseparse then provides whole chunks of data (as it should) at once
to be parsed, and so the assumptions used to optimize are no longer valid.

Fixes #667560.

gst/videoparsers/gsth264parse.c
gst/videoparsers/gsth264parse.h

index 182b00e..230fd85 100644 (file)
@@ -675,7 +675,7 @@ gst_h264_parse_check_valid_frame (GstBaseParse * parse,
   while (TRUE) {
     GstH264ParserResult pres;
 
-    if (h264parse->packetized)
+    if (h264parse->packetized_chunked)
       pres =
           gst_h264_parser_identify_nalu_unchecked (nalparser, data, current_off,
           size, &nalu);
@@ -697,7 +697,8 @@ gst_h264_parse_check_valid_frame (GstBaseParse * parse,
           h264parse->nalu = nalu;
 
         /* need 2 bytes of next nal */
-        if (!h264parse->packetized && (nalu.offset + nalu.size + 4 + 2 > size)) {
+        if (!h264parse->packetized_chunked &&
+            (nalu.offset + nalu.size + 4 + 2 > size)) {
           if (GST_BASE_PARSE_DRAINING (parse)) {
             drain = TRUE;
           } else {
@@ -705,7 +706,7 @@ gst_h264_parse_check_valid_frame (GstBaseParse * parse,
             current_off = nalu.sc_offset;
             goto more;
           }
-        } else if (h264parse->packetized) {
+        } else if (h264parse->packetized_chunked) {
           /* normal next nal based collection not possible,
            * _chain will have to tell us whether this was last one for AU */
           drain = h264parse->packetized_last;
@@ -776,7 +777,7 @@ gst_h264_parse_check_valid_frame (GstBaseParse * parse,
 
     /* In packetized mode we know there's only on NALU in each input packet,
      * but we may not have seen the whole AU already, possibly need more */
-    if (h264parse->packetized) {
+    if (h264parse->packetized_chunked) {
       if (drain)
         break;
       /* next NALU expected at end of current data */
@@ -1862,6 +1863,13 @@ gst_h264_parse_chain (GstPad * pad, GstBuffer * buffer)
             nalu.data + nalu.offset, nalu.size);
         /* at least this should make sense */
         GST_BUFFER_TIMESTAMP (sub) = GST_BUFFER_TIMESTAMP (buffer);
+        /* transfer flags (e.g. DISCONT) for first fragment */
+        if (nalu.offset <= nl)
+          gst_buffer_copy_metadata (sub, buffer, GST_BUFFER_COPY_FLAGS);
+        /* in reverse playback, baseparse gathers buffers, so we cannot
+         * guarantee a buffer to contain a single whole NALU */
+        h264parse->packetized_chunked =
+            (GST_BASE_PARSE (h264parse)->segment.rate > 0.0);
         h264parse->packetized_last =
             (nalu.offset + nalu.size + nl >= GST_BUFFER_SIZE (buffer));
         GST_LOG_OBJECT (h264parse, "pushing NAL of size %d, last = %d",
index 812ac4f..ff6eb59 100644 (file)
@@ -72,6 +72,7 @@ struct _GstH264Parse
   guint format;
   guint current_off;
   gboolean packetized_last;
+  gboolean packetized_chunked;
 
   GstClockTime last_report;
   gboolean push_codec;