音频量化格式和相关的工具函数
/** * Audio sample formats * * - The data described by the sample format is always in native-endian order. * Sample values can be expressed by native C types, hence the lack of a signed * 24-bit sample format even though it is a common raw audio data format. * * - The floating-point formats are based on full volume being in the range * [-1.0, 1.0]. Any values outside this range are beyond full volume level. * * - The data layout as used in av_samples_fill_arrays() and elsewhere in FFmpeg * (such as AVFrame in libavcodec) is as follows: * * @par * For planar sample formats, each audio channel is in a separate data plane, * and linesize is the buffer size, in bytes, for a single plane. All data * planes must be the same size. For packed sample formats, only the first data * plane is used, and samples for each channel are interleaved. In this case, * linesize is the buffer size, in bytes, for the 1 plane. * */ /* *planar:每个音频数据通道位于不同的plane,且所有plane的数据长度是一致的, data[0] = LLL..., data[1] = RRR...。 * linesize表示单个plane的buffer size(以字节为单位)。 *packed:仅使用了第一个plane,且数据是交错存储的,data[0] = LRLRLR...。 * linesize表示单个plane的buffer size(以字节为单位)。。。(仅使用了一个plane == 单个plane) */ enum AVSampleFormat { AV_SAMPLE_FMT_NONE = -1, AV_SAMPLE_FMT_U8, ///< unsigned 8 bits AV_SAMPLE_FMT_S16, ///< signed 16 bits AV_SAMPLE_FMT_S32, ///< signed 32 bits AV_SAMPLE_FMT_FLT, ///< float AV_SAMPLE_FMT_DBL, ///< double AV_SAMPLE_FMT_U8P, ///< unsigned 8 bits, planar AV_SAMPLE_FMT_S16P, ///< signed 16 bits, planar AV_SAMPLE_FMT_S32P, ///< signed 32 bits, planar AV_SAMPLE_FMT_FLTP, ///< float, planar AV_SAMPLE_FMT_DBLP, ///< double, planar AV_SAMPLE_FMT_S64, ///< signed 64 bits AV_SAMPLE_FMT_S64P, ///< signed 64 bits, planar AV_SAMPLE_FMT_NB ///< Number of sample formats. DO NOT USE if linking dynamically }; // 量化格式信息 typedef struct SampleFmtInfo { char name[8]; // 量化格式名称 int bits; // bits >> 3 占据字节数量(1byte = 8bit ( 8 == 2 ** 3)) int planar; // 是否为planar格式,1是,0不是 enum AVSampleFormat altform; ///< planar<->packed alternative form,相反的格式 } SampleFmtInfo; /** this table gives more information about formats */ // 量化格式参照表 static const SampleFmtInfo sample_fmt_info[AV_SAMPLE_FMT_NB] = { [AV_SAMPLE_FMT_U8] = { .name = "u8", .bits = 8, .planar = 0, .altform = AV_SAMPLE_FMT_U8P }, [AV_SAMPLE_FMT_S16] = { .name = "s16", .bits = 16, .planar = 0, .altform = AV_SAMPLE_FMT_S16P }, [AV_SAMPLE_FMT_S32] = { .name = "s32", .bits = 32, .planar = 0, .altform = AV_SAMPLE_FMT_S32P }, [AV_SAMPLE_FMT_S64] = { .name = "s64", .bits = 64, .planar = 0, .altform = AV_SAMPLE_FMT_S64P }, [AV_SAMPLE_FMT_FLT] = { .name = "flt", .bits = 32, .planar = 0, .altform = AV_SAMPLE_FMT_FLTP }, [AV_SAMPLE_FMT_DBL] = { .name = "dbl", .bits = 64, .planar = 0, .altform = AV_SAMPLE_FMT_DBLP }, [AV_SAMPLE_FMT_U8P] = { .name = "u8p", .bits = 8, .planar = 1, .altform = AV_SAMPLE_FMT_U8 }, [AV_SAMPLE_FMT_S16P] = { .name = "s16p", .bits = 16, .planar = 1, .altform = AV_SAMPLE_FMT_S16 }, [AV_SAMPLE_FMT_S32P] = { .name = "s32p", .bits = 32, .planar = 1, .altform = AV_SAMPLE_FMT_S32 }, [AV_SAMPLE_FMT_S64P] = { .name = "s64p", .bits = 64, .planar = 1, .altform = AV_SAMPLE_FMT_S64 }, [AV_SAMPLE_FMT_FLTP] = { .name = "fltp", .bits = 32, .planar = 1, .altform = AV_SAMPLE_FMT_FLT }, [AV_SAMPLE_FMT_DBLP] = { .name = "dblp", .bits = 64, .planar = 1, .altform = AV_SAMPLE_FMT_DBL }, };
av_get_sample_fmt_name
/** * Return the name of sample_fmt, or NULL if sample_fmt is not recognized. */ const char *av_get_sample_fmt_name(enum AVSampleFormat sample_fmt) { if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB) return NULL; return sample_fmt_info[sample_fmt].name; }
av_get_sample_fmt
/** * Return a sample format corresponding to name, or AV_SAMPLE_FMT_NONE * on error. */ enum AVSampleFormat av_get_sample_fmt(const char *name) { int i; for (i = 0; i < AV_SAMPLE_FMT_NB; i++) if (!strcmp(sample_fmt_info[i].name, name)) return i; return AV_SAMPLE_FMT_NONE; }
av_get_alt_sample_fmt
brief:获取相反的量化格式
parameter:sample_fmt:量化格式,planar:是否为planar格式
return:失败是返回AV_SAMPLE_FMT_NONE。
如果传递的sample_fmt已经采用请求的量化格式,则返回自己sample_fmt,比如 AV_SAMPLE_FMT_S16 = av_get_alt_sample_fmt(AV_SAMPLE_FMT_S16, 0);
否则返回对应的量化格式,比如AV_SAMPLE_FMT_S16P = av_get_alt_sample_fmt(AV_SAMPLE_FMT_S16, 1)。
/** * Return the planar<->packed alternative form of the given sample format, or * AV_SAMPLE_FMT_NONE on error. If the passed sample_fmt is already in the * requested planar/packed format, the format returned is the same as the * input. */ enum AVSampleFormat av_get_alt_sample_fmt(enum AVSampleFormat sample_fmt, int planar) { if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB) return AV_SAMPLE_FMT_NONE; if (sample_fmt_info[sample_fmt].planar == planar) return sample_fmt; return sample_fmt_info[sample_fmt].altform; }
av_get_packed_sample_fmt
brief:返回packed格式的量化格式
parameter:sample_fmt请求的量化格式
return:失败返回AV_SAMPLE_FMT_NONE;
如果输入的已经是packed的格式,则返回自己sample_fmt。
否则返回对应的的planar格式的量化格式
/** * Get the packed alternative form of the given sample format. * * If the passed sample_fmt is already in packed format, the format returned is * the same as the input. * * @return the packed alternative form of the given sample format or AV_SAMPLE_FMT_NONE on error. */ enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt) { if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB) return AV_SAMPLE_FMT_NONE; if (sample_fmt_info[sample_fmt].planar) return sample_fmt_info[sample_fmt].altform; return sample_fmt; }