mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2025-07-01 23:35:55 +00:00
Add (untested) Steam Link video decoding/rendering
This commit is contained in:
parent
a97e4babf9
commit
ad57a55d12
@ -101,6 +101,15 @@ libva {
|
|||||||
|
|
||||||
DEFINES += HAVE_LIBVA
|
DEFINES += HAVE_LIBVA
|
||||||
SOURCES += streaming/video/ffmpeg-renderers/vaapi.cpp
|
SOURCES += streaming/video/ffmpeg-renderers/vaapi.cpp
|
||||||
|
HEADERS += streaming/video/ffmpeg-renderers/vaapi.h
|
||||||
|
}
|
||||||
|
config_SLVideo {
|
||||||
|
message(SLVideo decoder/renderer selected)
|
||||||
|
|
||||||
|
DEFINES += HAVE_SLVIDEO
|
||||||
|
LIBS += -lSLVideo
|
||||||
|
SOURCES += streaming/video/sl.cpp
|
||||||
|
HEADERS += streaming/video/sl.h
|
||||||
}
|
}
|
||||||
win32 {
|
win32 {
|
||||||
message(DXVA2 renderer selected)
|
message(DXVA2 renderer selected)
|
||||||
|
@ -9,6 +9,10 @@
|
|||||||
#include "video/ffmpeg.h"
|
#include "video/ffmpeg.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SLVIDEO
|
||||||
|
#include "video/sl.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <openssl/rand.h>
|
#include <openssl/rand.h>
|
||||||
|
|
||||||
#include <QtEndian>
|
#include <QtEndian>
|
||||||
@ -85,6 +89,21 @@ bool Session::chooseDecoder(StreamingPreferences::VideoDecoderSelection vds,
|
|||||||
SDL_Window* window, int videoFormat, int width, int height,
|
SDL_Window* window, int videoFormat, int width, int height,
|
||||||
int frameRate, IVideoDecoder*& chosenDecoder)
|
int frameRate, IVideoDecoder*& chosenDecoder)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_SLVIDEO
|
||||||
|
chosenDecoder = new SLVideoDecoder();
|
||||||
|
if (chosenDecoder->initialize(vds, window, videoFormat, width, height, frameRate)) {
|
||||||
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"SLVideo video decoder chosen");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"Unable to load SLVideo decoder");
|
||||||
|
delete chosenDecoder;
|
||||||
|
chosenDecoder = nullptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_FFMPEG
|
#ifdef HAVE_FFMPEG
|
||||||
chosenDecoder = new FFmpegVideoDecoder();
|
chosenDecoder = new FFmpegVideoDecoder();
|
||||||
if (chosenDecoder->initialize(vds, window, videoFormat, width, height, frameRate)) {
|
if (chosenDecoder->initialize(vds, window, videoFormat, width, height, frameRate)) {
|
||||||
|
106
app/streaming/video/sl.cpp
Normal file
106
app/streaming/video/sl.cpp
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
#include "sl.h"
|
||||||
|
|
||||||
|
SLVideoDecoder::SLVideoDecoder()
|
||||||
|
: m_VideoContext(nullptr),
|
||||||
|
m_VideoStream(nullptr)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SLVideoDecoder::~SLVideoDecoder()
|
||||||
|
{
|
||||||
|
if (m_VideoStream != nullptr) {
|
||||||
|
SLVideo_FreeStream(m_VideoStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_VideoContext != nullptr) {
|
||||||
|
SLVideo_FreeContext(m_VideoContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
SLVideoDecoder::isHardwareAccelerated()
|
||||||
|
{
|
||||||
|
// SLVideo is always hardware accelerated
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
SLVideoDecoder::initialize(StreamingPreferences::VideoDecoderSelection vds,
|
||||||
|
SDL_Window*,
|
||||||
|
int videoFormat, int, int, int frameRate)
|
||||||
|
{
|
||||||
|
// SLVideo only supports hardware decoding
|
||||||
|
if (vds == StreamingPreferences::VDS_FORCE_SOFTWARE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SLVideo only supports H.264
|
||||||
|
if (videoFormat != VIDEO_FORMAT_H264) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_VideoContext = SLVideo_CreateContext();
|
||||||
|
if (!m_VideoContext) {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"SLVideo_CreateContext() failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a low latency H.264 stream
|
||||||
|
m_VideoStream = SLVideo_CreateStream(m_VideoContext, k_ESLVideoFormatH264, 1);
|
||||||
|
if (!m_VideoStream) {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"SLVideo_CreateStream() failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SLVideo_SetStreamTargetFramerate(m_VideoStream, frameRate, 1);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
SLVideoDecoder::submitDecodeUnit(PDECODE_UNIT du)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = SLVideo_BeginFrame(m_VideoStream, du->fullLength);
|
||||||
|
if (err < 0) {
|
||||||
|
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"SLVideo_BeginFrame() failed: %d",
|
||||||
|
err);
|
||||||
|
|
||||||
|
// Need an IDR frame to resync
|
||||||
|
return DR_NEED_IDR;
|
||||||
|
}
|
||||||
|
|
||||||
|
PLENTRY entry = du->bufferList;
|
||||||
|
while (entry != nullptr) {
|
||||||
|
err = SLVideo_WriteFrameData(m_VideoStream,
|
||||||
|
entry->data,
|
||||||
|
entry->length);
|
||||||
|
if (err < 0) {
|
||||||
|
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"SLVideo_WriteFrameData() failed: %d",
|
||||||
|
err);
|
||||||
|
|
||||||
|
// Need an IDR frame to resync
|
||||||
|
return DR_NEED_IDR;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry = entry->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = SLVideo_SubmitFrame(m_VideoStream);
|
||||||
|
if (err < 0) {
|
||||||
|
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"SLVideo_SubmitFrame() failed: %d",
|
||||||
|
err);
|
||||||
|
|
||||||
|
// Need an IDR frame to resync
|
||||||
|
return DR_NEED_IDR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DR_OK;
|
||||||
|
}
|
28
app/streaming/video/sl.h
Normal file
28
app/streaming/video/sl.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "decoder.h"
|
||||||
|
|
||||||
|
#include <SLVideo.h>
|
||||||
|
|
||||||
|
class SLVideoDecoder : public IVideoDecoder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SLVideoDecoder();
|
||||||
|
virtual ~SLVideoDecoder();
|
||||||
|
virtual bool initialize(StreamingPreferences::VideoDecoderSelection vds,
|
||||||
|
SDL_Window* window,
|
||||||
|
int videoFormat,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
int frameRate);
|
||||||
|
virtual bool isHardwareAccelerated();
|
||||||
|
virtual int submitDecodeUnit(PDECODE_UNIT du);
|
||||||
|
|
||||||
|
// Unused since rendering is done directly from the decode thread
|
||||||
|
virtual void renderFrame(SDL_UserEvent*) {}
|
||||||
|
virtual void dropFrame(SDL_UserEvent*) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
CSLVideoContext* m_VideoContext;
|
||||||
|
CSLVideoStream* m_VideoStream;
|
||||||
|
};
|
3
config.tests/SLVideo/SLVideo.pro
Normal file
3
config.tests/SLVideo/SLVideo.pro
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
SOURCES = main.cpp
|
||||||
|
LIBS += -lSLVideo
|
||||||
|
|
7
config.tests/SLVideo/main.cpp
Normal file
7
config.tests/SLVideo/main.cpp
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#include <SLVideo.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
SLVideo_CreateContext();
|
||||||
|
return 0;
|
||||||
|
}
|
@ -6,3 +6,7 @@ SUBDIRS = \
|
|||||||
app
|
app
|
||||||
|
|
||||||
CONFIG += ordered
|
CONFIG += ordered
|
||||||
|
|
||||||
|
# Run our compile tests
|
||||||
|
load(configure)
|
||||||
|
qtCompileTest(SLVideo)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user