Quoting Vittorio Giovara (2017-06-29 00:10:51)
> Signed-off-by: Vittorio Giovara <[email protected]>
> ---
> libavfilter/audio.c | 17 +++++++++++++--
> libavfilter/avfilter.c | 9 ++++----
> libavfilter/avfilter.h | 13 ++++++++++-
> libavfilter/avfiltergraph.c | 35 +++++++++++++++++++++++-------
> libavfilter/buffersink.c | 2 +-
> libavfilter/buffersrc.c | 53
> ++++++++++++++++++++++++++++-----------------
> libavfilter/buffersrc.h | 12 +++++++++-
> libavfilter/fifo.c | 7 +++---
> 8 files changed, 106 insertions(+), 42 deletions(-)
>
> diff --git a/libavfilter/audio.c b/libavfilter/audio.c
> index 5fe9da95c3..afd8bdc169 100644
> --- a/libavfilter/audio.c
> +++ b/libavfilter/audio.c
> @@ -31,7 +31,7 @@ AVFrame *ff_null_get_audio_buffer(AVFilterLink *link, int
> nb_samples)
> AVFrame *ff_default_get_audio_buffer(AVFilterLink *link, int nb_samples)
> {
> AVFrame *frame = av_frame_alloc();
> - int channels = av_get_channel_layout_nb_channels(link->channel_layout);
> + int channels = link->ch_layout.nb_channels;
> int ret;
>
> if (!frame)
> @@ -39,7 +39,20 @@ AVFrame *ff_default_get_audio_buffer(AVFilterLink *link,
> int nb_samples)
>
> frame->nb_samples = nb_samples;
> frame->format = link->format;
> - frame->channel_layout = link->channel_layout;
> +
> + ret = av_channel_layout_copy(&frame->ch_layout, &link->ch_layout);
> + if (ret < 0) {
> + av_frame_free(&frame);
> + return NULL;
> + }
> +#if FF_API_OLD_CHANNEL_LAYOUT
> +FF_DISABLE_DEPRECATION_WARNINGS
> + if (link->ch_layout.order == AV_CHANNEL_ORDER_NATIVE ||
> + link->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
> + frame->channel_layout = link->channel_layout;
This is incomplete, the channel layout should always be set, at least to
(1<<count) - 1.
> +FF_ENABLE_DEPRECATION_WARNINGS
> +#endif
> +
> frame->sample_rate = link->sample_rate;
> ret = av_frame_get_buffer(frame, 0);
> if (ret < 0) {
> diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
> index 83c1a7c20d..f2adefff3d 100644
> --- a/libavfilter/avfilter.c
> +++ b/libavfilter/avfilter.c
> @@ -247,16 +247,15 @@ void ff_dlog_link(void *ctx, AVFilterLink *link, int
> end)
> link->dst ? link->dst->filter->name : "",
> end ? "\n" : "");
> } else {
> - char buf[128];
> - av_get_channel_layout_string(buf, sizeof(buf), -1,
> link->channel_layout);
> -
> + char *chlstr = av_channel_layout_describe(&link->ch_layout);
> av_log(ctx, AV_LOG_TRACE,
> "link[%p r:%d cl:%s fmt:%-16s %-16s->%-16s]%s",
> - link, link->sample_rate, buf,
> + link, link->sample_rate, chlstr,
> av_get_sample_fmt_name(link->format),
> link->src ? link->src->filter->name : "",
> link->dst ? link->dst->filter->name : "",
> end ? "\n" : "");
> + av_free(chlstr);
> }
> }
>
> @@ -683,7 +682,7 @@ int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
> case AVMEDIA_TYPE_AUDIO:
> av_samples_copy(out->extended_data, frame->extended_data,
> 0, 0, frame->nb_samples,
> -
> av_get_channel_layout_nb_channels(frame->channel_layout),
> + frame->ch_layout.nb_channels,
> frame->format);
> break;
> default:
> diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h
> index 6df69dbbbf..5d5edf0ed3 100644
> --- a/libavfilter/avfilter.h
> +++ b/libavfilter/avfilter.h
> @@ -36,6 +36,7 @@
> #include "libavutil/attributes.h"
> #include "libavutil/avutil.h"
> #include "libavutil/buffer.h"
> +#include "libavutil/channel_layout.h"
> #include "libavutil/frame.h"
> #include "libavutil/log.h"
> #include "libavutil/samplefmt.h"
> @@ -334,7 +335,12 @@ struct AVFilterLink {
> int h; ///< agreed upon image height
> AVRational sample_aspect_ratio; ///< agreed upon sample aspect ratio
> /* These two parameters apply only to audio */
> - uint64_t channel_layout; ///< channel layout of current buffer (see
> libavutil/channel_layout.h)
> +#if FF_API_OLD_CHANNEL_LAYOUT
> + /**
> + * @deprecated use ch_layout instead
> + */
> + attribute_deprecated uint64_t channel_layout;
> +#endif
> int sample_rate; ///< samples per second
>
> int format; ///< agreed upon media format
> @@ -405,6 +411,11 @@ struct AVFilterLink {
> * AVHWFramesContext describing the frames.
> */
> AVBufferRef *hw_frames_ctx;
> +
> + /**
> + * Channel layout of current buffer.
What 'current buffer' is this talking about?
> + */
> + AVChannelLayout ch_layout;
> };
>
> /**
> diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
> index a0f797e283..c72016d2c8 100644
> --- a/libavfilter/avfiltergraph.c
> +++ b/libavfilter/avfiltergraph.c
> @@ -397,7 +397,13 @@ static int pick_format(AVFilterLink *link)
> return AVERROR(EINVAL);
> }
> link->in_channel_layouts->nb_channel_layouts = 1;
> +#if FF_API_OLD_CHANNEL_LAYOUT
> +FF_DISABLE_DEPRECATION_WARNINGS
> link->channel_layout = link->in_channel_layouts->channel_layouts[0];
> +FF_ENABLE_DEPRECATION_WARNINGS
> +#endif
> + av_channel_layout_from_mask(&link->ch_layout,
> +
> link->in_channel_layouts->channel_layouts[0]);
> }
>
> ff_formats_unref(&link->in_formats);
> @@ -578,23 +584,33 @@ static void
> swap_channel_layouts_on_filter(AVFilterContext *filter)
> for (j = 0; j < outlink->in_channel_layouts->nb_channel_layouts;
> j++) {
> uint64_t in_chlayout =
> link->out_channel_layouts->channel_layouts[0];
> uint64_t out_chlayout =
> outlink->in_channel_layouts->channel_layouts[j];
> - int in_channels =
> av_get_channel_layout_nb_channels(in_chlayout);
> - int out_channels =
> av_get_channel_layout_nb_channels(out_chlayout);
> - int count_diff = out_channels - in_channels;
> + int in_channels;
> + int out_channels;
> + int count_diff;
> int matched_channels, extra_channels;
> int score = 0;
> + AVChannelLayout in_ch_layout = {0};
> + AVChannelLayout out_ch_layout = {0};
> +
> + av_channel_layout_from_mask( &in_ch_layout, in_chlayout);
> + av_channel_layout_from_mask(&out_ch_layout, out_chlayout);
> + in_channels = in_ch_layout.nb_channels;
> + out_channels = out_ch_layout.nb_channels;
> + count_diff = out_channels - in_channels;
>
> /* channel substitution */
> for (k = 0; k < FF_ARRAY_ELEMS(ch_subst); k++) {
> uint64_t cmp0 = ch_subst[k][0];
> uint64_t cmp1 = ch_subst[k][1];
> + AVChannelLayout tmp = {0};
> if (( in_chlayout & cmp0) && (!(out_chlayout & cmp0)) &&
> (out_chlayout & cmp1) && (!( in_chlayout & cmp1))) {
> in_chlayout &= ~cmp0;
> out_chlayout &= ~cmp1;
> /* add score for channel match, minus a deduction for
> having to do the substitution */
> - score += 10 * av_get_channel_layout_nb_channels(cmp1) -
> 2;
> + av_channel_layout_from_mask(&tmp, cmp1);
> + score += 10 * tmp.nb_channels - 2;
> }
> }
>
> @@ -605,10 +621,13 @@ static void
> swap_channel_layouts_on_filter(AVFilterContext *filter)
> in_chlayout &= ~AV_CH_LOW_FREQUENCY;
> out_chlayout &= ~AV_CH_LOW_FREQUENCY;
>
> - matched_channels = av_get_channel_layout_nb_channels(in_chlayout
> &
> -
> out_chlayout);
> - extra_channels =
> av_get_channel_layout_nb_channels(out_chlayout &
> -
> (~in_chlayout));
> + av_channel_layout_uninit( &in_ch_layout);
> + av_channel_layout_uninit(&out_ch_layout);
> + av_channel_layout_from_mask( &in_ch_layout, in_chlayout &
> out_chlayout);
> + av_channel_layout_from_mask(&out_ch_layout, out_chlayout &
> (~in_chlayout));
> +
> + matched_channels = in_ch_layout.nb_channels;
> + extra_channels = out_ch_layout.nb_channels;
> score += 10 * matched_channels - 5 * extra_channels;
>
> if (score > best_score ||
> diff --git a/libavfilter/buffersink.c b/libavfilter/buffersink.c
> index 3b4d285ffd..1c2d912ad4 100644
> --- a/libavfilter/buffersink.c
> +++ b/libavfilter/buffersink.c
> @@ -107,7 +107,7 @@ int attribute_align_arg
> av_buffersink_get_samples(AVFilterContext *ctx,
> int ret = 0;
>
> if (!s->audio_fifo) {
> - int nb_channels =
> av_get_channel_layout_nb_channels(link->channel_layout);
> + int nb_channels = link->ch_layout.nb_channels;
> if (!(s->audio_fifo = av_audio_fifo_alloc(link->format, nb_channels,
> nb_samples)))
> return AVERROR(ENOMEM);
> }
> diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c
> index df00971514..838e3ac08d 100644
> --- a/libavfilter/buffersrc.c
> +++ b/libavfilter/buffersrc.c
> @@ -58,8 +58,7 @@ typedef struct BufferSourceContext {
> int sample_rate;
> enum AVSampleFormat sample_fmt;
> char *sample_fmt_str;
> - uint64_t channel_layout;
> - char *channel_layout_str;
> + AVChannelLayout ch_layout;
>
> int got_format_from_params;
> int eof;
> @@ -71,9 +70,9 @@ typedef struct BufferSourceContext {
> return AVERROR(EINVAL);\
> }
>
> -#define CHECK_AUDIO_PARAM_CHANGE(s, c, srate, ch_layout, format)\
> +#define CHECK_AUDIO_PARAM_CHANGE(s, c, srate, chlayout, format)\
> if (c->sample_fmt != format || c->sample_rate != srate ||\
> - c->channel_layout != ch_layout) {\
> + av_channel_layout_compare(&c->ch_layout, &chlayout)) {\
> av_log(s, AV_LOG_ERROR, "Changing frame properties on the fly is not
> supported.\n");\
> return AVERROR(EINVAL);\
> }
> @@ -92,6 +91,7 @@ AVBufferSrcParameters *av_buffersrc_parameters_alloc(void)
> int av_buffersrc_parameters_set(AVFilterContext *ctx, AVBufferSrcParameters
> *param)
> {
> BufferSourceContext *s = ctx->priv;
> + int ret;
>
> if (param->time_base.num > 0 && param->time_base.den > 0)
> s->time_base = param->time_base;
> @@ -124,8 +124,17 @@ int av_buffersrc_parameters_set(AVFilterContext *ctx,
> AVBufferSrcParameters *par
> }
> if (param->sample_rate > 0)
> s->sample_rate = param->sample_rate;
> - if (param->channel_layout)
> - s->channel_layout = param->channel_layout;
> +
> + ret = av_channel_layout_copy(&s->ch_layout, ¶m->ch_layout);
> + if (ret < 0)
> + return ret;
> +
> +#if FF_API_OLD_CHANNEL_LAYOUT
> +FF_DISABLE_DEPRECATION_WARNINGS
> + if (!av_channel_layout_check(&s->ch_layout))
> + av_channel_layout_from_mask(&s->ch_layout,
> param->channel_layout);
> +FF_ENABLE_DEPRECATION_WARNINGS
> +#endif
I think it would be more consistent to always prefer the deprecated
channel_layout if it is set.
> break;
> default:
> return AVERROR_BUG;
> @@ -170,7 +179,7 @@ int attribute_align_arg
> av_buffersrc_add_frame(AVFilterContext *ctx,
> frame->format);
> break;
> case AVMEDIA_TYPE_AUDIO:
> - CHECK_AUDIO_PARAM_CHANGE(ctx, s, frame->sample_rate,
> frame->channel_layout,
> + CHECK_AUDIO_PARAM_CHANGE(ctx, s, frame->sample_rate,
> frame->ch_layout,
> frame->format);
> break;
> default:
> @@ -261,7 +270,7 @@ static const AVOption audio_options[] = {
> { "time_base", NULL, OFFSET(time_base),
> AV_OPT_TYPE_RATIONAL, { .dbl = 0 }, 0, INT_MAX, A },
> { "sample_rate", NULL, OFFSET(sample_rate), AV_OPT_TYPE_INT,
> { .i64 = 0 }, 0, INT_MAX, A },
> { "sample_fmt", NULL, OFFSET(sample_fmt_str),
> AV_OPT_TYPE_STRING, .flags = A },
> - { "channel_layout", NULL, OFFSET(channel_layout_str),
> AV_OPT_TYPE_STRING, .flags = A },
> + { "channel_layout", NULL, OFFSET(ch_layout),
> AV_OPT_TYPE_CHANNEL_LAYOUT, .flags = A },
> { NULL },
> };
>
> @@ -275,6 +284,7 @@ static const AVClass abuffer_class = {
> static av_cold int init_audio(AVFilterContext *ctx)
> {
> BufferSourceContext *s = ctx->priv;
> + char *chlstr;
> int ret = 0;
>
> if (!(s->sample_fmt_str || s->got_format_from_params)) {
> @@ -290,24 +300,17 @@ static av_cold int init_audio(AVFilterContext *ctx)
> return AVERROR(EINVAL);
> }
>
> - if (s->channel_layout_str)
> - s->channel_layout = av_get_channel_layout(s->channel_layout_str);
> -
> - if (!s->channel_layout) {
> - av_log(ctx, AV_LOG_ERROR, "Invalid channel layout %s.\n",
> - s->channel_layout_str);
> - return AVERROR(EINVAL);
> - }
> -
> if (!(s->fifo = av_fifo_alloc(sizeof(AVFrame*))))
> return AVERROR(ENOMEM);
>
> if (!s->time_base.num)
> s->time_base = (AVRational){1, s->sample_rate};
>
> + chlstr = av_channel_layout_describe(&s->ch_layout);
> av_log(ctx, AV_LOG_VERBOSE, "tb:%d/%d samplefmt:%s samplerate: %d "
> "ch layout:%s\n", s->time_base.num, s->time_base.den,
> s->sample_fmt_str,
> - s->sample_rate, s->channel_layout_str);
> + s->sample_rate, chlstr);
> + av_free(chlstr);
>
> return ret;
> }
> @@ -344,7 +347,7 @@ static int query_formats(AVFilterContext *ctx)
> ff_add_format(&samplerates, c->sample_rate);
> ff_set_common_samplerates(ctx, samplerates);
>
> - ff_add_channel_layout(&channel_layouts, c->channel_layout);
> + ff_add_channel_layout(&channel_layouts, c->ch_layout.u.mask);
> ff_set_common_channel_layouts(ctx, channel_layouts);
> break;
> default:
> @@ -357,6 +360,7 @@ static int query_formats(AVFilterContext *ctx)
> static int config_props(AVFilterLink *link)
> {
> BufferSourceContext *c = link->src->priv;
> + int ret;
>
> switch (link->type) {
> case AVMEDIA_TYPE_VIDEO:
> @@ -371,7 +375,16 @@ static int config_props(AVFilterLink *link)
> }
> break;
> case AVMEDIA_TYPE_AUDIO:
> - link->channel_layout = c->channel_layout;
> + ret = av_channel_layout_copy(&link->ch_layout, &c->ch_layout);
> + if (ret < 0)
> + return ret;
> +#if FF_API_OLD_CHANNEL_LAYOUT
> +FF_DISABLE_DEPRECATION_WARNINGS
> + if (c->ch_layout.order == AV_CHANNEL_ORDER_NATIVE ||
> + c->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
> + link->channel_layout = c->ch_layout.u.mask;
Same as above.
--
Anton Khirnov
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel