summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--command.c153
-rw-r--r--mp_core.h2
-rw-r--r--mplayer.c76
3 files changed, 138 insertions, 93 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;
}
}
diff --git a/mp_core.h b/mp_core.h
index 1a01109307..9ef9e6c972 100644
--- a/mp_core.h
+++ b/mp_core.h
@@ -169,7 +169,7 @@ typedef struct MPContext {
int global_sub_pos; // this encompasses all subtitle sources
int set_of_sub_pos;
int set_of_sub_size;
- int global_sub_indices[SUB_SOURCES];
+ int sub_counts[SUB_SOURCES];
// set_of_ass_tracks[i] contains subtitles from set_of_subtitles[i]
// parsed by libass or NULL if format unsupported
struct ass_track *set_of_ass_tracks[MAX_SUBTITLE_FILES];
diff --git a/mplayer.c b/mplayer.c
index ad25bd9cbd..f29edd7021 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -1949,33 +1949,43 @@ static float timing_sleep(struct MPContext *mpctx, float time_frame)
return time_frame;
}
-static void select_subtitle(MPContext *mpctx)
+static int select_subtitle(MPContext *mpctx)
{
struct MPOpts *opts = &mpctx->opts;
// find the best sub to use
- int vobsub_index_id = vobsub_get_index_by_id(vo_vobsub, vobsub_id);
+ int id;
+ int found = 0;
mpctx->global_sub_pos = -1; // no subs by default
- if (vobsub_index_id >= 0) {
+ if (vobsub_id >= 0) {
// if user asks for a vobsub id, use that first.
- mpctx->global_sub_pos = mpctx->global_sub_indices[SUB_SOURCE_VOBSUB] + vobsub_index_id;
- } else if (opts->sub_id >= 0 && mpctx->global_sub_indices[SUB_SOURCE_DEMUX] >= 0) {
+ id = vobsub_id;
+ found = mp_property_do("sub_vob", M_PROPERTY_SET, &id, mpctx) == M_PROPERTY_OK;
+ }
+
+ if (!found && opts->sub_id >= 0) {
// if user asks for a dvd sub id, use that next.
- mpctx->global_sub_pos = mpctx->global_sub_indices[SUB_SOURCE_DEMUX] + opts->sub_id;
- } else if (mpctx->global_sub_indices[SUB_SOURCE_SUBS] >= 0) {
+ id = opts->sub_id;
+ found = mp_property_do("sub_demux", M_PROPERTY_SET, &id, mpctx) == M_PROPERTY_OK;
+ }
+
+ if (!found) {
// if there are text subs to use, use those. (autosubs come last here)
- mpctx->global_sub_pos = mpctx->global_sub_indices[SUB_SOURCE_SUBS];
- } else if (opts->sub_id == -1 && mpctx->global_sub_indices[SUB_SOURCE_DEMUX] >= 0) {
+ id = 0;
+ found = mp_property_do("sub_file", M_PROPERTY_SET, &id, mpctx) == M_PROPERTY_OK;
+ }
+
+ if (!found && opts->sub_id == -1) {
// finally select subs by language and container hints
if (opts->sub_id == -1 && opts->sub_lang)
opts->sub_id = demuxer_sub_track_by_lang(mpctx->demuxer, opts->sub_lang);
if (opts->sub_id == -1)
opts->sub_id = demuxer_default_sub_track(mpctx->demuxer);
- if (opts->sub_id >= 0)
- mpctx->global_sub_pos = mpctx->global_sub_indices[SUB_SOURCE_DEMUX] + opts->sub_id;
+ if (opts->sub_id >= 0) {
+ id = opts->sub_id;
+ found = mp_property_do("sub_demux", M_PROPERTY_SET, &id, mpctx) == M_PROPERTY_OK;
+ }
}
- // rather than duplicate code, use the SUB_SELECT handler to init the right one.
- mpctx->global_sub_pos--;
- mp_property_do("sub",M_PROPERTY_STEP_UP,NULL, mpctx);
+ return found;
}
#ifdef CONFIG_DVDNAV
@@ -2035,7 +2045,7 @@ static void mp_dvdnav_reset_stream (MPContext *ctx) {
}
audio_delay = 0.0f;
- ctx->global_sub_size = ctx->global_sub_indices[SUB_SOURCE_DEMUX] + mp_dvdnav_number_of_subs(ctx->stream);
+ ctx->sub_counts[SUB_SOURCE_DEMUX] = mp_dvdnav_number_of_subs(ctx->stream);
if (opts->sub_lang && opts->sub_id == dvdsub_lang_id) {
dvdsub_lang_id = mp_dvdnav_sid_from_lang(ctx->stream, opts->sub_lang);
if (dvdsub_lang_id != opts->sub_id) {
@@ -3438,7 +3448,7 @@ play_next_file:
// init global sub numbers
mpctx->global_sub_size = 0;
- { int i; for (i = 0; i < SUB_SOURCES; i++) mpctx->global_sub_indices[i] = -1; }
+ memset(mpctx->sub_counts, 0, sizeof(mpctx->sub_counts));
if (mpctx->filename) {
load_per_protocol_config (mpctx->mconfig, mpctx->filename);
@@ -3586,8 +3596,7 @@ if (edl_output_filename) {
mp_property_do("sub_forced_only", M_PROPERTY_SET, &forced_subs_only, mpctx);
// setup global sub numbering
- mpctx->global_sub_indices[SUB_SOURCE_VOBSUB] = mpctx->global_sub_size; // the global # of the first vobsub.
- mpctx->global_sub_size += vobsub_get_indexes_count(vo_vobsub);
+ mpctx->sub_counts[SUB_SOURCE_VOBSUB] = vobsub_get_indexes_count(vo_vobsub);
}
//============ Open & Sync STREAM --- fork cache2 ====================
@@ -3677,8 +3686,7 @@ if(mpctx->stream->type==STREAMTYPE_DVD){
if(opts->audio_id==-1) opts->audio_id=dvd_aid_from_lang(mpctx->stream,opts->audio_lang);
if(opts->sub_lang && opts->sub_id==-1) opts->sub_id=dvd_sid_from_lang(mpctx->stream,opts->sub_lang);
// setup global sub numbering
- mpctx->global_sub_indices[SUB_SOURCE_DEMUX] = mpctx->global_sub_size; // the global # of the first demux-specific sub.
- mpctx->global_sub_size += dvd_number_of_subs(mpctx->stream);
+ mpctx->sub_counts[SUB_SOURCE_DEMUX] = dvd_number_of_subs(mpctx->stream);
current_module=NULL;
}
#endif
@@ -3691,8 +3699,7 @@ if(mpctx->stream->type==STREAMTYPE_DVDNAV){
if(opts->sub_lang && opts->sub_id==-1)
dvdsub_lang_id = opts->sub_id = mp_dvdnav_sid_from_lang(mpctx->stream,opts->sub_lang);
// setup global sub numbering
- mpctx->global_sub_indices[SUB_SOURCE_DEMUX] = mpctx->global_sub_size; // the global # of the first demux-specific sub.
- mpctx->global_sub_size += mp_dvdnav_number_of_subs(mpctx->stream);
+ mpctx->sub_counts[SUB_SOURCE_DEMUX] = mp_dvdnav_number_of_subs(mpctx->stream);
current_module=NULL;
}
#endif
@@ -3790,20 +3797,6 @@ if(!mpctx->demuxer)
mpctx->initialized_flags|=INITIALIZED_DEMUXER;
-if (mpctx->stream->type != STREAMTYPE_DVD && mpctx->stream->type != STREAMTYPE_DVDNAV) {
- int i;
- int maxid = -1;
- // setup global sub numbering
- mpctx->global_sub_indices[SUB_SOURCE_DEMUX] = mpctx->global_sub_size; // the global # of the first demux-specific sub.
- for (i = 0; i < MAX_S_STREAMS; i++)
- if (mpctx->demuxer->s_streams[i])
- maxid = FFMAX(maxid, mpctx->demuxer->s_streams[i]->sid);
- mpctx->global_sub_size += maxid + 1;
-}
-// Make opts->sub_id always selectable if set.
-if (mpctx->global_sub_size <= mpctx->global_sub_indices[SUB_SOURCE_DEMUX] + opts->sub_id)
- mpctx->global_sub_size = mpctx->global_sub_indices[SUB_SOURCE_DEMUX] + opts->sub_id + 1;
-
#ifdef CONFIG_ASS
if (opts->ass_enabled && ass_library) {
for (int j = 0; j < mpctx->num_sources; j++) {
@@ -3959,15 +3952,10 @@ if(vo_spudec==NULL &&
}
free(tmp);
}
- if (mpctx->set_of_sub_size > 0) {
- // setup global sub numbering
- mpctx->global_sub_indices[SUB_SOURCE_SUBS] = mpctx->global_sub_size; // the global # of the first sub.
- mpctx->global_sub_size += mpctx->set_of_sub_size;
- }
-
+ if (mpctx->set_of_sub_size > 0)
+ mpctx->sub_counts[SUB_SOURCE_SUBS] = mpctx->set_of_sub_size;
-if (mpctx->global_sub_size) {
- select_subtitle(mpctx);
+if (select_subtitle(mpctx)) {
if(subdata)
switch (stream_dump_type) {
case 3: list_sub_file(subdata); break;