Openframeworks: ofVideoPlayer (AVFoundation) nextFrame update

Created on 7 Apr 2015  路  10Comments  路  Source: openframeworks/openFrameworks

Latest git on OS X 10.9, using nextFrame with update does not seem to update the frames.
Although if you switch the order of nextFrame and update it works. Am I missing something or is it an issue with the OS X video player?

Simple test app:

#include "ofMain.h"

class ofApp : public ofBaseApp
{
  public:
    void setup();
    void update();
    void draw();

    ofVideoPlayer fingerMovie;
};

void ofApp::setup()
{
    ofBackground(255,255,255);

    fingerMovie.load("movies/fingers.mov");
    fingerMovie.setLoopState(OF_LOOP_NORMAL);
    fingerMovie.play();
    fingerMovie.setPaused(true);
}

void ofApp::update()
{
    fingerMovie.nextFrame();
    fingerMovie.update();
}

void ofApp::draw()
{
    ofSetHexColor(0xFFFFFF);
    fingerMovie.draw(20,20);

    ofSetHexColor(0x000000);
    ofDrawBitmapString("frame: " + ofToString(fingerMovie.getCurrentFrame()) + "/" +
                       ofToString(fingerMovie.getTotalNumFrames()), 20, 380);
}
bug macOS prelim-analysis section-video

Most helpful comment

i don't think adding a delay is a good solution, it wouldn't warrant anything really and it would need to be a different delay depending on the machine, resolution, video format....

perhaps there should be a frame by frame api in which one can control from outside which frame has to be shown next and the player would block until it gets that frame. but i don't think having both apis in the player is a good idea since it would add a lot of complexity and most video formats are not very good at scrubbing or seeking anyway.

whenever i need to have control over the exact frame being played i usually use an image sequence, i'm also using https://github.com/vjacob/ofxHPVPlayer for a project right now which works quite nicely for syncing several videos to the same frame...

All 10 comments

I've noticed this with using switch statements in keyPressed. using nextFrame and previousFrame do not work at all properly.
it was fine with the last github repo, but this current one has seemed to have messed with nextFrame/previousFrame. unless im missing something completely

this is not a bug.
this issue is due to AVFoundations asynchronous nature. calling nextFrame() is a non-blocking call to a internal seek event which will call a completion-handler when finished.
calling update() directly after nextFrame() is not guaranteed to get the new frame, actually it is very likely that seeking for the next frame is not finished.

in order to make it work, one should wait for that completion handler and then update the frame.
to make that example work turn around the function calls in your update(). this gives the seek event some time before the next seek event is scheduled.

i just tested with frame-stepping with key-commands. this worked fine.

@i-n-g-o nextFrame() should wait for the completion-handler then. It is very confusing, not to mention the confusion with the return value of getCurrentFrame() after nextFrame().

hm. not sure about that.
this would synchronize asynchronous behaviour and lock nextFrame() to the mainthread.
the strength of asynchronous frameworks is that calls are not blocking.
waiting for the completion handler when calling nextFrame() would totally ignore this.

i think this is not the way to go.
instead we should work with events to know when e.g.: a frame is ready.

it might be necessary to do other work while waiting for nextFrame()...

You are right, but the name nextFrame() implies that when I call it I get the next frame, which is not the case here. There are use cases for both sync and async behaviour I think. And nextFrame() was working synchronously before. If it was called nextFrameAsync() or something I would agree, but one might still need the synchronous behaviour sometimes.

right. the confusion comes because it worked differently before.
we have the "Async" signature already when loading a file with loadAsync()

I've been looking at this recently for a project and I've found adding a tiny sleep can help make nextFrame() / update() work called sequentially. I wonder if it's possible add some logic to update() which adds a minimal delay if nextFrame or prevFrame has just been called if the movie position hasn't been updated.

i don't think adding a delay is a good solution, it wouldn't warrant anything really and it would need to be a different delay depending on the machine, resolution, video format....

perhaps there should be a frame by frame api in which one can control from outside which frame has to be shown next and the player would block until it gets that frame. but i don't think having both apis in the player is a good idea since it would add a lot of complexity and most video formats are not very good at scrubbing or seeking anyway.

whenever i need to have control over the exact frame being played i usually use an image sequence, i'm also using https://github.com/vjacob/ofxHPVPlayer for a project right now which works quite nicely for syncing several videos to the same frame...

Agreed w/ @arturoc on this one. I would say that we might consider updating our video player API / documentation to reflect that OS level video APIs are more asynchronous than they used to be (allowing higher bandwidth video and newer codecs) and make sure our documentation sets correct expectations.

Was this page helpful?
0 / 5 - 0 ratings