Skip to content

Commit 2737244

Browse files
committed
Added more windows support
1 parent c7f4269 commit 2737244

25 files changed

+672
-896
lines changed

Example/Screen_Capture_Example.cpp

+6-8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include "ScreenCaptureManager.h"
1+
#include "ScreenCapture.h"
22
#include <iostream>
33
#include <chrono>
44
#include <atomic>
@@ -14,15 +14,15 @@ int main()
1414
realcounter = 0;
1515
SL::Screen_Capture::ScreenCaptureManager framgrabber;
1616
SL::Screen_Capture::ImageCallback func = [&](const SL::Screen_Capture::CapturedImage& img) {
17-
if (img.ScreenIndex != 0) return;
18-
std::cout << "ScreenIndex " << img.ScreenIndex<<" Height " << img.Height << ", Width " << img.Width << ", Top " << img.AbsoluteTop << ", Left " << img.AbsoluteLeft << std::endl;
17+
18+
std::cout << "ScreenIndex " << img.ScreenIndex<<" Height " << img.Height << ", Width " << img.Width << ", OffsetY " << img.OffsetY << ", Offsetx " << img.Offsetx << std::endl;
1919
auto r = realcounter.fetch_add(1);
2020
std::string s;
21-
s += std::to_string(r) + std::string(" ") + std::to_string(img.AbsoluteTop) + std::string(",") + std::to_string(img.AbsoluteLeft) +std::string(" ") + std::string(".jpg");
21+
s += std::to_string(r) + std::string(" ") + std::to_string(img.OffsetY) + std::string(",") + std::to_string(img.Offsetx) +std::string(" ") + std::string(".jpg");
2222

23-
if (!tje_encode_to_file(s.c_str(), img.Width, img.Height, 4, (const unsigned char*)img.Data.get())) {
23+
/*if (!tje_encode_to_file(s.c_str(), img.Width, img.Height, 4, (const unsigned char*)img.Data.get())) {
2424
std::cout << "Could not write JPEG\n";
25-
}
25+
}*/
2626

2727
};
2828
framgrabber.StartCapturing(func, 100);
@@ -32,8 +32,6 @@ int main()
3232
}
3333

3434
framgrabber.StopCapturing();
35-
int k = 0;
36-
std::cin >> k;
3735
return 0;
3836
}
3937

include/ScreenCapture.h

+14-22
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,33 @@
22
#include <memory>
33
#include <functional>
44
#include <vector>
5+
#include <atomic>
56

67
namespace SL {
78
namespace Screen_Capture {
89
struct CapturedImage {
910
std::shared_ptr<char> Data;
1011
int Height = 0;
1112
int Width = 0;
12-
int RelativeTop = 0;
13-
int RelativeLeft = 0;
14-
int AbsoluteTop = 0;
15-
int AbsoluteLeft = 0;
13+
//Offset numbers are the number of pixels of offset within the current monitor
14+
int Offsetx = 0;
15+
int OffsetY = 0;
16+
1617
int ScreenIndex;
1718
const int PixelStride = 4;//in bytes
1819
};
1920
struct Monitor{
2021
int Index;
2122
int Height;
2223
int Width;
24+
//Offsets are the number of pixels that a monitor can be from the origin. For example, users can shuffle their monitors around so this affects their offset.
25+
int OffsetX;
26+
int OffsetY;
27+
std::string Name;
2328
};
2429
std::vector<Monitor> GetMonitors();
2530
typedef std::function<void(const CapturedImage& img)> ImageCallback;
26-
enum DUPL_RETURN
27-
{
28-
DUPL_RETURN_SUCCESS = 0,
29-
DUPL_RETURN_ERROR_EXPECTED = 1,
30-
DUPL_RETURN_ERROR_UNEXPECTED = 2
31-
};
31+
3232

3333
class ScreenCaptureManagerImpl;
3434
class ScreenCaptureManager {
@@ -39,17 +39,9 @@ namespace SL {
3939
~ScreenCaptureManager();
4040
void StartCapturing(ImageCallback img_cb, int min_interval);
4141
void StopCapturing();
42-
};
43-
struct THREAD_DATA
44-
{
45-
// Used to indicate abnormal error condition
46-
std::shared_ptr<std::atomic_bool> UnexpectedErrorEvent;
47-
// Used to indicate a transition event occurred e.g. PnpStop, PnpStart, mode change, TDR, desktop switch and the application needs to recreate the duplication interface
48-
std::shared_ptr<std::atomic_bool> ExpectedErrorEvent;
49-
// Used by WinProc to signal to threads to exit
50-
std::shared_ptr<std::atomic_bool> TerminateThreadsEvent;
51-
Monitor SelectedMonitor;
52-
ImageCallback CallBack;
53-
};
42+
};
43+
44+
45+
5446
}
5547
}

