1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410
|
/*
PsychSourceGL/Source/Common/Screen/PsychMovieSupport.c
PLATFORMS:
All.
AUTHORS:
Mario Kleiner mk mario.kleiner@tuebingen.mpg.de
HISTORY:
DESCRIPTION:
Psychtoolbox functions for dealing with movies.
This is the master dispatcher. Function herein get called by
other parts of Psychtoolbox, most notably the SCREENxxx functions
for movie playback. It dispatches into either the QuickTime based
or GStreamer based implementations of the movie playback functions,
depending on OS/Availability/Chosen configuration.
On OS/X and Windows with 32-bit Matlab/Octave, usually Quicktime is
used as movie playback engine. If GStreamer is supported on that
platforms and enabled via Screen('Preference','OverrideMultimediaEngine', 1);
then GStreamer is used.
On all other platforms it is either GStreamer or nothing, as Quicktime
isn't supported. These platforms are Window and OS/X with 64-bit Matlab/Octave,
and Linux. As of 30.11.2010, only Linux is supported, 64-bit OS/X and
Windows are planned.
NOTES:
*/
#include "Screen.h"
#if PSYCH_SYSTEM != PSYCH_LINUX
#if !defined(__LP64__) && !defined(_M_IA64)
#define PSYCHQTAVAIL 1
#include "PsychMovieSupportQuickTime.h"
#endif
#endif
#if defined(__LP64__) || defined(_M_IA64)
#define PSYCHOTHER64BIT 1
#else
#define PSYCHOTHER64BIT 0
#endif
#ifdef PTB_USE_GSTREAMER
#include "PsychMovieSupportGStreamer.h"
#define USE_GSTREAMER 1
#else
#define USE_GSTREAMER 0
#endif
static psych_bool firstTime = TRUE;
static psych_bool doUsegs = FALSE;
static psych_bool usegs(void) {
// First invocation since module load time?
if (firstTime) {
// Yes. Need to probe which engine to use:
firstTime = FALSE;
// Default to Quicktime instead of GStreamer,
// override in detection code below if appropriate:
doUsegs = FALSE;
// We always use GStreamer if we are running on
// Linux, or 64-Bit builds on OS/X or Windows, as
// these systems only support GStreamer, but they
// support it consistently:
if ((PSYCH_SYSTEM == PSYCH_LINUX) || PSYCHOTHER64BIT) {
// Yep: Unconditionally use GStreamer:
doUsegs = TRUE;
} else {
// This is a 32-bit build on Windows or OS/X.
// We use GStreamer if it is supported and usercode
// wants to use it, according to preference setting:
if (USE_GSTREAMER && (PsychPrefStateGet_UseGStreamer()==1)) {
doUsegs = TRUE;
}
}
}
// Return cached engine use flag:
return(doUsegs);
}
/*
* PsychMovieInit() -- Initialize movie subsystem.
* This routine is called by Screen's RegisterProject.c PsychModuleInit()
* routine at Screen load-time. It clears out the movieRecordBANK to
* bring the subsystem into a clean initial state.
*/
void PsychMovieInit(void)
{
#ifdef PTB_USE_GSTREAMER
// This will also first-time initialize Glib's threading system:
PsychGSMovieInit();
#endif
#ifdef PSYCHQTAVAIL
PsychQTMovieInit();
#endif
// Reset firstTime flag:
firstTime = TRUE;
return;
}
int PsychGetMovieCount(void)
{
if (usegs()) {
#ifdef PTB_USE_GSTREAMER
return(PsychGSGetMovieCount());
#endif
} else {
#ifdef PSYCHQTAVAIL
return(PsychQTGetMovieCount());
#endif
}
PsychErrorExitMsg(PsychError_unimplemented, "Sorry, Movie playback support not supported on your configuration.");
return(0);
}
/*
* PsychAsyncCreateMovie() -- Open a movie file in the background.
*
* This function is called by SCREENOpenMovie as main-function of
* a new Posix-Thread for background movie loading. It simply calls
* PsychCreateMovie(), waiting for it to return a new moviehandle.
* Then it returns those info and terminates.
* -> By calling PsychCreateMovie from the run-function of a dedicated
* Posix-Thread which runs independent of the main Matlab/PTB Thread with
* non-realtime priority, we can do the work of opening a Quicktime movie
* in the background, hopefully not affecting the timing of the main PTB
* thread too much.
*/
void* PsychAsyncCreateMovie(void* inmovieinfo)
{
int rc;
PsychAsyncMovieInfo* movieinfo = (PsychAsyncMovieInfo*) inmovieinfo;
// The special value -1000 tells PsychCreateMovie to not output any error-
// messages as this could easily crash Matlab/Octave.
int mymoviehandle=-1000;
// Reduce our scheduling priority to the minimum value of zero, so
// we do not interfere too much with the PTB main thread:
if ((rc=PsychSetThreadPriority(NULL, 0, 0))!=0) {
printf("PTB-WARNING: In PsychAsyncCreateMovie(): Failed to lower my priority to non-realtime [System errorcode %i]. Expect timing problems for movie playback!", rc);
}
// Execute our normal OpenMovie function: This does the hard work:
PsychCreateMovie(&(movieinfo->windowRecord), movieinfo->moviename, movieinfo->preloadSecs, &mymoviehandle, movieinfo->asyncFlag, movieinfo->specialFlags1);
// Ok, either we have a moviehandle to a valid movie, or we failed, which would
// be signalled to the calling function via some negative moviehandle:
movieinfo->moviehandle = mymoviehandle; // Return moviehandle.
movieinfo->asyncstate = 2; // Set state to "Completed"
// Exit from the routine. This will automatically terminate our Thread.
return(NULL);
}
/*
* PsychCreateMovie() -- Create a movie object.
*
* This function tries to open a Quicktime-Moviefile and create an
* associated movie object for it.
*
* win = Pointer to window record of associated onscreen window.
* moviename = char* with the name of the moviefile.
* moviehandle = handle to the new movie.
*/
void PsychCreateMovie(PsychWindowRecordType *win, const char* moviename, double preloadSecs, int* moviehandle, int asyncFlag, int specialFlags1)
{
if (usegs()) {
#ifdef PTB_USE_GSTREAMER
PsychGSCreateMovie(win, moviename, preloadSecs, moviehandle, asyncFlag, specialFlags1);
return;
#endif
} else {
#ifdef PSYCHQTAVAIL
PsychQTCreateMovie(win, moviename, preloadSecs, moviehandle, specialFlags1);
return;
#endif
}
PsychErrorExitMsg(PsychError_unimplemented, "Sorry, Movie playback support not supported on your configuration.");
}
/*
* PsychGetMovieInfo() - Return basic information about a movie.
*
* framecount = Total number of video frames in the movie, determined by counting.
* durationsecs = Total playback duration of the movie, in seconds.
* framerate = Estimated video playback framerate in frames per second (fps).
* width = Width of movie images in pixels.
* height = Height of movie images in pixels.
* nrdroppedframes = Total count of videoframes that had to be dropped during last movie playback,
* in order to keep the movie synced with the realtime clock.
* aspectRatio = Pixel aspect ratio of encoded pixels in movie frame. (GStreamer only).
*/
void PsychGetMovieInfos(int moviehandle, int* width, int* height, int* framecount, double* durationsecs, double* framerate, int* nrdroppedframes, double* aspectRatio)
{
if (usegs()) {
#ifdef PTB_USE_GSTREAMER
PsychGSGetMovieInfos(moviehandle, width, height, framecount, durationsecs, framerate, nrdroppedframes, aspectRatio);
return;
#endif
} else {
#ifdef PSYCHQTAVAIL
PsychQTGetMovieInfos(moviehandle, width, height, framecount, durationsecs, framerate, nrdroppedframes);
if (aspectRatio) *aspectRatio = 1.0;
return;
#endif
}
PsychErrorExitMsg(PsychError_unimplemented, "Sorry, Movie playback support not supported on your configuration.");
}
/*
* PsychDeleteMovie() -- Delete a movie object and release all associated ressources.
*/
void PsychDeleteMovie(int moviehandle)
{
if (usegs()) {
#ifdef PTB_USE_GSTREAMER
PsychGSDeleteMovie(moviehandle);
return;
#endif
} else {
#ifdef PSYCHQTAVAIL
PsychQTDeleteMovie(moviehandle);
return;
#endif
}
PsychErrorExitMsg(PsychError_unimplemented, "Sorry, Movie playback support not supported on your configuration.");
}
/*
* PsychDeleteAllMovies() -- Delete all movie objects and release all associated ressources.
*/
void PsychDeleteAllMovies(void)
{
if (usegs()) {
#ifdef PTB_USE_GSTREAMER
PsychGSDeleteAllMovies();
return;
#endif
} else {
#ifdef PSYCHQTAVAIL
PsychQTDeleteAllMovies();
return;
#endif
}
PsychErrorExitMsg(PsychError_unimplemented, "Sorry, Movie playback support not supported on your configuration.");
}
/*
* PsychGetTextureFromMovie() -- Create an OpenGL texture map from a specific videoframe from given movie object.
*
* win = Window pointer of onscreen window for which a OpenGL texture should be created.
* moviehandle = Handle to the movie object.
* checkForImage = true == Just check if new image available, false == really retrieve the image, blocking if necessary.
* timeindex = When not in playback mode, this allows specification of a requested frame by presentation time.
* If set to -1, or if in realtime playback mode, this parameter is ignored and the next video frame is returned.
* out_texture = Pointer to the Psychtoolbox texture-record where the new texture should be stored.
* presentation_timestamp = A ptr to a double variable, where the presentation timestamp of the returned frame should be stored.
*
* Returns true (1) on success, false (0) if no new image available, -1 if no new image available and there won't be any in future.
*/
int PsychGetTextureFromMovie(PsychWindowRecordType *win, int moviehandle, int checkForImage, double timeindex, PsychWindowRecordType *out_texture, double *presentation_timestamp)
{
if (usegs()) {
#ifdef PTB_USE_GSTREAMER
return(PsychGSGetTextureFromMovie(win, moviehandle, checkForImage, timeindex, out_texture, presentation_timestamp));
#endif
} else {
#ifdef PSYCHQTAVAIL
return(PsychQTGetTextureFromMovie(win, moviehandle, checkForImage, timeindex, out_texture, presentation_timestamp));
#endif
}
PsychErrorExitMsg(PsychError_unimplemented, "Sorry, Movie playback support not supported on your configuration.");
return(-1);
}
/*
* PsychFreeMovieTexture() - Release texture memory for a Quicktime texture.
*
* This routine is called by PsychDeleteTexture() in PsychTextureSupport.c
* It performs the special cleanup necessary for Quicktime created textures.
*
*/
void PsychFreeMovieTexture(PsychWindowRecordType *win)
{
if (usegs()) {
#ifdef PTB_USE_GSTREAMER
PsychGSFreeMovieTexture(win);
return;
#endif
} else {
#ifdef PSYCHQTAVAIL
PsychQTFreeMovieTexture(win);
return;
#endif
}
PsychErrorExitMsg(PsychError_unimplemented, "Sorry, Movie playback support not supported on your configuration.");
}
/*
* PsychPlaybackRate() - Start- and stop movieplayback, set playback parameters.
*
* moviehandle = Movie to start-/stop.
* playbackrate = zero == Stop playback, non-zero == Play movie with spec. rate,
* e.g., 1 = forward, 2 = double speed forward, -1 = backward, ...
* loop = 0 = Play once. 1 = Loop, aka rewind at end of movie and restart.
* soundvolume = 0 == Mute sound playback, between 0.0 and 1.0 == Set volume to 0 - 100 %.
* Returns Number of dropped frames to keep playback in sync.
*/
int PsychPlaybackRate(int moviehandle, double playbackrate, int loop, double soundvolume)
{
if (usegs()) {
#ifdef PTB_USE_GSTREAMER
return(PsychGSPlaybackRate(moviehandle, playbackrate, loop, soundvolume));
#endif
} else {
#ifdef PSYCHQTAVAIL
return(PsychQTPlaybackRate(moviehandle, playbackrate, loop, soundvolume));
#endif
}
PsychErrorExitMsg(PsychError_unimplemented, "Sorry, Movie playback support not supported on your configuration.");
return(0);
}
/*
* void PsychExitMovies() - Shutdown handler.
*
* This routine is called by Screen('CloseAll') and on clear Screen time to
* do final cleanup. It deletes all Quicktime textures and releases all Quicktime
* movie objects. Then it shuts down the Quicktime subsystem.
*
*/
void PsychExitMovies(void)
{
if (usegs()) {
#ifdef PTB_USE_GSTREAMER
PsychGSExitMovies();
#endif
} else {
#ifdef PSYCHQTAVAIL
PsychQTExitMovies();
#endif
}
// Reset firstTime flag:
firstTime = TRUE;
return;
}
/*
* PsychGetMovieTimeIndex() -- Return current playback time of movie.
*/
double PsychGetMovieTimeIndex(int moviehandle)
{
if (usegs()) {
#ifdef PTB_USE_GSTREAMER
return(PsychGSGetMovieTimeIndex(moviehandle));
#endif
} else {
#ifdef PSYCHQTAVAIL
return(PsychQTGetMovieTimeIndex(moviehandle));
#endif
}
PsychErrorExitMsg(PsychError_unimplemented, "Sorry, Movie playback support not supported on your configuration.");
return(0.0);
}
/*
* PsychSetMovieTimeIndex() -- Set current playback time of movie.
*/
double PsychSetMovieTimeIndex(int moviehandle, double timeindex, psych_bool indexIsFrames)
{
if (usegs()) {
#ifdef PTB_USE_GSTREAMER
return(PsychGSSetMovieTimeIndex(moviehandle, timeindex, indexIsFrames));
#endif
} else {
#ifdef PSYCHQTAVAIL
return(PsychQTSetMovieTimeIndex(moviehandle, timeindex, indexIsFrames));
#endif
}
PsychErrorExitMsg(PsychError_unimplemented, "Sorry, Movie playback support not supported on your configuration.");
return(0.0);
}
|