[MPlayer-dev-eng] [PATCH 2/3] Support MPEG streams embedded in generic MOV tracks

Petr Baudis pasky at ucw.cz
Wed May 24 02:58:33 CEST 2006


This patch makes mplayer able to play MOV files containing generic track
with a MPEG stream embedded by "hijacking" the MOV demuxer and replacing
it with a MPEG demuxer (seeked at the appropriate point of the stream).
The patch has been discussed on #mplayerdev.

Such MOV files can be found e.g. on animemusicvideos.org (registration
required, e.g. Ghibli - Rhythm of the Heat). I have uploaded an example
file to incoming at ftp.mplayerhq.hu as EpisodeI.mov (or something like
that) few days ago.

The patch depends on the fact that there is only a single track in such
a file, otherwise it emits an error message and ignores all but the first
MPEG generic track. I have no idea if this situation could even arise
in practice with any common MOV files, but I quite doubt it. mplayer
current demuxer design seems to make it hard to support the generic case
easily. :-(
---

 libmpdemux/demux_mov.c |   39 ++++++++++++++++++++++++++++++++++++++-
 1 files changed, 38 insertions(+), 1 deletions(-)

diff --git a/libmpdemux/demux_mov.c b/libmpdemux/demux_mov.c
index 078e8e7..0379e43 100644
--- a/libmpdemux/demux_mov.c
+++ b/libmpdemux/demux_mov.c
@@ -1767,6 +1767,8 @@ #endif
   return 0;
 }
 
+extern int audio_id, video_id, dvdsub_id;
+
 static demuxer_t* mov_read_header(demuxer_t* demuxer){
     mov_priv_t* priv=demuxer->priv;
     int t_no;
@@ -1786,7 +1788,42 @@ static demuxer_t* mov_read_header(demuxe
     lschunks(demuxer, 0, priv->moov_end, NULL);
     // just in case we have hit eof while parsing...
     demuxer->stream->eof = 0;
-//    mp_msg(MSGT_DEMUX, MSGL_INFO, "--------------\n");
+    mp_msg(MSGT_DEMUX, MSGL_V, "-------------- tracks #: %d\n", priv->track_db);
+
+    // in case there's a generic MPEG track...
+    for (t_no = 0; t_no < priv->track_db; t_no++) {
+        mov_track_t* trak=priv->tracks[t_no];
+	int i;
+	if (trak->type != MOV_TRAK_GENERIC)
+	    continue;
+
+	mp_msg(MSGT_DEMUX, MSGL_DBG2, "MOV: Generic track #%d, subtype %.4s\n",
+	       t_no, (char*) &trak->media_handler);
+	// There are lot and lot and lot of more generic track types.
+	if (trak->media_handler != MOV_FOURCC('M','P','E','G'))
+	    continue;
+	if (trak->samples_size < 1) {
+	    mp_msg(MSGT_DEMUX, MSGL_WARN, "MOV: Urgh. Found MPEG generic track, but with zero samples...? Skipping.\n");
+	    continue;
+	}
+
+	mp_msg(MSGT_DEMUX, MSGL_INFO, "MOV: Found MPEG generic track, switching to MPEG demux.\n");
+	if (priv->track_db > 1)
+	    mp_msg(MSGT_DEMUX, MSGL_WARN, "MOV: There are some other tracks in the file - I'm not going to play them since this situation just wouldn't arise in practice; complain to developers if it really did. Sorry and have a nice day.\n");
+	if (trak->samples_size > 1)
+	    mp_msg(MSGT_DEMUX, MSGL_WARN, "MOV: There are multiple (%d) samples with MPEG streams. Who on earth would do that?! I will play just the first one (OTOH, the MPEG code could manage to resync and go on playing the other samples as well, if you are lucky). You can tweak the code in libmpdemux/demux_mov.c - it's fun! ;-)\n", trak->samples_size);
+
+	// FIXME: Also honor trak->samples[0].size.
+	demuxer->stream->start_pos = trak->samples[0].pos;
+	// Hack from demux_rtp.c:
+	{
+	// DEMUXER_TYPE_UNKNOWN? I don't know if there can't be other kinds
+	// of MPEG here as well. --pasky
+	demuxer_t* od = demux_open(demuxer->stream, DEMUXER_TYPE_MPEG_PS,
+	                           audio_id, video_id, dvdsub_id, NULL);
+	return new_demuxers_demuxer(od, od, od);
+	}
+    }
 
     // find the best (longest) streams:
     for(t_no=0;t_no<priv->track_db;t_no++){



More information about the MPlayer-dev-eng mailing list