void benchmarkCloning(QFont &font) { int N = 1000000, fact = 1; int i; extern void doSomethingWithQFont(QFont&); double overhead; do { N *= fact; HRTime_tic(); QFont tmp(font); for (i = 0 ; i < N ; ++i) { doSomethingWithQFont(tmp); } overhead = HRTime_toc(); qInfo() << "overhead=" << overhead; fact = 2; } while (overhead < 0.05); QFontDatabase db; HRTime_tic(); for (i = 0 ; i < N ; ++i) { QFont tmp(stripStyleName(font, db)); doSomethingWithQFont(tmp); } double elapsed = HRTime_toc(); qWarning() << N << "times `QFont tmp=stripStyleName(font)`:" << elapsed - overhead << "seconds"; HRTime_tic(); for (i = 0 ; i < N ; ++i) { QFont tmp(clone(font)); doSomethingWithQFont(tmp); } elapsed = HRTime_toc(); qWarning() << N << "times `QFont tmp(font)`:" << elapsed - overhead << "seconds"; }
template <typename Fn> inline double bench () { #define ADAPT #define MIN_DURATION 2 #define ADAPT_FACTOR 2 Fn fn; double duration; #ifdef USE_REALTIMER init_HRTime(); #else clock_t start, finish; #endif for (unsigned int i = 0; i != prime_caches; ++i) fn (); tried= tries; #ifdef ADAPT do #endif { #ifdef USE_REALTIMER HRTime_tic(); #else start = clock (); #endif for (unsigned int j = 0; j != tried; ++j) fn (); #ifdef USE_REALTIMER duration = HRTime_toc(); #else finish = clock (); duration= (finish - start) / ((double) CLOCKS_PER_SEC); #endif #ifdef ADAPT if( duration< MIN_DURATION ){ /* fprintf( stderr, "dt=%g: %d -> %d\n", duration, tried, tried*ADAPT_FACTOR ); */ tried*= ADAPT_FACTOR; } #endif } #ifdef ADAPT while( duration< MIN_DURATION ); #endif return duration; }
int main( int argc, char *argv[] ) { int i; HANDLE bgThread; DWORD exitCode; SECURITY_ATTRIBUTES semSec; MSEmul_UseSharedMemory(true); #if 1 { char test[256], *head; test[0] = '\0'; head = test; fprintf( stderr, "appending to test[%lu] with snprintf:\n", sizeof(test) ); do{ int len = strlen(test), n; size_t ni = strlen("0123456789"); fprintf( stderr, "len(test[%lu])=%d, rem. %lu added", sizeof(test), len, (size_t)(sizeof(test) - len) ); fflush(stderr); n = snprintf( &test[len], (size_t)(sizeof(test) - len), "0123456789" ); head += n; fprintf( stderr, " %d (head[%lu]=", n, head - test ); fflush(stderr); if( len + n < sizeof(test) ){ fprintf( stderr, "%c) -> %lu\n", head[0], strlen(test) ); } else{ fprintf( stderr, "!$@#) -> %lu\n", strlen(test) ); } } while( strlen(test) < sizeof(test)-1 ); fprintf( stderr, "test = %s\n", test ); } #endif init_HRTime(); tStart = HRTime_Time(); HRTime_tic(); { double t0; DWORD ret; HANDLE hh; if( (hh = CreateSemaphore( NULL, 1, 0x7FFFFFFF, NULL )) ){ t0 = HRTime_Time(); ret = WaitForSingleObject(hh, (DWORD)(SLEEPTIMEFG*1000)); t0 = HRTime_Time() - t0; fprintf( stderr, "WaitForSingleObject(hh,%lu)==%lu took %g seconds\n", (DWORD)(SLEEPTIMEFG*1000), ret, t0 ); t0 = HRTime_Time(); ret = WaitForSingleObject(hh, (DWORD)(SLEEPTIMEFG*1000)); t0 = HRTime_Time() - t0; fprintf( stderr, "WaitForSingleObject(hh,%lu)==%lu took %g seconds\n", (DWORD)(SLEEPTIMEFG*1000), ret, t0 ); t0 = HRTime_Time(); ret = WaitForSingleObject(hh, 500); t0 = HRTime_Time() - t0; fprintf( stderr, "WaitForSingleObject(hh,500)==%lu took %g seconds\n", ret, t0 ); ReleaseSemaphore(hh, 1, NULL); t0 = HRTime_Time(); ret = WaitForSingleObject(hh, 500); t0 = HRTime_Time() - t0; fprintf( stderr, "WaitForSingleObject(hh,500)==%lu took %g seconds after ReleaseSemaphore()\n", ret, t0 ); CloseHandle(hh); } else{ fprintf( stderr, "Error creating semaphore: %s\n", winError(GetLastError()) ); } ret = 0; YieldProcessor(); fprintf( stderr, "sizeof(long)=%lu\n", sizeof(long) ); _WriteBarrier(); { long oval, lbool; void *ptr = NULL, *optr; oval = _InterlockedCompareExchange( (long*) &ret, 10L, 0L ); fprintf( stderr, "_InterlockedCompareExchange(&ret==0, 10, 0) == %lu, ret==%lu\n", oval, ret ); optr = InterlockedCompareExchangePointer( &ptr, (void*) fprintf, NULL ); fprintf( stderr, "InterlockedCompareExchangePointer(&ptr==NULL, fprintf==%p, NULL) == %p, ret==%p\n", fprintf, optr, ptr ); _InterlockedIncrement( (long*) &ret ); fprintf( stderr, "_InterlockedIncrement(&ret) ret=%lu\n", ret ); _InterlockedDecrement( (long*) &ret ); fprintf( stderr, "_InterlockedDecrement(&ret) ret=%lu\n", ret ); _ReadWriteBarrier(); lbool = false; _InterlockedSetTrue(&lbool); fprintf( stderr, "lbool = %ld\n", lbool ); _InterlockedSetTrue(&lbool); fprintf( stderr, "lbool = %ld\n", lbool ); _InterlockedSetFalse(&lbool); fprintf( stderr, "lbool = %ld\n", lbool ); } } #ifdef DEBUG { CSEScopedLock *scope = ObtainCSEScopedLock(NULL); fprintf( stderr, "NULL testscope %p:locked==%u\n", scope, IsCSEScopeLocked(scope) ); scope = ReleaseCSEScopedLock(scope); } #endif csex = CreateCSEHandle(4000); if( !csex ){ fprintf( stderr, "Failure creating CSEHandle\n" ); exit(1); } else{ fprintf( stderr, "Created a '%s' CSEHandle with spinMax==%lu\n", CSEHandleInfo(csex), csex->spinMax ); } fprintf( stderr, "GetCurrentThread() = 0x%p\n", GetCurrentThread() ); Sleep(5); fprintf( stderr, "GetCurrentThread() = 0x%p\n", GetCurrentThread() ); Sleep(5); fprintf( stderr, "GetCurrentThread() = 0x%p\n", GetCurrentThread() ); Sleep(5); fputs( "\n", stderr ); if( (bgThread = CreateThread( NULL, 0, bgThreadSleeper, NULL, CREATE_SUSPENDED, NULL )) ){ unsigned long ret; double tEnd; fprintf( stderr, ">%lx t=%g will start %lx and WaitForSingleObject on it (should take 5s)\n", GetCurrentThreadId(), HRTime_Time() - tStart, GetThreadId(bgThread) ); ResumeThread(bgThread); // Sleep(1); ret = WaitForSingleObject( bgThread, 1500 ); tEnd = HRTime_Time(); GetExitCodeThread( bgThread, &exitCode ); fprintf( stderr, ">%lx WaitForSingleObject(bgThread,1500)=%lu exitCode=%ld at t=%g\n", GetCurrentThreadId(), ret, exitCode, tEnd - tStart ); ret = WaitForSingleObject( bgThread, 10000 ); tEnd = HRTime_Time(); GetExitCodeThread( bgThread, &exitCode ); fprintf( stderr, ">%lx WaitForSingleObject(bgThread,10000)=%lu exitCode=%ld at t=%g\n", GetCurrentThreadId(), ret, exitCode, tEnd - tStart ); CloseHandle(bgThread); } fputs( "\n", stderr ); if( (nudgeEvent = CreateEvent( NULL, false, false, NULL )) ){ if( (bgThread = CreateThread( NULL, 0, bgThread2Nudge, NULL, 0, NULL )) ){ unsigned long ret; double tEnd; Sleep(1000); fprintf( stderr, ">%lx t=%g SetEvent(nudgeEvent) = %d; sleep(1ms) and then wait for return nudge\n", GetCurrentThreadId(), HRTime_Time() - tStart, SetEvent(nudgeEvent) ); Sleep(1); ret = WaitForSingleObject( nudgeEvent, INFINITE ); tEnd = HRTime_Time(); fprintf( stderr, ">%lx WaitForSingleObject( nudgeEvent, INFINITE ) = %lu at t=%g\n", GetCurrentThreadId(), ret, tEnd - tStart ); ret = WaitForSingleObject( bgThread, 5000 ); tEnd = HRTime_Time(); GetExitCodeThread( bgThread, &exitCode ); fprintf( stderr, ">%lx WaitForSingleObject(bgThread,5000)=%lu exitCode=%ld at t=%g\n", GetCurrentThreadId(), ret, exitCode, tEnd - tStart ); CloseHandle(bgThread); } CloseHandle(nudgeEvent); } fputs( "\n", stderr ); semSec.nLength = sizeof(SECURITY_ATTRIBUTES); semSec.lpSecurityDescriptor = NULL; semSec.bInheritHandle = true; // semSec does not actually need to be used: if( (nudgeEvent = CreateSemaphore( &semSec, 0, 0x7FFFFFFF, (char*) "cseSem" )) ){ if( (bgThread = CreateThread( NULL, 0, bgThread4SemTest, NULL, 0, NULL )) ){ unsigned long ret; double tEnd; Sleep(1000); fprintf( stderr, ">%lx t=%g ReleaseSemaphore(nudgeEvent,1,NULL) = %d; sleep(1ms) and then wait for return nudge\n", GetCurrentThreadId(), HRTime_Time() - tStart, ReleaseSemaphore(nudgeEvent, 1, NULL) ); Sleep(1); ret = WaitForSingleObject( nudgeEvent, INFINITE ); tEnd = HRTime_Time(); fprintf( stderr, ">%lx WaitForSingleObject( nudgeEvent, INFINITE ) = %lu at t=%g\n", GetCurrentThreadId(), ret, tEnd - tStart ); ret = WaitForSingleObject( bgThread, 5000 ); tEnd = HRTime_Time(); GetExitCodeThread( bgThread, &exitCode ); fprintf( stderr, ">%lx WaitForSingleObject(bgThread,5000)=%lu exitCode=%ld at t=%g\n", GetCurrentThreadId(), ret, exitCode, tEnd - tStart ); CloseHandle(bgThread); } CloseHandle(nudgeEvent); } fputs( "\n", stderr ); if( (bgThread = CreateThread( NULL, 0, bgCSEXaccess, NULL, CREATE_SUSPENDED, NULL )) ){ fprintf( stderr, "csex is %slocked\n", (IsCSEHandleLocked(csex))? "" : "not " ); SetThreadPriority( bgThread, GetThreadPriority(GetCurrentThread()) ); fprintf( stderr, "GetThreadPriority(GetCurrentThread()) = %d\n", GetThreadPriority(GetCurrentThread()) ); ResumeThread(bgThread); i = 0; fprintf( stderr, "entering main csex locking loop at t=%gs\n", HRTime_toc() ); while( i < 5 ){ double t0, t1; if( IsCSEHandleLocked(csex) ){ fprintf( stderr, "\tmain loop waiting for csex lock\n" ); } t0 = HRTime_toc(); { #ifdef LOCKSCOPEFG CSEScopedLock *scope = ObtainCSEScopedLock(csex); #else unsigned char unlock = LockCSEHandle(csex); #endif t1 = HRTime_toc(); i += 1; fprintf( stderr, "> got csex lock #%d=%d at t=%g after %gs; starting %g s wait\n", i, IsCSEHandleLocked(csex), t1, t1-t0, SLEEPTIMEFG ); fflush(stderr); #ifdef BUSYSLEEPING MMSleep(SLEEPTIMEFG); #else do{ t1 = HRTime_toc(); } while (t1-t0 < SLEEPTIMEFG); #endif fprintf( stderr, "\tmain loop wait #%d ended at t=%gs; csex lock=%d\n", i, HRTime_toc(), IsCSEHandleLocked(csex) ); fflush(stderr); #ifndef LOCKSCOPEFG UnlockCSEHandle( csex, unlock ); #else scope = ReleaseCSEScopedLock(scope); #endif } // just to give the other thread a chance to get a lock: Sleep(1); } fprintf( stderr, "exiting main csex locking loop at t=%gs\n", HRTime_toc() ); _InterlockedSetFalse(&bgRun); WaitForSingleObject( bgThread, 5000 ); CloseHandle(bgThread); fprintf( stderr, "Background loop finished at t=%gs\n", HRTime_toc() ); } else{ fprintf( stderr, "Failure creating bgCSEXaccess thread\n" ); } DeleteCSEHandle(csex); ASSERT(1); ASSERT(0); exit(0); }
unsigned long Read_VOD( char *theURL ) { unsigned long N = 0; VODFiles *fp; FOFFSET jpgOffset, prev_Offset=0, prev_fpos, audioOffset; uint32_t VOBid; VOB_JPEG_Headers jH, prev_jH; VOB_Audio_Headers aH; int current_vmgi; int ok, nextFound; VMGIs vmgi; double tskipped = 0, audioDuration = 0; struct readtables { int current_vmgi; FOFFSET current_vmgiPos; int VOB_Ns, vmgiAudioChunks, vmgiVideoFrames; int frames; int doubles; } *readtable, *rt; unsigned int readtableN = 0; char *mode = "rb"; double frameRate; FILE *dumpFP = NULL; int pcloseDumpFP = 0, gotPipeSignal; size_t jpgFrameCount = 0, mp4FragCount = 0; char dirTemp[128] = "VODconverting-XXXXXX", *bURL = NULL; MPG4_Fragments mp4Frag; struct { VOB_Dates StartDate; VOB_Times StartTime; int isSet; #if defined(_MSC_VER) || defined(__MINGW32__) struct _utimbuf ut; #else struct timeval t[2]; #endif } StartTimeStamp; #if defined(_MSC_VER) POpenExProperties popProps; #endif #ifdef EXTRACTCHANNELVIEWS int ff; FILE *pfp[4] = {NULL, NULL, NULL, NULL}; #endif init_HRTime(); HRTime_tic(); if( (fp = open_VODFile( &FP, theURL, mode )) ){ if( !validate_VODFile( fp, 0 ) ){ fprintf( stderr, "Not a VOD file \"%s\"\n", theURL ); close_VODFile(fp); return 0; } fprintf( stderr, "Opened VOD file \"%s\"\n", theURL ); #ifdef __APPLE_CC__ fpBase = FP.theFile->_bf._base; #endif readtable = (struct readtables*) calloc(1, sizeof(struct readtables)); mkdtemp(dirTemp); bURL = strdup( basename(theURL) ); #if defined(WIN32) || defined(_MSC_VER) || defined(__MINGW32__) strcat( dirTemp, "\\" ); #else strcat( dirTemp, "/" ); #endif fprintf( stderr, "@@\t average frequency: %gHz\n", (frameRate = VODFile_Find_averageRate(fp)) ); CLEAR_MPG4_FRAGMENT(&mp4Frag); memset( &StartTimeStamp, 0, sizeof(StartTimeStamp) ); VMGICHECK( Read_VMGI( fp ) ){ FOFFSET fpos; if( fp->hasMPG4 && !dumpFP ){ char command[1024]; #if defined(_MSC_VER) || defined(WIN32) || defined(__MINGW32__) const char *mode = "wb"; #else const char *mode = "w"; #endif snprintf( command, sizeof(command), "ffmpeg -y -v 1 -i - -vcodec copy \"%s.%4d%02d%02d%02d%02d.mov\"", theURL, fp->vmgi.StartDate.year, fp->vmgi.StartDate.month, fp->vmgi.StartDate.day, fp->vmgi.StartTime.hours, fp->vmgi.StartTime.minutes ); // snprintf( command, sizeof(command), "cat > %s.fragments.mov -", theURL ); fprintf( stderr, "Sending content to \"%s\"\n", command ); #if defined(_MSC_VER) popProps.commandShell = "ffmpeg.exe"; popProps.shellCommandArg = NULL; popProps.runPriorityClass = ABOVE_NORMAL_PRIORITY_CLASS; popProps.finishPriorityClass = HIGH_PRIORITY_CLASS; dumpFP = popenEx( command, mode, &popProps ); #else dumpFP = popen( command, mode ); #endif if( dumpFP ){ SetupPipeSignalHandler(&gotPipeSignal); pcloseDumpFP = 1; } #ifdef EXTRACTCHANNELVIEWS snprintf( command, sizeof(command), "ffmpeg -y -v 1 -i - -vf crop=360:288:0:0 -b:v 500k -vcodec mjpeg \"%s.%4d%02d%02d%02d%02d-camera1.mov\"", theURL, fp->vmgi.StartDate.year, fp->vmgi.StartDate.month, fp->vmgi.StartDate.day, fp->vmgi.StartTime.hours, fp->vmgi.StartTime.minutes ); #ifdef _MSC_VER pfp[0] = popenEx( command, mode, &popProps ); #else pfp[0] = popen( command, mode ); #endif snprintf( command, sizeof(command), "ffmpeg -y -v 1 -i - -vf crop=360:288:360:0 -b:v 500k -vcodec mjpeg \"%s.%4d%02d%02d%02d%02d-camera2.mov\"", theURL, fp->vmgi.StartDate.year, fp->vmgi.StartDate.month, fp->vmgi.StartDate.day, fp->vmgi.StartTime.hours, fp->vmgi.StartTime.minutes ); #ifdef _MSC_VER pfp[1] = popenEx( command, mode, &popProps ); #else pfp[1] = popen( command, mode ); #endif snprintf( command, sizeof(command), "ffmpeg -y -v 1 -i - -vf crop=360:288:0:288 -b:v 500k -vcodec mjpeg \"%s.%4d%02d%02d%02d%02d-camera3.mov\"", theURL, fp->vmgi.StartDate.year, fp->vmgi.StartDate.month, fp->vmgi.StartDate.day, fp->vmgi.StartTime.hours, fp->vmgi.StartTime.minutes ); #ifdef _MSC_VER pfp[2] = popenEx( command, mode, &popProps ); #else pfp[2] = popen( command, mode ); #endif snprintf( command, sizeof(command), "ffmpeg -y -v 1 -i - -vf crop=360:288:360:288 -b:v 500k -vcodec mjpeg \"%s.%4d%02d%02d%02d%02d-camera4.mov\"", theURL, fp->vmgi.StartDate.year, fp->vmgi.StartDate.month, fp->vmgi.StartDate.day, fp->vmgi.StartTime.hours, fp->vmgi.StartTime.minutes ); #ifdef _MSC_VER pfp[3] = popenEx( command, mode, &popProps ); #else pfp[3] = popen( command, mode ); #endif #endif // EXTRACTCHANNELVIEWS } current_vmgi = fp->current_vmgi; if( !StartTimeStamp.isSet ){ StartTimeStamp.StartDate = fp->vmgi.StartDate; StartTimeStamp.StartTime = fp->vmgi.StartTime; StartTimeStamp.isSet = 1; #ifdef _MSC_VER { struct tm tmm = {0}; // Fill out the modified time structure // tm_hour is supposed to be in UTC, so we correct for the fact we're in Western continental Europe tmm.tm_hour = fp->vmgi.StartTime.hours - 1; // guess whether DST was in effect: tmm.tm_isdst = (fp->vmgi.StartDate.month > 3 && fp->vmgi.StartDate.month < 11)? 1 : 0; tmm.tm_min = fp->vmgi.StartTime.minutes; tmm.tm_sec = fp->vmgi.StartTime.seconds; tmm.tm_mday = fp->vmgi.StartDate.day; // tm_mon is 0 based tmm.tm_mon = fp->vmgi.StartDate.month - 1; // tm_year starts at 1900 tmm.tm_year = fp->vmgi.StartDate.year - 1900; // Convert tm to time_t StartTimeStamp.ut.actime = StartTimeStamp.ut.modtime = mktime(&tmm); } #endif } fprintf( stderr, "## VMGI #%d @ 0x%lx (%.3g%%), %d video, %u audio frames%s%s, %4d%02d%02d::%02d:%02d:%02d - %4d%02d%02d::%02d:%02d:%02d\n", fp->current_vmgi, (unsigned long) fp->current_vmgiPos, ((double)fp->current_vmgiPos)/((double) fp->fileSize) * 100.0, fp->vmgiVideoFrames, fp->vmgiAudioChunks, (fp->vmgi.VOB_Ns != fp->vmgiVideoFrames+fp->vmgiAudioChunks)? " plus something else" : "", (fp->vmgi.InfoType==2)? ", GPS" : "", fp->vmgi.StartDate.year, fp->vmgi.StartDate.month, fp->vmgi.StartDate.day, fp->vmgi.StartTime.hours, fp->vmgi.StartTime.minutes, fp->vmgi.StartTime.seconds, fp->vmgi.EndDate.year, fp->vmgi.EndDate.month, fp->vmgi.EndDate.day, fp->vmgi.EndTime.hours, fp->vmgi.EndTime.minutes, fp->vmgi.EndTime.seconds ); fflush( stderr ); if( N == 0 ){ fpos = FFTELL(fp->theFile); // we save fp->vmgi because Read_VOB_JPEG_Header_Scan_Next() can update this field to the file's next VMGI // when in fact we still want to print out information from the current one... vmgi = fp->vmgi; } #ifdef USE_VMGI readtableN += 1; if( (readtable = (struct readtables*) realloc( readtable, readtableN*sizeof(struct readtables) )) ){ rt = &readtable[readtableN-1]; rt->current_vmgi = current_vmgi; rt->current_vmgiPos = fp->vmgiPos[current_vmgi]; rt->VOB_Ns = fp->vmgi.VOB_Ns; rt->vmgiAudioChunks = fp->vmgiAudioChunks; rt->vmgiVideoFrames = fp->vmgiVideoFrames; rt->frames = rt->doubles = 0; } else{ rt = NULL; } // fp and fp->vmgi are always up to date and never ahead of us. vmgi = fp->vmgi; fpos = FFTELL(fp->theFile); fp->readContent = 1; for( VOBid = 0; VOBid_Check(fp, VOBid, NULL); VOBid++ ){ fflush(stdout); switch( VODFILE_VOB_TYPE(fp,VOBid) ){ case VMGI_VOB_TYPE_VIDEO: if( (ok = Read_VOB_xPEG_Header( fp, VOBid, &jH, &jpgOffset, &nextFound, &mp4Frag, DUMP_JPGS /*&& (fp->vmgi.InfoType==2)*/ )) ){ if( ok < 0 ){ fputs( "((", stderr ); } if( VOB_Header_isJPEG( (VOB_Headers_Common*)&jH ) ){ size_t nameLen = (strlen(theURL)+strlen(dirTemp)+34)*sizeof(char); char *tmpName = (char*) malloc(nameLen); if( tmpName ){ snprintf( tmpName, nameLen, "%s%s.%04ld.jpg", dirTemp, bURL, fp->decodedFrames ); if( dumpFP ){ fclose(dumpFP); } if( (dumpFP = fopen(tmpName, "wb")) ){ fwrite( fp->lastReadContent, sizeof(unsigned char), fp->lastReadContentByteLength, dumpFP ); fclose(dumpFP); dumpFP = NULL; jpgFrameCount += 1; } free(tmpName); } if( VOBid == 0 || VOBid == fp->vmgi.VOB_Ns - 1 ){ fprintf( stderr, "jpeg image #%d at offset %ld; %hux%hu, %4d%02d%02d::%02d:%02d:%02d flags=%s\n", VOBid, (long) jpgOffset, jH.Width, jH.Height, jH.Date.year, jH.Date.month, jH.Date.day, jH.Time.hours, jH.Time.minutes, jH.Time.seconds, VOB_JPEG_Flags(&jH) ); if( VOBid == 0 ){ fputs( "...\n", stderr ); } } } else if( VOB_Header_isMPG4( (VOB_Headers_Common*)&jH ) ){ if( !dumpFP ){ size_t nameLen = (strlen(theURL)+strlen(dirTemp)+34)*sizeof(char); char *tmpName = (char*) malloc(nameLen); if( tmpName ){ snprintf( tmpName, nameLen, "%s%s.fragments.mp4", dirTemp, bURL, fp->decodedFrames ); dumpFP = fopen(tmpName, "wb"); free(tmpName); } } if( dumpFP ){ fwrite( fp->lastReadContent, sizeof(unsigned char), fp->lastReadContentByteLength, dumpFP ); if( gotPipeSignal ){ #ifdef _MSC_VER pcloseEx(dumpFP); #else pclose(dumpFP); #endif dumpFP = NULL; goto done; } mp4FragCount += 1; } #ifdef EXTRACTCHANNELVIEWS for( ff = 0 ; ff < 4 ; ff++ ){ if( pfp[ff] ){ fwrite( fp->lastReadContent, sizeof(unsigned char), fp->lastReadContentByteLength, pfp[ff] ); if( gotPipeSignal ){ #ifdef _MSC_VER pcloseEx(pfp[ff]); #else pclose(pfp[ff]); #endif pfp[ff] = NULL; goto done; } } } #endif #ifndef NO_FFMPEGLIBS_DEPEND fprintf( stderr, "MPEG4 fragment #%d.%d at offset %ld(%ld), %d(%lu) bytes of %lu; %hux%hu, %4d%02d%02d::%02d:%02d:%02d flags=%s\n", VOBid, mp4Frag.current.frameNr, (long) jpgOffset, (long) jpgOffset - (long) mp4Frag.fileOffset, mp4Frag.current.byteLength, jH.Length - sizeof(jH), mp4Frag.byteLength, jH.Width, jH.Height, jH.Date.year, jH.Date.month, jH.Date.day, jH.Time.hours, jH.Time.minutes, jH.Time.seconds, VOB_JPEG_Flags(&jH) ); #else fprintf( stderr, "MPEG4 fragment #%d.%d @0x%lx, %lu bytes; %hux%hu, %4d%02d%02d::%02d:%02d:%02d flags=%s\n", VOBid, mp4Frag.current.frameNr, (long) jpgOffset, mp4Frag.byteLength, jH.Width, jH.Height, jH.Date.year, jH.Date.month, jH.Date.day, jH.Time.hours, jH.Time.minutes, jH.Time.seconds, VOB_JPEG_Flags(&jH) ); #endif } if( fp->hasGPS ){ if( fp->gpsData.fieldsRead > 0 ){ fprintf( stderr, "\tGPS NMEA Sentence %s[%d] ; speed=%g\n", fp->nmeaSentence, fp->gpsData.fieldsRead, fp->gpsData.speed ); } } if( ok > 0 ){ if( rt ){ rt->frames += 1; if( jpgOffset == prev_Offset ){ rt->doubles += 1; } } tskipped += print_positions( stdout, fp, &vmgi, N, &jH, &prev_jH, jpgOffset, &prev_Offset, &fpos, &prev_fpos ); N += 1; } }; break; case VMGI_VOB_TYPE_AUDIO: Find_Next_VOB_Audio_Header(fp, NULL, NULL, 1); fp->curPos += 1; break; default: break; } fflush(stderr); } fp->readContent = 0; if( strncmp( fp->vmgi.Id, "VOBX", 4 ) == 0 && fp->vmgi.VOB_Ns == 0 ){ fprintf( stderr, "Encountered an empty VOBX instead of a VOBS - assuming end of recording!\n" ); break; } #else // !USE_VMGI fp->readContent = 1; while( (ok = Read_VOB_xPEG_Header_Scan_Next( fp, &jH, &jpgOffset, &nextFound, &mp4Frag, DUMP_JPGS )) || nextFound ){ if( current_vmgi != fp->current_vmgi || readtableN == 0 ){ current_vmgi = fp->current_vmgi; readtableN += 1; fprintf( stderr, "## VMGI #%d @ 0x%lx (%.3g%%), %d video, %u audio frames%s%s, %4d%02d%02d::%02d:%02d:%02d - %4d%02d%02d::%02d:%02d:%02d\n", fp->current_vmgi, (unsigned long) fp->current_vmgiPos, ((double)fp->current_vmgiPos)/((double) fp->fileSize) * 100.0, fp->vmgiVideoFrames, fp->vmgiAudioChunks, (fp->vmgi.VOB_Ns != fp->vmgiVideoFrames+fp->vmgiAudioChunks)? " plus something else" : "", (fp->vmgi.InfoType==2)? ", GPS" : "", fp->vmgi.StartDate.year, fp->vmgi.StartDate.month, fp->vmgi.StartDate.day, fp->vmgi.StartTime.hours, fp->vmgi.StartTime.minutes, fp->vmgi.StartTime.seconds, fp->vmgi.EndDate.year, fp->vmgi.EndDate.month, fp->vmgi.EndDate.day, fp->vmgi.EndTime.hours, fp->vmgi.EndTime.minutes, fp->vmgi.EndTime.seconds ); fflush( stderr ); if( (readtable = (struct readtables*) realloc( readtable, readtableN*sizeof(struct readtables) )) ){ rt = &readtable[readtableN-1]; rt->current_vmgi = current_vmgi; rt->current_vmgiPos = fp->vmgiPos[current_vmgi]; rt->VOB_Ns = fp->vmgi.VOB_Ns; rt->vmgiAudioChunks = fp->vmgiAudioChunks; rt->vmgiVideoFrames = fp->vmgiVideoFrames; rt->frames = rt->doubles = 0; } else{ rt = NULL; } } if( ok ){ fflush(stdout); if( ok < 0 ){ fputs( "((", stderr ); } if( VOB_Header_isJPEG( (VOB_Headers_Common*)&jH ) ){ size_t nameLen = (strlen(theURL)+strlen(dirTemp)+34)*sizeof(char); char *tmpName = (char*) malloc(nameLen); if( tmpName ){ snprintf( tmpName, nameLen, "%s%s.%04ld.jpg", dirTemp, bURL, fp->decodedFrames ); if( dumpFP ){ fclose(dumpFP); } if( (dumpFP = fopen(tmpName, "wb")) ){ fwrite( fp->lastReadContent, sizeof(unsigned char), fp->lastReadContentByteLength, dumpFP ); fclose(dumpFP); dumpFP = NULL; jpgFrameCount += 1; } free(tmpName); } fprintf( stderr, "jpeg image #%d:%d at offset %lu; %hux%hu, %4d%02d%02d::%02d:%02d:%02d\n", fp->current_vmgi, fp->current_VOBDes, (unsigned long) jpgOffset, jH.Width, jH.Height, jH.Date.year, jH.Date.month, jH.Date.day, jH.Time.hours, jH.Time.minutes, jH.Time.seconds ); } else if( VOB_Header_isMPG4( (VOB_Headers_Common*)&jH ) ){ if( !dumpFP ){ size_t nameLen = (strlen(theURL)+strlen(dirTemp)+34)*sizeof(char); char *tmpName = (char*) malloc(nameLen); if( tmpName ){ snprintf( tmpName, nameLen, "%s%s.fragments.mp4", dirTemp, bURL, fp->decodedFrames ); dumpFP = fopen(tmpName, "wb"); free(tmpName); } } if( dumpFP ){ fwrite( fp->lastReadContent, sizeof(unsigned char), fp->lastReadContentByteLength, dumpFP ); mp4FragCount += 1; } fprintf( stderr, "MPEG4 fragment #%d:%d at offset %lu, %lu bytes; %hux%hu, %4d%02d%02d::%02d:%02d:%02d\n", fp->current_vmgi, fp->current_VOBDes, (unsigned long) jpgOffset, fp->lastReadContentByteLength, jH.Width, jH.Height, jH.Date.year, jH.Date.month, jH.Date.day, jH.Time.hours, jH.Time.minutes, jH.Time.seconds ); } fflush( stderr ); if( ok > 0 ){ if( rt ){ rt->frames += 1; if( jpgOffset == prev_Offset ){ rt->doubles += 1; } } tskipped += print_positions( stdout, fp, &vmgi, N, &jH, &prev_jH, jpgOffset, &prev_Offset, &fpos, &prev_fpos ); N += 1; } } } fp->readContent = 0; #endif // USE_VMGI } done: // whether or not the scan of the file is complete is up to us to decide, though the routines in brigade.c // will set the flag if they encounter EOF. fp->scanComplete = 1; if( dumpFP ){ char fname[1024]; if( pcloseDumpFP ){ fflush(stdout); fprintf( stderr, "Waiting for ffmpeg to terminate..." ); fflush(stderr); #ifdef _MSC_VER pcloseEx(dumpFP); fprintf( stderr, " took %g user and %g kernel seconds\n", popProps.times.user, popProps.times.kernel ); #else pclose(dumpFP); fputs( "\n", stderr ); #endif snprintf( fname, sizeof(fname), "%s.%4d%02d%02d%02d%02d.mov", theURL, StartTimeStamp.StartDate.year, StartTimeStamp.StartDate.month, StartTimeStamp.StartDate.day, StartTimeStamp.StartTime.hours, StartTimeStamp.StartTime.minutes ); #ifdef _MSC_VER _utime( fname, &StartTimeStamp.ut ); #endif } else{ fclose(dumpFP); } dumpFP = NULL; } #ifdef EXTRACTCHANNELVIEWS for( ff = 0 ; ff < 4 ; ff++ ){ if( pfp[ff] ){ #ifdef _MSC_VER pcloseEx(pfp[ff]); #else pclose(pfp[ff]); #endif pfp[ff] = NULL; } } #endif if(0){ int aN = 0, pN = fp->NaudioPos; extern int Find_All_VOB_Audio_Headers( VODFiles *fp ); fprintf( stderr, "Doing an exhaustive scan for audio ... " ); fflush(stderr); aN = Find_All_VOB_Audio_Headers(fp); if( aN != pN ){ fprintf( stderr, " encountered %d chunks", aN ); } fputs( "\n", stderr ); rewind_VODFile(fp, NULL); } else{ rewind_VODFile(fp, NULL); } if( fp ){ fprintf( stderr, "Read %d VMGIs and encountered %d audio chunks while scanning for video frames\n", fp->NvmgiPos, fp->NaudioPos ); } else{ fprintf( stderr, "Error reopening file after rewind (%s)\n", strerror(errno) ); } if( fp && fp->NaudioPos ){ FILE *audioFP = NULL; char *tmpName; int tnl; if( (tmpName = (char*) malloc( (tnl = strlen(theURL)+32) * sizeof(char) )) ){ snprintf( tmpName, tnl, "%s.au1", fp->theURL ); audioFP = fopen( tmpName, "wb" ); free(tmpName), tmpName = NULL; } for( VOBid = 0, audioDuration = 0 ; VOBid < fp->NaudioPos ; VOBid++ ){ uint32_t audioLength; double duration, freq[] = { 8, 11025, 22050, 44100 }; if( VOBid == 0 || fp->audioPos[VOBid] != fp->audioPos[VOBid-1] ){ Read_VOB_Audio_Header_From_audioPos( fp, VOBid, &aH, &audioOffset, &audioLength, 1, audioFP ); if( aH.Audio_Channel == 2 ){ duration = audioLength / 2 / freq[aH.Audio_Rate]; } else{ duration = audioLength / freq[aH.Audio_Rate]; } fprintf( stderr, "Audio chunk #%d: %lu bytes at 0x%lx; duration=%gs\n", VOBid, audioLength, (unsigned long) audioOffset, duration ); audioDuration += duration; } } if( audioFP ){ fclose(audioFP); } } if( audioDuration ) { fprintf( stderr, "Total audio duration: %gs\n", audioDuration ); } Finalise_MPG4_Fragment(&mp4Frag); close_VODFile(fp); fprintf( stderr, "Average skipped bytes per frame: %g\n", tskipped / N ); #ifdef DEBUG if( readtable ){ int i, AudioChunks = 0; for( i = 0; i< readtableN; i++){ fprintf( stderr, "%03d VMGI #%d@0x%lu\tframes=%d\tVOB_Ns=%d,VideoFrames=%d,AudioChunks=%d", i, readtable[i].current_vmgi, (unsigned long)readtable[i].current_vmgiPos, readtable[i].frames, readtable[i].VOB_Ns, readtable[i].vmgiVideoFrames, readtable[i].vmgiAudioChunks ); if( rt->doubles ){ fprintf( stderr, "\tdoubles=%d", rt->doubles ); } fputc( '\n', stderr ); AudioChunks += readtable[i].vmgiAudioChunks; } free(readtable); readtable = NULL; } #endif { char command[1024]; if( jpgFrameCount ){ snprintf( command, sizeof(command), "ffmpeg -y -r %g -i %s%s.%%04d.jpg -vcodec copy \"%s.%4d%02d%02d%02d%02d.mov\"", frameRate, dirTemp, bURL, theURL, StartTimeStamp.StartDate.year, StartTimeStamp.StartDate.month, StartTimeStamp.StartDate.day, StartTimeStamp.StartTime.hours, StartTimeStamp.StartTime.minutes ); system( command ); } // if( mp4FragCount ){ // snprintf( command, sizeof(command), "ffmpeg -y -i %s%s.fragments.mp4 -vcodec copy %s.converted.mov", // dirTemp, bURL, theURL ); // system( command ); // } #if defined(WIN32) || defined(_MSC_VER) || defined(__MINGW32__) snprintf( command, sizeof(command), "rmdir /s /q %s", dirTemp ); #else snprintf( command, sizeof(command), "rm -rf %s", dirTemp ); #endif system(command); snprintf( command, sizeof(command), "%s.%4d%02d%02d%02d%02d.mov", theURL, StartTimeStamp.StartDate.year, StartTimeStamp.StartDate.month, StartTimeStamp.StartDate.day, StartTimeStamp.StartTime.hours, StartTimeStamp.StartTime.minutes ); #ifdef _MSC_VER _utime( command, &StartTimeStamp.ut ); #endif free(bURL); } #ifdef USE_VMGI if( mp4Frag.valid ){ fprintf( stderr, "Read %lu %gHz 1sec fragments from \"%s\" in %g sec (using VMGI info)\n", N, frameRate, theURL, HRTime_toc() ); } else{ fprintf( stderr, "Read %lu frames from \"%s\" in %g sec (using VMGI info)\n", N, theURL, HRTime_toc() ); } #else fprintf( stderr, "Read %lu frames from \"%s\" in %g sec\n", N, theURL, HRTime_toc() ); #endif } else{