Linux Media Controller development
 help / color / mirror / Atom feed
From: Stephane Chauveau <stephane@chauveau-central.net>
To: Mauro Carvalho Chehab <mchehab@redhat.com>, linux-media@vger.kernel.org
Subject: Re: [PATCH] media:  ir-rc5-decoder: improve responsiveness by 100ms to 250ms
Date: Thu, 18 Apr 2013 01:09:52 +0200	[thread overview]
Message-ID: <516F2BC0.60807@chauveau-central.net> (raw)
In-Reply-To: <516F1FC2.20208@chauveau-central.net>


And here are two small patches to obtain timings on the original decoder.

--- linux/drivers/media/rc/ir-rc5-decoder.c.orig    2013-04-17 
20:40:41.939326236 +0200
+++ linux/drivers/media/rc/ir-rc5-decoder.c    2013-04-18 
00:42:11.386539568 +0200
@@ -64,6 +64,8 @@ static int ir_rc5_decode(struct rc_dev *
      if (!geq_margin(ev.duration, RC5_UNIT, RC5_UNIT / 2))
          goto out;

+    printk( KERN_INFO "DECODE %c%02d (%dus)\n", 
(ev.pulse)?'+':'-',(ev.duration*10)/RC5_UNIT,  TO_US(ev.duration)) ;
+
  again:
      IR_dprintk(2, "RC5(x) decode started at state %i (%uus %s)\n",
             data->state, TO_US(ev.duration), TO_STR(ev.pulse));
@@ -99,13 +101,14 @@ again:
          if (!is_transition(&ev, &dev->raw->prev_ev))
              break;

-        if (data->count == data->wanted_bits)
+        if (data->count == data->wanted_bits)
              data->state = STATE_FINISHED;
          else if (data->count == CHECK_RC5X_NBITS)
              data->state = STATE_CHECK_RC5X;
          else
              data->state = STATE_BIT_START;
-
+        if (data->state == STATE_FINISHED)
+            printk( KERN_INFO "FINISHED\n");
          decrease_duration(&ev, RC5_BIT_END);
          goto again;

@@ -158,7 +161,7 @@ again:
              IR_dprintk(1, "RC5 scancode 0x%04x (toggle: %u)\n",
                     scancode, toggle);
          }
-
+        printk( KERN_INFO "KEYDOWN\n");
          rc_keydown(dev, scancode, toggle);
          data->state = STATE_INACTIVE;
          return 0;



