diff options
Diffstat (limited to 'libavcodec/vorbisdec.c')
-rw-r--r-- | libavcodec/vorbisdec.c | 33 |
1 files changed, 20 insertions, 13 deletions
diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c index 0457d8b..03ecc38 100644 --- a/libavcodec/vorbisdec.c +++ b/libavcodec/vorbisdec.c @@ -125,6 +125,7 @@ typedef struct { typedef struct vorbis_context_s { AVCodecContext *avccontext; + AVFrame frame; GetBitContext gb; DSPContext dsp; FmtConvertContext fmt_conv; @@ -1037,6 +1038,9 @@ static av_cold int vorbis_decode_init(AVCodecContext *avccontext) avccontext->sample_rate = vc->audio_samplerate; avccontext->frame_size = FFMIN(vc->blocksize[0], vc->blocksize[1]) >> 2; + avcodec_get_frame_defaults(&vc->frame); + avccontext->coded_frame = &vc->frame; + return 0; } @@ -1609,16 +1613,15 @@ static int vorbis_parse_audio_packet(vorbis_context *vc) // Return the decoded audio packet through the standard api -static int vorbis_decode_frame(AVCodecContext *avccontext, - void *data, int *data_size, - AVPacket *avpkt) +static int vorbis_decode_frame(AVCodecContext *avccontext, void *data, + int *got_frame_ptr, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; vorbis_context *vc = avccontext->priv_data; GetBitContext *gb = &(vc->gb); const float *channel_ptrs[255]; - int i, len, out_size; + int i, len, ret; av_dlog(NULL, "packet length %d \n", buf_size); @@ -1629,18 +1632,18 @@ static int vorbis_decode_frame(AVCodecContext *avccontext, if (!vc->first_frame) { vc->first_frame = 1; - *data_size = 0; + *got_frame_ptr = 0; return buf_size; } av_dlog(NULL, "parsed %d bytes %d bits, returned %d samples (*ch*bits) \n", get_bits_count(gb) / 8, get_bits_count(gb) % 8, len); - out_size = len * vc->audio_channels * - av_get_bytes_per_sample(avccontext->sample_fmt); - if (*data_size < out_size) { - av_log(avccontext, AV_LOG_ERROR, "output buffer is too small\n"); - return AVERROR(EINVAL); + /* get output buffer */ + vc->frame.nb_samples = len; + if ((ret = avccontext->get_buffer(avccontext, &vc->frame)) < 0) { + av_log(avccontext, AV_LOG_ERROR, "get_buffer() failed\n"); + return ret; } if (vc->audio_channels > 8) { @@ -1653,12 +1656,15 @@ static int vorbis_decode_frame(AVCodecContext *avccontext, } if (avccontext->sample_fmt == AV_SAMPLE_FMT_FLT) - vc->fmt_conv.float_interleave(data, channel_ptrs, len, vc->audio_channels); + vc->fmt_conv.float_interleave((float *)vc->frame.data[0], channel_ptrs, + len, vc->audio_channels); else - vc->fmt_conv.float_to_int16_interleave(data, channel_ptrs, len, + vc->fmt_conv.float_to_int16_interleave((int16_t *)vc->frame.data[0], + channel_ptrs, len, vc->audio_channels); - *data_size = out_size; + *got_frame_ptr = 1; + *(AVFrame *)data = vc->frame; return buf_size; } @@ -1682,6 +1688,7 @@ AVCodec ff_vorbis_decoder = { .init = vorbis_decode_init, .close = vorbis_decode_close, .decode = vorbis_decode_frame, + .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Vorbis"), .channel_layouts = ff_vorbis_channel_layouts, .sample_fmts = (const enum AVSampleFormat[]) { |