记录一下踩到的 AV_PKT_FLAG_DISCARD
一个坑。
背景
做一个 取帧 的性能,可能传入指定工夫,并获取该工夫点的帧。
实现步骤如下:
- 获取视频流的
duration
。
因为局部格局的素材须要做适配,所以这里是通过取pkt->pts + pkt->duration
的最大值来计算的。 - 依据
duration
做容错,大于或等于 duration
时,就取duration
工夫点的帧。 -
取帧的判断条件是:
if (frame->pts <= clock && clock < frame->pts + frame->duration) {// 采纳的是左闭右开的形式 [pts, pts+duration) 取帧 }
问题
看似都比拟失常,然而奇怪的事件呈现了,视频流的 duration
为 6133 (即: {pkt->pts: 6100, pkt->duration: 33})
。
然而解码进去最初一帧 AVFrame
的 pts
却是 6067
。
这就导致了依照上述的取帧形式始终取不到工夫点为 大于 6100
的帧。
解决
经排查,发现在计算视频流 duration
的时候,最初一个 AVPacket
的 flags
字段中蕴含了 AV_PKT_FLAG_DISCARD
标记。该标记的作用如下:
/**
* Flag is used to discard packets which are required to maintain valid
* decoder state but are not required for output and should be dropped
* after decoding.
**/
#define AV_PKT_FLAG_DISCARD 0x0004
大抵的意思能够简略的了解为: 带有该标记的 AVPacket 所携带的数据为解码器相干的信息,不会被解码出一幅图像。
起因找到了,计算 duration
的时候因为 AV_PKT_FLAG_DISCARD
标记的影响多计算了一帧的工夫,导致无奈获取到最初一帧。解决形式就是在计算 duration
的时候判断如果是该标记就跳过就好了。