qtdemux: Provide a 2 frames lead-in for audio decoders
authorMart Raudsepp <mart.raudsepp@collabora.com>
Wed, 5 Jun 2019 20:13:33 +0000 (23:13 +0300)
committerMart Raudsepp <mart.raudsepp@collabora.com>
Wed, 5 Jun 2019 20:13:33 +0000 (23:13 +0300)
AAC and various other audio codecs need a couple frames of lead-in to
decode it properly. The parser elements like aacparse take care of it
via gst_base_parse_set_frame_rate, but when inside a container, the
demuxer is doing the seek segment handling and never gives lead-in
data downstream.
Handle this similar to going back to a keyframe with video, in the
same place. Without a lead-in, the start of the segment is silence,
when it shouldn't, which becomes especially evident in NLE use cases.

gst/isomp4/qtdemux.c

index 6499015..64f7f29 100644 (file)
@@ -5148,6 +5148,19 @@ gst_qtdemux_activate_segment (GstQTDemux * qtdemux, QtDemuxStream * stream,
   /* find keyframe of the target index */
   kf_index = gst_qtdemux_find_keyframe (qtdemux, stream, index, FALSE);
 
+  /* go back two frames to provide lead-in for non-raw audio decoders */
+  if (stream->subtype == FOURCC_soun && !stream->need_clip) {
+    guint32 old_index = kf_index;
+    kf_index = MAX (kf_index, 2) - 2;
+    if (qtdemux_parse_samples (qtdemux, stream, kf_index)) {
+      GST_DEBUG_OBJECT (stream->pad,
+          "Moving backwards %u frames to ensure sufficient sound lead-in",
+          old_index - kf_index);
+    } else {
+      kf_index = old_index;
+    }
+  }
+
   /* if we move forwards, we don't have to go back to the previous
    * keyframe since we already sent that. We can also just jump to
    * the keyframe right before the target index if there is one. */
@@ -5171,9 +5184,9 @@ gst_qtdemux_activate_segment (GstQTDemux * qtdemux, QtDemuxStream * stream,
     }
   } else {
     GST_DEBUG_OBJECT (stream->pad,
-        "moving backwards to keyframe at %u "
+        "moving backwards to %sframe at %u "
         "(pts %" GST_TIME_FORMAT " dts %" GST_TIME_FORMAT " )",
-        kf_index,
+        (stream->subtype == FOURCC_soun) ? "audio " : "key", kf_index,
         GST_TIME_ARGS (QTSAMPLE_PTS (stream, &stream->samples[kf_index])),
         GST_TIME_ARGS (QTSAMPLE_DTS (stream, &stream->samples[kf_index])));
     gst_qtdemux_move_stream (qtdemux, stream, kf_index);