[FFmpeg-devel] [bug/patch] MPEG-TS muxer: PCR not in sync with PTS/DTS
Niobos
niobos.be
Tue Jul 21 17:24:53 CEST 2009
I'm trying to transcode a video file to h264/x264 + aac into an MPEG-
TS container. FFmpeg almost immediately (after a few seconds encoding)
warns me that "dts < pcr, TS is invalid". When I try to play the
resulting TS-file, it stops playing around the timestamp the warning
showed up. I tried playing on iPhone and VLC, both show the problem.
I only have a limited knowledge of MPEG-TS and ffmpeg, so be warned.
ffmpeg (libavformat/mpegtsenc.c in particular) calculates a muxrate
from the stream bitrates. The PCR is generated from this muxrate; the
PTS (and DTS) are generated from the stream itself.
The calculated muxrate is too low, this causes the stream (DTS) and
container (PCR) to slowly drift apart. Specifying a higher -muxrate on
the command line solves the "DTS < PCR" warning.
I'm not an expert programmer, but I gave it a shot to write a patch:
* mpegts-varname-freq-period.diff : Pure cosmetics : I was trying to
understand the calculation-code. There are 3 variables
{sdt,pat,pcr}_packet_freq. They contain the number of packets between
an {sdt,pat,pcr} insertion. I suggest renaming these to
{sdt,pat,pcr}_packet_period. A higher *frequency* means less time
between items, this is not how the vars are used in the code. A higher
*period* means more time between the items, which _is_ how they're
used. (period = 1/frequency)
* mpegts-overhead-calc.diff : Algorithm change : I rewrote the
overhead calculations. The PES overhead is correct for my specific
case (1 PES per video frame, 1 PES per 150ms audio), but might need
some work to be more generic. The PAT, PMT, SDT and PCR overhead
calculations should be correct; the original code was wrong: a
_longer_ time between PCRs would _increase_ the overhead...
The resulting code works much better, but the PCR still drifts apart
from the DTS. A "normal" MPEG-TS contains a NULL-stream to keep the
required bitrate constant. Another way to implement it would be to
indicate a rate incontinuity and change the muxrate. I consider
inserting NULL packets easier. The third patch is a try to implement
this in ffmpeg:
* The muxrate is put at 2% higher than calculated
* If DTS - PCR becomes larger than 1.5 seconds (just a guess,
hardcoded for now) one (or more) NULL-packet(s) is (are) inserted to
get the PCR near the DTS again
This whole thing is also posted on roundup, before I learned that this
mailinglist was a better place to post to: https://roundup.ffmpeg.org/roundup/ffmpeg/issue1279
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mpegts-overhead-calc.diff
Type: application/octet-stream
Size: 1954 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20090721/ecb54853/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mpegts-overhead-null-packets.diff
Type: application/octet-stream
Size: 1435 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20090721/ecb54853/attachment-0001.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mpegts-varname-freq-period.diff
Type: application/octet-stream
Size: 2601 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20090721/ecb54853/attachment-0002.obj>
-------------- next part --------------
PS: can anyone tell me how to convince Apple Mail that attachments are
a specific mime-type instead of octet-stream's?
PS2: can anyone tell me how to convince Apple Mail to bottom-reply
instead of top-reply?
More information about the ffmpeg-devel
mailing list