summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libmpdemux/demux_mkv.c113
-rw-r--r--libmpdemux/matroska.h5
-rw-r--r--mplayer.c31
3 files changed, 139 insertions, 10 deletions
diff --git a/libmpdemux/demux_mkv.c b/libmpdemux/demux_mkv.c
index 5e48363e4e..bdadcd6e2d 100644
--- a/libmpdemux/demux_mkv.c
+++ b/libmpdemux/demux_mkv.c
@@ -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 */
diff --git a/libmpdemux/matroska.h b/libmpdemux/matroska.h
index f5678aca77..1888083212 100644
--- a/libmpdemux/matroska.h
+++ b/libmpdemux/matroska.h
@@ -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 */
diff --git a/mplayer.c b/mplayer.c
index acc1315433..7bca9219cc 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -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;
@@ -3178,6 +3178,35 @@ if (stream->type==STREAMTYPE_DVDNAV && dvd_nav_still)
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) {