摘要

关于像素格式转换,搜到的帖子基本是NV16转RGB24 或 NV12转RGB24,对于NV16转NV12并没太多资料,因此我打算参照这两个像素格式的结构,实现这个转换接口。

NV16像素格式介绍

NV16可以理解为yuyv像素格式的变种,属于YUV422SP类型。整帧图像的大小为 Width * Height * 2。其像素格式如下:

  • start + 00: Y00 Y01 Y02 Y03
  • start + 04: Y10 Y11 Y12 Y13
  • start + 08: Y20 Y21 Y22 Y23
  • start + 12: Y30 Y31 Y32 Y33
  • start + 16: Cb00 Cr00 Cb01 Cr01
  • start + 20: Cb10 Cr10 Cb11 Cr11
  • start + 24: Cb20 Cr20 Cb21 Cr21
  • start + 28: Cb30 Cr30 Cb31 Cr31

NV12像素格式介绍

NV12则属于YUV420SP类型,整帧图像的大小为 Width * Height * 3 / 2。其像素格式如下:

  • start + 00: Y00 Y01 Y02 Y03
  • start + 04: Y10 Y11 Y12 Y13
  • start + 08: Y20 Y21 Y22 Y23
  • start + 12: Y30 Y31 Y32 Y33
  • start + 16: Ub00 Ur00 Ub01 Ur01
  • start + 20: Ub10 Ur10 Ub11 Ur11

转换规则介绍

  • Y数据直接拷贝。
  • NV12的 Ubxx取值NV16奇数行的Cbxx
  • NV12的 Urxx取值NV16偶数行的Crxx

例如:

NV16              NV12
Cb00 Cb01  ----> Ub00 Ub01
Cr10 Cr11  ----> Vr00 Vr01
Cb20 Cb21  ----> Ub10 Ub11
Cr30 Cr31  ----> Vr10 Vr11

代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>/*** 功能:nv16像素格式转换为nv12像素格式* 参数介绍:* nv16_buff:NV16格式一帧数据,大小为 w * h * 2,作为函数输入。* nv12_buff:NV12格式的一帧数据,大小为 w * h * 3 / 2,作为函数输出。* w:图像的宽度。* h:图像高度。*/
int pixel_format_nv16_to_nv12(char *nv16_buff, char *nv12_buff, int w, int h)
{unsigned char *nv16_y = NULL;unsigned char *nv16_uv = NULL;unsigned char *nv12_y = NULL;unsigned char *nv12_u = NULL;unsigned char *nv12_v = NULL;int i, j, offset;if (!nv16_buff || !nv12_buff || ((w*h) <= 0)) {printf("ERROR: %s input args invalid!\n", __func__);return -EINVAL;}/* get the right point */nv16_y = (unsigned char *)nv16_buff;nv16_uv = (unsigned char *)nv16_buff + w * h;nv12_y = (unsigned char *)nv12_buff;nv12_u = (unsigned char *)nv12_buff + w * h;nv12_v = nv12_u + 1;/* copy y dates directly */memcpy(nv12_y, nv16_y, w * h);/* get nv12_uv dates from nv16_uv* * >>>> nv16 pix formate:* start + 0:   Y'00   Y'01   Y'02   Y'03* start + 4:  Y'10   Y'11   Y'12   Y'13* start + 8:  Y'20   Y'21   Y'22   Y'23* start + 12: Y'30   Y'31   Y'32   Y'33* start + 16: Cb00    Cr00    Cb01    Cr01* start + 20:  Cb10    Cr10    Cb11    Cr11* start + 24:  Cb20    Cr20    Cb21    Cr21* start + 28:  Cb30    Cr30    Cb31    Cr31** >>>> nv12 pix formate:* start + 0:  Y'00   Y'01   Y'02   Y'03* start + 4:  Y'10   Y'11   Y'12   Y'13* start + 8:  Y'20   Y'21   Y'22   Y'23* start + 12: Y'30   Y'31   Y'32   Y'33* start + 16: Ub00    Vr00* start + 18:  Ub01    Vr01* start + 20:  Ub10    Vr10* start + 22:  Ub11    Vr11** nv16的uv分量与 nv12的uv分量对于关系:* 偶数行取Cb值,奇数行取Cr值* Cb00 Cb01  ----> Ub00 Ub01* Cr10 Cr11  ----> Vr00 Vr01* Cb20 Cb21  ----> Ub10 Ub11* Cr30 Cr31  ----> Vr10 Vr11*//* 奇数行取Cb */offset = 0;for (i = 0; i < h; i+=2) {offset = i * w;for (j = 0; j < w; j+=2) {*nv12_u = *(nv16_uv + offset + j);nv12_u += 2;}}/* 偶数行取Cr */offset = 0;for (i = 1; i < h; i+=2) {offset = i * w;for (j = 1; j < w; j+=2) {*nv12_v = *(nv16_uv + offset + j);nv12_v += 2;}}return 0;
}

工程下载地址

工程地址:https://download.csdn.net/download/lyy901135/11458140

完整工程,包含main函数,以及测试输入的nv16图片,只需执行make编译后即可运行。

运行命令:./nv16_to_nv12 test.nv16 test.nv12

