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

Custom AVIOContext fails to open input file #255

Open
adamhewitt627 opened this issue Mar 22, 2023 · 9 comments
Open

Custom AVIOContext fails to open input file #255

adamhewitt627 opened this issue Mar 22, 2023 · 9 comments

Comments

@adamhewitt627
Copy link

adamhewitt627 commented Mar 22, 2023

I'm submitting a bug report.

  • Do you want to request a feature or report a bug?
    This could be a bug with ffmpeg, but seems to be a failure with the managed/native callbacks. Our code worked under ffmpeg 4.3, and broke in 5.0. I checked again and it's still broken in ffmpeg6. I will work on a repro example, but wanted to get this filed.

  • What is the current behavior?

  1. Custom AVIOContext fails to open for reading a file.
  2. The Read callback executes once, but then an AccessViolationException is thrown.
  • *If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem:

  • What is the expected behavior?
    Reading a file with a custom IO context should work. (Interestingly, it does work for writing a file)

  • Please tell us about your environment:

  • version: ffmpeg6, Windows 11, .NET6.0 WPF application.
@adamhewitt627
Copy link
Author

Here is a sample project, just a small console app that tries to open the file. FfmegCustomIO.zip

  1. Fill in the ffmpeg.RootPath with your environment.
  2. Fill in the file path to some mp4, avi, etc.
  3. Run the app - should blow up on avformat_open_input. Breakpoints will show that the Read callback is executed once.

@adamhewitt627
Copy link
Author

Interesting, removing this line appears to resolve it but also calls Seek (which I wouldn't expect)

Reference->seekable = stream.CanSeek ? 1 : 0;

@zgabi
Copy link
Contributor

zgabi commented Mar 22, 2023

I haven't tried your code, but it looks very suspicious that
write_flag: stream.CanWrite ? 1 : 0,
and
write_packet: null,

I think you should set the write flag to 0 if the write delegate is null.

@adamhewitt627
Copy link
Author

True, I didn't get that line entirely pulled out of the minimum repro. But that will also always be 0 because the file is being opened readonly.

@Ruslan-B
Copy link
Owner

I think it could be related issue #217

@Ruslan-B
Copy link
Owner

I'll try to check integrity of AVIOContext structure.
As indeed when commenting out Reference->seekable = stream.CanSeek ? 1 : 0; it seems to be working fine.

@dubiousconst282
Copy link

dubiousconst282 commented Apr 3, 2023

The crash in avformat_open_input() seems to be happening somewhere around here: https://github.com/FFmpeg/FFmpeg/blob/5bad4856035ca5ed571e9d7d9b1d503a5c9ef0a5/libavformat/demux.c#L258-L272

The C# struct layout for AVIOContext seem to mismatch the one in the Win32 build. In particular, the field pb->seekable (at offset 0x90 in the C# struct) is swapped with pb->xxx_whitelist.

I didn't want to build ffmpeg myself, so I confirmed this by setting a dummy value like pb->seekable = 0x1234567, which ends up being passed to av_strdup() via rcx:

image

Also I don't think that the C# layout is wrong as it matches the clang output, so the maybe the problem is specific to Windows builds?

Edit: note that it's not necessary to set seekable manually because avio_alloc_context() already does so when you pass a non-null seek callback (ref). There seems to be no other way to check for the AVIO_SEEKABLE_NORMAL flag, so I'm just checking for pb->seek.Pointer != IntPtr.Zero; instead.

@Ruslan-B
Copy link
Owner

I updated state of research and passible actions in #217

@AnthonyParkssonos
Copy link

AnthonyParkssonos commented Nov 30, 2023

btw i encountered this with ffmpeg 5 feeding it a buffer of FLAC and consequently getting free() invalid pointer every time. i have been hitting my head against GDB for the past day trying to do something like this:

/// buffer comes from network, 
uint8_t buffer[4096] = // assume mock read 
AVFormatContext* pFormat = avformat_alloc_context()
AVIOContext* pAvioCtx = avio_alloc_context(buffer, 4096, 0, nullptr, nullptr, nullptr, nullptr);
pFormat->pb = pAvioCtx;
// SIGABRT free() invalid pointer occurs every time inside this ->
if (avformat_open_input(&pFormat, nullptr, nullptr, nullptr)) {
     log("couldn't open input");
}

zgabi added a commit to zgabi/ffmediaelement that referenced this issue Jun 10, 2024
remove setting of the seekable field, since it causes access violation errors, and unnecessary.

Check the comment from june 6, 2023: unosquare#642

Or:
Ruslan-B/FFmpeg.AutoGen#255

Currently I'm uusing my own package, but I'd liek to swicth your original version, but this issue block me.

Reproduce the issue: Just open any local video file with the following url:
customfile://C:\myfolder\myfile.mkv
It will use the FileInputStream which sets the seekable field. => access violation when trying to open the media.
mariodivece pushed a commit to unosquare/ffmediaelement that referenced this issue Jun 26, 2024
* remove setting of the seekable field

remove setting of the seekable field, since it causes access violation errors, and unnecessary.

Check the comment from june 6, 2023: #642

Or:
Ruslan-B/FFmpeg.AutoGen#255

Currently I'm uusing my own package, but I'd liek to swicth your original version, but this issue block me.

Reproduce the issue: Just open any local video file with the following url:
customfile://C:\myfolder\myfile.mkv
It will use the FileInputStream which sets the seekable field. => access violation when trying to open the media.

* fix the hw acceleration

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

No branches or pull requests

5 participants