[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