ffmpeg之samplefmt

2021/12/4 6:18:02

本文主要是介绍ffmpeg之samplefmt,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

目录
  • 类型说明
  • 便捷的工具函数
    • av_get_sample_fmt_name
    • av_get_sample_fmt
    • av_get_alt_sample_fmt
    • av_get_packed_sample_fmt

音频量化格式和相关的工具函数

类型说明

/**
 * 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

  • brief:获取量化格式对应的字符串名称
  • parameter: 量化格式
  • return: 成功返回量化格式的字符串名称,失败返回NULL
/**
 * 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

  • 获取字符串名称对应的量化格式
  • parameter: 量化格式的字符串名称
  • return:成功返回对应的量化格式,失败返回AV_SAMPLE_FMT_NONE
/**
 * 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;
}


这篇关于ffmpeg之samplefmt的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程