mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
DirectX9 Grabber (#1039)
This commit is contained in:
parent
65a036dfc0
commit
1d35338b83
30
.github/workflows/pull-request.yml
vendored
30
.github/workflows/pull-request.yml
vendored
@ -124,6 +124,7 @@ jobs:
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
VCINSTALLDIR: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC'
|
||||
QT_VERSION: 5.15.0
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v1
|
||||
@ -137,20 +138,37 @@ jobs:
|
||||
tr -d '\n' < version > temp && mv temp version
|
||||
echo -n "-PR#${{ github.event.pull_request.number }}" >> version
|
||||
|
||||
- name: Cache Qt
|
||||
uses: actions/cache@v2
|
||||
id: cache-qt-windows
|
||||
with:
|
||||
path: ${{ runner.workspace }}/Qt
|
||||
key: ${{ runner.os }}-Qt.${{ env.QT_VERSION }}
|
||||
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v2
|
||||
with:
|
||||
version: '5.15.0'
|
||||
version: ${{env.QT_VERSION}}
|
||||
target: 'desktop'
|
||||
arch: 'win64_msvc2019_64'
|
||||
cached: ${{ steps.cache-qt-windows.outputs.cache-hit }}
|
||||
|
||||
- name: Install Python
|
||||
uses: actions/setup-python@v1
|
||||
- name: Cache Chocolatey downloads
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
python-version: '3.x'
|
||||
path: C:\Users\runneradmin\AppData\Local\Temp\chocolatey
|
||||
key: ${{ runner.os }}-chocolatey
|
||||
|
||||
- name: Install OpenSSL & NSIS
|
||||
run: choco install --no-progress openssl nsis -y
|
||||
- name: "Remove Redistributable"
|
||||
shell: cmd
|
||||
run: |
|
||||
MsiExec.exe /passive /X{F0C3E5D1-1ADE-321E-8167-68EF0DE699A5}
|
||||
MsiExec.exe /passive /X{1D8E6291-B0D5-35EC-8441-6616F567A0F7}
|
||||
|
||||
- name: Install Python, NSIS, OpenSSL, DirectX SDK
|
||||
shell: powershell
|
||||
run: |
|
||||
choco install --no-progress python nsis openssl directx-sdk -y
|
||||
|
||||
- name: Set up x64 build architecture environment
|
||||
shell: cmd
|
||||
|
30
.github/workflows/push-master.yml
vendored
30
.github/workflows/push-master.yml
vendored
@ -95,26 +95,44 @@ jobs:
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
VCINSTALLDIR: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC'
|
||||
QT_VERSION: 5.15.0
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v1
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Cache Qt
|
||||
uses: actions/cache@v2
|
||||
id: cache-qt-windows
|
||||
with:
|
||||
path: ${{ runner.workspace }}/Qt
|
||||
key: ${{ runner.os }}-Qt.${{ env.QT_VERSION }}
|
||||
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v2
|
||||
with:
|
||||
version: '5.15.0'
|
||||
version: ${{ env.QT_VERSION }}
|
||||
target: 'desktop'
|
||||
arch: 'win64_msvc2019_64'
|
||||
cached: ${{ steps.cache-qt-windows.outputs.cache-hit }}
|
||||
|
||||
- name: Install Python
|
||||
uses: actions/setup-python@v1
|
||||
- name: Cache Chocolatey downloads
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
python-version: '3.x'
|
||||
path: C:\Users\runneradmin\AppData\Local\Temp\chocolatey
|
||||
key: ${{ runner.os }}-chocolatey
|
||||
|
||||
- name: Install OpenSSL & NSIS
|
||||
run: choco install --no-progress openssl nsis -y
|
||||
- name: "Remove Redistributable"
|
||||
shell: cmd
|
||||
run: |
|
||||
MsiExec.exe /passive /X{F0C3E5D1-1ADE-321E-8167-68EF0DE699A5}
|
||||
MsiExec.exe /passive /X{1D8E6291-B0D5-35EC-8441-6616F567A0F7}
|
||||
|
||||
- name: Install Python, NSIS, OpenSSL, DirectX SDK
|
||||
shell: powershell
|
||||
run: |
|
||||
choco install --no-progress python nsis openssl directx-sdk -y
|
||||
|
||||
- name: Set up x64 build architecture environment
|
||||
shell: cmd
|
||||
|
@ -39,9 +39,9 @@ endif()
|
||||
SET ( DEFAULT_AMLOGIC OFF )
|
||||
SET ( DEFAULT_DISPMANX OFF )
|
||||
SET ( DEFAULT_OSX OFF )
|
||||
SET ( DEFAULT_QT ON )
|
||||
SET ( DEFAULT_X11 OFF )
|
||||
SET ( DEFAULT_XCB OFF )
|
||||
SET ( DEFAULT_QT ON )
|
||||
SET ( DEFAULT_WS281XPWM OFF )
|
||||
SET ( DEFAULT_AVAHI ON )
|
||||
SET ( DEFAULT_USE_SHARED_AVAHI_LIBS ON )
|
||||
@ -58,6 +58,8 @@ IF ( ${CMAKE_SYSTEM} MATCHES "Linux" )
|
||||
SET ( DEFAULT_FB ON )
|
||||
SET ( DEFAULT_USB_HID ON )
|
||||
SET ( DEFAULT_CEC ON )
|
||||
ELSEIF ( WIN32 )
|
||||
SET ( DEFAULT_DX ON )
|
||||
ELSE()
|
||||
SET ( DEFAULT_V4L2 OFF )
|
||||
SET ( DEFAULT_FB OFF )
|
||||
@ -190,6 +192,9 @@ message(STATUS "ENABLE_XCB = ${ENABLE_XCB}")
|
||||
option(ENABLE_QT "Enable the qt grabber" ${DEFAULT_QT})
|
||||
message(STATUS "ENABLE_QT = ${ENABLE_QT}")
|
||||
|
||||
option(ENABLE_DX "Enable the DirectX grabber" ${DEFAULT_DX})
|
||||
message(STATUS "ENABLE_DX = ${ENABLE_DX}")
|
||||
|
||||
option(ENABLE_TESTS "Compile additional test applications" ${DEFAULT_TESTS})
|
||||
message(STATUS "ENABLE_TESTS = ${ENABLE_TESTS}")
|
||||
|
||||
@ -303,6 +308,12 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||
message(STATUS "Set Qt5 module path: ${SUBDIRQT}")
|
||||
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${SUBDIRQT}/msvc2019_64/lib/cmake/Qt5")
|
||||
endif()
|
||||
|
||||
# Search for DirectX9
|
||||
if (ENABLE_DX)
|
||||
find_package(DirectX9 REQUIRED)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
# Use GNU gold linker if available
|
||||
|
@ -24,6 +24,9 @@
|
||||
// Define to enable the qt grabber
|
||||
#cmakedefine ENABLE_QT
|
||||
|
||||
// Define to enable the DirectX grabber
|
||||
#cmakedefine ENABLE_DX
|
||||
|
||||
// Define to enable the spi-device
|
||||
#cmakedefine ENABLE_SPIDEV
|
||||
|
||||
|
32
cmake/FindDirectX9.cmake
Normal file
32
cmake/FindDirectX9.cmake
Normal file
@ -0,0 +1,32 @@
|
||||
# Find the DirectX 9 includes and library
|
||||
# This module defines:
|
||||
# DIRECTX9_INCLUDE_DIRS, where to find d3d9.h, etc.
|
||||
# DIRECTX9_LIBRARIES, libraries to link against to use DirectX.
|
||||
# DIRECTX9_FOUND, If false, do not try to use DirectX.
|
||||
# DIRECTX9_ROOT_DIR, directory where DirectX was installed.
|
||||
|
||||
set(DIRECTX9_INCLUDE_PATHS
|
||||
"$ENV{DXSDK_DIR}/Include"
|
||||
"$ENV{DIRECTX_ROOT}/Include"
|
||||
"C:/Program Files (x86)/Microsoft DirectX SDK (June 2010)/Include"
|
||||
"C:/Program Files/Microsoft DirectX SDK (June 2010)/Include"
|
||||
)
|
||||
find_path(DIRECTX9_INCLUDE_DIRS d3dx9.h ${DIRECTX9_INCLUDE_PATHS} NO_DEFAULT_PATH)
|
||||
|
||||
get_filename_component(DIRECTX9_ROOT_DIR "${DIRECTX9_INCLUDE_DIRS}/.." ABSOLUTE)
|
||||
|
||||
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(DIRECTX9_LIBRARY_PATHS "${DIRECTX9_ROOT_DIR}/Lib/x64")
|
||||
else ()
|
||||
set(DIRECTX9_LIBRARY_PATHS "${DIRECTX9_ROOT_DIR}/Lib/x86" "${DIRECTX9_ROOT_DIR}/Lib")
|
||||
endif ()
|
||||
|
||||
find_library(DIRECTX9_D3D9_LIBRARY d3d9 ${DIRECTX9_LIBRARY_PATHS} NO_DEFAULT_PATH)
|
||||
find_library(DIRECTX9_D3DX9_LIBRARY d3dx9 ${DIRECTX9_LIBRARY_PATHS} NO_DEFAULT_PATH)
|
||||
find_library(DIRECTX9_DXERR_LIBRARY DxErr ${DIRECTX9_LIBRARY_PATHS} NO_DEFAULT_PATH)
|
||||
set(DIRECTX9_LIBRARIES ${DIRECTX9_D3D9_LIBRARY} ${DIRECTX9_D3DX9_LIBRARY} ${DIRECTX9_DXERR_LIBRARY})
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set DIRECTX9_FOUND to TRUE if all listed variables are TRUE
|
||||
include(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(DirectX9 DEFAULT_MSG DIRECTX9_ROOT_DIR DIRECTX9_LIBRARIES DIRECTX9_INCLUDE_DIRS)
|
||||
mark_as_advanced(DIRECTX9_INCLUDE_DIRS DIRECTX9_D3D9_LIBRARY DIRECTX9_D3DX9_LIBRARY DIRECTX9_DXERR_LIBRARY)
|
79
include/grabber/DirectXGrabber.h
Normal file
79
include/grabber/DirectXGrabber.h
Normal file
@ -0,0 +1,79 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
|
||||
// DirectX 9 header
|
||||
#include <d3d9.h>
|
||||
#include <d3dx9.h>
|
||||
|
||||
// Hyperion-utils includes
|
||||
#include <utils/ColorRgb.h>
|
||||
#include <hyperion/Grabber.h>
|
||||
|
||||
///
|
||||
/// @brief The DirectX9 capture implementation
|
||||
///
|
||||
class DirectXGrabber : public Grabber
|
||||
{
|
||||
public:
|
||||
|
||||
DirectXGrabber(int cropLeft, int cropRight, int cropTop, int cropBottom, int pixelDecimation, int display);
|
||||
|
||||
virtual ~DirectXGrabber();
|
||||
|
||||
///
|
||||
/// Captures a single snapshot of the display and writes the data to the given image. The
|
||||
/// provided image should have the same dimensions as the configured values (_width and
|
||||
/// _height)
|
||||
///
|
||||
/// @param[out] image The snapped screenshot
|
||||
///
|
||||
virtual int grabFrame(Image<ColorRgb> & image);
|
||||
|
||||
///
|
||||
/// @brief Set a new video mode
|
||||
///
|
||||
virtual void setVideoMode(VideoMode mode);
|
||||
|
||||
///
|
||||
/// @brief Apply new width/height values, overwrite Grabber.h implementation
|
||||
///
|
||||
virtual bool setWidthHeight(int width, int height) { return true; };
|
||||
|
||||
///
|
||||
/// @brief Apply new pixelDecimation
|
||||
///
|
||||
virtual void setPixelDecimation(int pixelDecimation);
|
||||
|
||||
///
|
||||
/// Set the crop values
|
||||
/// @param cropLeft Left pixel crop
|
||||
/// @param cropRight Right pixel crop
|
||||
/// @param cropTop Top pixel crop
|
||||
/// @param cropBottom Bottom pixel crop
|
||||
///
|
||||
virtual void setCropping(unsigned cropLeft, unsigned cropRight, unsigned cropTop, unsigned cropBottom);
|
||||
|
||||
private:
|
||||
///
|
||||
/// @brief Setup a new capture display, will free the previous one
|
||||
/// @return True on success, false if no display is found
|
||||
///
|
||||
bool setupDisplay();
|
||||
|
||||
///
|
||||
/// @brief free the _screen pointer
|
||||
///
|
||||
void freeResources();
|
||||
|
||||
private:
|
||||
int _pixelDecimation;
|
||||
unsigned _displayWidth;
|
||||
unsigned _displayHeight;
|
||||
RECT* _srcRect;
|
||||
|
||||
IDirect3D9* _d3d9;
|
||||
IDirect3DDevice9* _device;
|
||||
IDirect3DSurface9* _surface;
|
||||
IDirect3DSurface9* _surfaceDest;
|
||||
};
|
36
include/grabber/DirectXWrapper.h
Normal file
36
include/grabber/DirectXWrapper.h
Normal file
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <hyperion/GrabberWrapper.h>
|
||||
#include <grabber/DirectXGrabber.h>
|
||||
|
||||
class DirectXWrapper: public GrabberWrapper
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Constructs the DirectX grabber with a specified grab size and update rate.
|
||||
///
|
||||
/// @param[in] cropLeft Remove from left [pixels]
|
||||
/// @param[in] cropRight Remove from right [pixels]
|
||||
/// @param[in] cropTop Remove from top [pixels]
|
||||
/// @param[in] cropBottom Remove from bottom [pixels]
|
||||
/// @param[in] pixelDecimation Decimation factor for image [pixels]
|
||||
/// @param[in] display The display used[index]
|
||||
/// @param[in] updateRate_Hz The image grab rate [Hz]
|
||||
///
|
||||
DirectXWrapper(int cropLeft, int cropRight, int cropTop, int cropBottom, int pixelDecimation, int display, const unsigned updateRate_Hz);
|
||||
|
||||
///
|
||||
/// Destructor of this DirectX grabber. Releases any claimed resources.
|
||||
///
|
||||
virtual ~DirectXWrapper() {};
|
||||
|
||||
public slots:
|
||||
///
|
||||
/// Performs a single frame grab and computes the led-colors
|
||||
///
|
||||
virtual void action();
|
||||
|
||||
private:
|
||||
/// The actual grabber
|
||||
DirectXGrabber _grabber;
|
||||
};
|
@ -29,3 +29,7 @@ endif()
|
||||
if (ENABLE_QT)
|
||||
add_subdirectory(qt)
|
||||
endif()
|
||||
|
||||
if (ENABLE_DX)
|
||||
add_subdirectory(directx)
|
||||
endif()
|
||||
|
14
libsrc/grabber/directx/CMakeLists.txt
Normal file
14
libsrc/grabber/directx/CMakeLists.txt
Normal file
@ -0,0 +1,14 @@
|
||||
# Define the current source locations
|
||||
SET( CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/grabber )
|
||||
SET( CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/grabber/directx )
|
||||
|
||||
include_directories(${DIRECTX9_INCLUDE_DIRS})
|
||||
|
||||
FILE ( GLOB DIRECTX_GRAB_SOURCES "${CURRENT_HEADER_DIR}/DirectX*.h" "${CURRENT_SOURCE_DIR}/*.h" "${CURRENT_SOURCE_DIR}/*.cpp" )
|
||||
|
||||
add_library( directx-grabber ${DIRECTX_GRAB_SOURCES} )
|
||||
|
||||
target_link_libraries(directx-grabber
|
||||
hyperion
|
||||
${DIRECTX9_LIBRARIES}
|
||||
)
|
181
libsrc/grabber/directx/DirectXGrabber.cpp
Normal file
181
libsrc/grabber/directx/DirectXGrabber.cpp
Normal file
@ -0,0 +1,181 @@
|
||||
#include <windows.h>
|
||||
#include <grabber/DirectXGrabber.h>
|
||||
#include <QImage>
|
||||
#pragma comment(lib, "d3d9.lib")
|
||||
#pragma comment(lib,"d3dx9.lib")
|
||||
|
||||
DirectXGrabber::DirectXGrabber(int cropLeft, int cropRight, int cropTop, int cropBottom, int pixelDecimation, int display)
|
||||
: Grabber("DXGRABBER", 0, 0, cropLeft, cropRight, cropTop, cropBottom)
|
||||
, _pixelDecimation(pixelDecimation)
|
||||
, _displayWidth(0)
|
||||
, _displayHeight(0)
|
||||
, _srcRect(0)
|
||||
, _d3d9(nullptr)
|
||||
, _device(nullptr)
|
||||
, _surface(nullptr)
|
||||
{
|
||||
// init
|
||||
setupDisplay();
|
||||
}
|
||||
|
||||
DirectXGrabber::~DirectXGrabber()
|
||||
{
|
||||
freeResources();
|
||||
}
|
||||
|
||||
void DirectXGrabber::freeResources()
|
||||
{
|
||||
if (_surface)
|
||||
_surface->Release();
|
||||
|
||||
if (_device)
|
||||
_device->Release();
|
||||
|
||||
if (_d3d9)
|
||||
_d3d9->Release();
|
||||
|
||||
delete _srcRect;
|
||||
}
|
||||
|
||||
bool DirectXGrabber::setupDisplay()
|
||||
{
|
||||
freeResources();
|
||||
|
||||
D3DDISPLAYMODE ddm;
|
||||
D3DPRESENT_PARAMETERS d3dpp;
|
||||
|
||||
if ((_d3d9 = Direct3DCreate9(D3D_SDK_VERSION)) == nullptr)
|
||||
{
|
||||
Error(_log, "Failed to create Direct3D");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (FAILED(_d3d9->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &ddm)))
|
||||
{
|
||||
Error(_log, "Failed to get current display mode");
|
||||
return false;
|
||||
}
|
||||
|
||||
SecureZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS));
|
||||
|
||||
d3dpp.Windowed = TRUE;
|
||||
d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
|
||||
d3dpp.BackBufferFormat = ddm.Format;
|
||||
d3dpp.BackBufferHeight = _displayHeight = ddm.Height;
|
||||
d3dpp.BackBufferWidth = _displayWidth = ddm.Width;
|
||||
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
|
||||
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
||||
d3dpp.hDeviceWindow = nullptr;
|
||||
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
|
||||
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
|
||||
|
||||
if (FAILED(_d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, nullptr, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &_device)))
|
||||
{
|
||||
Error(_log, "CreateDevice failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (FAILED(_device->CreateOffscreenPlainSurface(ddm.Width, ddm.Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &_surface, nullptr)))
|
||||
{
|
||||
Error(_log, "CreateOffscreenPlainSurface failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
int width = _displayWidth / _pixelDecimation;
|
||||
int height =_displayHeight / _pixelDecimation;
|
||||
|
||||
// calculate final image dimensions and adjust top/left cropping in 3D modes
|
||||
_srcRect = new RECT;
|
||||
switch (_videoMode)
|
||||
{
|
||||
case VideoMode::VIDEO_3DSBS:
|
||||
_width = width / 2;
|
||||
_height = height;
|
||||
_srcRect->left = _cropLeft * _pixelDecimation / 2;
|
||||
_srcRect->top = _cropTop * _pixelDecimation;
|
||||
_srcRect->right = (_displayWidth / 2) - (_cropRight * _pixelDecimation);
|
||||
_srcRect->bottom = _displayHeight - (_cropBottom * _pixelDecimation);
|
||||
break;
|
||||
case VideoMode::VIDEO_3DTAB:
|
||||
_width = width;
|
||||
_height = height / 2;
|
||||
_srcRect->left = _cropLeft * _pixelDecimation;
|
||||
_srcRect->top = (_cropTop * _pixelDecimation) / 2;
|
||||
_srcRect->right = _displayWidth - (_cropRight * _pixelDecimation);
|
||||
_srcRect->bottom = (_displayHeight / 2) - (_cropBottom * _pixelDecimation);
|
||||
break;
|
||||
case VideoMode::VIDEO_2D:
|
||||
default:
|
||||
_width = width;
|
||||
_height = height;
|
||||
_srcRect->left = _cropLeft * _pixelDecimation;
|
||||
_srcRect->top = _cropTop * _pixelDecimation;
|
||||
_srcRect->right = _displayWidth - _cropRight * _pixelDecimation;
|
||||
_srcRect->bottom = _displayHeight - _cropBottom * _pixelDecimation;
|
||||
break;
|
||||
}
|
||||
|
||||
if (FAILED(_device->CreateOffscreenPlainSurface(_width, _height, D3DFMT_R8G8B8, D3DPOOL_SCRATCH, &_surfaceDest, nullptr)))
|
||||
{
|
||||
Error(_log, "CreateOffscreenPlainSurface failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
Info(_log, "Update output image resolution to [%dx%d]", _width, _height);
|
||||
return true;
|
||||
}
|
||||
|
||||
int DirectXGrabber::grabFrame(Image<ColorRgb> & image)
|
||||
{
|
||||
if (!_enabled)
|
||||
return 0;
|
||||
|
||||
if (FAILED(_device->GetFrontBufferData(0, _surface)))
|
||||
{
|
||||
// reinit, this will disable capture on failure
|
||||
Error(_log, "Unable to get Buffer Surface Data");
|
||||
setEnabled(setupDisplay());
|
||||
return -1;
|
||||
}
|
||||
|
||||
D3DXLoadSurfaceFromSurface(_surfaceDest, nullptr, nullptr, _surface, nullptr, _srcRect, D3DX_DEFAULT, 0);
|
||||
|
||||
D3DLOCKED_RECT lockedRect;
|
||||
if (FAILED(_surfaceDest->LockRect(&lockedRect, nullptr, D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY)))
|
||||
{
|
||||
Error(_log, "Unable to lock destination Front Buffer Surface");
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(image.memptr(), lockedRect.pBits, _width * _height * 3);
|
||||
for (int idx = 0; idx < _width * _height; idx++)
|
||||
{
|
||||
const ColorRgb & color = image.memptr()[idx];
|
||||
image.memptr()[idx] = ColorRgb{color.blue, color.green, color.red};
|
||||
}
|
||||
|
||||
if (FAILED(_surfaceDest->UnlockRect()))
|
||||
{
|
||||
Error(_log, "Unable to unlock destination Front Buffer Surface");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DirectXGrabber::setVideoMode(VideoMode mode)
|
||||
{
|
||||
Grabber::setVideoMode(mode);
|
||||
setupDisplay();
|
||||
}
|
||||
|
||||
void DirectXGrabber::setPixelDecimation(int pixelDecimation)
|
||||
{
|
||||
_pixelDecimation = pixelDecimation;
|
||||
}
|
||||
|
||||
void DirectXGrabber::setCropping(unsigned cropLeft, unsigned cropRight, unsigned cropTop, unsigned cropBottom)
|
||||
{
|
||||
Grabber::setCropping(cropLeft, cropRight, cropTop, cropBottom);
|
||||
setupDisplay();
|
||||
}
|
11
libsrc/grabber/directx/DirectXWrapper.cpp
Normal file
11
libsrc/grabber/directx/DirectXWrapper.cpp
Normal file
@ -0,0 +1,11 @@
|
||||
#include <grabber/DirectXWrapper.h>
|
||||
|
||||
DirectXWrapper::DirectXWrapper(int cropLeft, int cropRight, int cropTop, int cropBottom, int pixelDecimation, int display, const unsigned updateRate_Hz)
|
||||
: GrabberWrapper("DirectX", &_grabber, 0, 0, updateRate_Hz)
|
||||
, _grabber(cropLeft, cropRight, cropTop, cropBottom, pixelDecimation, display)
|
||||
{}
|
||||
|
||||
void DirectXWrapper::action()
|
||||
{
|
||||
transferFrame(_grabber);
|
||||
}
|
@ -7,10 +7,10 @@
|
||||
{
|
||||
"type" : "string",
|
||||
"title" : "edt_conf_fg_type_title",
|
||||
"enum" : ["auto","dispmanx","amlogic","x11", "xcb", "framebuffer","qt"],
|
||||
"enum" : ["auto","dispmanx","amlogic","x11", "xcb", "framebuffer","qt","dx"],
|
||||
"options":
|
||||
{
|
||||
"enum_titles": ["edt_conf_enum_automatic","DispmanX","AMLogic","X11", "XCB", "Framebuffer","QT"]
|
||||
"enum_titles": ["edt_conf_enum_automatic","DispmanX","AMLogic","X11", "XCB", "Framebuffer","QT", "DirectX9"]
|
||||
},
|
||||
"default" : "auto",
|
||||
"propertyOrder" : 2
|
||||
|
@ -103,6 +103,11 @@ if (ENABLE_QT)
|
||||
target_link_libraries(hyperiond qt-grabber)
|
||||
endif ()
|
||||
|
||||
if (ENABLE_DX)
|
||||
include_directories(${DIRECTX9_INCLUDE_DIRS})
|
||||
target_link_libraries(hyperiond directx-grabber)
|
||||
endif ()
|
||||
|
||||
if (ENABLE_CEC)
|
||||
target_link_libraries(hyperiond cechandler)
|
||||
endif ()
|
||||
|
@ -81,6 +81,7 @@ HyperionDaemon::HyperionDaemon(const QString rootPath, QObject *parent, bool log
|
||||
, _fbGrabber(nullptr)
|
||||
, _osxGrabber(nullptr)
|
||||
, _qtGrabber(nullptr)
|
||||
, _dxGrabber(nullptr)
|
||||
, _ssdp(nullptr)
|
||||
, _cecHandler(nullptr)
|
||||
, _currVideoMode(VideoMode::VIDEO_2D)
|
||||
@ -135,7 +136,7 @@ HyperionDaemon::HyperionDaemon(const QString rootPath, QObject *parent, bool log
|
||||
connect(this, &HyperionDaemon::videoMode, _instanceManager, &HyperionIManager::newVideoMode);
|
||||
|
||||
// ---- grabber -----
|
||||
#if !defined(ENABLE_DISPMANX) && !defined(ENABLE_OSX) && !defined(ENABLE_FB) && !defined(ENABLE_X11) && !defined(ENABLE_XCB) && !defined(ENABLE_AMLOGIC) && !defined(ENABLE_QT)
|
||||
#if !defined(ENABLE_DISPMANX) && !defined(ENABLE_OSX) && !defined(ENABLE_FB) && !defined(ENABLE_X11) && !defined(ENABLE_XCB) && !defined(ENABLE_AMLOGIC) && !defined(ENABLE_QT) && !defined(ENABLE_DX)
|
||||
Warning(_log, "No platform capture can be instantiated, because all grabbers have been left out from the build");
|
||||
#endif
|
||||
|
||||
@ -244,6 +245,7 @@ void HyperionDaemon::freeObjects()
|
||||
delete _fbGrabber;
|
||||
delete _osxGrabber;
|
||||
delete _qtGrabber;
|
||||
delete _dxGrabber;
|
||||
delete _v4l2Grabber;
|
||||
|
||||
_v4l2Grabber = nullptr;
|
||||
@ -253,6 +255,7 @@ void HyperionDaemon::freeObjects()
|
||||
_fbGrabber = nullptr;
|
||||
_osxGrabber = nullptr;
|
||||
_qtGrabber = nullptr;
|
||||
_dxGrabber = nullptr;
|
||||
}
|
||||
|
||||
void HyperionDaemon::startNetworkServices()
|
||||
@ -458,6 +461,14 @@ void HyperionDaemon::handleSettingsUpdate(settings::type settingsType, const QJs
|
||||
_qtGrabber = nullptr;
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_DX
|
||||
if(_dxGrabber != nullptr)
|
||||
{
|
||||
_dxGrabber->stop();
|
||||
delete _dxGrabber;
|
||||
_dxGrabber = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
// create/start capture interface
|
||||
if (type == "framebuffer")
|
||||
@ -516,6 +527,14 @@ void HyperionDaemon::handleSettingsUpdate(settings::type settingsType, const QJs
|
||||
_qtGrabber->tryStart();
|
||||
#endif
|
||||
}
|
||||
else if (type == "dx")
|
||||
{
|
||||
if (_dxGrabber == nullptr)
|
||||
createGrabberDx(grabberConfig);
|
||||
#ifdef ENABLE_DX
|
||||
_dxGrabber->tryStart();
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
Error(_log, "Unknown platform capture type: %s", QSTRING_CSTR(type));
|
||||
@ -670,6 +689,25 @@ void HyperionDaemon::createGrabberQt(const QJsonObject &grabberConfig)
|
||||
#endif
|
||||
}
|
||||
|
||||
void HyperionDaemon::createGrabberDx(const QJsonObject &grabberConfig)
|
||||
{
|
||||
#ifdef ENABLE_DX
|
||||
_dxGrabber = new DirectXWrapper(
|
||||
_grabber_cropLeft, _grabber_cropRight, _grabber_cropTop, _grabber_cropBottom,
|
||||
grabberConfig["pixelDecimation"].toInt(8),
|
||||
grabberConfig["display"].toInt(0),
|
||||
_grabber_frequency);
|
||||
|
||||
// connect to HyperionDaemon signal
|
||||
connect(this, &HyperionDaemon::videoMode, _dxGrabber, &DirectXWrapper::setVideoMode);
|
||||
connect(this, &HyperionDaemon::settingsChanged, _dxGrabber, &DirectXWrapper::handleSettingsUpdate);
|
||||
|
||||
Info(_log, "DirectX grabber created");
|
||||
#else
|
||||
Error(_log, "The DirectX grabber can not be instantiated, because it has been left out from the build");
|
||||
#endif
|
||||
}
|
||||
|
||||
void HyperionDaemon::createGrabberFramebuffer(const QJsonObject &grabberConfig)
|
||||
{
|
||||
#ifdef ENABLE_FB
|
||||
|
@ -52,6 +52,12 @@
|
||||
typedef QObject QtWrapper;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_DX
|
||||
#include <grabber/DirectXWrapper.h>
|
||||
#else
|
||||
typedef QObject DirectXWrapper;
|
||||
#endif
|
||||
|
||||
#include <utils/Logger.h>
|
||||
#include <utils/VideoMode.h>
|
||||
|
||||
@ -153,6 +159,7 @@ private:
|
||||
void createGrabberXcb(const QJsonObject & grabberConfig);
|
||||
void createGrabberQt(const QJsonObject & grabberConfig);
|
||||
void createCecHandler();
|
||||
void createGrabberDx(const QJsonObject & grabberConfig);
|
||||
|
||||
Logger* _log;
|
||||
HyperionIManager* _instanceManager;
|
||||
@ -171,6 +178,7 @@ private:
|
||||
FramebufferWrapper* _fbGrabber;
|
||||
OsxWrapper* _osxGrabber;
|
||||
QtWrapper* _qtGrabber;
|
||||
DirectXWrapper* _dxGrabber;
|
||||
SSDPHandler* _ssdp;
|
||||
CECHandler* _cecHandler;
|
||||
FlatBufferServer* _flatBufferServer;
|
||||
|
Loading…
Reference in New Issue
Block a user