// Copyright (c) 2010-2011 SharpDX - Alexandre Mutel // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using SharpDX.Mathematics.Interop; using System; using System.IO; #if STORE_APP using Windows.Storage.Streams; #endif namespace SharpDX.MediaFoundation { public partial class SourceReader { private ByteStream byteStream; /// /// Creates the source reader from a URL /// /// The URL of a media file to open. ///

Pointer to the interface. You can use this parameter to configure the source reader. For more information, see Source Reader Attributes. This parameter can be null.

/// ///

Call CoInitialize(Ex) and before calling this function.

Internally, the source reader calls the method to create a media source from the byte stream. Therefore, a byte-stream handler must be registered for the byte stream. For more information about byte-stream handlers, see Scheme Handlers and Byte-Stream Handlers.

This function is available on Windows?Vista if Platform Update Supplement for Windows?Vista is installed.

///
/// dd388110 /// HRESULT MFCreateSourceReaderFromURL([In] const wchar_t* pwszURL,[In, Optional] IMFAttributes* pAttributes,[Out, Fast] IMFSourceReader** ppSourceReader) /// MFCreateSourceReaderFromURL public SourceReader(string url, MediaAttributes attributes = null) { MediaFactory.CreateSourceReaderFromURL(url, attributes, this); } /// /// Creates the source reader from a byte stream. /// ///

A reference to the interface of a byte stream. This byte stream will provide the source data for the source reader.

///

Pointer to the interface. You can use this parameter to configure the source reader. For more information, see Source Reader Attributes. This parameter can be null.

/// ///

Call CoInitialize(Ex) and before calling this function.

Internally, the source reader calls the method to create a media source from the byte stream. Therefore, a byte-stream handler must be registered for the byte stream. For more information about byte-stream handlers, see Scheme Handlers and Byte-Stream Handlers.

This function is available on Windows?Vista if Platform Update Supplement for Windows?Vista is installed.

///
/// dd388106 /// HRESULT MFCreateSourceReaderFromByteStream([In] IMFByteStream* pByteStream,[In, Optional] IMFAttributes* pAttributes,[Out, Fast] IMFSourceReader** ppSourceReader) /// MFCreateSourceReaderFromByteStream public SourceReader(byte[] buffer, MediaAttributes attributes = null) { byteStream = new ByteStream(new MemoryStream(buffer)); MediaFactory.CreateSourceReaderFromByteStream(byteStream, attributes, this); } /// /// Creates the source reader from a byte stream. /// ///

A reference to the interface of a byte stream. This byte stream will provide the source data for the source reader.

///

Pointer to the interface. You can use this parameter to configure the source reader. For more information, see Source Reader Attributes. This parameter can be null.

/// ///

Call CoInitialize(Ex) and before calling this function.

Internally, the source reader calls the method to create a media source from the byte stream. Therefore, a byte-stream handler must be registered for the byte stream. For more information about byte-stream handlers, see Scheme Handlers and Byte-Stream Handlers.

This function is available on Windows?Vista if Platform Update Supplement for Windows?Vista is installed.

///
/// dd388106 /// HRESULT MFCreateSourceReaderFromByteStream([In] IMFByteStream* pByteStream,[In, Optional] IMFAttributes* pAttributes,[Out, Fast] IMFSourceReader** ppSourceReader) /// MFCreateSourceReaderFromByteStream public SourceReader(Stream buffer, MediaAttributes attributes = null) { byteStream = new ByteStream(buffer); int capabilities = byteStream.Capabilities; MediaFactory.CreateSourceReaderFromByteStream(byteStream, attributes, this); } /// /// Creates the source reader from a /// /// Reference to the mediasource interface ///

Pointer to the interface. You can use this parameter to configure the source reader. For more information, see Source Reader Attributes. This parameter can be null.

/// ///

Call CoInitialize(Ex) and before calling this function.

