From f199f38573c4c02753f03ba8db04481038fa6f2e Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 12 Oct 2011 13:27:41 -0400 Subject: [PATCH] avplay: use avcodec_decode_audio4() --- avplay.c | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/avplay.c b/avplay.c index e2ce2cc17b..69cd6179f9 100644 --- a/avplay.c +++ b/avplay.c @@ -153,18 +153,16 @@ typedef struct VideoState { AVStream *audio_st; PacketQueue audioq; int audio_hw_buf_size; - /* samples output by the codec. we reserve more space for avsync - compensation */ - DECLARE_ALIGNED(16,uint8_t,audio_buf1)[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2]; - DECLARE_ALIGNED(16,uint8_t,audio_buf2)[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2]; uint8_t silence_buf[SDL_AUDIO_BUFFER_SIZE]; uint8_t *audio_buf; + uint8_t *audio_buf1; unsigned int audio_buf_size; /* in bytes */ int audio_buf_index; /* in bytes */ AVPacket audio_pkt_temp; AVPacket audio_pkt; enum AVSampleFormat audio_src_fmt; AVAudioConvert *reformat_ctx; + AVFrame *frame; int show_audio; /* if true, display audio samples */ int16_t sample_array[SAMPLE_ARRAY_SIZE]; @@ -2010,7 +2008,7 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr) AVPacket *pkt_temp = &is->audio_pkt_temp; AVPacket *pkt = &is->audio_pkt; AVCodecContext *dec= is->audio_st->codec; - int n, len1, data_size; + int n, len1, data_size, got_frame; double pts; int new_packet = 0; int flush_complete = 0; @@ -2018,13 +2016,16 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr) for(;;) { /* NOTE: the audio packet can contain several frames */ while (pkt_temp->size > 0 || (!pkt_temp->data && new_packet)) { + if (!is->frame) { + if (!(is->frame = avcodec_alloc_frame())) + return AVERROR(ENOMEM); + } else + avcodec_get_frame_defaults(is->frame); + if (flush_complete) break; new_packet = 0; - data_size = sizeof(is->audio_buf1); - len1 = avcodec_decode_audio3(dec, - (int16_t *)is->audio_buf1, &data_size, - pkt_temp); + len1 = avcodec_decode_audio4(dec, is->frame, &got_frame, pkt_temp); if (len1 < 0) { /* if error, we skip the frame */ pkt_temp->size = 0; @@ -2034,12 +2035,15 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr) pkt_temp->data += len1; pkt_temp->size -= len1; - if (data_size <= 0) { + if (!got_frame) { /* stop sending empty packets if the decoder is finished */ if (!pkt_temp->data && dec->codec->capabilities & CODEC_CAP_DELAY) flush_complete = 1; continue; } + data_size = av_samples_get_buffer_size(NULL, dec->channels, + is->frame->nb_samples, + dec->sample_fmt, 1); if (dec->sample_fmt != is->audio_src_fmt) { if (is->reformat_ctx) @@ -2056,21 +2060,26 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr) } if (is->reformat_ctx) { - const void *ibuf[6]= {is->audio_buf1}; - void *obuf[6]= {is->audio_buf2}; + const void *ibuf[6]= { is->frame->data[0] }; + void *obuf[6]; int istride[6]= {av_get_bytes_per_sample(dec->sample_fmt)}; int ostride[6]= {2}; int len= data_size/istride[0]; + obuf[0] = av_realloc(is->audio_buf1, FFALIGN(len * ostride[0], 32)); + if (!obuf[0]) { + return AVERROR(ENOMEM); + } + is->audio_buf1 = obuf[0]; if (av_audio_convert(is->reformat_ctx, obuf, ostride, ibuf, istride, len)<0) { printf("av_audio_convert() failed\n"); break; } - is->audio_buf= is->audio_buf2; + is->audio_buf = is->audio_buf1; /* FIXME: existing code assume that data_size equals framesize*channels*2 remove this legacy cruft */ data_size= len*2; }else{ - is->audio_buf= is->audio_buf1; + is->audio_buf = is->frame->data[0]; } /* if no pts, then compute it */ @@ -2106,8 +2115,7 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr) if (pkt->data == flush_pkt.data) avcodec_flush_buffers(dec); - pkt_temp->data = pkt->data; - pkt_temp->size = pkt->size; + *pkt_temp = *pkt; /* if update the audio clock with the pts */ if (pkt->pts != AV_NOPTS_VALUE) { @@ -2275,6 +2283,9 @@ static void stream_component_close(VideoState *is, int stream_index) if (is->reformat_ctx) av_audio_convert_free(is->reformat_ctx); is->reformat_ctx = NULL; + av_freep(&is->audio_buf1); + is->audio_buf = NULL; + av_freep(&is->frame); if (is->rdft) { av_rdft_end(is->rdft);