include/ThreadManager.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22
#include "ScreenCapture.h"
3+
#include "ThreadRunner.h"
34
#include <thread>
45
#include <vector>
56
#include <atomic>
@@ -17,7 +18,7 @@ namespace SL {
1718
public:
1819
ThreadManager();
1920
~ThreadManager();
20-
DUPL_RETURN Init(std::shared_ptr<std::atomic_bool>& unexpected, std::shared_ptr<std::atomic_bool>& expected, std::shared_ptr<std::atomic_bool>& terminate, ImageCallback& CallBack);
21+
void Init(std::shared_ptr<std::atomic_bool>& unexpected, std::shared_ptr<std::atomic_bool>& expected, std::shared_ptr<std::atomic_bool>& terminate, ImageCallback& CallBack, int mininterval);
2122
void Join();
2223
void Reset();
2324
};

include/ThreadRunner.h

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#pragma once
2+
#include "ScreenCapture.h"
3+
#include <memory>
4+
#include <atomic>
5+
6+
namespace SL {
7+
namespace Screen_Capture {
8+
9+
struct THREAD_DATA
10+
{
11+
// Used to indicate abnormal error condition
12+
std::shared_ptr<std::atomic_bool> UnexpectedErrorEvent;
13+
// Used to indicate a transition event occurred e.g. PnpStop, PnpStart, mode change, TDR, desktop switch and the application needs to recreate the duplication interface
14+
std::shared_ptr<std::atomic_bool> ExpectedErrorEvent;
15+
// Used by WinProc to signal to threads to exit
16+
std::shared_ptr<std::atomic_bool> TerminateThreadsEvent;
17+
Monitor SelectedMonitor;
18+
int CaptureInterval; //in milliseconds
19+
ImageCallback CallBack;
20+
};
21+
void RunCapture(std::shared_ptr<THREAD_DATA> data);
22+
23+
}
24+
}

include/windows/CommonTypes.h renamed to include/windows/DXCommon.h

+8-4
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,16 @@ namespace SL {
6060
DirectX::XMFLOAT2 TexCoord;
6161
};
6262

63+
enum DUPL_RETURN
64+
{
65+
DUPL_RETURN_SUCCESS = 0,
66+
DUPL_RETURN_ERROR_EXPECTED = 1,
67+
DUPL_RETURN_ERROR_UNEXPECTED = 2
68+
};
6369

6470
DUPL_RETURN ProcessFailure(ID3D11Device* Device, LPCWSTR Str, LPCWSTR Title, HRESULT hr, HRESULT* ExpectedErrors = nullptr);
65-
#define RAIIHDC(handle) std::unique_ptr<std::remove_pointer<HDC>::type, decltype(&::DeleteDC)>(handle, &::DeleteDC)
66-
#define RAIIHBITMAP(handle) std::unique_ptr<std::remove_pointer<HBITMAP>::type, decltype(&::DeleteObject)>(handle, &::DeleteObject)
67-
#define RAIIHANDLE(handle) std::unique_ptr<std::remove_pointer<HANDLE>::type, decltype(&::CloseHandle)>(handle, &::CloseHandle)
68-
71+
DUPL_RETURN DesktopDuplicationSupported();
72+
DUPL_RETURN Initialize(DX_RESOURCES& r);
6973

7074
}
7175
}

include/windows/DXDuplicationManager.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
// Copyright (c) Microsoft Corporation. All rights reserved
77

