文章目录
- 视频存储格式
- NV12转I420
- NV12转I444
- P010转I420
视频存储格式
P010格式与NV12格式一样,区别就是两个字节存一个像素值。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22Y 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
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29//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; //Y memcpy(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
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39//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; //Y memcpy(yuv444_dst[0], nv12_src[0], frameWidth * frameHeight); //UV for (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
复制代码
1
2p010有多种格式,区别在于数据的存放位置,即10bit的数据是如何放在16bit的空间里面的。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33//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; //Y for (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); } //UV for (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; } } }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35void 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; //Y for (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; } //UV for (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; } } }
最后
以上就是风趣冥王星最近收集整理的关于常用视频格式转换nv12,i420,i444,p010的全部内容,更多相关常用视频格式转换nv12内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复