From dfc4c9b315aa45e4ba117c24e5efd17baeb5687c Mon Sep 17 00:00:00 2001 From: Tai Date: Thu, 2 May 2019 21:35:46 +0800 Subject: [PATCH] add source clock counting --- src/virtual-source/CMakeLists.txt | 2 ++ src/virtual-source/clock.cpp | 37 ++++++++++++++++++++++++++++ src/virtual-source/clock.h | 5 ++++ src/virtual-source/virtual-audio.cpp | 12 ++++----- src/virtual-source/virtual-cam.cpp | 7 +++++- 5 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 src/virtual-source/clock.cpp create mode 100644 src/virtual-source/clock.h diff --git a/src/virtual-source/CMakeLists.txt b/src/virtual-source/CMakeLists.txt index 18da42f..fe5dd17 100644 --- a/src/virtual-source/CMakeLists.txt +++ b/src/virtual-source/CMakeLists.txt @@ -7,6 +7,7 @@ set(virtualsource_SOURCES dllmain.cpp virtual-cam.cpp virtual-audio.cpp + clock.cpp virtua-source.def ../queue/share_queue_read.cpp ) @@ -14,6 +15,7 @@ set(virtualsource_SOURCES set(virtualsource_HEADERS virtual-cam.h virtual-audio.h + clock.h ../queue/share_queue_read.h ../queue/share_queue.h ) diff --git a/src/virtual-source/clock.cpp b/src/virtual-source/clock.cpp new file mode 100644 index 0000000..838dd4c --- /dev/null +++ b/src/virtual-source/clock.cpp @@ -0,0 +1,37 @@ +#include "clock.h" + +static bool have_clockfreq = false; +static LARGE_INTEGER clock_freq; + +//directshow use 100ns as time unit + +uint64_t get_current_time(void) +{ + LARGE_INTEGER current_time; + double time_val; + + if (!have_clockfreq) { + QueryPerformanceFrequency(&clock_freq); + have_clockfreq = true; + } + + QueryPerformanceCounter(¤t_time); + time_val = (double)current_time.QuadPart; + time_val *= 10000000.0; + time_val /= (double)clock_freq.QuadPart; + + return (uint64_t)time_val; +} + +bool sleepto(uint64_t time_target) +{ + uint64_t t = get_current_time(); + uint32_t milliseconds; + + if (t >= time_target) + return false; + + milliseconds = (uint32_t)((time_target - t) / 10000); + if (milliseconds > 1) + Sleep(milliseconds - 1); +} \ No newline at end of file diff --git a/src/virtual-source/clock.h b/src/virtual-source/clock.h new file mode 100644 index 0000000..ff97384 --- /dev/null +++ b/src/virtual-source/clock.h @@ -0,0 +1,5 @@ +#include +#include + +uint64_t get_current_time(void); +bool sleepto(uint64_t time_target); \ No newline at end of file diff --git a/src/virtual-source/virtual-audio.cpp b/src/virtual-source/virtual-audio.cpp index 7e70e6f..54e0cf2 100644 --- a/src/virtual-source/virtual-audio.cpp +++ b/src/virtual-source/virtual-audio.cpp @@ -7,6 +7,7 @@ #include #include #include "virtual-audio.h" +#include "clock.h" CUnknown * WINAPI CVAudio::CreateInstance(LPUNKNOWN lpunk, HRESULT *phr) { @@ -85,6 +86,11 @@ HRESULT CVAudioStream::FillBuffer(IMediaSample *pms) if (!queue.hwnd) shared_queue_open(&queue, ModeAudio); + if (prev_end_ts <= 0) + prev_end_ts = get_current_time(); + + sleepto(prev_end_ts); + while (queue.header && !get_sample){ if (get_times > 20 || queue.header->state != OutputReady) @@ -120,16 +126,10 @@ HRESULT CVAudioStream::FillBuffer(IMediaSample *pms) dshow_start_ts = 0; } - if (prev_end_ts != start_time) - int a = 0; - REFERENCE_TIME duration = (REFERENCE_TIME)10000000 * size / (REFERENCE_TIME)SAMPLE_SIZE; end_time = start_time + duration; prev_end_ts = end_time; - - - pms->SetTime(&start_time, &end_time); pms->SetSyncPoint(TRUE); return NOERROR; diff --git a/src/virtual-source/virtual-cam.cpp b/src/virtual-source/virtual-cam.cpp index eda2fed..fe27ff7 100644 --- a/src/virtual-source/virtual-cam.cpp +++ b/src/virtual-source/virtual-cam.cpp @@ -4,6 +4,7 @@ #include #include #include "virtual-cam.h" +#include "clock.h" #define MIN_WIDTH 320 #define MIN_HEIGHT 240 @@ -158,7 +159,10 @@ HRESULT CVCamStream::FillBuffer(IMediaSample *pms) Sleep(5); get_times++; } - } + } + + if (prev_end_ts <= 0) + prev_end_ts = get_current_time(); if (get_sample && !obs_start_ts) { obs_start_ts = timestamp; @@ -170,6 +174,7 @@ HRESULT CVCamStream::FillBuffer(IMediaSample *pms) duration = time_perframe; } else { int size = pms->GetActualDataLength(); + sleepto(prev_end_ts); memset(dst, 127, size); start_time = prev_end_ts; duration = ((VIDEOINFOHEADER*)m_mt.pbFormat)->AvgTimePerFrame;