diff options
-rw-r--r-- | demux/demux.c | 19 | ||||
-rw-r--r-- | demux/demux.h | 1 | ||||
-rw-r--r-- | demux/demux_timeline.c | 16 |
3 files changed, 35 insertions, 1 deletions
diff --git a/demux/demux.c b/demux/demux.c index 2c252e6c20..6908bbcca5 100644 --- a/demux/demux.c +++ b/demux/demux.c @@ -220,6 +220,7 @@ struct demux_internal { bool enable_recording; struct mp_recorder *recorder; int64_t slave_unbuffered_read_bytes; // value repoted from demuxer impl. + int64_t hack_unbuffered_read_bytes; // for demux_get_bytes_read_hack() int64_t cache_unbuffered_read_bytes; // for demux_reader_state.bytes_per_second }; @@ -3049,6 +3050,7 @@ static void update_bytes_read(struct demux_internal *in) in->slave_unbuffered_read_bytes = 0; in->cache_unbuffered_read_bytes += new; + in->hack_unbuffered_read_bytes += new; } // must be called not locked @@ -3105,6 +3107,23 @@ void demux_report_unbuffered_read_bytes(struct demuxer *demuxer, int64_t new) in->slave_unbuffered_read_bytes += new; } +// Return bytes read since last query. It's a hack because it works only if +// the demuxer thread is disabled. +int64_t demux_get_bytes_read_hack(struct demuxer *demuxer) +{ + struct demux_internal *in = demuxer->in; + + // Required because demuxer==in->d_user, and we access in->d_thread. + // Locking won't solve this, because we also need to access struct stream. + assert(!in->threading); + + update_bytes_read(in); + + int64_t res = in->hack_unbuffered_read_bytes; + in->hack_unbuffered_read_bytes = 0; + return res; +} + void demux_get_bitrate_stats(struct demuxer *demuxer, double *rates) { struct demux_internal *in = demuxer->in; diff --git a/demux/demux.h b/demux/demux.h index 09f6895544..65566ea509 100644 --- a/demux/demux.h +++ b/demux/demux.h @@ -292,6 +292,7 @@ void demux_disable_cache(demuxer_t *demuxer); bool demux_is_network_cached(demuxer_t *demuxer); void demux_report_unbuffered_read_bytes(struct demuxer *demuxer, int64_t new); +int64_t demux_get_bytes_read_hack(struct demuxer *demuxer); struct sh_stream *demuxer_stream_by_demuxer_id(struct demuxer *d, enum stream_type t, int id); diff --git a/demux/demux_timeline.c b/demux/demux_timeline.c index 3c5304c6dc..7364ce8399 100644 --- a/demux/demux_timeline.c +++ b/demux/demux_timeline.c @@ -89,6 +89,11 @@ struct priv { static void add_tl(struct demuxer *demuxer, struct timeline *tl); +static void update_slave_stats(struct demuxer *demuxer, struct demuxer *slave) +{ + demux_report_unbuffered_read_bytes(demuxer, demux_get_bytes_read_hack(slave)); +} + static bool target_stream_used(struct segment *seg, struct virtual_stream *vs) { for (int n = 0; n < seg->num_stream_map; n++) { @@ -159,6 +164,8 @@ static void reselect_streams(struct demuxer *demuxer) selected = false; struct sh_stream *sh = demux_get_stream(seg->d, i); demuxer_select_track(seg->d, sh, MP_NOPTS_VALUE, selected); + + update_slave_stats(demuxer, seg->d); } } @@ -204,8 +211,10 @@ static void reopen_lazy_segments(struct demuxer *demuxer, demuxer->cancel, demuxer->global); if (!src->current->d && !demux_cancel_test(demuxer)) MP_ERR(demuxer, "failed to load segment\n"); - if (src->current->d) + if (src->current->d) { demux_disable_cache(src->current->d); + update_slave_stats(demuxer, src->current->d); + } associate_streams(demuxer, src, src->current); } @@ -218,6 +227,9 @@ static void switch_segment(struct demuxer *demuxer, struct virtual_source *src, MP_VERBOSE(demuxer, "switch to segment %d\n", new->index); + if (src->current && src->current->d) + update_slave_stats(demuxer, src->current->d); + src->current = new; reopen_lazy_segments(demuxer, src); if (!new->d) @@ -295,6 +307,8 @@ static bool d_read_packet(struct demuxer *demuxer, struct demux_packet **out_pkt if (!pkt || pkt->pts >= seg->end) src->eos_packets += 1; + update_slave_stats(demuxer, seg->d); + // Test for EOF. Do this here to properly run into EOF even if other // streams are disabled etc. If it somehow doesn't manage to reach the end // after demuxing a high (bit arbitrary) number of packets, assume one of |