By default, when the application releases the source reader, the source reader shuts down the media source by calling on the media source. At that point, the application can no longer use the media source.

To change this default behavior, set the attribute in the pAttributes parameter. If this attribute is TRUE, the application is responsible for shutting down the media source.

When using the Source Reader, do not call any of the following methods on the media source:

This function is available on Windows?Vista if Platform Update Supplement for Windows?Vista is installed.

Windows Phone 8.1: This API is supported.

///
/// dd388108 /// HRESULT MFCreateSourceReaderFromMediaSource([In] IMFMediaSource* pMediaSource,[In, Optional] IMFAttributes* pAttributes,[Out, Fast] IMFSourceReader** ppSourceReader) /// MFCreateSourceReaderFromMediaSource public SourceReader(MediaSource source, MediaAttributes attributes = null) { MediaFactory.CreateSourceReaderFromMediaSource(source, attributes, this); } #if STORE_APP /// /// Creates the source reader from a byte stream. /// ///

A reference to the interface of a byte stream. This byte stream will provide the source data for the source reader.

///

Pointer to the interface. You can use this parameter to configure the source reader. For more information, see Source Reader Attributes. This parameter can be null.

/// ///

Call CoInitialize(Ex) and before calling this function.

Internally, the source reader calls the method to create a media source from the byte stream. Therefore, a byte-stream handler must be registered for the byte stream. For more information about byte-stream handlers, see Scheme Handlers and Byte-Stream Handlers.

This function is available on Windows?Vista if Platform Update Supplement for Windows?Vista is installed.

///
/// dd388106 /// HRESULT MFCreateSourceReaderFromByteStream([In] IMFByteStream* pByteStream,[In, Optional] IMFAttributes* pAttributes,[Out, Fast] IMFSourceReader** ppSourceReader) /// MFCreateSourceReaderFromByteStream public SourceReader(IRandomAccessStream buffer, MediaAttributes attributes = null) { byteStream = new ByteStream(buffer); MediaFactory.CreateSourceReaderFromByteStream(byteStream, attributes, this); } #endif #if DESKTOP_APP /// /// Creates the source reader from a byte stream. /// ///

A reference to the interface of a byte stream. This byte stream will provide the source data for the source reader.

///

Pointer to the interface. You can use this parameter to configure the source reader. For more information, see Source Reader Attributes. This parameter can be null.

/// ///

Call CoInitialize(Ex) and before calling this function.

Internally, the source reader calls the method to create a media source from the byte stream. Therefore, a byte-stream handler must be registered for the byte stream. For more information about byte-stream handlers, see Scheme Handlers and Byte-Stream Handlers.

This function is available on Windows?Vista if Platform Update Supplement for Windows?Vista is installed.

///
/// dd388106 /// HRESULT MFCreateSourceReaderFromByteStream([In] IMFByteStream* pByteStream,[In, Optional] IMFAttributes* pAttributes,[Out, Fast] IMFSourceReader** ppSourceReader) /// MFCreateSourceReaderFromByteStream public SourceReader(SharpDX.Win32.ComStream comStream, MediaAttributes attributes = null) { byteStream = new ByteStream(comStream); MediaFactory.CreateSourceReaderFromByteStream(byteStream, attributes, this); } #endif /// ///

Applies to: desktop apps | Metro style apps

Gets a format that is supported natively by the media source.

///
///

Specifies which stream to query. The value can be any of the following.

ValueMeaning
0?0xFFFFFFFB

The zero-based index of a stream.

0xFFFFFFFC

The first video stream.

0xFFFFFFFD

The first audio stream.

?

///

The zero-based index of the media type to retrieve.

///

Receives a reference to the interface. The caller must release the interface.

/// ///

This method queries the underlying media source for its native output format. Potentially, each source stream can produce more than one output format. Use the dwMediaTypeIndex parameter to loop through the available formats. Generally, file sources offer just one format per stream, but capture devices might offer several formats.

