aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec/wavpack.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2011-12-03 02:08:55 +0100
committerMichael Niedermayer <michaelni@gmx.at>2011-12-03 03:00:30 +0100
commite4de71677f3adeac0f74b89ac8df5d417364df2c (patch)
tree4792dd8d85d24f0f4eaddabb65f6044727907daa /libavcodec/wavpack.c
parent12804348f5babf56a315fa01751eea1ffdddf98a (diff)
parentd268b79e3436107c11ee8bcdf9f3645368bb3fcd (diff)
downloadffmpeg-e4de71677f3adeac0f74b89ac8df5d417364df2c.tar.gz
Merge remote-tracking branch 'qatar/master'
* qatar/master: aac_latm: reconfigure decoder on audio specific config changes latmdec: fix audio specific config parsing Add avcodec_decode_audio4(). avcodec: change number of plane pointers from 4 to 8 at next major bump. Update developers documentation with coding conventions. svq1dec: avoid undefined get_bits(0) call ARM: h264dsp_neon cosmetics ARM: make some NEON macros reusable Do not memcpy raw video frames when using null muxer fate: update asf seektest vp8: flush buffers on size changes. doc: improve general documentation for MacOSX asf: use packet dts as approximation of pts asf: do not call av_read_frame rtsp: Initialize the media_type_mask in the rtp guessing demuxer Cleaned up alacenc.c Conflicts: doc/APIchanges doc/developer.texi libavcodec/8svx.c libavcodec/aacdec.c libavcodec/ac3dec.c libavcodec/avcodec.h libavcodec/nellymoserdec.c libavcodec/tta.c libavcodec/utils.c libavcodec/version.h libavcodec/wmadec.c libavformat/asfdec.c tests/ref/seek/lavf_asf Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/wavpack.c')
-rw-r--r--libavcodec/wavpack.c116
1 files changed, 44 insertions, 72 deletions
diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c
index 5ff9795ef8..1ccaec665d 100644
--- a/libavcodec/wavpack.c
+++ b/libavcodec/wavpack.c
@@ -115,8 +115,6 @@ typedef struct WavpackFrameContext {
int float_shift;
int float_max_exp;
WvChannel ch[2];
- int samples_left;
- int max_samples;
int pos;
SavedContext sc, extra_sc;
} WavpackFrameContext;
@@ -125,6 +123,7 @@ typedef struct WavpackFrameContext {
typedef struct WavpackContext {
AVCodecContext *avctx;
+ AVFrame frame;
WavpackFrameContext *fdec[WV_MAX_FRAME_DECODERS];
int fdec_num;
@@ -133,7 +132,6 @@ typedef struct WavpackContext {
int mkv_mode;
int block;
int samples;
- int samples_left;
int ch_offset;
} WavpackContext;
@@ -485,7 +483,6 @@ static float wv_get_value_float(WavpackFrameContext *s, uint32_t *crc, int S)
static void wv_reset_saved_context(WavpackFrameContext *s)
{
s->pos = 0;
- s->samples_left = 0;
s->sc.crc = s->extra_sc.crc = 0xFFFFFFFF;
}
@@ -502,8 +499,7 @@ static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb, vo
float *dstfl = dst;
const int channel_pad = s->avctx->channels - 2;
- if(s->samples_left == s->samples)
- s->one = s->zero = s->zeroes = 0;
+ s->one = s->zero = s->zeroes = 0;
do{
L = wv_get_value(s, gb, 0, &last);
if(last) break;
@@ -594,13 +590,8 @@ static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb, vo
dst16 += channel_pad;
}
count++;
- }while(!last && count < s->max_samples);
+ } while (!last && count < s->samples);
- if (last)
- s->samples_left = 0;
- else
- s->samples_left -= count;
- if(!s->samples_left){
wv_reset_saved_context(s);
if(crc != s->CRC){
av_log(s->avctx, AV_LOG_ERROR, "CRC error\n");
@@ -610,15 +601,7 @@ static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb, vo
av_log(s->avctx, AV_LOG_ERROR, "Extra bits CRC error\n");
return -1;
}
- }else{
- s->pos = pos;
- s->sc.crc = crc;
- s->sc.bits_used = get_bits_count(&s->gb);
- if(s->got_extra_bits){
- s->extra_sc.crc = crc_extra_bits;
- s->extra_sc.bits_used = get_bits_count(&s->gb_extra_bits);
- }
- }
+
return count * 2;
}
@@ -635,8 +618,7 @@ static inline int wv_unpack_mono(WavpackFrameContext *s, GetBitContext *gb, void
float *dstfl = dst;
const int channel_stride = s->avctx->channels;
- if(s->samples_left == s->samples)
- s->one = s->zero = s->zeroes = 0;
+ s->one = s->zero = s->zeroes = 0;
do{
T = wv_get_value(s, gb, 0, &last);
S = 0;
@@ -675,13 +657,8 @@ static inline int wv_unpack_mono(WavpackFrameContext *s, GetBitContext *gb, void
dst16 += channel_stride;
}
count++;
- }while(!last && count < s->max_samples);
+ } while (!last && count < s->samples);
- if (last)
- s->samples_left = 0;
- else
- s->samples_left -= count;
- if(!s->samples_left){
wv_reset_saved_context(s);
if(crc != s->CRC){
av_log(s->avctx, AV_LOG_ERROR, "CRC error\n");
@@ -691,15 +668,7 @@ static inline int wv_unpack_mono(WavpackFrameContext *s, GetBitContext *gb, void
av_log(s->avctx, AV_LOG_ERROR, "Extra bits CRC error\n");
return -1;
}
- }else{
- s->pos = pos;
- s->sc.crc = crc;
- s->sc.bits_used = get_bits_count(&s->gb);
- if(s->got_extra_bits){
- s->extra_sc.crc = crc_extra_bits;
- s->extra_sc.bits_used = get_bits_count(&s->gb_extra_bits);
- }
- }
+
return count;
}
@@ -743,6 +712,9 @@ static av_cold int wavpack_decode_init(AVCodecContext *avctx)
s->fdec_num = 0;
+ avcodec_get_frame_defaults(&s->frame);
+ avctx->coded_frame = &s->frame;
+
return 0;
}
@@ -759,7 +731,7 @@ static av_cold int wavpack_decode_end(AVCodecContext *avctx)
}
static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
- void *data, int *data_size,
+ void *data, int *got_frame_ptr,
const uint8_t *buf, int buf_size)
{
WavpackContext *wc = avctx->priv_data;
@@ -774,7 +746,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
int bpp, chan, chmask;
if (buf_size == 0){
- *data_size = 0;
+ *got_frame_ptr = 0;
return 0;
}
@@ -789,18 +761,16 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
return -1;
}
- if(!s->samples_left){
memset(s->decorr, 0, MAX_TERMS * sizeof(Decorr));
memset(s->ch, 0, sizeof(s->ch));
s->extra_bits = 0;
s->and = s->or = s->shift = 0;
s->got_extra_bits = 0;
- }
if(!wc->mkv_mode){
s->samples = AV_RL32(buf); buf += 4;
if(!s->samples){
- *data_size = 0;
+ *got_frame_ptr = 0;
return 0;
}
}else{
@@ -829,13 +799,6 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
wc->ch_offset += 1 + s->stereo;
- s->max_samples = *data_size / (bpp * avctx->channels);
- s->max_samples = FFMIN(s->max_samples, s->samples);
- if(s->samples_left > 0){
- s->max_samples = FFMIN(s->max_samples, s->samples_left);
- buf = buf_end;
- }
-
// parse metadata blocks
while(buf < buf_end){
id = *buf++;
@@ -1064,7 +1027,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
}
if(id & WP_IDF_ODD) buf++;
}
- if(!s->samples_left){
+
if(!got_terms){
av_log(avctx, AV_LOG_ERROR, "No block with decorrelation terms\n");
return -1;
@@ -1101,16 +1064,6 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
s->got_extra_bits = 0;
}
}
- s->samples_left = s->samples;
- }else{
- init_get_bits(&s->gb, orig_buf + s->sc.offset, s->sc.size);
- skip_bits_long(&s->gb, s->sc.bits_used);
- if(s->got_extra_bits){
- init_get_bits(&s->gb_extra_bits, orig_buf + s->extra_sc.offset,
- s->extra_sc.size);
- skip_bits_long(&s->gb_extra_bits, s->extra_sc.bits_used);
- }
- }
if(s->stereo_in){
if(avctx->sample_fmt == AV_SAMPLE_FMT_S16)
@@ -1167,7 +1120,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
}
}
- wc->samples_left = s->samples_left;
+ *got_frame_ptr = 1;
return samplecount * bpp;
}
@@ -1181,23 +1134,40 @@ static void wavpack_decode_flush(AVCodecContext *avctx)
wv_reset_saved_context(s->fdec[i]);
}
-static int wavpack_decode_frame(AVCodecContext *avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
+static int wavpack_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
WavpackContext *s = avctx->priv_data;
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
- int frame_size;
+ int frame_size, ret;
int samplecount = 0;
s->block = 0;
- s->samples_left = 0;
s->ch_offset = 0;
+ /* determine number of samples */
if(s->mkv_mode){
s->samples = AV_RL32(buf); buf += 4;
+ } else {
+ if (s->multichannel)
+ s->samples = AV_RL32(buf + 4);
+ else
+ s->samples = AV_RL32(buf);
+ }
+ if (s->samples <= 0) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid number of samples: %d\n",
+ s->samples);
+ return AVERROR(EINVAL);
+ }
+
+ /* get output buffer */
+ s->frame.nb_samples = s->samples;
+ if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
}
+
while(buf_size > 0){
if(!s->multichannel){
frame_size = buf_size;
@@ -1216,17 +1186,19 @@ static int wavpack_decode_frame(AVCodecContext *avctx,
wavpack_decode_flush(avctx);
return -1;
}
- if((samplecount = wavpack_decode_block(avctx, s->block, data,
- data_size, buf, frame_size)) < 0) {
+ if((samplecount = wavpack_decode_block(avctx, s->block, s->frame.data[0],
+ got_frame_ptr, buf, frame_size)) < 0) {
wavpack_decode_flush(avctx);
return -1;
}
s->block++;
buf += frame_size; buf_size -= frame_size;
}
- *data_size = samplecount * avctx->channels;
- return s->samples_left > 0 ? 0 : avpkt->size;
+ if (*got_frame_ptr)
+ *(AVFrame *)data = s->frame;
+
+ return avpkt->size;
}
AVCodec ff_wavpack_decoder = {
@@ -1238,6 +1210,6 @@ AVCodec ff_wavpack_decoder = {
.close = wavpack_decode_end,
.decode = wavpack_decode_frame,
.flush = wavpack_decode_flush,
- .capabilities = CODEC_CAP_SUBFRAMES,
+ .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("WavPack"),
};