java yuv420sp转nv21_音视频编解码: YUV存储格式中的YUV420P,YUV420SP,NV12, NV21理解(转)

概述

之前介绍了YUV码流的采样格式,下面分析下YUV码流的存储格式,YUV码流的存储格式与采样格式息息相关。总的来讲,YUV存储格式主要分为两种:

planar 平面格式

指先连续存储所有像素点的 Y 分量,然后存储 U 分量,最后是 V 分量。

packed 打包模式

指每个像素点的 Y、U、V 分量是连续交替存储的。

根据采样方式和存储格式的不同,就有了多种 YUV 格式。这些格式主要是基于 YUV 4:2:2 和 YUV 4:2:0 采样。

常见的基于 YUV 4:2:2 采样的格式如下表:

1a605e9e662b428eab7ab1997626117b.png

常见的基于 YUV 4:2:0 采样的格式如下表:

8ae6388e8d93bbb75f7a6c1a13c7a3fe.png

更多的 YUV 格式信息参考这里:YUV pixel formats

基于YUV4:2:2采样的格式

YUV 4:2:2 采样规定了 Y 和 UV 分量按照 2: 1 的比例采样,两个 Y 分量公用一组 UV 分量。

【YUYV格式】

YUYV 格式是采用打包格式进行存储的,指每个像素点都采用 Y 分量,但是每隔一个像素采样它的 UV 分量,排列顺序如下:

Y0 UO Y1 V0 Y2 U2 Y3 V2

Y0 和 Y1 公用 U0 V0 分量,Y2 和 Y3 公用 U2 V2 分量….

4a26d2cb14cbc20aff38c45968cf7f02.gif

【UYVY格式】

UYVY 格式也是采用打包格式进行存储,它的顺序和 YUYV 相反,先采用 U 分量再采样 Y 分量,排列顺序如下:

U0 Y0 V0 Y1 U2 Y2 V2 Y3

Y0 和 Y1 公用 U0 V0 分量,Y2 和 Y3 公用 U2 V2 分量….

根据 UV 和 Y 的顺序还有其他格式,比如,YVYU 格式,VYUY 格式等等,原理大致一样了。

f436d6443213c4e04b416f10fca7498a.gif

【YUV422P格式】

YUV 422P 格式,又叫做 I422,采用的是平面格式进行存储,先存储所有的 Y 分量,再存储所有的 U 分量,再存储所有的 V 分量。

基于YUV 4:2:0采样的格式

基于 YUV 4:2:0 采样的格式主要有 YUV 420P 和 YUV 420SP 两种类型,每个类型又对应其他具体格式。

YUV 420P 类型

YU12 格式

YV12 格式

YUV 420SP 类型

NV12 格式

NV21 格式

YUV 420P 和 YUV 420SP 都是基于 Planar 平面格式 进行存储的,先存储所有的 Y 分量后, YUV420P 类型就会先存储所有的 U 分量或者 V 分量,而 YUV420SP 则是按照 UV 或者 VU 的交替顺序进行存储了,具体查看看下图:

YUV420P 的格式:

6b6f93946e1e3ab4825376aeadef597e.png

其在码流中的表现形式为:

40f54d17469448e34f0036595141f612.png

YUV420SP的格式:

6453d498ce8f56d8ab324344ac4eb87e.png

其在码流中的表现形式为:

ebef50c0c99068cb9db87c4de1cd6f31.png

【YU12和YV12格式】

YU12 和 YV12 格式都属于YUV 420P 类型,即先存储 Y 分量,再存储 U、V 分量,区别在于:YU12 是先 Y 再 U 后 V,而 YV12 是先 Y 再 V 后 U 。YV 12 的存储格式如下图所示:

2685814045024cc1173493600c446781.gif

YU 12 又称作 I420 格式,它的存储格式就是把 V 和 U 反过来了。

【NV12和NV21格式】

NV12 和 NV21 格式都属于 YUV420SP 类型。它也是先存储了 Y 分量,但接下来并不是再存储所有的 U 或者 V 分量,而是把 UV 分量交替连续存储。

7c4334374f3fc50931816a0ed47d1eb8.gif

需要注意的是,

NV12是iOS中有的模式,它的存储顺序是先存Y分量,再YV进行交替存储。

NV21是Android中有的模式,它的存储顺序是先存Y分量,再VU交替存储。

参考链接:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java实现YUV420换为NV21格式,可以使用以下代码: ```java public class Yuv420ToNv21Converter { private byte[] yuv420; private byte[] nv21; private int width; private int height; public Yuv420ToNv21Converter(byte[] yuv420, int width, int height){ this.yuv420 = yuv420; this.width = width; this.height = height; nv21 = new byte[width * height * 3 / 2]; // NV21格式占用的空间大小为width * height * 3 / 2 } public byte[] convert(){ int frameSize = width * height; int chromaSize = frameSize / 4; //将Y数据直接复制到NV21数组 System.arraycopy(yuv420, 0, nv21, 0, frameSize); //将V、U数据交叉复制到NV21数组 for (int i = 0; i < chromaSize; i++) { nv21[frameSize + i * 2] = yuv420[frameSize + i + chromaSize]; // 交叉复制V数据 nv21[frameSize + i * 2 + 1] = yuv420[frameSize + i]; // 交叉复制U数据 } return nv21; } } ``` 解析: 1. 创建一个Yuv420ToNv21Converter类,构造函数接收YUV420数据、图像宽度和高度。 2. 定义yuv420和nv21两个byte数组,分别保存输入的YUV420数据和换后的NV21数据。 3. 在构造函数初始化nv21数组,大小为width * height * 3 / 2,因为NV21格式占用的空间大小为Y数据的大小加上U、V数据的一半大小。 4. convert()方法实现YUV420到NV21换: - 将Y数据直接复制到NV21数组。 - 将V、U数据交叉复制到NV21数组,交叉复制时先放置V数据,再放置U数据。 5. 返回换后的nv21数组。 使用以上代码,可以将YUV420数据换为NV21格式,适用于需要处理视频或图像数据的Java应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值