mirror of
https://github.com/moonlight-stream/moonlight-qt
synced 2024-12-14 13:22:27 +00:00
112 lines
2.6 KiB
C++
112 lines
2.6 KiB
C++
#include "slvid.h"
|
|
|
|
SLVideoDecoder::SLVideoDecoder(bool)
|
|
: 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;
|
|
}
|
|
|
|
int
|
|
SLVideoDecoder::getDecoderCapabilities()
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
bool
|
|
SLVideoDecoder::initialize(StreamingPreferences::VideoDecoderSelection vds,
|
|
SDL_Window*,
|
|
int videoFormat, int, int, int frameRate, bool, bool)
|
|
{
|
|
// 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;
|
|
}
|