Another suggestion for broadcast [PATCH]

Hi Heres a third try, the first was transmit_ts with unspecified buffers second was transmit_ts with a single specified buffer Here now comes the buffer state per syncpoint. It trivially allows the demuxer to find the needed preload, and allows trivial clock synchronization. Iam not sure how much more or less device dependant this is. It surely looks better if one considers broadcasting at a higher bitrate than the intended one. (lower will fail as with all other proposals) Also this is the smallest solution so far, and likely also has less overhead than the transmit_ts. -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Dictatorship naturally arises out of democracy, and the most aggravated form of tyranny and slavery out of the most extreme liberty. -- Plato

On Thu, Feb 07, 2008 at 03:55:46AM +0100, Michael Niedermayer wrote:
Hi
Heres a third try, the first was transmit_ts with unspecified buffers second was transmit_ts with a single specified buffer
Here now comes the buffer state per syncpoint. It trivially allows the demuxer to find the needed preload, and allows trivial clock synchronization.
Iam not sure how much more or less device dependant this is. It surely looks better if one considers broadcasting at a higher bitrate than the intended one. (lower will fail as with all other proposals)
Also this is the smallest solution so far, and likely also has less overhead than the transmit_ts.
This proposal is less offensive, but I still maintain that it's unnecessary. Can we please examine the actual numbers to evaluate my claims that all real-world scenarios can be covered without any additions to the spec? I can even make up some hypothetical cases like you did before and show how my design handles them if what I've said so far is too much abstract nonsense and handwaving. Or if you prefer I can work on a formal proof of the various bounds on delays and ability to correct clock skew, with nice formulas, etc. Rich

On Thursday 07 February 2008 03:55:46 Michael Niedermayer wrote:
Heres a third try, the first was transmit_ts with unspecified buffers second was transmit_ts with a single specified buffer
Here now comes the buffer state per syncpoint. It trivially allows the demuxer to find the needed preload, and allows trivial clock synchronization.
Iam not sure how much more or less device dependant this is. It surely looks better if one considers broadcasting at a higher bitrate than the intended one. (lower will fail as with all other proposals)
Also this is the smallest solution so far, and likely also has less overhead than the transmit_ts.
+buffer_fullness (v) + for broadcast mode: + The number of bytes the demuxer is supposed to have in its buffer. If + less data than that is in the buffer then the decoders should be slowed + down to allow the buffer to fill up. If more data than that is in the + buffer then the decoders should be speed up.
to me "fullness" conveys an idea of percentage that doesn't fit wth the descripion you gave of this item. Why not call it min_buffer_size?

Nico Sabbi wrote:
On Thursday 07 February 2008 03:55:46 Michael Niedermayer wrote:
Heres a third try, the first was transmit_ts with unspecified buffers second was transmit_ts with a single specified buffer
Here now comes the buffer state per syncpoint. It trivially allows the demuxer to find the needed preload, and allows trivial clock synchronization.
Iam not sure how much more or less device dependant this is. It surely looks better if one considers broadcasting at a higher bitrate than the intended one. (lower will fail as with all other proposals)
Also this is the smallest solution so far, and likely also has less overhead than the transmit_ts.
+buffer_fullness (v) + for broadcast mode: + The number of bytes the demuxer is supposed to have in its buffer. If + less data than that is in the buffer then the decoders should be slowed + down to allow the buffer to fill up. If more data than that is in the + buffer then the decoders should be speed up.
Please fix your quoting.
to me "fullness" conveys an idea of percentage that doesn't fit wth the descripion you gave of this item. Why not call it min_buffer_size?
If you find "fullness" confusing, perhaps it could be called "buffer_level" instead. Either way, the value is exact, not a minimum. -- Måns Rullgård mans@mansr.com

Michael Niedermayer wrote:
Hi
Heres a third try, the first was transmit_ts with unspecified buffers second was transmit_ts with a single specified buffer
Here now comes the buffer state per syncpoint. It trivially allows the demuxer to find the needed preload, and allows trivial clock synchronization.
Iam not sure how much more or less device dependant this is. It surely looks better if one considers broadcasting at a higher bitrate than the intended one. (lower will fail as with all other proposals)
Also this is the smallest solution so far, and likely also has less overhead than the transmit_ts.
I believe this will work, but you still need to specify a reference model for the buffer management. It will also require more effort on the receiver side to achieve exact clock recovery. With a timestamp transmitted clock recovery is trivial, whereas this will require the receiver to measure the (perceived) received bitrate in order to work out the necessary clock adjustments. -- Måns Rullgård mans@mansr.com