The method returns a copy of the media type, so it is safe to modify the object received in the ppMediaType parameter.

To set the output type for a stream, call the method.

This interface is available on Windows?Vista if Platform Update Supplement for Windows?Vista is installed.

///
/// dd374661 /// HRESULT IMFSourceReader::GetNativeMediaType([In] unsigned int dwStreamIndex,[In] unsigned int dwMediaTypeIndex,[Out] IMFMediaType** ppMediaType) /// IMFSourceReader::GetNativeMediaType public SharpDX.MediaFoundation.MediaType GetNativeMediaType(SourceReaderIndex readerIndex, int dwMediaTypeIndex) { return GetNativeMediaType((int)readerIndex, dwMediaTypeIndex); } /// ///

Applies to: desktop apps | Metro style apps

Selects or deselects one or more streams.

///
///

The stream to set. The value can be any of the following.

ValueMeaning
0?0xFFFFFFFB

The zero-based index of a stream.

0xFFFFFFFC

The first video stream.

0xFFFFFFFD

The first audio stream.

0xFFFFFFFE

All streams.

?

///

Specify TRUE to select streams or to deselect streams. If a stream is deselected, it will not generate data.

///

If this method succeeds, it returns . Otherwise, it returns an error code.

/// ///

There are two common uses for this method:

For an example of deselecting a stream, see Tutorial: Decoding Audio.

If a stream is deselected, the method returns MF_E_INVALIDREQUEST for that stream. Other methods are valid for deselected streams.

Stream selection does not affect how the source reader loads or unloads decoders in memory. In particular, deselecting a stream does not force the source reader to unload the decoder for that stream.

This interface is available on Windows?Vista if Platform Update Supplement for Windows?Vista is installed.

///
/// dd374669 /// HRESULT IMFSourceReader::SetStreamSelection([In] unsigned int dwStreamIndex,[In] BOOL fSelected) /// IMFSourceReader::SetStreamSelection public void SetStreamSelection(SourceReaderIndex readerIndex, RawBool fSelected) { SetStreamSelection((int)readerIndex, fSelected); } /// ///

Applies to: desktop apps | Metro style apps

Sets the media type for a stream.

This media type defines that format that the Source Reader produces as output. It can differ from the native format provided by the media source. See Remarks for more information.

///
/// No documentation. /// No documentation. ///

The method returns an . Possible values include, but are not limited to, those in the following table.

Return codeDescription

The method succeeded.

MF_E_INVALIDMEDIATYPE

At least one decoder was found for the native stream type, but the type specified by pMediaType was rejected.

MF_E_INVALIDREQUEST

One or more sample requests are still pending.

MF_E_INVALIDSTREAMNUMBER

The dwStreamIndex parameter is invalid.

MF_E_TOPO_CODEC_NOT_FOUND

Could not find a decoder for the native stream type.

?

/// ///

For each stream, you can set the media type to any of the following:

The source reader does not support audio resampling. If you need to resample the audio, you can use the Audio Resampler DSP.

If you set the attribute to TRUE when you create the Source Reader, the Source Reader will convert YUV video to RGB-32. This conversion is not optimized for real-time video playback.

This interface is available on Windows?Vista if Platform Update Supplement for Windows?Vista is installed.

///
/// dd374667 /// HRESULT IMFSourceReader::SetCurrentMediaType([In] unsigned int dwStreamIndex,[In] unsigned int* pdwReserved,[In] IMFMediaType* pMediaType) /// IMFSourceReader::SetCurrentMediaType public void SetCurrentMediaType(SourceReaderIndex readerIndex, MediaType mediaTypeRef) { SetCurrentMediaType((int)readerIndex, IntPtr.Zero, mediaTypeRef); } /// ///

Applies to: desktop apps | Metro style apps

Sets the media type for a stream.

This media type defines that format that the Source Reader produces as output. It can differ from the native format provided by the media source. See Remarks for more information.

///
/// No documentation. /// No documentation. ///

