core: merge oak-common into oak-core
CI / Build & test (Linux) (push) Successful in 24m6s
CI / Build & test (Windows) (push) Successful in 31m14s

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.
This commit is contained in:
2026-09-03 17:42:20 +08:00
parent 49fed365a4
commit 4babbf5de8
150 changed files with 3052 additions and 4030 deletions
+2 -2
View File
@@ -22,7 +22,7 @@
//! `Unavailable`. Deterministic per-channel filenames derive from the
//! source + target audio params.
use oak_common::filefunctions::FileFunctions;
use oak_core::filefunctions::FileFunctions;
use std::path::Path;
/// Conform state of one audio stream.
@@ -184,7 +184,7 @@ fn conform_filenames(
out
}
/// `oakcommon_filefunctions_get_unique_file_identifier` wrapper.
/// `oak_core_filefunctions_get_unique_file_identifier` wrapper.
fn unique_file_identifier(filename: &str) -> String {
FileFunctions::new()
.get_unique_file_identifier(filename)
+2 -2
View File
@@ -26,7 +26,7 @@
use std::path::Path;
use std::sync::{Arc, Mutex, OnceLock};
use oak_common::cancelatom::CancelAtom;
use oak_core::cancelatom::CancelAtom;
use oak_core::{Rational, TimeRange};
use crate::footagedescription::FootageDescription;
@@ -113,7 +113,7 @@ pub enum RenderMode {
/// "Don't force a color range" sentinel for
/// [`RetrieveVideoParams::force_range`] (the actual ranges are the
/// `OAKCOMMON_COLOR_RANGE_*` values).
/// `oak_core_COLOR_RANGE_*` values).
pub const K_COLOR_RANGE_DEFAULT: i32 = -1;
/// `Decoder::RetrieveVideoParams` — what a video retrieve call needs.
+3 -3
View File
@@ -269,10 +269,10 @@ impl EncodingParams {
}
}
/// Load from a compact XML preset string (oakcommon C++ XmlStreamReader).
/// Load from a compact XML preset string (oak_core C++ XmlStreamReader).
///
/// # CPP-PARITY
/// `EncodingParams::load` — uses oakcommon's C++ `XmlStreamReader`
/// `EncodingParams::load` — uses oak_core's C++ `XmlStreamReader`
/// (`src/common/src/xmlutils.h`), a C++-to-C++ coupling the bridge
/// cannot cover (NOTES.md §7). Preserves the load_v1 bug of not
/// assigning `custom_range`.
@@ -524,7 +524,7 @@ impl EncodingParams {
// ---------------------------------------------------------------------------
// Minimal XML helpers for the round-trip `load`/`save_to_string`.
//
// CPP-PARITY: the C++ `load`/`save_to_string` go through oakcommon's
// CPP-PARITY: the C++ `load`/`save_to_string` go through oak_core's
// `XmlStreamReader`/`XmlStreamWriter` (a C++-to-C++ coupling the Rust bridge
// cannot cover, NOTES.md §7). Rather than returning `Err`, this port keeps a
// minimal but faithful round-trip for the fields representable without the
+17 -17
View File
@@ -56,10 +56,10 @@ use ffmpeg::software::{resampling, scaling};
use ffmpeg::{ChannelLayout, Dictionary, Error as FfmpegError, Rational as FfRational};
use ffmpeg_next as ffmpeg;
use oak_common::cancelatom::CancelAtom;
use oak_common::colormath::YuvMatrix;
use oak_common::ocioutils::PixelFormat as OakPixelFormat;
use oak_common::videoparams::{Interlacing, VideoParams, VideoType};
use oak_core::cancelatom::CancelAtom;
use oak_core::colormath::YuvMatrix;
use oak_core::ocioutils::PixelFormat as OakPixelFormat;
use oak_core::videoparams::{Interlacing, VideoParams, VideoType};
use oak_core::{PixelFormat, Rational, SampleFormat, TimeRange};
use crate::audioparams::AudioParams;
@@ -69,10 +69,10 @@ use crate::encodingparams::EncodingParams;
use crate::footagedescription::{FootageDescription, StreamEntry};
use crate::frame::Frame;
/// `OAKCOMMON_COLOR_RANGE_FULL`.
const OAKCOMMON_COLOR_RANGE_FULL: i32 = 1;
/// `OAKCOMMON_COLOR_RANGE_LIMITED`.
const OAKCOMMON_COLOR_RANGE_LIMITED: i32 = 0;
/// `oak_core_COLOR_RANGE_FULL`.
const oak_core_COLOR_RANGE_FULL: i32 = 1;
/// `oak_core_COLOR_RANGE_LIMITED`.
const oak_core_COLOR_RANGE_LIMITED: i32 = 0;
/// `AVCOL_RANGE_JPEG` (full range; AVCOL_RANGE_MPEG = 1 is limited).
const AVCOL_RANGE_JPEG: i32 = 2;
/// swscale colorspace ids (`SWS_CS_*`, libswscale/swscale.h).
@@ -372,9 +372,9 @@ impl Decoder for FFmpegDecoder {
params.set_color_primaries(color_meta.color_primaries);
params.set_color_transfer(color_meta.color_trc);
params.set_color_range(if color_meta.full_range {
oak_common::videoparams::ColorRange::Full
oak_core::videoparams::ColorRange::Full
} else {
oak_common::videoparams::ColorRange::Limited
oak_core::videoparams::ColorRange::Limited
});
}
Ok(Arc::new(frame))
@@ -1099,9 +1099,9 @@ impl DecoderState {
// frame's own metadata (YUVJ sources are full range). The old path
// forced MPEG/limited for everything, crushing full-range screen
// captures and JPEG-derived footage.
let full_range = if force_range == OAKCOMMON_COLOR_RANGE_FULL {
let full_range = if force_range == oak_core_COLOR_RANGE_FULL {
true
} else if force_range == OAKCOMMON_COLOR_RANGE_LIMITED {
} else if force_range == oak_core_COLOR_RANGE_LIMITED {
false
} else {
yuvj_full || raw_range == AVCOL_RANGE_JPEG
@@ -1949,7 +1949,7 @@ fn convert_rgba8_to_f32(data: &[u8], w: u32, h: u32, stride: usize) -> Vec<u8> {
/// colorspace tables and full ranges on both sides, so no matrix and no
/// range recompression was applied. 10/12-bit sources arrive left-shifted
/// to 16-bit (code << 6 / code << 4) — exactly the code-value scale
/// [`oak_common::colormath::yuv444p16_to_rgb_f32`] expects.
/// [`oak_core::colormath::yuv444p16_to_rgb_f32`] expects.
fn convert_yuv444p16_to_rgba_f32(
out: &ffmpeg::frame::Video,
w: u32,
@@ -1958,7 +1958,7 @@ fn convert_yuv444p16_to_rgba_f32(
full_range: bool,
) -> Vec<u8> {
let mut rgba = vec![0.0f32; (w as usize) * (h as usize) * 4];
oak_common::colormath::yuv444p16_to_rgb_f32(
oak_core::colormath::yuv444p16_to_rgb_f32(
out.data(0),
out.stride(0),
out.data(1),
@@ -2111,9 +2111,9 @@ fn probe_file(filename: &str, cancelled: Option<&CancelAtom>) -> Option<FootageD
vp.set_color_primaries((*raw).color_primaries as i32);
vp.set_color_transfer((*raw).color_trc as i32);
vp.set_color_range(if (*raw).color_range as i32 == AVCOL_RANGE_JPEG {
oak_common::videoparams::ColorRange::Full
oak_core::videoparams::ColorRange::Full
} else {
oak_common::videoparams::ColorRange::Limited
oak_core::videoparams::ColorRange::Limited
});
}
desc.push_stream(StreamEntry::Video(vp));
@@ -3165,7 +3165,7 @@ mod tests {
#[test]
fn yuv_matrix_mapping_is_strict() {
use oak_common::colormath::YuvMatrix;
use oak_core::colormath::YuvMatrix;
assert_eq!(yuv_matrix_for(AVCOL_SPC_BT709, 1920, 1080), YuvMatrix::Bt709);
assert_eq!(yuv_matrix_for(AVCOL_SPC_BT470BG, 640, 480), YuvMatrix::Bt601);
assert_eq!(yuv_matrix_for(AVCOL_SPC_SMPTE170M, 1920, 1080), YuvMatrix::Bt601);
+11 -11
View File
@@ -18,13 +18,13 @@
//!
//! Mirrors `src/codec/src/footagedescription.h`. A value type describing
//! the streams a `Decoder::probe()` found in a file. Video and subtitle
//! streams are stored as oakcommon by-value handles; audio streams as
//! streams are stored as oak_core by-value handles; audio streams as
//! `oak_core::TimeRangeList`/raw audio params. The original's
//! `Track::Type` mapping and XML load/save are intentionally not reproduced
//! (NOTES.md §4) — use [`FootageDescription::stream_is_video`] etc.
use oak_common::subtitleparams::SubtitleParams;
use oak_common::videoparams::VideoParams;
use oak_core::subtitleparams::SubtitleParams;
use oak_core::videoparams::VideoParams;
use oak_core::{Rational, TimeRange};
use crate::audioparams::AudioParams;
@@ -214,14 +214,14 @@ mod tests {
fn video_params(index: i32) -> VideoParams {
let mut vp = VideoParams::new_basic(
1920,
1080,
oak_common::ocioutils::PixelFormat::from_code(0),
4,
1,
1,
0,
1,
1920,
1080,
oak_core::ocioutils::PixelFormat::from_code(0),
4,
1,
1,
0,
1,
);
vp.set_stream_index(index);
vp
+5 -5
View File
@@ -16,13 +16,13 @@
//! `olive::Frame` — a CPU pixel buffer plus a [`VideoParams`] value.
//!
//! Mirrors `src/codec/src/frame.h`. The params are held as an oakcommon
//! Mirrors `src/codec/src/frame.h`. The params are held as an oak_core
//! [`VideoParams`] value (single-lib unification; the former refcounted
//! oakcommon handle is gone, so copies are plain clones); the pixel data
//! oak_core handle is gone, so copies are plain clones); the pixel data
//! itself is a plain `Vec<u8>`. Line-size and pixel-format math lives
//! here.
use oak_common::videoparams::VideoParams;
use oak_core::videoparams::VideoParams;
use oak_core::{PixelFormat, Rational};
/// Number of channels in the internal RGBA pipeline layout
@@ -331,7 +331,7 @@ impl Frame {
#[cfg(test)]
mod tests {
use super::*;
use oak_common::ocioutils::PixelFormat as OakPixelFormat;
use oak_core::ocioutils::PixelFormat as OakPixelFormat;
fn frame(w: i32, h: i32) -> Frame {
let params = VideoParams::new_basic(w, h, OakPixelFormat::from_code(0), 4, 1, 1, 0, 1);
@@ -422,7 +422,7 @@ mod tests {
#[cfg(test)]
mod tests_extra {
use super::*;
use oak_common::ocioutils::PixelFormat as OakPixelFormat;
use oak_core::ocioutils::PixelFormat as OakPixelFormat;
fn frame(w: i32, h: i32) -> Frame {
let params = VideoParams::new_basic(w, h, OakPixelFormat::from_code(0), 4, 1, 1, 0, 1);
+2 -2
View File
@@ -27,7 +27,7 @@ use std::sync::{Arc, Mutex, OnceLock};
use std::thread;
use std::time::Duration;
use oak_common::videoparams::VideoParams;
use oak_core::videoparams::VideoParams;
use crate::frame::Frame;
/// `olive::FrameManager`: singleton frame pool with background GC.
@@ -148,7 +148,7 @@ fn frame_matches(frame: &Frame, params: &VideoParams) -> bool {
#[cfg(test)]
mod tests {
use super::*;
use oak_common::ocioutils::PixelFormat as OakPixelFormat;
use oak_core::ocioutils::PixelFormat as OakPixelFormat;
fn test_params(w: i32, h: i32) -> VideoParams {
VideoParams::new_basic(w, h, OakPixelFormat::from_code(0), 4, 1, 1, 0, 1)
+1 -1
View File
@@ -106,7 +106,7 @@ pub fn hardware_decoding_enabled() -> bool {
if let Ok(v) = std::env::var("OAK_HWACCEL") {
return v != "0";
}
match oak_common::configstore::ConfigStore::instance()
match oak_core::configstore::ConfigStore::instance()
.get(None, CONFIG_KEY_HARDWARE_DECODING)
{
Ok(value) => value != "false",
+10 -10
View File
@@ -18,7 +18,7 @@
//!
//! Mirrors `src/codec/src/oiio/{oiiodecoder,oiioencoder}.{h,cpp}`. OIIO
//! frame conversion goes through the local
//! [`crate::oiioframebridge`] helpers plus oakcommon's OIIO mapping
//! [`crate::oiioframebridge`] helpers plus oak_core's OIIO mapping
//! functions.
//!
//! The OIIO dylib (`liboakoiio`) is not linked into this build, so every
@@ -58,9 +58,9 @@ impl Decoder for OIIODecoder {
}
fn probe(
&self,
_filename: &str,
_cancelled: Option<&oak_common::cancelatom::CancelAtom>,
&self,
_filename: &str,
_cancelled: Option<&oak_core::cancelatom::CancelAtom>,
) -> Option<crate::footagedescription::FootageDescription> {
// Probing is a dylib operation; without it we cannot report anything.
None
@@ -113,12 +113,12 @@ impl Decoder for OIIODecoder {
}
fn conform_audio(
&self,
_output_filenames: &[String],
_sample_rate: i32,
_channel_layout: u64,
_sample_format: i32,
_cancelled: Option<&oak_common::cancelatom::CancelAtom>,
&self,
_output_filenames: &[String],
_sample_rate: i32,
_channel_layout: u64,
_sample_format: i32,
_cancelled: Option<&oak_core::cancelatom::CancelAtom>,
) -> crate::error::Result<()> {
Err(crate::error::Error::Failed(Self::NOT_AVAILABLE.to_string()))
}
+4 -4
View File
@@ -18,8 +18,8 @@
//! frame <-> pixel-buffer conversion.
//!
//! Mirrors `src/codec/src/oiioframebridge.{h,cpp}`. These are internal C++
//! functions that moved into codec from oakcommon (NOTES.md §oakcommon侧修复);
//! oakcommon keeps its OIIO mapping functions; the frame conversion itself
//! functions that moved into codec from oak_core (NOTES.md §oak_core侧修复);
//! oak_core keeps its OIIO mapping functions; the frame conversion itself
//! lives here.
//!
//! The C++ bridge copies pixels through the live OpenImageIO `ImageBuf`
@@ -30,8 +30,8 @@
//! timestamp and time base alongside the raw pixel rows, so a buffer can be
//! turned back into an equivalent [`Frame`] without any external state.
use oak_common::ocioutils::PixelFormat as OakPixelFormat;
use oak_common::videoparams::VideoParams;
use oak_core::ocioutils::PixelFormat as OakPixelFormat;
use oak_core::videoparams::VideoParams;
use crate::frame::Frame;
use oak_core::Rational;
use std::ffi::c_int;
+10 -10
View File
@@ -19,12 +19,12 @@
//! Mirrors `src/codec/src/proxymanager.h`. Stateless (NOTES.md): actual
//! transcodes are delegated to the global task submit callback
//! ([`crate::task`]); with no registrar, `get_or_start` reports the proxy
//! as missing. `proxy_params_from_config` reads the oakcommon config store
//! as missing. `proxy_params_from_config` reads the oak_core config store
//! with the compiled-in defaults as fallback (1280x720 / divider 1 / crf 23
//! / "mp4" / "veryfast" / audio included).
use oak_common::configstore::ConfigStore;
use oak_common::filefunctions::FileFunctions;
use oak_core::configstore::ConfigStore;
use oak_core::filefunctions::FileFunctions;
use std::path::Path;
/// Proxy state of a proxy file on disk.
@@ -127,13 +127,13 @@ impl ProxyManager {
ProxyParams::default()
}
/// Proxy parameters read from the oakcommon config, with the compiled-in
/// Proxy parameters read from the oak_core config, with the compiled-in
/// defaults as fallback.
///
/// # CPP-PARITY
/// `src/codec/src/proxymanager.h` `proxy_params_from_config` — reads
/// ProxyWidth/ProxyHeight/ProxyDivider/ProxyCRF/ProxyPreset/
/// ProxyIncludeAudio via `oakcommon_config_*`.
/// ProxyIncludeAudio via `oak_core_config_*`.
pub fn proxy_params_from_config() -> ProxyParams {
let mut p = ProxyParams::default();
p.width = config_get_int("ProxyWidth", p.width);
@@ -387,17 +387,17 @@ fn cstr_slice(a: &[u8; 32]) -> &str {
std::str::from_utf8(&a[..end]).unwrap_or("")
}
/// `oakcommon_config_get_int` wrapper (null group).
/// `oak_core_config_get_int` wrapper (null group).
fn config_get_int(key: &str, default: i32) -> i32 {
ConfigStore::instance().get_int(None, key, default)
}
/// `oakcommon_config_get_bool` wrapper (null group).
/// `oak_core_config_get_bool` wrapper (null group).
fn config_get_bool(key: &str, default: i32) -> i32 {
ConfigStore::instance().get_bool(None, key, default)
}
/// `oakcommon_config_get` string read; `None` when the stored value is
/// `oak_core_config_get` string read; `None` when the stored value is
/// empty or absent.
fn config_get_str(key: &str) -> Option<String> {
match ConfigStore::instance().get(None, key) {
@@ -406,14 +406,14 @@ fn config_get_str(key: &str) -> Option<String> {
}
}
/// `oakcommon_filefunctions_get_unique_file_identifier` wrapper.
/// `oak_core_filefunctions_get_unique_file_identifier` wrapper.
fn unique_file_identifier(filename: &str) -> String {
FileFunctions::new()
.get_unique_file_identifier(filename)
.unwrap_or_default()
}
/// `oakcommon_filefunctions_get_application_path` read.
/// `oak_core_filefunctions_get_application_path` read.
fn application_path() -> String {
FileFunctions::new()
.get_application_path()
+3 -3
View File
@@ -26,8 +26,8 @@
//! compiled without `#[cfg(test)]` and cannot resolve those symbols; see
//! `tests/ffi_contract_test.rs`).
use oak_common::ocioutils::PixelFormat as OakPixelFormat;
use oak_common::videoparams::VideoParams;
use oak_core::ocioutils::PixelFormat as OakPixelFormat;
use oak_core::videoparams::VideoParams;
use crate::decoder::{
CodecStream, Decoder, RenderMode, RetrieveAudioStatus, RetrieveVideoParams,
K_COLOR_RANGE_DEFAULT,
@@ -503,7 +503,7 @@ static HW_TEST_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(());
#[test]
fn hardware_decode_matches_software_decode() {
let _guard = HW_TEST_LOCK.lock().unwrap_or_else(|e| e.into_inner());
let config = oak_common::configstore::ConfigStore::instance();
let config = oak_core::configstore::ConfigStore::instance();
let key = crate::hwdecode::CONFIG_KEY_HARDWARE_DECODING;
let decode_at = |time: i64| -> (Option<String>, Arc<Frame>) {
+2 -2
View File
@@ -37,8 +37,8 @@
use std::path::Path;
use oak_common::ocioutils::PixelFormat as OakPixelFormat;
use oak_common::videoparams::VideoParams;
use oak_core::ocioutils::PixelFormat as OakPixelFormat;
use oak_core::videoparams::VideoParams;
use oak_core::{PixelFormat, Rational, SampleFormat};
use crate::encodingparams::EncodingParams;