MFManagedEncode


MFManagedEncode.exe


This is a managed tool written in C# and XAML that converts files from one media format to another. The source code is provided to use as a reference on how to interop with source reader, sink writer and the transcode API from a managed environment.


The sample previews media files using WPF’s MediaElement object and a custom control that can be used to trim the output media.


Supported output formats:



  • Windows Media (WMV with WMA)

  • MPEG-4 (H.264 with AAC)

Technique


The tool converts media files using the basic functionality of new APIs introduced with Windows 7. Two different methods are implemented by the tool:



  • Configure the media session using the high level transcode API.

  • Use source reader and sink writer.

Since Media Foundation is built on COM the required interfaces and unmanaged calls were ported to C# using .NET interoperability capabilities.


The transcode API provides the following benefits:



  • The media session controls the operation. Therefore, there is no need to manipulate the samples manually.

  • Media samples are not brought to the managed environment which improves speed and memory usage.

Source reader and sink writer provide the following benefits:



  • Media sample attributes can be edited individually which gives more control to the developer.

  • The media sample raw data can be acquired from the buffers and used for other purposes (for example it is easy to copy the data from a video sample to a System.Drawing.Bitmap object).

Usage


When the application is executed the main window will show up (Figure 1).


clip_image002
Figure 1


  1.  Select the media file you want to convert by clicking the “Browse…” button to the right of the “Source” text box. When you do this the source location will be automatically chosen as the output folder.

  2.  Change the output folder by clicking the “Browse…” button to the right of the “Output folder” text box.

  3.  Start playback by clicking on the media frame.

  4.  Seek to different positions by moving the arrow located below the time bar.

  5.  Convert only a selected portion of the media by moving the blue controls in the time bar to adjust the start and end times.

  6.  Select the output media format from the “Format” dropdown list.

  7.  Select the output video size from the “Video size” dropdown list.

  8.  Bring up options for changing the audio codec, video codec, audio bit rate or video bit rate by clicking on “Advanced options” at the bottom-left corner of the window.

  9.  Start the transcode operation by clicking continue. The progress window will show up and the conversion will begin (Figure 2).

clip_image004
Figure 2

   10. The conversion window (Figure 2) will be automatically closed when the conversion is complete.


Limitations


The sample is made using WPF so Visual Studio 2008 or later is required. If you don’t have Visual Studio 2008 the sample can be compiled using Visual C# 2008 Express Edition which can be downloaded for free from the Microsoft Website.


Only the COM interface methods used by the tool have been tested; marshaling of unused methods could be wrong or missing the correct enumerations or object definitions.


Project Structure


\MFManagedEncode.csproj



The main C# project generated by Visual Studio. It contains information about the platforms, configurations and project  features.


\MediaFoundation\Interop\Classes.cs



Definitions of the COM classes needed.


\MediaFoundation\Interop\Constants.cs



Media Foundation constants needed.


\MediaFoundation\Interop\Enums.cs



Media Foundation enumerations needed.


\MediaFoundation\Interop\Interfaces.cs



Definition of the Media Foundation COM interfaces needed to perform the format conversion.


\MediaFoundation\Interop\Structures.cs



Structures that help interoperating with Media Foundation COM objects.


\MediaFoundation\Interfaces\ISimpleEncode.cs



C# interface used by the encoding classes.


\MediaFoundation\Classes\SimpleFastEncode.cs



C# class that inherits ISimpleEncode and encodes content using the Windows 7 transcode API.


\MediaFoundation\Classes\SimpleSinklWriterEncode.cs



C# class that inherits ISimpleEncode and encodes content using source reader and sink writer.


\MediaFoundation\Classes\EncapsulatedSample.cs



C# class that keeps track of the unmanaged memory used by samples and simplifies garbage collection.


\MediaFoundation\Common\Classes.cs



Support classes used by the tool.


\MediaFoundation\Common\Helper.cs



Exports the required Media Foundation functions from mfplat.dll and mf.dll.


\App.xaml



Holds the attributes that control the startup behavior.


\App.xaml.cs



Interaction logic for App.xaml.


\GUI\Controls\VideoTrimmer.xaml



