Threaded loadMovie() misteriously crashing (almost there!)

Hey,

I’ve been trying to load movies into an ofVideoPlayer in a separate thread. This because whenever I tried loading them normally inside the main thread (testApp), there would always be a short freeze, the length of which depended on the size of the movie.

It all seems to be working, however, when I try to retrieve the pixels of the loaded, running movie from the thread to the main app, the app crashes with a nice ‘Segmentation fault’ message :smiley:

The crash is taking place specifically on the getPixels() call to the ofVideoPlayer inside the thread.

I get the feeling that this is the right approach to follow, because if I substitute all references to ofVideoPlayer for ofImage, it works perfectly. The loading takes place paralelly, not interrupting the main app, and the pixels do get loaded correctly into the mainapp, which draws the image perfectly.

Does anybody have an idea why this threaded approach would work on ofImage but not on ofVideoPlayer?

I’ve thought that it could be a platform specific issue, since I’m running OF 0.06 on Linux, which uses Gstreamer instead of Quicktime. It’d be cool if users of other platforms could try the following code…

Anyway, thanks for your attention, and any help would be extremely appreciated.

Regards,
Rodrigo

Here is my code:

testApp.h:

  
  
  
#ifndef _TEST_APP  
#define _TEST_APP  
  
#include "ofMain.h"  
#include "threadedObject.h"  
  
class testApp : public ofBaseApp{  
  
	public:  
  
		void setup();  
		void update();  
		void draw();  
  
		void keyPressed  (int key);  
  
		threadedObject	*   TO;  
		ofTexture texture;  
  
};  
  
#endif  
  
  

testApp.cpp:

  
  
  
#include "testApp.h"  
#include "stdio.h"  
  
bool    videoPlaying    =   false;  
float   debug           =   0;  
  
int textureWidth        =   704;    // <- w and h properties of the texture  
int textureHeight       =   576;  
  
//--------------------------------------------------------------  
void testApp::setup(){  
  
	TO = new threadedObject();  
	texture.allocate(textureWidth,textureHeight,GL_RGB);  
  
}  
  
//--------------------------------------------------------------  
void testApp::update(){  
	ofBackground(0,0,0);  
  
    // once the movie is loaded, run the following code by pressing '2':  
    if(videoPlaying &&  TO->movieLoaded)    {  
        TO->video->idleMovie();  
        texture.loadData(TO->getMovie(),textureWidth,textureHeight,GL_RGB);  
        videoPlaying=false;  
    }  
  
}  
  
//--------------------------------------------------------------  
void testApp::draw(){  
	ofSetColor(0xffffff);  
    texture.draw(30,30,textureWidth,textureHeight);  
  
    if(!TO->movieLoaded)  
        ofDrawBitmapString("press '1' to load movie",10,10);  
    else  
        ofDrawBitmapString("movie is loaded: now press '2'",10,10);  
  
  
}  
  
//--------------------------------------------------------------  
void testApp::keyPressed  (int key){  
  
    //  load the movie:  
    if (key == '1')  
        TO->start();  
  
    //  start running the movie once it has been loaded:  
    if (key == '2') {  
        TO->video->play();  
        videoPlaying=true;  
    }  
  
  
}  
  

threadedObject.h:

  
#ifndef _THREADED_OBJECT  
#define _THREADED_OBJECT  
  
#include "ofMain.h"  
#include "ofxThread.h"  
  
class threadedObject : public ofxThread{  
  
	public:  
  
        bool                movieLoaded;  
        ofVideoPlayer   *   video;  
  
		//--------------------------  
		threadedObject(){  
			movieLoaded =   false;  
			video   =   new ofVideoPlayer();  
            video->setUseTexture(false);  
		}  
  
		void start(){  
            startThread(true, false);   // blocking, verbose  
        }  
  
        void stop(){  
            stopThread();  
        }  
  
        unsigned char * getMovie() {  
            return  video->getPixels();  
        }  
  
		//--------------------------  
		void threadedFunction(){  
			while( isThreadRunning() != 0 ){  
				if( lock() ){  
					video->loadMovie("movies/fingers.mov");  
                    movieLoaded=true;  
					unlock();  
				}  
				stopThread();  
			}  
		}  
};  
  
#endif  
  

did you ever solve this?

this shouldn’t be necessary anymore, the video player object now has a loadAsync method that returns right away and starts loading the video in the background.