comparison rmdec.c @ 4143:6b3d9d41f18c libavformat

Merge videobuf and audiobuf.
author michael
date Wed, 31 Dec 2008 00:24:54 +0000
parents 5d57b8a9e597
children 4970ba98ca58
comparison
equal deleted inserted replaced
4142:5d57b8a9e597 4143:6b3d9d41f18c
22 #include "libavutil/avstring.h" 22 #include "libavutil/avstring.h"
23 #include "avformat.h" 23 #include "avformat.h"
24 #include "rm.h" 24 #include "rm.h"
25 25
26 struct RMStream { 26 struct RMStream {
27 uint8_t *videobuf; ///< place to store merged video frame 27 uint8_t *buf; ///< place to store merged video frame / reordered audio data
28 int videobufsize; ///< current assembled frame size 28 int videobufsize; ///< current assembled frame size
29 int videobufpos; ///< position for the next slice in the video buffer 29 int videobufpos; ///< position for the next slice in the video buffer
30 int curpic_num; ///< picture number of current frame 30 int curpic_num; ///< picture number of current frame
31 int cur_slice, slices; 31 int cur_slice, slices;
32 int64_t pktpos; ///< first slice position in file 32 int64_t pktpos; ///< first slice position in file
33 /// Audio descrambling matrix parameters 33 /// Audio descrambling matrix parameters
34 uint8_t *audiobuf; ///< place to store reordered audio data
35 int64_t audiotimestamp; ///< Audio packet timestamp 34 int64_t audiotimestamp; ///< Audio packet timestamp
36 int sub_packet_cnt; // Subpacket counter, used while reading 35 int sub_packet_cnt; // Subpacket counter, used while reading
37 int sub_packet_size, sub_packet_h, coded_framesize; ///< Descrambling parameters from container 36 int sub_packet_size, sub_packet_h, coded_framesize; ///< Descrambling parameters from container
38 int audio_framesize; /// Audio frame size from container 37 int audio_framesize; /// Audio frame size from container
39 int sub_packet_lengths[16]; /// Length of each subpacket 38 int sub_packet_lengths[16]; /// Length of each subpacket
79 return rms; 78 return rms;
80 } 79 }
81 80
82 void ff_rm_free_rmstream (RMStream *rms) 81 void ff_rm_free_rmstream (RMStream *rms)
83 { 82 {
84 av_freep(&rms->videobuf); 83 av_freep(&rms->buf);
85 av_freep(&rms->audiobuf);
86 } 84 }
87 85
88 static int rm_read_audio_stream_info(AVFormatContext *s, ByteIOContext *pb, 86 static int rm_read_audio_stream_info(AVFormatContext *s, ByteIOContext *pb,
89 AVStream *st, RMStream *ast, int read_all) 87 AVStream *st, RMStream *ast, int read_all)
90 { 88 {
155 if(ast->audio_framesize >= UINT_MAX / sub_packet_h){ 153 if(ast->audio_framesize >= UINT_MAX / sub_packet_h){
156 av_log(s, AV_LOG_ERROR, "ast->audio_framesize * sub_packet_h too large\n"); 154 av_log(s, AV_LOG_ERROR, "ast->audio_framesize * sub_packet_h too large\n");
157 return -1; 155 return -1;
158 } 156 }
159 157
160 ast->audiobuf = av_malloc(ast->audio_framesize * sub_packet_h); 158 ast->buf = av_malloc(ast->audio_framesize * sub_packet_h);
161 } else if ((!strcmp(buf, "cook")) || (!strcmp(buf, "atrc")) || (!strcmp(buf, "sipr"))) { 159 } else if ((!strcmp(buf, "cook")) || (!strcmp(buf, "atrc")) || (!strcmp(buf, "sipr"))) {
162 int codecdata_length; 160 int codecdata_length;
163 get_be16(pb); get_byte(pb); 161 get_be16(pb); get_byte(pb);
164 if (((version >> 16) & 0xff) == 5) 162 if (((version >> 16) & 0xff) == 5)
165 get_byte(pb); 163 get_byte(pb);
186 if(ast->audio_framesize >= UINT_MAX / sub_packet_h){ 184 if(ast->audio_framesize >= UINT_MAX / sub_packet_h){
187 av_log(s, AV_LOG_ERROR, "rm->audio_framesize * sub_packet_h too large\n"); 185 av_log(s, AV_LOG_ERROR, "rm->audio_framesize * sub_packet_h too large\n");
188 return -1; 186 return -1;
189 } 187 }
190 188
191 ast->audiobuf = av_malloc(ast->audio_framesize * sub_packet_h); 189 ast->buf = av_malloc(ast->audio_framesize * sub_packet_h);
192 } else if (!strcmp(buf, "raac") || !strcmp(buf, "racp")) { 190 } else if (!strcmp(buf, "raac") || !strcmp(buf, "racp")) {
193 int codecdata_length; 191 int codecdata_length;
194 get_be16(pb); get_byte(pb); 192 get_be16(pb); get_byte(pb);
195 if (((version >> 16) & 0xff) == 5) 193 if (((version >> 16) & 0xff) == 5)
196 get_byte(pb); 194 get_byte(pb);
521 //now we have to deal with single slice 519 //now we have to deal with single slice
522 520
523 if((seq & 0x7F) == 1 || vst->curpic_num != pic_num){ 521 if((seq & 0x7F) == 1 || vst->curpic_num != pic_num){
524 vst->slices = ((hdr & 0x3F) << 1) + 1; 522 vst->slices = ((hdr & 0x3F) << 1) + 1;
525 vst->videobufsize = len2 + 8*vst->slices + 1; 523 vst->videobufsize = len2 + 8*vst->slices + 1;
526 av_free(vst->videobuf); 524 av_free(vst->buf);
527 if(!(vst->videobuf = av_malloc(vst->videobufsize))) 525 if(!(vst->buf = av_malloc(vst->videobufsize)))
528 return AVERROR(ENOMEM); 526 return AVERROR(ENOMEM);
529 vst->videobufpos = 8*vst->slices + 1; 527 vst->videobufpos = 8*vst->slices + 1;
530 vst->cur_slice = 0; 528 vst->cur_slice = 0;
531 vst->curpic_num = pic_num; 529 vst->curpic_num = pic_num;
532 vst->pktpos = url_ftell(pb); 530 vst->pktpos = url_ftell(pb);
534 if(type == 2) 532 if(type == 2)
535 len = FFMIN(len, pos); 533 len = FFMIN(len, pos);
536 534
537 if(++vst->cur_slice > vst->slices) 535 if(++vst->cur_slice > vst->slices)
538 return 1; 536 return 1;
539 AV_WL32(vst->videobuf - 7 + 8*vst->cur_slice, 1); 537 AV_WL32(vst->buf - 7 + 8*vst->cur_slice, 1);
540 AV_WL32(vst->videobuf - 3 + 8*vst->cur_slice, vst->videobufpos - 8*vst->slices - 1); 538 AV_WL32(vst->buf - 3 + 8*vst->cur_slice, vst->videobufpos - 8*vst->slices - 1);
541 if(vst->videobufpos + len > vst->videobufsize) 539 if(vst->videobufpos + len > vst->videobufsize)
542 return 1; 540 return 1;
543 if (get_buffer(pb, vst->videobuf + vst->videobufpos, len) != len) 541 if (get_buffer(pb, vst->buf + vst->videobufpos, len) != len)
544 return AVERROR(EIO); 542 return AVERROR(EIO);
545 vst->videobufpos += len; 543 vst->videobufpos += len;
546 rm->remaining_len-= len; 544 rm->remaining_len-= len;
547 545
548 if(type == 2 || (vst->videobufpos) == vst->videobufsize){ 546 if(type == 2 || (vst->videobufpos) == vst->videobufsize){
549 vst->videobuf[0] = vst->cur_slice-1; 547 vst->buf[0] = vst->cur_slice-1;
550 if(av_new_packet(pkt, vst->videobufpos - 8*(vst->slices - vst->cur_slice)) < 0) 548 if(av_new_packet(pkt, vst->videobufpos - 8*(vst->slices - vst->cur_slice)) < 0)
551 return AVERROR(ENOMEM); 549 return AVERROR(ENOMEM);
552 memcpy(pkt->data, vst->videobuf, 1 + 8*vst->cur_slice); 550 memcpy(pkt->data, vst->buf, 1 + 8*vst->cur_slice);
553 memcpy(pkt->data + 1 + 8*vst->cur_slice, vst->videobuf + 1 + 8*vst->slices, 551 memcpy(pkt->data + 1 + 8*vst->cur_slice, vst->buf + 1 + 8*vst->slices,
554 vst->videobufpos - 1 - 8*vst->slices); 552 vst->videobufpos - 1 - 8*vst->slices);
555 pkt->pts = AV_NOPTS_VALUE; 553 pkt->pts = AV_NOPTS_VALUE;
556 pkt->pos = vst->pktpos; 554 pkt->pos = vst->pktpos;
557 return 0; 555 return 0;
558 } 556 }
604 ast->audiotimestamp = *timestamp; 602 ast->audiotimestamp = *timestamp;
605 603
606 switch(st->codec->codec_id) { 604 switch(st->codec->codec_id) {
607 case CODEC_ID_RA_288: 605 case CODEC_ID_RA_288:
608 for (x = 0; x < h/2; x++) 606 for (x = 0; x < h/2; x++)
609 get_buffer(pb, ast->audiobuf+x*2*w+y*cfs, cfs); 607 get_buffer(pb, ast->buf+x*2*w+y*cfs, cfs);
610 break; 608 break;
611 case CODEC_ID_ATRAC3: 609 case CODEC_ID_ATRAC3:
612 case CODEC_ID_COOK: 610 case CODEC_ID_COOK:
613 for (x = 0; x < w/sps; x++) 611 for (x = 0; x < w/sps; x++)
614 get_buffer(pb, ast->audiobuf+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), sps); 612 get_buffer(pb, ast->buf+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), sps);
615 break; 613 break;
616 } 614 }
617 615
618 if (++(ast->sub_packet_cnt) < h) 616 if (++(ast->sub_packet_cnt) < h)
619 return -1; 617 return -1;
621 ast->sub_packet_cnt = 0; 619 ast->sub_packet_cnt = 0;
622 rm->audio_stream_num = st->index; 620 rm->audio_stream_num = st->index;
623 rm->audio_pkt_cnt = h * w / st->codec->block_align - 1; 621 rm->audio_pkt_cnt = h * w / st->codec->block_align - 1;
624 // Release first audio packet 622 // Release first audio packet
625 av_new_packet(pkt, st->codec->block_align); 623 av_new_packet(pkt, st->codec->block_align);
626 memcpy(pkt->data, ast->audiobuf, st->codec->block_align); 624 memcpy(pkt->data, ast->buf, st->codec->block_align);
627 *timestamp = ast->audiotimestamp; 625 *timestamp = ast->audiotimestamp;
628 *flags = 2; // Mark first packet as keyframe 626 *flags = 2; // Mark first packet as keyframe
629 } 627 }
630 } else if (st->codec->codec_id == CODEC_ID_AAC) { 628 } else if (st->codec->codec_id == CODEC_ID_AAC) {
631 int x; 629 int x;
684 682
685 if (st->codec->codec_id == CODEC_ID_AAC) 683 if (st->codec->codec_id == CODEC_ID_AAC)
686 av_get_packet(pb, pkt, ast->sub_packet_lengths[ast->sub_packet_cnt - rm->audio_pkt_cnt]); 684 av_get_packet(pb, pkt, ast->sub_packet_lengths[ast->sub_packet_cnt - rm->audio_pkt_cnt]);
687 else { 685 else {
688 av_new_packet(pkt, st->codec->block_align); 686 av_new_packet(pkt, st->codec->block_align);
689 memcpy(pkt->data, ast->audiobuf + st->codec->block_align * 687 memcpy(pkt->data, ast->buf + st->codec->block_align *
690 (ast->sub_packet_h * ast->audio_framesize / st->codec->block_align - rm->audio_pkt_cnt), 688 (ast->sub_packet_h * ast->audio_framesize / st->codec->block_align - rm->audio_pkt_cnt),
691 st->codec->block_align); 689 st->codec->block_align);
692 } 690 }
693 rm->audio_pkt_cnt--; 691 rm->audio_pkt_cnt--;
694 pkt->flags = 0; 692 pkt->flags = 0;
718 if (st->codec->codec_id == CODEC_ID_RA_288) { 716 if (st->codec->codec_id == CODEC_ID_RA_288) {
719 int x, y; 717 int x, y;
720 718
721 for (y = 0; y < ast->sub_packet_h; y++) 719 for (y = 0; y < ast->sub_packet_h; y++)
722 for (x = 0; x < ast->sub_packet_h/2; x++) 720 for (x = 0; x < ast->sub_packet_h/2; x++)
723 if (get_buffer(pb, ast->audiobuf+x*2*ast->audio_framesize+y*ast->coded_framesize, ast->coded_framesize) <= 0) 721 if (get_buffer(pb, ast->buf+x*2*ast->audio_framesize+y*ast->coded_framesize, ast->coded_framesize) <= 0)
724 return AVERROR(EIO); 722 return AVERROR(EIO);
725 rm->audio_stream_num = 0; 723 rm->audio_stream_num = 0;
726 rm->audio_pkt_cnt = ast->sub_packet_h * ast->audio_framesize / st->codec->block_align - 1; 724 rm->audio_pkt_cnt = ast->sub_packet_h * ast->audio_framesize / st->codec->block_align - 1;
727 // Release first audio packet 725 // Release first audio packet
728 av_new_packet(pkt, st->codec->block_align); 726 av_new_packet(pkt, st->codec->block_align);
729 memcpy(pkt->data, ast->audiobuf, st->codec->block_align); 727 memcpy(pkt->data, ast->buf, st->codec->block_align);
730 pkt->flags |= PKT_FLAG_KEY; // Mark first packet as keyframe 728 pkt->flags |= PKT_FLAG_KEY; // Mark first packet as keyframe
731 pkt->stream_index = 0; 729 pkt->stream_index = 0;
732 } else { 730 } else {
733 /* just read raw bytes */ 731 /* just read raw bytes */
734 len = RAW_PACKET_SIZE; 732 len = RAW_PACKET_SIZE;