解碼CPU上的4k(3840x2160 @ 60hz)視頻以渲染到OpenGL ES紋理的軟件過程的最佳方式是什麼?將4k視頻呈現爲OpenGL ES紋理的最快方法?
我目前的做法如下:
創建像素緩衝器對象:
glGenBuffers(1, &pbo_id);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo_id);
分配3840x2160x4(寬度×高度×BPP)到PBO:
glBufferData(GL_PIXEL_UNPACK_BUFFER, size, NULL, GL_STREAM_DRAW);
地圖的PBO進入客戶端的內存空間:
GLubyte *ptr = (GLubyte *)glMapBufferRange(
GL_PIXEL_UNPACK_BUFFER,
0,
size,
GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
解碼直接進入該存儲器和手動沖洗:
glFlushMappedBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, size);
看來我能夠以每秒〜300幀執行此操作。這看起來很不錯,這是很多數據。
創建紋理:
glGenTextures(1, &texture_id);
glBindTexture(GL_TEXTURE_2D, texture_id);
複印PBO成質地:
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, 0);
這個階段是緩慢而限制了性能至〜60幀。
和渲染:
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
這一階段的限制進一步性能〜40個FPS。
這是最好的方法嗎?有沒有更好的方法在屏幕上獲取一次像素?每秒40幀速度不夠快。
筆記:
映射內存到客戶端的地址空間使得與視頻解碼集成簡單,轉移到GPU不必等待被解碼整個幀。
我可以使用兩個或多個PBO。將當前幀解碼爲一個PBO,然後渲染/顯示前一幀的PBO,以利用寫入PBO的異步特性?但是,這會增加額外的解碼延遲幀,我非常希望避免。
我的頂點和片段着色器現在是直通的。我沒有鎖定/擊劍atm,但顯然會稍後需要它。
我正在使用Linux,Wayland和EGL。直接使用DRM啞巴緩衝器我可以達到〜200 fps。