On Thu, Feb 07, 2008 at 12:13:23PM -0000, Måns Rullgård wrote:
Michael Niedermayer wrote:
Hi
Heres a third try, the first was transmit_ts with unspecified buffers second was transmit_ts with a single specified buffer
Here now comes the buffer state per syncpoint. It trivially allows the demuxer to find the needed preload, and allows trivial clock synchronization.
Iam not sure how much more or less device dependant this is. It surely looks better if one considers broadcasting at a higher bitrate than the intended one. (lower will fail as with all other proposals)
Also this is the smallest solution so far, and likely also has less overhead than the transmit_ts.
I believe this will work, but you still need to specify a reference model for the buffer management.
Yes, i know. I am trying to move in small steps to avoid another day of flaming.
It will also require more effort on the receiver side to achieve exact clock recovery. With a timestamp transmitted clock recovery is trivial, whereas this will require the receiver to measure the (perceived) received bitrate in order to work out the necessary clock adjustments.
No, i dont think that is needed. My idea was not to store the number of bytes to preload beginning with the syncpoint. But to store how much should be in the buffer the moment the syncpoint is reached. That way the buffer_fullness stored in the syncpoint will always match exactly the amount the decoder has in its buffer when reading the syncpoint. If it has more in its buffer it just would change its clock to one running at 100.1% and when it has less in its buffer it would choose a 99.9% clock as reference. (Or any approximetaly equivalent process) [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Good people do not need laws to tell them to act responsibly, while bad people will find a way around the laws. -- Plato

Michael Niedermayer wrote:
On Thu, Feb 07, 2008 at 12:13:23PM -0000, Måns Rullgård wrote:
Michael Niedermayer wrote:
Hi
Heres a third try, the first was transmit_ts with unspecified buffers second was transmit_ts with a single specified buffer
Here now comes the buffer state per syncpoint. It trivially allows the demuxer to find the needed preload, and allows trivial clock synchronization.
Iam not sure how much more or less device dependant this is. It surely looks better if one considers broadcasting at a higher bitrate than the intended one. (lower will fail as with all other proposals)
Also this is the smallest solution so far, and likely also has less overhead than the transmit_ts.
I believe this will work, but you still need to specify a reference model for the buffer management.
Yes, i know. I am trying to move in small steps to avoid another day of flaming.
Just making sure.
It will also require more effort on the receiver side to achieve exact clock recovery. With a timestamp transmitted clock recovery is trivial, whereas this will require the receiver to measure the (perceived) received bitrate in order to work out the necessary clock adjustments.
No, i dont think that is needed. My idea was not to store the number of bytes to preload beginning with the syncpoint. But to store how much should be in the buffer the moment the syncpoint is reached.
Yes, that was my understanding as well.
That way the buffer_fullness stored in the syncpoint will always match exactly the amount the decoder has in its buffer when reading the syncpoint. If it has more in its buffer it just would change its clock to one running at 100.1% and when it has less in its buffer it would choose a 99.9% clock as reference. (Or any approximetaly equivalent process)
That the buffer fullness is off by N bits doesn't tell you how much too fast or too slow your clock is, only the sign of the error. Knowing also the magnitude of the error allows much more rapid convergence. Providing the timestamp in the stream makes this trivial and independent of the buffering mechanism actually used. Only specifying expected buffer fullness (according to a reference model) requires that the receiver at the very least simulate the reference model, and for good performance also measure incoming bitrate. I am not saying this is unacceptable, only pointing out the added complexity required in the receiver for equal performance. -- Måns Rullgård mans@mansr.com

Måns Rullgård <mans@mansr.com> writes:
Michael Niedermayer wrote:
On Thu, Feb 07, 2008 at 12:13:23PM -0000, Måns Rullgård wrote:
Michael Niedermayer wrote:
Hi
Heres a third try, the first was transmit_ts with unspecified buffers second was transmit_ts with a single specified buffer
Here now comes the buffer state per syncpoint. It trivially allows the demuxer to find the needed preload, and allows trivial clock synchronization.
Iam not sure how much more or less device dependant this is. It surely looks better if one considers broadcasting at a higher bitrate than the intended one. (lower will fail as with all other proposals)
Also this is the smallest solution so far, and likely also has less overhead than the transmit_ts.
I believe this will work, but you still need to specify a reference model for the buffer management.
Yes, i know. I am trying to move in small steps to avoid another day of flaming.
Just making sure.
It will also require more effort on the receiver side to achieve exact clock recovery. With a timestamp transmitted clock recovery is trivial, whereas this will require the receiver to measure the (perceived) received bitrate in order to work out the necessary clock adjustments.
No, i dont think that is needed. My idea was not to store the number of bytes to preload beginning with the syncpoint. But to store how much should be in the buffer the moment the syncpoint is reached.
Yes, that was my understanding as well.
That way the buffer_fullness stored in the syncpoint will always match exactly the amount the decoder has in its buffer when reading the syncpoint. If it has more in its buffer it just would change its clock to one running at 100.1% and when it has less in its buffer it would choose a 99.9% clock as reference. (Or any approximetaly equivalent process)
That the buffer fullness is off by N bits doesn't tell you how much too fast or too slow your clock is, only the sign of the error. Knowing also the magnitude of the error allows much more rapid convergence. Providing the timestamp in the stream makes this trivial and independent of the buffering mechanism actually used. Only specifying expected buffer fullness (according to a reference model) requires that the receiver at the very least simulate the reference model, and for good performance also measure incoming bitrate.
I am not saying this is unacceptable, only pointing out the added complexity required in the receiver for equal performance.
No comments on this? -- Måns Rullgård mans@mansr.com

On Thu, Feb 07, 2008 at 01:58:32PM -0000, Måns Rullgård wrote:
Michael Niedermayer wrote:
[...]
That way the buffer_fullness stored in the syncpoint will always match exactly the amount the decoder has in its buffer when reading the syncpoint. If it has more in its buffer it just would change its clock to one running at 100.1% and when it has less in its buffer it would choose a 99.9% clock as reference. (Or any approximetaly equivalent process)
That the buffer fullness is off by N bits doesn't tell you how much too fast or too slow your clock is, only the sign of the error.
yes
Knowing also the magnitude of the error allows much more rapid convergence.
I am not so sure about this. I mean i dont dispute that more information should improve it, but i think its good enough with the too much/too little. A simple example, lets assume we have a decoder with a clock that drifts by up to D between syncpoints. That is, in the most ideal case we would have to accept that we are D off when we reach a syncpoint, assuming we synced to the previous perfectly. Now lets assume that we are within -2D .. +2D at syncpoint x, and we apply a +D correction if we are <0 and -D if we are >0. This correction could be applied slowly until the next syncpoint. What matters is that after the correction we are within -D .. +D and with the drift thats again -2D .. +2D at syncpoint x+1. Thus above is a proof by induction that just knowing the sign and the worst case clock drift is sufficient to be within a factor of 2 of the best achiveable clock sync. (comparing worst cases, not average)
Providing the timestamp in the stream makes this trivial and independent of the buffering mechanism actually used. Only specifying expected buffer fullness (according to a reference model) requires that the receiver at the very least simulate the reference model,
I think most receivers will use something quite similar to the reference model thus making this unneeded. Though yes a receiver using a different buffer model might need to simulate the reference one. But i have difficulty imageing a sufficiently different buffer model. I mean a receiver with split buffers could just be taking the sum of their buffer_fullness. A reciver which removes packets later or not instantaneously would just traverse the last few packets to find out how much the refernce buffer would contain. And if all else fails, something like the following should do: buffer_fullness += in_bytes; buffer= realloc(buffer, sizeof(packet)*(buffer_index+1)); buffer[buffer_index].dts = in_dts; buffer[buffer_index].size= in_bytes; for(i=0; i<buffer_index; i++){ if(buffer[i].dts > current_time) break; buffer_fullness -= buffer[i].size; } buffer_index++; memmove(buffer, buffer+i, sizeof(packet)*(buffer_index-i)); buffer_index -= i; Anyway if you say a timestamp would be better, i suspect rich would be harder to convince than me. [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Why not whip the teacher when the pupil misbehaves? -- Diogenes of Sinope

On Mon, Feb 11, 2008 at 02:19:29AM +0100, Michael Niedermayer wrote:
Anyway if you say a timestamp would be better, i suspect rich would be harder to convince than me.
Not necessarily. If something new is needed, I want it to be whatever's best (hopefully without being invasive). A good question to ask is what stage in the content generation the buffering data would be generated at and if the choice of what to store would influence that... Rich

On Sun, Feb 10, 2008 at 11:14:38PM -0500, Rich Felker wrote:
On Mon, Feb 11, 2008 at 02:19:29AM +0100, Michael Niedermayer wrote:
Anyway if you say a timestamp would be better, i suspect rich would be harder to convince than me.
Not necessarily. If something new is needed, I want it to be whatever's best (hopefully without being invasive). A good question to ask is what stage in the content generation the buffering data would be generated at
Well the transmit_ts / buffer_fullness or whatever would be generated by the muxer or transmitter. But they are constrained by the packets from the encoders. So if audio and video encoders would decide to use the whole buffer, then the muxer could not do anything short of also using the whole buffer. The muxer only has a guranteed choice if it has more bufferspace or bandwidth then what the encoders where told about. (interleaving is compared to mpeg also much more constrained in nut so thats also not a real area of choice) If the muxer had twice the bufferspace AND a little extra bandwidth AND was allowed to use twice the worst case preload. Then it could keep the buffer at an average as you proposed i _THINK_.
and if the choice of what to store would influence that...
buffer_fullness, transmit_ts and all of the others are equivalent One can be found from the other if you know assumed-bitrate, actual-bitrate and timestamps. [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB The misfortune of the wise is better than the prosperity of the fool. -- Epicurus

On Monday 11 February 2008 16:41:39 Michael Niedermayer wrote:
buffer_fullness, transmit_ts and all of the others are equivalent One can be found from the other if you know assumed-bitrate, actual-bitrate and timestamps.
[...]
but if you lose packets at the first recovery: -with the buffer_fullness method you may or may not reach the required buffer size (and possibly not flush, that may not be what the sender expects the receiver to do) - whereas with transmit_ts you are sure that you have to flush all packets with dts < transmit_ts, whatever size they actually amount to Or I'm missing something?

Nico Sabbi wrote:
On Monday 11 February 2008 16:41:39 Michael Niedermayer wrote:
buffer_fullness, transmit_ts and all of the others are equivalent One can be found from the other if you know assumed-bitrate, actual-bitrate and timestamps.
but if you lose packets at the first recovery: -with the buffer_fullness method you may or may not reach the required buffer size (and possibly not flush, that may not be what the sender expects the receiver to do) - whereas with transmit_ts you are sure that you have to flush all packets with dts < transmit_ts, whatever size they actually amount to
Good point. I hadn't thought of this problem. -- Måns Rullgård mans@mansr.com

On Monday 11 February 2008 17:15:20 Måns Rullgård wrote:
Nico Sabbi wrote:
On Monday 11 February 2008 16:41:39 Michael Niedermayer wrote:
buffer_fullness, transmit_ts and all of the others are equivalent One can be found from the other if you know assumed-bitrate, actual-bitrate and timestamps.
but if you lose packets at the first recovery: -with the buffer_fullness method you may or may not reach the required buffer size (and possibly not flush, that may not be what the sender expects the receiver to do) - whereas with transmit_ts you are sure that you have to flush all packets with dts < transmit_ts, whatever size they actually amount to
Good point. I hadn't thought of this problem.
I think that if MPEG specs included a history of experiments and a list of motivations for their choices they would be a bit less frowned upon, although just a little bit less :)

On Monday 11 February 2008 17:18:36 Nico Sabbi wrote:
I think that if MPEG specs included a history of experiments and a list of motivations for their choices they would be a bit less frowned upon, although just a little bit less :)
ah, and no: it's not an apology of mpeg, and I'm not an mpeg fanboy, so don't let's reignite the flame, please. Let's keep on being constructive

On Mon, Feb 11, 2008 at 04:51:46PM +0100, Nico Sabbi wrote:
On Monday 11 February 2008 16:41:39 Michael Niedermayer wrote:
buffer_fullness, transmit_ts and all of the others are equivalent One can be found from the other if you know assumed-bitrate, actual-bitrate and timestamps.
[...]
but if you lose packets at the first recovery: -with the buffer_fullness method you may or may not reach the required buffer size (and possibly not flush, that may not be what the sender expects the receiver to do) - whereas with transmit_ts you are sure that you have to flush all packets with dts < transmit_ts, whatever size they actually amount to
Or I'm missing something?
The demuxer should detect such missing packets and just flush the buffer and retry on initial recovery. This of course would be a disadvantage in terms of preload delay for streams with significant packet loss. [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB The educated differ from the uneducated as much as the living from the dead. -- Aristotle

Michael Niedermayer wrote:
On Thu, Feb 07, 2008 at 01:58:32PM -0000, Måns Rullgård wrote:
Michael Niedermayer wrote:
[...]
That way the buffer_fullness stored in the syncpoint will always match exactly the amount the decoder has in its buffer when reading the syncpoint. If it has more in its buffer it just would change its clock to one running at 100.1% and when it has less in its buffer it would choose a 99.9% clock as reference. (Or any approximetaly equivalent process)
That the buffer fullness is off by N bits doesn't tell you how much too fast or too slow your clock is, only the sign of the error.
yes
Knowing also the magnitude of the error allows much more rapid convergence.
I am not so sure about this. I mean i dont dispute that more information should improve it, but i think its good enough with the too much/too little.
A simple example, lets assume we have a decoder with a clock that drifts by up to D between syncpoints. That is, in the most ideal case we would have to accept that we are D off when we reach a syncpoint, assuming we synced to the previous perfectly.
Now lets assume that we are within -2D .. +2D at syncpoint x, and we apply a +D correction if we are <0 and -D if we are >0. This correction could be applied slowly until the next syncpoint. What matters is that after the correction we are within -D .. +D and with the drift thats again -2D .. +2D at syncpoint x+1. Thus above is a proof by induction that just knowing the sign and the worst case clock drift is sufficient to be within a factor of 2 of the best achiveable clock sync. (comparing worst cases, not average)
This is not how clock sync is usually done. A typical implementation involves a PLL-type construct to make the local clock accurately track the sender clock. Once locked, there is very little drift. To correctly compensate for what little drift inevitably remains, the size of the error must be known. The time difference can of course be computed from the difference in buffer fullness and the received bitrate, it merely takes a little more work on the receiver side.
Providing the timestamp in the stream makes this trivial and independent of the buffering mechanism actually used. Only specifying expected buffer fullness (according to a reference model) requires that the receiver at the very least simulate the reference model,
I think most receivers will use something quite similar to the reference model thus making this unneeded. Though yes a receiver using a different buffer model might need to simulate the reference one.
I think it very unlikely that any real implementation will use whatever precise buffer model we choose. Just about any implementation is likely to immediately extract the elementary streams of interest, and discard everything else, such as container headers and unwanted elementary streams.
But i have difficulty imageing a sufficiently different buffer model. I mean a receiver with split buffers could just be taking the sum of their buffer_fullness. A reciver which removes packets later or not instantaneously would just traverse the last few packets to find out how much the refernce buffer would contain.
I'm not saying it would very difficult to simulate the reference buffer, but something is always more than nothing.
Anyway if you say a timestamp would be better, i suspect rich would be harder to convince than me.
Of that I am certain. -- Måns Rullgård mans@mansr.com

On Mon, Feb 11, 2008 at 12:14:20PM -0000, Måns Rullgård wrote:
Michael Niedermayer wrote:
On Thu, Feb 07, 2008 at 01:58:32PM -0000, Måns Rullgård wrote:
Michael Niedermayer wrote:
[...]
That way the buffer_fullness stored in the syncpoint will always match exactly the amount the decoder has in its buffer when reading the syncpoint. If it has more in its buffer it just would change its clock to one running at 100.1% and when it has less in its buffer it would choose a 99.9% clock as reference. (Or any approximetaly equivalent process)
That the buffer fullness is off by N bits doesn't tell you how much too fast or too slow your clock is, only the sign of the error.
yes
Knowing also the magnitude of the error allows much more rapid convergence.
I am not so sure about this. I mean i dont dispute that more information should improve it, but i think its good enough with the too much/too little.
A simple example, lets assume we have a decoder with a clock that drifts by up to D between syncpoints. That is, in the most ideal case we would have to accept that we are D off when we reach a syncpoint, assuming we synced to the previous perfectly.
Now lets assume that we are within -2D .. +2D at syncpoint x, and we apply a +D correction if we are <0 and -D if we are >0. This correction could be applied slowly until the next syncpoint. What matters is that after the correction we are within -D .. +D and with the drift thats again -2D .. +2D at syncpoint x+1. Thus above is a proof by induction that just knowing the sign and the worst case clock drift is sufficient to be within a factor of 2 of the best achiveable clock sync. (comparing worst cases, not average)
This is not how clock sync is usually done. A typical implementation involves a PLL-type construct to make the local clock accurately track the sender clock. Once locked, there is very little drift. To correctly compensate for what little drift inevitably remains, the size of the error must be known.
Could you elaborate on how PLL based clock sync with transmit ts works? I am no PLL expert, what i know is more of the sort that a PLL takes a reference signal like a sine wave as input, not occasional scalars which represent time since some point 0. Iam also fine with a RTFM + an url.
The time difference can of course be computed from the difference in buffer fullness and the received bitrate, it merely takes a little more work on the receiver side.
instead of transmit_ts one can use internal_clock_ts + (buffer_fullness < real_fullness ? D : -D) That should provide a pretty good reference for the PLL IMHO
Providing the timestamp in the stream makes this trivial and independent of the buffering mechanism actually used. Only specifying expected buffer fullness (according to a reference model) requires that the receiver at the very least simulate the reference model,
I think most receivers will use something quite similar to the reference model thus making this unneeded. Though yes a receiver using a different buffer model might need to simulate the reference one.
I think it very unlikely that any real implementation will use whatever precise buffer model we choose. Just about any implementation is likely to immediately extract the elementary streams of interest, and discard everything else, such as container headers and unwanted elementary streams.
Well we can discard the container headers as well in the reference model.
But i have difficulty imageing a sufficiently different buffer model. I mean a receiver with split buffers could just be taking the sum of their buffer_fullness. A reciver which removes packets later or not instantaneously would just traverse the last few packets to find out how much the refernce buffer would contain.
I'm not saying it would very difficult to simulate the reference buffer, but something is always more than nothing.
yes but OTOH transmit_ts would not scale nicely with increased bandwidth. Do you have some suggestions here to avoid this disadvantage? [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Let us carefully observe those good qualities wherein our enemies excel us and endeavor to excel them, by avoiding what is faulty, and imitating what is excellent in them. -- Plutarch

Hi On Mon, Feb 11, 2008 at 04:19:32PM +0100, Michael Niedermayer wrote: [...]
Knowing also the magnitude of the error allows much more rapid convergence.
I am not so sure about this. I mean i dont dispute that more information should improve it, but i think its good enough with the too much/too little.
A simple example, lets assume we have a decoder with a clock that drifts by up to D between syncpoints. That is, in the most ideal case we would have to accept that we are D off when we reach a syncpoint, assuming we synced to the previous perfectly.
Now lets assume that we are within -2D .. +2D at syncpoint x, and we apply a +D correction if we are <0 and -D if we are >0. This correction could be applied slowly until the next syncpoint. What matters is that after the correction we are within -D .. +D and with the drift thats again -2D .. +2D at syncpoint x+1. Thus above is a proof by induction that just knowing the sign and the worst case clock drift is sufficient to be within a factor of 2 of the best achiveable clock sync. (comparing worst cases, not average)
This is not how clock sync is usually done. A typical implementation involves a PLL-type construct to make the local clock accurately track the sender clock. Once locked, there is very little drift. To correctly compensate for what little drift inevitably remains, the size of the error must be known.
Could you elaborate on how PLL based clock sync with transmit ts works? I am no PLL expert, what i know is more of the sort that a PLL takes a reference signal like a sine wave as input, not occasional scalars which represent time since some point 0. Iam also fine with a RTFM + an url.
The time difference can of course be computed from the difference in buffer fullness and the received bitrate, it merely takes a little more work on the receiver side.
instead of transmit_ts one can use internal_clock_ts + (buffer_fullness < real_fullness ? D : -D) That should provide a pretty good reference for the PLL IMHO
Also what i forgot to say was that a correction by +D/-D is much more robust than correcting by transmit_ts - internal_clock_ts. Its not a big issue with real broadcast and checksum protected transmit_ts. But if either the transmit_ts is unprotected or there is a significant randomness in the latency like UDP/TCP over the internet. Then limiting the correction to the worst case clock drift should work much better than compensating for the whole apparent drift. So at least clip(transmit_ts, internal_clock_ts - D, internal_clock_ts + D) should be used in practice and and not transmit_ts as such. [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB It is dangerous to be right in matters on which the established authorities are wrong. -- Voltaire

Michael Niedermayer <michaelni@gmx.at> writes:
The time difference can of course be computed from the difference in buffer fullness and the received bitrate, it merely takes a little more work on the receiver side.
instead of transmit_ts one can use internal_clock_ts + (buffer_fullness < real_fullness ? D : -D) That should provide a pretty good reference for the PLL IMHO
Also what i forgot to say was that a correction by +D/-D is much more robust than correcting by transmit_ts - internal_clock_ts. Its not a big issue with real broadcast and checksum protected transmit_ts. But if either the transmit_ts is unprotected or there is a significant randomness in the latency like UDP/TCP over the internet. Then limiting the correction to the worst case clock drift should work much better than compensating for the whole apparent drift. So at least clip(transmit_ts, internal_clock_ts - D, internal_clock_ts + D) should be used in practice and and not transmit_ts as such.
Some sanity checking on the input values is always advisable. This is completely orthogonal to the question of what those values are to represent. -- Måns Rullgård mans@mansr.com

Michael Niedermayer <michaelni@gmx.at> writes:
On Mon, Feb 11, 2008 at 12:14:20PM -0000, Måns Rullgård wrote:
Michael Niedermayer wrote:
On Thu, Feb 07, 2008 at 01:58:32PM -0000, Måns Rullgård wrote:
Michael Niedermayer wrote:
[...]
That way the buffer_fullness stored in the syncpoint will always match exactly the amount the decoder has in its buffer when reading the syncpoint. If it has more in its buffer it just would change its clock to one running at 100.1% and when it has less in its buffer it would choose a 99.9% clock as reference. (Or any approximetaly equivalent process)
That the buffer fullness is off by N bits doesn't tell you how much too fast or too slow your clock is, only the sign of the error.
yes
Knowing also the magnitude of the error allows much more rapid convergence.
I am not so sure about this. I mean i dont dispute that more information should improve it, but i think its good enough with the too much/too little.
A simple example, lets assume we have a decoder with a clock that drifts by up to D between syncpoints. That is, in the most ideal case we would have to accept that we are D off when we reach a syncpoint, assuming we synced to the previous perfectly.
Now lets assume that we are within -2D .. +2D at syncpoint x, and we apply a +D correction if we are <0 and -D if we are >0. This correction could be applied slowly until the next syncpoint. What matters is that after the correction we are within -D .. +D and with the drift thats again -2D .. +2D at syncpoint x+1. Thus above is a proof by induction that just knowing the sign and the worst case clock drift is sufficient to be within a factor of 2 of the best achiveable clock sync. (comparing worst cases, not average)
This is not how clock sync is usually done. A typical implementation involves a PLL-type construct to make the local clock accurately track the sender clock. Once locked, there is very little drift. To correctly compensate for what little drift inevitably remains, the size of the error must be known.
Could you elaborate on how PLL based clock sync with transmit ts works? I am no PLL expert, what i know is more of the sort that a PLL takes a reference signal like a sine wave as input, not occasional scalars which represent time since some point 0. Iam also fine with a RTFM + an url.
I recommend ISO 13818-1/ITU-T 222.0 Annex D. It can be downloaded for free from http://www.itu.int/rec/T-REC-H.222.0-200605-I/en
The time difference can of course be computed from the difference in buffer fullness and the received bitrate, it merely takes a little more work on the receiver side.
instead of transmit_ts one can use internal_clock_ts + (buffer_fullness < real_fullness ? D : -D) That should provide a pretty good reference for the PLL IMHO
This could easily end up oscillating around the correct rate, where using the precise error value would give a near-perfect match.
Providing the timestamp in the stream makes this trivial and independent of the buffering mechanism actually used. Only specifying expected buffer fullness (according to a reference model) requires that the receiver at the very least simulate the reference model,
I think most receivers will use something quite similar to the reference model thus making this unneeded. Though yes a receiver using a different buffer model might need to simulate the reference one.
I think it very unlikely that any real implementation will use whatever precise buffer model we choose. Just about any implementation is likely to immediately extract the elementary streams of interest, and discard everything else, such as container headers and unwanted elementary streams.
Well we can discard the container headers as well in the reference model.
We could, but I don't quite like the idea. The difference in implementation effort is fairly small, and I prefer to keep the spec as simple as possible.
But i have difficulty imageing a sufficiently different buffer model. I mean a receiver with split buffers could just be taking the sum of their buffer_fullness. A reciver which removes packets later or not instantaneously would just traverse the last few packets to find out how much the refernce buffer would contain.
I'm not saying it would very difficult to simulate the reference buffer, but something is always more than nothing.
yes but OTOH transmit_ts would not scale nicely with increased bandwidth. Do you have some suggestions here to avoid this disadvantage?
Could you elaborate on this issue? -- Måns Rullgård mans@mansr.com

On Mon, Feb 11, 2008 at 11:04:17PM +0000, Måns Rullgård wrote:
Michael Niedermayer <michaelni@gmx.at> writes:
On Mon, Feb 11, 2008 at 12:14:20PM -0000, Måns Rullgård wrote:
Michael Niedermayer wrote:
On Thu, Feb 07, 2008 at 01:58:32PM -0000, Måns Rullgård wrote:
Michael Niedermayer wrote:
[...]
That way the buffer_fullness stored in the syncpoint will always match exactly the amount the decoder has in its buffer when reading the syncpoint. If it has more in its buffer it just would change its clock to one running at 100.1% and when it has less in its buffer it would choose a 99.9% clock as reference. (Or any approximetaly equivalent process)
That the buffer fullness is off by N bits doesn't tell you how much too fast or too slow your clock is, only the sign of the error.
yes
Knowing also the magnitude of the error allows much more rapid convergence.
I am not so sure about this. I mean i dont dispute that more information should improve it, but i think its good enough with the too much/too little.
A simple example, lets assume we have a decoder with a clock that drifts by up to D between syncpoints. That is, in the most ideal case we would have to accept that we are D off when we reach a syncpoint, assuming we synced to the previous perfectly.
Now lets assume that we are within -2D .. +2D at syncpoint x, and we apply a +D correction if we are <0 and -D if we are >0. This correction could be applied slowly until the next syncpoint. What matters is that after the correction we are within -D .. +D and with the drift thats again -2D .. +2D at syncpoint x+1. Thus above is a proof by induction that just knowing the sign and the worst case clock drift is sufficient to be within a factor of 2 of the best achiveable clock sync. (comparing worst cases, not average)
This is not how clock sync is usually done. A typical implementation involves a PLL-type construct to make the local clock accurately track the sender clock. Once locked, there is very little drift. To correctly compensate for what little drift inevitably remains, the size of the error must be known.
Could you elaborate on how PLL based clock sync with transmit ts works? I am no PLL expert, what i know is more of the sort that a PLL takes a reference signal like a sine wave as input, not occasional scalars which represent time since some point 0. Iam also fine with a RTFM + an url.
I recommend ISO 13818-1/ITU-T 222.0 Annex D. It can be downloaded for free from http://www.itu.int/rec/T-REC-H.222.0-200605-I/en
thanks
The time difference can of course be computed from the difference in buffer fullness and the received bitrate, it merely takes a little more work on the receiver side.
instead of transmit_ts one can use internal_clock_ts + (buffer_fullness < real_fullness ? D : -D) That should provide a pretty good reference for the PLL IMHO
This could easily end up oscillating around the correct rate, where using the precise error value would give a near-perfect match.
I assumed a normal clock which would be reasonably accurate, that is 1min/day drift. In that case the oscilations would by <1ms per second with 1 transmit_ts per second. Though if one assumes a vastly inaccurate clock only stabilized by an input voltage like described above the simple +-D method would work less well. A simple improvment would be to double D if the error had the same sign as last time and half it if it had opposit signs. This method should converge within O(log N) time and stay pretty darn accurate once converged.
Providing the timestamp in the stream makes this trivial and independent of the buffering mechanism actually used. Only specifying expected buffer fullness (according to a reference model) requires that the receiver at the very least simulate the reference model,
I think most receivers will use something quite similar to the reference model thus making this unneeded. Though yes a receiver using a different buffer model might need to simulate the reference one.
I think it very unlikely that any real implementation will use whatever precise buffer model we choose. Just about any implementation is likely to immediately extract the elementary streams of interest, and discard everything else, such as container headers and unwanted elementary streams.
Well we can discard the container headers as well in the reference model.
We could, but I don't quite like the idea. The difference in implementation effort is fairly small, and I prefer to keep the spec as simple as possible.
Iam fine with either ...
But i have difficulty imageing a sufficiently different buffer model. I mean a receiver with split buffers could just be taking the sum of their buffer_fullness. A reciver which removes packets later or not instantaneously would just traverse the last few packets to find out how much the refernce buffer would contain.
I'm not saying it would very difficult to simulate the reference buffer, but something is always more than nothing.
yes but OTOH transmit_ts would not scale nicely with increased bandwidth. Do you have some suggestions here to avoid this disadvantage?
Could you elaborate on this issue?
The issue i saw is impossible, i must have been tired or something :) [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Freedom in capitalist society always remains about the same as it was in ancient Greek republics: Freedom for slave owners. -- Vladimir Lenin

On Thu, Feb 07, 2008 at 03:55:46AM +0100, Michael Niedermayer wrote:
Hi
Heres a third try, the first was transmit_ts with unspecified buffers second was transmit_ts with a single specified buffer
Here now comes the buffer state per syncpoint. It trivially allows the demuxer to find the needed preload, and allows trivial clock synchronization.
Iam not sure how much more or less device dependant this is. It surely looks better if one considers broadcasting at a higher bitrate than the intended one. (lower will fail as with all other proposals)
Also this is the smallest solution so far, and likely also has less overhead than the transmit_ts.
Iam planing to commit this in 24h, if someone has objections / wants me to wait say so. But putting it in info packets just doesnt work without allowing changeable info. Putting it in streams is a huge mess and changing nothing wont work as has been shown and i belive isnt disputed anymore? [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB No great genius has ever existed without some touch of madness. -- Aristotle

On Mon, Feb 11, 2008 at 12:54:56AM +0100, Michael Niedermayer wrote:
On Thu, Feb 07, 2008 at 03:55:46AM +0100, Michael Niedermayer wrote:
Hi
Heres a third try, the first was transmit_ts with unspecified buffers second was transmit_ts with a single specified buffer
Here now comes the buffer state per syncpoint. It trivially allows the demuxer to find the needed preload, and allows trivial clock synchronization.
Iam not sure how much more or less device dependant this is. It surely looks better if one considers broadcasting at a higher bitrate than the intended one. (lower will fail as with all other proposals)
Also this is the smallest solution so far, and likely also has less overhead than the transmit_ts.
Iam planing to commit this in 24h, if someone has objections / wants me to wait say so.
Can you wait a little bit for some more discussion? I'm not rejecting it but I'd like to think it through more.
But putting it in info packets just doesnt work without allowing changeable info. Putting it in streams is a huge mess and changing nothing wont work as has been shown and i belive isnt disputed anymore?
I agree that it probably won't work "optimally". I still think it's reasonable to ask for transmit_ts-dts to remain constant over moderate-sized windows, but Michael is correct that there are bitrate-utilization gains to be made by bending this rule. So if people want to make use of such gains, some solution is needed. Rich

On Sun, Feb 10, 2008 at 08:53:17PM -0500, Rich Felker wrote:
On Mon, Feb 11, 2008 at 12:54:56AM +0100, Michael Niedermayer wrote:
On Thu, Feb 07, 2008 at 03:55:46AM +0100, Michael Niedermayer wrote:
Hi
Heres a third try, the first was transmit_ts with unspecified buffers second was transmit_ts with a single specified buffer
Here now comes the buffer state per syncpoint. It trivially allows the demuxer to find the needed preload, and allows trivial clock synchronization.
Iam not sure how much more or less device dependant this is. It surely looks better if one considers broadcasting at a higher bitrate than the intended one. (lower will fail as with all other proposals)
Also this is the smallest solution so far, and likely also has less overhead than the transmit_ts.
Iam planing to commit this in 24h, if someone has objections / wants me to wait say so.
Can you wait a little bit for some more discussion? I'm not rejecting it but I'd like to think it through more.
ok
But putting it in info packets just doesnt work without allowing changeable info. Putting it in streams is a huge mess and changing nothing wont work as has been shown and i belive isnt disputed anymore?
I agree that it probably won't work "optimally". I still think it's reasonable to ask for transmit_ts-dts to remain constant over moderate-sized windows, but Michael is correct that there are bitrate-utilization gains to be made by bending this rule. So if people want to make use of such gains, some solution is needed.
Theres also the issue that encoders, be it mpeg4 or mpeg2 do not neccesarily make any attempt to keep transmit_ts-dts constant. Thus a muxer using such a rule will have to work with input that has been encoded without such a rule. Also a muxer will not know ahead of time how much off the input streams will be from a constant transmit_ts-dts. So it has to assume the worst case and that causes a considerable worse preload and buffer size. [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Why not whip the teacher when the pupil misbehaves? -- Diogenes of Sinope

On Mon, Feb 11, 2008 at 03:11:45AM +0100, Michael Niedermayer wrote:
On Sun, Feb 10, 2008 at 08:53:17PM -0500, Rich Felker wrote:
On Mon, Feb 11, 2008 at 12:54:56AM +0100, Michael Niedermayer wrote:
On Thu, Feb 07, 2008 at 03:55:46AM +0100, Michael Niedermayer wrote:
Hi
Heres a third try, the first was transmit_ts with unspecified buffers second was transmit_ts with a single specified buffer
Here now comes the buffer state per syncpoint. It trivially allows the demuxer to find the needed preload, and allows trivial clock synchronization.
Iam not sure how much more or less device dependant this is. It surely looks better if one considers broadcasting at a higher bitrate than the intended one. (lower will fail as with all other proposals)
Also this is the smallest solution so far, and likely also has less overhead than the transmit_ts.
Iam planing to commit this in 24h, if someone has objections / wants me to wait say so.
Can you wait a little bit for some more discussion? I'm not rejecting it but I'd like to think it through more.
ok
ping, i waited a week ... Ill add a transmit_ts in 48h (without buffer model) unless there is some sort of discussion happening before. [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Republics decline into democracies and democracies degenerate into despotisms. -- Aristotle

On Sun, Feb 17, 2008 at 03:47:27AM +0100, Michael Niedermayer wrote:
On Mon, Feb 11, 2008 at 03:11:45AM +0100, Michael Niedermayer wrote:
On Sun, Feb 10, 2008 at 08:53:17PM -0500, Rich Felker wrote:
On Mon, Feb 11, 2008 at 12:54:56AM +0100, Michael Niedermayer wrote:
On Thu, Feb 07, 2008 at 03:55:46AM +0100, Michael Niedermayer wrote:
Hi
Heres a third try, the first was transmit_ts with unspecified buffers second was transmit_ts with a single specified buffer
Here now comes the buffer state per syncpoint. It trivially allows the demuxer to find the needed preload, and allows trivial clock synchronization.
Iam not sure how much more or less device dependant this is. It surely looks better if one considers broadcasting at a higher bitrate than the intended one. (lower will fail as with all other proposals)
Also this is the smallest solution so far, and likely also has less overhead than the transmit_ts.
Iam planing to commit this in 24h, if someone has objections / wants me to wait say so.
Can you wait a little bit for some more discussion? I'm not rejecting it but I'd like to think it through more.
ok
ping, i waited a week ... Ill add a transmit_ts in 48h (without buffer model) unless there is some sort of discussion happening before.
transmit_ts or your other proposal? I think I like transmit_ts better but I'd like to know the motivations behind how the decision is made rather than a decision being made by default when no one discusses it. Even though this is not a feature I'm particularly interested in. Rich

On Mon, Feb 18, 2008 at 02:40:07AM -0500, Rich Felker wrote:
On Sun, Feb 17, 2008 at 03:47:27AM +0100, Michael Niedermayer wrote:
On Mon, Feb 11, 2008 at 03:11:45AM +0100, Michael Niedermayer wrote:
On Sun, Feb 10, 2008 at 08:53:17PM -0500, Rich Felker wrote:
On Mon, Feb 11, 2008 at 12:54:56AM +0100, Michael Niedermayer wrote:
On Thu, Feb 07, 2008 at 03:55:46AM +0100, Michael Niedermayer wrote:
Hi
Heres a third try, the first was transmit_ts with unspecified buffers second was transmit_ts with a single specified buffer
Here now comes the buffer state per syncpoint. It trivially allows the demuxer to find the needed preload, and allows trivial clock synchronization.
Iam not sure how much more or less device dependant this is. It surely looks better if one considers broadcasting at a higher bitrate than the intended one. (lower will fail as with all other proposals)
Also this is the smallest solution so far, and likely also has less overhead than the transmit_ts.
Iam planing to commit this in 24h, if someone has objections / wants me to wait say so.
Can you wait a little bit for some more discussion? I'm not rejecting it but I'd like to think it through more.
ok
ping, i waited a week ... Ill add a transmit_ts in 48h (without buffer model) unless there is some sort of discussion happening before.
transmit_ts or your other proposal? I think I like transmit_ts better
transmit_ts
but I'd like to know the motivations behind how the decision is made
Motivation, it seems transmit_ts or someting equivalent is needed for efficient broadcast. Your suggestion of keeping the buffer at an average is less efficient. And buffer_fullness is sensitive to packet loss.
rather than a decision being made by default when no one discusses it. Even though this is not a feature I'm particularly interested in.
Well what else should we do? Theres a problem, we know a solution, noone else suggested an equally efficient alternative. I dont have a proof that there is no better alternative. If we wait indefinitly the problem just wont be solved. And waiting while there are zero discussions wont lead to a new alternative being proposed ... [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB No human being will ever know the Truth, for even if they happen to say it by chance, they would not even known they had done so. -- Xenophanes

On Mon, Feb 18, 2008 at 07:56:32PM +0100, Michael Niedermayer wrote:
rather than a decision being made by default when no one discusses it. Even though this is not a feature I'm particularly interested in.
Well what else should we do? Theres a problem, we know a solution, noone else suggested an equally efficient alternative. I dont have a proof that there is no better alternative. If we wait indefinitly the problem just wont be solved. And waiting while there are zero discussions wont lead to a new alternative being proposed ...
Alright, I agree let's not delay a long time. Could the broadcast ppl (Måns and Nico? anyone else?) please speak up and say whether you approve of this solution? Rich

Rich Felker <dalias@aerifal.cx> writes:
On Mon, Feb 18, 2008 at 07:56:32PM +0100, Michael Niedermayer wrote:
rather than a decision being made by default when no one discusses it. Even though this is not a feature I'm particularly interested in.
Well what else should we do? Theres a problem, we know a solution, noone else suggested an equally efficient alternative. I dont have a proof that there is no better alternative. If we wait indefinitly the problem just wont be solved. And waiting while there are zero discussions wont lead to a new alternative being proposed ...
Alright, I agree let's not delay a long time. Could the broadcast ppl (Måns and Nico? anyone else?) please speak up and say whether you approve of this solution?
It's just like MPEG-TS, so it's go to be good ;-) -- Måns Rullgård mans@mansr.com

On Mon, Feb 18, 2008 at 08:35:06PM +0000, Måns Rullgård wrote:
Rich Felker <dalias@aerifal.cx> writes:
On Mon, Feb 18, 2008 at 07:56:32PM +0100, Michael Niedermayer wrote:
rather than a decision being made by default when no one discusses it. Even though this is not a feature I'm particularly interested in.
Well what else should we do? Theres a problem, we know a solution, noone else suggested an equally efficient alternative. I dont have a proof that there is no better alternative. If we wait indefinitly the problem just wont be solved. And waiting while there are zero discussions wont lead to a new alternative being proposed ...
Alright, I agree let's not delay a long time. Could the broadcast ppl (Måns and Nico? anyone else?) please speak up and say whether you approve of this solution?
It's just like MPEG-TS, so it's go to be good ;-)
Not quite. We don't have l33t 3-letter codes like SCR... Rich

Rich Felker <dalias@aerifal.cx> writes:
On Mon, Feb 18, 2008 at 08:35:06PM +0000, Måns Rullgård wrote:
Rich Felker <dalias@aerifal.cx> writes:
On Mon, Feb 18, 2008 at 07:56:32PM +0100, Michael Niedermayer wrote:
rather than a decision being made by default when no one discusses it. Even though this is not a feature I'm particularly interested in.
Well what else should we do? Theres a problem, we know a solution, noone else suggested an equally efficient alternative. I dont have a proof that there is no better alternative. If we wait indefinitly the problem just wont be solved. And waiting while there are zero discussions wont lead to a new alternative being proposed ...
Alright, I agree let's not delay a long time. Could the broadcast ppl (Måns and Nico? anyone else?) please speak up and say whether you approve of this solution?
It's just like MPEG-TS, so it's go to be good ;-)
Not quite. We don't have l33t 3-letter codes like SCR...
SCR is in MPEG-PS. In TS it's PCR. -- Måns Rullgård mans@mansr.com

Il Monday 18 February 2008 21:35:06 Måns Rullgård ha scritto:
Rich Felker <dalias@aerifal.cx> writes:
On Mon, Feb 18, 2008 at 07:56:32PM +0100, Michael Niedermayer wrote:
rather than a decision being made by default when no one discusses it. Even though this is not a feature I'm particularly interested in.
Well what else should we do? Theres a problem, we know a solution, noone else suggested an equally efficient alternative. I dont have a proof that there is no better alternative. If we wait indefinitly the problem just wont be solved. And waiting while there are zero discussions wont lead to a new alternative being proposed ...
Alright, I agree let's not delay a long time. Could the broadcast ppl (Måns and Nico? anyone else?) please speak up and say whether you approve of this solution?
It's just like MPEG-TS, so it's go to be good ;-)
it's the most efficient and less error-prone solution I can think of, let alone that it's trivial to implement at least in the receiver/demuxer

On Mon, Feb 18, 2008 at 07:56:32PM +0100, Michael Niedermayer wrote:
On Mon, Feb 18, 2008 at 02:40:07AM -0500, Rich Felker wrote:
transmit_ts or your other proposal? I think I like transmit_ts better
transmit_ts
but I'd like to know the motivations behind how the decision is made
Motivation, it seems transmit_ts or someting equivalent is needed for efficient broadcast. Your suggestion of keeping the buffer at an average is less efficient. And buffer_fullness is sensitive to packet loss.
rather than a decision being made by default when no one discusses it. Even though this is not a feature I'm particularly interested in.
Well what else should we do? Theres a problem, we know a solution, noone else suggested an equally efficient alternative. I dont have a proof that there is no better alternative. If we wait indefinitly the problem just wont be solved. And waiting while there are zero discussions wont lead to a new alternative being proposed ...
Could you present the exact patch again? I'd like to remember the exact syntax you intended. Did we decide on an "is_broadcast" flag? Besides the syntax which I would like to see before approving, I have no objections. - ods15

On Tue, Feb 19, 2008 at 08:37:56AM +0200, ods15@ods15.dyndns.org wrote:
On Mon, Feb 18, 2008 at 07:56:32PM +0100, Michael Niedermayer wrote:
On Mon, Feb 18, 2008 at 02:40:07AM -0500, Rich Felker wrote:
transmit_ts or your other proposal? I think I like transmit_ts better
transmit_ts
but I'd like to know the motivations behind how the decision is made
Motivation, it seems transmit_ts or someting equivalent is needed for efficient broadcast. Your suggestion of keeping the buffer at an average is less efficient. And buffer_fullness is sensitive to packet loss.
rather than a decision being made by default when no one discusses it. Even though this is not a feature I'm particularly interested in.
Well what else should we do? Theres a problem, we know a solution, noone else suggested an equally efficient alternative. I dont have a proof that there is no better alternative. If we wait indefinitly the problem just wont be solved. And waiting while there are zero discussions wont lead to a new alternative being proposed ...
Could you present the exact patch again? I'd like to remember the exact syntax you intended. Did we decide on an "is_broadcast" flag?
Besides the syntax which I would like to see before approving, I have no objections.
attached [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Frequently ignored awnser#1 FFmpeg bugs should be sent to our bugtracker. User questions about the command line tools should be sent to the ffmpeg-user ML. And questions about how to use libav* should be sent to the libav-user ML.

On Tue, Feb 19, 2008 at 06:45:05PM +0100, Michael Niedermayer wrote:
+main_flags (v) + Bit Name Description + 0 BROADCAST_MODE Set if broadcast mode is in use.
Doesn't nut.txt say bit numbering goes from highest to lowest? Of course this makes no sense for vlc bitfields... But it should probably be clarified. Or else explicit numeric values rather than but numbers should be used. Rich

Rich Felker <dalias@aerifal.cx> writes:
On Tue, Feb 19, 2008 at 06:45:05PM +0100, Michael Niedermayer wrote:
+main_flags (v) + Bit Name Description + 0 BROADCAST_MODE Set if broadcast mode is in use.
Doesn't nut.txt say bit numbering goes from highest to lowest? Of course this makes no sense for vlc bitfields... But it should probably be clarified. Or else explicit numeric values rather than but numbers should be used.
Why not make each flag its own 1-bit field? Or would that be bad for some reason I'm missing? -- Måns Rullgård mans@mansr.com

On Tue, Feb 19, 2008 at 07:50:27PM +0000, Måns Rullgård wrote:
Rich Felker <dalias@aerifal.cx> writes:
On Tue, Feb 19, 2008 at 06:45:05PM +0100, Michael Niedermayer wrote:
+main_flags (v) + Bit Name Description + 0 BROADCAST_MODE Set if broadcast mode is in use.
Doesn't nut.txt say bit numbering goes from highest to lowest? Of course this makes no sense for vlc bitfields... But it should probably be clarified. Or else explicit numeric values rather than but numbers should be used.
Why not make each flag its own 1-bit field? Or would that be bad for some reason I'm missing?
The flags fields are then not extensible. You have to keep adding more of them, possibly in discontiguous locations. Practically it just means slightly more wasted space in files not using obscure flags, but it's also ugly. I like vlc-flags better. Rich

Rich Felker <dalias@aerifal.cx> writes:
On Tue, Feb 19, 2008 at 07:50:27PM +0000, Måns Rullgård wrote:
Rich Felker <dalias@aerifal.cx> writes:
On Tue, Feb 19, 2008 at 06:45:05PM +0100, Michael Niedermayer wrote:
+main_flags (v) + Bit Name Description + 0 BROADCAST_MODE Set if broadcast mode is in use.
Doesn't nut.txt say bit numbering goes from highest to lowest? Of course this makes no sense for vlc bitfields... But it should probably be clarified. Or else explicit numeric values rather than but numbers should be used.
Why not make each flag its own 1-bit field? Or would that be bad for some reason I'm missing?
The flags fields are then not extensible. You have to keep adding more of them, possibly in discontiguous locations. Practically it just means slightly more wasted space in files not using obscure flags, but it's also ugly. I like vlc-flags better.
Another possibility is to precede each optional field with a 1-bit flag indicating its presence. The size of the containing element can then also implicitly exclude any unused fields at the end. This may of course not be desired for frequently repeated elements where the flags could be specified in a global header. -- Måns Rullgård mans@mansr.com

On Wed, Feb 20, 2008 at 01:32:14AM +0000, Måns Rullgård wrote:
Another possibility is to precede each optional field with a 1-bit flag indicating its presence. The size of the containing element can then also implicitly exclude any unused fields at the end. This may of course not be desired for frequently repeated elements where the flags could be specified in a global header.
I hope you understand, a 1bit field means a 1byte field. NUT has no support for sub-byte data units except when they're appropriately padded with reserved bits. Rich

Rich Felker <dalias@aerifal.cx> writes:
On Wed, Feb 20, 2008 at 01:32:14AM +0000, Måns Rullgård wrote:
Another possibility is to precede each optional field with a 1-bit flag indicating its presence. The size of the containing element can then also implicitly exclude any unused fields at the end. This may of course not be desired for frequently repeated elements where the flags could be specified in a global header.
I hope you understand, a 1bit field means a 1byte field. NUT has no support for sub-byte data units except when they're appropriately padded with reserved bits.
Sounds like a deficiency. -- Måns Rullgård mans@mansr.com

On Wed, Feb 20, 2008 at 09:32:48AM +0000, Måns Rullgård wrote:
Rich Felker <dalias@aerifal.cx> writes:
On Wed, Feb 20, 2008 at 01:32:14AM +0000, Måns Rullgård wrote:
Another possibility is to precede each optional field with a 1-bit flag indicating its presence. The size of the containing element can then also implicitly exclude any unused fields at the end. This may of course not be desired for frequently repeated elements where the flags could be specified in a global header.
I hope you understand, a 1bit field means a 1byte field. NUT has no support for sub-byte data units except when they're appropriately padded with reserved bits.
Sounds like a deficiency.
In what respect? That is what would we gain with droping byte alignment? I think we would gain a lot of complexity primarely ;) [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Breaking DRM is a little like attempting to break through a door even though the window is wide open and the only thing in the house is a bunch of things you dont want and which you would get tomorrow for free anyway

Michael Niedermayer wrote:
On Wed, Feb 20, 2008 at 09:32:48AM +0000, Måns Rullgård wrote:
Rich Felker <dalias@aerifal.cx> writes:
On Wed, Feb 20, 2008 at 01:32:14AM +0000, Måns Rullgård wrote:
Another possibility is to precede each optional field with a 1-bit flag indicating its presence. The size of the containing element can then also implicitly exclude any unused fields at the end. This may of course not be desired for frequently repeated elements where the flags could be specified in a global header.
I hope you understand, a 1bit field means a 1byte field. NUT has no support for sub-byte data units except when they're appropriately padded with reserved bits.
Sounds like a deficiency.
In what respect? That is what would we gain with droping byte alignment? I think we would gain a lot of complexity primarely ;)
I thought Nut was supposed to have minimal overhead. Requiring a syntax element to use 8 bits, even if it doesn't need them is not minimal. If you're willing to sacrifice a few bits for reduced complexity, that's fine. I merely had the, apparently incorrect, impression that Nut was trying very hard to remove any unnecessary overhead, even in the text of the format specification ;-) -- Måns Rullgård mans@mansr.com

On Wed, Feb 20, 2008 at 03:25:37PM -0000, Måns Rullgård wrote:
Michael Niedermayer wrote:
On Wed, Feb 20, 2008 at 09:32:48AM +0000, Måns Rullgård wrote:
Rich Felker <dalias@aerifal.cx> writes:
On Wed, Feb 20, 2008 at 01:32:14AM +0000, Måns Rullgård wrote:
Another possibility is to precede each optional field with a 1-bit flag indicating its presence. The size of the containing element can then also implicitly exclude any unused fields at the end. This may of course not be desired for frequently repeated elements where the flags could be specified in a global header.
I hope you understand, a 1bit field means a 1byte field. NUT has no support for sub-byte data units except when they're appropriately padded with reserved bits.
Sounds like a deficiency.
In what respect? That is what would we gain with droping byte alignment? I think we would gain a lot of complexity primarely ;)
I thought Nut was supposed to have minimal overhead. Requiring a syntax element to use 8 bits, even if it doesn't need them is not minimal.
True, but it simplifies things alot. Especially with byte aligned frame data. Also about overhead nut can for example store VBR mp3 with single byte frame headers, and at the same time removing 4 bytes from the mp3 frames, thats -3 bytes overhead. (We dont have an implemetation capable of muxing this yet though) This actually might make it advantaneous to store mp3 in nut instead of raw mp3, and even more so as one could accurately seek in the nut file.
If you're willing to sacrifice a few bits for reduced complexity, that's fine. I merely had the, apparently incorrect, impression that Nut was trying very hard to remove any unnecessary overhead,
even in the text of the format specification ;-)
Yes, theres no sense in saying something more than once :) [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Why not whip the teacher when the pupil misbehaves? -- Diogenes of Sinope

On Wed, Feb 20, 2008 at 03:25:37PM -0000, Måns Rullgård wrote:
Michael Niedermayer wrote:
On Wed, Feb 20, 2008 at 09:32:48AM +0000, Måns Rullgård wrote:
Rich Felker <dalias@aerifal.cx> writes:
On Wed, Feb 20, 2008 at 01:32:14AM +0000, Måns Rullgård wrote:
Another possibility is to precede each optional field with a 1-bit flag indicating its presence. The size of the containing element can then also implicitly exclude any unused fields at the end. This may of course not be desired for frequently repeated elements where the flags could be specified in a global header.
I hope you understand, a 1bit field means a 1byte field. NUT has no support for sub-byte data units except when they're appropriately padded with reserved bits.
Sounds like a deficiency.
In what respect? That is what would we gain with droping byte alignment? I think we would gain a lot of complexity primarely ;)
I thought Nut was supposed to have minimal overhead. Requiring a syntax element to use 8 bits, even if it doesn't need them is not minimal.
If you're willing to sacrifice a few bits for reduced complexity, that's fine. I merely had the, apparently incorrect, impression that Nut was trying very hard to remove any unnecessary overhead, even in the text of the format specification ;-)
In order for vlc to be efficient for numbers in the ranges of sanity, you need to use units larger than bits. It would be a huge waste to have a continuation bit corresponding to each data bit. One continuation bit for every 7 data bits works well in practice. Essentially all fields in nut are vlc, so worrying about non-vlc types' efficiency is really pointless. Rich

