comparison libmpdemux/demux_real.c @ 36545:f0e92381681d

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
author rtogni
date Sun, 19 Jan 2014 15:12:46 +0000
parents 139f2b064ef9
children b72ae5f17e3a
comparison
equal deleted inserted replaced
36544:cc8102c4ca83 36545:f0e92381681d
1 /* 1 /*
2 * Real parser & demuxer 2 * Real parser & demuxer
3 * copyright (C) 2001 Alex Beregszaszi 3 * copyright (C) 2001 Alex Beregszaszi
4 * copyright (C) 2005, 2006 Roberto Togni 4 * copyright (C) 2005, 2006, 2014 Roberto Togni
5 * based on FFmpeg's libav/rm.c 5 * based on FFmpeg's libav/rm.c
6 * 6 *
7 * audio codecs: (supported by RealPlayer8 for Linux) 7 * audio codecs: (supported by RealPlayer8 for Linux)
8 * DNET - RealAudio 3.0, really it's AC3 in swapped-byteorder 8 * DNET - RealAudio 3.0, really it's AC3 in swapped-byteorder
9 * SIPR - SiproLab's audio codec, ACELP decoder working with MPlayer, 9 * SIPR - SiproLab's audio codec, ACELP decoder working with MPlayer,
52 #include "demux_real.h" 52 #include "demux_real.h"
53 53
54 //#define mp_dbg(mod,lev, args... ) mp_msg_c((mod<<8)|lev, ## args ) 54 //#define mp_dbg(mod,lev, args... ) mp_msg_c((mod<<8)|lev, ## args )
55 55
56 #define MAX_STREAMS 32 56 #define MAX_STREAMS 32
57 #define MAX_MLTIIDX 16
57 58
58 static unsigned char sipr_swaps[38][2]={ 59 static unsigned char sipr_swaps[38][2]={
59 {0,63},{1,22},{2,44},{3,90},{5,81},{7,31},{8,86},{9,58},{10,36},{12,68}, 60 {0,63},{1,22},{2,44},{3,90},{5,81},{7,31},{8,86},{9,58},{10,36},{12,68},
60 {13,39},{14,73},{15,53},{16,69},{17,57},{19,88},{20,34},{21,71},{24,46}, 61 {13,39},{14,73},{15,53},{16,69},{17,57},{19,88},{20,34},{21,71},{24,46},
61 {25,94},{26,54},{28,75},{29,50},{32,70},{33,92},{35,74},{38,85},{40,56}, 62 {25,94},{26,54},{28,75},{29,50},{32,70},{33,92},{35,74},{38,85},{40,56},
79 int index_table_size[MAX_STREAMS]; 80 int index_table_size[MAX_STREAMS];
80 int index_malloc_size[MAX_STREAMS]; 81 int index_malloc_size[MAX_STREAMS];
81 int data_chunk_offset; 82 int data_chunk_offset;
82 int num_of_packets; 83 int num_of_packets;
83 int current_packet; 84 int current_packet;
85 int streams_in_file;
84 86
85 // need for seek 87 // need for seek
86 int audio_need_keyframe; 88 int audio_need_keyframe;
87 int video_after_seek; 89 int video_after_seek;
88 90
112 int a_num_of_packets; ///< Number of audio packets 114 int a_num_of_packets; ///< Number of audio packets
113 int v_num_of_packets; ///< Number of video packets 115 int v_num_of_packets; ///< Number of video packets
114 int a_bitrate; ///< Audio bitrate 116 int a_bitrate; ///< Audio bitrate
115 int v_bitrate; ///< Video bitrate 117 int v_bitrate; ///< Video bitrate
116 int stream_switch; ///< Flag used to switch audio/video demuxing 118 int stream_switch; ///< Flag used to switch audio/video demuxing
119
120 /**
121 * Used to demux MLTI files
122 */
123 int is_mlti; ///< != 0 for MLTI files
124 unsigned int mp2rm_streamid[MAX_STREAMS]; ///< Convert Mplayer stream_id to rm stream id
125 unsigned int rm2mp[MAX_STREAMS][MAX_MLTIIDX]; ///< Convert rm stream id and mlti index to Mplayer stream_id
117 126
118 /** 127 /**
119 * Used to reorder audio data 128 * Used to reorder audio data
120 */ 129 */
121 unsigned int intl_id[MAX_STREAMS]; ///< interleaver id, per stream 130 unsigned int intl_id[MAX_STREAMS]; ///< interleaver id, per stream
570 { 579 {
571 real_priv_t *priv = demuxer->priv; 580 real_priv_t *priv = demuxer->priv;
572 demux_stream_t *ds = NULL; 581 demux_stream_t *ds = NULL;
573 int len; 582 int len;
574 unsigned int timestamp; 583 unsigned int timestamp;
575 int stream_id; 584 int rm_stream_id, mp_stream_id;
576 #ifdef CRACK_MATRIX 585 #ifdef CRACK_MATRIX
577 int i; 586 int i;
578 #endif 587 #endif
579 int flags; 588 int flags;
580 int version; 589 int version;
581 int reserved; 590 int pk_group;;
582 demux_packet_t *dp; 591 demux_packet_t *dp;
583 int x, sps, cfs, sph, spc, w; 592 int x, sps, cfs, sph, spc, w;
584 int audioreorder_getnextpk = 0; 593 int audioreorder_getnextpk = 0;
585 594
586 // Don't demux video if video codec init failed 595 // Don't demux video if video codec init failed
628 if (len == -256){ /* EOF */ 637 if (len == -256){ /* EOF */
629 // printf("len==-256!\n"); 638 // printf("len==-256!\n");
630 return 0; 639 return 0;
631 } 640 }
632 if (len < 12){ 641 if (len < 12){
642 unsigned int idx_streamid;
633 mp_msg(MSGT_DEMUX, MSGL_V,"%08X: packet v%d len=%d \n",(int)demuxer->filepos,(int)version,(int)len); 643 mp_msg(MSGT_DEMUX, MSGL_V,"%08X: packet v%d len=%d \n",(int)demuxer->filepos,(int)version,(int)len);
634 mp_msg(MSGT_DEMUX, MSGL_WARN,"bad packet len (%d)\n", len); 644 mp_msg(MSGT_DEMUX, MSGL_WARN,"bad packet len (%d)\n", len);
635 if ((unsigned)demuxer->video->id < MAX_STREAMS) { 645 if ((unsigned)demuxer->video->id < MAX_STREAMS) {
636 if (priv->current_vpacket + 1 < priv->index_table_size[demuxer->video->id]) { 646 idx_streamid = priv->is_mlti ? priv->mp2rm_streamid[demuxer->video->id] : demuxer->video->id;
637 stream_seek(demuxer->stream, priv->index_table[demuxer->video->id][++priv->current_vpacket].offset); 647 if (priv->current_vpacket + 1 < priv->index_table_size[idx_streamid]) {
648 stream_seek(demuxer->stream, priv->index_table[idx_streamid][++priv->current_vpacket].offset);
638 } 649 }
639 } else if ((unsigned)demuxer->audio->id < MAX_STREAMS) { 650 } else if ((unsigned)demuxer->audio->id < MAX_STREAMS) {
640 if (priv->current_apacket + 1 < priv->index_table_size[demuxer->audio->id]) { 651 idx_streamid = priv->is_mlti ? priv->mp2rm_streamid[demuxer->audio->id] : demuxer->video->id;
641 stream_seek(demuxer->stream, priv->index_table[demuxer->audio->id][++priv->current_apacket].offset); 652 if (priv->current_apacket + 1 < priv->index_table_size[idx_streamid]) {
653 stream_seek(demuxer->stream, priv->index_table[idx_streamid][++priv->current_apacket].offset);
642 } 654 }
643 } 655 }
644 continue; //goto loop; 656 continue; //goto loop;
645 } 657 }
646 658
647 stream_id = stream_read_word(demuxer->stream); 659 rm_stream_id = stream_read_word(demuxer->stream);
648 timestamp = stream_read_dword(demuxer->stream); 660 timestamp = stream_read_dword(demuxer->stream);
649 reserved = stream_read_char(demuxer->stream); 661 pk_group = stream_read_char(demuxer->stream);
650 flags = stream_read_char(demuxer->stream); 662 flags = stream_read_char(demuxer->stream);
651 /* flags: */ 663 /* flags: */
652 /* 0x1 - reliable */ 664 /* 0x1 - reliable */
653 /* 0x2 - keyframe */ 665 /* 0x2 - keyframe */
654 666
655 if (version == 1) { 667 if (version == 1) {
656 int tmp; 668 int tmp;
657 tmp = stream_read_char(demuxer->stream); 669 tmp = stream_read_char(demuxer->stream);
658 mp_msg(MSGT_DEMUX, MSGL_DBG2,"Version: %d, skipped byte is %d\n", version, tmp); 670 mp_msg(MSGT_DEMUX, MSGL_DBG2,"Version: %d, skipped byte is %d\n", version, tmp);
659 len--; 671 len--;
672 if (priv->is_mlti)
673 mp_msg(MSGT_DEMUX, MSGL_WARN,"MLTI file with v1 DATA, expect problems! Please contact Mplayer developers.\n");
660 } 674 }
661 675
662 if (flags & 2) 676 if (flags & 2)
663 add_index_item(demuxer, stream_id, timestamp, demuxer->filepos); 677 add_index_item(demuxer, rm_stream_id, timestamp, demuxer->filepos);
664 678
665 // printf("%08X: packet v%d len=%4d id=%d pts=%6d rvd=%d flags=%d \n", 679 // printf("%08X: packet v%d len=%4d id=%d pts=%6d rvd=%d flags=%d \n",
666 // (int)demuxer->filepos,(int)version,(int)len, stream_id, 680 // (int)demuxer->filepos,(int)version,(int)len, stream_id,
667 // (int) timestamp, reserved, flags); 681 // (int) timestamp, reserved, flags);
668 682
669 mp_dbg(MSGT_DEMUX,MSGL_DBG2, "\npacket#%d: pos: 0x%0x, len: %d, id: %d, pts: %u, flags: %x rvd:%d\n", 683 mp_dbg(MSGT_DEMUX,MSGL_DBG2, "\npacket#%d: pos: 0x%0x, len: %d, rm_id: %d, pts: %u, flags: %x grp:%d\n",
670 priv->current_packet, (int)demuxer->filepos, len, stream_id, timestamp, flags, reserved); 684 priv->current_packet, (int)demuxer->filepos, len, rm_stream_id, timestamp, flags, pk_group);
671 685
672 priv->current_packet++; 686 priv->current_packet++;
673 len -= 12; 687 len -= 12;
674 688
675 // printf("s_id=%d aid=%d vid=%d \n",stream_id,demuxer->audio->id,demuxer->video->id); 689 // printf("s_id=%d aid=%d vid=%d \n",stream_id,demuxer->audio->id,demuxer->video->id);
676 690
691 // Map rm stream id and packet group to MPlayer stream aid or vid if file is MLTI
692 if (priv->is_mlti && rm_stream_id < MAX_STREAMS && (pk_group>>1) < MAX_MLTIIDX)
693 mp_stream_id = priv->rm2mp[rm_stream_id][(pk_group>>1)-1];
694 else
695 mp_stream_id = rm_stream_id;
696
677 /* check stream_id: */ 697 /* check stream_id: */
678 698
679 if(demuxer->audio->id==stream_id){ 699 if(demuxer->audio->id==mp_stream_id){
680 if (priv->audio_need_keyframe == 1&& flags != 0x2) 700 if (priv->audio_need_keyframe == 1&& flags != 0x2)
681 goto discard; 701 goto discard;
682 got_audio: 702 got_audio:
683 ds=demuxer->audio; 703 ds=demuxer->audio;
684 mp_dbg(MSGT_DEMUX,MSGL_DBG2, "packet is audio (id: %d)\n", stream_id); 704 mp_dbg(MSGT_DEMUX,MSGL_DBG2, "packet is audio (mp_id: %d)\n", mp_stream_id);
685 705
686 if (flags & 2) { 706 if (flags & 2) {
687 priv->sub_packet_cnt = 0; 707 priv->sub_packet_cnt = 0;
688 audioreorder_getnextpk = 0; 708 audioreorder_getnextpk = 0;
689 } 709 }
719 dp->pos = demuxer->filepos; 739 dp->pos = demuxer->filepos;
720 ds_add_packet(ds, dp); 740 ds_add_packet(ds, dp);
721 } 741 }
722 return 1; 742 return 1;
723 } 743 }
724 if ((priv->intl_id[stream_id] == mmioFOURCC('I', 'n', 't', '4')) || 744 if ((priv->intl_id[demuxer->audio->id] == mmioFOURCC('I', 'n', 't', '4')) ||
725 (priv->intl_id[stream_id] == mmioFOURCC('g', 'e', 'n', 'r')) || 745 (priv->intl_id[demuxer->audio->id] == mmioFOURCC('g', 'e', 'n', 'r')) ||
726 (priv->intl_id[stream_id] == mmioFOURCC('s', 'i', 'p', 'r'))) { 746 (priv->intl_id[demuxer->audio->id] == mmioFOURCC('s', 'i', 'p', 'r'))) {
727 sps = priv->sub_packet_size[stream_id]; 747 sps = priv->sub_packet_size[demuxer->audio->id];
728 sph = priv->sub_packet_h[stream_id]; 748 sph = priv->sub_packet_h[demuxer->audio->id];
729 cfs = priv->coded_framesize[stream_id]; 749 cfs = priv->coded_framesize[demuxer->audio->id];
730 w = priv->audiopk_size[stream_id]; 750 w = priv->audiopk_size[demuxer->audio->id];
731 spc = priv->sub_packet_cnt; 751 spc = priv->sub_packet_cnt;
732 switch (priv->intl_id[stream_id]) { 752 switch (priv->intl_id[demuxer->audio->id]) {
733 case mmioFOURCC('I', 'n', 't', '4'): 753 case mmioFOURCC('I', 'n', 't', '4'):
734 if (len < cfs * sph/2) 754 if (len < cfs * sph/2)
735 goto discard; 755 goto discard;
736 for (x = 0; x < sph / 2; x++) 756 for (x = 0; x < sph / 2; x++)
737 stream_read(demuxer->stream, priv->audio_buf + x * 2 * w + spc * cfs, cfs); 757 stream_read(demuxer->stream, priv->audio_buf + x * 2 * w + spc * cfs, cfs);
842 862
843 } // codec_id check, codec default case 863 } // codec_id check, codec default case
844 } 864 }
845 // we will not use audio index if we use -idx and have a video 865 // we will not use audio index if we use -idx and have a video
846 if(((!demuxer->video->sh && index_mode == 2) || priv->is_multirate) && (unsigned)demuxer->audio->id < MAX_STREAMS) { 866 if(((!demuxer->video->sh && index_mode == 2) || priv->is_multirate) && (unsigned)demuxer->audio->id < MAX_STREAMS) {
847 while (priv->current_apacket + 1 < priv->index_table_size[demuxer->audio->id] && 867 while (priv->current_apacket + 1 < priv->index_table_size[rm_stream_id] &&
848 timestamp > priv->index_table[demuxer->audio->id][priv->current_apacket].timestamp) { 868 timestamp > priv->index_table[rm_stream_id][priv->current_apacket].timestamp) {
849 priv->current_apacket += 1; 869 priv->current_apacket += 1;
850 priv->stream_switch = 1; 870 priv->stream_switch = 1;
851 } 871 }
852 if (priv->stream_switch) 872 if (priv->stream_switch)
853 priv->audio_curpos = stream_tell(demuxer->stream); 873 priv->audio_curpos = stream_tell(demuxer->stream);
858 continue; 878 continue;
859 879
860 return 1; 880 return 1;
861 } 881 }
862 882
863 if(demuxer->video->id==stream_id){ 883 if(demuxer->video->id==mp_stream_id){
864 got_video: 884 got_video:
865 ds=demuxer->video; 885 ds=demuxer->video;
866 mp_dbg(MSGT_DEMUX,MSGL_DBG2, "packet is video (id: %d)\n", stream_id); 886 mp_dbg(MSGT_DEMUX,MSGL_DBG2, "packet is video (mp_id: %d)\n", mp_stream_id);
867 887
868 // parse video chunk: 888 // parse video chunk:
869 { 889 {
870 // we need a more complicated, 2nd level demuxing, as the video 890 // we need a more complicated, 2nd level demuxing, as the video
871 // frames are stored fragmented in the video chunks :( 891 // frames are stored fragmented in the video chunks :(
1039 mp_msg(MSGT_DEMUX, MSGL_WARN,"\n******** !!!!!!!! BUG!! len=%d !!!!!!!!!!! ********\n",len); 1059 mp_msg(MSGT_DEMUX, MSGL_WARN,"\n******** !!!!!!!! BUG!! len=%d !!!!!!!!!!! ********\n",len);
1040 if(len>0) stream_skip(demuxer->stream, len); 1060 if(len>0) stream_skip(demuxer->stream, len);
1041 } 1061 }
1042 } 1062 }
1043 if ((unsigned)demuxer->video->id < MAX_STREAMS) { 1063 if ((unsigned)demuxer->video->id < MAX_STREAMS) {
1044 while (priv->current_vpacket + 1 < priv->index_table_size[demuxer->video->id] && 1064 while (priv->current_vpacket + 1 < priv->index_table_size[rm_stream_id] &&
1045 timestamp > priv->index_table[demuxer->video->id][priv->current_vpacket + 1].timestamp) { 1065 timestamp > priv->index_table[rm_stream_id][priv->current_vpacket + 1].timestamp) {
1046 priv->current_vpacket += 1; 1066 priv->current_vpacket += 1;
1047 priv->stream_switch = 1; 1067 priv->stream_switch = 1;
1048 } 1068 }
1049 if (priv->stream_switch) 1069 if (priv->stream_switch)
1050 priv->video_curpos = stream_tell(demuxer->stream); 1070 priv->video_curpos = stream_tell(demuxer->stream);
1051 } 1071 }
1052 1072
1053 return 1; 1073 return 1;
1054 } 1074 }
1055 1075
1056 if((unsigned)stream_id<MAX_STREAMS){ 1076 if((unsigned)rm_stream_id<MAX_STREAMS){
1057 1077 if(demuxer->audio->id==-1 && demuxer->a_streams[mp_stream_id]){
1058 if(demuxer->audio->id==-1 && demuxer->a_streams[stream_id]){ 1078 sh_audio_t *sh = demuxer->a_streams[mp_stream_id];
1059 sh_audio_t *sh = demuxer->a_streams[stream_id]; 1079 demuxer->audio->id=mp_stream_id;
1060 demuxer->audio->id=stream_id;
1061 sh->ds=demuxer->audio; 1080 sh->ds=demuxer->audio;
1062 demuxer->audio->sh=sh; 1081 demuxer->audio->sh=sh;
1063 priv->audio_buf = calloc(priv->sub_packet_h[demuxer->audio->id], priv->audiopk_size[demuxer->audio->id]); 1082 priv->audio_buf = calloc(priv->sub_packet_h[demuxer->audio->id], priv->audiopk_size[demuxer->audio->id]);
1064 priv->audio_timestamp = calloc(priv->sub_packet_h[demuxer->audio->id], sizeof(double)); 1083 priv->audio_timestamp = calloc(priv->sub_packet_h[demuxer->audio->id], sizeof(double));
1065 mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected RM audio ID = %d\n",stream_id); 1084 mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected RM audio ID = %d (rm id %d)\n",mp_stream_id, rm_stream_id);
1066 goto got_audio; 1085 goto got_audio;
1067 } 1086 }
1068 1087
1069 if(demuxer->video->id==-1 && demuxer->v_streams[stream_id]){ 1088 if(demuxer->video->id==-1 && demuxer->v_streams[mp_stream_id]){
1070 sh_video_t *sh = demuxer->v_streams[stream_id]; 1089 sh_video_t *sh = demuxer->v_streams[mp_stream_id];
1071 demuxer->video->id=stream_id; 1090 demuxer->video->id=mp_stream_id;
1072 sh->ds=demuxer->video; 1091 sh->ds=demuxer->video;
1073 demuxer->video->sh=sh; 1092 demuxer->video->sh=sh;
1074 mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected RM video ID = %d\n",stream_id); 1093 mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected RM video ID = %d (rm id %d)\n",mp_stream_id, rm_stream_id);
1075 goto got_video; 1094 goto got_video;
1076 } 1095 }
1077 1096
1078 } 1097 }
1079 1098
1080 mp_msg(MSGT_DEMUX,MSGL_DBG2, "unknown stream id (%d)\n", stream_id); 1099 mp_msg(MSGT_DEMUX,MSGL_DBG2, "unknown stream id (%d)\n", rm_stream_id);
1081 discard: 1100 discard:
1082 stream_skip(demuxer->stream, len); 1101 stream_skip(demuxer->stream, len);
1083 }// goto loop; 1102 }// goto loop;
1084 return 0; 1103 return 0;
1085 } 1104 }
1138 stream_skip(demuxer->stream, 4); /* preroll */ 1157 stream_skip(demuxer->stream, 4); /* preroll */
1139 priv->index_chunk_offset = stream_read_dword(demuxer->stream); 1158 priv->index_chunk_offset = stream_read_dword(demuxer->stream);
1140 mp_msg(MSGT_DEMUX,MSGL_V,"First index chunk offset: 0x%x\n", priv->index_chunk_offset); 1159 mp_msg(MSGT_DEMUX,MSGL_V,"First index chunk offset: 0x%x\n", priv->index_chunk_offset);
1141 priv->data_chunk_offset = stream_read_dword(demuxer->stream)+10; 1160 priv->data_chunk_offset = stream_read_dword(demuxer->stream)+10;
1142 mp_msg(MSGT_DEMUX,MSGL_V,"First data chunk offset: 0x%x\n", priv->data_chunk_offset); 1161 mp_msg(MSGT_DEMUX,MSGL_V,"First data chunk offset: 0x%x\n", priv->data_chunk_offset);
1143 stream_skip(demuxer->stream, 2); /* nb streams */ 1162 priv->streams_in_file = stream_read_word(demuxer->stream);
1163 mp_msg(MSGT_DEMUX,MSGL_V,"Number of streams in file: %d\n", priv->streams_in_file);
1144 #if 0 1164 #if 0
1145 stream_skip(demuxer->stream, 2); /* flags */ 1165 stream_skip(demuxer->stream, 2); /* flags */
1146 #else 1166 #else
1147 { 1167 {
1148 int flags = stream_read_word(demuxer->stream); 1168 int flags = stream_read_word(demuxer->stream);
1216 int codec_data_size; 1236 int codec_data_size;
1217 int codec_pos; 1237 int codec_pos;
1218 int tmp; 1238 int tmp;
1219 int len; 1239 int len;
1220 char *descr, *mimet = NULL; 1240 char *descr, *mimet = NULL;
1221
1222 stream_id = stream_read_word(demuxer->stream); 1241 stream_id = stream_read_word(demuxer->stream);
1223 mp_msg(MSGT_DEMUX,MSGL_V,"Found new stream (id: %d)\n", stream_id); 1242 mp_msg(MSGT_DEMUX,MSGL_V,"Found new stream (id: %d)\n", stream_id);
1224 1243
1225 stream_skip(demuxer->stream, 4); /* max bitrate */ 1244 stream_skip(demuxer->stream, 4); /* max bitrate */
1226 bitrate = stream_read_dword(demuxer->stream); /* avg bitrate */ 1245 bitrate = stream_read_dword(demuxer->stream); /* avg bitrate */
1252 #define stream_skip(st,siz) { int i; for(i=0;i<siz;i++) mp_msg(MSGT_DEMUX,MSGL_V," %02X",stream_read_char(st)); mp_msg(MSGT_DEMUX,MSGL_V,"\n");} 1271 #define stream_skip(st,siz) { int i; for(i=0;i<siz;i++) mp_msg(MSGT_DEMUX,MSGL_V," %02X",stream_read_char(st)); mp_msg(MSGT_DEMUX,MSGL_V,"\n");}
1253 #endif 1272 #endif
1254 1273
1255 if (!strncmp(mimet,"audio/",6)) { 1274 if (!strncmp(mimet,"audio/",6)) {
1256 if (strstr(mimet,"x-pn-realaudio") || strstr(mimet,"x-pn-multirate-realaudio")) { 1275 if (strstr(mimet,"x-pn-realaudio") || strstr(mimet,"x-pn-multirate-realaudio")) {
1276 int num_mlti, mlti_cnt, ra_size;
1257 tmp = stream_read_dword(demuxer->stream); 1277 tmp = stream_read_dword(demuxer->stream);
1278 if (tmp == MKTAG('I', 'T', 'L', 'M')) // MLTI chunk in audio
1279 {
1280 int num_streams, stream_cnt;
1281 mp_msg(MSGT_DEMUX,MSGL_V,"MLTI chunk in audio.\n");
1282 num_streams = stream_read_word(demuxer->stream);
1283 for (stream_cnt = 0; stream_cnt < num_streams; stream_cnt++)
1284 stream_skip(demuxer->stream, 2); // MDPR index, one per stream
1285 num_mlti = stream_read_word(demuxer->stream);
1286 if (num_mlti != 1) {
1287 mp_msg(MSGT_DEMUX,MSGL_V,"Found MLTI in audio with %d substreams.\n", num_mlti);
1288 priv->is_mlti = 1;
1289 } else
1290 mp_msg(MSGT_DEMUX,MSGL_V,"Found MLTI in audio with 1 substreams. Ingnoring\n", num_mlti);
1291 if (num_mlti > MAX_MLTIIDX) {
1292 mp_msg(MSGT_DEMUX,MSGL_ERR,"Too many (%d) MLTI audio, truncating; expect problems. Please report to Mplayer developers.\n", num_mlti);
1293 num_mlti = MAX_MLTIIDX - 1; // Limit to max MLTI
1294 }
1295 ra_size = stream_read_dword(demuxer->stream); // Size of the following .ra chunk
1296 tmp = stream_read_dword(demuxer->stream);
1297 } else {
1298 num_mlti = 1;
1299 ra_size = codec_data_size;
1300 }
1301 for (mlti_cnt = 0; mlti_cnt < num_mlti; mlti_cnt++) {
1302 if (mlti_cnt) {
1303 ra_size = stream_read_dword(demuxer->stream); // Size of the following .ra chunk
1304 tmp = stream_read_dword(demuxer->stream);
1305 }
1258 if (tmp != MKTAG(0xfd, 'a', 'r', '.')) 1306 if (tmp != MKTAG(0xfd, 'a', 'r', '.'))
1259 { 1307 {
1260 mp_msg(MSGT_DEMUX,MSGL_V,"Audio: can't find .ra in codec data\n"); 1308 mp_msg(MSGT_DEMUX,MSGL_V,"Audio: can't find .ra in codec data\n");
1309 stream_skip(demuxer->stream, ra_size - 4);
1261 } else { 1310 } else {
1262 /* audio header */ 1311 /* audio header */
1263 sh_audio_t *sh = new_sh_audio(demuxer, stream_id, NULL); 1312 int aid = priv->is_mlti ? priv->streams_in_file + a_streams + v_streams : stream_id;
1313 sh_audio_t *sh = new_sh_audio(demuxer, aid, NULL);
1264 char buf[128]; /* for codec name */ 1314 char buf[128]; /* for codec name */
1265 int frame_size; 1315 int frame_size;
1266 int sub_packet_size; 1316 int sub_packet_size;
1267 int sub_packet_h; 1317 int sub_packet_h;
1268 int version; 1318 int version;
1270 int coded_frame_size; 1320 int coded_frame_size;
1271 int codecdata_length; 1321 int codecdata_length;
1272 int i; 1322 int i;
1273 char *buft; 1323 char *buft;
1274 int hdr_size; 1324 int hdr_size;
1275 mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_AudioID, "real", stream_id); 1325 mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_AudioID, "real", aid);
1326 priv->mp2rm_streamid[aid] = stream_id;
1327 priv->rm2mp[stream_id][mlti_cnt] = aid;
1328 mp_msg(MSGT_DEMUX,MSGL_V,"Mplayer aid %d is rm stream %d with MDPR index %d\n", aid, stream_id, mlti_cnt);
1276 mp_msg(MSGT_DEMUX,MSGL_V,"Found audio stream!\n"); 1329 mp_msg(MSGT_DEMUX,MSGL_V,"Found audio stream!\n");
1277 version = stream_read_word(demuxer->stream); 1330 version = stream_read_word(demuxer->stream);
1278 mp_msg(MSGT_DEMUX,MSGL_V,"version: %d\n", version); 1331 mp_msg(MSGT_DEMUX,MSGL_V,"version: %d\n", version);
1279 if (version == 3) { 1332 if (version == 3) {
1280 stream_skip(demuxer->stream, 2); 1333 stream_skip(demuxer->stream, 2);
1353 sh->samplerate, sh->channels); 1406 sh->samplerate, sh->channels);
1354 1407
1355 if (version == 5) 1408 if (version == 5)
1356 { 1409 {
1357 stream_read(demuxer->stream, buf, 4); // interleaver id 1410 stream_read(demuxer->stream, buf, 4); // interleaver id
1358 priv->intl_id[stream_id] = MKTAG(buf[0], buf[1], buf[2], buf[3]); 1411 priv->intl_id[aid] = MKTAG(buf[0], buf[1], buf[2], buf[3]);
1359 stream_read(demuxer->stream, buf, 4); // fourcc 1412 stream_read(demuxer->stream, buf, 4); // fourcc
1360 buf[4] = 0; 1413 buf[4] = 0;
1361 } 1414 }
1362 else 1415 else
1363 { 1416 {
1364 /* Interleaver id */ 1417 /* Interleaver id */
1365 get_str(1, demuxer, buf, sizeof(buf)); 1418 get_str(1, demuxer, buf, sizeof(buf));
1366 priv->intl_id[stream_id] = MKTAG(buf[0], buf[1], buf[2], buf[3]); 1419 priv->intl_id[aid] = MKTAG(buf[0], buf[1], buf[2], buf[3]);
1367 /* Codec FourCC */ 1420 /* Codec FourCC */
1368 get_str(1, demuxer, buf, sizeof(buf)); 1421 get_str(1, demuxer, buf, sizeof(buf));
1369 } 1422 }
1370 } 1423 }
1371 1424
1407 goto skip_this_chunk; 1460 goto skip_this_chunk;
1408 } 1461 }
1409 sh->wf->cbSize = codecdata_length; 1462 sh->wf->cbSize = codecdata_length;
1410 sh->wf = realloc(sh->wf, sizeof(*sh->wf)+sh->wf->cbSize); 1463 sh->wf = realloc(sh->wf, sizeof(*sh->wf)+sh->wf->cbSize);
1411 stream_read(demuxer->stream, ((char*)(sh->wf+1)), codecdata_length); // extras 1464 stream_read(demuxer->stream, ((char*)(sh->wf+1)), codecdata_length); // extras
1412 if (priv->intl_id[stream_id] == MKTAG('g', 'e', 'n', 'r')) 1465 if (priv->intl_id[aid] == MKTAG('g', 'e', 'n', 'r'))
1413 sh->wf->nBlockAlign = sub_packet_size; 1466 sh->wf->nBlockAlign = sub_packet_size;
1414 else 1467 else
1415 sh->wf->nBlockAlign = coded_frame_size; 1468 sh->wf->nBlockAlign = coded_frame_size;
1416 1469
1417 break; 1470 break;
1436 default: 1489 default:
1437 mp_msg(MSGT_DEMUX,MSGL_V,"Audio: Unknown (%s)\n", buf); 1490 mp_msg(MSGT_DEMUX,MSGL_V,"Audio: Unknown (%s)\n", buf);
1438 } 1491 }
1439 1492
1440 // Interleaver setup 1493 // Interleaver setup
1441 priv->sub_packet_size[stream_id] = sub_packet_size; 1494 priv->sub_packet_size[aid] = sub_packet_size;
1442 priv->sub_packet_h[stream_id] = sub_packet_h; 1495 priv->sub_packet_h[aid] = sub_packet_h;
1443 priv->coded_framesize[stream_id] = coded_frame_size; 1496 priv->coded_framesize[aid] = coded_frame_size;
1444 priv->audiopk_size[stream_id] = frame_size; 1497 priv->audiopk_size[aid] = frame_size;
1445 1498
1446 sh->wf->wFormatTag = sh->format; 1499 sh->wf->wFormatTag = sh->format;
1447 1500
1448 mp_msg(MSGT_DEMUX,MSGL_V,"audio fourcc: %.4s (%x)\n", (char *)&sh->format, sh->format); 1501 mp_msg(MSGT_DEMUX,MSGL_V,"audio fourcc: %.4s (%x)\n", (char *)&sh->format, sh->format);
1449 if ( mp_msg_test(MSGT_DEMUX,MSGL_V) ) 1502 if ( mp_msg_test(MSGT_DEMUX,MSGL_V) )
1467 ++a_streams; 1520 ++a_streams;
1468 1521
1469 #ifdef stream_skip 1522 #ifdef stream_skip
1470 #undef stream_skip 1523 #undef stream_skip
1471 #endif 1524 #endif
1472 } 1525 } // .ra
1526 } // MLTI
1473 } else if (strstr(mimet,"X-MP3-draft-00")) { 1527 } else if (strstr(mimet,"X-MP3-draft-00")) {
1474 sh_audio_t *sh = new_sh_audio(demuxer, stream_id, NULL); 1528 sh_audio_t *sh = new_sh_audio(demuxer, stream_id, NULL);
1475 mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_AudioID, "real", stream_id); 1529 mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_AudioID, "real", stream_id);
1476 1530
1477 /* Emulate WAVEFORMATEX struct: */ 1531 /* Emulate WAVEFORMATEX struct: */
1516 } else { 1570 } else {
1517 mp_msg(MSGT_DEMUX,MSGL_V,"Unknown audio stream format\n"); 1571 mp_msg(MSGT_DEMUX,MSGL_V,"Unknown audio stream format\n");
1518 } 1572 }
1519 } else if (!strncmp(mimet,"video/",6)) { 1573 } else if (!strncmp(mimet,"video/",6)) {
1520 if (strstr(mimet,"x-pn-realvideo") || strstr(mimet,"x-pn-multirate-realvideo")) { 1574 if (strstr(mimet,"x-pn-realvideo") || strstr(mimet,"x-pn-multirate-realvideo")) {
1521 stream_skip(demuxer->stream, 4); // VIDO length, same as codec_data_size 1575 int num_mlti, mlti_cnt, vido_size, vido_pos;
1522 tmp = stream_read_dword(demuxer->stream); 1576 tmp = stream_read_dword(demuxer->stream);
1577 if (tmp == MKTAG('I', 'T', 'L', 'M')) // MLTI chunk in video
1578 {
1579 int num_streams, stream_cnt;
1580 mp_msg(MSGT_DEMUX,MSGL_V,"MLTI chunk in video.\n");
1581 num_streams = stream_read_word(demuxer->stream);
1582 for (stream_cnt = 0; stream_cnt < num_streams; stream_cnt++)
1583 stream_skip(demuxer->stream, 2); // MDPR index, one per stream
1584 num_mlti = stream_read_word(demuxer->stream);
1585 if (num_mlti != 1) {
1586 mp_msg(MSGT_DEMUX,MSGL_V,"Found MLTI in video with %d substreams.\n", num_mlti);
1587 priv->is_mlti = 1;
1588 } else
1589 mp_msg(MSGT_DEMUX,MSGL_V,"Found MLTI in audio with 1 substreams. Ingnoring\n", num_mlti);
1590 if (num_mlti > MAX_MLTIIDX) {
1591 mp_msg(MSGT_DEMUX,MSGL_ERR,"Too many (%d) MLTI video, truncating; expect problems. Please report to Mplayer developers.\n", num_mlti);
1592 num_mlti = MAX_MLTIIDX - 1; // Limit to max MLTI
1593 }
1594 vido_size = stream_read_dword(demuxer->stream); // Size of the following .vido chunk
1595 vido_pos = stream_tell(demuxer->stream);;
1596 stream_skip(demuxer->stream, 4);
1597 tmp = stream_read_dword(demuxer->stream);
1598 priv->is_mlti = 1;
1599 } else {
1600 num_mlti = 1;
1601 vido_size = codec_data_size;
1602 vido_pos = codec_pos;
1603 tmp = stream_read_dword(demuxer->stream);
1604 }
1605 for (mlti_cnt = 0; mlti_cnt < num_mlti; mlti_cnt++) {
1606 if (mlti_cnt) {
1607 vido_size = stream_read_dword(demuxer->stream); // Size of the following vido chunk
1608 mp_msg(MSGT_DEMUX,MSGL_V,"VIDO size: %x\n", vido_size);
1609 vido_pos = stream_tell(demuxer->stream);;
1610 stream_skip(demuxer->stream, 4);
1611 tmp = stream_read_dword(demuxer->stream);
1612 }
1523 if(tmp != MKTAG('O', 'D', 'I', 'V')) 1613 if(tmp != MKTAG('O', 'D', 'I', 'V'))
1524 { 1614 {
1525 mp_msg(MSGT_DEMUX,MSGL_V,"Video: can't find VIDO in codec data\n"); 1615 mp_msg(MSGT_DEMUX,MSGL_V,"Video: can't find VIDO in codec data\n");
1616 stream_skip(demuxer->stream, vido_size - 4);
1526 } else { 1617 } else {
1527 /* video header */ 1618 /* video header */
1528 sh_video_t *sh = new_sh_video(demuxer, stream_id); 1619 int vid = priv->is_mlti ? priv->streams_in_file + a_streams + v_streams : stream_id;
1529 mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_VideoID, "real", stream_id); 1620 sh_video_t *sh = new_sh_video(demuxer, vid);
1621 mp_msg(MSGT_DEMUX, MSGL_INFO, MSGTR_VideoID, "real", vid);
1622 priv->mp2rm_streamid[vid] = stream_id;
1623 priv->rm2mp[stream_id][mlti_cnt] = vid;
1624 mp_msg(MSGT_DEMUX,MSGL_V,"Mplayer vid %d is rm stream %d with MDPR index %d\n", vid, stream_id, mlti_cnt);
1530 1625
1531 sh->format = stream_read_dword_le(demuxer->stream); /* fourcc */ 1626 sh->format = stream_read_dword_le(demuxer->stream); /* fourcc */
1532 mp_msg(MSGT_DEMUX,MSGL_V,"video fourcc: %.4s (%x)\n", (char *)&sh->format, sh->format); 1627 mp_msg(MSGT_DEMUX,MSGL_V,"video fourcc: %.4s (%x)\n", (char *)&sh->format, sh->format);
1533 1628
1534 /* emulate BITMAPINFOHEADER */ 1629 /* emulate BITMAPINFOHEADER */
1567 } 1662 }
1568 stream_skip(demuxer->stream, 2); 1663 stream_skip(demuxer->stream, 2);
1569 1664
1570 { 1665 {
1571 // read and store codec extradata 1666 // read and store codec extradata
1572 unsigned int cnt = codec_data_size - (stream_tell(demuxer->stream) - codec_pos); 1667 unsigned int cnt = vido_size - (stream_tell(demuxer->stream) - vido_pos);
1573 if (cnt > 0x7fffffff - sizeof(*sh->bih)) { 1668 if (cnt > 0x7fffffff - sizeof(*sh->bih)) {
1574 mp_msg(MSGT_DEMUX, MSGL_ERR,"Extradata too big (%u)\n", cnt); 1669 mp_msg(MSGT_DEMUX, MSGL_ERR,"Extradata too big (%u)\n", cnt);
1575 } else { 1670 } else {
1576 sh->bih = realloc(sh->bih, sizeof(*sh->bih) + cnt); 1671 sh->bih = realloc(sh->bih, sizeof(*sh->bih) + cnt);
1577 sh->bih->biSize += cnt; 1672 sh->bih->biSize += cnt;
1594 demuxer->video->sh=sh; 1689 demuxer->video->sh=sh;
1595 } 1690 }
1596 1691
1597 ++v_streams; 1692 ++v_streams;
1598 1693
1599 } 1694 } // VIDO
1695 } // MLTI
1600 } else { 1696 } else {
1601 mp_msg(MSGT_DEMUX,MSGL_V,"Unknown video stream format\n"); 1697 mp_msg(MSGT_DEMUX,MSGL_V,"Unknown video stream format\n");
1602 } 1698 }
1603 } else if (strstr(mimet,"logical-")) { 1699 } else if (strstr(mimet,"logical-")) {
1604 if (strstr(mimet,"fileinfo")) { 1700 if (strstr(mimet,"fileinfo")) {
1659 break; 1755 break;
1660 } 1756 }
1661 } 1757 }
1662 1758
1663 header_end: 1759 header_end:
1760 if(priv->is_multirate && priv->is_mlti)
1761 mp_msg(MSGT_DEMUX,MSGL_ERR,"Multirate and MLTI in the same file is bad. Please contact Mplayer developers.\n");
1762
1664 if(priv->is_multirate) { 1763 if(priv->is_multirate) {
1665 mp_msg(MSGT_DEMUX,MSGL_V,"Selected video id %d audio id %d\n", demuxer->video->id, demuxer->audio->id); 1764 mp_msg(MSGT_DEMUX,MSGL_V,"Selected video id %d audio id %d\n", demuxer->video->id, demuxer->audio->id);
1666 /* Perform some sanity checks to avoid checking streams id all over the code*/ 1765 /* Perform some sanity checks to avoid checking streams id all over the code*/
1667 if (demuxer->audio->id >= MAX_STREAMS) { 1766 if (demuxer->audio->id >= MAX_STREAMS) {
1668 mp_msg(MSGT_DEMUX,MSGL_ERR,"Invalid audio stream %d. No sound will be played.\n", demuxer->audio->id); 1767 mp_msg(MSGT_DEMUX,MSGL_ERR,"Invalid audio stream %d. No sound will be played.\n", demuxer->audio->id);
1804 int next_offset = 0; 1903 int next_offset = 0;
1805 int64_t target_timestamp = 0; 1904 int64_t target_timestamp = 0;
1806 int streams = 0; 1905 int streams = 0;
1807 int retried = 0; 1906 int retried = 0;
1808 1907
1908
1909 if (priv->is_mlti && (unsigned)vid < MAX_STREAMS)
1910 vid = priv->mp2rm_streamid[d_video->id];
1911 if (priv->is_mlti && (unsigned)aid < MAX_STREAMS)
1912 aid = priv->mp2rm_streamid[d_audio->id];
1809 1913
1810 if (sh_video && (unsigned)vid < MAX_STREAMS && priv->index_table_size[vid]) 1914 if (sh_video && (unsigned)vid < MAX_STREAMS && priv->index_table_size[vid])
1811 streams |= 1; 1915 streams |= 1;
1812 if (sh_audio && (unsigned)aid < MAX_STREAMS && priv->index_table_size[aid]) 1916 if (sh_audio && (unsigned)aid < MAX_STREAMS && priv->index_table_size[aid])
1813 streams |= 2; 1917 streams |= 2;