summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-07-05 16:57:56 +0200
committerwm4 <wm4@nowhere>2014-07-05 17:07:15 +0200
commit338004bcfc224727d1477d303aa1521bf3ac21be (patch)
tree5066a689bb13f4c00a360d9b33a485d81eb17d72
parent4d2a4afdef24c343b98e71dddcb3382e85c09c96 (diff)
downloadmpv-338004bcfc224727d1477d303aa1521bf3ac21be.tar.bz2
mpv-338004bcfc224727d1477d303aa1521bf3ac21be.tar.xz
dvd, bluray, cdda: add demux_disc containing all related hacks
DVD and Bluray (and to some extent cdda) require awful hacks all over the codebase to make them work. The main reason is that they act like container, but are entirely implemented on the stream layer. The raw mpeg data resulting from these streams must be "extended" with the container-like metadata transported via STREAM_CTRLs. The result were hacks all over demux.c and some higher-level parts. Add a "disc" pseudo-demuxer, and move all these hacks and special-cases to it.
-rw-r--r--demux/demux.c86
-rw-r--r--demux/demux.h5
-rw-r--r--demux/demux_disc.c276
-rw-r--r--demux/demux_lavf.c16
-rw-r--r--old-makefile1
-rw-r--r--player/loadfile.c68
-rw-r--r--player/sub.c41
-rw-r--r--player/video.c5
-rw-r--r--stream/cache.c6
-rw-r--r--stream/stream.c5
-rw-r--r--stream/stream.h5
-rw-r--r--stream/stream_bluray.c3
-rw-r--r--stream/stream_cdda.c3
-rw-r--r--stream/stream_dvd.c4
-rw-r--r--stream/stream_dvdnav.c4
-rw-r--r--stream/tv.c1
-rw-r--r--video/decode/dec_video.c3
-rw-r--r--video/decode/dec_video.h1
-rw-r--r--wscript_build.py1
19 files changed, 304 insertions, 230 deletions
diff --git a/demux/demux.c b/demux/demux.c
index 7b780c4411..d6aff6d858 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -52,12 +52,14 @@ extern const demuxer_desc_t demuxer_desc_lavf;
extern const demuxer_desc_t demuxer_desc_libass;
extern const demuxer_desc_t demuxer_desc_subreader;
extern const demuxer_desc_t demuxer_desc_playlist;
+extern const demuxer_desc_t demuxer_desc_disc;
/* Please do not add any new demuxers here. If you want to implement a new
* demuxer, add it to libavformat, except for wrappers around external
* libraries and demuxers requiring binary support. */
const demuxer_desc_t *const demuxer_list[] = {
+ &demuxer_desc_disc,
&demuxer_desc_edl,
&demuxer_desc_cue,
&demuxer_desc_rawaudio,
@@ -86,7 +88,6 @@ struct demux_stream {
struct demux_packet *tail;
};
-static void add_stream_chapters(struct demuxer *demuxer);
void demuxer_sort_chapters(demuxer_t *demuxer);
static void ds_free_packs(struct demux_stream *ds)
@@ -131,8 +132,6 @@ struct sh_stream *new_sh_stream(demuxer_t *demuxer, enum stream_type type)
case STREAM_SUB: sh->sub = talloc_zero(demuxer, struct sh_sub); break;
}
- sh->ds->selected = demuxer->stream_autoselect;
-
return sh;
}
@@ -332,6 +331,18 @@ bool demux_stream_eof(struct sh_stream *sh)
return !sh || sh->ds->eof;
}
+// Read and return any packet we find.
+struct demux_packet *demux_read_any_packet(struct demuxer *demuxer)
+{
+ demux_fill_buffer(demuxer);
+ for (int n = 0; n < demuxer->num_streams; n++) {
+ struct sh_stream *sh = demuxer->streams[n];
+ if (sh->ds->head)
+ return demux_read_packet(sh);
+ }
+ return NULL;
+}
+
// ====================================================================
void demuxer_help(struct mp_log *log)
@@ -472,15 +483,6 @@ static struct demuxer *open_given_type(struct mpv_global *global,
demuxer->filetype, desc->desc);
else
mp_verbose(log, "Detected file format: %s\n", desc->desc);
- if (stream_manages_timeline(demuxer->stream)) {
- // Incorrect, but fixes some behavior with DVD/BD
- demuxer->ts_resets_possible = false;
- // Doesn't work, because stream_pts is a "guess".
- demuxer->accurate_seek = false;
- // Can be seekable even if the stream isn't.
- demuxer->seekable = true;
- }
- add_stream_chapters(demuxer);
demuxer_sort_chapters(demuxer);
demux_info_update(demuxer);
demux_export_replaygain(demuxer);
@@ -572,42 +574,9 @@ int demux_seek(demuxer_t *demuxer, float rel_seek_secs, int flags)
if (rel_seek_secs == MP_NOPTS_VALUE && (flags & SEEK_ABSOLUTE))
return 0;
- // clear demux buffers:
+ // clear the packet queues
demux_flush(demuxer);
- /* Note: this is for DVD and BD playback. The stream layer has to do these
- * seeks, and the demuxer has to react to DEMUXER_CTRL_RESYNC in order to
- * deal with the suddenly changing stream position.
- */
- struct stream *stream = demuxer->stream;
- if (stream_manages_timeline(stream)) {
- double pts;
-
- if (flags & SEEK_ABSOLUTE)
- pts = 0.0f;
- else {
- if (demuxer->stream_pts == MP_NOPTS_VALUE)
- goto dmx_seek;
- pts = demuxer->stream_pts;
- }
-
- if (flags & SEEK_FACTOR) {
- double tmp = 0;
- if (stream_control(demuxer->stream, STREAM_CTRL_GET_TIME_LENGTH,
- &tmp) == STREAM_UNSUPPORTED)
- goto dmx_seek;
- pts += tmp * rel_seek_secs;
- } else
- pts += rel_seek_secs;
-
- if (stream_control(demuxer->stream, STREAM_CTRL_SEEK_TO_TIME, &pts)
- != STREAM_UNSUPPORTED) {
- demux_control(demuxer, DEMUXER_CTRL_RESYNC, NULL);
- return 1;
- }
- }
-
- dmx_seek:
if (demuxer->desc->seek)
demuxer->desc->seek(demuxer, rel_seek_secs, flags);
@@ -698,11 +667,6 @@ void demuxer_select_track(struct demuxer *demuxer, struct sh_stream *stream,
}
}
-void demuxer_enable_autoselect(struct demuxer *demuxer)
-{
- demuxer->stream_autoselect = true;
-}
-
bool demuxer_stream_is_selected(struct demuxer *d, struct sh_stream *stream)
{
return stream && stream->ds->selected;
@@ -761,29 +725,9 @@ int demuxer_add_chapter(demuxer_t *demuxer, struct bstr name,
return demuxer->num_chapters - 1;
}
-static void add_stream_chapters(struct demuxer *demuxer)
-{
- if (demuxer->num_chapters)
- return;
- int num_chapters = 0;
- if (stream_control(demuxer->stream, STREAM_CTRL_GET_NUM_CHAPTERS,
- &num_chapters) != STREAM_OK)
- return;
- for (int n = 0; n < num_chapters; n++) {
- double p = n;
- if (stream_control(demuxer->stream, STREAM_CTRL_GET_CHAPTER_TIME, &p)
- != STREAM_OK)
- return;
- demuxer_add_chapter(demuxer, bstr0(""), p * 1e9, 0, 0);
- }
-}
-
double demuxer_get_time_length(struct demuxer *demuxer)
{
double len;
- if (stream_control(demuxer->stream, STREAM_CTRL_GET_TIME_LENGTH, &len) > 0)
- return len;
- // <= 0 means DEMUXER_CTRL_NOTIMPL or DEMUXER_CTRL_DONTKNOW
if (demux_control(demuxer, DEMUXER_CTRL_GET_TIME_LENGTH, &len) > 0)
return len;
return -1;
diff --git a/demux/demux.h b/demux/demux.h
index 10c4984564..56ac02ae88 100644
--- a/demux/demux.h
+++ b/demux/demux.h
@@ -38,10 +38,10 @@ struct MPOpts;
enum demuxer_type {
DEMUXER_TYPE_GENERIC = 0,
- DEMUXER_TYPE_TV,
DEMUXER_TYPE_MATROSKA,
DEMUXER_TYPE_EDL,
DEMUXER_TYPE_CUE,
+ DEMUXER_TYPE_DISC,
};
// DEMUXER control commands/answers
@@ -190,7 +190,6 @@ typedef struct demuxer {
struct sh_stream **streams;
int num_streams;
- bool stream_autoselect;
struct demux_edition *editions;
int num_editions;
@@ -234,6 +233,7 @@ struct demux_packet *demux_read_packet(struct sh_stream *sh);
double demux_get_next_pts(struct sh_stream *sh);
bool demux_has_packet(struct sh_stream *sh);
bool demux_stream_eof(struct sh_stream *sh);
+struct demux_packet *demux_read_any_packet(struct demuxer *demuxer);
struct sh_stream *new_sh_stream(struct demuxer *demuxer, enum stream_type type);
@@ -253,7 +253,6 @@ void demuxer_switch_track(struct demuxer *demuxer, enum stream_type type,
struct sh_stream *stream);
void demuxer_select_track(struct demuxer *demuxer, struct sh_stream *stream,
bool selected);
-void demuxer_enable_autoselect(struct demuxer *demuxer);
void demuxer_help(struct mp_log *log);
diff --git a/demux/demux_disc.c b/demux/demux_disc.c
new file mode 100644
index 0000000000..2901bb596b
--- /dev/null
+++ b/demux/demux_disc.c
@@ -0,0 +1,276 @@
+/*
+ * This file is part of mpv.
+ *
+ * mpv is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpv is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with mpv. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+#include <assert.h>
+
+#include "common/common.h"
+#include "common/msg.h"
+
+#include "stream/stream.h"
+#include "demux.h"
+#include "stheader.h"
+
+#include "video/csputils.h"
+
+struct priv {
+ struct demuxer *slave;
+ // streams[slave_stream_index] == our_stream
+ struct sh_stream **streams;
+ int num_streams;
+ // This contains each DVD sub stream, or NULL. Needed because
+ struct sh_stream *dvd_subs[32];
+};
+
+static void reselect_streams(demuxer_t *demuxer)
+{
+ struct priv *p = demuxer->priv;
+ for (int n = 0; n < MPMIN(p->slave->num_streams, p->num_streams); n++) {
+ if (p->streams[n]) {
+ demuxer_select_track(p->slave, p->slave->streams[n],
+ demuxer_stream_is_selected(demuxer, p->streams[n]));
+ }
+ }
+}
+
+static void get_disc_lang(struct stream *stream, struct sh_stream *sh)
+{
+ struct stream_lang_req req = {.type = sh->type, .id = sh->demuxer_id};
+ if (stream->uncached_type == STREAMTYPE_DVD && sh->type == STREAM_SUB)
+ req.id = req.id & 0x1F; // mpeg ID to index
+ stream_control(stream, STREAM_CTRL_GET_LANG, &req);
+ if (req.name[0])
+ sh->lang = talloc_strdup(sh, req.name);
+}
+
+static void add_dvd_streams(demuxer_t *demuxer)
+{
+ struct priv *p = demuxer->priv;
+ struct stream *stream = demuxer->stream;
+ if (stream->uncached_type != STREAMTYPE_DVD)
+ return;
+ struct stream_dvd_info_req info;
+ if (stream_control(stream, STREAM_CTRL_GET_DVD_INFO, &info) > 0) {
+ for (int n = 0; n < MPMIN(32, info.num_subs); n++) {
+ struct sh_stream *sh = new_sh_stream(demuxer, STREAM_SUB);
+ if (!sh)
+ break;
+ sh->demuxer_id = n + 0x20;
+ sh->codec = "dvd_subtitle";
+ get_disc_lang(stream, sh);
+ // p->streams _must_ match with p->slave->streams, so we can't add
+ // it yet - it has to be done when the real stream appears, which
+ // could be right on start, or any time later.
+ p->dvd_subs[n] = sh;
+
+ // emulate the extradata
+ struct mp_csp_params csp = MP_CSP_PARAMS_DEFAULTS;
+ csp.int_bits_in = 8;
+ csp.int_bits_out = 8;
+ float cmatrix[3][4];
+ mp_get_yuv2rgb_coeffs(&csp, cmatrix);
+
+ char *s = talloc_strdup(sh, "");
+ s = talloc_asprintf_append(s, "palette: ");
+ for (int i = 0; i < 16; i++) {
+ int color = info.palette[i];
+ int c[3] = {(color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff};
+ mp_map_int_color(cmatrix, 8, c);
+ color = (c[2] << 16) | (c[1] << 8) | c[0];
+
+ if (i != 0)
+ s = talloc_asprintf_append(s, ", ");
+ s = talloc_asprintf_append(s, "%06x", color);
+ }
+ s = talloc_asprintf_append(s, "\n");
+
+ sh->sub->extradata = s;
+ sh->sub->extradata_len = strlen(s);
+ }
+ }
+}
+
+static void add_streams(demuxer_t *demuxer)
+{
+ struct priv *p = demuxer->priv;
+
+ for (int n = p->num_streams; n < p->slave->num_streams; n++) {
+ struct sh_stream *src = p->slave->streams[n];
+ if (src->sub) {
+ struct sh_stream *sub = NULL;
+ if (src->demuxer_id >= 0x20 && src->demuxer_id <= 0x3F)
+ sub = p->dvd_subs[src->demuxer_id - 0x20];
+ if (sub) {
+ assert(p->num_streams == n); // directly mapped
+ MP_TARRAY_APPEND(p, p->streams, p->num_streams, sub);
+ continue;
+ }
+ }
+ struct sh_stream *sh = new_sh_stream(demuxer, src->type);
+ assert(p->num_streams == n); // directly mapped
+ MP_TARRAY_APPEND(p, p->streams, p->num_streams, sh);
+ // Copy all stream fields that might be relevant
+ sh->codec = talloc_strdup(sh, src->codec);
+ sh->format = src->format;
+ sh->lav_headers = src->lav_headers;
+ if (sh && src->video) {
+ double ar;
+ if (stream_control(demuxer->stream, STREAM_CTRL_GET_ASPECT_RATIO, &ar)
+ == STREAM_OK)
+ src->video->aspect = ar;
+ }
+ if (sh && src->audio)
+ sh->audio = src->audio;
+ }
+ reselect_streams(demuxer);
+}
+
+static void d_seek(demuxer_t *demuxer, float rel_seek_secs, int flags)
+{
+ struct priv *p = demuxer->priv;
+
+ if (demuxer->stream->uncached_type == STREAMTYPE_CDDA) {
+ demux_seek(p->slave, rel_seek_secs, flags);
+ return;
+ }
+
+ double pts;
+ if (flags & SEEK_ABSOLUTE)
+ pts = 0.0f;
+ else {
+ if (demuxer->stream_pts == MP_NOPTS_VALUE)
+ return;
+ pts = demuxer->stream_pts;
+ }
+
+ if (flags & SEEK_FACTOR) {
+ double tmp = 0;
+ stream_control(demuxer->stream, STREAM_CTRL_GET_TIME_LENGTH, &tmp);
+ pts += tmp * rel_seek_secs;
+ } else {
+ pts += rel_seek_secs;
+ }
+
+ stream_control(demuxer->stream, STREAM_CTRL_SEEK_TO_TIME, &pts);
+ demux_control(p->slave, DEMUXER_CTRL_RESYNC, NULL);
+}
+
+static int d_fill_buffer(demuxer_t *demuxer)
+{
+ struct priv *p = demuxer->priv;
+
+ struct demux_packet *pkt = demux_read_any_packet(p->slave);
+ if (!pkt)
+ return 0;
+
+ add_streams(demuxer);
+ if (pkt->stream >= p->num_streams) { // out of memory?
+ abort();
+ talloc_free(pkt);
+ return 0;
+ }
+
+ struct sh_stream *sh = p->streams[pkt->stream];
+
+ // Use only one stream for stream_pts, otherwise PTS might be jumpy.
+ if (sh->type == STREAM_VIDEO) {
+ double pts;
+ if (stream_control(demuxer->stream, STREAM_CTRL_GET_CURRENT_TIME, &pts) > 0)
+ pkt->stream_pts = pts;
+ }
+
+ demuxer_add_packet(demuxer, sh, pkt);
+ return 1;
+}
+
+static void add_stream_chapters(struct demuxer *demuxer)
+{
+ int num = 0;
+ if (stream_control(demuxer->stream, STREAM_CTRL_GET_NUM_CHAPTERS, &num) < 1)
+ return;
+ for (int n = 0; n < num; n++) {
+ double p = n;
+ if (stream_control(demuxer->stream, STREAM_CTRL_GET_CHAPTER_TIME, &p) < 1)
+ continue;
+ demuxer_add_chapter(demuxer, bstr0(""), p * 1e9, 0, 0);
+ }
+}
+
+static int d_open(demuxer_t *demuxer, enum demux_check check)
+{
+ struct priv *p = demuxer->priv = talloc_zero(demuxer, struct priv);
+
+ if (check != DEMUX_CHECK_FORCE)
+ return -1;
+
+ char *demux = "+lavf";
+ if (demuxer->stream->uncached_type == STREAMTYPE_CDDA)
+ demux = "+rawaudio";
+
+ p->slave = demux_open(demuxer->stream, demux, NULL, demuxer->global);
+ if (!p->slave)
+ return -1;
+
+ // Incorrect, but fixes some behavior
+ demuxer->ts_resets_possible = false;
+ // Doesn't work, because stream_pts is a "guess".
+ demuxer->accurate_seek = false;
+ // Can be seekable even if the stream isn't.
+ demuxer->seekable = true;
+
+ add_dvd_streams(demuxer);
+ add_streams(demuxer);
+ add_stream_chapters(demuxer);
+
+ return 0;
+}
+
+static void d_close(demuxer_t *demuxer)
+{
+ struct priv *p = demuxer->priv;
+ free_demuxer(p->slave);
+}
+
+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 DEMUXER_CTRL_OK;
+ }
+ case DEMUXER_CTRL_SWITCHED_TRACKS:
+ reselect_streams(demuxer);
+ return DEMUXER_CTRL_OK;
+ }
+ return demux_control(p->slave, cmd, arg);
+}
+
+const demuxer_desc_t demuxer_desc_disc = {
+ .name = "disc",
+ .desc = "CD/DVD/BD wrapper",
+ .fill_buffer = d_fill_buffer,
+ .open = d_open,
+ .close = d_close,
+ .seek = d_seek,
+ .control = d_control,
+ .type = DEMUXER_TYPE_DISC,
+};
diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c
index 619f06b32b..3c18866312 100644
--- a/demux/demux_lavf.c
+++ b/demux/demux_lavf.c
@@ -54,6 +54,7 @@
#include "stheader.h"
#include "options/m_option.h"
+
#define INITIAL_PROBE_SIZE STREAM_BUFFER_SIZE
#define PROBE_BUF_SIZE FFMIN(STREAM_MAX_BUFFER_SIZE, 2 * 1024 * 1024)
@@ -153,8 +154,6 @@ static int64_t mp_seek(void *opaque, int64_t pos, int whence)
struct demuxer *demuxer = opaque;
struct stream *stream = demuxer->stream;
int64_t current_pos;
- if (stream_manages_timeline(stream))
- return -1;
MP_TRACE(demuxer, "mp_seek(%p, %"PRId64", %d)\n", stream, pos, whence);
if (whence == SEEK_END || whence == AVSEEK_SIZE) {
int64_t end;
@@ -264,8 +263,7 @@ static int lavf_check_file(demuxer_t *demuxer, enum demux_check check)
MP_FATAL(demuxer, "Unknown lavf format %s\n", format);
return -1;
}
- MP_INFO(demuxer, "Forced lavf %s demuxer\n",
- priv->avif->long_name);
+ MP_VERBOSE(demuxer, "Forced lavf %s demuxer\n", priv->avif->long_name);
goto success;
}
@@ -762,10 +760,6 @@ static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check)
demuxer->start_time = priv->avfc->start_time == AV_NOPTS_VALUE ?
0 : (double)priv->avfc->start_time / AV_TIME_BASE;
- double time;
- if (stream_control(demuxer->stream, STREAM_CTRL_GET_START_TIME, &time) > 0)
- demuxer->start_time = time;
-
return 0;
}
@@ -816,12 +810,6 @@ static int demux_lavf_fill_buffer(demuxer_t *demux)
dp->duration = pkt->convergence_duration * av_q2d(st->time_base);
dp->pos = pkt->pos;
dp->keyframe = pkt->flags & AV_PKT_FLAG_KEY;
- // Use only one stream for stream_pts, otherwise PTS might be jumpy.
- if (stream->type == STREAM_VIDEO) {
- double pts;
- if (stream_control(demux->stream, STREAM_CTRL_GET_CURRENT_TIME, &pts) > 0)
- dp->stream_pts = pts;
- }
if (dp->pts != MP_NOPTS_VALUE) {
priv->last_pts = dp->pts * AV_TIME_BASE;
} else if (dp->dts != MP_NOPTS_VALUE) {
diff --git a/old-makefile b/old-makefile
index 96e4c48316..9c372c9b25 100644
--- a/old-makefile
+++ b/old-makefile
@@ -159,6 +159,7 @@ SOURCES = audio/audio.c \
demux/demux.c \
demux/demux_edl.c \
demux/demux_cue.c \
+ demux/demux_disc.c \
demux/demux_lavf.c \
demux/demux_mf.c \
demux/demux_mkv.c \
diff --git a/player/loadfile.c b/player/loadfile.c
index bae8f74fe9..c2242ea7c2 100644
--- a/player/loadfile.c
+++ b/player/loadfile.c
@@ -351,14 +351,6 @@ double timeline_set_from_time(struct MPContext *mpctx, double pts, bool *need_re
return -1;
}
-// Map stream number (as used by libdvdread) to MPEG IDs (as used by demuxer).
-static int map_id_from_demuxer(struct demuxer *d, enum stream_type type, int id)
-{
- if (d->stream->uncached_type == STREAMTYPE_DVD && type == STREAM_SUB)
- id = id & 0x1F;
- return id;
-}
-
static int find_new_tid(struct MPContext *mpctx, enum stream_type t)
{
int new_id = 0;
@@ -378,22 +370,6 @@ static struct track *add_stream_track(struct MPContext *mpctx,
struct track *track = mpctx->tracks[i];
if (track->stream == stream)
return track;
- // DVD subtitle track that was added later
- if (stream->type == STREAM_SUB && track->type == STREAM_SUB &&
- map_id_from_demuxer(stream->demuxer, stream->type,
- stream->demuxer_id) == track->demuxer_id
- && !track->stream)
- {
- track->stream = stream;
- track->demuxer_id = stream->demuxer_id;
- // Initialize lazily selected track
- demuxer_select_track(track->demuxer, stream, track->selected);
- if (mpctx->current_track[0][STREAM_SUB] == track)
- reinit_subs(mpctx, 0);
- if (mpctx->current_track[1][STREAM_SUB] == track)
- reinit_subs(mpctx, 1);
- return track;
- }
}
struct track *track = talloc_ptrtype(NULL, track);
@@ -411,21 +387,6 @@ static struct track *add_stream_track(struct MPContext *mpctx,
};
MP_TARRAY_APPEND(mpctx, mpctx->tracks, mpctx->num_tracks, track);
- // Needed for DVD and Blu-ray.
- struct stream *st = track->demuxer->stream;
- if (!track->lang && (st->uncached_type == STREAMTYPE_BLURAY ||
- st->uncached_type == STREAMTYPE_DVD))
- {
- struct stream_lang_req req = {
- .type = track->type,
- .id = map_id_from_demuxer(track->demuxer, track->type,
- track->demuxer_id)
- };
- stream_control(st, STREAM_CTRL_GET_LANG, &req);
- if (req.name[0])
- track->lang = talloc_strdup(track, req.name);
- }
-
demuxer_select_track(track->demuxer, stream, false);
mp_notify(mpctx, MPV_EVENT_TRACKS_CHANGED, NULL);
@@ -439,34 +400,6 @@ void add_demuxer_tracks(struct MPContext *mpctx, struct demuxer *demuxer)
add_stream_track(mpctx, demuxer->streams[n], !!mpctx->timeline);
}
-static void add_dvd_tracks(struct MPContext *mpctx)
-{
- struct demuxer *demuxer = mpctx->demuxer;
- struct stream *stream = demuxer->stream;
- struct stream_dvd_info_req info;
- if (stream->uncached_type != STREAMTYPE_DVD)
- return;
- if (stream_control(stream, STREAM_CTRL_GET_DVD_INFO, &info) > 0) {
- for (int n = 0; n < info.num_subs; n++) {
- struct track *track = talloc_ptrtype(NULL, track);
- *track = (struct track) {
- .type = STREAM_SUB,
- .user_tid = find_new_tid(mpctx, STREAM_SUB),
- .demuxer_id = n,
- .demuxer = mpctx->demuxer,
- };
- MP_TARRAY_APPEND(mpctx, mpctx->tracks, mpctx->num_tracks, track);
-
- struct stream_lang_req req = {.type = STREAM_SUB, .id = n};
- stream_control(stream, STREAM_CTRL_GET_LANG, &req);
- track->lang = talloc_strdup(track, req.name);
-
- mp_notify(mpctx, MPV_EVENT_TRACKS_CHANGED, NULL);
- }
- }
- demuxer_enable_autoselect(demuxer);
-}
-
// Result numerically higher => better match. 0 == no match.
static int match_lang(char **langs, char *lang)
{
@@ -1182,7 +1115,6 @@ goto_reopen_demuxer: ;
mpctx->demuxer = mpctx->timeline[0].source;
main_is_ok: ;
}
- add_dvd_tracks(mpctx);
add_demuxer_tracks(mpctx, mpctx->demuxer);
mpctx->timeline_part = 0;
diff --git a/player/sub.c b/player/sub.c
index e46438e66e..7202eff9e5 100644
--- a/player/sub.c
+++ b/player/sub.c
@@ -158,46 +158,6 @@ void update_subtitles(struct MPContext *mpctx)
update_subtitle(mpctx, 1);
}
-static void set_dvdsub_fake_extradata(struct dec_sub *dec_sub, struct stream *st,
- int width, int height)
-{
- if (!st)
- return;
-
- struct stream_dvd_info_req info;
- if (stream_control(st, STREAM_CTRL_GET_DVD_INFO, &info) < 0)
- return;
-
- struct mp_csp_params csp = MP_CSP_PARAMS_DEFAULTS;
- csp.int_bits_in = 8;
- csp.int_bits_out = 8;
- float cmatrix[3][4];
- mp_get_yuv2rgb_coeffs(&csp, cmatrix);
-
- if (width == 0 || height == 0) {
- width = 720;
- height = 480;
- }
-
- char *s = NULL;
- s = talloc_asprintf_append(s, "size: %dx%d\n", width, height);
- s = talloc_asprintf_append(s, "palette: ");
- for (int i = 0; i < 16; i++) {
- int color = info.palette[i];
- int c[3] = {(color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff};
- mp_map_int_color(cmatrix, 8, c);
- color = (c[2] << 16) | (c[1] << 8) | c[0];
-
- if (i != 0)
- s = talloc_asprintf_append(s, ", ");
- s = talloc_asprintf_append(s, "%06x", color);
- }
- s = talloc_asprintf_append(s, "\n");
-
- sub_set_extradata(dec_sub, s, strlen(s));
- talloc_free(s);
-}
-
static void reinit_subdec(struct MPContext *mpctx, struct track *track,
struct dec_sub *dec_sub)
{
@@ -210,7 +170,6 @@ static void reinit_subdec(struct MPContext *mpctx, struct track *track,
int h = sh_video ? sh_video->disp_h : 0;
float fps = sh_video ? sh_video->fps : 25;
- set_dvdsub_fake_extradata(dec_sub, track->demuxer->stream, w, h);
sub_set_video_res(dec_sub, w, h);
sub_set_video_fps(dec_sub, fps);
sub_set_ass_renderer(dec_sub, mpctx->ass_library, mpctx->ass_renderer);
diff --git a/player/video.c b/player/video.c
index c7d5cd8ddb..3d742c0081 100644
--- a/player/video.c
+++ b/player/video.c
@@ -183,7 +183,6 @@ int reinit_video_chain(struct MPContext *mpctx)
sh->video->disp_w, sh->video->disp_h,
sh->video->fps);
- double ar = -1.0;
//================== Init VIDEO (codec & libvo) ==========================
if (!opts->fixed_vo || !(mpctx->initialized_flags & INITIALIZED_VO)) {
mpctx->video_out = init_best_video_out(mpctx->global, mpctx->input,
@@ -212,10 +211,6 @@ int reinit_video_chain(struct MPContext *mpctx)
vo_control(mpctx->video_out, VOCTRL_GET_HWDEC_INFO, &d_video->hwdec_info);
- if (stream_control(sh->demuxer->stream, STREAM_CTRL_GET_ASPECT_RATIO, &ar)
- != STREAM_UNSUPPORTED)
- d_video->stream_aspect = ar;
-
recreate_video_filters(mpctx);
if (!video_init_best_codec(d_video, opts->video_decoders))
diff --git a/stream/cache.c b/stream/cache.c
index 3523f04704..f96cdef0e7 100644
--- a/stream/cache.c
+++ b/stream/cache.c
@@ -112,7 +112,6 @@ struct priv {
double stream_time_length;
double stream_start_time;
int64_t stream_size;
- bool stream_manages_timeline;
unsigned int stream_num_chapters;
int stream_cache_idle;
int stream_cache_fill;
@@ -381,9 +380,6 @@ static void update_cached_controls(struct priv *s)
s->stream_start_time = MP_NOPTS_VALUE;
if (stream_control(s->stream, STREAM_CTRL_GET_START_TIME, &d) == STREAM_OK)
s->stream_start_time = d;
- s->stream_manages_timeline = false;
- if (stream_control(s->stream, STREAM_CTRL_MANAGES_TIMELINE, NULL) == STREAM_OK)
- s->stream_manages_timeline = true;
s->stream_num_chapters = 0;
if (stream_control(s->stream, STREAM_CTRL_GET_NUM_CHAPTERS, &ui) == STREAM_OK)
s->stream_num_chapters = ui;
@@ -428,8 +424,6 @@ static int cache_get_cached_control(stream_t *cache, int cmd, void *arg)
return STREAM_UNSUPPORTED;
*(int64_t *)arg = s->stream_size;
return STREAM_OK;
- case STREAM_CTRL_MANAGES_TIMELINE:
- return s->stream_manages_timeline ? STREAM_OK : STREAM_UNSUPPORTED;
case STREAM_CTRL_GET_NUM_CHAPTERS:
*(unsigned int *)arg = s->stream_num_chapters;
return STREAM_OK;
diff --git a/stream/stream.c b/stream/stream.c
index 31d15fbf97..d2ab3d640a 100644
--- a/stream/stream.c
+++ b/stream/stream.c
@@ -968,11 +968,6 @@ struct bstr stream_read_complete(struct stream *s, void *talloc_ctx,
return (struct bstr){buf, total_read};
}
-bool stream_manages_timeline(struct stream *s)
-{
- return stream_control(s, STREAM_CTRL_MANAGES_TIMELINE, NULL) == STREAM_OK;
-}
-
void stream_print_proto_list(struct mp_log *log)
{
int count = 0;
diff --git a/stream/stream.h b/stream/stream.h
index 389a0a56e8..f2663f3435 100644
--- a/stream/stream.h
+++ b/stream/stream.h
@@ -39,6 +39,7 @@ enum streamtype {
STREAMTYPE_MF,
STREAMTYPE_EDL,
STREAMTYPE_AVDEVICE,
+ STREAMTYPE_CDDA,
};
#define STREAM_BUFFER_SIZE 2048
@@ -80,8 +81,6 @@ enum stream_ctrl {
STREAM_CTRL_GET_CACHE_IDLE,
STREAM_CTRL_RESUME_CACHE,
STREAM_CTRL_RECONNECT,
- // DVD/Bluray, signal general support for GET_CURRENT_TIME etc.
- STREAM_CTRL_MANAGES_TIMELINE,
STREAM_CTRL_GET_START_TIME,
STREAM_CTRL_GET_CHAPTER_TIME,
STREAM_CTRL_GET_DVD_INFO,
@@ -243,8 +242,6 @@ stream_t *open_memory_stream(void *data, int len);
bool stream_check_interrupt(struct stream *s);
-bool stream_manages_timeline(stream_t *s);
-
void mp_url_unescape_inplace(char *buf);
char *mp_url_escape(void *talloc_ctx, const char *s, const char *ok);
diff --git a/stream/stream_bluray.c b/stream/stream_bluray.c
index fb3c6d749a..ee6d4b9664 100644
--- a/stream/stream_bluray.c
+++ b/stream/stream_bluray.c
@@ -584,8 +584,6 @@ static int bluray_stream_control(stream_t *s, int cmd, void *arg)
*((double *)arg) = 0;
return STREAM_OK;
}
- case STREAM_CTRL_MANAGES_TIMELINE:
- return STREAM_OK;
case STREAM_CTRL_GET_DISC_NAME: {
const struct meta_dl *meta = bd_get_meta(b->bd);
if (!meta || !meta->di_name || !meta->di_name[0])
@@ -801,6 +799,7 @@ static int bluray_stream_open(stream_t *s)
s->end_pos = bd_get_title_size(bd);
s->sector_size = BLURAY_SECTOR_SIZE;
s->priv = b;
+ s->demuxer = "+disc";
MP_VERBOSE(s, "Blu-ray successfully opened.\n");
diff --git a/stream/stream_cdda.c b/stream/stream_cdda.c
index 8ad7608604..953cc812f6 100644
--- a/stream/stream_cdda.c
+++ b/stream/stream_cdda.c
@@ -396,7 +396,8 @@ static int open_cdda(stream_t *st)
st->control = control;
st->close = close_cdda;
- st->demuxer = "rawaudio";
+ st->type = STREAMTYPE_CDDA;
+ st->demuxer = "+disc";
print_cdtext(st, 0);
diff --git a/stream/stream_dvd.c b/stream/stream_dvd.c
index 9773e14fa1..7576dc879b 100644
--- a/stream/stream_dvd.c
+++ b/stream/stream_dvd.c
@@ -619,8 +619,6 @@ static int control(stream_t *stream,int cmd,void* arg)
snprintf(req->name, sizeof(req->name), "%c%c", lang >> 8, lang);
return STREAM_OK;
}
- case STREAM_CTRL_MANAGES_TIMELINE:
- return STREAM_OK;
case STREAM_CTRL_GET_DVD_INFO:
{
struct stream_dvd_info_req *req = arg;
@@ -899,6 +897,8 @@ static int open_s(stream_t *stream)
// ... (unimplemented)
// return NULL;
stream->type = STREAMTYPE_DVD;
+ stream->demuxer = "+disc";
+ stream->lavf_type = "mpeg";
stream->sector_size = 2048;
stream->fill_buffer = fill_buffer;
stream->control = control;
diff --git a/stream/stream_dvdnav.c b/stream/stream_dvdnav.c
index 9be03c6914..c366831aca 100644
--- a/stream/stream_dvdnav.c
+++ b/stream/stream_dvdnav.c
@@ -597,8 +597,6 @@ static int control(stream_t *stream, int cmd, void *arg)
snprintf(req->name, sizeof(req->name), "%c%c", lang >> 8, lang);
return STREAM_OK;
}
- case STREAM_CTRL_MANAGES_TIMELINE:
- return STREAM_OK;
case STREAM_CTRL_GET_DVD_INFO: {
struct stream_dvd_info_req *req = arg;
memset(req, 0, sizeof(*req));
@@ -733,7 +731,7 @@ static int open_s(stream_t *stream)
stream->control = control;
stream->close = stream_dvdnav_close;
stream->type = STREAMTYPE_DVD;
- stream->demuxer = "lavf";
+ stream->demuxer = "+disc";
stream->lavf_type = "mpeg";
stream->allow_caching = false;
diff --git a/stream/tv.c b/stream/tv.c
index 726b7d0880..291e20240e 100644
--- a/stream/tv.c
+++ b/stream/tv.c
@@ -1228,7 +1228,6 @@ static int demux_tv_control(demuxer_t *demuxer, int cmd, void *arg)
const demuxer_desc_t demuxer_desc_tv = {
.name = "tv",
.desc = "TV card demuxer",
- .type = DEMUXER_TYPE_TV,
.fill_buffer = demux_tv_fill_buffer,
.control = demux_tv_control,
.open = demux_open_tv,
diff --git a/video/decode/dec_video.c b/video/decode/dec_video.c
index 807ce2013c..b7002800fb 100644
--- a/video/decode/dec_video.c
+++ b/video/decode/dec_video.c
@@ -408,9 +408,6 @@ int video_reconfig_filters(struct dec_video *d_video,
}
float force_aspect = opts->movie_aspect;
- if (force_aspect > 0.0 && d_video->stream_aspect != 0.0)
- force_aspect = d_video->stream_aspect;
-
if (force_aspect >= 0.0)
vf_set_dar(&p.d_w, &p.d_h, p.w, p.h, force_aspect);
diff --git a/video/decode/dec_video.h b/video/decode/dec_video.h
index 9541cb3ca6..c9513ac3cd 100644
--- a/video/decode/dec_video.h
+++ b/video/decode/dec_video.h
@@ -72,7 +72,6 @@ struct dec_video {
// Final PTS of previously decoded image
double decoded_pts;
- float stream_aspect; // aspect ratio in media headers (DVD IFO files)
int bitrate; // compressed bits/sec
float fps; // FPS from demuxer or from user override
float initial_decoder_aspect;
diff --git a/wscript_build.py b/wscript_build.py
index 1b506d4b1f..95ca54b187 100644
--- a/wscript_build.py
+++ b/wscript_build.py
@@ -174,6 +174,7 @@ def build(ctx):
( "demux/codec_tags.c" ),
( "demux/demux.c" ),
( "demux/demux_cue.c" ),
+ ( "demux/demux_disc.c" ),
( "demux/demux_edl.c" ),
( "demux/demux_lavf.c" ),
( "demux/demux_libass.c", "libass"),