Files
oak-editor/docs/zh/plans/riir/M5-oakcodec.md
T
Mike-Solar 9b25772267 docs: module-split execution manuals for RIIR stage 1 (plans/riir/)
13 files: 00 overview, 01 two-layer adapter spec (init/free/func +
opaque handles + same-name adapter classes, frozen naming/ownership/
error/event rules), 02 dependency matrix + split order M1-M9 (from a
490-file include scan), 03 Google Test spec (per-C-API coverage,
roundtrip tests, leak counters), M1-M9 per-module manuals with frozen
C APIs (common/undo/node/timeline/codec/audio/render/task/plugin) and
the facade assembly-layer verdict.
2026-07-27 00:06:33 +08:00

4.3 KiB
Raw Blame History

M5 · oakcodec 拆分手册

内容:engine/codec/decoder/encoder/frame/waveform/proxymanager/ conformmanager)。 依赖:common 12、render 11M3.5 下沉后剩 ~3)、task 5、node 3、 core 4。 拆分顺序第 5 位。

1. 目标形态

oakcodec/
  include/oakcodec/{frame.h, decoder.h, encoder.h, waveform.h, proxy.h,
                   types.h, export.h}
  src/
  tests/  # oakcodec_gtest

2. 冻结 C API

2.1 oakcodec/frame.hrender 7 次引 codec/frame.h

typedef struct OakCodecFrame OakCodecFrame;
OAKCD_API OakCodecFrame *oakcodec_frame_init(void);
OAKCD_API OakCodecFrame *oakcodec_frame_init_copy(const OakCodecFrame *o);
OAKCD_API void oakcodec_frame_free(OakCodecFrame *f);
OAKCD_API OakCodecFrame *oakcodec_frame_retain(OakCodecFrame *f); /* +1 */
OAKCD_API int oakcodec_frame_set_params(OakCodecFrame *f,
	const oak_video_params *p);
OAKCD_API int oakcodec_frame_get_params(const OakCodecFrame *f,
	oak_video_params *out);
OAKCD_API int oakcodec_frame_allocate(OakCodecFrame *f);
OAKCD_API void *oakcodec_frame_data(OakCodecFrame *f);
OAKCD_API int oakcodec_frame_linesize(const OakCodecFrame *f);
OAKCD_API int64_t oakcodec_frame_timestamp(const OakCodecFrame *f);
OAKCD_API void oakcodec_frame_set_timestamp(OakCodecFrame *f, int64_t ts);

2.2 oakcodec/decoder.h

typedef struct OakCodecDecoder OakCodecDecoder;
OAKCD_API OakCodecDecoder *oakcodec_decoder_init(const char *filename);
OAKCD_API void oakcodec_decoder_free(OakCodecDecoder *d);
OAKCD_API int oakcodec_decoder_stream_count(const OakCodecDecoder *d,
	int media_type /* 0=video 1=audio */);
OAKCD_API int oakcodec_decoder_get_video_stream(const OakCodecDecoder *d,
	int index, oak_video_params *out, int64_t *duration_ts);
OAKCD_API int oakcodec_decoder_get_audio_stream(const OakCodecDecoder *d,
	int index, int *sample_rate, uint64_t *layout, int *format);
OAKCD_API OakCodecFrame *oakcodec_decoder_decode_video(
	OakCodecDecoder *d, int stream, int64_t ts);   /* NULL=EOF/错误 */
OAKCD_API int oakcodec_decoder_decode_audio(OakCodecDecoder *d,
	int stream, int64_t ts, float *buf, int frame_count);
OAKCD_API int oakcodec_decoder_last_error(OakCodecDecoder *d,
	char *buf, int n);

2.3 oakcodec/encoder.h

typedef struct OakCodecEncoder OakCodecEncoder;
OAKCD_API OakCodecEncoder *oakcodec_encoder_init(
	const oak_encoding_params *params);   /* POD 照 oakengine/encoding.h */
OAKCD_API void oakcodec_encoder_free(OakCodecEncoder *e);
OAKCD_API int oakcodec_encoder_write_video(OakCodecEncoder *e,
	const OakCodecFrame *f);
OAKCD_API int oakcodec_encoder_write_audio(OakCodecEncoder *e,
	const float *samples, int frame_count);
OAKCD_API int oakcodec_encoder_flush(OakCodecEncoder *e);
OAKCD_API int oakcodec_encoder_last_error(OakCodecEncoder *e,
	char *buf, int n);

2.4 oakcodec/waveform.hoakcodec/proxy.h

waveformoakcodec_waveform_extract(filename, stream, out_min_max_pairs, progress_cb)AudioWaveformCache 的磁盘格式不变)。 proxy:照 oakengine/proxy.h 模板(get_or_start/state/cancel)。

3. 切割点

现状 处理
codec → render/ 11 videoparams/subtitleparams/colortransform 已随 M3.5 下沉 oakcommon;剩 renderer.h(2)、framemanager.h(1) → framemanager 是 codec 内部缓存编排,随 codec 一起走(从 render/ 移入 oakcodec/src,纯文件移动,它本来就主要服务 codec)
codec → task/ 5taskmanager/conform/proxy 编排) proxy/conform 对 TaskManager 的引用改为 01 §4 回调注册(oakcodec_set_task_submit_cb),Task 对象创建上移 oaktaskM8),oakcodec 只调回调
codec → node/ 3 经 oaknode C ABIM3 已就位)

4. 测试(映射 03 §2/§3

  • frameparams 往返、allocate/data/linesize、retain/free 引用计数。
  • decodertests/demo.mp4 开流、stream 枚举、decode 首帧非空、 错误路径(不存在文件 → E_NOT_FOUND + last_error 非空)。
  • encoder:写小 mp4(照 oak_cli_transcode 的参数),flush 后文件 可再被 decoder 打开(往返)。
  • waveformdemo.mp4 提取返回非空且长度与时长一致(容差断言)。
  • proxymock 免(03 §4)——用 demo.mp4 低分辨率参数真跑一次或 按环境跳过。
  • oakcodec_debug_alive_count() 泄漏断言。