summaryrefslogtreecommitdiffstats
path: root/libavformat/iff.c
diff options
context:
space:
mode:
authorStefano Sabatini <stefano.sabatini-lala@poste.it>2011-05-15 13:24:46 +0200
committerStefano Sabatini <stefano.sabatini-lala@poste.it>2011-05-17 00:58:33 +0200
commite280a4da2ae6fd44f0079358ecc5aa08e388a5ed (patch)
tree68b2f9ca7cdee458183c9a94fb7e7dfcc7e7954d /libavformat/iff.c
parentd8353256a3ae9bbf76b9b080884b82566c4938ab (diff)
downloadffmpeg-streaming-e280a4da2ae6fd44f0079358ecc5aa08e388a5ed.zip
ffmpeg-streaming-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/iff.c')
-rw-r--r--libavformat/iff.c40
1 files changed, 4 insertions, 36 deletions
diff --git a/libavformat/iff.c b/libavformat/iff.c
index b092de0..f6edcdd 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;
}
OpenPOWER on IntegriCloud