I am working on a libavformat API wrapper that converts MP4 files with H.264 and AAC to MPEG-TS segments suitable for streaming. I am just doing a simple stream copy without re-encoding, but the files I produce play the video back at 3600 fps instead of 24 fps.
Here are some outputs from ffprobe https://gist.github.com/chrisballinger/6733678, the broken file is below:
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
The same input file manually sent through ffmpeg has proper timestamp information:
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
I believe the problem lies somewhere in my setup of libavformat here: https://github.com/OpenWatch/FFmpegWrapper/blob/master/FFmpegWrapper/FFmpegWrapper.m#L349 where I repurposed a bunch of code from ffmpeg.c that was required for the direct stream copy.
Since 3600 seems like a "magic number" (60*60), it could be as simple as me not setting the time scale properly, but I can't figure out where my code diverges from ffmpeg/avconv itself.
Similar question here, but I don't think they got as far as I did: Muxing a H.264 Annex B & AAC stream using libavformat with vcopy/acopy
Actually your pts and dts are messed up.
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 .
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With