查看输出图片(nv12):ffplay -f rawvideo -video_size 1920x1080 -pixel_format nv12 test.nv12
由图可见,转换后色度都是正确的。

NV16 转 NV12相关推荐

  1. YUV格式学习:YUV420P、YV12、NV12、NV21格式转换成RGB24

    YUV420有打包格式(Packed),一如前文所述.同时还有平面格式(Planar),即Y.U.V是分开存储的,每个分量占一块地方,其中Y为width*height,而U.V合占Y的一半,该种格式每 ...

  2. OpenGL实践系列之开篇: NV21 vs NV12

    手机从摄像头采集的预览数据一般都是NV21 NV21 的存储格式是,以4 X 4 图片为例子 占用内存为 4 X 4 X 3 / 2 = 24 个字节 Y Y Y Y Y Y Y Y Y Y Y Y ...

  3. Python 读取 YUV(NV12) 视频文件-优化

    一.YUV 简介 YUV:是一种颜色编码方法,常使用在各个视频处理组件中 Y'UV, YCbCr, YPbPr等专有名词都可以称为 YUV,彼此有重叠 Y表示明亮度(单取此通道即可得灰度图),U和V则 ...

  4. yuv420,yuv420p,yuv420sp,nv12,nv21,I420,YV12概念区别

    yuv420有yuv420p和yuv420sp两种.如果不加特别说明,yuv420指的就是yuv420p.而yuv420p又可分为I420与YV12,yuv420sp也可分为NV12和NV21.它们的 ...

  5. YV12 and NV12异同,

    用videoCapture和IAMStreamConfig拿到的支持的格式列表. 发现支持2中图像格式,YV12和NV12. 具体是怎么样的内存分布不知道.查了些文档.自己修改了几个图.看出了点端倪 ...

  6. YUV格式学习:NV12和YUV420P格式互换

    NV12和YUV420的转换是在相同采样空间的转换,只是个别分量位置的调整,只要明白了Y.U.V分量的布置,就很容易写出来. 代码如下: /** yyyy yyyy uv uv -> yyyy ...

  7. YUV格式学习:NV16和YUV422P格式互换

    其实以前也实现过SP转P的格式,现在再完善一些,写成此文.由于是相同采样空间的转换,只是个别分量位置的调整,只要明白了Y.U.V分量的布置,就很容易写出来. 代码如下: /** yyyy yyyy u ...

  8. YUV格式学习:YUV422P、YV16、NV16、NV61格式转换成RGB24

    对于YUV422的格式,网上有一大堆资料,这里就不说了.直奔主题,给出如何转换的函数,一如既往,只用代码说事. YUV422有打包格式(Packed),一如前文所述.同时还有平面格式(Planar), ...

  9. android Camera相关问题及NV12剪裁旋转

    1.SurfaceView不显示画面,可能是xml设置了背景色,这回遮挡视频画面. 2.如果想保存方形视频,而又不是通过缩放,可以在预览的适合遮挡不需要的画面.录制的适合剪裁一下. 3.因为Camer ...

  10. yv12转nv12,nv12转I420

    yv12跟I420区别其实就是u.v顺序不一样,是平面格式,内存中u.v在连续的一块,nv12是打包格式,u.v交叉. yv12转nv12: void swapYV12toNV12(byte[] yv ...

最新文章

  1. (拆点+最小路径覆盖) bzoj 2150
  2. 将图片资源文件整合到DLL文件中
  3. 搜索引擎大调整:百度出“惊雷算法”后360搜索又将上线“八戒算法”
  4. 用JAVA日志来写诗
  5. VTK:图片之ImageRange3D
  6. Spring Boot(四)Spring Boot @ConfigurationProperties实例
  7. 【pyqt5学习】——tablewidget控件学习
  8. 固件类型bios好还是uefi好_uefi启动是什么意思 UEFI启动对比Bios启动优势在哪里
  9. STL3-MyArray动态数组类模板实现
  10. 泉州海事学校计算机,泉州海事学校寝室图片、校园环境好吗?
  11. 戴机械手表有哪些事情就不能做了?
  12. T450的Fn lock
  13. SQL Server子查询实例
  14. 启动vue项目的时候报错提示To install it, you can run: npm install --save core-js/modules/es.regexp.dot
  15. 人物肖像速写_骄傲家庭:肖像项目
  16. 2021全新整合单机游戏 PC电脑版中文合集系列下载持续更新
  17. 微软收购雅虎遇新难题 或遭中国反垄断法阻碍
  18. 2021年转行软件测试能有前景吗?
  19. Genesis公链加速区块链行业发展
  20. 内存条 udimm rdimm 等和 ECC 功能

热门文章

  1. oracle中的存储过程和存储函数的区别
  2. 解决apicloud中真机同步海马玩模拟器中每次都要升级apploader的问题
  3. MaxScript与外部程序通讯
  4. mysql sqlyog讲解_MySQL与sqlyog安装教程图文详解
  5. 冯氏集团于进博会发布报告,分析影响全球服装采购格局的五大因素
  6. linux mint 中文字体,Linux Mint字体设置
  7. 高通手机调试烧录—QFIL工具
  8. BitComet(比特彗星) BT磁力链下载推荐
  9. 联想M490 BIOS H1ET69WW(1.12)刷网卡白名单
  10. Android性能优化典范-第2季