diff --git a/sunshine/stream.cpp b/sunshine/stream.cpp index 10e215b6..27fbe85a 100644 --- a/sunshine/stream.cpp +++ b/sunshine/stream.cpp @@ -895,7 +895,8 @@ void videoBroadcastThread(udp::socket &sock) { auto session = (session_t *)packet->channel_data; auto lowseq = session->video.lowseq; - std::string_view payload { (char *)packet->data, (size_t)packet->size }; + auto av_packet = packet->av_packet; + std::string_view payload { (char *)av_packet->data, (size_t)av_packet->size }; std::vector payload_new; auto nv_packet_header = "\0017charss"sv; @@ -904,7 +905,7 @@ void videoBroadcastThread(udp::socket &sock) { payload = { (char *)payload_new.data(), payload_new.size() }; - if(packet->flags & AV_PKT_FLAG_KEY) { + if(av_packet->flags & AV_PKT_FLAG_KEY) { for(auto &replacement : *packet->replacements) { auto frame_old = replacement.old; auto frame_new = replacement._new; @@ -969,9 +970,10 @@ void videoBroadcastThread(udp::socket &sock) { auto packets = (current_payload.size() + (blocksize - 1)) / blocksize; for(int x = 0; x < packets; ++x) { - auto *inspect = (video_packet_raw_t *)¤t_payload[x * blocksize]; + auto *inspect = (video_packet_raw_t *)¤t_payload[x * blocksize]; + auto av_packet = packet->av_packet; - inspect->packet.frameIndex = packet->pts; + inspect->packet.frameIndex = av_packet->pts; inspect->packet.streamPacketIndex = ((uint32_t)lowseq + x) << 8; // Match multiFecFlags with Moonlight @@ -1002,18 +1004,18 @@ void videoBroadcastThread(udp::socket &sock) { inspect->rtp.sequenceNumber = util::endian::big(lowseq + x); inspect->packet.multiFecBlocks = (blockIndex << 4) | lastBlockIndex; - inspect->packet.frameIndex = packet->pts; + inspect->packet.frameIndex = av_packet->pts; } for(auto x = 0; x < shards.size(); ++x) { sock.send_to(asio::buffer(shards[x]), session->video.peer); } - if(packet->flags & AV_PKT_FLAG_KEY) { - BOOST_LOG(verbose) << "Key Frame ["sv << packet->pts << "] :: send ["sv << shards.size() << "] shards..."sv; + if(av_packet->flags & AV_PKT_FLAG_KEY) { + BOOST_LOG(verbose) << "Key Frame ["sv << av_packet->pts << "] :: send ["sv << shards.size() << "] shards..."sv; } else { - BOOST_LOG(verbose) << "Frame ["sv << packet->pts << "] :: send ["sv << shards.size() << "] shards..."sv << std::endl; + BOOST_LOG(verbose) << "Frame ["sv << av_packet->pts << "] :: send ["sv << shards.size() << "] shards..."sv << std::endl; } ++blockIndex; diff --git a/sunshine/video.cpp b/sunshine/video.cpp index 0f7eff35..f49cac95 100644 --- a/sunshine/video.cpp +++ b/sunshine/video.cpp @@ -776,9 +776,10 @@ int encode(int64_t frame_nr, session_t &session, frame_t::pointer frame, safe::m } while(ret >= 0) { - auto packet = std::make_unique(nullptr); + auto packet = std::make_unique(nullptr); + auto av_packet = packet.get()->av_packet; - ret = avcodec_receive_packet(ctx.get(), packet.get()); + ret = avcodec_receive_packet(ctx.get(), av_packet); if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { return 0; } @@ -788,12 +789,12 @@ int encode(int64_t frame_nr, session_t &session, frame_t::pointer frame, safe::m if(session.inject) { if(session.inject == 1) { - auto h264 = cbs::make_sps_h264(ctx.get(), packet.get()); + auto h264 = cbs::make_sps_h264(ctx.get(), av_packet); sps = std::move(h264.sps); } else { - auto hevc = cbs::make_sps_hevc(ctx.get(), packet.get()); + auto hevc = cbs::make_sps_hevc(ctx.get(), av_packet); sps = std::move(hevc.sps); vps = std::move(hevc.vps); @@ -1470,20 +1471,21 @@ int validate_config(std::shared_ptr &disp, const encoder_t &en } } - auto packet = packets->pop(); - if(!(packet->flags & AV_PKT_FLAG_KEY)) { + auto packet = packets->pop(); + auto av_packet = packet->av_packet; + if(!(av_packet->flags & AV_PKT_FLAG_KEY)) { BOOST_LOG(error) << "First packet type is not an IDR frame"sv; return -1; } int flag = 0; - if(cbs::validate_sps(&*packet, config.videoFormat ? AV_CODEC_ID_H265 : AV_CODEC_ID_H264)) { + if(cbs::validate_sps(&*av_packet, config.videoFormat ? AV_CODEC_ID_H265 : AV_CODEC_ID_H264)) { flag |= VUI_PARAMS; } auto nalu_prefix = config.videoFormat ? hevc_nalu : h264_nalu; - std::string_view payload { (char *)packet->data, (std::size_t)packet->size }; + std::string_view payload { (char *)av_packet->data, (std::size_t)av_packet->size }; if(std::search(std::begin(payload), std::end(payload), std::begin(nalu_prefix), std::end(nalu_prefix)) != std::end(payload)) { flag |= NALU_PREFIX_5b; } diff --git a/sunshine/video.h b/sunshine/video.h index fab4ff76..05df4463 100644 --- a/sunshine/video.h +++ b/sunshine/video.h @@ -16,17 +16,9 @@ extern "C" { struct AVPacket; namespace video { -struct packet_raw_t : public AVPacket { +struct packet_raw_t { void init_packet() { - pts = AV_NOPTS_VALUE; - dts = AV_NOPTS_VALUE; - pos = -1; - duration = 0; - flags = 0; - stream_index = 0; - buf = nullptr; - side_data = nullptr; - side_data_elems = 0; + this->av_packet = av_packet_alloc(); } template @@ -39,7 +31,7 @@ struct packet_raw_t : public AVPacket { } ~packet_raw_t() { - av_packet_unref(this); + av_packet_unref(this->av_packet); } struct replace_t { @@ -51,8 +43,8 @@ struct packet_raw_t : public AVPacket { replace_t(std::string_view old, std::string_view _new) noexcept : old { std::move(old) }, _new { std::move(_new) } {} }; + AVPacket *av_packet; std::vector *replacements; - void *channel_data; };