Allow replacement of hevc headers

This commit is contained in:
loki
2021-06-20 15:29:51 +02:00
parent 7b86ea9e87
commit 9e7ecf8db2
11 changed files with 578 additions and 168 deletions

View File

@@ -317,15 +317,20 @@ struct encoder_t {
class session_t {
public:
session_t() = default;
session_t(ctx_t &&ctx, util::wrap_ptr<platf::hwdevice_t> &&device) : ctx { std::move(ctx) }, device { std::move(device) } {}
session_t(ctx_t &&ctx, util::wrap_ptr<platf::hwdevice_t> &&device, int inject) : ctx { std::move(ctx) }, device { std::move(device) }, inject { inject } {}
session_t(session_t &&other) noexcept : ctx { std::move(other.ctx) }, device { std::move(other.device) }, replacements { std::move(other.replacements) } {}
session_t(session_t &&other) noexcept = default;
// Ensure objects are destroyed in the correct order
session_t &operator=(session_t &&other) {
device = std::move(other.device);
ctx = std::move(other.ctx);
replacements = std::move(other.replacements);
sps = std::move(other.sps);
vps = std::move(other.vps);
pps = std::move(other.pps);
inject = other.inject;
return *this;
}
@@ -335,13 +340,12 @@ public:
std::vector<packet_raw_t::replace_t> replacements;
struct nal_t {
util::buffer_t<std::uint8_t> old;
util::buffer_t<std::uint8_t> _new;
};
cbs::nal_t sps;
cbs::nal_t vps;
cbs::nal_t pps;
nal_t sps;
nal_t vps;
// inject sps/vps data into idr pictures
int inject;
};
struct sync_session_ctx_t {
@@ -696,6 +700,8 @@ int encode(int64_t frame_nr, session_t &session, frame_t::pointer frame, packet_
auto &ctx = session.ctx;
auto &sps = session.sps;
auto &vps = session.vps;
auto &pps = session.pps;
/* send the frame to the encoder */
auto ret = avcodec_send_frame(ctx.get(), frame);
@@ -717,8 +723,25 @@ int encode(int64_t frame_nr, session_t &session, frame_t::pointer frame, packet_
return ret;
}
if(sps._new.size() && !sps.old.size()) {
sps.old = cbs::read_sps_h264(packet.get());
if(session.inject) {
if(session.inject == 1) {
auto h264 = cbs::make_sps_h264(ctx.get(), packet.get());
sps = std::move(h264.sps);
}
else {
auto hevc = cbs::make_sps_hevc(ctx.get(), packet.get());
sps = std::move(hevc.sps);
vps = std::move(hevc.vps);
session.replacements.emplace_back(
std::string_view((char *)std::begin(vps.old), vps.old.size()),
std::string_view((char *)std::begin(vps._new), vps._new.size()));
}
session.inject = 0;
session.replacements.emplace_back(
std::string_view((char *)std::begin(sps.old), sps.old.size()),
@@ -833,6 +856,9 @@ std::optional<session_t> make_session(const encoder_t &encoder, const config_t &
sw_fmt = encoder.dynamic_pix_fmt;
}
// Used by cbs::make_sps_hevc
ctx->sw_pix_fmt = sw_fmt;
buffer_t hwdevice_ctx;
if(hardware) {
ctx->pix_fmt = encoder.dev_pix_fmt;
@@ -943,13 +969,10 @@ std::optional<session_t> make_session(const encoder_t &encoder, const config_t &
session_t session {
std::move(ctx),
std::move(device),
};
if(!video_format[encoder_t::VUI_PARAMETERS]) {
if(config.videoFormat == 0) {
session.sps._new = cbs::make_sps_h264(session.ctx.get());
}
}
// 0 ==> don't inject, 1 ==> inject for h264, 2 ==> inject for hevc
(1 - (int)video_format[encoder_t::VUI_PARAMETERS]) * (1 + config.videoFormat),
};
if(!video_format[encoder_t::NALU_PREFIX_5b]) {
auto nalu_prefix = config.videoFormat ? hevc_nalu : h264_nalu;
@@ -1012,7 +1035,7 @@ void encode_run(
next_frame += delay;
// When Moonlight request an IDR frame, send frames even if there is no new captured frame
if(frame_nr > (key_frame_nr + config.framerate) || images->peek()) {
if(frame_nr > key_frame_nr || images->peek()) {
if(auto img = images->pop(delay)) {
session->device->convert(*img);
}
@@ -1474,6 +1497,9 @@ bool validate_encoder(encoder_t &encoder) {
}
}
encoder.h264[encoder_t::VUI_PARAMETERS] = encoder.h264[encoder_t::VUI_PARAMETERS] && !config::sunshine.flags[config::flag::FORCE_VIDEO_HEADER_REPLACE];
encoder.hevc[encoder_t::VUI_PARAMETERS] = encoder.hevc[encoder_t::VUI_PARAMETERS] && !config::sunshine.flags[config::flag::FORCE_VIDEO_HEADER_REPLACE];
if(!encoder.h264[encoder_t::VUI_PARAMETERS]) {
BOOST_LOG(warning) << encoder.name << ": h264 missing sps->vui parameters"sv;
}