[ANNOUNCE] improved LIRC remote for VDR-1.5.12

Message ID 47840ACB.9050205@gmx.de
State New
Headers

Commit Message

Reinhard Nissl Jan. 8, 2008, 11:44 p.m. UTC
  Hi,

I was quite annoyed how I could operate my EPIA MII-6000E using a
LIRC remote. It was almost not possible to navigate through the
OSD in a fast way.

The attached patch allows now to define timeouts and frequencies
for example in Make.config, so there is no need to patch every
VDR version. Furthermore, frequencies are now defined in unit 1/s
instead of the unit ms (which defined the period), making values
more intuitive.

There's now an additional frequency which defines, how fast a
user is allowed to press the same button repeatedly. The
originally used REPEATDELAY allowed only 2.85 button presses per
second.

On slow and busy machines like my EPIA it happened often that
several button presses were read by VDR in a single read, but
only the first one got processed. The code now reads only a
single button press from LIRC's socket, so button presses don't
get lost (although presses of the same button will be skipped as
the timeouts don't get reached).

To make it less likely that button presses get processed in
chunks a further define allows to decrease the thread's niceness
which means to boost it's priority. This feature requires VDR to
be run as root.

This is my setup which follows some common settings found in
mainboard bioses for keyboard repeat delay and frequency.

> #vdr
> REMOTE=LIRC
> LIRC_PUSHFREQ=64 # 1/s
> LIRC_REPEATDELAY=250 # ms
> LIRC_REPEATFREQ=32 # 1/s
> #LIRC_REPEATTIMEOUT=500 # ms
> #LIRC_RECONNECTDELAY=3000 # ms
> LIRC_PRIORITYBOOST=1

Bye.
  

Comments

Dominique Matz Jan. 9, 2008, 4:41 p.m. UTC | #1
Hi Reinhard,

sound very good, but vdr as root do not :-(

do you think it is possible to use this or something else with an non
root user?

I think many use vdr with an special non root user, for example all
which use gentoo.


greetings mentox aka dominique




Reinhard Nissl schrieb:
> Hi,
>
> I was quite annoyed how I could operate my EPIA MII-6000E using a
> LIRC remote. It was almost not possible to navigate through the
> OSD in a fast way.
>
> The attached patch allows now to define timeouts and frequencies
> for example in Make.config, so there is no need to patch every
> VDR version. Furthermore, frequencies are now defined in unit 1/s
> instead of the unit ms (which defined the period), making values
> more intuitive.
>
> There's now an additional frequency which defines, how fast a
> user is allowed to press the same button repeatedly. The
> originally used REPEATDELAY allowed only 2.85 button presses per
> second.
>
> On slow and busy machines like my EPIA it happened often that
> several button presses were read by VDR in a single read, but
> only the first one got processed. The code now reads only a
> single button press from LIRC's socket, so button presses don't
> get lost (although presses of the same button will be skipped as
> the timeouts don't get reached).
>
> To make it less likely that button presses get processed in
> chunks a further define allows to decrease the thread's niceness
> which means to boost it's priority. This feature requires VDR to
> be run as root.
>
> This is my setup which follows some common settings found in
> mainboard bioses for keyboard repeat delay and frequency.
>
>   
>> #vdr
>> REMOTE=LIRC
>> LIRC_PUSHFREQ=64 # 1/s
>> LIRC_REPEATDELAY=250 # ms
>> LIRC_REPEATFREQ=32 # 1/s
>> #LIRC_REPEATTIMEOUT=500 # ms
>> #LIRC_RECONNECTDELAY=3000 # ms
>> LIRC_PRIORITYBOOST=1
>>     
>
> Bye.
>   
> ------------------------------------------------------------------------
>
> _______________________________________________
> vdr mailing list
> vdr@linuxtv.org
> http://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr
  
Magnus Hörlin Jan. 9, 2008, 6:57 p.m. UTC | #2
I can't get Reinhard's h.264/dvb-s2 patches and multiproto to work when 
running both dvb-s2 and dvb-t at the same time. Dvb-t works if I don't 
load the dvb-s modules and dvb-s(2) works if I don't load the dvb-t 
modules but it doesn't work with both.
Instead I'm currently running my dvb-t vdr on my server as usual and 
another vdr with dvb-s2 on one of my diskless clients. However, 
recording hd channels over nfs and simulaneously streaming it to my 
other diskless client overloads my network. Therefore I'm interested to 
know how hard it would be to modify vdr so I can run one vdr process 
with, say /dev/dvb/adapter0-3 and a second one on adapter4? Where do I 
start looking? Is it doable?

I tried running a virtual Ubuntu on my Mandriva server and used dvb-t 
usb sticks on the ubuntu but usb in vmware wasn't stable enough, at 
least on my attempts.

/Magnus H
  
Gavin Hamill Jan. 9, 2008, 7:10 p.m. UTC | #3
On Wed, 2008-01-09 at 19:57 +0100, Magnus Hörlin wrote:

> other diskless client overloads my network. Therefore I'm interested to 
> know how hard it would be to modify vdr so I can run one vdr process 
> with, say /dev/dvb/adapter0-3 and a second one on adapter4? Where do I 
> start looking? Is it doable?

http://linux.die.net/man/8/vdr

-D num, --device=num
        Use only the given DVB device (num = 0, 1, 2...). There may be
        several -D options (by default all DVB devices will be used).

You could also use streamdev-client + server on each instance to allow
them to share resources. Not ideal but the best there is currently.

gdh
  
Magnus Hörlin Jan. 9, 2008, 7:21 p.m. UTC | #4
Gavin Hamill wrote:
> On Wed, 2008-01-09 at 19:57 +0100, Magnus Hörlin wrote:
>
>   
>> other diskless client overloads my network. Therefore I'm interested to 
>> know how hard it would be to modify vdr so I can run one vdr process 
>> with, say /dev/dvb/adapter0-3 and a second one on adapter4? Where do I 
>> start looking? Is it doable?
>>     
>
> http://linux.die.net/man/8/vdr
>
> -D num, --device=num
>         Use only the given DVB device (num = 0, 1, 2...). There may be
>         several -D options (by default all DVB devices will be used).
>
> You could also use streamdev-client + server on each instance to allow
> them to share resources. Not ideal but the best there is currently.
>
> gdh
>
>
>
> _______________________________________________
> vdr mailing list
> vdr@linuxtv.org
> http://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr
>   
Ooops. I'm really sorry. I've used vdr for years but forgot to RTFM.
Thanks,
/Magnus
  
Reinhard Nissl Jan. 9, 2008, 9:02 p.m. UTC | #5
Hi,

Dominique Matz schrieb:

> sound very good, but vdr as root do not :-(
> 
> do you think it is possible to use this or something else with an non
> root user?

Well, only the LIRC_PRIORITYBOOST option requires root privileges
to work. If you don't have root privileges, you'll just get an
error logged and the LIRC thread runs without any change in
priority -- that's all. See man setpriority for details.

Bye.
  
Nicolas Huillard Jan. 10, 2008, 9:22 a.m. UTC | #6
Reinhard Nissl a écrit :
> Dominique Matz schrieb:
> 
>> sound very good, but vdr as root do not :-(
>>
>> do you think it is possible to use this or something else with an non
>> root user?
> 
> Well, only the LIRC_PRIORITYBOOST option requires root privileges
> to work. If you don't have root privileges, you'll just get an
> error logged and the LIRC thread runs without any change in
> priority -- that's all. See man setpriority for details.

An option would be to lower priority of all threads except this one. I 
guess only relative priority within VDR is important.
You can also raise priority in your init scripts (nice=-N), before 
running VDR. This way every thread will have nice=0 priority, except the 
LIRC one, which will stay at nice=-N
  
Ludwig Nussel Jan. 10, 2008, 9:49 a.m. UTC | #7
Nicolas Huillard wrote:
> Reinhard Nissl a écrit :
> > Dominique Matz schrieb:
> > 
> >> sound very good, but vdr as root do not :-(
> >>
> >> do you think it is possible to use this or something else with an non
> >> root user?
> > 
> > Well, only the LIRC_PRIORITYBOOST option requires root privileges
> > to work. If you don't have root privileges, you'll just get an
> > error logged and the LIRC thread runs without any change in
> > priority -- that's all. See man setpriority for details.
> 
> An option would be to lower priority of all threads except this one. I 
> guess only relative priority within VDR is important.
> You can also raise priority in your init scripts (nice=-N), before 
> running VDR. This way every thread will have nice=0 priority, except the 
> LIRC one, which will stay at nice=-N

Since the lirc thread doesn't do anything except waiting for input
most of the time it should be scheduled quickly anyways. Maybe the
useless select timeout destroys that advantage somewhat.
Also if multiple lines in the buffer are a problem what about
changing the code to consume only one line at a time instead of
messing with thread priorities?

cu
Ludwig
  
serge pecher Jan. 10, 2008, 11:18 a.m. UTC | #8
I have the same problem with 1x dvb-s and 1x dvb-s2.
In the mean time I intend to buy a second dvb-S instead of the dvb-S2, but
of course I am interested in a solution to have s ans s2 working together

Serge

-----Oorspronkelijk bericht-----
Van: vdr-bounces@linuxtv.org [mailto:vdr-bounces@linuxtv.org] Namens Magnus
Hörlin
Verzonden: woensdag 9 januari 2008 19:58
Aan: VDR Mailing List
Onderwerp: [vdr] Two VDR's on one machine

I can't get Reinhard's h.264/dvb-s2 patches and multiproto to work when 
running both dvb-s2 and dvb-t at the same time. Dvb-t works if I don't 
load the dvb-s modules and dvb-s(2) works if I don't load the dvb-t 
modules but it doesn't work with both.
Instead I'm currently running my dvb-t vdr on my server as usual and 
another vdr with dvb-s2 on one of my diskless clients. However, 
recording hd channels over nfs and simulaneously streaming it to my 
other diskless client overloads my network. Therefore I'm interested to 
know how hard it would be to modify vdr so I can run one vdr process 
with, say /dev/dvb/adapter0-3 and a second one on adapter4? Where do I 
start looking? Is it doable?

I tried running a virtual Ubuntu on my Mandriva server and used dvb-t 
usb sticks on the ubuntu but usb in vmware wasn't stable enough, at 
least on my attempts.

/Magnus H
  
Grégoire Favre Jan. 10, 2008, 11:39 a.m. UTC | #9
On Thu, Jan 10, 2008 at 12:18:16PM +0100, serge pecher wrote:
> I have the same problem with 1x dvb-s and 1x dvb-s2.
> In the mean time I intend to buy a second dvb-S instead of the dvb-S2, but
> of course I am interested in a solution to have s ans s2 working together

??? I use VDR with two DVB-S and one DVB-S2 here without problem...
  
serge pecher Jan. 10, 2008, 1:29 p.m. UTC | #10
Thanks for the info.
Could you have a look at
http://dvbkivabien2.info/viewtopic.php?f=7&t=12943&p=121435#p121435 where a
gave more explanation about my problem. Its seems that the tuner of the
S2-3200 is not detected, but I don?t know what to do.

Thanks,

Serge

-----Oorspronkelijk bericht-----
Van: vdr-bounces@linuxtv.org [mailto:vdr-bounces@linuxtv.org] Namens
Gregoire Favre
Verzonden: donderdag 10 januari 2008 12:39
Aan: VDR Mailing List
Onderwerp: Re: [vdr] Two VDR's on one machine

On Thu, Jan 10, 2008 at 12:18:16PM +0100, serge pecher wrote:
> I have the same problem with 1x dvb-s and 1x dvb-s2.
> In the mean time I intend to buy a second dvb-S instead of the dvb-S2, but
> of course I am interested in a solution to have s ans s2 working together

??? I use VDR with two DVB-S and one DVB-S2 here without problem...
  
Grégoire Favre Jan. 10, 2008, 4:43 p.m. UTC | #11
On Thu, Jan 10, 2008 at 02:29:58PM +0100, serge pecher wrote:
> Thanks for the info.
> Could you have a look at
> http://dvbkivabien2.info/viewtopic.php?f=7&t=12943&p=121435#p121435 where a
> gave more explanation about my problem. Its seems that the tuner of the
> S2-3200 is not detected, but I don?t know what to do.

Well,

it don't seems you have a guest access to read it ?

I don't have a S2-3200, but I think the first revision has a problem
(that was the main reason not to buy one) the best place to seek for
information is vdrportal.de in which there are a few topics about this
card.

But honestly, if you did a ./scripts/rmmod.pl load from the v4l dir of
the http://jusst.de/hg/multiproto it should work out of the box :-)

I use this small script in order to update/compil it (p=4000.diff is
just a patch to enable support for my card which for an unknow reason
isn't included sofar in multiproto).

By the way, I have no idea if your card need a firmware or not... mine
even if it's a budget one need one.

Good luck,
  
serge pecher Jan. 10, 2008, 6:33 p.m. UTC | #12
Will try the script this evening

Someone told me while looking at my logs on the dvbkivabien site, that the
tuner of the S2-3200 was'tn detected. Do you know what I should see in lsmod
if it was (what are I looking for ?).

If a use a non dvbs2/h264 patched vdr, should the s2-3200 work in only dvb-s
mode or am I obliged to use a patched vdr to have any result ? (just looking
to have an image for the moment, not that interested in HD for the time
being).


Thanks,

Serge

-----Oorspronkelijk bericht-----
Van: vdr-bounces@linuxtv.org [mailto:vdr-bounces@linuxtv.org] Namens
Gregoire Favre
Verzonden: donderdag 10 januari 2008 17:44
Aan: VDR Mailing List
Onderwerp: Re: [vdr] Two VDR's on one machine

On Thu, Jan 10, 2008 at 02:29:58PM +0100, serge pecher wrote:
> Thanks for the info.
> Could you have a look at
> http://dvbkivabien2.info/viewtopic.php?f=7&t=12943&p=121435#p121435 where
a
> gave more explanation about my problem. Its seems that the tuner of the
> S2-3200 is not detected, but I don?t know what to do.

Well,

it don't seems you have a guest access to read it ?

I don't have a S2-3200, but I think the first revision has a problem
(that was the main reason not to buy one) the best place to seek for
information is vdrportal.de in which there are a few topics about this
card.

But honestly, if you did a ./scripts/rmmod.pl load from the v4l dir of
the http://jusst.de/hg/multiproto it should work out of the box :-)

I use this small script in order to update/compil it (p=4000.diff is
just a patch to enable support for my card which for an unknow reason
isn't included sofar in multiproto).

By the way, I have no idea if your card need a firmware or not... mine
even if it's a budget one need one.

Good luck,
  
Grégoire Favre Jan. 10, 2008, 8:46 p.m. UTC | #13
On Thu, Jan 10, 2008 at 07:33:11PM +0100, serge pecher wrote:

Hello,

> Will try the script this evening

You could maybe first start it with unload option to be sure there
aren't other modules loaded about DVB, also you have to be sure DVB
wasn't compiled in the kernel.

The simple script was only to update and compil the modules, use the
scripts/rmmod.pl to load / unload the modules.

> Someone told me while looking at my logs on the dvbkivabien site, that the
> tuner of the S2-3200 was'tn detected. Do you know what I should see in lsmod
> if it was (what are I looking for ?).

One could also simply use dmesg, like here :

dmesg |grep DVB|grep regi
which here gives me :

DVB: registering new adapter (TT-Budget/WinTV-NOVA-CI PCI)
DVB: registering frontend 0 (ST STV0299 DVB-S)...
DVB: registering new adapter (cx88[0])
DVB: registering frontend 1 (Conexant CX24116/CX24118)...
DVB: registering new adapter (cx88[1])
DVB: registering frontend 2 (Conexant CX24123/CX24109)...

So my 3 cards are detected right.

> If a use a non dvbs2/h264 patched vdr, should the s2-3200 work in only dvb-s
> mode or am I obliged to use a patched vdr to have any result ? (just looking
> to have an image for the moment, not that interested in HD for the time
> being).

If you use multiproto driver from just.de then you have to use a patched
VDR (it's a guess as I didn't try it with an vanilla VDR).

Good luck,
  
Reinhard Nissl Jan. 10, 2008, 9:43 p.m. UTC | #14
Hi,

serge pecher schrieb:

> Could you have a look at
> http://dvbkivabien2.info/viewtopic.php?f=7&t=12943&p=121435#p121435 where a
> gave more explanation about my problem. Its seems that the tuner of the
> S2-3200 is not detected, but I don’t know what to do.

Well, I don't understand French.

Try this:
cd /path/to/multiproto/tree
make unload
make load

Check the output of dmesg now or have a look at /var/log/messages
(other distributions my use a different file).

Bye.
  
serge pecher Jan. 11, 2008, 9:32 a.m. UTC | #15
As far as I can see I get the needed modules loaded (stb6100, stb0899,
lnbp21 saa7416, budget-ci)
When I try make unload and make load it loads 204 modules and I get no image
at all anymore in vdr, nor on the nexus-s nor on the s2-3200. I think
because s2-3200 comes as adapter0 and nexus as adapter1
When I rmmod all modules and just modprobe dvb-ttpci and stv0299, it works
normally.
When I modprobe stb6100, stb0899 and budget-ci, I can see an image on the
nexus for a few minutes and then I read in the logs "now tuned to ..." and I
get a black screen.

Thanks for your assistance

serge

-----Oorspronkelijk bericht-----
Van: vdr-bounces@linuxtv.org [mailto:vdr-bounces@linuxtv.org] Namens
Reinhard Nissl
Verzonden: donderdag 10 januari 2008 22:44
Aan: VDR Mailing List
Onderwerp: Re: [vdr] Two VDR's on one machine

Hi,

serge pecher schrieb:

> Could you have a look at
> http://dvbkivabien2.info/viewtopic.php?f=7&t=12943&p=121435#p121435 where
a
> gave more explanation about my problem. Its seems that the tuner of the
> S2-3200 is not detected, but I don't know what to do.

Well, I don't understand French.

Try this:
cd /path/to/multiproto/tree
make unload
make load

Check the output of dmesg now or have a look at /var/log/messages
(other distributions my use a different file).

Bye.
  
Joerg Knitter Jan. 11, 2008, 11:53 a.m. UTC | #16
Reinhard Nissl wrote:
> The attached patch allows now to define timeouts and frequencies
> for example in Make.config, so there is no need to patch every
> VDR version. Furthermore, frequencies are now defined in unit 1/s
> instead of the unit ms (which defined the period), making values
> more intuitive.
>   
I would prefer some OSD settings for LIRC (if possible) because on every 
VDR setup you are able to do first controls with the keyboard. So you 
could access the settings menu and tune the LIRC settings the way you 
want. A makefile settings also will not work if you use some prebuild 
packages. I also remember the time using LIRC when I always had to patch 
the lirc code - currently, I am glad being able to use DVB-IR. :)

With kind regards

Jörg
  
Reinhard Nissl Jan. 11, 2008, 10:26 p.m. UTC | #17
Hi,

Nicolas Huillard schrieb:

> An option would be to lower priority of all threads except this one. I 
> guess only relative priority within VDR is important.
> You can also raise priority in your init scripts (nice=-N), before 
> running VDR. This way every thread will have nice=0 priority, except the 
> LIRC one, which will stay at nice=-N

That doesn't work as there is no collection of threads in VDR
which would be necessary to catch all threads for example which
are created by plugins.

Bye.
  
Reinhard Nissl Jan. 11, 2008, 10:38 p.m. UTC | #18
Hi,

Ludwig Nussel schrieb:

> Since the lirc thread doesn't do anything except waiting for input
> most of the time it should be scheduled quickly anyways. Maybe the
> useless select timeout destroys that advantage somewhat.

I don't think so. In my case (i. e. on my EPIA MII-6000E), there
are a lot of other threads from xine-lib for example which cause
already noticeable load and due to the xine-lib design, boost
their priority a bit on their own (e. g. the video out thread).

> Also if multiple lines in the buffer are a problem what about
> changing the code to consume only one line at a time instead of
> messing with thread priorities?

The patch addresses this issue already. But VDR processes these
button presses with almost no delay so they will be dropped.

I think, the LIRC protocol misses a timestamp for each button
press. Or an even more favorable solution would be to put the
timeout and frequency processing into LIRC and have VDR to
process each key as it arrives, just like with the KBD remote.

I've first tried to process each key as it arrives but the result
wasn't useable as the remote used a too short repeat delay. So
most often, one moved on for two items instead of one (per button
press).

Bye.
  
Ville Skyttä Jan. 12, 2008, 12:38 p.m. UTC | #19
On Saturday 12 January 2008, Reinhard Nissl wrote:

> I think, the LIRC protocol misses a timestamp for each button
> press. Or an even more favorable solution would be to put the
> timeout and frequency processing into LIRC and have VDR to
> process each key as it arrives, just like with the KBD remote.

Would using liblirc_client instead of the current "homebrew" implementation 
help out with this?


Also, somewhat off topic: when running powertop[1] on my VDR box, I see lircd 
waking up the CPU from idle about 1000 times a second while VDR is connected 
to it:

Top causes for wakeups:
  54.3% (988.1)             lircd : schedule_timeout (process_timeout)
  28.5% (518.4)               vdr : futex_wait (hrtimer_wakeup)
[...]

I already tried adding some cCondWait::SleepMs's to VDR's lirc action loop but 
it didn't seem to have any effect.  Any ideas whether this is something that 
VDR could do anything about, or if it's a LIRC internal thing?

[1] http://www.lesswatts.org/projects/powertop/
  
Reinhard Nissl Jan. 12, 2008, 1:23 p.m. UTC | #20
Hi,

Ville Skyttä schrieb:

>> I think, the LIRC protocol misses a timestamp for each button
>> press. Or an even more favorable solution would be to put the
>> timeout and frequency processing into LIRC and have VDR to
>> process each key as it arrives, just like with the KBD remote.
> 
> Would using liblirc_client instead of the current "homebrew" implementation 
> help out with this?

When liblirc_client uses the same interface of lircd, then I
don't think that it will help.

> Also, somewhat off topic: when running powertop[1] on my VDR box, I see lircd 
> waking up the CPU from idle about 1000 times a second while VDR is connected 
> to it:
> 
> Top causes for wakeups:
>   54.3% (988.1)             lircd : schedule_timeout (process_timeout)
>   28.5% (518.4)               vdr : futex_wait (hrtimer_wakeup)
> [...]
> 
> I already tried adding some cCondWait::SleepMs's to VDR's lirc action loop but 
> it didn't seem to have any effect.  Any ideas whether this is something that 
> VDR could do anything about, or if it's a LIRC internal thing?

Well VDR's lirc action loop uses a timeout only when it needs to
generate a keyup event after a key repeat event. Otherwise it
blocks in cFile::FileReady's select() until a button gets pressed
on the remote.

Try running irw instead of VDR and check powertop again.

Bye.
  
Ville Skyttä Jan. 12, 2008, 1:36 p.m. UTC | #21
On Saturday 12 January 2008, Reinhard Nissl wrote:
> Ville Skyttä schrieb:
>
> > Also, somewhat off topic: when running powertop[1] on my VDR box, I see
> > lircd waking up the CPU from idle about 1000 times a second while VDR is
> > connected to it:
> >
> > Top causes for wakeups:
> >   54.3% (988.1)             lircd : schedule_timeout (process_timeout)
> >   28.5% (518.4)               vdr : futex_wait (hrtimer_wakeup)
> > [...]
> >
> > I already tried adding some cCondWait::SleepMs's to VDR's lirc action
> > loop but it didn't seem to have any effect.  Any ideas whether this is
> > something that VDR could do anything about, or if it's a LIRC internal
> > thing?
>
> Well VDR's lirc action loop uses a timeout only when it needs to
> generate a keyup event after a key repeat event. Otherwise it
> blocks in cFile::FileReady's select() until a button gets pressed
> on the remote.
>
> Try running irw instead of VDR and check powertop again.

Yep, same thing with irw so I suppose this needs to be addressed in LIRC, not 
VDR.  Thanks.
  
Klaus Schmidinger Feb. 9, 2008, 12:49 p.m. UTC | #22
On 01/09/08 00:44, Reinhard Nissl wrote:
> Hi,
> 
> I was quite annoyed how I could operate my EPIA MII-6000E using a
> LIRC remote. It was almost not possible to navigate through the
> OSD in a fast way.
> 
> The attached patch allows now to define timeouts and frequencies
> for example in Make.config, so there is no need to patch every
> VDR version. Furthermore, frequencies are now defined in unit 1/s
> instead of the unit ms (which defined the period), making values
> more intuitive.
> 
> There's now an additional frequency which defines, how fast a
> user is allowed to press the same button repeatedly. The
> originally used REPEATDELAY allowed only 2.85 button presses per
> second.
> 
> On slow and busy machines like my EPIA it happened often that
> several button presses were read by VDR in a single read, but
> only the first one got processed. The code now reads only a
> single button press from LIRC's socket, so button presses don't
> get lost (although presses of the same button will be skipped as
> the timeouts don't get reached).
> 
> To make it less likely that button presses get processed in
> chunks a further define allows to decrease the thread's niceness
> which means to boost it's priority. This feature requires VDR to
> be run as root.
> 
> This is my setup which follows some common settings found in
> mainboard bioses for keyboard repeat delay and frequency.
> 
>> #vdr
>> REMOTE=LIRC
>> LIRC_PUSHFREQ=64 # 1/s
>> LIRC_REPEATDELAY=250 # ms
>> LIRC_REPEATFREQ=32 # 1/s
>> #LIRC_REPEATTIMEOUT=500 # ms
>> #LIRC_RECONNECTDELAY=3000 # ms
>> LIRC_PRIORITYBOOST=1

Isn't there a way to have all this done in LIRC itself?
I can hardly imagine that all other applications using LIRC do
such elaborate parameter fiddling, too.

Klaus
  
Anssi Hannula Feb. 9, 2008, 12:53 p.m. UTC | #23
Klaus Schmidinger wrote:
> On 01/09/08 00:44, Reinhard Nissl wrote:
>>> #vdr
>>> REMOTE=LIRC
>>> LIRC_PUSHFREQ=64 # 1/s
>>> LIRC_REPEATDELAY=250 # ms
>>> LIRC_REPEATFREQ=32 # 1/s
>>> #LIRC_REPEATTIMEOUT=500 # ms
>>> #LIRC_RECONNECTDELAY=3000 # ms
>>> LIRC_PRIORITYBOOST=1
> 
> Isn't there a way to have all this done in LIRC itself?
> I can hardly imagine that all other applications using LIRC do
> such elaborate parameter fiddling, too.

I think most other applications use the lirc library instead of directly 
parsing the commands.
  
Klaus Schmidinger Feb. 9, 2008, 1:12 p.m. UTC | #24
On 02/09/08 13:53, Anssi Hannula wrote:
> Klaus Schmidinger wrote:
>> On 01/09/08 00:44, Reinhard Nissl wrote:
>>>> #vdr
>>>> REMOTE=LIRC
>>>> LIRC_PUSHFREQ=64 # 1/s
>>>> LIRC_REPEATDELAY=250 # ms
>>>> LIRC_REPEATFREQ=32 # 1/s
>>>> #LIRC_REPEATTIMEOUT=500 # ms
>>>> #LIRC_RECONNECTDELAY=3000 # ms
>>>> LIRC_PRIORITYBOOST=1
>> Isn't there a way to have all this done in LIRC itself?
>> I can hardly imagine that all other applications using LIRC do
>> such elaborate parameter fiddling, too.
> 
> I think most other applications use the lirc library instead of directly 
> parsing the commands.

Then maybe that would be a good idea for VDR, too?

Klaus
  

Patch

--- ../vdr-1.5.12-dvbs2-other/lirc.c	2006-05-28 10:48:13.000000000 +0200
+++ lirc.c	2008-01-08 22:28:38.000000000 +0100
@@ -13,10 +13,24 @@ 
 #include <netinet/in.h>
 #include <sys/socket.h>
 
-#define REPEATDELAY 350 // ms
-#define REPEATFREQ 100 // ms
-#define REPEATTIMEOUT 500 // ms
-#define RECONNECTDELAY 3000 // ms
+#ifndef LIRC_PUSHFREQ
+#define LIRC_PUSHFREQ 3 // 1/s
+#endif
+#ifndef LIRC_REPEATDELAY
+#define LIRC_REPEATDELAY 350 // ms
+#endif
+#ifndef LIRC_REPEATFREQ
+#define LIRC_REPEATFREQ 10 // 1/s
+#endif
+#ifndef LIRC_REPEATTIMEOUT
+#define LIRC_REPEATTIMEOUT 500 // ms
+#endif
+#ifndef LIRC_RECONNECTDELAY
+#define LIRC_RECONNECTDELAY 3000 // ms
+#endif
+#ifndef LIRC_PRIORITYBOOST
+#define LIRC_PRIORITYBOOST 0
+#endif
 
 cLircRemote::cLircRemote(const char *DeviceName)
 :cRemote("LIRC")
@@ -68,17 +82,33 @@  void cLircRemote::Action(void)
   bool repeat = false;
   int timeout = -1;
 
+  if (LIRC_PRIORITYBOOST)
+     SetPriority(GetPriority() - LIRC_PRIORITYBOOST);
   while (Running() && f >= 0) {
-
         bool ready = cFile::FileReady(f, timeout);
-        int ret = ready ? safe_read(f, buf, sizeof(buf)) : -1;
+        int ret = -1;
+        if (ready) {
+           // read one line of the line oriented lirc protocol
+           for (ret = 0; ret < (int)sizeof(buf); ret++) {
+               int ch = readchar(f);
+               if (ch < 0) {
+                  ret = -1;
+                  break;
+                  }
+               if (ch == '\n') {
+                  buf[ret++] = '\0';
+                  break;
+                  }
+               buf[ret] = ch;
+               }
+           }
 
         if (ready && ret <= 0 ) {
-           esyslog("ERROR: lircd connection broken, trying to reconnect every %.1f seconds", float(RECONNECTDELAY) / 1000);
+           esyslog("ERROR: lircd connection broken, trying to reconnect every %.1f seconds", float(LIRC_RECONNECTDELAY) / 1000);
            close(f);
            f = -1;
            while (Running() && f < 0) {
-                 cCondWait::SleepMs(RECONNECTDELAY);
+                 cCondWait::SleepMs(LIRC_RECONNECTDELAY);
                  if (Connect()) {
                     isyslog("reconnected to lircd");
                     break;
@@ -94,7 +124,7 @@  void cLircRemote::Action(void)
               continue;
               }
            if (count == 0) {
-              if (strcmp(KeyName, LastKeyName) == 0 && FirstTime.Elapsed() < REPEATDELAY)
+              if (strcmp(KeyName, LastKeyName) == 0 && FirstTime.Elapsed() < (1000 / LIRC_PUSHFREQ))
                  continue; // skip keys coming in too fast
               if (repeat)
                  Put(LastKeyName, false, true);
@@ -104,18 +134,18 @@  void cLircRemote::Action(void)
               timeout = -1;
               }
            else {
-              if (LastTime.Elapsed() < REPEATFREQ)
+              if (LastTime.Elapsed() < (1000 / LIRC_REPEATFREQ))
                  continue; // repeat function kicks in after a short delay (after last key instead of first key)
-              if (FirstTime.Elapsed() < REPEATDELAY)
+              if (FirstTime.Elapsed() < LIRC_REPEATDELAY)
                  continue; // skip keys coming in too fast (for count != 0 as well)
               repeat = true;
-              timeout = REPEATDELAY;
+              timeout = LIRC_REPEATDELAY;
               }
            LastTime.Set();
            Put(KeyName, repeat);
            }
         else if (repeat) { // the last one was a repeat, so let's generate a release
-           if (LastTime.Elapsed() >= REPEATTIMEOUT) {
+           if (LastTime.Elapsed() >= LIRC_REPEATTIMEOUT) {
               Put(LastKeyName, false, true);
               repeat = false;
               *LastKeyName = 0;
--- ../vdr-1.5.12-dvbs2-other/Makefile	2008-01-01 22:55:18.000000000 +0100
+++ Makefile	2008-01-08 22:23:41.000000000 +0100
@@ -58,6 +59,25 @@  RCU_DEVICE  ?= /dev/ttyS1
 
 DEFINES += -DLIRC_DEVICE=\"$(LIRC_DEVICE)\" -DRCU_DEVICE=\"$(RCU_DEVICE)\"
 
+ifdef LIRC_PUSHFREQ
+DEFINES += -DLIRC_PUSHFREQ=$(LIRC_PUSHFREQ)
+endif
+ifdef LIRC_REPEATDELAY
+DEFINES += -DLIRCD_REPEATDELAY=$(LIRC_REPEATDELAY)
+endif
+ifdef LIRC_REPEATFREQ
+DEFINES += -DLIRC_REPEATFREQ=$(LIRC_REPEATFREQ)
+endif
+ifdef LIRC_REPEATTIMEOUT
+DEFINES += -DLIRC_REPEATTIMEOUT=$(LIRC_REPEATTIMEOUT)
+endif
+ifdef LIRC_RECONNECTDELAY
+DEFINES += -DLIRC_RECONNECTDELAY=$(LIRC_RECONNECTDELAY)
+endif
+ifdef LIRC_PRIORITYBOOST
+DEFINES += -DLIRC_PRIORITYBOOST=$(LIRC_PRIORITYBOOST)
+endif
+
 DEFINES += -D_GNU_SOURCE
 
 DEFINES += -DVIDEODIR=\"$(VIDEODIR)\"
--- ../vdr-1.5.12-dvbs2-other/thread.c	2007-10-19 16:30:13.000000000 +0200
+++ thread.c	2008-01-08 22:39:48.000000000 +0100
@@ -218,9 +218,20 @@  cThread::~cThread()
   free(description);
 }
 
+int cThread::GetPriority(void)
+{
+  errno = 0;
+  int Priority = getpriority(PRIO_PROCESS, 0);
+  if (Priority == -1 && errno != 0) {
+     LOG_ERROR;
+     Priority = 0;
+     }
+  return Priority;
+}
+
 void cThread::SetPriority(int Priority)
 {
-  if (setpriority(PRIO_PROCESS, 0, Priority) < 0)
+  if (setpriority(PRIO_PROCESS, 0, max(-20, min(Priority, 19))) < 0)
      LOG_ERROR;
 }
 
--- ../vdr-1.5.12-dvbs2-other/thread.h	2007-02-24 17:13:28.000000000 +0100
+++ thread.h	2008-01-07 22:52:19.000000000 +0100
@@ -86,6 +86,7 @@  private:
   static tThreadId mainThreadId;
   static void *StartThread(cThread *Thread);
 protected:
+  int GetPriority(void);
   void SetPriority(int Priority);
   void Lock(void) { mutex.Lock(); }
   void Unlock(void) { mutex.Unlock(); }
--- ../vdr-1.5.12-dvbs2-other/tools.c	2008-01-01 22:55:18.000000000 +0100
+++ tools.c	2008-01-06 01:50:17.000000000 +0100
@@ -84,6 +84,14 @@  ssize_t safe_write(int filedes, const vo
   return p < 0 ? p : written;
 }
 
+int readchar(int filedes)
+{
+  char c;
+  if (safe_read(filedes, &c, sizeof(c)) != 1)
+     return -1;
+  return c;
+}
+
 void writechar(int filedes, char c)
 {
   safe_write(filedes, &c, sizeof(c));
--- ../vdr-1.5.12-dvbs2-other/tools.h	2008-01-01 22:55:18.000000000 +0100
+++ tools.h	2008-01-06 01:57:03.000000000 +0100
@@ -164,6 +164,7 @@  public:
 
 ssize_t safe_read(int filedes, void *buffer, size_t size);
 ssize_t safe_write(int filedes, const void *buffer, size_t size);
+int readchar(int filedes);
 void writechar(int filedes, char c);
 int WriteAllOrNothing(int fd, const uchar *Data, int Length, int TimeoutMs = 0, int RetryMs = 0);
     ///< Writes either all Data to the given file descriptor, or nothing at all.