2011-11-01 19 views
1

私はWindows上のネイティブ開発の初心者ですが、私はすべてのトランスをリストする小さなアプリケーションを作成することに任されていますさまざまなビデオ+オーディオコーデック用。システム上で利用可能なすべてのMicrosoft Media Foundation Transforms(MFT)のリストを取得する方法

MSDNのドキュメントを見ると、これを行うための直接的なドキュメントはあまりないようです。私が見つけたドキュメントは、この情報がレジストリに格納されていることを示しています(どこにいないかわからないため)。

  1. これは可能ですか?
  2. 一般的にどのようにすればよいですか?

おかげ

EDIT:

NULLに設定型MFT_REGISTER_TYPE_INFOのパラメータを持つMFTEnumExへの呼び出しは8

MFTEnumEx(MFT_CATEGORY_VIDEO_DECODER,MFT_ENUM_FLAG_ALL,NULL, NULL, &ppActivate, &count); 
assert(count > 0); 

まだ持っているの数を返すように見えるんしかし、実際の値を取得します。しかし、渡されたppActivateパラメータには列挙型が含まれている必要があります。

EDIT: それは意外だが、== 8以上のカウントながら、何のビデオまたはオーディオの属性が存在しない(ビデオ/オーディオIMFAttributesオブジェクトがNULLである)

IMFAttributes* videoAttributes = NULL;  
     if(SUCCEEDED(hr)){ 
      hr = pProfile->GetVideoAttributes(&videoAttributes); 
      //If there are no container attributes set in the transcode profile, the GetVideoAttributes method succeeds and videoAttributes receives NULL. 

     } 
assert(videoAttributes != NULL); //FAILS! 

EDIT:

これは、すべてのIMFMediaTypesをマシンからプルする方法です(本の修正コールはDeveloping Microsoft® Media Foundation Applicationsです)。

HRESULT CTranscoder::GetVideoOutputAvailableTypes(
    DWORD flags, 
    CComPtr<IMFCollection>& pTypeCollection) 
{ 
    HRESULT hr = S_OK; 
    IMFActivate** pActivateArray = NULL; 
    MFT_REGISTER_TYPE_INFO outputType; 
    UINT32 nMftsFound = 0; 

    do 
    { 
     // create the collection in which we will return the types found 
     hr = MFCreateCollection(&pTypeCollection); 
     BREAK_ON_FAIL(hr); 

     // initialize the structure that describes the output streams that the encoders must 
     // be able to produce. In this case we want video encoders - so major type is video, 
     // and we want the specified subtype 
     outputType.guidMajorType = MFMediaType_Video; 
     outputType.guidSubtype = MFVideoFormat_WMV3; 

     // get a collection of MFTs that fit the requested pattern - video encoders, 
     // with the specified subtype, and using the specified search flags 
     hr = MFTEnumEx(
      MFT_CATEGORY_VIDEO_ENCODER,   // type of object to find - video encoders 
      flags,        // search flags 
      NULL,        // match all input types for an encoder 
      &outputType,      // get encoders with specified output type 
      &pActivateArray, 
      &nMftsFound); 
     BREAK_ON_FAIL(hr); 

     // now that we have an array of activation objects for matching MFTs, loop through 
     // each of those MFTs, extracting all possible and available formats from each of them 
     for(UINT32 x = 0; x < nMftsFound; x++) 
     { 
      CComPtr<IMFTransform> pEncoder; 
      UINT32 typeIndex = 0; 

      // activate the encoder that corresponds to the activation object 
      hr = pActivateArray[x]->ActivateObject(IID_IMFTransform, 
       (void**)&pEncoder); 

      // while we don't have a failure, get each available output type for the MFT 
      // encoder we keep looping until there are no more available types. If there 
      // are no more types for the encoder, IMFTransform::GetOutputAvailableTypes[] 
      // will return MF_E_NO_MORE_TYPES 
      while(SUCCEEDED(hr)) 
      { 
       IMFMediaType* pType; 

       // get the avilable type for the type index, and increment the typeIndex 
       // counter 
       hr = pEncoder->GetOutputAvailableType(0, typeIndex++, &pType); 
       if(SUCCEEDED(hr)) 
       { 
        // store the type in the IMFCollection 
        hr = pTypeCollection->AddElement(pType); 
       } 
      } 
     } 
    } while(false); 

    // possible valid errors that may be returned after the previous for loop is done 
    if(hr == MF_E_NO_MORE_TYPES || hr == MF_E_TRANSFORM_TYPE_NOT_SET) 
     hr = S_OK; 

    // if we successfully used MFTEnumEx() to allocate an array of the MFT activation 
    // objects, then it is our responsibility to release each one and free up the memory 
    // used by the array 
    if(pActivateArray != NULL) 
    { 
     // release the individual activation objects 
     for(UINT32 x = 0; x < nMftsFound; x++) 
     { 
      if(pActivateArray[x] != NULL) 
       pActivateArray[x]->Release(); 
     } 

     // free the memory used by the array 
     CoTaskMemFree(pActivateArray); 
     pActivateArray = NULL; 
    } 

    return hr; 
} 

