// 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 System; using System.IO; using System.Runtime.InteropServices; using SharpDX.Mathematics.Interop; using SharpDX.Win32; using SharpDX.IO; #if STORE_APP using Windows.Storage.Streams; #endif namespace SharpDX.MediaFoundation { /// /// ByteStream class used /// public partial class ByteStream { private Stream sourceStream; private ComStream comStream; private ComStreamProxy streamProxy; private ComObject randomAccessStreamCom; /// /// Instantiates a new instance from a . /// /// hh162754 /// HRESULT MFCreateMFByteStreamOnStreamEx([In] IUnknown* punkStream,[Out] IMFByteStream** ppByteStream) /// MFCreateMFByteStreamOnStreamEx public ByteStream(Stream sourceStream) { this.sourceStream = sourceStream; #if STORE_APP var randomAccessStream = sourceStream.AsRandomAccessStream(); MediaFactory.CreateMFByteStreamOnStreamEx(new ComObject(Marshal.GetIUnknownForObject(randomAccessStream)), this); #else streamProxy = new ComStreamProxy(sourceStream); MediaFactory.CreateMFByteStreamOnStream(streamProxy, this); #endif } /// /// Instantiates a new instance from a . /// /// hh162754 /// HRESULT MFCreateMFByteStreamOnStreamEx([In] IUnknown* punkStream,[Out] IMFByteStream** ppByteStream) /// MFCreateMFByteStreamOnStreamEx public ByteStream(byte[] sourceStream) : this(new MemoryStream(sourceStream)) { } #if STORE_APP /// /// Instantiates a new instance from a . /// /// hh162754 /// HRESULT MFCreateMFByteStreamOnStreamEx([In] IUnknown* punkStream,[Out] IMFByteStream** ppByteStream) /// MFCreateMFByteStreamOnStreamEx public ByteStream(IRandomAccessStream sourceStream) { var randomAccessStream = sourceStream; MediaFactory.CreateMFByteStreamOnStreamEx(new ComObject(Marshal.GetIUnknownForObject(randomAccessStream)), this); } #endif #if DESKTOP_APP /// /// Instantiates a new instance from a . /// /// hh162754 /// HRESULT MFCreateMFByteStreamOnStreamEx([In] IUnknown* punkStream,[Out] IMFByteStream** ppByteStream) /// MFCreateMFByteStreamOnStreamEx public ByteStream(ComStream sourceStream) { this.comStream = sourceStream; MediaFactory.CreateMFByteStreamOnStream(sourceStream, this); } #endif /// ///

Applies to: desktop apps | Metro style apps

Retrieves the characteristics of the byte stream.

///
/// The capabilities of the stream. /// ///

This interface is available on the following platforms if the Windows Media Format 11 SDK redistributable components are installed:

///
/// ms698962 /// HRESULT IMFByteStream::GetCapabilities([Out] unsigned int* pdwCapabilities) /// IMFByteStream::GetCapabilities public int Capabilities { get { int result; GetCapabilities_(out result); return result; } } /// ///

Applies to: desktop apps | Metro style apps

Retrieves the length of the stream.

///
/// The length of the stream, in bytes. If the length is unknown, this value is -1. /// ///

This interface is available on the following platforms if the Windows Media Format 11 SDK redistributable components are installed:

///
/// ms698941 /// HRESULT IMFByteStream::GetLength([Out] unsigned longlong* pqwLength) /// IMFByteStream::GetLength public long Length { get { long length; GetLength_(out length); return length; } set { SetLength_(value); } } /// ///

Applies to: desktop apps | Metro style apps

Retrieves the current read or write position in the stream.

///
/// The current position, in bytes. /// ///

The methods that update the current position are Read, BeginRead, Write, BeginWrite, SetCurrentPosition, and Seek.

This interface is available on the following platforms if the Windows Media Format 11 SDK redistributable components are installed:

///
/// ms704059 /// HRESULT IMFByteStream::GetCurrentPosition([Out] unsigned longlong* pqwPosition) /// IMFByteStream::GetCurrentPosition public long CurrentPosition { get { long position; GetCurrentPosition_(out position); return position; } set { SetCurrentPosition_(value); } } /// ///

Applies to: desktop apps | Metro style apps

Queries whether the current position has reached the end of the stream.

///
/// true if the end of the stream has been reached /// ///

This interface is available on the following platforms if the Windows Media Format 11 SDK redistributable components are installed:

