ffmpeg對視頻文件進行解碼的大致流程

音視頻同步原理[ffmpeg]
2010年08月25日 星期三 12:11

 

ffmpeg對視頻文件進行解碼的大致流程

1. 註冊所有容器格式和CODEC: av_register_all()

2. 打開文件: av_open_input_file()

3. 從文件中提取流信息: av_find_stream_info()

4. 窮舉所有的流,查找其中種類爲CODEC_TYPE_VIDEO

5. 查找對應的解碼器: avcodec_find_decoder()

6. 打開編解碼器: avcodec_open()

7. 爲解碼幀分配內存: avcodec_alloc_frame()

8. 不停地從碼流中提取中幀數據: av_read_frame()

9. 判斷幀的類型,對於視頻幀調用: avcodec_decode_video()

10. 解碼完後,釋放解碼器: avcodec_close()

11. 關閉輸入文件:av_close_input_file()

output_example.c 中AV同步的代碼如下(我的代碼有些修改),這個實現相當簡單,不過挺說明問題。

閱讀前希望大家先了解一下時間戳的概念。

/* compute current audio and video time */
if (pOutputVars->pOutAudio_st)//存在音頻流
pOutputVars->audio_pts = (double)pOutputVars->pOutAudio_st->pts.val
* pOutputVars->pOutAudio_st->time_base.num
/ pOutputVars- >pOutAudio_st->time_base.den; //(pts是時間戳結構)輸出音頻的時間戳, 轉換爲基準時間
else
pOutputVars->audio_pts = 0.0;

if (pOutputVars->pOutVideo_st)
pOutputVars->video_pts = (double)pOutputVars->pOutVideo_st->pts.val
* pOutputVars->pOutVideo_st->time_base.num / pOutputVars- >pOutVideo_st->time_base.den;//輸出視頻時間戳
else
pOutputVars->video_pts = 0.0;

if (!pOutputVars->pOutAudio_st && !pOutputVars->pOutVideo_st)
return 0;

/* write interleaved audio and video frames */
if (!pOutputVars->pOutVideo_st || (pOutputVars->pOutVideo_st && pOutputVars->pOutAudio_st && pOutputVars->audio_pts <
pOutputVars->video_pts))
{
   write_audio_frame(pOutputVars->pOutFormatCtx, pOutputVars->pOutAudio_st, pInputAudioBuf);
   //沒有視頻流,或者音頻流時間沒趕上視頻流(通過比較時間戳), 則輸出(編碼輸出)音頻禎數據
}
else
{
write_video_frame(pOutputVars->pOutFormatCtx, pOutputVars->pOutVideo_st, pInputVedioFrame);//否則輸出視頻禎數據
}

輸出數據的時間戳怎麼得到的, 以音頻爲例:
   pkt.size= avcodec_encode_audio(c, audio_outbuf, audio_outbuf_size, pInputAudioBuf);//源數據應該包含時間戳, pInputAudio是源文
件解碼後的音頻數據
   pkt.pts= av_rescale_q(c->coded_frame->pts, c->time_base, st->time_base);//編碼後的禎也含有源文件的時間戳,這個函數應該是轉換同時
間基準,沒研究過
   pkt.flags |= PKT_FLAG_KEY;
   pkt.stream_index= st->index;
   pkt.data= audio_outbuf;
...
應該就是這麼個過程了,然後用av_write_frame(oc, &pkt), 把音頻禎和視頻禎交錯寫入到輸出文件. 通過上面分析,可以看到,有時候可能連續寫幾個音頻
禎或視頻禎.
播放時的同步可能ffplay中有,還沒細看

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章