The method returns an . Possible values include, but are not limited to, those in the following table.

Return codeDescription

The method succeeded.

MF_E_INVALIDMEDIATYPE

At least one decoder was found for the native stream type, but the type specified by pMediaType was rejected.

MF_E_INVALIDREQUEST

One or more sample requests are still pending.

MF_E_INVALIDSTREAMNUMBER

The dwStreamIndex parameter is invalid.

MF_E_TOPO_CODEC_NOT_FOUND

Could not find a decoder for the native stream type.

?

/// ///

For each stream, you can set the media type to any of the following:

The source reader does not support audio resampling. If you need to resample the audio, you can use the Audio Resampler DSP.

If you set the attribute to TRUE when you create the Source Reader, the Source Reader will convert YUV video to RGB-32. This conversion is not optimized for real-time video playback.

This interface is available on Windows?Vista if Platform Update Supplement for Windows?Vista is installed.

///
/// dd374667 /// HRESULT IMFSourceReader::SetCurrentMediaType([In] unsigned int dwStreamIndex,[In] unsigned int* pdwReserved,[In] IMFMediaType* pMediaType) /// IMFSourceReader::SetCurrentMediaType public void SetCurrentMediaType(int readerIndex, MediaType mediaTypeRef) { SetCurrentMediaType(readerIndex, IntPtr.Zero, mediaTypeRef); } /// ///

Applies to: desktop apps | Metro style apps

Seeks to a new position in the media source.

///
/// The position from which playback will be started. 100-nanosecond units. /// ///

The SetCurrentPosition method does not guarantee exact seeking. The accuracy of the seek depends on the media content. If the media content contains a video stream, the SetCurrentPosition method typically seeks to the nearest key frame before the desired position. The distance between key frames depends on several factors, including the encoder implementation, the video content, and the particular encoding settings used to encode the content. The distance between key frame can vary within a single video file (for example, depending on scene complexity).

After seeking, the application should call and advance to the desired position.

This interface is available on Windows?Vista if Platform Update Supplement for Windows?Vista is installed.

///
/// dd374668 /// HRESULT IMFSourceReader::SetCurrentPosition([In] const GUID& guidTimeFormat,[In] const PROPVARIANT& varPosition) /// IMFSourceReader::SetCurrentPosition public void SetCurrentPosition(long position) { SetCurrentPosition(Guid.Empty, new SharpDX.Win32.Variant { Value = position }); } /// ///

Applies to: desktop apps | Metro style apps

Gets the current media type for a stream.

///
///

The stream to query. The value can be any of the following.

ValueMeaning
0?0xFFFFFFFB

The zero-based index of a stream.

0xFFFFFFFC

The first video stream.

0xFFFFFFFD

The first audio stream.

?

///

Receives a reference to the interface. The caller must release the interface.

/// ///

This interface is available on Windows?Vista if Platform Update Supplement for Windows?Vista is installed.

///
/// dd374660 /// HRESULT IMFSourceReader::GetCurrentMediaType([In] unsigned int dwStreamIndex,[Out] IMFMediaType** ppMediaType) /// IMFSourceReader::GetCurrentMediaType public SharpDX.MediaFoundation.MediaType GetCurrentMediaType(SourceReaderIndex readerIndex) { return GetCurrentMediaType((int)readerIndex); } /// ///

Applies to: desktop apps | Metro style apps

Reads the next sample from the media source.

///
///

The stream to pull data from. The value can be any of the following.

ValueMeaning
0?0xFFFFFFFB

The zero-based index of a stream.

0xFFFFFFFC

The first video stream.

0xFFFFFFFD

The first audio stream.

0xFFFFFFFE

Get the next available sample, regardless of which stream.

?

///

A bitwise OR of zero or more flags from the enumeration.

///

Receives the zero-based index of the stream.

///

Receives a bitwise OR of zero or more flags from the enumeration.

///

