FFmpeg封装格式处理相关内容分为如下几篇文章:
[1]. FFmpeg封装格式处理-简介
[2]. FFmpeg封装格式处理-解复用例程
[3]. FFmpeg封装格式处理-复用例程
[4]. FFmpeg封装格式处理-转封装例程
这几篇文章内容联系紧密,但放在一篇文章里内容太长,遂作拆分。章节号不作调整。基于FFmpeg 4.1版本。
封装格式(container format)可以看作是编码流(音频流、视频流等)数据的一层外壳,将编码后的数据存储于此封装格式的文件之内。封装又称容器,容器的称法更为形象,所谓容器,就是存放内容的器具,饮料是内容,那么装饮料的瓶子就是容器。
不同封装格式适用于不同的场合,支持的编码格式不一样,几个常用的封装格式如下:
下表引用自“视音频编解码技术零基础学习方法”
AVI(.avi) Microsoft公司 不支持 几乎所有格式 几乎所有格式 BT下载影视
MP4(.mp4) MPEG组织 支持 MPEG-2/MPEG-4/H.264/H.263等 AAC/MPEG-1 Layers I,II,III/AC-3等 互联网视频网站
MPEGTS(.ts) MPEG组织 支持 MPEG-1/MPEG-2/MPEG-4/H.264 MPEG-1 Layers I,II,III/AAC IPTV,数字电视
Flash Video(.flv) Adobe公司 支持 Sorenson/VP6/H.264 MP3/ADPCM/Linear PCM/AAC等 互联网视频网站
Matroska(.mkv) CoreCodec公司 支持 几乎所有格式 几乎所有格式 互联网视频网站
Real Video(.rmvb) Real Networks公司 支持 RealVideo 8,9,10 AAC/Cook Codec/RealAudio Lossless BT下载影视
1.2 FFmpeg中的封装格式
FFmpeg关于封装格式的处理涉及打开输入文件、打开输出文件、从输入文件读取编码帧、往输出文件写入编码帧这几个步骤,这些都不涉及编码解码层面。
在FFmpeg中,mux指复用,是multiplex的缩写,表示将多路流(视频、音频、字幕等)混入一路输出中(普通文件、流等)。demux指解复用,是mux的反操作,表示从一路输入中分离出多路流(视频、音频、字幕等)。mux处理的是输入格式,demux处理的输出格式。输入/输出媒体格式涉及文件格式和封装格式两个概念。文件格式由文件扩展名标识,主要起提示作用,通过扩展名提示文件类型(或封装格式)信息。封装格式则是存储媒体内容的实际容器格式,不同的封装格式对应不同的文件扩展名,很多时候也用文件格式代指封装格式,例如常用ts格式(文件格式)代指mpegts格式(封装格式)。
例如,我们把test.ts改名为test.mkv,mkv扩展名提示了此文件封装格式为Matroska,但文件内容并无任何变化,使用ffprobe工具仍能正确探测出封装格式为mpegts。
1.2.1 查看FFmpeg支持的封装格式使用ffmpeg -formats命令可以查看FFmpeg支持的封装格式。FFmpeg支持的封装非常多,下面仅列出最常用的几种:
think@opensuse> ffmpeg -formats File formats: D. = Demuxing supported .E = Muxing supported -- DE flv FLV (Flash Video) D aac raw ADTS AAC (Advanced Audio Coding) DE h264 raw H.264 video DE hevc raw HEVC video E mp2 MP2 (MPEG audio layer 2) DE mp3 MP3 (MPEG audio layer 3) E mpeg2video raw MPEG-2 video DE mpegts MPEG-TS (MPEG-2 Transport Stream) 1.2.2 h264/aac裸流封装格式h264裸流封装格式和aac裸流封装格式在后面的解复用和复用例程中会用到,这里先讨论一下。
h264本来是编码格式,当作封装格式时表示的是H.264裸流格式,所谓裸流就是不含封装信息也流,也就是没穿衣服的流。aac等封装格式类似。
我们看一下FFmpeg工程源码中h264编码格式以及h264封装格式的定义:
FFmpeg工程包含h264解码器,而不包含h264编码器(一般使用第三方libx264编码器用作h264编码),所以只有解码器定义:
h264封装格式定义如下:
AVOutputFormat ff_h264_muxer = { .name = "h264", .long_name = NULL_IF_CONFIG_SMALL("raw H.264 video"), .extensions = "h264,264", .audio_codec = AV_CODEC_ID_NONE, .video_codec = AV_CODEC_ID_H264, .write_header = force_one_stream, .write_packet = ff_raw_write_packet, .check_bitstream = h264_check_bitstream, .flags = AVFMT_NOTIMESTAMPS, }; AVOutputFormat ff_h264_muxer = { .name = "h264", .long_name = NULL_IF_CONFIG_SMALL("raw H.264 video"), .extensions = "h264,264", .audio_codec = AV_CODEC_ID_NONE, .video_codec = AV_CODEC_ID_H264, .write_header = force_one_stream, .write_packet = ff_raw_write_packet, .check_bitstream = h264_check_bitstream, .flags = AVFMT_NOTIMESTAMPS, }; 1.2.3 mpegts封装格式