From 7487193e0569e9499aea47e10bd3bf413cf59693 Mon Sep 17 00:00:00 2001 From: Catxfish Date: Wed, 25 Sep 2019 00:41:33 +0800 Subject: [PATCH] add buffer timeout event --- src/virtual-source/virtual-audio.cpp | 27 +++++++++++++++++++-- src/virtual-source/virtual-audio.h | 4 +++- src/virtual-source/virtual-cam.cpp | 36 +++++++++++++++++++++++----- src/virtual-source/virtual-cam.h | 2 ++ 4 files changed, 60 insertions(+), 9 deletions(-) diff --git a/src/virtual-source/virtual-audio.cpp b/src/virtual-source/virtual-audio.cpp index 54e0cf2..afd92e7 100644 --- a/src/virtual-source/virtual-audio.cpp +++ b/src/virtual-source/virtual-audio.cpp @@ -68,6 +68,16 @@ HRESULT CVAudioStream::QueryInterface(REFIID riid, void **ppv) return S_OK; } +void CVAudioStream::SetTimeout() +{ + if (queue.header) { + sync_timeout = queue.header->queue_length * AUDIO_SIZE * 10000000 / 44100 * 4; + } + else { + sync_timeout = 10000000; + } +} + HRESULT CVAudioStream::FillBuffer(IMediaSample *pms) { @@ -76,6 +86,7 @@ HRESULT CVAudioStream::FillBuffer(IMediaSample *pms) uint8_t* dst; uint32_t size = 0; uint32_t get_times = 0; + uint64_t current_time = 0; uint64_t timestamp = 0; REFERENCE_TIME start_time = 0; REFERENCE_TIME end_time = 0; @@ -83,11 +94,23 @@ HRESULT CVAudioStream::FillBuffer(IMediaSample *pms) hr = pms->GetPointer((BYTE**)&dst); + current_time = get_current_time(); + + if (prev_end_ts <= 0) + prev_end_ts = current_time; + if (!queue.hwnd) shared_queue_open(&queue, ModeAudio); - if (prev_end_ts <= 0) - prev_end_ts = get_current_time(); + if (sync_timeout <= 0) { + SetTimeout(); + } + else if (current_time - prev_end_ts > sync_timeout) { + if (queue.header) + share_queue_init_index(&queue); + else + prev_end_ts = current_time; + } sleepto(prev_end_ts); diff --git a/src/virtual-source/virtual-audio.h b/src/virtual-source/virtual-audio.h index 2b43437..c27d960 100644 --- a/src/virtual-source/virtual-audio.h +++ b/src/virtual-source/virtual-audio.h @@ -95,16 +95,18 @@ class CVAudioStream : public CSourceStream, public IAMStreamConfig, HRESULT OnThreadCreate(void); HRESULT OnThreadDestroy(void); HRESULT ChangeMediaType(int nMediatype); - HRESULT ResetQueue(); HRESULT Stop(void); HRESULT Pause(void); private: + void SetTimeout(); + CVAudio *parent; share_queue queue; uint64_t obs_start_ts = 0; uint64_t dshow_start_ts = 0; + uint64_t sync_timeout = 0; REFERENCE_TIME prev_end_ts = 0; ALLOCATOR_PROPERTIES alloc_prop; diff --git a/src/virtual-source/virtual-cam.cpp b/src/virtual-source/virtual-cam.cpp index fe27ff7..c0f7a44 100644 --- a/src/virtual-source/virtual-cam.cpp +++ b/src/virtual-source/virtual-cam.cpp @@ -113,6 +113,17 @@ void CVCamStream::SetConvertContext() scale_info.dst_linesize[0] = pvi->bmiHeader.biWidth * 2; } +void CVCamStream::SetTimeout() +{ + if (queue.header) { + sync_timeout = queue.header->queue_length * + queue.header->frame_time / 100; + } + else { + sync_timeout = 10 * ((VIDEOINFOHEADER*)m_mt.pbFormat)->AvgTimePerFrame; + } +} + HRESULT CVCamStream::QueryInterface(REFIID riid, void **ppv) { if (riid == _uuidof(IAMStreamConfig)) @@ -132,21 +143,37 @@ HRESULT CVCamStream::FillBuffer(IMediaSample *pms) bool get_sample = false; int get_times = 0; uint64_t timestamp = 0; + uint64_t current_time = 0; REFERENCE_TIME start_time = 0; REFERENCE_TIME end_time = 0; REFERENCE_TIME duration = 0; hr = pms->GetPointer((BYTE**)&dst); + current_time = get_current_time(); + + if (prev_end_ts <= 0) + prev_end_ts = current_time; + if (!queue.hwnd) { if (shared_queue_open(&queue, queue_mode)) { shared_queue_get_video_format(queue_mode, &format, &frame_width, &frame_height, &time_perframe); SetConvertContext(); - reset_mode = false; + sync_timeout = 0; } } + if (sync_timeout <= 0) { + SetTimeout(); + } + else if (current_time - prev_end_ts > sync_timeout) { + if(queue.header) + share_queue_init_index(&queue); + else + prev_end_ts = current_time; + } + while (queue.header && !get_sample) { if (get_times > 20 || queue.header->state != OutputReady) @@ -160,9 +187,6 @@ HRESULT CVCamStream::FillBuffer(IMediaSample *pms) get_times++; } } - - if (prev_end_ts <= 0) - prev_end_ts = get_current_time(); if (get_sample && !obs_start_ts) { obs_start_ts = timestamp; @@ -180,11 +204,11 @@ HRESULT CVCamStream::FillBuffer(IMediaSample *pms) duration = ((VIDEOINFOHEADER*)m_mt.pbFormat)->AvgTimePerFrame; } - if (queue.header && queue.header->state == OutputStop || reset_mode || - get_times > 20) { + if (queue.header && queue.header->state == OutputStop || get_times > 20) { shared_queue_read_close(&queue, &scale_info); dshow_start_ts = 0; obs_start_ts = 0; + sync_timeout = 0; } end_time = start_time + duration; diff --git a/src/virtual-source/virtual-cam.h b/src/virtual-source/virtual-cam.h index 853c9cd..a30e5ba 100644 --- a/src/virtual-source/virtual-cam.h +++ b/src/virtual-source/virtual-cam.h @@ -108,6 +108,7 @@ class CVCamStream : public CSourceStream, public IAMStreamConfig, public IKsProp bool ListSupportFormat(void); bool CheckObsSetting(void); bool ValidateResolution(long width, long height); + void SetTimeout(); void SetConvertContext(void); CVCam *parent; @@ -124,6 +125,7 @@ class CVCamStream : public CSourceStream, public IAMStreamConfig, public IKsProp uint64_t obs_start_ts = 0; uint64_t dshow_start_ts = 0; uint64_t time_perframe = 0; + uint64_t sync_timeout = 0; REFERENCE_TIME prev_end_ts = 0; //obs format related