comparison rm.c @ 879:1f093ae472d8 libavformat

Cook compatibe decoder, patch by Benjamin Larsson Add cook demucing, change rm demuxer so that it reorders audio packets before sending them to the decoder, and send minimum decodeable sized packets; pass only real codec extradata fo the decoder Fix 28_8 decoder for the new demuxer strategy
author rtognimp
date Fri, 09 Dec 2005 16:08:18 +0000
parents 66cc656ea404
children 2ece9c9dd94c
comparison
equal deleted inserted replaced
878:8782b02914e3 879:1f093ae472d8
40 int data_pos; /* position of the data after the header */ 40 int data_pos; /* position of the data after the header */
41 int nb_packets; 41 int nb_packets;
42 int old_format; 42 int old_format;
43 int current_stream; 43 int current_stream;
44 int remaining_len; 44 int remaining_len;
45 /// Audio descrambling matrix parameters
46 uint8_t *audiobuf; ///< place to store reordered audio data
47 int64_t audiotimestamp; ///< Audio packet timestamp
48 int sub_packet_cnt; // Subpacket counter, used while reading
49 int sub_packet_size, sub_packet_h, coded_framesize; ///< Descrambling parameters from container
50 int audio_stream_num; ///< Stream number for audio packets
51 int audio_pkt_cnt; ///< Output packet counter
52 int audio_framesize; /// Audio frame size from container
45 } RMContext; 53 } RMContext;
46 54
47 #ifdef CONFIG_MUXERS 55 #ifdef CONFIG_MUXERS
48 static void put_str(ByteIOContext *s, const char *tag) 56 static void put_str(ByteIOContext *s, const char *tag)
49 { 57 {
476 } 484 }
477 485
478 static void rm_read_audio_stream_info(AVFormatContext *s, AVStream *st, 486 static void rm_read_audio_stream_info(AVFormatContext *s, AVStream *st,
479 int read_all) 487 int read_all)
480 { 488 {
489 RMContext *rm = s->priv_data;
481 ByteIOContext *pb = &s->pb; 490 ByteIOContext *pb = &s->pb;
482 char buf[128]; 491 char buf[128];
483 uint32_t version; 492 uint32_t version;
484 int i; 493 int i;
485 494
498 st->codec->sample_rate = 8000; 507 st->codec->sample_rate = 8000;
499 st->codec->channels = 1; 508 st->codec->channels = 1;
500 st->codec->codec_type = CODEC_TYPE_AUDIO; 509 st->codec->codec_type = CODEC_TYPE_AUDIO;
501 st->codec->codec_id = CODEC_ID_RA_144; 510 st->codec->codec_id = CODEC_ID_RA_144;
502 } else { 511 } else {
503 int flavor, sub_packet_h, coded_framesize; 512 int flavor, sub_packet_h, coded_framesize, sub_packet_size;
504 /* old version (4) */ 513 /* old version (4) */
505 get_be32(pb); /* .ra4 */ 514 get_be32(pb); /* .ra4 */
506 get_be32(pb); /* data size */ 515 get_be32(pb); /* data size */
507 get_be16(pb); /* version2 */ 516 get_be16(pb); /* version2 */
508 get_be32(pb); /* header size */ 517 get_be32(pb); /* header size */
509 flavor= get_be16(pb); /* add codec info / flavor */ 518 flavor= get_be16(pb); /* add codec info / flavor */
510 coded_framesize= get_be32(pb); /* coded frame size */ 519 rm->coded_framesize = coded_framesize = get_be32(pb); /* coded frame size */
511 get_be32(pb); /* ??? */ 520 get_be32(pb); /* ??? */
512 get_be32(pb); /* ??? */ 521 get_be32(pb); /* ??? */
513 get_be32(pb); /* ??? */ 522 get_be32(pb); /* ??? */
514 sub_packet_h= get_be16(pb); /* 1 */ 523 rm->sub_packet_h = sub_packet_h = get_be16(pb); /* 1 */
515 st->codec->block_align= get_be16(pb); /* frame size */ 524 st->codec->block_align= get_be16(pb); /* frame size */
516 get_be16(pb); /* sub packet size */ 525 rm->sub_packet_size = sub_packet_size = get_be16(pb); /* sub packet size */
517 get_be16(pb); /* ??? */ 526 get_be16(pb); /* ??? */
527 if (((version >> 16) & 0xff) == 5) {
528 get_be16(pb); get_be16(pb); get_be16(pb); }
518 st->codec->sample_rate = get_be16(pb); 529 st->codec->sample_rate = get_be16(pb);
519 get_be32(pb); 530 get_be32(pb);
520 st->codec->channels = get_be16(pb); 531 st->codec->channels = get_be16(pb);
532 if (((version >> 16) & 0xff) == 5) {
533 get_be32(pb);
534 buf[0] = get_byte(pb);
535 buf[1] = get_byte(pb);
536 buf[2] = get_byte(pb);
537 buf[3] = get_byte(pb);
538 buf[4] = 0;
539 } else {
521 get_str8(pb, buf, sizeof(buf)); /* desc */ 540 get_str8(pb, buf, sizeof(buf)); /* desc */
522 get_str8(pb, buf, sizeof(buf)); /* desc */ 541 get_str8(pb, buf, sizeof(buf)); /* desc */
542 }
523 st->codec->codec_type = CODEC_TYPE_AUDIO; 543 st->codec->codec_type = CODEC_TYPE_AUDIO;
524 if (!strcmp(buf, "dnet")) { 544 if (!strcmp(buf, "dnet")) {
525 st->codec->codec_id = CODEC_ID_AC3; 545 st->codec->codec_id = CODEC_ID_AC3;
526 } else if (!strcmp(buf, "28_8")) { 546 } else if (!strcmp(buf, "28_8")) {
527 st->codec->codec_id = CODEC_ID_RA_288; 547 st->codec->codec_id = CODEC_ID_RA_288;
528 st->codec->extradata_size= 10; 548 st->codec->extradata_size= 0;
549 rm->audio_framesize = st->codec->block_align;
550 st->codec->block_align = coded_framesize;
551 rm->audiobuf = av_malloc(rm->audio_framesize * sub_packet_h);
552 } else if (!strcmp(buf, "cook")) {
553 int codecdata_length, i;
554 get_be16(pb); get_byte(pb);
555 if (((version >> 16) & 0xff) == 5)
556 get_byte(pb);
557 codecdata_length = get_be32(pb);
558 st->codec->codec_id = CODEC_ID_COOK;
559 st->codec->extradata_size= codecdata_length;
529 st->codec->extradata= av_mallocz(st->codec->extradata_size); 560 st->codec->extradata= av_mallocz(st->codec->extradata_size);
530 /* this is completly braindead and broken, the idiot who added this codec and endianness 561 for(i = 0; i < codecdata_length; i++)
531 specific reordering to mplayer and libavcodec/ra288.c should be drowned in a see of cola */ 562 ((uint8_t*)st->codec->extradata)[i] = get_byte(pb);
532 //FIXME pass the unpermutated extradata 563 rm->audio_framesize = st->codec->block_align;
533 ((uint16_t*)st->codec->extradata)[1]= sub_packet_h; 564 st->codec->block_align = rm->sub_packet_size;
534 ((uint16_t*)st->codec->extradata)[2]= flavor; 565 rm->audiobuf = av_malloc(rm->audio_framesize * sub_packet_h);
535 ((uint16_t*)st->codec->extradata)[3]= coded_framesize;
536 } else { 566 } else {
537 st->codec->codec_id = CODEC_ID_NONE; 567 st->codec->codec_id = CODEC_ID_NONE;
538 pstrcpy(st->codec->codec_name, sizeof(st->codec->codec_name), 568 pstrcpy(st->codec->codec_name, sizeof(st->codec->codec_name),
539 buf); 569 buf);
540 } 570 }
817 if (len <= 0) { 847 if (len <= 0) {
818 return AVERROR_IO; 848 return AVERROR_IO;
819 } 849 }
820 pkt->size = len; 850 pkt->size = len;
821 st = s->streams[0]; 851 st = s->streams[0];
852 } else if (rm->audio_pkt_cnt) {
853 // If there are queued audio packet return them first
854 st = s->streams[rm->audio_stream_num];
855 av_new_packet(pkt, st->codec->block_align);
856 memcpy(pkt->data, rm->audiobuf + st->codec->block_align *
857 (rm->sub_packet_h * rm->audio_framesize / st->codec->block_align - rm->audio_pkt_cnt),
858 st->codec->block_align);
859 rm->audio_pkt_cnt--;
860 pkt->flags = 0;
861 pkt->stream_index = rm->audio_stream_num;
822 } else { 862 } else {
823 int seq=1; 863 int seq=1;
824 resync: 864 resync:
825 len=sync(s, &timestamp, &flags, &i, &pos); 865 len=sync(s, &timestamp, &flags, &i, &pos);
826 if(len<0) 866 if(len<0)
848 888
849 // av_log(NULL, AV_LOG_DEBUG, "%X len:%d pos:%d len2:%d pic_num:%d\n",h, len, pos, len2, pic_num); 889 // av_log(NULL, AV_LOG_DEBUG, "%X len:%d pos:%d len2:%d pic_num:%d\n",h, len, pos, len2, pic_num);
850 if(len2 && len2<len) 890 if(len2 && len2<len)
851 len=len2; 891 len=len2;
852 rm->remaining_len-= len; 892 rm->remaining_len-= len;
893 av_get_packet(pb, pkt, len);
894 }
895
896 if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
897 if ((st->codec->codec_id == CODEC_ID_RA_288) ||
898 (st->codec->codec_id == CODEC_ID_COOK)) {
899 int x;
900 int sps = rm->sub_packet_size;
901 int cfs = rm->coded_framesize;
902 int h = rm->sub_packet_h;
903 int y = rm->sub_packet_cnt;
904 int w = rm->audio_framesize;
905
906 if (flags & 2)
907 y = rm->sub_packet_cnt = 0;
908 if (!y)
909 rm->audiotimestamp = timestamp;
910
911 switch(st->codec->codec_id) {
912 case CODEC_ID_RA_288:
913 for (x = 0; x < h/2; x++)
914 get_buffer(pb, rm->audiobuf+x*2*w+y*cfs, cfs);
915 break;
916 case CODEC_ID_COOK:
917 for (x = 0; x < w/sps; x++)
918 get_buffer(pb, rm->audiobuf+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), sps);
919 break;
920 }
921
922 if (++(rm->sub_packet_cnt) < h)
923 goto resync;
924 else {
925 rm->sub_packet_cnt = 0;
926 rm->audio_stream_num = i;
927 rm->audio_pkt_cnt = h * w / st->codec->block_align - 1;
928 // Release first audio packet
929 av_new_packet(pkt, st->codec->block_align);
930 memcpy(pkt->data, rm->audiobuf, st->codec->block_align);
931 timestamp = rm->audiotimestamp;
932 flags = 2; // Mark first packet as keyframe
933 }
934 } else
935 av_get_packet(pb, pkt, len);
853 } 936 }
854 937
855 if( (st->discard >= AVDISCARD_NONKEY && !(flags&2)) 938 if( (st->discard >= AVDISCARD_NONKEY && !(flags&2))
856 || st->discard >= AVDISCARD_ALL){ 939 || st->discard >= AVDISCARD_ALL){
857 url_fskip(pb, len); 940 av_free_packet(pkt);
858 goto resync; 941 goto resync;
859 } 942 }
860 943
861 av_get_packet(pb, pkt, len);
862 pkt->stream_index = i; 944 pkt->stream_index = i;
863 945
864 #if 0 946 #if 0
865 if (st->codec->codec_type == CODEC_TYPE_VIDEO) { 947 if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
866 if(st->codec->codec_id == CODEC_ID_RV20){ 948 if(st->codec->codec_id == CODEC_ID_RV20){
894 return 0; 976 return 0;
895 } 977 }
896 978
897 static int rm_read_close(AVFormatContext *s) 979 static int rm_read_close(AVFormatContext *s)
898 { 980 {
981 RMContext *rm = s->priv_data;
982
983 av_free(rm->audiobuf);
899 return 0; 984 return 0;
900 } 985 }
901 986
902 static int rm_probe(AVProbeData *p) 987 static int rm_probe(AVProbeData *p)
903 { 988 {