视频编码与容器格式基础:H.264、MP4 与 FFmpeg

This article is extracted from the chat log with AI. Please identify it with caution.

AI 参与说明(Agent:Codex):本文由 Codex 根据 ITU-T、ISO、AOMedia、WebM Project、MP4 Registration Authority、IETF 与 FFmpeg 的一手资料辅助调研、撰写和校验,并用 FFmpeg 8.0 实测文中的示例。资料核验于 2026-08-26;播放器、硬件解码器和 FFmpeg build 的支持范围可能不同,交付前仍需在目标设备上验证。

先给结论#

H.264 和 MP4 不在同一层:

  • H.264,也称 AVC,是视频编码标准,规定如何表示和解码压缩后的视频;它不负责音频。H.264/AVC 这套标准在 ITU-TISO/IEC 体系中分别编号为 H.264 与 ISO/IEC 14496-10,各版发布时间可能不同。
  • MP4 是容器格式,负责把已经编码的视频、音频、字幕、时间戳和元数据组织成文件。当前 ISO/IEC 14496-12:2026 定义 ISO Base Media File Format(ISOBMFF),ISO/IEC 14496-14:2020 则定义由它派生的 MP4 file format。

因此,一个 .mp4 文件可以装 H.264 视频,但 .mp4 并不等于 H.264;H.264 也可以出现在 Matroska(.mkv)、MPEG-TS 等其他容器里。ISO 还用 ISO/IEC 14496-15:2024 专门规定 AVC 等 NAL unit structured video 在 ISOBMFF 中的存储方式。

flowchart TB
    A[原始视频帧 Raw video frames] -->|H.264 encoder| B[H.264 video stream]
    C[原始音频 Raw audio] -->|AAC encoder| D[AAC audio stream]
    B --> E[MP4 muxer]
    D --> E
    F[Subtitles 与 metadata] --> E
    E --> G[example.mp4]

日常说“用 H.264 codec”通常能被理解,但严格说,H.264 是编码标准与 bitstream format;具体 encoder 或 decoder 才是实现,例如本文通过 FFmpeg 的 libx264 wrapper 调用 x264 encoder。

名称与标准谱系#

视频领域的名称常把标准组织、标准编号和市场名称混在一起。最重要的对应关系如下:

常用名称同一标准的其他名称谱系与说明
H.264AVC(Advanced Video Coding)、MPEG-4 Part 10、ISO/IEC 14496-10ITU-T 与 ISO/IEC MPEG 的联合标准
H.265HEVC(High Efficiency Video Coding)、MPEG-H Part 2、ISO/IEC 23008-2H.264 的后继联合标准
H.266VVC(Versatile Video Coding)、MPEG-I Part 3、ISO/IEC 23090-3H.265 的后继联合标准
MPEG-4 VisualMPEG-4 Part 2、ISO/IEC 14496-2较早的 MPEG 视频标准,不是 H.264
VP8、VP9WebM video codecs由 Google/WebM Project 发布的两代规范
AV1AOMedia Video 1Alliance for Open Media 制定的开放视频标准

因此,H.26x、MPEG 与 AOM 不是三个互不相交的“文件格式清单”:H 是 ITU-T H-series Recommendation 的编号前缀,并不是 HEVC 的缩写;MPEG 的 Part 号用于标识同一标准套件中的组成部分,也不是 codec 的版本号。H.264、H.265、H.266 同时拥有 ITU-T 名称和 MPEG Part 名称;MPEG-4 Part 2 则是另一套较早的 bitstream,不能因“MPEG-4”几个字就与 H.264 混为一谈。VP8/VP9 所属的 WebM Project 与制定 AV1 的 AOMedia 也是不同项目,虽有产业参与者和技术路线的延续,AV1 的正式名称仍不是“VP10”。这些对应关系可在 ITU-T video coding 页面JVET 页面AOMedia AV1 specification 中核对。

这些名字可以逐层读:H.265 是 ITU-T Recommendation 编号,HEVC 是 High Efficiency Video Coding 的缩写,ISO/IEC 则把同一标准编为 MPEG-H Part 2。这里 MPEG 源自 Moving Picture Experts Group;MPEG-4、MPEG-H、MPEG-I 是标准套件名称,不是按 4、5、6 顺序排列的 codec 版本。x264、x265 只是 encoder 项目名,名称中的 x 也不代表另一套标准。

