From 9ceccd6fca553ec4f310685d02b1f088117cd9ba Mon Sep 17 00:00:00 2001 From: wm4 Date: Sun, 13 May 2018 16:22:57 +0200 Subject: demux: fix/improve aspects of EOF signaling When the current packet queue was completely empty, and EOF was reached, the queue->is_eof flag was not correctly set to true. Change this by reading ds->eof to check whether the stream is considered EOF. We also need to make sure update_seek_ranges() is called in this case, so change the code to simply call it when queue->is_eof changes. Also, read_packet() needs to call adjust_seek_range_on_packet() if ds->eof changes. In that case, the decoder also needs to be notified about EOF. So both of these should be called when ds->eof changes to true. (Other code outside of this function deals with the case when ds->eof is changed to false.) In addition, this code was kind of shoddy about calling wakeup_ds() correctly. It looks like there was an inverted condition, and sent a wakeup to the decoder only when ds->eof was already true, which is obviously bogus. The final EOF case tried to be somehow clever about checking in->last_eof for notifying the codec, which is sort of OK, but seems to be strictly worse than just checking whether ds->eof changed. Fix these things. --- demux/demux.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/demux/demux.c b/demux/demux.c index 40a68eacae..73d4927002 100644 --- a/demux/demux.c +++ b/demux/demux.c @@ -1236,6 +1236,7 @@ static void adjust_seek_range_on_packet(struct demux_stream *ds, { struct demux_queue *queue = ds->queue; bool attempt_range_join = false; + bool prev_eof = queue->is_eof; if (!ds->in->seekable_cache) return; @@ -1253,6 +1254,8 @@ static void adjust_seek_range_on_packet(struct demux_stream *ds, attempt_range_join = queue->range->seek_end > old_end; if (queue->keyframe_latest->kf_seek_pts != MP_NOPTS_VALUE) add_index_entry(queue, queue->keyframe_latest); + } else { + queue->is_eof |= ds->eof; } queue->keyframe_latest = dp; queue->keyframe_pts = queue->keyframe_end_pts = MP_NOPTS_VALUE; @@ -1268,12 +1271,12 @@ static void adjust_seek_range_on_packet(struct demux_stream *ds, queue->keyframe_pts = MP_PTS_MIN(queue->keyframe_pts, ts); queue->keyframe_end_pts = MP_PTS_MAX(queue->keyframe_end_pts, ts); - if (queue->is_eof) { - queue->is_eof = false; - update_seek_ranges(queue->range); - } + queue->is_eof = false; } + if (queue->is_eof != prev_eof) + update_seek_ranges(queue->range); + if (attempt_range_join) attempt_range_joining(ds->in); } @@ -1443,9 +1446,11 @@ static bool read_packet(struct demux_internal *in) for (int n = 0; n < in->num_streams; n++) { struct demux_stream *ds = in->streams[n]->ds; bool eof = !ds->reader_head; - if (eof && ds->eof) + if (!ds->eof && eof) { + ds->eof = true; + adjust_seek_range_on_packet(ds, NULL); wakeup_ds(ds); - ds->eof |= eof; + } } return false; } @@ -1477,11 +1482,11 @@ static bool read_packet(struct demux_internal *in) if (eof) { for (int n = 0; n < in->num_streams; n++) { struct demux_stream *ds = in->streams[n]->ds; - if (!ds->eof) + if (!ds->eof) { + ds->eof = true; adjust_seek_range_on_packet(ds, NULL); - ds->eof = true; - if (!in->last_eof && ds->wakeup_cb) wakeup_ds(ds); + } } // If we had EOF previously, then don't wakeup (avoids wakeup loop) if (!in->last_eof) { -- cgit v1.2.3