• 存储格式:packed和planar


    存储方式差异

    音视频都有packed和planar两种存储方式

    • packed方式为多个声道交错存储,比如双声道data[0] = LRLRLR…
    • planar方式为多个声道独立存储,比如双声道data[0] = LLL… data[1] = RRR…

    数据所在位置

    使用packed和planar存储的额数据位于AVFrame结构中,即解码后的数据和编码前的数据。

    • packed格式:frame.data[0]或frame.extended_data[0]包含说有的音频数据
    • planar格式:frame.data[i]活着frame.extended_data[i]表示第i个声道的数据,AVFrame.data的数组大小固定为8,如果声道超过8需要从frame.extended_data获取声道数据

    存储方式差异的影响

    planar模式ffmepg内部存储模式,但是实际使用的音频文件都是packed模式存储文件。

    Planar或者Packed模式直接影响到保存文件时写文件的操作,操作数据的时候一定要先检测音频采样格式。

    FFmpeg对存储方式的支持

    ffmpeg支持的存储方式包括

    enum AVSampleFormat {
        AV_SAMPLE_FMT_NONE = -1,
        // packed存储方式
        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
    
        // planar存储方式
        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
    };
    

    常见编码器定义

    每种编码器对应的默认编码存储格式是不同的

    • aac
    AVCodec ff_aac_encoder = {
        .name           = "aac",
        .long_name      = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
        .type           = AVMEDIA_TYPE_AUDIO,
        .id             = AV_CODEC_ID_AAC,
        .priv_data_size = sizeof(AACEncContext),
        .init           = aac_encode_init,
        .encode2        = aac_encode_frame,
        .close          = aac_encode_end,
        .defaults       = aac_encode_defaults,
        .supported_samplerates = mpeg4audio_sample_rates,
        .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE,
        .capabilities   = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY,
        .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,
                                                         AV_SAMPLE_FMT_NONE },
        .priv_class     = &aacenc_class,
    };
    
    
    • fdk_aac
    AVCodec ff_libfdk_aac_encoder = {
        .name                  = "libfdk_aac",
        .long_name             = NULL_IF_CONFIG_SMALL("Fraunhofer FDK AAC"),
        .type                  = AVMEDIA_TYPE_AUDIO,
        .id                    = AV_CODEC_ID_AAC,
        .priv_data_size        = sizeof(AACContext),
        .init                  = aac_encode_init,
        .encode2               = aac_encode_frame,
        .close                 = aac_encode_close,
        .capabilities          = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY,
        .sample_fmts           = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                                AV_SAMPLE_FMT_NONE },
        .priv_class            = &aac_enc_class,
        .defaults              = aac_encode_defaults,
        .profiles              = profiles,
        .supported_samplerates = aac_sample_rates,
        .channel_layouts       = aac_channel_layout,
        .wrapper_name          = "libfdk",
    };
    
    
    • mp3lamp
    AVCodec ff_libmp3lame_encoder = {
        .name                  = "libmp3lame",
        .long_name             = NULL_IF_CONFIG_SMALL("libmp3lame MP3 (MPEG audio layer 3)"),
        .type                  = AVMEDIA_TYPE_AUDIO,
        .id                    = AV_CODEC_ID_MP3,
        .priv_data_size        = sizeof(LAMEContext),
        .init                  = mp3lame_encode_init,
        .encode2               = mp3lame_encode_frame,
        .close                 = mp3lame_encode_close,
        .capabilities          = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SMALL_LAST_FRAME,
        .sample_fmts           = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S32P,
                                                                 AV_SAMPLE_FMT_FLTP,
                                                                 AV_SAMPLE_FMT_S16P,
                                                                 AV_SAMPLE_FMT_NONE },
        .supported_samplerates = libmp3lame_sample_rates,
        .channel_layouts       = (const uint64_t[]) { AV_CH_LAYOUT_MONO,
                                                      AV_CH_LAYOUT_STEREO,
                                                      0 },
        .priv_class            = &libmp3lame_class,
        .defaults              = libmp3lame_defaults,
        .wrapper_name          = "libmp3lame",
    };
    
    • flac
    AVCodec ff_flac_encoder = {
        .name           = "flac",
        .long_name      = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"),
        .type           = AVMEDIA_TYPE_AUDIO,
        .id             = AV_CODEC_ID_FLAC,
        .priv_data_size = sizeof(FlacEncodeContext),
        .init           = flac_encode_init,
        .encode2        = flac_encode_frame,
        .close          = flac_encode_close,
        .capabilities   = AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_LOSSLESS,
        .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                         AV_SAMPLE_FMT_S32,
                                                         AV_SAMPLE_FMT_NONE },
        .priv_class     = &flac_encoder_class,
    };
    
    

    本文来自博客园,作者:faithlocus,转载请注明原文链接:https://www.cnblogs.com/faithlocus/p/15659383.html

  • 相关阅读:
    水仙花数
    Edge browser hosts file
    tt0034583
    JavaScript中的面向对象
    滚动
    无缝滚动
    MySQL(一)
    JavaScript 精粹
    MYSQL新手入门篇
    用github来展示你的前端页面吧
  • 原文地址:https://www.cnblogs.com/faithlocus/p/15659383.html
Copyright © 2020-2023  润新知