http://blog.csdn.net/wfqxx/article/details/5497138
一 固定幀率
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的由來。
二 可變幀率
有很多的采集卡,攝像頭,在做采集的時候,明明設定的25FPS,但實際采集資料回調過來,發現并不是40毫秒的間隔,而是50,60,甚至100不等的時間間隔。
這就給編碼後打時間戳帶來很大的困難。
在libav裡,我們的預設編碼參數都是:
ptAvEncoder->ptAvStreamVideo->codec->time_base.den = s32Fps;
ptAvEncoder->ptAvStreamVideo->codec->time_base.num = 1;
這樣在編碼後的時間戳以1遞增,隻适合于固定幀率。
我們來改一下:
ptAvEncoder->ptAvStreamVideo->codec->time_base.den = s32Fps * 1000;
ptAvEncoder->ptAvStreamVideo->codec->time_base.num = 1* 1000;
這樣就把時間戳的scale變成了毫秒,就可以以毫秒為機關進行計算了,如下:
tAvPacket.pts = ((s64)u32TimeStamp * (s64)s32Fps);
u32TimeStamp是從開始記錄的時間內插補點,以毫秒為機關;s32Fps是幀率。
對于音頻,mp4檔案預設是采樣率為tick的,時間戳計算為:
tAvPacket.pts = (AvEncoderAudioInSizeGet(hHandle) * ( (s64)(u32TimeStamp)) / (AvEncoderAudioInSizeGet(hHandle) * 1000 / ptAvEncoder->ptAvStreamAudio->codec->sample_rate);
AvEncoderAudioInSizeGet(hHandle) 每次編碼器需要的PCM資料長度。
u32TimeStamp是從開始記錄的時間內插補點,以毫秒為機關。
ptAvEncoder->ptAvStreamAudio->codec->sample_rate PCM采樣率,代表一秒的資料量。
因為乘以了1000,是以也化成了毫秒機關。