diff --git a/include/Sleep.h b/include/Sleep.h index 2073eeb5..182ab46f 100644 --- a/include/Sleep.h +++ b/include/Sleep.h @@ -43,8 +43,24 @@ #ifdef _WINDOWS #include + + // Define a Windows-compatible usleep method (which sleeps for X microseconds). Linux/Mac already have a method for this. + void usleep(__int64 usec) + { + HANDLE timer; + LARGE_INTEGER ft; + + ft.QuadPart = -(10*usec); // Convert to 100 nanosecond interval, negative value indicates relative time + + timer = CreateWaitableTimer(NULL, TRUE, NULL); + SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0); + WaitForSingleObject(timer, INFINITE); + CloseHandle(timer); + } #else #include + + // Define a Linux/Mac compatible Sleep method (which sleeps for x seconds). Windows already has a method for this. #define Sleep(x) usleep((x)*1000) #endif diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index cae00b56..2d0c7e40 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -436,7 +436,7 @@ tr1::shared_ptr FFmpegReader::GetFrame(int requested_frame) throw(OutOfBo { // Greater than 30 frames away, or backwards, we need to seek to the nearest key frame cout << " >> TOO FAR, SO SEEK FIRST AND THEN WALK THE STREAM (diff: " << diff << ", requested_frame: " << requested_frame << ", last_frame: " << last_frame << ")" << endl; - final_cache.Display(); + //final_cache.Display(); if (enable_seek) // Only seek if enabled Seek(requested_frame); @@ -485,7 +485,7 @@ tr1::shared_ptr FFmpegReader::ReadStream(int requested_frame) // Wait if too many frames are being processed while (processing_video_frames.size() + processing_audio_frames.size() >= minimum_packets) - Sleep(1); + usleep(20 * 1000); // Get the next packet (if any) if (packet_error < 0) @@ -495,7 +495,7 @@ tr1::shared_ptr FFmpegReader::ReadStream(int requested_frame) // Wait for all frames to be processed while (processing_video_frames.size() + processing_audio_frames.size() == 0) - Sleep(1); + usleep(20 * 1000); break; } @@ -1076,7 +1076,7 @@ void FFmpegReader::Seek(int requested_frame) throw(TooManySeeks) throw TooManySeeks("Too many seek attempts... something seems wrong.", path); // If seeking to frame 1, we need to close and re-open the file (this is more reliable than seeking) - int buffer_amount = 10; + int buffer_amount = 6; if (requested_frame - buffer_amount <= 1) { // Close and re-open file (basically seeking to frame 1) @@ -1328,8 +1328,8 @@ void FFmpegReader::CheckWorkingFrames(bool end_of_stream) int smallest_audio_frame = 1; #pragma omp critical (processing_list) { - smallest_video_frame = GetSmallestVideoFrame() - 8; // Adjust to be sure the frame is completed - smallest_audio_frame = GetSmallestAudioFrame() - 8; // Adjust to be sure the frame is completed + smallest_video_frame = GetSmallestVideoFrame(); // Adjust to be sure the frame is completed + smallest_audio_frame = GetSmallestAudioFrame(); // Adjust to be sure the frame is completed // Adjust for video only, or audio only if (!info.has_video) diff --git a/src/examples/sintel_trailer-720p.mp4 b/src/examples/sintel_trailer-720p.mp4 new file mode 100644 index 00000000..c2867ac3 Binary files /dev/null and b/src/examples/sintel_trailer-720p.mp4 differ diff --git a/tests/FFmpegReader_Tests.cpp b/tests/FFmpegReader_Tests.cpp index 8f098a5a..de7cd9c5 100644 --- a/tests/FFmpegReader_Tests.cpp +++ b/tests/FFmpegReader_Tests.cpp @@ -117,7 +117,84 @@ TEST(FFmpegReader_Check_Video_File) CHECK_EQUAL(24672, pixels[112].green); CHECK_EQUAL(0, pixels[112].opacity); + // Close reader + r.Close(); +} + +TEST(FFmpegReader_Seek) +{ + // Create a reader + FFmpegReader r("../../src/examples/sintel_trailer-720p.mp4"); + r.Open(); + + // Get frame + tr1::shared_ptr f = r.GetFrame(1); + CHECK_EQUAL(1, f->number); + //f->Display(); + //f->DisplayWaveform(); + + // Get frame + f = r.GetFrame(300); + CHECK_EQUAL(300, f->number); + //f->Display(); + //f->DisplayWaveform(); + + // Get frame + f = r.GetFrame(301); + CHECK_EQUAL(301, f->number); + //f->Display(); + //f->DisplayWaveform(); + + // Get frame + f = r.GetFrame(315); + CHECK_EQUAL(315, f->number); + //f->Display(); + //f->DisplayWaveform(); + + // Get frame + f = r.GetFrame(275); + CHECK_EQUAL(275, f->number); + //f->Display(); + //f->DisplayWaveform(); + + // Get frame + f = r.GetFrame(270); + CHECK_EQUAL(270, f->number); + //f->Display(); + //f->DisplayWaveform(); + + // Get frame + f = r.GetFrame(500); + CHECK_EQUAL(500, f->number); + //f->Display(); + //f->DisplayWaveform(); + + // Get frame + f = r.GetFrame(100); + CHECK_EQUAL(100, f->number); + //f->Display(); + //f->DisplayWaveform(); + + // Get frame + f = r.GetFrame(600); + CHECK_EQUAL(600, f->number); + //f->Display(); + //f->DisplayWaveform(); + + // Get frame + f = r.GetFrame(1); + CHECK_EQUAL(1, f->number); + //f->Display(); + //f->DisplayWaveform(); + + // Get frame + f = r.GetFrame(700); + CHECK_EQUAL(700, f->number); + //f->Display(); + //f->DisplayWaveform(); + // Close reader r.Close(); } +