2012-10-03 53 views
4

我正在開發一個系統,該系統會在呈現完成後立即從服務器中完成的3D圖形向客戶端發送壓縮視頻。 我已經有代碼的工作,但我覺得它可能會更快(而且它已經在系統中的瓶頸)使用opengl和x264更快地編碼實時3D圖形

下面是我在做什麼:

首先我搶的framebuffer

glReadBuffer(GL_FRONT); 
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer); 

然後我翻轉framebuffer,因爲swsScale(我用於顏色空間轉換)有一個奇怪的錯誤,當我轉換時垂直翻轉圖像。我提前翻,沒有什麼幻想。

void VerticalFlip(int width, int height, byte* pixelData, int bitsPerPixel) 
{ 
byte* temp = new byte[width*bitsPerPixel]; 
height--; //remember height array ends at height-1 


for (int y = 0; y < (height+1)/2; y++) 
{ 
    memcpy(temp,&pixelData[y*width*bitsPerPixel],width*bitsPerPixel); 
    memcpy(&pixelData[y*width*bitsPerPixel],&pixelData[(height-y)*width*bitsPerPixel],width*bitsPerPixel); 
    memcpy(&pixelData[(height-y)*width*bitsPerPixel],temp,width*bitsPerPixel); 
} 
delete[] temp; 
} 

然後我將它轉換爲YUV420P

convertCtx = sws_getContext(width, height, PIX_FMT_RGB24, width, height, PIX_FMT_YUV420P, SWS_FAST_BILINEAR, NULL, NULL, NULL); 
uint8_t *src[3]= {buffer, NULL, NULL}; 

sws_scale(convertCtx, src, &srcstride, 0, height, pic_in.img.plane, pic_in.img.i_stride); 

然後,我非常簡單,只是調用的x264編碼器。我已經在使用零延遲預設。

int frame_size = x264_encoder_encode(_encoder, &nals, &i_nals, _inputPicture, &pic_out); 

我的猜測是應該有一個更快的方法來做到這一點。捕獲幀並將其轉換爲YUV420p。在GPU中將其轉換爲YUV420p並且僅在將其複製到系統內存之後纔會很好,並且希望有一種方法可以在不需要翻轉的情況下進行顏色轉換。

如果沒有更好的方法,至少這個問題可能會幫助有人試圖做到這一點,做到這一點,就像我做的一樣。使用PBOs.Here是example它加速UPS採用2個公益組織,其異步工作的閱讀,而不使管線停滯像readPixels使用directly.In我的應用我得到了80%的性能提升時不切換時

+1

有幾件事情可以使這個「更快」。你確實可以將一些計算任務卸載到GPU上,但是如果你的GPU已經成爲瓶頸,那對你來說無能爲力。你也可以通過使用PBO來改進這個代碼,所以你不會阻塞GPU管道。在這種情況下更快是相對的。先測量究竟是什麼問題。 – KillianDS

+1

另外,你只是想在這裏做屏幕抓取,或者你可以把東西呈現給FBO嗎?它對於優化你可以做的事情有很大的影響。我已經完成了這件事,可能會非常棘手。 – KillianDS

+0

對不起。通過讀像素將幀緩衝區複製到內存,整個翻轉和轉換都是瓶頸。複製後,所有內容都在主內存和CPU中完成。 我正在渲染到服務器中的屏幕,然後捕獲它。這可能很愚蠢,如果通過使用FBO,我可以避免進入顯示器並同時提高性能,那將會很棒。 我不熟悉幀緩衝區對象,但我可以肯定地給他們一個嘗試。我想我可以修改應用程序,而不是呈現到後臺緩衝區呈現給FBO。那有意義嗎? – cloudraven

回答

2

首先,使用異步讀取紋理到公益組織。 此外,在某些GPU上,glGetTexImage()的工作速度比glReadPixels()快,所以試試看。

但是,如果你真的想把視頻編碼提高到一個新的水平,你可以通過CUDA使用Nvidia Codec Library。我最近問了同樣的問題,所以this可以有所幫助。