summaryrefslogtreecommitdiffstats
path: root/command.c
diff options
context:
space:
mode:
Diffstat (limited to 'command.c')
-rw-r--r--command.c153
1 files changed, 105 insertions, 48 deletions
diff --git a/command.c b/command.c
index 8c3ad5d778..3a9c3aa179 100644
--- a/command.c
+++ b/command.c
@@ -103,19 +103,42 @@ static void rescale_input_coordinates(struct MPContext *mpctx, int ix, int iy,
vo->dheight, vo_fs);
}
-static int sub_source_by_pos(MPContext *mpctx, int pos)
+static int sub_pos_by_source(MPContext *mpctx, int src)
+{
+ int i, cnt = 0;
+ if (src >= SUB_SOURCES || mpctx->sub_counts[src] == 0)
+ return -1;
+ for (i = 0; i < src; i++)
+ cnt += mpctx->sub_counts[i];
+ return cnt;
+}
+
+static int sub_source_and_index_by_pos(MPContext *mpctx, int *pos)
{
- int source = -1;
- int top = -1;
+ int start = 0;
int i;
for (i = 0; i < SUB_SOURCES; i++) {
- int j = mpctx->global_sub_indices[i];
- if ((j >= 0) && (j > top) && (pos >= j)) {
- source = i;
- top = j;
+ int cnt = mpctx->sub_counts[i];
+ if (*pos >= start && *pos < start + cnt) {
+ *pos -= start;
+ return i;
}
+ start += cnt;
}
- return source;
+ *pos = -1;
+ return -1;
+}
+
+static int sub_source_by_pos(MPContext *mpctx, int pos)
+{
+ return sub_source_and_index_by_pos(mpctx, &pos);
+}
+
+static int sub_source_pos(MPContext *mpctx)
+{
+ int pos = mpctx->global_sub_pos;
+ sub_source_and_index_by_pos(mpctx, &pos);
+ return pos;
}
static int sub_source(MPContext *mpctx)
@@ -123,6 +146,37 @@ static int sub_source(MPContext *mpctx)
return sub_source_by_pos(mpctx, mpctx->global_sub_pos);
}
+static void update_global_sub_size(MPContext *mpctx)
+{
+ struct MPOpts *opts = &mpctx->opts;
+ int i;
+ int cnt = 0;
+
+ // update number of demuxer sub streams
+ for (i = 0; i < MAX_S_STREAMS; i++)
+ if (mpctx->demuxer->s_streams[i])
+ cnt++;
+ if (cnt > mpctx->sub_counts[SUB_SOURCE_DEMUX])
+ mpctx->sub_counts[SUB_SOURCE_DEMUX] = cnt;
+
+ // update global size
+ mpctx->global_sub_size = 0;
+ for (i = 0; i < SUB_SOURCES; i++)
+ mpctx->global_sub_size += mpctx->sub_counts[i];
+
+ // update global_sub_pos if we auto-detected a demuxer sub
+ if (mpctx->global_sub_pos == -1) {
+ int sub_id = -1;
+ if (mpctx->demuxer->sub)
+ sub_id = mpctx->demuxer->sub->id;
+ if (sub_id < 0)
+ sub_id = opts->sub_id;
+ if (sub_id >= 0 && sub_id < mpctx->sub_counts[SUB_SOURCE_DEMUX])
+ mpctx->global_sub_pos = sub_pos_by_source(mpctx, SUB_SOURCE_DEMUX) +
+ sub_id;
+ }
+}
+
/**
* \brief Log the currently displayed subtitle to a file
*
@@ -1400,10 +1454,13 @@ static int mp_property_sub(m_option_t *prop, int action, void *arg,
{
struct MPOpts *opts = &mpctx->opts;
demux_stream_t *const d_sub = mpctx->d_sub;
- const int global_sub_size = mpctx->global_sub_size;
int source = -1, reset_spu = 0;
+ int source_pos = -1;
char *sub_name;
+ update_global_sub_size(mpctx);
+ const int global_sub_size = mpctx->global_sub_size;
+
if (global_sub_size <= 0)
return M_PROPERTY_UNAVAILABLE;
@@ -1510,15 +1567,17 @@ static int mp_property_sub(m_option_t *prop, int action, void *arg,
return M_PROPERTY_NOT_IMPLEMENTED;
}
- if (mpctx->global_sub_pos >= 0)
+ if (mpctx->global_sub_pos >= 0) {
source = sub_source(mpctx);
+ source_pos = sub_source_pos(mpctx);
+ }
mp_msg(MSGT_CPLAYER, MSGL_DBG3,
"subtitles: %d subs, (v@%d s@%d d@%d), @%d, source @%d\n",
global_sub_size,
- mpctx->global_sub_indices[SUB_SOURCE_VOBSUB],
- mpctx->global_sub_indices[SUB_SOURCE_SUBS],
- mpctx->global_sub_indices[SUB_SOURCE_DEMUX],
+ mpctx->sub_counts[SUB_SOURCE_VOBSUB],
+ mpctx->sub_counts[SUB_SOURCE_SUBS],
+ mpctx->sub_counts[SUB_SOURCE_DEMUX],
mpctx->global_sub_pos, source);
mpctx->set_of_sub_pos = -1;
@@ -1536,10 +1595,9 @@ static int mp_property_sub(m_option_t *prop, int action, void *arg,
#endif
if (source == SUB_SOURCE_VOBSUB) {
- vobsub_id = vobsub_get_id_by_index(vo_vobsub, mpctx->global_sub_pos - mpctx->global_sub_indices[SUB_SOURCE_VOBSUB]);
+ vobsub_id = vobsub_get_id_by_index(vo_vobsub, source_pos);
} else if (source == SUB_SOURCE_SUBS) {
- mpctx->set_of_sub_pos =
- mpctx->global_sub_pos - mpctx->global_sub_indices[SUB_SOURCE_SUBS];
+ mpctx->set_of_sub_pos = source_pos;
#ifdef CONFIG_ASS
if (opts->ass_enabled && mpctx->set_of_ass_tracks[mpctx->set_of_sub_pos])
ass_track = mpctx->set_of_ass_tracks[mpctx->set_of_sub_pos];
@@ -1550,8 +1608,7 @@ static int mp_property_sub(m_option_t *prop, int action, void *arg,
vo_osd_changed(OSDTYPE_SUBTITLE);
}
} else if (source == SUB_SOURCE_DEMUX) {
- opts->sub_id =
- mpctx->global_sub_pos - mpctx->global_sub_indices[SUB_SOURCE_DEMUX];
+ opts->sub_id = source_pos;
if (d_sub && opts->sub_id < MAX_S_STREAMS) {
int i = 0;
// default: assume 1:1 mapping of sid and stream id
@@ -1600,6 +1657,7 @@ static int mp_property_sub_source(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
{
int source;
+ update_global_sub_size(mpctx);
if (!mpctx->sh_video || mpctx->global_sub_size <= 0)
return M_PROPERTY_UNAVAILABLE;
@@ -1636,9 +1694,10 @@ static int mp_property_sub_source(m_option_t *prop, int action, void *arg,
if (*(int *) arg < 0)
mpctx->global_sub_pos = -1;
else if (*(int *) arg != sub_source(mpctx)) {
- if (*(int *) arg != sub_source_by_pos(mpctx, mpctx->global_sub_indices[*(int *) arg]))
+ int new_pos = sub_pos_by_source(mpctx, *(int *)arg);
+ if (new_pos == -1)
return M_PROPERTY_UNAVAILABLE;
- mpctx->global_sub_pos = mpctx->global_sub_indices[*(int *) arg];
+ mpctx->global_sub_pos = new_pos;
}
break;
case M_PROPERTY_STEP_UP:
@@ -1655,7 +1714,7 @@ static int mp_property_sub_source(m_option_t *prop, int action, void *arg,
else if (source < -1)
source = SUB_SOURCES - 1;
if (source == cur_source || source == -1 ||
- source == sub_source_by_pos(mpctx, mpctx->global_sub_indices[source]))
+ mpctx->sub_counts[source])
step_all -= step;
}
if (source == cur_source)
@@ -1663,7 +1722,7 @@ static int mp_property_sub_source(m_option_t *prop, int action, void *arg,
if (source == -1)
mpctx->global_sub_pos = -1;
else
- mpctx->global_sub_pos = mpctx->global_sub_indices[source];
+ mpctx->global_sub_pos = sub_pos_by_source(mpctx, source);
break;
}
default:
@@ -1677,7 +1736,8 @@ static int mp_property_sub_source(m_option_t *prop, int action, void *arg,
static int mp_property_sub_by_type(m_option_t *prop, int action, void *arg,
MPContext *mpctx)
{
- int source, is_cur_source, offset;
+ int source, is_cur_source, offset, new_pos;
+ update_global_sub_size(mpctx);
if (!mpctx->sh_video || mpctx->global_sub_size <= 0)
return M_PROPERTY_UNAVAILABLE;
@@ -1690,17 +1750,18 @@ static int mp_property_sub_by_type(m_option_t *prop, int action, void *arg,
else
return M_PROPERTY_ERROR;
- offset = mpctx->global_sub_indices[source];
- if (offset < 0 || source != sub_source_by_pos(mpctx, offset))
+ offset = sub_pos_by_source(mpctx, source);
+ if (offset < 0)
return M_PROPERTY_UNAVAILABLE;
is_cur_source = sub_source(mpctx) == source;
+ new_pos = mpctx->global_sub_pos;
switch (action) {
case M_PROPERTY_GET:
if (!arg)
return M_PROPERTY_ERROR;
if (is_cur_source) {
- *(int *) arg = mpctx->global_sub_pos - offset;
+ *(int *) arg = sub_source_pos(mpctx);
if (source == SUB_SOURCE_VOBSUB)
*(int *) arg = vobsub_get_id_by_index(vo_vobsub, *(int *) arg);
}
@@ -1723,15 +1784,14 @@ static int mp_property_sub_by_type(m_option_t *prop, int action, void *arg,
int index = *(int *)arg;
if (source == SUB_SOURCE_VOBSUB)
index = vobsub_get_index_by_id(vo_vobsub, index);
- mpctx->global_sub_pos = offset + index;
- if (index < 0 || mpctx->global_sub_pos >= mpctx->global_sub_size
- || sub_source(mpctx) != source) {
- mpctx->global_sub_pos = -1;
+ new_pos = offset + index;
+ if (index < 0 || index > mpctx->sub_counts[source]) {
+ new_pos = -1;
*(int *) arg = -1;
}
}
else
- mpctx->global_sub_pos = -1;
+ new_pos = -1;
break;
case M_PROPERTY_STEP_UP:
case M_PROPERTY_STEP_DOWN: {
@@ -1740,27 +1800,27 @@ static int mp_property_sub_by_type(m_option_t *prop, int action, void *arg,
int step = (step_all > 0) ? 1 : -1;
int max_sub_pos_for_source = -1;
if (!is_cur_source)
- mpctx->global_sub_pos = -1;
+ new_pos = -1;
while (step_all) {
- if (mpctx->global_sub_pos == -1) {
+ if (new_pos == -1) {
if (step > 0)
- mpctx->global_sub_pos = offset;
+ new_pos = offset;
else if (max_sub_pos_for_source == -1) {
// Find max pos for specific source
- mpctx->global_sub_pos = mpctx->global_sub_size - 1;
- while (mpctx->global_sub_pos >= 0
+ new_pos = mpctx->global_sub_size - 1;
+ while (new_pos >= 0
&& sub_source(mpctx) != source)
- --mpctx->global_sub_pos;
+ new_pos--;
}
else
- mpctx->global_sub_pos = max_sub_pos_for_source;
+ new_pos = max_sub_pos_for_source;
}
else {
- mpctx->global_sub_pos += step;
- if (mpctx->global_sub_pos < offset ||
- mpctx->global_sub_pos >= mpctx->global_sub_size ||
+ new_pos += step;
+ if (new_pos < offset ||
+ new_pos >= mpctx->global_sub_size ||
sub_source(mpctx) != source)
- mpctx->global_sub_pos = -1;
+ new_pos = -1;
}
step_all -= step;
}
@@ -1769,8 +1829,7 @@ static int mp_property_sub_by_type(m_option_t *prop, int action, void *arg,
default:
return M_PROPERTY_NOT_IMPLEMENTED;
}
- --mpctx->global_sub_pos;
- return mp_property_sub(prop, M_PROPERTY_STEP_UP, NULL, mpctx);
+ return mp_property_sub(prop, M_PROPERTY_SET, &new_pos, mpctx);
}
/// Subtitle delay (RW)
@@ -2545,7 +2604,7 @@ static void remove_subtitle_range(MPContext *mpctx, int start, int count)
mpctx->global_sub_size -= count;
mpctx->set_of_sub_size -= count;
if (mpctx->set_of_sub_size <= 0)
- mpctx->global_sub_indices[SUB_SOURCE_SUBS] = -1;
+ mpctx->sub_counts[SUB_SOURCE_SUBS] = 0;
memmove(subs + start, subs + end, after * sizeof(*subs));
memset(subs + start + after, 0, count * sizeof(*subs));
@@ -3133,9 +3192,7 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
int n = mpctx->set_of_sub_size;
add_subtitles(mpctx, cmd->args[0].v.s, sh_video->fps, 0);
if (n != mpctx->set_of_sub_size) {
- if (mpctx->global_sub_indices[SUB_SOURCE_SUBS] < 0)
- mpctx->global_sub_indices[SUB_SOURCE_SUBS] =
- mpctx->global_sub_size;
+ mpctx->sub_counts[SUB_SOURCE_SUBS]++;
++mpctx->global_sub_size;
}
}