/// <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));
            }
        }
示例#7
0
 /// <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));
 }
示例#8
0
 /// <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));
 }