mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2026-06-16 21:51:17 +00:00
Add VDPAU renderer
This commit is contained in:
@@ -15,6 +15,7 @@ matrix:
|
|||||||
apt:
|
apt:
|
||||||
sources:
|
sources:
|
||||||
- sourceline: 'ppa:beineri/opt-qt596-xenial'
|
- sourceline: 'ppa:beineri/opt-qt596-xenial'
|
||||||
|
- sourceline: 'ppa:jonathonf/ffmpeg-4'
|
||||||
packages:
|
packages:
|
||||||
- qt59base
|
- qt59base
|
||||||
- qt59quickcontrols2
|
- qt59quickcontrols2
|
||||||
@@ -22,6 +23,9 @@ matrix:
|
|||||||
- libesd0-dev
|
- libesd0-dev
|
||||||
- libgl-dev
|
- libgl-dev
|
||||||
- libopus-dev
|
- libopus-dev
|
||||||
|
- ffmpeg
|
||||||
|
- libva-dev
|
||||||
|
- libvdpau-dev
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- '[ "$TRAVIS_OS_NAME" != osx ] || brew install qt5'
|
- '[ "$TRAVIS_OS_NAME" != osx ] || brew install qt5'
|
||||||
|
|||||||
+11
@@ -53,6 +53,10 @@ unix:!macx {
|
|||||||
packagesExist(libva) {
|
packagesExist(libva) {
|
||||||
CONFIG += libva
|
CONFIG += libva
|
||||||
}
|
}
|
||||||
|
|
||||||
|
packagesExist(vdpau) {
|
||||||
|
CONFIG += libvdpau
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
win32 {
|
win32 {
|
||||||
@@ -112,6 +116,13 @@ libva {
|
|||||||
SOURCES += streaming/video/ffmpeg-renderers/vaapi.cpp
|
SOURCES += streaming/video/ffmpeg-renderers/vaapi.cpp
|
||||||
HEADERS += streaming/video/ffmpeg-renderers/vaapi.h
|
HEADERS += streaming/video/ffmpeg-renderers/vaapi.h
|
||||||
}
|
}
|
||||||
|
libvdpau {
|
||||||
|
message(VDPAU renderer selected)
|
||||||
|
|
||||||
|
DEFINES += HAVE_LIBVDPAU
|
||||||
|
SOURCES += streaming/video/ffmpeg-renderers/vdpau.cpp
|
||||||
|
HEADERS += streaming/video/ffmpeg-renderers/vdpau.h
|
||||||
|
}
|
||||||
config_SLVideo {
|
config_SLVideo {
|
||||||
message(SLVideo decoder/renderer selected)
|
message(SLVideo decoder/renderer selected)
|
||||||
|
|
||||||
|
|||||||
@@ -138,6 +138,10 @@ bool Session::chooseDecoder(StreamingPreferences::VideoDecoderSelection vds,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(HAVE_FFMPEG) && !defined(HAVE_SLVIDEO)
|
||||||
|
#error No video decoding libraries available!
|
||||||
|
#endif
|
||||||
|
|
||||||
// If we reach this, we didn't initialize any decoders successfully
|
// If we reach this, we didn't initialize any decoders successfully
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,7 +70,6 @@ VAAPIRenderer::initialize(SDL_Window* window, int, int width, int height)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
err = av_hwdevice_ctx_create(&m_HwContext,
|
err = av_hwdevice_ctx_create(&m_HwContext,
|
||||||
AV_HWDEVICE_TYPE_VAAPI,
|
AV_HWDEVICE_TYPE_VAAPI,
|
||||||
nullptr, nullptr, 0);
|
nullptr, nullptr, 0);
|
||||||
@@ -81,6 +80,14 @@ VAAPIRenderer::initialize(SDL_Window* window, int, int width, int height)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This quirk is set for the VDPAU wrapper which doesn't work with our VAAPI renderer
|
||||||
|
if (((AVVAAPIDeviceContext*)((AVHWDeviceContext*)(m_HwContext->data))->hwctx)->driver_quirks & AV_VAAPI_DRIVER_QUIRK_SURFACE_ATTRIBUTES) {
|
||||||
|
// Fail and let our VDPAU renderer pick this up
|
||||||
|
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"Avoiding VDPAU wrapper for VAAPI decoding");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,10 +38,6 @@ public:
|
|||||||
virtual void renderFrame(AVFrame* frame);
|
virtual void renderFrame(AVFrame* frame);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static
|
|
||||||
enum AVPixelFormat ffGetFormat(AVCodecContext*,
|
|
||||||
const enum AVPixelFormat* pixFmts);
|
|
||||||
|
|
||||||
Window m_XWindow;
|
Window m_XWindow;
|
||||||
AVBufferRef* m_HwContext;
|
AVBufferRef* m_HwContext;
|
||||||
void* m_X11VaLibHandle;
|
void* m_X11VaLibHandle;
|
||||||
@@ -51,4 +47,3 @@ private:
|
|||||||
int m_DisplayWidth;
|
int m_DisplayWidth;
|
||||||
int m_DisplayHeight;
|
int m_DisplayHeight;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,292 @@
|
|||||||
|
#include "vdpau.h"
|
||||||
|
|
||||||
|
#include <SDL_syswm.h>
|
||||||
|
|
||||||
|
#define BAIL_ON_FAIL(status, something) if ((status) != VDP_STATUS_OK) { \
|
||||||
|
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, \
|
||||||
|
#something " failed: %d", (status)); \
|
||||||
|
return false; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GET_PROC_ADDRESS(id, func) status = vdpauCtx->get_proc_address(vdpauCtx->device, id, (void**)func); \
|
||||||
|
BAIL_ON_FAIL(status, id)
|
||||||
|
|
||||||
|
const VdpRGBAFormat VDPAURenderer::k_OutputFormats[] = {
|
||||||
|
VDP_RGBA_FORMAT_B8G8R8A8,
|
||||||
|
VDP_RGBA_FORMAT_R8G8B8A8
|
||||||
|
};
|
||||||
|
|
||||||
|
VDPAURenderer::VDPAURenderer()
|
||||||
|
: m_HwContext(nullptr),
|
||||||
|
m_PresentationQueueTarget(0),
|
||||||
|
m_PresentationQueue(0),
|
||||||
|
m_VideoMixer(0),
|
||||||
|
m_NextSurfaceIndex(0)
|
||||||
|
{
|
||||||
|
SDL_zero(m_OutputSurface);
|
||||||
|
}
|
||||||
|
|
||||||
|
VDPAURenderer::~VDPAURenderer()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < OUTPUT_SURFACE_COUNT; i++) {
|
||||||
|
if (m_OutputSurface[i] != 0) {
|
||||||
|
m_VdpOutputSurfaceDestroy(m_OutputSurface[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_VideoMixer != 0) {
|
||||||
|
m_VdpVideoMixerDestroy(m_VideoMixer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_PresentationQueue != 0) {
|
||||||
|
m_VdpPresentationQueueDestroy(m_PresentationQueue);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_PresentationQueueTarget != 0) {
|
||||||
|
m_VdpPresentationQueueTargetDestroy(m_PresentationQueueTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This must be done last as it frees VDPAU context required to call
|
||||||
|
// the functions above.
|
||||||
|
if (m_HwContext != nullptr) {
|
||||||
|
av_buffer_unref(&m_HwContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VDPAURenderer::initialize(SDL_Window* window, int, int width, int height)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
VdpStatus status;
|
||||||
|
SDL_SysWMinfo info;
|
||||||
|
|
||||||
|
m_VideoWidth = width;
|
||||||
|
m_VideoHeight = height;
|
||||||
|
|
||||||
|
err = av_hwdevice_ctx_create(&m_HwContext,
|
||||||
|
AV_HWDEVICE_TYPE_VDPAU,
|
||||||
|
nullptr, nullptr, 0);
|
||||||
|
if (err < 0) {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"Failed to create VDPAU context: %d",
|
||||||
|
err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
AVHWDeviceContext* devCtx = (AVHWDeviceContext*)m_HwContext->data;
|
||||||
|
AVVDPAUDeviceContext* vdpauCtx = (AVVDPAUDeviceContext*)devCtx->hwctx;
|
||||||
|
|
||||||
|
GET_PROC_ADDRESS(VDP_FUNC_ID_GET_ERROR_STRING, &m_VdpGetErrorString);
|
||||||
|
GET_PROC_ADDRESS(VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_DESTROY, &m_VdpPresentationQueueTargetDestroy);
|
||||||
|
GET_PROC_ADDRESS(VDP_FUNC_ID_VIDEO_MIXER_CREATE, &m_VdpVideoMixerCreate);
|
||||||
|
GET_PROC_ADDRESS(VDP_FUNC_ID_VIDEO_MIXER_DESTROY, &m_VdpVideoMixerDestroy);
|
||||||
|
GET_PROC_ADDRESS(VDP_FUNC_ID_VIDEO_MIXER_RENDER, &m_VdpVideoMixerRender);
|
||||||
|
GET_PROC_ADDRESS(VDP_FUNC_ID_PRESENTATION_QUEUE_CREATE, &m_VdpPresentationQueueCreate);
|
||||||
|
GET_PROC_ADDRESS(VDP_FUNC_ID_PRESENTATION_QUEUE_DESTROY, &m_VdpPresentationQueueDestroy);
|
||||||
|
GET_PROC_ADDRESS(VDP_FUNC_ID_PRESENTATION_QUEUE_DISPLAY, &m_VdpPresentationQueueDisplay);
|
||||||
|
GET_PROC_ADDRESS(VDP_FUNC_ID_PRESENTATION_QUEUE_SET_BACKGROUND_COLOR, &m_VdpPresentationQueueSetBackgroundColor);
|
||||||
|
GET_PROC_ADDRESS(VDP_FUNC_ID_PRESENTATION_QUEUE_BLOCK_UNTIL_SURFACE_IDLE, &m_VdpPresentationQueueBlockUntilSurfaceIdle);
|
||||||
|
GET_PROC_ADDRESS(VDP_FUNC_ID_OUTPUT_SURFACE_CREATE, &m_VdpOutputSurfaceCreate);
|
||||||
|
GET_PROC_ADDRESS(VDP_FUNC_ID_OUTPUT_SURFACE_DESTROY, &m_VdpOutputSurfaceDestroy);
|
||||||
|
GET_PROC_ADDRESS(VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_CAPABILITIES, &m_VdpOutputSurfaceQueryCapabilities);
|
||||||
|
|
||||||
|
SDL_GetWindowSize(window, (int*)&m_DisplayWidth, (int*)&m_DisplayHeight);
|
||||||
|
|
||||||
|
SDL_VERSION(&info.version);
|
||||||
|
|
||||||
|
if (!SDL_GetWindowWMInfo(window, &info)) {
|
||||||
|
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"SDL_GetWindowWMInfo() failed: %s",
|
||||||
|
SDL_GetError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_assert(info.subsystem == SDL_SYSWM_X11);
|
||||||
|
|
||||||
|
if (info.subsystem == SDL_SYSWM_X11) {
|
||||||
|
GET_PROC_ADDRESS(VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_CREATE_X11,
|
||||||
|
&m_VdpPresentationQueueTargetCreateX11);
|
||||||
|
status = m_VdpPresentationQueueTargetCreateX11(vdpauCtx->device,
|
||||||
|
info.info.x11.window,
|
||||||
|
&m_PresentationQueueTarget);
|
||||||
|
if (status != VDP_STATUS_OK) {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"VdpPresentationQueueTargetCreateX11() failed: %s",
|
||||||
|
m_VdpGetErrorString(status));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (info.subsystem == SDL_SYSWM_WAYLAND) {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"VDPAU backend does not currently support Wayland");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"Unsupported VDPAU rendering subsystem: %d",
|
||||||
|
info.subsystem);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try our available output formats to find something the GPU supports
|
||||||
|
bool foundFormat = false;
|
||||||
|
for (int i = 0; i < OUTPUT_SURFACE_FORMAT_COUNT; i++) {
|
||||||
|
VdpBool supported;
|
||||||
|
uint32_t maxWidth, maxHeight;
|
||||||
|
status = m_VdpOutputSurfaceQueryCapabilities(vdpauCtx->device, k_OutputFormats[i],
|
||||||
|
&supported, &maxWidth, &maxHeight);
|
||||||
|
if (status != VDP_STATUS_OK) {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"VdpOutputSurfaceQueryCapabilities() failed: %s",
|
||||||
|
m_VdpGetErrorString(status));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (supported) {
|
||||||
|
if (m_DisplayWidth <= maxWidth && m_DisplayHeight <= maxHeight) {
|
||||||
|
m_OutputSurfaceFormat = k_OutputFormats[i];
|
||||||
|
foundFormat = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"Display size not within capabilities %dx%d vs %dx%d",
|
||||||
|
m_DisplayWidth, m_DisplayWidth,
|
||||||
|
maxWidth, maxHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!foundFormat) {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"No compatible output surface format found!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the output surfaces
|
||||||
|
for (int i = 0; i < OUTPUT_SURFACE_COUNT; i++) {
|
||||||
|
status = m_VdpOutputSurfaceCreate(vdpauCtx->device, m_OutputSurfaceFormat,
|
||||||
|
m_DisplayWidth, m_DisplayHeight,
|
||||||
|
&m_OutputSurface[i]);
|
||||||
|
if (status != VDP_STATUS_OK) {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"VdpOutputSurfaceCreate() failed: %s",
|
||||||
|
m_VdpGetErrorString(status));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status = m_VdpPresentationQueueCreate(vdpauCtx->device, m_PresentationQueueTarget,
|
||||||
|
&m_PresentationQueue);
|
||||||
|
if (status != VDP_STATUS_OK) {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"VdpPresentationQueueCreate() failed: %s",
|
||||||
|
m_VdpGetErrorString(status));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the background to black
|
||||||
|
VdpColor color;
|
||||||
|
SDL_zero(color);
|
||||||
|
m_VdpPresentationQueueSetBackgroundColor(m_PresentationQueue, &color);
|
||||||
|
|
||||||
|
#define PARAM_COUNT 2
|
||||||
|
const VdpVideoMixerParameter params[PARAM_COUNT] = {
|
||||||
|
VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH,
|
||||||
|
VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT,
|
||||||
|
};
|
||||||
|
const void* const paramValues[PARAM_COUNT] = {
|
||||||
|
&m_VideoWidth,
|
||||||
|
&m_VideoHeight,
|
||||||
|
};
|
||||||
|
|
||||||
|
status = m_VdpVideoMixerCreate(vdpauCtx->device, 0, nullptr,
|
||||||
|
PARAM_COUNT, params, paramValues,
|
||||||
|
&m_VideoMixer);
|
||||||
|
if (status != VDP_STATUS_OK) {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"VdpVideoMixerCreate() failed: %s",
|
||||||
|
m_VdpGetErrorString(status));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VDPAURenderer::prepareDecoderContext(AVCodecContext* context)
|
||||||
|
{
|
||||||
|
context->hw_device_ctx = av_buffer_ref(m_HwContext);
|
||||||
|
|
||||||
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"Using VDPAU accelerated renderer");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VDPAURenderer::renderFrame(AVFrame* frame)
|
||||||
|
{
|
||||||
|
VdpStatus status;
|
||||||
|
VdpVideoSurface videoSurface = (VdpVideoSurface)(uintptr_t)frame->data[3];
|
||||||
|
|
||||||
|
// This is safe without locking because this is always called on the main thread
|
||||||
|
VdpOutputSurface chosenSurface = m_OutputSurface[m_NextSurfaceIndex];
|
||||||
|
m_NextSurfaceIndex = (m_NextSurfaceIndex + 1) % OUTPUT_SURFACE_COUNT;
|
||||||
|
|
||||||
|
// Wait for this frame to be off the screen
|
||||||
|
VdpTime pts;
|
||||||
|
m_VdpPresentationQueueBlockUntilSurfaceIdle(m_PresentationQueue, chosenSurface, &pts);
|
||||||
|
|
||||||
|
VdpRect outputRect;
|
||||||
|
|
||||||
|
// Center in frame and preserve aspect ratio
|
||||||
|
double srcAspectRatio = (double)m_VideoWidth / (double)m_VideoHeight;
|
||||||
|
double dstAspectRatio = (double)m_DisplayWidth / (double)m_DisplayHeight;
|
||||||
|
if (dstAspectRatio < srcAspectRatio) {
|
||||||
|
// Greater height per width
|
||||||
|
uint32_t drawHeight = (uint32_t)(m_DisplayWidth / srcAspectRatio);
|
||||||
|
outputRect.y0 = (m_DisplayHeight - drawHeight) / 2;
|
||||||
|
outputRect.y1 = outputRect.y0 + drawHeight;
|
||||||
|
outputRect.x0 = 0;
|
||||||
|
outputRect.x1 = outputRect.x0 + m_DisplayWidth;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Greater width per height
|
||||||
|
uint32_t drawWidth = (uint32_t)(m_DisplayHeight * srcAspectRatio);
|
||||||
|
outputRect.y0 = 0;
|
||||||
|
outputRect.y1 = outputRect.y0 + m_DisplayHeight;
|
||||||
|
outputRect.x0 = (m_DisplayWidth - drawWidth) / 2;
|
||||||
|
outputRect.x1 = outputRect.x0 + drawWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render the next frame into the output surface
|
||||||
|
status = m_VdpVideoMixerRender(m_VideoMixer,
|
||||||
|
VDP_INVALID_HANDLE, nullptr,
|
||||||
|
VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME,
|
||||||
|
0, nullptr,
|
||||||
|
videoSurface,
|
||||||
|
0, nullptr,
|
||||||
|
nullptr,
|
||||||
|
chosenSurface,
|
||||||
|
&outputRect,
|
||||||
|
nullptr,
|
||||||
|
0,
|
||||||
|
nullptr);
|
||||||
|
|
||||||
|
// The decoder can have this surface back now
|
||||||
|
av_frame_free(&frame);
|
||||||
|
|
||||||
|
if (status != VDP_STATUS_OK) {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"VdpVideoMixerRender() failed: %s",
|
||||||
|
m_VdpGetErrorString(status));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Queue the frame for display immediately
|
||||||
|
status = m_VdpPresentationQueueDisplay(m_PresentationQueue, chosenSurface, 0, 0, 0);
|
||||||
|
if (status != VDP_STATUS_OK) {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"VdpPresentationQueueDisplay() failed: %s",
|
||||||
|
m_VdpGetErrorString(status));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "renderer.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <vdpau/vdpau.h>
|
||||||
|
#include <vdpau/vdpau_x11.h>
|
||||||
|
#include <libavutil/hwcontext_vdpau.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
class VDPAURenderer : public IFFmpegRenderer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VDPAURenderer();
|
||||||
|
virtual ~VDPAURenderer();
|
||||||
|
virtual bool initialize(SDL_Window* window,
|
||||||
|
int videoFormat,
|
||||||
|
int width,
|
||||||
|
int height);
|
||||||
|
virtual bool prepareDecoderContext(AVCodecContext* context);
|
||||||
|
virtual void renderFrame(AVFrame* frame);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t m_VideoWidth, m_VideoHeight;
|
||||||
|
uint32_t m_DisplayWidth, m_DisplayHeight;
|
||||||
|
AVBufferRef* m_HwContext;
|
||||||
|
VdpPresentationQueueTarget m_PresentationQueueTarget;
|
||||||
|
VdpPresentationQueue m_PresentationQueue;
|
||||||
|
VdpVideoMixer m_VideoMixer;
|
||||||
|
VdpRGBAFormat m_OutputSurfaceFormat;
|
||||||
|
|
||||||
|
#define OUTPUT_SURFACE_COUNT 3
|
||||||
|
VdpOutputSurface m_OutputSurface[OUTPUT_SURFACE_COUNT];
|
||||||
|
int m_NextSurfaceIndex;
|
||||||
|
|
||||||
|
#define OUTPUT_SURFACE_FORMAT_COUNT 2
|
||||||
|
static const VdpRGBAFormat k_OutputFormats[OUTPUT_SURFACE_FORMAT_COUNT];
|
||||||
|
|
||||||
|
VdpGetErrorString* m_VdpGetErrorString;
|
||||||
|
VdpPresentationQueueTargetDestroy* m_VdpPresentationQueueTargetDestroy;
|
||||||
|
VdpVideoMixerCreate* m_VdpVideoMixerCreate;
|
||||||
|
VdpVideoMixerDestroy* m_VdpVideoMixerDestroy;
|
||||||
|
VdpVideoMixerRender* m_VdpVideoMixerRender;
|
||||||
|
VdpPresentationQueueCreate* m_VdpPresentationQueueCreate;
|
||||||
|
VdpPresentationQueueDestroy* m_VdpPresentationQueueDestroy;
|
||||||
|
VdpPresentationQueueDisplay* m_VdpPresentationQueueDisplay;
|
||||||
|
VdpPresentationQueueSetBackgroundColor* m_VdpPresentationQueueSetBackgroundColor;
|
||||||
|
VdpPresentationQueueBlockUntilSurfaceIdle* m_VdpPresentationQueueBlockUntilSurfaceIdle;
|
||||||
|
VdpOutputSurfaceCreate* m_VdpOutputSurfaceCreate;
|
||||||
|
VdpOutputSurfaceDestroy* m_VdpOutputSurfaceDestroy;
|
||||||
|
VdpOutputSurfaceQueryCapabilities* m_VdpOutputSurfaceQueryCapabilities;
|
||||||
|
|
||||||
|
// X11 stuff
|
||||||
|
VdpPresentationQueueTargetCreateX11* m_VdpPresentationQueueTargetCreateX11;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -13,6 +13,10 @@
|
|||||||
#include "ffmpeg-renderers/vaapi.h"
|
#include "ffmpeg-renderers/vaapi.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBVDPAU
|
||||||
|
#include "ffmpeg-renderers/vdpau.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
// This is gross but it allows us to use sizeof()
|
// This is gross but it allows us to use sizeof()
|
||||||
#include "ffmpeg_videosamples.cpp"
|
#include "ffmpeg_videosamples.cpp"
|
||||||
|
|
||||||
@@ -195,6 +199,10 @@ IFFmpegRenderer* FFmpegVideoDecoder::createAcceleratedRenderer(const AVCodecHWCo
|
|||||||
#ifdef HAVE_LIBVA
|
#ifdef HAVE_LIBVA
|
||||||
case AV_HWDEVICE_TYPE_VAAPI:
|
case AV_HWDEVICE_TYPE_VAAPI:
|
||||||
return new VAAPIRenderer();
|
return new VAAPIRenderer();
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_LIBVDPAU
|
||||||
|
case AV_HWDEVICE_TYPE_VDPAU:
|
||||||
|
return new VDPAURenderer();
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|||||||
Reference in New Issue
Block a user