Add Raspberry Pi Decoder (Fix #126) (#360)

This commit is contained in:
Blueroom VR 2020-11-14 10:51:08 -08:00 committed by GitHub
commit ea79836f0f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 543 additions and 7 deletions

View file

@ -30,6 +30,12 @@ enum class DisconnectAction
Ask
};
enum class Decoder
{
Ffmpeg,
Pi
};
class Settings : public QObject
{
Q_OBJECT
@ -69,6 +75,9 @@ class Settings : public QObject
unsigned int GetBitrate() const;
void SetBitrate(unsigned int bitrate);
Decoder GetDecoder() const;
void SetDecoder(Decoder decoder);
HardwareDecodeEngine GetHardwareDecodeEngine() const;
void SetHardwareDecodeEngine(HardwareDecodeEngine enabled);

View file

@ -25,6 +25,7 @@ class SettingsDialog : public QDialog
QComboBox *fps_combo_box;
QLineEdit *bitrate_edit;
QLineEdit *audio_buffer_size_edit;
QCheckBox *pi_decoder_check_box;
QComboBox *hardware_decode_combo_box;
QListWidget *registered_hosts_list_widget;
@ -41,6 +42,7 @@ class SettingsDialog : public QDialog
void BitrateEdited();
void AudioBufferSizeEdited();
void HardwareDecodeEngineSelected();
void UpdateHardwareDecodeEngineComboBox();
void UpdateRegisteredHosts();
void UpdateRegisteredHostsButtons();

View file

@ -6,6 +6,10 @@
#include <chiaki/session.h>
#include <chiaki/opusdecoder.h>
#if CHIAKI_LIB_ENABLE_PI_DECODER
#include <chiaki/pidecoder.h>
#endif
#if CHIAKI_GUI_ENABLE_SETSU
#include <setsu.h>
#endif
@ -14,6 +18,7 @@
#include "exception.h"
#include "sessionlog.h"
#include "controllermanager.h"
#include "settings.h"
#include <QObject>
#include <QImage>
@ -35,6 +40,7 @@ struct StreamSessionConnectInfo
{
Settings *settings;
QMap<Qt::Key, int> key_map;
Decoder decoder;
HardwareDecodeEngine hw_decode_engine;
uint32_t log_level_mask;
QString log_file;
@ -70,7 +76,10 @@ class StreamSession : public QObject
ChiakiControllerState keyboard_state;
VideoDecoder video_decoder;
VideoDecoder *video_decoder;
#if CHIAKI_LIB_ENABLE_PI_DECODER
ChiakiPiDecoder *pi_decoder;
#endif
unsigned int audio_buffer_size;
QAudioOutput *audio_output;
@ -101,7 +110,10 @@ class StreamSession : public QObject
void SetLoginPIN(const QString &pin);
Controller *GetController() { return controller; }
VideoDecoder *GetVideoDecoder() { return &video_decoder; }
VideoDecoder *GetVideoDecoder() { return video_decoder; }
#if CHIAKI_LIB_ENABLE_PI_DECODER
ChiakiPiDecoder *GetPiDecoder() { return pi_decoder; }
#endif
void HandleKeyboardEvent(QKeyEvent *event);
void HandleMouseEvent(QMouseEvent *event);

View file

@ -25,6 +25,7 @@ class StreamWindow: public QMainWindow
AVOpenGLWidget *av_widget;
void Init();
void UpdateVideoTransform();
protected:
void keyPressEvent(QKeyEvent *event) override;
@ -32,6 +33,9 @@ class StreamWindow: public QMainWindow
void closeEvent(QCloseEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
void resizeEvent(QResizeEvent *event) override;
void moveEvent(QMoveEvent *event) override;
void changeEvent(QEvent *event) override;
private slots:
void SessionQuit(ChiakiQuitReason reason, const QString &reason_str);

View file

@ -3,6 +3,8 @@
#include <settings.h>
#include <QKeySequence>
#include <chiaki/config.h>
#define SETTINGS_VERSION 1
Settings::Settings(QObject *parent) : QObject(parent)
@ -79,6 +81,28 @@ unsigned int Settings::GetAudioBufferSizeRaw() const
return settings.value("settings/audio_buffer_size", 0).toUInt();
}
static const QMap<Decoder, QString> decoder_values = {
{ Decoder::Ffmpeg, "ffmpeg" },
{ Decoder::Pi, "pi" }
};
static const Decoder decoder_default = Decoder::Pi;
Decoder Settings::GetDecoder() const
{
#if CHIAKI_LIB_ENABLE_PI_DECODER
auto v = settings.value("settings/decoder", decoder_values[decoder_default]).toString();
return decoder_values.key(v, decoder_default);
#else
return Decoder::Ffmpeg;
#endif
}
void Settings::SetDecoder(Decoder decoder)
{
settings.setValue("settings/decoder", decoder_values[decoder]);
}
static const QMap<HardwareDecodeEngine, QString> hw_decode_engine_values = {
{ HW_DECODE_NONE, "none" },
{ HW_DECODE_VAAPI, "vaapi" },

View file

@ -20,6 +20,8 @@
#include <QCheckBox>
#include <QLineEdit>
#include <chiaki/config.h>
const char * const about_string =
"<h1>Chiaki</h1> by thestr4ng3r, version " CHIAKI_VERSION
""
@ -157,6 +159,18 @@ SettingsDialog::SettingsDialog(Settings *settings, QWidget *parent) : QDialog(pa
auto decode_settings_layout = new QFormLayout();
decode_settings->setLayout(decode_settings_layout);
#if CHIAKI_LIB_ENABLE_PI_DECODER
pi_decoder_check_box = new QCheckBox(this);
pi_decoder_check_box->setChecked(settings->GetDecoder() == Decoder::Pi);
connect(pi_decoder_check_box, &QCheckBox::toggled, this, [this](bool checked) {
this->settings->SetDecoder(checked ? Decoder::Pi : Decoder::Ffmpeg);
UpdateHardwareDecodeEngineComboBox();
});
decode_settings_layout->addRow(tr("Use Raspberry Pi Decoder:"), pi_decoder_check_box);
#else
pi_decoder_check_box = nullptr;
#endif
hardware_decode_combo_box = new QComboBox(this);
static const QList<QPair<HardwareDecodeEngine, const char *>> hardware_decode_engines = {
{ HW_DECODE_NONE, "none"},
@ -173,6 +187,7 @@ SettingsDialog::SettingsDialog(Settings *settings, QWidget *parent) : QDialog(pa
}
connect(hardware_decode_combo_box, SIGNAL(currentIndexChanged(int)), this, SLOT(HardwareDecodeEngineSelected()));
decode_settings_layout->addRow(tr("Hardware decode method:"), hardware_decode_combo_box);
UpdateHardwareDecodeEngineComboBox();
// Registered Consoles
@ -281,6 +296,11 @@ void SettingsDialog::HardwareDecodeEngineSelected()
settings->SetHardwareDecodeEngine((HardwareDecodeEngine)hardware_decode_combo_box->currentData().toInt());
}
void SettingsDialog::UpdateHardwareDecodeEngineComboBox()
{
hardware_decode_combo_box->setEnabled(settings->GetDecoder() == Decoder::Ffmpeg);
}
void SettingsDialog::UpdateBitratePlaceholder()
{
bitrate_edit->setPlaceholderText(tr("Automatic (%1)").arg(settings->GetVideoProfile().bitrate));

View file

@ -18,6 +18,7 @@ StreamSessionConnectInfo::StreamSessionConnectInfo(Settings *settings, QString h
: settings(settings)
{
key_map = settings->GetControllerMappingForDecoding();
decoder = settings->GetDecoder();
hw_decode_engine = settings->GetHardwareDecodeEngine();
log_level_mask = settings->GetLogLevelMask();
log_file = CreateLogFilename();
@ -42,11 +43,30 @@ StreamSession::StreamSession(const StreamSessionConnectInfo &connect_info, QObje
: QObject(parent),
log(this, connect_info.log_level_mask, connect_info.log_file),
controller(nullptr),
video_decoder(connect_info.hw_decode_engine, log.GetChiakiLog()),
video_decoder(nullptr),
#if CHIAKI_LIB_ENABLE_PI_DECODER
pi_decoder(nullptr),
#endif
audio_output(nullptr),
audio_io(nullptr)
{
connected = false;
#if CHIAKI_LIB_ENABLE_PI_DECODER
if(connect_info.decoder == Decoder::Pi)
{
pi_decoder = CHIAKI_NEW(ChiakiPiDecoder);
if(chiaki_pi_decoder_init(pi_decoder, log.GetChiakiLog()) != CHIAKI_ERR_SUCCESS)
throw ChiakiException("Failed to initialize Raspberry Pi Decoder");
}
else
{
#endif
video_decoder = new VideoDecoder(connect_info.hw_decode_engine, log.GetChiakiLog());
#if CHIAKI_LIB_ENABLE_PI_DECODER
}
#endif
chiaki_opus_decoder_init(&opus_decoder, log.GetChiakiLog());
audio_buffer_size = connect_info.audio_buffer_size;
@ -75,7 +95,17 @@ StreamSession::StreamSession(const StreamSessionConnectInfo &connect_info, QObje
chiaki_opus_decoder_get_sink(&opus_decoder, &audio_sink);
chiaki_session_set_audio_sink(&session, &audio_sink);
chiaki_session_set_video_sample_cb(&session, VideoSampleCb, this);
#if CHIAKI_LIB_ENABLE_PI_DECODER
if(pi_decoder)
chiaki_session_set_video_sample_cb(&session, chiaki_pi_decoder_video_sample_cb, pi_decoder);
else
{
#endif
chiaki_session_set_video_sample_cb(&session, VideoSampleCb, this);
#if CHIAKI_LIB_ENABLE_PI_DECODER
}
#endif
chiaki_session_set_event_cb(&session, EventCb, this);
#if CHIAKI_GUI_ENABLE_SDL_GAMECONTROLLER
@ -107,6 +137,14 @@ StreamSession::~StreamSession()
#if CHIAKI_GUI_ENABLE_SETSU
setsu_free(setsu);
#endif
#if CHIAKI_LIB_ENABLE_PI_DECODER
if(pi_decoder)
{
chiaki_pi_decoder_fini(pi_decoder);
free(pi_decoder);
}
#endif
delete video_decoder;
}
void StreamSession::Start()
@ -285,7 +323,7 @@ void StreamSession::PushAudioFrame(int16_t *buf, size_t samples_count)
void StreamSession::PushVideoSample(uint8_t *buf, size_t buf_size)
{
video_decoder.PushFrame(buf, buf_size);
video_decoder->PushFrame(buf, buf_size);
}
void StreamSession::Event(ChiakiEvent *event)

View file

@ -47,8 +47,17 @@ void StreamWindow::Init()
connect(session, &StreamSession::SessionQuit, this, &StreamWindow::SessionQuit);
connect(session, &StreamSession::LoginPINRequested, this, &StreamWindow::LoginPINRequested);
av_widget = new AVOpenGLWidget(session->GetVideoDecoder(), this);
setCentralWidget(av_widget);
if(session->GetVideoDecoder())
{
av_widget = new AVOpenGLWidget(session->GetVideoDecoder(), this);
setCentralWidget(av_widget);
}
else
{
QWidget *bg_widget = new QWidget(this);
bg_widget->setStyleSheet("background-color: black;");
setCentralWidget(bg_widget);
}
grabKeyboard();
@ -167,3 +176,34 @@ void StreamWindow::ToggleFullscreen()
av_widget->HideMouse();
}
}
void StreamWindow::resizeEvent(QResizeEvent *event)
{
UpdateVideoTransform();
QMainWindow::resizeEvent(event);
}
void StreamWindow::moveEvent(QMoveEvent *event)
{
UpdateVideoTransform();
QMainWindow::moveEvent(event);
}
void StreamWindow::changeEvent(QEvent *event)
{
if(event->type() == QEvent::ActivationChange)
UpdateVideoTransform();
QMainWindow::changeEvent(event);
}
void StreamWindow::UpdateVideoTransform()
{
#if CHIAKI_LIB_ENABLE_PI_DECODER
ChiakiPiDecoder *pi_decoder = session->GetPiDecoder();
if(pi_decoder)
{
QRect r = geometry();
chiaki_pi_decoder_set_params(pi_decoder, r.x(), r.y(), r.width(), r.height(), isActiveWindow());
}
#endif
}