Click here to Skip to main content
15,889,216 members
Articles / All Topics

Video Encoder and Metadata Reading by Using Windows Media Foundation

Rate me:
Please Sign up or sign in to vote.
4.33/5 (4 votes)
11 Aug 2011Ms-PL2 min read 29.5K   1   5
Video encoder and metadata reading by using Windows Media Foundation

In 1996-1997, together with Internet Explorer 3.0, Microsoft released API to work with media content (for example movies). They used to call it Quartz. This was a very convenient set of interfaces and thus was widely used by the industry. Now we call it DirectShow. Years passed, but DirectShow remains the same. It worked and worked very well. A couple of years ago, Microsoft decided that change was required and started to design a new COM-based multimedia framework for Windows Vista, 7 and 8. They called it Media Foundation. This framework is much more generic and extensible, but also much more intricate. Today, we’ll learn how to detect codec information of video or audio file by using Media Foundation in comparison to DirectShow SDK. So let’s start...

Spaghetti COM

How to Detect Codec of Media File by Using DirectShow

This one is simple. Create a new instance of media detector:

C#
var mediaDet = (IMediaDet)new MediaDet();

Put your file inside:

C#
var hr = mediaDet.put_Filename(fileName);

Enumerate media streams inside:

C#
int streamCount;     
hr = mediaDet.get_OutputStreams(out streamCount);

Get each stream:

C#
for (int i = 0; i < streamCount; i++) {     
hr = mediaDet.put_CurrentStream(i);

Detect its type:

C#
Guid streamType;     
hr = mediaDet.get_StreamType(out streamType);

And if type is video, get FourCC codec code and decrypt:

C#
if (streamType == MediaType.Video) {     
var mediaType = new AMMediaType();
hr = mediaDet.get_StreamMediaType(mediaType);
if (mediaType.formatType == FormatType.VideoInfo) {     
var videoHeader = (VideoInfoHeader)Marshal.PtrToStructure
                  (mediaType.formatPtr, typeof(VideoInfoHeader));
var fourCC = FourCCToString(videoHeader.BmiHeader.Compression);     
}

You can also get stream length and retrieve other properties.

C#
double streamLength;     
hr = mediaDet.get_StreamLength(out streamLength);

And what about managed signatures of this API? No problem, here it comes + FourCC decoder as bonus.

C#
   private static string FourCCToString(int fourcc) {     
      byte[] bytes = new byte[4];
      bytes[0] = (byte)(fourcc & 0x000000ff); fourcc = fourcc >> 8;     
      bytes[1] = (byte)(fourcc & 0x000000ff); fourcc = fourcc >> 8;      
      bytes[2] = (byte)(fourcc & 0x000000ff); fourcc = fourcc >> 8;      
      bytes[3] = (byte)(fourcc & 0x000000ff);
      return Encoding.ASCII.GetString(bytes);     
   }
   static public class MediaType {     
      public static readonly Guid Null = Guid.Empty;      
      public static readonly Guid Video = new Guid(0×73646976, 
      0×0000, 0×0010, 0×80, 0×00, 0×00, 
      0xaa, 0×00, 0×38, 0x9b, 0×71);      
      public static readonly Guid Audio = new Guid(0×73647561, 
      0×0000, 0×0010, 0×80, 0×00, 0×00, 
      0xaa, 0×00, 0×38, 0x9b, 0×71);      
   }
   static public class FormatType {     
      public static readonly Guid Null = Guid.Empty;
      public static readonly Guid None = new Guid(0x0F6417D6, 0xc318, 
      0x11d0, 0xa4, 0x3f, 0×00, 0xa0, 0xc9, 0×22, 0×31, 0×96);     
      public static readonly Guid VideoInfo = new Guid(0x05589f80, 0xc356, 
      0x11ce, 0xbf, 0×01, 0×00, 0xaa, 0×00, 0×55, 0×59, 0x5a);      
      public static readonly Guid VideoInfo2 = new Guid(0xf72a76A0, 0xeb0a, 
      0x11d0, 0xac, 0xe4, 0×00, 0×00, 0xc0, 0xcc, 0×16, 0xba);      
      public static readonly Guid WaveEx = new Guid(0x05589f81, 0xc356, 
      0x11ce, 0xbf, 0×01, 0×00, 0xaa, 0×00, 0×55, 0×59, 0x5a);      
      public static readonly Guid MpegVideo = new Guid(0x05589f82, 0xc356, 
      0x11ce, 0xbf, 0×01, 0×00, 0xaa, 0×00, 0×55, 0×59, 0x5a);      
      public static readonly Guid MpegStreams = new Guid(0x05589f83, 0xc356, 
      0x11ce, 0xbf, 0×01, 0×00, 0xaa, 0×00, 0×55, 0×59, 0x5a);      
      public static readonly Guid DvInfo = new Guid(0x05589f84, 0xc356, 
      0x11ce, 0xbf, 0×01, 0×00, 0xaa, 0×00, 0×55, 0×59, 0x5a);      
      public static readonly Guid AnalogVideo = new Guid(0x0482dde0, 
      0×7817, 0x11cf, 0x8a, 0×03, 0×00, 0xaa, 0×00, 0x6e, 0xcb, 0×65);      
      public static readonly Guid Mpeg2Video = new Guid(0xe06d80e3, 
      0xdb46, 0x11cf, 0xb4, 0xd1, 0×00, 0×80, 0x5f, 0x6c, 0xbb, 0xea);      
      public static readonly Guid DolbyAC3 = new Guid(0xe06d80e4, 0xdb46, 
      0x11cf, 0xb4, 0xd1, 0×00, 0×80, 0x5f, 0x6c, 0xbb, 0xea);      
      public static readonly Guid Mpeg2Audio = new Guid(0xe06d80e5, 0xdb46, 
      0x11cf, 0xb4, 0xd1, 0×00, 0×80, 0x5f, 0x6c, 0xbb, 0xea);      
      public static readonly Guid WSS525 = new Guid(0xc7ecf04d, 0×4582, 
      0×4869, 0x9a, 0xbb, 0xbf, 0xb5, 0×23, 0xb6, 0x2e, 0xdf);      
      public static readonly Guid ETDTFilter_Tagged = new Guid(0xC4C4C4D1, 
      0×0049, 0x4E2B, 0×98, 0xFB, 0×95, 
      0×37, 0xF6, 0xCE, 0×51, 0x6D);      
      public static readonly Guid CPFilters_Processed = new Guid(0x6739b36f, 
      0x1d5f, 0x4ac2, 0×81, 0×92, 0×28, 0xbb, 0xe, 0×73, 0xd1, 0x6a);      
   }
   [ComImport, Guid("65BD0711-24D2-4ff7-9324-ED2E5D3ABAFA")]     
   public class MediaDet {      
   }
   [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), 
   Guid("65BD0710-24D2-4ff7-9324-ED2E5D3ABAFA")]     
   public interface IMediaDet {      
      [PreserveSig]      
      int get_Filter([MarshalAs(UnmanagedType.IUnknown)] out object pVal);
      [PreserveSig]     
      int put_Filter([MarshalAs(UnmanagedType.IUnknown)] object newVal);
      [PreserveSig]     
      int get_OutputStreams(out int pVal);
      [PreserveSig]     
      int get_CurrentStream(out int pVal);
      [PreserveSig]     
      int put_CurrentStream(int newVal);
      [PreserveSig]     
      int get_StreamType(out Guid pVal);
      [PreserveSig]     
      int get_StreamTypeB([MarshalAs(UnmanagedType.BStr)] out string pVal);
      [PreserveSig]     
      int get_StreamLength(out double pVal);
      [PreserveSig]     
      int get_Filename([MarshalAs(UnmanagedType.BStr)] out string pVal);
      [PreserveSig]     
      int put_Filename([MarshalAs(UnmanagedType.BStr)] string newVal);
      [PreserveSig]     
      int GetBitmapBits(double StreamTime, out int pBufferSize, 
      [In] IntPtr pBuffer, int Width, int Height);
      [PreserveSig]     
      int WriteBitmapBits(double StreamTime, int Width, int Height, 
      [In, MarshalAs(UnmanagedType.BStr)] string ilename);
      [PreserveSig]     
      int get_StreamMediaType([Out, MarshalAs(UnmanagedType.LPStruct)] AMMediaType pVal);      

      [PreserveSig]      
      int GetSampleGrabber(out ISampleGrabber ppVal);
      [PreserveSig]     
      int get_FrameRate(out double pVal);
      [PreserveSig]     
      int EnterBitmapGrabMode(double SeekTime);      
   }
   [ComImport, Guid("6B652FFF-11FE-4fce-92AD-0266B5D7C78F"), 
   InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]     
   public interface ISampleGrabber {      
      [PreserveSig]      
      int SetOneShot([In, MarshalAs(UnmanagedType.Bool)] bool OneShot);
      [PreserveSig]     
      int SetMediaType([In, MarshalAs(UnmanagedType.LPStruct)] AMMediaType pmt);
      [PreserveSig]     
      int GetConnectedMediaType([Out, MarshalAs(UnmanagedType.LPStruct)] AMMediaType pmt);
      [PreserveSig]     
      int SetBufferSamples([In, MarshalAs(UnmanagedType.Bool)] bool BufferThem);
      [PreserveSig]     
      int GetCurrentBuffer(ref int pBufferSize, IntPtr pBuffer);
      [PreserveSig]     
      int GetCurrentSample(out IMediaSample ppSample);
      [PreserveSig]     
      int SetCallback(ISampleGrabberCB pCallback, int WhichMethodToCallback);      
   }
   [ComImport, Guid("0579154A-2B53-4994-B0D0-E773148EFF85"), 
   InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]     
   public interface ISampleGrabberCB {      
      [PreserveSig]      
      int SampleCB(double SampleTime, IMediaSample pSample);
      [PreserveSig]     
      int BufferCB(double SampleTime, IntPtr pBuffer, int BufferLen);      
   }
   [ComImport, Guid("56a8689a-0ad4-11ce-b03a-0020af0ba770"), 
   InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]     
   public interface IMediaSample {      
      [PreserveSig]      
      int GetPointer([Out] out IntPtr ppBuffer);      
      [PreserveSig]      
      int GetSize();
      [PreserveSig]     
      int GetTime([Out] out long pTimeStart, [Out] out long pTimeEnd);
      [PreserveSig]     
      int SetTime([In, MarshalAs(UnmanagedType.LPStruct)] LONG pTimeStart, 
      [In, MarshalAs(UnmanagedType.LPStruct)] LONG pTimeEnd);
      [PreserveSig]     
      int IsSyncPoint();
      [PreserveSig]     
      int SetSyncPoint([In, MarshalAs(UnmanagedType.Bool)] bool bIsSyncPoint);
      [PreserveSig]     
      int IsPreroll();
      [PreserveSig]     
      int SetPreroll([In, MarshalAs(UnmanagedType.Bool)] bool bIsPreroll);
      [PreserveSig]     
      int GetActualDataLength();
      [PreserveSig]     
      int SetActualDataLength([In] int len);
      [PreserveSig]     
      int GetMediaType([Out, MarshalAs(UnmanagedType.LPStruct)] out AMMediaType ppMediaType);
      [PreserveSig]     
      int SetMediaType([In, MarshalAs(UnmanagedType.LPStruct)] AMMediaType pMediaType);
      [PreserveSig]     
      int IsDiscontinuity();
      [PreserveSig]     
      int SetDiscontinuity([In, MarshalAs(UnmanagedType.Bool)] bool bDiscontinuity);
      [PreserveSig]     
      int GetMediaTime([Out] out long pTimeStart, [Out] out long pTimeEnd);
      [PreserveSig]     
      int SetMediaTime([In, MarshalAs(UnmanagedType.LPStruct)] 
      LONG pTimeStart, [In, MarshalAs(UnmanagedType.LPStruct)] LONG pTimeEnd);      
   }
   [StructLayout(LayoutKind.Sequential)]     
   public class AMMediaType {      
      public Guid majorType;      
      public Guid subType;      
      [MarshalAs(UnmanagedType.Bool)]      
      public bool fixedSizeSamples;      
      [MarshalAs(UnmanagedType.Bool)]      
      public bool temporalCompression;      
      public int sampleSize;      
      public Guid formatType;      
      public IntPtr unkPtr;       
      public int formatSize;      
      public IntPtr formatPtr;      
   }
   [StructLayout(LayoutKind.Sequential)]     
   public class VideoInfoHeader {      
      public RECT SrcRect;      
      public RECT TargetRect;      
      public int BitRate;      
      public int BitErrorRate;      
      public long AvgTimePerFrame;      
      public BitmapInfoHeader BmiHeader;      
   }
   [StructLayout(LayoutKind.Sequential, Pack = 2)]     
   public class BitmapInfoHeader {      
      public int Size;      
      public int Width;      
      public int Height;      
      public short Planes;      
      public short BitCount;      
      public int Compression;      
      public int ImageSize;      
      public int XPelsPerMeter;      
      public int YPelsPerMeter;      
      public int ClrUsed;      
      public int ClrImportant;      
   }
   [StructLayout(LayoutKind.Sequential)]      
   public class RECT {      
      public int left;      
      public int top;      
      public int right;      
      public int bottom;      
   }
   [StructLayout(LayoutKind.Sequential)]     
   public class LONG {      
      private long Value;      
   }      
}

