架构大改之前

This commit is contained in:
2026-08-23 17:11:12 +08:00
parent 73a3152733
commit 3938e72bb7
34 changed files with 1111 additions and 327 deletions
+10 -4
View File
@@ -32,7 +32,7 @@ struct H264_Encoder::Private {
std::uint32_t width{}; /* 当前编码尺寸;尺寸变化时整体重建编码器。 */
std::uint32_t height{}; /* 当前编码尺寸;H.264 4:2:0 要求偶数。 */
Video_Pixel_Layout layout{Video_Pixel_Layout::bgra}; /* scaler 当前输入格式。 */
bool first_frame{true}; /* 编码器重建后必须立即产生可独立解码的关键帧。 */
bool key_frame_requested{true}; /* Track 新建或恢复时,下一 access unit 必须可独立解码。 */
explicit Private(double value_frame_rate) : frame_rate(value_frame_rate) {
if (!std::isfinite(frame_rate) || frame_rate <= 0.0)
@@ -47,7 +47,7 @@ struct H264_Encoder::Private {
avcodec_free_context(&codec_context);
width = 0;
height = 0;
first_frame = true;
key_frame_requested = true;
}
void configure(std::uint32_t next_width, std::uint32_t next_height,
Video_Pixel_Layout next_layout) {
@@ -103,6 +103,10 @@ H264_Encoder::H264_Encoder(double frame_rate)
: d(std::make_unique<Private>(frame_rate)) {}
H264_Encoder::~H264_Encoder() = default;
void H264_Encoder::request_key_frame() {
d->key_frame_requested = true;
}
std::shared_ptr<const Encoded_Video_Frame> H264_Encoder::encode(
std::span<const std::byte> pixels, std::uint32_t width,
std::uint32_t height, Video_Pixel_Layout layout,
@@ -118,7 +122,9 @@ std::shared_ptr<const Encoded_Video_Frame> H264_Encoder::encode(
d->yuv_frame->data, d->yuv_frame->linesize) != static_cast<int>(height))
throw std::runtime_error("FFmpeg did not convert the complete video frame");
d->yuv_frame->pts = presentation_time.count();
d->yuv_frame->pict_type = d->first_frame ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_NONE;
d->yuv_frame->pict_type = d->key_frame_requested
? AV_PICTURE_TYPE_I
: AV_PICTURE_TYPE_NONE;
require_ffmpeg(avcodec_send_frame(d->codec_context, d->yuv_frame),
"submitting frame to H.264 encoder");
const int received = avcodec_receive_packet(d->codec_context, d->packet);
@@ -130,7 +136,7 @@ std::shared_ptr<const Encoded_Video_Frame> H264_Encoder::encode(
output->presentation_time = presentation_time;
output->sequence = sequence;
output->key_frame = (d->packet->flags & AV_PKT_FLAG_KEY) != 0;
d->first_frame = false;
d->key_frame_requested = false;
av_packet_unref(d->packet);
return output;
}