Rich Felker wrote:
On Wed, Feb 20, 2008 at 03:25:37PM -0000, Måns Rullgård wrote:
Michael Niedermayer wrote:
On Wed, Feb 20, 2008 at 09:32:48AM +0000, Måns Rullgård wrote:
Rich Felker <dalias@aerifal.cx> writes:
On Wed, Feb 20, 2008 at 01:32:14AM +0000, Måns Rullgård wrote:
Another possibility is to precede each optional field with a 1-bit flag indicating its presence. The size of the containing element can then also implicitly exclude any unused fields at the end. This may of course not be desired for frequently repeated elements where the flags could be specified in a global header.
I hope you understand, a 1bit field means a 1byte field. NUT has no support for sub-byte data units except when they're appropriately padded with reserved bits.
Sounds like a deficiency.
In what respect? That is what would we gain with droping byte alignment? I think we would gain a lot of complexity primarely ;)
I thought Nut was supposed to have minimal overhead. Requiring a syntax element to use 8 bits, even if it doesn't need them is not minimal.
If you're willing to sacrifice a few bits for reduced complexity, that's fine. I merely had the, apparently incorrect, impression that Nut was trying very hard to remove any unnecessary overhead, even in the text of the format specification ;-)
In order for vlc to be efficient for numbers in the ranges of sanity, you need to use units larger than bits. It would be a huge waste to have a continuation bit corresponding to each data bit. One continuation bit for every 7 data bits works well in practice.
The optimal coding of a field depends on the distribution of values, not only on the valid range. For instance, if the value is very small, say 0--2, in 99% of all cases, but is occasionally much higher, other schemes become attractive. A simple one is the exp-golomb coding used in H.264. I assume you hate it, if for no other reason because it is used in an MPEG standard, but I mention it nonetheless (or maybe because of this).
Essentially all fields in nut are vlc, so worrying about non-vlc types' efficiency is really pointless.
A Nut vlc value is at least 8 bits, which is wasteful if, say, 3 bits are sufficient for a given syntax element. Grouping unrelated elements into a single vlc value to get around this inefficiency, strikes me as hackish. -- Måns Rullgård mans@mansr.com

