2015-05-31 95 views
3

嘗試通過的ffmpeg瞭解一些音頻/視頻同步問題,我注意到以下。運行此代碼爲什麼在AVFrame packet.pts!=幀 - > pkt_pts?

while (av_read_frame(formatCtx, &packet) >= 0) 
{ 
    if (packet.stream_index == videoStream) 
    { 
     avcodec_decode_video2(videoCodecCtx, frame, &got_frame, &packet); 
    } 

    printf("packet.pts = %d\n", packet.pts); 
    printf("frame->pkt_pts", frame->pkt_pts); 
} 

表明,幀 - > pkt_pts在從packet.pts一般儘管不同的文檔聲稱幀 - > pkt_pts是

PTS從被解碼爲AVPacket複製產生這個框架

此外我注意到,兩者之間的差異大到恰恰在音頻和視頻不同步的地方。

那麼,爲什麼packet.pts != frame->pkt_pts

回答

5

視頻可能已延遲的幀,這意味着輸入幀和輸出幀可以指不同地排序單元。例如。在MPEG的情況下,IBP的顯示順序被編碼爲IPB,和輸入的PTS是從輸出不同的,並且重排序引入輸入的PTS和輸出點之間的延遲。此外,使用多線程解碼時,會在輸入和輸出之間添加n_threads的附加延遲 - 1個數據包。在所有這些情況下,pkt.pts!= frame-> pkt_pts。爲了顯示,你應該依賴frame-> pkt_pts。

+0

你的意思是說,'avcodec_decode_video2(videoCodecCtx,框架,和got_frame,和包)'實際上可能不解碼'packet'但來得更早一些包?請注意,就我而言,所有框架都是關鍵幀(用拉加斯編碼)。我已經注意到frame-> pkt_pts實際上似乎一直落後於packet.pts兩個單位。根據你的解釋,這將適合avcodec_decode_video2的前兩個調用未能解碼任何幀。 P.S .:不幸的是,我不能滿足你的答案,因爲我沒有足夠的聲譽。 – BlenderBender

+0

對於關鍵幀,這是因爲我們使用多線程解碼。所以,假設你有2個線程,每個線程解碼一個獨立的關鍵幀。爲了使它們全部工作,頭2次調用decode_video2()會消耗一個數據包並立即返回,而不會返回一個已解碼的幀。線程在後臺解碼每一幀。 decode_video2()的第三次調用會阻塞,等待第一個返回,並且一旦它發生,它會給它一個新的數據包進行解碼,並且您將返回第一個數據包。所以當時的滯後時間是2,甚至認爲它只是關鍵幀。 –