[Ffmpeg-devel] Re: mpeg transport streams

Måns Rullgård mru
Fri May 27 16:47:09 CEST 2005

"Eric L. Hernes" <eric at hernes.ws> writes:

> "Eric L. Hernes" <eric at hernes.ws
> <http://mplayerhq.hu/mailman/listinfo/ffmpeg-devel>> writes:
>>> The changes to mpegtsenc.c are 
>>> * Send full frames as PES packets rather than breaking them into
>>> * transport sized blocks.
>> Oversized frames are not handled properly.  I-frames exceeding 64k
>> are not uncommon at moderate bitrates.
> That is easy to fix.

Yes, just split it in multiple PES packets.

>>> * Properly stuff the adaptation field if a packet is short.
>>> * Calculate a PCR from the PTS - framesize
>> It's not that simple.  The PCR doesn't have any direct relation to
>> the PTS.  The PCR is defined as the exact time the bits comprising
>> the PCR leave the muxer (pretend it's real-time), whereas the PTS is
>> the time (as given by the PCR) at which a frame should be displayed.
>> The elementary streams may have a variable bitrate (within VBV
>> constraints), so the offset between PTS and PCR will vary.  The only
>> requirement is that the PTS never be less than the PCR.  Allowing a
>> few additional milliseconds for decoding is usually a good idea.
>> The allowed PCR jitter is 500 ns, and your method doesn't get
>> anywhere near that.  Also note that the maximum interval between PCR
>> values is 100 ms (40 ms being commonly used), whereas PTS values may
>> have up to 700 ms intervals.
> This largely depends on your target.

My target is ISO-13181-1.

> With hardware muxers and a digital distribution, the transport
> streams are required to be at a constant bit rate, so it is the
> muxers job to null stuff the transport to get that rate.

It is indeed.

> The method that I'm using works much better than what's in CVS now.

It is an improvement, but it is not correct.  I tried that approach,
and found that it produced streams that were playable by most
decoders, but a few complained.  A closer inspection revealed
timestamps wildly out of spec.

> I know it isn't perfect, or possibly even close to correct, but it
> does work.  I also realize that with the setup I'm testing, these
> PCR values may only be used as a 'hint' to the hardware mux that
> rewrites the PCRs anyway.

A lot of equipment is rather tolerant to out-of-spec streams.  If it
works, that's good for you, but it doesn't mean the streams are

> So what is the correct way to calculate a PCR?

You need to count the bits output (including padding, PSI, etc.)
against the mux rate, and insert a PCR whenever the time is up.

> Have packet counters for the audio/video streams and calculate when
> the next packet needs to arrive?  We still need a clock from
> somewhere.  If a target mux-rate is specified we can use calculate a
> PCR from the mux_rate and packet count. If the mux_rate isn't
> specified we could use (video_bitrate + audio_bitrate +
> some_mux_overhead), but then it is no longer VBR.  In a VBR stream,
> the only clock available is the PTS (or frame_number/frame_rate), so
> we have to somehow derive the PCR from that.

The audio and video streams shall be assumed to be VBV compliant at
some known rate.  Use the sum of all the elementary stream rates plus
some overhead as the total mux rate.  Then push out the elementary
streams at their respective rates, keeping an eye on the PTS/DTS not
to let them drift.  If there is no elementary stream packet due for
delivery when the mux rate calls for a TS packet, insert null packets
as needed.

>> Another problem with your muxer is that it doesn't interleave the
>> streams at the TS packet level.  VBV buffer sizes often approach a
>> full second, so a transmission time of a few hundred milliseconds
>> for a single frame is not unlikely.  If this happens, and there is
>> no interleaving of audio data, the audio decoder is likely to
>> underrun unless it has a very large buffer, which is unusual with
>> hardware decoders.
> It is just as broken now as it was, I haven't done anything to fix or
> further break the interleaving of packets.  I haven't looked at the
> layers involved there.  The streams that I'm using are already ATSC
> streams, i.e. MPEG2/AC3, so my acodec is just 'copy', I'm assuming
> that the copy codec just sends an audio packet when it gets one so if
> the input is properly interleaved, so is the output.

I'm just pointing out a problem I've observed.  If your input packets
are already small enough, there is no need for further interleaving.
I was thinking more generally.

> One thing that may be helping me here is that I am only encoding
> standard definition resolutions, and decoding with a high-def box, so
> the set-top buffers are much bigger than what I need.

That might of course be making a difference.

M?ns Rullg?rd
mru at inprovide.com

More information about the ffmpeg-devel mailing list