Subject: RE: [rohc] The discussion on slope(s)

From: [email-masked]
Date: Wed, 1 Dec 2004 17:56:54 -0500

> Let me give an example for a good argument that dynamic 
> slopes are not in 3095. 
> Consider section 6.5.
> This section was intended as the basis for future documents 
> describing  context transfer, so it lists all the state that a compressor/a 
> decompressor needs to maintain. 
> Dynamic slopes are not among this state.

Carsten,

That is because dynamic slopes were not considered worthwhile 
to transfer. The benefit of transferring dynamic slopes is
to stay in SO state during context transfer. However it's
complicated because the compressor may not be in SO state 
at the beginning or in the middle of a context transfer.

Of course, the point is debatable. But we really haven't
had a chance to discuss. I was one of the proponents of 
context transfer, but many other authors opposed the idea of 
context transfer at that time. As a result, context relocation 
is not mentioned by 3095 at all, and there has been no serious 
discussion/work on context relocation in ROHC.

In 3GPP, however, ROHC context relocation has been discussed and
adopted in TS 25.331 (I remember it's optional). There, SYN_SLOPE_TS
(the last synchronized slope of TS) was defined as an optional
parameter in context transfer.

I think it's fair to also look at the arguments that dynamic
(or learned or implicit) slopes are in 3095. I have given some
back in March/April. Below is one of them. If I have to summarize
in one sentence, the argument is that if dynamic slopes are not
in 3095, many text (some are essential to encoding) wouldn't 
make sense without twisting hard the meaning of words.
http://www1.ietf.org/mail-archive/web/rohc/current/msg02101.html

BR, Zhigang

_______________________________________________
Rohc mailing list
[email-masked]
https://www1.ietf.org/mailman/listinfo/rohc

---

From: [email-masked]
Date: Thu, 2 Dec 2004 17:18:12 -0500

> http://www1.ietf.org/mail-archive/web/rohc/current/msg02081.html
> (the last one included questions to Zhigang, which were ignored)

Kristofer,

Lars-Erik pointed out that I didn't reply to your questions
(copied below) in the above email. Sorry about that. I probably 
missed them. Handing that many emails were not easy for me.

Short answers: section 4.5.3 is correct. The definition of
TS_STRIDE in section 2 is wrong.

Long answers. ROHC works at RTP packet level. That's for sure.
What section 4.5.3 says is that for video, you can still
scale the TS by TS_STRIDE (see example below). The mentioning 
of "frame delta" is to explain why and give reminder about
the special "ladder" characteristics of TS in video.

            <------ String 1 ------>  <-- String 2 --->
SN            11   12   13 ...    25   26   27   28 ...
TS          4000 4000 4000 ...  4000 7000 7000 7000 ... 
TS_SCALED      1    1    1 ...     1    2    2    2 ...
TS_OFFSET   1000 1000 1000 ...  1000 1000 1000 1000 ... 
slope       <--------  0 ---------->  <----- 0 ------->
offset      <--------- 1 ---------->  <----- 2 ------->

RE the definition of TS_STRIDE, it was probably written
with audio context - the most important application of
ROHC. But it's not generic enough to cover video.

Another note: TS scaling is optional. Of course, scaling 
by a factor of 1 is equivalent to no scaling.

BR, Zhigang

--------------------------------------------------------------------
Ok, now I see one reason that we both base ourselves on the spec but reach opposite conclusions.
This example in 4.5.3 actually explains your thinking:

In the case of video, there is usually a TS_STRIDE as well when the
video frame level is considered. The sample rate for most video
codecs is 90 kHz. If the video frame rate is fixed, say, to 30
frames/second, the TS will increase by n * 3000 (= n * 90000 / 30)
between video frames. Note that a video frame is often divided into
several RTP packets to increase robustness against packet loss. In
this case several RTP packets will carry the same TS.

That is a contradiction of 2.0:

Timestamp stride

The timestamp stride (TS_STRIDE) is the expected increase in the
timestamp value between two RTP packets with consecutive sequence
numbers.

4.5.3 talks about stride as the "frame delta" and 2.0 as the "packet delta".
So yes, if 4.5.3 "overrides" 2.0 then you're right that the stride cannot be 0, and then I can see why you think I'm silly to say we must define modulus 0. But if 2.0 overriders 4.5.3, then I still think I'm right.
That's one quite fundamental difference.

So, one is wrong. Which one?
-----------------------------------------------------------------

---

From: [email-masked]
Date: Thu, 2 Dec 2004 19:45:52 -0500

Carsten,

> > As it is described in section 4.5.3 and other places in RFC
> > 3095, TS_STRIDE is the factor by which an RTP Timestamp is
> > downscaled before compression. Obviously, it cannot be 0 (zero).
> 
> Well, zero is not exactly prohibited, but then you couldn't send any 
> other value than TS_OFFSET, which wouldn't be too useful.

A zero TS_STRIDE would also make section 4.5.3 look weird. For example, 
"it compresses the downscaled values: TS_SCALED = TS / TS_STRIDE."

> > Example 1 (audio stream with TS_STRIDE = 160):
> >
> > SN           11  12  13  14 ...   60    61    62    63 ...
> > TS          200 360 420 580 ... 8040 16040 16200 16360 ...
> > TS_SCALED     1   2   3   4 ...   50   100   101   102 ...
> > TS_OFFSET    40  40  40  40       40    40    40    40 ...
> > slope       <--------  1 ---------->    <----- 1 ------->
> > offset      <-------- (-10)-------->    <----- (39) ---->
> 
> The problem with this picture is that it does not identify 
> which of the packets are context-updating.
> The way I read msg934, the intention of this proposal was to only 
> compute slope from the points created by CRC-checked packets.

Yes. I re-draw the picture below to make it clear. Also, I corrected
a typo (TS in packet 13). Of course, there are many different scenarios
of context-updating packets or ACKs of them being lost (see below)
I can provide additional examples with detail if needed.

             <------- String 1 -------->    <----- String 2 ------->
SN           11  12  13  14  15 ...   60    61    62    63    64 ...
Ctxt-Update   x   x   x                      x     x     x
TS          200 360 520 680 840 ... 8040 16040 16200 16360 16520 ...
TS_SCALED     1   2   3   4   5 ...   50   100   101   102   103 ...
TS_OFFSET    40  40  40  40  40 ...   40    40    40    40    40 ...
slope       <-----------  1 ----------->    <---------- 1 --------->
offset      <----------- (-10)--------->    <--------- (39) ------->

> > After the fist string, the decompressor will update the
> > linear function from SN to X depending on how many packets carrying
> > field(X) have been correctly decompressed.
> 
> I'm not sure I understand this sentence.
>
> After SN-60 and SN-61 (assuming both are context-updating), 
> the msg934 slope is 50.

In the above example, the compressor wouldn't send SN-60 as
context-updating (CU) packet, since its TS_SCALED still conforms 
to the linear pattern. The compressor would send SN-61 as CU
since it's the one that breaks TS_SCALED pattern. For packets 
after SN-61, the compressor can have different options as follows
(basically text in section 5.5.1.2 of 3095):
1) Send all of them as CU until receiving two ACKs.
2) Send some of them as CU while others non-CU, until receiving two ACKs.
3) In this example, since the slope(String 1) = slope(String 2),
the compressor can be "lazy" by doing either 1 or 2, but just waiting 
for one ACK before sending -0 packets.