标准、encoder、wrapper 与硬件不是一回事#

以 H.264 和 H.265 为例,各层名称应这样读:

层次H.264/AVC 示例H.265/HEVC 示例
标准与 bitstreamH.264 / AVCH.265 / HEVC
software encoderx264x265
FFmpeg wrapperlibx264libx265
hardware encoderh264_videotoolboxh264_nvench264_qsvhevc_videotoolboxhevc_nvenchevc_qsv
MP4 sample entry / codec stringavc1avc3hvc1hev1
containerMP4、Matroska、MPEG-TS 等MP4、Matroska、MPEG-TS 等

x264、x265 是 CPU software encoder;FFmpeg 的 libx264libx265 是调用相应 library 的 wrapper,不是新编码标准。VideoToolbox、NVENC、QSV 则调用 Apple、NVIDIA、Intel 的硬件能力,是否可用取决于芯片、驱动和 FFmpeg build;它们与 software encoder 即使输出同一种 bitstream,在速度、画质、延迟和可调参数上也不必相同。FFmpeg 官方将 libx265 明确定义为 x265 H.265/HEVC encoder wrapper

H.264 与 H.265 怎么选#

HEVC 的设计目标是在相近主观质量下比 AVC 更节省传输或存储码率,但实际结果受素材、encoder、preset、rate control 和延迟约束影响,不能套用一个固定百分比。

直观地说,H.264 主要围绕 16×16 macroblock 组织画面,而 HEVC 改用最大可达 64×64、还能递归细分的 Coding Tree Unit,并增加更灵活的 prediction、transform 与 filtering 工具。编码器因此更容易用大块表示平坦区域、用小块表示复杂边缘;代价是编码时需要搜索更多可能性。RFC 7798 的 HEVC 概览 给出了这些结构差异。

维度H.264 / AVCH.265 / HEVC
Compression efficiency成熟、易获得稳定结果通常更省码率,仍应以目标素材实测
编解码复杂度软件与旧硬件负担通常较低软件编码通常更重;有硬件支持时结论会变化
Compatibility老设备、浏览器与实时链路通常更稳妥新设备和 4K 播放较常见,但 Web 与目标平台须逐项验证
Typical use cases通用分发、直播、视频会议、兼容性优先UHD/4K、长视频存储、带宽或容量更敏感的交付
Profile / Level常见 Baseline、Main、High 与 Level常见 Main、Main 10,以及 Tier / Level

Profile、Level、Tier 都是能力与约束信号,不是“低中高画质 preset”。codec 名称也不能单独证明 bit depth 或 HDR:HEVC Main 可以是 8-bit,Main 10 才允许更高 bit depth;HDR 还依赖 transfer characteristics、colour primaries、matrix coefficients、静态或动态 metadata,以及完整的显示链路。交付前应以 ffprobe 检查 profilepix_fmt 和 color metadata,再到目标终端实测。ITU-T 的 HEVC 项目说明ISO/IEC 23008-2 给出了标准定位。

Container 里面有什么#

容器可以理解为带时间轴的“盒子”。一个 MP4 文件通常包含若干 track,例如:

  • 一个 H.264 video track;
  • 一个 AAC audio track,也可能有多语言 audio track;
  • 可选的 subtitles、章节、封面、拍摄时间、旋转信息等 metadata;
  • 用于同步播放的 timing、索引和结构信息。

ISOBMFF 标准明确包含 timed media 的 timing、structure 与 media information;MP4 Registration Authority 也分别登记了 video、audio、subtitles、text 和 metadata 等 sample entry code。MP4RA codec registry 中既有 H.264/AVC 的 avc1,也有 AV1 的 av01,说明 MP4 family 并不绑定单一视频编码。