///
/// ms697369 /// HRESULT IMFByteStream::IsEndOfStream([Out] BOOL* pfEndOfStream) /// IMFByteStream::IsEndOfStream public bool IsEndOfStream { get { return IsEndOfStream_; } } /// ///

Applies to: desktop apps | Metro style apps

Reads data from the stream.

///
///

Pointer to a buffer that receives the data. The caller must allocate the buffer.

/// Offset into the buffer. ///

Size of the buffer in bytes.

/// The number of bytes that are copied into the buffer /// ///

This method reads at most cb bytes from the current position in the stream and copies them into the buffer provided by the caller. The number of bytes that were read is returned in the pcbRead parameter. The method does not return an error code on reaching the end of the file, so the application should check the value in pcbRead after the method returns.

This method is synchronous. It blocks until the read operation completes.

This interface is available on the following platforms if the Windows Media Format 11 SDK redistributable components are installed:

///
/// ms698913 /// HRESULT IMFByteStream::Read([Out, Buffer] unsigned char* pb,[In] unsigned int cb,[Out] unsigned int* pcbRead) /// IMFByteStream::Read public unsafe int Read(byte[] bRef, int offset, int count) { int result; fixed (void* ptr = &bRef[offset]) Read_((System.IntPtr) ptr, count, out result); return result; } /// ///

Applies to: desktop apps | Metro style apps

Begins an asynchronous read operation from the stream.

///
///

Pointer to a buffer that receives the data. The caller must allocate the buffer.

/// The offset in the buffer to begin reading from. ///

Size of the buffer in bytes.

///

Pointer to the interface of a callback object. The caller must implement this interface.

///

Pointer to the interface of a state object, defined by the caller. This parameter can be null. You can use this object to hold state information. The object is returned to the caller when the callback is invoked.

///

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

/// ///

When all of the data has been read into the buffer, the callback object's method is called. At that point, the application should call to complete the asynchronous request.

Do not read from, write to, free, or reallocate the buffer while an asynchronous read is pending.

This interface is available on the following platforms if the Windows Media Format 11 SDK redistributable components are installed:

///
/// ms704810 /// HRESULT IMFByteStream::BeginRead([Out, Buffer] unsigned char* pb,[In] unsigned int cb,[In] IMFAsyncCallback* pCallback,[In] IUnknown* punkState) /// IMFByteStream::BeginRead public unsafe void BeginRead(byte[] bRef, int offset, int count, SharpDX.MediaFoundation.IAsyncCallback callbackRef, object context) { fixed (void* ptr = &bRef[offset]) BeginRead_((System.IntPtr) ptr, count, callbackRef, context != null ? Marshal.GetIUnknownForObject(context) : IntPtr.Zero); } /// ///

Applies to: desktop apps | Metro style apps

Completes an asynchronous read operation.

///
///

Pointer to the interface. Pass in the same reference that your callback object received in the method.

/// The number of bytes that were read /// ///

Call this method after the method completes asynchronously.

This interface is available on the following platforms if the Windows Media Format 11 SDK redistributable components are installed:

///
/// ms704042 /// HRESULT IMFByteStream::EndRead([In] IMFAsyncResult* pResult,[Out] unsigned int* pcbRead) /// IMFByteStream::EndRead public int EndRead(SharpDX.MediaFoundation.AsyncResult resultRef) { int result; EndRead_(resultRef, out result); return result; } /// ///

Applies to: desktop apps | Metro style apps

Writes data to the stream.

///
///

Pointer to a buffer that contains the data to write.

/// The offset within the buffer to begin writing at. ///

Size of the buffer in bytes.

/// The number of bytes that are written. /// ///

This method writes the contents of the pb buffer to the stream, starting at the current stream position. The number of bytes that were written is returned in the pcbWritten parameter.

This method is synchronous. It blocks until the write operation completes.

This interface is available on the following platforms if the Windows Media Format 11 SDK redistributable components are installed:

///
/// ms703843 /// HRESULT IMFByteStream::Write([In, Buffer] const unsigned char* pb,[In] unsigned int cb,[Out] unsigned int* pcbWritten) /// IMFByteStream::Write public unsafe int Write(byte[] bRef, int offset, int count) { int result; fixed (void* ptr = &bRef[offset]) Write_((IntPtr) ptr, count, out result); return result; } /// ///

Applies to: desktop apps | Metro style apps

