2

私は Windows でのネイティブ開発の初心者ですが、さまざまなビデオ + オーディオ コーデックのすべてのトランスフォーマーを一覧表示する小さなアプリの作成を任されています。

MSDN のドキュメントを見ると、これに関する直接的なドキュメントはあまりないようです。私が見つけたドキュメントは、この情報がレジストリに保存されていることを示しているため (場所は不明)、ベクトルである可能性があります。

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

ありがとう

編集:

MFT_REGISTER_TYPE_INFO 型のパラメーターを NULL に設定して MFTEnumEx を呼び出すと、カウント 8 が返されるようです。

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

ただし、実際の値を取得する必要があります。ただし、渡された ppActivate パラメータには、それらの列挙が含まれている必要があります。

編集: 驚くべきことですが、カウントが == 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!

編集:

これは、マシンからすべての IMFMediaTypes を取得するメソッドです ( 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)は間違っているのではないかと思います。

4

1 に答える 1

2

これは昔からの質問ですが、誰も答えられないまま放置されるべきではありません。

あなたが発見したように、一括リスト、または条件でフィルタリングされたMFTEnumExのリストを提供できます。MFTs変換のコレクションを取得したら、IMFActivate利用可能なすべての変換を取得します。

IMFActivate手元にあるこのコード スニペットを参照して、この変換に関する情報を取得する方法を確認してください。属性をリストするか、そのキーを使用して目的の属性にアクセスすると、カテゴリ、入力および出力メディア タイプ ( MFT_INPUT_TYPES_AttributesMFT_OUTPUT_TYPES_Attributes) を取得できます。

サンプル コードと MFT ダンプのサンプルを次に示します。

于 2012-08-07T20:50:42.430 に答える