假设我有一个正在解码的音频文件ffmpeg。源格式类似于AAC将音频拆分为数据包的地方。当寻找特定时间时,很明显,大多数情况下,时间不会落在数据包边界上,而是落在数据包持续时间内的某处。我必须自己在数据包中寻找还是av_seek_frame自己完成这一切并设置解码,以便下一个解码的帧应该从我请求的位置开始?
如果我将函数av_seek_frame与 flag 一起使用AVSEEK_FLAG_BACKWARD,我假设av_read_frame返回的下一个数据包将是包含我正在寻找的时间位置的数据包。那正确吗?
如果我使用avcodec_decode_audio4解码这个数据包,返回的帧是否包含数据包开始时的音频数据,或者从我传递到av_seek_frame的时间开始?在后一种情况下,我如何找出帧/数据包时间戳以估计解码帧中要跳过的样本数?在PTS寻求后是零,DTS看起来无用要么。
是否可以使用 精确搜索特定时间ffmpeg?
是的,源代码确认av_seek_frame确实搜索到数据包边界。
为了在数据包内寻找,我使用 AVStream::cur_dts 时间戳,该时间戳由av_seek_frame更新以告诉它所寻找的边界。通过该值,我们可以找出数据包中要跳过的剩余样本数。这样就解决了问题。
ffmpeg 中没有帧精确或音频样本精确搜索,这是应用程序级问题。原因很简单:libavformat 进行查找,并且它不知道各个解复用器返回的数据包内有什么。它只有一个带有时间戳 X 和持续时间 Y 的数据块。它对这些数据一无所知,你必须解码数据才能用它做任何有意义的事情,这是 libavcodec,而不是 libvformat。
因此,回答您的问题: av_seek_frame 寻求数据包边界,AVSEEK_FLAG_BACKWARD 意味着数据包将严格位于给定 ts 之前;对于音频,这意味着数据包很可能包含您的时间戳。然而,情况并非总是如此,因为一些解复用器基于索引进行搜索,并且并非每个数据包都可能具有索引条目。在查找后到达包含指定时间戳的数据包之前,您可能需要多次调用 av_read_frame()。
除了调用 avcodec_flush() 之外,libavcodec 不知道任何有关查找的信息,因此下一次调用 avcodec_decode_audio4 的输出将从输入数据包的开头开始。对于特定样本的搜索,应用程序必须自行删除领先样本。
| 归档时间: |
|
| 查看次数: |
4238 次 |
| 最近记录: |