需要注意,avc1 是大小写敏感的 sample entry 或 codec string 前缀,不是 H.264 的同义词。avc1 / avc3hvc1 / hev1av01 描述 MP4 family 内的 sample entry 或 codec string,不是 encoder,也不是 container。IETF 的 RFC 6381 给出了 video/mp4; codecs="avc1.640028" 的例子,其中还携带 High Profile、Level 4.0 等信息。

MP4RA codec registry 的定义,hvc1 要求 HEVC parameter sets 只放在 sample entry;hev1 允许它们位于 sample entry,也允许随 media samples 携带。两者是 HEVC 在 ISOBMFF 中的不同承载约束,不是两个视频 codec;只改 FourCC/tag 并不能自动重排 parameter sets。MP4RA 的登记也只说明 code point 有规范定义,不能据此推断所有播放器、浏览器或 MP4 profile 都支持它。

影响画质、体积与兼容性的参数#

参数它描述什么初学者容易误解的地方
Resolution每帧的像素尺寸,例如 1920×1080分辨率更高不保证画质更好,还取决于 bitrate、编码器和源素材
Frame rate每秒显示多少帧,例如 24、30 或 60 fps更高通常更流畅,也会增加编码与解码压力
Bitrate单位时间的数据量,常用 kbit/s 或 Mbit/s同一编码下,提高 bitrate 通常能保留更多细节,但文件也更大
Profile一组编码工具与 bitstream 限制,例如 Baseline、Main、High它是解码能力与互操作边界,不是画质档位
Level对画面尺寸、处理速率、buffer、bitrate 等资源设限,例如 Level 4.0它也不是画质档位;目标设备必须能处理所用 Profile 与 Level

H.264 当前规范把 Profile 与 Level 分别列在 Annex A,并列出 Level 对 frame rate、decoded picture buffer 等能力的限制。ITU-T H.264 (06/2026) 目录 可直接定位这些条款。

粗略估算文件体积时,可以使用:

文件体积(byte)≈ 总 bitrate(bit/s)× 时长(s)÷ 8

这里的总 bitrate 要包含视频、音频和少量容器开销;Variable Bitrate(VBR)素材只能用平均 bitrate 估算。

Lossy、lossless、remuxing 与 transcoding#

  • Lossy compression 会丢弃部分信息以缩小体积。面向播放与分发的 H.264 通常这样使用;再次有损编码可能继续损失画质。
  • Lossless compression 能从压缩数据还原原始信息。FFmpeg 的 libx264 wrapper 确实支持 lossless mode,但这不是普通 H.264 分发文件的默认做法,体积与兼容性也要另行评估。FFmpeg libx264 文档
  • Remuxing 只更换或重组容器,不解码、不过滤、不重新编码 elementary stream。FFmpeg 的 -c copy 就是 streamcopy,因此速度快且没有重新编码造成的画质损失;不过目标容器必须接受被复制的 stream。
  • Transcoding 会先解码,再用目标编码器重新编码。它适合缩放、滤镜、修改编码或解决播放兼容性,计算成本更高,而且多数情况下有损。FFmpeg 对 streamcopy 与 transcoding 的说明

所以,把 H.264/AAC 的 MKV remux 成 MP4 时,视频内容可以保持不变;把它重新编码成另一组 H.264 参数时,即使输出仍是 .mp4,也属于 transcoding。

为什么同是 MP4,有的设备仍然打不开#

播放器必须同时满足多层条件:能识别 MP4 容器、能解码具体 video codec 及其 Profile/Level、能解码 audio codec,还要能处理所选 subtitle 与 metadata 格式。文件扩展名或 video/mp4 MIME type 本身都不能完整说明这些内部信息。

文件示例可以得出的结论还需验证什么
MP4 + H.264 High Profile + AAC-LC常见的交付组合目标设备支持的 Level、pixel format、分辨率与 frame rate
MP4 + AV1 + AACav01 已有正式登记目标播放器是否有 AV1 decoder;登记不等于终端支持
MKV + H.264 + AACH.264 video stream 并未因为容器不同而改变身份目标播放器是否支持 Matroska container
MP4 + H.264 + 某种 subtitle视频本身可能可播放muxer 与播放器是否接受该 subtitle sample entry

遇到“文件扩展名正确但打不开”时,先查看内部 stream,而不是继续修改扩展名。

