summaryrefslogtreecommitdiffstats
path: root/demux
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-06-20 13:57:58 +0200
committerwm4 <wm4@nowhere>2017-06-20 14:22:10 +0200
commit1890529857a3b963df476f53ca41faacab48a6d2 (patch)
treecad31a2b753e5aa2040dd8d8d8adc34ececebea0 /demux
parent5bfbe6dfde01704979dd086d5184ea2e697cb510 (diff)
downloadmpv-1890529857a3b963df476f53ca41faacab48a6d2.tar.bz2
mpv-1890529857a3b963df476f53ca41faacab48a6d2.tar.xz
demux: get rid of DEMUXER_CTRL_GET_TIME_LENGTH
Similar purpose as f34e1a0deea45e. Somehow this is much more natural too, and needs less code. This breaks runtime updates to duration. This could easily be fixed, but no important demuxer does this anyway. Only demux_raw and demux_disc might (the latter for BD/DVD). For the latter it might actually have some importance when changing titles at runtime (I guess?), but guess what, I don't care.
Diffstat (limited to 'demux')
-rw-r--r--demux/demux.c22
-rw-r--r--demux/demux.h4
-rw-r--r--demux/demux_cue.c16
-rw-r--r--demux/demux_disc.c11
-rw-r--r--demux/demux_edl.c12
-rw-r--r--demux/demux_lavf.c44
-rw-r--r--demux/demux_mf.c16
-rw-r--r--demux/demux_mkv.c22
-rw-r--r--demux/demux_mkv_timeline.c3
-rw-r--r--demux/demux_raw.c37
-rw-r--r--demux/demux_timeline.c11
11 files changed, 51 insertions, 147 deletions
diff --git a/demux/demux.c b/demux/demux.c
index 87c9879a59..3a3d9978f9 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -173,7 +173,6 @@ struct demux_internal {
// Cached state.
bool force_cache_update;
- double time_length;
struct mp_tags *stream_metadata;
struct stream_cache_info stream_cache_info;
int64_t stream_size;
@@ -1085,6 +1084,7 @@ static void demux_copy(struct demuxer *dst, struct demuxer *src)
dst->ts_resets_possible = src->ts_resets_possible;
dst->fully_read = src->fully_read;
dst->start_time = src->start_time;
+ dst->duration = src->duration;
dst->is_network = src->is_network;
dst->priv = src->priv;
}
@@ -1572,14 +1572,6 @@ int demuxer_add_chapter(demuxer_t *demuxer, char *name,
return demuxer->num_chapters - 1;
}
-double demuxer_get_time_length(struct demuxer *demuxer)
-{
- double len;
- if (demux_control(demuxer, DEMUXER_CTRL_GET_TIME_LENGTH, &len) > 0)
- return len;
- return -1;
-}
-
// must be called not locked
static void update_cache(struct demux_internal *in)
{
@@ -1587,21 +1579,14 @@ static void update_cache(struct demux_internal *in)
struct stream *stream = demuxer->stream;
// Don't lock while querying the stream.
- double time_length = -1;
struct mp_tags *stream_metadata = NULL;
struct stream_cache_info stream_cache_info = {.size = -1};
- if (demuxer->desc->control) {
- demuxer->desc->control(demuxer, DEMUXER_CTRL_GET_TIME_LENGTH,
- &time_length);
- }
-
int64_t stream_size = stream_get_size(stream);
stream_control(stream, STREAM_CTRL_GET_METADATA, &stream_metadata);
stream_control(stream, STREAM_CTRL_GET_CACHE_INFO, &stream_cache_info);
pthread_mutex_lock(&in->lock);
- in->time_length = time_length;
in->stream_size = stream_size;
in->stream_cache_info = stream_cache_info;
if (stream_metadata) {
@@ -1645,11 +1630,6 @@ static int cached_stream_control(struct demux_internal *in, int cmd, void *arg)
static int cached_demux_control(struct demux_internal *in, int cmd, void *arg)
{
switch (cmd) {
- case DEMUXER_CTRL_GET_TIME_LENGTH:
- if (in->time_length < 0)
- return CONTROL_FALSE;
- *(double *)arg = in->time_length;
- return CONTROL_OK;
case DEMUXER_CTRL_STREAM_CTRL: {
struct demux_ctrl_stream_ctrl *c = arg;
int r = cached_stream_control(in, c->ctrl, c->arg);
diff --git a/demux/demux.h b/demux/demux.h
index b1b83b3156..d3eed2bd28 100644
--- a/demux/demux.h
+++ b/demux/demux.h
@@ -32,7 +32,6 @@
enum demux_ctrl {
DEMUXER_CTRL_SWITCHED_TRACKS = 1,
- DEMUXER_CTRL_GET_TIME_LENGTH,
DEMUXER_CTRL_RESYNC,
DEMUXER_CTRL_IDENTIFY_PROGRAM,
DEMUXER_CTRL_STREAM_CTRL,
@@ -175,6 +174,7 @@ typedef struct demuxer {
bool seekable;
bool partially_seekable; // true if _maybe_ seekable; implies seekable=true
double start_time;
+ double duration; // -1 if unknown
// File format allows PTS resets (even if the current file is without)
bool ts_resets_possible;
// The file data was fully read, and there is no need to keep the stream
@@ -280,8 +280,6 @@ int demuxer_add_chapter(demuxer_t *demuxer, char *name,
void demux_set_stream_tags(struct demuxer *demuxer, struct sh_stream *sh,
struct mp_tags *tags);
-double demuxer_get_time_length(struct demuxer *demuxer);
-
int demux_stream_control(demuxer_t *demuxer, int ctrl, void *arg);
void demux_changed(demuxer_t *demuxer, int events);
diff --git a/demux/demux_cue.c b/demux/demux_cue.c
index a8d1176163..941f2a88d9 100644
--- a/demux/demux_cue.c
+++ b/demux/demux_cue.c
@@ -130,20 +130,6 @@ out:
return res;
}
-// return length of the source in seconds, or -1 if unknown
-static double source_get_length(struct demuxer *demuxer)
-{
- double get_time_ans;
- // <= 0 means DEMUXER_CTRL_NOTIMPL or DEMUXER_CTRL_DONTKNOW
- if (demuxer && demux_control(demuxer, DEMUXER_CTRL_GET_TIME_LENGTH,
- (void *) &get_time_ans) > 0)
- {
- return get_time_ans;
- } else {
- return -1;
- }
-}
-
static void build_timeline(struct timeline *tl)
{
struct priv *p = tl->demuxer->priv;
@@ -210,7 +196,7 @@ static void build_timeline(struct timeline *tl)
if (i + 1 < track_count && tracks[i].source == tracks[i + 1].source) {
duration = tracks[i + 1].start - tracks[i].start;
} else {
- duration = source_get_length(source);
+ duration = source->duration;
// Two cases: 1) last track of a single-file cue, or 2) any track of
// a multi-file cue. We need to do this for 1) only because the
// timeline needs to be terminated with the length of the last
diff --git a/demux/demux_disc.c b/demux/demux_disc.c
index f4c9c34332..6c88bc1adc 100644
--- a/demux/demux_disc.c
+++ b/demux/demux_disc.c
@@ -338,6 +338,10 @@ static int d_open(demuxer_t *demuxer, enum demux_check check)
add_streams(demuxer);
add_stream_chapters(demuxer);
+ double len;
+ if (stream_control(demuxer->stream, STREAM_CTRL_GET_TIME_LENGTH, &len) >= 1)
+ demuxer->duration = len;
+
return 0;
}
@@ -352,13 +356,6 @@ static int d_control(demuxer_t *demuxer, int cmd, void *arg)
struct priv *p = demuxer->priv;
switch (cmd) {
- case DEMUXER_CTRL_GET_TIME_LENGTH: {
- double len;
- if (stream_control(demuxer->stream, STREAM_CTRL_GET_TIME_LENGTH, &len) < 1)
- break;
- *(double *)arg = len;
- return CONTROL_OK;
- }
case DEMUXER_CTRL_RESYNC:
demux_flush(p->slave);
break; // relay to slave demuxer
diff --git a/demux/demux_edl.c b/demux/demux_edl.c
index 8b6f402b27..5bab4ae983 100644
--- a/demux/demux_edl.c
+++ b/demux/demux_edl.c
@@ -199,16 +199,6 @@ static void copy_chapters(struct demux_chapter **chapters, int *num_chapters,
}
}
-// return length of the source in seconds, or -1 if unknown
-static double source_get_length(struct demuxer *demuxer)
-{
- double time;
- // <= 0 means DEMUXER_CTRL_NOTIMPL or DEMUXER_CTRL_DONTKNOW
- if (demux_control(demuxer, DEMUXER_CTRL_GET_TIME_LENGTH, &time) <= 0)
- time = -1;
- return time;
-}
-
static void resolve_timestamps(struct tl_part *part, struct demuxer *demuxer)
{
if (part->chapter_ts) {
@@ -279,7 +269,7 @@ static void build_timeline(struct timeline *tl, struct tl_parts *parts)
resolve_timestamps(part, source);
- double end_time = source_get_length(source);
+ double end_time = source->duration;
if (end_time >= 0)
end_time += source->start_time;
diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c
index e2b6ca673d..da0dbd46aa 100644
--- a/demux/demux_lavf.c
+++ b/demux/demux_lavf.c
@@ -939,6 +939,26 @@ static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check)
demuxer->fully_read = priv->format_hack.fully_read;
+ if (priv->avfc->duration > 0) {
+ demuxer->duration = (double)priv->avfc->duration / AV_TIME_BASE;
+ } else {
+ double total_duration = 0;
+ double av_duration = 0;
+ for (int n = 0; n < priv->avfc->nb_streams; n++) {
+ AVStream *st = priv->avfc->streams[n];
+ if (st->duration <= 0)
+ continue;
+ double f_duration = st->duration * av_q2d(st->time_base);
+ total_duration = MPMAX(total_duration, f_duration);
+ if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO ||
+ st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
+ av_duration = MPMAX(av_duration, f_duration);
+ }
+ double duration = av_duration > 0 ? av_duration : total_duration;
+ if (duration > 0)
+ demuxer->duration = duration;
+ }
+
return 0;
}
@@ -1045,30 +1065,6 @@ static int demux_lavf_control(demuxer_t *demuxer, int cmd, void *arg)
lavf_priv_t *priv = demuxer->priv;
switch (cmd) {
- case DEMUXER_CTRL_GET_TIME_LENGTH:
- if (priv->avfc->duration <= 0) {
- double total_duration = 0;
- double av_duration = 0;
- for (int n = 0; n < priv->avfc->nb_streams; n++) {
- AVStream *st = priv->avfc->streams[n];
- if (st->duration <= 0)
- continue;
- double f_duration = st->duration * av_q2d(st->time_base);
- total_duration = MPMAX(total_duration, f_duration);
- if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO ||
- st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
- av_duration = MPMAX(av_duration, f_duration);
- }
- double duration = av_duration > 0 ? av_duration : total_duration;
- if (duration <= 0)
- return CONTROL_FALSE;
- *(double *)arg = duration;
- return CONTROL_OK;
- }
-
- *((double *)arg) = (double)priv->avfc->duration / AV_TIME_BASE;
- return CONTROL_OK;
-
case DEMUXER_CTRL_SWITCHED_TRACKS:
{
select_tracks(demuxer, 0);
diff --git a/demux/demux_mf.c b/demux/demux_mf.c
index 859a59925f..4b09ad8e86 100644
--- a/demux/demux_mf.c
+++ b/demux/demux_mf.c
@@ -335,6 +335,7 @@ static int demux_open_mf(demuxer_t *demuxer, enum demux_check check)
mf->sh = sh;
demuxer->priv = (void *)mf;
demuxer->seekable = true;
+ demuxer->duration = mf->nr_of_files / mf->sh->codec->fps;
return 0;
@@ -346,20 +347,6 @@ static void demux_close_mf(demuxer_t *demuxer)
{
}
-static int demux_control_mf(demuxer_t *demuxer, int cmd, void *arg)
-{
- mf_t *mf = demuxer->priv;
-
- switch (cmd) {
- case DEMUXER_CTRL_GET_TIME_LENGTH:
- *((double *)arg) = (double)mf->nr_of_files / mf->sh->codec->fps;
- return CONTROL_OK;
-
- default:
- return CONTROL_UNKNOWN;
- }
-}
-
const demuxer_desc_t demuxer_desc_mf = {
.name = "mf",
.desc = "image files (mf)",
@@ -367,5 +354,4 @@ const demuxer_desc_t demuxer_desc_mf = {
.open = demux_open_mf,
.close = demux_close_mf,
.seek = demux_seek_mf,
- .control = demux_control_mf,
};
diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c
index b040c45f23..3861aaf60a 100644
--- a/demux/demux_mkv.c
+++ b/demux/demux_mkv.c
@@ -411,6 +411,7 @@ static int demux_mkv_read_info(demuxer_t *demuxer)
mkv_d->duration = info.duration * mkv_d->tc_scale / 1e9;
MP_VERBOSE(demuxer, "| + duration: %.3fs\n",
mkv_d->duration);
+ demuxer->duration = mkv_d->duration;
}
if (info.title) {
mp_tags_set_str(demuxer->metadata, "TITLE", info.title);
@@ -3090,8 +3091,10 @@ static void probe_last_timestamp(struct demuxer *demuxer, int64_t start_pos)
if (!last_ts[STREAM_VIDEO])
last_ts[STREAM_VIDEO] = mkv_d->cluster_tc;
- if (last_ts[STREAM_VIDEO])
+ if (last_ts[STREAM_VIDEO]) {
mkv_d->duration = last_ts[STREAM_VIDEO] / 1e9 - demuxer->start_time;
+ demuxer->duration = mkv_d->duration;
+ }
stream_seek(demuxer->stream, start_pos);
mkv_d->cluster_start = mkv_d->cluster_end = 0;
@@ -3116,22 +3119,6 @@ static void probe_first_timestamp(struct demuxer *demuxer)
MP_VERBOSE(demuxer, "Start PTS: %f\n", demuxer->start_time);
}
-static int demux_mkv_control(demuxer_t *demuxer, int cmd, void *arg)
-{
- mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
-
- switch (cmd) {
- case DEMUXER_CTRL_GET_TIME_LENGTH:
- if (mkv_d->duration == 0)
- return CONTROL_FALSE;
-
- *((double *) arg) = (double) mkv_d->duration;
- return CONTROL_OK;
- default:
- return CONTROL_UNKNOWN;
- }
-}
-
static void mkv_free(struct demuxer *demuxer)
{
struct mkv_demuxer *mkv_d = demuxer->priv;
@@ -3149,7 +3136,6 @@ const demuxer_desc_t demuxer_desc_matroska = {
.fill_buffer = demux_mkv_fill_buffer,
.close = mkv_free,
.seek = demux_mkv_seek,
- .control = demux_mkv_control,
.load_timeline = build_ordered_chapter_timeline,
};
diff --git a/demux/demux_mkv_timeline.c b/demux/demux_mkv_timeline.c
index de7b2e0853..3ad24eb8a5 100644
--- a/demux/demux_mkv_timeline.c
+++ b/demux/demux_mkv_timeline.c
@@ -384,8 +384,7 @@ static void build_timeline_loop(struct tl_ctx *ctx,
/* If we're the source or it's a non-ordered edition reference,
* just add a timeline part from the source. */
if (current_source == j || !linked_m->uid.edition) {
- uint64_t source_full_length =
- demuxer_get_time_length(linked_source) * 1e9;
+ uint64_t source_full_length = linked_source->duration * 1e9;
uint64_t source_length = source_full_length - c->start;
int64_t join_diff = 0;
diff --git a/demux/demux_raw.c b/demux/demux_raw.c
index d9e7ebb63a..f2b20c597c 100644
--- a/demux/demux_raw.c
+++ b/demux/demux_raw.c
@@ -132,6 +132,18 @@ struct priv {
double frame_rate;
};
+static int generic_open(struct demuxer *demuxer)
+{
+ struct stream *s = demuxer->stream;
+ struct priv *p = demuxer->priv;
+
+ int64_t end = 0;
+ if (stream_control(s, STREAM_CTRL_GET_SIZE, &end) == STREAM_OK)
+ demuxer->duration = (end / p->frame_size) / p->frame_rate;
+
+ return 0;
+}
+
static int demux_rawaudio_open(demuxer_t *demuxer, enum demux_check check)
{
struct demux_rawaudio_opts *opts =
@@ -170,7 +182,7 @@ static int demux_rawaudio_open(demuxer_t *demuxer, enum demux_check check)
.read_frames = c->samplerate / 8,
};
- return 0;
+ return generic_open(demuxer);
}
static int demux_rawvideo_open(demuxer_t *demuxer, enum demux_check check)
@@ -255,7 +267,7 @@ static int demux_rawvideo_open(demuxer_t *demuxer, enum demux_check check)
.read_frames = 1,
};
- return 0;
+ return generic_open(demuxer);
}
static int raw_fill_buffer(demuxer_t *demuxer)
@@ -297,32 +309,12 @@ static void raw_seek(demuxer_t *demuxer, double seek_pts, int flags)
stream_seek(s, (pos / p->frame_size) * p->frame_size);
}
-static int raw_control(demuxer_t *demuxer, int cmd, void *arg)
-{
- struct priv *p = demuxer->priv;
-
- switch (cmd) {
- case DEMUXER_CTRL_GET_TIME_LENGTH: {
- stream_t *s = demuxer->stream;
- int64_t end = 0;
- if (stream_control(s, STREAM_CTRL_GET_SIZE, &end) != STREAM_OK)
- return CONTROL_FALSE;
-
- *((double *) arg) = (end / p->frame_size) / p->frame_rate;
- return CONTROL_OK;
- }
- default:
- return CONTROL_UNKNOWN;
- }
-}
-
const demuxer_desc_t demuxer_desc_rawaudio = {
.name = "rawaudio",
.desc = "Uncompressed audio",
.open = demux_rawaudio_open,
.fill_buffer = raw_fill_buffer,
.seek = raw_seek,
- .control = raw_control,
};
const demuxer_desc_t demuxer_desc_rawvideo = {
@@ -331,5 +323,4 @@ const demuxer_desc_t demuxer_desc_rawvideo = {
.open = demux_rawvideo_open,
.fill_buffer = raw_fill_buffer,
.seek = raw_seek,
- .control = raw_control,
};
diff --git a/demux/demux_timeline.c b/demux/demux_timeline.c
index 359f97f2bc..d7a5c36d70 100644
--- a/demux/demux_timeline.c
+++ b/demux/demux_timeline.c
@@ -363,6 +363,7 @@ static int d_open(struct demuxer *demuxer, enum demux_check check)
demuxer->editions = meta->editions;
demuxer->num_editions = meta->num_editions;
demuxer->edition = meta->edition;
+ demuxer->duration = p->duration;
int num_streams = demux_get_num_stream(meta);
for (int n = 0; n < num_streams; n++) {
@@ -431,17 +432,11 @@ static void d_close(struct demuxer *demuxer)
static int d_control(struct demuxer *demuxer, int cmd, void *arg)
{
- struct priv *p = demuxer->priv;
-
- switch (cmd) {
- case DEMUXER_CTRL_GET_TIME_LENGTH: {
- *(double *)arg = p->duration;
- return CONTROL_OK;
- }
- case DEMUXER_CTRL_SWITCHED_TRACKS:
+ if (cmd == DEMUXER_CTRL_SWITCHED_TRACKS) {
reselect_streams(demuxer);
return CONTROL_OK;
}
+
return CONTROL_UNKNOWN;
}