comparison src/wma/libffwma/asf.c @ 3123:a2093254960a

Sanity check to work around a WMA decoding error.
author John Lindgren <john.lindgren@tds.net>
date Wed, 06 May 2009 12:11:06 -0400
parents 55703f60fd54
children
comparison
equal deleted inserted replaced
3122:5744479b31f4 3123:a2093254960a
39 int ds_span; /* descrambling */ 39 int ds_span; /* descrambling */
40 int ds_packet_size; 40 int ds_packet_size;
41 int ds_chunk_size; 41 int ds_chunk_size;
42 int ds_data_size; 42 int ds_data_size;
43 int ds_silence_data; 43 int ds_silence_data;
44 44
45 int packet_pos; 45 int packet_pos;
46 46
47 } ASFStream; 47 } ASFStream;
48 48
49 typedef struct { 49 typedef struct {
187 const CodecTag codec_wav_tags[] = { 187 const CodecTag codec_wav_tags[] = {
188 /* { CODEC_ID_MP2, 0x50 }, 188 /* { CODEC_ID_MP2, 0x50 },
189 { CODEC_ID_MP3, 0x55 }, 189 { CODEC_ID_MP3, 0x55 },
190 { CODEC_ID_AC3, 0x2000 }, 190 { CODEC_ID_AC3, 0x2000 },
191 { CODEC_ID_PCM_S16LE, 0x01 }, 191 { CODEC_ID_PCM_S16LE, 0x01 },
192 { CODEC_ID_PCM_U8, 0x01 }, 192 { CODEC_ID_PCM_U8, 0x01 },
193 { CODEC_ID_PCM_ALAW, 0x06 }, 193 { CODEC_ID_PCM_ALAW, 0x06 },
194 { CODEC_ID_PCM_MULAW, 0x07 }, 194 { CODEC_ID_PCM_MULAW, 0x07 },
195 { CODEC_ID_ADPCM_MS, 0x02 }, 195 { CODEC_ID_ADPCM_MS, 0x02 },
196 { CODEC_ID_ADPCM_IMA_WAV, 0x11 }, 196 { CODEC_ID_ADPCM_IMA_WAV, 0x11 },
197 { CODEC_ID_ADPCM_IMA_DK4, 0x61 }, 197 { CODEC_ID_ADPCM_IMA_DK4, 0x61 },
198 { CODEC_ID_ADPCM_IMA_DK3, 0x62 },*/ 198 { CODEC_ID_ADPCM_IMA_DK3, 0x62 },*/
199 { CODEC_ID_WMAV1, 0x160, 0 }, 199 { CODEC_ID_WMAV1, 0x160, 0 },
200 { CODEC_ID_WMAV2, 0x161, 0 }, 200 { CODEC_ID_WMAV2, 0x161, 0 },
201 { 0, 0, 0 }, 201 { 0, 0, 0 },
202 }; 202 };
358 AVStream *st; 358 AVStream *st;
359 ASFStream *asf_st; 359 ASFStream *asf_st;
360 //int size, i; 360 //int size, i;
361 int i; 361 int i;
362 int64_t gsize; 362 int64_t gsize;
363 uint64_t block_begin;
363 364
364 av_set_pts_info(s, 32, 1, 1000); /* 32 bit pts in ms */ 365 av_set_pts_info(s, 32, 1, 1000); /* 32 bit pts in ms */
365 366
366 get_guid(pb, &g); 367 get_guid(pb, &g);
367 if (memcmp(&g, &asf_header, sizeof(GUID))) 368 if (memcmp(&g, &asf_header, sizeof(GUID)))
368 goto fail; 369 goto fail;
369 get_le64(pb); 370 get_le64(pb);
370 get_le32(pb); 371 get_le32(pb);
371 get_byte(pb); 372 get_byte(pb);
372 get_byte(pb); 373 get_byte(pb);
374
375 block_begin = 30;
376
373 memset(&asf->asfid2avid, -1, sizeof(asf->asfid2avid)); 377 memset(&asf->asfid2avid, -1, sizeof(asf->asfid2avid));
374 for(;;) { 378 for(;;) {
379 if (url_ftell (pb) != block_begin) /* sanity check */
380 {
381 printf ("ASF: error reading header; trying to recover...\n");
382 url_fseek (pb, block_begin, SEEK_SET);
383 }
384
375 get_guid(pb, &g); 385 get_guid(pb, &g);
376 gsize = get_le64(pb); 386 gsize = get_le64(pb);
377 #ifdef DEBUG 387 #ifdef DEBUG
378 printf("%08Lx: ", url_ftell(pb) - 24); 388 printf("%08Lx: ", url_ftell(pb) - 24);
379 print_guid(&g); 389 print_guid(&g);
380 printf(" size=0x%Lx\n", gsize); 390 printf(" size=0x%Lx\n", gsize);
381 #endif 391 #endif
382 if (gsize < 24) 392 if (gsize < 24)
383 goto fail; 393 goto fail;
394
395 block_begin += gsize;
396
384 if (!memcmp(&g, &file_header, sizeof(GUID))) { 397 if (!memcmp(&g, &file_header, sizeof(GUID))) {
385 get_guid(pb, &asf->hdr.guid); 398 get_guid(pb, &asf->hdr.guid);
386 asf->hdr.file_size = get_le64(pb); 399 asf->hdr.file_size = get_le64(pb);
387 asf->hdr.create_time = get_le64(pb); 400 asf->hdr.create_time = get_le64(pb);
388 asf->hdr.packets_count = get_le64(pb); 401 asf->hdr.packets_count = get_le64(pb);
409 asf_st = av_mallocz(sizeof(ASFStream)); 422 asf_st = av_mallocz(sizeof(ASFStream));
410 if (!asf_st) 423 if (!asf_st)
411 goto fail; 424 goto fail;
412 st->priv_data = asf_st; 425 st->priv_data = asf_st;
413 st->start_time = asf->hdr.preroll / (10000000 / AV_TIME_BASE); 426 st->start_time = asf->hdr.preroll / (10000000 / AV_TIME_BASE);
414 st->duration = (asf->hdr.send_time - asf->hdr.preroll) / 427 st->duration = (asf->hdr.send_time - asf->hdr.preroll) /
415 (10000000 / AV_TIME_BASE); 428 (10000000 / AV_TIME_BASE);
416 get_guid(pb, &g); 429 get_guid(pb, &g);
417 if (!memcmp(&g, &audio_stream, sizeof(GUID))) { 430 if (!memcmp(&g, &audio_stream, sizeof(GUID))) {
418 type = CODEC_TYPE_AUDIO; 431 type = CODEC_TYPE_AUDIO;
419 } else { 432 } else {
428 asf->asfid2avid[st->id] = s->nb_streams - 1; 441 asf->asfid2avid[st->id] = s->nb_streams - 1;
429 442
430 get_le32(pb); 443 get_le32(pb);
431 st->codec.codec_type = type; 444 st->codec.codec_type = type;
432 /* 1 fps default (XXX: put 0 fps instead) */ 445 /* 1 fps default (XXX: put 0 fps instead) */
433 st->codec.frame_rate = 1; 446 st->codec.frame_rate = 1;
434 st->codec.frame_rate_base = 1; 447 st->codec.frame_rate_base = 1;
435 if (type == CODEC_TYPE_AUDIO) { 448 if (type == CODEC_TYPE_AUDIO) {
436 get_wav_header(pb, &st->codec, type_specific_size); 449 get_wav_header(pb, &st->codec, type_specific_size);
437 st->need_parsing = 1; 450 st->need_parsing = 1;
438 /* We have to init the frame size at some point .... */ 451 /* We have to init the frame size at some point .... */
563 ASFContext *asf = s->priv_data; 576 ASFContext *asf = s->priv_data;
564 ByteIOContext *pb = &s->pb; 577 ByteIOContext *pb = &s->pb;
565 uint32_t packet_length, padsize; 578 uint32_t packet_length, padsize;
566 int rsize = 9; 579 int rsize = 9;
567 int c; 580 int c;
568 581
569 assert((url_ftell(&s->pb) - s->data_offset) % asf->packet_size == 0); 582 assert((url_ftell(&s->pb) - s->data_offset) % asf->packet_size == 0);
570 583
571 c = get_byte(pb); 584 c = get_byte(pb);
572 if ((c & 0x0f) == 2) { // always true for now 585 if ((c & 0x0f) == 2) { // always true for now
573 if (get_le16(pb) != 0) { 586 if (get_le16(pb) != 0) {
574 if (!url_feof(pb)) 587 if (!url_feof(pb))
575 printf("ff asf bad non zero\n"); 588 printf("ff asf bad non zero\n");
736 /* new packet */ 749 /* new packet */
737 av_new_packet(&asf_st->pkt, asf->packet_obj_size); 750 av_new_packet(&asf_st->pkt, asf->packet_obj_size);
738 asf_st->seq = asf->packet_seq; 751 asf_st->seq = asf->packet_seq;
739 asf_st->pkt.pts = asf->packet_frag_timestamp - asf->hdr.preroll; 752 asf_st->pkt.pts = asf->packet_frag_timestamp - asf->hdr.preroll;
740 asf_st->pkt.stream_index = asf->stream_index; 753 asf_st->pkt.stream_index = asf->stream_index;
741 asf_st->packet_pos= asf->packet_pos; 754 asf_st->packet_pos= asf->packet_pos;
742 //printf("new packet: stream:%d key:%d packet_key:%d audio:%d size:%d\n", 755 //printf("new packet: stream:%d key:%d packet_key:%d audio:%d size:%d\n",
743 //asf->stream_index, asf->packet_key_frame, asf_st->pkt.flags & PKT_FLAG_KEY, 756 //asf->stream_index, asf->packet_key_frame, asf_st->pkt.flags & PKT_FLAG_KEY,
744 //s->streams[asf->stream_index]->codec.codec_type == CODEC_TYPE_AUDIO, asf->packet_obj_size); 757 //s->streams[asf->stream_index]->codec.codec_type == CODEC_TYPE_AUDIO, asf->packet_obj_size);
745 if (s->streams[asf->stream_index]->codec.codec_type == CODEC_TYPE_AUDIO) 758 if (s->streams[asf->stream_index]->codec.codec_type == CODEC_TYPE_AUDIO)
746 asf->packet_key_frame = 1; 759 asf->packet_key_frame = 1;
747 if (asf->packet_key_frame) 760 if (asf->packet_key_frame)
748 asf_st->pkt.flags |= PKT_FLAG_KEY; 761 asf_st->pkt.flags |= PKT_FLAG_KEY;
749 } 762 }
750 763
833 asf->packet_frag_timestamp = 0; 846 asf->packet_frag_timestamp = 0;
834 asf->packet_multi_size = 0; 847 asf->packet_multi_size = 0;
835 asf->packet_obj_size = 0; 848 asf->packet_obj_size = 0;
836 asf->packet_time_delta = 0; 849 asf->packet_time_delta = 0;
837 asf->packet_time_start = 0; 850 asf->packet_time_start = 0;
838 851
839 for(i=0; i<s->nb_streams; i++){ 852 for(i=0; i<s->nb_streams; i++){
840 asf_st= s->streams[i]->priv_data; 853 asf_st= s->streams[i]->priv_data;
841 av_free_packet(&asf_st->pkt); 854 av_free_packet(&asf_st->pkt);
842 asf_st->frag_offset=0; 855 asf_st->frag_offset=0;
843 asf_st->seq=0; 856 asf_st->seq=0;
852 ASFStream *asf_st; 865 ASFStream *asf_st;
853 int64_t pts; 866 int64_t pts;
854 int64_t pos= *ppos; 867 int64_t pos= *ppos;
855 int i; 868 int i;
856 int64_t start_pos[s->nb_streams]; 869 int64_t start_pos[s->nb_streams];
857 870
858 for(i=0; i<s->nb_streams; i++){ 871 for(i=0; i<s->nb_streams; i++){
859 start_pos[i]= pos; 872 start_pos[i]= pos;
860 } 873 }
861 874
862 //printf("asf_read_pts\n"); 875 //printf("asf_read_pts\n");
878 assert((asf_st->packet_pos - s->data_offset) % asf->packet_size == 0); 891 assert((asf_st->packet_pos - s->data_offset) % asf->packet_size == 0);
879 pos= (asf_st->packet_pos - s->data_offset) / asf->packet_size; 892 pos= (asf_st->packet_pos - s->data_offset) / asf->packet_size;
880 893
881 av_add_index_entry(s->streams[i], pos, pts, pos - start_pos[i] + 1, AVINDEX_KEYFRAME); 894 av_add_index_entry(s->streams[i], pos, pts, pos - start_pos[i] + 1, AVINDEX_KEYFRAME);
882 start_pos[i]= pos + 1; 895 start_pos[i]= pos + 1;
883 896
884 if(pkt->stream_index == stream_index) 897 if(pkt->stream_index == stream_index)
885 break; 898 break;
886 } 899 }
887 } 900 }
888 901
897 ASFContext *asf = s->priv_data; 910 ASFContext *asf = s->priv_data;
898 AVStream *st; 911 AVStream *st;
899 int64_t pos; 912 int64_t pos;
900 int64_t pos_min, pos_max, pts_min, pts_max, cur_pts, pos_limit; 913 int64_t pos_min, pos_max, pts_min, pts_max, cur_pts, pos_limit;
901 int no_change; 914 int no_change;
902 915
903 if (stream_index == -1) 916 if (stream_index == -1)
904 stream_index= av_find_default_stream_index(s); 917 stream_index= av_find_default_stream_index(s);
905 918
906 if (asf->packet_size <= 0) 919 if (asf->packet_size <= 0)
907 return -1; 920 return -1;
908 921
909 pts_max= 922 pts_max=
910 pts_min= AV_NOPTS_VALUE; 923 pts_min= AV_NOPTS_VALUE;
940 } 953 }
941 if(pts_max == (int64_t)AV_NOPTS_VALUE){ 954 if(pts_max == (int64_t)AV_NOPTS_VALUE){
942 pos_max = (url_filesize(url_fileno(&s->pb)) - 1 - s->data_offset) / asf->packet_size; //FIXME wrong 955 pos_max = (url_filesize(url_fileno(&s->pb)) - 1 - s->data_offset) / asf->packet_size; //FIXME wrong
943 pts_max = s->duration; //FIXME wrong 956 pts_max = s->duration; //FIXME wrong
944 pos_limit= pos_max; 957 pos_limit= pos_max;
945 } 958 }
946 959
947 no_change=0; 960 no_change=0;
948 while (pos_min < pos_limit) { 961 while (pos_min < pos_limit) {
949 int64_t start_pos; 962 int64_t start_pos;
950 assert(pos_limit <= pos_max); 963 assert(pos_limit <= pos_max);
966 pos= pos_min + 1; 979 pos= pos_min + 1;
967 else if(pos > pos_limit) 980 else if(pos > pos_limit)
968 pos= pos_limit; 981 pos= pos_limit;
969 start_pos= pos; 982 start_pos= pos;
970 983
971 // read the next timestamp 984 // read the next timestamp
972 cur_pts = asf_read_pts(s, &pos, stream_index); 985 cur_pts = asf_read_pts(s, &pos, stream_index);
973 if(pos == pos_max) 986 if(pos == pos_max)
974 no_change++; 987 no_change++;
975 else 988 else
976 no_change=0; 989 no_change=0;
977 990
1007 }; 1020 };
1008 1021
1009 int asf_init(void) 1022 int asf_init(void)
1010 { 1023 {
1011 av_register_input_format(&asf_iformat); 1024 av_register_input_format(&asf_iformat);
1012 1025
1013 return 0; 1026 return 0;
1014 } 1027 }