locked
Looking for document about IMediaExtension implementation

    Question

  • According to the MSDN page for IMediaExtension, this interface has only one method SetProperties void SetProperties(IPropertySet configuration). In other words, one only needs to implement SetProperties to have class supporting IMediaExtension.  Is there something like guideline for implementing SetProperties?

    Actually I am not sure my above understanding is correct.  There are samples (1, 2) in C++.  Those implementations are as simple as the following:

    IFACEMETHODIMP CDecoder::SetProperties (ABI::Windows::Foundation::Collections::IPropertySet *pConfiguration)
    {
        return S_OK;
    }

    Could anyone shed some light on this?

    In case you wonder what I am asking this for, I want to have my customMediaSink in MediaCapture.StartRecordToCustomSinkAsync(MediaEncodingProfile encodingProfile, IMediaExtension customMediaSink).

     

    Hong

    Thursday, March 19, 2015 2:18 PM

Answers

All replies

  • Hi Hong,

    IMediaExtension isn't very interesting on its own. In this case it will be used on an object which also implements the IMFMediaSink interface . The IMFMediaSink does the bulk of the work. IMediaExtension allows the caller to pass in controlling properties.

    See Deiter's response in https://social.msdn.microsoft.com/Forums/en-US/de6c10ec-4260-4b05-bc17-1f101c8f968a/getting-video-frames-using-mediacapture-class-and-custom-sink?forum=winappswithnativecode for some code snippets on the interface skeleton.

    Thursday, March 19, 2015 2:55 PM
    Moderator
  • Thanks a lot for the prompt response, Rob.

    It makes sense to me now though I still feel a bit lost when it comes to how customMediaSink in MediaCapture.StartRecordToCustomSinkAsync(MediaEncodingProfile encodingProfile, IMediaExtension customMediaSink) is used under the hood.

    Out of curiosity, I made the simplest video sink:

        public class CustomVideoSink:IMediaExtension
        {
            public void SetProperties(IPropertySet configuration)
            {
                Debug.WriteLine(configuration.ToString());
            }
        }

    and used it as following:

    await mcCapture.StartRecordToCustomSinkAsync(recordProfile, new CustomVideoSink());

    The app can be built without any problem.  However it generates the following error at runtime:

    System.InvalidCastException was caught
      HResult=-2147467262
      Message=Specified cast is not valid.
      Source=mscorlib
      StackTrace:
           at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
           at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
           at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
           at MyApp.Main.<<InitializeCaptureAsync>b__1a>d__1f.MoveNext()
      InnerException: 

    SetProperties is never called.


    Hong

    Thursday, March 19, 2015 5:10 PM
  • Rob, could you offer a tip on how to port the following into C#?

    class CGetSamples WrlSealed
    	: public RuntimeClass<
    	RuntimeClassFlags< Microsoft::WRL::RuntimeClassType::WinRtClassicComMix >,
    	ABI::Windows::Media::IMediaExtension,
    	IMFMediaSink,
    	IMFClockStateSink>


    Hong

    Thursday, March 19, 2015 5:46 PM
  • Hi Hong,

    What are you trying to achieve here? What do you want your sink to do?

    You're just at the tip of the iceberg here.

    Your CustomVideoSink class isn't a video sink. The sink part is the IMFMediaSink implementation. This will get added into and called from the media pipeline.

    IMediaExtension allows the caller to provide properties to the media sink implementation. Your app would call SetProperties before passing the object into StartRecordToCustomSinkAsync and the sink can then use those properties to change how it handles the media stream.

    Media sinks are really designed to be written in native code, not managed code, although depending on what you need the sink to do it may be possible in managed as well. You'll need to convert the interface definitions to C# yourself since they aren't wrapped by the system already.

    Thursday, March 19, 2015 7:07 PM
    Moderator
  • Thanks a lot for the elucidation, Rob.  I think I have got all the wanted information.  A little bit additional experiment will suffice for making a decision. 

    Without getting into all the details, I think the best way to describe what I want is the VideoSink class of Silverlight which I have been using. Actually, it works quite well. More specifically, I want to grab frames in quasi-real-time manner (a bit latency is OK).


    Hong

    Thursday, March 19, 2015 7:24 PM
  • If you don't care about latency then you can probably do this in C#, but you'll still need to get past defining the interfaces. If you're at all familiar with C++ I'd recommend using that and starting with one of the samples that already implements IMFMediaSink.
    Thursday, March 19, 2015 7:57 PM
    Moderator
  • Will do.  Thanks for the advice.  Though I have much more years on C++ than C#, but am not comfortable with mixing them.  I took a look at CMediaSink which depends on CStreamSink.  These seem to be all one needs for a custom video sink.

    Hong

    Thursday, March 19, 2015 8:36 PM