Receives the time stamp of the sample, or the time of the stream event indicated in pdwStreamFlags. The time is given in 100-nanosecond units.

///

Receives a reference to the interface or the value null (see Remarks). If this parameter receives a non-null reference, the caller must release the interface.

/// ///

If the requested stream is not selected, the return code is MF_E_INVALIDREQUEST. See .

This method can complete synchronously or asynchronously. If you provide a callback reference when you create the source reader, the method is asynchronous. Otherwise, the method is synchronous. For more information about setting the callback reference, see .

Asynchronous Mode

In asynchronous mode:

Synchronous Mode

In synchronous mode:

In synchronous mode, if the dwStreamIndex parameter is , you should pass a non-null value for pdwActualStreamIndex, so that you know which stream delivered the sample.

This method can return flags in the pdwStreamFlags parameter without returning a media sample in ppSample. Therefore, the ppSample parameter can receive a null reference even when the method succeeds. For example, when the source reader reaches the end of the stream, it returns the flag in pdwStreamFlags and sets ppSample to null.

If there is a gap in the stream, pdwStreamFlags receives the flag, ppSample is null, and pllTimestamp indicates the time when the gap occurred.

This interface is available on Windows?Vista if Platform Update Supplement for Windows?Vista is installed.

///
/// dd374665 /// HRESULT IMFSourceReader::ReadSample([In] unsigned int dwStreamIndex,[In] unsigned int dwControlFlags,[Out, Optional] unsigned int* pdwActualStreamIndex,[Out, Optional] unsigned int* pdwStreamFlags,[Out, Optional] longlong* pllTimestamp,[Out, Optional] IMFSample** ppSample) /// IMFSourceReader::ReadSample public SharpDX.MediaFoundation.Sample ReadSample(SourceReaderIndex dwStreamIndex, SourceReaderControlFlags dwControlFlags, out int dwActualStreamIndexRef, out SourceReaderFlags dwStreamFlagsRef, out long llTimestampRef) { return ReadSample((int)dwStreamIndex, dwControlFlags, out dwActualStreamIndexRef, out dwStreamFlagsRef, out llTimestampRef); } /// ///

Applies to: desktop apps | Metro style apps

Flushes one or more streams.

///
///

The stream to flush. The value can be any of the following.

ValueMeaning
0?0xFFFFFFFB

The zero-based index of a stream.

0xFFFFFFFC

The first video stream.

0xFFFFFFFD

The first audio stream.

0xFFFFFFFE

All streams.

?

///

If this method succeeds, it returns . Otherwise, it returns an error code.

/// ///

The Flush method discards all queued samples and cancels all pending sample requests.

This method can complete either synchronously or asynchronously. If you provide a callback reference when you create the source reader, the method is asynchronous. Otherwise, the method is synchronous. For more information about the setting the callback reference, see .

In synchronous mode, the method blocks until the operation is complete.

In asynchronous mode, the application's method is called when the flush operation completes. While a flush operation is pending, the method returns MF_E_NOTACCEPTING.

Note??In Windows?7, there was a bug in the implementation of this method, which causes OnFlush to be called before the flush operation completes. A hotfix is available that fixes this bug. For more information, see http://support.microsoft.com/kb/979567.

This interface is available on Windows?Vista if Platform Update Supplement for Windows?Vista is installed.

///
/// /// dd374659 /// HRESULT IMFSourceReader::Flush([In] unsigned int dwStreamIndex) /// IMFSourceReader::Flush public void Flush(SourceReaderIndex dwStreamIndex) { Flush((int)dwStreamIndex); } /// ///

Applies to: desktop apps | Metro style apps

Queries the underlying media source or decoder for an interface.

///
///

The stream or object to query. If the value is , the method queries the media source. Otherwise, it queries the decoder that is associated with the specified stream. The following values are possible.

ValueMeaning
0?0xFFFFFFFB

The zero-based index of a stream.

0xFFFFFFFC

The first video stream.