Graphic design and animations of the user control used to trim media content.


\GUI\Controls\VideoTrimmer.xaml.cs



Interaction logic for VideoTrimmer.xaml which handles user input and events such as resizing.


\GUI\Windows\MainWindow.xaml



The main application window used to load media files and set the conversion parameters.


\GUI\Windows\MainWindow.xaml.cs



Interaction logic for MainWindow.xaml.


\GUI\Windows\ProgressWindow.xaml



The window that is shown during format conversion and displays the progress and estimated remaining time.


\GUI\Windows\ProgressWindow.xaml.cs



Interaction logic for ProgressWindow.xaml.


Downloading the Sample


You can download MFManagedEncode from http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=mfblog&DownloadId=9174


Follow the instruction at http://code.msdn.microsoft.com/mfblog for tips and instructions to build the sample.


This posting is provided “AS IS” with no warranties and confers no rights.

Comments (7)

  1. carlosp_uk says:

    Hello WMF team, and thanks for this excellent sample code – very useful.

    I am developing a C# application which will transcode local video files generated by windows media center (.WTV) files, and then stream them out to Silverlight.  (it contains a standalone webserver, it doesn’t use IIS)

    Firstly, I can’t seem to get the sample code to work with .wtv files, are they supported by the framework?  The thumbnail appears upon selecting a file, and the video aspect ratio is correctly determined, but conversion gives an exception from HRESULT of 0xC00D36D4.

    Secondly, how would I go about adapting this sample code to send the transcoded buffers out through a  System.Net.Socket object?  Just a couple of initial pointers appreciated.

    best,

    Carl Partridge

  2. Marcelo [MSFT] says:

    Hello Carl,

    This sample is exclusively using Media Foundation, so only those formats supported by MF can be used, and at the time this post was written DVR-MS and WTV are only supported by DShow. For a complete list of the containers and codecs supported by MF follow this link:

    http://msdn.microsoft.com/en-us/library/dd757927(VS.85).aspx

    Note that 3rd party MF decoders and parsers will be used by the application, so is possible to expand the formats supported by the in-box components.

    Regarding your second question, there are many ways of sending the sample data through a System.Net.Socket object, this suggestion use source reader and requires enabling unsafe code:

     IMFMediaBuffer sampleBuffer = null;

     IntPtr sampleBufferPtr = IntPtr.Zero;

     uint sampleBufferMax = 0;

     uint sampleBufferLength = 0;

     sample.MfSample.ConvertToContiguousBuffer(out sampleBuffer);

     sampleBuffer.Lock(sampleBufferPtr, out sampleBufferMax, out sampleBufferLength);

     byte* pDataSrc = (byte*)sampleBufferPtr.ToPointer();

       // Use the byte pointer to read the sample’s data, you

       // can also copy the data to a managed byte array if required

     sampleBuffer.Unlock();

    To make the previous code work you will need to make small modification to MediaFoundation/Interop/Interfaces.cs.

    Change the first parameter of:

    void Lock([Out] IntPtr ppbBuffer, out uint pcbMaxLength, out uint pcbCurrentLength);

    to:

    void Lock([Out] out IntPtr ppbBuffer, out uint pcbMaxLength, out uint pcbCurrentLength);

    Thanks!

    Marcelo

  3. carlosp_uk says:

    Hi Marcelo

    Thanks for your prompt answer and code.

    It’s disappointing that WMF doesn’t yet support the .wtv format as it’s an integral part of Windows 7 Media Center.  Is there any plans to support this soon?

    DShow support for transcoding .wtv is practically non-existent, unfortunately.

    Carl

  4. Hi Marcelo- this is an excellent project, and works really well- thank you.  I found previous attempts to wrap the MF objects in c# terribly frustrating (and unsuccessful), so well done on nailing it.

    You da man!

    Rhys

  5. I've had a go at using this project by example to make an aac-wav decoder, with no luck; have you written something to do this also?

  6. ltheonel says:

    Is it still possible to get a copy of the source?  The links in the blog no longer work.

    Thanks

  7. Ladislav Heller says:

    Hi!

    I am also interested in this topic. Where can I download the source code? The link in this blog post is dead.