Subject: Re: [avtext] Comments on draft-petithuguenin-avtext-multiple-clock-rates-00

From: Marc Petit-Huguenin <[email-masked]>
Date: Thu, 21 Apr 2011 11:26:29 -0700

Hi Magnus,

Going back to this topic after some vacations.  See below.

On 03/28/2011 12:47 AM, Magnus Westerlund wrote:
> Marc, WG
> 
> See Inline
> 
> Marc Petit-Huguenin skrev 2011-03-28 05:34:
>> Hi Magnus,
>>
>> Thanks for the review, and sorry to not responding sooner.
>>
>> On 03/24/2011 10:35 AM, Magnus Westerlund wrote:
>>> Hi,
>>>
>>> This mail is my personal opinions and not as a WG chair.
>>>
>>> I have reviewed the draft and think it is a reasonable starting point
>>> for meeting the WG's milestone.
>>>
>>> However, I do have some technical comments.
>>>

[...]

>>>
>>> In my view the method in 2.2.1 is incorrect in one important detail:
>>>
>>> timestamp = previous_timestamp + (current_capture_time -
>>>     previous_capture_time) * current_clock_rate
>>>
>>> The "current_clock_rate" should actually be previous clock rate. If one
>>> uses the clock rate from the previous packet to cover the time period up
>>> to a switch then one avoids any discontinuities and the jitter doesn't
>>> make a jump before one knows what the new clock rate is.
>>>
>>> It is also consistent with logical thinking for any media that had
>>> duration. Take for example audio with 20 ms frame lengths, the RTP TS
>>> value for a packet with one frame provides the time at the start of the
>>> frame. Then the frame has a duration of 20 ms, thus resulting in that
>>> the timestamp value of any next frame that are aligned with the current
>>> will be starting at last_TS+0.02*clock_rate.
>>>
>>> Thus resulting in that the formula should read:
>>> timestamp = previous_timestamp + (current_capture_time -
>>>     previous_capture_time) * previous_clock_rate
>>>
>>> One also needs to reconsider the arrival formulas to use previous:
>>>   (1)  current_time_capture = (current_timestamp - previous_timestamp) /
>>>        previous_clock_rate + previous_time_capture
>>>     (2)  transit = previous_clock_rate * (time_arrival -
>>>        current_time_capture)
>>>     (3)  previous_time_capture = current_time_capture
>>>     (4) previous_clock_rate = current_clock_rate
>>>
>>>
>>> Using these formulas to update table 2:
>>>
>>>     +-------+-------+-----------+---------+---------+--------+----------+
>>>     | Capt. | Clock | RTP       | Arrival | Transit | Jitter | Average  |
>>>     | time  | rate  | timestamp | time    |         |        | jitter   |
>>>     +-------+-------+-----------+---------+---------+--------+----------+
>>>     | 0     | 8000  | 0         | 0.1     | 800     |        |          |
>>>     | 0.02  | 8000  | 160       | 0.12    | 800     | 0      | 0        |
>>>     | 0.04  | 8000  | 320       | 0.14    | 800     | 0      | 0        |
>>>     | 0.06  | 8000  | 480       | 0.16    | 800     | 0      | 0        |
>>>     | 0.08  | 16000 | 640       | 0.18    | 800     | 0      | 0        |
>>>     | 0.1   | 16000 | 960       | 0.2     | 1600    | 0      | 0        |
>>>     | 0.12  | 16000 | 1280      | 0.22    | 1600    | 0      | 0        |
>>>     | 0.14  | 8000  | 1600      | 0.24    | 1600    | 0      | 0        |
>>>     | 0.16  | 8000  | 1760      | 0.26    | 320     | 0      | 0        |
>>>     +-------+-------+-----------+---------+---------+--------+----------+
>>>
>>>
>>> Which I think avoids all the issues with the jitter etc.
>>>
>>> If a packet loss occur with the first packet with the new rate then
>>> there will be a jitter value here due to the definition of jitter as
>>> using the timestamp values of the older packet part of the calculation.
>>>
>>>
>>> 2. Also I think Section 2.2.2 points to a naive implementation of that
>>> method. As I see it when you do calculations based on that method you
>>> need to use the more expanded formula:
>>
>> A the difference of the formula in 2.2.1 (which is what people actually use)), 
>> the formula in 2.2.2 is the one that the I-D tentatively set as the formula for 
>> future implementations that does not want to use a different SSRC (more about 
>> this below).
>>
>> Now you do not explain why this formula is better than the simpler formula 
>> capture_time * clock_rate.  See also my response to the next comments.
> 
> Well, it avoids the jump backwards in TS that you got unless you adjust
> the start point.

Yes, but - unless my calculations are incorrect - the jitter is still incorrect
with this formula.  I created a Google spreadsheet to illustrate this (in
"Magnus proposal" tab):

