存储格式:packed和planar
2021/12/7 23:46:44
本文主要是介绍存储格式:packed和planar,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
目录- 存储方式差异
- 数据所在位置
- 存储方式差异的影响
- FFmpeg对存储方式的支持
- 常见编码器定义
存储方式差异
音视频都有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, };
这篇关于存储格式:packed和planar的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享