2011-07-05 32 views
3

我正在構建一個應用程序,在其中創建一個視頻。 問題是,某個時候(好吧......大部分時間)幀採集過程不夠快。告訴libavcodec/ffmpeg放棄框架

我現在正在做的是跳過當前幀採集,如果我遲到,但FFMPEG/libavcodec認爲我傳遞給它的每一幀作爲下一幀在線,所以如果我從2幀中丟掉1幀,一個20秒的視頻將只能持續10.更多的問題一進來就加入聲音,因爲聲音處理速度更快......

我想告訴FFMPEG:「最後一幀應該連續兩次原本打算的更長時間「,或任何可以讓我實時處理的事物。

我試圖在一個點到堆棧幀,而這最終殺死了我所有的記憶(我也試着「堆」我在硬盤驅動器架,這是方法要慢,如我所料)

我想我必須手動使用pts,但是我所有的嘗試都失敗了,並且閱讀其他一些使用ffmpeg的應用程序代碼,例如VLC,對我來說幫助不大......所以,任何建議都可以非常感激!

非常感謝!

回答

0

許多(大多數?)視頻格式不允許刪除幀。相反,如果您無法及時獲得新視頻幀,請嘗試重新使用舊視頻幀。

+0

大多數容器實際上都支持廢棄框架。 MP4僅存儲每個幀的持續時間,對於所有幀而言不必相同。 mkv存儲演示時間戳。 IDK關於AVI;也許不是,但AVI對於現代編解碼器來說並不理想。 (沒有那麼多的通用視頻容器,不包括像ogm這樣的晦澀的容器,或者像螺母那樣模糊的) –

0

只是一個想法..當它滯後處理你試圖再次傳遞給它同一幀(並放棄當前的一個)?也許它可以快速處理複製幀。

+0

好吧,它有點改進,但​​視頻仍然太快... 我想這個來自我的調度算法(我不能稱之爲真正的算法...)) 我會盡力改善它明天,併發布後,如果這改善了一些東西。 感謝您的幫助無論如何(你和黃昏)! – chouquette

0

這個ffmpeg命令行開關-threads ...用於多核處理,所以你應該可以做類似的API(儘管我不知道如何)。這可能會解決您的問題。

1

您的輸出可能會被視爲可變幀率(vfr),但您可以簡單地使用wallclock時間生成一個時間戳,幀到達並將其應用於AVFrame,然後對其進行編碼。那麼該幀將在正確的播放時間顯示。

對於如何做到這一點的例子(至少指定自己的時間戳部分),看到的ffmpeg的發佈文檔/例子/ muxing.c(線491在我目前的git拉):

frame->pts += av_rescale_q(1, video_st->codec->time_base, video_st->time_base); 

這裏作者正在將視頻編解碼器時基上的幀時間戳增加1,重新調整爲視頻流的時基,但在您的情況下,您可以重新調整從開始捕獲從任意時基到輸出視頻流幀的秒數時基(如上例所示)。例如,如果你的任意時間基準爲1/1000,並收到0.25秒因爲你開始捕獲幀,然後做到這一點:

AVRational my_timebase = {1, 1000}; 
frame->pts = av_rescale_q(250, my_timebase, avstream->time_base); 

然後編碼幀像往常一樣。