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