feat(oakcodec): hardware video decoding by default on all platforms
FFmpeg 8 removed the standalone hardware decoders (h264_videotoolbox/ vaapi/nvdec/d3d11va no longer exist in its configure) — hardware decode now only exists as a hwaccel attached to the software decoder. The new oakcodec::hwdecode module therefore opens the regular decoder with the platform's hardware device context attached (VideoToolbox on macOS, VA-API then NVDEC on Linux, D3D11VA then NVDEC on Windows): FFmpeg engages the matching hwaccel, decodes into hardware surfaces, and we transfer them to system memory (NV12/P010) ahead of swscale. - HardwareDecoding config switch, default ON by mandate; a checkbox in Preferences > Rendering (EN/ZH); device creation failure skips to the next candidate and finally to software; a decode-time failure on a hardware session reopens it as software and retries once. - hw_decoder_name() observability hook plus a HW_TRANSFERS counter so tests can prove the hwaccel really engaged (not silently software). - Verification: demo.mp4 H.264 decodes through VideoToolbox with a transferred hardware surface, and the pixels match the software decode within 0.05; switch off forces software. - build-ffmpeg.sh also enables nvdec when ffnvcodec headers exist.
This commit is contained in:
@@ -95,6 +95,7 @@ pub struct PreferencesContent {
|
||||
theme: Entity<ComboBox>,
|
||||
cache_dir: Entity<PathField>,
|
||||
use_proxy: Entity<CheckBox>,
|
||||
hw_decode: Entity<CheckBox>,
|
||||
proxy_divider: Entity<ComboBox>,
|
||||
snapshot_interval: Entity<SpinBox>,
|
||||
transition_length: Entity<SpinBox>,
|
||||
@@ -251,6 +252,30 @@ impl PreferencesContent {
|
||||
combo.set_selected(Some(divider_selected), cx)
|
||||
});
|
||||
|
||||
// --- 渲染 Rendering: hardware decoding switch -------------------
|
||||
// Default ON (user mandate); off forces software decoding.
|
||||
let hw_decode = cx.new(|cx| {
|
||||
CheckBox::new(
|
||||
9,
|
||||
if config_get_bool("HardwareDecoding", true) {
|
||||
CheckState::Checked
|
||||
} else {
|
||||
CheckState::Unchecked
|
||||
},
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
.with_label(i18n::tr("preferences.hwdecode.enable"))
|
||||
});
|
||||
cx.subscribe(&hw_decode, |_this, check, event: &CheckBoxEvent, cx| {
|
||||
if let CheckBoxEvent::Toggled { state, .. } = event {
|
||||
let enabled = *state == CheckState::Checked;
|
||||
config_set_bool("HardwareDecoding", enabled);
|
||||
check.update(cx, |check, cx| check.set_state(*state, cx));
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
|
||||
// --- 项目 Project: snapshot interval + default transition ----------
|
||||
let snapshot_interval = cx.new(|cx| {
|
||||
let current =
|
||||
@@ -342,6 +367,7 @@ impl PreferencesContent {
|
||||
theme,
|
||||
cache_dir,
|
||||
use_proxy,
|
||||
hw_decode,
|
||||
proxy_divider,
|
||||
snapshot_interval,
|
||||
transition_length,
|
||||
@@ -499,6 +525,7 @@ impl Render for PreferencesContent {
|
||||
i18n::tr("preferences.backend").into(),
|
||||
self.backend.clone(),
|
||||
))
|
||||
.child(self.hw_decode.clone())
|
||||
// 缓存 Cache
|
||||
.child(section_header(&colors, i18n::tr("preferences.section.cache").into()))
|
||||
.child(form_row(
|
||||
|
||||
@@ -434,6 +434,7 @@ const EN: &[(&str, &str)] = &[
|
||||
("preferences.section.project", "Project"),
|
||||
("preferences.section.audio", "Audio"),
|
||||
("preferences.backend", "Renderer backend"),
|
||||
("preferences.hwdecode.enable", "Hardware-accelerated video decoding (VideoToolbox / VA-API / NVDEC / D3D11VA)"),
|
||||
("preferences.backend.placeholder", "Select a backend…"),
|
||||
("preferences.language", "Language"),
|
||||
("preferences.language.placeholder", "Select a language…"),
|
||||
@@ -899,6 +900,7 @@ const ZH: &[(&str, &str)] = &[
|
||||
("preferences.section.project", "项目"),
|
||||
("preferences.section.audio", "音频"),
|
||||
("preferences.backend", "渲染后端"),
|
||||
("preferences.hwdecode.enable", "硬件加速视频解码(VideoToolbox / VA-API / NVDEC / D3D11VA)"),
|
||||
("preferences.backend.placeholder", "选择一个后端…"),
|
||||
("preferences.language", "语言"),
|
||||
("preferences.language.placeholder", "选择语言…"),
|
||||
|
||||
Reference in New Issue
Block a user