C++ and SDL_Thread

Hello,

I would like to create a class which, when instantiated, owns a
thread calling one of its member functions. Thus, I have this class
(I’ve cut some parts that aren’t important to save space, but they
all work as intended, I’m just adding the threading to hopefully
speed things up a smidgeon):

================================================begin code

#ifndef _ve_media_h
#define _ve_media_h

#include “ffmpeg/avformat.h”
#include “ffmpeg/avcodec.h”
#include “ffmpeg/avutil.h”
#include “ffmpeg/swscale.h”

#include <SDL/SDL_thread.h>
#include <SDL/SDL_mutex.h>

class VE_Media;

class VE_Media {
private:
//…
//cut… variables for loading/processing video data
//…

bool			mThreadLives;
SDL_Thread		*mThread;

int thread_func( void *unused );
void killThread( void );

public:
VE_Media();
VE_Media(char *fName);
~VE_Media();

//accessors
bool exists();
int loadMedia(char *fName);
char *getError();
uint8_t *getNextVideoFrame();
uint8_t *getNextVideoFrame(int* w, int* h);
void getDimensions( int* w, int* h );

};

#endif

===========================and the .cpp file:

#include “VE_Media.h”
#include “string.h”

VE_Media::VE_Media() {
pFormatCtx = NULL;
error = “no data”;
filename = NULL;
vidStreamExists = false;
audStreamExists = false;
}

VE_Media::~VE_Media() {
delete buffer;
}

VE_Media::VE_Media(char *fName) {
//…
//cut…ffmpeg/libav initializers for file fName;
//…
mThreadLives = true;
mThread = SDL_CreateThread( thread_func, NULL );
if( mThread == NULL ) {
printf( “Error creating media thread\n” );
return;
}
}

void VE_Media::getDimensions( int *w, int *h ) {
if( vidStreamExists ) {
*w = pCodecCtx->width;
*h = pCodecCtx->height;
} else {
printf(“getDimensions: no video stream, no size\n”);
*w = -1;
*h = -1;
}
}
uint8_t *VE_Media::getNextVideoFrame() {
//…
//cut… pulls next video frame and converts to RGB data
//…
}

int VE_Media::thread_func( void *unused ) {
SDL_mutex *mutex = SDL_CreateMutex();

while( mThreadLives ) {
	//load video/audio data and perform conversions
	//while the rest of the program is doing its thing
}

SDL_DestroyMutex( mutex );
return 0;

}

uint8_t VE_Media::getNextVideoFrame(int w, int* h) {
*w = pCodecCtx->width;
*h = pCodecCtx->height;

	return getNextVideoFrame();

}

================================================end code

My compiler errors out saying:

error: argument of type ‘int (VE_Media::)(void*)’ does not match ‘int
()(void)’

I’m not a total n00b when it comes to C/C++, but I’ve not done enough
to have reason for knowing what’s going on here. I read some forum
posts about a similar topic which ended when it was suggested to make
a proxy struct, so that the compiler would think everything to be
right with the world, but I have no idea about typecasting functions
(I started on Java, so…), and thus no way to know if this is a good
way (or the best way) to get this done:

template
struct SDL_ThreadProxy
{
typedef int (T::TFunction)();
SDL_ThreadProxy(T * instance, TFunction function)
: _instance(instance)
, _function(function)
{}
static int run(SDL_ThreadProxy * _this)
{
return ((_this->_instance)->
(_this->_function))();
}

private:
T * _instance;
TFunction _function;
};

template
SDL_Thread * SDL_CreateMemberThread(T * instance, int (T::*function)())
{
SDL_ThreadProxy proxy(instance, function);
typedef int (*SDL_ThreadFunction)(void *);
return SDL_CreateThread(reinterpret_cast<SDL_ThreadFunction>
(SDL_ThreadProxy::run), &proxy);
}

Again, I have little more than a broad idea of what’s REALLY going
on, so does anyone have any comments on this? Is this an okay way to
handle things (cut/paste this code into a header in my project and
utilize as is-sort of thing)? Is there anything to be done in the
SDL codebase to make this sort of thing unnecessary? Has perhaps
something already been done?

Thanks for whatever comments you can supply,
– Scott

Hello,

I would like to create a class which, when instantiated, owns a
thread calling one of its member functions. Thus, I have this class
(I’ve cut some parts that aren’t important to save space, but they
all work as intended, I’m just adding the threading to hopefully
speed things up a smidgeon):

…snip…

Again, I have little more than a broad idea of what’s REALLY going
on, so does anyone have any comments on this? Is this an okay way to
handle things (cut/paste this code into a header in my project and
utilize as is-sort of thing)? Is there anything to be done in the
SDL codebase to make this sort of thing unnecessary? Has perhaps
something already been done?

I also found this as a possible solution:

class CMyClass
{
public:
static int UpdateHelper(void *);
int Update();
};

int CMyClass::UpdateHelper(void *t)
{
return ((CMyClass *)t)->Update();
}


UpdateThread = SDL_CreateThread(UpdateHelper, this);

That seems cleaner to me, so I’m going to go with this for now and
change if y’all have a better suggestion.
– ScottOn Jan 30, 2007, at 10:34 PM, Scott Harper wrote:

I would like to create a class which, when instantiated, owns a
thread calling one of its member functions. Thus, I have this class
(I’ve cut some parts that aren’t important to save space, but they
all work as intended, I’m just adding the threading to hopefully
speed things up a smidgeon):

Expect 17 replies saying this, but…

int thread_func( void *unused );

Needs to be

static int thread_func( void *unused );

Otherwise there’s a hidden parameter in C++. In terms of C, the first
one is more like:

int thread_func(VE_Media *this, void *unused);

…which obviously isn’t what you want.

Your UpdateHelper() approach in the second email you sent is actually
The Right Thing to do.

–ryan.