Releases: Eureka175/1KeyTranscoder
Release list
1KeyTranscoder v0.8.0 — 音频输出接入生产管线 · 格式感知 · 外挂音频
1KeyTranscoder v0.8.0 — 音频输出接入生产管线 · 格式感知 · 外挂音频
v0.8.0 把 v0.7.1 建立的 PCM 音频管线真正接进生产输出,并补上三件此前
只靠"调用方自觉"的事:输入格式判定、输出编码继承、外挂音频。
全部仍然是音频域内部的能力,视频编码后端与元数据保留管线一行未改。基线
v0.7.1(tagv0.7.1=e613b07)。
详细设计与实测证据见仓库
docs/release_notes_v0.8.0.md与
docs/design/architecture.md§6.2–§6.6。
Included
- Audio format-aware alignment — 输入是 PCM 还是 compressed 由 ffprobe 的
codec_name唯一判定(pcm_*= uncompressed,其余 = compressed):
PCM 输入默认允许进入 alignment,compressed 输入默认原样保留。
alignment: disabled可显式关闭。reference 仍然从不自动猜 —— 必须由
sync.reference显式给出,否则"允许对齐"不会产生任何 offset。 - Compressed audio re-encode for alignment — 显式要求 compressed 输入对齐时
输出 §5 的 warning,并走 decode → PCM → align → 重编码,输出 codec 保持
来源 codec。实测:注入 480 样本延迟的 Opus 目标估计出 480、AAC 目标
1504(480 + AAC 解码 priming 1024),两者对齐后互相关残差 0 —— 这正
是"禁止在压缩包上伪造时间戳平移"的量化理由。 - External audio discovery — 同一目录下按确定性文件名规则发现外挂录音:
音频主干必须以视频主干精确开头,且其后的第一个字符必须是结束 /-/_;
只扫描视频所在目录与音频扩展名白名单。排序完全确定(精确主干 → 数字序号 →
其它后缀),数字段按数值比较(clip001_2在clip001_10之前),前导零
归一化但仍是不同候选,同分用完整文件名 lexical order 收尾。多个候选全部
纳入,没有候选不报错。 - External audio mapping — 外挂音频严格遵循最终 mapping:
source(跟随每个
输入的流结构,默认)/independent(一声道一条流)/grouped(n)(连续 n 声道
一条流,跨文件继续成组)。4CH + grouped(2)→ 2×stereo,8CH + grouped(2)
→ 4×stereo,3CH + grouped(2)→ 2CH + 1CH(奇数剩余保留,不丢弃也不复制)。
不变量:Σ 输出声道 == 有效映射声道,否则报错而不是静默丢声道。 - AAC / Opus manual bitrate — 输出编码优先级链
manual override > source-derived defaults > encoder default:PCM 输入默认
PCM 输出,compressed 输入保持来源 codec + 来源 bitrate,手动format/
bitrate覆盖之(AAC 128k/192k/256k、Opus 64k/96k/128k …)。lossless 输出带
bitrate明确拒绝,不静默忽略。codec 继承按输出流进行,因此一条 AAC 外挂
录音与一条 PCM 源可以在同一份输出里各自保持自己的 codec。 - Mapping preservation — alignment 与重编码只移动样本时间轴,绝不改变声道
身份、流顺序或声道集合;原视频音频的输出结构由既有输出单元决定,不被 mapping
策略改写。整条完整源流仍然-map+ stream copy(不解码、不重编码),只有必须
重建的流才渲染 + 编码,两者可在同一次输出里混用。 - Regression coverage —
--level unit590 PASS / 0 FAIL,
--level full856 PASS / 0 FAIL(unit 590 + toolchain 16 + full 250)。
相对 Phase 4C 基线(unit 511 / full 728)新增 128 条断言、0 条 FAIL、
0 条被删除。
Fixed
- alignment 与 stream copy 不能混用:
-map没有"时间原点"可言,而有 offset 的
声道是按统一 timeline 重新取样的(window 起点可能不是 0)。两者混在一个容器里
就是两条流各有各的原点 —— 表现出来恰好是"对齐没生效"。现在一旦产生非零
offset,整份输出共用一份 render window,每条输出流都由 render 产出,组数与
每组声道保持不变。 - AAC 容器由裸 ADTS 改为 MP4 家族(
.m4a):实测PCM → AAC(ADTS) → 解码
会让内容整体后移 1024 个样本(编码器 priming,ADTS 无法携带),"为重编码对齐"
会被这一步吃掉;MP4 容器把 priming 写进 edit list,实测位置一致。
同时_probe_audio()不再把nb_frames当样本数 —— MP4 家族的音频流报的是
packet 数(AAC 一包 1024 样本)。
CLI
- 没有新增参数:全部能力通过既有的
--audio-planJSON 触达,新增四个
可选键:alignment/sync/mapping/external(schema 版本仍为 1,
因为这是加法式扩展;未知键依旧一律拒绝)。 - 不指定
--audio-plan时默认音频路径完全不变(-map 0+-c:a copy)。 --audio-plan仍只在经典软件路径(--encoder x265/svtav1)生效;硬件后端
与 Sony/DJI 保留管线明确报错(rc=2)而不是静默忽略,与--channel-sync
互斥(同样 rc=2)。
Package
自包含 Windows x64 包(与 v0.6.1 同一套打包脚本 release/build_release.py):
1KeyTranscoder-v0.8.0-win64-selfcontained.zip
sha256 7eb98a8077bda09f5c7e074198e83fc84aee0782204580923a52de5fe0f5c0ba
522 file records · 内含 release-manifest.json(逐文件 size + sha256)
runtime: ffmpeg/ffprobe 9.0.1 · NVEncC 9.31 · QSVEncC 8.26 · MP4Box 26.02
包完整性由 release/verify_package.py 复核:62/62 checks PASS(含逐文件
sha256 对账、开发产物不得入包、运行时版本可复现)。
Not implemented
drift correction: not implemented
resampling: not implemented
loudness: not implemented
也仍然没有:自动多文件同步(外挂音频只按文件名规则发现,不做内容匹配)、
codec 能力 / quality preset / VBR 策略框架、多 mixer sink 的输出结构、
硬件后端与 Sony/DJI 保留管线上的音频计划、P5。
Unchanged
- video encode backend —
encoders/、core/scaling.py、core/hwdecode.py
相对v0.7.1零改动,视频基本流 sha256 在每种音频处理下都和默认路径一致
(回归逐案断言)。 - metadata backend / Sony / DJI preservation —
preservation/相对v0.7.1
零改动。 - sync algorithm —
core/channel_sync.py/core/sync_estimate.py/
core/sync_fix.py/core/mp4_channel_sync.py零改动;arbitrary-reference
回归全部通过。 - default audio path — 未启用
--audio-plan时行为与 v0.7.1 完全一致。
1KeyTranscoder v0.7.1
1KeyTranscoder v0.7.1 — 音频处理架构与 PCM 管线
v0.7.1 focuses on the audio processing architecture and PCM pipeline.
全部为内部能力层:不新增 CLI,默认音频路径与输出行为未改变。基线
v0.7.0(hardware-decode integration,已并入main)。
详细设计与完整测试矩阵见仓库docs/release_notes_v0.7.1.md。
Included
- Audio model —
AudioSource/AudioStream/AudioChannel/AudioTrack/
AudioPlan/AudioSyncResult(纯数据层,零项目内依赖,JSON 往返稳定) - Source / stream / channel selection and mapping — 三维身份
{source_id}:s{stream}:c{channel}、AudioPlanner、AudioOutputTrack、
AudioMapSpec(dry-run,不执行 ffmpeg) - Unified timeline / EOF / offset handling —
AudioTimeline是时长·EOF·offset
的唯一权威:RenderPolicy.UNION、确定性静音补位、timeline = source − offset - PCM routing —
AudioPCMReader(ffmpeg → canonical float32,分块读取,
identitychannelmap防隐式重排)+AudioRouter(1:1 纯样本搬运) - WAV export —
WavExporter(PCM16/24/32 + float32,WAVE_FORMAT_EXTENSIBLE,
header 按实际字节回填) - PCM mixing and clipping policies —
AudioMixer(N→1、线性 gain、float32 累加、
MixStats检波、ClipPolicy=detect/hard_clip/error) - Regression coverage — 既有自动化回归套件 509 PASS / 0 FAIL
(unit 390 + toolchain 16 + full 103)
Unchanged
- default audio copy path —
AudioPlan = None→-map 0+-c:a copy;
Sony/DJI 仍由 GPAC 复制音频;生产代码对audio_*模块零 import - hardware decode —
encoders/与preservation/相对v0.7.0零改动 - video path —
1kt.py/core/batch_hw.py零改动 - x265 scaling —
encoders/x265.py与core/scaling.py零改动 - channel_sync algorithm — 算法、阈值、schema 零改动(模型只读取其报告 JSON)
相对
v0.7.0的唯一非音频改动是core/probe.py的-show_entries增加
stream_tags(纯增量,既有键与 CSV 字段白名单不变)。
RC1 修正与冻结(v0.7.1-rc1 之前)
29. 修正:混音图的 silence_samples 统计(F1)
AudioRenderResult.silence_samples 在 mixing 图下恒定错误地报"全程静音"。
原因:run_audio_render() 把 mixing_timeline() 的产物传给了
_count_faithful_mix(),而混音 timeline 的输出声道身份是 mix0/mix1;
该函数却按源声道(camera:s0:c0)去 lookup,必然全部 miss → total = 0
→ silence_samples = frames × output_channels。
| 图 | 1000f + 400f, 1 输出声道 | 修正前 | 修正后 |
|---|---|---|---|
| routing | source A 1ch + source B 1ch(2 输出声道) | 600 ✓ | 600 ✓ |
| mixing | A×0.5 + B×0.5(1 输出声道) | 0 ✓ |
修正方式:逐输入几何一律查未混音的 base timeline(core/audio_process.py),
并在 _count_faithful_mix() docstring 里写明该前提。
未改动:AudioMixer / AudioTimeline / EOF policy / 实际 PCM 输出 /
混音 timeline 的 mixN 输出身份 / routing 行为。
回归:l1.p3b.silence_samples 走 base timeline (混音图不恒报满) 与
l1.p3a.silence_samples (routing 1000f+400f, 2 输出声道) = 600。
(已验证:撤掉修正后前者立刻 FAIL,detail 恰为 silence=1000 total=1000。)
30. 修正:effective_mapping 提升为公开入口(F6)
core/audio_plan._effective_mapping() 被 core/audio_timeline.py 直接 import,
形成 Timeline → Plan 的私有名跨层依赖。
core/audio_plan.py:_effective_mapping→effective_mapping(公开,
进入__all__);参数、返回值、mapping 语义完全未变;- 保留
_effective_mapping = effective_mapping作为兼容别名(同一实现,
不是第二套); core/audio_timeline.py/core/audio_process.py一律引用公开名;- 项目代码中私有旧名只剩别名那一行。
未改动任何 JSON、任何测试预期、任何 mapping 行为。
31. 冻结:输出权威的分工(F5)
输出音频集合与顺序的唯一权威 = AudioTimeline
routing 图: output_channel_ids = 源声道身份 (camera:s2:c2)
mixing 图: output_channel_ids = 合成身份 (mix0 / mix1)
AudioMapSpec = -map / stream-copy / channel-filter 路径的执行规格
strategy == MIXING → 该路径**不可直接执行**, 必须转入 PCM processing graph
(不是"计划非法")
AudioMapSpec 并未失效:它定义的输出顺序来自 effective_mapping(),
而 AudioTimeline 消费的正是同一个函数,两者不会分叉。详见
docs/design/architecture.md §6.1.11。
32. 冻结:RC 边界(不保证兼容的部分)
以下对象在 v0.7.1-rc1 被显式标注为内部/预留 —— Phase 4 不得依赖:
AudioPlan.channel_map / wav_outputs reserved, 零写入者, 语义未定, 不保证兼容
AudioOutputSpec.kind 当前唯一合法值 "wav"; Phase 4B 可替换为枚举
AudioMixer.output_format internal (仅服务面向 WAV 的混音)
AudioMixer.frames() INTERNAL (契约与 AudioRouter.frames() 不一致)
AudioMixer.render_to() INTERNAL (当前无调用者)
AudioPCMReader.read() not thread-safe (共享 handles + 绝对 seek;
当前串行调用无问题, Phase 5/6 并行化须重新设计)
AudioPlan.notes stable string only, 非机器可读元数据契约
reason codes 中有两个 reserved、当前生产路径不可达:
audio_sync_offset_invalid _effective_offset() 对非法 offset 静默回退 0
audio_pcm_format_unsupported audio_pcm 解码路径无此拒绝; 该字符串目前由
core/audio_wav 以字面量形式发出
二者不是 active runtime error,不得据此编写分支逻辑。
序列化字段策略(自 v0.7.1 起):
新增字段: 默认可选, 为默认值时不写出 (旧 JSON 缺失该键必须照常工作)
删除字段: 必须递增 AUDIO_MODEL_VERSION; 不做 migration framework
未知键 / 未知 enum: 一律容错 (忽略 / 回退安全默认) —— 宁可"未知", 不可"猜"
详见 docs/design/architecture.md §6.1.12 / §6.1.13。
Deferred(未包含)
v0.7.1 明确不包含以下内容(仍属后续 Phase):
- selective MP4 retention
- audio encoding/mux
- automatic cross-file synchronization
- drift correction
- resampling(采样率不一致仍直接拒绝)
- loudness normalization / LUFS / AGC / limiter / compressor / EQ /
reverb / noise reduction / spectral processing / time-stretch / pitch shift
- 新音频 CLI(--audio-* 全部未开放)
- 多 bus 同时渲染(当前一次渲染只消费第一个 MixBus)
与仓库
docs/release_notes_v0.7.1.md§20 / §27 的"未实现"边界逐条一致;
§28 的总体清单(✅ = 本版已交付)如下:
WAV 导出 ✅(P3A)
PCM Routing ✅(P3A)
PCM Mixing ✅(P3B)
Selective MP4 retention ❌
音频编码 + mux 进 MP4 ❌
自动跨文件时间轴对齐 ❌
漂移校正 ❌
其余明确边界(重采样、loudness normalization / LUFS / AGC / limiter /
compressor / EQ / reverb / noise reduction / spectral processing /
time-stretch / pitch shift、新音频 CLI)见仓库
docs/release_notes_v0.7.1.md §20 / §27。
1KeyTranscoder v0.7.0 (hardware decode integration)
1KeyTranscoder v0.7.0 — Release Notes
发布类型:milestone release(Hardware Decode integration)· GitHub Pre-release
基线:main@b3245b7(main未被本版修改)
本版 tag 所在分支:feature/hardware-decode-integration
本版不是 1.0.0,也不代表完整 release capability。
--hw-decode的默认值仍是off,默认路径行为与集成前逐 token 相同。
1. Highlights
| 项 | 说明 |
|---|---|
| Hardware decode 接入 | 新增 --hw-decode off|auto|require(默认 off)与可选的 --hw-decode-verify(sequence 级闸门)。硬解是显式 opt-in 路径,不是新的默认行为 |
| Capability routing | 只有落在 runtime-proven allowlist 内的组合才允许走硬解;其余一律 not_proven → 软解(见 §4) |
| Integrity gate | 硬解产物必须通过帧完整性闸门:五方帧数对账 + reader 身份断言(count 级,启用硬解时始终开启);--hw-decode-verify 再加逐帧有序 fingerprint(sequence 级,opt-in,代价是每文件多一次编码) |
| Fallback / reason codes | 闸门不过 ⇒ 丢弃硬件产物 → WARNING + reason code → 同格式档软解重跑;回退上限 1 次(MAX_HW_DECODE_FALLBACKS),超出即 FATAL,不无限重试(见 §5) |
| Binary provenance 绑定 | 硬解只使用 provenance 校验过的 patched build(sha256 绑定);build 缺失或 hash 不符时给 reason code,绝不静默改用 shipped build |
| 默认行为零变化 | HD-B05 逐 token 断言:policy=off(不传任何开关)产出的 argv 与集成前完全一致(首部仍 --avsw) |
| 验证规模 | integration matrix 83/83 PASS(P0 61/61,0 FAIL / 0 BLOCKED / 0 SKIP);既有全量回归 tests/full_autotest.py --level full 248 PASS / 0 FAIL |
2. 版本号
VERSION 0.6.2 -> 0.7.0
python 1kt.py --version 1KeyTranscoder 0.7.0
VERSION 是唯一版本来源(core/version.py),1kt.py --version、
release/build_release.py 与 release/verify_package.py 均从该文件读取,
不存在第二处硬编码版本。本版未改动任何编码/解码行为、默认后端或默认硬解策略。
3. Integration 判定(机器可读闸门)
Branch: feature/hardware-decode-integration
Base: main @ b3245b7 (main 未被修改)
Commits: da27e28 .. f819eb4
Test Matrix: Total 83 | PASS 83 | FAIL 0 | BLOCKED 0 | SKIP 0
P0 61/61 · P1 21/21 · P2 1/1
既有回归: tests/full_autotest.py --level full -> 248 PASS / 0 FAIL (570.3s)
Final status: READY FOR REVIEW Blockers: (无)
判定规则未放宽:任何 P0 FAIL/BLOCKED ⇒ 最终状态必须 BLOCKED;
SKIP 与 BLOCKED 不计入通过。最终 0 个 P0 FAIL / 0 个 P0 BLOCKED。
分类覆盖:A toolchain 9 · B routing 10 · C frame integrity 13 · D temporal 9 ·
E preservation 7 · F fallback 8 · G existing features 9 · H resume/retry 5 ·
I concurrency 5 · J production/long-run 6 · K golden baseline 2。
矩阵的自动化状态为 100% auto —— 没有"需要人工播放视频检查"的条目。
4. 路由契约
policy = off | auto | require 默认 off(= v0.6.2 行为,零变化)
eligible(backend, codec, chroma, depth) :=
在 runtime-proven allowlist 内
AND 不在 known_refusals 内
AND 请求未携带时间 seek
AND 该组合未被本运行 memo 标记为不可用
off -> reader = avsw (不出任何提示)
auto -> eligible ? avhw : avsw (降级必须出声:WARNING + reason code)
require -> eligible ? avhw : ERROR (绝不静默降级)
runtime-proven allowlist(初始内容,全部经 research + 本次 integration 实测):
| backend | codec | chroma | depth | 依据 |
|---|---|---|---|---|
| nvenc | hevc | 4:2:0 | 10 | N−3 → N(30/330/10170 帧),与 --avsw 字节相同 |
| nvenc | h264 | 4:2:2 | 10 | N−2 → N(195 帧),与 --avsw 字节相同 |
| qsv | hevc | 4:2:0 | 10 | N−3 → N,逐帧 SHA-256 与 --avsw 相同 |
known_refusals:qsv + h264 + 4:2:2 + 10bit
(avqsv: codec h264(yuv422p10le) unable to decode by qsv. rc=−31、无 reader、无输出)。
allowlist 之外一律 not_proven → 软解(8-bit / All-I / 1080p / AV1 / VFR /
HEVC 4:2:2 等均未纳入)。这是"不把未实测 profile 静默塞进硬件路径"的落实,不是遗漏。
5. 帧完整性闸门与 reason codes
失败动作:丢弃硬件产物 → 出声(WARNING + reason code)→ 同格式档软解重跑。
两级闸门分别对应两类缺陷:
count级:工具 rc == 0 且产物非空;reader 身份断言(请求avhw
却构造出avsw即 silent software fallback,判 FAIL);五方对账
container_expected为参考真值,encoder_input/output_stream/
independent_decoded任一不等即 FAIL;reader 自报只记录、永不作参考。sequence级(--hw-decode-verifyopt-in):硬解与软解结果逐帧有序
fingerprint 比对,抓计数不变的错序/替换/重复。
Reason codes(互不相同、可审计):
policy_off · proven_combination · not_proven · capability_refused ·
reader_unavailable · device_unavailable · startup_failed ·
decode_failed · count_mismatch · sequence_mismatch ·
seek_not_equivalent · require_unmet · integrity_ok
端到端实测(真实 CLI,节选):
[HWDEC] decode tool: ...\tools\avhw\NVEncC_9.31_avhw\NVEncC64.exe
(patched build verified by sha256 dcf6d7a63143c777)
DECODE_ROUTE | backend=nvenc codec=hevc 4:2:0/10bit policy=auto -> HARDWARE
(reader=avhw, reason=proven_combination)
INTEGRITY | integrity gate [OK] reason=integrity_ok
counts={tool_rc:0, reader_identity:'avcuvid', encoder_input:360,
container_expected:360, container_method:'isobmff-stsz', ...}
6. Validation
| 项 | 结果 |
|---|---|
| Integration test matrix | 83/83 PASS(P0 61/61 · P1 21/21 · P2 1/1;0 FAIL / 0 BLOCKED / 0 SKIP,累计约 3.3 h) |
| 既有全量回归 | tests/full_autotest.py --level full → 248 PASS / 0 FAIL(570.3 s) |
| Golden baseline(软件基线自洽性) | HD-K01 / HD-K02 PASS:6 条 fixture 的软件基线在独立重跑下逐字节重 derive |
| 真实语料 | Sony testsets/20260904/*.MP4 取样 10 短 / 10 中 / 10 长;DJI action4 4K + 语料内 DJI 片段 |
| 工具链身份 | 每次运行前校验 binary sha256 + 补丁 sha256 + --version 字段,不符即 FAIL(不是 warning) |
矩阵执行过程中抓到 3 个真实问题(1 个生产缺陷:_encoded_ok() 曾接受被截断的
intermediate;1 个研究线未记录的行为差异;1 个集成缺陷:find_hw_tool 目录 glob
可能按排序捞到 patched build),final regression 又打回本 session 自己引入的 3 个缺陷 ——
全部先定位根因再修被测对象或判定逻辑,并重跑同一测试确认。
7. 边界声明(引用本版结论时必须带上)
- QSVEncC 补丁: Runtime-proven on QSVEncC 8.26 pinned revision; not yet a
general claim for later releases.(8.27–8.30 存在且未检验) - NVEncC 补丁: 仅在 9.31(
2cb9d810c045202548b98ff130b12bc764eb39ea)上验证。 - research build 不可分发: 两个 patched binary 都是 research build
(avs/vpy reader 关闭、CUDA MSBuild shim、FFmpeg 动态链接、QSVEncC 的 OneVPL
单独构建)。release/build_release.py的TOOL_DIRS白名单不含tools/avhw/。
因此发布安装中--hw-decode auto会以not_proven降级软解、require会明确
失败 —— 这是设计行为,不是缺陷。 - 跨 binary 性能不可比: patched 与 stock 工具链不同(CUDA 13.1/MSVC 14.51 vs
CUDA 11.8/MSVC 14.44),跨 binary 只比正确性,不比性能。 - 矩阵通过 ≠ 全新声明: 通过范围是 Sony XAVC HS(HEVC Main10 4:2:0)、
Sony XAVC S(H.264 4:2:2 10-bit)、DJI(HEVC Main10 4:2:0),
以及 x265 / synthetic / MKV 控制组。 FramePosList::setPocAndFix: 独立 metadata-table 缺陷,本版未研究、未修复;
consumer 侧缓解措施是"永不把 reader 自报当成帧数"(已落实为设计)。
8. Known Limitations
| # | 限制 | 影响 |
|---|---|---|
| 1 | QSVEncC 版本边界(仅 pinned 8.26) | 8.27–8.30 未检验,不纳入通过范围 |
| 2 | research build 不可分发 | 发布包中不含 patched binary ⇒ 发布安装里 --hw-decode auto 降级软解 |
| 3 | allowlist 是封闭的 | 8-bit / All-I / 1080p / AV1 / VFR / HEVC 4:2:2 均 not_proven → 软解 |
| 4 | --seek 两 reader 不等价 |
已由路由守卫覆盖(production 不使用 seek) |
| 5 | --frames N 三段语义 |
是 reader 共有行为,与硬解无关 |
| 6 | 单 GPU 主机 | 多 GPU / --device 选择未验证 |
| 7 | --seek 差异机制未解释 |
不影响生产路径 |
| 8 | 4-way 4K 并发上限与机制 | 本版无吞吐判据(实测 118.61 fps 与 research 的 8.01 fps 规格不同,不可比) |
| 9 | 遥测完整性 | CPU time / GPU util / VRAM 采样;平台未报告时记 null |
| 10 | raw-pipe 架构未采用 | 按 research 建议,FFmpeg CPU raw-pipe 不作为 production primary architecture |
仍未完成,不得视为已解决:
- Audio Drift(P2 漂移分类 / resample)—— NOT STARTED
- patched hardware binary 仍为 research build,不可分发 ⇒ 发布形态下硬解不可用(§7)
- 是否把 hardware decode 设为默认 —— 未决定,需矩阵全绿 + production benchmark 之后另行决策;
本版未改变默认值(仍off) - 其余 P2 follow-ups:
--seek机制解释、QSVEncC 8.27–8.30 复验、pipeline patch 反馈上游、
多 GPU 验证、allowlist 扩展(8-bit / 1080p / VFR)、--hw-decode-verify作为常规开关的成本评估、
4-way 4K 并发上限机制、FramePosList::setPocAndFix上游报告
9. Backward Compatibility
VERSION/--version→1KeyTranscoder 0.7.0;- 档位 JSON 与命令行无破坏性变更;未传
--hw-decode时命令行逐 token 与
v0.6.2 相同,reader 恒为avsw; - 默认后端选择(能力优先 NVENC → QSV → x265)与
--no-hw-autoselect语义未变; - 新增开关仅两个:
--hw-decode {off,auto,require}(默认off)与--hw-decode-verify(opt-in); - 硬解失败不会改变输出格式档:回退是在同一格式档上用软解重跑。
10. Package
本版没有自包含发布包(no binary asset)。
| 项 | 值 |
|---|---|
| Archive | —(本版不提供) |
| 原因 1 | 本版 tag 位于 feature/hardware-decode-integration,而 release/build_release.py 的分支守卫要求 main |
| 原因 2 | 硬解所需 patched binary 是 research build,按设计不入包(§7) |
| 最后一个带自包含包的版本 | v0.6.1(1KeyTranscoder-v0.6.1-win64-selfcontained.zip) |
从源码使用:git checkout v0.7.0,需要 Python 3.11+,并按 README.md §依赖
准备 tools/(ffmpeg/ffprobe 9.0.1、NVEncC 9.31、QSVEncC 8.26、GPAC)。
11. 相关文档
hardware-decode/integration-test-matrix.md— 主交付物,83 条测试的完整定义与成功条件hardware-decode/final-report.md— 结构化最终报告(判定、逐条结果、三个真实发现、边界声明)hardware-decode/toolchain-provenance.json— binary / 补丁的权威身份design/architecture.md— 端到端管线(适用范围仍为 v0.6.2,硬解路径尚未并入该文档)
复现矩阵:
python -m tests.hwdecode.harness provenance # 工具链身份(不符 = FAIL)
python -m tests.hwdecode.harness check-matrix # 文档与 matrix.json 漂移检查
python -m tests.hwdecode.inventory # 生成 control fixtures + 语料盘点
python -m tests.hwdecode.harness run --phase 1 # ... 依次到 --phase 6
python -m tests.hwdecode.harness summary # 汇总闸门1KeyTranscoder v0.6.1
1KeyTranscoder v0.6.1
bugfix release(无功能新增、无破坏性变更)。基线
v0.6.0,上游分支main。
Highlights
- Channel Sync P1 ——
--channel-sync自动轨间延时补偿:GCC-PHAT 两阶段测量 → 相位斜率精估 → 轨道级质量门 → 纯整数样本移位 → 复检;锚点按CH3 > CH4 > CH1 > CH2回退;轨道级部分成功(坏轨原样保留,不拖累健康轨) - AV1 mainline —— SVT-AV1(软件)/ NVENC-AV1 / QSV-AV1 三后端与 HEVC/x265 同处
main,共用一个入口与一套 Sony/DJI 元数据保留管线 - AV1 + channel-sync —— AV1 后端与
--channel-sync/--channel-sync-transparent组合路径已验证 - AV1 color metadata fidelity —— 源素材未声明色彩描述时,AV1 输出不再凭空带上 bt709
- Streaming memory fix(本版核心修复) ——
--channel-sync长素材内存无上限增长已修复 - Transparent / Sony / DJI preservation ——
--channel-sync-transparent剪辑前预处理;Sony XAVC(rtmd/nrtm/uuid)与 DJI(djmd/dbgi/tmcd)元数据原生保留
Fixed — --channel-sync 长素材内存无上限增长
10 分钟 / 4 轨 / 48 kHz 素材上峰值 RSS 曾达 605–713 MB 且随时长线性增长(每分钟 +50~137 MB)。
根因:np.memmap 并不等于低内存 —— 映射本身几乎不占内存(增量 +0.0 MB),但每个被触碰的 file-backed 页都计入进程 WorkingSet 并长期保留,而实现确实顺序触碰了每条轨的每一个字节:_track_health() 分块扫描整轨算 RMS → 每轨恰好 +110 MB(4 轨 +440 MB);shift_stream() 用 np.memmap(mode="w+") 写整轨 → 输出脏页常驻。阶段探针实测 719.0 MB 峰值中约 61% 来自整轨映射页驻留。
修复:新增 RawStream 有界窗口读取器(seek+read,1 MiB 对齐块 + 4 槽 LRU,每流约 4 MiB)取代整文件映射;shift_stream() 输出改普通文件句柄;estimate_pair() / recheck_residual() 拆为「所有权包装 + 纯计算」。
算法语义未变:块寻址落在与 memmap 相同的文件偏移,dtype 映射、f32→f64 转换点与 RMS 平方和归约顺序均未变;GCC-PHAT 数学、delay 方向、搜索窗、置信度/aligned/drift_min_ms 阈值、锚点优先级、low_confidence/insufficient_frames 判定与报告字段一行未改;未引入 resample / time-warp / fractional sinc / 新依赖。
Performance(本次实测)
规格: 600 s / 4 audio tracks / 48 kHz / --channel-sync / 单线程 (--jobs 1)
输入: LONG-CS-AUDIO.mp4 (600.02 s, 4× pcm_s24be 单声道, 真实 A7M5 素材流拷贝拼接)
Peak RSS: 153-288 MB (目标 <= 512 MB) PASS
Runtime: 45.3-52.7 s (目标 < 60 s) PASS
同步正确性:status=applied / scope=partial / 锚点 CH3;CH1 shift_samples=1051(= 冻结标定值 +21.8958 ms @48 kHz);复检残差 +0.0180 ms(≤0.05 ms 门限);CH2 复检超差 → 安全 untouched 未误修;4 条音轨完整、输出可解码。
时长扫描(v0.6.0 → v0.6.1):60 s 151.6→208.1、150 s 356.7→228.8、300 s 468.3→208.5、450 s 579.7→264.6、600 s 605.4→209.3 MB —— RSS 不再随时长增长。
Validation
| 项 | 结果 |
|---|---|
| 137 段真实 A7M5 baseline | 已对齐 111 / 实际修正 11 / 测量失败 15 完全复现;逐文件报告 JSON 137/137 字节相同 |
| Full short regression | --level full → 228 PASS / 0 FAIL(573 s) |
| Package integrity | 54/54 PASS(SHA256 / sidecar / manifest 对账 / ZIP CRC / 455 文件逐文件 hash / 无开发残留) |
| Clean-room cold-start | 77/77 PASS(版本 1KeyTranscoder 0.6.1;x265 / SVT-AV1 / QSV-AV1 / NVENC-AV1 / channel-sync / transparent / Sony preservation / AV1+channel-sync,全部 rc=0、可解码、音轨 4/4) |
| 600 s channel-sync benchmark | 20/20 PASS(RSS 288.3 MB / 46.4 s) |
Package
| 项 | 值 |
|---|---|
| Archive | 1KeyTranscoder-v0.6.1-win64-selfcontained.zip |
| Size | 575,571,948 B (548.9 MiB) |
| SHA256 | 1c3685cf7e23ea9e227d5f42b36ce1978fa4c68206c84e348882153f09b39d31 |
| 内置运行时 | ffmpeg/ffprobe 9.0.1(libsvtav1 v4.2.0 / libx265 / libvmaf)、NVEncC 9.31、QSVEncC 8.26、GPAC 26.02 |
| 不含 | .git/、work/、testsets/、docs/、logs/、dist/、release/、__pycache__/ |
需要 Python 3.11+ 与对应 GPU 驱动;解压即用。校验:
certutil -hashfile <zip> SHA256 或对照 .sha256 附件。
Known Limitations
- SVT-AV1 无场景关键帧(
scd只管码率分配)、mbr 为软上限(非 VBV 硬钳) - AV1 仅 MP4 容器,统一 4:2:0 输出
--channel-sync只做整数样本移位:无 resample、无 fractional sinc、无 time-warp;真实慢漂移(39–76 ppm)判non_constant并拒绝修正--channel-sync仅支持 48 / 96 kHz 线性 PCM、≥3 条独立单声道轨--channel-sync长程性能仅在 4 轨 / 48 kHz / 单线程规格下实测--channel-sync-transparent成功路径保留.1ktwork/(4×audio_*.mov+ 报告 JSON,10 分钟约 330 MB),属既有行为
仍未完成,不得视为已解决:Sony 10 分钟长程验证 · DJI 10 分钟长程验证 · --jobs auto 长程验证 · --experimental-multihw 长程验证 · P2 漂移分类与 resample(NOT STARTED)。
Compatibility
档位 JSON 与命令行无破坏性变更;--channel-sync 的阈值、默认值、报告字段与 JSON 结构完全不变;--channel-sync 关闭时输出与 v0.6.0 行为一致。
完整发布说明见仓库 docs/release_notes_v0.6.1.md。
1KeyTranscoder v0.5.1 (av1 · 软件+硬件 AV1)
1KeyTranscoder v0.5.1 — av1 分支 (软件 + 硬件 AV1)
自包含 win64 包: 项目代码 + ffmpeg/ffprobe 9.0.1 (libsvtav1 v4.2.0/libx265/libvmaf) + NVEncC 9.31 + QSVEncC 8.26 + GPAC 26.02。
本次增量 (相对 v0.5.0):
- full 检查新增 PSNR/SSIM 质量抽样 (同 main 线 v0.4.2)
- 环境版本记录 logs/env_versions.json/.csv (含 SVT-AV1 库版本实测)
- 档位重排 (用户判定标准: 每档质量≥x265 同档且码流更低则不动): UHQ preset 1 (1.07fps 对齐 x265 UHQ) / HQ crf 26 / SMALL crf 30 (双素材质量更高+码流更低) / FAST crf 30; 详见 docs/evaluation/av1_calibration.md §5
- Sony/DJI AV1 保留管线 (rtmd/nrtm/uuid/djmd 保真, 不打 XAVC tag, brand av01)
- 历史档案归档至 olddocs/
- 自动化测试 143/143 × 2 轮
用法见包内 RELEASE_NOTES.txt。Gyroflow (可选) 请从 gyroflow.xyz 单独安装。
第三方组件版权归各项目所有 (许可文本随包保留)。
1KeyTranscoder v0.4.2 (main · HEVC/265)
1KeyTranscoder v0.4.2 — main 分支 (HEVC/265 线)
自包含 win64 包: 项目代码 + ffmpeg/ffprobe 9.0.1 (libx265/libvmaf) + NVEncC 9.31 + QSVEncC 8.26 + GPAC 26.02。
本次增量 (相对 v0.4.1):
- full 检查新增 PSNR/SSIM 质量抽样: sha256 确定性 10 取 1、仅 ≤60s 短视频、setpts=N 帧索引对齐、防花屏阈值 (psnr 25dB/ssim 0.80/垃圾帧≤2%),Sony/DJI/经典三路径 (经典路径交付前拦截); 阈值经各档位 JSON quality_check 节可调
- 环境版本记录: 每批次 logs/env_versions.json/.csv (ffmpeg/NVEncC/QSVEncC/GPAC/Gyroflow + GPU 驱动)
- 历史档案归档至 olddocs/ (backup/、x265_archive.py、sony_poc.py)
- 自动化测试 109/109 × 2 轮
用法见包内 RELEASE_NOTES.txt。Gyroflow (可选, --check advanced/full 消费端校验) 请从 gyroflow.xyz 单独安装。
第三方组件版权归各项目所有 (许可文本随包保留)。
1KeyTranscoder v0.3.0-beta
1KeyTranscoder v0.3.0-beta
First beta release of the integrated 1KeyTranscoder pipeline.
Changes
1keytransc.pyis now the single main entry point.- Integrated GPAC-based container reconstruction.
- Integrated Sony metadata preservation.
- Preserves Sony RTMD timed metadata tracks.
- Preserves Sony NRTM metadata and Lens Profile when present.
- Preserves NonRealTimeMeta XML.
- Preserves Sony PROF, USMT, and other vendor-specific UUID structures.
- Preserves Sony metadata track relationships such as
tref/cdsc. - Uses GPAC-native timeline reconstruction in the normal pipeline.
- Added source-aware x265 pixel-format handling.
- Audio is preserved by stream copy.
- Original basenames are retained.
- Output extension is standardized to
.MP4. - Gyroflow validation passed on Sony A7M5 and A7M4 real-world test outputs.
Validated Sources
Sony A7M5
- 4K 59.94p
- 10-bit 4:2:0 HEVC
- Sony RTMD metadata
- Lens / stabilization metadata
- 4-track mono PCM audio
Sony A7M4
- 4K 29.97p
- 10-bit 4:2:2 H.264 source
- HEVC Rext output
- Sony RTMD metadata
- Sony vendor UUID structures
Current Scope
This beta primarily targets Sony camera footage and the current x265 workflow.
DJI Action 4 support and NVENC integration are planned next.
Known Limitations
- Sony Catalyst compatibility has not been independently validated.
- Audio is currently copy-only.
- Unsupported audio/container combinations fail explicitly instead of being automatically re-encoded.
- DJI metadata preservation is not yet implemented.
- Additional camera-specific metadata backends are not yet implemented.