|
|
|
@ -132,8 +132,7 @@ typedef struct PacketQueue { |
|
|
|
|
|
|
|
|
|
typedef struct AudioParams { |
|
|
|
|
int freq; |
|
|
|
|
int channels; |
|
|
|
|
int64_t channel_layout; |
|
|
|
|
AVChannelLayout ch_layout; |
|
|
|
|
enum AVSampleFormat fmt; |
|
|
|
|
int frame_size; |
|
|
|
|
int bytes_per_sec; |
|
|
|
@ -412,15 +411,6 @@ int cmp_audio_fmts(enum AVSampleFormat fmt1, int64_t channel_count1, |
|
|
|
|
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) |
|
|
|
|
{ |
|
|
|
|
MyAVPacketList pkt1; |
|
|
|
@ -1066,7 +1056,7 @@ static void video_audio_display(VideoState *s) |
|
|
|
|
nb_freq = 1 << (rdft_bits - 1); |
|
|
|
|
|
|
|
|
|
/* 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; |
|
|
|
|
if (!s->paused) { |
|
|
|
|
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 |
|
|
|
|
{ |
|
|
|
|
static const enum AVSampleFormat sample_fmts[] = { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }; |
|
|
|
|
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; |
|
|
|
|
char aresample_swr_opts[512] = ""; |
|
|
|
|
const AVDictionaryEntry *e = NULL; |
|
|
|
|
AVBPrint bp; |
|
|
|
|
char asrc_args[256]; |
|
|
|
|
int ret; |
|
|
|
|
|
|
|
|
@ -1965,20 +1954,20 @@ static int configure_audio_filters(VideoState *is, const char *afilters, int for |
|
|
|
|
return AVERROR(ENOMEM); |
|
|
|
|
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))) |
|
|
|
|
av_strlcatf(aresample_swr_opts, sizeof(aresample_swr_opts), "%s=%s:", e->key, e->value); |
|
|
|
|
if (strlen(aresample_swr_opts)) |
|
|
|
|
aresample_swr_opts[strlen(aresample_swr_opts)-1] = '\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), |
|
|
|
|
"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.channels, |
|
|
|
|
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); |
|
|
|
|
1, is->audio_filter_src.freq, bp.str); |
|
|
|
|
|
|
|
|
|
ret = avfilter_graph_create_filter(&filt_asrc, |
|
|
|
|
avfilter_get_by_name("abuffer"), "ffplay_abuffer", |
|
|
|
@ -1999,14 +1988,10 @@ static int configure_audio_filters(VideoState *is, const char *afilters, int for |
|
|
|
|
goto end; |
|
|
|
|
|
|
|
|
|
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; |
|
|
|
|
if ((ret = av_opt_set_int(filt_asink, "all_channel_counts", 0, AV_OPT_SEARCH_CHILDREN)) < 0) |
|
|
|
|
goto end; |
|
|
|
|
if ((ret = av_opt_set_int_list(filt_asink, "channel_layouts", channel_layouts, -1, 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) |
|
|
|
|
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, "sample_rates" , sample_rates , -1, AV_OPT_SEARCH_CHILDREN)) < 0) |
|
|
|
|
goto end; |
|
|
|
@ -2022,6 +2007,8 @@ static int configure_audio_filters(VideoState *is, const char *afilters, int for |
|
|
|
|
end: |
|
|
|
|
if (ret < 0) |
|
|
|
|
avfilter_graph_free(&is->agraph); |
|
|
|
|
av_bprint_finalize(&bp, NULL); |
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
#endif /* CONFIG_AVFILTER */ |
|
|
|
@ -2033,7 +2020,6 @@ static int audio_thread(void *arg) |
|
|
|
|
Frame *af; |
|
|
|
|
#if CONFIG_AVFILTER |
|
|
|
|
int last_serial = -1; |
|
|
|
|
int64_t dec_channel_layout; |
|
|
|
|
int reconfigure; |
|
|
|
|
#endif |
|
|
|
|
int got_frame = 0; |
|
|
|
@ -2051,27 +2037,26 @@ static int audio_thread(void *arg) |
|
|
|
|
tb = (AVRational){1, frame->sample_rate}; |
|
|
|
|
|
|
|
|
|
#if CONFIG_AVFILTER |
|
|
|
|
dec_channel_layout = get_valid_channel_layout(frame->channel_layout, frame->channels); |
|
|
|
|
|
|
|
|
|
reconfigure = |
|
|
|
|
cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.channels, |
|
|
|
|
frame->format, frame->channels) || |
|
|
|
|
is->audio_filter_src.channel_layout != dec_channel_layout || |
|
|
|
|
cmp_audio_fmts(is->audio_filter_src.fmt, is->audio_filter_src.ch_layout.nb_channels, |
|
|
|
|
frame->format, frame->ch_layout.nb_channels) || |
|
|
|
|
av_channel_layout_compare(&is->audio_filter_src.ch_layout, &frame->ch_layout) || |
|
|
|
|
is->audio_filter_src.freq != frame->sample_rate || |
|
|
|
|
is->auddec.pkt_serial != last_serial; |
|
|
|
|
|
|
|
|
|
if (reconfigure) { |
|
|
|
|
char buf1[1024], buf2[1024]; |
|
|
|
|
av_get_channel_layout_string(buf1, sizeof(buf1), -1, is->audio_filter_src.channel_layout); |
|
|
|
|
av_get_channel_layout_string(buf2, sizeof(buf2), -1, dec_channel_layout); |
|
|
|
|
av_channel_layout_describe(&is->audio_filter_src.ch_layout, buf1, sizeof(buf1)); |
|
|
|
|
av_channel_layout_describe(&frame->ch_layout, buf2, sizeof(buf2)); |
|
|
|
|
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", |
|
|
|
|
is->audio_filter_src.freq, is->audio_filter_src.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); |
|
|
|
|
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->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.channels = frame->channels; |
|
|
|
|
is->audio_filter_src.channel_layout = dec_channel_layout; |
|
|
|
|
ret = av_channel_layout_copy(&is->audio_filter_src.ch_layout, &frame->ch_layout); |
|
|
|
|
if (ret < 0) |
|
|
|
|
goto the_end; |
|
|
|
|
is->audio_filter_src.freq = frame->sample_rate; |
|
|
|
|
last_serial = is->auddec.pkt_serial; |
|
|
|
|
|
|
|
|
@ -2337,7 +2322,6 @@ static int synchronize_audio(VideoState *is, int nb_samples) |
|
|
|
|
static int audio_decode_frame(VideoState *is) |
|
|
|
|
{ |
|
|
|
|
int data_size, resampled_data_size; |
|
|
|
|
int64_t dec_channel_layout; |
|
|
|
|
av_unused double audio_clock0; |
|
|
|
|
int wanted_nb_samples; |
|
|
|
|
Frame *af; |
|
|
|
@ -2358,34 +2342,31 @@ static int audio_decode_frame(VideoState *is) |
|
|
|
|
frame_queue_next(&is->sampq); |
|
|
|
|
} 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->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); |
|
|
|
|
|
|
|
|
|
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 || |
|
|
|
|
(wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) { |
|
|
|
|
swr_free(&is->swr_ctx); |
|
|
|
|
is->swr_ctx = swr_alloc_set_opts(NULL, |
|
|
|
|
is->audio_tgt.channel_layout, is->audio_tgt.fmt, is->audio_tgt.freq, |
|
|
|
|
dec_channel_layout, af->frame->format, af->frame->sample_rate, |
|
|
|
|
0, NULL); |
|
|
|
|
swr_alloc_set_opts2(&is->swr_ctx, |
|
|
|
|
&is->audio_tgt.ch_layout, is->audio_tgt.fmt, is->audio_tgt.freq, |
|
|
|
|
&af->frame->ch_layout, af->frame->format, af->frame->sample_rate, |
|
|
|
|
0, NULL); |
|
|
|
|
if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) { |
|
|
|
|
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", |
|
|
|
|
af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), af->frame->channels, |
|
|
|
|
is->audio_tgt.freq, av_get_sample_fmt_name(is->audio_tgt.fmt), is->audio_tgt.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.ch_layout.nb_channels); |
|
|
|
|
swr_free(&is->swr_ctx); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
is->audio_src.channel_layout = dec_channel_layout; |
|
|
|
|
is->audio_src.channels = af->frame->channels; |
|
|
|
|
if (av_channel_layout_copy(&is->audio_src.ch_layout, &af->frame->ch_layout) < 0) |
|
|
|
|
return -1; |
|
|
|
|
is->audio_src.freq = af->frame->sample_rate; |
|
|
|
|
is->audio_src.fmt = af->frame->format; |
|
|
|
|
} |
|
|
|
@ -2394,7 +2375,7 @@ static int audio_decode_frame(VideoState *is) |
|
|
|
|
const uint8_t **in = (const uint8_t **)af->frame->extended_data; |
|
|
|
|
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_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; |
|
|
|
|
if (out_size < 0) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size() failed\n"); |
|
|
|
@ -2421,7 +2402,7 @@ static int audio_decode_frame(VideoState *is) |
|
|
|
|
swr_free(&is->swr_ctx); |
|
|
|
|
} |
|
|
|
|
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 { |
|
|
|
|
is->audio_buf = af->frame->data[0]; |
|
|
|
|
resampled_data_size = data_size; |
|
|
|
@ -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; |
|
|
|
|
const char *env; |
|
|
|
|
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}; |
|
|
|
|
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"); |
|
|
|
|
if (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)) { |
|
|
|
|
wanted_channel_layout = av_get_default_channel_layout(wanted_nb_channels); |
|
|
|
|
wanted_channel_layout &= ~AV_CH_LAYOUT_STEREO_DOWNMIX; |
|
|
|
|
if (wanted_channel_layout->order != AV_CHANNEL_ORDER_NATIVE) { |
|
|
|
|
av_channel_layout_uninit(wanted_channel_layout); |
|
|
|
|
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.freq = wanted_sample_rate; |
|
|
|
|
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 |
|
|
|
|
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) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, |
|
|
|
@ -2542,8 +2525,9 @@ static int audio_open(void *opaque, int64_t wanted_channel_layout, int wanted_nb |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
if (spec.channels != wanted_spec.channels) { |
|
|
|
|
wanted_channel_layout = av_get_default_channel_layout(spec.channels); |
|
|
|
|
if (!wanted_channel_layout) { |
|
|
|
|
av_channel_layout_uninit(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, |
|
|
|
|
"SDL advised channel count %d is not supported!\n", spec.channels); |
|
|
|
|
return -1; |
|
|
|
@ -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->freq = spec.freq; |
|
|
|
|
audio_hw_params->channel_layout = wanted_channel_layout; |
|
|
|
|
audio_hw_params->channels = spec.channels; |
|
|
|
|
audio_hw_params->frame_size = av_samples_get_buffer_size(NULL, audio_hw_params->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); |
|
|
|
|
if (av_channel_layout_copy(&audio_hw_params->ch_layout, wanted_channel_layout) < 0) |
|
|
|
|
return -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->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) { |
|
|
|
|
av_log(NULL, AV_LOG_ERROR, "av_samples_get_buffer_size failed\n"); |
|
|
|
|
return -1; |
|
|
|
@ -2572,8 +2556,8 @@ static int stream_component_open(VideoState *is, int stream_index) |
|
|
|
|
const char *forced_codec_name = NULL; |
|
|
|
|
AVDictionary *opts = NULL; |
|
|
|
|
const AVDictionaryEntry *t = NULL; |
|
|
|
|
int sample_rate, nb_channels; |
|
|
|
|
int64_t channel_layout; |
|
|
|
|
int sample_rate; |
|
|
|
|
AVChannelLayout ch_layout = { 0 }; |
|
|
|
|
int ret = 0; |
|
|
|
|
int stream_lowres = lowres; |
|
|
|
|
|
|
|
|
@ -2641,24 +2625,27 @@ static int stream_component_open(VideoState *is, int stream_index) |
|
|
|
|
AVFilterContext *sink; |
|
|
|
|
|
|
|
|
|
is->audio_filter_src.freq = avctx->sample_rate; |
|
|
|
|
is->audio_filter_src.channels = avctx->channels; |
|
|
|
|
is->audio_filter_src.channel_layout = get_valid_channel_layout(avctx->channel_layout, avctx->channels); |
|
|
|
|
ret = av_channel_layout_copy(&is->audio_filter_src.ch_layout, &avctx->ch_layout); |
|
|
|
|
if (ret < 0) |
|
|
|
|
goto fail; |
|
|
|
|
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); |
|
|
|
|
nb_channels = av_buffersink_get_channels(sink); |
|
|
|
|
channel_layout = av_buffersink_get_channel_layout(sink); |
|
|
|
|
ret = av_buffersink_get_ch_layout(sink, &ch_layout); |
|
|
|
|
if (ret < 0) |
|
|
|
|
goto fail; |
|
|
|
|
} |
|
|
|
|
#else |
|
|
|
|
sample_rate = avctx->sample_rate; |
|
|
|
|
nb_channels = avctx->channels; |
|
|
|
|
channel_layout = avctx->channel_layout; |
|
|
|
|
ret = av_channel_layout_copy(&ch_layout, &avctx->ch_layout); |
|
|
|
|
if (ret < 0) |
|
|
|
|
goto fail; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
/* 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; |
|
|
|
|
is->audio_hw_buf_size = ret; |
|
|
|
|
is->audio_src = is->audio_tgt; |
|
|
|
@ -2712,6 +2699,7 @@ 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; |
|
|
|
@ -3184,7 +3172,7 @@ static void stream_cycle_channel(VideoState *is, int codec_type) |
|
|
|
|
switch (codec_type) { |
|
|
|
|
case AVMEDIA_TYPE_AUDIO: |
|
|
|
|
if (st->codecpar->sample_rate != 0 && |
|
|
|
|
st->codecpar->channels != 0) |
|
|
|
|
st->codecpar->ch_layout.nb_channels != 0) |
|
|
|
|
goto the_end; |
|
|
|
|
break; |
|
|
|
|
case AVMEDIA_TYPE_VIDEO: |
|
|
|
|