bool ofxVideoRecorder::addFrame(const ofPixels &pixels) { if (!bIsRecording || bIsPaused) return false; if(bIsInitialized && bRecordVideo) { int framesToAdd = 1; //default add one frame per request if((bRecordAudio || bSysClockSync) && !bFinishing){ double syncDelta; double videoRecordedTime = videoFramesRecorded / frameRate; if (bRecordAudio) { //if also recording audio, check the overall recorded time for audio and video to make sure audio is not going out of sync //this also handles incoming dynamic framerate while maintaining desired outgoing framerate double audioRecordedTime = (audioSamplesRecorded/audioChannels) / (double)sampleRate; syncDelta = audioRecordedTime - videoRecordedTime; } else { //if just recording video, synchronize the video against the system clock //this also handles incoming dynamic framerate while maintaining desired outgoing framerate syncDelta = systemClock() - videoRecordedTime; } if(syncDelta > 1.0/frameRate) { //no enought video frames, we need to send extra video frames. int numFramesCopied = 0; while(syncDelta > 1.0/frameRate) { framesToAdd++; syncDelta -= 1.0/frameRate; } ofLogVerbose() << "ofxVideoRecorder: recDelta = " << syncDelta << ". Not enough video frames for desired frame rate, copied this frame " << framesToAdd << " times.\n"; } else if(syncDelta < -1.0/frameRate){ //more than one video frame is waiting, skip this frame framesToAdd = 0; ofLogVerbose() << "ofxVideoRecorder: recDelta = " << syncDelta << ". Too many video frames, skipping.\n"; } } for(int i=0;i<framesToAdd;i++){ //add desired number of frames frames.Produce(new ofPixels(pixels)); videoFramesRecorded++; } videoThread.signal(); return true; } return false; }
unsigned long TimingData::getClock() { #if TIMING_UNIX struct timeval tv; gettimeofday(&tv, 0); return tv.tv_sec * 1000 + tv.tv_usec/1000; #else return systemClock(); #endif }