Now the decompressor side:
- When it receives the first CU after -0 packets, it knows a
new string begins.
- If it received and ACKed only one CU before receiving another -0 
packet, it knows compressor is in case 3 above, which means
slope(String 2) = slope(String 1). It decompress -0 accordingly.
- Else, the decompressor knows the compressor is in case 1 or 2. 
Calculate the slope using the last two CUs that have been ACKed.

> Since you don't really know which of these actually arrived (even in 
> R-mode, you must wait for the ACKs to arrive, and some these 
> might even  be lost), 
> it will take a while before it is one again.
> This is one of the reasons I'm not a great fan of msg934 slopes.

But msg934 slope does not add much delay, since at least one CU packet 
is needed anyway to synchronize the offset.

a) if the slope of TS_SCALED is always equal to the default-slope, 
then msg934 slope also means one CU is needed. Same result.

b) Else, the new slope has to communicated to the decompressor.
Now, if we follow msg934, two CUs are needed. For R-mode, it means
RTT + another ACK (say compressor takes option 1). For UO-mode, 
it means L+1 CU packets need to be sent. The difference is just 
one packet.

Furthermore, for case b), I still need to see how exactly it would work 
without msg934. 

BR, Zhigang

---

From: "Lars-Erik Jonsson (LU/EAB)" <[email-masked]>
Date: Fri, 3 Dec 2004 14:48:44 +0100

> > Well, zero is not exactly prohibited, but then you couldn't 
> > send any other value than TS_OFFSET, which wouldn't be too useful.

It is true that with a TS_STRIDE of 0, one would not be able to
scale the TS value when it actually have to be sent, but I would
not say TS_OFFSET=0 is useless, as one would be able to omit the
TS in consecutive packets with constant TS.

> A zero TS_STRIDE would also make section 4.5.3 look weird. 
> For example, "it compresses the downscaled values:
> TS_SCALED = TS / TS_STRIDE."

Yes, this formula should be replaced by the actual scaling
formula: TS = TS_SCALED * TS_STRIDE + TS_OFFSET

The TS_SCALED = TS / TS_STRIDE formula is not really good in any
case, since with an undefined "/", it could be interpretred as if
it generates a TS_SCALED that is not necessarily an integer number.  

> > > linear function from SN to X depending on how many 
> > > packets carrying field(X) have been correctly decompressed.
> > 
> to the linear pattern. 