--- linux/drivers/media/rc/rc-main.c.orig    2013-04-18 
00:41:44.546364678 +0200
+++ linux/drivers/media/rc/rc-main.c    2013-04-18 00:42:49.122785516 +0200
@@ -533,6 +533,7 @@ static void ir_do_keyup(struct rc_dev *d
      if (!dev->keypressed)
          return;

+    printk( KERN_INFO "KEYUP\n");
      IR_dprintk(1, "keyup key 0x%04x\n", dev->last_keycode);
      input_report_key(dev->input_dev, dev->last_keycode, 0);
      if (sync)



On 04/18/2013 12:18 AM, Stephane Chauveau wrote:
> Here is a more detailed analysis of the problems my patch is supposed 
> to solve.
>
> I added a few printk in the module to obtain some detailed timings.
>
>  - DECODE is emited once at the begining of each call of 
> ir_rc5_decode() to describe the blank or pulse event reported by ite_cir
>  - FINISHED is emited during the last STATE_BIT_END when executing 
> state=STATE_FINISHED
>  - KEYDOWN is emited just before calling rc_keydown()
>  - KEYUP is emited by ir_do_keyup() in rc-main.c
>
> The value following DECODE is the length of the pulse (+) or blank 
> (-)  as multiples of RC5_UNIT/10 (e.g. +20 means a pulse of 2*RC5_UNIT 
> while -9 means a blank of 1*RC5_UNIT). The next value is that same 
> length in microseconds.
>
> Here are the timings for a single 'even' RC-5 message (last bit is 0 
> so a blank followed by a pulse) using the original module:
>
>  [507703.409737] DECODE +20  (1788us)
>  [507703.412097] DECODE -19  (1762us)
>  [507703.413282] DECODE +20  (1788us)
>  [507703.415622] DECODE -19  (1762us)
>  [507703.416822] DECODE +19  (1762us)
>  [507703.419159] DECODE -20  (1788us)
>  [507703.420357] DECODE +20  (1779us)
>  [507703.421523] DECODE -9   (885us)
>  [507703.422691] DECODE +10  (894us)
>  [507703.423869] DECODE -19  (1771us)
>  [507703.426239] DECODE +20  (1788us)
>  [507703.427406] DECODE -19  (1762us)
>  [507703.428639] DECODE +10  (894us)
>  [507703.429772] DECODE -9   (877us)
>  [507703.429779] DECODE +10  (894us)
>  [507703.430946] DECODE -9   (885us)
>  [507703.432131] DECODE +10  (894us)
>  [507703.432138] FINISHED
>  [507703.631331] DECODE -2255  (200317us)
>  [507703.631338] KEYDOWN
>  [507703.880020] KEYUP
>
>
> The last DECODE of 200ms is caused the timeout in the IR driver (see 
> ITE_IDLE_TIMEOUT in ite_cir.h).
>
> The final STATE_BIT_END is processed before that long event is 
> received but, because of the test after the 'goto again', the final 
> STATE_FINISHED is delayed until the 200ms blank is received.
>
> It is important to notice that the KEYDOWN occurs 220ms after the 
> first pulse and the keyup about 450ms after that the last pulse.
>
> The timings are similar for an odd RC-5 code (last bit is 1 so a pulse 
> followed by a blank)
>
>  [508157.054735] DECODE +19  (1762us)
>  [508157.055906] DECODE -10  (929us)
>  [508157.057098] DECODE +9   (868us)
>  [508157.057107] DECODE -10  (911us)
>  [508157.058259] DECODE +9   (842us)
>  [508157.060730] DECODE -20  (1823us)
>  [508157.061800] DECODE +19  (1762us)
>  [508157.064167] DECODE -20  (1788us)
>  [508157.065341] DECODE +19  (1727us)
>  [508157.066507] DECODE -10  (937us)
>  [508157.067686] DECODE +9   (868us)
>  [508157.068932] DECODE -19  (1771us)
>  [508157.071227] DECODE +20  (1779us)
>  [508157.072423] DECODE -20  (1797us)
>  [508157.073588] DECODE +9   (842us)
>  [508157.074759] DECODE -10  (929us)
>  [508157.075937] DECODE +19  (1736us)
>  [508157.275149] DECODE -2252  (200039us)
>  [508157.275156] FINISHED
>  [508157.275159] KEYDOWN
>  [508157.524021] KEYUP
>
> Here, the final STATE_BIT_END is a blank so it is processed as part of 
> the final timeout.
>
> In any cases, the KEYDOWN in STATE_FINISHED occurs after the 200ms 
> timeout so about 220ms after the first pulse.
>
> Finally, the KEYUP occurs 250ms after the KEYDOWN because of the 
> timeout in rc-main.c (see IR_KEYPRESS_TIMEOUT)
>
> The situation is slightly different when the button remains pressed 
> because the remote repeats the message after 113ms as required by the 
> RC-5 protocol:
>
>  [507866.803970] DECODE +20  (1831us)
>  [507866.805169] DECODE -9   (825us)
>  [507866.806330] DECODE +10  (894us)
>  [507866.806339] DECODE -10  (911us)
>  [507866.807511] DECODE +10  (955us)
>  [507866.809874] DECODE -19  (1736us)
>  [507866.811043] DECODE +19  (1701us)
>  [507866.813413] DECODE -21  (1875us)
>  [507866.814893] DECODE +18  (1675us)
>  [507866.815758] DECODE -10  (937us)
>  [507866.817038] DECODE +9   (868us)
>  [507866.818110] DECODE -20  (1823us)
>  [507866.820479] DECODE +20  (1788us)
>  [507866.821646] DECODE -19  (1762us)
>  [507866.822818] DECODE +9   (816us)
>  [507866.823989] DECODE -10  (937us)
>  [507866.823994] DECODE +9   (842us)
>  [507866.825244] DECODE -10  (963us)
>  [507866.826358] DECODE +9   (868us)
>  [507866.826364] FINISHED
>  [507866.915932] DECODE -1009  (89664us)
>  [507866.915938] KEYDOWN
>  [507866.917121] DECODE +19  (1753us)
>  [507866.918286] DECODE -10  (963us)
>  [507866.919463] DECODE +9   (842us)
>  [507866.920685] DECODE -10  (911us)
>  [507866.920696] DECODE +10  (894us)
>  [507866.922999] DECODE -20  (1797us)
>  [507866.924181] DECODE +19  (1727us)
>  [507866.926530] DECODE -20  (1797us)
>  [507866.927705] DECODE +20  (1840us)
>  [507866.928912] DECODE -9   (825us)
>  [507866.930067] DECODE +9   (842us)
>  [507866.931238] DECODE -20  (1823us)
>  [507866.933611] DECODE +20  (1788us)
>  [507866.934778] DECODE -19  (1762us)
>  [507866.935954] DECODE +9   (868us)
>  [507866.937150] DECODE -10  (937us)
>  [507866.938305] DECODE +9   (816us)
>  [507866.938310] DECODE -10  (963us)
>  [507866.939484] DECODE +10  (894us)
>  [507866.939488] FINISHED
>  [507867.139873] DECODE -2264  (201081us)
>  [507867.139880] KEYDOWN
>  [507867.388021] KEYUP
>
> The long 200ms blank is replaced by a 90ms blank so the first DECODE 
> occurs earlier and repeats itself every 113ms as long as the remote 
> keeps sending messages.
>
> The last message is processed as a single message and takes about 470ms:
>    - about 20ms for decoding the message itself.
>    - 200ms for the ITE_IDLE_TIMEOUT timeout until KEYDOWN.
>    - 250ms for the IR_KEYPRESS_TIMEOUT timeout until KEYUP.
>
> To summarize, the first KEYDOWN occurs 113ms or 220ms after the first 
> pulse and the final KEYUP occurs 450ms after the last pulse.
>
> The delay between the first KEYDOWN and final KEYUP is about 470ms for 
> a double message and 580ms for a triple message.
>
> I found that triple messages are quite common and they are likely to 
> cause at least one key repeat on most systems: the key repeat delay is 
> hard-coded to 500ms in XBMC which makes the remove almost unusable.
>
> My patch improves those timings using 2 techniques.
>
> First, the KEYDOWN is sent immediately after receiving the first half 
> of the last bit.
>
> Second, ITE_IDLE_TIMEOUT=200ms is longer than the required delay for 
> repeated messages in RC5 (113ms) so it is possible to explicitly send 
> the KEYUP event as soon as a long blank is received. This is 
> controlled by the macro RC5_UP_DELAY. An even better approach could be 
> to accumulate the duration of all pulses and space until 113ms is 
> reached but in practice waiting for a long blank seems to be good enough.
>
> With my patch, the timings for a single event look like that
>
>  [503403.889246] DECODE +19  (1753us)
>  [503403.890415] DECODE -11  (990us)
>  [503403.890421] DECODE +8   (790us)
>  [503403.891603] DECODE -10  (955us)
>  [503403.893012] DECODE +9   (816us)
>  [503403.895133] DECODE -20  (1849us)
>  [503403.896326] DECODE +19  (1701us)
>  [503403.898669] DECODE -20  (1849us)
>  [503403.899885] DECODE +19  (1701us)
>  [503403.901041] DECODE -10  (963us)
>  [503403.902201] DECODE +9   (807us)
>  [503403.903375] DECODE -21  (1884us)
>  [503403.905749] DECODE +18  (1675us)
>  [503403.906912] DECODE -20  (1849us)
>  [503403.908099] DECODE +9   (816us)
>  [503403.909281] DECODE -10  (963us)
>  [503403.909289] DECODE +9   (816us)
>  [503403.910440] DECODE -10  (963us)
>  [503403.910444] KEYDOWN
>  [503403.911660] DECODE +10  (894us)
>  [503403.911670] FINISHED
>  [503404.110830] DECODE -2255  (200256us)
>  [503404.110842] KEYUP
>
> The KEYDOWN and the KEYUP respectively occur 20ms and 220ms after the 
> first pulse (versus 220ms and 470ms with the original module)
>
> For a double message the timings are
>
>  [503489.269908] DECODE +20  (1788us)
>  [503489.271076] DECODE -9   (877us)
>  [503489.271081] DECODE +9   (868us)
>  [503489.272268] DECODE -10  (911us)
>  [503489.273443] DECODE +10  (894us)
>  [503489.275785] DECODE -20  (1797us)
>  [503489.276990] DECODE +19  (1727us)
>  [503489.279317] DECODE -19  (1771us)
>  [503489.280640] DECODE +19  (1753us)
>  [503489.281686] DECODE -10  (937us)
>  [503489.282855] DECODE +9   (842us)
>  [503489.284050] DECODE -20  (1849us)
>  [503489.286406] DECODE +19  (1701us)
>  [503489.287569] DECODE -21  (1875us)
>  [503489.288766] DECODE +9   (816us)
>  [503489.289929] DECODE -9   (877us)
>  [503489.289935] DECODE +10  (894us)
>  [503489.291108] DECODE -10  (911us)
>  [503489.291112] KEYDOWN
>  [503489.292308] DECODE +9   (868us)
>  [503489.292316] FINISHED
>  [503489.381904] DECODE -1009  (89682us)
>  [503489.383064] DECODE +20  (1779us)
>  [503489.384235] DECODE -10  (911us)
>  [503489.385408] DECODE +9   (868us)
>  [503489.386574] DECODE -10  (911us)
>  [503489.386579] DECODE +9   (868us)
>  [503489.388960] DECODE -20  (1823us)
>  [503489.390121] DECODE +19  (1701us)
>  [503489.392594] DECODE -21  (1901us)
>  [503489.393658] DECODE +18  (1675us)
>  [503489.394830] DECODE -10  (929us)
>  [503489.396039] DECODE +9   (816us)
>  [503489.397205] DECODE -20  (1823us)
>  [503489.399547] DECODE +19  (1727us)
>  [503489.400747] DECODE -20  (1849us)
>  [503489.401909] DECODE +9   (816us)
>  [503489.403074] DECODE -10  (963us)
>  [503489.404268] DECODE +9   (816us)
>  [503489.404278] DECODE -11  (990us)
>  [503489.404284] KEYDOWN
>  [503489.405456] DECODE +8   (781us)
>  [503489.405465] FINISHED
>  [503489.604647] DECODE -2252  (200031us)
>  [503489.604659] KEYUP
>
>
> The 2 KEYDOWNs and the KEYUP event respectively occur 21ms, 134ms and 
> 334ms after the first pulse (versus 111ms, 335ms and 584ms)
>
> The KEYUP occurs 200ms after the last pulse (versus 450ms).
>
> For a double message, the delay between the first KEYDOWN and the 
> final KEYUP is around 310ms (vs 470ms).
> For a triple message, the delay is 420ms (vs 580) which is still below 
> the key-repeat delay of 500ms used by XBMC and most desktops.
>
> On 04/17/2013 10:50 PM, Stephane Chauveau wrote:
>> Hello,
>>
>> Here is a patch to improve the responsiveness of the rc5 decoder when 
>> using the ite-cir driver. Most of the information below should also 
>> be applicable to other decoders and ir drivers (e.g. rc6 for sure). 
>> The problem is that the current decoder is subject to a double timeout:
>>
>>  (a)  200ms in ite-cir (see ITE_IDLE_TIMEOUT)
>>
>>  (b)  250ms in rc-main (see IR_KEYPRESS_TIMEOUT)
>>
>> The timeout (a) is causing a delay of up to 200ms on the keypress 
>> events because STATE_FINISHED is not processed until a blank is 
>> received.
>> The timeout (b) is causing an additional delay of 250ms on the final 
>> keyup.
>>
>> My patch is reducing those delays using two techniques:
>>
>>  (1) The keypress is sent as soon as the 1st half of the last bit is 
>> received. This is a bi-phase encoding so the second part is not 
>> strictly needed to figure out the value of that last bit.
>>
>>  (2) An explicit keyup in produced when the 200ms blank caused by 
>> timeout (a) is detected. In practice, timeout (b) never occurs.
>>
>> reminder: The RC5 protocol specifies that messages shall be be 
>> repeated every 113ms as long as the key remains pressed.
>>
>> Here are some real timings measured by adding a few printk:
>>
>> For a single RC5 message the KEYDOWN and the KEYUP respectively occur 
>> 20ms and 220ms after receiving the first pulse (versus 220ms and 
>> 470ms with the original decoder)
>>
>> For a double RC5 message the 2 KEYDOWNs and the KEYUP events 
>> respectively occur 21ms, 134ms and 334ms after the first pulse 
>> (versus 111ms, 335ms and 584ms)
>>
>> For a triple RC5 message the 3 KEYDOWNs and the KEYUP events 21ms, 
>> 134ms, 247 and 447ms after the first pulse (versus 111ms, 335ms, 
>> 448ms and 697ms)
>>
>> Unfortunately, triple RC5 messages are quite common when using the 
>> remote in a nomal way and, without my patch, the delay between the 
>> first keydown and the final keyup is about 590ms. This is enough to 
>> cause a key-repeat on most systems. For instance, XBMC has an 
>> hard-coded key-repeat delay of 500ms and so is almost unusable 
>> without my patch.
>>
>> Even with a key repeat delay set to 600ms or above, the original 
>> decoder feels sluggish and unreliable.
>>
>> I did not try but in theory the timeout (a) could be reduced to any 
>> value above 134ms to make the decoder even more responsive.
>>
>> Stephane.
>>
>>
>> --- ir-rc5-decoder.c.orig    2013-04-17 20:40:41.939326236 +0200
>> +++ ir-rc5-decoder.c    2013-04-17 21:51:40.368925128 +0200
>> @@ -30,11 +30,14 @@
>>  #define RC5_BIT_START        (1 * RC5_UNIT)
>>  #define RC5_BIT_END        (1 * RC5_UNIT)
>>  #define RC5X_SPACE        (4 * RC5_UNIT)
>> +#define RC5_UP_DELAY        114000000 /* ns */
>>
>>  enum rc5_state {
>>      STATE_INACTIVE,
>>      STATE_BIT_START,
>>      STATE_BIT_END,
>> +    STATE_LAST_START,
>> +    STATE_LAST_END,
>>      STATE_CHECK_RC5X,
>>      STATE_FINISHED,
>>  };
>> @@ -99,8 +102,8 @@ again:
>>          if (!is_transition(&ev, &dev->raw->prev_ev))
>>              break;
>>
>> -        if (data->count == data->wanted_bits)
>> -            data->state = STATE_FINISHED;
>> +        if (data->count == data->wanted_bits-1)
>> +            data->state = STATE_LAST_START;
>>          else if (data->count == CHECK_RC5X_NBITS)
>>              data->state = STATE_CHECK_RC5X;
>>          else
>> @@ -109,22 +112,16 @@ again:
>>          decrease_duration(&ev, RC5_BIT_END);
>>          goto again;
>>
>> -    case STATE_CHECK_RC5X:
>> -        if (!ev.pulse && geq_margin(ev.duration, RC5X_SPACE, 
>> RC5_UNIT / 2)) {
>> -            /* RC5X */
>> -            data->wanted_bits = RC5X_NBITS;
>> -            decrease_duration(&ev, RC5X_SPACE);
>> -        } else {
>> -            /* RC5 */
>> -            data->wanted_bits = RC5_NBITS;
>> -        }
>> -        data->state = STATE_BIT_START;
>> -        goto again;
>> -
>> -    case STATE_FINISHED:
>> -        if (ev.pulse)
>> +    case STATE_LAST_START:
>> +        if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2))
>>              break;
>>
>> +        data->bits <<= 1;
>> +        if (!ev.pulse)
>> +            data->bits |= 1;
>> +        data->count++;
>> +        data->state = STATE_LAST_END;
>> +
>>          if (data->wanted_bits == RC5X_NBITS) {
>>              /* RC5X */
>>              u8 xdata, command, system;
>> @@ -160,6 +157,42 @@ again:
>>          }
>>
>>          rc_keydown(dev, scancode, toggle);
>> +
>> +        return 0;
>> +
>> +    case STATE_LAST_END:
>> +        if (!is_transition(&ev, &dev->raw->prev_ev))
>> +            break;
>> +
>> +        data->state = STATE_FINISHED;
>> +
>> +        decrease_duration(&ev, RC5_BIT_END);
>> +        goto again;
>> +
>> +    case STATE_CHECK_RC5X:
>> +        if (!ev.pulse
>> +            && geq_margin(ev.duration, RC5X_SPACE, RC5_UNIT/2)) {
>> +            /* RC5X */
>> +            data->wanted_bits = RC5X_NBITS;
>> +            decrease_duration(&ev, RC5X_SPACE);
>> +        } else {
>> +            /* RC5 */
>> +            data->wanted_bits = RC5_NBITS;
>> +        }
>> +        data->state = STATE_BIT_START;
>> +        goto again;
>> +
>> +    case STATE_FINISHED:
>> +        if (ev.pulse)
>> +            break;
>> +
>> +        /* The message is repeated  RC5_UP_DELAY ns after the 1st pulse
>> +         * so a blank of RC5_UP_DELAY ns after the last pulse shall be
>> +         * enough to assume that the message is not repeated.
>> +         */
>> +        if (ev.duration > RC5_UP_DELAY)
>> +            rc_keyup(dev) ;
>> +
>>          data->state = STATE_INACTIVE;
>>          return 0;
>>      }
>> Signed-off-by: Stephane Chauveau <stephane@chauveau-central.net>
>>
>>
>> -- 
>> To unsubscribe from this list: send the line "unsubscribe 
>> linux-media" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
> -- 
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


      reply	other threads:[~2013-04-17 23:09 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-04-17 20:50 [PATCH] media: ir-rc5-decoder: improve responsiveness by 100ms to 250ms Stephane Chauveau
2013-04-17 22:18 ` Stephane Chauveau
2013-04-17 23:09   ` Stephane Chauveau [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=516F2BC0.60807@chauveau-central.net \
    --to=stephane@chauveau-central.net \
    --cc=linux-media@vger.kernel.org \
    --cc=mchehab@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox