From 1663d97a112261c10f989b70547545048f9e31c3 Mon Sep 17 00:00:00 2001 From: reimar Date: Sat, 10 Jul 2010 20:48:50 +0000 Subject: subs: Change global subtitle numbering scheme Change numbering so that demuxers can "asynchronously" add subtitles during playback. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@31678 b3059339-0415-0410-9bf9-f77b7e298cf2 Fix calculation of global_sub_size. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@31711 b3059339-0415-0410-9bf9-f77b7e298cf2 Update global_sub_pos if we auto-selected a subtitle. This avoid strange behaviour with subtitle selection in that case, because the subtitle selection code thinks no subtitle was displayed while we actually did display one. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@31863 b3059339-0415-0410-9bf9-f77b7e298cf2 Move function to avoid a forward declaration. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@31864 b3059339-0415-0410-9bf9-f77b7e298cf2 Fix subtitle selection: make selecting -sid 0 work again by replacing the M_PROPERTY_STEP_UP hack by M_PROPERTY_SET and set the global sub pos also when we do not yet have a subtitle stream but do know the number of subs from out-of-band as e.g. for DVD. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@31882 b3059339-0415-0410-9bf9-f77b7e298cf2 100l, re-add vobsub_get_id_by_index call accidentally removed in r31678. Patch by ubitux [ubitux gmail com]. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@31985 b3059339-0415-0410-9bf9-f77b7e298cf2 --- command.c | 153 ++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 105 insertions(+), 48 deletions(-) (limited to 'command.c') 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; } } -- cgit v1.2.3