diff options
author | Justin Ruggles <justin.ruggles@gmail.com> | 2011-09-06 12:17:45 -0400 |
---|---|---|
committer | Justin Ruggles <justin.ruggles@gmail.com> | 2011-12-02 17:40:40 -0500 |
commit | 0eea212943544d40f99b05571aa7159d78667154 (patch) | |
tree | 1e6b0271a633bf8a3f92c78bdfbaca275498ee26 /libavcodec/pcm.c | |
parent | 560f773c7ddd17f66e2621222980c1359a9027be (diff) | |
download | ffmpeg-0eea212943544d40f99b05571aa7159d78667154.tar.gz |
Add avcodec_decode_audio4().
Deprecate avcodec_decode_audio3().
Implement audio support in avcodec_default_get_buffer().
Implement the new audio decoder API in all audio decoders.
Diffstat (limited to 'libavcodec/pcm.c')
-rw-r--r-- | libavcodec/pcm.c | 42 |
1 files changed, 25 insertions, 17 deletions
diff --git a/libavcodec/pcm.c b/libavcodec/pcm.c index 0e9e685989..76d5c100bc 100644 --- a/libavcodec/pcm.c +++ b/libavcodec/pcm.c @@ -192,6 +192,7 @@ static int pcm_encode_frame(AVCodecContext *avctx, } typedef struct PCMDecode { + AVFrame frame; short table[256]; } PCMDecode; @@ -223,6 +224,9 @@ static av_cold int pcm_decode_init(AVCodecContext * avctx) if (avctx->sample_fmt == AV_SAMPLE_FMT_S32) avctx->bits_per_raw_sample = av_get_bits_per_sample(avctx->codec->id); + avcodec_get_frame_defaults(&s->frame); + avctx->coded_frame = &s->frame; + return 0; } @@ -243,22 +247,20 @@ static av_cold int pcm_decode_init(AVCodecContext * avctx) dst += size / 8; \ } -static int pcm_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) +static int pcm_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame_ptr, AVPacket *avpkt) { const uint8_t *src = avpkt->data; int buf_size = avpkt->size; PCMDecode *s = avctx->priv_data; - int sample_size, c, n, out_size; + int sample_size, c, n, ret, samples_per_block; uint8_t *samples; int32_t *dst_int32_t; - samples = data; - sample_size = av_get_bits_per_sample(avctx->codec_id)/8; /* av_get_bits_per_sample returns 0 for CODEC_ID_PCM_DVD */ + samples_per_block = 1; if (CODEC_ID_PCM_DVD == avctx->codec_id) { if (avctx->bits_per_coded_sample != 20 && avctx->bits_per_coded_sample != 24) { @@ -266,10 +268,13 @@ static int pcm_decode_frame(AVCodecContext *avctx, return AVERROR(EINVAL); } /* 2 samples are interleaved per block in PCM_DVD */ + samples_per_block = 2; sample_size = avctx->bits_per_coded_sample * 2 / 8; - } else if (avctx->codec_id == CODEC_ID_PCM_LXF) + } else if (avctx->codec_id == CODEC_ID_PCM_LXF) { /* we process 40-bit blocks per channel for LXF */ + samples_per_block = 2; sample_size = 5; + } if (sample_size == 0) { av_log(avctx, AV_LOG_ERROR, "Invalid sample_size\n"); @@ -288,14 +293,13 @@ static int pcm_decode_frame(AVCodecContext *avctx, n = buf_size/sample_size; - out_size = n * av_get_bytes_per_sample(avctx->sample_fmt); - if (avctx->codec_id == CODEC_ID_PCM_DVD || - avctx->codec_id == CODEC_ID_PCM_LXF) - out_size *= 2; - if (*data_size < out_size) { - av_log(avctx, AV_LOG_ERROR, "output buffer too small\n"); - return AVERROR(EINVAL); + /* get output buffer */ + s->frame.nb_samples = n * samples_per_block / avctx->channels; + if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return ret; } + samples = s->frame.data[0]; switch(avctx->codec->id) { case CODEC_ID_PCM_U32LE: @@ -401,7 +405,7 @@ static int pcm_decode_frame(AVCodecContext *avctx, case CODEC_ID_PCM_DVD: { const uint8_t *src8; - dst_int32_t = data; + dst_int32_t = (int32_t *)s->frame.data[0]; n /= avctx->channels; switch (avctx->bits_per_coded_sample) { case 20: @@ -433,7 +437,7 @@ static int pcm_decode_frame(AVCodecContext *avctx, { int i; const uint8_t *src8; - dst_int32_t = data; + dst_int32_t = (int32_t *)s->frame.data[0]; n /= avctx->channels; //unpack and de-planerize for (i = 0; i < n; i++) { @@ -454,7 +458,10 @@ static int pcm_decode_frame(AVCodecContext *avctx, default: return -1; } - *data_size = out_size; + + *got_frame_ptr = 1; + *(AVFrame *)data = s->frame; + return buf_size; } @@ -483,6 +490,7 @@ AVCodec ff_ ## name_ ## _decoder = { \ .priv_data_size = sizeof(PCMDecode), \ .init = pcm_decode_init, \ .decode = pcm_decode_frame, \ + .capabilities = CODEC_CAP_DR1, \ .sample_fmts = (const enum AVSampleFormat[]){sample_fmt_,AV_SAMPLE_FMT_NONE}, \ .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ } |