我正在开发一个libavformat API包装器,它将带有H.264和AAC的MP4文件转换为适合流式传输的MPEG-TS段。我只是在没有重新编码的情况下进行简单的流复制,但是我制作的文件以 3600 fps 而不是24 fps播放视频。
以下是ffprobe https://gist.github.com/chrisballinger/6733678的一些输出,损坏的文件如下:
r_frame_rate=1/1
avg_frame_rate=0/0
time_base=1/90000
start_pts=0
start_time=0.000000
duration_ts=2999
duration=0.033322
通过ffmpeg手动发送的相同输入文件具有正确的时间戳信息:
r_frame_rate=24/1
avg_frame_rate=0/0
time_base=1/90000
start_pts=126000
start_time=1.400000
duration_ts=449850
duration=4.998333
我认为这个问题存在于我的libavformat设置中:https://github.com/OpenWatch/FFmpegWrapper/blob/master/FFmpegWrapper/FFmpegWrapper.m#L349我在那里重新调整了ffmpeg.c中的一串代码,这是直接流副本所必需的。
由于3600看起来像一个“神奇的数字”(60 * 60),它可能就像我没有正确设置时间尺度一样简单,但我无法弄清楚我的代码与ffmpeg / avconv本身的区别。< / p>
这里有类似的问题,但我认为他们并没有像我一样:Muxing a H.264 Annex B & AAC stream using libavformat with vcopy/acopy
答案 0 :(得分:2)
实际上你的pts和dts搞砸了。
根据MP4时基,MP4文件有pts和dts,你将相同的pts和dts传递给ts muxer,后者使用90000Hz时钟。 例如,如果你的fps是每秒30帧,那么在ts中它意味着每3000个刻度显示一个视频帧。
你应该使用av_rescal_q将pts从mp4更改为ts timbase。
答案 1 :(得分:1)
花了一段时间,但这就是答案:https://stackoverflow.com/a/16903982/805882
packet.pts = av_rescale_q(packet->pts, inStream->time_base, outStream->time_base);
packet.dts = av_rescale_q(packet->dts, inStream->time_base, outStream->time_base);