aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--demux/demux.c2
-rw-r--r--demux/demux_disc.c347
-rwxr-xr-xold-configure10
-rw-r--r--options/options.c11
-rw-r--r--options/options.h6
-rw-r--r--player/command.c133
-rw-r--r--player/configfiles.c6
-rw-r--r--player/core.h9
-rw-r--r--player/discnav.c334
-rw-r--r--player/loadfile.c7
-rw-r--r--player/misc.c4
-rw-r--r--player/playloop.c2
-rw-r--r--stream/cache.c30
-rw-r--r--stream/stream.c15
-rw-r--r--stream/stream.h9
-rw-r--r--stream/stream_bluray.c831
-rw-r--r--stream/stream_dvd.c968
-rw-r--r--stream/stream_dvdnav.c755
-rw-r--r--sub/osd.c11
-rw-r--r--sub/osd.h8
-rw-r--r--wscript13
-rw-r--r--wscript_build.py6
22 files changed, 0 insertions, 3517 deletions
diff --git a/demux/demux.c b/demux/demux.c
index e716194614..b7f184c161 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -52,14 +52,12 @@ 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,
diff --git a/demux/demux_disc.c b/demux/demux_disc.c
deleted file mode 100644
index 06cea65d1a..0000000000
--- a/demux/demux_disc.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * 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 DVD packets
- // can come arbitrarily late in the MPEG stream, so the slave demuxer
- // might add the streams only later.
- struct sh_stream *dvd_subs[32];
- // Used to rewrite the raw MPEG timestamps to playback time.
- struct {
- double base_time; // playback display start time of current segment
- double base_dts; // packet DTS that maps to base_time
- double last_dts; // DTS of previously demuxed packet
- } pts[STREAM_TYPE_COUNT];
- double seek_pts;
- bool seek_reinit; // needs reinit after seek
-};
-
-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],
- demux_stream_is_selected(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)
- sh->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 = p->seek_pts;
- if (flags & SEEK_ABSOLUTE)
- pts = 0.0f;
-
- 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;
- }
-
- MP_VERBOSE(demuxer, "seek to: %f\n", pts);
-
- stream_control(demuxer->stream, STREAM_CTRL_SEEK_TO_TIME, &pts);
- demux_control(p->slave, DEMUXER_CTRL_RESYNC, NULL);
-
- p->seek_pts = pts;
- p->seek_reinit = true;
-}
-
-static void reset_pts(demuxer_t *demuxer)
-{
- struct priv *p = demuxer->priv;
-
- double base;
- if (stream_control(demuxer->stream, STREAM_CTRL_GET_CURRENT_TIME, &base) < 1)
- base = 0;
-
- MP_VERBOSE(demuxer, "reset to time: %f\n", base);
-
- for (int n = 0; n < STREAM_TYPE_COUNT; n++) {
- p->pts[n].base_dts = p->pts[n].last_dts = MP_NOPTS_VALUE;
- p->pts[n].base_time = base;
- }
-
- p->seek_reinit = false;
-}
-
-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;
-
- if (p->seek_reinit)
- reset_pts(demuxer);
-
- add_streams(demuxer);
- if (pkt->stream >= p->num_streams) { // out of memory?
- talloc_free(pkt);
- return 0;
- }
-
- struct sh_stream *sh = p->streams[pkt->stream];
- if (!demux_stream_is_selected(sh)) {
- talloc_free(pkt);
- return 1;
- }
-
- int t = sh->type;
-
- // Subtitle timestamps are not continuous, so the heuristic below can't be
- // applied. Instead, use the video stream as reference.
- if (t == STREAM_SUB)
- t = STREAM_VIDEO;
-
- MP_TRACE(demuxer, "ipts: %d %f %f\n", sh->type, pkt->pts, pkt->dts);
-
- if (sh->type == STREAM_SUB) {
- if (p->pts[t].base_dts == MP_NOPTS_VALUE)
- MP_WARN(demuxer, "subtitle packet along PTS reset, report a bug\n");
- } else if (pkt->dts != MP_NOPTS_VALUE) {
- if (p->pts[t].base_dts == MP_NOPTS_VALUE)
- p->pts[t].base_dts = p->pts[t].last_dts = pkt->dts;
-
- if (pkt->dts < p->pts[t].last_dts || pkt->dts > p->pts[t].last_dts + 0.5)
- {
- MP_VERBOSE(demuxer, "PTS discontinuity on stream %d\n", sh->type);
- p->pts[t].base_time += p->pts[t].last_dts - p->pts[t].base_dts;
- p->pts[t].base_dts = p->pts[t].last_dts = pkt->dts - pkt->duration;
- }
- p->pts[t].last_dts = pkt->dts;
- }
- if (p->pts[t].base_dts != MP_NOPTS_VALUE) {
- double delta = -p->pts[t].base_dts + p->pts[t].base_time;
- if (pkt->pts != MP_NOPTS_VALUE)
- pkt->pts += delta;
- if (pkt->dts != MP_NOPTS_VALUE)
- pkt->dts += delta;
- }
-
- MP_TRACE(demuxer, "opts: %d %f %f\n", sh->type, pkt->pts, pkt->dts);
-
- if (pkt->pts != MP_NOPTS_VALUE)
- p->seek_pts = pkt->pts;
-
- demux_add_packet(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";
-
- // Initialize the playback time. We need to read _some_ data to get the
- // correct stream-layer time (at least with libdvdnav).
- stream_peek(demuxer->stream, 1);
- reset_pts(demuxer);
-
- p->slave = demux_open(demuxer->stream, demux, NULL, demuxer->global);
- if (!p->slave)
- return -1;
-
- // So that we don't miss initial packets of delayed subtitle streams.
- p->slave->stream_select_default = true;
-
- // 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_RESYNC:
- demux_flush(p->slave);
- break; // relay to slave demuxer
- 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/old-configure b/old-configure
index a57be03a56..8de6ac7eda 100755
--- a/old-configure
+++ b/old-configure
@@ -179,9 +179,6 @@ options_state_machine() {
opt_yes_no _libquvi4 "libquvi 0.4.x"
opt_yes_no _libquvi9 "libquvi 0.9.x"
opt_yes_no _lcms2 "LCMS2 support"
- opt_yes_no _bluray "Blu-ray support"
- opt_yes_no _dvdread "libdvdread"
- opt_yes_no _dvdnav "libdvdnav"
opt_yes_no _enca "ENCA charset oracle library"
opt_yes_no _libass "subtitle rendering with libass"
opt_yes_no _libpostproc "postprocess filter (vf_pp)"
@@ -730,12 +727,6 @@ check_pkg_config "OpenAL" $_openal OPENAL 'openal >= 1.13'
check_pkg_config "ALSA audio" $_alsa ALSA 'alsa >= 1.0.9'
-check_pkg_config "Blu-ray support" $_bluray LIBBLURAY 'libbluray >= 0.2.1'
-
-check_pkg_config "dvdread" $_dvdread DVDREAD 'dvdread >= 4.1.0'
-
-check_pkg_config "dvdnav" $_dvdnav DVDNAV 'dvdnav >= 4.2.0'
-
check_pkg_config "libcdio" $_libcdio CDDA 'libcdio_paranoia'
_oldass=$_libass
@@ -961,7 +952,6 @@ cat > $TMPC << EOF
#define HAVE_SDL1 0
#define DEFAULT_CDROM_DEVICE "/dev/cdrom"
-#define DEFAULT_DVD_DEVICE "/dev/dvd"
#define PATH_DEV_DSP "/dev/dsp"
#define PATH_DEV_MIXER "/dev/mixer"
diff --git a/options/options.c b/options/options.c
index 84eda8db64..21adaf76c4 100644
--- a/options/options.c
+++ b/options/options.c
@@ -147,18 +147,9 @@ const m_option_t mp_opts[] = {
({"no", 0})),
OPT_INTRANGE("cache-pause-restart", stream_cache_unpause, 0, 0, 0x7fffffff),
-#if HAVE_DVDREAD || HAVE_DVDNAV
- OPT_STRING("dvd-device", dvd_device, 0),
- OPT_INT("dvd-speed", dvd_speed, 0),
- OPT_INTRANGE("dvd-angle", dvd_angle, 0, 1, 99),
-#endif /* HAVE_DVDREAD */
OPT_INTPAIR("chapter", chapterrange, 0),
OPT_CHOICE_OR_INT("edition", edition_id, 0, 0, 8190,
({"auto", -1})),
-#if HAVE_LIBBLURAY
- OPT_STRING("bluray-device", bluray_device, 0),
- OPT_INTRANGE("bluray-angle", bluray_angle, 0, 0, 999),
-#endif /* HAVE_LIBBLURAY */
OPT_STRINGLIST("http-header-fields", network_http_header_fields, 0),
OPT_STRING("user-agent", network_useragent, 0),
@@ -640,8 +631,6 @@ const struct MPOpts mp_default_opts = {
.index_mode = 1,
- .dvd_angle = 1,
-
.mf_fps = 1.0,
};
diff --git a/options/options.h b/options/options.h
index 100fded4a3..9cd5f800d9 100644
--- a/options/options.h
+++ b/options/options.h
@@ -251,12 +251,6 @@ typedef struct MPOpts {
struct dvb_params *stream_dvb_opts;
char *cdrom_device;
- int dvd_title;
- int dvd_angle;
- int dvd_speed;
- char *dvd_device;
- int bluray_angle;
- char *bluray_device;
double mf_fps;
char *mf_type;
diff --git a/player/command.c b/player/command.c
index fffa63bb70..facc890e8a 100644
--- a/player/command.c
+++ b/player/command.c
@@ -232,13 +232,6 @@ static int mp_property_media_title(void *ctx, struct m_property *prop,
name = demux_info_get(mpctx->master_demuxer, "title");
if (name && name[0])
return m_property_strdup_ro(action, arg, name);
- struct stream *stream = mpctx->master_demuxer->stream;
- if (stream_control(stream, STREAM_CTRL_GET_DISC_NAME, &name) > 0
- && name) {
- int r = m_property_strdup_ro(action, arg, name);
- talloc_free(name);
- return r;
- }
}
return mp_property_filename(ctx, prop, action, arg);
}
@@ -485,48 +478,6 @@ static int mp_property_playback_time(void *ctx, struct m_property *prop,
return property_time(action, arg, get_playback_time(mpctx));
}
-/// Current BD/DVD title (RW)
-static int mp_property_disc_title(void *ctx, struct m_property *prop,
- int action, void *arg)
-{
- MPContext *mpctx = ctx;
- struct demuxer *demuxer = mpctx->master_demuxer;
- if (!demuxer || !demuxer->stream)
- return M_PROPERTY_UNAVAILABLE;
- struct stream *stream = demuxer->stream;
- unsigned int title = -1;
- switch (action) {
- case M_PROPERTY_GET:
- if (stream_control(stream, STREAM_CTRL_GET_CURRENT_TITLE, &title) <= 0)
- return M_PROPERTY_UNAVAILABLE;
- *(int*)arg = title;
- return M_PROPERTY_OK;
- case M_PROPERTY_GET_TYPE:
- *(struct m_option *)arg = (struct m_option){
- .type = CONF_TYPE_INT,
- .flags = M_OPT_MIN,
- .min = -1,
- };
- return M_PROPERTY_OK;
- case M_PROPERTY_SET:
- title = *(int*)arg;
- if (stream_control(stream, STREAM_CTRL_SET_CURRENT_TITLE, &title) <= 0)
- return M_PROPERTY_NOT_IMPLEMENTED;
- return M_PROPERTY_OK;
- }
- return M_PROPERTY_NOT_IMPLEMENTED;
-}
-
-static int mp_property_disc_menu(void *ctx, struct m_property *prop,
- int action, void *arg)
-{
- MPContext *mpctx = ctx;
- int state = mp_nav_in_menu(mpctx);
- if (state < 0)
- return M_PROPERTY_UNAVAILABLE;
- return m_property_flag_ro(action, arg, !!state);
-}
-
/// Current chapter (RW)
static int mp_property_chapter(void *ctx, struct m_property *prop,
int action, void *arg)
@@ -806,19 +757,6 @@ static int mp_property_quvi_format(void *ctx, struct m_property *prop,
return mp_property_generic_option(mpctx, prop, action, arg);
}
-/// Number of titles in BD/DVD
-static int mp_property_disc_titles(void *ctx, struct m_property *prop,
- int action, void *arg)
-{
- MPContext *mpctx = ctx;
- struct demuxer *demuxer = mpctx->master_demuxer;
- unsigned int num_titles;
- if (!demuxer || stream_control(demuxer->stream, STREAM_CTRL_GET_NUM_TITLES,
- &num_titles) < 1)
- return M_PROPERTY_UNAVAILABLE;
- return m_property_int_ro(action, arg, num_titles);
-}
-
/// Number of chapters in file
static int mp_property_chapters(void *ctx, struct m_property *prop,
int action, void *arg)
@@ -842,69 +780,6 @@ static int mp_property_editions(void *ctx, struct m_property *prop,
return m_property_int_ro(action, arg, demuxer->num_editions);
}
-/// Current dvd angle (RW)
-static int mp_property_angle(void *ctx, struct m_property *prop,
- int action, void *arg)
-{
- MPContext *mpctx = ctx;
- struct demuxer *demuxer = mpctx->master_demuxer;
- if (!demuxer)
- return M_PROPERTY_UNAVAILABLE;
-
- int ris, angles = -1, angle = 1;
-
- ris = stream_control(demuxer->stream, STREAM_CTRL_GET_NUM_ANGLES, &angles);
- if (ris == STREAM_UNSUPPORTED)
- return M_PROPERTY_UNAVAILABLE;
-
- ris = stream_control(demuxer->stream, STREAM_CTRL_GET_ANGLE, &angle);
- if (ris == STREAM_UNSUPPORTED)
- return -1;
-
- if (angle < 0 || angles <= 1)
- return M_PROPERTY_UNAVAILABLE;
-
- switch (action) {
- case M_PROPERTY_GET:
- *(int *) arg = angle;
- return M_PROPERTY_OK;
- case M_PROPERTY_PRINT: {
- *(char **) arg = talloc_asprintf(NULL, "%d/%d", angle, angles);
- return M_PROPERTY_OK;
- }
- case M_PROPERTY_SET:
- angle = *(int *)arg;
- if (angle < 0 || angle > angles)
- return M_PROPERTY_ERROR;
- demux_flush(demuxer);
-
- ris = stream_control(demuxer->stream, STREAM_CTRL_SET_ANGLE, &angle);
- if (ris != STREAM_OK)
- return M_PROPERTY_ERROR;
-
- demux_control(demuxer, DEMUXER_CTRL_RESYNC, NULL);
-
- if (mpctx->d_video)
- video_reset_decoding(mpctx->d_video);
-
- if (mpctx->d_audio)
- audio_reset_decoding(mpctx->d_audio);
-
- return M_PROPERTY_OK;
- case M_PROPERTY_GET_TYPE: {
- struct m_option opt = {
- .type = CONF_TYPE_INT,
- .flags = CONF_RANGE,
- .min = 1,
- .max = angles,
- };
- *(struct m_option *)arg = opt;
- return M_PROPERTY_OK;
- }
- }
- return M_PROPERTY_NOT_IMPLEMENTED;
-}
-
static int get_tag_entry(int item, int action, void *arg, void *ctx)
{
struct mp_tags *tags = ctx;
@@ -2650,15 +2525,11 @@ static const struct m_property mp_properties[] = {
{"time-remaining", mp_property_remaining},
{"playtime-remaining", mp_property_playtime_remaining},
{"playback-time", mp_property_playback_time},
- {"disc-title", mp_property_disc_title},
- {"disc-menu-active", mp_property_disc_menu},
{"chapter", mp_property_chapter},
{"edition", mp_property_edition},
{"quvi-format", mp_property_quvi_format},
- {"disc-titles", mp_property_disc_titles},
{"chapters", mp_property_chapters},
{"editions", mp_property_editions},
- {"angle", mp_property_angle},
{"metadata", mp_property_metadata},
{"chapter-metadata", mp_property_chapter_metadata},
{"vf-metadata", mp_property_vf_metadata},
@@ -3780,10 +3651,6 @@ int run_command(MPContext *mpctx, mp_cmd_t *cmd)
mp_input_disable_section(mpctx->input, cmd->args[0].v.s);
break;
- case MP_CMD_DISCNAV:
- mp_nav_user_input(mpctx, cmd->args[0].v.s);
- break;
-
case MP_CMD_VO_CMDLINE:
if (mpctx->video_out) {
char *s = cmd->args[0].v.s;
diff --git a/player/configfiles.c b/player/configfiles.c
index d1c79c9c9d..b05184c5fb 100644
--- a/player/configfiles.c
+++ b/player/configfiles.c
@@ -173,7 +173,6 @@ void mp_load_auto_profiles(struct MPContext *mpctx)
static char *mp_get_playback_resume_config_filename(struct mpv_global *global,
const char *fname)
{
- struct MPOpts *opts = global->opts;
char *res = NULL;
void *tmp = talloc_new(NULL);
const char *realpath = fname;
@@ -184,11 +183,6 @@ static char *mp_get_playback_resume_config_filename(struct mpv_global *global,
goto exit;
realpath = mp_path_join(tmp, bstr0(cwd), bstr0(fname));
}
- if (bstr_startswith0(bfname, "dvd://"))
- realpath = talloc_asprintf(tmp, "%s - %s", realpath, opts->dvd_device);
- if (bstr_startswith0(bfname, "br://") || bstr_startswith0(bfname, "bd://") ||
- bstr_startswith0(bfname, "bluray://"))
- realpath = talloc_asprintf(tmp, "%s - %s", realpath, opts->bluray_device);
uint8_t md5[16];
av_md5_sum(md5, realpath, strlen(realpath));
char *conf = talloc_strdup(tmp, "");
diff --git a/player/core.h b/player/core.h
index 84b6123c1c..856e970945 100644
--- a/player/core.h
+++ b/player/core.h
@@ -350,7 +350,6 @@ typedef struct MPContext {
struct screenshot_ctx *screenshot_ctx;
struct command_ctx *command_ctx;
struct encode_lavc_context *encode_lavc_ctx;
- struct mp_nav_state *nav_state;
} MPContext;
// audio.c
@@ -371,14 +370,6 @@ void mp_write_watch_later_conf(struct MPContext *mpctx);
struct playlist_entry *mp_check_playlist_resume(struct MPContext *mpctx,
struct playlist *playlist);
-// discnav.c
-void mp_nav_init(struct MPContext *mpctx);
-void mp_nav_reset(struct MPContext *mpctx);
-void mp_nav_destroy(struct MPContext *mpctx);
-void mp_nav_user_input(struct MPContext *mpctx, char *command);
-void mp_handle_nav(struct MPContext *mpctx);
-int mp_nav_in_menu(struct MPContext *mpctx);
-
// loadfile.c
void uninit_player(struct MPContext *mpctx, unsigned int mask);
struct track *mp_add_subtitles(struct MPContext *mpctx, char *filename);
diff --git a/player/discnav.c b/player/discnav.c
deleted file mode 100644
index 0b52fed479..0000000000
--- a/player/discnav.c
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * 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 <limits.h>
-#include <pthread.h>
-#include <assert.h>
-
-#include "core.h"
-#include "command.h"
-
-#include "common/msg.h"
-#include "common/common.h"
-#include "input/input.h"
-
-#include "stream/discnav.h"
-
-#include "sub/dec_sub.h"
-#include "sub/osd.h"
-
-#include "video/mp_image.h"
-#include "video/decode/dec_video.h"
-
-struct mp_nav_state {
- struct mp_log *log;
-
- int nav_still_frame;
- bool nav_eof;
- bool nav_menu;
- bool nav_draining;
-
- // Accessed by OSD (possibly separate thread)
- // Protected by the given lock
- pthread_mutex_t osd_lock;
- int hi_visible;
- int highlight[4]; // x0 y0 x1 y1
- int vidsize[2];
- int subsize[2];
- struct sub_bitmap *hi_elem;
- struct sub_bitmap *overlays[2];
- struct sub_bitmap outputs[3];
-};
-
-static inline bool is_valid_size(int size[2])
-{
- return size[0] >= 1 && size[1] >= 1;
-}
-
-static void update_resolution(struct MPContext *mpctx)
-{
- struct mp_nav_state *nav = mpctx->nav_state;
- int size[2] = {0};
- if (mpctx->d_sub[0])
- sub_control(mpctx->d_sub[0], SD_CTRL_GET_RESOLUTION, size);
- if (!is_valid_size(size)) {
- struct mp_image_params vid = {0};
- if (mpctx->d_video)
- vid = mpctx->d_video->decoder_output;
- size[0] = vid.w;
- size[1] = vid.h;
- }
- pthread_mutex_lock(&nav->osd_lock);
- nav->vidsize[0] = size[0];
- nav->vidsize[1] = size[1];
- pthread_mutex_unlock(&nav->osd_lock);
-}
-
-// Send update events and such.
-static void update_state(struct MPContext *mpctx)
-{
- mp_notify_property(mpctx, "disc-menu-active");
-}
-
-// Return 1 if in menu, 0 if in video, or <0 if no navigation possible.
-int mp_nav_in_menu(struct MPContext *mpctx)
-{
- return mpctx->nav_state ? mpctx->nav_state->nav_menu : -1;
-}
-
-// Allocate state and enable navigation features. Must happen before
-// initializing cache, because the cache would read data. Since stream_dvdnav is
-// in a mode which skips all transitions on reading data (before enabling
-// navigation), this would skip some menu screens.
-void mp_nav_init(struct MPContext *mpctx)
-{
- assert(!mpctx->nav_state);
-
- // dvdnav is interactive
- if (mpctx->encode_lavc_ctx)
- return;
-
- struct mp_nav_cmd inp = {MP_NAV_CMD_ENABLE};
- if (stream_control(mpctx->stream, STREAM_CTRL_NAV_CMD, &inp) < 1)
- return;
-
- mpctx->nav_state = talloc_zero(NULL, struct mp_nav_state);
- mpctx->nav_state->log = mp_log_new(mpctx->nav_state, mpctx->log, "discnav");
- pthread_mutex_init(&mpctx->nav_state->osd_lock, NULL);
-
- MP_VERBOSE(mpctx->nav_state, "enabling\n");
-
- mp_input_enable_section(mpctx->input, "discnav", 0);
- mp_input_set_section_mouse_area(mpctx->input, "discnav-menu",
- INT_MIN, INT_MIN, INT_MAX, INT_MAX);
-
- update_state(mpctx);
-}
-
-void mp_nav_reset(struct MPContext *mpctx)
-{
- struct mp_nav_state *nav = mpctx->nav_state;
- if (!nav)
- return;
- struct mp_nav_cmd inp = {MP_NAV_CMD_RESUME};
- stream_control(mpctx->stream, STREAM_CTRL_NAV_CMD, &inp);
- osd_set_nav_highlight(mpctx->osd, NULL);
- nav->hi_visible = 0;
- nav->nav_menu = false;
- nav->nav_draining = false;
- nav->nav_still_frame = 0;
- mp_input_disable_section(mpctx->input, "discnav-menu");
- stream_control(mpctx->stream, STREAM_CTRL_RESUME_CACHE, NULL);
- update_state(mpctx);
-}
-
-void mp_nav_destroy(struct MPContext *mpctx)
-{
- osd_set_nav_highlight(mpctx->osd, NULL);
- if (!mpctx->nav_state)
- return;
- mp_input_disable_section(mpctx->input, "discnav");
- mp_input_disable_section(mpctx->input, "discnav-menu");
- pthread_mutex_destroy(&mpctx->nav_state->osd_lock);
- talloc_free(mpctx->nav_state);
- mpctx->nav_state = NULL;
- update_state(mpctx);
-}
-
-void mp_nav_user_input(struct MPContext *mpctx, char *command)
-{
- struct mp_nav_state *nav = mpctx->nav_state;
- if (!nav)
- return;
- if (strcmp(command, "mouse_move") == 0) {
- struct mp_image_params vid = {0};
- if (mpctx->d_video)
- vid = mpctx->d_video->decoder_output;
- struct mp_nav_cmd inp = {MP_NAV_CMD_MOUSE_POS};
- int x, y;
- mp_input_get_mouse_pos(mpctx->input, &x, &y);
- osd_coords_to_video(mpctx->osd, vid.w, vid.h, &x, &y);
- inp.u.mouse_pos.x = x;
- inp.u.mouse_pos.y = y;
- stream_control(mpctx->stream, STREAM_CTRL_NAV_CMD, &inp);
- } else {
- struct mp_nav_cmd inp = {MP_NAV_CMD_MENU};
- inp.u.menu.action = command;
- stream_control(mpctx->stream, STREAM_CTRL_NAV_CMD, &inp);
- }
-}
-
-void mp_handle_nav(struct MPContext *mpctx)
-{
- struct mp_nav_state *nav = mpctx->nav_state;
- if (!nav)
- return;
- while (1) {
- struct mp_nav_event *ev = NULL;
- stream_control(mpctx->stream, STREAM_CTRL_GET_NAV_EVENT, &ev);
- if (!ev)
- break;
- switch (ev->event) {
- case MP_NAV_EVENT_DRAIN: {
- nav->nav_draining = true;
- MP_VERBOSE(nav, "drain requested\n");
- break;
- }
- case MP_NAV_EVENT_RESET_ALL: {
- mpctx->stop_play = PT_RELOAD_DEMUXER;
- MP_VERBOSE(nav, "reload\n");
- // return immediately.
- // other events should be handled after reloaded.
- talloc_free(ev);
- return;
- }
- case MP_NAV_EVENT_RESET: {
- nav->nav_still_frame = 0;
- break;
- }
- case MP_NAV_EVENT_EOF:
- nav->nav_eof = true;
- break;
- case MP_NAV_EVENT_STILL_FRAME: {
- int len = ev->u.still_frame.seconds;
- MP_VERBOSE(nav, "wait for %d seconds\n", len);
- if (len > 0 && nav->nav_still_frame == 0)
- nav->nav_still_frame = len;
- break;
- }
- case MP_NAV_EVENT_MENU_MODE:
- nav->nav_menu = ev->u.menu_mode.enable;
- if (nav->nav_menu) {
- mp_input_enable_section(mpctx->input, "discnav-menu",
- MP_INPUT_ON_TOP);
- } else {
- mp_input_disable_section(mpctx->input, "discnav-menu");
- }
- update_state(mpctx);
- break;
- case MP_NAV_EVENT_HIGHLIGHT: {
- pthread_mutex_lock(&nav->osd_lock);
- MP_VERBOSE(nav, "highlight: %d %d %d - %d %d\n",
- ev->u.highlight.display,
- ev->u.highlight.sx, ev->u.highlight.sy,
- ev->u.highlight.ex, ev->u.highlight.ey);
- nav->highlight[0] = ev->u.highlight.sx;
- nav->highlight[1] = ev->u.highlight.sy;
- nav->highlight[2] = ev->u.highlight.ex;
- nav->highlight[3] = ev->u.highlight.ey;
- nav->hi_visible = ev->u.highlight.display;
- pthread_mutex_unlock(&nav->osd_lock);
- update_resolution(mpctx);
- osd_set_nav_highlight(mpctx->osd, mpctx);
- break;
- }
- case MP_NAV_EVENT_OVERLAY: {
- pthread_mutex_lock(&nav->osd_lock);
- for (int i = 0; i < 2; i++) {
- if (nav->overlays[i])
- talloc_free(nav->overlays[i]);
- nav->overlays[i] = talloc_steal(nav, ev->u.overlay.images[i]);
- }
- pthread_mutex_unlock(&nav->osd_lock);
- update_resolution(mpctx);
- osd_set_nav_highlight(mpctx->osd, mpctx);
- break;
- }
- default: ; // ignore
- }
- talloc_free(ev);
- }
- update_resolution(mpctx);
- if (mpctx->stop_play == AT_END_OF_FILE) {
- if (nav->nav_still_frame > 0) {
- // gross hack
- mpctx->time_frame += nav->nav_still_frame;
- mpctx->playing_last_frame = true;
- nav->nav_still_frame = -2;
- } else if (nav->nav_still_frame == -2) {
- struct mp_nav_cmd inp = {MP_NAV_CMD_SKIP_STILL};
- stream_control(mpctx->stream, STREAM_CTRL_NAV_CMD, &inp);
- }
- }
- if (nav->nav_draining && mpctx->stop_play == AT_END_OF_FILE) {
- MP_VERBOSE(nav, "execute drain\n");
- struct mp_nav_cmd inp = {MP_NAV_CMD_DRAIN_OK};
- stream_control(mpctx->stream, STREAM_CTRL_NAV_CMD, &inp);
- nav->nav_draining = false;
- stream_control(mpctx->stream, STREAM_CTRL_RESUME_CACHE, NULL);
- }
- // E.g. keep displaying still frames
- if (mpctx->stop_play == AT_END_OF_FILE && !nav->nav_eof)
- mpctx->stop_play = KEEP_PLAYING;
-}
-
-// Render "fake" highlights, because using actual dvd sub highlight elements
-// is too hard, and would require changes to libavcodec's dvdsub decoder.
-// Note: a proper solution would introduce something like
-// SD_CTRL_APPLY_DVDNAV, which would crop the vobsub frame,
-// and apply the current CLUT.
-void mp_nav_get_highlight(void *priv, struct mp_osd_res res,
- struct sub_bitmaps *out_imgs)
-{
- struct MPContext *mpctx = priv;
- struct mp_nav_state *nav = mpctx->nav_state;
-
- pthread_mutex_lock(&nav->osd_lock);
-
- struct sub_bitmap *sub = nav->hi_elem;
- if (!sub)
- sub = talloc_zero(nav, struct sub_bitmap);
-
- nav->hi_elem = sub;
- if (!is_valid_size(nav->vidsize)) {
- pthread_mutex_unlock(&nav->osd_lock);
- return;
- }
- int sizes[2] = {nav->vidsize[0], nav->vidsize[1]};
- if (sizes[0] != nav->subsize[0] || sizes[1] != nav->subsize[1]) {
- talloc_free(sub->bitmap);
- sub->bitmap = talloc_array(sub, uint32_t, sizes[0] * sizes[1]);
- memset(sub->bitmap, 0x80, talloc_get_size(sub->bitmap));
- nav->subsize[0] = sizes[0];
- nav->subsize[1] = sizes[1];
- }
-
- out_imgs->num_parts = 0;
-
- if (nav->hi_visible) {
- sub->x = nav->highlight[0];
- sub->y = nav->highlight[1];
- sub->w = MPCLAMP(nav->highlight[2] - sub->x, 0, sizes[0]);
- sub->h = MPCLAMP(nav->highlight[3] - sub->y, 0, sizes[1]);
- sub->stride = sub->w * 4;
- if (sub->w > 0 && sub->h > 0)
- nav->outputs[out_imgs->num_parts++] = *sub;
- }
-
- if (nav->overlays[0])
- nav->outputs[out_imgs->num_parts++] = *nav->overlays[0];
- if (nav->overlays[1])
- nav->outputs[out_imgs->num_parts++] = *nav->overlays[1];
-
- if (out_imgs->num_parts) {
- out_imgs->parts = nav->outputs;
- out_imgs->format = SUBBITMAP_RGBA;
- osd_rescale_bitmaps(out_imgs, sizes[0], sizes[1], res, -1);
- }
-
- pthread_mutex_unlock(&nav->osd_lock);
-}
diff --git a/player/loadfile.c b/player/loadfile.c
index e2a1e6e145..3f131d1df6 100644
--- a/player/loadfile.c
+++ b/player/loadfile.c
@@ -1050,9 +1050,6 @@ static void play_current_file(struct MPContext *mpctx)
goto terminate_playback;
}
- // Must be called before enabling cache.
- mp_nav_init(mpctx);
-
int res = stream_enable_cache(&mpctx->stream, &opts->stream_cache);
if (res == 0)
if (demux_was_interrupted(mpctx))
@@ -1062,8 +1059,6 @@ static void play_current_file(struct MPContext *mpctx)
goto_reopen_demuxer: ;
- mp_nav_reset(mpctx);
-
//============ Open DEMUXERS --- DETECT file type =======================
mpctx->audio_delay = opts->audio_delay;
@@ -1271,8 +1266,6 @@ goto_reopen_demuxer: ;
terminate_playback:
- mp_nav_destroy(mpctx);
-
if (mpctx->stop_play == KEEP_PLAYING)
mpctx->stop_play = AT_END_OF_FILE;
diff --git a/player/misc.c b/player/misc.c
index abaf5b208a..3da404f7ea 100644
--- a/player/misc.c
+++ b/player/misc.c
@@ -112,10 +112,6 @@ double get_start_time(struct MPContext *mpctx)
struct demuxer *demuxer = mpctx->demuxer;
if (!demuxer)
return 0;
- // We reload the demuxer on menu transitions; don't make it use the first
- // timestamp it finds as start PTS.
- if (mpctx->nav_state)
- return 0;
return demuxer->start_time;
}
diff --git a/player/playloop.c b/player/playloop.c
index 7e9b63995b..f992b0b064 100644
--- a/player/playloop.c
+++ b/player/playloop.c
@@ -1224,8 +1224,6 @@ void run_playloop(struct MPContext *mpctx)
mpctx->stop_play = AT_END_OF_FILE;
}
- mp_handle_nav(mpctx);
-
if (!mpctx->stop_play && !mpctx->restart_playback) {
// If no more video is available, one frame means one playloop iteration.
diff --git a/stream/cache.c b/stream/cache.c
index 197f7d3391..8c6a6a63dd 100644
--- a/stream/cache.c
+++ b/stream/cache.c
@@ -114,8 +114,6 @@ struct priv {
int stream_cache_idle;
int stream_cache_fill;
struct mp_tags *stream_metadata;
- char *disc_name;
- double start_pts;
};
enum {
@@ -171,7 +169,6 @@ static void cache_drop_contents(struct priv *s)
{
s->offset = s->min_filepos = s->max_filepos = s->read_filepos;
s->eof = false;
- s->start_pts = MP_NOPTS_VALUE;
}
// Copy at most dst_size from the cache at the given absolute file position pos.
@@ -271,14 +268,6 @@ static bool cache_fill(struct priv *s)
len = stream_read_partial(s->stream, &s->buffer[pos], space);
pthread_mutex_lock(&s->mutex);
- // Do this after reading a block, because at least libdvdnav updates the
- // stream position only after actually reading something after a seek.
- if (s->start_pts == MP_NOPTS_VALUE) {
- double pts;
- if (stream_control(s->stream, STREAM_CTRL_GET_CURRENT_TIME, &pts) > 0)
- s->start_pts = pts;
- }
-
s->max_filepos += len;
if (pos + len == s->buffer_size)
s->offset += s->buffer_size; // wrap...
@@ -356,7 +345,6 @@ static void update_cached_controls(struct priv *s)
int64_t i64;
double d;
struct mp_tags *tags;
- char *t;
s->stream_time_length = 0;
if (stream_control(s->stream, STREAM_CTRL_GET_TIME_LENGTH, &d) == STREAM_OK)
s->stream_time_length = d;
@@ -367,11 +355,6 @@ static void update_cached_controls(struct priv *s)
talloc_free(s->stream_metadata);
s->stream_metadata = talloc_steal(s, tags);
}
- if (stream_control(s->stream, STREAM_CTRL_GET_DISC_NAME, &t) == STREAM_OK)
- {
- talloc_free(s->disc_name);
- s->disc_name = talloc_steal(s, t);
- }
s->stream_size = -1;
if (stream_control(s->stream, STREAM_CTRL_GET_SIZE, &i64) == STREAM_OK)
s->stream_size = i64;
@@ -402,12 +385,6 @@ static int cache_get_cached_control(stream_t *cache, int cmd, void *arg)
case STREAM_CTRL_GET_NUM_CHAPTERS:
*(unsigned int *)arg = s->stream_num_chapters;
return STREAM_OK;
- case STREAM_CTRL_GET_CURRENT_TIME: {
- if (s->start_pts == MP_NOPTS_VALUE)
- return STREAM_UNSUPPORTED;
- *(double *)arg = s->start_pts;
- return STREAM_OK;
- }
case STREAM_CTRL_GET_METADATA: {
if (s->stream_metadata) {
ta_set_parent(s->stream_metadata, NULL);
@@ -417,12 +394,6 @@ static int cache_get_cached_control(stream_t *cache, int cmd, void *arg)
}
return STREAM_UNSUPPORTED;
}
- case STREAM_CTRL_GET_DISC_NAME: {
- if (!s->disc_name)
- return STREAM_UNSUPPORTED;
- *(char **)arg = talloc_strdup(NULL, s->disc_name);
- return STREAM_OK;
- }
case STREAM_CTRL_RESUME_CACHE:
s->idle = s->eof = false;
pthread_cond_signal(&s->wakeup);
@@ -435,7 +406,6 @@ static bool control_needs_flush(int stream_ctrl)
{
switch (stream_ctrl) {
case STREAM_CTRL_SEEK_TO_TIME:
- case STREAM_CTRL_SET_ANGLE:
case STREAM_CTRL_SET_CURRENT_TITLE:
return true;
}
diff --git a/stream/stream.c b/stream/stream.c
index d600088267..ba35e0f9ea 100644
--- a/stream/stream.c
+++ b/stream/stream.c
@@ -64,10 +64,6 @@ extern const stream_info_t stream_info_ffmpeg;
extern const stream_info_t stream_info_avdevice;
extern const stream_info_t stream_info_file;
extern const stream_info_t stream_info_ifo;
-extern const stream_info_t stream_info_dvd;
-extern const stream_info_t stream_info_dvdnav;
-extern const stream_info_t stream_info_bluray;
-extern const stream_info_t stream_info_bdnav;
extern const stream_info_t stream_info_rar_filter;
extern const stream_info_t stream_info_rar_entry;
extern const stream_info_t stream_info_edl;
@@ -90,17 +86,6 @@ static const stream_info_t *const stream_list[] = {
#if HAVE_LIBSMBCLIENT
&stream_info_smb,
#endif
-#if HAVE_DVDREAD
- &stream_info_ifo,
- &stream_info_dvd,
-#endif
-#if HAVE_DVDNAV
- &stream_info_dvdnav,
-#endif
-#if HAVE_LIBBLURAY
- &stream_info_bluray,
- &stream_info_bdnav,
-#endif
&stream_info_memory,
&stream_info_null,
diff --git a/stream/stream.h b/stream/stream.h
index 344e8b55ef..c49af132d8 100644
--- a/stream/stream.h
+++ b/stream/stream.h
@@ -33,8 +33,6 @@ enum streamtype {
STREAMTYPE_GENERIC = 0,
STREAMTYPE_FILE,
STREAMTYPE_DVB,
- STREAMTYPE_DVD,
- STREAMTYPE_BLURAY,
STREAMTYPE_TV,
STREAMTYPE_MF,
STREAMTYPE_EDL,
@@ -68,9 +66,6 @@ enum stream_ctrl {
STREAM_CTRL_SEEK_TO_TIME,
STREAM_CTRL_GET_SIZE,
STREAM_CTRL_GET_ASPECT_RATIO,
- STREAM_CTRL_GET_NUM_ANGLES,
- STREAM_CTRL_GET_ANGLE,
- STREAM_CTRL_SET_ANGLE,
STREAM_CTRL_GET_NUM_TITLES,
STREAM_CTRL_GET_LANG,
STREAM_CTRL_GET_CURRENT_TITLE,
@@ -82,13 +77,9 @@ enum stream_ctrl {
STREAM_CTRL_RESUME_CACHE,
STREAM_CTRL_RECONNECT,
STREAM_CTRL_GET_CHAPTER_TIME,
- STREAM_CTRL_GET_DVD_INFO,
STREAM_CTRL_SET_CONTENTS,
STREAM_CTRL_GET_METADATA,
STREAM_CTRL_GET_BASE_FILENAME,
- STREAM_CTRL_GET_NAV_EVENT, // struct mp_nav_event**
- STREAM_CTRL_NAV_CMD, // struct mp_nav_cmd*
- STREAM_CTRL_GET_DISC_NAME,
STREAM_CTRL_TV_SET_SCAN,
STREAM_CTRL_SET_TV_FREQ,
STREAM_CTRL_GET_TV_FREQ,
diff --git a/stream/stream_bluray.c b/stream/stream_bluray.c
deleted file mode 100644
index 686541b551..0000000000
--- a/stream/stream_bluray.c
+++ /dev/null
@@ -1,831 +0,0 @@
-/*
- * Copyright (C) 2010 Benjamin Zores <ben@geexbox.org>
- *
- * This file is part of MPlayer.
- *
- * MPlayer 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.
- *
- * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-/*
- * Blu-ray parser/reader using libbluray
- * Use 'git clone git://git.videolan.org/libbluray' to get it.
- *
- * TODO:
- * - Add descrambled keys database support (KEYDB.cfg)
- *
- */
-
-#include <string.h>
-#include <assert.h>
-
-#include <libbluray/bluray.h>
-#include <libbluray/meta_data.h>
-#include <libbluray/overlay.h>
-#include <libbluray/keys.h>
-#include <libbluray/bluray-version.h>
-#include <libavutil/common.h>
-
-#include "config.h"
-#include "talloc.h"
-#include "common/common.h"
-#include "common/msg.h"
-#include "options/m_option.h"
-#include "options/options.h"
-#include "stream.h"
-#include "osdep/timer.h"
-#include "discnav.h"
-#include "sub/osd.h"
-#include "sub/img_convert.h"
-#include "video/mp_image.h"
-#include "video/mp_image_pool.h"
-
-#define BLURAY_SECTOR_SIZE 6144
-
-#define BLURAY_DEFAULT_ANGLE 0
-#define BLURAY_DEFAULT_CHAPTER 0
-#define BLURAY_DEFAULT_TITLE -2
-#define BLURAY_MENU_TITLE -1
-
-// 90khz ticks
-#define BD_TIMEBASE (90000)
-#define BD_TIME_TO_MP(x) ((x) / (double)(BD_TIMEBASE))
-#define BD_TIME_FROM_MP(x) ((uint64_t)(x * BD_TIMEBASE))
-
-// copied from aacs.h in libaacs
-#define AACS_ERROR_CORRUPTED_DISC -1 /* opening or reading of AACS files failed */
-#define AACS_ERROR_NO_CONFIG -2 /* missing config file */
-#define AACS_ERROR_NO_PK -3 /* no matching processing key */
-#define AACS_ERROR_NO_CERT -4 /* no valid certificate */
-#define AACS_ERROR_CERT_REVOKED -5 /* certificate has been revoked */
-#define AACS_ERROR_MMC_OPEN -6 /* MMC open failed (no MMC drive ?) */
-#define AACS_ERROR_MMC_FAILURE -7 /* MMC failed */
-#define AACS_ERROR_NO_DK -8 /* no matching device key */
-
-struct bluray_overlay {
- struct sub_bitmap *image;
- bool clean, hidden;
- int x, y, w, h;
-};
-
-struct bluray_priv_s {
- BLURAY *bd;
- BLURAY_TITLE_INFO *title_info;
- int num_titles;
- int current_angle;
- int current_title;
- int current_playlist;
-
- int cfg_title;
- char *cfg_device;
-
- // overlay stuffs
- struct bluray_overlay overlays[2], ol_flushed[2];
- struct mp_image_pool *pool;
-
- // navigation stuffs
- uint64_t next_event;
- uint32_t still_length;
- int mousex, mousey;
- bool in_menu, use_nav, nav_enabled, popup_enabled;
-};
-
-static const struct bluray_priv_s bluray_stream_priv_dflts = {
- .cfg_title = BLURAY_DEFAULT_TITLE,
-};
-
-static const struct bluray_priv_s bdnav_stream_priv_dflts = {
- .cfg_title = BLURAY_DEFAULT_TITLE,
- .use_nav = true,
-};
-
-#define OPT_BASE_STRUCT struct bluray_priv_s
-static const m_option_t bluray_stream_opts_fields[] = {
- OPT_CHOICE_OR_INT("title", cfg_title, 0, 0, 99999,
- ({"longest", BLURAY_DEFAULT_TITLE})),
- OPT_STRING("device", cfg_device, 0),
- {0}
-};
-
-static const m_option_t bdnav_stream_opts_fields[] = {
- OPT_CHOICE_OR_INT("title", cfg_title, 0, 0, 99999,
- ({"menu", BLURAY_MENU_TITLE},
- {"first", BLURAY_DEFAULT_TITLE})),
- OPT_STRING("device", cfg_device, 0),
- {0}
-};
-
-static void destruct(struct bluray_priv_s *priv)
-{
- if (priv->title_info)
- bd_free_title_info(priv->title_info);
- bd_close(priv->bd);
- talloc_free(priv->pool);
-}
-
-inline static int play_title(struct bluray_priv_s *priv, int title)
-{
- if (priv->use_nav) {
- if (title == priv->num_titles - 1)
- title = BLURAY_TITLE_FIRST_PLAY;
- return bd_play_title(priv->bd, title);
- } else
- return bd_select_title(priv->bd, title);
-}
-
-static void overlay_release(struct bluray_overlay *overlay)
-{
- if (overlay->image)
- talloc_free(overlay->image);
- *overlay = (struct bluray_overlay) { .clean = true };
-}
-
-static void overlay_alloc(struct bluray_priv_s *priv,
- struct bluray_overlay *overlay,
- int x, int y, int w, int h)
-{
- assert(overlay->image == NULL);
- struct sub_bitmap *image = talloc_zero(NULL, struct sub_bitmap);
- overlay->w = image->w = image->dw = w;
- overlay->h = image->h = image->dh = h;
- overlay->x = image->x = x;
- overlay->y = image->y = y;
- struct mp_image *mpi = mp_image_pool_get(priv->pool, IMGFMT_RGBA, w, h);
- mpi = talloc_steal(image, mpi);
- assert(image->w > 0 && image->h > 0 && mpi != NULL);
- image->stride = mpi->stride[0];
- image->bitmap = mpi->planes[0];
- overlay->image = image;
- overlay->clean = true;
- overlay->hidden = false;
-}
-
-static void overlay_close_all(struct bluray_priv_s *priv)
-{
- for (int i = 0; i < 2; i++)
- overlay_release(&priv->overlays[i]);
-}
-
-static void overlay_close(struct bluray_priv_s *priv,
- const BD_OVERLAY *const bo)
-{
- overlay_release(&priv->overlays[bo->plane]);
-}
-
-static inline uint32_t conv_rgba(const BD_PG_PALETTE_ENTRY *p)
-{
- uint32_t rgba;
- uint8_t *out = (uint8_t*)&rgba;
- const int y = p->Y, cb = (int)p->Cb - 128, cr = (int)p->Cr - 128;
- // CAUTION: inaccurate but fast, broken in big endian
-#define CONV(a) (MPCLAMP((a), 0, 255)*p->T >> 8)
- out[0] = CONV(y + cb + (cb >> 1) + (cb >> 2) + (cb >> 6));
- out[1] = CONV(y - ((cb >> 2) + (cb >> 4) + (cb >> 5))
- - ((cr >> 3) + (cr >> 4) + (cr >> 5)));
- out[2] = CONV(y + cr + (cr >> 2) + (cr >> 3) + (cr >> 5));
- out[3] = p->T;
-#undef CONV
- return rgba;
-}
-
-static void overlay_process(void *data, const BD_OVERLAY *const bo)
-{
- stream_t *s = data;
- struct bluray_priv_s *priv = s->priv;
- if (!bo) {
- overlay_close_all(priv);
- return;
- }
- struct bluray_overlay *overlay = &priv->overlays[bo->plane];
- switch (bo->cmd) {
- case BD_OVERLAY_INIT:
- overlay_alloc(priv, overlay, bo->x, bo->y, bo->w, bo->h);
- break;
- case BD_OVERLAY_CLOSE:
- overlay_close(priv, bo);
- break;
- case BD_OVERLAY_CLEAR:
- if (!overlay->clean) {
- memset(overlay->image->bitmap, 0,
- overlay->image->stride*overlay->h);
- overlay->clean = true;
- }
- break;
- case BD_OVERLAY_DRAW: {
- if (!bo->img)
- break;
- overlay->hidden = false;
- overlay->clean = false;
- struct sub_bitmap *img = overlay->image;
- uint32_t *const origin = img->bitmap;
- const BD_PG_RLE_ELEM *in = bo->img;
- for (int y = 0; y < bo->h; y++) {
- uint32_t *out = origin + (img->stride/4) * (y + bo->y) + bo->x;
- for (int x = 0; x < bo->w; ) {
- uint32_t c = 0;
- if (bo->palette[in->color].T) {
- c = conv_rgba(&bo->palette[in->color]);
- for (int i = 0; i < in->len; i++)
- *out++ = c;
- } else {
- memset(out, 0, in->len*4);
- out += in->len;
- }
- x += in->len;
- ++in;
- }
- }
- break;
- }
- case BD_OVERLAY_WIPE: {
- uint32_t *const origin = overlay->image->bitmap;
- for (int y = 0; y < bo->h; y++)
- memset(origin + overlay->w * (y + bo->y) + bo->x, 0, 4 * bo->w);
- break;
- }
- case BD_OVERLAY_HIDE:
- priv->overlays[bo->plane].hidden = true;
- break;
- case BD_OVERLAY_FLUSH: {
- struct bluray_overlay *in = overlay;
- struct bluray_overlay *out = &priv->ol_flushed[bo->plane];
- if (out->image && (out->image->stride != in->image->stride ||
- out->image->h != in->image->h))
- overlay_release(out);
- if (!out->image)
- overlay_alloc(priv, out, in->x, in->y, in->w, in->h);
- const int len = in->image->stride*in->image->h;
- memcpy(out->image->bitmap, in->image->bitmap, len);
- out->clean = in->clean;
- out->hidden = in->hidden;
- priv->next_event |= 1 << MP_NAV_EVENT_OVERLAY;
- break;
- } default:
- break;
- }
-}
-
-static inline bool set_event_type(struct bluray_priv_s *priv, int type,
- struct mp_nav_event *event)
-{
- if (!(priv->next_event & (1 << type)))
- return false;
- priv->next_event &= ~(1 << type);
- event->event = type;
- return true;
-}
-
-static void fill_next_event(stream_t *s, struct mp_nav_event **ret)
-{
- struct bluray_priv_s *priv = s->priv;
- struct mp_nav_event e = {0};
- // this should be checked before any other events
- if (!set_event_type(priv, MP_NAV_EVENT_RESET_ALL, &e))
- for (int n = 0; n < 30 && !set_event_type(priv, n, &e); n++) ;
- switch (e.event) {
- case MP_NAV_EVENT_NONE:
- return;
- case MP_NAV_EVENT_OVERLAY: {
- for (int i = 0; i < 2; i++) {
- struct bluray_overlay *o = &priv->ol_flushed[i];
- e.u.overlay.images[i] = NULL;
- if (!o->clean && !o->hidden) {
- e.u.overlay.images[i] = o->image;
- o->image = NULL;
- }
- }
- break;
- }
- case MP_NAV_EVENT_MENU_MODE:
- e.u.menu_mode.enable = priv->in_menu;
- break;
- case MP_NAV_EVENT_STILL_FRAME:
- e.u.still_frame.seconds = priv->still_length;
- break;
- }
- *ret = talloc(NULL, struct mp_nav_event);
- **ret = e;
-}
-
-static void bluray_stream_close(stream_t *s)
-{
- destruct(s->priv);
-}
-
-static void handle_event(stream_t *s, const BD_EVENT *ev)
-{
- static const int reset_flags = (1 << MP_NAV_EVENT_RESET_ALL)
- | (1 << MP_NAV_EVENT_RESET);
- struct bluray_priv_s *b = s->priv;
- switch (ev->event) {
- case BD_EVENT_MENU:
- b->in_menu = ev->param;
- b->next_event |= 1 << MP_NAV_EVENT_MENU_MODE;
- break;
- case BD_EVENT_STILL:
- b->still_length = ev->param ? -1 : 0;
- if (b->nav_enabled)
- b->next_event |= 1 << MP_NAV_EVENT_STILL_FRAME;
- break;
- case BD_EVENT_STILL_TIME:
- b->still_length = ev->param ? -1 : ev->param*1000;
- if (b->nav_enabled)
- b->next_event |= 1 << MP_NAV_EVENT_STILL_FRAME;
- else
- bd_read_skip_still(b->bd);
- break;
- case BD_EVENT_END_OF_TITLE:
- overlay_close_all(b);
- break;
- case BD_EVENT_PLAYLIST:
- b->next_event = reset_flags;
- b->current_playlist = ev->param;
- if (!b->use_nav)
- b->current_title = bd_get_current_title(b->bd);
- if (b->title_info)
- bd_free_title_info(b->title_info);
- b->title_info = bd_get_playlist_info(b->bd, b->current_playlist,
- b->current_angle);
- break;
- case BD_EVENT_TITLE:
- b->next_event = reset_flags;
- if (ev->param == BLURAY_TITLE_FIRST_PLAY) {
- if (b->use_nav)
- b->current_title = b->num_titles - 1;
- else
- b->current_title = bd_get_current_title(b->bd);
- } else
- b->current_title = ev->param;
- if (b->title_info) {
- bd_free_title_info(b->title_info);
- b->title_info = NULL;
- }
- break;
- case BD_EVENT_ANGLE:
- b->current_angle = ev->param;
- if (b->title_info) {
- bd_free_title_info(b->title_info);
- b->title_info = bd_get_playlist_info(b->bd, b->current_playlist,
- b->current_angle);
- }
- break;
- case BD_EVENT_POPUP:
- b->popup_enabled = ev->param;
- break;
-#if BLURAY_VERSION >= BLURAY_VERSION_CODE(0, 5, 0)
- case BD_EVENT_DISCONTINUITY:
- b->next_event = reset_flags;
- break;
-#endif
- default:
- MP_TRACE(s, "Unhandled event: %d %d\n", ev->event, ev->param);
- break;
- }
-}
-
-static int bluray_stream_fill_buffer(stream_t *s, char *buf, int len)
-{
- struct bluray_priv_s *b = s->priv;
- assert(!b->use_nav);
- BD_EVENT event;
- while (bd_get_event(b->bd, &event))
- handle_event(s, &event);
- return bd_read(b->bd, buf, len);
-}
-
-static int bdnav_stream_fill_buffer(stream_t *s, char *buf, int len)
-{
- struct bluray_priv_s *b = s->priv;
- assert(b->use_nav);
- BD_EVENT event;
- int read = -1;
- for (;;) {
- read = bd_read_ext(b->bd, buf, len, &event);
- if (read < 0)
- return read;
- if (read == 0) {
- if (event.event == BD_EVENT_NONE)
- return 0; // end of stream
- handle_event(s, &event);
- } else
- break;
- }
- return read;
-}
-
-static bd_vk_key_e translate_nav_menu_action(const char *cmd)
-{
- if (strcmp(cmd, "mouse") == 0)
- return BD_VK_MOUSE_ACTIVATE;
- if (strcmp(cmd, "up") == 0)
- return BD_VK_UP;
- if (strcmp(cmd, "down") == 0)
- return BD_VK_DOWN;
- if (strcmp(cmd, "left") == 0)
- return BD_VK_LEFT;
- if (strcmp(cmd, "right") == 0)
- return BD_VK_RIGHT;
- if (strcmp(cmd, "select") == 0)
- return BD_VK_ENTER;
- return BD_VK_NONE;
-}
-
-static void handle_nav_command(stream_t *s, struct mp_nav_cmd *ev)
-{
- struct bluray_priv_s *priv = s->priv;
- switch (ev->event) {
- case MP_NAV_CMD_ENABLE:
- priv->nav_enabled = true;
- break;
- case MP_NAV_CMD_MENU: {
- const int64_t pts = mp_time_us();
- const char *action = ev->u.menu.action;
- bd_vk_key_e key = translate_nav_menu_action(action);
- if (key != BD_VK_NONE) {
- if (key == BD_VK_MOUSE_ACTIVATE)
- bd_mouse_select(priv->bd, pts, priv->mousex, priv->mousey);
- bd_user_input(priv->bd, pts, key);
- } else if (strcmp(action, "menu") == 0) {
- if (priv->popup_enabled)
- bd_user_input(priv->bd, pts, BD_VK_POPUP);
- else
- bd_menu_call(priv->bd, pts);
- }
- break;
- } case MP_NAV_CMD_MOUSE_POS:
- priv->mousex = ev->u.mouse_pos.x;
- priv->mousey = ev->u.mouse_pos.y;
- bd_mouse_select(priv->bd, mp_time_us(), priv->mousex, priv->mousey);
- break;
- case MP_NAV_CMD_SKIP_STILL:
- bd_read_skip_still(priv->bd);
- break;
- }
-}
-
-static int bluray_stream_control(stream_t *s, int cmd, void *arg)
-{
- struct bluray_priv_s *b = s->priv;
-
- switch (cmd) {
- case STREAM_CTRL_GET_NUM_CHAPTERS: {
- const BLURAY_TITLE_INFO *ti = b->title_info;
- if (!ti)
- return STREAM_UNSUPPORTED;
- *((unsigned int *) arg) = ti->chapter_count;
- return STREAM_OK;
- }
- case STREAM_CTRL_GET_CHAPTER_TIME: {
- const BLURAY_TITLE_INFO *ti = b->title_info;
- if (!ti)
- return STREAM_UNSUPPORTED;
- int chapter = *(double *)arg;
- double time = MP_NOPTS_VALUE;
- if (chapter >= 0 || chapter < ti->chapter_count)
- time = BD_TIME_TO_MP(ti->chapters[chapter].start);
- if (time == MP_NOPTS_VALUE)
- return STREAM_ERROR;
- *(double *)arg = time;
- return STREAM_OK;
- }
- case STREAM_CTRL_SET_CURRENT_TITLE: {
- const uint32_t title = *((unsigned int*)arg);
- if (title >= b->num_titles || !play_title(b, title))
- return STREAM_UNSUPPORTED;
- b->current_title = title;
- return STREAM_OK;
- }
- case STREAM_CTRL_GET_CURRENT_TITLE: {
- *((unsigned int *) arg) = b->current_title;
- return STREAM_OK;
- }
- case STREAM_CTRL_GET_NUM_TITLES: {
- *((unsigned int *)arg) = b->num_titles;
- return STREAM_OK;
- }
- case STREAM_CTRL_GET_TIME_LENGTH: {
- const BLURAY_TITLE_INFO *ti = b->title_info;
- if (!ti)
- return STREAM_UNSUPPORTED;
- *((double *) arg) = BD_TIME_TO_MP(ti->duration);
- return STREAM_OK;
- }
- case STREAM_CTRL_GET_CURRENT_TIME: {
- *((double *) arg) = BD_TIME_TO_MP(bd_tell_time(b->bd));
- return STREAM_OK;
- }
- case STREAM_CTRL_SEEK_TO_TIME: {
- double pts = *((double *) arg);
- bd_seek_time(b->bd, BD_TIME_FROM_MP(pts));
- stream_drop_buffers(s);
- // API makes it hard to determine seeking success
- return STREAM_OK;
- }
- case STREAM_CTRL_GET_NUM_ANGLES: {
- const BLURAY_TITLE_INFO *ti = b->title_info;
- if (!ti)
- return STREAM_UNSUPPORTED;
- *((int *) arg) = ti->angle_count;
- return STREAM_OK;
- }
- case STREAM_CTRL_GET_ANGLE: {
- *((int *) arg) = b->current_angle;
- return STREAM_OK;
- }
- case STREAM_CTRL_SET_ANGLE: {
- const BLURAY_TITLE_INFO *ti = b->title_info;
- if (!ti)
- return STREAM_UNSUPPORTED;
- int angle = *((int *) arg);
- if (angle < 0 || angle > ti->angle_count)
- return STREAM_UNSUPPORTED;
- b->current_angle = angle;
- bd_seamless_angle_change(b->bd, angle);
- return STREAM_OK;
- }
- case STREAM_CTRL_GET_LANG: {
- const BLURAY_TITLE_INFO *ti = b->title_info;
- if (ti && ti->clip_count) {
- struct stream_lang_req *req = arg;
- BLURAY_STREAM_INFO *si = NULL;
- int count = 0;
- switch (req->type) {
- case STREAM_AUDIO:
- count = ti->clips[0].audio_stream_count;
- si = ti->clips[0].audio_streams;
- break;
- case STREAM_SUB:
- count = ti->clips[0].pg_stream_count;
- si = ti->clips[0].pg_streams;
- break;
- }
- for (int n = 0; n < count; n++) {
- BLURAY_STREAM_INFO *i = &si[n];
- if (i->pid == req->id) {
- snprintf(req->name, sizeof(req->name), "%.4s", i->lang);
- return STREAM_OK;
- }
- }
- }
- return STREAM_ERROR;
- }
- 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])
- break;
- *(char**)arg = talloc_strdup(NULL, meta->di_name);
- return STREAM_OK;
- }
- case STREAM_CTRL_NAV_CMD:
- if (!b->use_nav)
- return STREAM_UNSUPPORTED;
- handle_nav_command(s, arg);
- return STREAM_OK;
- case STREAM_CTRL_GET_NAV_EVENT: {
- struct mp_nav_event **ev = arg;
- if (ev)
- fill_next_event(s, ev);
- return STREAM_OK;
- }
- default:
- break;
- }
-
- return STREAM_UNSUPPORTED;
-}
-
-static const char *aacs_strerr(int err)
-{
- switch (err) {
- case AACS_ERROR_CORRUPTED_DISC: return "opening or reading of AACS files failed";
- case AACS_ERROR_NO_CONFIG: return "missing config file";
- case AACS_ERROR_NO_PK: return "no matching processing key";
- case AACS_ERROR_NO_CERT: return "no valid certificate";
- case AACS_ERROR_CERT_REVOKED: return "certificate has been revoked";
- case AACS_ERROR_MMC_OPEN: return "MMC open failed (maybe no MMC drive?)";
- case AACS_ERROR_MMC_FAILURE: return "MMC failed";
- case AACS_ERROR_NO_DK: return "no matching device key";
- default: return "unknown error";
- }
-}
-
-static bool check_disc_info(stream_t *s)
-{
- struct bluray_priv_s *b = s->priv;
- const BLURAY_DISC_INFO *info = bd_get_disc_info(b->bd);
-
- // check Blu-ray
- if (!info->bluray_detected) {
- MP_ERR(s, "Given stream is not a Blu-ray.\n");
- return false;
- }
-
- // check AACS
- if (info->aacs_detected) {
- if (!info->libaacs_detected) {
- MP_ERR(s, "AACS encryption detected but cannot find libaacs.\n");
- return false;
- }
- if (!info->aacs_handled) {
- MP_ERR(s, "AACS error: %s\n", aacs_strerr(info->aacs_error_code));
- return false;
- }
- }
-
- // check BD+
- if (info->bdplus_detected) {
- if (!info->libbdplus_detected) {
- MP_ERR(s, "BD+ encryption detected but cannot find libbdplus.\n");
- return false;
- }
- if (!info->bdplus_handled) {
- MP_ERR(s, "Cannot decrypt BD+ encryption.\n");
- return false;
- }
- }
-
- return true;
-}
-
-static void select_initial_title(stream_t *s, int title_guess) {
- struct bluray_priv_s *b = s->priv;
-
- int title = -1;
- if (b->use_nav) {
- if (b->cfg_title == BLURAY_MENU_TITLE)
- title = 0; // BLURAY_TITLE_TOP_MENU
- else if (b->cfg_title == BLURAY_DEFAULT_TITLE)
- title = b->num_titles - 1;
- else
- title = b->cfg_title;
- } else {
- if (b->cfg_title != BLURAY_DEFAULT_TITLE )
- title = b->cfg_title;
- else
- title = title_guess;
- }
- if (title < 0)
- return;
-
- if (play_title(b, title))
- b->current_title = title;
- else {
- MP_WARN(s, "Couldn't start title '%d'.\n", title);
- if (!b->use_nav) // cannot query title info in nav
- b->current_title = bd_get_current_title(b->bd);
- }
-}
-
-static void select_initial_angle(stream_t *s) {
- struct bluray_priv_s *b = s->priv;
- if (!b->use_nav) // no way to figure out current title info
- return;
- BLURAY_TITLE_INFO *info = bd_get_title_info(b->bd, b->current_title, 0);
- if (!info)
- return;
- /* Select angle */
- unsigned int angle = s->opts->bluray_angle;
- if (!angle)
- angle = BLURAY_DEFAULT_ANGLE;
- angle = FFMIN(angle, info->angle_count);
- if (angle)
- bd_select_angle(b->bd, angle);
- b->current_angle = bd_get_current_angle(b->bd);
- bd_free_title_info(info);
-}
-
-static int bluray_stream_open(stream_t *s)
-{
- struct bluray_priv_s *b = s->priv;
-
- const char *device = NULL;
- /* find the requested device */
- if (b->cfg_device && b->cfg_device[0])
- device = b->cfg_device;
- else if (s->opts->bluray_device && s->opts->bluray_device[0])
- device = s->opts->bluray_device;
-
- if (!device) {
- MP_ERR(s, "No Blu-ray device/location was specified ...\n");
- return STREAM_UNSUPPORTED;
- }
-
- /* open device */
- BLURAY *bd = bd_open(device, NULL);
- if (!bd) {
- MP_ERR(s, "Couldn't open Blu-ray device: %s\n", device);
- return STREAM_UNSUPPORTED;
- }
- b->bd = bd;
-
- if (!check_disc_info(s)) {
- destruct(b);
- return STREAM_UNSUPPORTED;
- }
-
- int title_guess = BLURAY_DEFAULT_TITLE;
- if (b->use_nav) {
- const BLURAY_DISC_INFO *disc_info = bd_get_disc_info(b->bd);
- b->num_titles = disc_info->num_hdmv_titles + disc_info->num_bdj_titles;
- ++b->num_titles; // for BLURAY_TITLE_TOP_MENU
- ++b->num_titles; // for BLURAY_TITLE_FIRST_PLAY
- } else {
- /* check for available titles on disc */
- b->num_titles = bd_get_titles(bd, TITLES_RELEVANT, 0);
- if (!b->num_titles) {
- MP_ERR(s, "Can't find any Blu-ray-compatible title here.\n");
- destruct(b);
- return STREAM_UNSUPPORTED;
- }
-
- /* parse titles information */
- uint64_t max_duration = 0;
- for (int i = 0; i < b->num_titles; i++) {
- BLURAY_TITLE_INFO *ti = bd_get_title_info(bd, i, 0);
- if (!ti)
- continue;
-
- /* try to guess which title may contain the main movie */
- if (ti->duration > max_duration) {
- max_duration = ti->duration;
- title_guess = i;
- }
-
- bd_free_title_info(ti);
- }
- }
-
- // these should be set before any callback
- b->pool = mp_image_pool_new(6);
- b->current_angle = -1;
- b->current_title = -1;
-
- // initialize libbluray event queue
- bd_get_event(bd, NULL);
-
- if (b->use_nav) {
- if (!bd_play(bd)) {
- destruct(b);
- return STREAM_ERROR;
- }
- bd_register_overlay_proc(bd, s, overlay_process);
- }
-
- select_initial_title(s, title_guess);
- select_initial_angle(s);
-
- if (b->use_nav)
- s->fill_buffer = bdnav_stream_fill_buffer;
- else
- s->fill_buffer = bluray_stream_fill_buffer;
- s->close = bluray_stream_close;
- s->control = bluray_stream_control;
- s->type = STREAMTYPE_BLURAY;
- 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");
-
- return STREAM_OK;
-}
-
-const stream_info_t stream_info_bluray = {
- .name = "bd",
- .open = bluray_stream_open,
- .protocols = (const char*const[]){ "bd", "br", "bluray", NULL },
- .priv_defaults = &bluray_stream_priv_dflts,
- .priv_size = sizeof(struct bluray_priv_s),
- .options = bluray_stream_opts_fields,
- .url_options = (const char*const[]){
- "hostname=title",
- "filename=device",
- NULL
- },
-};
-
-const stream_info_t stream_info_bdnav = {
- .name = "bdnav",
- .open = bluray_stream_open,
- .protocols = (const char*const[]){ "bdnav", "brnav", "bluraynav", NULL },
- .priv_defaults = &bdnav_stream_priv_dflts,
- .priv_size = sizeof(struct bluray_priv_s),
- .options = bdnav_stream_opts_fields,
- .url_options = (const char*const[]){
- "hostname=title",
- "filename=device",
- NULL
- },
-};
diff --git a/stream/stream_dvd.c b/stream/stream_dvd.c
deleted file mode 100644
index 857d144a65..0000000000
--- a/stream/stream_dvd.c
+++ /dev/null
@@ -1,968 +0,0 @@
-/*
- * This file is part of MPlayer.
- *
- * Original author: Benjamin Zores
- *
- * MPlayer 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.
- *
- * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <string.h>
-#include <strings.h>
-#include <libgen.h>
-#include <errno.h>
-#include <stdint.h>
-
-#include <dvdread/dvd_reader.h>
-#include <dvdread/ifo_types.h>
-#include <dvdread/ifo_read.h>
-#include <dvdread/nav_read.h>
-
-#include "config.h"
-#include "talloc.h"
-#include "common/common.h"
-#include "common/msg.h"
-
-#define FIRST_AC3_AID 128
-#define FIRST_DTS_AID 136
-#define FIRST_MPG_AID 0
-#define FIRST_PCM_AID 160
-
-#include "stream.h"
-#include "options/m_option.h"
-#include "options/options.h"
-
-#include "stream_dvd_common.h"
-
-#define LIBDVDREAD_VERSION(maj,min,micro) ((maj)*10000 + (min)*100 + (micro))
-/*
- * Try to autodetect the libdvd-0.9.0 library
- * (0.9.0 removed the <dvdread/dvd_udf.h> header, and moved the two defines
- * DVD_VIDEO_LB_LEN and MAX_UDF_FILE_NAME_LEN from it to
- * <dvdread/dvd_reader.h>)
- */
-#ifndef DVDREAD_VERSION
-#if defined(DVD_VIDEO_LB_LEN) && defined(MAX_UDF_FILE_NAME_LEN)
-#define DVDREAD_VERSION LIBDVDREAD_VERSION(0,9,0)
-#else
-#define DVDREAD_VERSION LIBDVDREAD_VERSION(0,8,0)
-#endif
-#endif
-
-typedef struct {
- int id; // 0 - 31 mpeg; 128 - 159 ac3; 160 - 191 pcm
- int language;
- int type;
- int channels;
-} stream_language_t;
-
-typedef struct {
- dvd_reader_t *dvd;
- dvd_file_t *title;
- ifo_handle_t *vmg_file;
- tt_srpt_t *tt_srpt;
- ifo_handle_t *vts_file;
- vts_ptt_srpt_t *vts_ptt_srpt;
- pgc_t *cur_pgc;
-//
- int cur_title;
- int cur_cell;
- int last_cell;
- int cur_pack;
- int cell_last_pack;
- int cur_pgc_idx;
-// Navi:
- int packs_left;
- dsi_t dsi_pack;
- int angle_seek;
- unsigned int *cell_times_table;
-// audio datas
- int nr_of_channels;
- stream_language_t audio_streams[32];
-// subtitles
- int nr_of_subtitles;
- stream_language_t subtitles[32];
-
- int dvd_angle;
- char *dvd_device_current;
- int dvd_speed;
- int dvd_title;
-
- int cfg_title;
- char *cfg_device;
-} dvd_priv_t;
-
-static const dvd_priv_t stream_priv_dflts = {
- .cfg_title = 0,
-};
-
-#define OPT_BASE_STRUCT dvd_priv_t
-/// URL definition
-static const m_option_t stream_opts_fields[] = {
- OPT_INTRANGE("title", cfg_title, 0, 0, 99),
- OPT_STRING("device", cfg_device, 0),
- {0}
-};
-
-static int dvd_lang_from_aid(stream_t *stream, int id) {
- dvd_priv_t *d;
- int i;
- if (!stream) return 0;
- d = stream->priv;
- if (!d) return 0;
- for(i=0;i<d->nr_of_channels;i++) {
- if(d->audio_streams[i].id==id)
- return d->audio_streams[i].language;
- }
- return 0;
-}
-
-static int dvd_number_of_subs(stream_t *stream) {
- int i;
- int maxid = -1;
- dvd_priv_t *d;
- if (!stream) return -1;
- d = stream->priv;
- if (!d) return -1;
- for (i = 0; i < d->nr_of_subtitles; i++)
- if (d->subtitles[i].id > maxid) maxid = d->subtitles[i].id;
- return maxid + 1;
-}
-
-static int dvd_lang_from_sid(stream_t *stream, int id) {
- int i;
- dvd_priv_t *d;
- if (!stream) return 0;
- d = stream->priv;
- if (!d) return 0;
- for (i = 0; i < d->nr_of_subtitles; i++)
- if (d->subtitles[i].id == id && d->subtitles[i].language) return d->subtitles[i].language;
- return 0;
-}
-
-static int dvd_next_cell(stream_t *stream, dvd_priv_t *d) {
- int next_cell=d->cur_cell;
-
- MP_DBG(stream, "dvd_next_cell: next1=0x%X \n",next_cell);
- if( d->cur_pgc->cell_playback[ next_cell ].block_type == BLOCK_TYPE_ANGLE_BLOCK ) {
- while(next_cell<d->last_cell) {
- if( d->cur_pgc->cell_playback[next_cell].block_mode == BLOCK_MODE_LAST_CELL )
- break;
- ++next_cell;
- }
- }
- MP_DBG(stream, "dvd_next_cell: next2=0x%X \n",next_cell);
-
- ++next_cell;
- if(next_cell>=d->last_cell)
- return -1; // EOF
- if(d->cur_pgc->cell_playback[next_cell].block_type == BLOCK_TYPE_ANGLE_BLOCK ) {
- next_cell+=d->dvd_angle-1;
- if(next_cell>=d->last_cell)
- return -1; // EOF
- }
- MP_DBG(stream, "dvd_next_cell: next3=0x%X \n",next_cell);
- return next_cell;
-}
-
-static int dvd_read_sector(stream_t *stream, dvd_priv_t *d, unsigned char *data)
-{
- int len;
-
- if(d->packs_left==0) {
- /**
- * If we're not at the end of this cell, we can determine the next
- * VOBU to display using the VOBU_SRI information section of the
- * DSI. Using this value correctly follows the current angle,
- * avoiding the doubled scenes in The Matrix, and makes our life
- * really happy.
- *
- * Otherwise, we set our next address past the end of this cell to
- * force the code above to go to the next cell in the program.
- */
- if(d->dsi_pack.vobu_sri.next_vobu != SRI_END_OF_CELL) {
- d->cur_pack= d->dsi_pack.dsi_gi.nv_pck_lbn + ( d->dsi_pack.vobu_sri.next_vobu & 0x7fffffff );
- MP_DBG(stream, "Navi new pos=0x%X \n",d->cur_pack);
- } else {
- // end of cell! find next cell!
- MP_VERBOSE(stream, "--- END OF CELL !!! ---\n");
- d->cur_pack=d->cell_last_pack+1;
- }
- }
-
-read_next:
- if(d->cur_pack>d->cell_last_pack) {
- // end of cell!
- int next=dvd_next_cell(stream, d);
- if(next>=0) {
- d->cur_cell=next;
- // if( d->cur_pgc->cell_playback[d->cur_cell].block_type
- // == BLOCK_TYPE_ANGLE_BLOCK ) d->cur_cell+=dvd_angle-1;
- d->cur_pack = d->cur_pgc->cell_playback[ d->cur_cell ].first_sector;
- d->cell_last_pack=d->cur_pgc->cell_playback[ d->cur_cell ].last_sector;
- MP_VERBOSE(stream, "DVD next cell: %d pack: 0x%X-0x%X \n",d->cur_cell,d->cur_pack,d->cell_last_pack);
- } else
- return -1; // EOF
- }
-
- len = DVDReadBlocks(d->title, d->cur_pack, 1, data);
- // only == 0 should indicate an error, but some dvdread version are buggy when used with dvdcss
- if(len <= 0) return -1; //error
-
- if(data[38]==0 && data[39]==0 && data[40]==1 && data[41]==0xBF &&
- data[1024]==0 && data[1025]==0 && data[1026]==1 && data[1027]==0xBF) {
- // found a Navi packet!!!
-#if DVDREAD_VERSION >= LIBDVDREAD_VERSION(0,9,0)
- navRead_DSI(&d->dsi_pack, &(data[ DSI_START_BYTE ]));
-#else
- navRead_DSI(&d->dsi_pack, &(data[ DSI_START_BYTE ]), sizeof(dsi_t));
-#endif
- if(d->cur_pack != d->dsi_pack.dsi_gi.nv_pck_lbn ) {
- MP_VERBOSE(stream, "Invalid NAVI packet! lba=0x%X navi=0x%X \n",
- d->cur_pack,d->dsi_pack.dsi_gi.nv_pck_lbn);
- } else {
- // process!
- d->packs_left = d->dsi_pack.dsi_gi.vobu_ea;
- MP_DBG(stream, "Found NAVI packet! lba=0x%X len=%d \n",d->cur_pack,d->packs_left);
- //navPrint_DSI(&d->dsi_pack);
- MP_TRACE(stream, "\r### CELL %d: Navi: %d/%d IFO: %d/%d \n",d->cur_cell,
- d->dsi_pack.dsi_gi.vobu_c_idn,d->dsi_pack.dsi_gi.vobu_vob_idn,
- d->cur_pgc->cell_position[d->cur_cell].cell_nr,
- d->cur_pgc->cell_position[d->cur_cell].vob_id_nr);
-
- if(d->angle_seek) {
- int i,skip=0;
- for(i=0;i<9;i++) // check if all values zero:
- if((skip=d->dsi_pack.sml_agli.data[i].address)!=0) break;
- if(skip && skip!=0x7fffffff) {
- // sml_agli table has valid data (at least one non-zero):
- d->cur_pack=d->dsi_pack.dsi_gi.nv_pck_lbn+
- d->dsi_pack.sml_agli.data[d->dvd_angle-1].address;
- d->angle_seek=0;
- d->cur_pack--;
- MP_VERBOSE(stream, "Angle-seek synced using sml_agli map! new_lba=0x%X \n",d->cur_pack);
- } else {
- // check if we're in the right cell, jump otherwise:
- if( (d->dsi_pack.dsi_gi.vobu_c_idn==d->cur_pgc->cell_position[d->cur_cell].cell_nr) &&
- (d->dsi_pack.dsi_gi.vobu_vob_idn==d->cur_pgc->cell_position[d->cur_cell].vob_id_nr) ){
- d->angle_seek=0;
- MP_VERBOSE(stream, "Angle-seek synced by cell/vob IDN search! \n");
- } else {
- // wrong angle, skip this vobu:
- d->cur_pack=d->dsi_pack.dsi_gi.nv_pck_lbn+
- d->dsi_pack.dsi_gi.vobu_ea;
- d->angle_seek=2; // DEBUG
- }
- }
- }
- }
- ++d->cur_pack;
- goto read_next;
- }
-
- ++d->cur_pack;
- if(d->packs_left>=0) --d->packs_left;
-
- if(d->angle_seek) {
- if(d->angle_seek==2) MP_VERBOSE(stream, "!!! warning! reading packet while angle_seek !!!\n");
- goto read_next; // searching for Navi packet
- }
-
- return d->cur_pack-1;
-}
-
-static int fill_buffer(stream_t *s, char *buf, int len)
-{
- int64_t pos;
- if (len < 2048)
- return -1;
- pos = dvd_read_sector(s, s->priv, buf);
- if (pos < 0)
- return -1;
- return 2048; // full sector
-}
-
-static void stream_dvd_close(stream_t *s) {
- dvd_priv_t *d = s->priv;
- ifoClose(d->vts_file);
- ifoClose(d->vmg_file);
- DVDCloseFile(d->title);
- DVDClose(d->dvd);
- if (d->dvd_speed)
- dvd_set_speed(s,d->dvd_device_current, -1); /* -1 => restore default */
-}
-
-static int mp_get_titleset_length(ifo_handle_t *vts_file, tt_srpt_t *tt_srpt, int title_no)
-{
- int vts_ttn; ///< title number within video title set
- int pgc_no; ///< program chain number
- int msec; ///< time length in milliseconds
-
- msec=0;
- if(!vts_file || !tt_srpt)
- return 0;
-
- if(vts_file->vtsi_mat && vts_file->vts_pgcit)
- {
- vts_ttn = tt_srpt->title[title_no].vts_ttn - 1;
- pgc_no = vts_file->vts_ptt_srpt->title[vts_ttn].ptt[0].pgcn - 1;
- msec = mp_dvdtimetomsec(&vts_file->vts_pgcit->pgci_srp[pgc_no].pgc->playback_time);
- }
- return msec;
-}
-
-
-static int get_num_chapter(ifo_handle_t *vts_file, tt_srpt_t *tt_srpt, int title_no)
-{
- if(!vts_file || !tt_srpt)
- return 0;
-
- if(title_no < 0 || title_no >= tt_srpt->nr_of_srpts)
- return 0;
-
- // map global title to vts title
- title_no = tt_srpt->title[title_no].vts_ttn - 1;
-
- if(title_no < 0 || title_no >= vts_file->vts_ptt_srpt->nr_of_srpts)
- return 0;
-
- return vts_file->vts_ptt_srpt->title[title_no].nr_of_ptts;
-}
-
-// p: in=chapter number, out=PTS
-static int get_chapter_time(ifo_handle_t *vts_file, tt_srpt_t *tt_srpt, int title_no, double *p)
-{
- unsigned int i, cell, last_cell;
- unsigned int t=0;
- ptt_info_t *ptt;
- pgc_t *pgc;
-
- title_no = tt_srpt->title[title_no].vts_ttn - 1;
- if(vts_file->vts_ptt_srpt->title[title_no].nr_of_ptts < 2)
- return 0;
- ptt = vts_file->vts_ptt_srpt->title[title_no].ptt;
-
- int cur = 0;
- for(i=0; i<vts_file->vts_ptt_srpt->title[title_no].nr_of_ptts; i++)
- {
- pgc = vts_file->vts_pgcit->pgci_srp[ptt[i].pgcn-1].pgc;
- cell = pgc->program_map[ptt[i].pgn-1]; //here the cell is 1-based
- if(ptt[i].pgn<pgc->nr_of_programs)
- last_cell = pgc->program_map[ptt[i].pgn];
- else
- last_cell = 0;
- while (cell < last_cell) {
- if(!(pgc->cell_playback[cell-1].block_type == BLOCK_TYPE_ANGLE_BLOCK &&
- pgc->cell_playback[cell-1].block_mode != BLOCK_MODE_FIRST_CELL)
- ) {
- if (cur == *p) {
- *p = t / 1000.0;
- return 1;
- }
- t += mp_dvdtimetomsec(&pgc->cell_playback[cell-1].playback_time);
- cur++;
- }
- cell++;
- }
- }
- return 0;
-}
-
-static void list_chapters(stream_t *stream, ifo_handle_t *vts_file, tt_srpt_t *tt_srpt, int title_no)
-{
- MP_INFO(stream, "CHAPTERS: ");
- for (int n = 0; ; n++) {
- double p = n;
- int r;
- r = get_chapter_time(vts_file, tt_srpt, title_no, &p);
- if (!r)
- break;
- int t = p * 1000;
- MP_INFO(stream, "%02d:%02d:%02d.%03d,", t/3600000, (t/60000)%60, (t/1000)%60, t%1000);
- }
- MP_INFO(stream, "\n");
-}
-
-static double dvd_get_current_time(stream_t *stream, int cell)
-{
- int i, tm;
- dvd_priv_t *d = stream->priv;
-
- tm=0;
- if(cell < 0) cell=d->cur_cell;
- for(i=0; i<cell; i++) {
- if(d->cur_pgc->cell_playback[i].block_type == BLOCK_TYPE_ANGLE_BLOCK &&
- d->cur_pgc->cell_playback[i].block_mode != BLOCK_MODE_FIRST_CELL
- )
- continue;
- tm += d->cell_times_table[i];
- }
- tm += mp_dvdtimetomsec(&d->dsi_pack.dsi_gi.c_eltm);
-
- return (double)tm/1000.0;
-}
-
-static void dvd_seek(stream_t *stream, dvd_priv_t *d, int pos)
-{
- d->packs_left=-1;
- d->cur_pack=pos;
-
- // check if we stay in current cell (speedup things, and avoid angle skip)
- if(d->cur_pack>d->cell_last_pack ||
- d->cur_pack<d->cur_pgc->cell_playback[ d->cur_cell ].first_sector) {
-
- // ok, cell change, find the right cell!
- cell_playback_t *cell;
- for(d->cur_cell=0; d->cur_cell < d->cur_pgc->nr_of_cells; d->cur_cell++) {
- cell = &(d->cur_pgc->cell_playback[d->cur_cell]);
- if(cell->block_type == BLOCK_TYPE_ANGLE_BLOCK && cell->block_mode != BLOCK_MODE_FIRST_CELL)
- continue;
- d->cell_last_pack=cell->last_sector;
- if(d->cur_pack<cell->first_sector) {
- d->cur_pack=cell->first_sector;
- break;
- }
- if(d->cur_pack<=d->cell_last_pack) break; // ok, we find it! :)
- }
- }
-
- MP_VERBOSE(stream, "DVD Seek! lba=0x%X cell=%d packs: 0x%X-0x%X \n",
- d->cur_pack,d->cur_cell,d->cur_pgc->cell_playback[ d->cur_cell ].first_sector,d->cell_last_pack);
-
- // if we're in interleaved multi-angle cell, find the right angle chain!
- // (read Navi block, and use the seamless angle jump table)
- d->angle_seek=1;
-}
-
-static int do_seek(stream_t *s, int64_t newpos) {
- stream_drop_buffers(s);
- dvd_seek(s, s->priv,newpos/2048);
- return 1;
-}
-
-static int dvd_seek_to_time(stream_t *stream, ifo_handle_t *vts_file, double sec)
-{
- unsigned int i, j, k, timeunit, ac_time, tmap_sector=0, cell_sector=0, vobu_sector=0;
- int t=0;
- double tm, duration;
- int64_t pos = -1;
- dvd_priv_t *d = stream->priv;
- vts_tmapt_t *vts_tmapt = vts_file->vts_tmapt;
-
- if(!vts_file->vts_tmapt || sec < 0)
- return 0;
-
- duration = (double) mp_get_titleset_length(d->vts_file, d->tt_srpt, d->cur_title) / 1000.0f;
- if(sec > duration)
- return 0;
-
- i=d->cur_pgc_idx;
- timeunit = vts_tmapt->tmap[i].tmu;
- for(j = 0; j < vts_tmapt->tmap[i].nr_of_entries; j++) {
- ac_time = timeunit * (j + 1);
- if(ac_time >= sec)
- break;
- tmap_sector = vts_tmapt->tmap[i].map_ent[j] & 0x7fffffff;
- }
- //search enclosing cell
- for(i=0; i<d->cur_pgc->nr_of_cells; i++) {
- if(tmap_sector >= d->cur_pgc->cell_playback[i].first_sector && tmap_sector <= d->cur_pgc->cell_playback[i].last_sector) {
- cell_sector = d->cur_pgc->cell_playback[i].first_sector;
- break;
- }
- }
-
- pos = ((int64_t)cell_sector)<<11;
- do_seek(stream, pos);
- do {
- char buf[2048];
- if (dvd_read_sector(stream, stream->priv, buf) < 0) // skip
- break;
- t = mp_dvdtimetomsec(&d->dsi_pack.dsi_gi.c_eltm);
- } while(!t);
- tm = dvd_get_current_time(stream, -1);
-
- pos = ((int64_t)tmap_sector)<<11;
- do_seek(stream, pos);
- //now get current time in terms of the cell+cell time offset
- memset(&d->dsi_pack.dsi_gi.c_eltm, 0, sizeof(dvd_time_t));
- while(tm <= sec) {
- char buf[2048];
- if (dvd_read_sector(stream, stream->priv, buf) < 0) // skip
- break;
- pos += 2048;
- tm = dvd_get_current_time(stream, -1);
- };
- tmap_sector = pos >> 11;
-
- //search closest VOBU sector
- k=(vts_file->vts_vobu_admap->last_byte + 1 - VOBU_ADMAP_SIZE)/4; //entries in the vobu admap
- for(i=1; i<k; i++) {
- if(vts_file->vts_vobu_admap->vobu_start_sectors[i] > tmap_sector)
- break;
- }
- vobu_sector = vts_file->vts_vobu_admap->vobu_start_sectors[i-1];
- pos = ((int64_t)vobu_sector) << 11;
- do_seek(stream, pos);
-
- return 1;
-}
-
-static int control(stream_t *stream,int cmd,void* arg)
-{
- dvd_priv_t *d = stream->priv;
- switch(cmd)
- {
- case STREAM_CTRL_GET_TIME_LENGTH:
- {
- *((double *)arg) = (double) mp_get_titleset_length(d->vts_file, d->tt_srpt, d->cur_title)/1000.0;
- return 1;
- }
- case STREAM_CTRL_GET_NUM_TITLES:
- {
- *((unsigned int *)arg) = d->vmg_file->tt_srpt->nr_of_srpts;
- return 1;
- }
- case STREAM_CTRL_GET_NUM_CHAPTERS:
- {
- int r;
- r = get_num_chapter(d->vts_file, d->tt_srpt, d->cur_title);
- if(! r) return STREAM_UNSUPPORTED;
- *((unsigned int *)arg) = r;
- return 1;
- }
- case STREAM_CTRL_GET_CHAPTER_TIME:
- {
- int r;
- r = get_chapter_time(d->vts_file, d->tt_srpt, d->cur_title, (double *)arg);
- if(! r) return STREAM_UNSUPPORTED;
- return 1;
- }
- case STREAM_CTRL_GET_CURRENT_TITLE:
- {
- *((unsigned int *)arg) = d->cur_title;
- return 1;
- }
- case STREAM_CTRL_GET_CURRENT_TIME:
- {
- double tm;
- tm = dvd_get_current_time(stream, -1);
- if(tm != -1) {
- *((double *)arg) = tm;
- return 1;
- }
- break;
- }
- case STREAM_CTRL_SEEK_TO_TIME:
- {
- if(dvd_seek_to_time(stream, d->vts_file, *((double*)arg)))
- return 1;
- break;
- }
- case STREAM_CTRL_GET_ASPECT_RATIO:
- {
- *((double *)arg) = !d->vts_file->vtsi_mat->vts_video_attr.display_aspect_ratio ? 4.0/3.0 : 16.0/9.0;
- return 1;
- }
- case STREAM_CTRL_GET_NUM_ANGLES:
- {
- *((int *)arg) = d->vmg_file->tt_srpt->title[d->dvd_title].nr_of_angles;
- return 1;
- }
- case STREAM_CTRL_GET_ANGLE:
- {
- *((int *)arg) = d->dvd_angle;
- return 1;
- }
- case STREAM_CTRL_SET_ANGLE:
- {
- int ang = *((int *)arg);
- if(ang>d->vmg_file->tt_srpt->title[d->dvd_title].nr_of_angles || ang<=0)
- break;
- d->dvd_angle = ang;
- d->angle_seek = 1;
- return 1;
- }
- case STREAM_CTRL_GET_LANG:
- {
- struct stream_lang_req *req = arg;
- int lang = 0;
- switch(req->type) {
- case STREAM_AUDIO:
- lang = dvd_lang_from_aid(stream, req->id);
- break;
- case STREAM_SUB:
- lang = dvd_lang_from_sid(stream, req->id);
- break;
- }
- if (!lang)
- break;
- snprintf(req->name, sizeof(req->name), "%c%c", lang >> 8, lang);
- return STREAM_OK;
- }
- case STREAM_CTRL_GET_DVD_INFO:
- {
- struct stream_dvd_info_req *req = arg;
- memset(req, 0, sizeof(*req));
- req->num_subs = dvd_number_of_subs(stream);
- memcpy(req->palette, d->cur_pgc->palette, sizeof(req->palette));
- return STREAM_OK;
- }
- case STREAM_CTRL_GET_DISC_NAME:
- {
- char buffer[128];
- if (DVDUDFVolumeInfo(d->dvd, buffer, sizeof(buffer), NULL, 0) < 0 &&
- DVDISOVolumeInfo(d->dvd, buffer, sizeof(buffer), NULL, 0) < 0)
- break;
- if (!buffer[0])
- break;
- *(char**)arg = talloc_strdup(NULL, buffer);
- return STREAM_OK;
- }
- }
- return STREAM_UNSUPPORTED;
-}
-
-
-static int open_s(stream_t *stream)
-{
- int k;
- dvd_priv_t *d = stream->priv;
-
- d->dvd_angle = stream->opts->dvd_angle;
-
- MP_VERBOSE(stream, "URL: %s\n", stream->url);
- d->dvd_title = d->cfg_title + 1;
- if(1){
- //int ret,ret2;
- int ttn,pgc_id,pgn;
- dvd_reader_t *dvd;
- dvd_file_t *title;
- ifo_handle_t *vmg_file;
- tt_srpt_t *tt_srpt;
- ifo_handle_t *vts_file;
- pgc_t *pgc;
- /**
- * Open the disc.
- */
- if(d->cfg_device && d->cfg_device[0])
- d->dvd_device_current = d->cfg_device;
- else if(stream->opts->dvd_device && stream->opts->dvd_device[0])
- d->dvd_device_current = talloc_strdup(stream, stream->opts->dvd_device);
- else
- d->dvd_device_current = DEFAULT_DVD_DEVICE;
- d->dvd_speed = stream->opts->dvd_speed;
- dvd_set_speed(stream,d->dvd_device_current, d->dvd_speed);
-#if defined(__APPLE__) || defined(__DARWIN__)
- /* Dynamic DVD drive selection on Darwin */
- if(!strcmp(d->dvd_device_current, "/dev/rdiskN")) {
- int i;
- size_t len = strlen(d->dvd_device_current)+1;
- char *temp_device = malloc(len);
-
- for (i = 1; i < 10; i++) {
- snprintf(temp_device, len, "/dev/rdisk%d", i);
- dvd = DVDOpen(temp_device);
- if(!dvd) {
- MP_ERR(stream, "Couldn't open DVD device: %s (%s)\n",temp_device, strerror(errno));
- } else {
-#if DVDREAD_VERSION <= LIBDVDREAD_VERSION(0,9,4)
- dvd_file_t *dvdfile = DVDOpenFile(dvd,d->dvd_title,DVD_READ_INFO_FILE);
- if(!dvdfile) {
- MP_ERR(stream, "Couldn't open DVD device: %s (%s)\n",temp_device, strerror(errno));
- DVDClose(dvd);
- continue;
- }
- DVDCloseFile(dvdfile);
-#endif
- break;
- }
- }
- free(temp_device);
-
- if(!dvd) {
- return STREAM_UNSUPPORTED;
- }
- } else
-#endif /* defined(__APPLE__) || defined(__DARWIN__) */
- {
- dvd = DVDOpen(d->dvd_device_current);
- if(!dvd) {
- MP_ERR(stream, "Couldn't open DVD device: %s (%s)\n",d->dvd_device_current, strerror(errno));
- return STREAM_UNSUPPORTED;
- }
- }
-
- MP_VERBOSE(stream, "Reading disc structure, please wait...\n");
-
- /**
- * Load the video manager to find out the information about the titles on
- * this disc.
- */
- vmg_file = ifoOpen(dvd, 0);
- if(!vmg_file) {
- MP_ERR(stream, "Can't open VMG info!\n");
- DVDClose( dvd );
- return STREAM_UNSUPPORTED;
- }
- tt_srpt = vmg_file->tt_srpt;
- /**
- * Make sure our title number is valid.
- */
- MP_INFO(stream, "There are %d titles on this DVD.\n", tt_srpt->nr_of_srpts );
- if(d->dvd_title < 1 || d->dvd_title > tt_srpt->nr_of_srpts) {
- MP_ERR(stream, "Invalid DVD title number: %d\n", d->dvd_title);
- ifoClose( vmg_file );
- DVDClose( dvd );
- return STREAM_UNSUPPORTED;
- }
- --(d->dvd_title); // remap 1.. -> 0..
- /**
- * Make sure the angle number is valid for this title.
- */
- MP_INFO(stream, "There are %d angles in this DVD title.\n", tt_srpt->title[d->dvd_title].nr_of_angles);
- if(d->dvd_angle<1 || d->dvd_angle>tt_srpt->title[d->dvd_title].nr_of_angles) {
- MP_ERR(stream, "Invalid DVD angle number: %d\n", d->dvd_angle);
- goto fail;
- }
-
- ttn = tt_srpt->title[d->dvd_title].vts_ttn - 1;
- /**
- * Load the VTS information for the title set our title is in.
- */
- vts_file = ifoOpen( dvd, tt_srpt->title[d->dvd_title].title_set_nr );
- if(!vts_file) {
- MP_ERR(stream, "Cannot open the IFO file for DVD title %d.\n", tt_srpt->title[d->dvd_title].title_set_nr );
- goto fail;
- }
- /**
- * We've got enough info, time to open the title set data.
- */
- title = DVDOpenFile(dvd, tt_srpt->title[d->dvd_title].title_set_nr, DVD_READ_TITLE_VOBS);
- if(!title) {
- MP_ERR(stream, "Cannot open title VOBS (VTS_%02d_1.VOB).\n", tt_srpt->title[d->dvd_title].title_set_nr);
- ifoClose( vts_file );
- goto fail;
- }
-
- MP_VERBOSE(stream, "DVD successfully opened.\n");
- // store data
- d->dvd=dvd;
- d->title=title;
- d->vmg_file=vmg_file;
- d->tt_srpt=tt_srpt;
- d->vts_file=vts_file;
- d->cur_title = d->dvd_title;
-
- pgc = vts_file->vts_pgcit ? vts_file->vts_pgcit->pgci_srp[ttn].pgc : NULL;
- /**
- * Check number of audio channels and types
- */
- {
- d->nr_of_channels=0;
- if(vts_file->vts_pgcit) {
- int i;
- for(i=0;i<8;i++)
- if(pgc->audio_control[i] & 0x8000) {
- audio_attr_t * audio = &vts_file->vtsi_mat->vts_audio_attr[i];
- int language = 0;
- char tmp[] = "unknown";
- stream_language_t *audio_stream = &d->audio_streams[d->nr_of_channels];
-
- if(audio->lang_type == 1) {
- language=audio->lang_code;
- tmp[0]=language>>8;
- tmp[1]=language&0xff;
- tmp[2]=0;
- }
-
- audio_stream->language=language;
- audio_stream->id=pgc->audio_control[i] >> 8 & 7;
- switch(audio->audio_format) {
- case 0: // ac3
- audio_stream->id+=FIRST_AC3_AID;
- break;
- case 6: // dts
- audio_stream->id+=FIRST_DTS_AID;
- break;
- case 2: // mpeg layer 1/2/3
- case 3: // mpeg2 ext
- audio_stream->id+=FIRST_MPG_AID;
- break;
- case 4: // lpcm
- audio_stream->id+=FIRST_PCM_AID;
- break;
- }
-
- audio_stream->type=audio->audio_format;
- // Pontscho: to my mind, tha channels:
- // 1 - stereo
- // 5 - 5.1
- audio_stream->channels=audio->channels;
- MP_INFO(stream, "audio stream: %d format: %s (%s) language: %s aid: %d.\n",
- d->nr_of_channels,
- dvd_audio_stream_types[ audio->audio_format ],
- dvd_audio_stream_channels[ audio->channels ],
- tmp,
- audio_stream->id
- );
-
- d->nr_of_channels++;
- }
- }
- MP_INFO(stream, "number of audio channels on disk: %d.\n",d->nr_of_channels );
- }
-
- /**
- * Check number of subtitles and language
- */
- {
- int i;
-
- d->nr_of_subtitles=0;
- for(i=0;i<32;i++)
- if(pgc->subp_control[i] & 0x80000000) {
- subp_attr_t * subtitle = &vts_file->vtsi_mat->vts_subp_attr[i];
- video_attr_t *video = &vts_file->vtsi_mat->vts_video_attr;
- int language = 0;
- char tmp[] = "unknown";
- stream_language_t *sub_stream = &d->subtitles[d->nr_of_subtitles];
-
- if(subtitle->type == 1) {
- language=subtitle->lang_code;
- tmp[0]=language>>8;
- tmp[1]=language&0xff;
- tmp[2]=0;
- }
-
- sub_stream->language=language;
- sub_stream->id=d->nr_of_subtitles;
- if(video->display_aspect_ratio == 0) /* 4:3 */
- sub_stream->id = pgc->subp_control[i] >> 24 & 31;
- else if(video->display_aspect_ratio == 3) /* 16:9 */
- sub_stream->id = pgc->subp_control[i] >> 8 & 31;
-
- MP_INFO(stream, "subtitle ( sid ): %d language: %s\n", sub_stream->id, tmp);
- d->nr_of_subtitles++;
- }
- MP_INFO(stream, "number of subtitles on disk: %d\n",d->nr_of_subtitles);
- }
-
- /**
- * Determine which program chain we want to watch. This is based on the
- * chapter number.
- */
- pgc_id = vts_file->vts_ptt_srpt->title[ttn].ptt[0].pgcn; // local
- pgn = vts_file->vts_ptt_srpt->title[ttn].ptt[0].pgn; // local
- d->cur_pgc_idx = pgc_id-1;
- d->cur_pgc = vts_file->vts_pgcit->pgci_srp[pgc_id-1].pgc;
- d->cur_cell = d->cur_pgc->program_map[pgn-1] - 1; // start playback here
- d->packs_left=-1; // for Navi stuff
- d->angle_seek=0;
- d->last_cell=d->cur_pgc->nr_of_cells;
-
- if(d->cur_pgc->cell_playback[d->cur_cell].block_type == BLOCK_TYPE_ANGLE_BLOCK )
- d->cur_cell+=d->dvd_angle-1;
- d->cur_pack = d->cur_pgc->cell_playback[ d->cur_cell ].first_sector;
- d->cell_last_pack=d->cur_pgc->cell_playback[ d->cur_cell ].last_sector;
- MP_VERBOSE(stream, "DVD start cell: %d pack: 0x%X-0x%X \n",d->cur_cell,d->cur_pack,d->cell_last_pack);
-
- //assign cell_times_table
- d->cell_times_table = malloc(sizeof(unsigned int) * d->cur_pgc->nr_of_cells);
- if(d->cell_times_table == NULL)
- return STREAM_UNSUPPORTED;
- for(k=0; k<d->cur_pgc->nr_of_cells; k++)
- d->cell_times_table[k] = mp_dvdtimetomsec(&d->cur_pgc->cell_playback[k].playback_time);
- list_chapters(stream, vts_file,tt_srpt,d->dvd_title);
-
- // ... (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;
- stream->close = stream_dvd_close;
- stream->end_pos = (int64_t)(d->cur_pgc->cell_playback[d->last_cell-1].last_sector)*2048;
- MP_VERBOSE(stream, "DVD start=%d end=%d \n",d->cur_pack,d->cur_pgc->cell_playback[d->last_cell-1].last_sector);
- stream->priv = (void*)d;
- return STREAM_OK;
-
-fail:
- ifoClose(vmg_file);
- DVDClose(dvd);
- return STREAM_UNSUPPORTED;
- }
- MP_ERR(stream, "mpv was compiled without DVD support, exiting.\n");
- return STREAM_UNSUPPORTED;
-}
-
-static int ifo_stream_open (stream_t *stream)
-{
- char* filename;
- dvd_priv_t *priv = talloc_ptrtype(stream, priv);
- stream->priv = priv;
- *priv = stream_priv_dflts;
-
- // "file://" prefix -> decode URL-style escapes
- if (strlen(stream->url) > strlen(stream->path))
- mp_url_unescape_inplace(stream->path);
-
- int len = strlen(stream->path);
- if (len < 4 || strcasecmp (stream->path + len - 4, ".ifo"))
- return STREAM_UNSUPPORTED;
-
- MP_INFO(stream, ".IFO detected. Redirecting to dvd://\n");
-
- filename = strdup(basename(stream->path));
-
- talloc_free(priv->cfg_device);
- priv->cfg_device = talloc_strdup(NULL, dirname(stream->path));
- if(!strncasecmp(filename,"vts_",4))
- {
- if(sscanf(filename+3, "_%02d_", &priv->cfg_title)!=0)
- priv->cfg_title = 0;
- }else
- priv->cfg_title = 0;
-
- free(filename);
- stream->url=talloc_strdup(stream, "dvdread://");
-
- return open_s(stream);
-}
-
-const stream_info_t stream_info_dvd = {
- .name = "dvd",
- .open = open_s,
- .protocols = (const char*const[]){ "dvdread", NULL },
- .priv_size = sizeof(dvd_priv_t),
- .priv_defaults = &stream_priv_dflts,
- .options = stream_opts_fields,
- .url_options = (const char*const[]){
- "hostname=title",
- "filename=device",
- NULL
- },
-};
-
-const stream_info_t stream_info_ifo = {
- .name = "ifo",
- .open = ifo_stream_open,
- .protocols = (const char*const[]){ "file", "", NULL },
-};
diff --git a/stream/stream_dvdnav.c b/stream/stream_dvdnav.c
deleted file mode 100644
index 2d9658bc78..0000000000
--- a/stream/stream_dvdnav.c
+++ /dev/null
@@ -1,755 +0,0 @@
-/*
- * This file is part of MPlayer.
- *
- * MPlayer 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.
- *
- * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-#include <libavutil/common.h>
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-
-#include <dvdnav/dvdnav.h>
-
-#include "options/options.h"
-#include "common/msg.h"
-#include "input/input.h"
-#include "options/m_option.h"
-#include "osdep/timer.h"
-#include "stream.h"
-#include "demux/demux.h"
-#include "discnav.h"
-#include "video/out/vo.h"
-#include "stream_dvd_common.h"
-
-#define TITLE_MENU -1
-#define TITLE_LONGEST -2
-
-struct priv {
- dvdnav_t *dvdnav; // handle to libdvdnav stuff
- char *filename; // path
- unsigned int duration; // in milliseconds
- int mousex, mousey;
- int title;
- uint32_t spu_clut[16];
- bool spu_clut_valid;
- dvdnav_highlight_event_t hlev;
- int still_length; // still frame duration
- unsigned long next_event; // bitmask of events to return to player
- bool suspended_read;
- bool nav_enabled;
- bool had_initial_vts;
-
- int dvd_speed;
-
- int track;
- char *device;
-};
-
-static const struct priv stream_priv_dflts = {
- .track = TITLE_LONGEST,
-};
-
-#define OPT_BASE_STRUCT struct priv
-static const m_option_t stream_opts_fields[] = {
- OPT_CHOICE_OR_INT("title", track, 0, 0, 99,
- ({"menu", TITLE_MENU},
- {"longest", TITLE_LONGEST})),
- OPT_STRING("device", device, 0),
- {0}
-};
-
-#define DNE(e) [e] = # e
-static const char *const mp_dvdnav_events[] = {
- DNE(DVDNAV_BLOCK_OK),
- DNE(DVDNAV_NOP),
- DNE(DVDNAV_STILL_FRAME),
- DNE(DVDNAV_SPU_STREAM_CHANGE),
- DNE(DVDNAV_AUDIO_STREAM_CHANGE),
- DNE(DVDNAV_VTS_CHANGE),
- DNE(DVDNAV_CELL_CHANGE),
- DNE(DVDNAV_NAV_PACKET),
- DNE(DVDNAV_STOP),
- DNE(DVDNAV_HIGHLIGHT),
- DNE(DVDNAV_SPU_CLUT_CHANGE),
- DNE(DVDNAV_HOP_CHANNEL),
- DNE(DVDNAV_WAIT),
-};
-
-static const char *const mp_nav_cmd_types[] = {
- DNE(MP_NAV_CMD_NONE),
- DNE(MP_NAV_CMD_ENABLE),
- DNE(MP_NAV_CMD_DRAIN_OK),
- DNE(MP_NAV_CMD_RESUME),
- DNE(MP_NAV_CMD_SKIP_STILL),
- DNE(MP_NAV_CMD_MENU),
- DNE(MP_NAV_CMD_MOUSE_POS),
-};
-
-static const char *const mp_nav_event_types[] = {
- DNE(MP_NAV_EVENT_NONE),
- DNE(MP_NAV_EVENT_RESET),
- DNE(MP_NAV_EVENT_RESET_CLUT),
- DNE(MP_NAV_EVENT_RESET_ALL),
- DNE(MP_NAV_EVENT_DRAIN),
- DNE(MP_NAV_EVENT_STILL_FRAME),
- DNE(MP_NAV_EVENT_HIGHLIGHT),
- DNE(MP_NAV_EVENT_MENU_MODE),
- DNE(MP_NAV_EVENT_EOF),
-};
-
-#define LOOKUP_NAME(array, i) \
- (((i) >= 0 && (i) < MP_ARRAY_SIZE(array)) ? array[(i)] : "?")
-
-static void dvdnav_get_highlight(struct priv *priv, int display_mode)
-{
- pci_t *pnavpci = NULL;
- dvdnav_highlight_event_t *hlev = &(priv->hlev);
- int btnum;
-
- if (!priv || !priv->dvdnav)
- return;
-
- pnavpci = dvdnav_get_current_nav_pci(priv->dvdnav);
- if (!pnavpci) {
- hlev->display = 0;
- return;
- }
-
- dvdnav_get_current_highlight(priv->dvdnav, &(hlev->buttonN));
- hlev->display = display_mode; /* show */
-
- if (hlev->buttonN > 0 && pnavpci->hli.hl_gi.btn_ns > 0 && hlev->display) {
- for (btnum = 0; btnum < pnavpci->hli.hl_gi.btn_ns; btnum++) {
- btni_t *btni = &(pnavpci->hli.btnit[btnum]);
-
- if (hlev->buttonN == btnum + 1) {
- hlev->sx = FFMIN(btni->x_start, btni->x_end);
- hlev->ex = FFMAX(btni->x_start, btni->x_end);
- hlev->sy = FFMIN(btni->y_start, btni->y_end);
- hlev->ey = FFMAX(btni->y_start, btni->y_end);
-
- hlev->palette = (btni->btn_coln == 0) ?
- 0 : pnavpci->hli.btn_colit.btn_coli[btni->btn_coln - 1][0];
- break;
- }
- }
- } else { /* hide button or no button */
- hlev->sx = hlev->ex = 0;
- hlev->sy = hlev->ey = 0;
- hlev->palette = hlev->buttonN = 0;
- }
-}
-
-static void handle_menu_input(stream_t *stream, const char *cmd)
-{
- struct priv *priv = stream->priv;
- dvdnav_t *nav = priv->dvdnav;
- dvdnav_status_t status = DVDNAV_STATUS_ERR;
- pci_t *pci = dvdnav_get_current_nav_pci(nav);
-
- MP_VERBOSE(stream, "DVDNAV: input '%s'\n", cmd);
-
- if (!pci)
- return;
-
- if (strcmp(cmd, "up") == 0) {
- status = dvdnav_upper_button_select(nav, pci);
- } else if (strcmp(cmd, "down") == 0) {
- status = dvdnav_lower_button_select(nav, pci);
- } else if (strcmp(cmd, "left") == 0) {
- status = dvdnav_left_button_select(nav, pci);
- } else if (strcmp(cmd, "right") == 0) {
- status = dvdnav_right_button_select(nav, pci);
- } else if (strcmp(cmd, "menu") == 0) {
- status = dvdnav_menu_call(nav, DVD_MENU_Root);
- } else if (strcmp(cmd, "prev") == 0) {
- int title = 0, part = 0;
- dvdnav_current_title_info(nav, &title, &part);
- if (title)
- status = dvdnav_menu_call(nav, DVD_MENU_Part);
- if (status != DVDNAV_STATUS_OK)
- status = dvdnav_menu_call(nav, DVD_MENU_Title);
- if (status != DVDNAV_STATUS_OK)
- status = dvdnav_menu_call(nav, DVD_MENU_Root);
- } else if (strcmp(cmd, "select") == 0) {
- status = dvdnav_button_activate(nav, pci);
- } else if (strcmp(cmd, "mouse") == 0) {
- status = dvdnav_mouse_activate(nav, pci, priv->mousex, priv->mousey);
- } else {
- MP_VERBOSE(stream, "Unknown DVDNAV command: '%s'\n", cmd);
- }
-}
-
-static void handle_mouse_pos(stream_t *stream, int x, int y)
-{
- struct priv *priv = stream->priv;
- dvdnav_t *nav = priv->dvdnav;
- pci_t *pci = dvdnav_get_current_nav_pci(nav);
-
- if (!pci)
- return;
-
- dvdnav_mouse_select(nav, pci, x, y);
- priv->mousex = x;
- priv->mousey = y;
-}
-
-/**
- * \brief mp_dvdnav_lang_from_aid() returns the language corresponding to audio id 'aid'
- * \param stream: - stream pointer
- * \param sid: physical subtitle id
- * \return 0 on error, otherwise language id
- */
-static int mp_dvdnav_lang_from_aid(stream_t *stream, int aid)
-{
- uint8_t lg;
- uint16_t lang;
- struct priv *priv = stream->priv;
-
- if (aid < 0)
- return 0;
- lg = dvdnav_get_audio_logical_stream(priv->dvdnav, aid & 0x7);
- if (lg == 0xff)
- return 0;
- lang = dvdnav_audio_stream_to_lang(priv->dvdnav, lg);
- if (lang == 0xffff)
- return 0;
- return lang;
-}
-
-/**
- * \brief mp_dvdnav_lang_from_sid() returns the language corresponding to subtitle id 'sid'
- * \param stream: - stream pointer
- * \param sid: physical subtitle id
- * \return 0 on error, otherwise language id
- */
-static int mp_dvdnav_lang_from_sid(stream_t *stream, int sid)
-{
- uint8_t k;
- uint16_t lang;
- struct priv *priv = stream->priv;
- if (sid < 0)
- return 0;
- for (k = 0; k < 32; k++)
- if (dvdnav_get_spu_logical_stream(priv->dvdnav, k) == sid)
- break;
- if (k == 32)
- return 0;
- lang = dvdnav_spu_stream_to_lang(priv->dvdnav, k);
- if (lang == 0xffff)
- return 0;
- return lang;
-}
-
-/**
- * \brief mp_dvdnav_number_of_subs() returns the count of available subtitles
- * \param stream: - stream pointer
- * \return 0 on error, something meaningful otherwise
- */
-static int mp_dvdnav_number_of_subs(stream_t *stream)
-{
- struct priv *priv = stream->priv;
- uint8_t lg, k, n = 0;
-
- for (k = 0; k < 32; k++) {
- lg = dvdnav_get_spu_logical_stream(priv->dvdnav, k);
- if (lg == 0xff)
- continue;
- if (lg >= n)
- n = lg + 1;
- }
- return n;
-}
-
-static void handle_cmd(stream_t *s, struct mp_nav_cmd *ev)
-{
- struct priv *priv = s->priv;
- MP_VERBOSE(s, "DVDNAV: input '%s'\n",
- LOOKUP_NAME(mp_nav_cmd_types, ev->event));
- switch (ev->event) {
- case MP_NAV_CMD_ENABLE:
- priv->nav_enabled = true;
- break;
- case MP_NAV_CMD_DRAIN_OK:
- dvdnav_wait_skip(priv->dvdnav);
- break;
- case MP_NAV_CMD_RESUME:
- priv->suspended_read = false;
- break;
- case MP_NAV_CMD_SKIP_STILL:
- dvdnav_still_skip(priv->dvdnav);
- break;
- case MP_NAV_CMD_MENU:
- handle_menu_input(s, ev->u.menu.action);
- break;
- case MP_NAV_CMD_MOUSE_POS:
- handle_mouse_pos(s, ev->u.mouse_pos.x, ev->u.mouse_pos.y);
- break;
- }
-
-}
-
-static inline bool set_event_type(struct priv *priv, int type,
- struct mp_nav_event *event)
-{
- if (!(priv->next_event & (1 << type)))
- return false;
- priv->next_event &= ~(1 << type);
- event->event = type;
- return true;
-}
-
-static void fill_next_event(stream_t *s, struct mp_nav_event **ret)
-{
- struct priv *priv = s->priv;
- struct mp_nav_event e = {0};
- if (!set_event_type(priv, MP_NAV_EVENT_RESET_ALL, &e))
- for (int n = 0; n < 30 && !set_event_type(priv, n, &e); n++) ;
- switch (e.event) {
- case MP_NAV_EVENT_NONE:
- return;
- case MP_NAV_EVENT_HIGHLIGHT: {
- dvdnav_highlight_event_t hlev = priv->hlev;
- e.u.highlight.display = hlev.display;
- e.u.highlight.sx = hlev.sx;
- e.u.highlight.sy = hlev.sy;
- e.u.highlight.ex = hlev.ex;
- e.u.highlight.ey = hlev.ey;
- e.u.highlight.palette = hlev.palette;
- break;
- }
- case MP_NAV_EVENT_MENU_MODE:
- e.u.menu_mode.enable = !dvdnav_is_domain_vts(priv->dvdnav);
- break;
- case MP_NAV_EVENT_STILL_FRAME:
- e.u.still_frame.seconds = priv->still_length;
- break;
- }
- *ret = talloc(NULL, struct mp_nav_event);
- **ret = e;
-
- MP_VERBOSE(s, "DVDNAV: player event '%s'\n",
- LOOKUP_NAME(mp_nav_event_types, e.event));
-}
-
-static int fill_buffer(stream_t *s, char *buf, int max_len)
-{
- struct priv *priv = s->priv;
- dvdnav_t *dvdnav = priv->dvdnav;
-
- if (max_len < 2048)
- return -1;
-
- while (1) {
- if (priv->suspended_read)
- return -1;
-
- int len = -1;
- int event = DVDNAV_NOP;
- if (dvdnav_get_next_block(dvdnav, buf, &event, &len) != DVDNAV_STATUS_OK)
- {
- MP_ERR(s, "Error getting next block from DVD %d (%s)\n",
- event, dvdnav_err_to_string(dvdnav));
- return 0;
- }
- if (event != DVDNAV_BLOCK_OK) {
- const char *name = LOOKUP_NAME(mp_dvdnav_events, event);
- MP_VERBOSE(s, "DVDNAV: event %s (%d).\n", name, event);
- dvdnav_get_highlight(priv, 1);
- }
- switch (event) {
- case DVDNAV_BLOCK_OK:
- return len;
- case DVDNAV_STOP: {
- priv->next_event |= 1 << MP_NAV_EVENT_EOF;
- return 0;
- }
- case DVDNAV_NAV_PACKET: {
- pci_t *pnavpci = dvdnav_get_current_nav_pci(dvdnav);
- uint32_t start_pts = pnavpci->pci_gi.vobu_s_ptm;
- MP_TRACE(s, "start pts = %"PRIu32"\n", start_pts);
- break;
- }
- case DVDNAV_STILL_FRAME: {
- dvdnav_still_event_t *still_event = (dvdnav_still_event_t *) buf;
- priv->still_length = still_event->length;
- if (priv->still_length == 255)
- priv->still_length = -1;
- MP_VERBOSE(s, "len=%d\n", priv->still_length);
- /* set still frame duration */
- if (priv->still_length <= 1) {
- pci_t *pnavpci = dvdnav_get_current_nav_pci(dvdnav);
- priv->duration = mp_dvdtimetomsec(&pnavpci->pci_gi.e_eltm);
- }
- if (priv->nav_enabled) {
- priv->next_event |= 1 << MP_NAV_EVENT_STILL_FRAME;
- } else {
- dvdnav_still_skip(dvdnav);
- }
- return 0;
- }
- case DVDNAV_WAIT: {
- if (priv->nav_enabled) {
- priv->next_event |= 1 << MP_NAV_EVENT_DRAIN;
- } else {
- dvdnav_wait_skip(dvdnav);
- }
- return 0;
- }
- case DVDNAV_HIGHLIGHT: {
- dvdnav_get_highlight(priv, 1);
- priv->next_event |= 1 << MP_NAV_EVENT_HIGHLIGHT;
- break;
- }
- case DVDNAV_VTS_CHANGE: {
- int tit = 0, part = 0;
- dvdnav_vts_change_event_t *vts_event =
- (dvdnav_vts_change_event_t *)s->buffer;
- MP_INFO(s, "DVDNAV, switched to title: %d\n",
- vts_event->new_vtsN);
- if (!priv->had_initial_vts) {
- // dvdnav sends an initial VTS change before any data; don't
- // cause a blocking wait for the player, because the player in
- // turn can't initialize the demuxer without data.
- priv->had_initial_vts = true;
- break;
- }
- // clear all previous events
- priv->next_event = 0;
- priv->next_event |= 1 << MP_NAV_EVENT_RESET;
- priv->next_event |= 1 << MP_NAV_EVENT_RESET_ALL;
- if (dvdnav_current_title_info(dvdnav, &tit, &part) == DVDNAV_STATUS_OK)
- {
- MP_VERBOSE(s, "DVDNAV, NEW TITLE %d\n", tit);
- dvdnav_get_highlight(priv, 0);
- if (priv->title > 0 && tit != priv->title) {
- priv->next_event |= 1 << MP_NAV_EVENT_EOF;;
- MP_WARN(s, "Requested title not found\n");
- }
- }
- if (priv->nav_enabled)
- priv->suspended_read = true;
- break;
- }
- case DVDNAV_CELL_CHANGE: {
- dvdnav_cell_change_event_t *ev = (dvdnav_cell_change_event_t *)buf;
-
- priv->next_event |= 1 << MP_NAV_EVENT_RESET;
- priv->next_event |= 1 << MP_NAV_EVENT_MENU_MODE;
- if (ev->pgc_length)
- priv->duration = ev->pgc_length / 90;
-
- dvdnav_get_highlight(priv, 1);
- break;
- }
- case DVDNAV_SPU_CLUT_CHANGE: {
- memcpy(priv->spu_clut, buf, 16 * sizeof(uint32_t));
- priv->spu_clut_valid = true;
- priv->next_event |= 1 << MP_NAV_EVENT_RESET_CLUT;
- break;
- }
- }
- }
- return 0;
-}
-
-static int control(stream_t *stream, int cmd, void *arg)
-{
- struct priv *priv = stream->priv;
- dvdnav_t *dvdnav = priv->dvdnav;
- int tit, part;
-
- switch (cmd) {
- case STREAM_CTRL_GET_NUM_CHAPTERS: {
- if (dvdnav_current_title_info(dvdnav, &tit, &part) != DVDNAV_STATUS_OK)
- break;
- if (dvdnav_get_number_of_parts(dvdnav, tit, &part) != DVDNAV_STATUS_OK)
- break;
- if (!part)
- break;
- *(unsigned int *)arg = part;
- return 1;
- }
- case STREAM_CTRL_GET_CHAPTER_TIME: {
- double *ch = arg;
- int chapter = *ch;
- if (dvdnav_current_title_info(dvdnav, &tit, &part) != DVDNAV_STATUS_OK)
- break;
- uint64_t *parts = NULL, duration = 0;
- int n = dvdnav_describe_title_chapters(dvdnav, tit, &parts, &duration);
- if (!parts)
- break;
- if (chapter < 0 || chapter >= n)
- break;
- *ch = parts[chapter] / 90000.0;
- free(parts);
- return 1;
- }
- case STREAM_CTRL_GET_TIME_LENGTH: {
- if (priv->duration) {
- *(double *)arg = (double)priv->duration / 1000.0;
- return 1;
- }
- break;
- }
- case STREAM_CTRL_GET_ASPECT_RATIO: {
- uint8_t ar = dvdnav_get_video_aspect(dvdnav);
- *(double *)arg = !ar ? 4.0 / 3.0 : 16.0 / 9.0;
- return 1;
- }
- case STREAM_CTRL_GET_CURRENT_TIME: {
- double tm;
- tm = dvdnav_get_current_time(dvdnav) / 90000.0f;
- if (tm != -1) {
- *(double *)arg = tm;
- return 1;
- }
- break;
- }
- case STREAM_CTRL_GET_NUM_TITLES: {
- int32_t num_titles = 0;
- if (dvdnav_get_number_of_titles(dvdnav, &num_titles) != DVDNAV_STATUS_OK)
- break;
- *((unsigned int*)arg)= num_titles;
- return STREAM_OK;
- }
- case STREAM_CTRL_GET_CURRENT_TITLE: {
- if (dvdnav_current_title_info(dvdnav, &tit, &part) != DVDNAV_STATUS_OK)
- break;
- *((unsigned int *) arg) = tit - 1;
- return STREAM_OK;
- }
- case STREAM_CTRL_SET_CURRENT_TITLE: {
- int title = *((unsigned int *) arg);
- if (dvdnav_title_play(priv->dvdnav, title + 1) != DVDNAV_STATUS_OK)
- break;
- stream_drop_buffers(stream);
- return STREAM_OK;
- }
- case STREAM_CTRL_SEEK_TO_TIME: {
- double d = *(double *)arg;
- int64_t tm = (int64_t)(d * 90000);
- if (tm < 0)
- tm = 0;
- if (priv->duration && tm >= (priv->duration * 90))
- tm = priv->duration * 90 - 1;
- MP_VERBOSE(stream, "seek to PTS %f (%"PRId64")\n", d, tm);
- if (dvdnav_time_search(dvdnav, tm) != DVDNAV_STATUS_OK)
- break;
- stream_drop_buffers(stream);
- d = dvdnav_get_current_time(dvdnav) / 90000.0f;
- MP_VERBOSE(stream, "landed at: %f\n", d);
- return STREAM_OK;
- }
- case STREAM_CTRL_GET_NUM_ANGLES: {
- uint32_t curr, angles;
- if (dvdnav_get_angle_info(dvdnav, &curr, &angles) != DVDNAV_STATUS_OK)
- break;
- *(int *)arg = angles;
- return 1;
- }
- case STREAM_CTRL_GET_ANGLE: {
- uint32_t curr, angles;
- if (dvdnav_get_angle_info(dvdnav, &curr, &angles) != DVDNAV_STATUS_OK)
- break;
- *(int *)arg = curr;
- return 1;
- }
- case STREAM_CTRL_SET_ANGLE: {
- uint32_t curr, angles;
- int new_angle = *(int *)arg;
- if (dvdnav_get_angle_info(dvdnav, &curr, &angles) != DVDNAV_STATUS_OK)
- break;
- if (new_angle > angles || new_angle < 1)
- break;
- if (dvdnav_angle_change(dvdnav, new_angle) != DVDNAV_STATUS_OK)
- return 1;
- }
- case STREAM_CTRL_GET_LANG: {
- struct stream_lang_req *req = arg;
- int lang = 0;
- switch (req->type) {
- case STREAM_AUDIO:
- lang = mp_dvdnav_lang_from_aid(stream, req->id);
- break;
- case STREAM_SUB:
- lang = mp_dvdnav_lang_from_sid(stream, req->id);
- break;
- }
- if (!lang)
- break;
- snprintf(req->name, sizeof(req->name), "%c%c", lang >> 8, lang);
- return STREAM_OK;
- }
- case STREAM_CTRL_GET_DVD_INFO: {
- struct stream_dvd_info_req *req = arg;
- memset(req, 0, sizeof(*req));
- req->num_subs = mp_dvdnav_number_of_subs(stream);
- assert(sizeof(uint32_t) == sizeof(unsigned int));
- memcpy(req->palette, priv->spu_clut, sizeof(req->palette));
- return STREAM_OK;
- }
- case STREAM_CTRL_GET_NAV_EVENT: {
- struct mp_nav_event **ev = arg;
- if (ev)
- fill_next_event(stream, ev);
- return STREAM_OK;
- }
- case STREAM_CTRL_NAV_CMD: {
- handle_cmd(stream, (struct mp_nav_cmd *)arg);
- return STREAM_OK;
- }
- case STREAM_CTRL_GET_DISC_NAME: {
- const char *volume = NULL;
- if (dvdnav_get_title_string(dvdnav, &volume) != DVDNAV_STATUS_OK)
- break;
- if (!volume || !volume[0])
- break;
- *(char**)arg = talloc_strdup(NULL, volume);
- return STREAM_OK;
- }
- }
-
- return STREAM_UNSUPPORTED;
-}
-
-static void stream_dvdnav_close(stream_t *s)
-{
- struct priv *priv = s->priv;
- dvdnav_close(priv->dvdnav);
- priv->dvdnav = NULL;
- if (priv->dvd_speed)
- dvd_set_speed(s, priv->filename, -1);
- if (priv->filename)
- free(priv->filename);
-}
-
-static struct priv *new_dvdnav_stream(stream_t *stream, char *filename)
-{
- struct priv *priv = stream->priv;
- const char *title_str;
-
- if (!filename)
- return NULL;
-
- if (!(priv->filename = strdup(filename)))
- return NULL;
-
- priv->dvd_speed = stream->opts->dvd_speed;
- dvd_set_speed(stream, priv->filename, priv->dvd_speed);
-
- if (dvdnav_open(&(priv->dvdnav), priv->filename) != DVDNAV_STATUS_OK) {
- free(priv->filename);
- priv->filename = NULL;
- return NULL;
- }
-
- if (!priv->dvdnav)
- return NULL;
-
- dvdnav_set_readahead_flag(priv->dvdnav, 1);
- if (dvdnav_set_PGC_positioning_flag(priv->dvdnav, 1) != DVDNAV_STATUS_OK)
- MP_ERR(stream, "stream_dvdnav, failed to set PGC positioning\n");
- /* report the title?! */
- dvdnav_get_title_string(priv->dvdnav, &title_str);
-
- return priv;
-}
-
-static int open_s(stream_t *stream)
-{
- struct priv *priv, *p;
- priv = p = stream->priv;
- char *filename;
-
- if (p->device && p->device[0])
- filename = p->device;
- else if (stream->opts->dvd_device && stream->opts->dvd_device[0])
- filename = stream->opts->dvd_device;
- else
- filename = DEFAULT_DVD_DEVICE;
- if (!new_dvdnav_stream(stream, filename)) {
- MP_ERR(stream, "Couldn't open DVD device: %s\n",
- filename);
- return STREAM_UNSUPPORTED;
- }
-
- if (p->track == TITLE_LONGEST) { // longest
- dvdnav_t *dvdnav = priv->dvdnav;
- uint64_t best_length = 0;
- int best_title = -1;
- int32_t num_titles;
- if (dvdnav_get_number_of_titles(dvdnav, &num_titles) == DVDNAV_STATUS_OK) {
- for (int n = 1; n <= num_titles; n++) {
- uint64_t *parts = NULL, duration = 0;
- dvdnav_describe_title_chapters(dvdnav, n, &parts, &duration);
- if (parts) {
- if (duration > best_length) {
- best_length = duration;
- best_title = n;
- }
- free(parts);
- }
- }
- }
- p->track = best_title - 1;
- MP_INFO(stream, "Selecting title %d.\n", p->track);
- }
-
- if (p->track >= 0) {
- priv->title = p->track;
- if (dvdnav_title_play(priv->dvdnav, p->track + 1) != DVDNAV_STATUS_OK) {
- MP_FATAL(stream, "dvdnav_stream, couldn't select title %d, error '%s'\n",
- p->track, dvdnav_err_to_string(priv->dvdnav));
- return STREAM_UNSUPPORTED;
- }
- } else {
- if (dvdnav_menu_call(priv->dvdnav, DVD_MENU_Root) != DVDNAV_STATUS_OK)
- dvdnav_menu_call(priv->dvdnav, DVD_MENU_Title);
- }
- if (stream->opts->dvd_angle > 1)
- dvdnav_angle_change(priv->dvdnav, stream->opts->dvd_angle);
-
- stream->sector_size = 2048;
- stream->fill_buffer = fill_buffer;
- stream->control = control;
- stream->close = stream_dvdnav_close;
- stream->type = STREAMTYPE_DVD;
- stream->demuxer = "+disc";
- stream->lavf_type = "mpeg";
- stream->allow_caching = false;
-
- return STREAM_OK;
-}
-
-const stream_info_t stream_info_dvdnav = {
- .name = "dvdnav",
- .open = open_s,
- .protocols = (const char*const[]){ "dvd", "dvdnav", NULL },
- .priv_size = sizeof(struct priv),
- .priv_defaults = &stream_priv_dflts,
- .options = stream_opts_fields,
- .url_options = (const char*const[]){
- "hostname=title",
- "filename=device",
- NULL
- },
-};
diff --git a/sub/osd.c b/sub/osd.c
index e88df98afe..3a3c8b6c25 100644
--- a/sub/osd.c
+++ b/sub/osd.c
@@ -206,14 +206,6 @@ void osd_set_external2(struct osd_state *osd, struct sub_bitmaps *imgs)
pthread_mutex_unlock(&osd->lock);
}
-void osd_set_nav_highlight(struct osd_state *osd, void *priv)
-{
- pthread_mutex_lock(&osd->lock);
- osd->objs[OSDTYPE_NAV_HIGHLIGHT]->highlight_priv = priv;
- osd_changed_unlocked(osd, OSDTYPE_NAV_HIGHLIGHT);
- pthread_mutex_unlock(&osd->lock);
-}
-
static void render_object(struct osd_state *osd, struct osd_object *obj,
struct mp_osd_res res, double video_pts,
const bool sub_formats[SUBBITMAP_COUNT],
@@ -247,9 +239,6 @@ static void render_object(struct osd_state *osd, struct osd_object *obj,
*out_imgs = *obj->external2;
obj->external2->bitmap_id = obj->external2->bitmap_pos_id = 0;
}
- } else if (obj->type == OSDTYPE_NAV_HIGHLIGHT) {
- if (obj->highlight_priv)
- mp_nav_get_highlight(obj->highlight_priv, obj->vo_res, out_imgs);
} else {
osd_object_get_bitmaps(osd, obj, out_imgs);
}
diff --git a/sub/osd.h b/sub/osd.h
index 2a5bf71b05..97bc2f067d 100644
--- a/sub/osd.h
+++ b/sub/osd.h
@@ -84,8 +84,6 @@ enum mp_osdtype {
OSDTYPE_SUB,
OSDTYPE_SUB2,
- OSDTYPE_NAV_HIGHLIGHT, // dvdnav fake highlights
-
OSDTYPE_PROGBAR,
OSDTYPE_OSD,
@@ -174,8 +172,6 @@ void osd_set_external(struct osd_state *osd, int res_x, int res_y, char *text);
void osd_set_external2(struct osd_state *osd, struct sub_bitmaps *imgs);
-void osd_set_nav_highlight(struct osd_state *osd, void *priv);
-
enum mp_osd_draw_flags {
OSD_DRAW_SUB_FILTER = (1 << 0),
OSD_DRAW_SUB_ONLY = (1 << 1),
@@ -224,8 +220,4 @@ void osd_get_function_sym(char *buffer, size_t buffer_size, int osd_function);
void osd_object_get_resolution(struct osd_state *osd, int obj,
int *out_w, int *out_h);
-// defined in player
-void mp_nav_get_highlight(void *priv, struct mp_osd_res res,
- struct sub_bitmaps *out_imgs);
-
#endif /* MPLAYER_SUB_H */
diff --git a/wscript b/wscript
index bb55ba411e..288db5443a 100644
--- a/wscript
+++ b/wscript
@@ -281,19 +281,6 @@ If you really mean to compile without libass support use --disable-libass."
'desc' : 'lirc',
'func': check_cc(header_name='lirc/lirc_client.h', lib='lirc_client'),
}, {
- 'name': '--libbluray',
- 'desc': 'Bluray support',
- 'func': check_pkg_config('libbluray', '>= 0.3.0'),
- }, {
- 'name': '--dvdread',
- 'desc': 'dvdread support',
- 'func': check_pkg_config('dvdread', '>= 4.1.0'),
- }, {
- 'name': '--dvdnav',
- 'desc': 'dvdnav support',
- 'deps': [ 'dvdread' ],
- 'func': check_pkg_config('dvdnav', '>= 4.2.0'),
- }, {
'name': '--cdda',
'desc': 'cdda support (libcdio)',
'func': check_pkg_config('libcdio_paranoia'),
diff --git a/wscript_build.py b/wscript_build.py
index 62446d1907..c4d1be440e 100644
--- a/wscript_build.py
+++ b/wscript_build.py
@@ -174,7 +174,6 @@ 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"),
@@ -216,7 +215,6 @@ def build(ctx):
( "player/client.c" ),
( "player/command.c" ),
( "player/configfiles.c" ),
- ( "player/discnav.c" ),
( "player/loadfile.c" ),
( "player/main.c" ),
( "player/misc.c" ),
@@ -244,12 +242,8 @@ def build(ctx):
( "stream/rar.c" ),
( "stream/stream.c" ),
( "stream/stream_avdevice.c" ),
- ( "stream/stream_bluray.c", "libbluray" ),
( "stream/stream_cdda.c", "cdda" ),
( "stream/stream_dvb.c", "dvbin" ),
- ( "stream/stream_dvd.c", "dvdread" ),
- ( "stream/stream_dvd_common.c", "dvdread" ),
- ( "stream/stream_dvdnav.c", "dvdnav" ),
( "stream/stream_edl.c" ),
( "stream/stream_file.c" ),
( "stream/stream_lavf.c" ),