http://6352513.blog.51cto.com/6342513/1180742
http://blog.csdn.net/happydeer/article/details/206765
http://blog.csdn.net/sidumqz/article/details/53102623
對pts、dts、duration的處理主要集中在兩大函數里面
1、process_input()讀入數據並處理,放到濾鏡里面
2、reap_filters()從濾鏡讀出數據,處理后寫入文件
媒體內容在播放時,最令人頭痛的就是音視頻不同步。從技術上來說,解決音視頻同步問題的最佳方案就是時間戳:
首先選擇一個參考時鍾(要求參考時鍾上的時間是線性遞增的);
生成數據流時依據參考時鍾上的時間給每個數據塊都打上時間戳(一般包括開始時間和結束時間);
在播放時,讀取數據塊上的時間戳,同時參考當前參考時鍾上的時間來安排播放(如果數據塊的開始時間大於當前參考時鍾上的時間,則不急於播放該數據塊,直到參考時鍾達到數據塊的開始時間;如果數據塊的開始時間小於當前參考時鍾上的時間,則“盡快”播放這塊數據或者索性將這塊數據“丟棄”,以使播放進度追上參考時鍾)。
圖2.8 解決音視頻同步問題的時間戳方案
可見,避免音視頻不同步現象有兩個關鍵——
一是在生成數據流時要打上正確的時間戳。如果數據塊上打的時間戳本身就有問題,那么播放時再怎么調整也於事無補。
如圖2.8,視頻流內容是從0s開始的,假設10s時有人開始說話,要求配上音頻流,那么音頻流的起始時間應該是10s,如果時間戳從0s或其它時間開始打,則這個混合的音視頻流在時間同步上本身就出了問題。
打時間戳時,視頻流和音頻流都是參考參考時鍾的時間,而數據流之間不會發生參考關系;也就是說,視頻流和音頻流是通過一個中立的第三方(也就是參考時鍾)來實現同步的。
第二個關鍵的地方,就是在播放時基於時間戳對數據流的控制,也就是對數據塊早到或晚到采取不同的處理方法。
圖2.8中,參考時鍾時間在0-10s內播放視頻流內容過程中,即使收到了音頻流數據塊也不能立即播放它,而必須等到參考時鍾的時間達到10s之后才可以,否則就會引起音視頻不同步問題。
基於時間戳的播放過程中,僅僅對早到的或晚到的數據塊進行等待或快速處理,有時候是不夠的。
如果想要更加主動並且有效地調節播放性能,需要引入一個反饋機制,也就是要將當前數據流速度太快或太慢的狀態反饋給“源”,讓源去放慢或加快數據流的速度。
熟悉DirectShow的讀者一定知道,DirectShow中的質量控制(Quality Control)就是這么一個反饋機制。DirectShow對於音視頻同步的解決方案是相當出色的。但WMF SDK在播放時只負責將ASF數據流讀出並解碼,而並不負責音視頻內容的最終呈現,所以它也缺少這樣的一個反饋機制。
為了更好地理解基於時間戳的音視頻同步方案,下面舉一個生活中的例子。假設你和你的一個朋友約好了今天18:00在滬上廣場見面,然后一起吃飯,再去打游戲。實際上,這個18:00就是你和你朋友保持同步的一個時間點。結果你17:50就到了滬上廣場,那么你必須等你的朋友。10分鍾過后,你的朋友還沒有到,這時他打來電話說有事耽擱了,要晚一點才能到。你沒辦法,因為你已經在旁邊的餐廳預訂了位置,如果不馬上趕過去,預訂就會被取消,於是你告訴你的朋友直接到餐廳碰頭吧,要他加快點。於是在餐廳將來的某個時間點就成為你和你朋友的又一個同步點。雖然具體時間不定(要看你朋友趕過來的速度),但這樣努力的方向是對的,你和你朋友肯定能在餐廳見到面。結果呢?你朋友終於在18:30趕過來了,你們最終“同步”了。吃完飯19:30了,你臨時有事要處理一下,於是跟你朋友再約好了20:00在附近的一家游戲廳碰頭。你們又不同步了,但在游戲廳將來的某個時間點你們還是會再次同步的。
悟出什么道理了沒有?其實,同步是一個動態的過程,是一個有人等待、有人追趕的過程。同步只是暫時的,而不同步才是常態。人們總是在同步的水平線上振盪波動,但不會偏離這條基線太遠。
在對音視頻重新編碼並需要進行同步的場景中,需要遵守幾項基本原則(否則音視頻就會卡頓,不流暢。以音頻aac編碼頻率44.1k,視頻h264編碼25幀幀率為例):
1. 保證輸入端的音視頻幀到達間隔基本精確。音頻aac每幀時長是23.2ms(1000*1024/44100),視頻每幀時長是40ms(1000/25)。所以,用於編碼的原始音頻samples的到達頻率(或從buffer中獲取的頻率)應該為441 samples/per channel/ per 10ms(每個樣本假設16bits,即882字節/通道/10ms,如果原始音頻采樣率不是44.1k,編碼前需要重新采樣);原始視頻幀到達頻率(或從buffer中獲取的頻率)應該為1幀/per 40ms(視頻幀率可能需要重新采樣)。如果輸出的音視頻流不流暢,可先檢查輸入端音視頻流的輸入間隔情況。
2.保證輸出端的音視頻流時間戳使用同一參考系。比如音視頻流都使用當前系統時間作為同一時間參考系,但音視頻流可以有不同的系統時間起始點。比如音頻流先開始於1492764087000 ms,視頻稍后700ms開始於1492764087700ms。比如rtmp里面使用32位時間戳,則音視頻流只能使用相對時間戳,接上例,音頻時間戳增長到700ms的時候視頻流才從0開始,表示視頻流是從音頻流的700ms處開始的,這樣才能達到同步的效果。 另外一種時間戳方案是每個音視頻幀按固定間隔增長,比如音視頻時間戳都從0開始,音頻每個aac幀增加23.2ms,每個視頻幀增長40ms。正常情況下,音視頻流是同時從0開始按相應各自間隔發送幀的,但也有視頻流晚於音頻流或音頻流晚於視頻流的情況。這種情況需要做時間戳同步,稍晚的流起始時間要根據超前的流的時間來設置。
3.保證交叉輸出時音視頻間隔基本精確。這里的輸出端就完全等同於一個硬件編碼器,只有保證交叉輸出的音視頻幀間隔穩定,才能保證播放端的流暢。比如rtmp,每個aac音頻幀輸出間隔應該在23ms左右,每個視頻幀輸出間隔應該在40ms左右,而且音視頻幀是交叉輸出。換句話說,每23ms要發送一個aac音頻幀,每40ms發送一個視頻幀(可以使用兩個單獨的線程來分別發送音視頻流)。如果排除了上面的兩個問題還是不能流暢播放,可以檢查這個環節是否正常。
總之,重新編碼並同步的這個環節,必須建立在數學測量的基礎上。有錯誤或補充的地方,歡迎指出。
================
http://www.cnblogs.com/my_life/articles/6944054.html
視頻中幀就是一個圖片采樣。音頻中一幀一般包含多個樣本,如AAC格式會包含1024個樣本。
http://blog.sina.com.cn/s/blog_6b87c7eb010182hs.html
http://www.jianshu.com/p/030288800a61
采樣頻率是指將模擬聲音波形進行數字化時,每秒鍾抽取聲波幅度樣本的次數。
正常人聽覺的頻率范圍大約在20Hz~20kHz之間,根據奈奎斯特采樣理論,為了保證聲音不失真,采樣頻率應該在40kHz左右。常用的音頻采樣頻率有8kHz、11.025kHz、22.05kHz、16kHz、37.8kHz、44.1kHz、48kHz等,如果采用更高的采樣頻率,還可以達到DVD的音質。
音頻
在數字音頻領域,常用的采樣率有:
- 8,000 Hz - 電話所用采樣率, 對於人的說話已經足夠
- 11,025 Hz
- 22,050 Hz - 無線電廣播所用采樣率
- 32,000 Hz - miniDV 數碼視頻 camcorder、DAT (LP mode)所用采樣率
- 44,100 Hz - 音頻CD, 也常用於MPEG-1 音頻(VCD, SVCD, MP3)所用采樣率
- 47,250 Hz - Nippon Columbia (Denon)開發的世界上第一個商用 PCM 錄音機所用采樣率
- 48,000 Hz - miniDV、數字電視、DVD、DAT、電影和專業音頻所用的數字聲音所用采樣率
- 50,000 Hz - 二十世紀七十年代后期出現的3M 和Soundstream 開發的第一款商用數字錄音機所用采樣率
- 50,400 Hz - 三菱 X-80 數字錄音機所用所用采樣率
- 96,000 或者 192,000 Hz - DVD-Audio、一些 LPCM DVD 音軌、BD-ROM(藍光盤)音軌、和 HD-DVD (高清晰度 DVD)音軌所用所用采樣率
- 2.8224 MHz - SACD、索尼 和 飛利浦 聯合開發的稱為Direct Stream Digital的1位sigma-delta modulation 過程所用采樣率。
采樣頻率定義了每秒從連續信號中提取並組成離散信號的采樣個數,采樣頻率的倒數是采樣周期或者叫作采樣時間,它是采樣之間的時間間隔
44100已是CD音質, 超過48000或96000的采樣對人耳已經沒有意義。這和電影的每秒 24 幀圖片的道理差不多。
AAC一幀可以解析出的音頻時長
- 一個AAC原始幀包含一段時間內1024個采樣及相關數據
- 音頻幀的播放時間=一個AAC幀對應的采樣樣本的個數/采樣頻率(單位為s)
- 一幀 1024個 sample。采樣率 Samplerate 44100KHz,每秒44100個sample, 所以 根據公式 音頻幀的播放時間=一個AAC幀對應的采樣樣本的個數/采樣頻率
- 當前AAC一幀的播放時間是= 1024*1000000/44100= 22.32ms(單位為ms)
(一個aac幀是由1024個樣本組成的,一秒內aac的采樣次數是44.1k次,所以一個aac幀的時長是1*1024/44.1k, 單位為秒)
對采樣率為44.1kHz的AAC音頻進行解碼時,一幀的解碼時間須控制在23.22毫秒內。
MP3一幀可以解析出的音頻時長
- mp3 每幀均為1152個字節 (樣本), 則:
- frame_duration = 1152 * 1000000 / sample_rate
- sample_rate = 44100HZ時, 計算出的時長為26.122ms,這就是經常聽到的mp3每幀播放時間固定為26ms的由來。
H264 視頻
視頻的一個幀的播放時間跟幀率有關:
frame_duration = 1000/幀率(fps)
例如:fps = 25.00 ,計算出來的時常為40ms,這就是同行所說的40ms一幀視頻數據。
================
http://blog.csdn.net/aoshilang2249/article/details/38469051
http://blog.csdn.net/ownWell/article/details/8114121
【采樣位數】
- 1 字節(也就是8bit) 只能記錄 256 個數, 也就是只能將振幅划分成 256 個等級;
- 2 字節(也就是16bit) 可以細到 65536 個數, 這已是 CD 標准了;
- 4 字節(也就是32bit) 能把振幅細分到 4294967296 個等級, 實在是沒必要了.
【交錯模式】
數字音頻信號存儲的方式。數據以 連續幀的方式存放,即首先記錄幀1的左聲道樣本和右聲道樣本,再開始幀2的記錄...
【非交錯模式】
以電話為例,每秒3000次取樣,每個取樣是7比特,那么電話的比特率是21000。而CD是每秒44100次取樣,兩個聲道,每個取樣是13位PCM編碼,所以CD的比特率是44100*2*13=1146600,也就是說CD每秒的數據量大約是144KB,而一張CD的容量是74分等於4440秒,就是639360KB=640MB。
最近研究了FFMPEG的同步技巧,覺得其精妙絕倫,完全不用擔心隨着時間的推移會發生如上問題!下面簡述下FFMPEG下如何進行音視頻同步的吧!
FFMPEG有三種同步方式,視頻同步音頻,音頻同步視頻,同步到外部時鍾!
第三種,同步到外部始終也就是PCR同步和我原來說的那中同步方式,一樣!
用的最多的還是,視頻同步音頻,為什么呢?
廢話少說了!用視頻同步音頻,做法很簡單!
1、幀率控制
幀率控制的方法有千萬種,最2的方法無非是每解碼/顯示一幀就進行延時,為了方便我們在進行幀率控制的同時能夠理解音視頻同步,我在此采用PCR同步的方式來進行幀率控制。網上關於PCR同步的原理講了一大堆,有些很是難懂,一點兒也不通俗,我這里來給大家把晦澀的理論以最通俗的方式表達出來。還希望大家多多指教!
拿1280x720@30p的視頻源來做理解。30P也就是說每秒鍾30幀,也就是每一幀需要1/30*1000ms大概也就是每隔33.33ms就必須顯示一幀。
要想知道如何正確的進行解碼,就必須先了解編碼端是如何工作的!
說了這么多,那么我就那個PCR信息來給大家分析分析。PCR信息是33bit組成的一個INT64_T的數據,從解復用器里面出來我們可以得到一個很龐大的數字,看這個我們當然看不太懂!但是如果知道這個數字如何生成的那就好理解多了!
PCR信息說白了就是給視頻的時間戳信息,比如一部電影是從 (00:01:23:033)時 : 分 : 秒 : 毫秒 開始,那么這個時間基點生成的PCR信息就是 (((00*60+1)*60+23.033)*90K)%2^33。90K為27M,300分頻的結果。 剛剛說了PCR會每30ms更新一次,那么PCR每次遞增的數值就為0.030*90K=2700,這和PTS的值原理是相同的,這里先提一下,其實這個增量也不重要。我們需要的知識第一個PCR值就OK,但是如果考慮到后期校准,還是要用到以后的PCR值的。這里先不管校准的問題!
說了PCR,還有個值是我們需要的,那就是PTS。其實對於硬解碼器來說DTS信息我們根本就不需要管他,我們只需要一幀一幀的把數據送進去,順便把每一幀的PTS信息送進去,解碼器送出來的就是排列好了PTS信息的幀了,其他解碼器不知道至少RK3288是這樣的。大家可以試着把解復用后的每一幀的PTS打印出來,你會發現在解復用后一般是這樣排列的9000 3000 6000 18000 12000 15000.......這種是AVC編碼的使用的是預測編碼決定的,先不管他,你只管這樣把沒一幀依次送入解碼器,解碼器解碼輸出后自然就排列成3000 6000 9000 12000 15000 18000這才是我們需要的PTS! 至於什么是PTS,實際上和PCR原理差不多,但是有個關鍵的地方PTS的增量值可不是默認的30ms了,他是由視頻的幀率來決定的!說道重要的地方了哈!根據上面PCR的原理,如果是30p的視頻那么每一幀就是1/30這么多的增量,再乘90K=3000。
說透了,我們這里就是利用這個PTS值來進行同步順便進行幀率控制!
關鍵的地方來了!
如果視頻流現在來了,我們先獲取到第一個PCR值為1230000,我們現在馬上在解碼器端重建一個90K的時鍾!這就是關鍵所在,至於如何重建90K的時鍾,說白了就是開一個定時器,定時時間為1/90K(11.11us),每隔11.11us我們就把PCR計數值+1,同時這時候解碼器也在工作,試想一下,如果是30P的視頻,也就是33.33ms顯示一次,那么當過了33.33ms后,PCR的數值加到好多了呢?沒錯就是33.33ms/11.11us=3000,這個增量不是和PTS的增量一摸一樣!這時候你只需要在解碼線程里判斷當前幀的PTS是不是和這個PCR相等,如果相等就顯示,如果PCR大可以丟棄當前幀,也就是說的跳幀,如果PCR小說明解碼快了,這個時候就可以等待定時器線程到PCR==PTS。
這樣就很巧妙的解決了幀率控制的問題了!同理,音視頻同步也可以這樣!你可以讓音頻的PTS去和PCR對比!其實大多數情況下都是以視頻同步音頻,音頻解碼不用管它,直接解碼播放就OK了,你只需要進行幀率控制就OK了!同時注意隨着時間的推移有可能出現延時,那么這個時候就需要重新來獲取PCR來更新定時器線程里面的PCR基值了!
=====================
http://www.cnblogs.com/NerdWill/p/6744432.html
在對音視頻重新編碼並需要進行同步的場景中,需要遵守幾項基本原則(否則音視頻就會卡頓,不流暢。以音頻aac編碼頻率44.1k,視頻h264編碼25幀幀率為例):
1. 保證輸入端的音視頻幀到達間隔基本精確。音頻aac每幀時長是23.2ms(1000*1024/44100),視頻每幀時長是40ms(1000/25)。所以,用於編碼的原始音頻samples的到達頻率(或從buffer中獲取的頻率)應該為441 samples/per channel/ per 10ms(每個樣本假設16bits,即882字節/通道/10ms,如果原始音頻采樣率不是44.1k,編碼前需要重新采樣);原始視頻幀到達頻率(或從buffer中獲取的頻率)應該為1幀/per 40ms(視頻幀率可能需要重新采樣)。如果輸出的音視頻流不流暢,可先檢查輸入端音視頻流的輸入間隔情況。
2.保證輸出端的音視頻流時間戳使用同一參考系。比如音視頻流都使用當前系統時間作為同一時間參考系,但音視頻流可以有不同的系統時間起始點。比如音頻流先開始於1492764087000 ms,視頻稍后700ms開始於1492764087700ms。比如rtmp里面使用32位時間戳,則音視頻流只能使用相對時間戳,接上例,音頻時間戳增長到700ms的時候視頻流才從0開始,表示視頻流是從音頻流的700ms處開始的,這樣才能達到同步的效果。 另外一種時間戳方案是每個音視頻幀按固定間隔增長,比如音視頻時間戳都從0開始,音頻每個aac幀增加23.2ms,每個視頻幀增長40ms。正常情況下,音視頻流是同時從0開始按相應各自間隔發送幀的,但也有視頻流晚於音頻流或音頻流晚於視頻流的情況。這種情況需要做時間戳同步,稍晚的流起始時間要根據超前的流的時間來設置。
3.保證交叉輸出時音視頻間隔基本精確。這里的輸出端就完全等同於一個硬件編碼器,只有保證交叉輸出的音視頻幀間隔穩定,才能保證播放端的流暢。比如rtmp,每個aac音頻幀輸出間隔應該在23ms左右,每個視頻幀輸出間隔應該在40ms左右,而且音視頻幀是交叉輸出。換句話說,每23ms要發送一個aac音頻幀,每40ms發送一個視頻幀(可以使用兩個單獨的線程來分別發送音視頻流)。如果排除了上面的兩個問題還是不能流暢播放,可以檢查這個環節是否正常。
總之,重新編碼並同步的這個環節,必須建立在數學測量的基礎上。有錯誤或補充的地方,歡迎指出。
======================
http://www.xuebuyuan.com/1400936.html
視頻、音頻打時間戳的方法
http://blog.csdn.net/wfqxx/article/details/5497138
AVCodecContext *m_VCtx;
一 固定幀率
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);
注:見AVCodecContext 的代碼注釋:
對於固定幀率, timebase == 1/framerate
framerate = fps
2. 音頻時間戳
pts = inc++ * (frame_size * 1000 / sample_rate)
在ffmpeg中的代碼為
pkt.pts= m_nAudioTimeStamp++ * (m_ACtx->frame_size * 1000 / m_ACtx->sample_rate);
注: frame_size: Number of samples per channel in an audio frame. 每個音頻幀的 sample 個數.
采樣頻率是指將模擬聲音波形進行數字化時,每秒鍾抽取聲波幅度樣本的次數。
正常人聽覺的頻率范圍大約在20Hz~20kHz之間,根據奈奎斯特采樣理論,為了保證聲音不失真,采樣頻率應該在40kHz左右。常用的音頻采樣頻率有8kHz、11.025kHz、22.05kHz、16kHz、37.8kHz、44.1kHz、48kHz等,如果采用更高的采樣頻率,還可以達到DVD的音質
對采樣率為44.1kHz的AAC音頻進行解碼時,一幀的解碼時間須控制在23.22毫秒內。
背景知識:
(一個AAC原始幀包含一段時間內1024個采樣及相關數據)
(一個MP3原始幀包含一段時間內1152個采樣及相關數據)
分析:
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毫秒(1s=1000ms; 1000ms / 25 = 40 ms)的間隔,而是50,60,甚至100不等的時間間隔。這就給編碼后打時間戳帶來很大的困難。
在libav里,我們的默認編碼參數都是:
ptAvEncoder->ptAvStreamVideo->codec->time_base.den = s32Fps; //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,所以也化成了毫秒單位。
=============示例AVInputFormat mio===========
音頻基本信息初始化(read_header):
st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
st->codecpar->sample_rate = 48000;
st->codecpar->channels = 2;
avpriv_set_pts_info(st, 64, 1, AV_TIME_BASE); /* 64 bits pts in us */
// to assume AAC encode
md->a_frame_duration = AV_TIME_BASE * 1024 / st->codecpar->sample_rate; //每個音頻幀的時長
給音頻幀打時間戳(read_packet):
int64_t ats = 0;
av_init_packet(&pkt);
pkt.pts = (ats += a_frame_duration); //計算方式其實跟上面 pts = inc++ * (frame_size * 1000 / sample_rate)一樣
pkt.dts = pkt.pts;
pkt.data = (uint8_t *)abuf;
pkt.size = rtval;
pkt.stream_index = audio_index;
====視頻基本信息的初始化==
st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
st->codecpar->width = vhcnt;
st->codecpar->height = vvcnt;
st->codecpar->codec_id = AV_CODEC_ID_RAWVIDEO;
st->codecpar->format = AV_PIX_FMT_UYVY422;
st->codecpar->codec_tag = MKTAG('U', 'Y', 'V', 'Y');
st->time_base = av_make_q(1, 25); //25: 幀率
st->avg_frame_rate = av_inv_q(st->time_base);
md->v_frame_duration = av_q2d(st->time_base) * AV_TIME_BASE; //每個視頻幀的時長
avpriv_set_pts_info(st, 64, 1, AV_TIME_BASE); /* 64 bits pts in use */
給視頻幀打時間戳(read_packet):
int64_t vts = 0;
av_init_packet(&pkt);
pkt.pts = (vts += v_frame_duration);
pkt.dts = pkt.pts;
pkt.data = (uint8_t *)vbuf;
pkt.size = rtval;
pkt.stream_index = video_index;