5

我正在开发一个 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 本身的差异。

类似的问题在这里,但我认为他们没有像我所做的那样:Muxing a H.264 Annex B & AAC stream using libavformat with vcopy/acopy

4

2 回答 2

2

实际上你的 pts 和 dts 搞砸了。

The MP4 file has pts and dts according to MP4 timebase and you are passing the same pts and dts to the ts muxer which works with 90000Hz clock. for example if your fps is 30 frames per second then in ts it will mean that show a video frame on every 3000 ticks.

you should use av_rescal_q to change the pts from mp4 to ts timbase .

于 2013-10-01T05:14:06.793 回答
1

It took a while, but this is the answer: 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);
于 2013-10-01T23:20:48.310 回答