Added new usleep method for Windows, and improved speed of Seek() operation on the FFmpegReader. Also added some Seek unit tests.

This commit is contained in:
Jonathan Thomas
2014-04-03 22:35:25 -05:00
parent e073ad89f5
commit a229ced036
4 changed files with 99 additions and 6 deletions

View File

@@ -43,8 +43,24 @@
#ifdef _WINDOWS
#include <windows.h>
// 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 <unistd.h>
// 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

View File

@@ -436,7 +436,7 @@ tr1::shared_ptr<Frame> 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<Frame> 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<Frame> 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)

Binary file not shown.

View File

@@ -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<Frame> 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();
}