2013-08-21 69 views
1

我試圖使用CUDA解碼器項目中的代碼將解碼圖像文件保存爲BMP圖像。將輸出幀保存爲圖像文件CUDA解碼器

  if (g_bReadback && g_ReadbackSID) 
      { 
       CUresult result = cuMemcpyDtoHAsync(g_bFrameData[active_field], pDecodedFrame[active_field], (nDecodedPitch * nHeight * 3/2), g_ReadbackSID); 



       long padded_size = (nWidth * nHeight * 3); 
       CString output_file; 
       output_file.Format(_T("image/sample_45.BMP")); 
       SaveBMP(g_bFrameData[active_field],nWidth,nHeight,padded_size,output_file); 

       if (result != CUDA_SUCCESS) 
       { 
        printf("cuMemAllocHost returned %d\n", (int)result); 
       } 
      } 

但保存的圖像看起來像這樣enter image description here

任何人可以幫助我在這裏我在做什麼錯。謝謝。

+1

嘗試使用'cuMemcpyDtoH'而不是'cuMemcpyDtoHAsync'並查看它是否有任何區別。 – talonmies

+0

nope輸出仍然是相同的 – Hadi

+0

在這種情況下,您沒有CUDA編程問題,我可以看到。唯一明顯可能出錯的是您正在使用異步存儲器傳輸,在開始保存幀之前可能無法完成這項工作。但是這並沒有幫助。因此,這兩種選擇都是 - 數據已經從GPU上錯誤地進入(這可能意味着它正在進入),或者保存例程期望它接收到的數據與正在傳遞的數據不同。這裏顯示的任何內容都可以幫助解決這兩個問題中的任何一個 – talonmies

回答

3

經過進一步調查後,我對您的方法做了幾處修改。

  • pDecodedFrame實際上是在一些非RGB格式,我認爲它是NV12格式,我相信這是一個particular YUV variant
  • pDecodedFrame使用特定CUDA內核被轉換到在GPU上的RGB格式
  • 用於該轉化的目標緩衝器將或者被OpenGL的提供一種表面如果g_bUseInterop指定,否則由駕駛員API分配一個普通的區域如果未指定interop,則版本爲cudaMalloc

上面提到的目標緩衝區是pInteropFrame(即使在非互操作的情況下)。所以爲了給你舉個例子,爲了簡單起見,我選擇了只使用非互操作的情況,因爲在這種情況下獲取RGB緩衝區(pInteropFrame)要容易得多。

這裏的方法將pInteropFrame拷貝回主機,之後已經用cudaPostProcessFrame填充適當的RGB圖像。還有一個例程將圖像保存爲位圖文件。我所有的修改都被描述爲包含RMC的註釋,因此如果您想查找我所做的所有更改/添加,請搜索。

要使用,請將該文件放在cudaDecodeGL項目中,替代videoDecodeGL.cpp源文件。然後重建項目。然後正常運行可執行文件以顯示視頻。要捕獲特定的幀,請使用nointerop命令行開關運行可執行文件,例如。 cudaDecodGL nointerop,視頻將不會顯示,但將進行解碼操作和幀捕獲,並且幀將保存在framecap.bmp文件中。如果要更改捕獲的特定幀號,請將g_FrameCapSelect = 37;變量修改爲除37之外的其他數字,然後重新編譯。

Here is the replacement對於videoDecodeGL.cpp我使用了pastebin,因爲SO對可以在問題主體中輸入的字符數量有限制。

請注意,我的方法與是否指定回讀無關。我建議不要使用回讀這個序列。