summaryrefslogtreecommitdiffstats
path: root/demux
diff options
context:
space:
mode:
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;
}