summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/input.rst27
-rw-r--r--player/command.c33
-rw-r--r--stream/stream.h57
-rw-r--r--stream/stream_dvd.c12
-rw-r--r--stream/stream_dvdnav.c16
5 files changed, 123 insertions, 22 deletions
diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst
index dd2c20bee3..5bfa7c3150 100644
--- a/DOCS/man/input.rst
+++ b/DOCS/man/input.rst
@@ -773,6 +773,33 @@ Property list
``disc-titles``
Number of BD/DVD titles.
+ This has a number of sub-properties. Replace ``N`` with the 0-based edition
+ index.
+
+ ``disc-titles/count``
+ Number of titles.
+
+ ``disc-titles/id``
+ Title ID as integer. Currently, this is the same as the title index.
+
+ ``disc-titles/length``
+ Length in seconds. Can be unavailable in a number of cases (currently
+ it works for libdvdnav only).
+
+ When querying the property with the client API using ``MPV_FORMAT_NODE``,
+ or with Lua ``mp.get_property_native``, this will return a mpv_node with
+ the following contents:
+
+ ::
+
+ MPV_FORMAT_NODE_ARRAY
+ MPV_FORMAT_NODE_MAP (for each edition)
+ "id" MPV_FORMAT_INT64
+ "length" MPV_FORMAT_DOUBLE
+
+``disc-title-list``
+ List of BD/DVD titles.
+
``disc-title`` (RW)
Current BD/DVD title number. Writing works only for ``dvdnav://`` and
``bd://`` (and aliases for these).
diff --git a/player/command.c b/player/command.c
index 1b7156bb6c..febbb785b0 100644
--- a/player/command.c
+++ b/player/command.c
@@ -910,6 +910,38 @@ static int mp_property_disc_titles(void *ctx, struct m_property *prop,
return m_property_int_ro(action, arg, num_titles);
}
+static int get_disc_title_entry(int item, int action, void *arg, void *ctx)
+{
+ struct MPContext *mpctx = ctx;
+ struct demuxer *demuxer = mpctx->master_demuxer;
+
+ double len = item;
+ if (demux_stream_control(demuxer, STREAM_CTRL_GET_TITLE_LENGTH, &len) < 1)
+ len = -1;
+
+ struct m_sub_property props[] = {
+ {"id", SUB_PROP_INT(item)},
+ {"length", {.type = CONF_TYPE_TIME}, {.time = len},
+ .unavailable = len < 0},
+ {0}
+ };
+
+ return m_property_read_sub(props, action, arg);
+}
+
+static int mp_property_list_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 || demux_stream_control(demuxer, STREAM_CTRL_GET_NUM_TITLES,
+ &num_titles) < 1)
+ return M_PROPERTY_UNAVAILABLE;
+ return m_property_read_list(action, arg, num_titles,
+ get_disc_title_entry, mpctx);
+}
+
/// Number of chapters in file
static int mp_property_chapters(void *ctx, struct m_property *prop,
int action, void *arg)
@@ -3227,6 +3259,7 @@ static const struct m_property mp_properties[] = {
{"chapter-list", mp_property_list_chapters},
{"track-list", property_list_tracks},
{"edition-list", property_list_editions},
+ {"disc-title-list", mp_property_list_disc_titles},
{"playlist", mp_property_playlist},
{"playlist-pos", mp_property_playlist_pos},
diff --git a/stream/stream.h b/stream/stream.h
index ccbee9cc1b..4c9805dab3 100644
--- a/stream/stream.h
+++ b/stream/stream.h
@@ -65,33 +65,28 @@ enum streamtype {
#define STREAM_OK 1
enum stream_ctrl {
- STREAM_CTRL_GET_TIME_LENGTH = 1,
- STREAM_CTRL_GET_NUM_CHAPTERS,
- STREAM_CTRL_GET_CURRENT_TIME,
- 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,
- STREAM_CTRL_SET_CURRENT_TITLE,
+ STREAM_CTRL_GET_SIZE = 1,
+
+ // Cache
STREAM_CTRL_GET_CACHE_SIZE,
STREAM_CTRL_SET_CACHE_SIZE,
STREAM_CTRL_GET_CACHE_FILL,
STREAM_CTRL_GET_CACHE_IDLE,
STREAM_CTRL_RESUME_CACHE,
- STREAM_CTRL_RECONNECT,
- STREAM_CTRL_GET_CHAPTER_TIME,
- STREAM_CTRL_GET_DVD_INFO,
+
+ // stream_memory.c
STREAM_CTRL_SET_CONTENTS,
- STREAM_CTRL_GET_METADATA,
+
+ // stream_rar.c
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,
+
+ // Certain network protocols
+ STREAM_CTRL_RECONNECT,
+ STREAM_CTRL_AVSEEK,
+ STREAM_CTRL_HAS_AVSEEK,
+ STREAM_CTRL_GET_METADATA,
+
+ // TV
STREAM_CTRL_TV_SET_SCAN,
STREAM_CTRL_SET_TV_FREQ,
STREAM_CTRL_GET_TV_FREQ,
@@ -104,8 +99,26 @@ enum stream_ctrl {
STREAM_CTRL_TV_LAST_CHAN,
STREAM_CTRL_DVB_SET_CHANNEL,
STREAM_CTRL_DVB_STEP_CHANNEL,
- STREAM_CTRL_AVSEEK,
- STREAM_CTRL_HAS_AVSEEK,
+
+ // Optical discs
+ STREAM_CTRL_GET_TIME_LENGTH,
+ STREAM_CTRL_GET_DVD_INFO,
+ STREAM_CTRL_GET_NAV_EVENT, // struct mp_nav_event**
+ STREAM_CTRL_NAV_CMD, // struct mp_nav_cmd*
+ STREAM_CTRL_GET_DISC_NAME,
+ STREAM_CTRL_GET_NUM_CHAPTERS,
+ STREAM_CTRL_GET_CURRENT_TIME,
+ STREAM_CTRL_GET_CHAPTER_TIME,
+ STREAM_CTRL_SEEK_TO_TIME,
+ 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_TITLE_LENGTH, // double* (in: title number, out: len)
+ STREAM_CTRL_GET_LANG,
+ STREAM_CTRL_GET_CURRENT_TITLE,
+ STREAM_CTRL_SET_CURRENT_TITLE,
};
struct stream_lang_req {
diff --git a/stream/stream_dvd.c b/stream/stream_dvd.c
index 5ec1e522bd..5be70b2d1d 100644
--- a/stream/stream_dvd.c
+++ b/stream/stream_dvd.c
@@ -541,6 +541,18 @@ static int control(stream_t *stream,int cmd,void* arg)
*((unsigned int *)arg) = d->vmg_file->tt_srpt->nr_of_srpts;
return 1;
}
+ case STREAM_CTRL_GET_TITLE_LENGTH:
+ {
+ int t = *(double *)arg;
+ if (t < 0 || t >= d->vmg_file->tt_srpt->nr_of_srpts)
+ break;
+ if (d->tt_srpt->title[t].title_set_nr !=
+ d->tt_srpt->title[d->dvd_title].title_set_nr)
+ break;
+ *(double *)arg =
+ mp_get_titleset_length(d->vts_file, d->tt_srpt, t) / 1000.0;
+ return 1;
+ }
case STREAM_CTRL_GET_NUM_CHAPTERS:
{
int r;
diff --git a/stream/stream_dvdnav.c b/stream/stream_dvdnav.c
index be116e65ba..c1513e9e85 100644
--- a/stream/stream_dvdnav.c
+++ b/stream/stream_dvdnav.c
@@ -535,6 +535,22 @@ static int control(stream_t *stream, int cmd, void *arg)
*((unsigned int*)arg)= num_titles;
return STREAM_OK;
}
+ case STREAM_CTRL_GET_TITLE_LENGTH: {
+ int t = *(double *)arg;
+ int32_t num_titles = 0;
+ if (dvdnav_get_number_of_titles(dvdnav, &num_titles) != DVDNAV_STATUS_OK)
+ break;
+ if (t < 0 || t >= num_titles)
+ break;
+ uint64_t duration = 0;
+ uint64_t *parts = NULL;
+ dvdnav_describe_title_chapters(dvdnav, t + 1, &parts, &duration);
+ if (!parts)
+ break;
+ free(parts);
+ *(double *)arg = duration / 90000.0;
+ return STREAM_OK;
+ }
case STREAM_CTRL_GET_CURRENT_TITLE: {
if (dvdnav_current_title_info(dvdnav, &tit, &part) != DVDNAV_STATUS_OK)
break;