On Wednesday 20 February 2008 18:01:31 Måns Rullgård wrote:
The optimal coding of a field depends on the distribution of values, not only on the valid range. For instance, if the value is very small, say 0--2, in 99% of all cases, but is occasionally much higher, other schemes become attractive. A simple one is the exp-golomb coding used in H.264. I assume you hate it, if for no other reason because it is used in an MPEG standard, but I mention it nonetheless (or maybe because of this).
but golomb coding is much heavier to decode than vlc, and considering that the CPU has to waste a lot of time decoding video and audio it seems a real waste of resources to me, especially considering the minimal advantages it takes and the added complexity it requires in a demuxer

On Wed, Feb 20, 2008 at 05:01:31PM -0000, Måns Rullgård wrote:
Essentially all fields in nut are vlc, so worrying about non-vlc types' efficiency is really pointless.
A Nut vlc value is at least 8 bits, which is wasteful if, say, 3 bits are sufficient for a given syntax element.
The only fields that make any difference to overhead are in syncpoints and frame headers. If 3 bits are really sufficient for one of these fields, then the framecode will do a perfectly nice job without nasty computational overhead.
Grouping unrelated elements into a single vlc value to get around this inefficiency, strikes me as hackish.
Do you mean framecodes? Or flags-style fields? In either case, it's pragmatic; in the case of flags it's standard practice. In any case the time for this discussion is long past, by 5+ years.. Rich

