ffmpeg音视频同步

在调用ffmpeg函数合并音视频流时,最让人摸不着头脑的是音视频的时间戳同步问题,稍不注意就会导致服务端解析出错,播放不出画面来。
先解释一下ffmpeg里的timebase,这个就是ffmpeg里计量的时间单位。
一般视频encoder的timebase是1/fps,音频encoder的timebase是1/samplerate。
stream的timebase都是1/1000,表示ms
在编码时,送入编码器的frame会置pts,视频frame的pts是当前的帧数、duration是1,音频frame的pts是当前总共发送的sample数、duration是一帧的sample数(aac是1024)
编码器中如果编码器类型不是AV_CODEC_CAP_DELAY时,会将frame的pts赋值给pkt的pts
应用层在获取到pkt时,直接用里面的pts即可。
但是h264和aac偏偏都是AV_CODEC_CAP_DELAY类型,pkt的pts需要应用层来赋值。可以用下面的函数

pkt.pts=av_rescale_q(frame.pts, out_codec_ctx->time_base, out_stream->time_base);
pkt.duration=av_rescale_q(frame.duration, out_codec_ctx->time_base, out_stream->time_base);

av_rescale_q函数的作用是将codec的时间单位换算成发送流stream的时间单位,公式为

(frame.pts*out_codec_ctx->time_base)/out_stream->time_base

代入计算后,视频pkt的duration就是1*1000/25=40ms,aac音频pkt的duration是1024*1000/16000=64ms(取samplerate为16k)

还有一点要注意的是,在推送h264和aac的rtmp流时,需要将codec的extradata赋值给stream,代码如下

out_stream->codecpar->extradata_size = out_codec_ctx->extradata_size;
out_stream->codecpar->extradata = static_cast(av_mallocz(out_codec_ctx->extradata_size));
memcpy(out_stream->codecpar->extradata, out_codec_ctx->extradata, out_codec_ctx->extradata_size);

这样在avformat_write_header时才会将h264和aac相关编码信息发送到服务端。
具体代码可以参考 https://github.com/lipku/python_rtmpstream

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值