PsychError SCREENVideoCaptureDevices(void) { int engineId; // All sub functions should have these two lines PsychPushHelp(useString2, synopsisString2, seeAlsoString); if(PsychIsGiveHelp()) {PsychGiveHelp(); return(PsychError_none);}; PsychErrorExit(PsychCapNumInputArgs(1)); // Max. 1 input args. PsychErrorExit(PsychRequireNumInputArgs(0)); // Min. 1 input args required. PsychErrorExit(PsychCapNumOutputArgs(1)); // Max. 1 output args. engineId = PsychPrefStateGet_VideoCaptureEngine(); PsychCopyInIntegerArg(1, FALSE, &engineId); // Do actual enumeration for the given engineId: PsychEnumerateVideoSources(engineId, 1); // Ready! return(PsychError_none); }
PsychError SCREENPreference(void) { PsychArgFormatType arg1Type; char *preferenceName, *newFontName; const char *tableCreator, *oldDefaultFontName; psych_bool preferenceNameArgumentValid, booleanInput, ignoreCase, tempFlag, textAlphaBlendingFlag, suppressAllWarningsFlag; int numInputArgs, i, newFontStyleNumber, newFontSize, tempInt, tempInt2, tempInt3, tempInt4; double returnDoubleValue, inputDoubleValue; double maxStddev, maxDeviation, maxDuration; int minSamples; double *dheads = NULL; //all sub functions should have these two lines PsychPushHelp(useString, synopsisString,seeAlsoString); if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);}; //check for superfluous or missing arguments PsychErrorExit(PsychCapNumInputArgs(5)); PsychErrorExit(PsychRequireNumInputArgs(1)); PsychErrorExit(PsychCapNumOutputArgs(4)); numInputArgs=PsychGetNumInputArgs(); arg1Type=PsychGetArgType(1); preferenceNameArgumentValid=FALSE; //Cases which require both a window pointer or screen number and preference name. Argument 1 is the wposn and argument 2 is the preference name. if( numInputArgs >= 2 && (PsychIsScreenNumberArg(1) || PsychIsScreenNumberArg(1)) && PsychGetArgType(2)==PsychArgType_char ){ PsychAllocInCharArg(2, kPsychArgRequired, &preferenceName); //preferences which require window pointer or screen number argument which we DO NOT support for(i=0;i<kPsychNumUnsupportedMacVideoPreferences;i++){ if(PsychMatch(preferenceName, unsupportedMacVideoPreferenceNames[i])) PsychErrorExit(PsychError_unsupportedOS9Preference); } //insert here conditionals to act on prefernces which accept a window pointer or screen number argument which we DO support. PsychErrorExit(PsychError_unrecognizedPreferenceName); } //Cases which do not require a wposn. Argument 1 is the preference name. if present Argument 2 is the new value if(arg1Type==PsychArgType_char){ PsychAllocInCharArg(1, kPsychArgRequired, &preferenceName); //Preferernces which we do not support and which do not require a wposn for(i=0;i<kPsychNumUnsupportedMacNonVideoPreferences;i++){ if(PsychMatch(preferenceName, unsupportedMacNonVideoPreferenceNames[i])) PsychErrorExit(PsychError_unsupportedOS9Preference); } //Preferences which we do support if(PsychMatch(preferenceName, "IgnoreCase")){ ignoreCase=!PsychIsPsychMatchCaseSensitive(); PsychCopyOutFlagArg(1, kPsychArgOptional, ignoreCase); if(numInputArgs==2){ PsychCopyInFlagArg(2, kPsychArgRequired, &booleanInput); PsychSetPsychMatchCaseSenstive(!booleanInput); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "Tick0Secs")){ if(PsychCopyInDoubleArg(2, kPsychArgOptional, &inputDoubleValue) && inputDoubleValue==PsychGetNanValue()) PsychEstimateGetSecsValueAtTickCountZero(); returnDoubleValue=PsychGetEstimatedSecsValueAtTickCountZero(); PsychCopyOutDoubleArg(1, kPsychArgOptional, returnDoubleValue); preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "PsychTableVersion")){ if(numInputArgs==2) PsychErrorExit(PsychError_extraInputArg); PsychCopyOutDoubleArg(1, kPsychArgOptional, (double)PsychPrefStateGet_PsychTableVersion()); preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "PsychTableCreator")){ if(numInputArgs==2) PsychErrorExit(PsychError_extraInputArg); tableCreator=PsychPrefStateGet_PsychTableCreator(); PsychCopyOutCharArg(1, kPsychArgOptional, tableCreator); preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "Process")){ if(numInputArgs==2) PsychErrorExit(PsychError_extraInputArg); PsychCopyOutDoubleArg(1, kPsychArgOptional, (double) (psych_int64) getpid()); preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "DefaultFontName")){ PsychPrefStateGet_DefaultFontName(&oldDefaultFontName); PsychCopyOutCharArg(1, kPsychArgOptional, oldDefaultFontName); if(numInputArgs==2){ PsychAllocInCharArg(2, kPsychArgRequired, &newFontName); PsychPrefStateSet_DefaultFontName(newFontName); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "TextEncodingLocale")){ PsychCopyOutCharArg(1, kPsychArgOptional, PsychGetUnicodeTextConversionLocale()); if(numInputArgs==2){ PsychAllocInCharArg(2, kPsychArgRequired, &newFontName); if (!PsychSetUnicodeTextConversionLocale(newFontName)) PsychErrorExitMsg(PsychError_user, "Setting the 'TextEncodingLocale' failed, most likely because you provided an invalid/unknown locale setting string."); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "DefaultFontStyle")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_DefaultTextStyle()); if(numInputArgs==2){ PsychCopyInIntegerArg(2, kPsychArgRequired, &newFontStyleNumber); PsychPrefStateSet_DefaultTextStyle(newFontStyleNumber); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "OverrideMultimediaEngine")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_UseGStreamer()); if(numInputArgs==2){ PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt); PsychPrefStateSet_UseGStreamer(tempInt); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "DefaultTextYPositionIsBaseline")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_TextYPositionIsBaseline()); if(numInputArgs==2){ PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt); PsychPrefStateSet_TextYPositionIsBaseline(tempInt); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "TextAntiAliasing")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_TextAntiAliasing()); if(numInputArgs==2){ PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt); PsychPrefStateSet_TextAntiAliasing(tempInt); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "TextRenderer")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_TextRenderer()); if(numInputArgs==2){ PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt); PsychPrefStateSet_TextRenderer(tempInt); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "DefaultFontSize")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_DefaultTextSize()); if(numInputArgs==2){ PsychCopyInIntegerArg(2, kPsychArgRequired, &newFontSize); PsychPrefStateSet_DefaultTextSize(newFontSize); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "DebugMakeTexture")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_DebugMakeTexture()); if(numInputArgs==2){ PsychCopyInFlagArg(2, kPsychArgRequired, &tempFlag); PsychPrefStateSet_DebugMakeTexture(tempFlag); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "SkipSyncTests")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_SkipSyncTests()); if(numInputArgs==2){ PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt); PsychPrefStateSet_SkipSyncTests(tempInt); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "VisualDebugLevel")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_VisualDebugLevel()); if(numInputArgs==2){ PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt); PsychPrefStateSet_VisualDebugLevel(tempInt); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "VBLTimestampingMode")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_VBLTimestampingMode()); if(numInputArgs>=2){ PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt); PsychPrefStateSet_VBLTimestampingMode(tempInt); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "SyncTestSettings")){ PsychPrefStateGet_SynctestThresholds(&maxStddev, &minSamples, &maxDeviation, &maxDuration); PsychCopyOutDoubleArg(1, kPsychArgOptional, maxStddev); PsychCopyOutDoubleArg(2, kPsychArgOptional, minSamples); PsychCopyOutDoubleArg(3, kPsychArgOptional, maxDeviation); PsychCopyOutDoubleArg(4, kPsychArgOptional, maxDuration); if(numInputArgs>=2){ PsychCopyInDoubleArg( 2, kPsychArgOptional, &maxStddev); PsychCopyInIntegerArg(3, kPsychArgOptional, &minSamples); PsychCopyInDoubleArg( 4, kPsychArgOptional, &maxDeviation); PsychCopyInDoubleArg( 5, kPsychArgOptional, &maxDuration); PsychPrefStateSet_SynctestThresholds(maxStddev, minSamples, maxDeviation, maxDuration); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "VBLEndlineOverride")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_VBLEndlineOverride()); if(numInputArgs>=2){ PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt); PsychPrefStateSet_VBLEndlineOverride(tempInt); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "DefaultVideocaptureEngine")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_VideoCaptureEngine()); if(numInputArgs==2){ PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt); PsychPrefStateSet_VideoCaptureEngine(tempInt); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "WindowShieldingLevel")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_WindowShieldingLevel()); if(numInputArgs==2){ PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt); PsychPrefStateSet_WindowShieldingLevel(tempInt); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "ConserveVRAM") || PsychMatch(preferenceName, "Workarounds1")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_ConserveVRAM()); if(numInputArgs==2){ PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt); PsychPrefStateSet_ConserveVRAM(tempInt); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "Verbosity")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_Verbosity()); if(numInputArgs==2){ PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt); PsychPrefStateSet_Verbosity(tempInt); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "FrameRectCorrection")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_FrameRectCorrection()); if(numInputArgs==2){ PsychCopyInDoubleArg(2, kPsychArgRequired, &inputDoubleValue); PsychPrefStateSet_FrameRectCorrection(inputDoubleValue); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "EmulateOldPTB")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_EmulateOldPTB()); if(numInputArgs==2){ PsychCopyInFlagArg(2, kPsychArgRequired, &tempFlag); PsychPrefStateSet_EmulateOldPTB(tempFlag); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "Enable3DGraphics")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_3DGfx()); if(numInputArgs==2){ PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt); PsychPrefStateSet_3DGfx(tempInt); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "TextAlphaBlending")){ textAlphaBlendingFlag=PsychPrefStateGet_TextAlphaBlending(); PsychCopyOutFlagArg(1, kPsychArgOptional, textAlphaBlendingFlag); if(numInputArgs==2){ PsychCopyInFlagArg(2, kPsychArgRequired, &booleanInput); PsychPrefStateSet_TextAlphaBlending(booleanInput); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "SuppressAllWarnings")){ suppressAllWarningsFlag=PsychPrefStateGet_SuppressAllWarnings(); PsychCopyOutFlagArg(1, kPsychArgOptional, suppressAllWarningsFlag); if(numInputArgs==2){ PsychCopyInFlagArg(2, kPsychArgRequired, &booleanInput); PsychPrefStateSet_SuppressAllWarnings(booleanInput); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "SynchronizeDisplays")){ if(numInputArgs >= 2) { // This is a special call: It currently doesn't set a preference setting, // but instead triggers an instantaneous synchronization of all available // display heads, if possible. We may have a more clever and "standard" interface // interface for this later on, but for first tests this will do. // Syncmethod is hard-coded to 0 -> Use whatever's available to sync. // timeout for retries is 5.0 seconds. // Acceptable residual offset is +/- 2 scanlines. // Returns the real residual offset after sync. PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt); if (!PsychCopyInIntegerArg(3, kPsychArgOptional, &tempInt3)) { // No screenId specified: Resync default screen or whatever... tempInt2 = 0; if (PsychSynchronizeDisplayScreens(&tempInt2, NULL, &tempInt, tempInt, 5.0, 2)!=PsychError_none) PsychErrorExitMsg(PsychError_user, "Sync failed for reasons mentioned above."); } else { // Specific screenId provided: Resync crtc's associated with this screenId if possible: tempInt2 = 1; if (PsychSynchronizeDisplayScreens(&tempInt2, &tempInt3, &tempInt, tempInt, 5.0, 2)!=PsychError_none) PsychErrorExitMsg(PsychError_user, "Sync failed for reasons mentioned above."); } PsychCopyOutDoubleArg(1, kPsychArgOptional, tempInt); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "ScreenToHead")){ // screenId is required: PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt); if (tempInt < 0 || tempInt >= PsychGetNumDisplays() || tempInt >= kPsychMaxPossibleDisplays) PsychErrorExitMsg(PsychError_user, "Invalid screenId provided. Out of valid range!"); // Return old mappings for this screenId: for (tempInt2 = 0; (tempInt2 < kPsychMaxPossibleCrtcs) && (PsychPrefStateGet_ScreenToHead(tempInt, tempInt2) >= 0); tempInt2++); PsychAllocOutDoubleMatArg(1, kPsychArgOptional, 2, tempInt2, 1, &dheads); tempInt4 = 0; for (tempInt3 = 0; tempInt3 < tempInt2; tempInt3++) { dheads[tempInt4++] = (double) PsychPrefStateGet_ScreenToHead(tempInt, tempInt3); dheads[tempInt4++] = (double) PsychPrefStateGet_ScreenToCrtcId(tempInt, tempInt3); } // Optionally retrieve and set new mappings for this screenId: if(numInputArgs>=3) { // Set new headId for screenId: PsychCopyInIntegerArg(3, kPsychArgRequired, &tempInt2); if (tempInt2 < 0) PsychErrorExitMsg(PsychError_user, "Invalid negative headId provided!"); // Set new crtcId for screenId: PsychCopyInIntegerArg(4, kPsychArgRequired, &tempInt3); if (tempInt3 < 0) PsychErrorExitMsg(PsychError_user, "Invalid negative crtcId provided!"); // Assign primary head by default (index 0), but allow optionally others as well: tempInt4 = 0; PsychCopyInIntegerArg(5, kPsychArgOptional, &tempInt4); if (tempInt4 < 0 || tempInt4 >= kPsychMaxPossibleCrtcs) PsychErrorExitMsg(PsychError_user, "Invalid rankId provided! Too many heads for one screen!"); PsychPrefStateSet_ScreenToHead(tempInt, tempInt2, tempInt3, tempInt4); } preferenceNameArgumentValid=TRUE; }else PsychErrorExit(PsychError_unrecognizedPreferenceName); } if(!preferenceNameArgumentValid) PsychErrorExitMsg(PsychError_user, "Invalid arguments to preferences command"); return(PsychError_none); }
PsychError SCREENOpenVideoCapture(void) { PsychWindowRecordType *windowRecord; int deviceIndex; int capturehandle = -1; double framerate; int width; int height; PsychRectType roirectangle; Boolean roiassigned; int reqdepth = 0; int num_dmabuffers = 0; int allow_lowperf_fallback = 1; char* moviename; int recordingflags; int engineId; // All sub functions should have these two lines PsychPushHelp(useString, synopsisString, seeAlsoString); if(PsychIsGiveHelp()) {PsychGiveHelp(); return(PsychError_none);}; PsychErrorExit(PsychCapNumInputArgs(9)); // Max. 9 input args. PsychErrorExit(PsychRequireNumInputArgs(1)); // Min. 1 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, "OpenVideoCapture called on something else than an onscreen window."); } // Get the device index. We default to the first device if none is given: deviceIndex=0; PsychCopyInIntegerArg(2, FALSE, &deviceIndex); // Get the optional roi rectangle: roiassigned = PsychCopyInRectArg(3, FALSE, roirectangle); if (IsPsychRectEmpty(roirectangle)) PsychErrorExitMsg(PsychError_user, "OpenVideoCapture called with invalid (empty) roirectangle argument."); // Query (optional) output texture pixel depth: By default, we take whatever we get from the capture device: PsychCopyInIntegerArg(4, FALSE, &reqdepth); if (reqdepth<0) PsychErrorExitMsg(PsychError_user, "OpenVideoCapture called with invalid (negative) pixeldepth argument."); // Query number of ringbuffers to use. Our default is coded in the OS dependent subroutines. PsychCopyInIntegerArg(5, FALSE, &num_dmabuffers); if (num_dmabuffers<0) PsychErrorExitMsg(PsychError_user, "OpenVideoCapture called with invalid (negative) numbuffers argument."); // Query, if use of low-performance fallback code is allowed if high-perf engine fails: PsychCopyInIntegerArg(6, FALSE, &allow_lowperf_fallback); if (allow_lowperf_fallback<0) PsychErrorExitMsg(PsychError_user, "OpenVideoCapture called with invalid (negative) allowfallback flag."); // Query optional moviename for recording the grabbed video into a Quicktime movie file: moviename = NULL; PsychAllocInCharArg(7, FALSE, &moviename); // Query optional movie recording flags: // 0 = Record video, stream to disk immediately (slower, but unlimited recording duration). // 1 = Record video, stream to memory, then at end of recording to disk (limited duration by RAM size, but faster). // 2 = Record audio as well. recordingflags = 0; PsychCopyInIntegerArg(8, FALSE, &recordingflags); // Copy in optional id of video capture engine to use. We default to the one set via the Screen('Preference', 'DefaultVideocaptureEngine'); // setting, which by itself defaults to LibDC1394 (type 1) on Linux, and Quicktime/SG (type 0) on all other OSs. engineId = PsychPrefStateGet_VideoCaptureEngine(); PsychCopyInIntegerArg(9, FALSE, &engineId); if (engineId<0 || engineId>1) PsychErrorExitMsg(PsychError_user, "OpenVideoCapture called with invalid 'captureEngineType' argument. Valid are zero and one."); // Try to open the capture device and create & initialize a corresponding capture object. // A MATLAB handle to the video capture object is returned upon successfull operation. if (roiassigned) { PsychOpenVideoCaptureDevice(engineId, windowRecord, deviceIndex, &capturehandle, roirectangle, reqdepth, num_dmabuffers, allow_lowperf_fallback, moviename, recordingflags); } else { PsychOpenVideoCaptureDevice(engineId, windowRecord, deviceIndex, &capturehandle, NULL, reqdepth, num_dmabuffers, allow_lowperf_fallback, moviename, recordingflags); } // Upon sucessfull completion, we'll have a valid handle in 'capturehandle'. Return it to Matlab-world: PsychCopyOutDoubleArg(1, TRUE, (double) capturehandle); // Ready! return(PsychError_none); }
PsychError SCREENPreference(void) { PsychArgFormatType arg1Type; char *preferenceName, *newFontName; const char *tableCreator, *oldDefaultFontName; Boolean preferenceNameArgumentValid, booleanInput, ignoreCase, tempFlag, textAlphaBlendingFlag, suppressAllWarningsFlag; int numInputArgs, i, newFontStyleNumber, newFontSize, tempInt, tempInt2, tempInt3; double returnDoubleValue, inputDoubleValue; //all sub functions should have these two lines PsychPushHelp(useString, synopsisString,seeAlsoString); if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);}; //check for superfluous or missing arguments PsychErrorExit(PsychCapNumInputArgs(3)); PsychErrorExit(PsychRequireNumInputArgs(1)); PsychErrorExit(PsychCapNumOutputArgs(1)); numInputArgs=PsychGetNumInputArgs(); arg1Type=PsychGetArgType(1); preferenceNameArgumentValid=FALSE; //Cases which require both a window pointer or screen number and preference name. Argument 1 is the wposn and argument 2 is the preference name. if( numInputArgs >= 2 && (PsychIsScreenNumberArg(1) || PsychIsScreenNumberArg(1)) && PsychGetArgType(2)==PsychArgType_char ){ PsychAllocInCharArg(2, kPsychArgRequired, &preferenceName); //preferences which require window pointer or screen number argument which we DO NOT support for(i=0;i<kPsychNumUnsupportedMacVideoPreferences;i++){ if(PsychMatch(preferenceName, unsupportedMacVideoPreferenceNames[i])) PsychErrorExit(PsychError_unsupportedOS9Preference); } //insert here conditionals to act on prefernces which accept a window pointer or screen number argument which we DO support. PsychErrorExit(PsychError_unrecognizedPreferenceName); } //Cases which do not require a wposn. Argument 1 is the preference name. if present Argument 2 is the new value if(arg1Type==PsychArgType_char){ PsychAllocInCharArg(1, kPsychArgRequired, &preferenceName); //Preferernces which we do not support and which do not require a wposn for(i=0;i<kPsychNumUnsupportedMacNonVideoPreferences;i++){ if(PsychMatch(preferenceName, unsupportedMacNonVideoPreferenceNames[i])) PsychErrorExit(PsychError_unsupportedOS9Preference); } //Preferences which we do support if(PsychMatch(preferenceName, "IgnoreCase")){ ignoreCase=!PsychIsPsychMatchCaseSensitive(); PsychCopyOutFlagArg(1, kPsychArgOptional, ignoreCase); if(numInputArgs==2){ PsychCopyInFlagArg(2, kPsychArgRequired, &booleanInput); PsychSetPsychMatchCaseSenstive(!booleanInput); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "Tick0Secs")){ if(PsychCopyInDoubleArg(2, kPsychArgOptional, &inputDoubleValue) && inputDoubleValue==PsychGetNanValue()) PsychEstimateGetSecsValueAtTickCountZero(); returnDoubleValue=PsychGetEstimatedSecsValueAtTickCountZero(); PsychCopyOutDoubleArg(1, kPsychArgOptional, returnDoubleValue); preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "PsychTableVersion")){ if(numInputArgs==2) PsychErrorExit(PsychError_extraInputArg); PsychCopyOutDoubleArg(1, kPsychArgOptional, (double)PsychPrefStateGet_PsychTableVersion()); preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "PsychTableCreator")){ if(numInputArgs==2) PsychErrorExit(PsychError_extraInputArg); tableCreator=PsychPrefStateGet_PsychTableCreator(); PsychCopyOutCharArg(1, kPsychArgOptional, tableCreator); preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "Process")){ if(numInputArgs==2) PsychErrorExit(PsychError_extraInputArg); PsychCopyOutDoubleArg(1, kPsychArgOptional, (double)getpid()); preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "DefaultFontName")){ PsychPrefStateGet_DefaultFontName(&oldDefaultFontName); PsychCopyOutCharArg(1, kPsychArgOptional, oldDefaultFontName); if(numInputArgs==2){ PsychAllocInCharArg(2, kPsychArgRequired, &newFontName); PsychPrefStateSet_DefaultFontName(newFontName); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "DefaultFontStyle")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_DefaultTextStyle()); if(numInputArgs==2){ PsychCopyInIntegerArg(2, kPsychArgRequired, &newFontStyleNumber); PsychPrefStateSet_DefaultTextStyle(newFontStyleNumber); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "DefaultTextYPositionIsBaseline")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_TextYPositionIsBaseline()); if(numInputArgs==2){ PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt); PsychPrefStateSet_TextYPositionIsBaseline(tempInt); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "TextAntiAliasing")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_TextAntiAliasing()); if(numInputArgs==2){ PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt); PsychPrefStateSet_TextAntiAliasing(tempInt); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "TextRenderer")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_TextRenderer()); if(numInputArgs==2){ PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt); PsychPrefStateSet_TextRenderer(tempInt); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "DefaultFontSize")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_DefaultTextSize()); if(numInputArgs==2){ PsychCopyInIntegerArg(2, kPsychArgRequired, &newFontSize); PsychPrefStateSet_DefaultTextSize(newFontSize); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "DebugMakeTexture")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_DebugMakeTexture()); if(numInputArgs==2){ PsychCopyInFlagArg(2, kPsychArgRequired, &tempFlag); PsychPrefStateSet_DebugMakeTexture(tempFlag); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "SkipSyncTests")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_SkipSyncTests()); if(numInputArgs==2){ PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt); PsychPrefStateSet_SkipSyncTests(tempInt); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "VisualDebugLevel")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_VisualDebugLevel()); if(numInputArgs==2){ PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt); PsychPrefStateSet_VisualDebugLevel(tempInt); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "VBLTimestampingMode")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_VBLTimestampingMode()); if(numInputArgs>=2){ PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt); PsychPrefStateSet_VBLTimestampingMode(tempInt); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "VBLEndlineOverride")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_VBLEndlineOverride()); if(numInputArgs>=2){ PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt); PsychPrefStateSet_VBLEndlineOverride(tempInt); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "DefaultVideocaptureEngine")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_VideoCaptureEngine()); if(numInputArgs==2){ PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt); PsychPrefStateSet_VideoCaptureEngine(tempInt); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "ConserveVRAM") || PsychMatch(preferenceName, "Workarounds1")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_ConserveVRAM()); if(numInputArgs==2){ PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt); PsychPrefStateSet_ConserveVRAM(tempInt); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "Verbosity")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_Verbosity()); if(numInputArgs==2){ PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt); PsychPrefStateSet_Verbosity(tempInt); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "EmulateOldPTB")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_EmulateOldPTB()); if(numInputArgs==2){ PsychCopyInFlagArg(2, kPsychArgRequired, &tempFlag); PsychPrefStateSet_EmulateOldPTB(tempFlag); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "Enable3DGraphics")){ PsychCopyOutDoubleArg(1, kPsychArgOptional, PsychPrefStateGet_3DGfx()); if(numInputArgs==2){ PsychCopyInFlagArg(2, kPsychArgRequired, &tempFlag); PsychPrefStateSet_3DGfx(tempFlag); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "TextAlphaBlending")){ textAlphaBlendingFlag=PsychPrefStateGet_TextAlphaBlending(); PsychCopyOutFlagArg(1, kPsychArgOptional, textAlphaBlendingFlag); if(numInputArgs==2){ PsychCopyInFlagArg(2, kPsychArgRequired, &booleanInput); PsychPrefStateSet_TextAlphaBlending(booleanInput); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "SuppressAllWarnings")){ suppressAllWarningsFlag=PsychPrefStateGet_SuppressAllWarnings(); PsychCopyOutFlagArg(1, kPsychArgOptional, suppressAllWarningsFlag); if(numInputArgs==2){ PsychCopyInFlagArg(2, kPsychArgRequired, &booleanInput); PsychPrefStateSet_SuppressAllWarnings(booleanInput); } preferenceNameArgumentValid=TRUE; }else if(PsychMatch(preferenceName, "SynchronizeDisplays")){ if(numInputArgs==2){ // This is a special call: It currently doesn't set a preference setting, // but instead triggers an instantaneous synchronization of all available // display heads, if possible. We may have a more clever and "standard" interface // interface for this later on, but for first tests this will do. // Syncmethod is hard-coded to 0 -> Use whatever's available to sync. // timeout for retries is 5.0 seconds. // Acceptable residual offset is +/- 2 scanlines. // Returns the real residual offset after sync. PsychCopyInIntegerArg(2, kPsychArgRequired, &tempInt); tempInt2 = 0; if (PsychSynchronizeDisplayScreens(&tempInt2, NULL, &tempInt, tempInt, 5.0, 2)!=PsychError_none) PsychErrorExitMsg(PsychError_user, "Sync failed for reasons mentioned above."); PsychCopyOutDoubleArg(1, kPsychArgOptional, tempInt); } preferenceNameArgumentValid=TRUE; }else PsychErrorExit(PsychError_unrecognizedPreferenceName); } if(!preferenceNameArgumentValid) PsychErrorExitMsg(PsychError_user, "Invalid arguments to preferences command"); return(PsychError_none); }
PsychError SCREENOpenVideoCapture(void) { PsychWindowRecordType *windowRecord; int deviceIndex; int capturehandle = -1; double framerate; int width; int height; PsychRectType roirectangle; psych_bool roiassigned; int reqdepth = 0; int num_dmabuffers = 0; int allow_lowperf_fallback = 1; char* moviename; int recordingflags; int engineId; // All sub functions should have these two lines PsychPushHelp(useString, synopsisString, seeAlsoString); if(PsychIsGiveHelp()) {PsychGiveHelp(); return(PsychError_none);}; PsychErrorExit(PsychCapNumInputArgs(9)); // Max. 9 input args. PsychErrorExit(PsychRequireNumInputArgs(1)); // Min. 1 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, "OpenVideoCapture called on something else than an onscreen window."); } // Get the device index. We default to the first device if none is given: deviceIndex=0; PsychCopyInIntegerArg(2, FALSE, &deviceIndex); // Get the optional roi rectangle: roiassigned = PsychCopyInRectArg(3, FALSE, roirectangle); if (roiassigned && IsPsychRectEmpty(roirectangle)) PsychErrorExitMsg(PsychError_user, "OpenVideoCapture called with invalid (empty) roirectangle argument."); // Query (optional) output texture pixel depth: By default, we take whatever we get from the capture device: PsychCopyInIntegerArg(4, FALSE, &reqdepth); if (reqdepth<0) PsychErrorExitMsg(PsychError_user, "OpenVideoCapture called with invalid (negative) pixeldepth argument."); // Query number of ringbuffers to use. Our default is coded in the OS dependent subroutines. PsychCopyInIntegerArg(5, FALSE, &num_dmabuffers); if (num_dmabuffers<0) PsychErrorExitMsg(PsychError_user, "OpenVideoCapture called with invalid (negative) numbuffers argument."); // Query, if use of low-performance fallback code is allowed if high-perf engine fails: PsychCopyInIntegerArg(6, FALSE, &allow_lowperf_fallback); if (allow_lowperf_fallback<0) PsychErrorExitMsg(PsychError_user, "OpenVideoCapture called with invalid (negative) allowfallback flag."); // Query optional moviename for recording the grabbed video into a Quicktime movie file: moviename = NULL; PsychAllocInCharArg(7, FALSE, &moviename); // Query optional movie recording flags: // 0 = Record video, stream to disk immediately (slower, but unlimited recording duration). // 1 = Record video, stream to memory, then at end of recording to disk (limited duration by RAM size, but faster). // 2 = Record audio as well. // 4 = Do not return capture data via Screen('GetCapturedImage') during video recording to disc. // 8 = Avoid some performance optimizations which may cause trouble with some codecs. // 16= Use multi-threading for automatic background processing and cpu offloading. // 32= Return high quality textures via 'GetCapturedImage' if recording in parallel --> Quality tradeoff live feed vs. recording. // 64= Return timestamps in engine time instead of GetSecs() time. recordingflags = 0; PsychCopyInIntegerArg(8, FALSE, &recordingflags); // Copy in optional id of video capture engine to use. We default to the one set via the Screen('Preference', 'DefaultVideocaptureEngine'); // setting, which by itself defaults to LibDC1394 (type 1) on Linux, ARVideo (type 2) and Quicktime/SG (type 0) on OS/X for now. engineId = PsychPrefStateGet_VideoCaptureEngine(); PsychCopyInIntegerArg(9, FALSE, &engineId); if (engineId < 0 || engineId > 3) PsychErrorExitMsg(PsychError_user, "OpenVideoCapture called with invalid 'captureEngineType'. Valid are 0,1,2,3."); if (engineId == 2) { printf("\n\n"); printf("PTB-INFO: Your script explicitely requests use of video capture engine type 2 - the ARVideo video capture engine.\n"); printf("PTB-INFO: This engine has been permanently disabled and removed from Psychtoolbox since beginning of the year 2011.\n"); printf("PTB-INFO: We recommend use of the GStreamer video capture engine (engine type 3) as a technically superior replacement\n"); printf("PTB-INFO: on GNU-Linux and MS-Windows. For Mac OS/X for now we recommend use of the Quicktime engine (engine type 0)\n"); printf("PTB-INFO: as an interims solution. The Quicktime engine will be eventually replaced on OS/X by the GStreamer engine as well.\n"); printf("PTB-INFO: In most cases, the selected replacement should work without need for any further changes to your code.\n\n"); } // Try to open the capture device and create & initialize a corresponding capture object. // A MATLAB handle to the video capture object is returned upon successfull operation. if (roiassigned) { PsychOpenVideoCaptureDevice(engineId, windowRecord, deviceIndex, &capturehandle, roirectangle, reqdepth, num_dmabuffers, allow_lowperf_fallback, moviename, recordingflags); } else { PsychOpenVideoCaptureDevice(engineId, windowRecord, deviceIndex, &capturehandle, NULL, reqdepth, num_dmabuffers, allow_lowperf_fallback, moviename, recordingflags); } // Upon sucessfull completion, we'll have a valid handle in 'capturehandle'. Return it to Matlab-world: PsychCopyOutDoubleArg(1, TRUE, (double) capturehandle); // Ready! return(PsychError_none); }