Skip to content

Possible bug with av_frame_get_buffer() when trying to get audio frame buffer #50

Open

Description

Using FFmpeg version 7.1, though I did test with 7.0 and it persisted there as well.

Image

The upper half of this snippet always fails with the EINVAL error return code, despite the fact that the frame has the nb_samples, ch_layout, and sample_format fields set, which should be all that is required to allocate the buffers according to the documentation.. I have looked over the libav source code and manually tried the checks that can return EINVAL, and this setup shouldn't be tripping them as far as I can tell. The video frame buffer get is there as a sanity check and it works exactly as expected.

Addendum: I finally managed to make a C project to test this, and have confirmed that it works fine in raw C. This code should be equivalent to the C# code:

Image

This correctly returns 0 and allocates the buffers, whereas the C# code has the previously described error.

Activity

  1. zgabi commented on Jan 18, 2025

    @zgabi

    I got 0:

    Image

    I'm using ffmpeg 7.0.1, from gyan.dev:
    ffmpeg-7.0.1-full_build-shared.7z

    After upgrade to 7.1 it still works. So probaby you are using a "wrong" ffmpeg version. From where did you download id?

  2. Error-String-Expected-Got-Nil commented on Jan 19, 2025

    @Error-String-Expected-Got-Nil
    Author

    After MUCH investigation I figured out what the problem was.

    In my use-case, I am running a 32-bit process (I'm making a video encoder I intend to build into a mod for a Unity game, which is 32 bit). The AVFrame struct in C/direct libav has 4 fields of type size_t, which is an unsigned integer type who's size is system/platform-dependent, as it has a size of 8 bytes in 64 bit, and 4 bytes on 32 bit.

    The AVFrame struct in FFmpeg.AutoGen, however, just uses ulongs for these fields. Thus, when accessing the fields of the AVFrame in C#, there is a serious misalignment of their locations in memory, making writes and reads to certain fields go to the wrong locations. None of the affected fields are relevant for video frames (as only fields sequentially below the size_t fields are affected), but they are relevant for audio frames.

    I made my own version of the AVFrame struct in C# using uints instead of ulongs for these fields, and with some pointer casts, it proceeded to work exactly as expected.

    I'm not sure if there's a good library-side solution for this, I don't think there's a way to make the type of some field depend on whether the process is 32 or 64 bit. But at least the issue is clear now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions