diff --git a/src/queue/share_queue.cpp b/src/queue/share_queue.cpp index ab29496..a5e0b16 100644 --- a/src/queue/share_queue.cpp +++ b/src/queue/share_queue.cpp @@ -172,6 +172,19 @@ bool share_queue_init_index(share_queue* q) return true; } +bool shared_queue_get_video_format(share_queue* q,int* format ,int* width, + int* height, int64_t* avgtime) +{ + if (!q || !q->header) + return false; + + *format = q->header->format; + *width = q->header->frame_width; + *height = q->header->frame_height; + *avgtime = (q->header->frame_time)/100; + return true; +} + bool shared_queue_get_video(share_queue* q, uint8_t** data, uint32_t*linesize, uint64_t* timestamp) { @@ -251,7 +264,7 @@ bool shared_queue_push_video(share_queue* q, uint32_t* linesize, uint8_t* buff = (uint8_t*)q->header + offset; frame_header* head = (frame_header*)buff; uint8_t* data = (uint8_t*)buff + q->header->element_header_size; - uint32_t planes = 0; + int planes = 0; switch (q->header->format) { case AV_PIX_FMT_NONE: diff --git a/src/queue/share_queue.h b/src/queue/share_queue.h index d3327c1..206e9b5 100644 --- a/src/queue/share_queue.h +++ b/src/queue/share_queue.h @@ -65,6 +65,9 @@ bool shared_queue_open(share_queue* q, int mode); void shared_queue_close(share_queue* q); bool shared_queue_check(int mode); bool shared_queue_set_delay(share_queue* q, int delay_video_frame); +bool share_queue_init_index(share_queue* q); +bool shared_queue_get_video_format(share_queue* q, int* format, int* width, + int* height, int64_t* avgtime); bool shared_queue_get_video(share_queue* q, uint8_t** dst_ptr, uint32_t*linesize, uint64_t* timestamp); bool shared_queue_push_video(share_queue* q, uint32_t* linesize, diff --git a/src/virtual-source/dllmain.cpp b/src/virtual-source/dllmain.cpp index cec5736..dc12182 100644 --- a/src/virtual-source/dllmain.cpp +++ b/src/virtual-source/dllmain.cpp @@ -149,8 +149,7 @@ STDAPI RegisterFilters(BOOL bRegister) fm->Release(); } - if (SUCCEEDED(hr) && !bRegister) - { + if (SUCCEEDED(hr) && !bRegister){ hr = AMovieSetupUnregisterServer(CLSID_OBS_VirtualA); hr = AMovieSetupUnregisterServer(CLSID_OBS_VirtualV); } diff --git a/src/virtual-source/virtual-audio.cpp b/src/virtual-source/virtual-audio.cpp index 1d5e55b..f6d32ab 100644 --- a/src/virtual-source/virtual-audio.cpp +++ b/src/virtual-source/virtual-audio.cpp @@ -182,9 +182,8 @@ HRESULT CVAudioStream::CheckMediaType(const CMediaType *pMediaType) { WAVEFORMATEX *paf = (WAVEFORMATEX *)(pMediaType->Format()); if (*pMediaType != m_mt) - { return E_INVALIDARG; - } + return S_OK; } @@ -197,8 +196,7 @@ HRESULT CVAudioStream::DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERT CheckPointer(pProperties, E_POINTER); WAVEFORMATEX* pwfex = (WAVEFORMATEX*)m_mt.Format(); - if (pwfex) - { + if (pwfex){ pProperties->cBuffers = 1; pProperties->cbBuffer = AUDIO_BUFFER_SIZE; diff --git a/src/virtual-source/virtual-cam.cpp b/src/virtual-source/virtual-cam.cpp index 8349a03..55e3575 100644 --- a/src/virtual-source/virtual-cam.cpp +++ b/src/virtual-source/virtual-cam.cpp @@ -77,15 +77,15 @@ HRESULT CVCamStream::FillBuffer(IMediaSample *pms) uint64_t timestamp=0; REFERENCE_TIME start_time=0; REFERENCE_TIME end_time = 0; + REFERENCE_TIME duration = 0; hr = pms->GetPointer((BYTE**)&dst[0]); if (!queue.hwnd){ if (shared_queue_open(&queue, ModeVideo)){ - int format = queue.header->format; - int width = queue.header->frame_width; - int height = queue.header->frame_height; - SetConvertContext(width, height, (AVPixelFormat)format); + shared_queue_get_video_format(&queue, &format, &frame_width, + &frame_height, &time_perframe); + SetConvertContext(frame_width, frame_height, (AVPixelFormat)format); } } @@ -112,12 +112,15 @@ HRESULT CVCamStream::FillBuffer(IMediaSample *pms) dshow_start_ts = prev_end_ts; } - if (get_sample) + if (get_sample){ start_time = dshow_start_ts + (timestamp - obs_start_ts) / 100; + duration = time_perframe; + } else{ int size = pms->GetActualDataLength(); memset(dst[0], 127, size); start_time = prev_end_ts; + duration = ((VIDEOINFOHEADER*)m_mt.pbFormat)->AvgTimePerFrame; } if (queue.header && queue.header->state == OutputStop || get_times > 20){ @@ -127,8 +130,7 @@ HRESULT CVCamStream::FillBuffer(IMediaSample *pms) obs_start_ts = 0; } - REFERENCE_TIME avg_time= ((VIDEOINFOHEADER*)m_mt.pbFormat)->AvgTimePerFrame; - end_time = start_time + avg_time; + end_time = start_time + duration; prev_end_ts = end_time; pms->SetTime(&start_time, &end_time); pms->SetSyncPoint(TRUE); @@ -165,12 +167,15 @@ HRESULT CVCamStream::GetMediaType(int iPosition,CMediaType *pmt) case 1: pvi->bmiHeader.biWidth = 1280; pvi->bmiHeader.biHeight = 720; + break; case 2: pvi->bmiHeader.biWidth = 960; pvi->bmiHeader.biHeight = 540; + break; case 3: pvi->bmiHeader.biWidth = 640; pvi->bmiHeader.biHeight = 360; + break; } pvi->AvgTimePerFrame = 333333; @@ -214,16 +219,26 @@ HRESULT CVCamStream::CheckMediaType(const CMediaType *pMediaType) if (pvi->AvgTimePerFrame < 166666 || pvi->AvgTimePerFrame >1000000) return E_INVALIDARG; - if (pvi->bmiHeader.biWidth == 1920 && pvi->bmiHeader.biHeight == 1080 || - pvi->bmiHeader.biWidth == 1280 && pvi->bmiHeader.biHeight == 720 || - pvi->bmiHeader.biWidth == 960 && pvi->bmiHeader.biHeight == 540 || - pvi->bmiHeader.biWidth == 640 && pvi->bmiHeader.biHeight == 360 - ) - return S_OK; + if (ValidateResolution(pvi->bmiHeader.biWidth, pvi->bmiHeader.biHeight)) + return S_OK; return E_INVALIDARG; } +bool CVCamStream::ValidateResolution(long width,long height) +{ + if (width < 320 || height <240) + return false; + else if (width > 4096) + return false; + else if (width * 9 == height * 16) + return true; + else if (width * 3 == height * 4) + return true; + else + return false; +} + HRESULT CVCamStream::DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pProperties) { @@ -262,21 +277,21 @@ HRESULT CVCamStream::OnThreadDestroy() HRESULT STDMETHODCALLTYPE CVCamStream::SetFormat(AM_MEDIA_TYPE *pmt) { - if (CheckMediaType((CMediaType *)pmt) != S_OK) { + if (parent->GetState() != State_Stopped) return E_FAIL; - } - VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER *)(pmt->pbFormat); + if (CheckMediaType((CMediaType *)pmt) != S_OK) + return E_FAIL; - if (pvi->bmiHeader.biWidth == 1920 && pvi->bmiHeader.biHeight == 1080) - GetMediaType(0, &m_mt); - else if(pvi->bmiHeader.biWidth == 1280 && pvi->bmiHeader.biHeight == 720) - GetMediaType(1, &m_mt); - else if (pvi->bmiHeader.biWidth == 960 && pvi->bmiHeader.biHeight == 540) - GetMediaType(2, &m_mt); - else if (pvi->bmiHeader.biWidth == 640 && pvi->bmiHeader.biHeight == 360) - GetMediaType(3, &m_mt); + VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER *)(pmt->pbFormat); + VIDEOINFOHEADER *pvi_src = (VIDEOINFOHEADER *)m_mt.Format(); + pvi_src->bmiHeader.biWidth = pvi->bmiHeader.biWidth; + pvi_src->bmiHeader.biHeight = pvi->bmiHeader.biHeight; + pvi_src->bmiHeader.biSizeImage = pvi->bmiHeader.biWidth* + pvi->bmiHeader.biHeight * 2; + pvi_src->AvgTimePerFrame = pvi->AvgTimePerFrame; + m_mt.SetSampleSize(pvi_src->bmiHeader.biSizeImage); IPin* pin; ConnectedTo(&pin); diff --git a/src/virtual-source/virtual-cam.h b/src/virtual-source/virtual-cam.h index 81000c6..0230c5c 100644 --- a/src/virtual-source/virtual-cam.h +++ b/src/virtual-source/virtual-cam.h @@ -3,7 +3,6 @@ extern "C" { #include "libswscale/swscale.h" -#include "libswresample/swresample.h" }; #include "../queue/share_queue.h" @@ -24,6 +23,7 @@ class CVCam : public CSource static CUnknown * WINAPI CreateInstance(LPUNKNOWN lpunk, HRESULT *phr); STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv); IFilterGraph *GetGraph() { return m_pGraph; } + FILTER_STATE GetState(){ return m_State; } CVCam(LPUNKNOWN lpunk, HRESULT *phr); }; @@ -79,8 +79,8 @@ class CVCamStream : public CSourceStream, public IAMStreamConfig,public IKsPrope HRESULT SetMediaType(const CMediaType *pmt); HRESULT OnThreadCreate(void); HRESULT OnThreadDestroy(void); - HRESULT ChangeMediaType(int nMediatype); + bool ValidateResolution(long width, long height); void SetConvertContext(int width, int height, AVPixelFormat fotmat); @@ -94,5 +94,9 @@ class CVCamStream : public CSourceStream, public IAMStreamConfig,public IKsPrope uint8_t* dst[1]; uint32_t linesize[8]; uint32_t dst_linesize[1]; + int format = 0; + int frame_width = 0; + int frame_height = 0; + int64_t time_perframe = 0; struct SwsContext *convert_ctx = nullptr; };