mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 17:50:36 +00:00
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.
This commit is contained in:
parent
e7450c2df7
commit
804f65e6db
1 changed files with 8 additions and 12 deletions
|
@ -121,6 +121,8 @@ static void
|
||||||
gst_asf_payload_queue_for_stream (GstASFDemux * demux, AsfPayload * payload,
|
gst_asf_payload_queue_for_stream (GstASFDemux * demux, AsfPayload * payload,
|
||||||
AsfStream * stream)
|
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 */
|
/* remember the first timestamp in the stream */
|
||||||
if (!GST_CLOCK_TIME_IS_VALID (demux->first_ts) &&
|
if (!GST_CLOCK_TIME_IS_VALID (demux->first_ts) &&
|
||||||
GST_CLOCK_TIME_IS_VALID (payload->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 */
|
/* make timestamps start from 0 */
|
||||||
if (!demux->streaming)
|
if (!demux->streaming) {
|
||||||
|
if (demux->first_ts < payload->ts)
|
||||||
payload->ts -= demux->first_ts;
|
payload->ts -= demux->first_ts;
|
||||||
|
else
|
||||||
|
payload->ts = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* remove any incomplete payloads that will never be completed */
|
/* remove any incomplete payloads that will never be completed */
|
||||||
while (stream->payloads->len > 0) {
|
while (stream->payloads->len > 0) {
|
||||||
|
|
Loading…
Reference in a new issue