用FFMPEG SDK進行視頻轉碼壓縮時解決音視頻不同步問題的方法(轉) PTS DTS

用FFMPEG SDK進行視頻轉碼壓縮的時候,轉碼成功后去看視頻的內容,發現音視頻是不同步的。這個的確是一個惱火的事情。我在用FFMPEG SDK做h264格式的FLV文件編碼Filter的時候就碰到了這個問題。

??????? 經過研究發現,FFMPEG SDK寫入視頻的時候有兩個地方用來控制寫入的時間戳,一個是AvPacket, 一個是AvFrame。 在調用avcodec_encode_video的時候需要傳入AvFrame的對象指針,也就是傳入一幀未壓縮的視頻進行壓縮處理,AvFrame包含一個pts的參數,這個參數就是當前幀將來在還原播放的時候的時間戳。而AvPacket里面也有pts,還有dts。說起這個就必須要說明一下I,P,B三種視頻壓縮幀。I幀就是關鍵幀,不依賴于其他視頻幀,P幀是向前預測的幀,只依賴于前面的視頻幀,而B幀是雙向預測視頻幀,依賴于前后視頻幀。由于B幀的存在,因為它是雙向的,必須知道前面的視頻幀和后面的視頻幀的詳細內容后,才能知道本B幀最終該呈現什么圖像。而pts和dts兩個參數就是用來控制視頻幀的顯示和解碼的順序。

????? pts就是幀顯示的順序。

????? dts就是幀被讀取進行解碼的順序。

???? 如果沒有B幀存在,dts和pts是相同的。反之,則是不相同的。關于這個的詳細介紹可以參考一下mpeg的原理。

再說說AvPacket中包含的pts和dts兩個到底該設置什么值?

pts和dts需要設置的就是視頻幀解碼和顯示的順序。每增加一幀就加一,并不是播放視頻的時間戳。

但是實踐證明經過rmvb解碼的視頻有時候并不是固定幀率的,而是變幀率的,這樣,如果每壓縮一幀,pts和dts加一的方案為導致音視頻不同步。

那怎么來解決音視頻同步的問題呢?

請看如下代碼段。

lTimeStamp 是通過directshow 獲取的當前的視頻幀的時間戳。

m_llframe_index為當前已經經過壓縮處理的幀的數量。

首先av_rescale計算得到當前壓縮處理已經需要處理什么時間戳的視頻幀,如果該時間戳尚未到達directshow當前提供的視頻幀的時間戳,則將該幀丟棄掉。

否則進行壓縮操作。并設置AVPacket的pts和dts。這里假設B幀不存在。

因為在將來播放的時候視頻以我們設定的固定播放幀率進行播放,所以需要根據設定的播放幀率計算得到的視頻幀時間戳和directshow提供的當前視頻幀的時間戳進行比較,設定是否需要進行實施延緩播放的策略。如果需要延緩播放,則將pts增加步長2,否則以普通速度播放,則設置為1.dts與之相同。
__int64 x = av_rescale(m_llframe_index,AV_TIME_BASE*(int64_t)c->time_base.num,c->time_base.den);

if( x > lTimeStamp )
{
return TRUE;
}
m_pVideoFrame2->pts = lTimeStamp;
m_pVideoFrame2->pict_type = 0;

