summaryrefslogtreecommitdiffstats
path: root/demux
diff options
context:
space:
mode:
Diffstat (limited to 'demux')
-rw-r--r--demux/demux.c31
-rw-r--r--demux/demux.h2
2 files changed, 29 insertions, 4 deletions
diff --git a/demux/demux.c b/demux/demux.c
index 9646bf4f64..4ccb03a17d 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -197,6 +197,8 @@ struct demux_internal {
double highest_av_pts; // highest non-subtitle PTS seen - for duration
+ bool blocked;
+
// Cached state.
bool force_cache_update;
struct mp_tags *stream_metadata;
@@ -605,6 +607,7 @@ static void update_stream_selection_state(struct demux_internal *in,
// other streams too, because they depend on other stream's selections.
bool any_av_streams = false;
+ bool any_streams = false;
for (int n = 0; n < in->num_streams; n++) {
struct demux_stream *s = in->streams[n]->ds;
@@ -612,6 +615,7 @@ static void update_stream_selection_state(struct demux_internal *in,
s->eager = s->selected && !s->sh->attached_picture;
if (s->eager)
any_av_streams |= s->type != STREAM_SUB;
+ any_streams |= s->selected;
}
// Subtitles are only eagerly read if there are no other eagerly read
@@ -625,6 +629,9 @@ static void update_stream_selection_state(struct demux_internal *in,
}
}
+ if (!any_streams)
+ in->blocked = false;
+
// Make sure any stream reselection or addition is reflected in the seek
// ranges, and also get rid of data that is not needed anymore (or
// rather, which can't be kept consistent). This has to happen after we've
@@ -1279,7 +1286,7 @@ static bool read_packet(struct demux_internal *in)
in->eof = false;
in->idle = true;
- if (!in->reading)
+ if (!in->reading || in->blocked)
return false;
// Check if we need to read a new packet. We do this if all queues are below
@@ -1552,7 +1559,7 @@ static struct demux_packet *dequeue_packet(struct demux_stream *ds)
pkt->stream = ds->sh->index;
return pkt;
}
- if (!ds->reader_head)
+ if (!ds->reader_head || ds->in->blocked)
return NULL;
struct demux_packet *pkt = ds->reader_head;
ds->reader_head = pkt->next;
@@ -1622,7 +1629,7 @@ struct demux_packet *demux_read_packet(struct sh_stream *sh)
const char *t = stream_type_name(ds->type);
MP_DBG(in, "reading packet for %s\n", t);
in->eof = false; // force retry
- while (ds->selected && !ds->reader_head) {
+ while (ds->selected && !ds->reader_head && !in->blocked) {
in->reading = true;
// Note: the following code marks EOF if it can't continue
if (in->threading) {
@@ -1673,6 +1680,8 @@ int demux_read_packet_async(struct sh_stream *sh, struct demux_packet **out_pkt)
r = *out_pkt ? 1 : -1;
}
pthread_mutex_unlock(&ds->in->lock);
+ } else if (ds->in->blocked) {
+ r = 0;
} else {
*out_pkt = demux_read_packet(sh);
r = *out_pkt ? 1 : -1;
@@ -1698,7 +1707,7 @@ struct demux_packet *demux_read_any_packet(struct demuxer *demuxer)
struct demux_internal *in = demuxer->in;
assert(!in->threading); // doesn't work with threading
bool read_more = true;
- while (read_more) {
+ while (read_more && !in->blocked) {
for (int n = 0; n < in->num_streams; n++) {
in->reading = true; // force read_packet() to read
struct demux_packet *pkt = dequeue_packet(in->streams[n]->ds);
@@ -2223,6 +2232,7 @@ static void clear_reader_state(struct demux_internal *in)
ds_clear_reader_state(in->streams[n]->ds);
in->warned_queue_overflow = false;
in->d_user->filepos = -1; // implicitly synchronized
+ in->blocked = false;
assert(in->fw_bytes == 0);
}
@@ -2719,6 +2729,19 @@ void demux_disable_cache(demuxer_t *demuxer)
pthread_mutex_unlock(&in->lock);
}
+// Disallow reading any packets and make readers think there is no new data
+// yet, until a seek is issued.
+void demux_block_reading(struct demuxer *demuxer, bool block)
+{
+ struct demux_internal *in = demuxer->in;
+ assert(demuxer == in->d_user);
+
+ pthread_mutex_lock(&in->lock);
+ in->blocked = block;
+ pthread_cond_signal(&in->wakeup);
+ pthread_mutex_unlock(&in->lock);
+}
+
// must be called not locked
static void update_cache(struct demux_internal *in)
{
diff --git a/demux/demux.h b/demux/demux.h
index e0c68a82cb..ffed39c770 100644
--- a/demux/demux.h
+++ b/demux/demux.h
@@ -285,6 +285,8 @@ void demux_set_ts_offset(struct demuxer *demuxer, double offset);
int demux_control(struct demuxer *demuxer, int cmd, void *arg);
+void demux_block_reading(struct demuxer *demuxer, bool block);
+
void demuxer_select_track(struct demuxer *demuxer, struct sh_stream *stream,
double ref_pts, bool selected);
void demux_set_stream_autoselect(struct demuxer *demuxer, bool autoselect);