Mercurial > libavformat.hg
changeset 2144:7fe203e939e5 libavformat
add support for real audio in matroska
author | aurel |
---|---|
date | Mon, 04 Jun 2007 22:19:17 +0000 |
parents | a3d59411106f |
children | 3dd44fd1cbf4 |
files | matroska.c matroskadec.c |
diffstat | 2 files changed, 90 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/matroska.c Mon Jun 04 22:17:55 2007 +0000 +++ b/matroska.c Mon Jun 04 22:19:17 2007 +0000 @@ -53,6 +53,11 @@ {"A_FLAC" , CODEC_ID_FLAC}, {"A_WAVPACK4" , CODEC_ID_WAVPACK}, {"A_TTA1" , CODEC_ID_TTA}, + {"A_REAL/14_4" , CODEC_ID_RA_144}, + {"A_REAL/28_8" , CODEC_ID_RA_288}, + {"A_REAL/ATRC" , CODEC_ID_ATRAC3}, + {"A_REAL/COOK" , CODEC_ID_COOK}, +// {"A_REAL/SIPR" , CODEC_ID_SIPRO}, {NULL , CODEC_ID_NONE} /* TODO: AC3-9/10 (?), Real, Musepack, Quicktime */ };
--- a/matroskadec.c Mon Jun 04 22:17:55 2007 +0000 +++ b/matroskadec.c Mon Jun 04 22:19:17 2007 +0000 @@ -79,6 +79,16 @@ bitdepth, internal_samplerate, samplerate; + int block_align; + + /* real audio header */ + int coded_framesize; + int sub_packet_h; + int frame_size; + int sub_packet_size; + int sub_packet_cnt; + int pkt_cnt; + uint8_t *buf; //.. } MatroskaAudioTrack; @@ -2103,6 +2113,37 @@ track->flags |= MATROSKA_TRACK_REAL_V; } + else if (codec_id == CODEC_ID_RA_144) { + MatroskaAudioTrack *audiotrack = (MatroskaAudioTrack *)track; + audiotrack->samplerate = 8000; + audiotrack->channels = 1; + } + + else if (codec_id == CODEC_ID_RA_288 || + codec_id == CODEC_ID_COOK || + codec_id == CODEC_ID_ATRAC3) { + MatroskaAudioTrack *audiotrack = (MatroskaAudioTrack *)track; + ByteIOContext b; + + init_put_byte(&b, track->codec_priv, track->codec_priv_size, 0, + NULL, NULL, NULL, NULL); + url_fskip(&b, 24); + audiotrack->coded_framesize = get_be32(&b); + url_fskip(&b, 12); + audiotrack->sub_packet_h = get_be16(&b); + audiotrack->frame_size = get_be16(&b); + audiotrack->sub_packet_size = get_be16(&b); + audiotrack->buf = av_malloc(audiotrack->frame_size * audiotrack->sub_packet_h); + if (codec_id == CODEC_ID_RA_288) { + audiotrack->block_align = audiotrack->coded_framesize; + track->codec_priv_size = 0; + } else { + audiotrack->block_align = audiotrack->sub_packet_size; + extradata_offset = 78; + track->codec_priv_size -= extradata_offset; + } + } + if (codec_id == CODEC_ID_NONE) { av_log(matroska->ctx, AV_LOG_INFO, "Unknown/unsupported CodecID %s.\n", @@ -2159,6 +2200,7 @@ st->codec->codec_type = CODEC_TYPE_AUDIO; st->codec->sample_rate = audiotrack->samplerate; st->codec->channels = audiotrack->channels; + st->codec->block_align = audiotrack->block_align; } else if (track->type == MATROSKA_TRACK_TYPE_SUBTITLE) { st->codec->codec_type = CODEC_TYPE_SUBTITLE; } @@ -2347,6 +2389,43 @@ slice_size = lace_size[n] - slice_offset; else slice_size = rv_offset(data, slice+1, slices) - slice_offset; + + if (st->codec->codec_id == CODEC_ID_RA_288 || + st->codec->codec_id == CODEC_ID_COOK || + st->codec->codec_id == CODEC_ID_ATRAC3) { + MatroskaAudioTrack *audiotrack = (MatroskaAudioTrack *)matroska->tracks[track]; + int a = st->codec->block_align; + int sps = audiotrack->sub_packet_size; + int cfs = audiotrack->coded_framesize; + int h = audiotrack->sub_packet_h; + int y = audiotrack->sub_packet_cnt; + int w = audiotrack->frame_size; + int x; + + if (!audiotrack->pkt_cnt) { + if (st->codec->codec_id == CODEC_ID_RA_288) + for (x=0; x<h/2; x++) + memcpy(audiotrack->buf+x*2*w+y*cfs, + data+x*cfs, cfs); + else + for (x=0; x<w/sps; x++) + memcpy(audiotrack->buf+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), data+x*sps, sps); + + if (++audiotrack->sub_packet_cnt >= h) { + audiotrack->sub_packet_cnt = 0; + audiotrack->pkt_cnt = h*w / a; + } + } + while (audiotrack->pkt_cnt) { + pkt = av_mallocz(sizeof(AVPacket)); + av_new_packet(pkt, a); + memcpy(pkt->data, audiotrack->buf + + a * (h*w / a - audiotrack->pkt_cnt--), a); + pkt->pos = pos; + pkt->stream_index = matroska->tracks[track]->stream_index; + matroska_queue_packet(matroska, pkt); + } + } else { pkt = av_mallocz(sizeof(AVPacket)); /* XXX: prevent data copy... */ if (av_new_packet(pkt, slice_size) < 0) { @@ -2365,6 +2444,7 @@ pkt->duration = duration; matroska_queue_packet(matroska, pkt); + } if (timecode != AV_NOPTS_VALUE) timecode = duration ? timecode + duration : AV_NOPTS_VALUE; @@ -2625,6 +2705,11 @@ av_free(track->name); av_free(track->language); + if (track->type == MATROSKA_TRACK_TYPE_AUDIO) { + MatroskaAudioTrack *audiotrack = (MatroskaAudioTrack *)track; + av_free(audiotrack->buf); + } + av_free(track); }