用V4L2成功採集到了YUYV視頻,然後需要將它編碼成h.264檔案,因為之前有做過將yuv420編碼成h.264的程式,所以覺得將yuv422編碼成h.264也是大同小異,應該挺簡單的。
於是我很開心的寫編碼函數了,編碼yuv420我是參考的這篇和這篇博文,我馬上下手,我感到聖母瑪麗亞正在向我招手,我覺得我馬上就要成功啦
^_^
可是,我知道,作為一個程式員,如果不遇上一些問題,不遇到一些困難,都會不好意思滴 ^_^
是啊,我遇到困難了,我編碼出來的視頻是花的,紅紅綠綠,好像春天百花齊放!
因為參考編碼yuv420的代碼中也是隔行掃描的,它的yuv序列是下面這樣:
YYYY
YYYY
UVUV
於是我天真的認為我的yuv422儲存的也是這樣的序列,因為它們都是隔行掃描啊。
後來知道了YUYV隔行掃描序列不是這樣的,yuv422的序列應該是下面這樣:
YU YV YU YV YU YV
就是說UV確實是交叉儲存,只不過得和Y一起交叉。
知道了這樣的儲存序列,要把其編碼成h.264就簡單啦。
下面看我的編碼代碼:
char *y = en->picture->img.plane[0];char *u = en->picture->img.plane[1];char *v = en->picture->img.plane[2];int is_y = 1, is_u = 1;int y_index = 0, u_index = 0, v_index = 0;int yuv422_length = 2 * en->param->i_width * en->param->i_height;//序列為YU YV YU YV,一個yuv422幀的長度 width * height * 2 個位元組for (i = 0; i < yuv422_length; ++i) {if (is_y) {*(y + y_index) = *(in + i);++y_index;is_y = 0;} else {if (is_u) {*(u + u_index) = *(in + i);++u_index;is_u = 0;} else {*(v + v_index) = *(in + i);++v_index;is_u = 1;}is_y = 1;}}
註:in 是指向yuv422序列的指標,即指向了yuv422的起始地址。
我們只要將yuv422序列中的
y 賦值給 plane[0]
u 賦值給 plane[1]
v 賦值給 plane[2], 就可以編碼了。