int out_size = avcodec_encode_video( c, m_pvideo_outbuf, video_outbuf_size, m_pVideoFrame2 );
/* if zero size, it means the image was buffered */
if (out_size > 0)
{
AVPacket pkt;
av_init_packet(&pkt);

if( x > lTimeStamp )
{
?? pkt.pts = pkt.dts = m_llframe_index;
?? pkt.duration = 0;
}
else
{
?? pkt.duration = (lTimeStamp - x)*c->time_base.den/1000000 + 1;
?? pkt.pts = m_llframe_index;
?? pkt.dts = pkt.pts;
?? m_llframe_index += pkt.duration;
}

//pkt.pts = lTimeStamp * (__int64)frame_rate.den / 1000;
if( c->coded_frame && c->coded_frame->key_frame )
{
??? pkt.flags |= PKT_FLAG_KEY;
}

pkt.stream_index= m_pVideoStream->index;
pkt.data= m_pvideo_outbuf;
pkt.size= out_size;

/* write the compressed frame in the media file */
ret = av_interleaved_write_frame( m_pAvFormatContext, &pkt );
}
else
{
ret = 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/254431.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/254431.shtml
英文地址,請注明出處:http://en.pswp.cn/news/254431.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

深度學習環境搭建(GPU)CUDA安裝(完全版)

文章目錄1、查詢電腦硬件2、環境搭建與軟件安裝1、安裝CUDA運算平臺軟件2、安裝cuDNN支持包3、配置環境變量3、驗證CUDA與cuDNN安裝前幾天在看深度學習。因為對深度學習不是很了解,在配置環境時走了許多彎路,也總是戰戰兢兢的。現在對深度學習的環境搭建…

Linux 中的文件壓縮與解壓

.tar tar xvf FileName.tar # 解壓 tar cvf FileName.tar DirName # 壓縮 .gz gunzip FileName.gz # 解壓 gzip -d FileName.gz # 解壓 gzip FileName # 壓縮 .tar.gz 和 .tgz tar zxvf FileName.tar.gz # 解壓 tar zcvf FileName.tar.gz DirName # 壓縮 .bz2 bzip2 -d FileNam…

Unity3D游戲開發之自由視角下的角色控制

秦元培的博客:http://blog.csdn.net/qinyuanpei/article/details/39125353 1,[Unity3D]Unity3D游戲開發之角色控制漫談 2,[Unity3D]Unity3D游戲開發之自由視角下的角色控制 3,[Unity3D]Unity3D游戲開發之仿仙劍奇俠傳角色控制效果 轉載于:h…

Pycharm用鼠標滾輪控制字體大小

一、pycharm字體放大的設置 File —> setting —> Keymap —>在搜尋框中輸入:increase —> Increase Font Size(雙擊) —> 在彈出的對話框中選擇Add Mouse Shortcut 在彈出的對話框中同時按住ctrl鍵和鼠標滾輪向上滑。 二、…

Halcon自定義函數封裝方法(全網最詳細)

文章目錄1、名詞解釋2、例子介紹1、處理原圖與任務:2、代碼與解析:3、Halcon函數封裝方式①明確需求②選取函數部分進行函數創建,更改函數接口③運行驗證與函數更改操作有網友說不太清楚這個halcon函數的封裝方法。今天寫個教程帖子&#xff…

ffmpeg庫音頻解碼示例

#include <stdio.h> #include <stdlib.h> extern "C"{// #include "avcodec.h" #include "avformat.h" } int main(char arg,char *argv[]) { char *filename "02.swf"; av_register_all();//注冊所有可…

SQL Where in list 問題

不過,這種做法有兩個缺陷1.Oracle In列表的數目有限制(1000)2.不能復用執行計劃,每次幾乎都是硬解析.3.In拼接可能存在SQL注入的風險

readn writen實現linux下socket緩沖區讀寫

socket上的read write 操作不同與一般的文件IO操作&#xff0c;socket上的用read write讀寫的字節數可能比要求的少,但這并不是錯誤&#xff0c;原因是socket的緩沖區可能已經達到了極限。此時所需要的就是再次調用read write 以寫入或輸出剩余的字符。這種情況在socket中很常見…

傅里葉變換進行缺陷檢測detect_indent_fft.hdev(源代碼與詳細解析)

文章目錄簡介程序解析處理結果預覽算法講解簡介 detect_indent_fft.hdev是halcon的示例程序&#xff0c;是傅里葉變換進行缺陷檢測的一個例子&#xff0c;主要是傅里葉變換在復雜背景下的缺陷檢測。 這個程序展示了如何利用快速傅里葉變換&#xff08;FFT&#xff09;對塑料制…

lua環境搭建

前言 Linux & Mac上安裝 Lua 安裝非常簡單&#xff0c;只需要下載源碼包并在終端解壓編譯即可&#xff0c;本文介紹Linux 系統上&#xff0c;lua5.3.0版本安裝步驟&#xff1a; Linux 系統上安裝 [rootgitlab ~]# mkdir /app/tools/lua -p [rootgitlab ~]# cd /app/tools/l…

八、job管理

查看用法&#xff1a; [rootsuper65 ~]# salt-run -d|grep jobsjobs.active:                      #查看當前執行的job Return a report on all actively running jobs from a job id centric salt-run jobs.activejobs.list_job: salt-run jobs.list_j…

pthread_join/pthread_exit用法實例

函數pthread_join用來等待一個線程的結束。函數原型為&#xff1a;   extern int pthread_join __P ((pthread_t __th, void **__thread_return));   第一個參數為被等待的線程標識符&#xff0c;第二個參數為一個用戶定義的指針&#xff0c;它可以用來存儲被等待線程的返回…

thinkphp5 內置接口開發與使用

最近的一個項目在用tp5&#xff0c;對于tp3都幾乎沒用過的我來說~~~ tp5最好的一點就是對接口的單獨封裝&#xff0c;只要嚴格按照要求一步一步來就可以成功了 開啟命令行&#xff1a;配置環境變量安裝tp5項目cmd進入項目目錄&#xff0c;運行php think&#xff0c;出現如下內容…

Halcon2019軟件安裝教程

文章目錄1、halcon介紹2、安裝halcon-19.11.0.0-windows.exe1、下載halcon-19.11.0.0-windows.exe安裝包2、halcon-19.11.0.0-windows.exe軟件安裝3、驗證Halcon安裝1、halcon介紹 HALCON是德國MVtec公司開發的一套完善的標準的機器視覺算法包&#xff0c;擁有應用廣泛的機器視…

爬蟲常用庫的安裝

請求庫(requests,selenium)、解析庫(beautifulsop)、存儲庫、工具庫等 urelib re 上面這兩個是python自帶的庫 需要自己安裝額庫&#xff1a; (在windows下&#xff0c;使用pip install 命令) requests selenium用來驅動瀏覽器&#xff0c;做自動化測試&#xff0c;一些被js…

Python: 編程遇到的一些問題以及網上解決辦法?

0.Python: TypeError: str does not support the buffer interface,(點我) fp.write(url.encode("utf-8")) 1.Python:object of type Response has no len()&#xff0c;如何解決&#xff1f;(點我) Traceback (most recent call last):File "F:/Python/TD.py&q…

快排簡要介紹

<!DOCTYPE html><html lang"en"><head> <meta charset"UTF-8"> <title>Title</title></head> <body> <script> var arr [6,10,2,9,3,8,11,4,5]; function quickSort(data, start, end) { // 確定要…

在django中使用celery

前言: 針對高延時任務, 直接在一次網絡請求中處理完畢會導致很不好的體驗, celery則可以不阻塞請求后臺處理這些任務, 并且可以使用django的models進行數據庫操作.環境 python models: celery-4.1.1redis-2.10.6django-1.11.7其他: redis-3.2.9macospython3.6創建django工程 dj…

關于pragma pack的用法(一)

一個很重要的參數#pragma pack(n)數據邊界對齊方式:以如下結構為例: struct {char a;WORD b;DWORD c;char d;}在Windows默認結構大小: sizeof(struct) 444416;與 #pragma pack(4)一樣若設為 #pragma pack(1), 則結構大小: sizeof(struct) 12418;若設為 #pragma pack(2), 則…

TCL語言筆記:TCL中的String命令

一、介紹 字符串是 Tcl 中的基本數據類型&#xff0c;所以有大量的字符串操作命令。一個比較重要的問題就是模式匹配&#xff0c;通過模式匹配將字符串與指定的模式&#xff08;格式&#xff09;相匹配來進行字符串的比較、搜索等操作。 二、string命令列表 命 令 說 …