Ticket #364: rmdec.diff
| File rmdec.diff, 13.8 KB (added by , 15 years ago) |
|---|
-
libavformat/rmdec.c
diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c index d952391..baff50d 100644
a b typedef struct { 48 48 int remaining_len; 49 49 int audio_stream_num; ///< Stream number for audio packets 50 50 int audio_pkt_cnt; ///< Output packet counter 51 52 int video_after_seek; 53 int64_t kf_base; ///< timestamp of the prev. video keyframe 54 uint32_t kf_pts; ///< timestamp of next video keyframe 51 55 } RMDemuxContext; 52 56 53 57 static const unsigned char sipr_swaps[38][2] = { … … static const unsigned char sipr_swaps[38][2] = { 65 69 66 70 const unsigned char ff_sipr_subpk_size[4] = { 29, 19, 37, 20 }; 67 71 72 #define RM_SKIP_BITS(n) buffer<<=n 73 #define RM_SHOW_BITS(n) ((buffer)>>(32-(n))) 74 75 static int rm_fix_timestamp(uint8_t *buf, uint32_t timestamp, uint32_t format, 76 int64_t *kf_base, int *kf_pts, int *pts) 77 { 78 uint8_t *s = buf + 1 + (*buf+1)*8; 79 uint32_t buffer = (s[0]<<24) + (s[1]<<16) + (s[2]<<8) + s[3]; 80 uint32_t kf = timestamp; 81 int pict_type; 82 uint32_t orig_kf; 83 84 if(format == MKTAG('R','V','3','0') || format == MKTAG('R','V','4','0')){ 85 if(format == MKTAG('R','V','3','0')){ 86 RM_SKIP_BITS(3); 87 pict_type = RM_SHOW_BITS(2); 88 RM_SKIP_BITS(2 + 7); 89 }else{ 90 RM_SKIP_BITS(1); 91 pict_type = RM_SHOW_BITS(2); 92 RM_SKIP_BITS(2 + 7 + 3); 93 } 94 orig_kf = kf = RM_SHOW_BITS(13); // kf= 2*SHOW_BITS(12); 95 if(pict_type <= 1){ 96 // I frame, sync timestamps: 97 *kf_base = (int64_t)timestamp-kf; 98 av_log(NULL, AV_LOG_DEBUG,"\nTS: base=%08"PRIX64"\n",*kf_base); 99 kf = timestamp; 100 } else { 101 // P/B frame, merge timestamps: 102 int64_t tmp = (int64_t)timestamp - *kf_base; 103 kf |= tmp&(~0x1fff); // combine with packet timestamp 104 if(kf<tmp-4096) kf += 8192; else // workaround wrap-around problems 105 if(kf>tmp+4096) kf -= 8192; 106 kf += *kf_base; 107 } 108 if(pict_type != 3){ // P || I frame -> swap timestamps 109 uint32_t tmp=kf; 110 kf = *kf_pts; 111 *kf_pts = tmp; 112 } 113 av_log(NULL, AV_LOG_DEBUG,"\nTS: %08X -> %08X (%04X) %d %02X %02X %02X %02X %5u\n", 114 timestamp,kf,orig_kf,pict_type,s[0],s[1],s[2],s[3],pts?kf-(*pts):0); 115 } 116 if(pts) 117 *pts = kf; 118 return kf; 119 } 120 121 static void process_video_timestamp(RMDemuxContext *rm, uint32_t codec_tag,AVPacket *pkt) 122 { 123 //FIXME: it seems that only RV30 can deliver the braindamaged AV_NOPTS_VALUE 124 if(pkt->pts == AV_NOPTS_VALUE) 125 return; 126 if(rm->video_after_seek){ 127 rm->kf_base = 0; 128 rm->kf_pts = pkt->pts; 129 rm->video_after_seek = 0; 130 } 131 pkt->pts = rm_fix_timestamp(pkt->data, pkt->pts, 132 codec_tag, 133 &rm->kf_base, &rm->kf_pts, 134 NULL); 135 } 136 68 137 static inline void get_strl(AVIOContext *pb, char *buf, int buf_size, int len) 69 138 { 70 139 int i; 71 char *q , r;140 char *q = buf, r; 72 141 73 142 q = buf; 74 143 for(i=0;i<len;i++) { … … static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, 125 194 AVStream *st, RMStream *ast, int read_all) 126 195 { 127 196 char buf[256]; 128 uint32_t version ;197 uint32_t version,headsize; 129 198 int ret; 130 199 131 200 /* ra type header */ 132 201 version = avio_rb16(pb); /* version */ 202 headsize = avio_rb16(pb); 133 203 if (version == 3) { 134 int header_size = avio_rb16(pb);135 204 int64_t startpos = avio_tell(pb); 205 int64_t headoffset = startpos + headsize; 206 136 207 avio_skip(pb, 14); 137 208 rm_read_metadata(s, 0); 138 if ( (startpos + header_size)>= avio_tell(pb) + 2) {209 if (headoffset >= avio_tell(pb) + 2) { 139 210 // fourcc (should always be "lpcJ") 140 211 avio_r8(pb); 141 212 get_str8(pb, buf, sizeof(buf)); 142 213 } 143 214 // Skip extra header crap (this should never happen) 144 if ( (startpos + header_size)> avio_tell(pb))145 avio_skip(pb, head er_size + startpos- avio_tell(pb));215 if (headoffset > avio_tell(pb)) 216 avio_skip(pb, headoffset - avio_tell(pb)); 146 217 st->codec->sample_rate = 8000; 147 218 st->codec->channels = 1; 148 219 st->codec->codec_type = AVMEDIA_TYPE_AUDIO; 149 220 st->codec->codec_id = CODEC_ID_RA_144; 150 221 } else { 151 int flavor , sub_packet_h, coded_framesize, sub_packet_size;222 int flavor; 152 223 int codecdata_length; 153 224 /* old version (4) */ 154 avio_skip(pb, 2); /* unused */155 225 avio_rb32(pb); /* .ra4 */ 156 226 avio_rb32(pb); /* data size */ 157 227 avio_rb16(pb); /* version2 */ 158 228 avio_rb32(pb); /* header size */ 159 229 flavor= avio_rb16(pb); /* add codec info / flavor */ 160 ast->coded_framesize = coded_framesize =avio_rb32(pb); /* coded frame size */230 ast->coded_framesize = avio_rb32(pb); /* coded frame size */ 161 231 avio_rb32(pb); /* ??? */ 162 232 avio_rb32(pb); /* ??? */ 163 233 avio_rb32(pb); /* ??? */ 164 ast->sub_packet_h = sub_packet_h =avio_rb16(pb); /* 1 */234 ast->sub_packet_h = avio_rb16(pb); /* 1 */ 165 235 st->codec->block_align= avio_rb16(pb); /* frame size */ 166 ast->sub_packet_size = sub_packet_size =avio_rb16(pb); /* sub packet size */236 ast->sub_packet_size = avio_rb16(pb); /* sub packet size */ 167 237 avio_rb16(pb); /* ??? */ 168 238 if (version == 5) { 169 avio_rb16(pb); avio_rb16(pb); avio_rb16(pb); 239 avio_rb16(pb); 240 avio_rb16(pb); 241 avio_rb16(pb); 170 242 } 171 243 st->codec->sample_rate = avio_rb16(pb); 172 avio_rb32(pb); 244 avio_rb16(pb); /* ??? */ 245 avio_rb16(pb); /* sample size */ 173 246 st->codec->channels = avio_rb16(pb); 174 247 if (version == 5) { 175 248 avio_rb32(pb); … … static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, 177 250 buf[4] = 0; 178 251 } else { 179 252 get_str8(pb, buf, sizeof(buf)); /* desc */ 180 get_str8(pb, buf, sizeof(buf)); /* desc*/253 get_str8(pb, buf, sizeof(buf)); /* FOURCC */ 181 254 } 182 255 st->codec->codec_type = AVMEDIA_TYPE_AUDIO; 183 256 st->codec->codec_tag = AV_RL32(buf); … … static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, 190 263 case CODEC_ID_RA_288: 191 264 st->codec->extradata_size= 0; 192 265 ast->audio_framesize = st->codec->block_align; 193 st->codec->block_align = coded_framesize;266 st->codec->block_align = ast->coded_framesize; 194 267 195 if(ast->audio_framesize >= UINT_MAX / sub_packet_h){268 if(ast->audio_framesize >= UINT_MAX / ast->sub_packet_h){ 196 269 av_log(s, AV_LOG_ERROR, "ast->audio_framesize * sub_packet_h too large\n"); 197 270 return -1; 198 271 } 199 272 200 av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h);273 av_new_packet(&ast->pkt, ast->audio_framesize * ast->sub_packet_h); 201 274 break; 202 275 case CODEC_ID_COOK: 203 276 case CODEC_ID_ATRAC3: … … static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, 220 293 } 221 294 st->codec->block_align = ff_sipr_subpk_size[flavor]; 222 295 } else { 223 if( sub_packet_size <= 0){296 if(ast->sub_packet_size <= 0){ 224 297 av_log(s, AV_LOG_ERROR, "sub_packet_size is invalid\n"); 225 298 return -1; 226 299 } … … static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, 229 302 if ((ret = rm_read_extradata(pb, st->codec, codecdata_length)) < 0) 230 303 return ret; 231 304 232 if(ast->audio_framesize >= UINT_MAX / sub_packet_h){305 if(ast->audio_framesize >= UINT_MAX / ast->sub_packet_h){ 233 306 av_log(s, AV_LOG_ERROR, "rm->audio_framesize * sub_packet_h too large\n"); 234 307 return -1; 235 308 } 236 309 237 av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h);310 av_new_packet(&ast->pkt, ast->audio_framesize * ast->sub_packet_h); 238 311 break; 239 312 case CODEC_ID_AAC: 240 313 avio_rb16(pb); avio_r8(pb); … … ff_rm_read_mdpr_codecdata (AVFormatContext *s, AVIOContext *pb, 281 354 if (rm_read_audio_stream_info(s, pb, st, rst, 0)) 282 355 return -1; 283 356 } else { 284 int fps, fps2;357 int gcd, fps; 285 358 if (avio_rl32(pb) != MKTAG('V', 'I', 'D', 'O')) { 286 359 fail1: 287 360 av_log(st->codec, AV_LOG_ERROR, "Unsupported video codec\n"); 361 st->codec->codec_id = CODEC_ID_NONE; 288 362 goto skip; 289 363 } 290 364 st->codec->codec_tag = avio_rl32(pb); … … ff_rm_read_mdpr_codecdata (AVFormatContext *s, AVIOContext *pb, 296 370 st->codec->width = avio_rb16(pb); 297 371 st->codec->height = avio_rb16(pb); 298 372 st->codec->time_base.num= 1 << 16; 299 fps= avio_rb16(pb);373 avio_rb16(pb); /* bpp */ 300 374 st->codec->codec_type = AVMEDIA_TYPE_VIDEO; 301 375 avio_rb32(pb); 302 fps 2= avio_rb32(pb);376 fps= avio_rb32(pb); 303 377 304 378 if ((ret = rm_read_extradata(pb, st->codec, codec_data_size - (avio_tell(pb) - codec_pos))) < 0) 305 379 return ret; 306 380 307 381 // av_log(s, AV_LOG_DEBUG, "fps= %d fps2= %d\n", fps, fps2); 308 st->codec->time_base.den = fps2; 382 st->codec->time_base.den = fps; 383 gcd = av_gcd(st->codec->time_base.num, st->codec->time_base.den); 384 st->codec->time_base.num /= gcd; 385 st->codec->time_base.den /= gcd; 309 386 //XXX: do we really need that? 310 387 switch(st->codec->extradata[4]>>4){ 311 388 case 1: st->codec->codec_id = CODEC_ID_RV10; break; … … skip: 370 447 return 0; 371 448 } 372 449 450 /* audio data is CBR */ 373 451 static int rm_read_header_old(AVFormatContext *s, AVFormatParameters *ap) 374 452 { 375 453 RMDemuxContext *rm = s->priv_data; … … static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) 388 466 RMDemuxContext *rm = s->priv_data; 389 467 AVStream *st; 390 468 AVIOContext *pb = s->pb; 391 unsigned int tag ;469 unsigned int tag, head_size; 392 470 int tag_size; 393 unsigned int start_time, duration;394 471 unsigned int data_off = 0, indx_off = 0; 395 472 char buf[128]; 396 473 int flags = 0; … … static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) 403 480 return AVERROR(EIO); 404 481 } 405 482 406 avio_rb32(pb); /* header size */ 407 avio_rb16(pb); 408 avio_rb32(pb); 483 head_size = avio_rb32(pb); /* header size */ 484 avio_rb16(pb); /* chunk version */ 485 /* file version */ 486 if(0x12 == head_size) 487 avio_rb32(pb); 488 else 489 avio_rb16(pb); 409 490 avio_rb32(pb); /* number of headers */ 410 491 411 492 for(;;) { … … static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) 413 494 return -1; 414 495 tag = avio_rl32(pb); 415 496 tag_size = avio_rb32(pb); 416 avio_rb16(pb); 497 avio_rb16(pb); /* version */ 417 498 #if 0 418 499 printf("tag=%c%c%c%c (%08x) size=%d\n", 419 500 (tag) & 0xff, … … static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) 433 514 avio_rb32(pb); /* max packet size */ 434 515 avio_rb32(pb); /* avg packet size */ 435 516 avio_rb32(pb); /* nb packets */ 436 avio_rb32(pb); /* duration */437 avio_rb32(pb); /* preroll */438 indx_off = avio_rb32(pb); /* index offset */439 data_off = avio_rb32(pb); /* data offset */517 avio_rb32(pb); /* duration in ms */ 518 avio_rb32(pb); /* preroll in ms */ 519 indx_off = avio_rb32(pb); /* the first index offset */ 520 data_off = avio_rb32(pb); /* the first data offset */ 440 521 avio_rb16(pb); /* nb streams */ 441 522 flags = avio_rb16(pb); /* flags */ 442 523 break; … … static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) 449 530 return AVERROR(ENOMEM); 450 531 st->id = avio_rb16(pb); 451 532 avio_rb32(pb); /* max bit rate */ 452 st->codec->bit_rate = avio_rb32(pb); /* bit rate */533 st->codec->bit_rate = avio_rb32(pb); /* avg bit rate */ 453 534 avio_rb32(pb); /* max packet size */ 454 535 avio_rb32(pb); /* avg packet size */ 455 start_time = avio_rb32(pb); /* start time */ 456 avio_rb32(pb); /* preroll */ 457 duration = avio_rb32(pb); /* duration */ 458 st->start_time = start_time; 459 st->duration = duration; 536 st->start_time = avio_rb32(pb); /* start time in ms */ 537 avio_rb32(pb); /* preroll in ms */ 538 st->duration = avio_rb32(pb); /* duration in ms */ 460 539 get_str8(pb, buf, sizeof(buf)); /* desc */ 461 540 get_str8(pb, buf, sizeof(buf)); /* mimetype */ 462 541 st->codec->codec_type = AVMEDIA_TYPE_DATA; … … ff_rm_parse_packet (AVFormatContext *s, AVIOContext *pb, 786 865 pkt->pts= timestamp; 787 866 if (flags & 2) 788 867 pkt->flags |= AV_PKT_FLAG_KEY; 868 if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO) 869 process_video_timestamp(rm,st->codec->codec_tag,pkt); 789 870 790 871 return st->codec->codec_type == AVMEDIA_TYPE_AUDIO ? rm->audio_pkt_cnt : 0; 791 872 } … … ff_rm_retrieve_cache (AVFormatContext *s, AVIOContext *pb, 809 890 rm->audio_pkt_cnt--; 810 891 if ((pkt->pts = ast->audiotimestamp) != AV_NOPTS_VALUE) { 811 892 ast->audiotimestamp = AV_NOPTS_VALUE; 812 pkt->flags = AV_PKT_FLAG_KEY;893 pkt->flags |= AV_PKT_FLAG_KEY; 813 894 } else 814 pkt->flags = 0;895 pkt->flags &= (~AV_PKT_FLAG_KEY); 815 896 pkt->stream_index = st->index; 816 897 817 898 return rm->audio_pkt_cnt; … … static int64_t rm_read_dts(AVFormatContext *s, int stream_index, 934 1015 avio_skip(s->pb, len); 935 1016 } 936 1017 *ppos = pos; 1018 rm->video_after_seek = 1; 937 1019 return dts; 938 1020 } 939 1021
