ffmpeg enum AVChannel枚举解析
AVChannel枚举是在2022-12-20的提交中添加的,对应的版本号是5.1.
这个提交的描述是"avutil/channel_layout: add AVChannel enum and related
functions"。
原型
typedef struct AVChannelCustom {enum AVChannel id;char name[16];void *opaque;
} AVChannelCustom;enum AVChannel {///< Invalid channel indexAV_CHAN_NONE = -1,AV_CHAN_FRONT_LEFT,AV_CHAN_FRONT_RIGHT,AV_CHAN_FRONT_CENTER,AV_CHAN_LOW_FREQUENCY,AV_CHAN_BACK_LEFT,AV_CHAN_BACK_RIGHT,AV_CHAN_FRONT_LEFT_OF_CENTER,AV_CHAN_FRONT_RIGHT_OF_CENTER,AV_CHAN_BACK_CENTER,AV_CHAN_SIDE_LEFT,AV_CHAN_SIDE_RIGHT,AV_CHAN_TOP_CENTER,AV_CHAN_TOP_FRONT_LEFT,AV_CHAN_TOP_FRONT_CENTER,AV_CHAN_TOP_FRONT_RIGHT,AV_CHAN_TOP_BACK_LEFT,AV_CHAN_TOP_BACK_CENTER,AV_CHAN_TOP_BACK_RIGHT,/** Stereo downmix. */AV_CHAN_STEREO_LEFT = 29,/** See above. */AV_CHAN_STEREO_RIGHT,AV_CHAN_WIDE_LEFT,AV_CHAN_WIDE_RIGHT,AV_CHAN_SURROUND_DIRECT_LEFT,AV_CHAN_SURROUND_DIRECT_RIGHT,AV_CHAN_LOW_FREQUENCY_2,AV_CHAN_TOP_SIDE_LEFT,AV_CHAN_TOP_SIDE_RIGHT,AV_CHAN_BOTTOM_FRONT_CENTER,AV_CHAN_BOTTOM_FRONT_LEFT,AV_CHAN_BOTTOM_FRONT_RIGHT,/** Channel is empty can be safely skipped. */AV_CHAN_UNUSED = 0x200,/** Channel contains data, but its position is unknown. */AV_CHAN_UNKNOWN = 0x300,/*** Range of channels between AV_CHAN_AMBISONIC_BASE and* AV_CHAN_AMBISONIC_END represent Ambisonic components using the ACN system.** Given a channel id <i> between AV_CHAN_AMBISONIC_BASE and* AV_CHAN_AMBISONIC_END (inclusive), the ACN index of the channel <n> is* <n> = <i> - AV_CHAN_AMBISONIC_BASE.** @note these values are only used for AV_CHANNEL_ORDER_CUSTOM channel* orderings, the AV_CHANNEL_ORDER_AMBISONIC ordering orders the channels* implicitly by their position in the stream.*/AV_CHAN_AMBISONIC_BASE = 0x400,// leave space for 1024 ids, which correspond to maximum order-32 harmonics,// which should be enough for the foreseeable use casesAV_CHAN_AMBISONIC_END = 0x7ff,
};
描述
AVChannel
是一个枚举类型,用于表示音频数据的各个声道。在音频数据中,一个“声道”是一个独立的音频信号,它可以被独立处理和播放。例如,在立体声音频中,有两个声道:左声道和右声道。
这个枚举中的每个值都代表一个特定的声道。例如,AV_CHAN_FRONT_LEFT
代表前左声道,AV_CHAN_FRONT_RIGHT
代表前右声道,等等。这些值可以用于处理具有特定声道布局的音频数据。
以下是一些特殊的枚举值的解释:
AV_CHAN_NONE
:无效的声道索引。AV_CHAN_STEREO_LEFT
和AV_CHAN_STEREO_RIGHT
:立体声混音的左声道和右声道。AV_CHAN_UNUSED
:声道是空的,可以安全地跳过。AV_CHAN_UNKNOWN
:声道包含数据,但其位置未知。AV_CHAN_AMBISONIC_BASE
和AV_CHAN_AMBISONIC_END
:表示使用 ACN 系统的 Ambisonic 组件的声道范围。Ambisonics 是一种全方位的声音录制和再现技术,可以捕捉和再现声音场的三维空间信息。
请注意,这个枚举的具体值可能会根据你使用的 FFmpeg 版本和 API 而有所不同。你应该查阅你正在使用的 FFmpeg 版本和 API 的文档,以获取最准确的信息。
相关输出接口
/*** Get the channel with the given index in a channel layout.** @param channel_layout input channel layout* @return channel with the index idx in channel_layout on success or* AV_CHAN_NONE on failure (if idx is not valid or the channel order is* unspecified)*/
enum AVChannel
av_channel_layout_channel_from_index(const AVChannelLayout *channel_layout, unsigned int idx);
/*** Get a channel described by the given string.** This function accepts channel names in the same format as* @ref av_channel_from_string().** @param channel_layout input channel layout* @return a channel described by the given string in channel_layout on success* or AV_CHAN_NONE on failure (if the string is not valid or the channel* order is unspecified)*/
enum AVChannel
av_channel_layout_channel_from_string(const AVChannelLayout *channel_layout,const char *name);/*** This is the inverse function of @ref av_channel_name().** @return the channel with the given name* AV_CHAN_NONE when name does not identify a known channel*/
enum AVChannel av_channel_from_string(const char *name);
这些函数都是用来从不同的输入获取 AVChannel
枚举类型的。下面是每个函数的简单解释和示例:
av_channel_layout_channel_from_string
:这个函数从给定的声道布局中获取由给定字符串描述的声道。例如:
const AVChannelLayout *layout = codec_ctx_->channel_layout;
const char *name = "FL"; // Front Left
AVChannel channel = av_channel_layout_channel_from_string(layout, name);
av_channel_layout_channel_from_index
:这个函数从给定的声道布局中获取给定索引的声道。例如:
const AVChannelLayout *layout = codec_ctx_->channel_layout;
unsigned int idx = 0; // Index of the channel
AVChannel channel = av_channel_layout_channel_from_index(layout, idx);
av_channel_from_string
:这个函数获取给定名称的声道。例如:
const char *name = "FL"; // Front Left
AVChannel channel = av_channel_from_string(name);
请注意,这些函数都可能返回 AV_CHAN_NONE
,这表示输入无效,或者声道顺序未指定。在使用这些函数时,你应该检查返回值是否为 AV_CHAN_NONE
。
相关输入接口
/*** Get a human readable string in an abbreviated form describing a given channel.* This is the inverse function of @ref av_channel_from_string().** @param buf pre-allocated buffer where to put the generated string* @param buf_size size in bytes of the buffer.* @return amount of bytes needed to hold the output string, or a negative AVERROR* on failure. If the returned value is bigger than buf_size, then the* string was truncated.*/
int av_channel_name(char *buf, size_t buf_size, enum AVChannel channel);/*** bprint variant of av_channel_name().** @note the string will be appended to the bprint buffer.*/
void av_channel_name_bprint(struct AVBPrint *bp, enum AVChannel channel_id);/*** Get a human readable string describing a given channel.** @param buf pre-allocated buffer where to put the generated string* @param buf_size size in bytes of the buffer.* @return amount of bytes needed to hold the output string, or a negative AVERROR* on failure. If the returned value is bigger than buf_size, then the* string was truncated.*/
int av_channel_description(char *buf, size_t buf_size, enum AVChannel channel);/*** bprint variant of av_channel_description().** @note the string will be appended to the bprint buffer.*/
void av_channel_description_bprint(struct AVBPrint *bp, enum AVChannel channel_id);
/*** Get the index of a given channel in a channel layout. In case multiple* channels are found, only the first match will be returned.** @param channel_layout input channel layout* @return index of channel in channel_layout on success or a negative number if* channel is not present in channel_layout.*/
int av_channel_layout_index_from_channel(const AVChannelLayout *channel_layout,enum AVChannel channel);
这些函数都是用来获取 AVChannel
枚举值的描述的。下面是每个函数的简单解释和示例:
av_channel_name
:这个函数获取给定声道的简短描述。例如:
char buf[256];
AVChannel channel = AV_CHAN_FRONT_LEFT;
int ret = av_channel_name(buf, sizeof(buf), channel);
if (ret < 0) {// Handle error
} else {printf("Channel name: %s\n", buf);
}
av_channel_name_bprint
:这个函数是av_channel_name
的 bprint 变体,它将字符串追加到 bprint 缓冲区。例如:
AVBPrint bp;
av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED);
AVChannel channel = AV_CHAN_FRONT_LEFT;
av_channel_name_bprint(&bp, channel);
printf("Channel name: %s\n", bp.str);
av_bprint_finalize(&bp, NULL);
av_channel_description
:这个函数获取给定声道的详细描述。例如:
char buf[256];
AVChannel channel = AV_CHAN_FRONT_LEFT;
int ret = av_channel_description(buf, sizeof(buf), channel);
if (ret < 0) {// Handle error
} else {printf("Channel description: %s\n", buf);
}
av_channel_description_bprint
:这个函数是av_channel_description
的 bprint 变体,它将字符串追加到 bprint 缓冲区。例如:
AVBPrint bp;
av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED);
AVChannel channel = AV_CHAN_FRONT_LEFT;
av_channel_description_bprint(&bp, channel);
printf("Channel description: %s\n", bp.str);
av_bprint_finalize(&bp, NULL);
请注意,这些函数都可能返回错误。在使用这些函数时,你应该检查返回值是否为负数,如果是,那么说明发生了错误。
5. av_channel_layout_index_from_channel
函数用于获取给定声道在声道布局中的索引。如果在声道布局中找到多个相同的声道,只会返回第一个匹配的索引。
这个函数接受两个参数:
channel_layout
:输入的声道布局。channel
:要查找的声道。
如果声道在声道布局中存在,函数会返回声道的索引;如果声道在声道布局中不存在,函数会返回一个负数。
以下是一个使用示例:
const AVChannelLayout *layout = codec_ctx_->channel_layout;
AVChannel channel = AV_CHAN_FRONT_LEFT;
int index = av_channel_layout_index_from_channel(layout, channel);
if (index < 0) {printf("Channel is not present in the layout\n");
} else {printf("Index of the channel in the layout: %d\n", index);
}
在这个示例中,我们首先获取编解码器上下文的声道布局,然后定义我们要查找的声道(在这个例子中是前左声道)。然后,我们调用 av_channel_layout_index_from_channel
函数来获取声道在声道布局中的索引。如果索引是负数,那么声道在声道布局中不存在;否则,我们打印出声道在声道布局中的索引。
应用场景
FFmpeg 是一个非常灵活的库,它允许你以多种方式处理音频和视频数据。这种灵活性的一个结果是,很多函数需要你手动指定参数,而不是自动从结构体中获取信息。这是因为在不同的上下文中,你可能需要以不同的方式处理数据。
例如,av_channel_layout_channel_from_string
和 av_channel_layout_channel_from_index
函数允许你从一个声道布局中获取一个特定的声道。你需要手动指定声道的名称或索引,因为 FFmpeg 不知道你想获取哪个声道。你可能想获取前左声道,也可能想获取前右声道,或者其他任何声道。FFmpeg 提供了这些函数,让你可以根据你的需要获取任何声道。
同样,av_channel_from_string
函数允许你获取一个给定名称的声道。你需要手动指定声道的名称,因为 FFmpeg 不知道你想获取哪个声道。你可能想获取 “FL”(前左)声道,也可能想获取 “FR”(前右)声道,或者其他任何声道。FFmpeg 提供了这个函数,让你可以根据你的需要获取任何声道。
虽然这些函数需要你手动指定参数,但这并不意味着代码的兼容性不强。相反,这种设计使得你的代码可以在不同的上下文中工作,只要你正确地指定了参数。如果你想写更通用的代码,你可以编写一个函数,它接受一个 FFmpeg 结构体作为参数,然后从这个结构体中获取所需的信息,然后调用这些 FFmpeg 函数。