Commit f199f385 authored by Justin Ruggles's avatar Justin Ruggles

avplay: use avcodec_decode_audio4()

parent e2a2c49f
...@@ -153,18 +153,16 @@ typedef struct VideoState { ...@@ -153,18 +153,16 @@ typedef struct VideoState {
AVStream *audio_st; AVStream *audio_st;
PacketQueue audioq; PacketQueue audioq;
int audio_hw_buf_size; 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 silence_buf[SDL_AUDIO_BUFFER_SIZE];
uint8_t *audio_buf; uint8_t *audio_buf;
uint8_t *audio_buf1;
unsigned int audio_buf_size; /* in bytes */ unsigned int audio_buf_size; /* in bytes */
int audio_buf_index; /* in bytes */ int audio_buf_index; /* in bytes */
AVPacket audio_pkt_temp; AVPacket audio_pkt_temp;
AVPacket audio_pkt; AVPacket audio_pkt;
enum AVSampleFormat audio_src_fmt; enum AVSampleFormat audio_src_fmt;
AVAudioConvert *reformat_ctx; AVAudioConvert *reformat_ctx;
AVFrame *frame;
int show_audio; /* if true, display audio samples */ int show_audio; /* if true, display audio samples */
int16_t sample_array[SAMPLE_ARRAY_SIZE]; int16_t sample_array[SAMPLE_ARRAY_SIZE];
...@@ -2010,7 +2008,7 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr) ...@@ -2010,7 +2008,7 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr)
AVPacket *pkt_temp = &is->audio_pkt_temp; AVPacket *pkt_temp = &is->audio_pkt_temp;
AVPacket *pkt = &is->audio_pkt; AVPacket *pkt = &is->audio_pkt;
AVCodecContext *dec= is->audio_st->codec; AVCodecContext *dec= is->audio_st->codec;
int n, len1, data_size; int n, len1, data_size, got_frame;
double pts; double pts;
int new_packet = 0; int new_packet = 0;
int flush_complete = 0; int flush_complete = 0;
...@@ -2018,13 +2016,16 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr) ...@@ -2018,13 +2016,16 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr)
for(;;) { for(;;) {
/* NOTE: the audio packet can contain several frames */ /* NOTE: the audio packet can contain several frames */
while (pkt_temp->size > 0 || (!pkt_temp->data && new_packet)) { 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) if (flush_complete)
break; break;
new_packet = 0; new_packet = 0;
data_size = sizeof(is->audio_buf1); len1 = avcodec_decode_audio4(dec, is->frame, &got_frame, pkt_temp);
len1 = avcodec_decode_audio3(dec,
(int16_t *)is->audio_buf1, &data_size,
pkt_temp);
if (len1 < 0) { if (len1 < 0) {
/* if error, we skip the frame */ /* if error, we skip the frame */
pkt_temp->size = 0; pkt_temp->size = 0;
...@@ -2034,12 +2035,15 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr) ...@@ -2034,12 +2035,15 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr)
pkt_temp->data += len1; pkt_temp->data += len1;
pkt_temp->size -= len1; pkt_temp->size -= len1;
if (data_size <= 0) { if (!got_frame) {
/* stop sending empty packets if the decoder is finished */ /* stop sending empty packets if the decoder is finished */
if (!pkt_temp->data && dec->codec->capabilities & CODEC_CAP_DELAY) if (!pkt_temp->data && dec->codec->capabilities & CODEC_CAP_DELAY)
flush_complete = 1; flush_complete = 1;
continue; 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 (dec->sample_fmt != is->audio_src_fmt) {
if (is->reformat_ctx) if (is->reformat_ctx)
...@@ -2056,21 +2060,26 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr) ...@@ -2056,21 +2060,26 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr)
} }
if (is->reformat_ctx) { if (is->reformat_ctx) {
const void *ibuf[6]= {is->audio_buf1}; const void *ibuf[6]= { is->frame->data[0] };
void *obuf[6]= {is->audio_buf2}; void *obuf[6];
int istride[6]= {av_get_bytes_per_sample(dec->sample_fmt)}; int istride[6]= {av_get_bytes_per_sample(dec->sample_fmt)};
int ostride[6]= {2}; int ostride[6]= {2};
int len= data_size/istride[0]; 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) { if (av_audio_convert(is->reformat_ctx, obuf, ostride, ibuf, istride, len)<0) {
printf("av_audio_convert() failed\n"); printf("av_audio_convert() failed\n");
break; break;
} }
is->audio_buf= is->audio_buf2; is->audio_buf = is->audio_buf1;
/* FIXME: existing code assume that data_size equals framesize*channels*2 /* FIXME: existing code assume that data_size equals framesize*channels*2
remove this legacy cruft */ remove this legacy cruft */
data_size= len*2; data_size= len*2;
}else{ }else{
is->audio_buf= is->audio_buf1; is->audio_buf = is->frame->data[0];
} }
/* if no pts, then compute it */ /* if no pts, then compute it */
...@@ -2106,8 +2115,7 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr) ...@@ -2106,8 +2115,7 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr)
if (pkt->data == flush_pkt.data) if (pkt->data == flush_pkt.data)
avcodec_flush_buffers(dec); avcodec_flush_buffers(dec);
pkt_temp->data = pkt->data; *pkt_temp = *pkt;
pkt_temp->size = pkt->size;
/* if update the audio clock with the pts */ /* if update the audio clock with the pts */
if (pkt->pts != AV_NOPTS_VALUE) { if (pkt->pts != AV_NOPTS_VALUE) {
...@@ -2275,6 +2283,9 @@ static void stream_component_close(VideoState *is, int stream_index) ...@@ -2275,6 +2283,9 @@ static void stream_component_close(VideoState *is, int stream_index)
if (is->reformat_ctx) if (is->reformat_ctx)
av_audio_convert_free(is->reformat_ctx); av_audio_convert_free(is->reformat_ctx);
is->reformat_ctx = NULL; is->reformat_ctx = NULL;
av_freep(&is->audio_buf1);
is->audio_buf = NULL;
av_freep(&is->frame);
if (is->rdft) { if (is->rdft) {
av_rdft_end(is->rdft); av_rdft_end(is->rdft);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment