AcademySoftwareFoundation / OpenImageIO

Reading, writing, and processing images in a wide variety of file formats, using a format-agnostic API, aimed at VFX applications.
https://openimageio.readthedocs.org
Apache License 2.0
1.91k stars 574 forks source link

[BUG] reading .mp4 files results in crash #2688

Open mathisloge opened 3 years ago

mathisloge commented 3 years ago

Describe the bug So, i don't really know what happens. If I'm executing the oiiotool to just read an video file (mp4), it creates the temporary destination file and then exits without any error. I can play the video via ffplay without problems.

If I'm running oiio with in my own program, it will open the video file and read the metainfo like size etc. But as soon as I call the read_image function, it will crash without an error like the oiiotool. While debugging, i've noticed that it will crash at the function FFmpegInput::read_native_callback. The debugger stops at the line of the return. So I guess that it will be some problem at the memcpy call.

Unfortunately I'll get no error or some other crash report. Just the exit of the whole program.

To Reproduce Build with vcpkg with openimageio[ffmpeg,tools]

Expected behavior I would expect, that the video file would be read into the data array

Platform information:

wgergely commented 3 years ago

I was going to file an issue for the exact same symptom a few weeks back. Using a build against the master branch & python bindings I came up against the same bug. Sorry, I don't know if this is only affecting h264s or all ffmpeg formats. I built a few versions of OpenImageIO on Windows to check and the last version that seems to work ok is 2.2.1 (I could be wrong!).

lgritz commented 3 years ago

Can you be more specific? Like, what is the exact oiiotool command line that has this behavior, and is there a publicly available movie file that exhibits the symptoms? Or does it do that with all movie files and formats?

mathisloge commented 3 years ago

I'm currently downloading some video files to test it tomorrow. I'll let you know my test results.

the command line was oiiotool.exe input.mp4 -o output.png and oiiotool.exe input.mp4 -o output.jpg

lgritz commented 3 years ago

Just to be clear on the expected behavior:

When you give oiiotool a movie file as input and then output to a single-image format, exactly what do you expect/desire to happen?

mathisloge commented 3 years ago

As far as i have understand the documentation, i expect to at least create an Image, that is the size of the resolution of the movie file. But in my understanding it will be the first frame of the Video file extracted into a Single Image.

If i m using the c++ api and specify the subimage in the read_image function, i expect the output data to be the Image at the given subimage(frame)

lgritz commented 3 years ago

OK, just checking. That is the behavior I'm seeing on Mac in the current master.

But then I just used some random movie file I had lying around, so I'm curious to try on a specific file known to be a problem for you. Maybe it's a particular format or file. (Or could be particular to Windows, that will be harder for me to track down.)

So when you use your own program to read the first frame from the movie file, it crashes when you do the read_image?

mathisloge commented 3 years ago

After trying it again today, i've get a stacktrace following below. I can confirm, that it happens eg. when recording some video files via the window game center (keyboard: win + g). With an internal video the image will be extracted. So it might be a special problem for some special videos? The video which has produced the expected output had the following specs: h264, avc1, yuv420p, 1920x1080

the video which crashes the oiiotool has the same specs but has a resolution of 1920x1168. I will uplaod the example video later today.

So when you use your own program to read the first frame from the movie file, it crashes when you do the read_image?

correct. As described it will crash at the memcpy in FFmpegInput::read_native_callback

Stacktrace from the oiiotool.exe:

C:\dev\vcpkg\installed\x64-windows\tools\openimageio>oiiotool.exe "C:\Users\user\Videos\Captures\example.mp4" -o "C:\Users\user\Videos\Captures\test.png"
 0# boost::stacktrace::basic_stacktrace<std::allocator<boost::stacktrace::frame> >::init at C:\dev\vcpkg\installed\x64-windows\include\boost\stacktrace\stacktrace.hpp:76
 1# OpenImageIO_v2_1::Sysutil::stacktrace at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libutil\sysutil.cpp:602
 2# OpenImageIO_v2_1::stacktrace_signal_handler at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libutil\sysutil.cpp:622
 3# seh_filter_exe in ucrtbase
 4# `__scrt_common_main_seh'::`1'::filt$0 at D:\agent\_work\9\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:304
 5# _C_specific_handler in VCRUNTIME140
 6# _chkstk in ntdll
 7# RtlRaiseException in ntdll
 8# KiUserExceptionDispatcher in ntdll
 9# memcmp in VCRUNTIME140
