[Ffmpeg-devel] Re: mpeg transport streams
Eric L. Hernes
Tue May 31 17:04:54 CEST 2005
M?ns Rullg?rd wrote:
>>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
>That won't do for audio packets. Even though it's pathological, I
>don't think the muxer should break if it happens.
Since your original complaint was that "I-Frames exceeding 64k are not
uncommon ...", I didn't know we were talking about audio. I was under
the impression that audio packets were tiny, on the order of 3-4k. My
latest thoughts are not touching the PES stuff, except to fix the broken
partial packet stuffing.
>>>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.
I actually didn't catch the typo, I knew what you meant. What I meant
was that the current version isn't very close to the spec in at least
two ways. First there are no PCRs at all. Secondly, it doesn't
properly stuff partial transport packets, it just stuffs the end of the
PES packet, which technically works (for mpeg2 video), but it is not the
correct way to stuff transports.
>>>>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
>>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.
The fundamental difference being in how the program is designed. If it
needs to stream realtime output, the muxer needs to be in control and
pulling data from somwehere. This is not how ffmpeg works, the muxer is
>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.
That sounds fine if the muxer is running as a data-puller. Ffmpeg's
muxer is being pushed data. I know that to turn a push model into a
pull, just you just buffer the data. However, if a solution can be
found that doesn't require re-buffering, it will be more efficient.
On the other hand, re-buffering the audio should be a step towards
properly interleaving the data.
Is it ok to just calculate packet intervals up front and ignore
rounding? For example, say we have a muxrate of 6Mb and PCR interval of
40ms. This would indicate we should have a PCR every 159.57 packets,
can we just round this and send a PCR every 160th packet?
I was also assuming that the ES streams were VBR, and that the mux rate
was high enough for all ES streams, plus overhead.
Does a VBV constrained stream guarantee a stream will be exactly the
bitrate, or does the VBV just put a cap on the rate?
More information about the ffmpeg-devel