Begins an asynchronous write operation to the stream.

///
///

Pointer to a buffer containing the data to write.

/// The offset within the buffer to begin writing at. ///

Size of the buffer in bytes.

///

Pointer to the interface of a callback object. The caller must implement this interface.

///

Pointer to the interface of a state object, defined by the caller. This parameter can be null. You can use this object to hold state information. The object is returned to the caller when the callback is invoked.

///

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

/// ///

When all of the data has been written to the stream, the callback object's method is called. At that point, the application should call to complete the asynchronous request.

Do not reallocate, free, or write to the buffer while an asynchronous write is still pending.

This interface is available on the following platforms if the Windows Media Format 11 SDK redistributable components are installed:

///
/// ms694005 /// HRESULT IMFByteStream::BeginWrite([In, Buffer] const unsigned char* pb,[In] unsigned int cb,[In] IMFAsyncCallback* pCallback,[In] IUnknown* punkState) /// IMFByteStream::BeginWrite public unsafe void BeginWrite(byte[] bRef, int offset, int count, SharpDX.MediaFoundation.IAsyncCallback callbackRef, object context) { fixed (void* ptr = &bRef[offset]) BeginWrite_((System.IntPtr)ptr, count, callbackRef, context != null ? Marshal.GetIUnknownForObject(context) : IntPtr.Zero); } /// ///

Applies to: desktop apps | Metro style apps

Completes an asynchronous write operation.

///
///

Pointer to the interface. Pass in the same reference that your callback object received in the method.

/// The number of bytes that were written /// ///

Call this method when the method completes asynchronously.

This interface is available on the following platforms if the Windows Media Format 11 SDK redistributable components are installed:

///
/// ms703863 /// HRESULT IMFByteStream::EndWrite([In] IMFAsyncResult* pResult,[Out] unsigned int* pcbWritten) /// IMFByteStream::EndWrite public int EndWrite(SharpDX.MediaFoundation.AsyncResult resultRef) { int result; EndWrite_(resultRef, out result); return result; } /// ///

Applies to: desktop apps | Metro style apps

Moves the current position in the stream by a specified offset.

///
///

Specifies the origin of the seek as a member of the enumeration. The offset is calculated relative to this position.

///

Specifies the new position, as a byte offset from the seek origin.

///

Specifies zero or more flags. The following flags are defined.

ValueMeaning
MFBYTESTREAM_SEEK_FLAG_CANCEL_PENDING_IO

All pending I/O requests are canceled after the seek request completes successfully.

?

/// The new position after the seek /// ///

This interface is available on the following platforms if the Windows Media Format 11 SDK redistributable components are installed:

///
/// ms697053 /// HRESULT IMFByteStream::Seek([In] MFBYTESTREAM_SEEK_ORIGIN SeekOrigin,[In] longlong llSeekOffset,[In] unsigned int dwSeekFlags,[Out] unsigned longlong* pqwCurrentPosition) /// IMFByteStream::Seek public long Seek(SharpDX.MediaFoundation.ByteStreamSeekOrigin seekOrigin, long llSeekOffset, int dwSeekFlags) { long result; Seek_(seekOrigin, llSeekOffset, dwSeekFlags, out result); return result; } /// ///

Applies to: desktop apps | Metro style apps

Clears any internal buffers used by the stream. If you are writing to the stream, the buffered data is written to the underlying file or device.

///
///

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

/// ///

If the byte stream is read-only, this method has no effect.

This interface is available on the following platforms if the Windows Media Format 11 SDK redistributable components are installed:

///
/// ms694833 /// HRESULT IMFByteStream::Flush() /// IMFByteStream::Flush public void Flush() { Flush_(); } /// ///

Applies to: desktop apps | Metro style apps

Closes the stream and releases any resources associated with the stream, such as sockets or file handles. This method also cancels any pending asynchronous I/O requests.

///
///

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

/// ///

This interface is available on the following platforms if the Windows Media Format 11 SDK redistributable components are installed:

///
/// ms703909 /// HRESULT IMFByteStream::Close() /// IMFByteStream::Close public void Close() { Close_(); } protected override unsafe void Dispose(bool disposing) { base.Dispose(disposing); if (streamProxy != null) { streamProxy.Dispose(); streamProxy = null; } if (randomAccessStreamCom != null) { randomAccessStreamCom.Dispose(); randomAccessStreamCom = null; } } } }