10# OpenImageIO_v2_1::FFmpegInput::read_native_scanline at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\ffmpeg.imageio\ffmpeginput.cpp:582
11# OpenImageIO_v2_1::ImageInput::read_native_scanlines at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libOpenImageIO\imageinput.cpp:348
12# OpenImageIO_v2_1::ImageInput::read_native_scanlines at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libOpenImageIO\imageinput.cpp:368
13# OpenImageIO_v2_1::ImageInput::read_scanlines at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libOpenImageIO\imageinput.cpp:284
14# OpenImageIO_v2_1::ImageInput::read_image at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libOpenImageIO\imageinput.cpp:908
15# OpenImageIO_v2_1::pvt::ImageCacheFile::read_untiled at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libtexture\imagecache.cpp:1010
16# OpenImageIO_v2_1::pvt::ImageCacheFile::read_tile at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libtexture\imagecache.cpp:795
17# OpenImageIO_v2_1::pvt::ImageCacheTile::read at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libtexture\imagecache.cpp:1484
18# OpenImageIO_v2_1::pvt::ImageCacheImpl::add_tile_to_cache at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libtexture\imagecache.cpp:2373
19# OpenImageIO_v2_1::pvt::ImageCacheImpl::find_tile_main_cache at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libtexture\imagecache.cpp:2337
20# OpenImageIO_v2_1::pvt::ImageCacheImpl::find_tile at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libtexture\imagecache_pvt.h:944
21# OpenImageIO_v2_1::pvt::ImageCacheImpl::get_tile at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libtexture\imagecache.cpp:3118
22# OpenImageIO_v2_1::pvt::ImageCacheImpl::get_tile at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libtexture\imagecache.cpp:3093
23# OpenImageIO_v2_1::ImageBufImpl::retile at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libOpenImageIO\imagebuf.cpp:2540
24# <lambda_f02ec546a7795849e46070ca4649c3ca>::operator() at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libOpenImageIO\imagebuf.cpp:1935
25# std::_Func_impl_no_alloc<<lambda_f02ec546a7795849e46070ca4649c3ca>,void,OpenImageIO_v2_1::ROI>::_Do_call at C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.27.29110\include\functional:904
26# std::_Func_impl_no_alloc<<lambda_baa0f49dea1e45303ac57e74a4d97fdb>,void,int,__int64,__int64,__int64,__int64>::_Do_call at C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.27.29110\include\functional:904
27# std::_Func_impl_no_alloc<std::_Binder<std::_Unforced,std::function<void __cdecl(int,__int64,__int64,__int64,__int64)> &,std::_Ph<1> const &,__int64 &,__int64 &,__int64 &,__int64 &>,void,int>::_Do_call at C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.27.29110\include\functional:904
28# std::_Packaged_state<void __cdecl(int)>::_Call_immediate at C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.27.29110\include\future:604
29# OpenImageIO_v2_1::thread_pool::Impl::run_one_task at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libutil\thread.cpp:260
30# OpenImageIO_v2_1::task_set::wait at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libutil\thread.cpp:538
31# OpenImageIO_v2_1::parallel_for_chunked_2D at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libutil\thread.cpp:654
32# OpenImageIO_v2_1::ImageBufAlgo::parallel_image at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\include\OpenImageIO\imagebufalgo_util.h:90
33# OpenImageIO_v2_1::get_pixels_<float,float> at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libOpenImageIO\imagebuf.cpp:1944
34# OpenImageIO_v2_1::ImageBuf::get_pixels at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libOpenImageIO\imagebuf.cpp:1972
35# OpenImageIO_v2_1::ImageBuf::write at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libOpenImageIO\imagebuf.cpp:1128
36# output_file at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\oiiotool\oiiotool.cpp:5252
37# OpenImageIO_v2_1::ArgParse::Impl::parse at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libutil\argparse.cpp:405
38# getargs at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\oiiotool\oiiotool.cpp:5866
39# main at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\oiiotool\oiiotool.cpp:6129
40# __scrt_common_main_seh at D:\agent\_work\9\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
41# BaseThreadInitThunk in KERNEL32
42# RtlUserThreadStart in ntdll
 0# boost::stacktrace::basic_stacktrace<std::allocator<boost::stacktrace::frame> >::init at C:\dev\vcpkg\installed\x64-windows\include\boost\stacktrace\stacktrace.hpp:76
 1# OpenImageIO_v2_1::Sysutil::stacktrace at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libutil\sysutil.cpp:602
 2# OpenImageIO_v2_1::stacktrace_signal_handler at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libutil\sysutil.cpp:622
 3# raise in ucrtbase
 4# OpenImageIO_v2_1::stacktrace_signal_handler at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libutil\sysutil.cpp:632
 5# seh_filter_exe in ucrtbase
 6# `__scrt_common_main_seh'::`1'::filt$0 at D:\agent\_work\9\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:304
 7# _C_specific_handler in VCRUNTIME140
 8# _chkstk in ntdll
 9# RtlRaiseException in ntdll
