Search code examples
iosavfoundationvideo-captureavplayer

AVPlayerItem's stepByCount only smooth for forward, but choppy for backwards?


I have implemented AVPlayerItem's stepByCount method to manually go through a video frame by frame. Here's how it looks like for forward 1 step.

    AVPlayer *player = [AVPlayer playerWithURL:url];
    [player.currentItem stepByCount:1];

And backward 1 step

    AVPlayer *player = [AVPlayer playerWithURL:url];
    [player.currentItem stepByCount:-1];

The forward 1 step (going forward in time frame by frame) works well. However when I try to go backward frame by frame, it's not as smooth as the forward step. Am I missing something? Or is this because of the way videos are encoded--it's meant to be viewed forward but not backwards--inherently?


Solution

  • Not sure what encoding format your video is in but compressed videos are encoded with keyframes. These occur either at regular intervals (like once a second) or when the scene changes (like when a cut is made from close up to wide shot). The data between keyframes just describes the cumulative changes since the last keyframe - only pixels that change are noted. As you have deduced, this means that a video in reverse is not how it is designed to be played. When you skip backwards the encoder needs to skip back to the previous keyframe (which could be hundreds or even thousands of frames before your current position) then recreate all the frames up to your required frame before actually presenting you with the composited frame. The only way around this in your situation is to either use an already flattened video format or to flatten it before scanning. You might want to take a look at http://opencv.org/ if you want to get into decompression.