視頻、音頻打時間戳的方法
1. 視頻時間戳
pts = inc++ *(1000/fps); 其中inc是一個靜態的,初始值為0,每次打完時間戳inc加1.
在ffmpeg,中的代碼為
pkt.pts= m_nVideoTimeStamp++ * (m_VCtx->time_base.num * 1000 / m_VCtx->time_base.den);
2. 音頻時間戳
pts = inc++ * (frame_size * 1000 / sample_rate)
在ffmpeg中的代碼為
pkt.pts= m_nAudioTimeStamp++ * (m_ACtx->frame_size * 1000 / m_ACtx->sample_rate);
采樣頻率是指將模擬聲音波形進行數字化時,每秒鍾抽取聲波幅度樣本的次數。
。正常人聽覺的頻率范圍大約在20Hz~20kHz之間,根據奈奎斯特采樣理論,為了保證聲音不失真,采樣頻率應該在40kHz左右。常用的音頻采樣頻率有8kHz、11.025kHz、22.05kHz、16kHz、37.8kHz、44.1kHz、48kHz等,如果采用更高的采樣頻率,還可以達到DVD的音質
對采樣率為44.1kHz的AAC音頻進行解碼時,一幀的解碼時間須控制在23.22毫秒內。
背景知識:
(一個AAC原始幀包含一段時間內1024個采樣及相關數據)
分析:
1 AAC
音頻幀的播放時間=一個AAC幀對應的采樣樣本的個數/采樣頻率(單位為s)
一幀 1024個 sample。采樣率 Samplerate 44100KHz,每秒44100個sample, 所以 根據公式 音頻幀的播放時間=一個AAC幀對應的采樣樣本的個數/采樣頻率
當前AAC一幀的播放時間是= 1024*1000000/44100= 22.32ms(單位為ms)
2 MP3
mp3 每幀均為1152個字節, 則:
frame_duration = 1152 * 1000000 / sample_rate
例如:sample_rate = 44100HZ時, 計算出的時長為26.122ms,這就是經常聽到的mp3每幀播放時間固定為26ms的由來。
每一幀音頻或視頻都有一個持續時間:duration:
采樣頻率是指將模擬聲音波形進行數字化時,每秒鍾抽取聲波幅度樣本的次數。
。正常人聽覺的頻率范圍大約在20Hz~20kHz之間,根據奈奎斯特采樣理論,為了保證聲音不失真,采樣頻率應該在40kHz左右。常用的音頻采樣頻率有8kHz、
11.025kHz、22.05kHz、16kHz、37.8kHz、44.1kHz、48kHz等,如果采用更高的采樣頻率,還可以達到DVD的音質
對采樣率為44.1kHz的AAC音頻進行解碼時,一幀的解碼時間須控制在23.22毫秒內。
背景知識:
(一個AAC原始幀包含一段時間內1024個采樣及相關數據)
分析:
1) AAC
音頻幀的播放時間=一個AAC幀對應的采樣樣本的個數/采樣頻率(單位為s)
一幀 1024個 sample。采樣率 Samplerate 44100KHz,每秒44100個sample, 所以根據公式 音頻幀的播放時間=一個AAC幀對應的采樣樣本的個數/采樣頻率
當前AAC一幀的播放時間是= 1024*1000000/44100= 22.32ms(單位為ms)
2) MP3
mp3 每幀均為1152個字節, 則:
frame_duration = 1152 * 1000000 / sample_rate
例如:sample_rate = 44100HZ時,計算出的時長為26.122ms,這就是經常聽到的mp3每幀播放時間固定為26ms的由來。
3)H264
視頻的播放時間跟幀率有關 frame_duration = 1000/fps
例如:fps = 25.00 ,計算出來的時常為40ms,這就是同行所說的40ms一幀視頻數據。
理論上的音視頻(播放)同步是這樣的:
由此得到了每一幀數據的持續時間,音視頻交叉存儲在容器中:一個時間軸:
時間軸:0 22.32 40 44.62 66.96 80 89.16 111.48 120 ................
音 頻 :0 22.32 44.62 66.96 89.16 111.48 ................
視 頻 :0 40 80 120 ................
即視頻的持續時間相加 和音頻的持續時間相加作比較,誰小寫入哪個。
但實際情況(播放)是不成立的
1:首先解決一個問題
為什么不 音頻播音頻的 視頻播視頻的 即上面的 到 第22.32ms播一幀音頻 ,到40ms播一幀視頻。
因為這個22.32ms 或40ms是算不准的或者說和聲卡播的時間是不一樣的。這里就需要知道聲卡播一幀/或者說播放一個buf音頻需要多長時間。
2:聲卡每次播一個采樣點 而不是一幀。聲音當一個采樣點丟失了都可以聽出來,視頻則不然。
3:音視頻同步方式:1----回調方式
假設聲卡有兩塊緩存都是存放要播放的聲音pcm的 一直在播放"B"buf 首先確定幾點
(1)buf大小是固定的這樣播放一個buf的時間就是固定的,假設30ms;
(2)當buf“B”播放完畢即buf用完,再播放buf“A",保證音頻pcm一直都連續
(3)當一個buf播放完畢,那說明系統(聲卡)過了30ms, 這時候有可能真正的時間過了40ms(這里不用關心),這里則通過回調得到一次時間30ms;
(4)再去用視頻對應音頻的30ms,這時候的時間就是准確的:
時間軸:0 30 60 90 120 ................
音 頻 :0 22.32 44.62 66.96 89.16 111.48 ................
視 頻 :0 40 80 120 ................
(5)這里有個問題就是 視頻中 30ms 到40ms 這中間的10ms是怎么算出來的,這個是不用關心的,因為人的眼睛10ms是看不出來的,
即當音頻的30ms一次回調時,就可以播放第二幀視頻,如上圖
第一次回調(30ms)---播(40ms)視頻,
第一次回調(60ms)---播(80ms)視頻,
第一次回調(90ms)---不播視頻,
第一次回調(120ms)---播(120ms)視頻。
4:音視頻同步方式:1----阻塞方式
還是看上面的圖
(1)buf"B"一直在播放,傳入buf"A"的外部buf把數據給buf"A"后 不立即返回,等到buf"B"播放完成再返回,
這時從傳入到經過阻塞出來就是一個buf的時間例如上面的30ms。
(2)然后buf"A"一直在播放,傳入buf"B"的外部buf把數據給buf"B"后 不立即返回,等到buf"A"播放完成再返回,
這時從傳入到經過阻塞出來就是一個buf的時間例如上面的30ms。
(3)循環上面(1)(2),即得到了如回調方式同樣的那個30ms時間。下面和回調方式一樣,見回調方式(4)(5)。
轉自 http://blog.csdn.net/zhuweigangzwg/article/details/25815851