android nv21,NV21与I420

Android Camera对象通过setPreviewCallback 函数,在onPreviewFrame(byte[] data,Camera camera)中回调采集的数据就是NV21格式。而x264编码的输入数据却为I420格式。

因此,当我们采集到摄像头数据之后需要将NV21转为I420。

NV21和I420都是属于YUV420格式。而NV21是一种two-plane模式,即Y和UV分为两个Plane(平面),但是UV(CbCr)交错存储,2个平面,而不是分为三个。这种排列方式被称之为YUV420SP,而I420则称之为YUV420P。(Y:明亮度、灰度,UV:色度、饱和度)

下图是大小为4x4的NV21数据:Y1、Y2、Y5、Y6共用V1与U1,......

9ad01d4f824c

yuv.png

而I420则是

9ad01d4f824c

I420.png

可以看出无论是哪种排列方式,YUV420的数据量都为: wh+w/2h/2+w/2h/2 即为wh*3/2

将NV21转位I420则为:

Y数据按顺序完整复制,U数据则是从整个Y数据之后加一个字节再每隔一个字节取一次。

手机摄像头的图像数据来源于摄像头硬件的图像传感器,这个图像传感器被固定到手机上后会有一个默认的取景方向,这个取景方向坐标原点于手机横放时的左上角。当应用是横屏时候:图像传感器方向与屏幕自然方向原点一致。而当手机为竖屏时:

9ad01d4f824c

方向.png

传感器与屏幕自然方向不一致,将图像传感器的坐标系逆时针旋转90度,才能显示到屏幕的坐标系上。所以看到的画面是逆时针旋转了90度的,因此我们需要将图像顺时针旋转90度才能看到正常的画面。而Camera对象提供一个setDisplayOrientation接口能够设置预览显示的角度:

9ad01d4f824c

设置方向.png

根据文档,配置完Camera之后预览确实正常了,但是在onPreviewFrame中回调获得的数据依然是逆时针旋转了90度的。所以如果需要使用预览回调的数据,还需要对onPreviewFrame回调的byte[] 进行旋转。

旋转前:

9ad01d4f824c

yuv.png

后置摄像头需要顺时针旋转90度,旋转后:

9ad01d4f824c

yuv顺时针旋转90度.png

前置摄像头需要逆时针旋转90度,旋转后:

9ad01d4f824c

yuv逆时针旋转90度.png

前置摄像头可能还需要进一步镜像处理,镜像后:

9ad01d4f824c

yuv逆时针旋转90度&镜像.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值