Signed-off-by: Vittorio Giovara <vittorio.giov...@gmail.com> --- 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; +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. + */ + 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 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; +FF_ENABLE_DEPRECATION_WARNINGS +#endif link->sample_rate = c->sample_rate; break; default: diff --git a/libavfilter/buffersrc.h b/libavfilter/buffersrc.h index dcea3da79b..ac1631cdff 100644 --- a/libavfilter/buffersrc.h +++ b/libavfilter/buffersrc.h @@ -25,6 +25,8 @@ * Memory buffer source API. */ +#include "libavutil/channel_layout.h" + #include "avfilter.h" /** @@ -80,10 +82,18 @@ typedef struct AVBufferSrcParameters { */ int sample_rate; +#if FF_API_OLD_CHANNEL_LAYOUT /** - * Audio only, the audio channel layout + * @deprecated use ch_layout instead */ + attribute_deprecated uint64_t channel_layout; +#endif + + /** + * Audio only, the audio channel layout + */ + AVChannelLayout ch_layout; } AVBufferSrcParameters; /** diff --git a/libavfilter/fifo.c b/libavfilter/fifo.c index a414585ece..85730cccd7 100644 --- a/libavfilter/fifo.c +++ b/libavfilter/fifo.c @@ -104,7 +104,7 @@ static void queue_pop(FifoContext *s) static void buffer_offset(AVFilterLink *link, AVFrame *frame, int offset) { - int nb_channels = av_get_channel_layout_nb_channels(link->channel_layout); + int nb_channels = link->ch_layout.nb_channels; int planar = av_sample_fmt_is_planar(link->format); int planes = planar ? nb_channels : 1; int block_align = av_get_bytes_per_sample(link->format) * (planar ? 1 : nb_channels); @@ -128,8 +128,7 @@ static void buffer_offset(AVFilterLink *link, AVFrame *frame, static int calc_ptr_alignment(AVFrame *frame) { - int planes = av_sample_fmt_is_planar(frame->format) ? - av_get_channel_layout_nb_channels(frame->channel_layout) : 1; + int planes = av_sample_fmt_is_planar(frame->format) ? frame->ch_layout.nb_channels : 1; int min_align = 128; int p; @@ -170,7 +169,7 @@ static int return_audio_frame(AVFilterContext *ctx) buffer_offset(link, head, link->request_samples); } } else { - int nb_channels = av_get_channel_layout_nb_channels(link->channel_layout); + int nb_channels = link->ch_layout.nb_channels; if (!s->out) { s->out = ff_get_audio_buffer(link, link->request_samples); -- 2.13.1 _______________________________________________ libav-devel mailing list libav-devel@libav.org https://lists.libav.org/mailman/listinfo/libav-devel