[Ffmpeg-devel] Re: mpeg transport streams

Måns Rullgård mru
Fri May 27 18:59:25 CEST 2005


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

> M?ns Rullg?rd wrote:
>
>>>>are not uncommon at moderate bitrates.
>>>>
>>>That is easy to fix.
>>
>>Yes, just split it in multiple PES packets.
>>
> I was thinking more like 'if (pkt_size > 64k) pkt_size = 0;' and going
> with the option that a video PES in a transport stream can be
> unbounded.

That won't do for audio packets.  Even though it's pathological, I
don't think the muxer should break if it happens.

>>My target is ISO-13181-1.
>>
> The current version isn't very close to that.

Right, that should be 13818-1.  Fingers not obeying properly today.

>>>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.
>>
> Isn't something that is playable by most decoders (but still not
> perfect), better than something that completely ignores the PCR issue?

Of course it is.

>>>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.
>
> You are apparently talking about realtime encoding to a network?
> Won't that require some kind of async processing (either a thread or a
> callback) to send the PCRs and nulls if no ES packets are available.

There's no fundamental difference.  The only thing that differs is
whether you sync the PCR against the actual time.

> I'm off-line transcoding to a file that will later be sent to a
> network.  So I am counting packets between PTSs (although these should
> probably be DTSs), to determine how much to null-stuff before the next
> PES.
> In the case of an un-specified mux_rate, I was doing the same thing,
> just not null-stuffing.  This would give a transport stream that is
> ok, except for the absence of null-packets.  Then the MPTS
> (multi-program) muxer can null stuff or stuff w/ other streams as as
> necessary on the way out.
>
> So one option would be to modify retransmit_si_info() to look at the
> PCR streams and send PCRs based on bit counts and bit rates.  Since
> this function has no ES data available, these packets would be just an
> adaptation field w/ PCR and no payload.  If we send PCRs from here, I
> can't see readily how to null stuff.  I think we need both a PCR and a
> DTS to know how much to stuff, right?

OK, here's how you do it:

1. decide on a mux rate, and rates for the elementary streams
2. create a few counters, one for the PCR and a time counter for each
   elementary stream
3. if the smallest ES time is <= PCR, write one TS packet from that ES,
      and increase the ES time accordingly (bits / rate)
4. else, write a null packet
5. increase PCR by 188*8 / muxrate
6. send PSI, if required, and increase PCR
7. repeat from 3

PCR values can be attached to one of the elementary stream PIDs
(usually video), or use a separate PID.

If you are streaming in realtime, just add a delay somewhere in the
loop to keep the PCR in sync with the clock.

The problem is if you don't know the elementary stream rates, or they
are not VBV constrained.  In that case, it is necessary to continously
measure the rates based on PTS/DTS.

-- 
M?ns Rullg?rd
mru at inprovide.com





More information about the ffmpeg-devel mailing list