2011-07-18 148 views
2

我正在使用Ffmpeg來解碼和播放視頻文件。我目前播放的視頻和播放的音頻速度與CPU可以解碼和顯示的速度一樣快。問題是我想用系統時鐘同步播放視頻和音頻。使用Ffmpeg同步解碼視頻

我已經搜索了一些幫助,但除了dranger的tutorial 05之外找不到其他任何東西,但我並不真正瞭解他在做什麼,因爲我的程序的寫法與他的方式不同。

我使用的是mjpeg文件,因此每次解碼幀時都會檢索pts,我已將時間基數乘以時間基數,因爲dranger會以秒爲單位獲取值,但分辨率似乎只有秒因此,當視頻以每秒25幀的速度運行時,我得到的值是「6」25倍,然後是「7」25倍。

是否沒有更準確的值?或者獲得更準確的價值的方法,如果是這樣,我將如何去同步到這個值?我正在使用SDL來顯示值,所以我可以只使用我獲得的值的SDL_Delay()?

感謝您的時間,

Infinitifizz

+0

檢查以確認您使用的是正確的類型,也許您正在將'pts * time_base'計算爲int而不是float。 –

+0

那麼PTS值似乎是在int64t不浮動或雙。 –

+0

查看dranger的教程,他基本上使用構成幀的第一個數據包的點作爲幀的點,或者如果不存在,則使用數據包的dts值。然後這個值乘以video time_base(作爲double),但仍然是uint64_t,所以我得到如下輸出:0,0,0,0,0,0,1,1,1,1,1,1,1 ,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4等,而不是以毫秒爲單位的任何事物,或比秒更準確的事物。 –

回答

2

要PTS或DTS轉換爲浮點秒,在適當的基time_base使用av_q2d():

// You got the context from open_input: 
AVFormatContext *pFormatCtx; 
avformat_open_input(&pFormatCtx, inputfilename, NULL, &format_opts); 

// Get a stream from the context 
AVStream pStream= pFormatCtx->streams[i]; 

// Convert packet time (here, dts) to seconds with: 
double seconds= (dts - pStream->start_time) * av_q2d(pStream->time_base); 

// Or convert frame number to seconds with the codec context 
AVCodecContext *pCodecCtx= pStream->pVideoStream->codec; 
double seconds= framenumber * av_q2d(pCodecCtx->time_base); 

這將返回時從 - 視頻在幾秒鐘內啓動。

+0

什麼是「框架」,從哪裏獲得「DTS」? –

+1

您可能已經解決了您的問題,但是對於未來的搜索者:'framenumber'從'pCodecCtx'獲得,'dts'來自您在調用解碼函數後獲得的'AVPacket'。 – Sam