YUV格式转换、旋转

做过流媒体开发的人应该对YUV数据不陌生,YUV将视频帧编码成Y(亮度)、U(蓝色)、V(红色)三个分量,在内存中,Y分量长度为w*h,U、V分量长度一般为w/2 * h/2。基本上从摄像头采集到的视频数据都属于这种格式。在此主要介绍下YUV的一些格式间相互转换和视频帧旋转的实现。

基于三个分量在内存中的排列方式,YUV又分为多种不同的格式。在工作中我遇到过最多的,有如下四种格式:
- NV21
- YUV420SP
- YV12
- YUV420P

常见的几种YUV格式及三分量排列方式:

名称 排列方式 说明
NV21 YYY…VUVU…. Y分量在前,VU分量交替排在后面
YUV420SP YYY…UVUV…. Y分量在前,UV分量交替排在后面
YV12 YYY…VV..UU.. Y分量在前,其次是V分量,其次是U分量
YUV420P YYY…UU..VV.. Y分量在前,其次是U分量,其次是V分量

是不是绕晕了?其实有规律的,都是Y在前面,然后名称里带‘S’的,表示UV分量交错呈现;不带‘S’,表示UV分量分开呈现;最后U、V的顺序就要自己查资料了。

实际应用中,我们可能需要将YUV数据进行转换、旋转,比方说安卓硬编码目前不支持NV21和YV12,支持420P和420SP,那我们就需要将摄像头采集到的视频数据先转换成420P或420SP;还有,摄像头竖屏采集的时候,为了播放端能正常显示,我们需要将视频帧旋转90度。

理解了这几种格式的分量的排列方式,将它们相互之间进行转换也就不难了。下面我们做几个转换和旋转的示例。假设视频帧的宽、高分别为width、height

NV21转420SP:

// 跳过Y分量,将UV‘点’相互颠倒一下
int uLen = width*height*0.5;
int len = width*height;

for (int i=len; i< len + uLen; i++)
{
    jbyte temp = *(pData +i);
    *(pData + i) = *(pData + i +1);
    *(pData + i +1) = temp;
    ++i;
}

YV12转420P:

// 也是跳过Y分量,将UV‘块’颠倒一下
int
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值