Mercurial > mplayer.hg
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)){ |