1
0
mirror of https://github.com/mpv-player/mpv synced 2025-04-09 11:11:52 +00:00

demux: simplify API for returning cache status

Instead of going through those weird DEMUXER_CTRLs, query this
information directly. I'm not sure which kind of brain damage made me
use CTRLs for these. Since there are no other DEMUXER_CTRLs that make
sense for the frontend, remove the remaining infrastructure for them
too.
This commit is contained in:
wm4 2018-09-07 22:26:48 +02:00
parent 5282b5ea12
commit 4b2cbefc0d
5 changed files with 77 additions and 159 deletions

View File

@ -197,9 +197,6 @@ struct demux_internal {
double ts_offset; // timestamp offset to apply to everything double ts_offset; // timestamp offset to apply to everything
void (*run_fn)(void *); // if non-NULL, function queued to be run on
void *run_fn_arg; // the thread as run_fn(run_fn_arg)
// (sorted by least recent use: index 0 is least recently used) // (sorted by least recent use: index 0 is least recently used)
struct demux_cached_range **ranges; struct demux_cached_range **ranges;
int num_ranges; int num_ranges;
@ -1768,12 +1765,6 @@ static void execute_seek(struct demux_internal *in)
// Make demuxing progress. Return whether progress was made. // Make demuxing progress. Return whether progress was made.
static bool thread_work(struct demux_internal *in) static bool thread_work(struct demux_internal *in)
{ {
if (in->run_fn) {
in->run_fn(in->run_fn_arg);
in->run_fn = NULL;
pthread_cond_signal(&in->wakeup);
return true;
}
if (in->tracks_switched) { if (in->tracks_switched) {
execute_trackswitch(in); execute_trackswitch(in);
return true; return true;
@ -3116,12 +3107,13 @@ static void update_cache(struct demux_internal *in)
pthread_mutex_unlock(&in->lock); pthread_mutex_unlock(&in->lock);
} }
// must be called locked void demux_get_bitrate_stats(struct demuxer *demuxer, double *rates)
static int cached_demux_control(struct demux_internal *in, int cmd, void *arg)
{ {
switch (cmd) { struct demux_internal *in = demuxer->in;
case DEMUXER_CTRL_GET_BITRATE_STATS: { assert(demuxer == in->d_user);
double *rates = arg;
pthread_mutex_lock(&in->lock);
for (int n = 0; n < STREAM_TYPE_COUNT; n++) for (int n = 0; n < STREAM_TYPE_COUNT; n++)
rates[n] = -1; rates[n] = -1;
for (int n = 0; n < in->num_streams; n++) { for (int n = 0; n < in->num_streams; n++) {
@ -3129,11 +3121,18 @@ static int cached_demux_control(struct demux_internal *in, int cmd, void *arg)
if (ds->selected && ds->bitrate >= 0) if (ds->selected && ds->bitrate >= 0)
rates[ds->type] = MPMAX(0, rates[ds->type]) + ds->bitrate; rates[ds->type] = MPMAX(0, rates[ds->type]) + ds->bitrate;
} }
return CONTROL_OK;
pthread_mutex_unlock(&in->lock);
} }
case DEMUXER_CTRL_GET_READER_STATE: {
struct demux_ctrl_reader_state *r = arg; void demux_get_reader_state(struct demuxer *demuxer, struct demux_reader_state *r)
*r = (struct demux_ctrl_reader_state){ {
struct demux_internal *in = demuxer->in;
assert(demuxer == in->d_user);
pthread_mutex_lock(&in->lock);
*r = (struct demux_reader_state){
.eof = in->last_eof, .eof = in->last_eof,
.ts_reader = MP_NOPTS_VALUE, .ts_reader = MP_NOPTS_VALUE,
.ts_end = MP_NOPTS_VALUE, .ts_end = MP_NOPTS_VALUE,
@ -3148,8 +3147,7 @@ static int cached_demux_control(struct demux_internal *in, int cmd, void *arg)
bool any_packets = false; bool any_packets = false;
for (int n = 0; n < in->num_streams; n++) { for (int n = 0; n < in->num_streams; n++) {
struct demux_stream *ds = in->streams[n]->ds; struct demux_stream *ds = in->streams[n]->ds;
if (ds->eager && !(!ds->queue->head && ds->eof) && !ds->ignore_eof) if (ds->eager && !(!ds->queue->head && ds->eof) && !ds->ignore_eof) {
{
r->underrun |= !ds->reader_head && !ds->eof && !ds->still_image; r->underrun |= !ds->reader_head && !ds->eof && !ds->still_image;
r->ts_reader = MP_PTS_MAX(r->ts_reader, ds->base_ts); r->ts_reader = MP_PTS_MAX(r->ts_reader, ds->base_ts);
r->ts_end = MP_PTS_MAX(r->ts_end, ds->queue->last_ts); r->ts_end = MP_PTS_MAX(r->ts_end, ds->queue->last_ts);
@ -3174,75 +3172,8 @@ static int cached_demux_control(struct demux_internal *in, int cmd, void *arg)
}; };
} }
} }
return CONTROL_OK;
}
}
return CONTROL_UNKNOWN;
}
struct demux_control_args {
struct demuxer *demuxer;
int cmd;
void *arg;
int *r;
};
static void thread_demux_control(void *p)
{
struct demux_control_args *args = p;
struct demuxer *demuxer = args->demuxer;
int cmd = args->cmd;
void *arg = args->arg;
struct demux_internal *in = demuxer->in;
int r = CONTROL_UNKNOWN;
pthread_mutex_unlock(&in->lock); pthread_mutex_unlock(&in->lock);
if (r != CONTROL_OK) {
if (in->threading)
MP_VERBOSE(demuxer, "blocking for DEMUXER_CTRL %d\n", cmd);
if (demuxer->desc->control)
r = demuxer->desc->control(demuxer->in->d_thread, cmd, arg);
}
pthread_mutex_lock(&in->lock);
*args->r = r;
}
int demux_control(demuxer_t *demuxer, int cmd, void *arg)
{
struct demux_internal *in = demuxer->in;
assert(demuxer == in->d_user);
if (in->threading) {
pthread_mutex_lock(&in->lock);
int cr = cached_demux_control(in, cmd, arg);
pthread_mutex_unlock(&in->lock);
if (cr != CONTROL_UNKNOWN)
return cr;
}
int r = 0;
struct demux_control_args args = {demuxer, cmd, arg, &r};
if (in->threading) {
MP_VERBOSE(in, "blocking on demuxer thread\n");
pthread_mutex_lock(&in->lock);
while (in->run_fn)
pthread_cond_wait(&in->wakeup, &in->lock);
in->run_fn = thread_demux_control;
in->run_fn_arg = &args;
pthread_cond_signal(&in->wakeup);
while (in->run_fn)
pthread_cond_wait(&in->wakeup, &in->lock);
pthread_mutex_unlock(&in->lock);
} else {
pthread_mutex_lock(&in->lock);
thread_demux_control(&args);
pthread_mutex_unlock(&in->lock);
}
return r;
} }
bool demux_cancel_test(struct demuxer *demuxer) bool demux_cancel_test(struct demuxer *demuxer)

View File

@ -32,8 +32,6 @@
enum demux_ctrl { enum demux_ctrl {
DEMUXER_CTRL_SWITCHED_TRACKS = 1, DEMUXER_CTRL_SWITCHED_TRACKS = 1,
DEMUXER_CTRL_GET_READER_STATE,
DEMUXER_CTRL_GET_BITRATE_STATS, // double[STREAM_TYPE_COUNT]
DEMUXER_CTRL_REPLACE_STREAM, DEMUXER_CTRL_REPLACE_STREAM,
}; };
@ -43,7 +41,7 @@ struct demux_seek_range {
double start, end; double start, end;
}; };
struct demux_ctrl_reader_state { struct demux_reader_state {
bool eof, underrun, idle; bool eof, underrun, idle;
double ts_duration; double ts_duration;
double ts_reader; // approx. timerstamp of decoder position double ts_reader; // approx. timerstamp of decoder position
@ -60,12 +58,6 @@ struct demux_ctrl_reader_state {
struct demux_seek_range seek_ranges[MAX_SEEK_RANGES]; struct demux_seek_range seek_ranges[MAX_SEEK_RANGES];
}; };
struct demux_ctrl_stream_ctrl {
int ctrl;
void *arg;
int res;
};
#define SEEK_FACTOR (1 << 1) // argument is in range [0,1] #define SEEK_FACTOR (1 << 1) // argument is in range [0,1]
#define SEEK_FORWARD (1 << 2) // prefer later time if not exact #define SEEK_FORWARD (1 << 2) // prefer later time if not exact
// (if unset, prefer earlier time) // (if unset, prefer earlier time)
@ -291,7 +283,8 @@ void demux_flush(struct demuxer *demuxer);
int demux_seek(struct demuxer *demuxer, double rel_seek_secs, int flags); int demux_seek(struct demuxer *demuxer, double rel_seek_secs, int flags);
void demux_set_ts_offset(struct demuxer *demuxer, double offset); void demux_set_ts_offset(struct demuxer *demuxer, double offset);
int demux_control(struct demuxer *demuxer, int cmd, void *arg); void demux_get_bitrate_stats(struct demuxer *demuxer, double *rates);
void demux_get_reader_state(struct demuxer *demuxer, struct demux_reader_state *r);
void demux_block_reading(struct demuxer *demuxer, bool block); void demux_block_reading(struct demuxer *demuxer, bool block);

View File

@ -1423,9 +1423,8 @@ static int mp_property_cache_speed(void *ctx, struct m_property *prop,
if (!mpctx->demuxer) if (!mpctx->demuxer)
return M_PROPERTY_UNAVAILABLE; return M_PROPERTY_UNAVAILABLE;
struct demux_ctrl_reader_state s; struct demux_reader_state s;
if (demux_control(mpctx->demuxer, DEMUXER_CTRL_GET_READER_STATE, &s) < 1) demux_get_reader_state(mpctx->demuxer, &s);
return M_PROPERTY_UNAVAILABLE;
uint64_t val = s.bytes_per_second; uint64_t val = s.bytes_per_second;
@ -1443,9 +1442,8 @@ static int mp_property_demuxer_cache_duration(void *ctx, struct m_property *prop
if (!mpctx->demuxer) if (!mpctx->demuxer)
return M_PROPERTY_UNAVAILABLE; return M_PROPERTY_UNAVAILABLE;
struct demux_ctrl_reader_state s; struct demux_reader_state s;
if (demux_control(mpctx->demuxer, DEMUXER_CTRL_GET_READER_STATE, &s) < 1) demux_get_reader_state(mpctx->demuxer, &s);
return M_PROPERTY_UNAVAILABLE;
if (s.ts_duration < 0) if (s.ts_duration < 0)
return M_PROPERTY_UNAVAILABLE; return M_PROPERTY_UNAVAILABLE;
@ -1460,9 +1458,8 @@ static int mp_property_demuxer_cache_time(void *ctx, struct m_property *prop,
if (!mpctx->demuxer) if (!mpctx->demuxer)
return M_PROPERTY_UNAVAILABLE; return M_PROPERTY_UNAVAILABLE;
struct demux_ctrl_reader_state s; struct demux_reader_state s;
if (demux_control(mpctx->demuxer, DEMUXER_CTRL_GET_READER_STATE, &s) < 1) demux_get_reader_state(mpctx->demuxer, &s);
return M_PROPERTY_UNAVAILABLE;
if (s.ts_end == MP_NOPTS_VALUE) if (s.ts_end == MP_NOPTS_VALUE)
return M_PROPERTY_UNAVAILABLE; return M_PROPERTY_UNAVAILABLE;
@ -1477,9 +1474,8 @@ static int mp_property_demuxer_cache_idle(void *ctx, struct m_property *prop,
if (!mpctx->demuxer) if (!mpctx->demuxer)
return M_PROPERTY_UNAVAILABLE; return M_PROPERTY_UNAVAILABLE;
struct demux_ctrl_reader_state s; struct demux_reader_state s;
if (demux_control(mpctx->demuxer, DEMUXER_CTRL_GET_READER_STATE, &s) < 1) demux_get_reader_state(mpctx->demuxer, &s);
return M_PROPERTY_UNAVAILABLE;
return m_property_flag_ro(action, arg, s.idle); return m_property_flag_ro(action, arg, s.idle);
} }
@ -1498,9 +1494,8 @@ static int mp_property_demuxer_cache_state(void *ctx, struct m_property *prop,
if (action != M_PROPERTY_GET) if (action != M_PROPERTY_GET)
return M_PROPERTY_NOT_IMPLEMENTED; return M_PROPERTY_NOT_IMPLEMENTED;
struct demux_ctrl_reader_state s; struct demux_reader_state s;
if (demux_control(mpctx->demuxer, DEMUXER_CTRL_GET_READER_STATE, &s) < 1) demux_get_reader_state(mpctx->demuxer, &s);
return M_PROPERTY_UNAVAILABLE;
struct mpv_node *r = (struct mpv_node *)arg; struct mpv_node *r = (struct mpv_node *)arg;
node_init(r, MPV_FORMAT_NODE_MAP, NULL); node_init(r, MPV_FORMAT_NODE_MAP, NULL);
@ -3030,8 +3025,7 @@ static int mp_property_packet_bitrate(void *ctx, struct m_property *prop,
return M_PROPERTY_UNAVAILABLE; return M_PROPERTY_UNAVAILABLE;
double r[STREAM_TYPE_COUNT]; double r[STREAM_TYPE_COUNT];
if (demux_control(demuxer, DEMUXER_CTRL_GET_BITRATE_STATS, &r) < 1) demux_get_bitrate_stats(demuxer, r);
return M_PROPERTY_UNAVAILABLE;
if (r[type] < 0) if (r[type] < 0)
return M_PROPERTY_UNAVAILABLE; return M_PROPERTY_UNAVAILABLE;

View File

@ -232,8 +232,8 @@ static char *get_term_status_msg(struct MPContext *mpctx)
if (mpctx->demuxer && demux_is_network_cached(mpctx->demuxer)) { if (mpctx->demuxer && demux_is_network_cached(mpctx->demuxer)) {
saddf(&line, " Cache: "); saddf(&line, " Cache: ");
struct demux_ctrl_reader_state s = {.ts_duration = -1}; struct demux_reader_state s;
demux_control(mpctx->demuxer, DEMUXER_CTRL_GET_READER_STATE, &s); demux_get_reader_state(mpctx->demuxer, &s);
if (s.ts_duration < 0) { if (s.ts_duration < 0) {
saddf(&line, "???"); saddf(&line, "???");

View File

@ -625,8 +625,8 @@ static void handle_pause_on_low_cache(struct MPContext *mpctx)
double now = mp_time_sec(); double now = mp_time_sec();
struct demux_ctrl_reader_state s = {.idle = true, .ts_duration = -1}; struct demux_reader_state s;
demux_control(mpctx->demuxer, DEMUXER_CTRL_GET_READER_STATE, &s); demux_get_reader_state(mpctx->demuxer, &s);
int cache_buffer = 100; int cache_buffer = 100;
bool use_pause_on_low_cache = demux_is_network_cached(mpctx->demuxer) && bool use_pause_on_low_cache = demux_is_network_cached(mpctx->demuxer) &&