[導讀]一.音視頻同步的原理 mp4v2內部采用一套時間刻度基準,由我們自己設定,不一定是采用我們常用的1秒有1000個單位(毫秒)??赡苁?秒里有90000個單位或80000個單位。音頻和視頻可以采用
一.音視頻同步的原理 mp4v2內部采用一套時間刻度基準,由我們自己設定,不一定是采用我們常用的1秒有1000個單位(毫秒)??赡苁?秒里有90000個單位或80000個單位。音頻和視頻可以采用不同的時間刻度基準,只是為方便區(qū)分,大都采用不同的刻度。 我們在每次向mp4文件寫數(shù)據時(調用函數(shù)MP4WriteSample),就需要考慮上一次寫數(shù)據和這一次寫數(shù)據之間的時間間隔,把這個間隔換算成mp4v2內部的時間刻度基準間隔值(duration),然后mp4v2按照這個刻度基準間隔值(duration)把這一次數(shù)據放在對應的位置上。例子說明:用時間戳實時修改mp4v2里的上下幀間隔對應的ticks值。1.mp4v2庫初始化時?音頻使用48000刻度基準,視頻使用90000刻度基準。不采用固定幀間隔對應的ticks(duration)。①H264--視頻初始化 MP4AddH264VideoTrack(MP4File,TimeScale, MP4_INVALID_DURATION,width, height, spsBuf[1], spsBuf[2], spsBuf[3], 3); 第二個參數(shù)TimeScale的值是90000(也可以是別的值,在計算上下幀對應的ticks值時,需要使用這個刻度基準)。第三個參數(shù)值采用MP4_INVALID_DURATION,意思是我們使用變化的ticks,也就是函數(shù)MP4WriteSample里的第5個參數(shù)。如果幀與幀間隔值比較固定,也可以把第三個參數(shù)值寫成固定的對應ticks,比如每秒固定有25幀數(shù)據,那么第三個參數(shù)值可以是:duration= (1/25)秒/(1/90000) = 36000;duration = (timestamp-lasttimestamp)/(1/timescale)②.Audio--音頻初始化 MP4AddAudioTrack(MP4File, TIMESCALE,MP4_INVALID_DURATION , MP4_MPEG4_AUDIO_TYPE); 第二個參數(shù)TIMESCALE的值是48000(也可以是別的值,在計算上下幀對應的ticks值時,需要使用這個刻度基準。很多人用采樣率,雖然是建議,但容易產生概念混淆。這個值我們把它設置成1000都可以)。第三個參數(shù)值采用MP4_INVALID_DURATION,同理①。2.在向mp4文件實時寫數(shù)據 利用音視頻的時間戳間隔換算來變化的ticks。(向文件寫的第一幀數(shù)據需再優(yōu)化處理,否則mp4文件無法單個循環(huán)播放)。我使用AudioDuration代表音頻數(shù)據上下幀對應的ticks值;使用VideoDuration代表視頻數(shù)據上下幀對應的ticks值。 ①向mp4文件寫的第一幀數(shù)據需要注意。 我寫第一幀數(shù)據的ticks值采用了固定值(隨意的經驗值): vedio使用MP4WriteSample(MP4File, VideoId, (const uint8_t *)buf, (int)(pbuf - buf),3600,0,true); audio使用MP4WriteSample(MP4File, VideoId, (const uint8_t *)buf, (int)(pbuf - buf), 400+VideoDuration,0,true) ②.向mp4文件寫其他幀數(shù)據時,視頻和音頻上下幀間隔對應的ticks值使用公式: Duration = (timestamp-lasttimestamp)/(1/timescale)二.備注: ①.模數(shù)轉換,在模擬采樣音頻的時候,1幀(數(shù)據包)音頻包含1024(1024是底層硬件進行模數(shù)轉換時使用的固定值,大都用這個數(shù)值)個采樣。例如使用48k的音頻采樣,那么1秒就有48000/1024個幀,約47幀。這些數(shù)據包按時間先后順序和視頻數(shù)據包安放在一起。所以會發(fā)現(xiàn)一包音視頻數(shù)據中,有1幀視頻和2-3幀音頻。 而在嵌入式內部對這些數(shù)據處理(比如向mp4文件寫數(shù)據)是一種純數(shù)字化的處理,和采樣率關系已經不大。 ②.在使用時間戳實時修改mp4v2里的上下幀間隔對應的ticks值這種方式時,發(fā)現(xiàn)在關閉文件時需要等很久才成功、形成可播放的mp4文件(或形成的mp4文件無法播放)。我們可以參照mp4v2庫的源碼添加打印,依次跟蹤,解決問題。 但我發(fā)現(xiàn)在移植mp4v2源碼到嵌入式海思平臺時,修改配置項時使用命令CC=arm-hisiv100nptl-linux-gcc CXX=arm-hisiv100nptl-linux-g++ ./configure --host=arm-hisiv100nptl-linux --prefix=/usr/local/mp4v2 --disable-option-checking --disable-debug --disable-optimize --disable-fvisibility --disable-gch --disable-largefile --disable-util --disable-dependency-tracking --disable-libtool-lock,編譯生成的庫用到設備里,就不會產生無法立刻形成mp4文件問題。具體移植方法參考我另一個博客文章“mp4v2源碼編譯并移植到海思平臺”.三.其他函數(shù)說明 許多函數(shù)說明可以參考File.h中的注釋解釋。 ①創(chuàng)建文件時, tsThis->m_pMP4File = MP4CreateEx(filename,MP4_CREATE_64BIT_DATA,1,1,0,0,0,0); MP4CreateEx的第二個參數(shù),標記允許文件總大小超過64位的數(shù)據。我理解的是,允許單個mp4文件的容量超過2^32KB=4GB。 ②關閉文件時, MP4Close(tsThis->m_pMP4File,MP4_CLOSE_DO_NOT_COMPUTE_BITRATE); 第二個參數(shù),在關閉文件時,不計算整個文件的大小,這樣可以更快關閉文件。
本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯(lián)系該專欄作者,如若文章內容侵犯您的權益,請及時聯(lián)系本站刪除。