From: Marton Balint <cus@passwd.hu> To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org> Subject: Re: [FFmpeg-devel] [PATCH 001/289 v4] Add a new channel layout API Date: Mon, 17 Jan 2022 21:53:59 +0100 (CET) Message-ID: <2f8bb21a-1bc6-1927-d0ec-744d665b06a@passwd.hu> (raw) In-Reply-To: <20220117183056.2125-1-jamrial@gmail.com> On Mon, 17 Jan 2022, James Almer wrote: [...] > -static const char *get_channel_name(int channel_id) > +static const char *get_channel_name(enum AVChannel channel_id) > { > - if (channel_id < 0 || channel_id >= FF_ARRAY_ELEMS(channel_names)) > + if ((unsigned) channel_id >= FF_ARRAY_ELEMS(channel_names) || > + !channel_names[channel_id].name) > return NULL; > return channel_names[channel_id].name; > } > > -static const struct { > +void av_channel_name_bprint(AVBPrint *bp, enum AVChannel channel_id) > +{ > + av_bprint_clear(bp); Clearing should not be done here. Maybe the user wants to construct a string, and the channel name is only a part of it. If not, the user can clear the bprint buffer himself before calling this. > + > + if ((unsigned)channel_id < FF_ARRAY_ELEMS(channel_names)) > + av_bprintf(bp, "%s", channel_names[channel_id].name); > + else > + av_bprintf(bp, "USR%d", channel_id); > +} > + > +int av_channel_name(char *buf, size_t buf_size, enum AVChannel channel_id) > +{ > + AVBPrint bp; > + > + if (!buf && buf_size) > + return AVERROR(EINVAL); > + > + av_bprint_init_for_buffer(&bp, buf, buf_size); > + av_channel_name_bprint(&bp, channel_id); > + > + return bp.len; > +} > + > +void av_channel_description_bprint(AVBPrint *bp, enum AVChannel channel_id) > +{ > + av_bprint_clear(bp); Same here. > + > + if ((unsigned)channel_id < FF_ARRAY_ELEMS(channel_names)) > + av_bprintf(bp, "%s", channel_names[channel_id].description); > + else > + av_bprintf(bp, "user %d", channel_id); > +} > + > +int av_channel_description(char *buf, size_t buf_size, enum AVChannel channel_id) > +{ > + AVBPrint bp; > + > + if (!buf && buf_size) > + return AVERROR(EINVAL); > + > + av_bprint_init_for_buffer(&bp, buf, buf_size); > + av_channel_description_bprint(&bp, channel_id); > + > + return bp.len; > +} [...] > +int av_channel_layout_from_string(AVChannelLayout *channel_layout, > + const char *str) > +{ > + int i; > + int channels = 0, native = 1; > + enum AVChannel highest_channel = AV_CHAN_NONE; > + const char *dup = str; > + char *end; > + uint64_t mask = 0; > + > + /* channel layout names */ > + for (i = 0; i < FF_ARRAY_ELEMS(channel_layout_map); i++) { > + if (channel_layout_map[i].name && !strcmp(str, channel_layout_map[i].name)) { > + *channel_layout = channel_layout_map[i].layout; > + return 0; > + } > + } > + > + /* channel names */ > + while (*dup) { > + char *chname = av_get_token(&dup, "+"); > + if (!chname) > + return AVERROR(ENOMEM); > + if (*dup) > + dup++; // skip separator > + for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++) { > + if (channel_names[i].name && !strcmp(chname, channel_names[i].name)) { > + if (i < highest_channel || mask & (1ULL << i)) > + native = 0; // Not a native layout, use a custom one > + highest_channel = i; > + mask |= 1ULL << i; > + break; > + } > + } > + > + if (i >= FF_ARRAY_ELEMS(channel_names)) { > + char *endptr = chname; > + enum AVChannel id = AV_CHAN_NONE; > + > + if (!strncmp(chname, "USR", 3)) { > + const char *p = chname + 3; > + id = strtol(p, &endptr, 0); > + } > + if (id < 0 || *endptr) { > + native = 0; // Unknown channel name > + channels = 0; > + mask = 0; > + av_free(chname); > + break; > + } > + if (id > 63) > + native = 0; // Not a native layout, use a custom one > + else { > + if (id < highest_channel || mask & (1ULL << id)) > + native = 0; // Not a native layout, use a custom one > + highest_channel = id; > + mask |= 1ULL << id; > + } > + } > + channels++; > + av_free(chname); > + } > + if (mask && native) { > + av_channel_layout_from_mask(channel_layout, mask); > + return 0; > + } > + > + /* custom layout of channel names */ > + if (channels && !native) { > + int idx = 0; > + > + channel_layout->u.map = av_calloc(channels, sizeof(*channel_layout->u.map)); > + if (!channel_layout->u.map) > + return AVERROR(ENOMEM); > + > + channel_layout->order = AV_CHANNEL_ORDER_CUSTOM; > + channel_layout->nb_channels = channels; > + > + dup = str; > + while (*dup) { > + char *chname = av_get_token(&dup, "+"); > + if (!chname) { > + av_freep(&channel_layout->u.map); > + return AVERROR(ENOMEM); > + } > + if (*dup) > + dup++; // skip separator > + for (i = 0; i < FF_ARRAY_ELEMS(channel_names); i++) { > + if (channel_names[i].name && !strcmp(chname, channel_names[i].name)) { > + channel_layout->u.map[idx++].id = i; > + break; > + } > + } > + if (i >= FF_ARRAY_ELEMS(channel_names)) { > + const char *p = chname + 3; > + channel_layout->u.map[idx++].id = strtol(p, NULL, 0); > + } > + av_free(chname); > + } > + > + return 0; > + } > + > + /* channel layout mask */ > + if (!strncmp(str, "0x", 2) && sscanf(str + 2, "%"SCNx64, &mask) == 1) { > + av_channel_layout_from_mask(channel_layout, mask); > + return 0; > + } > + > + errno = 0; > + channels = strtol(str, &end, 10); > + > + /* number of channels */ > + if (!errno && *end == 'c' && !*(end + 1) && channels >= 0) { > + av_channel_layout_default(channel_layout, channels); > + return 0; > + } > + > + /* number of unordered channels */ > + if (!errno && (!*end || (*end == 'C' && !*(end + 1)) || av_strnstr(str, "channels", strlen(str))) > + && channels >= 0) { > + channel_layout->order = AV_CHANNEL_ORDER_UNSPEC; > + channel_layout->nb_channels = channels; > + return 0; > + } > + > + return AVERROR_INVALIDDATA; rather AVERROR(EINVAL), no? > +} > + > +void av_channel_layout_uninit(AVChannelLayout *channel_layout) > +{ > + if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM) > + av_freep(&channel_layout->u.map); > + memset(channel_layout, 0, sizeof(*channel_layout)); > +} > + > +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_array(src->nb_channels, sizeof(*dst->u.map)); > + if (!dst->u.map) > + return AVERROR(ENOMEM); > + memcpy(dst->u.map, src->u.map, src->nb_channels * sizeof(*src->u.map)); > + } > + return 0; > +} > + > +int av_channel_layout_describe_bprint(const AVChannelLayout *channel_layout, > + AVBPrint *bp) > +{ > + int i; > + > + av_bprint_clear(bp); Same as above, clearing should not be done. Thanks, Marton _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
prev parent reply other threads:[~2022-01-17 20:54 UTC|newest] Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top 2022-01-17 18:30 James Almer 2022-01-17 20:53 ` Marton Balint [this message]
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=2f8bb21a-1bc6-1927-d0ec-744d665b06a@passwd.hu \ --to=cus@passwd.hu \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git