mirror of
https://github.com/moonlight-stream/moonlight-qt
synced 2024-11-10 13:44:17 +00:00
Merge branch 'master' of github.com:cgutman/moonlight-qt
This commit is contained in:
commit
48c2a8c5b0
4 changed files with 67 additions and 39 deletions
|
@ -101,6 +101,11 @@ bool Session::chooseDecoder(StreamingPreferences::VideoDecoderSelection vds,
|
||||||
|
|
||||||
int Session::drSetup(int videoFormat, int width, int height, int frameRate, void *, int)
|
int Session::drSetup(int videoFormat, int width, int height, int frameRate, void *, int)
|
||||||
{
|
{
|
||||||
|
s_ActiveSession->m_ActiveVideoFormat = videoFormat;
|
||||||
|
s_ActiveSession->m_ActiveVideoWidth = width;
|
||||||
|
s_ActiveSession->m_ActiveVideoHeight = height;
|
||||||
|
s_ActiveSession->m_ActiveVideoFrameRate = frameRate;
|
||||||
|
|
||||||
if (!chooseDecoder(s_ActiveSession->m_Preferences.videoDecoderSelection,
|
if (!chooseDecoder(s_ActiveSession->m_Preferences.videoDecoderSelection,
|
||||||
s_ActiveSession->m_Window,
|
s_ActiveSession->m_Window,
|
||||||
videoFormat, width, height, frameRate,
|
videoFormat, width, height, frameRate,
|
||||||
|
@ -117,7 +122,16 @@ int Session::drSubmitDecodeUnit(PDECODE_UNIT du)
|
||||||
// from underneath the session when we initiate destruction.
|
// from underneath the session when we initiate destruction.
|
||||||
// We need to destroy the decoder on the main thread to satisfy
|
// We need to destroy the decoder on the main thread to satisfy
|
||||||
// some API constraints (like DXVA2).
|
// some API constraints (like DXVA2).
|
||||||
|
|
||||||
SDL_AtomicLock(&s_ActiveSession->m_DecoderLock);
|
SDL_AtomicLock(&s_ActiveSession->m_DecoderLock);
|
||||||
|
|
||||||
|
if (s_ActiveSession->m_NeedsIdr) {
|
||||||
|
// If we reset our decoder, we'll need to request an IDR frame
|
||||||
|
s_ActiveSession->m_NeedsIdr = false;
|
||||||
|
SDL_AtomicUnlock(&s_ActiveSession->m_DecoderLock);
|
||||||
|
return DR_NEED_IDR;
|
||||||
|
}
|
||||||
|
|
||||||
IVideoDecoder* decoder = s_ActiveSession->m_VideoDecoder;
|
IVideoDecoder* decoder = s_ActiveSession->m_VideoDecoder;
|
||||||
if (decoder != nullptr) {
|
if (decoder != nullptr) {
|
||||||
int ret = decoder->submitDecodeUnit(du);
|
int ret = decoder->submitDecodeUnit(du);
|
||||||
|
@ -160,7 +174,8 @@ Session::Session(NvComputer* computer, NvApp& app)
|
||||||
m_App(app),
|
m_App(app),
|
||||||
m_Window(nullptr),
|
m_Window(nullptr),
|
||||||
m_VideoDecoder(nullptr),
|
m_VideoDecoder(nullptr),
|
||||||
m_DecoderLock(0)
|
m_DecoderLock(0),
|
||||||
|
m_NeedsIdr(false)
|
||||||
{
|
{
|
||||||
LiInitializeVideoCallbacks(&m_VideoCallbacks);
|
LiInitializeVideoCallbacks(&m_VideoCallbacks);
|
||||||
m_VideoCallbacks.setup = drSetup;
|
m_VideoCallbacks.setup = drSetup;
|
||||||
|
@ -510,6 +525,32 @@ void Session::exec()
|
||||||
m_VideoDecoder->renderFrame(&event.user);
|
m_VideoDecoder->renderFrame(&event.user);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case SDL_RENDER_DEVICE_RESET:
|
||||||
|
case SDL_RENDER_TARGETS_RESET:
|
||||||
|
SDL_AtomicLock(&m_DecoderLock);
|
||||||
|
|
||||||
|
// Destroy the old decoder
|
||||||
|
delete m_VideoDecoder;
|
||||||
|
|
||||||
|
// Chose a new decoder (hopefully the same one, but possibly
|
||||||
|
// not if a GPU was removed or something).
|
||||||
|
if (!chooseDecoder(m_Preferences.videoDecoderSelection,
|
||||||
|
m_Window, m_ActiveVideoFormat, m_ActiveVideoWidth,
|
||||||
|
m_ActiveVideoHeight, m_ActiveVideoFrameRate,
|
||||||
|
s_ActiveSession->m_VideoDecoder)) {
|
||||||
|
SDL_AtomicUnlock(&m_DecoderLock);
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"Failed to recreate decoder after reset");
|
||||||
|
goto DispatchDeferredCleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request an IDR frame to complete the reset
|
||||||
|
m_NeedsIdr = true;
|
||||||
|
|
||||||
|
SDL_AtomicUnlock(&m_DecoderLock);
|
||||||
|
break;
|
||||||
|
|
||||||
case SDL_KEYUP:
|
case SDL_KEYUP:
|
||||||
case SDL_KEYDOWN:
|
case SDL_KEYDOWN:
|
||||||
inputHandler.handleKeyEvent(&event.key);
|
inputHandler.handleKeyEvent(&event.key);
|
||||||
|
|
|
@ -94,6 +94,12 @@ private:
|
||||||
SDL_Window* m_Window;
|
SDL_Window* m_Window;
|
||||||
IVideoDecoder* m_VideoDecoder;
|
IVideoDecoder* m_VideoDecoder;
|
||||||
SDL_SpinLock m_DecoderLock;
|
SDL_SpinLock m_DecoderLock;
|
||||||
|
bool m_NeedsIdr;
|
||||||
|
|
||||||
|
int m_ActiveVideoFormat;
|
||||||
|
int m_ActiveVideoWidth;
|
||||||
|
int m_ActiveVideoHeight;
|
||||||
|
int m_ActiveVideoFrameRate;
|
||||||
|
|
||||||
static SDL_AudioDeviceID s_AudioDevice;
|
static SDL_AudioDeviceID s_AudioDevice;
|
||||||
static OpusMSDecoder* s_OpusDecoder;
|
static OpusMSDecoder* s_OpusDecoder;
|
||||||
|
|
|
@ -409,28 +409,6 @@ void DXVA2Renderer::renderFrame(AVFrame* frame)
|
||||||
IDirect3DSurface9* surface = reinterpret_cast<IDirect3DSurface9*>(frame->data[3]);
|
IDirect3DSurface9* surface = reinterpret_cast<IDirect3DSurface9*>(frame->data[3]);
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
hr = m_Device->TestCooperativeLevel();
|
|
||||||
switch (hr) {
|
|
||||||
case D3D_OK:
|
|
||||||
break;
|
|
||||||
case D3DERR_DEVICELOST:
|
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
|
||||||
"D3D device lost!");
|
|
||||||
av_frame_free(&frame);
|
|
||||||
return;
|
|
||||||
case D3DERR_DEVICENOTRESET:
|
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
|
||||||
"D3D device not reset!");
|
|
||||||
av_frame_free(&frame);
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
|
||||||
"Unknown D3D error: %x",
|
|
||||||
hr);
|
|
||||||
av_frame_free(&frame);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DXVA2_VideoSample sample = {};
|
DXVA2_VideoSample sample = {};
|
||||||
sample.Start = m_FrameIndex;
|
sample.Start = m_FrameIndex;
|
||||||
sample.End = m_FrameIndex + 1;
|
sample.End = m_FrameIndex + 1;
|
||||||
|
@ -473,25 +451,33 @@ void DXVA2Renderer::renderFrame(AVFrame* frame)
|
||||||
|
|
||||||
bltParams.Alpha = DXVA2_Fixed32OpaqueAlpha();
|
bltParams.Alpha = DXVA2_Fixed32OpaqueAlpha();
|
||||||
|
|
||||||
hr = m_Device->Clear(0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_ARGB(255, 0, 0, 0), 0.0f, 0);
|
if (SDL_RenderClear(m_SdlRenderer) != 0) {
|
||||||
if (FAILED(hr)) {
|
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
"SDL_RenderClear() failed: %s",
|
||||||
"Clear() failed: %x",
|
SDL_GetError());
|
||||||
hr);
|
|
||||||
av_frame_free(&frame);
|
av_frame_free(&frame);
|
||||||
|
|
||||||
|
// We're going to cheat a little bit here. It seems SDL's
|
||||||
|
// renderer may flake out in scenarios like moving the window
|
||||||
|
// between monitors, so generate a synthetic reset event for
|
||||||
|
// the main loop to consume.
|
||||||
|
SDL_Event event;
|
||||||
|
event.type = SDL_RENDER_TARGETS_RESET;
|
||||||
|
SDL_PushEvent(&event);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = m_Processor->VideoProcessBlt(m_RenderTarget, &bltParams, &sample, 1, nullptr);
|
hr = m_Processor->VideoProcessBlt(m_RenderTarget, &bltParams, &sample, 1, nullptr);
|
||||||
|
av_frame_free(&frame);
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
"VideoProcessBlt() failed: %x",
|
"VideoProcessBlt() failed: %x",
|
||||||
hr);
|
hr);
|
||||||
av_frame_free(&frame);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Device->Present(nullptr, nullptr, nullptr, nullptr);
|
// We must try to present to trigger SDL's logic to recover the render target,
|
||||||
|
// even if VideoProcessBlt() fails.
|
||||||
av_frame_free(&frame);
|
SDL_RenderPresent(m_SdlRenderer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,14 +128,9 @@ FFmpegVideoDecoder::~FFmpegVideoDecoder()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
avcodec_close(m_VideoDecoderCtx);
|
avcodec_free_context(&m_VideoDecoderCtx);
|
||||||
av_free(m_VideoDecoderCtx);
|
|
||||||
m_VideoDecoderCtx = nullptr;
|
|
||||||
|
|
||||||
m_HwDecodeCfg = nullptr;
|
|
||||||
|
|
||||||
delete m_Renderer;
|
delete m_Renderer;
|
||||||
m_Renderer = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FFmpegVideoDecoder::initialize(
|
bool FFmpegVideoDecoder::initialize(
|
||||||
|
|
Loading…
Reference in a new issue