Don't rely on nb_frames to be correct#25844
Merged
asmorkalov merged 1 commit intoopencv:4.xfrom Jul 5, 2024
Merged
Conversation
Contributor
Author
|
Thanks @asmorkalov and @opencv-alalek ! |
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
Patch to opencv_extra has the same branch name.
This is an attempt to fix #4362; It probably needs discussion/review.
Similar to this issue originally reported in 2012 (but which also has comments from 2023), I have a video where it seems like OpenCV does not read all frames.
I put the problematic video file here: https://github.com/dietmar/opencv/blob/problem_video/samples/data/interviewsample.mp4
I received this file from a co-worker, unfortunately I don't know how exactly it was produced. It's the first 3.5 minutes of this video: https://www.youtube.com/watch?v=YawI85U7QtA
The problem I encounter is with looping the video's frames; OpenCV stops way too early, after 160 frames, using Python code like:
Or equivalently in C++ something like:
It looks like the problem with this file is that ffmpeg reports
nb_framesas 160, but there are "really" 6,554 frames:I traced the problem back to the
CvCapture_FFMPEG::grabFrame()function inmodules/videoio/src/cap_ffmpeg_impl.hpp(here) where we have this check:So, such Python/C++ loops stop when the current
frame_numberis greater than the value ofnb_frames, the latter coming from some file header presumably.I propose to just remove this check. The code is not wrong in the sense that there is no programming error, and one could argue that we are just adhering to the file headers, as we have no reliable way of telling whether they are "incorrect".
However, I'd argue that OpenCV is currently relying too strongly on the information in the headers and behaves unexpectedly for most people: My "problematic" file from above plays fine (i.e., all 6,554 frames == 03:38) in video players (VLC, mplayer, Totem), so it looks like they don't rely on
nb_framesto be correct.ffmpegitself also does not adhere tonb_frameswhen we ask it to actually do something with the video. For example:The above command interprets the input file as 6,554 frames long and produces an output file where the headers are now "correct":
So my proposal is to grab as many frames from a video as we can, and not as many as the headers tell us are there. In doing so, OpenCV would handle such contradictory situations the same way as video players and the ffmpeg executable also seem to be handling them.
In my tests, just removing the check against
nb_frameswas unproblematic; at the end of the file,avcodec_send_packetreturned something < 0 here and consequently my loops stopped gracefully.