2014-01-06 82 views
1

我即將編寫堆棧軟件。因此,我想將一個或多個視頻文件的幀提取到opencl緩衝區,然後使用opencl kernel進行處理。OpenCL視頻處理

但我不知道如何加載視頻幀,因爲我從來沒有使用過視頻。 正如我使用opencl我的主要重點顯然是高性能

我知道有像ffmpegopencv等圖書館,但因爲我沒有進入它,我不知道哪一個最適合我的需求。

所以,你可以給我建議哪個庫/函數使用最好(最快)與opencl結合使用?

我還沒有找到有用的東西。我可以從哪裏開始? (類似短的ducumentation或教程將是種)

在此先感謝!

我正在Linux下(不需要跨平臺)使用nvidia卡,我的(首選)編程語言是c++。我更喜歡h264作爲視頻格式,但avi,mov,mp4,...也是可能的。

回答

0

我的一位朋友一直快樂與OpenGL的圖像處理框架使用的ffmpeg,所以不該OpenCL也沒有任何問題。我會選擇通過供應商特定的庫。如果您使用OpenCV,請記住您的應用程序可能必須隨附OpenCV共享庫,即使它不需要所有額外的東西,即在用戶計算機上浪費硬盤空間。大約2年前我發現ffmpeg很容易使用。

使用OpenCV讀取幀的唯一原因是如果您還需要某些圖像處理功能。如果沒有,那麼我會使用ffmpeg。

1

如果您在Windows上使用AMD GPU並嘗試使用AMD Media SDK。

從SemiAcurate網站http://semiaccurate.com/2012/06/18/amd-media-sdk-announced-at-afds/

「AMD的媒體SDK。該SDK的目標是通過API和代碼示例展示AMD的固定功能硬件模塊和GPU加速功能。在競爭激烈的市場背景下,AMD需要開發人員利用其APU中的基於GPU的功能,以便APU爲一般計算工作負載提供切實的好處。爲此,AMD正在準備示例應用程序,爲開發人員在他們的應用程序中使用API​​創建API,並且使用指南和教程記錄所有內容,這是他們創建該媒體SDK的努力的一部分。

http://developer.amd.com/tools-and-sdks/heterogeneous-computing/media-sdk/

我認爲它仍處於測試階段,但有一組例子

http://amd.wpengine.com/app-sdk/codelisting.php?q=Media

+0

謝謝,但我正在用** nvidia卡**在Linux上工作。 (但這可能仍然與其他人有關) – Scindix

+0

那麼爲什麼要使用OpenCL? CUDA通常功能更豐富,並且對視頻流處理有更多的支持。 Nvidia對OpenCL的支持僅在1.1規範級別。沒有跡象表明這將很快改變。但是,您可以期待英特爾ARM和AMD實施OpenCL 1.2和新的2.0規範。 –

+0

原因是我在OpenCL有一些經驗,但在CUDA中沒有。我不知道這會有什麼不同。不過我想我會試試看。 – Scindix

1

FFmpeg可以是正確的選擇,它有很多低級優化&運行速度非常快。

最簡單的解碼應用程序可以ffmpeg的樣品中找到: http://www.ffmpeg.org/doxygen/trunk/doc_2examples_2decoding_encoding_8c-example.html

看一看函數decode_write_frame()。解碼圖像被存儲在結構AVFrame:(我加1個參數 - 爲了OpenCL上下文分配對象MEM

static int decode_write_frame(
    const char  *outfilename, 
    AVCodecContext *avctx, 
    AVFrame  *frame, 
    int   *frame_count, 
    AVPacket  *pkt, 
    int   last, 
    cl_context  context) 
{ 
    int len, got_frame; 
    len = avcodec_decode_video2(avctx, frame, &got_frame, pkt); 

    if (len < 0) { 
     fprintf(stderr, "Error while decoding frame %d\n", *frame_count); 
     return len; 
    } 

    cl_int ret_code; 

    //frame->data[0] is Y plane 
    cl_mem y_plane = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR, 
     frame->width * frame->height, frame->data[0], &ret_code); 

    if(ret_code != CL_SUCCESS){ 
     fprintf(stderr, "Error %d occured.\n", ret_code); 
    } 

    //frame->data[1] is Cb plane 
    //frame->data[2] is Cr plane  
    //Remember, that video is usually encoded in YCbCr420, which means that 
    //Cb & Cr planes are smaller than Y plane 2 times in each dimension 

    if (pkt->data) { 
     pkt->size -= len; 
     pkt->data += len; 
    } 
    return 0; 
} 

P. S. 不要混淆的編解碼器&容器。 Avi或Mov容器可以存儲比特流,該比特流由MPEG4,MPEG2 &其他編碼器編碼。