Looks simple? It is. However there are two problems. One is that all those interfaces have been defined as deprecated by Microsoft. Second (which probably was the reason for deprecation of DirectShow), this is not really extensible interfaces. Now let’s see how it is done in Media Foundation.

How to Detect Codec of Media File by Using Media Foundation

First of all, we need to create source of the resolver:

C#
IMFSourceResolver res;     
var hr = MFCreateSourceResolver(out res);

Then create the actual resolver object:

C#
IMFMediaSource source = null;     
var objectType = MF_OBJECT_TYPE.Invalid;      
object srs;      
hr = res.CreateObjectFromURL(filePath, MFResolution.MediaSource, null, out objectType, out srs);      
objectType == MF_OBJECT_TYPE.MediaSource;      
source = (IMFMediaSource)srs;

When we have it, we’ll need to create descriptor.

C#
IMFPresentationDescriptor desc;     
source.CreatePresentationDescriptor(out desc);

Now we have everything to get streams count and retrieve streams.

C#
int count;     
desc.GetStreamDescriptorCount(out count);
for (int i = 0; i < count; i++) {     
IMFStreamDescriptor descriptor;      
bool selected;      
desc.GetStreamDescriptorByIndex(i, out selected, out descriptor);      
if (selected) {

Let’s get type handlers to have format:

C#
IMFMediaTypeHandler handler;     
descriptor.GetMediaTypeHandler(out handler);      
IMFMediaType type;      
handler.GetCurrentMediaType(out type);
Guid mediaType;     
type.GetMajorType(out mediaType);      
if (mediaType == MFMediaType.Video) {

And then actual media type and decoder code:

C#
hr = MFCreateMFVideoFormatFromMFMediaType(type, out format, out size));     
var fourCC = FourCCToString(format.surfaceInfo.Format);

Looks more complicated than the DirectShow approach. Let’s take a look into the actual interp definitions.

C#
[DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]     
public static extern void MFShutdown();
[DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]     
public static extern void MFStartup(int Version, MFSTARTUP dwFlags);
[DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]     
public static extern int MFCreateMFVideoFormatFromMFMediaType([In] 
IMFMediaType pMFType, out MFVIDEOFORMAT ppMFVF, out int pcbSize);      
      
[DllImport("mf.dll", ExactSpelling = true, PreserveSig = false)]      
public static extern int MFCreateSourceResolver(out IMFSourceResolver ppISourceResolver);
[DllImport("mf.dll", ExactSpelling = true, PreserveSig = false)]     
public static extern void MFGetService
([In, MarshalAs(UnmanagedType.Interface)] object punkObject, 
[In, MarshalAs(UnmanagedType.LPStruct)] Guid guidService, 
[In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, 
[Out, MarshalAs(UnmanagedType.Interface)] out object ppvObject);
#region INTERFACES
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), 
Guid("FBE5A32D-A497-4B61-BB85-97B1A848A6E3")]     
public interface IMFSourceResolver {      
   int CreateObjectFromURL([In, MarshalAs(UnmanagedType.LPWStr)] string pwszURL, 
   [In] MFResolution dwFlags, IPropertyStore pProps, out MF_OBJECT_TYPE pObjectType, 
   [MarshalAs(UnmanagedType.IUnknown)] out object ppObject);
   int CreateObjectFromByteStream([In, MarshalAs(UnmanagedType.Interface)] 
   IMFByteStream pByteStream, [In, MarshalAs(UnmanagedType.LPWStr)] string pwszURL, 
   [In] MFResolution dwFlags, 
   [In, MarshalAs(UnmanagedType.Interface)] IPropertyStore pProps, 
   out MF_OBJECT_TYPE pObjectType, [MarshalAs(UnmanagedType.IUnknown)] out object ppObject);
   int BeginCreateObjectFromURL([In, MarshalAs(UnmanagedType.LPWStr)] string pwszURL, 
   MFResolution dwFlags, IPropertyStore pProps, 
   [MarshalAs(UnmanagedType.IUnknown)] out object ppIUnknownCancelCookie, 
   IMFAsyncCallback pCallback, [In, MarshalAs(UnmanagedType.IUnknown)] object punkState);
   int EndCreateObjectFromURL(IMFAsyncResult pResult, out MF_OBJECT_TYPE pObjectType, 
   [MarshalAs(UnmanagedType.Interface)] out object ppObject);
   int BeginCreateObjectFromByteStream([In, MarshalAs(UnmanagedType.Interface)] 
   IMFByteStream pByteStream, [In, MarshalAs(UnmanagedType.LPWStr)] string pwszURL, 
   [In] MFResolution dwFlags, IPropertyStore pProps, [MarshalAs(UnmanagedType.IUnknown)] 
   out object ppIUnknownCancelCookie, IMFAsyncCallback pCallback, 
   [MarshalAs(UnmanagedType.IUnknown)] object punkState);
   int EndCreateObjectFromByteStream(IMFAsyncResult pResult, 
   out MF_OBJECT_TYPE pObjectType, [MarshalAs(UnmanagedType.IUnknown)] 
   out object ppObject);
   int CancelObjectCreation([In, MarshalAs(UnmanagedType.IUnknown)] 
   object pIUnknownCancelCookie);     
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), 
Guid("AD4C1B00-4BF7-422F-9175-756693D9130D")]     
public interface IMFByteStream {      
   void GetCapabilities(out MFBYTESTREAM pdwCapabilities);
   void GetLength(out long pqwLength);
   void SetLength([In] long qwLength);
   void GetCurrentPosition(out long pqwPosition);
   void SetCurrentPosition([In] long qwPosition);
   void IsEndOfStream([MarshalAs(UnmanagedType.Bool)] out bool pfEndOfStream);
   void Read(IntPtr pb, [In] int cb, out int pcbRead);
   void BeginRead(IntPtr pb, [In] int cb, 
   [In, MarshalAs(UnmanagedType.Interface)] 
   IMFAsyncCallback pCallback, [In, MarshalAs(UnmanagedType.IUnknown)] 
   object pUnkState);
   void EndRead([In, MarshalAs(UnmanagedType.Interface)] 
   IMFAsyncResult pResult, out int pcbRead);
   void Write(IntPtr pb, [In] int cb, out int pcbWritten);
   void BeginWrite(IntPtr pb, [In] int cb, 
   [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncCallback pCallback, 
   [In, MarshalAs(UnmanagedType.IUnknown)] object pUnkState);
   void EndWrite([In, MarshalAs(UnmanagedType.Interface)] 
   IMFAsyncResult pResult, out int pcbWritten);
   void Seek([In] MFBYTESTREAM_SEEK_ORIGIN SeekOrigin, 
   [In] long llSeekOffset, [In] MFBYTESTREAM_SEEK_FLAG dwSeekFlags, 
   out long pqwCurrentPosition);
   void Flush();
   void Close();     
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), 
Guid("886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99")]     
public interface IPropertyStore {      
   [MethodImpl(MethodImplOptions.InternalCall, 
   MethodCodeType = MethodCodeType.Runtime)]      
   void GetCount(out uint cProps);
   [MethodImpl(MethodImplOptions.InternalCall, 
   MethodCodeType = MethodCodeType.Runtime)]     
   void GetAt([In] uint iProp, out PROPERTYKEY pkey);
   [MethodImpl(MethodImplOptions.InternalCall, 
   MethodCodeType = MethodCodeType.Runtime)]     
   void GetValue([In] PROPERTYKEY key, out PROPVARIANT pv);
   [MethodImpl(MethodImplOptions.InternalCall, 
   MethodCodeType = MethodCodeType.Runtime)]     
   void SetValue([In] PROPERTYKEY key, [In] ref PROPVARIANT  pv);
   [MethodImpl(MethodImplOptions.InternalCall, 
   MethodCodeType = MethodCodeType.Runtime)]     
   void Commit();      
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), 
Guid("A27003CF-2354-4F2A-8D6A-AB7CFF15437E")]     
public interface IMFAsyncCallback {      
   void GetParameters(out MFASYNC pdwFlags, out MFASYNC_CALLBACK_QUEUE pdwQueue);
   void Invoke([In, MarshalAs(UnmanagedType.Interface)] IMFAsyncResult pAsyncResult);     
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), 
Guid("AC6B7889-0740-4D51-8619-905994A55CC6")]     
public interface IMFAsyncResult {      
   void GetState([MarshalAs(UnmanagedType.IUnknown)] out object ppunkState);
   [PreserveSig]     
   int GetStatus();
   void SetStatus([In, MarshalAs(UnmanagedType.Error)] int hrStatus);
   void GetObject([MarshalAs(UnmanagedType.Interface)] out object ppObject);
   [PreserveSig]     
   IntPtr GetStateNoAddRef();      
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), 
Guid("DF598932-F10C-4E39-BBA2-C308F101DAA3")]     
public interface IMFMediaEvent : IMFAttributes {      
   #region IMFAttributes methods
   new void GetItem([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, IntPtr pValue);
   new void GetItemType([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out MF_ATTRIBUTE_TYPE pType);
   new void CompareItem([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, IntPtr Value, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);
   new void Compare([MarshalAs(UnmanagedType.Interface)] 
   IMFAttributes pTheirs, MF_ATTRIBUTES_MATCH_TYPE MatchType, 
   [MarshalAs(UnmanagedType.Bool)] out bool pbResult);
   new void GetUINT32([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out int punValue);
   new void GetUINT64([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out long punValue);
   new void GetDouble([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out double pfValue);
   new void GetGUID([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out Guid pguidValue);
   new void GetStringLength([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out int pcchLength);
   new void GetString([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, 
   int cchBufSize, out int pcchLength);
   new void GetAllocatedString([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, out int pcchLength);
   new void GetBlobSize([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out int pcbBlobSize);
   new void GetBlob([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, 
   [Out, MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, int cbBufSize, out int pcbBlobSize);
   // Use GetBlob instead of this     
   new void GetAllocatedBlob([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out IntPtr ip, out int pcbSize);
   new void GetUnknown([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, 
   [MarshalAs(UnmanagedType.IUnknown)] out object ppv);
   new void SetItem([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, IntPtr Value);
   new void DeleteItem([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey);
   new void DeleteAllItems();
   new void SetUINT32([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, int unValue);
   new void SetUINT64([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, long unValue);
   new void SetDouble([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, double fValue);
   new void SetGUID([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidValue);
   new void SetString([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, [In, MarshalAs(UnmanagedType.LPWStr)] string wszValue);
   new void SetBlob([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, [In, MarshalAs(UnmanagedType.LPArray, 
   SizeParamIndex = 2)] byte[] pBuf, int cbBufSize);
   new void SetUnknown([MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, [In, MarshalAs(UnmanagedType.IUnknown)] object pUnknown);
   new void LockStore();
   new void UnlockStore();
   new void GetCount(out int pcItems);
   new void GetItemByIndex(int unIndex, out Guid pguidKey, IntPtr pValue);
   new void CopyAllItems([In, MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest);
   #endregion     
   void GetType(out MediaEventType pmet);
   void GetExtendedType(out Guid pguidExtendedType);
   void GetStatus([MarshalAs(UnmanagedType.Error)] out int phrStatus);
   void GetValue([In, Out] ref object pvValue);     
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), 
Guid("03CB2711-24D7-4DB6-A17F-F3A7A479A536")]     
public interface IMFPresentationDescriptor : IMFAttributes {
   #region IMFAttributes methods
   new void GetItem([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, IntPtr pValue);
   new void GetItemType([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out MF_ATTRIBUTE_TYPE pType);
   new void CompareItem([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, IntPtr Value, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);
   new void Compare([MarshalAs(UnmanagedType.Interface)] 
   IMFAttributes pTheirs, MF_ATTRIBUTES_MATCH_TYPE MatchType, 
   [MarshalAs(UnmanagedType.Bool)] out bool pbResult);
   new void GetUINT32([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out int punValue);
   new void GetUINT64([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out long punValue);
   new void GetDouble([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out double pfValue);
   new void GetGUID([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out Guid pguidValue);
   new void GetStringLength([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out int pcchLength);
   new void GetString([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, 
   int cchBufSize, out int pcchLength);
   new void GetAllocatedString([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, [MarshalAs(UnmanagedType.LPWStr)] 
   out string ppwszValue, out int pcchLength);
   new void GetBlobSize([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out int pcbBlobSize);
   new void GetBlob([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, 
   [Out, MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, int cbBufSize, out int pcbBlobSize);
   // Use GetBlob instead of this     
   new void GetAllocatedBlob([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out IntPtr ip, out int pcbSize);
   new void GetUnknown([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, 
   [MarshalAs(UnmanagedType.IUnknown)] out object ppv);
   new void SetItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr Value);
   new void DeleteItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey);
   new void DeleteAllItems();
   new void SetUINT32([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, int unValue);
   new void SetUINT64([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, long unValue);
   new void SetDouble([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, double fValue);
   new void SetGUID([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidValue);
   new void SetString([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, [In, MarshalAs(UnmanagedType.LPWStr)] string wszValue);
   new void SetBlob([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, [In, MarshalAs(UnmanagedType.LPArray, 
   SizeParamIndex = 2)] byte[] pBuf, int cbBufSize);
   new void SetUnknown([MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, [In, MarshalAs(UnmanagedType.IUnknown)] object pUnknown);
   new void LockStore();
   new void UnlockStore();
   new void GetCount(out int pcItems);
   new void GetItemByIndex(int unIndex, out Guid pguidKey, IntPtr pValue);
   new void CopyAllItems([In, MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest);
   #endregion
   void GetStreamDescriptorCount(out int pdwDescriptorCount);
   void GetStreamDescriptorByIndex([In] int dwIndex, 
   [MarshalAs(UnmanagedType.Bool)] out bool pfSelected, 
   [MarshalAs(UnmanagedType.Interface)] out IMFStreamDescriptor ppDescriptor);
   void SelectStream([In] int dwDescriptorIndex);
   void DeselectStream([In] int dwDescriptorIndex);
   void Clone([MarshalAs(UnmanagedType.Interface)] 
   out IMFPresentationDescriptor ppPresentationDescriptor);     
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), 
Guid("56C03D9C-9DBB-45F5-AB4B-D80F47C05938")]     
public interface IMFStreamDescriptor : IMFAttributes {      
   #region IMFAttributes methods
   new void GetItem([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, IntPtr pValue);
   new void GetItemType([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out MF_ATTRIBUTE_TYPE pType);
   new void CompareItem([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, IntPtr Value, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);
   new void Compare([MarshalAs(UnmanagedType.Interface)] 
   IMFAttributes pTheirs, MF_ATTRIBUTES_MATCH_TYPE MatchType, 
   [MarshalAs(UnmanagedType.Bool)] out bool pbResult);
   new void GetUINT32([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out int punValue);
   new void GetUINT64([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out long punValue);
   new void GetDouble([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out double pfValue);
   new void GetGUID([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out Guid pguidValue);
   new void GetStringLength([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out int pcchLength);
   new void GetString([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, [Out, MarshalAs(UnmanagedType.LPWStr)] 
   StringBuilder pwszValue, int cchBufSize, out int pcchLength);
   new void GetAllocatedString([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, out int pcchLength);
   new void GetBlobSize([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out int pcbBlobSize);
   new void GetBlob([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, 
   [Out, MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, int cbBufSize, out int pcbBlobSize);
   // Use GetBlob instead of this     
   new void GetAllocatedBlob([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out IntPtr ip, out int pcbSize);
   new void GetUnknown([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, 
   [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, 
   [MarshalAs(UnmanagedType.IUnknown)] out object ppv);
   new void SetItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr Value);
   new void DeleteItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey);
   new void DeleteAllItems();
   new void SetUINT32
   ([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, int unValue);
   new void SetUINT64
   ([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, long unValue);
   new void SetDouble
   ([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, double fValue);
   new void SetGUID
   ([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, 
   [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidValue);
   new void SetString([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, 
   [In, MarshalAs(UnmanagedType.LPWStr)] string wszValue);
   new void SetBlob([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, 
   [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, int cbBufSize);
   new void SetUnknown([MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, 
   [In, MarshalAs(UnmanagedType.IUnknown)] object pUnknown);
   new void LockStore();
   new void UnlockStore();
   new void GetCount(out int pcItems);
   new void GetItemByIndex(int unIndex, out Guid pguidKey, IntPtr pValue);
   new void CopyAllItems
   ([In, MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest);
   #endregion
   void GetStreamIdentifier(out int pdwStreamIdentifier);
   void GetMediaTypeHandler([MarshalAs(UnmanagedType.Interface)] 
   out IMFMediaTypeHandler ppMediaTypeHandler);     
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), 
Guid("44AE0FA8-EA31-4109-8D2E-4CAE4997C555")]     
public interface IMFMediaType : IMFAttributes {
   #region IMFAttributes methods
   new void GetItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, 
   IntPtr pValue);
   new void GetItemType([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out MF_ATTRIBUTE_TYPE pType);
   new void CompareItem([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, IntPtr Value, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);
   new void Compare([MarshalAs(UnmanagedType.Interface)] 
   IMFAttributes pTheirs, MF_ATTRIBUTES_MATCH_TYPE MatchType, 
   [MarshalAs(UnmanagedType.Bool)] out bool pbResult);
   new void GetUINT32([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out int punValue);
   new void GetUINT64([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out long punValue);
   new void GetDouble([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out double pfValue);
   new void GetGUID([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out Guid pguidValue);
   new void GetStringLength([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out int pcchLength);
   new void GetString([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, 
   [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, 
   int cchBufSize, out int pcchLength);
   new void GetAllocatedString([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, 
   [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, out int pcchLength);
   new void GetBlobSize([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, 
   out int pcbBlobSize);
   new void GetBlob([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, 
   [Out, MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, int cbBufSize, out int pcbBlobSize);
   // Use GetBlob instead of this     
   new void GetAllocatedBlob([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, 
   out IntPtr ip, out int pcbSize);
   new void GetUnknown([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, 
   [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, 
   [MarshalAs(UnmanagedType.IUnknown)] out object ppv);
   new void SetItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr Value);
   new void DeleteItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey);
   new void DeleteAllItems();
   new void SetUINT32
   ([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, int unValue);
   new void SetUINT64
   ([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, long unValue);
   new void SetDouble
   ([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, double fValue);
   new void SetGUID
   ([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, 
   [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidValue);
   new void SetString
   ([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, 
   [In, MarshalAs(UnmanagedType.LPWStr)] string wszValue);
   new void SetBlob([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, 
   [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, int cbBufSize);
   new void SetUnknown([MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, 
   [In, MarshalAs(UnmanagedType.IUnknown)] object pUnknown);
   new void LockStore();
   new void UnlockStore();
   new void GetCount(out int pcItems);
   new void GetItemByIndex(int unIndex, out Guid pguidKey, IntPtr pValue);
   new void CopyAllItems([In, MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest);
   #endregion
   void GetMajorType(out Guid pguidMajorType);
   void IsCompressedFormat([MarshalAs(UnmanagedType.Bool)] out bool pfCompressed);
   [PreserveSig]     
   int IsEqual([In, MarshalAs(UnmanagedType.Interface)] 
   IMFMediaType pIMediaType, out MF_MEDIATYPE_EQUAL pdwFlags);
   void GetRepresentation([In, MarshalAs(UnmanagedType.Struct)] 
   Guid guidRepresentation, out IntPtr ppvRepresentation);
   void FreeRepresentation([In, MarshalAs(UnmanagedType.Struct)] 
   Guid guidRepresentation, [In] IntPtr pvRepresentation);     
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), 
Guid("2CD2D921-C447-44A7-A13C-4ADABFC247E3")]     
public interface IMFAttributes {      
   void GetItem([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, IntPtr pValue);
   void GetItemType([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out MF_ATTRIBUTE_TYPE pType);
   void CompareItem([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, IntPtr Value, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);
   void Compare([MarshalAs(UnmanagedType.Interface)] 
   IMFAttributes pTheirs, MF_ATTRIBUTES_MATCH_TYPE MatchType, 
   [MarshalAs(UnmanagedType.Bool)] out bool pbResult);
   void GetUINT32([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out int punValue);
   void GetUINT64([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out long punValue);
   void GetDouble([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out double pfValue);
   void GetGUID([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out Guid pguidValue);
   void GetStringLength([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out int pcchLength);
   void GetString([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, 
   [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, 
   int cchBufSize, out int pcchLength);
   void GetAllocatedString([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, out int pcchLength);
   void GetBlobSize([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out int pcbBlobSize);
   void GetBlob([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, 
   [Out, MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, int cbBufSize, out int pcbBlobSize);
   void GetAllocatedBlob([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, out IntPtr ip, out int pcbSize);
   void GetUnknown([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, 
   [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, 
   [MarshalAs(UnmanagedType.IUnknown)] out object ppv);
   void SetItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr Value);
   void DeleteItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey);
   void DeleteAllItems();
   void SetUINT32([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, int unValue);
   void SetUINT64([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, long unValue);
   void SetDouble([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, double fValue);
   void SetGUID([In, MarshalAs(UnmanagedType.LPStruct)] 
   Guid guidKey, [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidValue);
   void SetString([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, 
   [In, MarshalAs(UnmanagedType.LPWStr)] string wszValue);
   void SetBlob([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, 
   [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, int cbBufSize);
   void SetUnknown([MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, 
   [In, MarshalAs(UnmanagedType.IUnknown)] object pUnknown);
   void LockStore();
   void UnlockStore();
   void GetCount(out int pcItems);
   void GetItemByIndex(int unIndex, out Guid pguidKey, IntPtr pValue);
   void CopyAllItems([In, MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest);     
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), 
Guid("2CD0BD52-BCD5-4B89-B62C-EADC0C031E7D")]     
public interface IMFMediaEventGenerator {      
   void GetEvent([In] IMFMediaEvent dwFlags, 
   [MarshalAs(UnmanagedType.Interface)] out IMFMediaEvent ppEvent);
   void BeginGetEvent([In, MarshalAs(UnmanagedType.Interface)] 
   IMFAsyncCallback pCallback, [In, MarshalAs(UnmanagedType.IUnknown)] object o);
   void EndGetEvent(IMFAsyncResult pResult, out IMFMediaEvent ppEvent);
   void QueueEvent([In] MediaEventType met, 
   [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidExtendedType, 
   [In] int hrStatus, [In] ref object pvValue);     
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), 
Guid("E93DCF6C-4B07-4E1E-8123-AA16ED6EADF5")]     
public interface IMFMediaTypeHandler {      
   void IsMediaTypeSupported([In, MarshalAs(UnmanagedType.Interface)] 
   IMFMediaType pMediaType, IntPtr ppMediaType);
   void GetMediaTypeCount(out int pdwTypeCount);
   void GetMediaTypeByIndex([In] int dwIndex, 
   [MarshalAs(UnmanagedType.Interface)] out IMFMediaType ppType);
   void SetCurrentMediaType([In, MarshalAs(UnmanagedType.Interface)] 
   IMFMediaType pMediaType);
   void GetCurrentMediaType([MarshalAs(UnmanagedType.Interface)] out 
   IMFMediaType ppMediaType);
   void GetMajorType(out Guid pguidMajorType);     
}
[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), 
Guid("279A808D-AEC7-40C8-9C6B-A6B492C78A66")]      
public interface IMFMediaSource : IMFMediaEventGenerator {      
   #region IMFMediaEventGenerator methods
   #pragma warning disable 109     
   new void GetEvent([In] MF_EVENT_FLAG dwFlags, 
   [MarshalAs(UnmanagedType.Interface)] out IMFMediaEvent ppEvent);      
   #pragma warning restore 109
   new void BeginGetEvent([In, MarshalAs(UnmanagedType.Interface)] 
   IMFAsyncCallback pCallback, [In, MarshalAs(UnmanagedType.IUnknown)] object o);
   new void EndGetEvent(IMFAsyncResult pResult, out IMFMediaEvent ppEvent);
   new void QueueEvent([In] MediaEventType met, 
   [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidExtendedType, 
   [In] int hrStatus, [In] ref object pvValue);
   #endregion
   void GetCharacteristics(out MFMEDIASOURCE_CHARACTERISTICS pdwCharacteristics);
   void CreatePresentationDescriptor
   (out IMFPresentationDescriptor ppPresentationDescriptor);
   void Start([In, MarshalAs(UnmanagedType.Interface)] 
   IMFPresentationDescriptor pPresentationDescriptor, 
   [In, MarshalAs(UnmanagedType.LPStruct)] Guid pguidTimeFormat, 
   [In] ref object pvarStartPosition);
   void Stop();
   void Pause();
   void Shutdown();     
}
#endregion

Plus some data objects:

C#
#region WM
      #region STRUCTS     
      #pragma warning restore 618
      [StructLayout(LayoutKind.Sequential, Pack = 8)]     
      public class MFVIDEOFORMAT {      
         public int dwSize;      
         public MFVideoInfo videoInfo;      
         public Guid guidFormat;      
         public MFVideoCompressedInfo compressedInfo;      
         public MFVideoSurfaceInfo surfaceInfo;      
      }
      [StructLayout(LayoutKind.Sequential, Pack = 4)]     
      public struct MFVideoSurfaceInfo {      
         public int Format;      
         public int PaletteEntries;      
         public MFPaletteEntry[] Palette;      
      }
      [StructLayout(LayoutKind.Explicit, Pack = 1)]     
      public struct MFPaletteEntry {      
         [FieldOffset(0)]      
         public MFARGB ARGB;      
         [FieldOffset(0)]      
         public MFAYUVSample AYCbCr;      
      }
      [StructLayout(LayoutKind.Sequential, Pack = 1)]     
      public struct MFAYUVSample {      
         public byte bCrValue;      
         public byte bCbValue;      
         public byte bYValue;      
         public byte bSampleAlpha8;      
      }
      [StructLayout(LayoutKind.Sequential, Pack = 1)]     
      public struct MFARGB {      
         public byte rgbBlue;      
         public byte rgbGreen;      
         public byte rgbRed;      
         public byte rgbAlpha;      
      }
      [StructLayout(LayoutKind.Sequential, Pack = 8)]     
      public struct MFVideoCompressedInfo {      
         public long AvgBitrate;      
         public long AvgBitErrorRate;      
         public int MaxKeyFrameSpacing;      
      }
      [StructLayout(LayoutKind.Sequential, Pack = 8)]     
      public struct MFVideoInfo {      
         public int dwWidth;      
         public int dwHeight;      
         public MFRatio PixelAspectRatio;      
         public MFVideoChromaSubsampling SourceChromaSubsampling;      
         public MFVideoInterlaceMode InterlaceMode;      
         public MFVideoTransferFunction TransferFunction;      
         public MFVideoPrimaries ColorPrimaries;      
         public MFVideoTransferMatrix TransferMatrix;      
         public MFVideoLighting SourceLighting;      
         public MFRatio FramesPerSecond;      
         public MFNominalRange NominalRange;      
         public MFVideoArea GeometricAperture;      
         public MFVideoArea MinimumDisplayAperture;      
         public MFVideoArea PanScanAperture;      
         public MFVideoFlags VideoFlags;      
      }
      [StructLayout(LayoutKind.Sequential, Pack = 4)]     
      public struct MFRatio {      
         public int Numerator;      
         public int Denominator;
         public MFRatio(int n, int d) {     
            Numerator = n;      
            Denominator = d;      
         }      
      }
      [StructLayout(LayoutKind.Sequential, Pack = 4)]     
      public class MFVideoArea {      
         public MFOffset OffsetX;      
         public MFOffset OffsetY;      
         public SIZE Area;
         public MFVideoArea() {     
            OffsetX = new MFOffset();      
            OffsetY = new MFOffset();      
         }
         public MFVideoArea(float x, float y, int width, int height) {     
            OffsetX = new MFOffset(x);      
            OffsetY = new MFOffset(y);      
            Area = new SIZE(width, height);      
         }
         public void MakeArea(float x, float y, int width, int height) {     
            OffsetX.MakeOffset(x);      
            OffsetY.MakeOffset(y);      
            Area.cx = width;      
            Area.cy = height;      
         }      
      }
      [StructLayout(LayoutKind.Sequential, Pack = 2)]     
      public class MFOffset {      
         public short fract;      
         public short Value;
         public MFOffset() {     
         }
         public MFOffset(float v) {     
            Value = (short)v;      
            fract = (short)(65536 * (v – Value));      
         }
         public void MakeOffset(float v) {     
            Value = (short)v;      
            fract = (short)(65536 * (v – Value));      
         }
         public float GetOffset() {     
            return ((float)Value) + (((float)fract) / 65536.0f);      
         }      
      }      
      #endregion
      #region ENUMS     
      public enum MFVideoInterlaceMode {      
         FieldInterleavedLowerFirst = 4,      
         FieldInterleavedUpperFirst = 3,      
         FieldSingleLower = 6,      
         FieldSingleUpper = 5,      
         ForceDWORD = 0x7fffffff,      
         Last = 8,      
         MixedInterlaceOrProgressive = 7,      
         Progressive = 2,      
         Unknown = 0      
      }
      public enum MFVideoChromaSubsampling {     
         Cosited = 7,      
         DV_PAL = 6,      
         ForceDWORD = 0x7fffffff,      
         Horizontally_Cosited = 4,      
         Last = 8,      
         MPEG1 = 1,      
         MPEG2 = 5,      
         ProgressiveChroma = 8,      
         Unknown = 0,      
         Vertically_AlignedChromaPlanes = 1,      
         Vertically_Cosited = 2      
      }
      public enum MFVideoTransferFunction {     
         Func10 = 1,      
         Func18 = 2,      
         Func20 = 3,      
         Func22 = 4,      
         Func240M = 6,      
         Func28 = 8,      
         Func709 = 5,      
         ForceDWORD = 0x7fffffff,      
         Last = 9,      
         sRGB = 7,      
         Unknown = 0      
      }
      public enum MFVideoPrimaries {     
         BT470_2_SysBG = 4,      
         BT470_2_SysM = 3,      
         BT709 = 2,      
         EBU3213 = 7,      
         ForceDWORD = 0x7fffffff,      
         Last = 9,      
         reserved = 1,      
         SMPTE_C = 8,      
         SMPTE170M = 5,      
         SMPTE240M = 6,      
         Unknown = 0      
      }
      public enum MFVideoTransferMatrix {     
         BT601 = 2,      
         BT709 = 1,      
         ForceDWORD = 0x7fffffff,      
         Last = 4,      
         SMPTE240M = 3,      
         Unknown = 0      
      }
      public enum MFVideoLighting {     
         Bright = 1,      
         Dark = 4,      
         Dim = 3,      
         ForceDWORD = 0x7fffffff,      
         Last = 5,      
         Office = 2,      
         Unknown = 0      
      }
      public enum MFNominalRange {     
         MFNominalRange_0_255 = 1,      
         MFNominalRange_16_235 = 2,      
         MFNominalRange_48_208 = 3,      
         MFNominalRange_ForceDWORD = 0x7fffffff,      
         MFNominalRange_Last = 4,      
         MFNominalRange_Normal = 1,      
         MFNominalRange_Unknown = 0,      
         MFNominalRange_Wide = 2      
      }
      [Flags]     
      public enum MFVideoFlags : long {      
         PAD_TO_Mask = 0×0001 | 0×0002,      
         PAD_TO_None = 0 * 0×0001,      
         PAD_TO_4x3 = 1 * 0×0001,      
         PAD_TO_16x9 = 2 * 0×0001,      
         SrcContentHintMask = 0×0004 | 0×0008 | 0×0010,      
         SrcContentHintNone = 0 * 0×0004,      
         SrcContentHint16x9 = 1 * 0×0004,      
         SrcContentHint235_1 = 2 * 0×0004,      
         AnalogProtected = 0×0020,      
         DigitallyProtected = 0×0040,      
         ProgressiveContent = 0×0080,      
         FieldRepeatCountMask = 0×0100 | 0×0200 | 0×0400,      
         FieldRepeatCountShift = 8,      
         ProgressiveSeqReset = 0×0800,      
         PanScanEnabled = 0×20000,      
         LowerFieldFirst = 0×40000,      
         BottomUpLinearRep = 0×80000,      
         DXVASurface = 0×100000,      
         RenderTargetSurface = 0×400000,      
         ForceQWORD = 0x7FFFFFFF      
      }
      [Flags]     
      public enum MF_EVENT_FLAG {      
         None = 0,      
         NoWait = 0×00000001      
      }
      public enum MFASYNC_CALLBACK_QUEUE {     
         Undefined = 0×00000000,      
         Standard = 0×00000001,      
         RT = 0×00000002,      
         IO = 0×00000003,      
         Timer = 0×00000004,      
         LongFunction = 0×00000007,      
         PrivateMask = unchecked((int)0xFFFF0000),      
         All = unchecked((int)0xFFFFFFFF)      
      }
      [Flags]     
      public enum MFASYNC {      
         None = 0,      
         FastIOProcessingCallback = 0×00000001,      
         SignalCallback = 0×00000002      
      }
      public enum MFSTARTUP {     
         NoSocket = 0×1,      
         Lite = 0×1,      
         Full = 0      
      }
      [Flags]     
      public enum MFResolution {      
         None = 0×0,      
         MediaSource = 0×00000001,      
         ByteStream = 0×00000002,      
         ContentDoesNotHaveToMatchExtensionOrMimeType = 0×00000010,      
         KeepByteStreamAliveOnFail = 0×00000020,      
         Read = 0×00010000,      
         Write = 0×00020000      
      }
      [Flags]     
      public enum MFBYTESTREAM {      
         None = 0×00000000,      
         IsReadable = 0×00000001,      
         IsWritable = 0×00000002,      
         IsSeekable = 0×00000004,      
         IsRemote = 0×00000008,      
         IsDirectory = 0×00000080,      
         HasSlowSeek = 0×00000100,      
         IsPartiallyDownloaded = 0×00000200      
      }
      public enum MFBYTESTREAM_SEEK_ORIGIN {     
         Begin,      
         Current      
      }
      [Flags]     
      public enum MFBYTESTREAM_SEEK_FLAG {      
         None = 0,      
         CancelPendingIO = 1      
      }
      public enum MF_OBJECT_TYPE {     
         MediaSource,      
         ByteStream,      
         Invalid      
      }
      public enum MediaEventType {     
         MEUnknown = 0,      
         MEError = (MEUnknown + 1),      
         MEExtendedType = (MEError + 1),      
         MESessionUnknown = 100,      
         MESessionTopologySet = (MESessionUnknown + 1),      
         MESessionTopologiesCleared = (MESessionTopologySet + 1),      
         MESessionStarted = (MESessionTopologiesCleared + 1),      
         MESessionPaused = (MESessionStarted + 1),      
         MESessionStopped = (MESessionPaused + 1),      
         MESessionClosed = (MESessionStopped + 1),      
         MESessionEnded = (MESessionClosed + 1),      
         MESessionRateChanged = (MESessionEnded + 1),      
         MESessionScrubSampleComplete = (MESessionRateChanged + 1),      
         MESessionCapabilitiesChanged = (MESessionScrubSampleComplete + 1),      
         MESessionTopologyStatus = (MESessionCapabilitiesChanged + 1),      
         MESessionNotifyPresentationTime = (MESessionTopologyStatus + 1),      
         MENewPresentation = (MESessionNotifyPresentationTime + 1),      
         MELicenseAcquisitionStart = (MENewPresentation + 1),      
         MELicenseAcquisitionCompleted = (MELicenseAcquisitionStart + 1),      
         MEIndividualizationStart = (MELicenseAcquisitionCompleted + 1),      
         MEIndividualizationCompleted = (MEIndividualizationStart + 1),      
         MEEnablerProgress = (MEIndividualizationCompleted + 1),      
         MEEnablerCompleted = (MEEnablerProgress + 1),      
         MEPolicyError = (MEEnablerCompleted + 1),      
         MEPolicyReport = (MEPolicyError + 1),      
         MEBufferingStarted = (MEPolicyReport + 1),      
         MEBufferingStopped = (MEBufferingStarted + 1),      
         MEConnectStart = (MEBufferingStopped + 1),      
         MEConnectEnd = (MEConnectStart + 1),      
         MEReconnectStart = (MEConnectEnd + 1),      
         MEReconnectEnd = (MEReconnectStart + 1),      
         MERendererEvent = (MEReconnectEnd + 1),      
         MESessionStreamSinkFormatChanged = (MERendererEvent + 1),      
         MESourceUnknown = 200,      
         MESourceStarted = (MESourceUnknown + 1),      
         MEStreamStarted = (MESourceStarted + 1),      
         MESourceSeeked = (MEStreamStarted + 1),      
         MEStreamSeeked = (MESourceSeeked + 1),      
         MENewStream = (MEStreamSeeked + 1),      
         MEUpdatedStream = (MENewStream + 1),      
         MESourceStopped = (MEUpdatedStream + 1),      
         MEStreamStopped = (MESourceStopped + 1),      
         MESourcePaused = (MEStreamStopped + 1),      
         MEStreamPaused = (MESourcePaused + 1),      
         MEEndOfPresentation = (MEStreamPaused + 1),      
         MEEndOfStream = (MEEndOfPresentation + 1),      
         MEMediaSample = (MEEndOfStream + 1),      
         MEStreamTick = (MEMediaSample + 1),      
         MEStreamThinMode = (MEStreamTick + 1),      
         MEStreamFormatChanged = (MEStreamThinMode + 1),      
         MESourceRateChanged = (MEStreamFormatChanged + 1),      
         MEEndOfPresentationSegment = (MESourceRateChanged + 1),      
         MESourceCharacteristicsChanged = (MEEndOfPresentationSegment + 1),      
         MESourceRateChangeRequested = (MESourceCharacteristicsChanged + 1),      
         MESourceMetadataChanged = (MESourceRateChangeRequested + 1),      
         MESequencerSourceTopologyUpdated = (MESourceMetadataChanged + 1),      
         MESinkUnknown = 300,      
         MEStreamSinkStarted = (MESinkUnknown + 1),      
         MEStreamSinkStopped = (MEStreamSinkStarted + 1),      
         MEStreamSinkPaused = (MEStreamSinkStopped + 1),      
         MEStreamSinkRateChanged = (MEStreamSinkPaused + 1),      
         MEStreamSinkRequestSample = (MEStreamSinkRateChanged + 1),      
         MEStreamSinkMarker = (MEStreamSinkRequestSample + 1),      
         MEStreamSinkPrerolled = (MEStreamSinkMarker + 1),      
         MEStreamSinkScrubSampleComplete = (MEStreamSinkPrerolled + 1),      
         MEStreamSinkFormatChanged = (MEStreamSinkScrubSampleComplete + 1),      
         MEStreamSinkDeviceChanged = (MEStreamSinkFormatChanged + 1),      
         MEQualityNotify = (MEStreamSinkDeviceChanged + 1),      
         MESinkInvalidated = (MEQualityNotify + 1),      
         MEAudioSessionNameChanged = (MESinkInvalidated + 1),      
         MEAudioSessionVolumeChanged = (MEAudioSessionNameChanged + 1),      
         MEAudioSessionDeviceRemoved = (MEAudioSessionVolumeChanged + 1),      
         MEAudioSessionServerShutdown = (MEAudioSessionDeviceRemoved + 1),      
         MEAudioSessionGroupingParamChanged = (MEAudioSessionServerShutdown + 1),      
         MEAudioSessionIconChanged = (MEAudioSessionGroupingParamChanged + 1),      
         MEAudioSessionFormatChanged = (MEAudioSessionIconChanged + 1),      
         MEAudioSessionDisconnected = (MEAudioSessionFormatChanged + 1),      
         MEAudioSessionExclusiveModeOverride = (MEAudioSessionDisconnected + 1),      
         METrustUnknown = 400,      
         MEPolicyChanged = (METrustUnknown + 1),      
         MEContentProtectionMessage = (MEPolicyChanged + 1),      
         MEPolicySet = (MEContentProtectionMessage + 1),      
         MEWMDRMLicenseBackupCompleted = 500,      
         MEWMDRMLicenseBackupProgress = 501,      
         MEWMDRMLicenseRestoreCompleted = 502,      
         MEWMDRMLicenseRestoreProgress = 503,      
         MEWMDRMLicenseAcquisitionCompleted = 506,      
         MEWMDRMIndividualizationCompleted = 508,      
         MEWMDRMIndividualizationProgress = 513,      
         MEWMDRMProximityCompleted = 514,      
         MEWMDRMLicenseStoreCleaned = 515,      
         MEWMDRMRevocationDownloadCompleted = 516,      
         MEReservedMax = 10000      
      }
      public enum MF_ATTRIBUTE_TYPE {     
         None = 0×0,      
         Blob = 0×1011,      
         Double = 0×5,      
         Guid = 0×48,      
         IUnknown = 13,      
         String = 0x1f,      
         Uint32 = 0×13,      
         Uint64 = 0×15      
      }
      public enum MF_ATTRIBUTES_MATCH_TYPE {     
         OurItems,      
         TheirItems,      
         AllItems,      
         InterSection,      
         Smaller      
      }
      [Flags]     
      public enum MFMEDIASOURCE_CHARACTERISTICS {      
         None = 0,      
         IsLive = 0×1,      
         CanSeek = 0×2,      
         CanPause = 0×4,      
         HasSlowSeek = 0×8      
      }
      [Flags]     
      public enum MF_MEDIATYPE_EQUAL {      
         None = 0,      
         MajorTypes = 0×00000001,      
         FormatTypes = 0×00000002,      
         FormatData = 0×00000004,      
         FormatUserData = 0×00000008      
      }      
      #endregion
      #endregion

Some cumbersome, right? It is! however those interfaces are extensible. Here for example, some added value of such approach.

How to Read Media Metadata by Using Media Foundation

Now, when we did most of the work, metadata is a piece of cake. All we need is to get service handle...

C#
object s;     
MFGetService(source, MFServices.MF_PROPERTY_HANDLER_SERVICE, typeof(IPropertyStore).GUID, out s);      
var store = (IPropertyStore)s;

...and get information out of the property bag:

C#
track.Album = _getInfo<string>(store, MFPropertyKeys.AlbumTitle);     
track.Name = _getInfo<string>(store, MFPropertyKeys.Title);      
track.Comments = _getInfo<string>(store, MFPropertyKeys.Comment);      
track.Duration = TimeSpan.FromTicks(_getInfo<long>(store, Interop.MFPropertyKeys.MediaDuration));      
…

Those interfaces use COM property bag to retrieve information of invariant type:

C#
private static T _getInfo<T>(IPropertyStore store, PROPERTYKEY key) {     
         PROPVARIANT val;      
         store.GetValue(key, out val);      
        return (T)val.Value;      
      }

Here is how this object looks in managed code:

C#
[StructLayout(LayoutKind.Sequential)]     
public class PROPERTYKEY {
public PROPERTYKEY(Guid tid, uint id) {     
fmtid = tid;      
pid = id;      
}
public Guid fmtid;
public uint pid;     
}
#pragma warning disable 618     
[StructLayout(LayoutKind.Explicit)]      
public struct PROPVARIANT {      
[FieldOffset(0)]      
short vt;      
[FieldOffset(2)]      
short wReserved1;      
[FieldOffset(4)]      
short wReserved2;      
[FieldOffset(6)]      
short wReserved3;      
[FieldOffset(8)]      
sbyte cVal;      
[FieldOffset(8)]      
byte bVal;      
[FieldOffset(8)]      
short iVal;      
[FieldOffset(8)]      
ushort uiVal;      
[FieldOffset(8)]      
int lVal;      
[FieldOffset(8)]      
uint ulVal;      
[FieldOffset(8)]      
int intVal;      
[FieldOffset(8)]      
uint uintVal;      
[FieldOffset(8)]      
long hVal;      
[FieldOffset(8)]      
long uhVal;      
[FieldOffset(8)]      
float fltVal;      
[FieldOffset(8)]      
double dblVal;      
[FieldOffset(8)]      
bool boolVal;      
[FieldOffset(8)]      
int scode;      
[FieldOffset(8)]      
DateTime date;      
[FieldOffset(8)]      
FILETIME filetime;      
[FieldOffset(8)]      
BLOB blobVal;      
[FieldOffset(8)]      
IntPtr pwszVal;
private byte[] _getBlob() {     
var result = new byte[blobVal.cbSize];      
Marshal.Copy(blobVal.pBlobData, result, 0, result.Length);      
return result;      
}
public object Value {     
get {      
VarEnum ve = (VarEnum)vt;      
switch (ve) {      
case VarEnum.VT_I1:      
return bVal;      
case VarEnum.VT_I2:      
return iVal;      
case VarEnum.VT_I4:      
return lVal;      
case VarEnum.VT_I8:      
return hVal;      
case VarEnum.VT_INT:      
return iVal;      
case VarEnum.VT_UI4:      
return ulVal;      
case VarEnum.VT_UI8:      
return uhVal;      
case VarEnum.VT_LPWSTR:      
return Marshal.PtrToStringUni(pwszVal);      
case VarEnum.VT_BLOB:      
return _getBlob();      
case VarEnum.VT_EMPTY:      
case VarEnum.VT_NULL:      
return null;      
}      
throw new NotImplementedException("PROPVARIANT: " + ve.ToString());      
}      
}      
}

And some additional classes and guids to fulfill solution:

C#
public static class MFAttributesClsid {     
public static readonly Guid MF_PD_DURATION = new Guid
(0x6c990d33, 0xbb8e, 0x477a, 0×85, 
0×98, 0xd, 0x5d, 0×96, 0xfc, 0xd8, 0x8a);      
public static readonly Guid MF_MT_SUBTYPE = 
new Guid(0xf7e34c9a, 0x42e8, 0×4714, 0xb7, 0x4b, 0xcb, 
0×29, 0xd7, 0x2c, 0×35, 0xe5);      
public static readonly Guid MF_MT_AVG_BITRATE = 
new Guid(0×20332624, 0xfb0d, 0x4d9e, 0xbd, 0x0d, 0xcb, 0xf6, 
0×78, 0x6c, 0×10, 0x2e);      
}
public static class MFMediaType {     
public static readonly Guid Default = new Guid(0x81A412E6, 
0×8103, 0x4B06, 0×85, 0x7F, 0×18, 0×62, 
0×78, 0×10, 0×24, 0xAC);      
public static readonly Guid Audio = new Guid(0×73647561, 
0×0000, 0×0010, 0×80, 0×00, 0×00, 
0xAA, 0×00, 0×38, 0x9B, 0×71);      
public static readonly Guid Video = new Guid(0×73646976, 
0×0000, 0×0010, 0×80, 0×00, 0×00, 
0xAA, 0×00, 0×38, 0x9B, 0×71);      
}
public static class MFServices {     
public static readonly Guid MF_PROPERTY_HANDLER_SERVICE = 
new Guid(0xa3face02, 0x32b8, 0x41dd, 0×90, 0xe7, 0x5f, 0xef, 
0x7c, 0×89, 0×91, 0xb5);      
}
public static class MFPropertyKeys {     
public static readonly PROPERTYKEY Title = new PROPERTYKEY
(new Guid(0xf29f85e0, 0x4ff9, 0×1068, 0xab, 0×91, 
0×08, 0×00, 0x2b, 0×27, 0xb3, 0xd9), 2);      
public static readonly PROPERTYKEY AlbumTitle = new PROPERTYKEY
(new Guid(0x56A3372E, 0xCE9C, 0x11D2, 0x9F, 0x0E, 0×00, 
0×60, 0×97, 0xC6, 0×86, 0xF6), 4);      
public static readonly PROPERTYKEY Author = new PROPERTYKEY
(new Guid(0xF29F85E0, 0x4FF9, 0×1068, 0xAB, 0×91, 
0×08, 0×00, 0x2B, 0×27, 0xB3, 0xD9), 4);      
public static readonly PROPERTYKEY AudioCompression = 
new PROPERTYKEY(new Guid(0×64440490, 0x4C8B, 0x11D1, 0x8B, 
0×70, 0×08, 0×00, 0×36, 0xB1, 0x1A, 0×03), 10);      
public static readonly PROPERTYKEY AudioFormat = new PROPERTYKEY
(new Guid(0×64440490, 0x4C8B, 0x11D1, 0x8B, 0×70, 
0×08, 0×00, 0×36, 0xB1, 0x1A, 0×03), 2);      
public static readonly PROPERTYKEY Category = new PROPERTYKEY
(new Guid(0xD5CDD502, 0x2E9C, 0x101B, 0×93, 0×97, 
0×08, 0×00, 0x2B, 0x2C, 0xF9, 0xAE), 2);      
public static readonly PROPERTYKEY Company = new PROPERTYKEY
(new Guid(0xD5CDD502, 0x2E9C, 0x101B, 0×93, 0×97, 
0×08, 0×00, 0x2B, 0x2C, 0xF9, 0xAE), 15);      
public static readonly PROPERTYKEY Copyright = 
new PROPERTYKEY(new Guid(0×64440492, 0x4C8B, 0x11D1, 0x8B, 
0×70, 0×08, 0×00, 0×36, 0xB1, 0x1A, 0×03), 11);      
public static readonly PROPERTYKEY Comment = new PROPERTYKEY
(new Guid(0xF29F85E0, 0x4FF9, 0×1068, 0xAB, 0×91, 
0×08, 0×00, 0x2B, 0×27, 0xB3, 0xD9), 6);      
public static readonly PROPERTYKEY MediaDuration = new PROPERTYKEY
(new Guid(0×64440490, 0x4C8B, 0x11D1, 0x8B, 0×70, 0×08, 
0×00, 0×36, 0xB1, 0x1A, 0×03), 3);      
public static readonly PROPERTYKEY VideoCompression = new PROPERTYKEY
(new Guid(0×64440491, 0x4C8B, 0x11D1, 0x8B, 0×70, 0×08, 
0×00, 0×36, 0xB1, 0x1A, 0×03), 10);      
public static readonly PROPERTYKEY VideoDirector = new PROPERTYKEY
(new Guid(0×64440492, 0x4C8B, 0x11D1, 0x8B, 0×70, 0×08, 
0×00, 0×36, 0xB1, 0x1A, 0×03), 20);      
public static readonly PROPERTYKEY VideoFourCC = new PROPERTYKEY
(new Guid(0×64440491, 0x4C8B, 0x11D1, 0x8B, 0×70, 0×08, 
0×00, 0×36, 0xB1, 0x1A, 0×03), 44);      
}

We almost finished. The only thing is not to forget to release all COM objects (Marshal.ReleaseComObject(…)) to prevent memory leaks and init and shutdown Media Foundation:

C#
MFStartup(0×10070, Interop.MFSTARTUP.Lite);     
…      
MFShutdown();

You choose what to use: simple, but not supported or complicated but extensible approach. Both will bring the same results. So have a nice day and be good people.

Related Posts

  1. RSA private key import from PEM format in C#

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)


Written By
Architect Better Place
Israel Israel
Hello! My name is Tamir Khason, and I am software architect, project manager, system analyst and [of course] programmer. In addition to writing big amount of documentation, I also write code, a lot of code. I used to work as a freelance architect, project manager, trainer, and consultant here, in Israel, but recently join the company with extremely persuasive idea - to make a world better place. I have very pretty wife and 3 charming kids, but unfortunately almost no time for them.

To be updated within articles, I publishing, visit my blog or subscribe RSS feed. Also you can follow me on Twitter to be up to date about my everyday life.

Comments and Discussions

 
QuestionHe Pin
Alitrix-kms18-Oct-19 3:50
Alitrix-kms18-Oct-19 3:50 
QuestionWM/Picture to System.Drawing.Image Pin
akshaysoft31-May-12 21:44
akshaysoft31-May-12 21:44 
GeneralThanks! A lot of info in one place. Pin
Alex Perepletov11-Nov-11 17:28
Alex Perepletov11-Nov-11 17:28 
GeneralMy vote of 1 Pin
Berat Bilgin15-Aug-11 21:23
Berat Bilgin15-Aug-11 21:23 
QuestionAudio Pin
Greg_moon15-Aug-11 10:38
Greg_moon15-Aug-11 10:38 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.