I'm preparing AacWaveFormat based on WaveFormat which has a variable 'Extra Size' at the end. So I added a byte[] array at the end like in WaveFormatExtraData.cs
In AacWaveFormat:
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
private byte[] pbAudioSpecificConfig = new byte[40];
In WaveFormatExtraData.cs:
// try with 100 bytes for now, increase if necessary
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
private byte[] extraData = new byte[100];
But Media Foundation doesn't accept it, it says:
System.Runtime.InteropServices.COMException (0xC00D36B4): The data specified for the media type is invalid, inconsistent, or not supported by this object. (Exception from HRESULT: 0xC00D36B4)
at NAudio.MediaFoundation.IMFTransform.SetInputType(Int32 dwInputStreamID, IMFMediaType pType, _MFT_SET_TYPE_FLAGS dwFlags)
The weird thing is that I can add as many normal bytes as I want
public byte pbAudioSpecificConfig1;
public byte pbAudioSpecificConfig2;
...
public byte pbAudioSpecificConfig7;
public byte pbAudioSpecificConfig9999999;
...which is fine because the ExtraSize is 12 (stock standard AAC Extra Size), anything before pbAudioSpecificConfig1 is not read anyway.
But as soon as I add a "private byte[] pbAudioSpecificConfig = new byte[1];" of any size including 0, I get an exception, even though it is AFTER the 12 standard AAC extra bytes which should be ignored.
Why does MF fail when I introduce a byte[] array AFTER the bytes it is told to read?
Maybe WaveFormatExtraData.cs has the same problem, which I believe it does because I am getting the same exception when loading a WaveFormatExtraData in Media Foundation.
It appears a byte[] array is simply not acceptable in a StructLayout used through a COM interface.
... UPDATE
Apparently removing the "= new byte[x]" from the Struct and adding it to the constructor is supposed to work, but no dice.
http://social.msdn.microsoft.com/Forums/vstudio/en-US/876ff2aa-07ff-4924-a124-8ff2b7642eb4/c-to-c-send-structur-with-byte-array-from-c-to-c?forum=csharpgeneral
Maybe byte[] arrays only work with "Pack = 1" since they are an array of sequential data?
In AacWaveFormat:
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
private byte[] pbAudioSpecificConfig = new byte[40];
In WaveFormatExtraData.cs:
// try with 100 bytes for now, increase if necessary
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
private byte[] extraData = new byte[100];
But Media Foundation doesn't accept it, it says:
System.Runtime.InteropServices.COMException (0xC00D36B4): The data specified for the media type is invalid, inconsistent, or not supported by this object. (Exception from HRESULT: 0xC00D36B4)
at NAudio.MediaFoundation.IMFTransform.SetInputType(Int32 dwInputStreamID, IMFMediaType pType, _MFT_SET_TYPE_FLAGS dwFlags)
The weird thing is that I can add as many normal bytes as I want
public byte pbAudioSpecificConfig1;
public byte pbAudioSpecificConfig2;
...
public byte pbAudioSpecificConfig7;
public byte pbAudioSpecificConfig9999999;
...which is fine because the ExtraSize is 12 (stock standard AAC Extra Size), anything before pbAudioSpecificConfig1 is not read anyway.
But as soon as I add a "private byte[] pbAudioSpecificConfig = new byte[1];" of any size including 0, I get an exception, even though it is AFTER the 12 standard AAC extra bytes which should be ignored.
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 2)]
public class AacWaveFormat : WaveFormat
{
// *** typedef struct heaacwaveformat_tag {
// *** HEAACWAVEINFO wfInfo;
// *** BYTE pbAudioSpecificConfig[1];
// *** } HEAACWAVEFORMAT, *PHEAACWAVEFORMAT;
/* HEAACWAVEINFO structure */
public ushort wPayloadType;
/// <summary>
/// wPayloadType
/// </summary>
public ushort wAudioProfileLevelIndication;
/// <summary>
/// wStructType
/// </summary>
public ushort wStructType;
/// <summary>
/// wReserved1
/// </summary>
public ushort wReserved1;
/// <summary>
/// dwReserved2
/// </summary>
public UInt32 dwReserved2;
// All of the above is the 12 standard bytes. Anything after is not read...
/* BYTE pbAudioSpecificConfig[1]; */
/// <summary>
/// pbAudioSpecificConfig
/// </summary>
//public byte[] pbAudioSpecificConfig = new byte[2]; // EXCEPTION
public byte pbAudioSpecificConfig1; // no problem
public byte pbAudioSpecificConfig2; // no problem
public byte pbAudioSpecificConfig3; // test... no problem
public byte pbAudioSpecificConfig4; // test
public byte pbAudioSpecificConfig5; // test
public byte pbAudioSpecificConfig6; // test
public byte pbAudioSpecificConfig7; // test .. I can add a million of these, no problem
// EXCEPTION The data specified is invalid
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
private byte[] pbAudioSpecificConfig = new byte[1]; // byte[2]; // byte[100]; // byte[0]
Tried making it public, no change. Tried removing the MarshalAs, no change. Tried making it an empty array (byte[0]), no change.Why does MF fail when I introduce a byte[] array AFTER the bytes it is told to read?
Maybe WaveFormatExtraData.cs has the same problem, which I believe it does because I am getting the same exception when loading a WaveFormatExtraData in Media Foundation.
It appears a byte[] array is simply not acceptable in a StructLayout used through a COM interface.
... UPDATE
Apparently removing the "= new byte[x]" from the Struct and adding it to the constructor is supposed to work, but no dice.
http://social.msdn.microsoft.com/Forums/vstudio/en-US/876ff2aa-07ff-4924-a124-8ff2b7642eb4/c-to-c-send-structur-with-byte-array-from-c-to-c?forum=csharpgeneral
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
private byte[] pbAudioSpecificConfig;// = new byte[2];
public AacWaveFormat(......)
{
....
....
pbAudioSpecificConfig = new byte[2]; // same exception. If I remove this, it works fine. But I can't allocate the bytes obviously, plus it is fixed to 2 bytes since "SizeConst = 2" in the struct.
}
Perhaps it is because "Pack = 2"?Maybe byte[] arrays only work with "Pack = 1" since they are an array of sequential data?