diff options
author | James Almer <jamrial@gmail.com> | 2022-01-19 18:40:42 -0300 |
---|---|---|
committer | James Almer <jamrial@gmail.com> | 2022-03-15 09:42:46 -0300 |
commit | 0995e1f1b31f6e937a1b527407ed3e850f138098 (patch) | |
tree | e35233254d3dfc6143e061ebfc1ced15544ac667 | |
parent | a8b885f2944d4fc748ca0efd8f99875950efe8aa (diff) | |
download | ffmpeg-0995e1f1b31f6e937a1b527407ed3e850f138098.tar.gz |
ffplay: convert to new channel layout-API
Signed-off-by: James Almer <jamrial@gmail.com>
-rw-r--r-- | fftools/ffplay.c | 140 |
1 files changed, 64 insertions, 76 deletions
diff --git a/fftools/ffplay.c b/fftools/ffplay.c index ac48d8765d..92ad7ce1a6 100644 --- a/fftools/ffplay.c +++ b/fftools/ffplay.c @@ -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: |