1. 程式人生 > >使用ffmpeg製作視訊播放器(分享原始碼)

使用ffmpeg製作視訊播放器(分享原始碼)

使用ffmpeg製作c++視訊播放器(分享原始碼)

    專案地址: 點選開啟連結,歡迎pr。

    本專案採用ffmpeg解碼視訊檔案,使用多執行緒處理解碼等操作,是學習多執行緒的不錯的機會,在這個專案開發過程中鞏固了不少多執行緒的知識,視訊的處理主要是ffmpeg,音訊採用SDL播放,介面使用QT,使用QTmer定時器去重新整理一幀幀的視訊。音視訊同步的採用視訊追逐音訊的方式實現的同步,缺點是當視訊執行緒處理緩慢的時候會出現視訊過慢,但是一會就回追上音訊,這種現象出現的非常少。專案的結構如下:


   1,專案中的多執行緒

  執行緒使用的是Qt自帶的QThread,主要有兩條執行緒,一個解壓音視訊檔案獲取音視訊包的執行緒,一個解碼視訊包將視訊包中的視訊幀讀出到幀佇列的執行緒。除了這兩個執行緒另外還有一個音訊處理 的回撥函式,和一個重新整理視訊的定時器,這幾部分構成了整個專案的骨架。本專案使用QWaitCondition,QMutex和QMutexLocker保護執行緒安全,使用兩個執行緒安全的佇列分別儲存視訊包,視訊幀。

2,關於音視訊同步

       音視訊同步是這個專案最複雜的部分了,弄了好久,最後還是參考網上的教程程式碼實現了同步。由於音訊是線性儲存在音視訊檔案中的,所以直接解壓後解碼,用SDL相關的api就可以播放了。而視訊不一樣,視訊幀有好幾種,I幀,B幀和P幀。每一幀有一個播放時間pts和解碼時間dts,視訊幀有很多重複幀,需要跳過他們,然後可以根據前後兩幀(應該播放的幀)的pts和音訊的pts比較進行音視同步。因為音訊時間是沒問題的,只要讓視訊跟上音訊就行。計算下一幀的視訊pts方法也很簡單,把大約十幾二十幀存到幀佇列,獲取前後兩幀的pts就可以了,如果視訊pts稍微比音訊快,就延長視訊重新整理的時間,比音訊慢就減少延時時間。這個音視同步的方法效果很不錯了,之前嘗試了使用系統時鐘來實現同步,總體效果還行,但是如果要控制視訊進度就麻煩了,進度可以調整,但是系統時間是不可以調整啊,硬要使用這個方法也不是不可以,只是比直接視訊追音訊麻煩太多。至於還有一個同步方法,音視追逐視訊,,,音訊本來好好的,硬要改變反而不好。

3,視訊filter

      處理視訊的一些特效我直接用一個過濾器來處理了,每一個特效當做一個任務,放在任務集合裡面,每播放一幀視訊之前,視訊幀經過集合中的各個任務處理後,被QT訊號傳送出去,ui執行緒接收這一幀影象,顯示出來,這個視訊功能比較少,以後會增加,有了這個過濾器,增加新功能就簡單多了。只要使用一下步驟:1,建立任務,2,新增實現演算法的方法,3,將任務和演算法放在過濾器對應的地方,4,修改介面讓使用者新增任務到任務佇列。後面程式碼過濾器的位置就不要改變就行。

專案地址: 點選開啟連結,歡迎pr,因為這個播放器功能還是很少的,以後還會繼續增加他的功能。