Skip to content

Commit

Permalink
Change to Unicode
Browse files Browse the repository at this point in the history
Change project to Unicode for wide character folder name support
FillBuffer correct cast for TimeGetTime calculations
Use TimeBeginPeriod for maximum precision of TimeGetTime and Sleep
DirectX device not required - in SpoutDX class.
Do not go to static on first DirectX initialize.
Verson 2.023
  • Loading branch information
leadedge committed Oct 17, 2020
1 parent a12f2f3 commit 71dbc11
Show file tree
Hide file tree
Showing 11 changed files with 144 additions and 134 deletions.
19 changes: 6 additions & 13 deletions SpoutCamDX.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,23 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
Expand Down Expand Up @@ -114,9 +114,6 @@
<PostBuildEvent>
<Command>copy /y $(TargetPath) release\win32\SpoutCam32.ax</Command>
</PostBuildEvent>
<Manifest>
<EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
Expand Down Expand Up @@ -144,11 +141,10 @@
</Link>
<PostBuildEvent>
<Command>copy /y $(TargetPath) release\win32\SpoutCam32.ax


</Command>
</PostBuildEvent>
<Manifest>
<EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
Expand Down Expand Up @@ -193,9 +189,6 @@
<PostBuildEvent>
<Command>copy /y $(TargetPath) release\x64\SpoutCam64.ax</Command>
</PostBuildEvent>
<Manifest>
<EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness>
</Manifest>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="source\cam.cpp" />
Expand Down
8 changes: 4 additions & 4 deletions SpoutDX/winproj2017/SpoutDX.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -50,27 +50,27 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
Expand Down
1 change: 1 addition & 0 deletions baseclasses/winproj2017/BaseClasses.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
Expand Down
Binary file modified release/win32/SpoutCam32.ax
Binary file not shown.
Binary file modified release/x64/SpoutCam64.ax
Binary file not shown.
143 changes: 78 additions & 65 deletions source/cam.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,12 @@
Returned to timing by RED5
Conditional receive if DirectX initialization failed
Version 2.022
16.10.20 FillBuffer correct cast for TimeGetTime calculations
Use TimeBeginPeriod for maximum precision of TimeGetTime and Sleep
DirectX device not required - in SpoutDX class.
Do not go to static on first DirectX initialize.
17.10.20 Change to Unicode for WCHAR folder name support
Verson 2.023
*/

Expand Down Expand Up @@ -293,7 +299,7 @@ CUnknown * WINAPI CVCam::CreateInstance(LPUNKNOWN lpunk, HRESULT *phr)
// debug console window
// OpenSpoutConsole(); // Empty console
// EnableSpoutLog(); // Show error logs
// printf("SpoutCamDX ~~ Vers 2.021\n");
// printf("SpoutCamDX ~~ Vers 2.023\n");

// For clear options dialog for scaled display
SetProcessDPIAware();
Expand Down Expand Up @@ -512,7 +518,6 @@ HRESULT CVCamStream::put_Settings(DWORD dwFps, DWORD dwResolution, DWORD dwMirro
CVCamStream::CVCamStream(HRESULT *phr, CVCam *pParent, LPCWSTR pPinName) :
CSourceStream(NAME(SPOUTCAMNAME), phr, pParent, pPinName), m_pParent(pParent) //VS: replaced SpoutCamName with makro SPOUTCAMNAME, NAME() expects LPCTSTR
{
g_pd3dDevice = nullptr;
bDXinitialized = false; // DirectX
bMemoryMode = false; // Default mode is texture, true means memoryshare
bInvert = true; // Not currently used
Expand All @@ -521,6 +526,10 @@ CVCamStream::CVCamStream(HRESULT *phr, CVCam *pParent, LPCWSTR pPinName) :
g_Height = 480;
g_SenderName[0] = 0;
g_ActiveSender[0] = 0;

// Maximum precision of timeGetTime used in FillBuffer
timeGetDevCaps(&g_caps, sizeof(g_caps));
timeBeginPeriod(g_caps.wPeriodMin);

//
// Retrieve fps and resolution from registry "SpoutCamConfig"
Expand Down Expand Up @@ -717,6 +726,10 @@ CVCamStream::~CVCamStream()

if (bDXinitialized)
receiver.CleanupDX11();

// End timer precision
timeEndPeriod(g_caps.wPeriodMin);

}

HRESULT CVCamStream::QueryInterface(REFIID riid, void **ppv)
Expand Down Expand Up @@ -753,7 +766,7 @@ HRESULT CVCamStream::FillBuffer(IMediaSample *pms)
HRESULT hr = S_OK;
BYTE *pData = nullptr;

VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER *) m_mt.Format();
VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER *)m_mt.Format();

