VideoReader reads frames significantly faster forward than backwards

7 次查看(过去 30 天)
Going forward with frames is significantly faster (about 20x) than going backwards (even when accessing frames by index):
vReader = VideoReader('xylophone.mp4');
tic
for i=1:100
for iFrame=1:vReader.NumFrames
frame = read(vReader, iFrame);
end
end
toc
tic
for i=1:100
for iFrame=vReader.NumFrames:-1:1
frame = read(vReader, iFrame);
end
end
toc
Elapsed time is 7.784752 seconds.
Elapsed time is 152.097742 seconds.
Is this known behavior, and if so is there a workaround?

回答(1 个)

Walter Roberson
Walter Roberson 2020-12-29
it is expected that it would be slower.
The decoder does not build a frame index starting from the beginning of the file.
mp4 files are not indexed by frame number: they are indexed by frame time. But they are potentially variable-rate, so knowing the current frame time and the reported frame rate does not always give enough information to calculate a frame time directly. Even files that are not variable rate cannot count on the reported frame rate, as the reported frame rate is considered an approximation. For example, 30 frames per second might be reported for NTSC, or 29.9 frames, when NTSC is 29.97-something frames.
The internal code needs to keep a buffer of the current GOP (group of frames) when moving forward; for MPEG-2 the needed buffering was more restricted. But the code discards the buffer and moves forward from the beginning of the file whenever you move backwards. Potentially it could avoid doing that if the requested frame was within the current GOP. Skipping forward from the current frame does not require going back to the beginning -- the code knows the current frame number and so scan skim forward just figuring out how many frames are there without decoding the details until it arrives at the correct GOP.
Potentially you might be able to do better moving in reverse if you ran forward first building an index of frame numbers to frame times, allowing you to set the frame time (which is indexed) instead of asking for a frame number (which is not.)
Anyhow: what you can do to improve performance is position backwards by several groups of frames, and read several frames, and release them in reverse order, so that you reduce the amount of seeking within the file that is needed.
  1 个评论
Andreas Nord
Andreas Nord 2021-1-4
This clarifies things. Is this the proper way to index by time?
videoReader.CurrentTime = t;
readFrame(videoReader);
This is very slow for me.

请先登录,再进行评论。

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by