FFmpeg 像素格式(pix_fmt)通关指南:从 YUV420P 到 NV12、RGB24 到底怎么选

目录

一、先建立两个底层认知

[1. pix_fmt 决定的是「内存布局」,不是「颜色」](#1. pix_fmt 决定的是「内存布局」,不是「颜色」)

[2. YUV 的三个关键维度](#2. YUV 的三个关键维度)

[二、YUV Planar 三剑客](#二、YUV Planar 三剑客)

[1.YUV420P(AV_PIX_FMT_YUV420P,别名 I420)](#1.YUV420P(AV_PIX_FMT_YUV420P,别名 I420))

2.YUV422P(AV_PIX_FMT_YUV422P)

3.YUV444P(AV_PIX_FMT_YUV444P)

[三、Semi-Planar:NV12 / NV21](#三、Semi-Planar:NV12 / NV21)

1.NV12(AV_PIX_FMT_NV12)

2.NV21(AV_PIX_FMT_NV21)

[四、Packed YUV(采集卡 / UVC 摄像头)](#四、Packed YUV(采集卡 / UVC 摄像头))

[1.YUYV422(AV_PIX_FMT_YUYV422,也叫 YUY2)](#1.YUYV422(AV_PIX_FMT_YUYV422,也叫 YUY2))

2.UYVY422(AV_PIX_FMT_UYVY422)

[五、RGB 家族(给人看 / 给算法看)](#五、RGB 家族(给人看 / 给算法看))

1.RGB24(AV_PIX_FMT_RGB24)

2.BGR24(AV_PIX_FMT_BGR24)

[3.RGBA / BGRA / ARGB](#3.RGBA / BGRA / ARGB)

4.GRAY8

[六、10bit / HDR 常用格式(别再只认 8bit 了)](#六、10bit / HDR 常用格式(别再只认 8bit 了))

[七、带 Alpha 的 YUV](#七、带 Alpha 的 YUV)

YUVA420P(AV_PIX_FMT_YUVA420P)

八、一张选型速查表

九、三个新手必踩的坑

[坑 1:颜色发灰](#坑 1:颜色发灰)

[坑 2:sws_scale 崩溃](#坑 2:sws_scale 崩溃)

[坑 3:Stride ≠ Width](#坑 3:Stride ≠ Width)

十、总结


觉得有用,就请您帮忙点赞转发收藏吧,您的鼓励是我创作的动力,多谢看官。

由于能力水平有限,文中的错误或不严谨的地方在所难免,还请批评指正。

做音视频开发的人,基本都曾被 pix_fmt坑过:解码出来是 nv12,OpenCV 死活打不开,转成 yuv420p后颜色发灰。sws_scale崩了,发现是 planar / semi-planar 没分清。硬解出来一堆 cuda、vaapi不知道怎么落地,本文就把FFmpeg 里最常见、最实用的 pix_fmt按「是什么 / 内存怎么排 / 用在哪」捋一遍。

一、先建立两个底层认知

1. pix_fmt 决定的是「内存布局」,不是「颜色」

同一个画面,可以存成:

  • YUV420P(省一半带宽)

  • NV12(给 GPU/硬编吃)

  • RGB24(给人眼和 OpenCV 看)

颜色最终一样,但字节排列方式完全不同

FFmpeg 中对应的是枚举:

复制代码
enum AVPixelFormat;

命令行里就是:

复制代码
-pix_fmt yuv420p

查全部支持格式:

复制代码
ffmpeg -pix_fmts

2. YUV 的三个关键维度

维度 说明
色度子采样 444 / 422 / 420
存储方式 Planar / Semi-Planar / Packed
位深 8bit / 10bit / 16bit

人眼对亮度敏感、对色度不敏感,所以 YUV 能「色度降采样」省数据。


二、YUV Planar 三剑客

1.YUV420P(AV_PIX_FMT_YUV420P,别名 I420)

  • 布局:Y 平面 → U 平面 → V 平面

  • 采样:4:2:0(每 2×2 像素共享 1 个 U、1 个 V)

  • 占用:12 bit/pixel = 1.5 字节/像素

复制代码
YY YY YY YY
YY YY YY YY
U  U  U  U 
V  V  V  V
  • FFmpeg 软解默认

  • x264 / x265 / VP9 / AV1 最爱吃

  • OpenCV、libswscale、自写算法最友好

复制代码
ffmpeg -i in.mp4 -pix_fmt yuv420p out.yuv

工程里说「I420」基本就是它。


2.YUV422P(AV_PIX_FMT_YUV422P)

  • 水平色度减半,垂直不变

  • 16 bit/pixel

  • 专业剪辑、广播、ProRes 中间格式

适合:多次转码、调色、字幕渲染。


3.YUV444P(AV_PIX_FMT_YUV444P)

  • 无子采样,YUV 完全 1:1

  • 24 bit/pixel,体积爆炸

  • 影视母带、绿幕抠像、无损中间件

复制代码
ffmpeg -i in.mov -pix_fmt yuv444p -c:v libx264 -qp 0 out.mkv

三、Semi-Planar:NV12 / NV21

1.NV12(AV_PIX_FMT_NV12)

  • Y 单独一面

  • UV 交错存:UVUVUV...

  • 仍是 4:2:0,1.5 字节/像素

复制代码
YYYYYYYY
UVUVUVUV

优点:

  • GPU 纹理上传极快

  • iOS Camera、Metal、Vulkan、DXVA、MediaCodec 原生喜欢

  • 硬编硬解零拷贝友好

骁龙/iOS 上 NV12 → GPU 纹理比 I420 快好几倍。


2.NV21(AV_PIX_FMT_NV21)

  • 和 NV12 唯一区别:VUVUVU...

  • Android Camera 历史默认输出

    Y 平面
    VUVUVU...

NV12 ↔ NV21 只交换 U/V,不重算像素。


四、Packed YUV(采集卡 / UVC 摄像头)

1.YUYV422(AV_PIX_FMT_YUYV422,也叫 YUY2)

  • 打包存储:Y0 U Y1 V

  • 2 像素共用 UV

  • 16 bit/pixel

  • USB 摄像头、UVC 设备常见

2.UYVY422(AV_PIX_FMT_UYVY422)

  • U Y0 V Y1

  • 专业 SDI、采集卡

Packed 特点:只有一个 data0,没有 plane 概念,sws_scale 时要注意 stride。


五、RGB 家族(给人看 / 给算法看)

1.RGB24(AV_PIX_FMT_RGB24)

  • RGB RGB RGB

  • 24 bit/pixel

  • 截图、图像算法、rawvideo 管道

    ffmpeg -i in.mp4 -pix_fmt rgb24 out.rgb

2.BGR24(AV_PIX_FMT_BGR24)

  • OpenCV Mat默认就是它

  • 顺序反了,直接当 RGB 会蓝脸

3.RGBA / BGRA / ARGB

  • 32 bit/pixel

  • 带透明通道

  • SDL、OpenGL、UI 合成、水印

注意大小端:rgb32在小端其实是 BGRA。

4.GRAY8

  • 单通道 8bit

  • 人脸识别、亮度图、预处理


六、10bit / HDR 常用格式(别再只认 8bit 了)

格式 说明
yuv420p10le 10bit 420,H.265/VP9/AV1 主流
yuv422p10le ProRes 4444 XQ 常用
yuv444p10le HDR 调色中间格式
p010le NV12 的 10bit 版(半平面)
复制代码
ffmpeg -i hdr.mov -pix_fmt yuv420p10le -c:v libx265 out.mkv

10bit 不是"颜色更多",是"梯度更细、少色带"。


七、带 Alpha 的 YUV

YUVA420P(AV_PIX_FMT_YUVA420P)

  • YUV420 + 独立 A 平面

  • 网页动画、合成、转场

  • 普通播放器不支持,别拿来喂 H.264


八、一张选型速查表

场景 推荐 pix_fmt
H264/HEVC 编码输入 yuv420p/ nv12
FFmpeg 软解 + CPU 算法 yuv420p
iOS / GPU 纹理 nv12
Android Camera nv21(转 nv12
USB 摄像头 yuyv422
OpenCV 处理 bgr24
专业调色/母带 yuv422p/ yuv444p
HDR / 10bit yuv420p10le
带透明视频 yuva420p/ rgba

九、三个新手必踩的坑

坑 1:颜色发灰

不是格式错了,是色彩范围没对齐

  • 有限范围 TV 16--235

  • 全范围 PC 0--255

复制代码
-color_range tv / pc

坑 2:sws_scale 崩溃

Planar 格式:

复制代码
data[0]=Y, data[1]=U, data[2]=V

NV12:

复制代码
data[0]=Y, data[1]=UV

别把 NV12 当 YUV420P 拷。

坑 3:Stride ≠ Width

frame->linesize[0]经常比 width大(内存对齐)。

写裸数据一定要按 linesize 走,不然花屏。


十、总结

YUV420P 是软件标准,NV12 是硬件标准,RGB24/BGR24 是人眼与算法标准;420 省带宽、444 保画质、10bit 防色带。

真正做项目时,格式选择不是"哪个高级用哪个",而是:

解码器输出 → 处理链路 → 编码器/渲染器输入​ 三段对齐。

相关推荐
AI码农小姐姐4 小时前
AI漫剧推文短视频推理加速:LCM-LoRA与少步采样实践
人工智能·音视频·ai工具·ai漫剧
2601_962380764 小时前
考研数学公式推导和解题步骤怎么做成动画讲解视频
音视频
Niuguangshuo5 小时前
论文解读:w2v-BERT,把 wav2vec 2.0 和 BERT 合成一根管子的语音 SSL
算法·音视频·语音识别
科技小E5 小时前
国标视频分析平台EasyGBS×自动化AI算法训练服务器DLTM,把通用AI炼成你的现场AI
算法·自动化·音视频
揽秀亭长5 小时前
视频转脚本如何实现自动化?完整流程与技术思路
人工智能·音视频
AI码农小姐姐5 小时前
AI漫剧推文短视频生成中的数据版本管理:基于DVC的模型与素材追踪实践
人工智能·音视频·ai工具·ai漫剧
揽秀亭长6 小时前
视频转脚本实际怎么做?对比3个不同方案,拆解视频转脚本不同技术流程
人工智能·音视频
换个昵称都难6 小时前
webrtc音频调参(WebRTC M153/7985 APM + NetEq 100+ 参数表)
音视频
m0_614523557 小时前
剪映数字人视频口播不自然怎么办?从音频断句到口型验收
音视频·视频编辑
Niuguangshuo7 小时前
论文解读:Paraformer,非自回归中文 ASR 的并行 Transformer
算法·音视频·语音识别