Add (untested) Steam Link video decoding/rendering

This commit is contained in:
Cameron Gutman 2018-07-21 20:22:00 -07:00
parent a97e4babf9
commit ad57a55d12
7 changed files with 176 additions and 0 deletions

View file

@ -101,6 +101,15 @@ libva {
DEFINES += HAVE_LIBVA
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 {
message(DXVA2 renderer selected)

View file

@ -9,6 +9,10 @@
#include "video/ffmpeg.h"
#endif
#ifdef HAVE_SLVIDEO
#include "video/sl.h"
#endif
#include <openssl/rand.h>
#include <QtEndian>
@ -85,6 +89,21 @@ bool Session::chooseDecoder(StreamingPreferences::VideoDecoderSelection vds,
SDL_Window* window, int videoFormat, int width, int height,
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
chosenDecoder = new FFmpegVideoDecoder();
if (chosenDecoder->initialize(vds, window, videoFormat, width, height, frameRate)) {

106
app/streaming/video/sl.cpp Normal file
View 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
View 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;
};

View file

@ -0,0 +1,3 @@
SOURCES = main.cpp
LIBS += -lSLVideo

View file

@ -0,0 +1,7 @@
#include <SLVideo.h>
int main()
{
SLVideo_CreateContext();
return 0;
}

View file

@ -6,3 +6,7 @@ SUBDIRS = \
app
CONFIG += ordered
# Run our compile tests
load(configure)
qtCompileTest(SLVideo)