[MPlayer-cvslog] r36641 - trunk/libmpdemux/demux_real.c

rtogni subversion at mplayerhq.hu
Sun Jan 19 16:12:47 CET 2014


Author: rtogni
Date: Sun Jan 19 16:12:46 2014
New Revision: 36641

Log:
Add support for files with MLTI chunks.

Fixes 06.rm and 08_lect_01.rm from FFmpeg trac #2152
Fixes also files from ftp://ftp.aduni.org/videos/


The patch has these limitations:
 - no multirate files with MLTI chunks
 - no mixed files (eg. MLTI for audio but not for video)
 - no MLTI for video together with non-ra audio (eg. ralf)
 - only DATA v0 (no v1, versions greater than 1 should not exist)
Files with these feature shuld not really exist anyway.

Also video MLTI files with only one stream are supported but untested

Modified:
   trunk/libmpdemux/demux_real.c

Modified: trunk/libmpdemux/demux_real.c
==============================================================================
--- trunk/libmpdemux/demux_real.c	Sun Jan 19 16:10:42 2014	(r36640)
+++ trunk/libmpdemux/demux_real.c	Sun Jan 19 16:12:46 2014	(r36641)
@@ -1,7 +1,7 @@
 /*
  * Real parser & demuxer
  * copyright (C) 2001 Alex Beregszaszi
- * copyright (C) 2005, 2006 Roberto Togni
+ * copyright (C) 2005, 2006, 2014 Roberto Togni
  * based on FFmpeg's libav/rm.c
  *
  * audio codecs: (supported by RealPlayer8 for Linux)
@@ -54,6 +54,7 @@
 //#define mp_dbg(mod,lev, args... ) mp_msg_c((mod<<8)|lev, ## args )
 
 #define MAX_STREAMS 32
+#define MAX_MLTIIDX 16
 
 static unsigned char sipr_swaps[38][2]={
     {0,63},{1,22},{2,44},{3,90},{5,81},{7,31},{8,86},{9,58},{10,36},{12,68},
@@ -81,6 +82,7 @@ typedef struct {
     int		data_chunk_offset;
     int		num_of_packets;
     int		current_packet;
+    int		streams_in_file;
 
 // need for seek
     int		audio_need_keyframe;
@@ -116,6 +118,13 @@ typedef struct {
     int stream_switch; ///< Flag used to switch audio/video demuxing
 
    /**
+    * Used to demux MLTI files
+    */
+    int is_mlti; ///< != 0 for MLTI files
+    unsigned int mp2rm_streamid[MAX_STREAMS]; ///< Convert Mplayer stream_id to rm stream id
+    unsigned int rm2mp[MAX_STREAMS][MAX_MLTIIDX]; ///< Convert rm stream id and mlti index to Mplayer stream_id
+
+   /**
     * Used to reorder audio data
     */
     unsigned int intl_id[MAX_STREAMS]; ///< interleaver id, per stream