On Tue, Feb 19, 2008 at 12:58:25PM -0500, Rich Felker wrote:
On Tue, Feb 19, 2008 at 06:45:05PM +0100, Michael Niedermayer wrote:
+main_flags (v) + Bit Name Description + 0 BROADCAST_MODE Set if broadcast mode is in use.
First we have existing flags which use the same form of description.
Doesn't nut.txt say bit numbering goes from highest to lowest? Of course this makes no sense for vlc bitfields... But it should probably be clarified. Or else explicit numeric values rather than but numbers should be used.
There were explicit numbers until: --- r463 | ivo | 2006-11-24 17:35:22 +0100 (Fri, 24 Nov 2006) | 3 lines specify the bitnumber for frame_flags, instead of a decimal bitmask --- Iam all for changing things back to r462 flag bit wise. [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB I know you won't believe me, but the highest form of Human Excellence is to question oneself and others. -- Socrates

Michael Niedermayer <michaelni@gmx.at> writes:
+transmit_ts (t) + The timestamp at which the first bit of the syncpoint is transmitted.
In MPEG-TS, the PCR value is the time of arrival of the last bit (actually the byte containing the last bit). This could be seen as more logical, as then no timestamp will refer to a time in the past. I doubt the distinction is relevant in practice, but I wanted to point it out nonetheless.
+ MUST be less than or equal to all following dts.
I'm not happy with this. It allows the clock to reach the DTS of a frame before the frame has arrived. Placing restrictions on the transmit_ts value is not sufficient to avoid this condition. Instead, it must be a rule that a frame must be completely received before the reference clock reaches its DTS value.
+ Demuxers in non broadcast mode MUST ignore the value of this field.
Why does it matter what demuxers do with it?
+ Muxers in broadcast mode MUST NOT ommit this field.
"omit" -- Måns Rullgård mans@mansr.com

On Tue, Feb 19, 2008 at 08:19:39PM +0000, Måns Rullgård wrote:
Michael Niedermayer <michaelni@gmx.at> writes:
+transmit_ts (t) + The timestamp at which the first bit of the syncpoint is transmitted.
In MPEG-TS, the PCR value is the time of arrival of the last bit (actually the byte containing the last bit). This could be seen as more logical, as then no timestamp will refer to a time in the past. I doubt the distinction is relevant in practice, but I wanted to point it out nonetheless.
Last bit of what? The transmit_ts or the syncpoint? A well written demuxer/receiver will check the crc of the syncpoint before using transmit_ts thus it would still be in the past if its the last bit of transmit_ts. Also either way transmit_ts is variable length and that would slightly complicate setting it exactly to the time of the last bit.
+ MUST be less than or equal to all following dts.
I'm not happy with this. It allows the clock to reach the DTS of a frame before the frame has arrived. Placing restrictions on the transmit_ts value is not sufficient to avoid this condition. Instead, it must be a rule that a frame must be completely received before the reference clock reaches its DTS value.
What about: transmit_ts (t) The value of the reference clock at the moment when the first bit of transmit_ts is transmitted/received. The reference clock MUST always be less than or equal to the DTS of every not yet completely received frame. ?
+ Demuxers in non broadcast mode MUST ignore the value of this field.
Why does it matter what demuxers do with it?
Rich?
+ Muxers in broadcast mode MUST NOT ommit this field.
"omit"
Fixed [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB No human being will ever know the Truth, for even if they happen to say it by chance, they would not even known they had done so. -- Xenophanes

Michael Niedermayer <michaelni@gmx.at> writes:
On Tue, Feb 19, 2008 at 08:19:39PM +0000, Måns Rullgård wrote:
Michael Niedermayer <michaelni@gmx.at> writes:
+transmit_ts (t) + The timestamp at which the first bit of the syncpoint is transmitted.
In MPEG-TS, the PCR value is the time of arrival of the last bit (actually the byte containing the last bit). This could be seen as more logical, as then no timestamp will refer to a time in the past. I doubt the distinction is relevant in practice, but I wanted to point it out nonetheless.
Last bit of what? The transmit_ts or the syncpoint? A well written demuxer/receiver will check the crc of the syncpoint before using transmit_ts thus it would still be in the past if its the last bit of transmit_ts. Also either way transmit_ts is variable length and that would slightly complicate setting it exactly to the time of the last bit.
First bit is fine. As I said, I only mentioned this since it is a difference from MPEG TS.
+ MUST be less than or equal to all following dts.
I'm not happy with this. It allows the clock to reach the DTS of a frame before the frame has arrived. Placing restrictions on the transmit_ts value is not sufficient to avoid this condition. Instead, it must be a rule that a frame must be completely received before the reference clock reaches its DTS value.
What about:
transmit_ts (t) The value of the reference clock at the moment when the first bit of transmit_ts is transmitted/received. The reference clock MUST always be less than or equal to the DTS of every not yet completely received frame.
Much better. -- Måns Rullgård mans@mansr.com

On Thu, Feb 07, 2008 at 03:55:46AM +0100, Michael Niedermayer wrote:
--- nut.txt (revision 590) +++ nut.txt (working copy) @@ -412,6 +412,8 @@ syncpoint: global_key_pts t back_ptr_div16 v + if(bytes remaining in the syncpoint) + buffer_fullness v reserved_bytes
Would it be possible to have this be: if (bcast flag present in global header && bytes remaining in syncpoint) This way files not utilizing the broadcast functionality would not be forced to waste an extra byte per syncpoint in the future when there might be other new fields in the syncpoint that they want to use. Also it's not clear that just coding a 0 for this field would even be valid, according to the description you wrote for buffer_fullness. Having a "broadcast" flag (or buffer-controlled or whatever you like to call it) in the header to indicate that the field is present and to be used solves both problems at once. Rich

On Sun, Feb 10, 2008 at 08:56:56PM -0500, Rich Felker wrote:
On Thu, Feb 07, 2008 at 03:55:46AM +0100, Michael Niedermayer wrote:
--- nut.txt (revision 590) +++ nut.txt (working copy) @@ -412,6 +412,8 @@ syncpoint: global_key_pts t back_ptr_div16 v + if(bytes remaining in the syncpoint) + buffer_fullness v reserved_bytes
Would it be possible to have this be:
if (bcast flag present in global header && bytes remaining in syncpoint)
This way files not utilizing the broadcast functionality would not be forced to waste an extra byte per syncpoint in the future when there might be other new fields in the syncpoint that they want to use. Also it's not clear that just coding a 0 for this field would even be valid, according to the description you wrote for buffer_fullness. Having a "broadcast" flag (or buffer-controlled or whatever you like to call it) in the header to indicate that the field is present and to be used solves both problems at once.
ok, ill add a main_flags v to the main header and use if(main_flags & WHATEVER) buffer_fullness v in case we agree on the buffer_fullness field I think we dont need the "if(bytes remaining in the syncpoint)" then anymore [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB I do not agree with what you have to say, but I'll defend to the death your right to say it. -- Voltaire

On Mon, Feb 11, 2008 at 03:16:26AM +0100, Michael Niedermayer wrote:
ok, ill add a main_flags v to the main header
I assume this is in the reserved bytes of main header?
and use if(main_flags & WHATEVER) buffer_fullness v in case we agree on the buffer_fullness field
I think we dont need the "if(bytes remaining in the syncpoint)" then anymore
I suppose not. Would you be happier considering files with the flag in the main header, but with missing buffer field(s) in syncpoints, as corrupt/broken files? Rich

Rich Felker wrote:
On Mon, Feb 11, 2008 at 03:16:26AM +0100, Michael Niedermayer wrote:
ok, ill add a main_flags v to the main header
I assume this is in the reserved bytes of main header?
and use if(main_flags & WHATEVER) buffer_fullness v in case we agree on the buffer_fullness field
I think we dont need the "if(bytes remaining in the syncpoint)" then anymore
I suppose not. Would you be happier considering files with the flag in the main header, but with missing buffer field(s) in syncpoints, as corrupt/broken files?
Of course such a file would be broken. A demuxer might of course choose to attempt playback anyway, but that's beside the point. -- Måns Rullgård mans@mansr.com

On Sun, Feb 10, 2008 at 10:26:10PM -0500, Rich Felker wrote:
On Mon, Feb 11, 2008 at 03:16:26AM +0100, Michael Niedermayer wrote:
ok, ill add a main_flags v to the main header
I assume this is in the reserved bytes of main header?
yes, old demuxers would see it that way. For new ones its before the reserved bytes.
and use if(main_flags & WHATEVER) buffer_fullness v in case we agree on the buffer_fullness field
I think we dont need the "if(bytes remaining in the syncpoint)" then anymore
I suppose not. Would you be happier considering files with the flag in the main header, but with missing buffer field(s) in syncpoints, as corrupt/broken files?
yes [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB I do not agree with what you have to say, but I'll defend to the death your right to say it. -- Voltaire

Rich Felker wrote:
On Thu, Feb 07, 2008 at 03:55:46AM +0100, Michael Niedermayer wrote:
--- nut.txt (revision 590) +++ nut.txt (working copy) @@ -412,6 +412,8 @@ syncpoint: global_key_pts t back_ptr_div16 v + if(bytes remaining in the syncpoint) + buffer_fullness v reserved_bytes
Would it be possible to have this be:
if (bcast flag present in global header && bytes remaining in syncpoint)
This way files not utilizing the broadcast functionality would not be forced to waste an extra byte per syncpoint in the future when there might be other new fields in the syncpoint that they want to use. Also it's not clear that just coding a 0 for this field would even be valid, according to the description you wrote for buffer_fullness. Having a "broadcast" flag (or buffer-controlled or whatever you like to call it) in the header to indicate that the field is present and to be used solves both problems at once.
A flag, wherever it is placed, signalling the presence of optional fields is a good idea. That's how MPEG does it. -- Måns Rullgård mans@mansr.com
participants (5)
-
Michael Niedermayer
-
Måns Rullgård
-
Nico Sabbi
-
ods15@ods15.dyndns.org
-
Rich Felker