Message ID | 20220315203013.14304-2-cus@passwd.hu |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel,1/4] avutil/channel_layout: print channels using av_channel_name_bprint in av_channel_layout_describe_bprint | expand |
Context | Check | Description |
---|---|---|
yinshiyou/make_loongarch64 | success | Make finished |
yinshiyou/make_fate_loongarch64 | success | Make fate finished |
andriy/make_x86 | success | Make finished |
andriy/make_fate_x86 | success | Make fate finished |
On 3/15/2022 5:30 PM, Marton Balint wrote: > Signed-off-by: Marton Balint <cus@passwd.hu> > --- > libavutil/channel_layout.c | 40 ++++++++++++++++++++++++++------------ > 1 file changed, 28 insertions(+), 12 deletions(-) > > diff --git a/libavutil/channel_layout.c b/libavutil/channel_layout.c > index c60ccf368f..fb2335a334 100644 > --- a/libavutil/channel_layout.c > +++ b/libavutil/channel_layout.c > @@ -644,29 +644,29 @@ int av_channel_layout_copy(AVChannelLayout *dst, const AVChannelLayout *src) > } > > /** > - * If the custom layout is n-th order standard-order ambisonic, with optional > - * extra non-diegetic channels at the end, write its string description in bp. > - * Return a negative error code on error. > + * If the layout is n-th order standard-order ambisonic, with optional > + * extra non-diegetic channels at the end, return the order. > + * Return a negative error code otherwise. > */ > -static int try_describe_ambisonic(AVBPrint *bp, const AVChannelLayout *channel_layout) > +static int ambisonic_order(const AVChannelLayout *channel_layout) > { > int i, highest_ambi, order; > > highest_ambi = -1; > - if (channel_layout->order == AV_CHANNEL_ORDER_AMBISONIC) > + if (channel_layout->order == AV_CHANNEL_ORDER_AMBISONIC) { > highest_ambi = channel_layout->nb_channels - av_popcount64(channel_layout->u.mask) - 1; > - else { > + } else if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM) { It's not called for any other order, so this is not needed. Maybe add an av_assert0() instead. > const AVChannelCustom *map = channel_layout->u.map; > for (i = 0; i < channel_layout->nb_channels; i++) { > int is_ambi = CHAN_IS_AMBI(map[i].id); > > /* ambisonic following non-ambisonic */ > if (i > 0 && is_ambi && !CHAN_IS_AMBI(map[i - 1].id)) > - return 0; > + return AVERROR(EINVAL); > > /* non-default ordering */ > if (is_ambi && map[i].id - AV_CHAN_AMBISONIC_BASE != i) > - return 0; > + return AVERROR(EINVAL); > > if (CHAN_IS_AMBI(map[i].id)) > highest_ambi = i; > @@ -674,17 +674,33 @@ static int try_describe_ambisonic(AVBPrint *bp, const AVChannelLayout *channel_l > } > /* no ambisonic channels*/ > if (highest_ambi < 0) > - return 0; > + return AVERROR(EINVAL); > > order = floor(sqrt(highest_ambi)); > /* incomplete order - some harmonics are missing */ > if ((order + 1) * (order + 1) != highest_ambi + 1) > + return AVERROR(EINVAL); > + > + return order; > +} > + > +/** > + * If the custom layout is n-th order standard-order ambisonic, with optional > + * extra non-diegetic channels at the end, write its string description in bp. > + * Return a negative error code on error. > + */ > +static int try_describe_ambisonic(AVBPrint *bp, const AVChannelLayout *channel_layout) > +{ > + int nb_ambi_channels; > + int order = ambisonic_order(channel_layout); > + if (order < 0) > return 0; > > av_bprintf(bp, "ambisonic %d", order); > > /* extra channels present */ > - if (highest_ambi < channel_layout->nb_channels - 1) { > + nb_ambi_channels = (order + 1) * (order + 1); > + if (nb_ambi_channels < channel_layout->nb_channels) { > AVChannelLayout extra = { 0 }; > char buf[128]; > > @@ -696,12 +712,12 @@ static int try_describe_ambisonic(AVBPrint *bp, const AVChannelLayout *channel_l > const AVChannelCustom *map = channel_layout->u.map; > > extra.order = AV_CHANNEL_ORDER_CUSTOM; > - extra.nb_channels = channel_layout->nb_channels - highest_ambi - 1; > + extra.nb_channels = channel_layout->nb_channels - nb_ambi_channels; > extra.u.map = av_calloc(extra.nb_channels, sizeof(*extra.u.map)); > if (!extra.u.map) > return AVERROR(ENOMEM); > > - memcpy(extra.u.map, &map[highest_ambi + 1], > + memcpy(extra.u.map, &map[nb_ambi_channels], > sizeof(*extra.u.map) * extra.nb_channels); > } Should be ok.
diff --git a/libavutil/channel_layout.c b/libavutil/channel_layout.c index c60ccf368f..fb2335a334 100644 --- a/libavutil/channel_layout.c +++ b/libavutil/channel_layout.c @@ -644,29 +644,29 @@ int av_channel_layout_copy(AVChannelLayout *dst, const AVChannelLayout *src) } /** - * If the custom layout is n-th order standard-order ambisonic, with optional - * extra non-diegetic channels at the end, write its string description in bp. - * Return a negative error code on error. + * If the layout is n-th order standard-order ambisonic, with optional + * extra non-diegetic channels at the end, return the order. + * Return a negative error code otherwise. */ -static int try_describe_ambisonic(AVBPrint *bp, const AVChannelLayout *channel_layout) +static int ambisonic_order(const AVChannelLayout *channel_layout) { int i, highest_ambi, order; highest_ambi = -1; - if (channel_layout->order == AV_CHANNEL_ORDER_AMBISONIC) + if (channel_layout->order == AV_CHANNEL_ORDER_AMBISONIC) { highest_ambi = channel_layout->nb_channels - av_popcount64(channel_layout->u.mask) - 1; - else { + } else if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM) { const AVChannelCustom *map = channel_layout->u.map; for (i = 0; i < channel_layout->nb_channels; i++) { int is_ambi = CHAN_IS_AMBI(map[i].id); /* ambisonic following non-ambisonic */ if (i > 0 && is_ambi && !CHAN_IS_AMBI(map[i - 1].id)) - return 0; + return AVERROR(EINVAL); /* non-default ordering */ if (is_ambi && map[i].id - AV_CHAN_AMBISONIC_BASE != i) - return 0; + return AVERROR(EINVAL); if (CHAN_IS_AMBI(map[i].id)) highest_ambi = i; @@ -674,17 +674,33 @@ static int try_describe_ambisonic(AVBPrint *bp, const AVChannelLayout *channel_l } /* no ambisonic channels*/ if (highest_ambi < 0) - return 0; + return AVERROR(EINVAL); order = floor(sqrt(highest_ambi)); /* incomplete order - some harmonics are missing */ if ((order + 1) * (order + 1) != highest_ambi + 1) + return AVERROR(EINVAL); + + return order; +} + +/** + * If the custom layout is n-th order standard-order ambisonic, with optional + * extra non-diegetic channels at the end, write its string description in bp. + * Return a negative error code on error. + */ +static int try_describe_ambisonic(AVBPrint *bp, const AVChannelLayout *channel_layout) +{ + int nb_ambi_channels; + int order = ambisonic_order(channel_layout); + if (order < 0) return 0; av_bprintf(bp, "ambisonic %d", order); /* extra channels present */ - if (highest_ambi < channel_layout->nb_channels - 1) { + nb_ambi_channels = (order + 1) * (order + 1); + if (nb_ambi_channels < channel_layout->nb_channels) { AVChannelLayout extra = { 0 }; char buf[128]; @@ -696,12 +712,12 @@ static int try_describe_ambisonic(AVBPrint *bp, const AVChannelLayout *channel_l const AVChannelCustom *map = channel_layout->u.map; extra.order = AV_CHANNEL_ORDER_CUSTOM; - extra.nb_channels = channel_layout->nb_channels - highest_ambi - 1; + extra.nb_channels = channel_layout->nb_channels - nb_ambi_channels; extra.u.map = av_calloc(extra.nb_channels, sizeof(*extra.u.map)); if (!extra.u.map) return AVERROR(ENOMEM); - memcpy(extra.u.map, &map[highest_ambi + 1], + memcpy(extra.u.map, &map[nb_ambi_channels], sizeof(*extra.u.map) * extra.nb_channels); }
Signed-off-by: Marton Balint <cus@passwd.hu> --- libavutil/channel_layout.c | 40 ++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-)