H.264 与“闭眼抽帧”学习笔记

在 PPT、网页操作、数据看板这类屏幕录制视频里,不一定要先把每一帧都解码成图像再判断页面变化,而是可以先观察 H.264 压缩码流里的数据包大小变化。编码器本来就已经分析过相邻画面的差异;如果画面很容易预测,压缩数据通常很小,如果画面突然大面积变化,压缩数据往往会明显变大。

所以所谓“闭眼抽帧”,不是完全不处理视频,而是在候选检测阶段不看像素画面,只看压缩数据的时间变化;等找到可能的换页位置后,再解码少量代表帧。

一、为什么这个问题可以从编码数据里找线索

DataAgent 的视频理解任务里,视频内容通常是界面操作、PPT 或类似页面讲解。这类视频有一个很明显的特点:大部分时间画面是静止的,只有在换页、弹窗、表格加载、动画出现时才发生大面积变化。

如果按固定间隔抽帧,会遇到两个问题:一是同一个静止页面会被抽出很多重复帧;二是停留时间很短但重要的页面可能被错过。传统做法是解码所有帧,然后用像素差、直方图、SSIM、感知哈希或视觉模型比较前后画面。这样当然可行,但成本比较高。

H.264 给了另一条线索。它的压缩依赖预测:能从当前画面内部或前后参考画面预测出来的内容,就不需要完整保存;预测不准的地方,才需要编码更多残差。于是,页面静止时包通常很小,页面切换时包大小会出现一簇明显上升。

可以粗略理解为:

1
2
静止页面:预测准确 -> 残差小 -> 包小
页面切换:预测失效 -> 残差大 -> 包变大

这个近似并不是在所有视频上都成立,但在静态 UI 和 PPT 类视频里通常很有用。

二、H.264 为什么能压缩视频

H.264,也叫 AVC,是一种视频压缩编码标准。如果每一帧都按完整图片保存,视频会非常大。它主要利用两类冗余来压缩:

第一类是空间冗余。同一张画面内部,相邻区域经常很像。比如 PPT 里有大面积白色背景,没有必要把每个白色像素都完整记录一遍。

第二类是时间冗余。相邻帧通常变化很小。比如一个页面停留 5 秒,标题、表格、背景都不动,可能只有鼠标移动了一点。编码器没必要反复保存整张页面,只要记录“哪些地方和参考画面不同”。

一帧画面的编码过程可以简化成:

1
2
3
4
5
6
7
原始画面
-> 分块
-> 预测当前块
-> 计算真实画面和预测画面的残差
-> 变换与量化
-> 熵编码
-> 压缩码流

这里最关键的是预测和残差。预测越准,残差越小,需要保存的新信息越少;预测越失败,残差越大,压缩后的数据量也就越容易上升。换页、整屏刷新、弹出大面积内容,都会让原来的参考画面失效,这就是包大小能够反映画面变化的原因。

三、I/P/B 帧应该怎么理解

工程里经常说 I 帧、P 帧、B 帧。严格来说,H.264 中定义的是不同类型的 slice,但在抽帧讨论里,直接按帧类型理解问题不大。

I 帧的 I 是 Intra,主要靠当前画面内部的信息进行压缩,不依赖其他视频帧来恢复当前画面。它可以理解为重新描述一张相对完整的画面,但它不是未压缩图片,仍然会经过帧内预测、残差、变换、量化和熵编码。I 帧通常比较大,也常用于随机访问、拖动进度条和错误恢复。工程上常把 I 帧叫关键帧,但更严格地说,适合随机访问的通常是 IDR 帧:IDR 帧通常是 I 帧,但 I 帧不一定都是 IDR 帧。

P 帧的 P 是 Predictive,主要参考过去的画面。常见说法是 P 帧只记录“相对于上一帧发生了什么变化”,这个说法便于理解,但不够严谨,因为 P 帧可以参考不止一帧,也不一定只参考紧邻上一帧。对屏幕录制来说,如果当前页面基本没变,P 帧只需要记录很小的残差、少量运动向量或鼠标变化,数据可能只有几十或几百字节;如果页面从 A 切到 B,大量区域无法预测,P 帧也会变得很大。

B 帧的 B 是 Bi-predictive,可以使用两组参考画面做预测,常见理解是同时参考前后画面。它通常压缩率更高,但编码顺序和播放顺序可能不同。比如播放顺序是:

1
I -> B -> B -> P

为了让 B 帧参考后面的 P 帧,编码器可能先处理 I 和 P,再处理中间的 B 帧。

三类帧可以简单对比:

类型 主要参考信息 一般特点
I 帧 当前画面内部 相对独立,通常较大
P 帧 过去的参考画面 静止场景下通常较小,变化大时也会变大
B 帧 两组参考画面 预测更充分,通常压缩率更高

需要注意,帧类型不是包大小的唯一原因。量化参数、码率控制、分辨率、GOP/keyint、编码器的场景切换策略、封装格式,以及一个画面被拆成多少个包,都会影响最终大小。

四、包大小里的 burst 信号

对 PPT 或 UI 视频来说,包大小时间序列通常会呈现一种很清楚的形态。

页面静止时,连续包可能是:

