diff --git a/gui/include/settings.h b/gui/include/settings.h index dc8db49..c2320b8 100644 --- a/gui/include/settings.h +++ b/gui/include/settings.h @@ -75,6 +75,9 @@ class Settings : public QObject unsigned int GetBitrate() const; void SetBitrate(unsigned int bitrate); + ChiakiCodec GetCodec() const; + void SetCodec(ChiakiCodec codec); + Decoder GetDecoder() const; void SetDecoder(Decoder decoder); diff --git a/gui/include/settingsdialog.h b/gui/include/settingsdialog.h index 5b741dd..d564bef 100644 --- a/gui/include/settingsdialog.h +++ b/gui/include/settingsdialog.h @@ -24,6 +24,7 @@ class SettingsDialog : public QDialog QComboBox *resolution_combo_box; QComboBox *fps_combo_box; QLineEdit *bitrate_edit; + QComboBox *codec_combo_box; QLineEdit *audio_buffer_size_edit; QComboBox *audio_device_combo_box; QCheckBox *pi_decoder_check_box; @@ -41,6 +42,7 @@ class SettingsDialog : public QDialog void ResolutionSelected(); void FPSSelected(); void BitrateEdited(); + void CodecSelected(); void AudioBufferSizeEdited(); void AudioOutputSelected(); void HardwareDecodeEngineSelected(); diff --git a/gui/src/settings.cpp b/gui/src/settings.cpp index c8c2a9d..715c2d5 100644 --- a/gui/src/settings.cpp +++ b/gui/src/settings.cpp @@ -132,6 +132,24 @@ void Settings::SetBitrate(unsigned int bitrate) settings.setValue("settings/bitrate", bitrate); } +static const QMap codecs = { + { CHIAKI_CODEC_H264, "h264"}, + { CHIAKI_CODEC_H265, "h265"} +}; + +static const ChiakiCodec codec_default = CHIAKI_CODEC_H265; + +ChiakiCodec Settings::GetCodec() const +{ + auto v = settings.value("settings/codec", codecs[codec_default]).toString(); + return codecs.key(v, codec_default); +} + +void Settings::SetCodec(ChiakiCodec codec) +{ + settings.setValue("settings/codec", codecs[codec]); +} + unsigned int Settings::GetAudioBufferSizeDefault() const { return 9600; @@ -202,7 +220,7 @@ ChiakiConnectVideoProfile Settings::GetVideoProfile() unsigned int bitrate = GetBitrate(); if(bitrate) profile.bitrate = bitrate; - profile.codec = CHIAKI_CODEC_H264; // TODO: add a setting + profile.codec = GetCodec(); return profile; } diff --git a/gui/src/settingsdialog.cpp b/gui/src/settingsdialog.cpp index c93e63b..b8bd412 100644 --- a/gui/src/settingsdialog.cpp +++ b/gui/src/settingsdialog.cpp @@ -174,6 +174,21 @@ SettingsDialog::SettingsDialog(Settings *settings, QWidget *parent) : QDialog(pa connect(bitrate_edit, &QLineEdit::textEdited, this, &SettingsDialog::BitrateEdited); UpdateBitratePlaceholder(); + codec_combo_box = new QComboBox(this); + static const QList> codec_strings = { + { CHIAKI_CODEC_H264, "H264" }, + { CHIAKI_CODEC_H265, "H265 (PS5 only)" } + }; + auto current_codec = settings->GetCodec(); + for(const auto &p : codec_strings) + { + codec_combo_box->addItem(p.second, (int)p.first); + if(current_codec == p.first) + codec_combo_box->setCurrentIndex(codec_combo_box->count() - 1); + } + connect(codec_combo_box, SIGNAL(currentIndexChanged(int)), this, SLOT(CodecSelected())); + stream_settings_layout->addRow(tr("Codec:"), codec_combo_box); + audio_buffer_size_edit = new QLineEdit(this); audio_buffer_size_edit->setValidator(new QIntValidator(1024, 0x20000, audio_buffer_size_edit)); unsigned int audio_buffer_size = settings->GetAudioBufferSizeRaw(); @@ -317,6 +332,11 @@ void SettingsDialog::BitrateEdited() settings->SetBitrate(bitrate_edit->text().toUInt()); } +void SettingsDialog::CodecSelected() +{ + settings->SetCodec((ChiakiCodec)codec_combo_box->currentData().toInt()); +} + void SettingsDialog::AudioBufferSizeEdited() { settings->SetAudioBufferSize(audio_buffer_size_edit->text().toUInt()); diff --git a/gui/src/streamsession.cpp b/gui/src/streamsession.cpp index e1b8cd6..fedae10 100644 --- a/gui/src/streamsession.cpp +++ b/gui/src/streamsession.cpp @@ -68,7 +68,7 @@ StreamSession::StreamSession(const StreamSessionConnectInfo &connect_info, QObje chiaki_log_sniffer_init(&sniffer, CHIAKI_LOG_ALL, GetChiakiLog()); ChiakiErrorCode err = chiaki_ffmpeg_decoder_init(ffmpeg_decoder, chiaki_log_sniffer_get_log(&sniffer), - connect_info.video_profile.codec, + chiaki_target_is_ps5(connect_info.target) ? connect_info.video_profile.codec : CHIAKI_CODEC_H264, connect_info.hw_decoder.isEmpty() ? NULL : connect_info.hw_decoder.toUtf8().constData(), FfmpegFrameCb, this); if(err != CHIAKI_ERR_SUCCESS) diff --git a/lib/include/chiaki/common.h b/lib/include/chiaki/common.h index 74bb344..630c954 100644 --- a/lib/include/chiaki/common.h +++ b/lib/include/chiaki/common.h @@ -85,9 +85,10 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_lib_init(); typedef enum { + // values must not change CHIAKI_CODEC_H264 = 0, - CHIAKI_CODEC_H265, - CHIAKI_CODEC_H265_HDR + CHIAKI_CODEC_H265 = 1, + CHIAKI_CODEC_H265_HDR = 2 } ChiakiCodec; static inline bool chiaki_codec_is_h265(ChiakiCodec codec) diff --git a/lib/src/ctrl.c b/lib/src/ctrl.c index a3b8461..f92d12b 100644 --- a/lib/src/ctrl.c +++ b/lib/src/ctrl.c @@ -971,6 +971,7 @@ static ChiakiErrorCode ctrl_connect(ChiakiCtrl *ctrl) && session->connect_info.video_profile_auto_downgrade && session->connect_info.video_profile.height == 1080) { + // regular PS4 doesn't support >= 1080p CHIAKI_LOGI(session->log, "1080p was selected but server would not support it. Downgrading."); chiaki_connect_video_profile_preset( &session->connect_info.video_profile, @@ -979,6 +980,13 @@ static ChiakiErrorCode ctrl_connect(ChiakiCtrl *ctrl) ? CHIAKI_VIDEO_FPS_PRESET_60 : CHIAKI_VIDEO_FPS_PRESET_30); } + if((server_type == 0 || server_type == 1) + && session->connect_info.video_profile.codec != CHIAKI_CODEC_H264) + { + // PS4 doesn't support anything except h264 + CHIAKI_LOGI(session->log, "A codec other than H264 was selected but server would not support it. Downgrading."); + session->connect_info.video_profile.codec = CHIAKI_CODEC_H264; + } } else CHIAKI_LOGE(session->log, "No valid Server Type in ctrl response"); diff --git a/lib/src/session.c b/lib/src/session.c index 1c0c388..de2f4e2 100644 --- a/lib/src/session.c +++ b/lib/src/session.c @@ -88,6 +88,7 @@ CHIAKI_EXPORT ChiakiTarget chiaki_rp_version_parse(const char *rp_version_str, b CHIAKI_EXPORT void chiaki_connect_video_profile_preset(ChiakiConnectVideoProfile *profile, ChiakiVideoResolutionPreset resolution, ChiakiVideoFPSPreset fps) { + profile->codec = CHIAKI_CODEC_H264; switch(resolution) { case CHIAKI_VIDEO_RESOLUTION_PRESET_360p: