Mercurial > mplayer.hg
changeset 13126:b59e16a8dfc7
Support for subtitle switching in Matroska.
author | mosu |
---|---|
date | Tue, 24 Aug 2004 20:58:29 +0000 |
parents | 69f13a4cbab9 |
children | 957fc21fc10a |
files | libmpdemux/demux_mkv.c libmpdemux/matroska.h mplayer.c |
diffstat | 3 files changed, 139 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/libmpdemux/demux_mkv.c Tue Aug 24 20:48:24 2004 +0000 +++ b/libmpdemux/demux_mkv.c Tue Aug 24 20:58:29 2004 +0000 @@ -1973,6 +1973,46 @@ return 0; } +/** \brief Parse the private data for VobSub subtitle tracks. + + This function tries to parse the private data for all VobSub tracks. + The private data contains the normal text from the original .idx file. + Things like the palette, subtitle dimensions and custom colors are + stored here. + + \param demuxer The generic demuxer. +*/ +static void +demux_mkv_parse_vobsub_data (demuxer_t *demuxer) +{ + mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; + mkv_track_t *track; + int i, m, size; + uint8_t *buffer; + + for (i = 0; i < mkv_d->num_tracks; i++) + { + track = mkv_d->tracks[i]; + if ((track->type != MATROSKA_TRACK_SUBTITLE) || + (track->subtitle_type != MATROSKA_SUBTYPE_VOBSUB)) + continue; + + size = track->private_size; + m = demux_mkv_decode (track,track->private_data,&buffer,&size,2); + if (buffer && m) + { + free (track->private_data); + track->private_data = buffer; + } + if (!demux_mkv_parse_idx (track)) + { + free (track->private_data); + track->private_data = NULL; + track->private_size = 0; + } + } +} + static int demux_mkv_open_sub (demuxer_t *demuxer, mkv_track_t *track) { @@ -1980,15 +2020,7 @@ { if (track->subtitle_type == MATROSKA_SUBTYPE_VOBSUB) { - int m, size = track->private_size; - uint8_t *buffer; - m = demux_mkv_decode (track,track->private_data,&buffer,&size,2); - if (buffer && m) - { - free (track->private_data); - track->private_data = buffer; - } - if (demux_mkv_parse_idx (track)) + if (track->private_data != NULL) { demuxer->sub->sh = malloc(sizeof(mkv_sh_sub_t)); if (demuxer->sub->sh != NULL) @@ -2206,6 +2238,7 @@ demuxer->audio->id = -2; } + demux_mkv_parse_vobsub_data (demuxer); /* DO NOT automatically select a subtitle track and behave like DVD */ /* playback: only show subtitles if the user explicitely wants them. */ track = NULL; @@ -3122,4 +3155,66 @@ } } +/** \brief Return the number of subtitle tracks in the file. + + \param demuxer The demuxer for which the number of subtitle tracks + should be returned. +*/ +int +demux_mkv_num_subs (demuxer_t *demuxer) +{ + mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; + int i, num; + + num = 0; + for (i = 0; i < mkv_d->num_tracks; i++) + if ((mkv_d->tracks[i]->type == MATROSKA_TRACK_SUBTITLE) && + (mkv_d->tracks[i]->subtitle_type != MATROSKA_SUBTYPE_UNKNOWN)) + num++; + + return num; +} + +/** \brief Change the current subtitle track and return its ID. + + Changes the current subtitle track. If the new subtitle track is a + VobSub track then the SPU decoder will be re-initialized. + + \param demuxer The demuxer whose subtitle track will be changed. + \param new_num The number of the new subtitle track. The number must be + between 0 and demux_mkv_num_subs - 1. + + \returns The Matroska track number of the newly selected track. +*/ +int +demux_mkv_change_subs (demuxer_t *demuxer, int new_num) +{ + mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv; + mkv_track_t *track; + int i, num; + + num = 0; + track = NULL; + for (i = 0; i < mkv_d->num_tracks; i++) + { + if ((mkv_d->tracks[i]->type == MATROSKA_TRACK_SUBTITLE) && + (mkv_d->tracks[i]->subtitle_type != MATROSKA_SUBTYPE_UNKNOWN)) + num++; + if (num == (new_num + 1)) + { + track = mkv_d->tracks[i]; + break; + } + } + if (track == NULL) + return -1; + + if (demuxer->sub->sh == NULL) + demuxer->sub->sh = malloc(sizeof(mkv_sh_sub_t)); + if (demuxer->sub->sh != NULL) + memcpy(demuxer->sub->sh, &track->sh_sub, sizeof(mkv_sh_sub_t)); + + return track->tnum; +} + #endif /* HAVE_MATROSKA */
--- a/libmpdemux/matroska.h Tue Aug 24 20:48:24 2004 +0000 +++ b/libmpdemux/matroska.h Tue Aug 24 20:58:29 2004 +0000 @@ -7,6 +7,8 @@ #ifndef __MATROSKA_H #define __MATROSKA_H +#include "demuxer.h" + #define MKV_A_AAC_2MAIN "A_AAC/MPEG2/MAIN" #define MKV_A_AAC_2LC "A_AAC/MPEG2/LC" #define MKV_A_AAC_2SBR "A_AAC/MPEG2/LC/SBR" @@ -61,4 +63,7 @@ int forced_subs_only; } mkv_sh_sub_t; +int demux_mkv_num_subs(demuxer_t *); +int demux_mkv_change_subs(demuxer_t *, int); + #endif /* __MATROSKA_H */
--- a/mplayer.c Tue Aug 24 20:48:24 2004 +0000 +++ b/mplayer.c Tue Aug 24 20:58:29 2004 +0000 @@ -1590,7 +1590,7 @@ demux_info_print(demuxer); //================== Read SUBTITLES (DVD & TEXT) ========================== -if(vo_spudec==NULL && sh_video && stream->type==STREAMTYPE_DVD){ +if(vo_spudec==NULL && sh_video && (stream->type==STREAMTYPE_DVD || demuxer->type==DEMUXER_TYPE_MATROSKA)){ if (spudec_ifo) { unsigned int palette[16], width, height; @@ -3178,6 +3178,35 @@ d_dvdsub->id = demux_ogg_sub_id(new_id); } #endif +#ifdef HAVE_MATROSKA + if (d_dvdsub && demuxer->type == DEMUXER_TYPE_MATROSKA) { + int new_id = dvdsub_id + 1; + if (dvdsub_id < 0) + new_id = 0; + if ((unsigned int) new_id >= demux_mkv_num_subs(demuxer)) + new_id = -1; + if (new_id != dvdsub_id) + osd_show_vobsub_changed = sh_video->fps; + dvdsub_id = new_id; + d_dvdsub->id = demux_mkv_change_subs(demuxer, new_id); + if (d_dvdsub->id >= 0 && ((mkv_sh_sub_t *)d_dvdsub->sh)->type == 'v') { + mkv_sh_sub_t *mkv_sh_sub = (mkv_sh_sub_t *)d_dvdsub->sh; + if (vo_spudec != NULL) + spudec_free(vo_spudec); + vo_spudec = + spudec_new_scaled_vobsub(mkv_sh_sub->palette, mkv_sh_sub->colors, + mkv_sh_sub->custom_colors, + mkv_sh_sub->width, + mkv_sh_sub->height); + if (!forced_subs_only) + forced_subs_only = mkv_sh_sub->forced_subs_only; + if (vo_spudec) { + spudec_set_forced_subs_only(vo_spudec, forced_subs_only); + inited_flags |= INITED_SPUDEC; + } + } + } +#endif break; case MP_CMD_SUB_FORCED_ONLY: if (vo_spudec) {