2015-03-13 117 views
3

我使用ffmpeg函數來解碼h264幀並在Windows平臺上的窗口中顯示。我使用的方法是如下面(從FFMPEG Frame to DirectX Surface):FFMPEG幀到DirectX表面硬件加速

AVFrame *frame; 
avcodec_decode_video(_ffcontext, frame, etc...); 

lockYourSurface(); 
uint8_t *buf = getPointerToYourSurfacePixels(); 

// Create an AVPicture structure which contains a pointer to the RGB surface. 
AVPicture pict; 

memset(&pict, 0, sizeof(pict)); 

avpicture_fill(&pict, buf, PIX_FMT_RGB32, 
       _ffcontext->width, _ffcontext->height); 



// Convert the image into RGB and copy to the surface. 
img_convert(&pict, PIX_FMT_RGB32, (AVPicture *)frame, 
      _context->pix_fmt, _context->width, _context->height); 


unlockYourSurface(); 

在代碼中,我使用sws_scale代替img_convert的。

當我將表面數據指針傳遞給sws_scale(實際上在avpicture_fill中)時,似乎數據指針實際上是在RAM上,而不是在GPU內存上,而當我想要顯示錶面時,似乎數據是轉移到GPU然後顯示。據我所知,當數據在RAM和GPU內存之間複製時,CPU利用率很高。

我如何可以直接將ffmpeg渲染到GPU內存的表面(而不是RAM上的數據指針)?

+0

如果數據指針在RAM中,是不是因爲getPointerToYourSurfacePixels()函數,這意味着ffmpeg不能改變它的任何內容? – stijn 2015-11-18 20:19:51

回答

0

我找到了這個問題的答案。爲了防止在使用ffmpeg顯示幀時額外使用cpu,我們不得將幀解碼爲RGB。幾乎所有的視頻文件都被解碼爲YUV(這是視頻文件中的原始圖像格式)。這裏的要點是,GPU能夠直接顯示YUV數據,而無需將其轉換爲RGB。據我所知,使用ffmpeg通常的版本,解碼後的數據總是在RAM上。對於一幀,與相同幀的RGB解碼等效值相比,YUV數據量非常小。所以,當我們移動YUV數據到GPU,而不是轉換爲RGB,然後轉移到GPU中,我們從兩個方面加快操作:

  1. 沒有轉換爲RGB
  2. 量的數據RAM和GPU之間移動降低

因此,總體CPU使用率降低。