Quantcast
Channel: NAudio
Viewing all articles
Browse latest Browse all 5831

New Post: Odd byte[] array behaviour in WaveFormat

$
0
0
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.
   [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?

Viewing all articles
Browse latest Browse all 5831

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>