YUV格式学习:YUV420P、YV12、NV12、NV21格式转换成RGB24
生活随笔
收集整理的這篇文章主要介紹了
YUV格式学习:YUV420P、YV12、NV12、NV21格式转换成RGB24
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
YUV420有打包格式(Packed),一如前文所述。同時還有平面格式(Planar),即Y、U、V是分開存儲的,每個分量占一塊地方,其中Y為width*height,而U、V合占Y的一半,該種格式每個像素占12比特。根據U、V的順序,分出2種格式,U前V后即YUV420P,也叫I420,V前U后,叫YV12(YV表示Y后面跟著V,12表示12bit)。另外,還有一種半平面格式(Semi-planar),即Y單獨占一塊地方,但其后U、V又緊挨著排在一起,根據U、V的順序,又有2種,U前V后叫NV12,在國內好像很多人叫它為YUV420SP格式;V前U后叫NV21。這種格式似乎比NV16稍受歡迎。
首先給出轉換查詢表的生成函數,代碼是在網上找來的,如下:
static long int crv_tab[256]; static long int cbu_tab[256]; static long int cgu_tab[256]; static long int cgv_tab[256]; static long int tab_76309[256]; static unsigned char clp[1024]; //for clip in CCIR601 void init_yuv420p_table() { long int crv,cbu,cgu,cgv; int i,ind; static int init = 0;if (init == 1) return;crv = 104597; cbu = 132201; /* fra matrise i global.h */ cgu = 25675; cgv = 53279; for (i = 0; i < 256; i++) { crv_tab[i] = (i-128) * crv; cbu_tab[i] = (i-128) * cbu; cgu_tab[i] = (i-128) * cgu; cgv_tab[i] = (i-128) * cgv; tab_76309[i] = 76309*(i-16); } for (i = 0; i < 384; i++) clp[i] = 0; ind = 384; for (i = 0;i < 256; i++) clp[ind++] = i; ind = 640; for (i = 0;i < 384; i++) clp[ind++] = 255;init = 1; }下面給出YUV420平面格式的轉換函數,如下:
/** 內存分布w+--------------------+|Y0Y1Y2Y3... ||... | h|... || |+--------------------+|U0U1 ||... | h/2|... || |+----------+|V0V1 ||... | h/2|... || |+----------+w/2*/ void yuv420p_to_rgb24(YUV_TYPE type, unsigned char* yuvbuffer,unsigned char* rgbbuffer, int width,int height) {int y1, y2, u, v; unsigned char *py1, *py2; int i, j, c1, c2, c3, c4; unsigned char *d1, *d2; unsigned char *src_u, *src_v;static int init_yuv420p = 0;src_u = yuvbuffer + width * height; // usrc_v = src_u + width * height / 4; // vif (type == FMT_YV12){src_v = yuvbuffer + width * height; // vsrc_u = src_u + width * height / 4; // u}py1 = yuvbuffer; // ypy2 = py1 + width; d1 = rgbbuffer; d2 = d1 + 3 * width; init_yuv420p_table();for (j = 0; j < height; j += 2) { for (i = 0; i < width; i += 2) {u = *src_u++; v = *src_v++; c1 = crv_tab[v]; c2 = cgu_tab[u]; c3 = cgv_tab[v]; c4 = cbu_tab[u]; //up-left y1 = tab_76309[*py1++]; *d1++ = clp[384+((y1 + c1)>>16)]; *d1++ = clp[384+((y1 - c2 - c3)>>16)]; *d1++ = clp[384+((y1 + c4)>>16)]; //down-left y2 = tab_76309[*py2++]; *d2++ = clp[384+((y2 + c1)>>16)]; *d2++ = clp[384+((y2 - c2 - c3)>>16)]; *d2++ = clp[384+((y2 + c4)>>16)]; //up-right y1 = tab_76309[*py1++]; *d1++ = clp[384+((y1 + c1)>>16)]; *d1++ = clp[384+((y1 - c2 - c3)>>16)]; *d1++ = clp[384+((y1 + c4)>>16)]; //down-right y2 = tab_76309[*py2++]; *d2++ = clp[384+((y2 + c1)>>16)]; *d2++ = clp[384+((y2 - c2 - c3)>>16)]; *d2++ = clp[384+((y2 + c4)>>16)]; }d1 += 3*width;d2 += 3*width;py1 += width;py2 += width;} }再給出YUV420SP轉換的函數,如下:
void yuv420sp_to_rgb24(YUV_TYPE type, unsigned char* yuvbuffer,unsigned char* rgbbuffer, int width,int height) {int y1, y2, u, v; unsigned char *py1, *py2; int i, j, c1, c2, c3, c4; unsigned char *d1, *d2; unsigned char *src_u;static int init_yuv420p = 0;src_u = yuvbuffer + width * height; // upy1 = yuvbuffer; // ypy2 = py1 + width; d1 = rgbbuffer; d2 = d1 + 3 * width; init_yuv420p_table();for (j = 0; j < height; j += 2) { for (i = 0; i < width; i += 2) {if (type == FMT_NV12){u = *src_u++; v = *src_u++; // v緊跟u,在u的下一個位置}if (type == FMT_NV21){v = *src_u++; u = *src_u++; // u緊跟v,在v的下一個位置}c1 = crv_tab[v]; c2 = cgu_tab[u]; c3 = cgv_tab[v]; c4 = cbu_tab[u]; //up-left y1 = tab_76309[*py1++]; *d1++ = clp[384+((y1 + c1)>>16)]; *d1++ = clp[384+((y1 - c2 - c3)>>16)]; *d1++ = clp[384+((y1 + c4)>>16)]; //down-left y2 = tab_76309[*py2++]; *d2++ = clp[384+((y2 + c1)>>16)]; *d2++ = clp[384+((y2 - c2 - c3)>>16)]; *d2++ = clp[384+((y2 + c4)>>16)]; //up-right y1 = tab_76309[*py1++]; *d1++ = clp[384+((y1 + c1)>>16)]; *d1++ = clp[384+((y1 - c2 - c3)>>16)]; *d1++ = clp[384+((y1 + c4)>>16)]; //down-right y2 = tab_76309[*py2++]; *d2++ = clp[384+((y2 + c1)>>16)]; *d2++ = clp[384+((y2 - c2 - c3)>>16)]; *d2++ = clp[384+((y2 + c4)>>16)]; }d1 += 3*width;d2 += 3*width;py1 += width;py2 += width;} }
總結
以上是生活随笔為你收集整理的YUV格式学习:YUV420P、YV12、NV12、NV21格式转换成RGB24的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows 2008 R2_NLB网
- 下一篇: mac 上安装服务,查看服务,重启和关闭