発信者:私は、呼び出し側でそれらの上に列挙

hr=transcoder.GetVideoOutputAvailableTypes(MFT_ENUM_FLAG_ALL, availableTypes); 
    if (FAILED(hr)){ 
     wprintf_s(L"didn't like the printVideoProfiles method"); 
    } 

    DWORD availableInputTypeCount =0; 
    if(SUCCEEDED(hr)){ 
     hr= availableTypes->GetElementCount(&availableInputTypeCount); 
    } 
    for(DWORD i = 0; i< availableInputTypeCount && SUCCEEDED(hr); i++) 
    { 

     //really a IMFMediaType* 
     IMFAttributes* mediaInterface = NULL; 
      if(SUCCEEDED(hr)){ 
       hr = availableTypes->GetElement(i, (IUnknown**)&mediaInterface) ;} 

      if(SUCCEEDED(hr)){ 
       //see http://msdn.microsoft.com/en-us/library/aa376629(v=VS.85).aspx for a list of attributes to pull off the media interface. 

       GUID majorType; 
       hr = mediaInterface->GetGUID(MF_MT_MAJOR_TYPE, &majorType); 
       LPOLESTR majorGuidString = NULL; 
       hr = StringFromCLSID(majorType,&majorGuidString); 
       wprintf_s(L"major type: %s \n", majorGuidString); 
       wprintf_s(L"is a video? %i \n", IsEqualGUID(MFMediaType_Video,majorType)); 

       GUID subType; 
       if(SUCCEEDED(mediaInterface->GetGUID(MF_MT_SUBTYPE, &subType))){ 
        LPOLESTR minorGuidString = NULL; 
        if(SUCCEEDED(StringFromCLSID(subType,&minorGuidString))) 
         wprintf_s(L"subtype: %s \n", minorGuidString); 
       } 

       //Contains a DirectShow format GUID for a media type: http://msdn.microsoft.com/en-us/library/dd373477(v=VS.85).aspx 
       GUID formatType; 
       if(SUCCEEDED(mediaInterface->GetGUID(MF_MT_AM_FORMAT_TYPE, &formatType))){ 
        LPOLESTR formatTypeString = NULL; 
        if(SUCCEEDED(StringFromCLSID(formatType,&formatTypeString))) 
         wprintf_s(L"format type: %s \n", formatTypeString); 
       } 

       UINT32 numeratorFrameRate = 0; 
       UINT32 denominatorFrameRate = 0; 
       if(SUCCEEDED(MFGetAttributeRatio(mediaInterface, MF_MT_FRAME_RATE, &numeratorFrameRate, &denominatorFrameRate))) 
        wprintf_s(L"framerate: %i/%i \n", numeratorFrameRate, denominatorFrameRate); 

       UINT32 widthOfFrame = 0; 
       UINT32 heightOfFrame = 0; 
       if(SUCCEEDED(MFGetAttributeSize(mediaInterface, MF_MT_FRAME_SIZE, &widthOfFrame, &heightOfFrame))) 
        wprintf_s(L"height of frame: %i width of frame: %i \n", heightOfFrame, widthOfFrame); 

       UINT32 isCompressedP = 0; 
       if(SUCCEEDED(mediaInterface->GetUINT32(MF_MT_COMPRESSED, &isCompressedP))) 
        wprintf_s(L"is media compressed? %iu \n", (BOOL)isCompressedP); 

       BOOL isCompressedP2 = 0; 
       if(SUCCEEDED((((IMFMediaType*)mediaInterface)->IsCompressedFormat(&isCompressedP2)))) 
        wprintf_s(L"is media compressed2? %i \n", isCompressedP2); 

       UINT32 fixedSampleSizeP = 0; 
       if(SUCCEEDED(mediaInterface->GetUINT32(MF_MT_FIXED_SIZE_SAMPLES, &fixedSampleSizeP))) 
        wprintf_s(L"is fixed sample size? %iu \n", fixedSampleSizeP); 

       UINT32 sampleSize = 0; 
       if(SUCCEEDED(mediaInterface->GetUINT32(MF_MT_SAMPLE_SIZE, &sampleSize))) 
        wprintf_s(L"sample size: %iu \n", sampleSize); 

       UINT32 averateBitrate = 0; 
       if(SUCCEEDED(mediaInterface->GetUINT32(MF_MT_AVG_BITRATE, &averateBitrate))) 
        wprintf_s(L"average bitrate: %iu \n", averateBitrate); 

       UINT32 aspectRatio = 0; 
       if(SUCCEEDED(mediaInterface->GetUINT32(MF_MT_PAD_CONTROL_FLAGS, &aspectRatio))) 
        wprintf_s(L"4 by 3? %i 16 by 9? %i None? %i \n", aspectRatio == MFVideoPadFlag_PAD_TO_4x3, MFVideoPadFlag_PAD_TO_16x9 == aspectRatio, MFVideoPadFlag_PAD_TO_None == aspectRatio); 

       UINT32 drmFlag = 0; 
       if(SUCCEEDED(mediaInterface->GetUINT32(MF_MT_DRM_FLAGS, &drmFlag))) 
        wprintf_s(L"requires digital drm: %i requires analog drm: %i requires no drm: %i", drmFlag == MFVideoDRMFlag_DigitallyProtected, drmFlag == MFVideoDRMFlag_AnalogProtected, MFVideoDRMFlag_None == drmFlag); 

       UINT32 panScanEnabled = 0; 
       if(SUCCEEDED(mediaInterface->GetUINT32(MF_MT_PAN_SCAN_ENABLED, &panScanEnabled))) 
        wprintf_s(L"pan/scan enabled? %i", panScanEnabled); 

       UINT32 maxFrameRateNumerator = 0; 
       UINT32 maxFrameRateDenominator = 0; 
       if(SUCCEEDED(MFGetAttributeRatio(mediaInterface, MF_MT_FRAME_RATE_RANGE_MAX, &maxFrameRateNumerator, &maxFrameRateDenominator))) 
        wprintf_s(L"max framerate range: %i/%i \n", maxFrameRateNumerator, maxFrameRateDenominator); 

      } 

    } 

それはIMFMediaInterfaceからいくつかの属性を取得していますが、多くの属性がmediaInterface->GetUINT32(MF_MT_COMPRESSED, &isCompressedP)への呼び出しが成功しなかった設定と されているわけではないが、 (IMFMediaType*)mediaInterface)->IsCompressedFormat(&isCompressedP2)への呼び出しは、私が間違っているのではないかと思います。

答えて

0

これは古い質問ですが、未回答の人はいないはずです。

あなたは発見として、MFTEnumExはあなたにMFTsのリストを与える、いずれかのバルクリスト、または基準で濾過することができます。いったん変換のコレクションを取得すると、利用可能な変換ごとにIMFActivateが得られます。

手にIMFActivateを持って、あなたはに関する情報を取得することができますどのようにthis code snippetを参照してください。この変換:あなたは、あなたは、カテゴリ、入力および出力メディアタイプ(MFT_INPUT_TYPES_AttributesMFT_OUTPUT_TYPES_Attributes)を得ることができ、そのキーを使用して属性や関心のアクセス属性を一覧表示します。ここで

は、サンプルコードとMFTダンプのサンプルです:

関連する問題