10# KiUserExceptionDispatcher in ntdll
11# memcmp in VCRUNTIME140
12# OpenImageIO_v2_1::FFmpegInput::read_native_scanline at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\ffmpeg.imageio\ffmpeginput.cpp:582
13# OpenImageIO_v2_1::ImageInput::read_native_scanlines at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libOpenImageIO\imageinput.cpp:348
14# OpenImageIO_v2_1::ImageInput::read_native_scanlines at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libOpenImageIO\imageinput.cpp:368
15# OpenImageIO_v2_1::ImageInput::read_scanlines at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libOpenImageIO\imageinput.cpp:284
16# OpenImageIO_v2_1::ImageInput::read_image at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libOpenImageIO\imageinput.cpp:908
17# OpenImageIO_v2_1::pvt::ImageCacheFile::read_untiled at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libtexture\imagecache.cpp:1010
18# OpenImageIO_v2_1::pvt::ImageCacheFile::read_tile at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libtexture\imagecache.cpp:795
19# OpenImageIO_v2_1::pvt::ImageCacheTile::read at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libtexture\imagecache.cpp:1484
20# OpenImageIO_v2_1::pvt::ImageCacheImpl::add_tile_to_cache at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libtexture\imagecache.cpp:2373
21# OpenImageIO_v2_1::pvt::ImageCacheImpl::find_tile_main_cache at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libtexture\imagecache.cpp:2337
22# OpenImageIO_v2_1::pvt::ImageCacheImpl::find_tile at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libtexture\imagecache_pvt.h:944
23# OpenImageIO_v2_1::pvt::ImageCacheImpl::get_tile at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libtexture\imagecache.cpp:3118
24# OpenImageIO_v2_1::pvt::ImageCacheImpl::get_tile at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libtexture\imagecache.cpp:3093
25# OpenImageIO_v2_1::ImageBufImpl::retile at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libOpenImageIO\imagebuf.cpp:2540
26# <lambda_f02ec546a7795849e46070ca4649c3ca>::operator() at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libOpenImageIO\imagebuf.cpp:1935
27# std::_Func_impl_no_alloc<<lambda_f02ec546a7795849e46070ca4649c3ca>,void,OpenImageIO_v2_1::ROI>::_Do_call at C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.27.29110\include\functional:904
28# std::_Func_impl_no_alloc<<lambda_baa0f49dea1e45303ac57e74a4d97fdb>,void,int,__int64,__int64,__int64,__int64>::_Do_call at C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.27.29110\include\functional:904
29# std::_Func_impl_no_alloc<std::_Binder<std::_Unforced,std::function<void __cdecl(int,__int64,__int64,__int64,__int64)> &,std::_Ph<1> const &,__int64 &,__int64 &,__int64 &,__int64 &>,void,int>::_Do_call at C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.27.29110\include\functional:904
30# std::_Packaged_state<void __cdecl(int)>::_Call_immediate at C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.27.29110\include\future:604
31# OpenImageIO_v2_1::thread_pool::Impl::run_one_task at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libutil\thread.cpp:260
32# OpenImageIO_v2_1::task_set::wait at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libutil\thread.cpp:538
33# OpenImageIO_v2_1::parallel_for_chunked_2D at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libutil\thread.cpp:654
34# OpenImageIO_v2_1::ImageBufAlgo::parallel_image at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\include\OpenImageIO\imagebufalgo_util.h:90
35# OpenImageIO_v2_1::get_pixels_<float,float> at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libOpenImageIO\imagebuf.cpp:1944
36# OpenImageIO_v2_1::ImageBuf::get_pixels at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libOpenImageIO\imagebuf.cpp:1972
37# OpenImageIO_v2_1::ImageBuf::write at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libOpenImageIO\imagebuf.cpp:1128
38# output_file at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\oiiotool\oiiotool.cpp:5252
39# OpenImageIO_v2_1::ArgParse::Impl::parse at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\libutil\argparse.cpp:405
40# getargs at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\oiiotool\oiiotool.cpp:5866
41# main at C:\dev\vcpkg\buildtrees\openimageio\src\e-2.1.18.1-f372df05ef.clean\src\oiiotool\oiiotool.cpp:6129
42# __scrt_common_main_seh at D:\agent\_work\9\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
43# BaseThreadInitThunk in KERNEL32
44# RtlUserThreadStart in ntdll
mathisloge commented 3 years ago