用 FFmpeg 看清并验证#

以下命令已在 macOS、FFmpeg 8.0 上实测。前置条件是系统里同时有 ffmpegffprobe,而且当前 build 启用了 libx264libx265 与 AAC encoder;可以用 ffmpeg -hide_banner -encoders 检查。FFmpeg 官方说明这些 wrapper 需要在构建时启用相应 library。FFmpeg codec documentation

1. 生成可复现的测试素材#

下面生成 1 秒、320×180、30 fps 的 H.264 + AAC Matroska 文件:

ffmpeg -f lavfi -i 'testsrc2=size=320x180:rate=30' \
  -f lavfi -i 'sine=frequency=1000:sample_rate=48000' \
  -t 1 -c:v libx264 -pix_fmt yuv420p -c:a aac input.mkv

2. 用 ffprobe 查看 container 与 stream#

ffprobe -v error \
  -show_entries 'format=format_name,duration,size:stream=index,codec_type,codec_name,profile,width,height,r_frame_rate,bit_rate' \
  -of json input.mkv

预期能看到 format_name 近似 matroska,webm,video stream 的 codec_nameh264profileHigh、尺寸为 320×180、r_frame_rate30/1,另有一个 aac audio stream。短素材或某些容器可能不提供 stream-level bit_rate,字段缺失不等于没有数据。ffprobe 官方文档 说明 -show_entries 用于筛选字段,-of json 用于 JSON 输出。

3. Remux 成 MP4,不重新编码#

ffmpeg -i input.mkv \
  -map 0:v:0 -map 0:a:0 \
  -c copy remuxed.mp4

再次对 remuxed.mp4 执行上面的 ffprobe 命令,预期 container 变成 MOV/MP4 family,而 video 与 audio 的 codec_name 仍是 h264aac。这表示 encoded packets 被复制到了新容器;两个文件的二进制内容和 container metadata 不会相同,但没有发生重新编码。若输入含 MP4 不接受的 codec、subtitle 或必要信息不足,命令可能失败,这时不能靠 -c copy 强行兼容。

4. Transcode 成一组明确的 H.264/AAC 参数#

ffmpeg -i input.mkv \
  -map 0:v:0 -map 0:a:0 \
  -c:v libx264 -crf 23 -preset medium -pix_fmt yuv420p \
  -c:a aac -b:a 128k transcoded.mp4

这里 -crf 23 选择 libx264 的 constant-quality mode,-preset medium 选择 encoding preset,-pix_fmt yuv420p 明确输出 pixel format,audio 则重新编码为 128 kbit/s AAC。输出仍是 H.264 + AAC 的 MP4,但 video 与 audio 都已重新编码,体积、bitrate 和画质可能改变;FFmpeg 对 crfpreset 与 Profile 等选项的当前定义见 libx264 wrapper 文档

实际处理自己的文件时,应先 ffprobe,再决定能否 remux;只有 codec、分辨率、frame rate、pixel format 或兼容性确实需要变化时,才 transcode。

5. 生成并识别最小 HEVC/MP4 样本#

下面用 FFmpeg 的 libx265 wrapper 编码一秒测试画面,并用 hvc1 sample entry 写入 MP4:

ffmpeg -v error -f lavfi -i 'testsrc2=size=320x180:rate=30' \
  -t 1 -c:v libx265 -preset medium -crf 28 \
  -x265-params log-level=error -tag:v hvc1 -an hevc.mp4

ffprobe -v error -select_streams v:0 \
  -show_entries stream=codec_name,codec_long_name,profile,codec_tag_string,pix_fmt \
  -of default=noprint_wrappers=1 hevc.mp4

本机预期输出包含 codec_name=hevcprofile=Maincodec_tag_string=hvc1pix_fmt=yuv420p。这里的 CRF 28 只为生成演示文件;x265 与 x264 的 CRF 标尺、编码工具和结果不同,不能把它与前例的 x264 CRF 23 直接比较。

参考资料#

资料与链接核验日期:2026-08-26。

本文共 5154 字,创建于 Aug 26, 2026

相关标签: Multi-Media, Tools, ByAI