Commit c74f97bcd8 for ffmpeg
commit c74f97bcd8627458a8b4f2554af2815b933fd5d4
Author: Michael Niedermayer <michael@niedermayer.cc>
Date: Thu Oct 15 03:54:36 2026 +0200
ffplay: factor starting the audio output out of stream_component_open()
The audio device is opened once the audio decoder is set up, and a
failure to start the audio output closes the audio stream again.
Assisted-by: Claude
diff --git a/fftools/ffplay.c b/fftools/ffplay.c
index fed54fe3ae..1a7acb8897 100644
--- a/fftools/ffplay.c
+++ b/fftools/ffplay.c
@@ -1364,6 +1364,7 @@ static void stream_component_close(VideoState *is, int stream_index)
case AVMEDIA_TYPE_AUDIO:
decoder_abort(&is->auddec, &is->sampq);
SDL_CloseAudioDevice(is->audio_dev);
+ is->audio_dev = 0;
decoder_destroy(&is->auddec);
swr_free(&is->swr_ctx);
av_freep(&is->audio_buf1);
@@ -2883,6 +2884,35 @@ static int init_lcevc_graph(AVFormatContext *ic, int stream_index)
return 0;
}
+/* opens the audio device for the output of the audio filters and starts decoding and playing the audio */
+static int audio_start(VideoState *is)
+{
+ AVChannelLayout ch_layout = { 0 };
+ int ret = av_buffersink_get_ch_layout(is->out_audio_filter, &ch_layout);
+
+ if (ret >= 0)
+ ret = audio_open(is, &ch_layout, av_buffersink_get_sample_rate(is->out_audio_filter), &is->audio_tgt);
+ av_channel_layout_uninit(&ch_layout);
+ if (ret < 0)
+ return ret;
+ is->audio_hw_buf_size = ret;
+ is->audio_src = is->audio_tgt;
+ is->audio_buf_size = 0;
+ is->audio_buf_index = 0;
+
+ /* init averaging filter */
+ is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
+ is->audio_diff_avg_count = 0;
+ /* since we do not have a precise anough audio FIFO fullness,
+ we correct audio sync only if larger than this threshold */
+ is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
+
+ if ((ret = decoder_start(&is->auddec, audio_thread, "audio_decoder", is)) < 0)
+ return ret;
+ SDL_PauseAudioDevice(is->audio_dev, 0);
+ return 0;
+}
+
/* open a given stream. Return 0 if OK */
static int stream_component_open(VideoState *is, int stream_index)
{
@@ -2892,8 +2922,6 @@ static int stream_component_open(VideoState *is, int stream_index)
const AVCodec *codec;
const char *forced_codec_name = NULL;
AVDictionary *opts = NULL;
- int sample_rate;
- AVChannelLayout ch_layout = { 0 };
int ret = 0;
int stream_lowres = lowres;
@@ -2968,8 +2996,6 @@ static int stream_component_open(VideoState *is, int stream_index)
switch (avctx->codec_type) {
case AVMEDIA_TYPE_AUDIO:
{
- AVFilterContext *sink;
-
is->audio_filter_src.freq = avctx->sample_rate;
ret = av_channel_layout_copy(&is->audio_filter_src.ch_layout, &avctx->ch_layout);
if (ret < 0)
@@ -2977,28 +3003,8 @@ static int stream_component_open(VideoState *is, int stream_index)
is->audio_filter_src.fmt = avctx->sample_fmt;
if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
goto fail;
- sink = is->out_audio_filter;
- sample_rate = av_buffersink_get_sample_rate(sink);
- ret = av_buffersink_get_ch_layout(sink, &ch_layout);
- if (ret < 0)
- goto fail;
}
- /* prepare audio output */
- if ((ret = audio_open(is, &ch_layout, sample_rate, &is->audio_tgt)) < 0)
- goto fail;
- is->audio_hw_buf_size = ret;
- is->audio_src = is->audio_tgt;
- is->audio_buf_size = 0;
- is->audio_buf_index = 0;
-
- /* init averaging filter */
- is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
- is->audio_diff_avg_count = 0;
- /* since we do not have a precise anough audio FIFO fullness,
- we correct audio sync only if larger than this threshold */
- is->audio_diff_threshold = (double)(is->audio_hw_buf_size) / is->audio_tgt.bytes_per_sec;
-
is->audio_stream = stream_index;
is->audio_st = ic->streams[stream_index];
@@ -3008,9 +3014,8 @@ static int stream_component_open(VideoState *is, int stream_index)
is->auddec.start_pts = is->audio_st->start_time;
is->auddec.start_pts_tb = is->audio_st->time_base;
}
- if ((ret = decoder_start(&is->auddec, audio_thread, "audio_decoder", is)) < 0)
- goto out;
- SDL_PauseAudioDevice(is->audio_dev, 0);
+ if ((ret = audio_start(is)) < 0)
+ stream_component_close(is, stream_index);
break;
case AVMEDIA_TYPE_VIDEO:
is->video_stream = stream_index;
@@ -3043,7 +3048,6 @@ static int stream_component_open(VideoState *is, int stream_index)
fail:
avcodec_free_context(&avctx);
out:
- av_channel_layout_uninit(&ch_layout);
av_dict_free(&opts);
return ret;