Support for subtitle switching in Matroska.

git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@13127 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
mosu 2004-08-24 20:58:29 +00:00
parent 23e9e1c031
commit 55e4ded2bc
3 changed files with 139 additions and 10 deletions

View File

@ -1973,6 +1973,46 @@ demux_mkv_open_audio (demuxer_t *demuxer, mkv_track_t *track)
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 @@ demux_mkv_open_sub (demuxer_t *demuxer, mkv_track_t *track)
{
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 @@ demux_mkv_open (demuxer_t *demuxer)
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 @@ demux_mkv_control (demuxer_t *demuxer, int cmd, void *arg)
}
}
/** \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 */

View File

@ -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 @@ typedef struct {
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 */

View File

@ -1590,7 +1590,7 @@ if(!sh_video && !sh_audio){
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;
@ -3177,6 +3177,35 @@ if (stream->type==STREAMTYPE_DVDNAV && dvd_nav_still)
dvdsub_id = new_id;
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: