NV16 转 NV12
生活随笔
收集整理的這篇文章主要介紹了
NV16 转 NV12
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
摘要
關于像素格式轉換,搜到的帖子基本是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的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java调用百度API实现翻译
- 下一篇: java使用百度翻译接口实现前后端翻译功