88
#pragma once
9-
#include "CommonTypes.h"
9+
#include "DXCommon.h"
1010
#include <memory>
1111
namespace SL {
1212
namespace Screen_Capture {
@@ -18,7 +18,6 @@ namespace SL {
1818
DUPL_RETURN GetFrame(FRAME_DATA* Data, bool* Timeout);
1919
DUPL_RETURN DoneWithFrame();
2020
DUPL_RETURN InitDupl(ID3D11Device* Device, UINT Output);
21-
DUPL_RETURN GetMouse(PTR_INFO* PtrInfo, DXGI_OUTDUPL_FRAME_INFO* FrameInfo);
2221
void GetOutputDesc(DXGI_OUTPUT_DESC* DescPtr);
2322

2423
private:

include/windows/DXFrameProcessor.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
#pragma once
2-
#include "CommonTypes.h"
2+
#include "ScreenCapture.h"
3+
#include "DXCommon.h"
34
#include <memory>
45

56
namespace SL {
67
namespace Screen_Capture {
78

89
class DXFrameProcessor {
910
public:
10-
DXFrameProcessor();
11+
DXFrameProcessor(DX_RESOURCES& Data, ImageCallback& cb);
1112
~DXFrameProcessor();
12-
void InitD3D(THREAD_DATA* Data);
13-
void CleanRefs();
13+
1414
DUPL_RETURN ProcessFrame(FRAME_DATA* Data, DXGI_OUTPUT_DESC* DeskDesc);
1515

1616
private:

include/windows/DXThread.h

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#pragma once
2+
#include "ThreadRunner.h"
3+
4+
namespace SL {
5+
namespace Screen_Capture {
6+
7+
void DXThread(std::shared_ptr<THREAD_DATA> data);
8+
}
9+
}

include/windows/DXThreadManager.h

-30
This file was deleted.

include/windows/GDIThread.h

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#pragma once
2+
#include "ThreadRunner.h"
3+
4+
namespace SL {
5+
namespace Screen_Capture {
6+
7+
void GDIThread(std::shared_ptr<THREAD_DATA> data);
8+
}
9+
}

include/windows/ScreenCaptureWindows.h

-16
This file was deleted.

lib/CMakeLists.txt

+9-7
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,18 @@ project(Screen_Capturelib)
22

33
if(WIN32)
44
set(SCREEN_CAPTURE_PLATFORM_SRC
5-
${Screen_Capture_SOURCE_DIR}/include/windows/ScreenCaptureWindows.h
6-
${Screen_Capture_SOURCE_DIR}/src/windows/ScreenCaptureWindows.cpp
5+
${Screen_Capture_SOURCE_DIR}/src/windows/GetMonitors.cpp
76
${Screen_Capture_SOURCE_DIR}/include/windows/DXDuplicationManager.h
87
${Screen_Capture_SOURCE_DIR}/src/windows/DXDuplicationManager.cpp
98
${Screen_Capture_SOURCE_DIR}/include/windows/DXFrameProcessor.h
109
${Screen_Capture_SOURCE_DIR}/src/windows/DXFrameProcessor.cpp
11-
${Screen_Capture_SOURCE_DIR}/include/windows/DXThreadManager.h
12-
${Screen_Capture_SOURCE_DIR}/src/windows/DXThreadManager.cpp
13-
${Screen_Capture_SOURCE_DIR}/src/windows/ScreenCaptureGDI.cpp
14-
${Screen_Capture_SOURCE_DIR}/include/windows/CommonTypes.h
15-
${Screen_Capture_SOURCE_DIR}/src/windows/CommonTypes.cpp
10+
${Screen_Capture_SOURCE_DIR}/include/windows/DXThread.h
11+
${Screen_Capture_SOURCE_DIR}/src/windows/DXThread.cpp
12+
${Screen_Capture_SOURCE_DIR}/src/windows/GDIThread.cpp
13+
${Screen_Capture_SOURCE_DIR}/include/windows/GDIThread.h
14+
${Screen_Capture_SOURCE_DIR}/include/windows/DXCommon.h
15+
${Screen_Capture_SOURCE_DIR}/src/windows/DXCommon.cpp
16+
${Screen_Capture_SOURCE_DIR}/src/windows/ThreadRunner.cpp
1617
${Screen_Capture_SOURCE_DIR}/src/windows/PixelShader.hlsl
1718
${Screen_Capture_SOURCE_DIR}/src/windows/VertexShader.hlsl
1819
)
@@ -34,6 +35,7 @@ endif()
3435
set(SCREEN_CAPTURE_COMMON_SRC
3536
${Screen_Capture_SOURCE_DIR}/include/ScreenCapture.h
3637
${Screen_Capture_SOURCE_DIR}/src/ScreenCapture.cpp
38+
${Screen_Capture_SOURCE_DIR}/include/ThreadRunner.h
3739
${Screen_Capture_SOURCE_DIR}/include/ThreadManager.h
3840
${Screen_Capture_SOURCE_DIR}/src/ThreadManager.cpp
3941
)

src/ScreenCapture.cpp

+4-19
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ namespace SL {
3030

3131
bool FirstTime = true;
3232

33-
while (*_TerminateThread) {
34-
DUPL_RETURN Ret = DUPL_RETURN_SUCCESS;
33+
while (!*_TerminateThread) {
34+
3535
if (FirstTime || *expected)
3636
{
3737
if (!FirstTime)
@@ -48,24 +48,9 @@ namespace SL {
4848
// First time through the loop so nothing to clean up
4949
FirstTime = false;
5050
}
51-
Ret = ThreadMgr.Init(unexpected, expected, _TerminateThread, callback);
51+
ThreadMgr.Init(unexpected, expected, _TerminateThread, callback, sleeptime);
5252
}
53-
54-
// Check if for errors
55-
if (Ret != DUPL_RETURN_SUCCESS)
56-
{
57-
if (Ret == DUPL_RETURN_ERROR_EXPECTED)
58-
{
59-
// Some type of system transition is occurring so retry
60-
*expected = true;
61-
}
62-
else
63-
{
64-
// Unexpected error so exit
65-
break;
66-
}
67-
}
68-
std::this_thread::sleep_for(std::chrono::milliseconds(sleeptime));
53+
std::this_thread::sleep_for(std::chrono::milliseconds(30));
6954
}
7055
*_TerminateThread = true;
7156
ThreadMgr.Join();

src/ThreadManager.cpp

+3-18
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
#include "ThreadManager.h"
2-
#ifdef WIN32
3-
#include "ScreenCaptureWindows.h"
4-
#endif
52

63
SL::Screen_Capture::ThreadManager::ThreadManager()
74
{
@@ -14,13 +11,12 @@ SL::Screen_Capture::ThreadManager::~ThreadManager() {
1411
Join();
1512
}
1613

17-
SL::Screen_Capture::DUPL_RETURN SL::Screen_Capture::ThreadManager::Init(std::shared_ptr<std::atomic_bool>& unexpected, std::shared_ptr<std::atomic_bool>& expected, std::shared_ptr<std::atomic_bool>& terminate, ImageCallback & CallBack)
14+
void SL::Screen_Capture::ThreadManager::Init(std::shared_ptr<std::atomic_bool>& unexpected, std::shared_ptr<std::atomic_bool>& expected, std::shared_ptr<std::atomic_bool>& terminate, ImageCallback & CallBack, int mininterval)
1815
{
1916
auto monitors = GetMonitors();
2017
m_ThreadHandles.resize(monitors.size());
2118
m_ThreadData.resize(monitors.size());
2219

23-
DUPL_RETURN Ret = DUPL_RETURN_SUCCESS;
2420
for (int i = 0; i < monitors.size(); ++i)
2521
{
2622
m_ThreadData[i] = std::make_shared<THREAD_DATA>();
@@ -29,19 +25,8 @@ SL::Screen_Capture::DUPL_RETURN SL::Screen_Capture::ThreadManager::Init(std::sha
2925
m_ThreadData[i]->TerminateThreadsEvent = terminate;
3026
m_ThreadData[i]->SelectedMonitor = monitors[i];
3127
m_ThreadData[i]->CallBack = CallBack;
32-
33-
#ifdef WIN32
34-
auto framegrabber = std::make_shared<SL::Screen_Capture::ScreenCaptureWindows>(m_ThreadData[i]);
35-
#endif
36-
37-
Ret = InitializeDx(&m_ThreadData[i]->DxRes);
38-
39-
if (Ret != DUPL_RETURN_SUCCESS)
40-
{
41-
return Ret;
42-
}
43-
44-
m_ThreadHandles[i] = std::thread(&SL::Screen_Capture::RunThread, this, &m_ThreadData[i]);
28+
m_ThreadData[i]->CaptureInterval = mininterval;
29+
m_ThreadHandles[i] = std::thread(&SL::Screen_Capture::RunCapture, m_ThreadData[i]);
4530

4631
}
4732
}

0 commit comments

Comments
 (0)