From: Edward Hervey Date: Thu, 23 Apr 2009 07:04:41 +0000 (+0200) Subject: asfpacket: Fix pull-mode timestamping handling. X-Git-Tag: 1.19.3~505^2~1409 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=804f65e6db54e9ef311ea553c5a1ce6250e63eeb;p=platform%2Fupstream%2Fgstreamer.git asfpacket: Fix pull-mode timestamping handling. The problem that happens is the following: * A packet with multiple payloads comes in * Those payloads get handled one by one * The first payload contains the first audio payload with timestamp A * The second payload contains the first video (key)frame with timestamp V (where V < A) With the previous code, the following would happen: * the first payload gets processed, then passed to queue_for_stream * queue_for_stream detects it's the first valid timestamp received and stores first_ts = A * the second payload gets processed, then pass to queue_for_stream * queue_for_stream detects the timestamp is lower than first_ts... and discards it... resulting in losing the first keyframe of the video stream We've been having this issue for *ages*... it's just that nobody noticed it that much with playbin. But with playbin2's aggresive multiqueue handling, this will result in multiqueue not being able to preroll (because the video decoder will be dropping a ton of buffers before (maybe) receiving the next keyframe). Tested with over 200 asf files, and they all play the first frame correctly now, even the most braindead ones. --- diff --git a/gst/asfdemux/asfpacket.c b/gst/asfdemux/asfpacket.c index e973a7e..5266f07 100644 --- a/gst/asfdemux/asfpacket.c +++ b/gst/asfdemux/asfpacket.c @@ -121,6 +121,8 @@ static void gst_asf_payload_queue_for_stream (GstASFDemux * demux, AsfPayload * payload, AsfStream * stream) { + GST_DEBUG_OBJECT (demux, "Got payload for stream %d ts:%" GST_TIME_FORMAT, + stream->id, GST_TIME_ARGS (payload->ts)); /* remember the first timestamp in the stream */ if (!GST_CLOCK_TIME_IS_VALID (demux->first_ts) && GST_CLOCK_TIME_IS_VALID (payload->ts)) { @@ -134,19 +136,13 @@ gst_asf_payload_queue_for_stream (GstASFDemux * demux, AsfPayload * payload, } } - /* better drop a few frames at the beginning than send bogus timestamps */ - if (G_UNLIKELY (payload->ts < demux->first_ts)) { - GST_LOG_OBJECT (stream->pad, "Dropping payload with timestamp %" - GST_TIME_FORMAT " which is before the first timestamp %" - GST_TIME_FORMAT, GST_TIME_ARGS (payload->ts), - GST_TIME_ARGS (demux->first_ts)); - gst_buffer_replace (&payload->buf, NULL); - return; - } - /* make timestamps start from 0 */ - if (!demux->streaming) - payload->ts -= demux->first_ts; + if (!demux->streaming) { + if (demux->first_ts < payload->ts) + payload->ts -= demux->first_ts; + else + payload->ts = 0; + } /* remove any incomplete payloads that will never be completed */ while (stream->payloads->len > 0) {