the corresponding example video which fails example.zip

lgritz commented 3 years ago

I can reproduce with this example!

That's very good news, it means there's something about this file that is triggering a bug. And it's not Windows specific.

lgritz commented 3 years ago

Good news:

The crash itself is fixed by a patch, PR #2693, which could occur when certain kinds of decoding failures leave the buffer pointer as NULL.

Bad news:

I have no idea why this particular file is having decoding failures. I can play the video with vlc, so I'm going to assume there is nothing wrong with the file per se. Is it some slightly uncommon corner of the format that is not handled properly by ffmpeg, or by our code in ffmpeginput.cpp (either because it's outright wrong or failing to do something extra when encountering whatever is different about this file)?

I'm not an ffmpeg expert, and in fact I am not the author of this ffmpeginput.cpp file. I also don't have the time at the moment to immerse myself in either of those things, so I am perhaps not well suited to track this down.

The problem is almost certainly with the logic in our FFmpegInput::read_frame. I think that somehow the current_frame == frame && finished condition is never satisfied, so it just keeps looping until it hits the ret == AVERROR_EOF test and fails. That's as far as I've gotten, from here on out it's all Greek to me because I have no experience with programming to ffmpeg's APIs.

What I'm hoping for is that somebody more familiar with ffmpeg API can take a look at figuring out what's going on here.

@dankamongmen, @skycaptain, @sopvop, @fafik23, @mikaelsundell You all seem to be the last several people who have touched this code substantially in the last few years. Does any of this ring a bell, or maybe one of you can take a quick look at read_frame and help us spot the error?

dankamongmen commented 3 years ago

If we've got the offending video, which it appears we do, I'm happy to take a look at it, and ought be able to get to it by this weekend's end.g

lgritz commented 3 years ago

Thanks, I really appreciate that!

dankamongmen commented 3 years ago

Please forgive my somewhat annoyed and vulgar debugging nomenclature, and focus on the numbers:

Term: 52x80 vte-256color (VTE with xterm 256-colors)
current subimage: 0 frame: (nil)
SUBIMAGE: 0
READING: 0 0
SEEKING: 0
M)READ)FRAME: 0
RECEIVING FRAME (av_read_frame) fin: 0 ret: 0
RECEIVED FRAME (av_read_frame) fin: 1 ret: 0
CURRENT_FRAME: -53292 WANT FRAME:0
RECEIVING FRAME (av_read_frame) fin: 1 ret: 0
RECEIVED FRAME (av_read_frame) fin: 1 ret: 0
CURRENT_FRAME: -53089 WANT FRAME:0
DONE READING FRAME: 1
ERROR READING FRAME, BITCH!
LIFE SUCKS 
/home/dank/example.mp4: Notcurses failed to create a new visual

this file generates a series of frame numbers ranging from -53291 to -53089, with between zero and two instances of each frame number. this not being Minus World, these frame IDs seem suspicious. looking into why the ID is wrong now; i expect to have this solved very soon.

dankamongmen commented 3 years ago

If I uncomment the line from ffmpeginput.cpp:

            int current_frame = int((pts - m_start_time) * fps() + 0.5f);  //???
            current_frame =   m_frame->display_picture_number;

I can decode all 203 frames.

I assure you that the line suffixed with ??? is very broken, though I cannot yet conjecture that the subsequent line is correct in all cases.

dankamongmen commented 3 years ago

I don't think that this second line works, either -- I get the same image for every decode (but can at least walk the file). It's always returning 0 for this particular file. "Seeking" in libav is a lot more filetype-dependent than you'd like it to be -- a lot of these fields (pts, display_picture_number, etc.) aren't defined for all input types. Sad but true.

The ffmpeg module in Notcurses doesn't try to seek per se, but just takes frames as they come, and numbers them itself. Let me see what I can do for the OIIO case, where I assume arbitrary seeking is important. But these two lines are your problem.

BTW my ffmpeg code is here, and works for all files I can find in an ffmpeg-based Notcurses build: https://github.com/dankamongmen/notcurses/blob/master/src/lib/ffmpeg.cpp

dankamongmen commented 3 years ago

another thing: this time_stamp() function doesn't seem to properly work for at least this file and some others i tested with. I'm not sure what exactly is going on with both the av_seek_frame() call (in OIIO's seek()) and the frame walking in read_frame(), but that seek() smells:

[grimes](0) $ cat e | grep OFFS
SEEK OFFSET: 0 r: 0
SEEK OFFSET: 2 r: 0
SEEK OFFSET: 3 r: 0
SEEK OFFSET: 4 r: 0
SEEK OFFSET: 5 r: 0
SEEK OFFSET: 6 r: 0
SEEK OFFSET: 7 r: 0
[grimes](0) $ 

those are supposed to be timestamps, but they're clearly frame ids.

dankamongmen commented 3 years ago

I have a patch now which properly walks this file, and decodes each subsequent frame correctly (I've verified this at the pixel level). With that said, I cannot guarantee that it seeks around arbitrarily correctly, and I have tested it only with three files (including the provided sample). It works for all three.

I'm not sure how I feel about this. Personally, I think ffmpeginput.cpp is wrongheaded in some of its approach, and the bits I've highlighted definitely seem errors. There are also great mysteries like this:

        av_free_packet(&pkt);  //because seek(int) uses m_format_context
        seek(1 << 29);
        av_init_packet(&pkt);  //Is this needed?

which, what the hell is that, exactly. My PR purges seek(), which is just plain broken, and counts frames manually. It is likely broken for files which store images out of presentation order, though I'm not personally aware of any such schemes (I'm sure there are some).

I'll put it up momentarily. Whether you want to apply it is your own call, Visioned Leader.

dankamongmen commented 3 years ago

My PR definitely breaks arbitrary seeking around within a file, but I'd argue this was already pretty broken. I've removed any attempt to do so -- it now enforces that the read_frame() call is 1 plus the previous counted frame.