2012-02-02 38 views

回答

2

由於訪問這個帖子的數量明顯我會回答我的問題。

訣竅是枚舉所有MJPG和YUY2之間的轉換,因爲它似乎沒有MJPG和RGB32之間的直接轉換。爲了轉化YUY2和RBG32之間的圖像使用色彩轉換器DSP: http://msdn.microsoft.com/en-us/library/windows/desktop/ff819079%28v=vs.85%29.aspx

我用這個方法來從一個1080p的網絡攝像頭的樣本,然後進行解碼MJPG到YUY2然後解碼YUY2到RGB32然後加載的OpenGL RGB32紋理,然後顯示它。它是以30fps的速度完成的,搭配核心2雙核和Radeon HD5650。當用OpenCL(幾個卷積)對圖像進行計算時,它會下降到15 fps。

代碼以創建一個MJPG到YUY2變換:

MFT_REGISTER_TYPE_INFO inputFilter = { MFMediaType_Video, MFVideoFormat_MJPG }; 
MFT_REGISTER_TYPE_INFO outputFilter = { MFMediaType_Video, MFVideoFormat_YUY2 }; 
UINT32 unFlags = MFT_ENUM_FLAG_SYNCMFT | MFT_ENUM_FLAG_LOCALMFT | MFT_ENUM_FLAG_SORTANDFILTER; 

HRESULT r = MFTEnumEx(MFT_CATEGORY_VIDEO_DECODER, unFlags, &inputFilter, &outputFilter, &ppActivate, &numDecodersMJPG); 
if (FAILED(r)) throw gcnew Exception(""); 
if (numDecodersMJPG < 1) throw gcnew Exception(""); 

// Activate transform 
IMFTransform *pMPEG4 = NULL; 
r = ppActivate[0]->ActivateObject(__uuidof(IMFTransform), (void**)&pMPEG4); 
if (FAILED(r)) throw gcnew Exception("No se pudo crear el decodificador MJPG."); 

下一部分是用所述解碼器將壓縮的樣品(從第一到MJPG YUY2,然後從YUY2到RGB32)進行解碼。 http://msdn.microsoft.com/en-us/library/windows/desktop/aa965264%28v=vs.85%29.aspx

或者:

 MFT_OUTPUT_STREAM_INFO osi; 

    HRESULT r = pDecoder->ProcessMessage(MFT_MESSAGE_NOTIFY_BEGIN_STREAMING, 0); 
    if (FAILED(r)) throw gcnew Exception(""); 

    r = pDecoder->ProcessInput(0, sample, 0); 
    if (FAILED(r)) throw gcnew Exception(""); 

    r = pDecoder->GetOutputStreamInfo(0, &osi); 
    if (FAILED(r)) throw gcnew Exception(""); 

    DWORD status = 0; 
    r = pDecoder->GetOutputStatus(&status); 
    if (FAILED(r)) throw gcnew Exception(""); 
    if (status = MFT_OUTPUT_STATUS_SAMPLE_READY) { 
    } 

    // Use your own CreateSample function 
    IMFSample *outputSample = CreateSample(osi.cbSize); 

    DWORD outStatus = 0; 
    MFT_OUTPUT_DATA_BUFFER odf; 
    odf.dwStreamID = 0; 
    odf.pSample = outputSample; 
    odf.dwStatus = 0; 
    odf.pEvents = NULL; 
    r = pDecoder->ProcessOutput(0, 1, &odf, &outStatus); 
    if (r != MF_E_TRANSFORM_NEED_MORE_INPUT && FAILED(r)) { 
     outputSample->Release(); 
     throw gcnew Exception(""); 
    } 

    r = pDecoder->ProcessMessage(MFT_MESSAGE_NOTIFY_END_OF_STREAM, 0); 
    if (FAILED(r)) { 
     outputSample->Release(); 
     throw gcnew Exception(""); 
    } 

    r = pDecoder->ProcessMessage(MFT_MESSAGE_COMMAND_DRAIN, 0); 
    if (FAILED(r)) { 
     outputSample->Release(); 
     throw gcnew Exception(""); 
    } 

    return outputSample; 
它在解釋