diff --git a/android/app/src/main/kotlin/com/mag160c/thermal/ui/live/LiveViewModel.kt b/android/app/src/main/kotlin/com/mag160c/thermal/ui/live/LiveViewModel.kt index 1deae86..b436439 100644 --- a/android/app/src/main/kotlin/com/mag160c/thermal/ui/live/LiveViewModel.kt +++ b/android/app/src/main/kotlin/com/mag160c/thermal/ui/live/LiveViewModel.kt @@ -279,10 +279,19 @@ class LiveViewModel(app: Application) : AndroidViewModel(app) { // user can add or remove probes while recording. rec.marks = probesAsMarks() if (rec.frameCount == 0) { - // evidence the recording really carries annotations: the first - // frame logs how many markers and which extremes were burned in + // Evidence the recording really carries annotations, and why the + // count is what it is: the first frame logs how many markers were + // burned in plus the inputs that decide it, so a video that is + // missing its max/min can be diagnosed from the log alone + // (trace mode set to 关闭, no extreme measured yet, probes cleared + // by a restart, ...). + val st = _state.value com.mag160c.thermal.media.DebugLog.log( - "rec", "annotation: ${rec.marks.size} markers burned into video frames", + "rec", + "annotation: ${rec.marks.size} markers burned into video frames " + + "(probes=${st.probes.size} trace=${st.traceMode} " + + "minPos=${st.minPos} maxPos=${st.maxPos} " + + "minC=${st.minTempC} maxC=${st.maxTempC})", ) } rec.offerFrame(bmp) diff --git a/build-artifacts/mag160c-app-debug.apk b/build-artifacts/mag160c-app-debug.apk index 91a8bdf..a4bff42 100644 --- a/build-artifacts/mag160c-app-debug.apk +++ b/build-artifacts/mag160c-app-debug.apk @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4ca5458de77631e86ec824b8050342d0a349a19657d7b4bc1a2219b26bfacdf4 +oid sha256:6f582585ff0275a63a3196a946b3f6f9de7262119d79714aae255553d0e3b461 size 12741424 diff --git a/docs/android_app/session_state.md b/docs/android_app/session_state.md index 83168de..53c8ce5 100644 --- a/docs/android_app/session_state.md +++ b/docs/android_app/session_state.md @@ -611,17 +611,29 @@ SDK 内部默认档——无法据此对齐具体档位,故本应用把它做 - **屏幕熄灭时的行为(实测)**:渲染线程随 SurfaceView 停止绘制(无空转), USB 读取继续,整机 CPU 占用 3.7%——后台不烧电、不崩溃。 -**本轮真机验证(小米 22041211AC / Android 12 / MIUI,无线 adb 192.168.88.137:44323)**: +**本轮真机验证(小米 22041211AC / Android 12 / MIUI)**: -- [x] 渲染帧率 6.5 → **15.1 帧/秒**,单帧 134ms → **6.4ms**(开增强 11.3ms) +- [x] 渲染帧率 6.5 → **15.1 帧/秒**,单帧 134ms → **6.4ms**(开增强 9~11ms) - [x] 拍照:`capture: nuc=yes probes=2 mirror(h=false,v=true) extremes=2 saved=true` -- [x] 照片上标记风格与实时界面一致(同一 MarkerPainter),`max 32.6℃` 在热区、 - `min 22.0℃` 在冷区、Pt1/Pt2 带白底标签,互不压字 +- [x] 照片上标记风格与实时界面一致(同一 MarkerPainter),`max` 在热区、 + `min` 在冷区(贴近右边缘时标签自动翻到左侧)、Pt1/Pt2 带白底标签,互不压字 - [x] 分析界面:标点与照片烧录位置对齐,**只有一个 min、一个 max** -- [x] 分析面板数值可见且与照片一致(最高 32.9 / 最低 22.0 / 中心 24.4℃) -- [x] 图像增强:档位生效、修正后不再放大噪声、15.1fps 不掉帧 +- [x] 照片 / 分析面板 / 底部面板三方数值完全一致 + (真机同帧:照片 max 36.0 min 20.4 Pt1 21.7 Pt2 26.1;面板 36.0/20.4/24.5 + 21.7/26.1) +- [x] 图像增强:6 档与 8 档生效、修正后不再放大噪声、15.1fps 不掉帧 - [x] 设置持久化跨冷启动(`mag160c_settings.xml`:enhanceLevel / imageFlipV) +- [x] 录像:99 帧 / 0 丢弃 / 1.6MB,首帧日志证明极值标记已烧入 + (`annotation: 2 markers ... trace=BOTH minPos=159 maxPos=16269`) +- [x] **重启后冷启动**(USB 权限被系统清空后重新授权):一次成功、15.1fps、 + 无重枚举、无重连风暴 - [x] 屏幕熄灭时无空转(CPU 3.7%)、USB 读取继续、不崩溃 +- [x] 长时间运行 60s+:15.1fps 稳定、无丢帧、无崩溃 + +**排查方法记录(本轮新增)**: +- 判断"自绘画面"的帧率/耗时**不能用 `dumpsys gfxinfo`**(它看不到 SurfaceView 的 + lockCanvas 绘制,实测只记到 28 帧而流在 15fps)。本应用已内置 `MAG160C/render` + 日志:每 5 秒打印 `paints=N avg=x ms worst=y ms`,这是唯一能看到真实绘制性能的途径。 +- 录像标注是否齐全可从 `MAG160C/rec` 首帧日志直接读出(含 trace 模式与极值输入)。 **教训记录**: - `dumpsys gfxinfo` 不统计 SurfaceView 的 lockCanvas 绘制。判断自绘画面性能 diff --git a/v_live.png b/v_live.png new file mode 100644 index 0000000..d673369 --- /dev/null +++ b/v_live.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0de82a1fdcc9fc66b1dd606a9e82fc165f73ed3c75e71d034a464384f4586cce +size 1539185