0xFFFFFFFD

The first audio stream.

0xFFFFFFFF

The media source.

?

///

A service identifier . If the value is GUID_NULL, the method calls QueryInterface to get the requested interface. Otherwise, the method calls the method. For a list of service identifiers, see Service Interfaces.

///

The interface identifier (IID) of the interface being requested.

///

Receives a reference to the requested interface. The caller must release the interface.

/// ///

This interface is available on Windows?Vista if Platform Update Supplement for Windows?Vista is installed.

///
/// dd374663 /// HRESULT IMFSourceReader::GetServiceForStream([In] unsigned int dwStreamIndex,[In] const GUID& guidService,[In] const GUID& riid,[Out] void** ppvObject) /// IMFSourceReader::GetServiceForStream public System.IntPtr GetServiceForStream(SourceReaderIndex dwStreamIndex, System.Guid guidService, System.Guid riid) { return GetServiceForStream((int) dwStreamIndex, guidService, riid); } /// ///

Applies to: desktop apps | Metro style apps

Gets an attribute from the underlying media source.

///
///

The stream or object to query. The value can be any of the following.

ValueMeaning
0?0xFFFFFFFB

The zero-based index of a stream.

0xFFFFFFFC

The first video stream.

0xFFFFFFFD

The first audio stream.

0xFFFFFFFF

The media source.

?

///

A that identifies the attribute to retrieve. If the dwStreamIndex parameter equals , guidAttribute can specify one of the following:

Otherwise, if the dwStreamIndex parameter specifies a stream, guidAttribute specifies a stream descriptor attribute. For a list of values, see Stream Descriptor Attributes.

/// a that receives the value of the attribute. /// ///

This interface is available on Windows?Vista if Platform Update Supplement for Windows?Vista is installed.

///
/// dd374662 /// HRESULT IMFSourceReader::GetPresentationAttribute([In] unsigned int dwStreamIndex,[In] const GUID& guidAttribute,[Out] PROPVARIANT* pvarAttribute) /// IMFSourceReader::GetPresentationAttribute public T GetPresentationAttribute(SourceReaderIndex dwStreamIndex, MediaAttributeKey guidAttribute) { var variant = GetPresentationAttribute((int)dwStreamIndex, guidAttribute.Guid); return (T)Convert.ChangeType(variant.Value, typeof (T)); } /// ///

Applies to: desktop apps | Metro style apps

Gets an attribute from the underlying media source.

///
///

The stream or object to query. The value can be any of the following.

ValueMeaning
0?0xFFFFFFFB

The zero-based index of a stream.

0xFFFFFFFC

The first video stream.

0xFFFFFFFD

The first audio stream.

0xFFFFFFFF

The media source.

?

///

A that identifies the attribute to retrieve. If the dwStreamIndex parameter equals , guidAttribute can specify one of the following:

  • A presentation descriptor attribute. For a list of values, see Presentation Descriptor Attributes.
  • . Use this value to get characteristics flags from the media source.

Otherwise, if the dwStreamIndex parameter specifies a stream, guidAttribute specifies a stream descriptor attribute. For a list of values, see Stream Descriptor Attributes.

/// a that receives the value of the attribute. /// ///

This interface is available on Windows?Vista if Platform Update Supplement for Windows?Vista is installed.

///
/// dd374662 /// HRESULT IMFSourceReader::GetPresentationAttribute([In] unsigned int dwStreamIndex,[In] const GUID& guidAttribute,[Out] PROPVARIANT* pvarAttribute) /// IMFSourceReader::GetPresentationAttribute public SharpDX.Win32.Variant GetPresentationAttribute(SourceReaderIndex dwStreamIndex, System.Guid guidAttribute) { return GetPresentationAttribute((int)dwStreamIndex, guidAttribute); } protected override void Dispose(bool disposing) { base.Dispose(disposing); if (byteStream != null) { byteStream.Dispose(); byteStream = null; } } } }