From 1f6b3863253a9acb4599f69ed646f2d9d2e4d859 Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Sat, 22 Oct 2016 22:09:47 -0700 Subject: [PATCH] Implement frame timestamps and use wpi::Now() for generation. --- src/Frame.h | 3 +-- src/MJPEGServerImpl.cpp | 4 +--- src/SourceImpl.cpp | 10 ++++++++++ src/SourceImpl.h | 3 +++ src/USBCameraImpl.cpp | 3 ++- src/cameraserver_cpp.cpp | 7 ++++++- 6 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/Frame.h b/src/Frame.h index f0ae61de14..721c7b3f96 100644 --- a/src/Frame.h +++ b/src/Frame.h @@ -9,7 +9,6 @@ #define CAMERASERVER_FRAME_H_ #include -#include #include #include "llvm/StringRef.h" @@ -24,7 +23,7 @@ class Frame { friend class SourceImpl; public: - typedef std::chrono::system_clock::time_point Time; + typedef uint64_t Time; private: struct Data { diff --git a/src/MJPEGServerImpl.cpp b/src/MJPEGServerImpl.cpp index 435995ab6e..abbca3f4e6 100644 --- a/src/MJPEGServerImpl.cpp +++ b/src/MJPEGServerImpl.cpp @@ -401,9 +401,7 @@ void MJPEGServerImpl::SendStream(wpi::raw_socket_ostream& os) { // print the individual mimetype and the length // sending the content-length fixes random stream disruption observed // with firefox - double timestamp = std::chrono::duration_cast( - frame.time().time_since_epoch()) - .count(); + double timestamp = frame.time() / 10000000.0; header.clear(); oss << "Content-Type: image/jpeg\r\n" << "Content-Length: " << frame.size() << "\r\n" diff --git a/src/SourceImpl.cpp b/src/SourceImpl.cpp index ffea5e0b06..30e8041de3 100644 --- a/src/SourceImpl.cpp +++ b/src/SourceImpl.cpp @@ -32,6 +32,16 @@ SourceImpl::~SourceImpl() { // Everything else can clean up itself. } +uint64_t SourceImpl::GetCurFrameTime() { + std::unique_lock lock{m_frameMutex}; + return m_frame.time(); +} + +Frame SourceImpl::GetCurFrame() { + std::unique_lock lock{m_frameMutex}; + return m_frame; +} + Frame SourceImpl::GetNextFrame() { std::unique_lock lock{m_frameMutex}; // TODO: handle spurious wakeup by comparing frame timestamps diff --git a/src/SourceImpl.h b/src/SourceImpl.h index 8f5e4c4d4f..0b710a7154 100644 --- a/src/SourceImpl.h +++ b/src/SourceImpl.h @@ -65,6 +65,9 @@ class SourceImpl { NumSinksEnabledChanged(); } + // Gets the current frame time (without waiting for a new one). + uint64_t GetCurFrameTime(); + // Gets the current frame (without waiting for a new one). Frame GetCurFrame(); diff --git a/src/USBCameraImpl.cpp b/src/USBCameraImpl.cpp index 25b000af6c..b65a42c272 100644 --- a/src/USBCameraImpl.cpp +++ b/src/USBCameraImpl.cpp @@ -31,6 +31,7 @@ #include "llvm/raw_ostream.h" #include "llvm/SmallString.h" +#include "support/timestamp.h" #include "cameraserver_cpp.h" #include "c_util.h" @@ -561,7 +562,7 @@ void USBCameraImpl::CameraThreadMain() { llvm::StringRef( static_cast(m_buffers[buf.index].m_data), static_cast(buf.bytesused)), - Frame::Time{}); // TODO: time + wpi::Now()); // TODO: time } // Requeue buffer diff --git a/src/cameraserver_cpp.cpp b/src/cameraserver_cpp.cpp index 7f733b2097..b73cf0519d 100644 --- a/src/cameraserver_cpp.cpp +++ b/src/cameraserver_cpp.cpp @@ -198,7 +198,12 @@ llvm::StringRef GetSourceDescription(CS_Source source, } uint64_t GetSourceLastFrameTime(CS_Source source, CS_Status* status) { - return 0; // TODO + auto data = Sources::GetInstance().Get(source); + if (!data) { + *status = CS_INVALID_HANDLE; + return 0; + } + return data->source->GetCurFrameTime(); } bool IsSourceConnected(CS_Source source, CS_Status* status) {