Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong Frame Size for MPEG-2 #10

Open
kmcclellan opened this issue Oct 23, 2018 · 4 comments
Open

Wrong Frame Size for MPEG-2 #10

kmcclellan opened this issue Oct 23, 2018 · 4 comments

Comments

@kmcclellan
Copy link

I was getting an exception when decoding MPEG Version 2. Figured out it was because the frame lengths were being calculated incorrectly. I believe the issue is here (in MpegFrame.cs):

// calculate the frame's length
int frameSize;
if (BitRateIndex > 0)
{
    if (Layer == MpegLayer.LayerI)
    {
        frameSize = (12 * BitRate / SampleRate + Padding) * 4;
    }
    else
    {
        frameSize = 144 * BitRate / SampleRate + Padding;
    }
}

Compare to the length calculation used by NAudio:

int coefficient = frame.SampleCount/8;
if (frame.MpegLayer == MpegLayer.Layer1)
{
    frame.FrameLength = (coefficient*frame.BitRate/frame.SampleRate + nPadding)*4;
}
else
{
    frame.FrameLength = (coefficient*frame.BitRate)/frame.SampleRate + nPadding;
}

I don't have access to the specs, but it looks like the hard-coded 144 is only going to be correct for MPEG-1 (when sample count is 1152). Appears to have solved my error switching to use SampleCount / 8.

@markheath
Copy link
Contributor

Thanks for reporting, if you have a test file you can share that would be helpful.

@kmcclellan
Copy link
Author

I can't share the file I first ran into it with, but I found one online that is enough to reproduce: Sample

Test method NLayerTests.UnitTest1.TestMethod1 threw exception: 
System.IndexOutOfRangeException: Index was outside the bounds of the array.
    at NLayer.Decoder.LayerIIDecoderBase.GetCRC(MpegFrame frame, Int32[] rateTable, Int32[][] allocLookupTable, Boolean readScfsiBits, UInt32& crc)
   at NLayer.Decoder.MpegFrame.ValidateCRC()
   at NLayer.Decoder.MpegFrame.Validate()
   at NLayer.Decoder.MpegStreamReader.FindNextFrame()
   at NLayer.Decoder.MpegStreamReader.ReadToEnd()
   at NLayer.Decoder.MpegStreamReader.get_SampleCount()
   at NLayer.MpegFile.get_Length()
   at NLayerTests.UnitTest1.TestMethod1()

I believe any file using MPEG Version 2 or MPEG Version 2.5 will use the wrong frame length and not decode properly. Once it gets out of sync it ends up reading some invalid frame headers and invoking the wrong decoders (i.e. Layer I or II), causing an exception like the above.

@markheath
Copy link
Contributor

I'm not sure NAudio is correctly parsing the frames on that file either - I can't load it through the NLayer.NAudioSupport

@wei-kris
Copy link

wei-kris commented Feb 27, 2023

NAudio correctly parsed , But NAudio does not support android.


IndexOutOfRangeException: Index was outside the bounds of the array.
NLayer.Decoder.LayerIIIDecoder.Dequantize (System.Int32 idx, System.Single val, System.Int32 gr, System.Int32 ch) (at Assets/NLayer/Decoder/LayerIIIDecoder.cs:1427)
NLayer.Decoder.LayerIIIDecoder.ReadSamples (System.Int32 sfBits, System.Int32 gr, System.Int32 ch) (at Assets/NLayer/Decoder/LayerIIIDecoder.cs:1393)
NLayer.Decoder.LayerIIIDecoder.DecodeFrame (NLayer.IMpegFrame frame, System.Single[] ch0, System.Single[] ch1) (at Assets/NLayer/Decoder/LayerIIIDecoder.cs:562)
NLayer.MpegFrameDecoder.DecodeFrameImpl (NLayer.IMpegFrame frame, System.Array dest, System.Int32 destOffset) (at Assets/NLayer/MpegFrameDecoder.cs:143)
NLayer.MpegFrameDecoder.DecodeFrame (NLayer.IMpegFrame frame, System.Single[] dest, System.Int32 destOffset) (at Assets/NLayer/MpegFrameDecoder.cs:105)
NLayer.MpegFile.ReadSamplesImpl (System.Array buffer, System.Int32 index, System.Int32 count) (at Assets/NLayer/MpegFile.cs:263)
NLayer.MpegFile.ReadSamples (System.Single[] buffer, System.Int32 index, System.Int32 count) (at Assets/NLayer/MpegFile.cs:205)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants