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
|
runs-on: windows-latest
|
||||||
env:
|
env:
|
||||||
VCINSTALLDIR: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC'
|
VCINSTALLDIR: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC'
|
||||||
|
QT_VERSION: 5.15.0
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v1
|
uses: actions/checkout@v1
|
||||||
@ -137,20 +138,37 @@ jobs:
|
|||||||
tr -d '\n' < version > temp && mv temp version
|
tr -d '\n' < version > temp && mv temp version
|
||||||
echo -n "-PR#${{ github.event.pull_request.number }}" >> 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
|
- name: Install Qt
|
||||||
uses: jurplel/install-qt-action@v2
|
uses: jurplel/install-qt-action@v2
|
||||||
with:
|
with:
|
||||||
version: '5.15.0'
|
version: ${{env.QT_VERSION}}
|
||||||
target: 'desktop'
|
target: 'desktop'
|
||||||
arch: 'win64_msvc2019_64'
|
arch: 'win64_msvc2019_64'
|
||||||
|
cached: ${{ steps.cache-qt-windows.outputs.cache-hit }}
|
||||||
|
|
||||||
- name: Install Python
|
- name: Cache Chocolatey downloads
|
||||||
uses: actions/setup-python@v1
|
uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
python-version: '3.x'
|
path: C:\Users\runneradmin\AppData\Local\Temp\chocolatey
|
||||||
|
key: ${{ runner.os }}-chocolatey
|
||||||
|
|
||||||
- name: Install OpenSSL & NSIS
|
- name: "Remove Redistributable"
|
||||||
run: choco install --no-progress openssl nsis -y
|
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
|
- name: Set up x64 build architecture environment
|
||||||
shell: cmd
|
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
|
runs-on: windows-latest
|
||||||
env:
|
env:
|
||||||
VCINSTALLDIR: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC'
|
VCINSTALLDIR: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC'
|
||||||
|
QT_VERSION: 5.15.0
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v1
|
uses: actions/checkout@v1
|
||||||
with:
|
with:
|
||||||
submodules: true
|
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
|
- name: Install Qt
|
||||||
uses: jurplel/install-qt-action@v2
|
uses: jurplel/install-qt-action@v2
|
||||||
with:
|
with:
|
||||||
version: '5.15.0'
|
version: ${{ env.QT_VERSION }}
|
||||||
target: 'desktop'
|
target: 'desktop'
|
||||||
arch: 'win64_msvc2019_64'
|
arch: 'win64_msvc2019_64'
|
||||||
|
cached: ${{ steps.cache-qt-windows.outputs.cache-hit }}
|
||||||
|
|
||||||
- name: Install Python
|
- name: Cache Chocolatey downloads
|
||||||
uses: actions/setup-python@v1
|
uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
python-version: '3.x'
|
path: C:\Users\runneradmin\AppData\Local\Temp\chocolatey
|
||||||
|
key: ${{ runner.os }}-chocolatey
|
||||||
|
|
||||||
- name: Install OpenSSL & NSIS
|
- name: "Remove Redistributable"
|
||||||
run: choco install --no-progress openssl nsis -y
|
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
|
- name: Set up x64 build architecture environment
|
||||||
shell: cmd
|
shell: cmd
|
||||||
|
@ -39,9 +39,9 @@ endif()
|
|||||||
SET ( DEFAULT_AMLOGIC OFF )
|
SET ( DEFAULT_AMLOGIC OFF )
|
||||||
SET ( DEFAULT_DISPMANX OFF )
|
SET ( DEFAULT_DISPMANX OFF )
|
||||||
SET ( DEFAULT_OSX OFF )
|
SET ( DEFAULT_OSX OFF )
|
||||||
|
SET ( DEFAULT_QT ON )
|
||||||
SET ( DEFAULT_X11 OFF )
|
SET ( DEFAULT_X11 OFF )
|
||||||
SET ( DEFAULT_XCB OFF )
|
SET ( DEFAULT_XCB OFF )
|
||||||
SET ( DEFAULT_QT ON )
|
|
||||||
SET ( DEFAULT_WS281XPWM OFF )
|
SET ( DEFAULT_WS281XPWM OFF )
|
||||||
SET ( DEFAULT_AVAHI ON )
|
SET ( DEFAULT_AVAHI ON )
|
||||||
SET ( DEFAULT_USE_SHARED_AVAHI_LIBS ON )
|
SET ( DEFAULT_USE_SHARED_AVAHI_LIBS ON )
|
||||||
@ -58,6 +58,8 @@ IF ( ${CMAKE_SYSTEM} MATCHES "Linux" )
|
|||||||
SET ( DEFAULT_FB ON )
|
SET ( DEFAULT_FB ON )
|
||||||
SET ( DEFAULT_USB_HID ON )
|
SET ( DEFAULT_USB_HID ON )
|
||||||
SET ( DEFAULT_CEC ON )
|
SET ( DEFAULT_CEC ON )
|
||||||
|
ELSEIF ( WIN32 )
|
||||||
|
SET ( DEFAULT_DX ON )
|
||||||
ELSE()
|
ELSE()
|
||||||
SET ( DEFAULT_V4L2 OFF )
|
SET ( DEFAULT_V4L2 OFF )
|
||||||
SET ( DEFAULT_FB OFF )
|
SET ( DEFAULT_FB OFF )
|
||||||
@ -190,6 +192,9 @@ message(STATUS "ENABLE_XCB = ${ENABLE_XCB}")
|
|||||||
option(ENABLE_QT "Enable the qt grabber" ${DEFAULT_QT})
|
option(ENABLE_QT "Enable the qt grabber" ${DEFAULT_QT})
|
||||||
message(STATUS "ENABLE_QT = ${ENABLE_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})
|
option(ENABLE_TESTS "Compile additional test applications" ${DEFAULT_TESTS})
|
||||||
message(STATUS "ENABLE_TESTS = ${ENABLE_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}")
|
message(STATUS "Set Qt5 module path: ${SUBDIRQT}")
|
||||||
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${SUBDIRQT}/msvc2019_64/lib/cmake/Qt5")
|
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${SUBDIRQT}/msvc2019_64/lib/cmake/Qt5")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Search for DirectX9
|
||||||
|
if (ENABLE_DX)
|
||||||
|
find_package(DirectX9 REQUIRED)
|
||||||
|
endif()
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Use GNU gold linker if available
|
# Use GNU gold linker if available
|
||||||
|
@ -24,6 +24,9 @@
|
|||||||
// Define to enable the qt grabber
|
// Define to enable the qt grabber
|
||||||
#cmakedefine ENABLE_QT
|
#cmakedefine ENABLE_QT
|
||||||
|
|
||||||
|
// Define to enable the DirectX grabber
|
||||||
|
#cmakedefine ENABLE_DX
|
||||||
|
|
||||||
// Define to enable the spi-device
|
// Define to enable the spi-device
|
||||||
#cmakedefine ENABLE_SPIDEV
|
#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)
|
if (ENABLE_QT)
|
||||||
add_subdirectory(qt)
|
add_subdirectory(qt)
|
||||||
endif()
|
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",
|
"type" : "string",
|
||||||
"title" : "edt_conf_fg_type_title",
|
"title" : "edt_conf_fg_type_title",
|
||||||
"enum" : ["auto","dispmanx","amlogic","x11", "xcb", "framebuffer","qt"],
|
"enum" : ["auto","dispmanx","amlogic","x11", "xcb", "framebuffer","qt","dx"],
|
||||||
"options":
|
"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",
|
"default" : "auto",
|
||||||
"propertyOrder" : 2
|
"propertyOrder" : 2
|
||||||
|
@ -103,6 +103,11 @@ if (ENABLE_QT)
|
|||||||
target_link_libraries(hyperiond qt-grabber)
|
target_link_libraries(hyperiond qt-grabber)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
if (ENABLE_DX)
|
||||||
|
include_directories(${DIRECTX9_INCLUDE_DIRS})
|
||||||
|
target_link_libraries(hyperiond directx-grabber)
|
||||||
|
endif ()
|
||||||
|
|
||||||
if (ENABLE_CEC)
|
if (ENABLE_CEC)
|
||||||
target_link_libraries(hyperiond cechandler)
|
target_link_libraries(hyperiond cechandler)
|
||||||
endif ()
|
endif ()
|
||||||
|
@ -81,6 +81,7 @@ HyperionDaemon::HyperionDaemon(const QString rootPath, QObject *parent, bool log
|
|||||||
, _fbGrabber(nullptr)
|
, _fbGrabber(nullptr)
|
||||||
, _osxGrabber(nullptr)
|
, _osxGrabber(nullptr)
|
||||||
, _qtGrabber(nullptr)
|
, _qtGrabber(nullptr)
|
||||||
|
, _dxGrabber(nullptr)
|
||||||
, _ssdp(nullptr)
|
, _ssdp(nullptr)
|
||||||
, _cecHandler(nullptr)
|
, _cecHandler(nullptr)
|
||||||
, _currVideoMode(VideoMode::VIDEO_2D)
|
, _currVideoMode(VideoMode::VIDEO_2D)
|
||||||
@ -135,7 +136,7 @@ HyperionDaemon::HyperionDaemon(const QString rootPath, QObject *parent, bool log
|
|||||||
connect(this, &HyperionDaemon::videoMode, _instanceManager, &HyperionIManager::newVideoMode);
|
connect(this, &HyperionDaemon::videoMode, _instanceManager, &HyperionIManager::newVideoMode);
|
||||||
|
|
||||||
// ---- grabber -----
|
// ---- 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");
|
Warning(_log, "No platform capture can be instantiated, because all grabbers have been left out from the build");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -244,6 +245,7 @@ void HyperionDaemon::freeObjects()
|
|||||||
delete _fbGrabber;
|
delete _fbGrabber;
|
||||||
delete _osxGrabber;
|
delete _osxGrabber;
|
||||||
delete _qtGrabber;
|
delete _qtGrabber;
|
||||||
|
delete _dxGrabber;
|
||||||
delete _v4l2Grabber;
|
delete _v4l2Grabber;
|
||||||
|
|
||||||
_v4l2Grabber = nullptr;
|
_v4l2Grabber = nullptr;
|
||||||
@ -253,6 +255,7 @@ void HyperionDaemon::freeObjects()
|
|||||||
_fbGrabber = nullptr;
|
_fbGrabber = nullptr;
|
||||||
_osxGrabber = nullptr;
|
_osxGrabber = nullptr;
|
||||||
_qtGrabber = nullptr;
|
_qtGrabber = nullptr;
|
||||||
|
_dxGrabber = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HyperionDaemon::startNetworkServices()
|
void HyperionDaemon::startNetworkServices()
|
||||||
@ -458,6 +461,14 @@ void HyperionDaemon::handleSettingsUpdate(settings::type settingsType, const QJs
|
|||||||
_qtGrabber = nullptr;
|
_qtGrabber = nullptr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef ENABLE_DX
|
||||||
|
if(_dxGrabber != nullptr)
|
||||||
|
{
|
||||||
|
_dxGrabber->stop();
|
||||||
|
delete _dxGrabber;
|
||||||
|
_dxGrabber = nullptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// create/start capture interface
|
// create/start capture interface
|
||||||
if (type == "framebuffer")
|
if (type == "framebuffer")
|
||||||
@ -516,6 +527,14 @@ void HyperionDaemon::handleSettingsUpdate(settings::type settingsType, const QJs
|
|||||||
_qtGrabber->tryStart();
|
_qtGrabber->tryStart();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
else if (type == "dx")
|
||||||
|
{
|
||||||
|
if (_dxGrabber == nullptr)
|
||||||
|
createGrabberDx(grabberConfig);
|
||||||
|
#ifdef ENABLE_DX
|
||||||
|
_dxGrabber->tryStart();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Error(_log, "Unknown platform capture type: %s", QSTRING_CSTR(type));
|
Error(_log, "Unknown platform capture type: %s", QSTRING_CSTR(type));
|
||||||
@ -670,6 +689,25 @@ void HyperionDaemon::createGrabberQt(const QJsonObject &grabberConfig)
|
|||||||
#endif
|
#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)
|
void HyperionDaemon::createGrabberFramebuffer(const QJsonObject &grabberConfig)
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_FB
|
#ifdef ENABLE_FB
|
||||||
|
@ -52,6 +52,12 @@
|
|||||||
typedef QObject QtWrapper;
|
typedef QObject QtWrapper;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_DX
|
||||||
|
#include <grabber/DirectXWrapper.h>
|
||||||
|
#else
|
||||||
|
typedef QObject DirectXWrapper;
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <utils/Logger.h>
|
#include <utils/Logger.h>
|
||||||
#include <utils/VideoMode.h>
|
#include <utils/VideoMode.h>
|
||||||
|
|
||||||
@ -153,6 +159,7 @@ private:
|
|||||||
void createGrabberXcb(const QJsonObject & grabberConfig);
|
void createGrabberXcb(const QJsonObject & grabberConfig);
|
||||||
void createGrabberQt(const QJsonObject & grabberConfig);
|
void createGrabberQt(const QJsonObject & grabberConfig);
|
||||||
void createCecHandler();
|
void createCecHandler();
|
||||||
|
void createGrabberDx(const QJsonObject & grabberConfig);
|
||||||
|
|
||||||
Logger* _log;
|
Logger* _log;
|
||||||
HyperionIManager* _instanceManager;
|
HyperionIManager* _instanceManager;
|
||||||
@ -171,6 +178,7 @@ private:
|
|||||||
FramebufferWrapper* _fbGrabber;
|
FramebufferWrapper* _fbGrabber;
|
||||||
OsxWrapper* _osxGrabber;
|
OsxWrapper* _osxGrabber;
|
||||||
QtWrapper* _qtGrabber;
|
QtWrapper* _qtGrabber;
|
||||||
|
DirectXWrapper* _dxGrabber;
|
||||||
SSDPHandler* _ssdp;
|
SSDPHandler* _ssdp;
|
||||||
CECHandler* _cecHandler;
|
CECHandler* _cecHandler;
|
||||||
FlatBufferServer* _flatBufferServer;
|
FlatBufferServer* _flatBufferServer;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user