1
55 B、62 B、48 B、70 B、60 B

它们在时间轴上贴近底部,波动很小。页面切换或大面积动画出现时,可能变成:

1
60 B、1200 B、6800 B、11000 B、4000 B、900 B、70 B

这不是一根孤立的尖峰,而是一簇连续变大的包。这种连续突变可以称为 burst。换页、表格加载、元素飞入、整屏刷新,都可能形成 burst。

真正需要警惕的是孤立大包。编码器可能根据 keyint 或 GOP 设置,周期性插入 I 帧或 IDR 帧。即使画面完全没变,这类帧也可能比周围 P/B 帧大很多:

1
2
3
60 B、55 B、48 B、30000 B、62 B、51 B
^
周期性 I 帧

这根尖峰前后都很平静,更像是编码器强制插入的关键帧,而不是真实换页。真实换页更像:

1
2
60 B、55 B、1500 B、6000 B、9000 B、2000 B、80 B
^ 连续一簇变化

所以不能用“包大 = 换页”这种单点规则。更合理的判断是:连续出现一簇大包,前后状态发生明显变化,并且之后重新回到稳定小包,才更可能是真实页面变化。

五、“闭眼抽帧”的实际流程

传统抽帧是先解码全部视频帧,再比较图像差异:

1
解码全部帧 -> 比较前后画面 -> 找换页 -> 保留代表帧

闭眼抽帧则把前面的候选检测放到压缩码流上:

1
2
3
4
5
6
读取包大小、时间戳、帧类型
-> 建立包大小时间序列
-> 检测连续 burst
-> 过滤孤立关键帧
-> 合并临近变化
-> 在页面稳定后解码少量代表帧

它不是完全不解码。因为最终要得到图片,仍然需要解码候选帧;而且 P/B 帧依赖参考画面,解码器可能还要从前面的关键位置一路解码到目标时间。性能收益主要来自三点:不对所有帧做图像比较,不把所有帧送给视觉模型,最后只保留少量高清代表帧

阈值一般应该偏向召回:宁可多保留几个候选点,也不要漏掉真正的页面。后续可以再用图像去重、OCR、版面分析或多模态模型筛掉重复帧。

六、为什么要在 burst 结束后取帧

页面切换不是瞬间完成的。比如 10 秒开始换页,过程可能是:

1
2
3
4
5
10.00 s:旧页面
10.10 s:淡出
10.20 s:新旧页面重叠
10.30 s:新页面还没加载完整
10.50 s:新页面稳定

如果在 burst 中间截图,很可能拿到过渡画面、模糊画面、新旧重叠画面,或者动画还没结束的半成品。因此更稳的方式是在 burst 结束、包大小重新回落后再取一张稳定帧。

但这个稳定帧的“逻辑时间戳”可以记为 burst 开始时间:

1
2
3
burst 开始:10.00 s
实际截图:10.50 s
逻辑时间戳:10.00 s

这样做的好处是和 ASR 旁白更容易对齐。讲解者往往在页面刚开始切换时说“接下来我们看这个页面”,而真正稳定的画面会晚一点出现。截图取稳定时刻,语义对齐用变化开始时刻,两者可以分开记录。

七、适用边界和工程注意点

这种方法特别适合 PPT、操作界面、屏幕讲解、数据看板这类视频,因为它们通常满足几个条件:页面长时间静止,换页时变化面积大,自然运动少,同一页面停留数秒,换页前后有清晰稳定状态。

它不适合一直在运动的视频,比如电影、足球比赛、手持自拍视频、游戏录像、高频动画、摄像机持续移动的视频。这些视频的包大小会持续波动,很难区分普通运动和真正场景切换。

另外,“包大小反映画面变化”只是一个近似。更严谨地说,在编码参数相对稳定、内容主要是静态界面的条件下,编码数据量通常与画面预测难度和变化程度有较强相关性。实际实现时最好综合使用:

  • 包大小;
  • 时间连续性;
  • 帧类型;
  • burst 形态;
  • 前后是否恢复稳定;
  • 相近 burst 是否属于同一页动画。

孤立的大 I 帧要过滤,同一页里的多个小动画要合并,页面稳定后再截图。这样才能避免把编码器周期性关键帧当成换页,也避免同一个页面被重复抽很多次。

八、和 ASR、版面结构一起使用

抽帧只是视频理解链路的一部分。最终送给下游模型的最好不是孤立图片,而是把代表帧、ASR 旁白和版面结构按时间轴对齐。

可以理解成:

1
2
3
4
5
时间 10 s:ASR 旁白
时间 11 s:稳定页面帧
时间 11 s:页面标题、表格、按钮、字段等版面结构
时间 18 s:下一段 ASR 旁白
时间 19 s:下一张稳定页面帧

这样能处理一些只看画面容易误判的情况。比如某页包含很多数字和表格,看起来很重要,但旁白说“This is not the page we need.”,那么结合 ASR 后就能判断它可能是干扰页。

我对这套方法的理解是:它不是用包大小替代视觉理解,而是用 H.264 编码器留下的变化信号,先低成本缩小候选范围。真正稳定可靠的系统,还是要把压缩码流信号、少量代表帧、ASR 文本和页面结构一起用。