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
|
/*
PsychSourceGL/Source/Common/Screen/PsychMovieSupport.c
PLATFORMS:
All.
AUTHORS:
Mario Kleiner mk mario.kleiner.de@gmail.com
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.
On all platforms it is currently GStreamer or nothing.
*/
#include "Screen.h"
#ifdef PTB_USE_GSTREAMER
#include "PsychMovieSupportGStreamer.h"
#endif
/*
* 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
return;
}
int PsychGetMovieCount(void)
{
#ifdef PTB_USE_GSTREAMER
return(PsychGSGetMovieCount());
#endif
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 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, movieinfo->pixelFormat, movieinfo->maxNumberThreads, movieinfo->movieOptions);
// 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 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, int pixelFormat, int maxNumberThreads, char* movieOptions)
{
#ifdef PTB_USE_GSTREAMER
PsychGSCreateMovie(win, moviename, preloadSecs, moviehandle, asyncFlag, specialFlags1, pixelFormat, maxNumberThreads, movieOptions);
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)
{
#ifdef PTB_USE_GSTREAMER
PsychGSGetMovieInfos(moviehandle, width, height, framecount, durationsecs, framerate, nrdroppedframes, aspectRatio);
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)
{
#ifdef PTB_USE_GSTREAMER
PsychGSDeleteMovie(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)
{
#ifdef PTB_USE_GSTREAMER
PsychGSDeleteAllMovies();
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)
{
#ifdef PTB_USE_GSTREAMER
return(PsychGSGetTextureFromMovie(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 movie texture.
*
* This routine is called by PsychDeleteTexture() in PsychTextureSupport.c
* It performs the special cleanup necessary for movie cached textures.
*
*/
void PsychFreeMovieTexture(PsychWindowRecordType *win)
{
#ifdef PTB_USE_GSTREAMER
PsychGSFreeMovieTexture(win);
return;
#endif
}
/*
* 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)
{
#ifdef PTB_USE_GSTREAMER
return(PsychGSPlaybackRate(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 textures and releases all movie objects.
* Then it shuts down the movie subsystem.
*
*/
void PsychExitMovies(void)
{
#ifdef PTB_USE_GSTREAMER
PsychGSExitMovies();
#endif
return;
}
/*
* PsychGetMovieTimeIndex() -- Return current playback time of movie.
*/
double PsychGetMovieTimeIndex(int moviehandle)
{
#ifdef PTB_USE_GSTREAMER
return(PsychGSGetMovieTimeIndex(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)
{
#ifdef PTB_USE_GSTREAMER
return(PsychGSSetMovieTimeIndex(moviehandle, timeindex, indexIsFrames));
#endif
PsychErrorExitMsg(PsychError_unimplemented, "Sorry, Movie playback support not supported on your configuration.");
return(0.0);
}
/*
* PsychCopyOutMovieHDRMetaData() -- Return a struct with HDR static metadata about this movie to scripting environment.
*/
void PsychCopyOutMovieHDRMetaData(int moviehandle, int argPosition)
{
#ifdef PTB_USE_GSTREAMER
PsychGSCopyOutMovieHDRMetaData(moviehandle, argPosition);
return;
#endif
PsychErrorExitMsg(PsychError_unimplemented, "Sorry, Movie playback support not supported on your configuration.");
}
|