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.
This commit is contained in:
wm4 2018-05-13 16:22:57 +02:00
parent 7428cc5149
commit 9ceccd6fca
1 changed files with 14 additions and 9 deletions

View File

@ -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) {