@@ -414,68 +414,43 @@ pub fn process_frame(
414414 & grid, last_changed_texts, tier,
415415 ) ;
416416 } else {
417- // 区域路径无可用产出(误判/空白区域/垃圾块)→ 整帧 OCR 兜底
418- // (结构性回退链:误判/空白区域不得阻断全帧识别——真实画面文字必须仍有出口)
419- // H2 修复:改用有界等待变体——引擎卡死时本帧超时计入 ocr_err 后
420- // 继续下一帧(降级不阻塞整条管线)
421- match engines. recognize_image_timeout ( rgb, crate :: engine:: OCR_REQUEST_TIMEOUT ) {
422- Ok ( blocks) => {
423- stats. ocr_err += failed_regions as u64 ;
424- stats. ocr_ok += 1 ;
425- trigger. last_ocr_at = Instant :: now ( ) ;
426- trigger. last_full_ocr_at = Instant :: now ( ) ;
427- crate :: live_keyframes:: handle_full_frame (
428- & frame, & blocks, db, app, session_id, last_full_texts, frame_samples,
429- last_archived_text, last_archived_at, image_store, ocr_input_hash,
430- ocr_input_dhash, ui_junk, screen_tracker, layout_changed,
431- & grid, last_changed_texts, tier,
432- ) ;
433- }
434- Err ( e) => {
435- stats. ocr_err += 1 + failed_regions as u64 ;
436- eprintln ! ( "[ScreenWorker] 整帧 OCR 兜底失败(区域 OCR 亦无产出): {}" , e) ;
437- }
417+ // v0.12.0 M5(视频会话全帧 OCR 下线):区域路径无可用产出时不再整帧
418+ // OCR 兜底——关键帧纯图归档(handle_full_frame 空块走 grid-change 触发,
419+ // 存图不识别;真实画面要点经 vision-exp 精修提取)
420+ if !roi_tracker. foreground_foreign ( ) {
421+ crate :: live_keyframes:: handle_full_frame (
422+ & frame, & [ ] , db, app, session_id, last_full_texts, frame_samples,
423+ last_archived_text, last_archived_at, image_store, ocr_input_hash,
424+ ocr_input_dhash, ui_junk, screen_tracker, layout_changed,
425+ & grid, last_changed_texts, tier,
426+ ) ;
438427 }
439428 }
440- } else {
429+ } else if is_subtitle {
430+ // 字幕区:既有路径不变(v0.12.0 M5 只下线全帧画面要点 OCR)
441431 // H2 修复:同上有界等待——超时时走 Err 分支计 ocr_err 并继续下一帧
442432 match engines. recognize_image_timeout ( rgb, crate :: engine:: OCR_REQUEST_TIMEOUT ) {
443433 Ok ( blocks) => {
444434 stats. ocr_ok += 1 ;
445435 // 成功识别即刷新 OCR 时刻(无论是否产出文本——防漏检兜底周期基准)
446436 trigger. last_ocr_at = Instant :: now ( ) ;
447- if is_subtitle {
448- // M2/REQ-037:bbox 回喂 ROI 跟踪器(锁定/失效判定;
449- // 裁剪图坐标系 + 原点平移 + TD-046 缩放比反算;
450- // REQ-084:前台非目标窗口期间 feed_ocr 内部冻结)
451- let boxes: Vec < crate :: types:: TextBox > =
452- blocks. iter ( ) . filter_map ( |b| b. bbox ) . collect ( ) ;
453- roi_tracker. feed_ocr ( & boxes, crop_origin, ocr_input_scale) ;
454- // REQ-084:前台切换期间其他窗口内容不得进字幕投票器
455- if !roi_tracker. foreground_foreign ( ) {
456- // REQ-087(ADR-011):UI 面板活跃期 → 字幕源头丢弃
457- // (控制栏/弹窗文本不得进投票器/落段;原料层不动可复查)
458- if trigger. panel . is_active ( ) {
459- stats. panel_filtered += 1 ;
460- } else {
461- handle_subtitle_frame (
462- & frame, & blocks, voter, & mut trigger. scrolling ,
463- last_frame_text, last_preview, db, app,
464- session_id, subtitle_segments, ui_junk, stats,
465- ) ;
466- }
467- }
468- } else {
469- // 全帧 OCR 成功时刻:带外触发冷却基准(ADR-011)
470- trigger. last_full_ocr_at = Instant :: now ( ) ;
471- // v0.7.3(REQ-157):前台非目标窗口期间画面要点不落库
472- // (复用 REQ-084 字幕先例——根治其他窗口内容混入屏卡)
473- if !roi_tracker. foreground_foreign ( ) {
474- crate :: live_keyframes:: handle_full_frame (
475- & frame, & blocks, db, app, session_id, last_full_texts, frame_samples,
476- last_archived_text, last_archived_at, image_store, ocr_input_hash,
477- ocr_input_dhash, ui_junk, screen_tracker, None ,
478- & grid, last_changed_texts, tier,
437+ // M2/REQ-037:bbox 回喂 ROI 跟踪器(锁定/失效判定;
438+ // 裁剪图坐标系 + 原点平移 + TD-046 缩放比反算;
439+ // REQ-084:前台非目标窗口期间 feed_ocr 内部冻结)
440+ let boxes: Vec < crate :: types:: TextBox > =
441+ blocks. iter ( ) . filter_map ( |b| b. bbox ) . collect ( ) ;
442+ roi_tracker. feed_ocr ( & boxes, crop_origin, ocr_input_scale) ;
443+ // REQ-084:前台切换期间其他窗口内容不得进字幕投票器
444+ if !roi_tracker. foreground_foreign ( ) {
445+ // REQ-087(ADR-011):UI 面板活跃期 → 字幕源头丢弃
446+ // (控制栏/弹窗文本不得进投票器/落段;原料层不动可复查)
447+ if trigger. panel . is_active ( ) {
448+ stats. panel_filtered += 1 ;
449+ } else {
450+ handle_subtitle_frame (
451+ & frame, & blocks, voter, & mut trigger. scrolling ,
452+ last_frame_text, last_preview, db, app,
453+ session_id, subtitle_segments, ui_junk, stats,
479454 ) ;
480455 }
481456 }
@@ -485,6 +460,18 @@ pub fn process_frame(
485460 eprintln ! ( "[ScreenWorker] OCR 识别失败(下帧重试): {}" , e)
486461 }
487462 }
463+ } else {
464+ // v0.12.0 M5(视频会话全帧 OCR 下线):全帧画面要点不再识别——关键帧纯图
465+ // 归档(handle_full_frame 空块走 grid-change 触发,存图不识别;真实画面
466+ // 要点经 vision-exp 精修提取)。前台非目标窗口期间不归档(REQ-157)。
467+ if !roi_tracker. foreground_foreign ( ) {
468+ crate :: live_keyframes:: handle_full_frame (
469+ & frame, & [ ] , db, app, session_id, last_full_texts, frame_samples,
470+ last_archived_text, last_archived_at, image_store, ocr_input_hash,
471+ ocr_input_dhash, ui_junk, screen_tracker, layout_changed,
472+ & grid, last_changed_texts, tier,
473+ ) ;
474+ }
488475 }
489476}
490477
0 commit comments