Files
oak-editor/crates/oak-task/src/precache.rs
T
Mike-Solar 4babbf5de8
CI / Build & test (Linux) (push) Successful in 24m6s
CI / Build & test (Windows) (push) Successful in 31m14s
core: merge oak-common into oak-core
oak-common is gone; its modules (configstore, xmlutils, ocioutils,
oiioutils, colormath, colortransform, videoparams, ffmpegutils, ...)
now live in oak-core alongside the value types. The render value/GPU
types moved too: backend (wgpu context + DisplayRenderer), color
(ColorProcessor over ocio-rs), texture, frame, and the commonutil
config helpers.

Fix-ups to make the merged tree build and pass tests:

- oak-core Cargo.toml: wgpu back to 25 (the moved backend code is
  written against that API generation); add the toml/quick-xml/image
  deps oak-common carried.
- lib.rs: drop the duplicate 'pub mod error;'.
- error.rs: unified OAKCORE_* codes; restore Error::new() and
  From<OcioError> from oak-common's error type.
- backend.rs/color.rs: oak_core::/oak_render:: self-references
  rewritten to crate::; the shaderfx-dependent GPU effect test moved
  to oak-render's shaderfx tests (shaderfx depends on oak-node and
  cannot live in oak-core).
- oak-render's error module re-exports oak_core::error::{Error,
  Result}; the OAKRENDER_* codes stay as the public-code contract.
- oak-node jobs.rs: ColorProcessor imported from oak_core::color.
- Integration tests repointed at oak_core::{texture, frame, backend,
  color, colormath}.
- the display-ICC regression test treats an empty OAK_DISPLAY_ICC as
  unset, matching displayicc::env_override_icc.
2026-09-03 17:42:20 +08:00

140 lines
5.2 KiB
Rust

// Oak Video Editor - Non-Linear Video Editor
// Copyright (C) 2026 Oak Team
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//! `PreCacheTask`, mirroring `src/task/src/precache/precachetask.h`.
//!
//! Renders a footage node through [`crate::render::RenderTask`] to fill
//! the playback cache. The footage and its sequence are now
//! [`crate::nodeops::NodeRef`] domain references (the deleted oaknode C
//! ABI stubs are gone); video params come from the sequence's parameter
//! streams and the cache range is the full footage video length.
//!
//! **Simplifications over the C++**: the deep project copy / viewer
//! wiring is not built (the render drives the given footage directly —
//! the ticket carries the footage filename and the footage node's
//! identity as the cache key) and the timeline work-area intersection is
//! replaced by the full footage length. The direct ticket arena's eval
//! producer does not persist frames to the frame cache yet, so this
//! render pass warms nothing on disk; the plumbing is in place.
//!
//! CPP-PARITY: src/task/src/precache/precachetask.h
use oak_core::videoparams::VideoParams;
use crate::error::Result;
use crate::nodeops::{self, NodeRef};
use crate::render::{RenderTask, RenderTaskBehavior};
use crate::task::{Task, TaskBehavior};
use oak_core::{Rational, TimeRange};
/// A pre-cache task: renders frames of a footage node into the playback
/// cache without any output file.
pub struct PreCacheTask {
/// The render base (itself a task).
pub render: RenderTask,
/// The footage being cached.
pub footage: NodeRef,
/// Frame index within the footage being cached.
pub index: i32,
/// The sequence context the footage lives in.
pub sequence: NodeRef,
}
impl PreCacheTask {
/// Create a pre-cache task for the given footage at `index` inside
/// `sequence`. The old `footage: CHandle` / `sequence: CHandle`
/// signature is replaced by domain [`NodeRef`]s (single-lib
/// unification).
pub fn new(footage: NodeRef, index: i32, sequence: NodeRef) -> PreCacheTask {
// The sequence's video params drive the render timebase (the
// deleted `oaknode_sequence_get_video_params` stub is replaced by
// the direct behavior query).
let video_params: Option<VideoParams> =
nodeops::sequence_video_params(&sequence.0, sequence.1, 0);
// The footage filename labels the task (the deleted
// `oaknode_footage_filename` stub is replaced by the direct
// behavior query).
let filename = nodeops::footage_filename(&footage.0, footage.1);
let title = format!("Pre-caching {filename}:{index}");
let base = Task::new(&title, None);
// The render target is the footage node itself (pre-cache fills
// that footage's frame cache).
let render = RenderTask::new(base, video_params, footage.clone(), Default::default(), None);
PreCacheTask {
render,
footage,
index,
sequence,
}
}
}
impl TaskBehavior for PreCacheTask {
fn run(&mut self, task: &mut Task) -> Result<()> {
// Share the caller's cancellation atom with the inner render base.
self.render.base.set_cancel_atom(task.get_cancel_atom());
// The full footage length is the cache range (simplified: no
// work-area intersection). The deleted `oaknode_footage_get_video_length`
// stub is replaced by the direct behavior query.
let length = nodeops::node_length(&self.footage.0, self.footage.1);
let range = TimeRange::new(Rational::new(0, 1), length);
// No color manager / frame-cache handles exist on the direct
// ticket path (the arena keys the cache by the footage node
// identity — see `RenderTask::build_video_ticket`).
self.render.set_render_inputs(0 /* k_online */, false, range);
// Drive the render with `self` as the subclass behavior (the C++
// virtual dispatch receiver); the render is temporarily moved out to
// avoid a self-referential borrow and put back before returning.
let mut render =
std::mem::replace(&mut self.render, crate::render::RenderTask::placeholder());
let result = render.render(task, self);
self.render = render;
result
}
}
impl RenderTaskBehavior for PreCacheTask {
fn frame_downloaded(&mut self, task: &mut Task, frame: &oak_core::texture::Texture) -> Result<()> {
// Do nothing: pre-cache just fills the frame cache (the direct
// ticket arena records the render through the ticket's cache
// identity; see the module docs).
let _ = (task, frame);
Ok(())
}
fn audio_downloaded(
&mut self,
task: &mut Task,
buffer: &oak_render::ticket::AudioSamples,
) -> Result<()> {
// Pre-cache doesn't cache any audio.
let _ = (task, buffer);
Ok(())
}
fn encode_subtitle(&mut self, task: &mut Task, text: &str) -> Result<()> {
let _ = (task, text);
Ok(())
}
}