mirror of
https://git.sr.ht/~thestr4ng3r/chiaki
synced 2025-08-19 21:13:12 -07:00
parent
8b6f9a5fc1
commit
ea79836f0f
14 changed files with 543 additions and 7 deletions
|
@ -16,6 +16,7 @@ option(CHIAKI_ENABLE_ANDROID "Enable Android (Use only as part of the Gradle Pro
|
||||||
option(CHIAKI_ENABLE_SWITCH "Enable Nintendo Switch (Requires devKitPro libnx)" OFF)
|
option(CHIAKI_ENABLE_SWITCH "Enable Nintendo Switch (Requires devKitPro libnx)" OFF)
|
||||||
tri_option(CHIAKI_ENABLE_SETSU "Enable libsetsu for touchpad input from controller" AUTO)
|
tri_option(CHIAKI_ENABLE_SETSU "Enable libsetsu for touchpad input from controller" AUTO)
|
||||||
option(CHIAKI_LIB_ENABLE_OPUS "Use Opus as part of Chiaki Lib" ON)
|
option(CHIAKI_LIB_ENABLE_OPUS "Use Opus as part of Chiaki Lib" ON)
|
||||||
|
tri_option(CHIAKI_ENABLE_PI_DECODER "Enable Raspberry Pi-specific video decoder (requires libraspberrypi0 and libraspberrypi-doc)" AUTO)
|
||||||
option(CHIAKI_LIB_ENABLE_MBEDTLS "Use mbedtls instead of OpenSSL as part of Chiaki Lib" OFF)
|
option(CHIAKI_LIB_ENABLE_MBEDTLS "Use mbedtls instead of OpenSSL as part of Chiaki Lib" OFF)
|
||||||
option(CHIAKI_LIB_OPENSSL_EXTERNAL_PROJECT "Use OpenSSL as CMake external project" OFF)
|
option(CHIAKI_LIB_OPENSSL_EXTERNAL_PROJECT "Use OpenSSL as CMake external project" OFF)
|
||||||
option(CHIAKI_GUI_ENABLE_SDL_GAMECONTROLLER "Use SDL Gamecontroller for Input" ON)
|
option(CHIAKI_GUI_ENABLE_SDL_GAMECONTROLLER "Use SDL Gamecontroller for Input" ON)
|
||||||
|
@ -99,6 +100,27 @@ if(CHIAKI_LIB_ENABLE_MBEDTLS)
|
||||||
add_definitions(-DCHIAKI_LIB_ENABLE_MBEDTLS)
|
add_definitions(-DCHIAKI_LIB_ENABLE_MBEDTLS)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(CHIAKI_ENABLE_PI_DECODER)
|
||||||
|
find_package(ILClient)
|
||||||
|
if(ILClient_FOUND)
|
||||||
|
set(CHIAKI_ENABLE_PI_DECODER ON)
|
||||||
|
else()
|
||||||
|
if(NOT CHIAKI_ENABLE_PI_DECODER STREQUAL AUTO)
|
||||||
|
message(FATAL_ERROR "
|
||||||
|
CHIAKI_ENABLE_PI_DECODER is set to ON, but its dependencies (ilclient source and libs) could not be resolved.
|
||||||
|
The Raspberry Pi Decoder is only supported on Raspberry Pi OS and requires libraspberrypi0 and libraspberrypi-doc.")
|
||||||
|
endif()
|
||||||
|
set(CHIAKI_ENABLE_PI_DECODER OFF)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CHIAKI_ENABLE_PI_DECODER)
|
||||||
|
message(STATUS "Pi Decoder enabled")
|
||||||
|
else()
|
||||||
|
message(STATUS "Pi Decoder disabled")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
add_subdirectory(lib)
|
add_subdirectory(lib)
|
||||||
|
|
||||||
if(CHIAKI_ENABLE_CLI)
|
if(CHIAKI_ENABLE_CLI)
|
||||||
|
|
57
cmake/FindILClient.cmake
Normal file
57
cmake/FindILClient.cmake
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
# Provides ILClient::ILClient
|
||||||
|
# (Raspberry Pi-specific video decoding stuff, very specific for libraspberrypi0 and libraspberrypi-doc)
|
||||||
|
|
||||||
|
set(_required_libs
|
||||||
|
/opt/vc/lib/libbcm_host.so
|
||||||
|
/opt/vc/lib/libvcilcs.a
|
||||||
|
/opt/vc/lib/libvchiq_arm.so
|
||||||
|
/opt/vc/lib/libvcos.so)
|
||||||
|
|
||||||
|
unset(_libvars)
|
||||||
|
foreach(_lib ${_required_libs})
|
||||||
|
get_filename_component(_libname "${_lib}" NAME_WE)
|
||||||
|
set(_libvar "ILClient_${_libname}_LIBRARY")
|
||||||
|
list(APPEND _libvars "${_libvar}")
|
||||||
|
if(EXISTS "${_lib}")
|
||||||
|
set("${_libvar}" "${_lib}")
|
||||||
|
else()
|
||||||
|
set("${_libvar}" "${_libvar}-NOTFOUND")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
find_path(ILClient_INCLUDE_DIR bcm_host.h
|
||||||
|
PATHS /opt/vc/include
|
||||||
|
NO_DEFAULT_PATH)
|
||||||
|
|
||||||
|
find_path(ILClient_SOURCE_DIR ilclient.c
|
||||||
|
PATHS /opt/vc/src/hello_pi/libs/ilclient)
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(ILClient
|
||||||
|
FOUND_VAR ILClient_FOUND
|
||||||
|
REQUIRED_VARS
|
||||||
|
${_libvars}
|
||||||
|
ILClient_INCLUDE_DIR
|
||||||
|
ILClient_SOURCE_DIR)
|
||||||
|
|
||||||
|
if(ILClient_FOUND)
|
||||||
|
if(NOT TARGET ILClient::ILClient)
|
||||||
|
# see /opt/vc/src/hello_pi/libs/ilclient/Makefile
|
||||||
|
add_library(ilclient STATIC
|
||||||
|
"${ILClient_SOURCE_DIR}/ilclient.c"
|
||||||
|
"${ILClient_SOURCE_DIR}/ilcore.c")
|
||||||
|
target_include_directories(ilclient PUBLIC
|
||||||
|
"${ILClient_INCLUDE_DIR}"
|
||||||
|
"${ILClient_SOURCE_DIR}")
|
||||||
|
target_compile_definitions(ilclient PUBLIC
|
||||||
|
HAVE_LIBOPENMAX=2
|
||||||
|
OMX
|
||||||
|
OMX_SKIP64BIT
|
||||||
|
USE_EXTERNAL_OMX
|
||||||
|
HAVE_LIBBCM_HOST
|
||||||
|
USE_EXTERNAL_LIBBCM_HOST
|
||||||
|
USE_VCHIQ_ARM)
|
||||||
|
target_link_libraries(ilclient PUBLIC ${_required_libs})
|
||||||
|
add_library(ILClient::ILClient ALIAS ilclient)
|
||||||
|
endif()
|
||||||
|
endif()
|
|
@ -30,6 +30,12 @@ enum class DisconnectAction
|
||||||
Ask
|
Ask
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class Decoder
|
||||||
|
{
|
||||||
|
Ffmpeg,
|
||||||
|
Pi
|
||||||
|
};
|
||||||
|
|
||||||
class Settings : public QObject
|
class Settings : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -69,6 +75,9 @@ class Settings : public QObject
|
||||||
unsigned int GetBitrate() const;
|
unsigned int GetBitrate() const;
|
||||||
void SetBitrate(unsigned int bitrate);
|
void SetBitrate(unsigned int bitrate);
|
||||||
|
|
||||||
|
Decoder GetDecoder() const;
|
||||||
|
void SetDecoder(Decoder decoder);
|
||||||
|
|
||||||
HardwareDecodeEngine GetHardwareDecodeEngine() const;
|
HardwareDecodeEngine GetHardwareDecodeEngine() const;
|
||||||
void SetHardwareDecodeEngine(HardwareDecodeEngine enabled);
|
void SetHardwareDecodeEngine(HardwareDecodeEngine enabled);
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ class SettingsDialog : public QDialog
|
||||||
QComboBox *fps_combo_box;
|
QComboBox *fps_combo_box;
|
||||||
QLineEdit *bitrate_edit;
|
QLineEdit *bitrate_edit;
|
||||||
QLineEdit *audio_buffer_size_edit;
|
QLineEdit *audio_buffer_size_edit;
|
||||||
|
QCheckBox *pi_decoder_check_box;
|
||||||
QComboBox *hardware_decode_combo_box;
|
QComboBox *hardware_decode_combo_box;
|
||||||
|
|
||||||
QListWidget *registered_hosts_list_widget;
|
QListWidget *registered_hosts_list_widget;
|
||||||
|
@ -41,6 +42,7 @@ class SettingsDialog : public QDialog
|
||||||
void BitrateEdited();
|
void BitrateEdited();
|
||||||
void AudioBufferSizeEdited();
|
void AudioBufferSizeEdited();
|
||||||
void HardwareDecodeEngineSelected();
|
void HardwareDecodeEngineSelected();
|
||||||
|
void UpdateHardwareDecodeEngineComboBox();
|
||||||
|
|
||||||
void UpdateRegisteredHosts();
|
void UpdateRegisteredHosts();
|
||||||
void UpdateRegisteredHostsButtons();
|
void UpdateRegisteredHostsButtons();
|
||||||
|
|
|
@ -6,6 +6,10 @@
|
||||||
#include <chiaki/session.h>
|
#include <chiaki/session.h>
|
||||||
#include <chiaki/opusdecoder.h>
|
#include <chiaki/opusdecoder.h>
|
||||||
|
|
||||||
|
#if CHIAKI_LIB_ENABLE_PI_DECODER
|
||||||
|
#include <chiaki/pidecoder.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if CHIAKI_GUI_ENABLE_SETSU
|
#if CHIAKI_GUI_ENABLE_SETSU
|
||||||
#include <setsu.h>
|
#include <setsu.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -14,6 +18,7 @@
|
||||||
#include "exception.h"
|
#include "exception.h"
|
||||||
#include "sessionlog.h"
|
#include "sessionlog.h"
|
||||||
#include "controllermanager.h"
|
#include "controllermanager.h"
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
|
@ -35,6 +40,7 @@ struct StreamSessionConnectInfo
|
||||||
{
|
{
|
||||||
Settings *settings;
|
Settings *settings;
|
||||||
QMap<Qt::Key, int> key_map;
|
QMap<Qt::Key, int> key_map;
|
||||||
|
Decoder decoder;
|
||||||
HardwareDecodeEngine hw_decode_engine;
|
HardwareDecodeEngine hw_decode_engine;
|
||||||
uint32_t log_level_mask;
|
uint32_t log_level_mask;
|
||||||
QString log_file;
|
QString log_file;
|
||||||
|
@ -70,7 +76,10 @@ class StreamSession : public QObject
|
||||||
|
|
||||||
ChiakiControllerState keyboard_state;
|
ChiakiControllerState keyboard_state;
|
||||||
|
|
||||||
VideoDecoder video_decoder;
|
VideoDecoder *video_decoder;
|
||||||
|
#if CHIAKI_LIB_ENABLE_PI_DECODER
|
||||||
|
ChiakiPiDecoder *pi_decoder;
|
||||||
|
#endif
|
||||||
|
|
||||||
unsigned int audio_buffer_size;
|
unsigned int audio_buffer_size;
|
||||||
QAudioOutput *audio_output;
|
QAudioOutput *audio_output;
|
||||||
|
@ -101,7 +110,10 @@ class StreamSession : public QObject
|
||||||
void SetLoginPIN(const QString &pin);
|
void SetLoginPIN(const QString &pin);
|
||||||
|
|
||||||
Controller *GetController() { return controller; }
|
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 HandleKeyboardEvent(QKeyEvent *event);
|
||||||
void HandleMouseEvent(QMouseEvent *event);
|
void HandleMouseEvent(QMouseEvent *event);
|
||||||
|
|
|
@ -25,6 +25,7 @@ class StreamWindow: public QMainWindow
|
||||||
AVOpenGLWidget *av_widget;
|
AVOpenGLWidget *av_widget;
|
||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
|
void UpdateVideoTransform();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void keyPressEvent(QKeyEvent *event) override;
|
void keyPressEvent(QKeyEvent *event) override;
|
||||||
|
@ -32,6 +33,9 @@ class StreamWindow: public QMainWindow
|
||||||
void closeEvent(QCloseEvent *event) override;
|
void closeEvent(QCloseEvent *event) override;
|
||||||
void mousePressEvent(QMouseEvent *event) override;
|
void mousePressEvent(QMouseEvent *event) override;
|
||||||
void mouseReleaseEvent(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:
|
private slots:
|
||||||
void SessionQuit(ChiakiQuitReason reason, const QString &reason_str);
|
void SessionQuit(ChiakiQuitReason reason, const QString &reason_str);
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#include <settings.h>
|
#include <settings.h>
|
||||||
#include <QKeySequence>
|
#include <QKeySequence>
|
||||||
|
|
||||||
|
#include <chiaki/config.h>
|
||||||
|
|
||||||
#define SETTINGS_VERSION 1
|
#define SETTINGS_VERSION 1
|
||||||
|
|
||||||
Settings::Settings(QObject *parent) : QObject(parent)
|
Settings::Settings(QObject *parent) : QObject(parent)
|
||||||
|
@ -79,6 +81,28 @@ unsigned int Settings::GetAudioBufferSizeRaw() const
|
||||||
return settings.value("settings/audio_buffer_size", 0).toUInt();
|
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 = {
|
static const QMap<HardwareDecodeEngine, QString> hw_decode_engine_values = {
|
||||||
{ HW_DECODE_NONE, "none" },
|
{ HW_DECODE_NONE, "none" },
|
||||||
{ HW_DECODE_VAAPI, "vaapi" },
|
{ HW_DECODE_VAAPI, "vaapi" },
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
#include <QCheckBox>
|
#include <QCheckBox>
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
|
|
||||||
|
#include <chiaki/config.h>
|
||||||
|
|
||||||
const char * const about_string =
|
const char * const about_string =
|
||||||
"<h1>Chiaki</h1> by thestr4ng3r, version " CHIAKI_VERSION
|
"<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();
|
auto decode_settings_layout = new QFormLayout();
|
||||||
decode_settings->setLayout(decode_settings_layout);
|
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);
|
hardware_decode_combo_box = new QComboBox(this);
|
||||||
static const QList<QPair<HardwareDecodeEngine, const char *>> hardware_decode_engines = {
|
static const QList<QPair<HardwareDecodeEngine, const char *>> hardware_decode_engines = {
|
||||||
{ HW_DECODE_NONE, "none"},
|
{ 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()));
|
connect(hardware_decode_combo_box, SIGNAL(currentIndexChanged(int)), this, SLOT(HardwareDecodeEngineSelected()));
|
||||||
decode_settings_layout->addRow(tr("Hardware decode method:"), hardware_decode_combo_box);
|
decode_settings_layout->addRow(tr("Hardware decode method:"), hardware_decode_combo_box);
|
||||||
|
UpdateHardwareDecodeEngineComboBox();
|
||||||
|
|
||||||
// Registered Consoles
|
// Registered Consoles
|
||||||
|
|
||||||
|
@ -281,6 +296,11 @@ void SettingsDialog::HardwareDecodeEngineSelected()
|
||||||
settings->SetHardwareDecodeEngine((HardwareDecodeEngine)hardware_decode_combo_box->currentData().toInt());
|
settings->SetHardwareDecodeEngine((HardwareDecodeEngine)hardware_decode_combo_box->currentData().toInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SettingsDialog::UpdateHardwareDecodeEngineComboBox()
|
||||||
|
{
|
||||||
|
hardware_decode_combo_box->setEnabled(settings->GetDecoder() == Decoder::Ffmpeg);
|
||||||
|
}
|
||||||
|
|
||||||
void SettingsDialog::UpdateBitratePlaceholder()
|
void SettingsDialog::UpdateBitratePlaceholder()
|
||||||
{
|
{
|
||||||
bitrate_edit->setPlaceholderText(tr("Automatic (%1)").arg(settings->GetVideoProfile().bitrate));
|
bitrate_edit->setPlaceholderText(tr("Automatic (%1)").arg(settings->GetVideoProfile().bitrate));
|
||||||
|
|
|
@ -18,6 +18,7 @@ StreamSessionConnectInfo::StreamSessionConnectInfo(Settings *settings, QString h
|
||||||
: settings(settings)
|
: settings(settings)
|
||||||
{
|
{
|
||||||
key_map = settings->GetControllerMappingForDecoding();
|
key_map = settings->GetControllerMappingForDecoding();
|
||||||
|
decoder = settings->GetDecoder();
|
||||||
hw_decode_engine = settings->GetHardwareDecodeEngine();
|
hw_decode_engine = settings->GetHardwareDecodeEngine();
|
||||||
log_level_mask = settings->GetLogLevelMask();
|
log_level_mask = settings->GetLogLevelMask();
|
||||||
log_file = CreateLogFilename();
|
log_file = CreateLogFilename();
|
||||||
|
@ -42,11 +43,30 @@ StreamSession::StreamSession(const StreamSessionConnectInfo &connect_info, QObje
|
||||||
: QObject(parent),
|
: QObject(parent),
|
||||||
log(this, connect_info.log_level_mask, connect_info.log_file),
|
log(this, connect_info.log_level_mask, connect_info.log_file),
|
||||||
controller(nullptr),
|
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_output(nullptr),
|
||||||
audio_io(nullptr)
|
audio_io(nullptr)
|
||||||
{
|
{
|
||||||
connected = false;
|
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());
|
chiaki_opus_decoder_init(&opus_decoder, log.GetChiakiLog());
|
||||||
audio_buffer_size = connect_info.audio_buffer_size;
|
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_opus_decoder_get_sink(&opus_decoder, &audio_sink);
|
||||||
chiaki_session_set_audio_sink(&session, &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);
|
chiaki_session_set_event_cb(&session, EventCb, this);
|
||||||
|
|
||||||
#if CHIAKI_GUI_ENABLE_SDL_GAMECONTROLLER
|
#if CHIAKI_GUI_ENABLE_SDL_GAMECONTROLLER
|
||||||
|
@ -107,6 +137,14 @@ StreamSession::~StreamSession()
|
||||||
#if CHIAKI_GUI_ENABLE_SETSU
|
#if CHIAKI_GUI_ENABLE_SETSU
|
||||||
setsu_free(setsu);
|
setsu_free(setsu);
|
||||||
#endif
|
#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()
|
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)
|
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)
|
void StreamSession::Event(ChiakiEvent *event)
|
||||||
|
|
|
@ -47,8 +47,17 @@ void StreamWindow::Init()
|
||||||
connect(session, &StreamSession::SessionQuit, this, &StreamWindow::SessionQuit);
|
connect(session, &StreamSession::SessionQuit, this, &StreamWindow::SessionQuit);
|
||||||
connect(session, &StreamSession::LoginPINRequested, this, &StreamWindow::LoginPINRequested);
|
connect(session, &StreamSession::LoginPINRequested, this, &StreamWindow::LoginPINRequested);
|
||||||
|
|
||||||
av_widget = new AVOpenGLWidget(session->GetVideoDecoder(), this);
|
if(session->GetVideoDecoder())
|
||||||
setCentralWidget(av_widget);
|
{
|
||||||
|
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();
|
grabKeyboard();
|
||||||
|
|
||||||
|
@ -167,3 +176,34 @@ void StreamWindow::ToggleFullscreen()
|
||||||
av_widget->HideMouse();
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -73,6 +73,12 @@ set(SOURCE_FILES
|
||||||
src/regist.c
|
src/regist.c
|
||||||
src/opusdecoder.c)
|
src/opusdecoder.c)
|
||||||
|
|
||||||
|
if(CHIAKI_ENABLE_PI_DECODER)
|
||||||
|
list(APPEND HEADER_FILES include/chiaki/pidecoder.h)
|
||||||
|
list(APPEND SOURCE_FILES src/pidecoder.c)
|
||||||
|
endif()
|
||||||
|
set(CHIAKI_LIB_ENABLE_PI_DECODER "${CHIAKI_ENABLE_PI_DECODER}")
|
||||||
|
|
||||||
add_subdirectory(protobuf)
|
add_subdirectory(protobuf)
|
||||||
set_source_files_properties(${CHIAKI_LIB_PROTO_SOURCE_FILES} ${CHIAKI_LIB_PROTO_HEADER_FILES} PROPERTIES GENERATED TRUE)
|
set_source_files_properties(${CHIAKI_LIB_PROTO_SOURCE_FILES} ${CHIAKI_LIB_PROTO_HEADER_FILES} PROPERTIES GENERATED TRUE)
|
||||||
include_directories("${CHIAKI_LIB_PROTO_INCLUDE_DIR}")
|
include_directories("${CHIAKI_LIB_PROTO_INCLUDE_DIR}")
|
||||||
|
@ -119,6 +125,10 @@ endif()
|
||||||
target_link_libraries(chiaki-lib Nanopb::nanopb)
|
target_link_libraries(chiaki-lib Nanopb::nanopb)
|
||||||
target_link_libraries(chiaki-lib Jerasure::Jerasure)
|
target_link_libraries(chiaki-lib Jerasure::Jerasure)
|
||||||
|
|
||||||
|
if(CHIAKI_ENABLE_PI_DECODER)
|
||||||
|
target_link_libraries(chiaki-lib ILClient::ILClient)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(CHIAKI_LIB_ENABLE_OPUS)
|
if(CHIAKI_LIB_ENABLE_OPUS)
|
||||||
target_link_libraries(chiaki-lib ${Opus_LIBRARIES})
|
target_link_libraries(chiaki-lib ${Opus_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -4,5 +4,6 @@
|
||||||
#define CHIAKI_CONFIG_H
|
#define CHIAKI_CONFIG_H
|
||||||
|
|
||||||
#cmakedefine01 CHIAKI_LIB_ENABLE_OPUS
|
#cmakedefine01 CHIAKI_LIB_ENABLE_OPUS
|
||||||
|
#cmakedefine01 CHIAKI_LIB_ENABLE_PI_DECODER
|
||||||
|
|
||||||
#endif // CHIAKI_CONFIG_H
|
#endif // CHIAKI_CONFIG_H
|
||||||
|
|
36
lib/include/chiaki/pidecoder.h
Normal file
36
lib/include/chiaki/pidecoder.h
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#ifndef CHIAKI_PI_DECODER_H
|
||||||
|
#define CHIAKI_PI_DECODER_H
|
||||||
|
|
||||||
|
#include <chiaki/config.h>
|
||||||
|
#include <chiaki/log.h>
|
||||||
|
|
||||||
|
#include <ilclient.h>
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct chiaki_pi_decoder_t
|
||||||
|
{
|
||||||
|
ChiakiLog *log;
|
||||||
|
TUNNEL_T tunnel[2];
|
||||||
|
COMPONENT_T *components[3];
|
||||||
|
ILCLIENT_T *client;
|
||||||
|
COMPONENT_T *video_decode;
|
||||||
|
COMPONENT_T *video_render;
|
||||||
|
bool port_settings_changed;
|
||||||
|
bool first_packet;
|
||||||
|
} ChiakiPiDecoder;
|
||||||
|
|
||||||
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_pi_decoder_init(ChiakiPiDecoder *decoder, ChiakiLog *log);
|
||||||
|
CHIAKI_EXPORT void chiaki_pi_decoder_fini(ChiakiPiDecoder *decoder);
|
||||||
|
CHIAKI_EXPORT void chiaki_pi_decoder_set_params(ChiakiPiDecoder *decoder, int x, int y, int w, int h, bool visible);
|
||||||
|
CHIAKI_EXPORT bool chiaki_pi_decoder_video_sample_cb(uint8_t *buf, size_t buf_size, void *user);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // CHIAKI_PI_DECODER_H
|
261
lib/src/pidecoder.c
Normal file
261
lib/src/pidecoder.c
Normal file
|
@ -0,0 +1,261 @@
|
||||||
|
|
||||||
|
#include <chiaki/pidecoder.h>
|
||||||
|
|
||||||
|
#include <bcm_host.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#define MAX_DECODE_UNIT_SIZE 262144
|
||||||
|
|
||||||
|
CHIAKI_EXPORT ChiakiErrorCode chiaki_pi_decoder_init(ChiakiPiDecoder *decoder, ChiakiLog *log)
|
||||||
|
{
|
||||||
|
memset(decoder, 0, sizeof(ChiakiPiDecoder));
|
||||||
|
|
||||||
|
bcm_host_init();
|
||||||
|
|
||||||
|
if(!(decoder->client = ilclient_init()))
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(decoder->log, "ilclient_init failed");
|
||||||
|
chiaki_pi_decoder_fini(decoder);
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(OMX_Init() != OMX_ErrorNone)
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(decoder->log, "OMX_Init failed");
|
||||||
|
chiaki_pi_decoder_fini(decoder);
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ilclient_create_component(decoder->client, &decoder->video_decode, "video_decode",
|
||||||
|
ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_INPUT_BUFFERS) != 0)
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(decoder->log, "ilclient_create_component failed for video_decode");
|
||||||
|
chiaki_pi_decoder_fini(decoder);
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
decoder->components[0] = decoder->video_decode;
|
||||||
|
|
||||||
|
if(ilclient_create_component(decoder->client, &decoder->video_render, "video_render", ILCLIENT_DISABLE_ALL_PORTS) != 0)
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(decoder->log, "ilclient_create_component failed for video_render");
|
||||||
|
chiaki_pi_decoder_fini(decoder);
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
decoder->components[1] = decoder->video_render;
|
||||||
|
|
||||||
|
set_tunnel(decoder->tunnel, decoder->video_decode, 131, decoder->video_render, 90);
|
||||||
|
|
||||||
|
ilclient_change_component_state(decoder->video_decode, OMX_StateIdle);
|
||||||
|
|
||||||
|
OMX_VIDEO_PARAM_PORTFORMATTYPE format;
|
||||||
|
memset(&format, 0, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
|
||||||
|
format.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE);
|
||||||
|
format.nVersion.nVersion = OMX_VERSION;
|
||||||
|
format.nPortIndex = 130;
|
||||||
|
format.eCompressionFormat = OMX_VIDEO_CodingAVC;
|
||||||
|
|
||||||
|
OMX_PARAM_DATAUNITTYPE unit;
|
||||||
|
memset(&unit, 0, sizeof(OMX_PARAM_DATAUNITTYPE));
|
||||||
|
unit.nSize = sizeof(OMX_PARAM_DATAUNITTYPE);
|
||||||
|
unit.nVersion.nVersion = OMX_VERSION;
|
||||||
|
unit.nPortIndex = 130;
|
||||||
|
unit.eUnitType = OMX_DataUnitCodedPicture;
|
||||||
|
unit.eEncapsulationType = OMX_DataEncapsulationElementaryStream;
|
||||||
|
|
||||||
|
if(OMX_SetParameter(ILC_GET_HANDLE(decoder->video_decode), OMX_IndexParamVideoPortFormat, &format) != OMX_ErrorNone
|
||||||
|
|| OMX_SetParameter(ILC_GET_HANDLE(decoder->video_decode), OMX_IndexParamBrcmDataUnit, &unit) != OMX_ErrorNone)
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(decoder->log, "OMX_SetParameter failed for video parameters");
|
||||||
|
chiaki_pi_decoder_fini(decoder);
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
OMX_CONFIG_LATENCYTARGETTYPE latencyTarget;
|
||||||
|
memset(&latencyTarget, 0, sizeof(OMX_CONFIG_LATENCYTARGETTYPE));
|
||||||
|
latencyTarget.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
|
||||||
|
latencyTarget.nVersion.nVersion = OMX_VERSION;
|
||||||
|
latencyTarget.nPortIndex = 90;
|
||||||
|
latencyTarget.bEnabled = OMX_TRUE;
|
||||||
|
latencyTarget.nFilter = 2;
|
||||||
|
latencyTarget.nTarget = 4000;
|
||||||
|
latencyTarget.nShift = 3;
|
||||||
|
latencyTarget.nSpeedFactor = -135;
|
||||||
|
latencyTarget.nInterFactor = 500;
|
||||||
|
latencyTarget.nAdjCap = 20;
|
||||||
|
|
||||||
|
if(OMX_SetParameter(ILC_GET_HANDLE(decoder->video_render), OMX_IndexConfigLatencyTarget, &latencyTarget) != OMX_ErrorNone)
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(decoder->log, "OMX_SetParameter failed for render parameters");
|
||||||
|
chiaki_pi_decoder_fini(decoder);
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
OMX_CONFIG_ROTATIONTYPE rotationType;
|
||||||
|
memset(&rotationType, 0, sizeof(OMX_CONFIG_ROTATIONTYPE));
|
||||||
|
rotationType.nSize = sizeof(OMX_CONFIG_ROTATIONTYPE);
|
||||||
|
rotationType.nVersion.nVersion = OMX_VERSION;
|
||||||
|
rotationType.nPortIndex = 90;
|
||||||
|
//rotationType.nRotation = 90; // example
|
||||||
|
|
||||||
|
if(OMX_SetParameter(ILC_GET_HANDLE(decoder->video_render), OMX_IndexConfigCommonRotate, &rotationType) != OMX_ErrorNone)
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(decoder->log, "OMX_SetParameter failed for rotation");
|
||||||
|
chiaki_pi_decoder_fini(decoder);
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
OMX_PARAM_PORTDEFINITIONTYPE port;
|
||||||
|
|
||||||
|
memset(&port, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
|
||||||
|
port.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
|
||||||
|
port.nVersion.nVersion = OMX_VERSION;
|
||||||
|
port.nPortIndex = 130;
|
||||||
|
if(OMX_GetParameter(ILC_GET_HANDLE(decoder->video_decode), OMX_IndexParamPortDefinition, &port) != OMX_ErrorNone)
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(decoder->log, "Failed to get decoder port definition\n");
|
||||||
|
chiaki_pi_decoder_fini(decoder);
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increase the buffer size to fit the largest possible frame
|
||||||
|
port.nBufferSize = MAX_DECODE_UNIT_SIZE;
|
||||||
|
|
||||||
|
if(OMX_SetParameter(ILC_GET_HANDLE(decoder->video_decode), OMX_IndexParamPortDefinition, &port) != OMX_ErrorNone)
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(decoder->log, "OMX_SetParameter failed for port");
|
||||||
|
chiaki_pi_decoder_fini(decoder);
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ilclient_enable_port_buffers(decoder->video_decode, 130, NULL, NULL, NULL) != 0)
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(decoder->log, "ilclient_enable_port_buffers failed");
|
||||||
|
chiaki_pi_decoder_fini(decoder);
|
||||||
|
return CHIAKI_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
decoder->port_settings_changed = false;
|
||||||
|
decoder->first_packet = true;
|
||||||
|
|
||||||
|
ilclient_change_component_state(decoder->video_decode, OMX_StateExecuting);
|
||||||
|
|
||||||
|
CHIAKI_LOGI(decoder->log, "Raspberry Pi Decoder initialized");
|
||||||
|
return CHIAKI_ERR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHIAKI_EXPORT void chiaki_pi_decoder_fini(ChiakiPiDecoder *decoder)
|
||||||
|
{
|
||||||
|
if(decoder->video_decode)
|
||||||
|
{
|
||||||
|
OMX_BUFFERHEADERTYPE *buf;
|
||||||
|
if((buf = ilclient_get_input_buffer(decoder->video_decode, 130, 1)))
|
||||||
|
{
|
||||||
|
buf->nFilledLen = 0;
|
||||||
|
buf->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN | OMX_BUFFERFLAG_EOS;
|
||||||
|
OMX_EmptyThisBuffer(ILC_GET_HANDLE(decoder->video_decode), buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// need to flush the renderer to allow video_decode to disable its input port
|
||||||
|
ilclient_flush_tunnels(decoder->tunnel, 0);
|
||||||
|
|
||||||
|
ilclient_disable_port_buffers(decoder->video_decode, 130, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
ilclient_disable_tunnel(decoder->tunnel);
|
||||||
|
ilclient_teardown_tunnels(decoder->tunnel);
|
||||||
|
|
||||||
|
ilclient_state_transition(decoder->components, OMX_StateIdle);
|
||||||
|
ilclient_state_transition(decoder->components, OMX_StateLoaded);
|
||||||
|
|
||||||
|
ilclient_cleanup_components(decoder->components);
|
||||||
|
}
|
||||||
|
|
||||||
|
OMX_Deinit();
|
||||||
|
if(decoder->client)
|
||||||
|
ilclient_destroy(decoder->client);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool push_buffer(ChiakiPiDecoder *decoder, uint8_t *buf, size_t buf_size)
|
||||||
|
{
|
||||||
|
OMX_BUFFERHEADERTYPE *omx_buf = ilclient_get_input_buffer(decoder->video_decode, 130, 1);
|
||||||
|
if(!omx_buf)
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(decoder->log, "ilclient_get_input_buffer failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(omx_buf->nAllocLen < buf_size)
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(decoder->log, "Buffer from omx is too small for frame");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
omx_buf->nFilledLen = 0;
|
||||||
|
omx_buf->nOffset = 0;
|
||||||
|
omx_buf->nFlags = OMX_BUFFERFLAG_ENDOFFRAME;
|
||||||
|
if(decoder->first_packet)
|
||||||
|
{
|
||||||
|
omx_buf->nFlags |= OMX_BUFFERFLAG_STARTTIME;
|
||||||
|
decoder->first_packet = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(omx_buf->pBuffer + omx_buf->nFilledLen, buf, buf_size);
|
||||||
|
omx_buf->nFilledLen += buf_size;
|
||||||
|
|
||||||
|
if(!decoder->port_settings_changed
|
||||||
|
&& ((omx_buf->nFilledLen > 0 && ilclient_remove_event(decoder->video_decode, OMX_EventPortSettingsChanged, 131, 0, 0, 1) == 0)
|
||||||
|
|| (omx_buf->nFilledLen == 0 && ilclient_wait_for_event(decoder->video_decode, OMX_EventPortSettingsChanged, 131, 0, 0, 1, ILCLIENT_EVENT_ERROR | ILCLIENT_PARAMETER_CHANGED, 10000) == 0)))
|
||||||
|
{
|
||||||
|
decoder->port_settings_changed = true;
|
||||||
|
|
||||||
|
if(ilclient_setup_tunnel(decoder->tunnel, 0, 0) != 0)
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(decoder->log, "ilclient_setup_tunnel failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ilclient_change_component_state(decoder->video_render, OMX_StateExecuting);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(OMX_EmptyThisBuffer(ILC_GET_HANDLE(decoder->video_decode), omx_buf) != OMX_ErrorNone)
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(decoder->log, "OMX_EmptyThisBuffer failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define OMX_INIT_STRUCTURE(a) \
|
||||||
|
memset(&(a), 0, sizeof(a)); \
|
||||||
|
(a).nSize = sizeof(a); \
|
||||||
|
(a).nVersion.s.nVersionMajor = OMX_VERSION_MAJOR; \
|
||||||
|
(a).nVersion.s.nVersionMinor = OMX_VERSION_MINOR; \
|
||||||
|
(a).nVersion.s.nRevision = OMX_VERSION_REVISION; \
|
||||||
|
(a).nVersion.s.nStep = OMX_VERSION_STEP
|
||||||
|
|
||||||
|
CHIAKI_EXPORT void chiaki_pi_decoder_set_params(ChiakiPiDecoder *decoder, int x, int y, int w, int h, bool visible)
|
||||||
|
{
|
||||||
|
OMX_CONFIG_DISPLAYREGIONTYPE configDisplay;
|
||||||
|
OMX_INIT_STRUCTURE(configDisplay);
|
||||||
|
configDisplay.nPortIndex = 90;
|
||||||
|
configDisplay.set = (OMX_DISPLAYSETTYPE)(OMX_DISPLAY_SET_NOASPECT | OMX_DISPLAY_SET_MODE | OMX_DISPLAY_SET_FULLSCREEN | OMX_DISPLAY_SET_PIXEL | OMX_DISPLAY_SET_DEST_RECT | OMX_DISPLAY_SET_ALPHA);
|
||||||
|
configDisplay.mode = OMX_DISPLAY_MODE_LETTERBOX;
|
||||||
|
configDisplay.fullscreen = OMX_FALSE;
|
||||||
|
configDisplay.noaspect = OMX_FALSE;
|
||||||
|
configDisplay.dest_rect.x_offset = x;
|
||||||
|
configDisplay.dest_rect.y_offset = y;
|
||||||
|
configDisplay.dest_rect.width = w;
|
||||||
|
configDisplay.dest_rect.height = h;
|
||||||
|
configDisplay.alpha = visible ? 255 : 0;
|
||||||
|
|
||||||
|
if(OMX_SetParameter(ILC_GET_HANDLE(decoder->video_render), OMX_IndexConfigDisplayRegion, &configDisplay) != OMX_ErrorNone)
|
||||||
|
CHIAKI_LOGE(decoder->log, "OMX_SetParameter failed for display params");
|
||||||
|
}
|
||||||
|
|
||||||
|
CHIAKI_EXPORT bool chiaki_pi_decoder_video_sample_cb(uint8_t *buf, size_t buf_size, void *user)
|
||||||
|
{
|
||||||
|
return push_buffer(user, buf, buf_size);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue