summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--command.c72
-rw-r--r--etc/input.conf1
-rw-r--r--libmpdemux/demux_mkv.c3
-rw-r--r--libmpdemux/demuxer.h3
-rw-r--r--mp_core.h1
-rw-r--r--mplayer.c9
6 files changed, 84 insertions, 5 deletions
diff --git a/command.c b/command.c
index 065802b6d0..f0b17719db 100644
--- a/command.c
+++ b/command.c
@@ -434,6 +434,51 @@ static int mp_property_chapter(m_option_t *prop, int action, void *arg,
return M_PROPERTY_OK;
}
+static int mp_property_edition(m_option_t *prop, int action, void *arg,
+ MPContext *mpctx)
+{
+ struct MPOpts *opts = &mpctx->opts;
+ struct demuxer *demuxer = mpctx->master_demuxer;
+ if (!demuxer)
+ return M_PROPERTY_UNAVAILABLE;
+ if (demuxer->num_editions <= 0)
+ return M_PROPERTY_UNAVAILABLE;
+
+ int edition = demuxer->edition;
+
+ switch (action) {
+ case M_PROPERTY_GET:
+ case M_PROPERTY_PRINT:
+ return m_property_int_ro(prop, action, arg, edition);
+ case M_PROPERTY_SET:
+ if (!arg)
+ return M_PROPERTY_ERROR;
+ M_PROPERTY_CLAMP(prop, *(int *)arg);
+ edition = *(int *)arg;
+ break;
+ case M_PROPERTY_STEP_UP:
+ case M_PROPERTY_STEP_DOWN: {
+ edition += arg ? *(int *)arg : (action == M_PROPERTY_STEP_UP ? 1 : -1);
+ if (edition < 0)
+ edition = demuxer->num_editions - 1;
+ if (edition >= demuxer->num_editions)
+ edition = 0;
+ break;
+ }
+ default:
+ return M_PROPERTY_NOT_IMPLEMENTED;
+ }
+
+ if (edition != demuxer->edition) {
+ opts->edition_id = edition;
+ mpctx->stop_play = PT_RESTART;
+ set_osd_tmsg(mpctx, OSD_MSG_TEXT, 1, opts->osd_duration,
+ "Playing edition %d of %d.", edition + 1,
+ demuxer->num_editions);
+ }
+ return M_PROPERTY_OK;
+}
+
/// Number of titles in file
static int mp_property_titles(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
@@ -441,10 +486,9 @@ static int mp_property_titles(m_option_t *prop, int action, void *arg,
struct demuxer *demuxer = mpctx->master_demuxer;
if (!demuxer)
return M_PROPERTY_UNAVAILABLE;
- if (demuxer->num_titles == 0)
- stream_control(demuxer->stream, STREAM_CTRL_GET_NUM_TITLES,
- &demuxer->num_titles);
- return m_property_int_ro(prop, action, arg, demuxer->num_titles);
+ int num_titles = 0;
+ stream_control(demuxer->stream, STREAM_CTRL_GET_NUM_TITLES, &num_titles);
+ return m_property_int_ro(prop, action, arg, num_titles);
}
/// Number of chapters in file
@@ -457,6 +501,17 @@ static int mp_property_chapters(m_option_t *prop, int action, void *arg,
return m_property_int_ro(prop, action, arg, count);
}
+static int mp_property_editions(m_option_t *prop, int action, void *arg,
+ MPContext *mpctx)
+{
+ struct demuxer *demuxer = mpctx->master_demuxer;
+ if (!demuxer)
+ return M_PROPERTY_UNAVAILABLE;
+ if (demuxer->num_editions <= 0)
+ return M_PROPERTY_UNAVAILABLE;
+ return m_property_int_ro(prop, action, arg, demuxer->num_editions);
+}
+
/// Current dvd angle (RW)
static int mp_property_angle(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
@@ -1638,10 +1693,13 @@ static const m_option_t mp_properties[] = {
M_OPT_MIN, 0, 0, NULL },
{ "chapter", mp_property_chapter, CONF_TYPE_INT,
M_OPT_MIN, 0, 0, NULL },
+ { "edition", mp_property_edition, CONF_TYPE_INT,
+ M_OPT_MIN, -1, 0, NULL },
{ "titles", mp_property_titles, CONF_TYPE_INT,
0, 0, 0, NULL },
{ "chapters", mp_property_chapters, CONF_TYPE_INT,
0, 0, 0, NULL },
+ { "editions", mp_property_editions, CONF_TYPE_INT },
{ "angle", mp_property_angle, CONF_TYPE_INT,
CONF_RANGE, -2, 10, NULL },
{ "metadata", mp_property_metadata, CONF_TYPE_STRING_LIST,
@@ -2110,6 +2168,12 @@ static void show_tracks_on_osd(MPContext *mpctx)
res = talloc_asprintf_append(res, "\n");
}
+ struct demuxer *demuxer = mpctx->master_demuxer;
+ if (demuxer && demuxer->num_editions > 1)
+ res = talloc_asprintf_append(res, "\nEdition: %d of %d\n",
+ demuxer->edition + 1,
+ demuxer->num_editions);
+
set_osd_msg(mpctx, OSD_MSG_TEXT, 1, opts->osd_duration, "%s", res);
talloc_free(res);
}
diff --git a/etc/input.conf b/etc/input.conf
index a7732acf01..3744df8431 100644
--- a/etc/input.conf
+++ b/etc/input.conf
@@ -125,6 +125,7 @@ MUTE mute
CLOSE_WIN quit
! seek_chapter -1 # skip to previous chapter
@ seek_chapter 1 # next
+E step_property_osd edition # next edition
A switch_angle 1
U stop
diff --git a/libmpdemux/demux_mkv.c b/libmpdemux/demux_mkv.c
index b5ab880916..3943bff733 100644
--- a/libmpdemux/demux_mkv.c
+++ b/libmpdemux/demux_mkv.c
@@ -856,6 +856,9 @@ static int demux_mkv_read_chapters(struct demuxer *demuxer)
"[mkv] Found %d editions, will play #%d (first is 0).\n",
num_editions, selected_edition);
+ demuxer->num_editions = num_editions;
+ demuxer->edition = selected_edition;
+
talloc_free(parse_ctx.talloc_ctx);
mp_msg(MSGT_DEMUX, MSGL_V,
"[mkv] \\---- [ parsing chapters ] ---------\n");
diff --git a/libmpdemux/demuxer.h b/libmpdemux/demuxer.h
index cf81ce988c..f2236c6016 100644
--- a/libmpdemux/demuxer.h
+++ b/libmpdemux/demuxer.h
@@ -249,7 +249,8 @@ typedef struct demuxer {
struct sh_stream **streams;
int num_streams;
- int num_titles;
+ int num_editions;
+ int edition;
struct demux_chapter *chapters;
int num_chapters;
diff --git a/mp_core.h b/mp_core.h
index 04a3dac735..ea21752767 100644
--- a/mp_core.h
+++ b/mp_core.h
@@ -55,6 +55,7 @@ enum stop_play_reason {
PT_NEXT_ENTRY, // prepare to play next entry in playlist
PT_CURRENT_ENTRY, // prepare to play mpctx->playlist->current
PT_STOP, // stop playback, clear playlist
+ PT_RESTART, // restart previous file
PT_QUIT, // stop playback, quit player
};
diff --git a/mplayer.c b/mplayer.c
index fd409cc27c..f27551cd1b 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -516,6 +516,11 @@ static void print_file_properties(struct MPContext *mpctx, const char *filename)
}
}
}
+ struct demuxer *demuxer = mpctx->master_demuxer;
+ if (demuxer->num_editions > 1)
+ mp_msg(MSGT_CPLAYER, MSGL_INFO,
+ "Playing edition %d of %d (--edition=%d).\n",
+ demuxer->edition + 1, demuxer->num_editions, demuxer->edition);
for (int t = 0; t < STREAM_TYPE_COUNT; t++) {
for (int n = 0; n < mpctx->num_tracks; n++)
if (mpctx->tracks[n]->type == t)
@@ -4023,6 +4028,10 @@ static void play_files(struct MPContext *mpctx)
new_entry = playlist_get_next(mpctx->playlist, +1);
} else if (mpctx->stop_play == PT_CURRENT_ENTRY) {
new_entry = mpctx->playlist->current;
+ } else if (mpctx->stop_play == PT_RESTART) {
+ // The same as PT_CURRENT_ENTRY, unless we decide that the current
+ // playlist entry can be removed during playback.
+ new_entry = mpctx->playlist->current;
} else { // PT_STOP
playlist_clear(mpctx->playlist);
}