avcodec_decode_video2()解码视频后丢帧的问题解决
生活随笔
收集整理的這篇文章主要介紹了
avcodec_decode_video2()解码视频后丢帧的问题解决
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
使用libav轉碼視頻時發現一個問題:
使用下面這段代碼解碼視頻時,視頻尾巴上會丟掉幾幀。
while(av_read_frame(ifmt_ctx,&packet) >= 0){ret = avcodec_decode_video2(video_dec_ctx, vframe, &got_frame, &packet);if (got_frame) {packet.pts = av_rescale_q(packet.pts,video_dec_st->time_base,video_enc_st->time_base);write_video_frame(ofmt_ctx,video_enc_st,vframe);} }這是因為源視頻中PTS與DTS的不同造成的。
av_read_frame()按照PTS順序讀幀的時候,如果此幀需要參考后面的幀,那么此時avcodec_decode_video2()是沒有能力解碼此幀的,表現為got_frame返回0。
比如說遇上如下EFGH四幀:
ID : E F G H
KIND: I B P P
PTS : 1 2 3 4
DTS : 1 4 2 3
那么順序讀到F時,由于F需要參考G幀,而此時我們還沒讀到G幀,我們是沒有解碼F的能力的,got_frame就返回0了。如果我們對此事不做處理,那么我們就會丟掉一個幀(但丟掉的未必是F,因為av_read_frame()和avcodec_decode_video2()是1:1調用的)。
所以我們需要在while(av_read_frame())讀完整個視頻后,繼續調用avcodec_decode_video2()把之前那些沒有成功解碼的幀都解出來。調用的次數就是之前got_frame返回0的次數。
按照上述思路變更代碼為以下,成功找回丟失的幀。
int skipped_frame = 0;while(av_read_frame(ifmt_ctx,&packet) >= 0){ret = avcodec_decode_video2(video_dec_ctx, vframe, &got_frame, &packet);if (got_frame) {packet.pts = av_rescale_q(packet.pts,video_dec_st->time_base,video_enc_st->time_base);write_video_frame(ofmt_ctx,video_enc_st,vframe);}else{skipped_frame++;} }for(int i=skipped_frame; i>0; i--) {ret = avcodec_decode_video2(video_dec_ctx, vframe, &got_frame, &packet);if (got_frame) {packet.pts = av_rescale_q(packet.pts,video_dec_st->time_base,video_enc_st->time_base);write_video_frame(ofmt_ctx,video_enc_st,vframe);} }?
轉載于:https://www.cnblogs.com/yinxiangpei/articles/3891827.html
總結
以上是生活随笔為你收集整理的avcodec_decode_video2()解码视频后丢帧的问题解决的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: js之base64上传图片
- 下一篇: 计算机网络知识简单介绍