diff options
author | Stefano Sabatini <stefano.sabatini-lala@poste.it> | 2011-05-15 13:24:46 +0200 |
---|---|---|
committer | Stefano Sabatini <stefano.sabatini-lala@poste.it> | 2011-05-17 00:58:33 +0200 |
commit | e280a4da2ae6fd44f0079358ecc5aa08e388a5ed (patch) | |
tree | 68b2f9ca7cdee458183c9a94fb7e7dfcc7e7954d /libavformat | |
parent | d8353256a3ae9bbf76b9b080884b82566c4938ab (diff) | |
download | ffmpeg-e280a4da2ae6fd44f0079358ecc5aa08e388a5ed.tar.gz |
iff/8svx: redesign 8SVX demuxing and decoding for handling stereo samples correctly
Make the iff demuxer send the whole audio chunk to the decoder as a
single packet, move stereo interleaving from the iff demuxer to the
decoder, and introduce an 8svx_raw decoder which performs
stereo interleaving.
This is required for handling stereo data correctly, indeed samples
are stored like:
LLLLLL....RRRRRR
that is all left samples are at the beginning of the chunk, all right
samples at the end, so it is necessary to store and process the whole
buffer in order to decode each frame. Thus the decoder needs all the
audio chunk before it can return interleaved data.
Fix decoding of files 8svx_exp.iff and 8svx_fib.iff, fix trac issue #169.
Diffstat (limited to 'libavformat')
-rw-r--r-- | libavformat/iff.c | 40 |
1 files changed, 4 insertions, 36 deletions
diff --git a/libavformat/iff.c b/libavformat/iff.c index b092de0b08..f6edcdda2e 100644 --- a/libavformat/iff.c +++ b/libavformat/iff.c @@ -60,8 +60,6 @@ #define RIGHT 4 #define STEREO 6 -#define PACKET_SIZE 1024 - /** * This number of bytes if added at the beginning of each AVPacket * which contain additional information about video properties @@ -97,19 +95,6 @@ typedef struct { unsigned masking; ///< masking method used } IffDemuxContext; - -static void interleave_stereo(const uint8_t *src, uint8_t *dest, int size) -{ - uint8_t *end = dest + size; - size = size>>1; - - while(dest < end) { - *dest++ = *src; - *dest++ = *(src+size); - src++; - } -} - /* Metadata string read */ static int get_metadata(AVFormatContext *s, const char *const tag, @@ -255,7 +240,7 @@ static int iff_read_header(AVFormatContext *s, switch (iff->svx8_compression) { case COMP_NONE: - st->codec->codec_id = CODEC_ID_PCM_S8; + st->codec->codec_id = CODEC_ID_8SVX_RAW; break; case COMP_FIB: st->codec->codec_id = CODEC_ID_8SVX_FIB; @@ -330,15 +315,8 @@ static int iff_read_packet(AVFormatContext *s, if(iff->sent_bytes >= iff->body_size) return AVERROR(EIO); - if(st->codec->channels == 2) { - uint8_t sample_buffer[PACKET_SIZE]; - - ret = avio_read(pb, sample_buffer, PACKET_SIZE); - if(av_new_packet(pkt, PACKET_SIZE) < 0) { - av_log(s, AV_LOG_ERROR, "cannot allocate packet\n"); - return AVERROR(ENOMEM); - } - interleave_stereo(sample_buffer, pkt->data, PACKET_SIZE); + if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { + ret = av_get_packet(pb, pkt, iff->body_size); } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { uint8_t *buf; @@ -349,23 +327,13 @@ static int iff_read_packet(AVFormatContext *s, buf = pkt->data; bytestream_put_be16(&buf, 2); ret = avio_read(pb, buf, iff->body_size); - } else { - ret = av_get_packet(pb, pkt, PACKET_SIZE); } if(iff->sent_bytes == 0) pkt->flags |= AV_PKT_FLAG_KEY; + iff->sent_bytes = iff->body_size; - if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - iff->sent_bytes += PACKET_SIZE; - } else { - iff->sent_bytes = iff->body_size; - } pkt->stream_index = 0; - if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - pkt->pts = iff->audio_frame_count; - iff->audio_frame_count += ret / st->codec->channels; - } return ret; } |