FFMPEG寻求带来音频文物

问题描述:

我正在使用ffmpeg实现音频解码器。 在阅读音频,甚至寻求已经工作的时候,我无法找到一种方法来清除缓冲区后,所以我没有任何文物,当应用程序开始读取音频后立即寻求。FFMPEG寻求带来音频文物

avcodec_flush_buffers似乎对内部缓冲区没有任何影响。所有解码器(mp3,aac,wma,...)都会发生此问题,但PCM/WAV(由于音频没有压缩,因此不使用内部缓冲器来保存数据以解码)。

的代码片段很简单:

av_seek_frame(audioFilePack->avContext, audioFilePack->stream, posInTimeFrame, AVSEEK_FLAG_ANY); 
avcodec_flush_buffers(audioFilePack->avContext->streams[audioFilePack->stream]->codec); 

解释:

audioFilePack->avContext = FormatContext 
audioFilePack->stream = Stream Position (also used to read audio packets) 
audioFilePack->avContext->streams[audioFilePack->stream]->codec = CodecContext for the codec used 

上我应该做的,所以我可以寻求和获得无残留的音频任何想法? 谢谢!

+0

请问,没有想法?我试图解决这个问题近2个星期没有任何想法可能会导致这种情况...应该如何工作? –

+0

消息也发送到ffmpeg用户的官方邮件列表。帮助仍然需要。 –

+0

你能更详细地描述工件吗?他们是否点击并弹出? –

我从来没有写过一个具有搜索功能的音频播放器,但我怀疑正在发生的是这样的。每个音频包都解码成原始声波的片段。通常情况下,这些片段依次彼此相邻,结果是连续的波形,这种波形听起来没有任何伪影。当你寻求时,你强迫文件的不同部分的两个片段彼此邻接。这通常会在所产生的声波中引入一个不连续性,耳朵会将其视为咔嗒声或流行音乐,或者当您称之为(我猜测)一个神器时。

下面是一个更具体的例子。假设您在寻找之前播放了前25个音频包。假设数据包25解码为最后一个样本为12345的波形。当数据包25正在呈现给扬声器时,您寻找数据包66.假设数据包66的第一个样本是-23456。因此,数字音频流在搜索中从12345跳到-23456。这是一个巨大的不连续性,并将作为流行音乐被听到。

我认为一种解决方案是在开始寻找之前抓取一个额外的数据包(在我的示例中为数据包26),将其解码为离线缓冲区,应用淡出,然后将其放入播放队列。在你寻找你想要的位置之后,取第一个数据包(我的eaxmple中的66),将它解码到另一个离线缓冲区,应用淡入,然后将它放入回放队列。这应该确保平稳的声波和无伪影寻找。

如果您很聪明,可以根据需要将淡出和淡入淡入或淡入。我认为只有几毫秒应该足以防止失真。您甚至可以应用旧数据包和新数据包的交叉淡入淡出。在查找之前仅记下最后一个数据包中的最后一个样本值就足够了,并且在几个样本上逐渐降低到零,而不是立即将其拉到零。这可能比解码额外的数据包更容易。

这是我对这个问题如何解决的猜测。这显然是一个解决的问题,所以我鼓励你也看看开放源代码的音频播放器,看看它们如何实现寻找。 Audacity,Totem,Banshee,RhythmBox,Amarok或VLC等程序或GStreamer等框架可能是很好的例子。如果你发现他们采用了显着的技术,请在这里报告主题。我想人们会想知道他们是什么。祝你好运!

这是ffmpeg中的一个bug。内部缓冲区没有被刷新,因此当你在冲洗后得到一个数据包/帧时,你会得到预搜索数据。它似乎是固定的3-16-12,所以你可以自己加入这个修复,或升级ffmpeg。

http://permalink.gmane.org/gmane.comp.video.libav.devel/23455

作为更新,错误上面确实是一个问题,但有一个与AAC第二错误特别。

从五个月前,另一个用户发现了这个错误,据报道它是固定的。 https://ffmpeg.org/trac/ffmpeg/ticket/420

该修复程序是一个flush函数被添加到aacdec.c清除其内部缓冲区。 问题是在aacdec.c中定义了两个解码器,并且只有一个被赋予了flush函数指针。如果您使用其他(更常见的)解码器,它仍然不会被正确清除。

如果您在建立自己的ffmpeg的位置的时候,解决方法是添加 .flush =平齐, 到avcodec中ff_aac_decoder定义的底部(这是在文件的底部。)

我会让ffmpeg家伙知道如此希望它可以包含在主分支中。

+0

碰撞让原来的海报有希望看到这个 – JHawkZZ

+0

非常感谢!我会重新编译它,并放弃我的另一种方式......这是丑陋的,但工程... –