From 804bf91570a24b949a6c68530daaf9162df9a234 Mon Sep 17 00:00:00 2001 From: mplayer-svn Date: Sun, 19 Feb 2012 13:15:41 +0000 Subject: commands, dvd, dvdnav, bluray: cleanup sub/audio track language display Code cleanup: Use a stream_control instead of global functions to get the language associate with a audio or subtitle stream from the streaming layer. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@34736 b3059339-0415-0410-9bf9-f77b7e298cf2 Support showing the stream language with br:// playback. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@34737 b3059339-0415-0410-9bf9-f77b7e298cf2 Fix DVDs showing the subtitle language as "unknown" for a long time. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@34777 b3059339-0415-0410-9bf9-f77b7e298cf2 Author: reimar Note: heavily modified by wm4 for this fork of mplayer. --- command.c | 76 ++++++++------------------------------------------ libmpdemux/demuxer.c | 36 ++++++++++++++++++++++++ libmpdemux/demuxer.h | 3 ++ stream/cache2.c | 9 ++++++ stream/stream.h | 13 ++++++++- stream/stream_bluray.c | 30 ++++++++++++++++++++ stream/stream_dvd.c | 22 +++++++++++++-- stream/stream_dvd.h | 2 -- stream/stream_dvdnav.c | 44 ++++++++++++++++++----------- stream/stream_dvdnav.h | 2 -- 10 files changed, 150 insertions(+), 87 deletions(-) diff --git a/command.c b/command.c index dd7a1ee34c..053ac653ee 100644 --- a/command.c +++ b/command.c @@ -941,36 +941,21 @@ static int mp_property_audio(m_option_t *prop, int action, void *arg, if (!arg) return M_PROPERTY_ERROR; - if (current_id < 0) + if (!sh || current_id < 0) *(char **) arg = talloc_strdup(NULL, mp_gtext("disabled")); - else if (sh && (sh->lang || sh->title)) { - char *lang = sh->lang ? sh->lang : mp_gtext("unknown"); + else { + char *lang = demuxer_audio_lang(mpctx->demuxer, current_id); + if (!lang) + lang = talloc_strdup(NULL, mp_gtext("unknown")); + if (sh->title) *(char **)arg = talloc_asprintf(NULL, "(%d) %s (\"%s\")", current_id, lang, sh->title); else *(char **)arg = talloc_asprintf(NULL, "(%d) %s", current_id, lang); - } else { - char lang[40]; - strncpy(lang, mp_gtext("unknown"), sizeof(lang)); - if (0) ; -#ifdef CONFIG_DVDREAD - else if (mpctx->stream->type == STREAMTYPE_DVD) { - int code = dvd_lang_from_aid(mpctx->stream, current_id); - if (code) { - lang[0] = code >> 8; - lang[1] = code; - lang[2] = 0; - } - } -#endif -#ifdef CONFIG_DVDNAV - else if (mpctx->stream->type == STREAMTYPE_DVDNAV) - mp_dvdnav_lang_from_aid(mpctx->stream, current_id, lang); -#endif - *(char **)arg = talloc_asprintf(NULL, "(%d) %s", current_id, lang); + talloc_free(lang); } return M_PROPERTY_OK; @@ -1572,34 +1557,6 @@ static int mp_property_sub(m_option_t *prop, int action, void *arg, strlen(tmp) < 20 ? tmp : tmp + strlen(tmp) - 19); return M_PROPERTY_OK; } -#ifdef CONFIG_DVDNAV - if (mpctx->stream->type == STREAMTYPE_DVDNAV) { - if (vo_spudec && opts->sub_id >= 0) { - unsigned char lang[3]; - if (mp_dvdnav_lang_from_sid(mpctx->stream, opts->sub_id, - lang)) { - *(char **) arg = talloc_asprintf(NULL, "(%d) %s", - opts->sub_id, lang); - return M_PROPERTY_OK; - } - } - } -#endif - - if ((d_sub->demuxer->type == DEMUXER_TYPE_MATROSKA - || d_sub->demuxer->type == DEMUXER_TYPE_LAVF - || d_sub->demuxer->type == DEMUXER_TYPE_LAVF_PREFERRED) - && d_sub->sh && opts->sub_id >= 0) { - struct sh_sub *sh = d_sub->sh; - char *lang = sh->lang ? sh->lang : mp_gtext("unknown"); - if (sh->title) - *(char **)arg = talloc_asprintf(NULL, "(%d) %s (\"%s\")", - opts->sub_id, lang, sh->title); - else - *(char **)arg = talloc_asprintf(NULL, "(%d) %s", - opts->sub_id, lang); - return M_PROPERTY_OK; - } if (vo_vobsub && vobsub_id >= 0) { const char *language = mp_gtext("unknown"); @@ -1608,22 +1565,13 @@ static int mp_property_sub(m_option_t *prop, int action, void *arg, vobsub_id, language ? language : mp_gtext("unknown")); return M_PROPERTY_OK; } -#ifdef CONFIG_DVDREAD - if (vo_spudec && mpctx->stream->type == STREAMTYPE_DVD - && opts->sub_id >= 0) { - char lang[3]; - int code = dvd_lang_from_sid(mpctx->stream, opts->sub_id); - lang[0] = code >> 8; - lang[1] = code; - lang[2] = 0; - *(char **) arg = talloc_asprintf(NULL, "(%d) %s", - opts->sub_id, lang); - return M_PROPERTY_OK; - } -#endif if (opts->sub_id >= 0) { + char *lang = demuxer_sub_lang(mpctx->demuxer, opts->sub_id); + if (!lang) + lang = talloc_strdup(NULL, mp_gtext("unknown")); *(char **) arg = talloc_asprintf(NULL, "(%d) %s", opts->sub_id, - mp_gtext("unknown")); + lang); + talloc_free(lang); return M_PROPERTY_OK; } *(char **) arg = talloc_strdup(NULL, mp_gtext("disabled")); diff --git a/libmpdemux/demuxer.c b/libmpdemux/demuxer.c index f68c8c93f6..a9a827dd7a 100644 --- a/libmpdemux/demuxer.c +++ b/libmpdemux/demuxer.c @@ -1452,6 +1452,42 @@ int demuxer_set_angle(demuxer_t *demuxer, int angle) return angle; } +char *demuxer_audio_lang(demuxer_t *d, int id) +{ + struct stream_lang_req req; + sh_audio_t *sh; + if (id < 0 || id >= MAX_A_STREAMS) + return NULL; + sh = d->a_streams[id]; + if (!sh) + return NULL; + if (sh->lang) + return talloc_strdup(NULL, sh->lang); + req.type = stream_ctrl_audio; + req.id = sh->aid; + if (stream_control(d->stream, STREAM_CTRL_GET_LANG, &req) == STREAM_OK) + return req.name; + return NULL; +} + +char *demuxer_sub_lang(demuxer_t *d, int id) +{ + struct stream_lang_req req; + sh_sub_t *sh; + if (id < 0 || id >= MAX_S_STREAMS) + return NULL; + sh = d->s_streams[id]; + if (sh && sh->lang) + return talloc_strdup(NULL, sh->lang); + req.type = stream_ctrl_sub; + // assume 1:1 mapping so we can show the language of + // DVD subs even when we have not yet created the stream. + req.id = sh ? sh->sid : id; + if (stream_control(d->stream, STREAM_CTRL_GET_LANG, &req) == STREAM_OK) + return req.name; + return NULL; +} + int demuxer_audio_track_by_lang_and_default(struct demuxer *d, char **langt) { int n = 0; diff --git a/libmpdemux/demuxer.h b/libmpdemux/demuxer.h index bdc401dd14..285ac3a7af 100644 --- a/libmpdemux/demuxer.h +++ b/libmpdemux/demuxer.h @@ -415,4 +415,7 @@ int demuxer_angles_count(struct demuxer *demuxer); int demuxer_audio_track_by_lang_and_default(struct demuxer *d, char **langt); int demuxer_sub_track_by_lang_and_default(struct demuxer *d, char **langt); +char *demuxer_audio_lang(demuxer_t *d, int id); +char *demuxer_sub_lang(demuxer_t *d, int id); + #endif /* MPLAYER_DEMUXER_H */ diff --git a/stream/cache2.c b/stream/cache2.c index b6bdd10b25..488e453dc6 100644 --- a/stream/cache2.c +++ b/stream/cache2.c @@ -88,6 +88,7 @@ typedef struct { volatile int control; volatile unsigned control_uint_arg; volatile double control_double_arg; + volatile struct stream_lang_req control_lang_arg; volatile int control_res; volatile double stream_time_length; volatile double stream_time_pos; @@ -310,6 +311,9 @@ static int cache_execute_control(cache_vars_t *s) { s->control_res = s->stream->control(s->stream, s->control, &uint_res); s->control_uint_arg = uint_res; break; + case STREAM_CTRL_GET_LANG: + s->control_res = s->stream->control(s->stream, s->control, (void *)&s->control_lang_arg); + break; default: s->control_res = STREAM_UNSUPPORTED; break; @@ -620,6 +624,8 @@ int cache_do_control(stream_t *stream, int cmd, void *arg) { case STREAM_CTRL_GET_CURRENT_TIME: *(double *)arg = s->stream_time_pos; return s->stream_time_pos != MP_NOPTS_VALUE ? STREAM_OK : STREAM_UNSUPPORTED; + case STREAM_CTRL_GET_LANG: + s->control_lang_arg = *(struct stream_lang_req *)arg; case STREAM_CTRL_GET_NUM_CHAPTERS: case STREAM_CTRL_GET_CURRENT_CHAPTER: case STREAM_CTRL_GET_ASPECT_RATIO: @@ -665,6 +671,9 @@ int cache_do_control(stream_t *stream, int cmd, void *arg) { case STREAM_CTRL_GET_ANGLE: *(unsigned *)arg = s->control_uint_arg; break; + case STREAM_CTRL_GET_LANG: + *(struct stream_lang_req *)arg = s->control_lang_arg; + break; } return s->control_res; } diff --git a/stream/stream.h b/stream/stream.h index c34da4b61a..df1f15c0b0 100644 --- a/stream/stream.h +++ b/stream/stream.h @@ -99,7 +99,18 @@ #define STREAM_CTRL_GET_ANGLE 10 #define STREAM_CTRL_SET_ANGLE 11 #define STREAM_CTRL_GET_NUM_TITLES 12 - +#define STREAM_CTRL_GET_LANG 13 + +enum stream_ctrl_type { + stream_ctrl_audio, + stream_ctrl_sub, +}; + +struct stream_lang_req { + enum stream_ctrl_type type; + int id; + char *name; +}; typedef enum { streaming_stopped_e, diff --git a/stream/stream_bluray.c b/stream/stream_bluray.c index 7563a9eb77..7c4f970159 100644 --- a/stream/stream_bluray.c +++ b/stream/stream_bluray.c @@ -34,6 +34,7 @@ #include "config.h" #include "libavutil/common.h" #include "libmpdemux/demuxer.h" +#include "talloc.h" #include "mp_msg.h" #include "m_struct.h" #include "m_option.h" @@ -191,6 +192,35 @@ static int bluray_stream_control(stream_t *s, int cmd, void *arg) return 1; } + case STREAM_CTRL_GET_LANG: { + struct stream_lang_req *req = arg; + BLURAY_TITLE_INFO *ti = bd_get_title_info(b->bd, b->current_title, b->current_angle); + if (ti->clip_count) { + BLURAY_STREAM_INFO *si = NULL; + int count = 0; + switch (req->type) { + case stream_ctrl_audio: + count = ti->clips[0].audio_stream_count; + si = ti->clips[0].audio_streams; + break; + case stream_ctrl_sub: + count = ti->clips[0].pg_stream_count; + si = ti->clips[0].pg_streams; + break; + } + while (count-- > 0) { + if (si->pid == req->id) { + req->name = talloc_strndup(NULL, si->lang, 4); + bd_free_title_info(ti); + return STREAM_OK; + } + si++; + } + } + bd_free_title_info(ti); + return STREAM_ERROR; + } + default: break; } diff --git a/stream/stream_dvd.c b/stream/stream_dvd.c index b9ffafed8f..e3e1595619 100644 --- a/stream/stream_dvd.c +++ b/stream/stream_dvd.c @@ -24,6 +24,7 @@ #include #include "config.h" +#include "talloc.h" #include "mp_msg.h" #include @@ -112,7 +113,7 @@ int dvd_chapter_from_cell(dvd_priv_t* dvd,int title,int cell) return chapter; } -int dvd_lang_from_aid(stream_t *stream, int id) { +static int dvd_lang_from_aid(stream_t *stream, int id) { dvd_priv_t *d; int i; if (!stream) return 0; @@ -155,7 +156,7 @@ int dvd_number_of_subs(stream_t *stream) { return maxid + 1; } -int dvd_lang_from_sid(stream_t *stream, int id) { +static int dvd_lang_from_sid(stream_t *stream, int id) { int i; dvd_priv_t *d; if (!stream) return 0; @@ -687,6 +688,23 @@ static int control(stream_t *stream,int cmd,void* arg) d->angle_seek = 1; return 1; } + case STREAM_CTRL_GET_LANG: + { + struct stream_lang_req *req = arg; + int lang = 0; + switch(req->type) { + case stream_ctrl_audio: + lang = dvd_lang_from_aid(stream, req->id); + break; + case stream_ctrl_sub: + lang = dvd_lang_from_sid(stream, req->id); + break; + } + if (!lang) + break; + req->name = talloc_strdup(NULL, (char[]) {lang >> 8, lang, 0}); + return STREAM_OK; + } } return STREAM_UNSUPPORTED; } diff --git a/stream/stream_dvd.h b/stream/stream_dvd.h index fe52d4399a..ff6cb771d2 100644 --- a/stream/stream_dvd.h +++ b/stream/stream_dvd.h @@ -57,8 +57,6 @@ typedef struct { } dvd_priv_t; int dvd_number_of_subs(stream_t *stream); -int dvd_lang_from_aid(stream_t *stream, int id); -int dvd_lang_from_sid(stream_t *stream, int id); int dvd_aid_from_lang(stream_t *stream, char **lang); int dvd_sid_from_lang(stream_t *stream, char **lang); int dvd_chapter_from_cell(dvd_priv_t *dvd,int title,int cell); diff --git a/stream/stream_dvdnav.c b/stream/stream_dvdnav.c index 6bdc59d8a4..d0e29446d3 100644 --- a/stream/stream_dvdnav.c +++ b/stream/stream_dvdnav.c @@ -402,6 +402,9 @@ static int fill_buffer(stream_t *s, char *but, int len) return len; } +static int mp_dvdnav_lang_from_sid(stream_t *stream, int sid); +static int mp_dvdnav_lang_from_aid(stream_t *stream, int sid); + static int control(stream_t *stream, int cmd, void* arg) { dvdnav_priv_t* priv=stream->priv; int tit, part; @@ -496,6 +499,23 @@ static int control(stream_t *stream, int cmd, void* arg) { if(dvdnav_angle_change(priv->dvdnav, new_angle) != DVDNAV_STATUS_OK) return 1; } + case STREAM_CTRL_GET_LANG: + { + struct stream_lang_req *req = arg; + int lang = 0; + switch(req->type) { + case stream_ctrl_audio: + lang = mp_dvdnav_lang_from_aid(stream, req->id); + break; + case stream_ctrl_sub: + lang = mp_dvdnav_lang_from_sid(stream, req->id); + break; + } + if (!lang) + break; + req->name = talloc_strdup(NULL, (char[]) {lang >> 8, lang, 0}); + return STREAM_OK; + } } return STREAM_UNSUPPORTED; @@ -756,13 +776,12 @@ int mp_dvdnav_aid_from_lang(stream_t *stream, char **language) { } /** - * \brief mp_dvdnav_lang_from_aid() assigns to buf the language corresponding to audio id 'aid' + * \brief mp_dvdnav_lang_from_aid() returns the language corresponding to audio id 'aid' * \param stream: - stream pointer * \param sid: physical subtitle id - * \param buf: buffer to contain the 2-chars language string - * \return 0 on error, 1 if successful + * \return 0 on error, otherwise language id */ -int mp_dvdnav_lang_from_aid(stream_t *stream, int aid, unsigned char *buf) { +static int mp_dvdnav_lang_from_aid(stream_t *stream, int aid) { uint8_t lg; uint16_t lang; dvdnav_priv_t * priv = stream->priv; @@ -773,10 +792,7 @@ int mp_dvdnav_lang_from_aid(stream_t *stream, int aid, unsigned char *buf) { if(lg == 0xff) return 0; lang = dvdnav_audio_stream_to_lang(priv->dvdnav, lg); if(lang == 0xffff) return 0; - buf[0] = lang >> 8; - buf[1] = lang & 0xFF; - buf[2] = 0; - return 1; + return lang; } @@ -806,13 +822,12 @@ int mp_dvdnav_sid_from_lang(stream_t *stream, char **language) { } /** - * \brief mp_dvdnav_lang_from_sid() assigns to buf the language corresponding to subtitle id 'sid' + * \brief mp_dvdnav_lang_from_sid() returns the language corresponding to subtitle id 'sid' * \param stream: - stream pointer * \param sid: physical subtitle id - * \param buf: buffer to contain the 2-chars language string - * \return 0 on error, 1 if successful + * \return 0 on error, otherwise language id */ -int mp_dvdnav_lang_from_sid(stream_t *stream, int sid, unsigned char *buf) { +static int mp_dvdnav_lang_from_sid(stream_t *stream, int sid) { uint8_t k; uint16_t lang; dvdnav_priv_t *priv = stream->priv; @@ -824,10 +839,7 @@ int mp_dvdnav_lang_from_sid(stream_t *stream, int sid, unsigned char *buf) { return 0; lang = dvdnav_spu_stream_to_lang(priv->dvdnav, k); if(lang == 0xffff) return 0; - buf[0] = lang >> 8; - buf[1] = lang & 0xFF; - buf[2] = 0; - return 1; + return lang; } /** diff --git a/stream/stream_dvdnav.h b/stream/stream_dvdnav.h index ae58367320..f8f50a0123 100644 --- a/stream/stream_dvdnav.h +++ b/stream/stream_dvdnav.h @@ -31,9 +31,7 @@ typedef struct { int mp_dvdnav_number_of_subs(stream_t *stream); int mp_dvdnav_aid_from_audio_num(stream_t *stream, int audio_num); int mp_dvdnav_aid_from_lang(stream_t *stream, char **language); -int mp_dvdnav_lang_from_aid(stream_t *stream, int id, unsigned char *buf); int mp_dvdnav_sid_from_lang(stream_t *stream, char **language); -int mp_dvdnav_lang_from_sid(stream_t *stream, int sid, unsigned char *buf); void mp_dvdnav_handle_input(stream_t *stream, int cmd, int *button); void mp_dvdnav_update_mouse_pos(stream_t *stream, int32_t x, int32_t y, int* button); void mp_dvdnav_get_highlight (stream_t *stream, nav_highlight_t *hl); -- cgit v1.2.3