常用视频格式转换nv12,i420,i444,p010

news/2024/11/20 6:20:16/

文章目录

    • 视频存储格式
    • NV12转I420
    • NV12转I444
    • P010转I420

视频存储格式

P010格式与NV12格式一样,区别就是两个字节存一个像素值。

Y Y Y Y Y Y      Y Y Y Y Y Y      Y Y Y Y Y Y      Y Y Y Y Y Y
Y Y Y Y Y Y      Y Y Y Y Y Y      Y Y Y Y Y Y      Y Y Y Y Y Y
Y Y Y Y Y Y      Y Y Y Y Y Y      Y Y Y Y Y Y      Y Y Y Y Y Y
Y Y Y Y Y Y      Y Y Y Y Y Y      Y Y Y Y Y Y      Y Y Y Y Y Y
U U U U U U      V V V V V V      U V U V U V      V U V U V U
V V V V V V      U U U U U U      U V U V U V      V U V U V U- I420 -          - YV12 -         - NV12 -         - NV21 -Y Y Y Y Y Y      Y Y Y Y Y Y    
Y Y Y Y Y Y      Y Y Y Y Y Y
Y Y Y Y Y Y      Y Y Y Y Y Y
Y Y Y Y Y Y      Y Y Y Y Y Y
U U U U U U      V V V V V V
U U U U U U      V V V V V V
U U U U U U      V V V V V V
U U U U U U      V V V V V V
V V V V V V      U U U U U U
V V V V V V      U U U U U U
V V V V V V      U U U U U U
V V V V V V      U U U U U U- I444 -          - YV24 -

NV12转I420

//NV12 转 I420 
void NV12_to_I420(uint8_t* nv12data, uint8_t* i420data, int frameWidth, int frameHeight) {uint8_t* nv12_src[2];nv12_src[0] = nv12data;nv12_src[1] = nv12_src[0] + frameWidth * frameHeight;uint8_t* yuv420_dst[3];yuv420_dst[0] = i420data;yuv420_dst[1] = yuv420_dst[0] + frameWidth * frameHeight;yuv420_dst[2] = yuv420_dst[1] + frameWidth * frameHeight / 4;//Ymemcpy(yuv420_dst[0], nv12_src[0], frameWidth * frameHeight);// for(int i = 0; i < frameWidth * frameHeight ; i++){//     *(yuv420_dst[0]++) = *(nv12_src[0] + i);// }for (int i = 0; i < frameWidth * frameHeight / 2; i++) {unsigned char b = *(nv12_src[1] + i);if (i % 2 == 0) {//U*(yuv420_dst[1]++) = *(nv12_src[1] + i);}else {//V*(yuv420_dst[2]++) = *(nv12_src[1] + i);}}
}

NV12转I444

//NV12转YUV444
void NV12_to_I444(uint8_t* nv12data, uint8_t* i444data, int frameWidth, int frameHeight) {uint8_t* nv12_src[2];nv12_src[0] = nv12data;nv12_src[1] = nv12_src[0] + frameWidth * frameHeight;uint8_t* yuv444_dst[3];yuv444_dst[0] = i444data;yuv444_dst[1] = yuv444_dst[0] + frameWidth * frameHeight;yuv444_dst[2] = yuv444_dst[1] + frameWidth * frameHeight;//Ymemcpy(yuv444_dst[0], nv12_src[0], frameWidth * frameHeight);//UVfor (int i = 0; i < frameWidth * frameHeight / 2; i++) {if (i % 2 == 0) {//U,NV12中一位对应444中4位*(yuv444_dst[1]) = *(nv12_src[1] + i);*(yuv444_dst[1] + frameWidth) = *(nv12_src[1] + i);yuv444_dst[1]++;*(yuv444_dst[1]) = *(nv12_src[1] + i);*(yuv444_dst[1] + frameWidth) = *(nv12_src[1] + i);yuv444_dst[1]++;}else {//V,NV12中一位对应444中4位*(yuv444_dst[2]) = *(nv12_src[1] + i);*(yuv444_dst[2] + frameWidth) = *(nv12_src[1] + i);yuv444_dst[2]++;*(yuv444_dst[2]) = *(nv12_src[1] + i);*(yuv444_dst[2] + frameWidth) = *(nv12_src[1] + i);yuv444_dst[2]++;}if ((i > frameWidth && i % frameWidth == 0)) {//UV分量跳行yuv444_dst[1] = yuv444_dst[1] + frameWidth;yuv444_dst[2] = yuv444_dst[2] + frameWidth;}}
}

P010转I420

