FFmpeg封装格式处理

FFmpeg封装格式处理相关内容分为如下几篇文章:
[1]. FFmpeg封装格式处理-简介
[2]. FFmpeg封装格式处理-解复用例程
[3]. FFmpeg封装格式处理-复用例程
[4]. FFmpeg封装格式处理-转封装例程
这几篇文章内容联系紧密,但放在一篇文章里内容太长,遂作拆分。章节号不作调整。基于FFmpeg 4.1版本。

1. 概述 1.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编码),所以只有解码器定义:

AVCodec ff_h264_decoder = { .name = "h264", .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_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封装格式

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyjjjg.html