using System;
using System.Runtime.InteropServices;
using NAudio.Utils;
namespace NAudio.Dmo
{
///
/// Attempting to implement the COM IMediaBuffer interface as a .NET object
/// Not sure what will happen when I pass this to an unmanaged object
///
public class MediaBuffer : IMediaBuffer, IDisposable
{
private IntPtr buffer;
private int length;
private readonly int maxLength;
///
/// Creates a new Media Buffer
///
/// Maximum length in bytes
public MediaBuffer(int maxLength)
{
buffer = Marshal.AllocCoTaskMem(maxLength);
this.maxLength = maxLength;
}
///
/// Dispose and free memory for buffer
///
public void Dispose()
{
if (buffer != IntPtr.Zero)
{
Marshal.FreeCoTaskMem(buffer);
buffer = IntPtr.Zero;
GC.SuppressFinalize(this);
}
}
///
/// Finalizer
///
~MediaBuffer()
{
Dispose();
}
#region IMediaBuffer Members
///
/// Set length of valid data in the buffer
///
/// length
/// HRESULT
int IMediaBuffer.SetLength(int length)
{
//System.Diagnostics.Debug.WriteLine(String.Format("Set Length {0}", length));
if (length > maxLength)
{
return HResult.E_INVALIDARG;
}
this.length = length;
return HResult.S_OK;
}
///
/// Gets the maximum length of the buffer
///
/// Max length (output parameter)
/// HRESULT
int IMediaBuffer.GetMaxLength(out int maxLength)
{
//System.Diagnostics.Debug.WriteLine("Get Max Length");
maxLength = this.maxLength;
return HResult.S_OK;
}
///
/// Gets buffer and / or length
///
/// Pointer to variable into which buffer pointer should be written
/// Pointer to variable into which valid data length should be written
/// HRESULT
int IMediaBuffer.GetBufferAndLength(IntPtr bufferPointerPointer, IntPtr validDataLengthPointer)
{
//System.Diagnostics.Debug.WriteLine(String.Format("Get Buffer and Length {0},{1}",
// bufferPointerPointer,validDataLengthPointer));
if (bufferPointerPointer != IntPtr.Zero)
{
Marshal.WriteIntPtr(bufferPointerPointer, this.buffer);
}
if (validDataLengthPointer != IntPtr.Zero)
{
Marshal.WriteInt32(validDataLengthPointer, this.length);
}
//System.Diagnostics.Debug.WriteLine("Finished Getting Buffer and Length");
return HResult.S_OK;
}
#endregion
///
/// Length of data in the media buffer
///
public int Length
{
get { return length; }
set
{
if (length > maxLength)
{
throw new ArgumentException("Cannot be greater than maximum buffer size");
}
length = value;
}
}
///
/// Loads data into this buffer
///
/// Data to load
/// Number of bytes to load
public void LoadData(byte[] data, int bytes)
{
this.Length = bytes;
Marshal.Copy(data, 0, buffer, bytes);
}
///
/// Retrieves the data in the output buffer
///
/// buffer to retrieve into
/// offset within that buffer
public void RetrieveData(byte[] data, int offset)
{
Marshal.Copy(buffer, data, offset, Length);
}
}
}