Skip to content
This repository was archived by the owner on Mar 15, 2021. It is now read-only.

Commit

Permalink
change directshow resolution support
Browse files Browse the repository at this point in the history
  • Loading branch information
CatxFish committed Jul 23, 2017
1 parent bc28b28 commit 1c12049
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 33 deletions.
15 changes: 14 additions & 1 deletion src/queue/share_queue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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:
Expand Down
3 changes: 3 additions & 0 deletions src/queue/share_queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
3 changes: 1 addition & 2 deletions src/virtual-source/dllmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
6 changes: 2 additions & 4 deletions src/virtual-source/virtual-audio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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;
Expand Down
63 changes: 39 additions & 24 deletions src/virtual-source/virtual-cam.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand All @@ -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){
Expand All @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);
Expand Down
8 changes: 6 additions & 2 deletions src/virtual-source/virtual-cam.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
extern "C"
{
#include "libswscale/swscale.h"
#include "libswresample/swresample.h"
};

#include "../queue/share_queue.h"
Expand All @@ -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);

};
Expand Down Expand Up @@ -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);


Expand All @@ -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;
};

0 comments on commit 1c12049

Please sign in to comment.