PsychError SCREENCreateMovie(void)
{
    static char useString[] = "moviePtr = Screen('CreateMovie', windowPtr, movieFile [, width][, height][, frameRate=30][, movieOptions][, numChannels=4][, bitdepth=8]);";
    static char synopsisString[] =
        "Create a new movie file with filename 'movieFile' and according to given 'movieOptions'.\n"
        "The function returns a handle 'moviePtr' to the file.\n"
        "Currently only single-track video encoding is supported.\n"
        "See 'Screen AddAudioBufferToMovie?' on how to add audio tracks to movies.\n"
        "\n"
        "Movie creation is a 3 step procedure:\n"
        "1. Create a movie and define encoding options via 'CreateMovie'.\n"
        "2. Add video and audio data to the movie via calls to 'AddFrameToMovie' et al.\n"
        "3. Finalize and close the movie via a call to 'FinalizeMovie'.\n\n"
        "All following parameters are optional and have reasonable defaults:\n\n"
        "'width' Width of movie video frames in pixels. Defaults to width of window 'windowPtr'.\n"
        "'height' Height of movie video frames in pixels. Defaults to height of window 'windowPtr'.\n"
        "'frameRate' Playback framerate of movie. Defaults to 30 fps. Technically this is not the "
        "playback framerate but the granularity in 1/frameRate seconds with which the duration of "
        "a single movie frame can be specified. When you call 'AddFrameToMovie', there's an optional "
        "parameter 'frameDuration' which defaults to one. The parameter defines the display duration "
        "of that frame as the fraction 'frameDuration' / 'frameRate' seconds, so 'frameRate' defines "
        "the denominator of that term. However, for a default 'frameDuration' of one, this is equivalent "
        "to the 'frameRate' of the movie, at least if you leave everything at defaults.\n\n"
        "'movieoptions' a textstring which allows to define additional parameters via keyword=parm pairs. "
        "For GStreamer movie writing, you can provide the same options as for GStreamer video recording. "
        "See 'help VideoRecording' for supported options and tips.\n"
        "Keywords unknown to a certain implementation or codec will be silently ignored:\n"
        "EncodingQuality=x Set encoding quality to value x, in the range 0.0 for lowest movie quality to "
        "1.0 for highest quality. Default is 0.5 = normal quality. 1.0 often provides near-lossless encoding.\n"
        "'numChannels' Optional number of image channels to encode: Can be 1, 3 or 4 on OpenGL graphics hardware, "
        "and 3 or 4 on OpenGL-ES hardware. 1 = Red/Grayscale channel only, 3 = RGB, 4 = RGBA. Please note that not "
        "all video codecs can encode pure 1 channel data or RGBA data, ie. an alpha channel. If an unsuitable codec "
        "is selected, movie writing may fail, or unsupported channels (e.g., the alpha channel) may get silently "
        "discarded. It could also happen that a codec which doesn't support 1 channel storage will replicate "
        "the Red/Grayscale data into all three RGB channels, leading to no data loss but increased movie file size. "
        "Default is to request RGBA 4 channel data from the system, encoding to RGBA or RGB, depending on codec.\n"
        "'bitdepth' Optional color/intensity resolution of each channel: Default is 8 bpc, for 8 bit per component "
        "storage. OpenGL graphics hardware, but not OpenGL-ES, also supports 16 bpc image readback. However, not all "
        "codecs can encode with > 8 bpc color/luminance precision, so encoding with 16 bpc may fail or silently reduce "
        "precision to less bits, possibly 8 bpc or less. If you specify the special keyword UsePTB16BPC in 'movieoptions', "
        "then PTB will use its own proprietary 16 bpc format for 1 or 3 channel mode. This format can only be read by "
        "PTB's own movie playback functions, not by other software.\n"
        "In general, embedded OpenGL-ES graphics hardware is more restricted in the type of image data it can return. "
        "Most video codecs are lossy codecs. They will intentionally throw away color or spatial precision of encoded "
        "video to reduce video file size or network bandwidth, often in a way that is not easily perceptible to the "
        "naked eye. If you require high fidelity, make sure to double-check your results for a given codec + parameter "
        "setup, e.g., via encoding + decoding the movie and checking the original data against decoded data.\n"
        "\n";

    static char seeAlsoString[] = "FinalizeMovie AddFrameToMovie CloseMovie PlayMovie GetMovieImage GetMovieTimeIndex SetMovieTimeIndex";

    PsychWindowRecordType                   *windowRecord;
    char                                    *moviefile;
    char                                    *movieOptions;
    int                                     moviehandle = -1;
    double                                  framerate = 30.0;
    int                                     width;
    int                                     height;
    int                                     numChannels, bitdepth;
    char                                    defaultOptions[2] = "";

    // All sub functions should have these two lines
    PsychPushHelp(useString, synopsisString, seeAlsoString);
    if(PsychIsGiveHelp()) {PsychGiveHelp(); return(PsychError_none);};

    PsychErrorExit(PsychCapNumInputArgs(8));            // Max. 8 input args.
    PsychErrorExit(PsychRequireNumInputArgs(2));        // Min. 2 input args required.
    PsychErrorExit(PsychCapNumOutputArgs(1));           // Max. 1 output args.

    // Get the window record from the window record argument and get info from the window record
    PsychAllocInWindowRecordArg(kPsychUseDefaultArgPosition, TRUE, &windowRecord);
    // Only onscreen windows allowed:
    if(!PsychIsOnscreenWindow(windowRecord)) {
        PsychErrorExitMsg(PsychError_user, "CreateMovie called on something else than an onscreen window.");
    }

    // Get the movie name string:
    moviefile = NULL;
    PsychAllocInCharArg(2, kPsychArgRequired, &moviefile);

    // Get the optional size:
    // Default Width and Height of movie frames is derived from size of window:
    width  = (int) PsychGetWidthFromRect(windowRecord->clientrect);
    height = (int) PsychGetHeightFromRect(windowRecord->clientrect);
    PsychCopyInIntegerArg(3, kPsychArgOptional, &width);
    PsychCopyInIntegerArg(4, kPsychArgOptional, &height);

    // Get the optional framerate:
    PsychCopyInDoubleArg(5, kPsychArgOptional, &framerate);

    // Get the optional options string:
    movieOptions = defaultOptions;
    PsychAllocInCharArg(6, kPsychArgOptional, &movieOptions);

    // Get optional number of channels of movie:
    numChannels = 4;
    PsychCopyInIntegerArg(7, kPsychArgOptional, &numChannels);
    if (numChannels != 1 && numChannels != 3 && numChannels != 4) PsychErrorExitMsg(PsychError_user, "Invalid number of channels 'numChannels' provided. Only 1, 3 or 4 channels allowed!");

    // Get optional bitdepth of movie:
    bitdepth = 8;
    PsychCopyInIntegerArg(8, kPsychArgOptional, &bitdepth);
    if (bitdepth != 8 && bitdepth != 16) PsychErrorExitMsg(PsychError_user, "Invalid 'bitdepth' provided. Only 8 bpc or 16 bpc allowed!");

    // Create movie of given size and framerate with given options:
    moviehandle = PsychCreateNewMovieFile(moviefile, width, height, framerate, numChannels, bitdepth, movieOptions, NULL);
    if (0 > moviehandle) {
        PsychErrorExitMsg(PsychError_user, "CreateMovie failed for reason mentioned above.");
    }

    // Return handle to it:
    PsychCopyOutDoubleArg(1, FALSE, (double) moviehandle);

    return(PsychError_none);
}
PsychError SCREENCreateMovie(void)
{
	static char useString[] = "moviePtr = Screen('CreateMovie', windowPtr, movieFile [, width][, height][, frameRate=30][, movieOptions]);";
	static char synopsisString[] = 
		"Create a new movie file with filename 'movieFile' and according to given 'movieOptions'.\n"
		"The function returns a handle 'moviePtr' to the file.\n"
		"Currently, movie creation and recording is only supported on OS/X and Windows, as it "
		"needs Apple's Quicktime to be installed. It can use any Quicktime codec that is installed "
		"on your system. Currently only single-track video encoding is supported, audio support is tbd.\n\n"
		"Movie creation is a 3 step procedure:\n"
		"1. Create a movie and define encoding options via 'CreateMovie'.\n"
		"2. Add video frames to the movie via calls to 'AddFrameToMovie'.\n"
		"3. Finalize and close the movie via a call to 'FinalizeMovie'.\n\n"
		"All following parameters are optional and have reasonable defaults:\n\n"
		"'width' Width of movie video frames in pixels. Defaults to width of window 'windowPtr'.\n"
		"'height' Height of movie video frames in pixels. Defaults to height of window 'windowPtr'.\n"
		"'frameRate' Playback framerate of movie. Defaults to 30 fps. Technically this is not the "
		"playback framerate but the granularity in 1/frameRate seconds with which the duration of "
		"a single movie frame can be specified. When you call 'AddFrameToMovie', there's an optional "
		"parameter 'frameDuration' which defaults to one. The parameter defines the display duration "
		"of that frame as the fraction 'frameDuration' / 'frameRate' seconds, so 'frameRate' defines "
		"the denominator of that term. However, for a default 'frameDuration' of one, this is equivalent "
		"to the 'frameRate' of the movie, at least if you leave everything at defaults.\n\n"
		"'movieoptions' a textstring which allows to define additional parameters via keyword=parm pairs. "
		"Keywords unknown to a certain implementation or codec will be silently ignored:\n"
		"EncodingQuality=x Set encoding quality to value x, in the range 0.0 for lowest movie quality to "
		"1.0 for highest quality. Default is 0.5 = normal quality. 1.0 usually provides lossless encoding.\n"
		"CodecFOURCCId=id FOURCC id. The FOURCC of a desired video codec as a number. Defaults to H.264 codec.\n"
		"Choice of codec and quality defines a tradeoff between filesize, quality, processing demand and speed, "
		"as well as on which target devices you'll be able to play your movie.\n"
		"CodecFOURCC=xxxx FOURCC as a four character text string instead of a number.\n"
		"\n";

	static char seeAlsoString[] = "FinalizeMovie AddFrameToMovie CloseMovie PlayMovie GetMovieImage GetMovieTimeIndex SetMovieTimeIndex";
	
	PsychWindowRecordType					*windowRecord;
	char                                    *moviefile;
	char									*movieOptions;
	int                                     moviehandle = -1;
	double                                  framerate = 30.0;
	int                                     width;
	int                                     height;
	char									defaultOptions[2] = "";
	
	// All sub functions should have these two lines
	PsychPushHelp(useString, synopsisString, seeAlsoString);
	if(PsychIsGiveHelp()) {PsychGiveHelp(); return(PsychError_none);};
	
	PsychErrorExit(PsychCapNumInputArgs(6));            // Max. 6 input args.
	PsychErrorExit(PsychRequireNumInputArgs(2));        // Min. 2 input args required.
	PsychErrorExit(PsychCapNumOutputArgs(1));           // Max. 1 output args.
	
	// Get the window record from the window record argument and get info from the window record
	PsychAllocInWindowRecordArg(kPsychUseDefaultArgPosition, TRUE, &windowRecord);
	// Only onscreen windows allowed:
	if(!PsychIsOnscreenWindow(windowRecord)) {
		PsychErrorExitMsg(PsychError_user, "CreateMovie called on something else than an onscreen window.");
	}
	
	// Get the movie name string:
	moviefile = NULL;
	PsychAllocInCharArg(2, kPsychArgRequired, &moviefile);
	
	// Get the optional size:
	// Default Width and Height of movie frames is derived from size of window:
	width = PsychGetWidthFromRect(windowRecord->rect);
	height = PsychGetHeightFromRect(windowRecord->rect);
	PsychCopyInIntegerArg(3, kPsychArgOptional, &width);
	PsychCopyInIntegerArg(4, kPsychArgOptional, &height);
	
	// Get the optional framerate:
	PsychCopyInDoubleArg(5, kPsychArgOptional, &framerate);
	
	// Get the optional options string:
	movieOptions = defaultOptions;
	PsychAllocInCharArg(6, kPsychArgOptional, &movieOptions);

	// Create movie of given size and framerate with given options:
	moviehandle = PsychCreateNewMovieFile(moviefile, width, height, framerate, movieOptions);
	if (0 > moviehandle) {
		printf("See http://developer.apple.com/documentation/QuickTime/APIREF/ErrorCodes.htm#//apple_ref/doc/constant_group/Error_Codes.\n\n");
		PsychErrorExitMsg(PsychError_user, "CreateMovie failed for reason mentioned above.");
	}
	
	// Return handle to it:
	PsychCopyOutDoubleArg(1, FALSE, (double) moviehandle);
	
	return(PsychError_none);
}