mirror of
https://github.com/jetkvm/kvm.git
synced 2026-05-21 05:20:35 +00:00
Revert "fix(video): plumb source vrefresh into MPP encoder rate control"
This reverts commit fa36843. Empirically the MPP encoder forwards every
input frame whether or not Src/DstFrameRateNum/Den are set in the rate
control struct — those fields appear to only size the bitrate budget,
not gate frame submission. With this code in, dmesg shows
fps fix [120/1] -> fix [120/1] gop i [60]; with it reverted, dmesg
shows fps fix [30/1] -> fix [30/1] gop i [30]; in both cases WebRTC
inbound-rtp framesPerSecond sustains ~120 at the receiver. Drop the
plumbing to keep the PR's surface area minimal — the EDID-side change
alone is what unlocks 120 Hz end-to-end.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -116,30 +116,21 @@ double calculate_bitrate(float bitrate_factor, int width, int height)
|
||||
return bitrate;
|
||||
}
|
||||
|
||||
static void populate_venc_attr(VENC_CHN_ATTR_S *stAttr, RK_U32 bitrate, RK_U32 max_bitrate, RK_U32 width, RK_U32 height, RK_U32 fps)
|
||||
static void populate_venc_attr(VENC_CHN_ATTR_S *stAttr, RK_U32 bitrate, RK_U32 max_bitrate, RK_U32 width, RK_U32 height)
|
||||
{
|
||||
memset(stAttr, 0, sizeof(VENC_CHN_ATTR_S));
|
||||
|
||||
RK_U32 min_bitrate = bitrate / 2;
|
||||
if (min_bitrate < 2) min_bitrate = 2;
|
||||
|
||||
// GOP scales with framerate so IDR cadence stays ~0.5s regardless of source
|
||||
// refresh — keeps WebRTC recovery latency bounded at 60 Hz and 120 Hz alike.
|
||||
RK_U32 gop = fps > 0 ? fps / 2 : 30;
|
||||
if (gop < 1) gop = 1;
|
||||
|
||||
if (codec_type == 1) {
|
||||
// H.265 (HEVC)
|
||||
stAttr->stRcAttr.enRcMode = VENC_RC_MODE_H265VBR;
|
||||
stAttr->stRcAttr.stH265Vbr.u32BitRate = bitrate;
|
||||
stAttr->stRcAttr.stH265Vbr.u32MaxBitRate = max_bitrate;
|
||||
stAttr->stRcAttr.stH265Vbr.u32MinBitRate = min_bitrate;
|
||||
stAttr->stRcAttr.stH265Vbr.u32Gop = gop;
|
||||
stAttr->stRcAttr.stH265Vbr.u32Gop = 30;
|
||||
stAttr->stRcAttr.stH265Vbr.u32StatTime = 2;
|
||||
stAttr->stRcAttr.stH265Vbr.u32SrcFrameRateNum = fps;
|
||||
stAttr->stRcAttr.stH265Vbr.u32SrcFrameRateDen = 1;
|
||||
stAttr->stRcAttr.stH265Vbr.fr32DstFrameRateNum = fps;
|
||||
stAttr->stRcAttr.stH265Vbr.fr32DstFrameRateDen = 1;
|
||||
stAttr->stVencAttr.enType = RK_VIDEO_ID_HEVC;
|
||||
stAttr->stVencAttr.u32Profile = H265E_PROFILE_MAIN;
|
||||
} else {
|
||||
@@ -148,12 +139,8 @@ static void populate_venc_attr(VENC_CHN_ATTR_S *stAttr, RK_U32 bitrate, RK_U32 m
|
||||
stAttr->stRcAttr.stH264Vbr.u32BitRate = bitrate;
|
||||
stAttr->stRcAttr.stH264Vbr.u32MaxBitRate = max_bitrate;
|
||||
stAttr->stRcAttr.stH264Vbr.u32MinBitRate = min_bitrate;
|
||||
stAttr->stRcAttr.stH264Vbr.u32Gop = gop;
|
||||
stAttr->stRcAttr.stH264Vbr.u32Gop = 30;
|
||||
stAttr->stRcAttr.stH264Vbr.u32StatTime = 2;
|
||||
stAttr->stRcAttr.stH264Vbr.u32SrcFrameRateNum = fps;
|
||||
stAttr->stRcAttr.stH264Vbr.u32SrcFrameRateDen = 1;
|
||||
stAttr->stRcAttr.stH264Vbr.fr32DstFrameRateNum = fps;
|
||||
stAttr->stRcAttr.stH264Vbr.fr32DstFrameRateDen = 1;
|
||||
stAttr->stVencAttr.enType = RK_VIDEO_ID_AVC;
|
||||
stAttr->stVencAttr.u32Profile = H264E_PROFILE_HIGH;
|
||||
}
|
||||
@@ -170,11 +157,11 @@ static void populate_venc_attr(VENC_CHN_ATTR_S *stAttr, RK_U32 bitrate, RK_U32 m
|
||||
|
||||
pthread_t *venc_read_thread = NULL;
|
||||
volatile bool venc_running = false;
|
||||
static int32_t venc_start(int32_t bitrate, int32_t max_bitrate, int32_t width, int32_t height, int32_t fps)
|
||||
static int32_t venc_start(int32_t bitrate, int32_t max_bitrate, int32_t width, int32_t height)
|
||||
{
|
||||
int32_t ret;
|
||||
VENC_CHN_ATTR_S stAttr;
|
||||
populate_venc_attr(&stAttr, bitrate, max_bitrate, width, height, fps);
|
||||
populate_venc_attr(&stAttr, bitrate, max_bitrate, width, height);
|
||||
|
||||
ret = RK_MPI_VENC_CreateChn(VENC_CHANNEL, &stAttr);
|
||||
if (ret < 0)
|
||||
@@ -379,9 +366,6 @@ static void *venc_read_stream(void *arg)
|
||||
}
|
||||
|
||||
uint32_t detected_width, detected_height;
|
||||
// detected_fps is the rounded source vrefresh from the latest dv-timings query.
|
||||
// 60 is a safe default until the first SOURCE_CHANGE event fires.
|
||||
uint32_t detected_fps = 60;
|
||||
bool detected_signal = false, streaming_flag = false;
|
||||
|
||||
bool streaming_stopped = true;
|
||||
@@ -460,7 +444,6 @@ void *run_video_stream(void *arg)
|
||||
|
||||
uint32_t width = detected_width;
|
||||
uint32_t height = detected_height;
|
||||
uint32_t fps = detected_fps;
|
||||
struct v4l2_format fmt;
|
||||
memset(&fmt, 0, sizeof(struct v4l2_format));
|
||||
fmt.type = type;
|
||||
@@ -570,7 +553,7 @@ void *run_video_stream(void *arg)
|
||||
|
||||
// Set VENC parameters
|
||||
int32_t bitrate = calculate_bitrate(quality_factor, width, height);
|
||||
RK_S32 ret = venc_start(bitrate, bitrate * 3 / 2, width, height, fps);
|
||||
RK_S32 ret = venc_start(bitrate, bitrate * 3 / 2, width, height);
|
||||
if (ret != RK_SUCCESS)
|
||||
{
|
||||
log_error("Set VENC parameters failed with %#x", ret);
|
||||
@@ -878,19 +861,10 @@ void *run_detect_format(void *arg)
|
||||
dv_timings.bt.hbackporch));
|
||||
log_info("Frames per second: %.2f fps", frames_per_second);
|
||||
|
||||
// Round to nearest integer for the encoder rate control. CVT-RB
|
||||
// sources land a touch under (e.g. 119.91); rounding keeps the
|
||||
// encoder sized for the nominal rate.
|
||||
uint32_t fps_int = (uint32_t)(frames_per_second + 0.5);
|
||||
if (fps_int < 1) fps_int = 1;
|
||||
// Tolerate ±1 fps wobble between SOURCE_CHANGE events without
|
||||
// tearing down the pipeline.
|
||||
bool fps_changed = fps_int > detected_fps + 1 || fps_int + 1 < detected_fps;
|
||||
bool should_restart = dv_timings.bt.width != detected_width || dv_timings.bt.height != detected_height || fps_changed || !detected_signal;
|
||||
bool should_restart = dv_timings.bt.width != detected_width || dv_timings.bt.height != detected_height || !detected_signal;
|
||||
|
||||
detected_width = dv_timings.bt.width;
|
||||
detected_height = dv_timings.bt.height;
|
||||
detected_fps = fps_int;
|
||||
detected_signal = true;
|
||||
video_report_format(true, NULL, detected_width, detected_height, frames_per_second);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user