Re: [rohc] SN Encoding clarification
Ang Way Chuang <wcang@nav6.org> Fri, 17 July 2009 02:26 UTC
Return-Path: <wcang@nav6.org>
X-Original-To: rohc@core3.amsl.com
Delivered-To: rohc@core3.amsl.com
Received: from localhost (localhost [127.0.0.1]) by core3.amsl.com (Postfix) with ESMTP id 2E21C3A6E15 for <rohc@core3.amsl.com>; Thu, 16 Jul 2009 19:26:56 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -0.427
X-Spam-Level:
X-Spam-Status: No, score=-0.427 tagged_above=-999 required=5 tests=[AWL=-0.228, BAYES_00=-2.599, J_CHICKENPOX_13=0.6, J_CHICKENPOX_14=0.6, J_CHICKENPOX_16=0.6, J_CHICKENPOX_31=0.6]
Received: from mail.ietf.org ([64.170.98.32]) by localhost (core3.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id zmyplr3UyEIQ for <rohc@core3.amsl.com>; Thu, 16 Jul 2009 19:26:54 -0700 (PDT)
Received: from nav6.org (mail.nav6.org [219.93.2.80]) by core3.amsl.com (Postfix) with ESMTP id 456AF3A6E12 for <rohc@ietf.org>; Thu, 16 Jul 2009 19:26:52 -0700 (PDT)
Received: from localhost (unknown [127.0.0.1]) by nav6.org (Postfix) with ESMTP id 1D7FB1D60165; Fri, 17 Jul 2009 02:27:23 +0000 (UTC)
X-Virus-Scanned: amavisd-new at nav6.org
Received: from [10.207.161.112] (unknown [10.207.161.112]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by nav6.org (Postfix) with ESMTP id 5710A1D600CB; Fri, 17 Jul 2009 10:27:11 +0800 (MYT)
Message-ID: <4A5FE17E.3090703@nav6.org>
Date: Fri, 17 Jul 2009 10:27:10 +0800
From: Ang Way Chuang <wcang@nav6.org>
User-Agent: Thunderbird 2.0.0.22 (X11/20090608)
MIME-Version: 1.0
To: Karthik Balaguru <Karthik.Balaguru@lntinfotech.com>
References: <OFA961666C.233250EC-ON652575F4.0044E5B0-652575F5.004F73EB@lntinfotech.com>
In-Reply-To: <OFA961666C.233250EC-ON652575F4.0044E5B0-652575F5.004F73EB@lntinfotech.com>
Content-Type: text/plain; charset="ISO-8859-1"; format="flowed"
Content-Transfer-Encoding: 7bit
Cc: rohc@ietf.org
Subject: Re: [rohc] SN Encoding clarification
X-BeenThere: rohc@ietf.org
X-Mailman-Version: 2.1.9
Precedence: list
List-Id: Robust Header Compression <rohc.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/listinfo/rohc>, <mailto:rohc-request@ietf.org?subject=unsubscribe>
List-Archive: <http://www.ietf.org/mail-archive/web/rohc>
List-Post: <mailto:rohc@ietf.org>
List-Help: <mailto:rohc-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/rohc>, <mailto:rohc-request@ietf.org?subject=subscribe>
X-List-Received-Date: Fri, 17 Jul 2009 02:26:56 -0000
Karthik Balaguru wrote: > > Hi, > > Thanks for your reply. > > 1) Yes, the info conveyed by you is correct. In opensource code, it > looks that d_lsb_decode( ) function does not handle wrap around cases > properly. > > But, If Sequence number are in sequence, the opensource decoding > would work fine for wrap around scenario, because the following line in > the > d_lsb_decode( ) will take care of the wrap around condtion. > if(sn<lower) sn+= 1 <<k; Didn't notice that before. Thanks. > And, for the out of ordered SN, the decoding using d_lsb_decode( ) > has problems. > > 2) In the method that you have explained using __lsb_decode( ), the > definition for __builtin_expect(curr, 1) and > vector->calc_p(vector->bits) functions are missing in the code. Can > you please send those definitions. And also can you please explain > the method of calculation of the p value dynamically. > Sorry about that. For: if (__builtin_expect(curr, 1)) val = lsb->val; else val = lsb->prev_val; /* decode LSB encoded data using latest reference value and * return the decoded value * @m: LSB value to be decoded * @k: number of bits used by @m * if someone can optimize or suggest more elegant, please notify me */ uint32_t lsb_decode(struct lsb_data * lsb, uint32_t m, uint8_t k) { return __lsb_decode(lsb, m, k, 1); } /* decode LSB encoded data using prev reference value and return the * decoded value */ uint32_t lsb_decode_prev(struct lsb_data * lsb, uint32_t m, uint8_t k) { return __lsb_decode(lsb, m, k, 0); } __lsb_decode is an internal function used by 2 other functions shown above. The curr variable is used to determine whether LSB is going to decoded using latest reference value or otherwise. That is useful for CRC correction attempt. __builtin_expect is a built-in function specific to gcc to inform compiler to optimize for a particular branch. In non-gcc speak, it will be similar to if (curr == 1) . /* function type to compute the value of p for LSB */ typedef int32_t (*p_func_t)(uint8_t k); The function calc_p has the signature as shown above. It takes in the k (k-bits) and calculate the value of p according to k. For example, SN for UDP profile will be something like this: #define p_constant(name, x) static inline uint32_t p_constant_##name(uint8_t k) {return x;} p_constant(negone, -1) /* p_constant_negone */ For RTP SN, obviously the p needs to adjust according to k. We, Universiti Sains Malaysia, plan to release the buggy user space ROHC library source code that we modified when it is ready in a few months, I hope. > Thx in advans, > Karthik Balaguru > > > > > *Ang Way Chuang <wcang@nav6.org>* > Sent by: rohc-bounces@ietf.org > > 07/14/2009 07:16 AM > > > To > Karthik Balaguru <Karthik.Balaguru@lntinfotech.com> > cc > rohc@ietf.org > Subject > Re: [rohc] SN Encoding clarification > > > > > > > > > Hi, > > If my understanding is correct, the g function is > rohc.sourceforge.net > is incorrect when there is wraparound. d_lsb_decode is also incorrect > when there is a wraparound. > > > 1. Modifying the GPL'ed, rohc.sourceforge.net. Here is, in my opinion, > how g function should look like: > /* Calculates the f(vref, k) interval for LSB > * @vref: reference that will be used to calculate interval > * @bits: is the number of bits that actual vref carry > * @k: number of bits that is used to encode LSB > * @min: the minimum will be stored here after function returns > * @max: the maximum of the range will be stored here. > * > * Note that it is possible for max < min if wraparound occurs which > * is correct according RFC 3905 (or at least according to my > * interpretation of the RFC :) ) > */ > static inline void f_interval(uint32_t vref, uint8_t k, uint8_t bits, > int32_t p, uint32_t * min, uint32_t * max) > { > uint32_t bitmask; > > bitmask = ((((uint64_t) 1 << bits) - 1) & 0xffffffff); > *min = (vref - p) & bitmask; > *max = (vref + (1 << k) - 1 - p) & bitmask; > } > > /** > * finds minimum k so that v falls into the interval f(v_ref, k) > * Part of the LSB calculation algorithm > * @vector: wlsb_vector object itself > * @v_ref: reference value to create LSB > * @v: actual value to be encoded > */ > static inline uint8_t g(struct wlsb_vector * vector, uint32_t v_ref, > uint32_t v) > { > uint8_t k; > uint32_t min, max; > > for(k = 0; k < vector->bits; k++) { > f_interval(v_ref, k, vector->bits, > vector->calc_p(vector->bits), &min, > &max); > > if (min > max) { /* wrap-around */ > if (v >= min || v <= max) > break; > } > > if ((v <= max) && (v >= min)) > break; > } > > return k; > } > > 2. Here is in my opinion, how LSB decoding should look like taking into > account the possibility of wrap around: > > /** > * struct lsb_data - LSB decoding data structure > * @val: current value > * @prev_valu: previous value > * @calc_p: function that calculate the value of p > * @bits: the number of bits of the contained value > */ > struct lsb_data > { > uint32_t val; > uint32_t prev_val; > p_func_t calc_p; > uint8_t bits; > }; > > static inline uint32_t __lsb_decode(struct lsb_data * lsb, uint32_t m, > uint8_t k, int curr) > { > uint32_t bitmask; > uint32_t val; > uint32_t min; > uint32_t max; > uint32_t min_mask; > > if (__builtin_expect(curr, 1)) > val = lsb->val; > else > val = lsb->prev_val; > > f_interval(val, k, lsb->bits, lsb->calc_p(k), &min, &max); > bitmask = ~((((uint64_t) 1 << k) - 1) & 0xffffffff); > val = (val & bitmask) | (m & ~bitmask); > > if (max < min) { /* wraparound */ > /* extract LSB of min */ > min_mask = (min & ((1 << k) - 1)); > > if (min_mask > m) > return m; > else > return min + (m - > min_mask); > } > > /* non wraparound from now on */ > if (val > max) > val -= (1 << k); > > if (val < min) > val += (1 << k); > > return val; > } > > The logic behind __lsb_decode function is described in the attached > text. The note was written by myself for myself in case I forget. Sorry > if it is incomprehensible to others. It's good if some of the expert > ROHCers can verify whether this code is correct according to ROHC. > > > Karthik Balaguru wrote: > > > > Hi, > > > > Need clarifications on SN Encoding. > > > > I wonder why the 'g funtion' has not been very explicitly defined in the > > RFC 3095. > > > > For SN WLSB - > > 1. As per the understanding & also based on the IETF mailing list > > discussions , the 'g function' in > > the Compressor for K bit calculation looks as below - > > ( Reference - > > http://www.ietf.org/mail-archive/web/rohc/old-archive/msg02263.html ) > > > > g(v_minmax, v) > > { > > FLOOR( log2 ( v_minmax XOR v ) ) + 1; > > } > > k1 = g(v_min, v); > > k2 = g(v_max, v); > > Sn_k = max(k1, k2); > > Here, v is Received SN , v_min & v_max are the minimum SN & > > maximum SN repectively in the window > > > > And in the Decompressor, packet it looks as below :- > > mask = ~((1 << Sn_k) - 1); // mask is uint16 > > rtpSeq = ((v_ref & mask) | ESn); > > Here, ESn is the Extracted SN bits from the Compressed packets. > > > > > > 2. But, from the opensource RoHC code , the below info was obtained :- > > ( Reference - http://rohc.sourceforge.net/download.php ) > > > > On the compressor side, the 'g function' is as below - > > static void f(int v_ref, int k, int p, int * min, int * max) > > { > > *min = v_ref - p; > > *max = v_ref + ((1 << k) - 1) - p; // (1 << k) = > > 2 to the power of k > > } > > > > static int g(int v_ref, int v, int p, int bits) > > { > > int k, min, max; > > for(k = 0; k < bits; k++){ > > f(v_ref, k, p, &min, &max); > > if( (v <= max) && (v >= min) ) break; > > } > > return k; > > } > > > > And in the decompressor , it is as below - > > int d_lsb_decode(struct sd_lsb_decode * s, int m, int k) > > { > > int lower = (s->v_ref_d - s->p); > > // int higher = (ref - s->p) + 1 << k - 1; > > int bitmask = ~((1 << k) - 1); > > int sn = (s->v_ref_d & bitmask) | m; > > if (sn < lower) sn += 1 << k; > > return sn & 0xFFFF; > > } > > > > So, Kindly let me know the method that is inline with RFC 3095 for the > > 'g function' . > > > > Thx in advans, > > Karthik Balaguru > > ______________________________________________________________________ > > > > > > ------------------------------------------------------------------------ > > > > _______________________________________________ > > Rohc mailing list > > Rohc@ietf.org > > https://www.ietf.org/mailman/listinfo/rohc > > > > ______________________________________________________________________Note > on LSB > =========== > Interpretation interval is given by this formulae: > > f(v_ref, k) = [v_ref - p, v_ref + (2^k - 1) - p] > > When receiving m-bits LSBs, the decompressor uses the interpretation > interval f(v_ref_d, m), called interval_d. It picks as the > decompressed value the one in interval_d whose LSBs match the > received m bits. > > Case study of value wraparound > --------------------------------- > Let's analyse the case where the value of to be encoded is of 16 > bits long. Let's say that, > > vref = 0xfff0 > val = 0x0 > p = 0 > > According to RFC 3095: > > "The scheme is guaranteed to be correct if the compressor and the > decompressor each use interpretation intervals > 1) in which the original value resides, and > 2) in which the original value is the only value that has the > exact same k least significant bits as those transmitted." > > To fulfill statement 1, k=5 bits is good enough assuming that the > interpretation interval wraps around in which the interpretation > interval will be 0xfff0 - 0x000f. If 5 bits is used, the > encoded value will be 0 for uncompressed value of 0. Statement 2 is > also fulfilled because the LSB of 0xfff0 is 10000b instead of 00000b. > > The full list of encoded values and its uncompressed values for > these parameters are: > vref = 0xfff0 > k = 5 > p = 0 > m=0, v=0 > m=1, v=1 > . > . > . > m=0xf, v=0xf > m=0x10, v=0xfff0 > m=0x11, v=0xfff1 > . > . > . > m=0x1f, v=0xffff > > > So in the case of where parameters are like this: > vref = 0x0 > k = 3 > p = 5 > The list of encoded values and its uncompressed values: > m=0b, v=0 m=100b, v=0xfffc > m=1b, v=1 m=101b, v=0xfffd > m=10b, v=2 m=110b, v=0xfffe > m=11b, v=0xfffb m=111b, v=0xffff > > Now comes the interesting part -- to put this into algorithm. > For wraparound case, minimum value in the interpretation interval is > greater than maximum value in the interpretation interval. Notice > the examples above, the minimum value (0xfff0 and 0xfffb) becomes > the threshold in itself. So to get the threshold value for m which > is equivalent masking minimum value: > > 1. min_mask = (min & ((1 << k) - 1)); > > If m is less than min_mask (threshold), then nothing need to be done > since that is the decoded value. > > 2. if (min_mask > m) > 3. return m; > > However, m is greater to or equal threshold value, then decoded > value can be calculated by adding the difference between m and > threshold value (min_mask) to minimum value in the interpretation > interval (min). > > 4. else > 5. return min + (m - min_mask); > > > > > Non-wraparound value > -------------------- > Potential to downgrade/upgrade using AND 0xffff bitmask against vref > --------------------------------------------------------------- > Suppose 16-bits value is used again, but with these parameters > vref = 10 (potential to upgrade m=111b to v=15) > k = 3 > p = 5 > f(v_ref, k) = [5, 12] > > The list of encoded values and its uncompressed values: > m=0b, v=8 m=100b, v=12 > m=1b, v=9 m=101b, v=5 > m=10b, v=10 vref = 0xfff0 > val = 0x0 > p = 0m=110b, v=6 > m=11b, v=11 m=111b, v=7 > > If vref = 7 (potential to downgrade m=0 to v=0) > k = 3 (potential to upgrade m=111b to v=15) > p = 5 > f(v_ref, k) = [2, 9] > The list of encoded values and its uncompressed values: > m=0b, v=8 m=100b, v=4 > m=1b, v=9 m=101b, v=5 > m=10b, v=2 m=110b, v=6 > m=11b, v=3 m=111b, v=7 > > If vref = 11 (potential to upgrade m=111b to v=15) > k = 3 > p = 5 > f(v_ref, k) = [6, 13] > The list of encoded values and its uncompressed values: > m=0b, v=8 m=100b, v=12 > m=1b, v=9 m=101b, v=13 > m=10b, v=10 m=110b, v=6 > m=11b, v=11 m=111b, v=7 > > If vref = 14 (potential to downgrade m=0 to v=8) > k = 3 > p = 5 > f(v_ref, k) = [9, 16] > The list of encoded values and its uncompressed values: > m=0b, v=16 m=100b, v=12 > m=1b, v=9 m=101b, v=13 > m=10b, v=10 m=110b, v=14 > m=11b, v=11 m=111b, v=15 > > Do note that the downgrade problem can be fixed by adding 2^k to > decoded value if the decoded value is found to be less than minimum > value. > > Upgrade problem can be fixed by deducting 2^k to decoded value if > the decoded value is found to be greater than maximum value. > > > > > _______________________________________________ > Rohc mailing list > Rohc@ietf.org > https://www.ietf.org/mailman/listinfo/rohc > > > ______________________________________________________________________ > > > ------------------------------------------------------------------------ > > _______________________________________________ > Rohc mailing list > Rohc@ietf.org > https://www.ietf.org/mailman/listinfo/rohc
- [rohc] Support of ROHC Piggyback Feedback in LTE Karthik Balaguru
- Re: [rohc] Support of ROHC Piggyback Feedback in … pelle
- Re: [rohc] Support of ROHC Piggyback Feedback in … Karthik Balaguru
- [rohc] SN Encoding clarification Karthik Balaguru
- Re: [rohc] SN Encoding clarification Ang Way Chuang
- Re: [rohc] SN Encoding clarification Karthik Balaguru
- Re: [rohc] SN Encoding clarification Ang Way Chuang