mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-05-13 21:26:33 +02:00
ffplay: handle audio buffersink output properly with buffering filters
Fixes cases when the audio filter generates less or more frames than the input. Signed-off-by: Marton Balint <cus@passwd.hu>
This commit is contained in:
parent
325846aac0
commit
0b24e341ed
26
ffplay.c
26
ffplay.c
@ -188,6 +188,7 @@ typedef struct VideoState {
|
|||||||
unsigned int audio_buf1_size;
|
unsigned int audio_buf1_size;
|
||||||
int audio_buf_index; /* in bytes */
|
int audio_buf_index; /* in bytes */
|
||||||
int audio_write_buf_size;
|
int audio_write_buf_size;
|
||||||
|
int audio_buf_frames_pending;
|
||||||
AVPacket audio_pkt_temp;
|
AVPacket audio_pkt_temp;
|
||||||
AVPacket audio_pkt;
|
AVPacket audio_pkt;
|
||||||
int audio_pkt_temp_serial;
|
int audio_pkt_temp_serial;
|
||||||
@ -2153,10 +2154,12 @@ static int audio_decode_frame(VideoState *is)
|
|||||||
int flush_complete = 0;
|
int flush_complete = 0;
|
||||||
int wanted_nb_samples;
|
int wanted_nb_samples;
|
||||||
AVRational tb;
|
AVRational tb;
|
||||||
|
int ret;
|
||||||
|
int reconfigure;
|
||||||
|
|
||||||
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) || is->audio_buf_frames_pending) {
|
||||||
if (!is->frame) {
|
if (!is->frame) {
|
||||||
if (!(is->frame = avcodec_alloc_frame()))
|
if (!(is->frame = avcodec_alloc_frame()))
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
@ -2171,6 +2174,8 @@ static int audio_decode_frame(VideoState *is)
|
|||||||
if (is->paused)
|
if (is->paused)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (!is->audio_buf_frames_pending) {
|
||||||
|
|
||||||
if (flush_complete)
|
if (flush_complete)
|
||||||
break;
|
break;
|
||||||
new_packet = 0;
|
new_packet = 0;
|
||||||
@ -2200,10 +2205,6 @@ static int audio_decode_frame(VideoState *is)
|
|||||||
pkt_temp->pts += (double) is->frame->nb_samples / is->frame->sample_rate / av_q2d(is->audio_st->time_base);
|
pkt_temp->pts += (double) is->frame->nb_samples / is->frame->sample_rate / av_q2d(is->audio_st->time_base);
|
||||||
|
|
||||||
#if CONFIG_AVFILTER
|
#if CONFIG_AVFILTER
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
int reconfigure;
|
|
||||||
|
|
||||||
dec_channel_layout = get_valid_channel_layout(is->frame->channel_layout, av_frame_get_channels(is->frame));
|
dec_channel_layout = get_valid_channel_layout(is->frame->channel_layout, av_frame_get_channels(is->frame));
|
||||||
|
|
||||||
reconfigure =
|
reconfigure =
|
||||||
@ -2235,10 +2236,18 @@ static int audio_decode_frame(VideoState *is)
|
|||||||
if ((ret = av_buffersrc_add_frame(is->in_audio_filter, is->frame)) < 0)
|
if ((ret = av_buffersrc_add_frame(is->in_audio_filter, is->frame)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
av_frame_unref(is->frame);
|
av_frame_unref(is->frame);
|
||||||
if ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, is->frame, 0)) < 0)
|
#endif
|
||||||
return ret;
|
|
||||||
tb = is->out_audio_filter->inputs[0]->time_base;
|
|
||||||
}
|
}
|
||||||
|
#if CONFIG_AVFILTER
|
||||||
|
if ((ret = av_buffersink_get_frame_flags(is->out_audio_filter, is->frame, 0)) < 0) {
|
||||||
|
if (ret == AVERROR(EAGAIN)) {
|
||||||
|
is->audio_buf_frames_pending = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
is->audio_buf_frames_pending = 1;
|
||||||
|
tb = is->out_audio_filter->inputs[0]->time_base;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(is->frame),
|
data_size = av_samples_get_buffer_size(NULL, av_frame_get_channels(is->frame),
|
||||||
@ -2340,6 +2349,7 @@ static int audio_decode_frame(VideoState *is)
|
|||||||
if (pkt->data == flush_pkt.data) {
|
if (pkt->data == flush_pkt.data) {
|
||||||
avcodec_flush_buffers(dec);
|
avcodec_flush_buffers(dec);
|
||||||
flush_complete = 0;
|
flush_complete = 0;
|
||||||
|
is->audio_buf_frames_pending = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
*pkt_temp = *pkt;
|
*pkt_temp = *pkt;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user