p010有多种格式,区别在于数据的存放位置,即10bit的数据是如何放在16bit的空间里面的。
//P010转I420
void P010le_to_I420(uint8_t* p010data, uint8_t* i420data, int frameWidth, int frameHeight) {uint8_t* p010_src[2];p010_src[0] = p010data;p010_src[1] = p010_src[0] + frameWidth * frameHeight * 2;uint8_t* yuv420_dst[3];yuv420_dst[0] = i420data;yuv420_dst[1] = yuv420_dst[0] + frameWidth * frameHeight;yuv420_dst[2] = yuv420_dst[1] + frameWidth * frameHeight / 4;uint16_t Y, U, V;//Yfor (int i = 0; i < frameWidth * frameHeight; i++) {Y = *((uint16_t*)p010_src[0] + i) >> 6;Y = Y < 64 ? 64 : Y;Y = Y > 940 ? 940 : Y;*(yuv420_dst[0]++) = (uint8_t)(Y >> 2);}//UVfor (int i = 0; i < frameWidth * frameHeight / 2; i++) {if (i % 2 == 0) {U = (*((uint16_t*)p010_src[1] + i)) & 0x00ff;*(yuv420_dst[1]++) = U;}else {V = (*((uint16_t*)p010_src[1] + i)) & 0x00ff;*(yuv420_dst[2]++) = V;}}
}
void P010_to_I420(uint8_t* P010data, uint8_t* I420data, int frameWidth, int frameHeight) {uint8_t* p010_src[2];p010_src[0] = P010data;p010_src[1] = p010_src[0] + frameWidth * frameHeight * 2;uint8_t* yuv420_dst[3];yuv420_dst[0] = I420data;yuv420_dst[1] = yuv420_dst[0] + frameWidth * frameHeight;yuv420_dst[2] = yuv420_dst[1] + frameWidth * frameHeight / 4;uint8_t Y, U, V;//Yfor (int i = 0; i < frameWidth * frameHeight; i++) {Y = *((uint16_t*)p010_src[0] + i) >> 8;Y = Y < 16 ? 16 : (Y > 235 ? 235 : Y);*(yuv420_dst[0]++) = Y;}//UVfor (int i = 0; i < frameWidth * frameHeight / 2; i++) {if (i % 2 == 0) {U = (*((uint16_t*)p010_src[1] + i)) >> 8;//U = (((U - 128) * (200 + 256)) >> 8) + 128;U = U < 16 ? 16 : (U > 235 ? 235 : U);*(yuv420_dst[1]++) = U;}else {V = (*((uint16_t*)p010_src[1] + i)) >> 8;//V = (((V - 128) * (200 + 256)) >> 8) + 128;V = V < 16 ? 16 : (V > 235 ? 235 : V);*(yuv420_dst[2]++) = V;}}
}

http://www.ppmy.cn/news/287159.html

相关文章

百度领航团零基础Python-Day1

百度领航团零基础Python-Day1 文章目录 简介安装执行python代码语法基础第一个 Python 程序基本数据类型Python数据类型转换算术运算符条件语句循环语句for 循环 作业 课程链接&#xff1a;https://aistudio.baidu.com/aistudio/course/introduce/7073 简介 python是一种解释性…

树莓派中的 IM 私有云支持多少并发?

美信拓扑技术分享系列 0x01。关注「美信拓扑」微信公众号&#xff0c;第一时间阅读本系列后续文章&#xff0c;了解美信拓扑IM的协议、架构和源码。 4000人同时在线&#xff0c;这是美信拓扑 IM 私有云的数据。是的&#xff0c;只需要一个400块的树莓派4B。注意&#xff0c;这不…

砸冰箱维权是“公益秀”

先引用一篇老罗的《秋菊男的故事》&#xff0c;这篇文章最早刊登在《独唱团》上。 十四年前......这是一个真实的故事。十四年前&#xff0c;我在东北老家延吉市的一个外语培训机构学过一段时间的许国璋英语。这是一个韩国人开的私立学校&#xff0c;名字 很土&#xff0c;叫三…

钱大妈,一家卖猪肉的广告公司

文 | 易不二 来源 | 螳螂财经&#xff08;ID:TanglangFin&#xff09; “中国的一个小区一般有3000户就是1万人&#xff0c;一万人在欧美是一个大型的小镇。在欧美&#xff0c;一个小镇就会有一家大卖场很多的商业配套。所以你们可以试想中国未来的小区会迸发出什么样的红利&…

一篇文章入门python基础

python python入门 人生苦短&#xff0c;我用python python的特点&#xff1a;简洁性、易读性、可扩展性 my_number3200 guess_numberinput("这台冰箱多少钱&#xff1f;") guess_numberint(guess_number) while guess_number!my_number:if guess_number<my_nu…

一个女人究竟该花多少钱?

奥斯卡王尔德说&#xff1a;“量入为出的人是最缺乏想象力的。”这话放在朱迪思莱文&#xff08;Judith Levine&#xff09;身上可不太公平。 最近&#xff0c;美国作家朱迪思莱文的新著《不买东西》&#xff08;Not Buying It&#xff09;在英国出版&#xff0c;有趣的是&…

飞桨/百度领航团/零基础Python 课节1: Python环境搭建及入门

课节1: Python环境搭配搭建入门教程 TIOBE 指数&#xff1a;最受关注的语言排行榜 python的特点 简洁性 实现同样的功能&#xff0c;python代码的行数往往是java的1/5。 易读性 代码像纯英语一样易于理解。 可扩展性 开源&#xff0c;任何人都可以做出自己的贡献。 课…

玩推推需三思而后行,晒晒昆明结婚需要多少钱

高中时候,老师常说,不要谈恋爱,这要负责任的。 那么负责任要多少钱呢&#xff1f; 我就以自己实际情况告诉大家结婚需要多少钱&#xff0c;希望各位伸手党玩推推需三思而后行。 1、住房一套&#xff0c;市区100平方米 我的房子在王府井附近&#xff0c;其实当时房子不贵&#x…