根因(实测确认,非推测) 上游 nvenc 0.1.0 的 encode_picture 只设置 picture_type=NV_ENC_PIC_TYPE_IDR, 却从未设置 encode_pic_flags=NV_ENC_PIC_FLAG_FORCEIDR。NVENC 会据此忽略请求、 继续输出 P 帧。首帧之所以「看起来正常」,是因为 frame_idx==0 本来就强制 IDR, 与该字段无关——这也是该缺陷长期未被发现的原因。 证据(同一 frame_count=4,修复前后) - 修复前:输出 NAL 首字节 0x61 → 0x61 & 0x1F = 1 = 普通 P 片 - 修复后:输出 NAL 首字节 0x65 → 0x65 & 0x1F = 5 = IDR 片 影响 这解释了构建运行手册 §6.1 记录的「静止桌面黑屏」:NVENC 路径的重编 IDR 从未 真正生效,KeyFrameReq 拿不到 IDR 就无法从解码错误中恢复。 改动 - 新增 vendor/nvenc(上游为 MIT 许可,可自由修改分发,符合商用要求) - vendor/nvenc/src/safe/encoder.rs:picture_type=IDR 时置 ForceIDR; IntraRefresh 时置 ForceIntra。改动处有「本项目补丁」注释标记 - agent/Cargo.toml:nvenc 改为 path 依赖指向 vendor 版本 建议后续向上游提 PR(github.com/AlsoSylv/nvenc),以降低长期维护成本。 验证:跳帧后发 KeyFrameReq,第 3 帧即收到 IDR 并解码成功
34 lines
1.3 KiB
Markdown
34 lines
1.3 KiB
Markdown
### If you like my work and want to support what I do, support me on Ko-Fi 💜!
|
|
[](https://ko-fi.com/cyberite)
|
|
---
|
|
|
|
  
|
|
|
|
The following example is for Linux GLX
|
|
|
|
```rust
|
|
use nvenc::{session::Session, encoder::Encoder};
|
|
|
|
fn main() {
|
|
// Setup GLX context
|
|
let session: Session<NeedsConfig> = Session::open_gl();
|
|
let (session, config): (Session<NeedsInit>, NVencPresetConfig)
|
|
= session.get_preset_config(
|
|
NV_ENC_CODEC_H264_GUID,
|
|
NV_ENC_PRESET_P3_GUID,
|
|
NVencTuningInfo::LowLatency
|
|
);
|
|
let init_params = nvenc::session::InitParams {
|
|
encode_guid: NV_ENC_H264_GUID,
|
|
preset_guid: NV_ENC_PRESET_P3_GUID,
|
|
resolution: [1920, 1080],
|
|
aspect_ratio: [16, 9],
|
|
frame_rate: [30, 1],
|
|
tuning_info: NVencTuningInfo::LowLatency,
|
|
buffer_format: NVencBufferFormat::ARGB,
|
|
encode_config: &mut config.preset_cfg,
|
|
enable_ptd: true,
|
|
};
|
|
let encoder: Encoder = session.init(init_params);
|
|
}
|
|
``` |