mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-23 05:41:20 -08:00
fix(jassub): [PKG-JASSUB-09] checkpoint hybrid canvas ownership and frame completion
This commit is contained in:
1 parent
b4b0276fe9
commit
7f185f698d
22 files changed
+18866
-37
No files matched your search
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"task": "PKG-JASSUB-09",
|
||||
"baselineCommit": "b4b0276fe9df13218ece21c3ba6a51b42948e16d",
|
||||
"file": "packages/artplayer-plugin-jassub/src/jassub.es.js",
|
||||
"originalSha256LF": "6a96af7914f702eb7d6303b466cbe16abddd278040f60cd29f153cdf60e92cb2",
|
||||
"patchedSha256LF": "60590f2fca6ffded74f96f8a6001a86c32eb38f5e1fae26338cbbb43e93fb70a",
|
||||
"patchFile": "refactor/baselines/jassub-hybrid.patch",
|
||||
"patchSha256LF": "e1ff5591ea38fc66b46140458db93156c66aaaeceacb5ea433021cd8868651eb",
|
||||
"predecessor": "refactor/baselines/jassub-offscreen-patch.json",
|
||||
"purpose": "Release obsolete hybrid bitmaps before any render/scheduler/color-space effect while the display is offscreen; prevent public track calls from recreating canvas after hybrid destruction."
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,27 @@
|
||||
diff --git a/packages/artplayer-plugin-jassub/src/jassub.es.js b/packages/artplayer-plugin-jassub/src/jassub.es.js
|
||||
index 6bd2bc2c6..88088b0ca 100644
|
||||
--- a/packages/artplayer-plugin-jassub/src/jassub.es.js
|
||||
+++ b/packages/artplayer-plugin-jassub/src/jassub.es.js
|
||||
@@ -527,9 +527,9 @@ class o extends EventTarget {
|
||||
}
|
||||
// if the video or track changed, we need to re-attach the offscreen canvas
|
||||
_reAttachOffscreen() {
|
||||
- if (!this._offscreenRender || !this._ctx)
|
||||
+ if (this._destroyed || !this._offscreenRender || !this._ctx)
|
||||
return null;
|
||||
- this._canvas.remove(), this._createCanvas(), this._canvasctrl = this._canvas.transferControlToOffscreen(), this._ctx = !1, this.sendMessage("offscreenCanvas", null, [this._canvasctrl]), this.resize(0, 0, 0, 0, !0);
|
||||
+ this._canvas.remove(), this._createCanvas(), this._canvasctrl = this._canvas.transferControlToOffscreen(), this._ctx = !1, this.busy = !1, this._lastDemandTime = null, this.sendMessage("offscreenCanvas", null, [this._canvasctrl]), this.resize(0, 0, 0, 0, !0);
|
||||
}
|
||||
_updateColorSpace() {
|
||||
if (this._destroyed || this._colorCallback != null) return;
|
||||
@@ -559,6 +559,10 @@ class o extends EventTarget {
|
||||
!e || !t || e !== t && (this._detachOffscreen(), this._ctx.filter = `url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='f'><feColorMatrix type='matrix' values='${f[e][t]} 0 0 0 0 0 1 0'/></filter></svg>#f")`);
|
||||
}
|
||||
_render({ images: e, asyncRender: t, times: s, width: r, height: n, colorSpace: a }) {
|
||||
+ if (!this._ctx) {
|
||||
+ for (const image of e) image.image?.close?.();
|
||||
+ return;
|
||||
+ }
|
||||
this._unbusy(), this.debug && (s.IPCTime = Date.now() - s.JSRenderTime), (this._canvasctrl.width !== r || this._canvasctrl.height !== n) && (this._canvasctrl.width = r, this._canvasctrl.height = n, this._verifyColorSpace({ subtitleColorSpace: a })), this._ctx.clearRect(0, 0, this._canvasctrl.width, this._canvasctrl.height);
|
||||
for (const i of e)
|
||||
i.image && (t ? (this._ctx.drawImage(i.image, i.x, i.y), i.image.close()) : (this._bufferCanvas.width = i.w, this._bufferCanvas.height = i.h, this._bufferCtx.putImageData(new ImageData(this._fixAlpha(new Uint8ClampedArray(i.image)), i.w, i.h), 0, 0), this._ctx.drawImage(this._bufferCanvas, i.x, i.y)));
|
||||
@@ -0,0 +1,87 @@
|
||||
# PKG-JASSUB-09 混合绘制的画布与等待状态归属
|
||||
|
||||
状态:doing 检查点。hybrid 修复已有受控及原生证据;Firefox 默认模式的继承
|
||||
回归缺口仍需处理,因此此提交不把 09 或 05 标为完成。
|
||||
|
||||
## 复现与修复
|
||||
|
||||
在 05 补全字幕切换验收时,从 `b4b0276fe9df13218ece21c3ba6a51b42948e16d`
|
||||
发现两类相连的生命周期缺陷。ASS 色彩矩阵和视频不一致时,JASSUB 会从纯
|
||||
offscreen 转为 hybrid:Worker 返回 ImageBitmap,主线程用 canvas filter 修正
|
||||
颜色。公开 setTrack/setTrackByUrl 随后重新转移画布。如果旧 hybrid 帧已经到达
|
||||
消息队列,它会对 `_ctx=false` 执行绘制,或者在尺寸不同时借旧色彩信息重新创建
|
||||
主线程画布,破坏刚完成的转移。销毁 hybrid 实例后调用上述方法也会创建新画布。
|
||||
|
||||
修复保留 API-04/05/08/12 的公开工厂、方法返回、选项、资源和 Worker 协议:
|
||||
|
||||
- 当前画布由 offscreen 所有时,旧 hybrid render 先关闭其 bitmap,立即返回,
|
||||
不改 busy、不做色彩转换、不创建/绘制新画布。正常 hybrid 帧继续绘制和关闭。
|
||||
- reattach 先退休旧模式的 busy/待处理时间,再对新画布请求强制绘制。否则丢弃
|
||||
的旧 render 同时也是等待中的完成通知,后续 RVFC 只积累待处理时间,字幕会
|
||||
持续空白。新的强制绘制及其 unbusy 通知恢复当前帧处理。
|
||||
- reattach 遇到已销毁实例直接返回,两个公开切字幕方法不能重新创建或转移画布。
|
||||
|
||||
没有修改 Worker JS、WASM、字体、公共声明、版本或依赖。原 07/08 补丁保留,
|
||||
新增[补丁记录](../baselines/jassub-hybrid-patch.json)和
|
||||
[独立 diff](../baselines/jassub-hybrid.patch)。来源测试按三段实际 Git 基线验证
|
||||
原文件、修改后文件和 diff 身份,再反向检查最后一个补丁;不是覆盖旧指纹。
|
||||
包内 ARCHITECTURE.md 同步了旧等待退休、强制新绘制、bitmap 和终态归属。
|
||||
|
||||
## 测试设计与中间失败
|
||||
|
||||
新增五项受控边界,和原 offscreen 六项一起,冻结 08 产物为 7 通过/4 失败,
|
||||
最终候选 11 通过。它们分别保护迟到帧不解除新需求、正常帧实际绘制和释放、
|
||||
切换时强制重绘,以及两个终态公开方法。没有把五项全部声称为旧版失败。
|
||||
|
||||
真实浏览器用不同 YCbCr Matrix 的 ASS 触发实际 WASM 色彩响应。Chromium 的
|
||||
VideoFrame 对本视频返回 bt709,因此可自然进入 hybrid。测试截留一条已经从
|
||||
原生 Worker 收到的 ImageBitmap 消息,在同步 setTrack 完成 reattach 后交付,
|
||||
验证新 canvas 身份不变、bitmap width 归零,以及后续字幕像素和终态调用。
|
||||
这是受控消息时序下的真实资源验证,不是未经拦截的全部生产时序或 GPU 耐久证明。
|
||||
|
||||
第一次只检查迟到消息是否抛错是不充分的:旧代码通过色彩修正重新创建画布,
|
||||
可能不抛错。测试补上 canvas 身份和模式断言,旧 Chromium 明确失败。
|
||||
第一次只丢弃旧 bitmap 的候选又出现持续空白,原生 sent 序列停在重连 canvas,
|
||||
推动补上旧 busy/需求退休及 force=true 回归。两次失败都保留。
|
||||
|
||||
Firefox 155.0 对本样本的 VideoFrame matrix 返回 null;WebKit 26.6 没有转移
|
||||
能力。它们仍执行真实字幕切换、像素变化和清理,但不能计入 hybrid 位图交错覆盖。
|
||||
测试按真实能力走明确分支,没有 mock 出色彩矩阵或调用内部方法伪造原生转换。
|
||||
受控测试才直接调用内部模式方法,负责确定性的状态机边界。
|
||||
|
||||
另有一轮 Firefox 在首次像素/网页全屏时超时:该轮同时运行安装类型检查。
|
||||
失败中默认模式的 Worker received 没有 render,只有 unbusy;该页面也未调用
|
||||
track 重新挂载,因此本补丁两个新分支并未在这条失败路径执行。去掉同时运行的
|
||||
重负载检查后,候选 11 通过/1 失败,仍复现 published 核心的全屏超时。
|
||||
08 产物单独播放三项通过,但先执行字幕切换再播放的顺序对照为 2 通过/2 失败,
|
||||
也在两个旧核心复现。说明不能仅归因于本次补丁或 CPU 并发;真正原因未确定。
|
||||
额外的 JASSUB-FIREFOX-OFFSCREEN-01 保持 open,不把重跑成功当作修复依据。
|
||||
|
||||
## 验证、复跑与剩余范围
|
||||
|
||||
最终命令、计数、候选指纹、安装成员和红绿浏览器结果见
|
||||
[验证记录](../baselines/jassub-hybrid-validation.json)。联合检查含旧行为基线,
|
||||
不是全部新功能测试。联合 196 项、源码/main/legacy 各 79 项、实际安装 15 个
|
||||
类型矩阵通过;legacy 切换三项和显式主线程九项原生验证通过。默认 main 最终
|
||||
顺序验证仍是 11 通过/1 失败,不能汇总成全绿。正常 main/legacy/ESM 均由仓库 build 生成并与 docs 副本
|
||||
核对。安装验证在最终包文档和源码构建后重新运行;首次 pack 属中间候选。
|
||||
|
||||
```sh
|
||||
yarn test:jassub
|
||||
yarn test:jassub-types-package
|
||||
yarn build artplayer-plugin-jassub
|
||||
node --test test/jassub-offscreen.test.js
|
||||
node --test refactor/scripts/jassub-vendor-patch.test.mjs
|
||||
yarn test:browser test/browser/jassub-hybrid.spec.js --workers=1
|
||||
```
|
||||
|
||||
设置 ARTPLAYER_JASSUB_ARTIFACT 选择正常 main/legacy;默认播放回归另设置
|
||||
ARTPLAYER_JASSUB_OFFSCREEN=default 并执行 jassub-native.spec.js。不设置后者
|
||||
验证显式主线程路径。归档共享浏览器报告后才开始下一轮;排查媒体等待问题时
|
||||
避免同时运行其他重负载任务,并保留对照范围及原始失败。
|
||||
|
||||
本检查点记录已实现的 hybrid 归属修复,但任务和风险验收仍未关闭。05 继续完整字幕/核心组合、Firefox
|
||||
稳定性、设备和持续 GPU/内存验证;06 与 VENDOR-04/05 保留分发/通知要求。
|
||||
没有声明完整 JASSUB 验收、major 升级、CI/CD 远程运行、三轮复盘或发布已完成。
|
||||
不 push/tag/publish。回退本 commit 并正常构建可恢复 08;不要对运行中 Worker
|
||||
热替换协议或只回退来源指纹而保留不一致的 wrapper。
|
||||
+6
-4
@@ -2,9 +2,9 @@
|
||||
|
||||
> 由 tasks.json 生成。请修改数据后运行 `node refactor/scripts/plan.mjs --write`,不要手改本表。
|
||||
|
||||
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 233 项,范围 22 个包及工作区/示例。
|
||||
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 234 项,范围 22 个包及工作区/示例。
|
||||
|
||||
状态:todo 62 / doing 14 / blocked 0 / done 157 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
|
||||
状态:todo 62 / doing 15 / blocked 0 / done 157 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
|
||||
|
||||
前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
| artplayer-plugin-dash-control | 1.1.0 | PKG-DASH-01, PKG-DASH-02, PKG-DASH-03, PKG-DASH-04, PKG-DASH-05, PKG-DASH-06 |
|
||||
| artplayer-plugin-document-pip | 1.1.0 | PKG-DPIP-01, PKG-DPIP-02, PKG-DPIP-03, PKG-DPIP-04, PKG-DPIP-05, PKG-DPIP-06 |
|
||||
| artplayer-plugin-hls-control | 1.1.0 | PKG-HLS-01, PKG-HLS-02, PKG-HLS-03, PKG-HLS-04, PKG-HLS-SDK-01, PKG-HLS-05, PKG-HLS-06 |
|
||||
| artplayer-plugin-jassub | 1.1.0 | PKG-JASSUB-01, PKG-JASSUB-02, PKG-JASSUB-03, PKG-JASSUB-04, PKG-JASSUB-05, PKG-JASSUB-06, PKG-JASSUB-07, PKG-JASSUB-08 |
|
||||
| artplayer-plugin-jassub | 1.1.0 | PKG-JASSUB-01, PKG-JASSUB-02, PKG-JASSUB-03, PKG-JASSUB-04, PKG-JASSUB-05, PKG-JASSUB-06, PKG-JASSUB-07, PKG-JASSUB-08, PKG-JASSUB-09 |
|
||||
| artplayer-plugin-multiple-subtitles | 1.2.0 | PKG-MULTI-SUB-01, PKG-MULTI-SUB-02, PKG-MULTI-SUB-03, PKG-MULTI-SUB-04, PKG-MULTI-SUB-07, PKG-MULTI-SUB-05, PKG-MULTI-SUB-06 |
|
||||
| artplayer-plugin-vast | 1.2.0 | PKG-VAST-01, PKG-VAST-02, PKG-VAST-03, PKG-VAST-04, PKG-VAST-05, PKG-VAST-06 |
|
||||
| artplayer-plugin-vtt-thumbnail | 1.1.0 | PKG-VTT-THUMB-01, PKG-VTT-THUMB-02, PKG-VTT-THUMB-03, PKG-VTT-THUMB-04, PKG-VTT-THUMB-05, PKG-VTT-THUMB-06 |
|
||||
@@ -233,10 +233,11 @@
|
||||
| PKG-JASSUB-02 | artplayer-plugin-jassub<br>建立特有行为与错误测试 | PKG-JASSUB-01, ENG-03, ENG-05 | ASS 字体、时钟/seek/倍率/resize、加载失败和销毁 | 旧版本行为可重跑,成功/失败/切源/销毁有必要断言 | H | done |
|
||||
| PKG-JASSUB-03 | artplayer-plugin-jassub<br>整理内部职责与资源 | PKG-JASSUB-02, CORE-15, CORE-16 | 仅整理自有 adapter/销毁;保留第三方文件及来源 | 结构变化和缺陷修复分开记录;原 API/事件/资源生命周期通过 | H | done |
|
||||
| PKG-JASSUB-04 | artplayer-plugin-jassub<br>迁移自有源码和公开类型 | PKG-JASSUB-03, ENG-04, ENG-06, CORE-07 | JASSUB option/instance 的兼容类型包装,vendor JS 例外记录 | 严格类型检查、旧消费样例通过;声明路径/导出和同步异步兼容 | H | done |
|
||||
| PKG-JASSUB-05 | artplayer-plugin-jassub<br>验证新旧核心和组合 | PKG-JASSUB-04, CORE-22, PKG-JASSUB-07, PKG-JASSUB-08 | 真实 worker/WASM 字幕渲染与全屏、旧核心测试 | 最终核心与原支持范围核心分别通过;设备/SDK 缺证据不能标完成 | H | todo |
|
||||
| PKG-JASSUB-05 | artplayer-plugin-jassub<br>验证新旧核心和组合 | PKG-JASSUB-04, CORE-22, PKG-JASSUB-07, PKG-JASSUB-08, PKG-JASSUB-09 | 真实 worker/WASM 字幕渲染与全屏、旧核心测试 | 最终核心与原支持范围核心分别通过;设备/SDK 缺证据不能标完成 | H | todo |
|
||||
| PKG-JASSUB-06 | artplayer-plugin-jassub<br>验证分发并同步文档 | PKG-JASSUB-05, ENG-07 | jassub.js、外部资源路径、许可和离线失败记录;接续 VENDOR-04/05 完整组件/字体通知、LGPL 源码分发核对及六份未明确字体的分发处置 | tarball 入口/资源、类型、8082 demo 和 README 一致,有回退记录;来源身份已由01冻结,完整通知和未明确字体的发布处理必须闭环,不能以来源相同替代许可结论 | H | todo |
|
||||
| PKG-JASSUB-07 | artplayer-plugin-jassub<br>修复 vendor 生命周期与字幕时钟 | PKG-JASSUB-03, PKG-JASSUB-02 | 独立记录 vendor 适配差异;幂等销毁、跨容器 setVideo、构造回滚、逐帧归属和倍率/能力边界;查询 timeout/Worker error 的缺失数据回调及每请求监听器/定时器清理(JASSUB-QUERY-01) | 保持公开真实 instance、同步方法与资源路径;保留原 vendor 来源指纹并记录每项实际补丁;候选修复正例和真实字幕/失败/时钟验证通过,未证实设备不得冒充通过 | H | done |
|
||||
| PKG-JASSUB-08 | artplayer-plugin-jassub<br>修复默认 offscreen 初始化消息顺序 | PKG-JASSUB-07 | 在释放排队绘制消息前转移初始画布;独立 vendor 补丁、默认模式原生回归和维护文档 | 保留默认能力选择、Worker/资源和公开同步 API;旧红新绿消息顺序测试及真实默认 offscreen 播放/seek/全屏通过,主线程绘制保持 | H | done |
|
||||
| PKG-JASSUB-09 | artplayer-plugin-jassub<br>修复 hybrid 迟到绘制与销毁后画布重建 | PKG-JASSUB-08 | 释放旧混合绘制 bitmap,不改变新模式的画布/时钟;销毁后切字幕不重新分配画布;来源补丁、原生排队消息及维护记录 | 旧红新绿验证旧帧不能重建画布/解除新绘制等待;正常 hybrid 绘制保持;真实 Worker/ImageBitmap 交错、主线程及默认模式回归通过,能力缺口明确 | H | doing |
|
||||
|
||||
## 5 包迁移:artplayer-plugin-danmuku-mask
|
||||
|
||||
@@ -604,3 +605,4 @@
|
||||
- PKG-DANMUKU-11: [记录](changes/2026-09-13-PKG-DANMUKU-11-visible-lifetime.md) [记录](baselines/danmuku-lifetime-validation.json)
|
||||
- PKG-DANMUKU-12: [记录](changes/2026-09-13-PKG-DANMUKU-12-frame-sampling.md) [记录](baselines/danmuku-frame-sampling-validation.json)
|
||||
- PKG-JASSUB-08: [记录](changes/2026-09-14-PKG-JASSUB-08-offscreen.md) [记录](baselines/jassub-offscreen-validation.json) [记录](baselines/jassub-offscreen-patch.json)
|
||||
- PKG-JASSUB-09: [记录](changes/2026-09-14-PKG-JASSUB-09-hybrid.md) [记录](baselines/jassub-hybrid-validation.json) [记录](baselines/jassub-hybrid-patch.json)
|
||||
@@ -1,5 +1,18 @@
|
||||
# 进度与证据
|
||||
|
||||
## PKG-JASSUB-09 hybrid 归属修复检查点(doing)
|
||||
|
||||
修复旧混合帧干扰新 offscreen 画布、被丢弃完成通知导致等待卡死,以及销毁后
|
||||
两个切字幕方法重新分配画布。受控 11 项旧产物 7 通过/4 失败,候选全部通过;
|
||||
联合 196 项、源码/main/legacy 各 79 项和 15 个实际安装类型组合通过。
|
||||
Chromium 实际 Worker/ImageBitmap 跨公开切字幕交错通过,legacy 切换三项和主线程
|
||||
九项通过;Firefox matrix=null、WebKit 无转移能力均只算普通切换控制。
|
||||
默认 main 最终顺序回归 11 通过/1 Firefox 全屏失败,08 产物同顺序也复现旧核心
|
||||
失败;不能归因于并发负载,根因仍待查。09/05 及相关风险不标完成。
|
||||
[检查点记录](changes/2026-09-14-PKG-JASSUB-09-hybrid.md)和
|
||||
[完整红绿证据](baselines/jassub-hybrid-validation.json)保留中间不完整修复和对照。
|
||||
下一步处理 JASSUB-FIREFOX-OFFSCREEN-01,再继续完整分包验收和未完成迁移。
|
||||
|
||||
## PKG-JASSUB-08 默认 offscreen 初始化完成
|
||||
|
||||
05 默认模式验收发现 Chromium/Firefox 六项真实页面错误;初始 canvas 消息先于
|
||||
|
||||
@@ -250,3 +250,5 @@
|
||||
| JASSUB-NATIVE-FRAME-01 | resolved / 已复现 | Windows WebKit default frame-clock path does not produce subtitle demands in actual playback | PKG-JASSUB-02, PKG-JASSUB-07, PKG-JASSUB-05 |
|
||||
| JASSUB-QUERY-01 | resolved / 已复现 | Subtitle query errors throw before calling the consumer and leave request listeners attached | PKG-JASSUB-07, PKG-JASSUB-05 |
|
||||
| JASSUB-OFFSCREEN-01 | resolved / 已复现 | Default offscreen initialization lets queued resize render before Worker canvas ownership, raising clearRect on false context | PKG-JASSUB-08, PKG-JASSUB-05 |
|
||||
| JASSUB-HYBRID-01 | open / 已复现 | Late hybrid frames mutate the new offscreen canvas or throw; terminal track calls recreate transferred canvases | PKG-JASSUB-09, PKG-JASSUB-05 |
|
||||
| JASSUB-FIREFOX-OFFSCREEN-01 | open / 已复现 | Windows Firefox default offscreen readback/playback can stall after a preceding subtitle-switch test and web fullscreen | PKG-JASSUB-09, PKG-JASSUB-05 |
|
||||
@@ -5621,6 +5621,40 @@
|
||||
"test/jassub-offscreen.test.js"
|
||||
],
|
||||
"resolutionRationale": "Controlled queue test reproduces pre-fix canvas-before-transfer order. Candidate transfers before opening readiness and passes actual default offscreen Chromium/Firefox playback/seek/layout; Windows WebKit default capability fallback and explicit main-thread/lifecycle regressions remain green. Full device/hybrid/error recovery remains task05."
|
||||
},
|
||||
{
|
||||
"id": "JASSUB-HYBRID-01",
|
||||
"title": "Late hybrid frames mutate the new offscreen canvas or throw; terminal track calls recreate transferred canvases",
|
||||
"confirmation": "reproduced",
|
||||
"status": "open",
|
||||
"owners": [
|
||||
"PKG-JASSUB-09",
|
||||
"PKG-JASSUB-05"
|
||||
],
|
||||
"evidence": [
|
||||
"test/jassub-offscreen.test.js",
|
||||
"test/browser/jassub-hybrid.spec.js"
|
||||
],
|
||||
"compatibleResolution": "Ignore obsolete hybrid render side effects while releasing their bitmaps, and preserve terminal canvas ownership in reattachment.",
|
||||
"closureCriteria": "Controlled and held-native-bitmap red/green cases preserve the newly reattached canvas and pending demand; terminal public track calls allocate nothing, normal hybrid and default/main-thread rendering remain valid. Native capability limitations are recorded."
|
||||
},
|
||||
{
|
||||
"id": "JASSUB-FIREFOX-OFFSCREEN-01",
|
||||
"title": "Windows Firefox default offscreen readback/playback can stall after a preceding subtitle-switch test and web fullscreen",
|
||||
"confirmation": "reproduced",
|
||||
"status": "open",
|
||||
"owners": [
|
||||
"PKG-JASSUB-09",
|
||||
"PKG-JASSUB-05"
|
||||
],
|
||||
"evidence": [
|
||||
"refactor/changes/2026-09-14-PKG-JASSUB-09-hybrid.md",
|
||||
"refactor/baselines/jassub-hybrid-validation.json",
|
||||
"test/browser/jassub-native.spec.js",
|
||||
"test/browser/jassub-hybrid.spec.js"
|
||||
],
|
||||
"compatibleResolution": "Isolate native media/compositor/readback and sequence effects without globally disabling default offscreen or deleting assertions. The pre-09 artifact also fails in the same sequence; do not claim the new hybrid guard caused or fixed this separate failure.",
|
||||
"closureCriteria": "Identify and verify a compatible fix or a reviewed precise platform boundary with native controls. Preserve known red sequence and successful standalone comparison; candidate playback/fullscreen pixels and lifetime must be justified, not merely rerun to green."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -6,23 +6,26 @@ import test from 'node:test'
|
||||
import { hash } from './releases.mjs'
|
||||
|
||||
test('JASSUB local vendor patch retains its exact original, changed source and reversible patch identity', () => {
|
||||
const record = JSON.parse(fs.readFileSync('refactor/baselines/jassub-vendor-patch.json', 'utf8'))
|
||||
const original = execFileSync('git', ['show', `${record.baselineCommit}:${record.file}`], { encoding: 'utf8' }).replaceAll('\r\n', '\n')
|
||||
const followUp = JSON.parse(fs.readFileSync('refactor/baselines/jassub-offscreen-patch.json', 'utf8'))
|
||||
const current = execFileSync('git', ['show', `${followUp.baselineCommit}:${record.file}`], { encoding: 'utf8' }).replaceAll('\r\n', '\n')
|
||||
const patch = fs.readFileSync(record.patchFile, 'utf8').replaceAll('\r\n', '\n')
|
||||
assert.equal(hash(original), record.originalSha256LF)
|
||||
assert.equal(hash(current), record.patchedSha256LF)
|
||||
assert.equal(hash(patch), record.patchSha256LF)
|
||||
assert.notEqual(record.originalSha256LF, record.patchedSha256LF)
|
||||
const committedPatch = execFileSync('git', ['diff', '--no-ext-diff', record.baselineCommit, followUp.baselineCommit, '--', record.file], { encoding: 'utf8' }).replaceAll('\r\n', '\n')
|
||||
assert.equal(hash(committedPatch), record.patchSha256LF)
|
||||
assert.equal(followUp.originalSha256LF, record.patchedSha256LF)
|
||||
assert.equal(hash(fs.readFileSync(record.file, 'utf8').replaceAll('\r\n', '\n')), followUp.patchedSha256LF)
|
||||
assert.equal(hash(fs.readFileSync(followUp.patchFile, 'utf8').replaceAll('\r\n', '\n')), followUp.patchSha256LF)
|
||||
execFileSync('git', ['apply', '--check', '--reverse', '--ignore-space-change', followUp.patchFile], { stdio: 'pipe' })
|
||||
const records = ['vendor', 'offscreen', 'hybrid'].map(name => JSON.parse(fs.readFileSync(`refactor/baselines/jassub-${name}-patch.json`, 'utf8')))
|
||||
for (const [index, record] of records.entries()) {
|
||||
const next = records[index + 1]
|
||||
const original = execFileSync('git', ['show', `${record.baselineCommit}:${record.file}`], { encoding: 'utf8' }).replaceAll('\r\n', '\n')
|
||||
const current = (next ? execFileSync('git', ['show', `${next.baselineCommit}:${record.file}`], { encoding: 'utf8' }) : fs.readFileSync(record.file, 'utf8')).replaceAll('\r\n', '\n')
|
||||
assert.equal(hash(original), record.originalSha256LF)
|
||||
assert.equal(hash(current), record.patchedSha256LF)
|
||||
assert.equal(hash(fs.readFileSync(record.patchFile, 'utf8').replaceAll('\r\n', '\n')), record.patchSha256LF)
|
||||
assert.notEqual(record.originalSha256LF, record.patchedSha256LF)
|
||||
if (next) {
|
||||
assert.equal(next.originalSha256LF, record.patchedSha256LF)
|
||||
const committedPatch = execFileSync('git', ['diff', '--no-ext-diff', record.baselineCommit, next.baselineCommit, '--', record.file], { encoding: 'utf8' }).replaceAll('\r\n', '\n')
|
||||
assert.equal(hash(committedPatch), record.patchSha256LF)
|
||||
}
|
||||
else {
|
||||
execFileSync('git', ['apply', '--check', '--reverse', '--ignore-space-change', record.patchFile], { stdio: 'pipe' })
|
||||
}
|
||||
}
|
||||
const registry = JSON.parse(fs.readFileSync('refactor/third-party.json', 'utf8'))
|
||||
const group = registry.vendored.find(item => item.id === 'jassub-code-and-workers')
|
||||
assert.equal(group.localPatch.originalSha256LF, record.originalSha256LF)
|
||||
assert.equal(group.fingerprints.find(item => item.path === record.file).sha256, followUp.patchedSha256LF)
|
||||
assert.equal(group.localPatch.originalSha256LF, records[0].originalSha256LF)
|
||||
assert.equal(group.fingerprints.find(item => item.path === records[0].file).sha256, records.at(-1).patchedSha256LF)
|
||||
})
|
||||
+22
-1
@@ -2497,7 +2497,8 @@
|
||||
"PKG-JASSUB-04",
|
||||
"CORE-22",
|
||||
"PKG-JASSUB-07",
|
||||
"PKG-JASSUB-08"
|
||||
"PKG-JASSUB-08",
|
||||
"PKG-JASSUB-09"
|
||||
],
|
||||
"status": "todo",
|
||||
"risk": "H",
|
||||
@@ -4790,6 +4791,26 @@
|
||||
"baselines/jassub-offscreen-validation.json",
|
||||
"baselines/jassub-offscreen-patch.json"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "PKG-JASSUB-09",
|
||||
"phase": "5 包迁移:artplayer-plugin-jassub",
|
||||
"title": "修复 hybrid 迟到绘制与销毁后画布重建",
|
||||
"scope": [
|
||||
"artplayer-plugin-jassub"
|
||||
],
|
||||
"dependsOn": [
|
||||
"PKG-JASSUB-08"
|
||||
],
|
||||
"status": "doing",
|
||||
"risk": "H",
|
||||
"deliverable": "释放旧混合绘制 bitmap,不改变新模式的画布/时钟;销毁后切字幕不重新分配画布;来源补丁、原生排队消息及维护记录",
|
||||
"acceptance": "旧红新绿验证旧帧不能重建画布/解除新绘制等待;正常 hybrid 绘制保持;真实 Worker/ImageBitmap 交错、主线程及默认模式回归通过,能力缺口明确",
|
||||
"evidence": [
|
||||
"changes/2026-09-14-PKG-JASSUB-09-hybrid.md",
|
||||
"baselines/jassub-hybrid-validation.json",
|
||||
"baselines/jassub-hybrid-patch.json"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -355,7 +355,8 @@
|
||||
"PKG-JASSUB-01",
|
||||
"PKG-JASSUB-06",
|
||||
"PKG-JASSUB-07",
|
||||
"PKG-JASSUB-08"
|
||||
"PKG-JASSUB-08",
|
||||
"PKG-JASSUB-09"
|
||||
],
|
||||
"sourceStatus": "Original wrapper matched npm 1.8.8; PKG-JASSUB-07 now carries an explicitly recorded local lifecycle/clock/query patch (baselines/jassub-vendor-patch.json). Worker JS is unchanged. Both WASM binaries still exactly match Pages nightly 747e392d7f6fe7c38bbcdfe05c9ada46b0b62daf/source 6b19a04ddfbad8f9bfd3237395788dd76218841b. Original wrapper hash, unchanged binaries/fonts, pinned build and submodules remain separately recorded; no independent WASM rebuild.",
|
||||
"licenseStatus": "Matching source LICENSE and nightly COPYRIGHT identified and byte-verified; full component notice assembly, LGPL source/distribution review and full FreeType license remain PKG-JASSUB-06 gates. VENDOR-04 remains open.",
|
||||
@@ -387,7 +388,7 @@
|
||||
{
|
||||
"path": "packages/artplayer-plugin-jassub/src/jassub.es.js",
|
||||
"algorithm": "sha256-lf",
|
||||
"sha256": "6a96af7914f702eb7d6303b466cbe16abddd278040f60cd29f153cdf60e92cb2"
|
||||
"sha256": "60590f2fca6ffded74f96f8a6001a86c32eb38f5e1fae26338cbbb43e93fb70a"
|
||||
},
|
||||
{
|
||||
"path": "packages/artplayer-plugin-jassub/worker/jassub-worker-modern.wasm",
|
||||
@@ -410,7 +411,11 @@
|
||||
"record": "refactor/baselines/jassub-vendor-patch.json",
|
||||
"originalSha256LF": "b973508ade00b5b9cea2f299d49f4943003372729be7350b6938e44fddb32038",
|
||||
"patchedSha256LF": "1fdcf24d206e8711348dddcb5fe7b656007a9b1d81a992bb497c6d10bd0a2cdb",
|
||||
"followUp": "refactor/baselines/jassub-offscreen-patch.json"
|
||||
"followUp": "refactor/baselines/jassub-offscreen-patch.json",
|
||||
"followUps": [
|
||||
"refactor/baselines/jassub-offscreen-patch.json",
|
||||
"refactor/baselines/jassub-hybrid-patch.json"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user