// If graph is inactive stop cueing samples
if(!m_pParent->IsActive()) {
Expand All @@ -763,66 +776,69 @@ HRESULT CVCamStream::FillBuffer(IMediaSample *pms)
// Memory share mode not supported by DirectX
if (bMemoryMode)
return FALSE;

/*

//
// Timing - modified from Red5 method
//
// Simple timing modifed from original Vcam
// https://github.com/johnmaccormick/MultiCam/blob/master/vcam/Filters.cpp
// Causes hesitations in some software
REFERENCE_TIME rtNow;
REFERENCE_TIME avgFrameTime = ((VIDEOINFOHEADER*)m_mt.pbFormat)->AvgTimePerFrame;
rtNow = m_rtLastTime;
m_rtLastTime += avgFrameTime;
pms->SetTime(&rtNow, &m_rtLastTime);
pms->SetSyncPoint(TRUE);
*/

// Timing from Red 5
// Seems stable for more applications
// Set the timestamps that will govern playback frame rate.
// The current time is the sample's start.
REFERENCE_TIME rtNow = m_rtLastTime;
REFERENCE_TIME avgFrameTime = g_FrameTime; // Desired average frame time is set by the user

//create some working info
REFERENCE_TIME rtNow, rtDelta, rtDelta2 = 0;//delta for dropped, delta 2 for sleep.
REFERENCE_TIME avgFrameTime = ((VIDEOINFOHEADER*)m_mt.pbFormat)->AvgTimePerFrame;
// Create some working info
REFERENCE_TIME rtDelta, rtDelta2 = 0LL; // delta for dropped, delta 2 for sleep.

//What TIme is iT REALLY???
//
// What time is it REALLY ???
//
m_pParent->GetSyncSource(&m_pClock);

m_pClock->GetTime(&refSync1);
if (m_pClock)
if (m_pClock) {
m_pClock->GetTime(&refSync1);
m_pClock->Release();
if (NumFrames <= 1)
{//initiate values
refStart = refSync1;//FirstFrame No Drop.
refSync2 = 0;
}
else {
// Some programs do not implement the DirectShow clock and can crash if assumed
// so we can use TimeGetTime instead. Only millisecond precision, but so is Sleep.
refSync1 = (REFERENCE_TIME)timeGetTime() * 10000LL; // Cast before the multiply to avoid overflow
}

if (NumFrames <= 1) {
// initiate values
refStart = refSync1; // FirstFrame No Drop
refSync2 = 0;
}

rtNow = m_rtLastTime;
m_rtLastTime = avgFrameTime + m_rtLastTime;

//IAMDropppedFrame. We only have avgFrameTime to generate image.
// Find generated stream time and compare to real elapsed time
// IAMDropppedFrame. We only have avgFrameTime to generate image.
// Find generated stream time and compare to real elapsed time.
rtDelta = ((refSync1 - refStart) - (((NumFrames)*avgFrameTime) - avgFrameTime));

if (rtDelta - refSync2 < 0)
{//we are early
if (rtDelta - refSync2 < 0) {
// we are early
rtDelta2 = rtDelta - refSync2;
if (abs(rtDelta2 / 10000) >= 1)
Sleep(abs(rtDelta2 / 10000));
DWORD dwSleep = (DWORD)abs(rtDelta2 / 10000LL);
if (dwSleep >= 1)
Sleep(dwSleep);
}
else if (rtDelta / avgFrameTime > NumDroppedFrames)
{ //new dropped frame
else if (rtDelta / avgFrameTime > NumDroppedFrames) {
// new dropped frame
NumDroppedFrames = rtDelta / avgFrameTime;
// Figure new RT for sleeping
refSync2 = NumDroppedFrames * avgFrameTime;
//Our time stamping needs adjustment.
//Find total real stream time from start time
// Our time stamping needs adjustment.
// Find total real stream time from start time.
rtNow = refSync1 - refStart;
m_rtLastTime = rtNow + avgFrameTime;
pms->SetDiscontinuity(true);
}
pms->SetTime(&rtNow, &m_rtLastTime);
pms->SetSyncPoint(TRUE);

// The SetTime method sets the stream times when this sample should begin and finish.
hr = pms->SetTime(&rtNow, &m_rtLastTime);
// Set true on every sample for uncompressed frames
hr = pms->SetSyncPoint(true);
// ============== END OF INITIAL TIMING ============

// Check access to the sample's data buffer
pms->GetPointer(&pData);
Expand All @@ -838,7 +854,6 @@ HRESULT CVCamStream::FillBuffer(IMediaSample *pms)
return NOERROR;
}


// Sizes should be OK, but check again
unsigned int size = (unsigned int)pms->GetSize();
// TODO : check imagesize = width*height*3;
Expand All @@ -859,32 +874,31 @@ HRESULT CVCamStream::FillBuffer(IMediaSample *pms)
if (!receiver.OpenDirectX11()) {
return NOERROR;
}
g_pd3dDevice = receiver.GetDevice();
bDXinitialized = true;
} // endif !bDXinitialized
else {
// Get bgr pixels from the sender bgra shared texture
// ReceiveImage handles sender detection, connection and copy of pixels
if (receiver.ReceiveImage(pData, g_Width, g_Height, true, bInvert)) {
// rgb(not rgba) = true, invert = true
// If IsUpdated() returns true, the sender has changed
if (receiver.IsUpdated()) {
if (strcmp(g_SenderName, receiver.GetSenderName()) != 0) {
// Only test for change of sender name.
// The pixel buffer (pData) remains the same size and
// ReceiveImage uses resampling for a different texture size
strcpy_s(g_SenderName, 256, receiver.GetSenderName());
// Set the sender name to the registry for SpoutCamSettings
WritePathToRegistry(HKEY_CURRENT_USER, "Software\\Leading Edge\\SpoutCam", "sendername", g_SenderName);
}

// DirectX is initialized OK
// Get bgr pixels from the sender bgra shared texture
// ReceiveImage handles sender detection, connection and copy of pixels
if (receiver.ReceiveImage(pData, g_Width, g_Height, true, bInvert)) {
// rgb(not rgba) = true, invert = true
// If IsUpdated() returns true, the sender has changed
if (receiver.IsUpdated()) {
if (strcmp(g_SenderName, receiver.GetSenderName()) != 0) {
// Only test for change of sender name.
// The pixel buffer (pData) remains the same size and
// ReceiveImage uses resampling for a different texture size
strcpy_s(g_SenderName, 256, receiver.GetSenderName());
// Set the sender name to the registry for SpoutCamSettings
WritePathToRegistry(HKEY_CURRENT_USER, "Software\\Leading Edge\\SpoutCam", "sendername", g_SenderName);
}
bInitialized = true;
NumFrames++;
return NOERROR;
}
else {
ReleaseCamReceiver();
}
bInitialized = true;
NumFrames++;
return NOERROR;
}
else {
ReleaseCamReceiver();
}

ShowStatic :
Expand Down Expand Up @@ -989,7 +1003,6 @@ HRESULT CVCamStream::GetMediaType(int iPosition, CMediaType *pmt)
const GUID SubTypeGUID = GetBitmapSubtype(&pvi->bmiHeader);
pmt->SetSubtype(&SubTypeGUID);
pmt->SetVariableSize(); // LJ - to be checked

pmt->SetSampleSize(pvi->bmiHeader.biSizeImage);

return NOERROR;
Expand Down
7 changes: 6 additions & 1 deletion source/cam.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@
#include "..\SpoutDX\source\SpoutDX.h"
#include <streams.h>

// LJ DEBUG
#include <chrono>
#include <thread>
using namespace std::chrono_literals;

//<==================== VS-START ====================>
#include "dshowutil.h"

Expand Down Expand Up @@ -210,7 +215,6 @@ class CVCamStream : public CSourceStream, public IAMStreamConfig, public IKsProp

char g_SenderName[256];
char g_ActiveSender[256]; // The name of any Spout sender being received
ID3D11Device* g_pd3dDevice; // DirectX 11.0 device pointer
bool bMemoryMode; // true = memory, false = texture
bool bInvert;
bool bInitialized;
Expand All @@ -222,6 +226,7 @@ class CVCamStream : public CSourceStream, public IAMStreamConfig, public IKsProp
DWORD dwFps; // Fps from SpoutCamConfig
DWORD dwResolution; // Resolution from SpoutCamConfig
int g_FrameTime; // Frame time to use based on fps selection
TIMECAPS g_caps; // Timer capability for Sleep precision

private:

Expand Down
Loading

0 comments on commit 71dbc11

Please sign in to comment.