So, you mean that you would have to force the compressor not to
send updating packets to avoid the slope being accidentially
updated? There are other reasons for sending updating packets
than to establish an implicit slope, the periodic R-0-CRC for
SN update, for example.

I still miss the full logic for how a new slope is established at
the decompressor, as well as all the rules the compressor will
have to follow to ensure it makes the correct assumptions for
which slope is established at the decompressor, and (maybe most
important) how the compressor ensures it does not accidentially
makes the decompressor update the slope. A complete picture for
all modes would be very interesting (or maybe terrifying) to see.

/L-E

---

From: "Lars-Erik Jonsson (LU/EAB)" <[email-masked]>
Date: Fri, 3 Dec 2004 16:04:20 +0100

> TS in consecutive packets with constant TS.

Of course, I meant "I would not say TS_STRIDE=0 is useless"

/L-E

---

From: [email-masked]
Date: Fri, 3 Dec 2004 11:16:27 -0500

> > I probably missed Kristofer's email. 
> 
> Well, you answered, but not to the questions he asked.

Lars-Erik,

Which questions I didn't answer?

BR, Zhigang

---

From: [email-masked]
Date: Fri, 3 Dec 2004 11:45:01 -0500

Lars-Erik,

Could you walk me through the two examples I gave in my email below,
and tell me exactly how ROHC should work in your opinion, step-by-step?

BR, Zhigang

---

From: "Lars-Erik Jonsson (LU/EAB)" <[email-masked]>
Date: Mon, 6 Dec 2004 09:54:46 +0100

Example 2 (video stream with TS_STRIDE = 0):

            <------ String 1 ------>  <-- String 2 --->
SN            11   12   13 ...    25   26   27   28   29   30 ...
TS          4000 4000 4000 ...  4000 7000 7000 7000 7000 7000 ... 
TS_SCALED      -    -    - ...     -    -    -    -    -    - ...
TS(unsc. LSB)  -    -    - ...     - 7000 7000 7000    -    - ...
TS_OFFSET   4000 4000 4000 ...  4000 7000 7000 7000 7000 7000 ... 

> -----Original Message-----
> From: [email-masked] [mailto:[email-masked]]On Behalf Of
> [email-masked]
> Sent: den 3 december 2004 17:45
> To: Lars-Erik Jonsson (LU/EAB); [email-masked]
> Cc: [email-masked]
> Subject: RE: [rohc] The discussion on slope(s)
> 
> 
> Lars-Erik,
>

---

From: [email-masked]
Date: Thu, 9 Dec 2004 17:46:48 -0500

> But it won't use any "slope" component of X as a reference 
> unless it is a R-0-CRC.

Right, but it will use the {SN, TS} in X as reference, which
is also used to calculate the slope. So, if {SN, TS} has
an undetected error (the reason of incorrect slope), the error
will be detected with high probability this time and triggers 
a context resynchorinzation, including the slope value.

Probably this will be clearer below.

> The part I'm not sure about is why Kristofer thinks these wouldn't 
> update the dynamic slope, too.
> (I don't think anyone has proposed a detailed algorithm for when/how 
> exactly dynamic slopes would be updated, yet.)

I think I more or less explained the algorithm in previous emails.
http://www1.ietf.org/mail-archive/web/rohc/old-archive/msg00934.html
http://www1.ietf.org/mail-archive/web/rohc/current/msg03054.html
But let me try again, because it's critical for the discussion. 

For simplicity, I'll use TS as example below, but the same can 
be applied to IP-ID and other header fields. Furthermore, I'll
assume TS is unscaled, i.e. TS = TS_SCALED.

- Initialization. For TS and IP-ID, default-slopes are specified
in section 5.7 of 3095. 

- When to update slope(TS)? 

The compressor will update slope(TS) if the cur_slope(TS) 
!= prev_slope(TS), where cur_slope(TS) and prev_slope(TS) are
the slope(TS) of current and previous string, respectively. 

Note: for the first string for a context, prev_slope(TS) = default-slope(TS).

Note: if cur_slope(TS) == prev_slope(TS), the compressor does not
have to update slope(TS) during current string. But it may do so 
if it is not confident about prev_slope(TS).

- How to update slope(TS)? 

The compressor must be sure that the decompressor has at least
received and correctly decompressed two update packets that
a) belong to current string, AND 
b) both of them carry TS field. 

As usual, the confidence of the compressor depends on mode. For 
UO-mode, it's the repetition (i.e. L). For R-mode, it's the ACKs.

The decompressor calculates cur_slope(TS) as follows:

    cur_slope(TS) = (TS2 - TS1) / (SN2 - SN1)

where {SN1, TS1} and {SN2, TS2} are the decompressed SN and TS values
of the last two update packets it has received and ACKed.

For example and more details, see bottom part of msg03054.

BR,
Zhigang