Commit 0995e1f1 authored by James Almer's avatar James Almer

ffplay: convert to new channel layout-API

Signed-off-by: 's avatarJames Almer <jamrial@gmail.com>
parent a8b885f2
...@@ -132,8 +132,7 @@ typedef struct PacketQueue { ...@@ -132,8 +132,7 @@ typedef struct PacketQueue {
typedef struct AudioParams { typedef struct AudioParams {
int freq; int freq;
int channels; AVChannelLayout ch_layout;
int64_t channel_layout;
enum AVSampleFormat fmt; enum AVSampleFormat fmt;
int frame_size; int frame_size;
int bytes_per_sec; int bytes_per_sec;
...@@ -412,15 +411,6 @@ int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1, ...@@ -412,15 +411,6 @@ int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1,
return channel_count1 != channel_count2 || fmt1 != fmt2; return channel_count1 != channel_count2 || fmt1 != fmt2;
} }
static inline
int64_t get_valid_channel_layout(int64_t channel_layout, int channels)
{
if (channel_layout && av_get_channel_layout_nb_channels(channel_layout) == channels)
return channel_layout;
else
return 0;
}
static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt) static int packet_queue_put_private(PacketQueue *q, AVPacket *pkt)
{ {
MyAVPacketList pkt1; MyAVPacketList pkt1;
...@@ -1066,7 +1056,7 @@ static void video_audio_display(VideoState *s) ...@@ -1066,7 +1056,7 @@ static void video_audio_display(VideoState *s)
nb_freq = 1 << (rdft_bits - 1); nb_freq = 1 << (rdft_bits - 1);
/* compute display index : center on currently output samples */ /* compute display index : center on currently output samples */
channels = s->audio_tgt.channels; channels = s->audio_tgt.ch_layout.nb_channels;
nb_display_channels = channels; nb_display_channels = channels;
if (!s->paused) { if (!s->paused) {
int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq); int data_used= s->show_mode == SHOW_MODE_WAVES ? s->width : (2*nb_freq);
...@@ -1952,11 +1942,10 @@ static int configure_audio_filters(VideoState *is, const char *afilters, int for ...@@ -1952,11 +1942,10 @@ static int configure_audio_filters(VideoState *is, const char *afilters, int for
{ {
static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }; static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE };
int sample_rates[2] = { 0, -1 }; int sample_rates[2] = { 0, -1 };
int64_t channel_layouts[2] = { 0, -1 };
int channels[2] = { 0, -1 };
AVFilterContext *filt_asrc = NULL, *filt_asink = NULL; AVFilterContext *filt_asrc = NULL, *filt_asink = NULL;
char aresample_swr_opts[512] = ""; char aresample_swr_opts[512] = "";
const AVDictionaryEntry *e = NULL; const AVDictionaryEntry *e = NULL;
AVBPrint bp;
char asrc_args[256]; char asrc_args[256];
int ret; int ret;
...@@ -1965,20 +1954,20 @@ static int configure_audio_filters(VideoState *is, const char *afilters, int for ...@@ -1965,20 +1954,20 @@ static int configure_audio_filters(VideoState *is, const char *afilters, int for
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
is->agraph->nb_threads = filter_nbthreads; is->agraph->nb_threads = filter_nbthreads;
av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC);
while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX))) while ((e = av_dict_get(swr_opts, "", e, AV_DICT_IGNORE_SUFFIX)))
av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value); av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value);
if (strlen(aresample_swr_opts)) if (strlen(aresample_swr_opts))
aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0'; aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\0';
av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0); av_opt_set(is->agraph, "aresample_swr_opts", aresample_swr_opts, 0);
av_channel_layout_describe_bprint(&is->audio_filter_src.ch_layout, &bp);
ret = snprintf(asrc_args, sizeof(asrc_args), ret = snprintf(asrc_args, sizeof(asrc_args),
"sample_rate=%d:sample_fmt=%s:channels=%d:time_base=%d/%d", "sample_rate=%d:sample_fmt=%s:time_base=%d/%d:channel_layout=%s",
is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt), is->audio_filter_src.freq, av_get_sample_fmt_name(is->audio_filter_src.fmt),
is->audio_filter_src.channels, 1, is->audio_filter_src.freq, bp.str);
1, is->audio_filter_src.freq);
if (is->audio_filter_src.channel_layout)
snprintf(asrc_args + ret, sizeof(asrc_args) - ret,
":channel_layout=0x%"PRIx64, is->audio_filter_src.channel_layout);
ret = avfilter_graph_create_filter(&filt_asrc, ret = avfilter_graph_create_filter(&filt_asrc,
avfilter_get_by_name("abuffer"), "ffplay_abuffer", avfilter_get_by_name("abuffer"), "ffplay_abuffer",
...@@ -1999,14 +1988,10 @@ static int configure_audio_filters(VideoState *is, const char *afilters, int for ...@@ -1999,14 +1988,10 @@ static int configure_audio_filters(VideoState *is, const char *afilters, int for
goto end; goto end;
if (force_output_format) { if (force_output_format) {
channel_layouts[0] = is->audio_tgt.channel_layout;
channels [0] = is->audio_tgt.channel_layout ? -1 : is->audio_tgt.channels;
sample_rates [0] = is->audio_tgt.freq; sample_rates [0] = is->audio_tgt.freq;
if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0) if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0)
goto end; goto end;
if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, AV_OPT_SEARCH_CHILDREN)) < 0) if ((ret = av_opt_set(filt_asink, "ch_layouts", bp.str, AV_OPT_SEARCH_CHILDREN)) < 0)
goto end;
if ((ret = av_opt_set_int_list(filt_asink, "channel_counts" , channels , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
goto end; goto end;
if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0) if ((ret = av_opt_set_int_list(filt_asink, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0)
goto end; goto end;
...@@ -2022,6 +2007,8 @@ static int configure_audio_filters(VideoState *is, const char *afilters, int for ...@@ -2022,6 +2007,8 @@ static int configure_audio_filters(VideoState *is, const char *afilters, int for
end: end:
if (ret < 0) if (ret < 0)
avfilter_graph_free(&is->agraph); avfilter_graph_free(&is->agraph);
av_bprint_finalize(&bp, NULL);
return ret; return ret;
} }
#endif /* CONFIG_AVFILTER */ #endif /* CONFIG_AVFILTER */
...@@ -2033,7 +2020,6 @@ static int audio_thread(void *arg) ...@@ -2033,7 +2020,6 @@ static int audio_thread(void *arg)
Frame *af; Frame *af;
#if CONFIG_AVFILTER #if CONFIG_AVFILTER
int last_serial = -1; int last_serial = -1;
int64_t dec_channel_layout;
int reconfigure; int reconfigure;
#endif #endif
int got_frame = 0; int got_frame = 0;
...@@ -2051,27 +2037,26 @@ static int audio_thread(void *arg) ...@@ -2051,27 +2037,26 @@ static int audio_thread(void *arg)
tb = (AVRational){1, frame->sample_rate}; tb = (AVRational){1, frame->sample_rate};
#if CONFIG_AVFILTER #if CONFIG_AVFILTER
dec_channel_layout = get_valid_channel_layout(frame->channel_layout, frame->channels);
reconfigure = reconfigure =
cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels, cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.ch_layout.nb_channels,
frame->format, frame->channels) || frame->format, frame->ch_layout.nb_channels) ||
is->audio_filter_src.channel_layout != dec_channel_layout || av_channel_layout_compare(&is->audio_filter_src.ch_layout, &frame->ch_layout) ||
is->audio_filter_src.freq != frame->sample_rate || is->audio_filter_src.freq != frame->sample_rate ||
is->auddec.pkt_serial != last_serial; is->auddec.pkt_serial != last_serial;
if (reconfigure) { if (reconfigure) {
char buf1[1024], buf2[1024]; char buf1[1024], buf2[1024];
av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout); av_channel_layout_describe(&is->audio_filter_src.ch_layout, buf1, sizeof(buf1));
av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout); av_channel_layout_describe(&frame->ch_layout, buf2, sizeof(buf2));
av_log(NULL, AV_LOG_DEBUG, av_log(NULL, AV_LOG_DEBUG,
"Audio frame changed from rate:%d ch:%d fmt:%s layout:%s serial:%d to rate:%d ch:%d fmt:%s layout:%s serial:%d\n", "Audio frame changed from rate:%d ch:%d fmt:%s layout:%s serial:%d to rate:%d ch:%d fmt:%s layout:%s serial:%d\n",
is->audio_filter_src.freq, is->audio_filter_src.channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial, is->audio_filter_src.freq, is->audio_filter_src.ch_layout.nb_channels, av_get_sample_fmt_name(is->audio_filter_src.fmt), buf1, last_serial,
frame->sample_rate, frame->channels, av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial); frame->sample_rate, frame->ch_layout.nb_channels, av_get_sample_fmt_name(frame->format), buf2, is->auddec.pkt_serial);
is->audio_filter_src.fmt = frame->format; is->audio_filter_src.fmt = frame->format;
is->audio_filter_src.channels = frame->channels; ret = av_channel_layout_copy(&is->audio_filter_src.ch_layout, &frame->ch_layout);
is->audio_filter_src.channel_layout = dec_channel_layout; if (ret < 0)
goto the_end;
is->audio_filter_src.freq = frame->sample_rate; is->audio_filter_src.freq = frame->sample_rate;
last_serial = is->auddec.pkt_serial; last_serial = is->auddec.pkt_serial;
...@@ -2337,7 +2322,6 @@ static int synchronize_audio(VideoState *is, int nb_samples) ...@@ -2337,7 +2322,6 @@ static int synchronize_audio(VideoState *is, int nb_samples)
static int audio_decode_frame(VideoState *is) static int audio_decode_frame(VideoState *is)
{ {
int data_size, resampled_data_size; int data_size, resampled_data_size;
int64_t dec_channel_layout;
av_unused double audio_clock0; av_unused double audio_clock0;
int wanted_nb_samples; int wanted_nb_samples;
Frame *af; Frame *af;
...@@ -2358,34 +2342,31 @@ static int audio_decode_frame(VideoState *is) ...@@ -2358,34 +2342,31 @@ static int audio_decode_frame(VideoState *is)
frame_queue_next(&is->sampq); frame_queue_next(&is->sampq);
} while (af->serial != is->audioq.serial); } while (af->serial != is->audioq.serial);
data_size = av_samples_get_buffer_size(NULL, af->frame->channels, data_size = av_samples_get_buffer_size(NULL, af->frame->ch_layout.nb_channels,
af->frame->nb_samples, af->frame->nb_samples,
af->frame->format, 1); af->frame->format, 1);
dec_channel_layout =
(af->frame->channel_layout && af->frame->channels == av_get_channel_layout_nb_channels(af->frame->channel_layout)) ?
af->frame->channel_layout : av_get_default_channel_layout(af->frame->channels);
wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples); wanted_nb_samples = synchronize_audio(is, af->frame->nb_samples);
if (af->frame->format != is->audio_src.fmt || if (af->frame->format != is->audio_src.fmt ||
dec_channel_layout != is->audio_src.channel_layout || av_channel_layout_compare(&af->frame->ch_layout, &is->audio_src.ch_layout) ||
af->frame->sample_rate != is->audio_src.freq || af->frame->sample_rate != is->audio_src.freq ||
(wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) { (wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
swr_free(&is->swr_ctx); swr_free(&is->swr_ctx);
is->swr_ctx = swr_alloc_set_opts(NULL, swr_alloc_set_opts2(&is->swr_ctx,
is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq, &is->audio_tgt.ch_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
dec_channel_layout, af->frame->format, af->frame->sample_rate, &af->frame->ch_layout, af->frame->format, af->frame->sample_rate,
0, NULL); 0, NULL);
if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) { if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
av_log(NULL, AV_LOG_ERROR, av_log(NULL, AV_LOG_ERROR,
"Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n", "Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), af->frame->channels, af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), af->frame->ch_layout.nb_channels,
is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.channels); is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.ch_layout.nb_channels);
swr_free(&is->swr_ctx); swr_free(&is->swr_ctx);
return -1; return -1;
} }
is->audio_src.channel_layout = dec_channel_layout; if (av_channel_layout_copy(&is->audio_src.ch_layout, &af->frame->ch_layout) < 0)
is->audio_src.channels = af->frame->channels; return -1;
is->audio_src.freq = af->frame->sample_rate; is->audio_src.freq = af->frame->sample_rate;
is->audio_src.fmt = af->frame->format; is->audio_src.fmt = af->frame->format;
} }
...@@ -2394,7 +2375,7 @@ static int audio_decode_frame(VideoState *is) ...@@ -2394,7 +2375,7 @@ static int audio_decode_frame(VideoState *is)
const uint8_t **in = (const uint8_t **)af->frame->extended_data; const uint8_t **in = (const uint8_t **)af->frame->extended_data;
uint8_t **out = &is->audio_buf1; uint8_t **out = &is->audio_buf1;
int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256; int out_count = (int64_t)wanted_nb_samples * is->audio_tgt.freq / af->frame->sample_rate + 256;
int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.channels, out_count, is->audio_tgt.fmt, 0); int out_size = av_samples_get_buffer_size(NULL, is->audio_tgt.ch_layout.nb_channels, out_count, is->audio_tgt.fmt, 0);
int len2; int len2;
if (out_size < 0) { if (out_size < 0) {
av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n"); av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n");
...@@ -2421,7 +2402,7 @@ static int audio_decode_frame(VideoState *is) ...@@ -2421,7 +2402,7 @@ static int audio_decode_frame(VideoState *is)
swr_free(&is->swr_ctx); swr_free(&is->swr_ctx);
} }
is->audio_buf = is->audio_buf1; is->audio_buf = is->audio_buf1;
resampled_data_size = len2 * is->audio_tgt.channels * av_get_bytes_per_sample(is->audio_tgt.fmt); resampled_data_size = len2 * is->audio_tgt.ch_layout.nb_channels * av_get_bytes_per_sample(is->audio_tgt.fmt);
} else { } else {
is->audio_buf = af->frame->data[0]; is->audio_buf = af->frame->data[0];
resampled_data_size = data_size; resampled_data_size = data_size;
...@@ -2490,24 +2471,26 @@ static void sdl_audio_callback(void *opaque, Uint8 *stream, int len) ...@@ -2490,24 +2471,26 @@ static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
} }
} }
static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb_channels, int wanted_sample_rate, struct AudioParams *audio_hw_params) static int audio_open(void *opaque, AVChannelLayout *wanted_channel_layout, int wanted_sample_rate, struct AudioParams *audio_hw_params)
{ {
SDL_AudioSpec wanted_spec, spec; SDL_AudioSpec wanted_spec, spec;
const char *env; const char *env;
static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6}; static const int next_nb_channels[] = {0, 0, 1, 6, 2, 6, 4, 6};
static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000}; static const int next_sample_rates[] = {0, 44100, 48000, 96000, 192000};
int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1; int next_sample_rate_idx = FF_ARRAY_ELEMS(next_sample_rates) - 1;
int wanted_nb_channels = wanted_channel_layout->nb_channels;
env = SDL_getenv("SDL_AUDIO_CHANNELS"); env = SDL_getenv("SDL_AUDIO_CHANNELS");
if (env) { if (env) {
wanted_nb_channels = atoi(env); wanted_nb_channels = atoi(env);
wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels); av_channel_layout_uninit(wanted_channel_layout);
av_channel_layout_default(wanted_channel_layout, wanted_nb_channels);
} }
if (!wanted_channel_layout || wanted_nb_channels != av_get_channel_layout_nb_channels(wanted_channel_layout)) { if (wanted_channel_layout->order != AV_CHANNEL_ORDER_NATIVE) {
wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels); av_channel_layout_uninit(wanted_channel_layout);
wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX; av_channel_layout_default(wanted_channel_layout, wanted_nb_channels);
} }
wanted_nb_channels = av_get_channel_layout_nb_channels(wanted_channel_layout); wanted_nb_channels = wanted_channel_layout->nb_channels;
wanted_spec.channels = wanted_nb_channels; wanted_spec.channels = wanted_nb_channels;
wanted_spec.freq = wanted_sample_rate; wanted_spec.freq = wanted_sample_rate;
if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) { if (wanted_spec.freq <= 0 || wanted_spec.channels <= 0) {
...@@ -2534,7 +2517,7 @@ static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb ...@@ -2534,7 +2517,7 @@ static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb
return -1; return -1;
} }
} }
wanted_channel_layout = av_get_default_channel_layout(wanted_spec.channels); av_channel_layout_default(wanted_channel_layout, wanted_spec.channels);
} }
if (spec.format != AUDIO_S16SYS) { if (spec.format != AUDIO_S16SYS) {
av_log(NULL, AV_LOG_ERROR, av_log(NULL, AV_LOG_ERROR,
...@@ -2542,8 +2525,9 @@ static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb ...@@ -2542,8 +2525,9 @@ static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb
return -1; return -1;
} }
if (spec.channels != wanted_spec.channels) { if (spec.channels != wanted_spec.channels) {
wanted_channel_layout = av_get_default_channel_layout(spec.channels); av_channel_layout_uninit(wanted_channel_layout);
if (!wanted_channel_layout) { av_channel_layout_default(wanted_channel_layout, spec.channels);
if (wanted_channel_layout->order != AV_CHANNEL_ORDER_NATIVE) {
av_log(NULL, AV_LOG_ERROR, av_log(NULL, AV_LOG_ERROR,
"SDL advised channel count %d is not supported!\n", spec.channels); "SDL advised channel count %d is not supported!\n", spec.channels);
return -1; return -1;
...@@ -2552,10 +2536,10 @@ static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb ...@@ -2552,10 +2536,10 @@ static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb
audio_hw_params->fmt = AV_SAMPLE_FMT_S16; audio_hw_params->fmt = AV_SAMPLE_FMT_S16;
audio_hw_params->freq = spec.freq; audio_hw_params->freq = spec.freq;
audio_hw_params->channel_layout = wanted_channel_layout; if (av_channel_layout_copy(&audio_hw_params->ch_layout, wanted_channel_layout) < 0)
audio_hw_params->channels = spec.channels; return -1;
audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->channels, 1, audio_hw_params->fmt, 1); audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->ch_layout.nb_channels, 1, audio_hw_params->fmt, 1);
audio_hw_params->bytes_per_sec = av_samples_get_buffer_size(NULL, audio_hw_params->channels, audio_hw_params->freq, audio_hw_params->fmt, 1); audio_hw_params->bytes_per_sec = av_samples_get_buffer_size(NULL, audio_hw_params->ch_layout.nb_channels, audio_hw_params->freq, audio_hw_params->fmt, 1);
if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) { if (audio_hw_params->bytes_per_sec <= 0 || audio_hw_params->frame_size <= 0) {
av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n"); av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n");
return -1; return -1;
...@@ -2572,8 +2556,8 @@ static int stream_component_open(VideoState *is, int stream_index) ...@@ -2572,8 +2556,8 @@ static int stream_component_open(VideoState *is, int stream_index)
const char *forced_codec_name = NULL; const char *forced_codec_name = NULL;
AVDictionary *opts = NULL; AVDictionary *opts = NULL;
const AVDictionaryEntry *t = NULL; const AVDictionaryEntry *t = NULL;
int sample_rate, nb_channels; int sample_rate;
int64_t channel_layout; AVChannelLayout ch_layout = { 0 };
int ret = 0; int ret = 0;
int stream_lowres = lowres; int stream_lowres = lowres;
...@@ -2641,24 +2625,27 @@ static int stream_component_open(VideoState *is, int stream_index) ...@@ -2641,24 +2625,27 @@ static int stream_component_open(VideoState *is, int stream_index)
AVFilterContext *sink; AVFilterContext *sink;
is->audio_filter_src.freq = avctx->sample_rate; is->audio_filter_src.freq = avctx->sample_rate;
is->audio_filter_src.channels = avctx->channels; ret = av_channel_layout_copy(&is->audio_filter_src.ch_layout, &avctx->ch_layout);
is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels); if (ret < 0)
goto fail;
is->audio_filter_src.fmt = avctx->sample_fmt; is->audio_filter_src.fmt = avctx->sample_fmt;
if ((ret = configure_audio_filters(is, afilters, 0)) < 0) if ((ret = configure_audio_filters(is, afilters, 0)) < 0)
goto fail; goto fail;
sink = is->out_audio_filter; sink = is->out_audio_filter;
sample_rate = av_buffersink_get_sample_rate(sink); sample_rate = av_buffersink_get_sample_rate(sink);
nb_channels = av_buffersink_get_channels(sink); ret = av_buffersink_get_ch_layout(sink, &ch_layout);
channel_layout = av_buffersink_get_channel_layout(sink); if (ret < 0)
goto fail;
} }
#else #else
sample_rate = avctx->sample_rate; sample_rate = avctx->sample_rate;
nb_channels = avctx->channels; ret = av_channel_layout_copy(&ch_layout, &avctx->ch_layout);
channel_layout = avctx->channel_layout; if (ret < 0)
goto fail;
#endif #endif
/* prepare audio output */ /* prepare audio output */
if ((ret = audio_open(is, channel_layout, nb_channels, sample_rate, &is->audio_tgt)) < 0) if ((ret = audio_open(is, &ch_layout, sample_rate, &is->audio_tgt)) < 0)
goto fail; goto fail;
is->audio_hw_buf_size = ret; is->audio_hw_buf_size = ret;
is->audio_src = is->audio_tgt; is->audio_src = is->audio_tgt;
...@@ -2712,6 +2699,7 @@ static int stream_component_open(VideoState *is, int stream_index) ...@@ -2712,6 +2699,7 @@ static int stream_component_open(VideoState *is, int stream_index)
fail: fail:
avcodec_free_context(&avctx); avcodec_free_context(&avctx);
out: out:
av_channel_layout_uninit(&ch_layout);
av_dict_free(&opts); av_dict_free(&opts);
return ret; return ret;
...@@ -3184,7 +3172,7 @@ static void stream_cycle_channel(VideoState *is, int codec_type) ...@@ -3184,7 +3172,7 @@ static void stream_cycle_channel(VideoState *is, int codec_type)
switch (codec_type) { switch (codec_type) {
case AVMEDIA_TYPE_AUDIO: case AVMEDIA_TYPE_AUDIO:
if (st->codecpar->sample_rate != 0 && if (st->codecpar->sample_rate != 0 &&
st->codecpar->channels != 0) st->codecpar->ch_layout.nb_channels != 0)
goto the_end; goto the_end;
break; break;
case AVMEDIA_TYPE_VIDEO: case AVMEDIA_TYPE_VIDEO:
......
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