10v转16v_nv12和nv21区别

10v转16v_nv12和nv21区别摘要关于像素格式转换,搜到的帖子基本是NV16转RGB24或NV12转RGB24,对于NV16转NV12并没太多资料,因此我打算参照这两个像素格式的结构,实现这个转换接口。NV16像素格式介绍NV16可以理解为yuyv像素格式的变种,属于YUV422SP类型。整帧图像的大小为Width*Height*2。其像素格式如下:start+00: Y’00 Y’01 Y’02 …

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

摘要

关于像素格式转换,搜到的帖子基本是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
由图可见,转换后色度都是正确的。
在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/189897.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • idea集成svn使用教程_idea导入svn项目

    idea集成svn使用教程_idea导入svn项目1.查看svn仓库调出svn视图:连接svn服务器:连接后效果如下:补充:如果输入正确的连接地址后出现错误—系统找不到指定的文件请到设置中检查(File|Settings|VersionControl|Subversion)SVC客户端路径配置的对不对(选中bin目录下的svn.exe)?如果找不到svn.exe,看下图解释2.Idea集成svn如果不小心选错了其他选项,比如cvs,可以在settings中重新选择;…

    2022年10月18日
    0
  • 二叉树的五大性质及证明「建议收藏」

    二叉树的五大性质及证明「建议收藏」二叉树(BinaryTree)定义:一棵二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根结点加上两棵分别称为左子树和右子树的、互不相交的二叉树组成。特点:每个结点至多只有两棵子树(二叉树中不存在度大于2的结点)五种形态: 1.性质1性质1 在二叉树的第i层至多有2^(i-1)个结点。(i&gt;=1) [用数学归纳法证明]  …

    2022年5月18日
    39
  • 2021navicat激活码(注册激活)

    (2021navicat激活码)2021最新分享一个能用的的激活码出来,希望能帮到需要激活的朋友。目前这个是能用的,但是用的人多了之后也会失效,会不定时更新的,大家持续关注此网站~IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html…

    2022年3月28日
    702
  • U8 8.9 数据库置疑恢复方法

    U8 8.9 数据库置疑恢复方法A.我们使用默认方式建立一个供恢复使用的数据库(如test)。可以在SQLServerEnterpriseManager里面建立。B.停掉数据库服务器。C.将刚才生成的数据库的日志文件test_log.ldf删除,用要恢复的数据库mdf文件覆盖刚才生成的数据库数据文件test_data.mdf。D.启动数据库服务器。此时会看到数据库test的状态为“置疑”。这时候不能对此数据库进行任何操作。…

    2022年8月20日
    3
  • executeupdate mysql_executeUpdate(sql) 返回值是什么?

    executeupdate mysql_executeUpdate(sql) 返回值是什么?展开全部executeUpdate(sql)的返回值是一个整数(int)。当executeUpdate(sql)是INSERT、UPDATE或DELETE语句时e69da5e6ba9062616964757a686964616f31333431356566,返回的是受影响的行数(即更新的行数)。当executeUpdate(sql)是CREATETABLE或DROPTABLE等不…

    2022年10月20日
    1
  • pytorch交叉熵损失函数_yolov5损失函数

    pytorch交叉熵损失函数_yolov5损失函数均方损失函数:这里,loss,x,y的维度是一样的,可以使向量或者矩阵,i是下标。很多的loss函数都有size_average和reduce两个布尔类型的参数,因为一般损失函数都是直接计算batch的数据,因此返回的loss结果都是维度为(batch_size,)的向量。1)如果reduce=False,那么size_average参数失效,直接返回向量形式的loss2)如果…

    2022年9月17日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号