音视频同步原理[ffmpeg]

音视频同步原理[ffmpeg]

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中有,还没细看
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);//编码后的祯也含有源文件的时间戳,这个函数应该是转换同时
间基准,没研究过

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值