[FFmpeg-devel] [PATCH 001/279 v2] Add a new channel layout API
James Almer
jamrial at gmail.com
Fri Dec 17 14:43:33 EET 2021
On 12/16/2021 8:27 PM, Marton Balint wrote:
>
>
> On Thu, 16 Dec 2021, James Almer wrote:
>
>> - Added a 16 byte fixed array to AVChannelCustom to give custom
>> labels to channels in Custom order layouts. These labes will
>> be used by the helpers when querying channels by name or
>> describing the layout.
>
> I don't think this is a good idea to use the labels directly in helpers
> instead of the channel designation names. See more below.
>
> It is also not great that if the user wants to label a channel, he has
> to use a custom layout. So I'd rather remove the name field from
> AVChannelCustom, I find it limited anyway.
>
> [..]
>
>> +enum AVChannel av_channel_from_string(const char *str)
>> +{
>> + int i;
>> + char *endptr = (char *)str;
>> + enum AVChannel id = AV_CHAN_NONE;
>> + for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++) {
>> + if (channel_names[i].name && !strcmp(str,
>> channel_names[i].name))
>> + return i;
>> + }
>> + if (!strncmp(str, "USR", 3)) {
>> + const char *p = str + 3;
>> + id = strtol(p, &endptr, 0);
>> + }
>> + if (id > 0 && !*endptr)
>
> id >= 0
>
> [..]
>
>
>> +int av_channel_layout_from_mask(AVChannelLayout *channel_layout,
>> + uint64_t mask)
>> +{
>> + if (!mask)
>> + return AVERROR(EINVAL);
>> +
>> + channel_layout->order = AV_CHANNEL_ORDER_NATIVE;
>> + channel_layout->nb_channels = av_popcount64(mask);
>> + channel_layout->u.mask = mask;
>> +
>> + return 0;
>> +}
>
> Probably a constructor for custom layout would also make sense:
>
> int av_channel_layout_custom(AVChannelLayout *channel_layout, int
> nb_channels)
Doesn't seem too useful to me. It will basically just call av_malloc for
u.map for you. You still need to fill the array with the channels in the
order you want it, unlike av_channel_layout_from_mask() which gives you
a usable layout directly on return.
You can use av_channel_layout_from_string() for this instead, thanks to
your suggestion to use generic USR%d designations for no-name ids. In
the tests from patch 2 i have a couple examples of it.
>
> [...]
>
>> +
>> +int av_channel_layout_copy(AVChannelLayout *dst, const
>> AVChannelLayout *src)
>> +{
>> + av_channel_layout_uninit(dst);
>> + *dst = *src;
>> + if (src->order == AV_CHANNEL_ORDER_CUSTOM) {
>> + dst->u.map = av_malloc(src->nb_channels * sizeof(*dst->u.map));
>
> av_malloc_array()
>
>> +int av_channel_layout_describe_bprint(const AVChannelLayout
>> *channel_layout,
>> + AVBPrint *bp)
>> +{
>> + int i;
>> +
>> + av_bprint_clear(bp);
>> +
>> + switch (channel_layout->order) {
>> + case AV_CHANNEL_ORDER_NATIVE:
>> + for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++)
>> + if (channel_layout->u.mask ==
>> channel_layout_map[i].layout.u.mask) {
>> + av_bprintf(bp, "%s", channel_layout_map[i].name);
>> + return 0;
>> + }
>> + // fall-through
>> + case AV_CHANNEL_ORDER_CUSTOM:
>> + for (i = 0; i < channel_layout->nb_channels; i++) {
>> + const char *ch_name = NULL;
>> + enum AVChannel ch = AV_CHAN_NONE;
>> +
>> + if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM &&
>> + channel_layout->u.map[i].name[0])
>> + ch_name = channel_layout->u.map[i].name;
>> + if (channel_layout->order == AV_CHANNEL_ORDER_NATIVE ||
>> !ch_name) {
>> + ch =
>> av_channel_layout_channel_from_index(channel_layout, i);
>> + ch_name = get_channel_name(ch);
>> + }
>
> You are mixing channel labels and channel designations, and it can be
> the source of confusion. I guess the main problem is that the label of
> the channel can be totally unrelated to the channel designation.
>
> You could show it as some combination. E.g. FL at label. This way there
> will be no confusion, that part before @ is the designation, part after
> the @ is the channel label.
>
> [..]
>
>> +enum AVChannel
>> +av_channel_layout_channel_from_string(const AVChannelLayout
>> *channel_layout,
>> + const char *name)
>> +{
>> + int channel, ret;
>> +
>> + switch (channel_layout->order) {
>> + case AV_CHANNEL_ORDER_CUSTOM:
>> + for (int i = 0; i < channel_layout->nb_channels; i++) {
>> + if (channel_layout->u.map[i].name[0] && !strcmp(name,
>> channel_layout->u.map[i].name))
>> + return channel_layout->u.map[i].id;
>
> This is the reverse case, I also find it confusing that name can be a
> label and a designation at the same time and it depends on the channel
> layout type which one is it... Yet again, some syntax could help. E.g. a
> string without @ is a designation, @label is a label without any filter
> for channel designation, designation at label filters both.
>
> [..]
>
>> +int av_channel_layout_index_from_string(const AVChannelLayout
>> *channel_layout,
>> + const char *name)
>> +{
>> + enum AVChannel ch;
>> +
>> + switch (channel_layout->order) {
>> + case AV_CHANNEL_ORDER_CUSTOM:
>> + for (int i = 0; i < channel_layout->nb_channels; i++) {
>> + if (channel_layout->u.map[i].name[0] && !strcmp(name,
>> channel_layout->u.map[i].name))
>> + return i;
>
> Same here.
>
> [..]
>
>> +int av_channel_layout_check(const AVChannelLayout *channel_layout)
>
> av_channel_layout_valid would be more readable.
>
> Thanks,
> Marton
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".
More information about the ffmpeg-devel
mailing list