ffmpeg 如何音视频同步

output_example.c AV同步的代码如下(我的代码有些修改),这个实现相当简单,不过挺说明问题。


音视频同步方法:选择一个参考时钟,参考时钟上的时间是线性递增的,生成数据流时依据参考时钟上的时间给每个数据块

都打上时间戳(一般包括开始时间和结束时间)。在播放时,读取数据块上的时间戳,同时参考当前参考时钟上的时间来安

排播放。数据流不会发生参考关系。

  步骤:
1, 首先分离器分解为音频和视频数据流

2,输出以前进行时间戳比较,相同则是同步的,直接输出。

3,不同的则经过同步函数进行调整之后再输出

decoder 可以根据frame rate 计算每个frame 的间隔时间,只要知道第一个frame 的pts,后面的pts就可以根据frame rate计算出来。

PTS:presentation time stamp 显示时间戳
DTS主要用于视频的解码,在解码阶段使用.PTS主要用于视频的同步和输出.在display的时候使用.在没有B frame的情况

下.DTS和PTS的输出顺序是一样的.

 

阅读前希望大家先了解一下时间戳的概念。

/*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);//源数据应该包含时间戳,pInputAudioBuf是源文件解码后的音频数据

   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中有,还没细看

实现转码一个普通视频文件为视频mpeg4,音频mp3的功能的程序

 

本程序实现转码一个普通视频文件为视频mpeg4,音频mp3的功能

#include<avcodec.h>

#include<avformat.h>

#include<stdio.h>

#include<avutil.h>

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

 

main(intargc,char **argv)

{  

  const char*input_file_name="/root/movies/ddh1.mpg";

  av_register_all();//注册库中所有可用的文件格式和编码器

  AVFormatContext *ic;

  //输入文件处理部分

  ic=av_alloc_format_context();

 if(av_open_input_file(&ic,input_file_name,NULL,0,NULL)!=0)

  {

     printf("can't open the file%s\n",input_file_name);

     exit(1);

  }//打开输入文件

  if(av_find_stream_info(ic)<0)

  <

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值