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 防色带。

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

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

相关推荐
小白学大数据3 小时前
基于Python的抖音网页版视频点赞数增长趋势追踪系统设计与实现
开发语言·爬虫·python·搜索引擎·音视频
DogDaoDao3 小时前
FFmpeg 9.0 “Lei“ 正式发布:十年之后,以你之名
ffmpeg·音视频·实时音视频·视频编解码·ffprobe·ffmpeg 9.0
开开心心_Every3 小时前
电脑文件搜索软件支持内容和拼音搜索
linux·服务器·人工智能·r语言·pdf·音视频·symfony
weixin_495248404 小时前
带硬字幕的老视频也能出海:短剧出海翻译服务商如何擦除重制?
人工智能·音视频
weixin_446260854 小时前
Video-DeepResearch:面向下一代视频多模态深度研究智能体
人工智能·音视频
硅谷秋水15 小时前
EgoSteer:一种基于第一人称视角视频、实现可控灵巧操作的全栈系统
深度学习·机器学习·语言模型·机器人·音视频
波罗丁牌18 小时前
uni-app 实现视频聊天、屏幕分享,支持Android、HarmonyOS、iOS
android·uni-app·音视频
不爱记笔记21 小时前
视频转PPT工具测评:通义听悟、Ai好记、讯飞听见谁更懂画面信息?
人工智能·powerpoint·音视频
cpp_learner1 天前
FFmpeg H264视频编码全流程解析
ffmpeg