Udostępnij za pośrednictwem


MFCopy

MFCopy.exe - This is a command line tool showcasing the Windows 7 Media Foundation source reader and sink writer APIs. This tool copies multimedia files from one multimedia container to another. Copying can involve simply remultiplexing the streams, transcoding to convert the streams to a different format. The source code is provided to use as a reference for learning about the source reader and sink writer.

Techniques:

Transcoding is converting from one media format to another. The previous blog post described three mechanisms that Media Foundation provides to perform transcoding, taking a detailed look at the transcode API.

 

clip_image002

Figure 1. Three ways to perform transcoding

 

We will now describe the source reader and sink writer objects, and how they can be used for transcoding.

Source Reader:

The source reader is a Media Foundation component that provides direct access to multimedia data. Applications can use the source reader to extract sample data in the native format (usually compressed, but not necessarily), or can request that the source reader decode the multimedia data and output uncompressed samples. The source reader provides a consistent API regardless or container or format. Since it is built on the Media Foundation platform, the source reader supports any of the media sources and codecs registered with the platform.

How to use the Source Reader:

  • Create the reader object from either a URL, a byte stream, or an existing media source instance.
  • Select or deselect streams.
  • Configure the desired output format for the streams.
  • Seek to the starting position if desired.
    • Process multimedia data by calling IMFSourceReader::ReadSample until reaching the end of the stream, or until you have processed as much data as you want. The source reader supports both synchronous and asynchronous processing.

To read more about the source reader: https://msdn.microsoft.com/en-us/library/dd389281(VS.85).aspx

Sink Writer:

The sink writer is a Media Foundation component that provides a simple way to generate multimedia files. The application configures the target container and format for each stream and then gives each sample received from the source reader to the writer object. Like the source reader, the sink writer provides a consistent API regardless of the destination container or format.

How to use the Sink Writer:

  • Create the writer object from either a URL, a byte stream, or an existing media sink instance.
  • Add output streams, specifying the format of the data that will be written to the file.
  • Configure the input format, specifying the format of the data that will be passed to sink writer.
  • Call IMFSinkWriter::BeginWriting.
  • Process multimedia data by calling IMFSinkWriter::WriteSample until the end of the stream.Call IMFSinkWriter::Finalize to complete the file authoring process. This method can either block or call an asynchronous callback method when it completes.

To read more about the sink writer: https://msdn.microsoft.com/en-us/library/dd374642(VS.85).aspx

Project Structure:

MFCopy.vcproj

The Visual Studio project file

main.cpp

Contains the application entry point and all user interaction, including command-line parsing and progress notification.

mfcopy.cpp

Implements the copying engine that configures the source reader and sink writer and processes multimedia samples.

Usage:

mfcopy.exe [-?] [-a audio_format] [-nc num_channels] [-sr sample_rate] [-v video format] [-fs resolution] [-fr framerate] [-im interlace_mode] [-br video_bitrate] [-q] [-s milliseconds] [-d milliseconds] [-d milliseconds] [-hw] [-xa] [-xv] [-xo] [-xm] input_filename output_filename

-?
Display usage information.
-a audio_format
Set the output audio format. Defaults to the native format from the input file.
Examples: AAC, WMAudioV8, WMAudioV9, WMAudio_Lossless
-nc num_channels
Set the number of audio channels.
Example: 2
-sr sample_rate
Resample the audio to the specified rate.
Examples: 44100, 48000
-v video_format
Set the output video format. Defaults to the native format from the input file.
Examples: H264, WMV2, WMV3, WVC1
-fs resolution
Resize the video to the specified width and height.
Example: 640x480
-fr framerate
Convert the video frame rate to the specified rate.
Example: 30:1
-im interlace_mode
Set the video interlace mode.
Example: Progressive
-br video_bitrate
Set the average encoded bit rate for the video stream.
Example: 5000000
-q
Quiet mode.
-s milliseconds
Specify a start position in milliseconds.
-d milliseconds
Specify the duration to copy in milliseconds.
-hw
Enable hardware transforms.
-xa
Exclude audio streams.
-xv
Exclude video streams.
-xo
Exclude non audio/video streams (for example, text or script streams).
-xm
Exclude metadata.
input_filename
The path to the source file.
output_filename
The path to the destination file.

Examples:

  1. Copy 20 seconds of a WMV file without re-encoding: mfcopy.exe -d 20000 input.wmv output.wmv
  2. Resize the video from a WMV file while preserving the original audio stream: mfcopy.exe -fs 320x240 input.wmv output.wmv
  3. Transcode WMV to MP4 ensuring progressive video: mfcopy.exe -a AAC -v H264 -im Progressive input.wmv output.mp4
  4. Extract the audio stream from a WMV clip: mfcopy.exe -xv input.wmv output.wma

Limitations:

  1. The in-box Media Foundation file archive sinks support a maximum of one audio stream and one video stream in the output file.
  2. The Media Foundation source reader and sink writer do not support DRM transcoding.
  3. This tool cannot transcode to the MP3 format unless a third-party MP3 encoder MFT is installed. This is because the inbox MP3 encoder MFT is licensed for Microsoft applications only and will not work when loaded by third-party applications.
  4. Remuxing to a different container type might fail due to the specific container requirements.

Downloading the Sample

You can download MFCopy from https://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=mfblog&DownloadId=8574

Follow the instruction at https://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

  • Anonymous
    December 19, 2009
    I'm using the sink writer in my projects.  Is it possible to set WMV properties such as author, copyright, etc. in a programmatic way?  I can't find any documentation on this.

  • Anonymous
    December 25, 2009
    Sink Writer supports editing metadata if the underlying Media Sink supports it. For WMV you need to call IMFSinkWriter::GetServiceForStream querying the IMFMetadataProvider interface of the ASF Media Sink. More information: http://msdn.microsoft.com/en-us/library/dd374649(VS.85).aspx

  • Anonymous
    December 25, 2009
    Perfect, thanks.

  • Anonymous
    December 27, 2009
    The comment has been removed

  • Anonymous
    December 29, 2009
    You need to configure the audio renderer sink before calling MFCreateSinkWriterFromMediaSink; try the following (but remember to release the interfaces): IMFMediaSink *pAudioRenderer = NULL; IMFSinkWriter *pSink = NULL; IMFStreamSink *pStreamSink = NULL; IMFMediaTypeHandler *pMediaTypeHandler = NULL; IMFMediaType *pMediaType = NULL; EIF( MFCreateAudioRenderer(NULL, &pAudioRenderer) ); EIF( pAudioRenderer->GetStreamSinkByIndex(0, &pStreamSink) ); EIF( pStreamSink->GetMediaTypeHandler(&pMediaTypeHandler) ); EIF( MFCreateMediaType(&pMediaType) ); EIF( pMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio) ); EIF( pMediaType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_PCM) ); EIF( pMediaType->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, 2) ); EIF( pMediaType->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100) ); EIF( pMediaType->SetUINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 4) ); EIF( pMediaType->SetUINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 176400 ) ); EIF( pMediaType->SetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 16) ); EIF( pMediaType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE) ); EIF( pMediaTypeHandler->SetCurrentMediaType(pMediaType)); EIF( MFCreateSinkWriterFromMediaSink(pAudioRenderer, NULL, & pSink) );

  • Anonymous
    December 29, 2009
    Perfect; it works!  Thanks for your help.

  • Anonymous
    June 18, 2014
    Why did you pull down all the example code?

  • Anonymous
    August 18, 2015
    The comment has been removed