cinder / Cinder

Cinder is a community-developed, free and open source library for professional-quality creative coding in C++.
http://libcinder.org
Other
5.34k stars 944 forks source link

Looping movie missing frame in Linux #2033

Open gaborpapp opened 6 years ago

gaborpapp commented 6 years ago

Writing a very simple MovieGl player:

// setup()
mMovie = qtime::MovieGl::create( moviePath );
mMovie->setLoop();
mMovie->play()
...
// draw()
if ( mMovie && mMovie->isPlaying() )
{
    gl::draw( mMovie->getTexture() );
}

It seems that when the movie is looping there's a short period, maybe one frame, when it is not playing, while it would be expected that the first frame comes immediately after the last one. During this the following is displayed in the console:

|info   | GstStateChangeReturn gst::video::GstPlayer::getStateChange()[992] Pipeline CURRENT state : PLAYING with PENDING : VOID_PENDING
|info   | gboolean gst::video::checkBusMessagesAsync(GstBus*, GstMessage*, gpointer)[261] Pipeline state changed from : PAUSED to : PLAYING with pending : VOID_PENDING
PetrosKataras commented 6 years ago

Hi Gabor,

If I understand correctly you mean that the loop is not entirely seamless but instead has a small pause ( of one frame ) in between or you are actually missing the first frame when looping?

I suppose you mean the former - Looping is currently implemented by seeking to start when reaching the end of video file, but this is not ideal, especially for larger video files and lower end computers, and I have been meaning to revise it and use segment seeks for seamless looping as suggested by GStreamer ( https://gstreamer.freedesktop.org/documentation/design/seeking.html )

I haven't found the time to give it a go, but this example ( https://github.com/GStreamer/gst-plugins-good/blob/master/tests/icles/test-segment-seeks.c ) should contain all the relevant parts to implement this. Hope I can find some time in the next weeks to work on this since I believe it should not be much of an effort to integrate it.

gaborpapp commented 6 years ago

Hi Petros,

Thanks. It's the former I think, but didn't have time to look into it thoroughly. For one frame (or more) the movie is not playing. This is not an issue on macOS. I don't think it's a larger video file or lower end computer issue, because I tried it on two computers, both with ssd, gtx 1060. Thanks for the pointers. I'm not sure if I will have the time in the coming weeks either. I used a workaround to store the texture and draw it always. So when the movie is not playing it's drawing the saved texture from the previous frame, it's more or less solves the problem, but results in a one frame pause.

PetrosKataras commented 6 years ago

What happens if you omit the isPlaying check ? So smt like this :

if( mMovie ) {
    auto texture = mMovie->getTexture();
    if( texture )
        gl::draw( texture );
}

Do you still get the same behavior ?

gaborpapp commented 6 years ago

Thanks. This also works, and the returned texture is always valid. Probably still there is a one frame pause at the end, though.