Mercurial > libavformat.hg
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; |