@@ -572,13 +581,13 @@ static int demux_real_fill_buffer(demuxe
     demux_stream_t *ds = NULL;
     int len;
     unsigned int timestamp;
-    int stream_id;
+    int rm_stream_id, mp_stream_id;
 #ifdef CRACK_MATRIX
     int i;
 #endif
     int flags;
     int version;
-    int reserved;
+    int pk_group;;
     demux_packet_t *dp;
     int x, sps, cfs, sph, spc, w;
     int audioreorder_getnextpk = 0;
@@ -630,23 +639,26 @@ static int demux_real_fill_buffer(demuxe
 	return 0;
     }
     if (len < 12){
+    	unsigned int idx_streamid;
 	mp_msg(MSGT_DEMUX, MSGL_V,"%08X: packet v%d len=%d  \n",(int)demuxer->filepos,(int)version,(int)len);
 	mp_msg(MSGT_DEMUX, MSGL_WARN,"bad packet len (%d)\n", len);
 	if ((unsigned)demuxer->video->id < MAX_STREAMS) {
-	    if (priv->current_vpacket + 1 < priv->index_table_size[demuxer->video->id]) {
-		stream_seek(demuxer->stream, priv->index_table[demuxer->video->id][++priv->current_vpacket].offset);
+	    idx_streamid = priv->is_mlti ? priv->mp2rm_streamid[demuxer->video->id] : demuxer->video->id;
+	    if (priv->current_vpacket + 1 < priv->index_table_size[idx_streamid]) {
+		stream_seek(demuxer->stream, priv->index_table[idx_streamid][++priv->current_vpacket].offset);
 	    }
 	} else if ((unsigned)demuxer->audio->id < MAX_STREAMS) {
-	    if (priv->current_apacket + 1 < priv->index_table_size[demuxer->audio->id]) {
-		stream_seek(demuxer->stream, priv->index_table[demuxer->audio->id][++priv->current_apacket].offset);
+	    idx_streamid = priv->is_mlti ? priv->mp2rm_streamid[demuxer->audio->id] : demuxer->video->id;
+	    if (priv->current_apacket + 1 < priv->index_table_size[idx_streamid]) {
+		stream_seek(demuxer->stream, priv->index_table[idx_streamid][++priv->current_apacket].offset);
 	    }
 	}
 	continue; //goto loop;
     }
 
-    stream_id = stream_read_word(demuxer->stream);
+    rm_stream_id = stream_read_word(demuxer->stream);
     timestamp = stream_read_dword(demuxer->stream);
-    reserved = stream_read_char(demuxer->stream);
+    pk_group = stream_read_char(demuxer->stream);
     flags = stream_read_char(demuxer->stream);
     /* flags:		*/
     /*  0x1 - reliable  */
@@ -657,31 +669,39 @@ static int demux_real_fill_buffer(demuxe
         tmp = stream_read_char(demuxer->stream);
         mp_msg(MSGT_DEMUX, MSGL_DBG2,"Version: %d, skipped byte is %d\n", version, tmp);
         len--;
+        if (priv->is_mlti)
+            mp_msg(MSGT_DEMUX, MSGL_WARN,"MLTI file with v1 DATA, expect problems! Please contact Mplayer developers.\n");
     }
 
     if (flags & 2)
-      add_index_item(demuxer, stream_id, timestamp, demuxer->filepos);
+      add_index_item(demuxer, rm_stream_id, timestamp, demuxer->filepos);
 
 //    printf("%08X: packet v%d len=%4d  id=%d  pts=%6d  rvd=%d  flags=%d  \n",
 //	(int)demuxer->filepos,(int)version,(int)len, stream_id,
 //	(int) timestamp, reserved, flags);
 
-    mp_dbg(MSGT_DEMUX,MSGL_DBG2,  "\npacket#%d: pos: 0x%0x, len: %d, id: %d, pts: %u, flags: %x rvd:%d\n",
-	priv->current_packet, (int)demuxer->filepos, len, stream_id, timestamp, flags, reserved);
+    mp_dbg(MSGT_DEMUX,MSGL_DBG2,  "\npacket#%d: pos: 0x%0x, len: %d, rm_id: %d, pts: %u, flags: %x grp:%d\n",
+	priv->current_packet, (int)demuxer->filepos, len, rm_stream_id, timestamp, flags, pk_group);
 
     priv->current_packet++;
     len -= 12;
 
 //    printf("s_id=%d  aid=%d  vid=%d  \n",stream_id,demuxer->audio->id,demuxer->video->id);
 
+    // Map rm stream id and packet group to MPlayer stream aid or vid if file is MLTI
+    if (priv->is_mlti && rm_stream_id < MAX_STREAMS && (pk_group>>1) < MAX_MLTIIDX)
+        mp_stream_id = priv->rm2mp[rm_stream_id][(pk_group>>1)-1];
+    else
+        mp_stream_id = rm_stream_id;
+
     /* check stream_id: */
 
-    if(demuxer->audio->id==stream_id){
+    if(demuxer->audio->id==mp_stream_id){
     	if (priv->audio_need_keyframe == 1&& flags != 0x2)
 		goto discard;
 got_audio:
 	ds=demuxer->audio;
-	mp_dbg(MSGT_DEMUX,MSGL_DBG2, "packet is audio (id: %d)\n", stream_id);
+	mp_dbg(MSGT_DEMUX,MSGL_DBG2, "packet is audio (mp_id: %d)\n", mp_stream_id);
 
         if (flags & 2) {
     	    priv->sub_packet_cnt = 0;
@@ -721,15 +741,15 @@ got_audio:
 		}
 		return 1;
 	    }
-        if ((priv->intl_id[stream_id] == mmioFOURCC('I', 'n', 't', '4')) ||
-            (priv->intl_id[stream_id] == mmioFOURCC('g', 'e', 'n', 'r')) ||
-            (priv->intl_id[stream_id] == mmioFOURCC('s', 'i', 'p', 'r'))) {
-            sps = priv->sub_packet_size[stream_id];
-            sph = priv->sub_packet_h[stream_id];
-            cfs = priv->coded_framesize[stream_id];
-            w = priv->audiopk_size[stream_id];
+        if ((priv->intl_id[demuxer->audio->id] == mmioFOURCC('I', 'n', 't', '4')) ||
+            (priv->intl_id[demuxer->audio->id] == mmioFOURCC('g', 'e', 'n', 'r')) ||
+            (priv->intl_id[demuxer->audio->id] == mmioFOURCC('s', 'i', 'p', 'r'))) {
+            sps = priv->sub_packet_size[demuxer->audio->id];
+            sph = priv->sub_packet_h[demuxer->audio->id];
+            cfs = priv->coded_framesize[demuxer->audio->id];
+            w = priv->audiopk_size[demuxer->audio->id];
             spc = priv->sub_packet_cnt;
-            switch (priv->intl_id[stream_id]) {
+            switch (priv->intl_id[demuxer->audio->id]) {
                 case mmioFOURCC('I', 'n', 't', '4'):
                     if (len < cfs * sph/2)
                         goto discard;
@@ -844,8 +864,8 @@ got_audio:
 	}
 // we will not use audio index if we use -idx and have a video
 	if(((!demuxer->video->sh && index_mode == 2) || priv->is_multirate) && (unsigned)demuxer->audio->id < MAX_STREAMS) {
-		while (priv->current_apacket + 1 < priv->index_table_size[demuxer->audio->id] &&
-		       timestamp > priv->index_table[demuxer->audio->id][priv->current_apacket].timestamp) {
+		while (priv->current_apacket + 1 < priv->index_table_size[rm_stream_id] &&
+		       timestamp > priv->index_table[rm_stream_id][priv->current_apacket].timestamp) {
 			priv->current_apacket += 1;
 			priv->stream_switch = 1;
 		}
@@ -860,10 +880,10 @@ got_audio:
 	return 1;
     }
 
-    if(demuxer->video->id==stream_id){
+    if(demuxer->video->id==mp_stream_id){
 got_video:
 	ds=demuxer->video;
-	mp_dbg(MSGT_DEMUX,MSGL_DBG2, "packet is video (id: %d)\n", stream_id);
+	mp_dbg(MSGT_DEMUX,MSGL_DBG2, "packet is video (mp_id: %d)\n", mp_stream_id);
 
 	// parse video chunk:
 	{
@@ -1041,8 +1061,8 @@ got_video:
 	    }
 	}
 	if ((unsigned)demuxer->video->id < MAX_STREAMS) {
-		while (priv->current_vpacket + 1 < priv->index_table_size[demuxer->video->id] &&
-		       timestamp > priv->index_table[demuxer->video->id][priv->current_vpacket + 1].timestamp) {
+		while (priv->current_vpacket + 1 < priv->index_table_size[rm_stream_id] &&
+		       timestamp > priv->index_table[rm_stream_id][priv->current_vpacket + 1].timestamp) {
 			priv->current_vpacket += 1;
 			priv->stream_switch = 1;
 		}
@@ -1053,31 +1073,30 @@ got_video:
 	return 1;
     }
 
-if((unsigned)stream_id<MAX_STREAMS){
-
-    if(demuxer->audio->id==-1 && demuxer->a_streams[stream_id]){
-	sh_audio_t *sh = demuxer->a_streams[stream_id];
-	demuxer->audio->id=stream_id;
+if((unsigned)rm_stream_id<MAX_STREAMS){
+    if(demuxer->audio->id==-1 && demuxer->a_streams[mp_stream_id]){
+	sh_audio_t *sh = demuxer->a_streams[mp_stream_id];
+	demuxer->audio->id=mp_stream_id;
 	sh->ds=demuxer->audio;
 	demuxer->audio->sh=sh;
 	priv->audio_buf = calloc(priv->sub_packet_h[demuxer->audio->id], priv->audiopk_size[demuxer->audio->id]);
 	priv->audio_timestamp = calloc(priv->sub_packet_h[demuxer->audio->id], sizeof(double));
-        mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected RM audio ID = %d\n",stream_id);
+        mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected RM audio ID = %d (rm id %d)\n",mp_stream_id, rm_stream_id);
 	goto got_audio;
     }
 
-    if(demuxer->video->id==-1 && demuxer->v_streams[stream_id]){
-	sh_video_t *sh = demuxer->v_streams[stream_id];
-	demuxer->video->id=stream_id;
+    if(demuxer->video->id==-1 && demuxer->v_streams[mp_stream_id]){
+	sh_video_t *sh = demuxer->v_streams[mp_stream_id];
+	demuxer->video->id=mp_stream_id;
 	sh->ds=demuxer->video;
 	demuxer->video->sh=sh;
-        mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected RM video ID = %d\n",stream_id);
+        mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected RM video ID = %d (rm id %d)\n",mp_stream_id, rm_stream_id);
 	goto got_video;
     }
 
 }
 
-    mp_msg(MSGT_DEMUX,MSGL_DBG2, "unknown stream id (%d)\n", stream_id);
+    mp_msg(MSGT_DEMUX,MSGL_DBG2, "unknown stream id (%d)\n", rm_stream_id);
 discard:
     stream_skip(demuxer->stream, len);
   }//    goto loop;
@@ -1140,7 +1159,8 @@ static demuxer_t* demux_open_real(demuxe
 		mp_msg(MSGT_DEMUX,MSGL_V,"First index chunk offset: 0x%x\n", priv->index_chunk_offset);
 		priv->data_chunk_offset = stream_read_dword(demuxer->stream)+10;
 		mp_msg(MSGT_DEMUX,MSGL_V,"First data chunk offset: 0x%x\n", priv->data_chunk_offset);
-		stream_skip(demuxer->stream, 2); /* nb streams */
+		priv->streams_in_file = stream_read_word(demuxer->stream);
+		mp_msg(MSGT_DEMUX,MSGL_V,"Number of streams in file: %d\n", priv->streams_in_file);
 #if 0
 		stream_skip(demuxer->stream, 2); /* flags */
 #else
@@ -1218,7 +1238,6 @@ static demuxer_t* demux_open_real(demuxe
 		int tmp;
 		int len;
 		char *descr, *mimet = NULL;
-
 		stream_id = stream_read_word(demuxer->stream);
 		mp_msg(MSGT_DEMUX,MSGL_V,"Found new stream (id: %d)\n", stream_id);
 
@@ -1254,13 +1273,44 @@ static demuxer_t* demux_open_real(demuxe
 
 	if (!strncmp(mimet,"audio/",6)) {
 	  if (strstr(mimet,"x-pn-realaudio") || strstr(mimet,"x-pn-multirate-realaudio")) {
+		int num_mlti, mlti_cnt, ra_size;
 		tmp = stream_read_dword(demuxer->stream);
+		if (tmp == MKTAG('I', 'T', 'L', 'M')) // MLTI chunk in audio
+		{
+		    int num_streams, stream_cnt;
+		    mp_msg(MSGT_DEMUX,MSGL_V,"MLTI chunk in audio.\n");
+		    num_streams = stream_read_word(demuxer->stream);
+		    for (stream_cnt = 0; stream_cnt < num_streams; stream_cnt++)
+		        stream_skip(demuxer->stream, 2); // MDPR index, one per stream
+		    num_mlti = stream_read_word(demuxer->stream);
+		    if (num_mlti != 1) {
+		        mp_msg(MSGT_DEMUX,MSGL_V,"Found MLTI in audio with %d substreams.\n", num_mlti);
+		        priv->is_mlti = 1;
+		    } else
+		        mp_msg(MSGT_DEMUX,MSGL_V,"Found MLTI in audio with 1 substreams. Ingnoring\n", num_mlti);
+		    if (num_mlti > MAX_MLTIIDX) {
+		        mp_msg(MSGT_DEMUX,MSGL_ERR,"Too many (%d) MLTI audio, truncating; expect problems. Please report to Mplayer developers.\n", num_mlti);
+		        num_mlti = MAX_MLTIIDX - 1; // Limit to max MLTI
+		    }
+		    ra_size = stream_read_dword(demuxer->stream); // Size of the following .ra chunk
+		    tmp = stream_read_dword(demuxer->stream);
+		} else {
+		    num_mlti = 1;
+		    ra_size = codec_data_size;
+		}
+		for (mlti_cnt = 0; mlti_cnt < num_mlti; mlti_cnt++) {
+		if (mlti_cnt) {
+		    ra_size = stream_read_dword(demuxer->stream); // Size of the following .ra chunk
+		    tmp = stream_read_dword(demuxer->stream);
+		}
 		if (tmp != MKTAG(0xfd, 'a', 'r', '.'))
 		{
 		    mp_msg(MSGT_DEMUX,MSGL_V,"Audio: can't find .ra in codec data\n");
+		    stream_skip(demuxer->stream, ra_size - 4);
 		} else {
 		    /* audio header */
-		    sh_audio_t *sh = new_sh_audio(demuxer, stream_id, NULL);
+		    int aid = priv->is_mlti ? priv->streams_in_file + a_streams + v_streams : stream_id;
+		    sh_audio_t *sh = new_sh_audio(demuxer, aid, NULL);
 		    char buf[128]; /* for codec name */
 		    int frame_size;
 		    int sub_packet_size;
@@ -1272,7 +1322,10 @@ static demuxer_t* demux_open_real(demuxe
 		    int i;
 		    char *buft;
 		    int hdr_size;
-		    mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_AudioID, "real", stream_id);
+		    mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_AudioID, "real", aid);
+		    priv->mp2rm_streamid[aid] = stream_id;
+		    priv->rm2mp[stream_id][mlti_cnt] = aid;
+		    mp_msg(MSGT_DEMUX,MSGL_V,"Mplayer aid %d is rm stream %d with MDPR index %d\n", aid, stream_id, mlti_cnt);
 		    mp_msg(MSGT_DEMUX,MSGL_V,"Found audio stream!\n");
 		    version = stream_read_word(demuxer->stream);
 		    mp_msg(MSGT_DEMUX,MSGL_V,"version: %d\n", version);
@@ -1355,7 +1408,7 @@ static demuxer_t* demux_open_real(demuxe
 		    if (version == 5)
 		    {
 			stream_read(demuxer->stream, buf, 4);  // interleaver id
-			priv->intl_id[stream_id] = MKTAG(buf[0], buf[1], buf[2], buf[3]);
+			priv->intl_id[aid] = MKTAG(buf[0], buf[1], buf[2], buf[3]);
 			stream_read(demuxer->stream, buf, 4); // fourcc
 			buf[4] = 0;
 		    }
@@ -1363,7 +1416,7 @@ static demuxer_t* demux_open_real(demuxe
 		    {
 			/* Interleaver id */
 			get_str(1, demuxer, buf, sizeof(buf));
-			priv->intl_id[stream_id] = MKTAG(buf[0], buf[1], buf[2], buf[3]);
+			priv->intl_id[aid] = MKTAG(buf[0], buf[1], buf[2], buf[3]);
 			/* Codec FourCC */
 			get_str(1, demuxer, buf, sizeof(buf));
 		    }
@@ -1409,7 +1462,7 @@ static demuxer_t* demux_open_real(demuxe
 			    sh->wf->cbSize = codecdata_length;
 			    sh->wf = realloc(sh->wf, sizeof(*sh->wf)+sh->wf->cbSize);
 			    stream_read(demuxer->stream, ((char*)(sh->wf+1)), codecdata_length); // extras
-                if (priv->intl_id[stream_id] == MKTAG('g', 'e', 'n', 'r'))
+                if (priv->intl_id[aid] == MKTAG('g', 'e', 'n', 'r'))
     			    sh->wf->nBlockAlign = sub_packet_size;
     			else
     			    sh->wf->nBlockAlign = coded_frame_size;
@@ -1438,10 +1491,10 @@ static demuxer_t* demux_open_real(demuxe
 		    }
 
 		    // Interleaver setup
-		    priv->sub_packet_size[stream_id] = sub_packet_size;
-		    priv->sub_packet_h[stream_id] = sub_packet_h;
-		    priv->coded_framesize[stream_id] = coded_frame_size;
-		    priv->audiopk_size[stream_id] = frame_size;
+		    priv->sub_packet_size[aid] = sub_packet_size;
+		    priv->sub_packet_h[aid] = sub_packet_h;
+		    priv->coded_framesize[aid] = coded_frame_size;
+		    priv->audiopk_size[aid] = frame_size;
 
 		    sh->wf->wFormatTag = sh->format;
 
@@ -1469,7 +1522,8 @@ static demuxer_t* demux_open_real(demuxe
 #ifdef stream_skip
 #undef stream_skip
 #endif
-		}
+		} // .ra
+		} // MLTI
 	  } else if (strstr(mimet,"X-MP3-draft-00")) {
 		    sh_audio_t *sh = new_sh_audio(demuxer, stream_id, NULL);
     		    mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_AudioID, "real", stream_id);
@@ -1518,15 +1572,56 @@ static demuxer_t* demux_open_real(demuxe
 		}
 	} else if (!strncmp(mimet,"video/",6)) {
 	  if (strstr(mimet,"x-pn-realvideo") || strstr(mimet,"x-pn-multirate-realvideo")) {
-		stream_skip(demuxer->stream, 4);  // VIDO length, same as codec_data_size
+		int num_mlti, mlti_cnt, vido_size, vido_pos;
 		tmp = stream_read_dword(demuxer->stream);
+		if (tmp == MKTAG('I', 'T', 'L', 'M')) // MLTI chunk in video
+		{
+		    int num_streams, stream_cnt;
+		    mp_msg(MSGT_DEMUX,MSGL_V,"MLTI chunk in video.\n");
+		    num_streams = stream_read_word(demuxer->stream);
+		    for (stream_cnt = 0; stream_cnt < num_streams; stream_cnt++)
+		        stream_skip(demuxer->stream, 2); // MDPR index, one per stream
+		    num_mlti = stream_read_word(demuxer->stream);
+		    if (num_mlti != 1) {
+		        mp_msg(MSGT_DEMUX,MSGL_V,"Found MLTI in video with %d substreams.\n", num_mlti);
+		         priv->is_mlti = 1;
+		    } else
+		        mp_msg(MSGT_DEMUX,MSGL_V,"Found MLTI in audio with 1 substreams. Ingnoring\n", num_mlti);
+		    if (num_mlti > MAX_MLTIIDX) {
+		        mp_msg(MSGT_DEMUX,MSGL_ERR,"Too many (%d) MLTI video, truncating; expect problems. Please report to Mplayer developers.\n", num_mlti);
+		        num_mlti = MAX_MLTIIDX - 1; // Limit to max MLTI
+		    }
+		    vido_size = stream_read_dword(demuxer->stream); // Size of the following .vido chunk
+		    vido_pos = stream_tell(demuxer->stream);;
+		    stream_skip(demuxer->stream, 4);
+		    tmp = stream_read_dword(demuxer->stream);
+		    priv->is_mlti = 1;
+		} else {
+		    num_mlti = 1;
+		    vido_size = codec_data_size;
+		    vido_pos = codec_pos;
+		    tmp = stream_read_dword(demuxer->stream);
+		}
+		for (mlti_cnt = 0; mlti_cnt < num_mlti; mlti_cnt++) {
+		if (mlti_cnt) {
+		    vido_size = stream_read_dword(demuxer->stream); // Size of the following vido chunk
+		    mp_msg(MSGT_DEMUX,MSGL_V,"VIDO size: %x\n", vido_size);
+		    vido_pos = stream_tell(demuxer->stream);;
+		    stream_skip(demuxer->stream, 4);
+		    tmp = stream_read_dword(demuxer->stream);
+		}
 		if(tmp != MKTAG('O', 'D', 'I', 'V'))
 		{
 		    mp_msg(MSGT_DEMUX,MSGL_V,"Video: can't find VIDO in codec data\n");
+		    stream_skip(demuxer->stream, vido_size - 4);
 		} else {
 		    /* video header */
-		    sh_video_t *sh = new_sh_video(demuxer, stream_id);
-		    mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_VideoID, "real", stream_id);
+		    int vid = priv->is_mlti ? priv->streams_in_file + a_streams + v_streams : stream_id;
+		    sh_video_t *sh = new_sh_video(demuxer, vid);
+		    mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_VideoID, "real", vid);
+		    priv->mp2rm_streamid[vid] = stream_id;
+		    priv->rm2mp[stream_id][mlti_cnt] = vid;
+		    mp_msg(MSGT_DEMUX,MSGL_V,"Mplayer vid %d is rm stream %d with MDPR index %d\n", vid, stream_id, mlti_cnt);
 
 		    sh->format = stream_read_dword_le(demuxer->stream); /* fourcc */
 		    mp_msg(MSGT_DEMUX,MSGL_V,"video fourcc: %.4s (%x)\n", (char *)&sh->format, sh->format);
@@ -1569,7 +1664,7 @@ static demuxer_t* demux_open_real(demuxe
 
 		    {
 			    // read and store codec extradata
-			    unsigned int cnt = codec_data_size - (stream_tell(demuxer->stream) - codec_pos);
+			    unsigned int cnt = vido_size - (stream_tell(demuxer->stream) - vido_pos);
 			    if (cnt > 0x7fffffff - sizeof(*sh->bih)) {
 			        mp_msg(MSGT_DEMUX, MSGL_ERR,"Extradata too big (%u)\n", cnt);
 			    } else  {
@@ -1596,7 +1691,8 @@ static demuxer_t* demux_open_real(demuxe
 
 		    ++v_streams;
 
-		}
+		} // VIDO
+		} // MLTI
 	  } else {
 		 mp_msg(MSGT_DEMUX,MSGL_V,"Unknown video stream format\n");
 	  }
@@ -1661,6 +1757,9 @@ skip_this_chunk:
     }
 
 header_end:
+    if(priv->is_multirate && priv->is_mlti)
+        mp_msg(MSGT_DEMUX,MSGL_ERR,"Multirate and MLTI in the same file is bad. Please contact Mplayer developers.\n");
+
     if(priv->is_multirate) {
         mp_msg(MSGT_DEMUX,MSGL_V,"Selected video id %d audio id %d\n", demuxer->video->id, demuxer->audio->id);
         /* Perform some sanity checks to avoid checking streams id all over the code*/
@@ -1807,6 +1906,11 @@ static void demux_seek_real(demuxer_t *d
     int retried = 0;
 
 
+    if (priv->is_mlti && (unsigned)vid < MAX_STREAMS)
+	vid = priv->mp2rm_streamid[d_video->id];
+    if (priv->is_mlti && (unsigned)aid < MAX_STREAMS)
+	aid = priv->mp2rm_streamid[d_audio->id];
+
     if (sh_video && (unsigned)vid < MAX_STREAMS && priv->index_table_size[vid])
 	streams |= 1;
     if (sh_audio && (unsigned)aid < MAX_STREAMS && priv->index_table_size[aid])


More information about the MPlayer-cvslog mailing list