Skip to content

Commit d0b5697

Browse files
committed
ensure we initialize encoder correctly and send keyframe first
1 parent 328fe34 commit d0b5697

2 files changed

Lines changed: 18 additions & 0 deletions

File tree

webrtc-sys/src/v4l2/v4l2_h264_encoder_wrapper.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,12 @@ bool V4l2H264EncoderWrapper::Initialize(int width,
288288
fd_ = -1;
289289
return false;
290290
}
291+
292+
// Zero-fill the buffer so unprimed slots contain valid black YUV data
293+
// rather than random memory. The Pi 4 V4L2 M2M encoder may reference
294+
// multiple output buffers internally before the pipeline is fully primed,
295+
// causing distorted/green frames if buffers contain garbage.
296+
memset(output_buffers_[i].start, 0, output_buffers_[i].length);
291297
}
292298

293299
// --- Request and mmap capture buffers (encoder output) ---
@@ -373,6 +379,7 @@ bool V4l2H264EncoderWrapper::Initialize(int width,
373379
<< " @ " << framerate << " fps, bitrate " << bitrate;
374380
initialized_ = true;
375381
next_output_index_ = 0;
382+
first_frame_ = true;
376383
return true;
377384
}
378385

@@ -418,6 +425,13 @@ bool V4l2H264EncoderWrapper::Encode(const uint8_t* y,
418425
return false;
419426
}
420427

428+
// Always force an IDR on the very first frame so the decoder starts clean,
429+
// avoiding startup artifacts from the encoder pipeline not being primed yet.
430+
if (first_frame_) {
431+
forceIDR = true;
432+
first_frame_ = false;
433+
}
434+
421435
// Request a keyframe if needed.
422436
if (forceIDR) {
423437
v4l2_control ctrl = {};

webrtc-sys/src/v4l2/v4l2_h264_encoder_wrapper.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ class V4l2H264EncoderWrapper {
9797

9898
// Index of the next output buffer to use (round-robin).
9999
int next_output_index_ = 0;
100+
101+
// Force the first encoded frame to be an IDR keyframe so the decoder
102+
// starts with a clean reference and doesn't show startup artifacts.
103+
bool first_frame_ = true;
100104
};
101105

102106
} // namespace livekit_ffi

0 commit comments

Comments
 (0)