comparison libmpdemux/demux_real.c @ 14402:53a70339c70c

Real multirate files support
author rtognimp
date Thu, 06 Jan 2005 16:29:46 +0000
parents 4f55098c2e19
children 5dac1eeb8d6b
comparison
equal deleted inserted replaced
14401:ddf3ac9a7539 14402:53a70339c70c
75 /* stream id table */ 75 /* stream id table */
76 // int last_a_stream; 76 // int last_a_stream;
77 // int a_streams[MAX_STREAMS]; 77 // int a_streams[MAX_STREAMS];
78 // int last_v_stream; 78 // int last_v_stream;
79 // int v_streams[MAX_STREAMS]; 79 // int v_streams[MAX_STREAMS];
80
81 /**
82 * Used to demux multirate files
83 */
84 int is_multirate; ///< != 0 for multirate files
85 int str_data_offset[MAX_STREAMS]; ///< Data chunk offset for every audio/video stream
86 int audio_curpos; ///< Current file position for audio demuxing
87 int video_curpos; ///< Current file position for video demuxing
88 int a_num_of_packets; ///< Number of audio packets
89 int v_num_of_packets; ///< Number of video packets
90 int a_idx_ptr; ///< Audio index position pointer
91 int v_idx_ptr; ///< Video index position pointer
92 int a_bitrate; ///< Audio bitrate
93 int v_bitrate; ///< Video bitrate
94 int stream_switch; ///< Flag used to switch audio/video demuxing
80 } real_priv_t; 95 } real_priv_t;
81 96
82 /* originally from FFmpeg */ 97 /* originally from FFmpeg */
83 static void get_str(int isbyte, demuxer_t *demuxer, char *buf, int buf_size) 98 static void get_str(int isbyte, demuxer_t *demuxer, char *buf, int buf_size)
84 { 99 {
512 int reserved; 527 int reserved;
513 demux_packet_t *dp; 528 demux_packet_t *dp;
514 529
515 while(1){ 530 while(1){
516 531
532 /* Handle audio/video demxing switch for multirate files (non-interleaved) */
533 if (priv->is_multirate && priv->stream_switch) {
534 if (priv->a_idx_ptr >= priv->index_table_size[demuxer->audio->id])
535 demuxer->audio->eof = 1;
536 if (priv->v_idx_ptr >= priv->index_table_size[demuxer->video->id])
537 demuxer->video->eof = 1;
538 if (demuxer->audio->eof && demuxer->video->eof)
539 return 0;
540 else if (!demuxer->audio->eof && demuxer->video->eof)
541 stream_seek(demuxer->stream, priv->audio_curpos); // Get audio
542 else if (demuxer->audio->eof && !demuxer->video->eof)
543 stream_seek(demuxer->stream, priv->video_curpos); // Get video
544 else if (priv->index_table[demuxer->audio->id][priv->a_idx_ptr].timestamp <
545 priv->index_table[demuxer->video->id][priv->v_idx_ptr].timestamp)
546 stream_seek(demuxer->stream, priv->audio_curpos); // Get audio
547 else
548 stream_seek(demuxer->stream, priv->video_curpos); // Get video
549 priv->stream_switch = 0;
550 }
551
517 demuxer->filepos = stream_tell(demuxer->stream); 552 demuxer->filepos = stream_tell(demuxer->stream);
518 version = stream_read_word(demuxer->stream); /* version */ 553 version = stream_read_word(demuxer->stream); /* version */
519 len = stream_read_word(demuxer->stream); 554 len = stream_read_word(demuxer->stream);
520 if ((version==0x4441) && (len==0x5441)) { // new data chunk 555 if ((version==0x4441) && (len==0x5441)) { // new data chunk
521 mp_msg(MSGT_DEMUX,MSGL_INFO,"demux_real: New data chunk is coming!!!\n"); 556 mp_msg(MSGT_DEMUX,MSGL_INFO,"demux_real: New data chunk is coming!!!\n");
557 if (priv->is_multirate)
558 return 0; // EOF
522 stream_skip(demuxer->stream,14); 559 stream_skip(demuxer->stream,14);
523 demuxer->filepos = stream_tell(demuxer->stream); 560 demuxer->filepos = stream_tell(demuxer->stream);
524 version = stream_read_word(demuxer->stream); /* version */ 561 version = stream_read_word(demuxer->stream); /* version */
525 len = stream_read_word(demuxer->stream); 562 len = stream_read_word(demuxer->stream);
526 } else if ((version == 0x494e) && (len == 0x4458)) { 563 } else if ((version == 0x494e) && (len == 0x4458)) {
545 reserved = stream_read_char(demuxer->stream); 582 reserved = stream_read_char(demuxer->stream);
546 flags = stream_read_char(demuxer->stream); 583 flags = stream_read_char(demuxer->stream);
547 /* flags: */ 584 /* flags: */
548 /* 0x1 - reliable */ 585 /* 0x1 - reliable */
549 /* 0x2 - keyframe */ 586 /* 0x2 - keyframe */
587
588 if (version == 1) {
589 int tmp;
590 tmp = stream_read_char(demuxer->stream);
591 mp_msg(MSGT_DEMUX, MSGL_DBG2,"Version: %d, skipped byte is %d\n", version, tmp);
592 len--;
593 }
550 594
551 if (flags & 2) 595 if (flags & 2)
552 add_index_item(demuxer, stream_id, timestamp, demuxer->filepos); 596 add_index_item(demuxer, stream_id, timestamp, demuxer->filepos);
553 597
554 // printf("%08X: packet v%d len=%4d id=%d pts=%6d rvd=%d flags=%d \n", 598 // printf("%08X: packet v%d len=%4d id=%d pts=%6d rvd=%d flags=%d \n",
646 // we will not use audio index if we use -idx and have a video 690 // we will not use audio index if we use -idx and have a video
647 if(!demuxer->video->sh && index_mode == 2 && (unsigned)demuxer->audio->id < MAX_STREAMS) 691 if(!demuxer->video->sh && index_mode == 2 && (unsigned)demuxer->audio->id < MAX_STREAMS)
648 while (priv->current_apacket + 1 < priv->index_table_size[demuxer->audio->id] && 692 while (priv->current_apacket + 1 < priv->index_table_size[demuxer->audio->id] &&
649 timestamp > priv->index_table[demuxer->audio->id][priv->current_apacket].timestamp) 693 timestamp > priv->index_table[demuxer->audio->id][priv->current_apacket].timestamp)
650 priv->current_apacket += 1; 694 priv->current_apacket += 1;
695
696 if(priv->is_multirate)
697 while (priv->a_idx_ptr + 1 < priv->index_table_size[demuxer->audio->id] &&
698 timestamp > priv->index_table[demuxer->audio->id][priv->a_idx_ptr + 1].timestamp) {
699 priv->a_idx_ptr++;
700 priv->audio_curpos = stream_tell(demuxer->stream);
701 priv->stream_switch = 1;
702 }
651 703
652 return 1; 704 return 1;
653 } 705 }
654 706
655 if(demuxer->video->id==stream_id){ 707 if(demuxer->video->id==stream_id){
856 if ((unsigned)demuxer->video->id < MAX_STREAMS) 908 if ((unsigned)demuxer->video->id < MAX_STREAMS)
857 while (priv->current_vpacket + 1 < priv->index_table_size[demuxer->video->id] && 909 while (priv->current_vpacket + 1 < priv->index_table_size[demuxer->video->id] &&
858 timestamp > priv->index_table[demuxer->video->id][priv->current_vpacket + 1].timestamp) 910 timestamp > priv->index_table[demuxer->video->id][priv->current_vpacket + 1].timestamp)
859 priv->current_vpacket += 1; 911 priv->current_vpacket += 1;
860 912
913 if(priv->is_multirate)
914 while (priv->v_idx_ptr + 1 < priv->index_table_size[demuxer->video->id] &&
915 timestamp > priv->index_table[demuxer->video->id][priv->v_idx_ptr + 1].timestamp) {
916 priv->v_idx_ptr++;
917 priv->video_curpos = stream_tell(demuxer->stream);
918 priv->stream_switch = 1;
919 }
920
861 return 1; 921 return 1;
862 } 922 }
863 923
864 if(stream_id<256){ 924 if(stream_id<256){
865 925
1023 int stream_id; 1083 int stream_id;
1024 int bitrate; 1084 int bitrate;
1025 int codec_data_size; 1085 int codec_data_size;
1026 int codec_pos; 1086 int codec_pos;
1027 int tmp; 1087 int tmp;
1088 int len;
1089 char *descr, *mimet;
1028 1090
1029 stream_id = stream_read_word(demuxer->stream); 1091 stream_id = stream_read_word(demuxer->stream);
1030 mp_msg(MSGT_DEMUX,MSGL_V,"Found new stream (id: %d)\n", stream_id); 1092 mp_msg(MSGT_DEMUX,MSGL_V,"Found new stream (id: %d)\n", stream_id);
1031 1093
1032 stream_skip(demuxer->stream, 4); /* max bitrate */ 1094 stream_skip(demuxer->stream, 4); /* max bitrate */
1035 stream_skip(demuxer->stream, 4); /* avg packet size */ 1097 stream_skip(demuxer->stream, 4); /* avg packet size */
1036 stream_skip(demuxer->stream, 4); /* start time */ 1098 stream_skip(demuxer->stream, 4); /* start time */
1037 stream_skip(demuxer->stream, 4); /* preroll */ 1099 stream_skip(demuxer->stream, 4); /* preroll */
1038 stream_skip(demuxer->stream, 4); /* duration */ 1100 stream_skip(demuxer->stream, 4); /* duration */
1039 1101
1040 skip_str(1, demuxer); /* stream description (name) */ 1102 // skip_str(1, demuxer); /* stream description (name) */
1041 skip_str(1, demuxer); /* mimetype */ 1103 if ((len = stream_read_char(demuxer->stream)) > 0) {
1104 descr = malloc(len+1);
1105 stream_read(demuxer->stream, descr, len);
1106 descr[len] = 0;
1107 printf("Stream description: %s\n", descr);
1108 free(descr);
1109 }
1110 // skip_str(1, demuxer); /* mimetype */
1111 if ((len = stream_read_char(demuxer->stream)) > 0) {
1112 mimet = malloc(len+1);
1113 stream_read(demuxer->stream, mimet, len);
1114 mimet[len] = 0;
1115 printf("Stream mimetype: %s\n", mimet);
1116 }
1042 1117
1043 /* Type specific header */ 1118 /* Type specific header */
1044 codec_data_size = stream_read_dword(demuxer->stream); 1119 codec_data_size = stream_read_dword(demuxer->stream);
1045 codec_pos = stream_tell(demuxer->stream); 1120 codec_pos = stream_tell(demuxer->stream);
1046 1121
1047 if (!codec_data_size) {
1048 mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_real: no codec data in MDPR chunk at fpos=0x%X\n", codec_pos);
1049 break;
1050 }
1051
1052 tmp = stream_read_dword(demuxer->stream);
1053
1054 mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_real: type_spec: len=%d fpos=0x%X first_dword=0x%X (%.4s) \n",
1055 (int)codec_data_size,(int)codec_pos,tmp,&tmp);
1056
1057 #if 1
1058 // skip unknown shit - FIXME: find a better/cleaner way!
1059 { int len=codec_data_size;
1060 while(--len>=8){
1061 if(tmp==MKTAG(0xfd, 'a', 'r', '.')) break; // audio
1062 if(tmp==MKTAG('O', 'D', 'I', 'V')) break; // video
1063 tmp=(tmp<<8)|stream_read_char(demuxer->stream);
1064 }
1065 }
1066 #endif
1067
1068 #ifdef MP_DEBUG 1122 #ifdef MP_DEBUG
1069 #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");} 1123 #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");}
1070 #endif 1124 #endif
1071 1125
1072 if (tmp == MKTAG(0xfd, 'a', 'r', '.')) 1126 if (!strncmp(mimet,"audio/",6)) {
1127 if (strstr(mimet,"x-pn-realaudio") || strstr(mimet,"x-pn-multirate-realaudio")) {
1128 // skip unknown shit - FIXME: find a better/cleaner way!
1129 len=codec_data_size;
1130 tmp = stream_read_dword(demuxer->stream);
1131 // mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_real: type_spec: len=%d fpos=0x%X first_dword=0x%X (%.4s) \n",
1132 // (int)codec_data_size,(int)codec_pos,tmp,&tmp);
1133 while(--len>=8){
1134 if(tmp==MKTAG(0xfd, 'a', 'r', '.')) break; // audio
1135 tmp=(tmp<<8)|stream_read_char(demuxer->stream);
1136 }
1137 if (tmp != MKTAG(0xfd, 'a', 'r', '.'))
1073 { 1138 {
1139 mp_msg(MSGT_DEMUX,MSGL_V,"Audio: can't find .ra in codec data\n");
1140 } else {
1074 /* audio header */ 1141 /* audio header */
1075 sh_audio_t *sh = new_sh_audio(demuxer, stream_id); 1142 sh_audio_t *sh = new_sh_audio(demuxer, stream_id);
1076 char buf[128]; /* for codec name */ 1143 char buf[128]; /* for codec name */
1077 int frame_size; 1144 int frame_size;
1078 int sub_packet_size; 1145 int sub_packet_size;
1311 sh->wf->wFormatTag = sh->format; 1378 sh->wf->wFormatTag = sh->format;
1312 1379
1313 if (verbose > 0) 1380 if (verbose > 0)
1314 print_wave_header(sh->wf); 1381 print_wave_header(sh->wf);
1315 1382
1383 /* Select audio stream with highest bitrate if multirate file*/
1384 if (priv->is_multirate && ((demuxer->audio->id == -1) ||
1385 ((demuxer->audio->id >= 0) && priv->a_bitrate && (bitrate > priv->a_bitrate)))) {
1386 demuxer->audio->id = stream_id;
1387 priv->a_bitrate = bitrate;
1388 mp_msg(MSGT_DEMUX,MSGL_DBG2,"Multirate autoselected audio id %d with bitrate %d\n", stream_id, bitrate);
1389 }
1390
1316 if(demuxer->audio->id==stream_id){ 1391 if(demuxer->audio->id==stream_id){
1317 demuxer->audio->id=stream_id; 1392 demuxer->audio->id=stream_id;
1318 sh->ds=demuxer->audio; 1393 sh->ds=demuxer->audio;
1319 demuxer->audio->sh=sh; 1394 demuxer->audio->sh=sh;
1320 } 1395 }
1323 1398
1324 #ifdef stream_skip 1399 #ifdef stream_skip
1325 #undef stream_skip 1400 #undef stream_skip
1326 #endif 1401 #endif
1327 } 1402 }
1328 else 1403 #if 0
1329 // case MKTAG('V', 'I', 'D', 'O'): 1404 } else if (strstr(mimet,"X-MP3")) {
1330 if(tmp == MKTAG('O', 'D', 'I', 'V')) 1405 sh_audio_t *sh = new_sh_audio(demuxer, stream_id);
1406
1407 /* Emulate WAVEFORMATEX struct: */
1408 sh->wf = malloc(sizeof(WAVEFORMATEX));
1409 memset(sh->wf, 0, sizeof(WAVEFORMATEX));
1410 sh->wf->nChannels = 0;//sh->channels;
1411 sh->wf->wBitsPerSample = 16;
1412 sh->wf->nSamplesPerSec = 0;//sh->samplerate;
1413 sh->wf->nAvgBytesPerSec = 0;//bitrate;
1414 sh->wf->nBlockAlign = 0;//frame_size;
1415 sh->wf->cbSize = 0;
1416 sh->wf->wFormatTag = sh->format = 0x55;
1417
1418 if(demuxer->audio->id==stream_id){
1419 sh->ds=demuxer->audio;
1420 demuxer->audio->sh=sh;
1421 }
1422
1423 ++a_streams;
1424 #endif
1425 } else if (strstr(mimet,"x-ralf-mpeg4")) {
1426 mp_msg(MSGT_DEMUX,MSGL_ERR,"Real lossless audio not supported yet\n");
1427 } else {
1428 mp_msg(MSGT_DEMUX,MSGL_V,"Unknown audio stream format\n");
1429 }
1430 } else if (!strncmp(mimet,"video/",6)) {
1431 if (strstr(mimet,"x-pn-realvideo") || strstr(mimet,"x-pn-multirate-realvideo")) {
1432 tmp = stream_read_dword(demuxer->stream);
1433 // mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_real: type_spec: len=%d fpos=0x%X first_dword=0x%X (%.4s) \n",
1434 // (int)codec_data_size,(int)codec_pos,tmp,&tmp);
1435 // skip unknown shit - FIXME: find a better/cleaner way!
1436 len=codec_data_size;
1437 while(--len>=8){
1438 if(tmp==MKTAG('O', 'D', 'I', 'V')) break; // video
1439 tmp=(tmp<<8)|stream_read_char(demuxer->stream);
1440 }
1441 if(tmp != MKTAG('O', 'D', 'I', 'V'))
1331 { 1442 {
1443 mp_msg(MSGT_DEMUX,MSGL_V,"Video: can't find VIDO in codec data\n");
1444 } else {
1332 /* video header */ 1445 /* video header */
1333 sh_video_t *sh = new_sh_video(demuxer, stream_id); 1446 sh_video_t *sh = new_sh_video(demuxer, stream_id);
1334 1447
1335 sh->format = stream_read_dword_le(demuxer->stream); /* fourcc */ 1448 sh->format = stream_read_dword_le(demuxer->stream); /* fourcc */
1336 mp_msg(MSGT_DEMUX,MSGL_V,"video fourcc: %.4s (%x)\n", (char *)&sh->format, sh->format); 1449 mp_msg(MSGT_DEMUX,MSGL_V,"video fourcc: %.4s (%x)\n", (char *)&sh->format, sh->format);
1409 // read secondary WxH for the cmsg24[] (see vd_realvid.c) 1522 // read secondary WxH for the cmsg24[] (see vd_realvid.c)
1410 ((unsigned short*)(sh->bih+1))[4]=4*(unsigned short)stream_read_char(demuxer->stream); //widht 1523 ((unsigned short*)(sh->bih+1))[4]=4*(unsigned short)stream_read_char(demuxer->stream); //widht
1411 ((unsigned short*)(sh->bih+1))[5]=4*(unsigned short)stream_read_char(demuxer->stream); //height 1524 ((unsigned short*)(sh->bih+1))[5]=4*(unsigned short)stream_read_char(demuxer->stream); //height
1412 } 1525 }
1413 1526
1527 /* Select video stream with highest bitrate if multirate file*/
1528 if (priv->is_multirate && ((demuxer->video->id == -1) ||
1529 ((demuxer->video->id >= 0) && priv->v_bitrate && (bitrate > priv->v_bitrate)))) {
1530 demuxer->video->id = stream_id;
1531 priv->v_bitrate = bitrate;
1532 mp_msg(MSGT_DEMUX,MSGL_DBG2,"Multirate autoselected video id %d with bitrate %d\n", stream_id, bitrate);
1533 }
1534
1414 if(demuxer->video->id==stream_id){ 1535 if(demuxer->video->id==stream_id){
1415 demuxer->video->id=stream_id; 1536 demuxer->video->id=stream_id;
1416 sh->ds=demuxer->video; 1537 sh->ds=demuxer->video;
1417 demuxer->video->sh=sh; 1538 demuxer->video->sh=sh;
1418 } 1539 }
1419 1540
1420 ++v_streams; 1541 ++v_streams;
1421 1542
1422 } 1543 }
1544 } else {
1545 mp_msg(MSGT_DEMUX,MSGL_V,"Unknown video stream format\n");
1546 }
1547 } else if (strstr(mimet,"logical-")) {
1548 if (strstr(mimet,"fileinfo")) {
1549 mp_msg(MSGT_DEMUX,MSGL_V,"Got a logical-fileinfo chunk\n");
1550 } else if (strstr(mimet,"-audio") || strstr(mimet,"-video")) {
1551 int i, stream_cnt;
1552 int stream_list[MAX_STREAMS];
1553
1554 priv->is_multirate = 1;
1555 stream_skip(demuxer->stream, 4); // Length of codec data (repeated)
1556 stream_cnt = stream_read_dword(demuxer->stream); // Get number of audio or video streams
1557 if (stream_cnt >= MAX_STREAMS) {
1558 mp_msg(MSGT_DEMUX,MSGL_ERR,"Too many streams in %s. Big troubles ahead.\n", mimet);
1559 goto skip_this_chunk;
1560 }
1561 for (i = 0; i < stream_cnt; i++)
1562 stream_list[i] = stream_read_word(demuxer->stream);
1563 for (i = 0; i < stream_cnt; i++)
1564 if (stream_list[i] >= MAX_STREAMS) {
1565 mp_msg(MSGT_DEMUX,MSGL_ERR,"Stream id out of range: %d. Ignored.\n", stream_list[i]);
1566 stream_skip(demuxer->stream, 4); // Skip DATA offset for broken stream
1567 } else {
1568 priv->str_data_offset[stream_list[i]] = stream_read_dword(demuxer->stream);
1569 mp_msg(MSGT_DEMUX,MSGL_V,"Stream %d with DATA offset 0x%08x\n", stream_list[i], priv->str_data_offset[stream_list[i]]);
1570 }
1571 // Skip the rest of this chunk
1572 } else
1573 mp_msg(MSGT_DEMUX,MSGL_V,"Unknown logical stream\n");
1574 }
1423 else { 1575 else {
1424 mp_msg(MSGT_DEMUX, MSGL_ERR, "Not audio/video stream or unsupported!\n"); 1576 mp_msg(MSGT_DEMUX, MSGL_ERR, "Not audio/video stream or unsupported!\n");
1425 } 1577 }
1426 // break; 1578 // break;
1427 // default: 1579 // default:
1428 //skip_this_chunk: 1580 skip_this_chunk:
1429 /* skip codec info */ 1581 /* skip codec info */
1430 tmp = stream_tell(demuxer->stream) - codec_pos; 1582 tmp = stream_tell(demuxer->stream) - codec_pos;
1431 mp_msg(MSGT_DEMUX,MSGL_V,"### skipping %d bytes of codec info\n", codec_data_size - tmp); 1583 mp_msg(MSGT_DEMUX,MSGL_V,"### skipping %d bytes of codec info\n", codec_data_size - tmp);
1432 #if 0 1584 #if 0
1433 { int i; 1585 { int i;
1436 mp_msg(MSGT_DEMUX, MSGL_V,"\n"); 1588 mp_msg(MSGT_DEMUX, MSGL_V,"\n");
1437 } 1589 }
1438 #else 1590 #else
1439 stream_skip(demuxer->stream, codec_data_size - tmp); 1591 stream_skip(demuxer->stream, codec_data_size - tmp);
1440 #endif 1592 #endif
1593 if (mimet)
1594 free (mimet);
1441 break; 1595 break;
1442 // } 1596 // }
1443 } 1597 }
1444 case MKTAG('D', 'A', 'T', 'A'): 1598 case MKTAG('D', 'A', 'T', 'A'):
1445 goto header_end; 1599 goto header_end;
1450 break; 1604 break;
1451 } 1605 }
1452 } 1606 }
1453 1607
1454 header_end: 1608 header_end:
1609 if(priv->is_multirate) {
1610 mp_msg(MSGT_DEMUX,MSGL_V,"Selected video id %d audio id %d\n", demuxer->video->id, demuxer->audio->id);
1611 /* Perform some sanity checks to avoid checking streams id all over the code*/
1612 if (demuxer->audio->id >= MAX_STREAMS) {
1613 mp_msg(MSGT_DEMUX,MSGL_ERR,"Invalid audio stream %d. No sound will be played.\n", demuxer->audio->id);
1614 demuxer->audio->id = -2;
1615 } else if ((demuxer->audio->id >= 0) && (priv->str_data_offset[demuxer->audio->id] == 0)) {
1616 mp_msg(MSGT_DEMUX,MSGL_ERR,"Audio stream %d not found. No sound will be played.\n", demuxer->audio->id);
1617 demuxer->audio->id = -2;
1618 }
1619 if (demuxer->video->id >= MAX_STREAMS) {
1620 mp_msg(MSGT_DEMUX,MSGL_ERR,"Invalid video stream %d. No video will be played.\n", demuxer->video->id);
1621 demuxer->video->id = -2;
1622 } else if ((demuxer->video->id >= 0) && (priv->str_data_offset[demuxer->video->id] == 0)) {
1623 mp_msg(MSGT_DEMUX,MSGL_ERR,"Video stream %d not found. No video will be played.\n", demuxer->video->id);
1624 demuxer->video->id = -2;
1625 }
1626 }
1627
1628 if(priv->is_multirate && ((demuxer->video->id >= 0) || (demuxer->audio->id >=0))) {
1629 /* If audio or video only, seek to right place and behave like standard file */
1630 if (demuxer->video->id < 0) {
1631 // Stream is audio only, or -novideo
1632 stream_seek(demuxer->stream, priv->data_chunk_offset = priv->str_data_offset[demuxer->audio->id]+10);
1633 priv->is_multirate = 0;
1634 }
1635 if (demuxer->audio->id < 0) {
1636 // Stream is video only, or -nosound
1637 stream_seek(demuxer->stream, priv->data_chunk_offset = priv->str_data_offset[demuxer->video->id]+10);
1638 priv->is_multirate = 0;
1639 }
1640 }
1641
1642 if(!priv->is_multirate) {
1455 // printf("i=%d num_of_headers=%d \n",i,num_of_headers); 1643 // printf("i=%d num_of_headers=%d \n",i,num_of_headers);
1456 priv->num_of_packets = stream_read_dword(demuxer->stream); 1644 priv->num_of_packets = stream_read_dword(demuxer->stream);
1457 // stream_skip(demuxer->stream, 4); /* number of packets */ 1645 // stream_skip(demuxer->stream, 4); /* number of packets */
1458 stream_skip(demuxer->stream, 4); /* next data header */ 1646 stream_skip(demuxer->stream, 4); /* next data header */
1459 1647
1460 mp_msg(MSGT_DEMUX,MSGL_V,"Packets in file: %d\n", priv->num_of_packets); 1648 mp_msg(MSGT_DEMUX,MSGL_V,"Packets in file: %d\n", priv->num_of_packets);
1461 1649
1462 if (priv->num_of_packets == 0) 1650 if (priv->num_of_packets == 0)
1463 priv->num_of_packets = -10; 1651 priv->num_of_packets = -10;
1652 } else {
1653 priv->audio_curpos = priv->str_data_offset[demuxer->audio->id] + 18;
1654 stream_seek(demuxer->stream, priv->str_data_offset[demuxer->audio->id]+10);
1655 priv->a_num_of_packets=priv->a_num_of_packets = stream_read_dword(demuxer->stream);
1656 priv->video_curpos = priv->str_data_offset[demuxer->video->id] + 18;
1657 stream_seek(demuxer->stream, priv->str_data_offset[demuxer->video->id]+10);
1658 priv->v_num_of_packets = stream_read_dword(demuxer->stream);
1659 priv->stream_switch = 1;
1660 /* Index required for multirate playback, force building if it's not there */
1661 /* but respect user request to force index regeneration */
1662 if (index_mode == -1)
1663 index_mode = 1;
1664 }
1464 1665
1465 1666
1466 priv->audio_need_keyframe = 0; 1667 priv->audio_need_keyframe = 0;
1467 priv->video_after_seek = 0; 1668 priv->video_after_seek = 0;
1468 1669
1489 demuxer->seekable = 1; 1690 demuxer->seekable = 1;
1490 break; 1691 break;
1491 default: // do nothing 1692 default: // do nothing
1492 break; 1693 break;
1493 } 1694 }
1695
1696 if(priv->is_multirate)
1697 demuxer->seekable = 0; // No seeking yet for multirate streams
1494 1698
1495 // detect streams: 1699 // detect streams:
1496 if(demuxer->video->id==-1 && v_streams>0){ 1700 if(demuxer->video->id==-1 && v_streams>0){
1497 // find the valid video stream: 1701 // find the valid video stream:
1498 if(!ds_fill_buffer(demuxer->video)){ 1702 if(!ds_fill_buffer(demuxer->video)){