拿到視頻的幀數(shù)據(jù)后对湃,可能width并不等于linesize,直接使用width來生成紋理會導(dǎo)致扭曲遗淳。
width是視頻的寬度拍柒,這個是實(shí)際的,linesize是一行數(shù)據(jù)的字節(jié)數(shù)量屈暗。圖像是2維的拆讯,但數(shù)據(jù)存儲確實(shí)1維的,即uint8_t*
恐锦,而不是用二維數(shù)組來存儲,不是每行數(shù)據(jù)單獨(dú)一個指針往果。
所以就需要知道一行的數(shù)據(jù)大小,這樣才能確定每一行的數(shù)據(jù)開頭在哪一铅。比如數(shù)據(jù)是:12345678,每行兩個陕贮,那第二行就是34,如果每行3個,那么就是456潘飘。
對于YUV420p,3個分量是分層的肮之,但看Y,每個像素的1個字節(jié)卜录,如果寬度為100戈擒,那么一行就有100個Y,那么linesize就是100。也就是說一般情況下艰毒,Y這個層的linesize就等于width,那么為什么會可能會不等于呢筐高?應(yīng)該是因?yàn)榫幋a的時候使用內(nèi)存對齊導(dǎo)致的。比如視頻寬度232,然后使用24作為對齊的基本單位丑瞧,那么linesize就會變成240柑土,會多出8個字節(jié)。
如果直接使用width作為linesize绊汹,為什么會導(dǎo)致扭曲稽屏?
假設(shè)正確數(shù)據(jù)是:
1234567x
1234567x
1234567x
x是對齊多出來的無用數(shù)據(jù),使用linesize為8就是正常顯示西乖,然后width是7狐榔,使用7就會變成:
1234567
x123456
7x12345
單看1或者2,就會發(fā)現(xiàn)變成傾斜的了获雕,實(shí)際看起來視頻就是這樣充滿了右斜的線薄腻。
怎么解決?
可以對視頻幀數(shù)據(jù)進(jìn)行重采樣,把多余的數(shù)據(jù)刪掉典鸡,比如上面被廓,把數(shù)據(jù)變成1234567 1234567 1234567
,使用linesize為7也是正確的。
只是這樣貌似消耗太大萝玷,要進(jìn)行大量的內(nèi)存拷貝嫁乘。
如果只是把linesize從width改為正確的值,視頻不扭曲了球碉,但是在右邊會出現(xiàn)因?yàn)闊o用數(shù)據(jù)導(dǎo)致的空白區(qū)(我測試在iOS上顯示綠色)蜓斧。
怎么去除這個空白區(qū)?
想象一下視頻裁剪睁冬,假如我們可以裁剪挎春,那么直接把右側(cè)那部分裁掉不就好了。
參考這篇文章texture對齊和裁剪,使用glPixelStorei(GL_UNPACK_ROW_LENGTH, linesize[0]);
可以讓紋理讀取數(shù)據(jù)的時候按照設(shè)定的大小讀取豆拨,這個值概念上跟linesize是一樣的直奋,這樣就不會把無效的數(shù)據(jù)讀取進(jìn)去了。