-
Notifications
You must be signed in to change notification settings - Fork 29
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
imageReader reads all but two frames of a video #58
Comments
When I read back the frames and print out an element of each vector, I see that the 2nd frame is dropped, but the 5th is duplicated, the 9th is dropped, the 12th is duplicated, 16th dropped, 19th duplicated, and it repeats like that every 3 or 4 frames for the entire video. Finally at the end, the 596th is duplicated, and frames 598-600 are dropped. Here's the first 20 frames:
Here's an updated import Codec.FFmpeg
import Codec.Picture
import Control.Monad.Loops
import Data.Maybe
import qualified Data.Vector.Storable as V
readAllFrames :: IO Int
readAllFrames = do
initFFmpeg
(reader, cleanup) <- imageReader (File "pulse.mov") :: IO (IO (Maybe (Image PixelRGB8)), IO ())
frames <- unfoldM reader
mapM (putStrLn . show . V.head . imageData) frames
return $ length frames Not sure yet why this is happening. |
The frame timing things I mentioned that I'm suspicious of are here and a lot of things starting here. It may be worth instrumenting that code to see what frame times are being used for the pulse example. I can imagine things going wrong in various ways, such as mixing use of rational and floating point times. I don't know exactly what we're doing wrong, but this has always struck me as a real Danger Zone. |
Hey @burkaman, did you ever have a chance to dig into this any further? |
Not a lot yet, unfortunately. I did a little bit of light logging around the lines you mentioned and I didn't see anything suspicious yet, but I didn't look very deeply. I've somewhat convinced myself the problem is in decoding though, not encoding, which is where your suspicious sections are. If I ask This is still on my list, but I haven't managed to devote very much time to it yet. |
I have encountered a similar issue in my gloss-to-flv project, while testing that writing and reading back a video with ffmpeg-light gives back what I started with. Since the encoding is lossy, I don't expect to get exactly the same thing I started with, but I did notice some duplicated frames. Using a tolerance check in order to detect such roundtrip errors automatically, I noticed that roundtrip errors get more common when the fps is increased. Here is my data. I am encoding a 1 second video at 2 fps up to 300 fps, and I am printing the frame numbers which don't round-trip properly. So the line my data
Here are the things I have noticed in that data.
|
A roundtrip failure indicates that the encoding and the decoding don't match, but it doesn't say which of the two directions has the bug. One advantage of rendering the timestamp over rendering a solid shade of grey is that is is easy to distinguish two frames visually. I took one of the videos exhibiting the glitch, and I compared the frames produced by ffmpeg-light's |
Wait, that doesn't sound right: @burkaman tried the opposite, using |
Turns out the file format matters a lot. If I change nothing except the name of the output file, from |
my data
My hypothesis looked good for a while, but then the 100 fps case falsified it! I think that means there are at least two bugs. Assuming that the fact that some frame rates are unrepresentable in the target format and that the 100 fps case can be represented in a gif, that 100 fps case should only have one bug (or at least one fewer bug), so I plan to focus on that case next. |
imageReader
reads all but two frames when attempting to read all frames of a video, regardless of the video length. I'm not yet sure which frames are not being read.OS: NixOS 20.03
ffmpeg version: 3.4.7
Things I would like to try but haven't yet: other OSes, other ffmpeg versions, other video types, and making a short video with numbered frames so I can save the images and see which frames are dropped.
Steps to Reproduce
Make sure you have the following packages installed:
ffmpeg-light
,JuicyPixels
,monad-loops
.pulse.mov
, either by building the demo application and running with no arguments, or loading /demo/Main.hs in ghci and runningtestEncode
.ffmpeg -i pulse.mov -map 0:v:0 -c copy -f null -
, and in the second to last line of output you'll seeframe= 600
, indicating that this video has 600 frames.readAllFrames
. The output is 598, indicatingimageReader
only got 598 frames out of this video.Here's a gist with the output of
ffmpeg
andreadAllFrames
with log level set to trace: https://gist.github.com/burkaman/0bb1e18b6769eed13cdf521c240222c4The text was updated successfully, but these errors were encountered: