/// <summary> /// Writes asynchronously data to a byte stream /// </summary> /// <typeparam name="T">A value type.</typeparam> /// <param name="byteStream">A valid IMFByteStream instance.</param> /// <param name="buffer">An array segment of value types that contain the data to write.</param> /// <returns>A task that represents the asynchronous write operation. The task's result contain the number of items written.</returns> public static Task <int> WriteAsync <T>(this IMFByteStream byteStream, ArraySegment <T> buffer) where T : struct { if (byteStream == null) { throw new ArgumentNullException("byteStream"); } int sizeOfT = Marshal.SizeOf(typeof(T)); // Pin the array to get its addess and to avoid a GC move during the asynchronous operation GCPin pin = new GCPin(buffer.Array); // Get the start address - ArraySegment.Offset is exprimed in item offset IntPtr startAddress = pin.PinnedAddress + (buffer.Offset * sizeOfT); // Get the task for a byte pointer operation Task <int> result = byteStream.WriteAsync(startAddress, buffer.Count * sizeOfT); // return that Task with a continuation to do cleanup and correct the result return(result.ContinueWith <int>((an) => { // Release the GC handle pin.Dispose(); // Result must be exprimed in items count , not in bytes return an.Result / sizeOfT; })); }
/// <summary> /// Converts the attribute store's contents to a byte array. /// </summary> /// <param name="attributes">A valid IMFAttributes instance.</param> /// <param name="buffer">Receives a byte array filled with attribute data.</param> /// <returns>If this function succeeds, it returns the S_OK member. Otherwise, it returns another HResult's member that describe the error.</returns> public static HResult GetAttributesAsBlob(this IMFAttributes attributes, out byte[] buffer) { if (attributes == null) { throw new ArgumentNullException("attributes"); } buffer = null; int sizeInBytes; HResult hr = MFExtern.MFGetAttributesAsBlobSize(attributes, out sizeInBytes); if (hr.Succeeded()) { byte[] result = new byte[sizeInBytes]; using (GCPin pin = new GCPin(result)) { hr = MFExtern.MFGetAttributesAsBlob(attributes, pin.PinnedAddress, result.Length); if (hr.Succeeded()) { buffer = result; } } } return(hr); }
/// <summary> /// Initializes the contents of an attribute store from a byte array. /// </summary> /// <param name="attributes">A valid IMFAttributes instance.</param> /// <param name="buffer">A byte array previously filled with <see cref="GetAttributesAsBlob"/>.</param> /// <returns>If this function succeeds, it returns the S_OK member. Otherwise, it returns another HResult's member that describe the error.</returns> public static HResult InitializeAttributesFromBlob(this IMFAttributes attributes, byte[] buffer) { if (attributes == null) { throw new ArgumentNullException("attributes"); } if (buffer == null) { throw new ArgumentNullException("buffer"); } using (GCPin pin = new GCPin(buffer)) { return(MFExtern.MFInitAttributesFromBlob(attributes, pin.PinnedAddress, buffer.Length)); } }
/// <summary> /// Copies this buffer into a byte array, converting the data to contiguous format. /// </summary> /// <param name="value">A valid IMF2DBuffer instance.</param> /// <param name="destinationBuffer">The destination byte array.</param> /// <returns>If this function succeeds, it returns the S_OK member. Otherwise, it returns another HResult's member that describe the error.</returns> public static HResult ContiguousCopyTo(this IMF2DBuffer buffer, byte[] destinationBuffer) { if (buffer == null) { throw new ArgumentNullException("value"); } if (destinationBuffer == null) { throw new ArgumentNullException("destinationBuffer"); } using (GCPin pinnedArray = new GCPin(destinationBuffer)) { return(buffer.ContiguousCopyFrom(pinnedArray.PinnedAddress, destinationBuffer.Length)); } }
/// <summary> /// Reads data from a byte stream /// </summary> /// <typeparam name="T">A value type.</typeparam> /// <param name="byteStream">A valid IMFByteStream instance.</param> /// <param name="buffer">An array segment of value types that receives the data.</param> /// <param name="itemsRead">The total number of values read into the array segment.</param> /// <returns>If this function succeeds, it returns the S_OK member. Otherwise, it returns another HResult's member that describe the error.</returns> public static HResult Read <T>(this IMFByteStream byteStream, ArraySegment <T> buffer, out int itemsRead) where T : struct { if (byteStream == null) { throw new ArgumentNullException("byteStream"); } int sizeOfT = Marshal.SizeOf(typeof(T)); using (GCPin pin = new GCPin(buffer.Array)) { IntPtr startAddress = pin.PinnedAddress + (buffer.Offset * sizeOfT); HResult hr = byteStream.Read(startAddress, buffer.Count * sizeOfT, out itemsRead); itemsRead /= sizeOfT; return(hr); } }
/// <summary> /// Copies data to this buffer from a byte array segment that has a contiguous format. /// </summary> /// <param name="value">A valid IMF2DBuffer instance.</param> /// <param name="sourceBuffer">A byte array segment.</param> /// <returns>If this function succeeds, it returns the S_OK member. Otherwise, it returns another HResult's member that describe the error.</returns> public static HResult ContiguousCopyFrom(this IMF2DBuffer buffer, ArraySegment <byte> sourceBuffer) { if (buffer == null) { throw new ArgumentNullException("value"); } if (sourceBuffer.Array == null) { throw new ArgumentNullException("sourceBuffer.Array"); } using (GCPin pinnedArray = new GCPin(sourceBuffer.Array)) { IntPtr startAddress = pinnedArray.PinnedAddress + sourceBuffer.Offset; return(buffer.ContiguousCopyFrom(startAddress, sourceBuffer.Count)); } }
/// <summary>Create a stream from Memory (byte[]).</summary> public static int CreateStream(byte[] Memory, long Offset, long Length, BassFlags Flags) { return(GCPin.CreateStreamHelper(Pointer => CreateStream(Pointer, Offset, Length, Flags), Memory)); }
/// <summary> /// Streams a WMA file from Memory (byte[]) authenticating using given <paramref name="UserName"/> and <paramref name="Password"/>. /// </summary> public static int CreateStream(byte[] Memory, long Length, BassFlags Flags, string UserName, string Password) { return(GCPin.CreateStreamHelper(Pointer => CreateStream(Pointer, Length, Flags, UserName, Password), Memory)); }