none
SetInputType on Decoder always returns MF_E_INVALIDMEDIATYPE

    Question

  • Hi,

    I'm working on making a video player using media foundation. I'm using the Sourcereader for this (not through media session pipeline).
    Here, I wish to prevent the source reader from loading a decoder. Therefore I do not set any preferred output media type. ( I wish insert a decoder on my own after reading the sample. However, I'm not able to successfully use the decoder)
    I'm doing the following to create the decoder:


        MFT_REGISTER_TYPE_INFO info    = {MFMediaType_Video, m_pVideoSubtype};  //Here, in my case MEDIASUBTYPE_WVC1
    
        UINT32 unFlags = MFT_ENUM_FLAG_SYNCMFT|MFT_ENUM_FLAG_LOCALMFT|MFT_ENUM_FLAG_SORTANDFILTER;
    
        CHECKHR (hr = MFTEnumEx(
                MFT_CATEGORY_VIDEO_DECODER,
                unFlags,
                &info,      // Input type
                NULL,       // Output type
                &ppActivate,
                &count
                ) );
    
    
        CHECKHR (hr = ppActivate[0]->ActivateObject(IID_PPV_ARGS(m_pDecoder)) );
    
    
    All seems to work fine until here.
    
    
        IMFMediaType *pSrcType = NULL;
        GUID guidCurrent;
        GUID guidMajor;
    
        for (int i = 0; i< 8; i++)
        {
            hr = m_pDecoder>GetInputAvailableType (0, i, &pSrcType);
            pSrcType->GetGUID(MF_MT_MAJOR_TYPE, &guidMajor);
    
            if (guidMajor == MFMediaType_Video)    //safety check
            {
                if (hr == MF_E_NO_MORE_TYPES)
                {
                    break;
                }
    
                pSrcType->GetGUID( MF_MT_SUBTYPE, &guidCurrent );
    
                if ( guidCurrent == m_pVideoSubtype )        //m_pVideoSubtype = MEDIASUBTYPE_WVC1
                {
                    break;
                }
                else
                    SafeRelease(&pSrcType);
            }
        }
    
    


    Here, I manage to get the correct available IMFMediaType while iterating the loop.

    Now, I set the following attributes to the IMFMediaType
        CHECK_HR( hr = MFSetAttributeRatio(pSrcType, MF_MT_FRAME_RATE, 30000, 1001) );
        CHECK_HR( hr = MFSetAttributeSize(pSrcType, MF_MT_FRAME_SIZE, 1280, 720) );
        CHECK_HR( hr = pSrcType->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive) );   
        CHECK_HR( hr = MFSetAttributeRatio(pSrcType, MF_MT_PIXEL_ASPECT_RATIO, 1, 1));
        CHECK_HR( hr = pSrcType->SetUINT32(MF_MT_AVG_BITRATE, 5942130) );
    
    



    (I've checked for the above values on the input media type)
    However, I could not get the values for:
    MF_MT_ALL_SAMPLES_INDEPENDENT, MF_MT_FIXED_SIZE_SAMPLES, MF_MT_DEFAULT_STRIDE, MF_MT_SAMPLE_SIZE

    After that, when I try to set the above media type as input type to the decoder, I always get MF_E_INVALIDMEDIATYPE

    CHECK_HR( hr = ppVideoDecoder->SetInputType(0 , pSrcType, 0) );        //always returns MF_E_INVALIDMEDIATYPE

    Any help would be appreciated.

    Thanks,
    Mots
    Thursday, September 08, 2011 2:46 PM

Answers

  • MF_MT_USER_DATA is not a UINT32 value, but a blob.  You need to retrieve it using the GetBlob function.

    Matching up media types is typically the way to set media types between components.  However, a source (in general) only has one media type.  Your only option is to set the type that the source can output, so any type matching code is extraneous.  You cannot modify the media type that the source exposes, as that would mean modifying the content that the source exposes as well.

    You can enumerate through items in an attribute store using IMFAttributes::GetCount and IMFAttributes::GetItemByIndex.   As I mentioned before though, this is much more effort than is necessary to resolve media types with a source.

     

    • Marked as answer by mots_g Wednesday, November 30, 2011 5:38 AM
    Thursday, October 27, 2011 10:56 PM

All replies

  • It looks to me that every codec under Windows Media Foundation has a different requirement in setting up its input and output. In my experience, setting up the H264 encoder follows a different procedure than setting up the WMV encoder. I did not work with decoders, and can't tell how (sorry). You need to carefully read the related documentation and follow the instructions precisely. Even though, there is no guarantee that it will work. I posted a question on the forum (http://social.msdn.microsoft.com/Forums/en-US/mediafoundationdevelopment/thread/85a57f1b-62bf-4d21-a247-b71a808fc545/)  a month ago, and haven't got a reply from Microsoft.


    jon

    • Edited by jon4112 Tuesday, September 13, 2011 1:48 PM
    Tuesday, September 13, 2011 1:45 PM
  • Thanks jon. I'll look into it further and update my findings here.

    Regards

    mots

    Wednesday, September 14, 2011 11:27 AM
  • The attribute that you are likely missing is MF_MT_USER_DATA, which contains the codec private data necessary to decode the content.  This information is typically stored in the source file.  The easiest thing to do is just get the native type exposed by the media source or source reader and set it on the decoder.

    Tuesday, October 04, 2011 12:44 AM
  • Hi Matt,

    If I try to retrieve 'MF_MT_USER_DATA' on the native type, it fails with hr - 'MF_E_INVALIDTYPE'

     

    CHECK_HR( hr = pNativeMediaType->GetUINT32(MF_MT_USER_DATA, &m_UrsData) );

     

     

    Now, if I directly set the native type from source as input on the decoder, it works fine but fails on 'SetOutputType' with hr - 'MF_E_TRANSFORM_TYPE_NOT_SET'

    (Also the documents seems suggest to first 'GetInputAvailableType(s)', find a match to the source input type, set relevant attributes and then set it as an input type.)

     

    There's one more way I'm wish to try but I'm stuck. The IMFMediaType interface exposes 'CopyAllItems' method to get a copy of all its attributes. But I couldn't find how to set these attributes on an enumerated input type?

     

    Thanks,

    Mots

     

    Friday, October 07, 2011 6:48 AM
  • MF_MT_USER_DATA is not a UINT32 value, but a blob.  You need to retrieve it using the GetBlob function.

    Matching up media types is typically the way to set media types between components.  However, a source (in general) only has one media type.  Your only option is to set the type that the source can output, so any type matching code is extraneous.  You cannot modify the media type that the source exposes, as that would mean modifying the content that the source exposes as well.

    You can enumerate through items in an attribute store using IMFAttributes::GetCount and IMFAttributes::GetItemByIndex.   As I mentioned before though, this is much more effort than is necessary to resolve media types with a source.

     

    • Marked as answer by mots_g Wednesday, November 30, 2011 5:38 AM
    Thursday, October 27, 2011 10:56 PM
  • Thanks Matt this worked!

    Now it seems to be failing elsewhere in the flow. However, I've not had time to dig into this. I'll get back if stuck on it again.

     

    Regards,

    Mots

    Wednesday, November 30, 2011 5:40 AM
  • hi, Matt, i encounterd a similar problem, help me to fix it. 

    http://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/2810ed05-7598-4b68-a674-5b34f6cbf584/first-configuration-on-imfsinkwriter-with-sok-then-setinputmediatype-method-error-what-is-the?forum=mediafoundationdevelopment

    Friday, July 11, 2014 3:41 AM