https://spreadsheets.google.com/ccc?key=0AndnqRvudSVbdDhwMEhuOEVGdzVDdnNkMlluRGRnb1E&hl=en&authkey=CLaT9oAI

Please let me know if I missed something.

> 
>>
>>>
>>> timestamp = (capture_time-capture_start) * clock_rate + Start_offset
>>>
>>> Then every time you change the rate you need to set new values for
>>> "capture_start" and Start_offset:
>>>
>>> Start_offset = (capture_time_start_of_new_rate-capture_start)
>>> *previous_clock_rate
>>> capture_start = capture_time_start_of_new_rate
>>>

[...]

- -- 
Marc Petit-Huguenin
Personal email: [email-masked]
Professional email: [email-masked]
Blog: http://blog.marc.petit-huguenin.org

---

From: Randell Jesup <[email-masked]>
Date: Thu, 21 Apr 2011 23:01:13 -0400

>Please let me know if I missed something.

Well, I should note that "incorrect" implies that there's a canonical
"correct" value.  I would assert there isn't; there's merely the value
calculated as per the spec.  Since the original spec didn't anticipate
clock-rate changes, the fact that the jitter readings for Magnus'
proposal doesn't match what the legacy algorithm would calculate doesn't
mean they're 'wrong'; just different.

The jitter values reported in RTCP are rather imprecise to begin with,
since if I remember they're affected by things like duplicate packets.

Note: I have not reviewed the proposal (though I took part in discussions on
this issue here 3 or 4 years ago) and have no opinion on it currently.

-- 
Randell Jesup, Worldgate
[email-masked]

---

From: Marc Petit-Huguenin <[email-masked]>
Date: Thu, 21 Apr 2011 20:33:34 -0700

> mean they're 'wrong'; just different.

The formula I proposed in 2.2.2 (capture_time * clock_rate) does not have this
problem, and I think that if we recommend a formula for the new implementations
that still insist on switching clock rates inside the same SSRC, it should be
better than the legacy formula.  Note also (I missed this in my previous email)
that this formula does not seem to prevent the TS to jump backward, as shown in
the spreadsheet.

> since if I remember they're affected by things like duplicate packets.

Right, but we should still try to do better than sending pseudo random values if
we can.

- -- 
Marc Petit-Huguenin

---

From: Magnus Westerlund <[email-masked]>
Date: Wed, 27 Apr 2011 09:30:12 +0200

>>>> capture_start = capture_time_start_of_new_rate

To me it appears that the error in the spreadsheet is that you use
"capture_start" in cell E7 as D6, instead of D7 as it should be. If you
set it to that I think you will get the correct value for the timestap,
i.e. 640 in E7. Then the jitter becomes 0.

To me E7 should be =(A7-D7)*B7+C7

In other words for this method you need to update the base values
Start_offset, and Capture_Start prior to calculating the first timestamp
for the new clock rate. This is different from the other method I
included in my previous method that first calculates and then updates.

In similar fashion there is an error in the cells when switching back.

Cheers

Magnus Westerlund

----------------------------------------------------------------------
Multimedia Technologies, Ericsson Research EAB/TVM
----------------------------------------------------------------------
Ericsson AB                | Phone  +46 10 7148287
Färögatan 6                | Mobile +46 73 0949079
SE-164 80 Stockholm, Sweden| mailto: [email-masked]
----------------------------------------------------------------------

---

From: Magnus Westerlund <[email-masked]>
Date: Thu, 28 Apr 2011 10:12:43 +0200

Hi,

Marc give me the rights to update his spreadsheet and I have figured out
why he gotten spikes even after the update for the jitter. It has to do
with the calculation of the jitter previously in the spread sheet.

So the Section 2.2.2 formula proposal by me (clarified):

Then every time you change the rate you need to set new values for
"capture_start" and Start_offset prior to calculating the new rates
timestamp value:

When it comes to jitter calculation I find that the calculation will
become all 0 over a rate switch as long as one use the following version
of the RFC 3550 interarrival formula

D(i,j) = (Rj - Ri) - (Sj - Si) = (Rj - Sj) - (Ri - Si)

What is not specified in the RFC 3550 on this matter is the need for
deriving Ri and Rj using the same clock rate and that clock rate to be
the one of the older packet. The reason one needs to use the older rate
is due to the packet duration aspect.

I will note that if one loses the first packet for a new rate, there
will be jitter values as the receiver will consider the timestamp
different and the clock rate as all being according to the old one, when
in fact it is one old and one new duration present in the interval.

Thus I use in the spread sheet the calculation that is:

ABS((Arrival_Time_i*Previous_clock_rate-timestamp_i)-(Previous_Arrival_Time*Previous_clock_rate-previous_timestamp)

Where previous is the value for last prior received packets in this flow.

I also applied this jitter calculation to the non-monotomic and legacy
proposals to see what happens.

I also verified my proposal for 2.2.1 and that also appears to be valid.

Cheers

Magnus Westerlund