summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--COPYING340
-rw-r--r--FAQ25
-rw-r--r--HISTORY388
-rw-r--r--Makefile145
-rw-r--r--README397
-rw-r--r--TODO5
-rw-r--r--common.c89
-rw-r--r--common.h47
-rw-r--r--device.c1705
-rw-r--r--device.h160
-rw-r--r--example/README.channel-conv13
-rwxr-xr-xexample/channel-conv.sh81
-rw-r--r--example/channels.conf_newsyntax.example77
-rwxr-xr-xexample/externchannelswitch.sh.example21
-rw-r--r--filter.c105
-rw-r--r--filter.h34
-rw-r--r--global.h11
-rw-r--r--menu.c714
-rw-r--r--menu.h68
-rw-r--r--patches/vdr/vdr-1.4.7-pluginparam.patch299
-rw-r--r--patches/vdr/vdr-1.6.0-pluginparam.patch287
-rw-r--r--patches/vdr/vdr-1.7.9-pluginparam.patch287
-rw-r--r--po/ca_ES.po194
-rw-r--r--po/cs_CZ.po195
-rw-r--r--po/da_DK.po194
-rw-r--r--po/de_DE.po203
-rw-r--r--po/el_GR.po194
-rw-r--r--po/es_ES.po195
-rw-r--r--po/et_EE.po195
-rw-r--r--po/fi_FI.po195
-rw-r--r--po/fr_FR.po195
-rw-r--r--po/hr_HR.po194
-rw-r--r--po/hu_HU.po194
-rw-r--r--po/i18n-template.c22
-rw-r--r--po/i18n.h23
-rw-r--r--po/it_IT.po211
-rw-r--r--po/nl_NL.po194
-rw-r--r--po/nn_NO.po194
-rw-r--r--po/pl_PL.po194
-rw-r--r--po/pt_PT.po194
-rw-r--r--po/ro_RO.po213
-rw-r--r--po/ru_RU.po194
-rw-r--r--po/sl_SI.po194
-rwxr-xr-xpo2i18n.pl201
-rw-r--r--pvrinput.c131
-rw-r--r--pvrinput.h27
-rw-r--r--reader.c486
-rw-r--r--reader.h37
-rw-r--r--setup.c51
-rw-r--r--setup.h66
50 files changed, 10078 insertions, 0 deletions
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..5b6e7c6
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/FAQ b/FAQ
new file mode 100644
index 0000000..993afc2
--- /dev/null
+++ b/FAQ
@@ -0,0 +1,25 @@
+Q:
+what about the SID-parameter in channels.conf?
+A:
+It has to be a unique number.
+w_scan and wirbelscan use the following method:
+
+- for TV/radio: Frequency in MHz * 16 = SID
+ example: 112250 = 112,25 MHz. 112,25 * 16 = 1796
+
+-for external inputs: start numbering with 9001
+
+
+Q:
+Why don`t you use regular version numbers instead of
+YYYY-MM-DD ?
+A:
+wait and see :-)
+
+
+Q:
+What about the HVR 1300?
+A:
+support is not finished yet.
+
+
diff --git a/HISTORY b/HISTORY
new file mode 100644
index 0000000..c475845
--- /dev/null
+++ b/HISTORY
@@ -0,0 +1,388 @@
+VDR Plugin 'pvrinput' Revision History
+--------------------------------------
+
+1.7.0-rc9 (Dr. Seltsam)
+- remove PvrSetup.Pvrusb2StopOnChange as there is a
+ driver solution now available
+- fix exception handling for PVR500 (volume, useOnlyCard)
+- don't write INVALID_VALUE in setup.conf.
+ This fixes zero values if no device is present
+- update README
+- fix initial Video Size setting by using driver default
+- fix handling of PAL_60
+- fix ProvidesChannel: no longer switch between pvr devices
+ when zapping while osdteletxt is running
+
+1.7.0-rc8 (mini73)
+- add support for the Hauppauge HD PVR
+
+1.7.0-rc7 (mini73)
+- embed PAT, PMT and PCR into the transport stream
+
+1.7.0-rc6 (Dr. Seltsam)
+- fix ProvidesChannel() (thanks to Wirbel)
+- add possibility to use an externchannelswitch.sh script
+ (see README).
+
+1.7.0-rc4+rc5: only for selected testers with additional debug stuff
+
+1.7.0-rc3 (Dr. Seltsam)
+- improve error log messages
+- fix possible race condition in OpenDvr
+
+1.7.0-rc2 (Dr. Seltsam)
+- remove bool isTuning, because it seems to result in problems in few cases.
+ As tuning is done in OpenDvr, it is no more necessary anyway.
+- remove outcommented code in reader.c, was a leftover from tests
+
+1.7.0-rc1 (Dr. Seltsam)
+- add support for cx18-based devices
+- various small bugfixes
+- restruct OpenDvr/CloseDvr. We stop and start
+ the encoder now here and also execute the driver commands for channel
+ switching.
+- start readThread not at plugin start, but at first OpenDvr() call
+- fix initialize value of v4l2_fd in Probe()
+- also log error number in Tune()
+- remove check for driver name IVTV, as it is "ivtv" since a long time
+- improve detecting if read thread exists by using the new bool
+ readThreadRunning
+- remove unused bool stop in reader.c
+- reader.c: use parent->v4l2_fd instead of int video_fd and int VideoDevice
+- extend logging - now also write into syslog
+- add NumProvidedSystems for vdr 1.7.x
+- common.c: fix checking if device is open. If not, log an error
+- fix translation of "pvr picture settings" and plugin description
+- Fix a bug in PesToTS which wrote a wrong Pid in the header. This was a major
+ bug which prevented vdr 1.7 from working with pvrinput
+- repeat read access in Action() three times before abort
+- remove support for old channels syntax (CAID A1). Show an OSD error message
+ in case the old syntax is found
+- allow V4L2_MPEG_STREAM_TYPE_MPEG2_DVD for DVD-compatible streams (see README)
+- rename plugin.c/h to pvrinput.c/h
+- check vbi capabilities
+- PesToTs cannot handle all vbi data, only Teletext. Therefore only embedd
+ V4L2_SLICED_TELETEXT_B into the mpeg stream. This makes channel switching
+ faster
+- allow usage of different video sub standards like SECAM-D/K, PAL-D/K etc.
+ by using more parameters in channels.conf
+- when using a PVR350, automatically stop the decoder before switching the
+ video standard. This avoids EBUSY errors in case of a race condition
+ (pvrinput may be faster than the pvr350-plugin)
+- An exception audio level can be set for certain cards (see README)
+- fix gcc 4.3 compiler warnings
+- change default log level to 2, as to much debug messages
+ increase channel switching time
+- mute audio for pvrusb2 devices while switching channels in case
+ "PVRUSB2 Stop on Change" is set to no.
+- remove setting of separate video bitrate for radio recordings. (With new
+ version of pvr350-plugin it is no longer necessary to use VPID 301
+ (video stream) for radio)
+
+2009-01-24 (Dr. Seltsam)
+- fix frequency of k09 in channels.conf examples
+ (thanks to panik105 from vdrportal)
+
+
+2008-12-24 (Dr. Seltsam)
+- The previous fix in cPluginPvrInput::MainMenuAction must depend on
+ PLUGINPARAMPATCHVERSNUM. Oherwise it does not compile with a vdr version
+ that is not patched with the pluginparam-patch
+- fix frequency of S30 in channels.conf examples, add S29 and S35
+
+2008-10-26 (Dr. Seltsam)
+- fix usage of PvrMenuMain on channels with iptv-syntax
+- fix permission of directories
+- remove executable flag from patches and conf files
+- fix Makefile
+
+
+2008-10-03 (Dr. Seltsam)
+- add possibility to force the plugin to use only a certain card by using the
+ new value PvrSetup.UseOnlyCard. (see README)
+- update README
+- add vdr-1.7.0-pluginparam.patch
+
+2008-09-14 (Dr. Seltsam)
+- remove usage of vbi device, as it is not needed for sliced vbi
+- remove unused bool dvrOpen
+
+2008-09-13 (Wirbel)
+- further work on future support of HVR 1300
+- fix radio detecting
+- remove PvrSetup.UseDeviceType
+
+2008-09-04 (Dr. Seltsam)
+- move and simplify the check for radio presence from SetChannelDevice to
+ ProvidesChannel.
+- updated italian language file (thanks to Diego Pierotto)
+- Stop VBI sliced mode when plugin stops. This avoids full ivtv vbi buffers.
+- implement a new method to detect the matching radio device
+
+2008-06-23 (Wirbel)
+- moved sysfx fix to patches - we need a better solution here, not using /sys at all.
+- moved channel validity checks to ProvidesChannel
+- ParseChannel now also gets Pointer to card
+- ParseChannel (old syntax): if no input was given -> default to TV input
+- ParseChannel change *only* vars given by pointer, don't access global vars directly.
+- ParseChannel log output now only for pvrinput channels.
+- ProvidesChannel now calls ParseChannel to check wether a channel can be switched to
+- changed debug output of tune (readability)
+- updated README (description of new channel syntax)
+
+2008-07-05 (Dr. Seltsam)
+- fix handling of CARD-parameter (thanks to mgoeben from vdrportal for reporting
+ the problem, and to Wirbel for telling me how to solve it :-) )
+- extend log info for SetChannelDevice and ProvidesChannel (add number of device)
+- don't allow tuning to a radio channel if device has no radio
+ (avoids endless "Can start transfer mode" loop)
+- increase number of kMaxPvrDevices to 8 (vdr also increased the maximum number
+ of DVB devices to 8 in vdr 1.5.1)
+
+2008-06-19 (Dr. Seltsam)
+- fix setting of Tuner Audio Mode
+
+2008-06-01 (Dr. Seltsam)
+- added a patch from <christian.jarczyk@freenet.de> for improved autodetection
+ of ivtv radio devices. As it is only rarely tested, the patch is optional.
+ Uncomment "#define SYSFS_FIX" in device.c if you want to try it.
+- update README and HISTORY
+- update example channels.conf files
+- add patches for pvrusb2 driver
+- start with a FAQ
+
+2008-05-28 (Dr. Seltsam)
+- fixed a bug in ParseChannel. Now the external inputs work also with the
+ new channelssyntax.
+
+2008-05-24 (Dr. Seltsam)
+- added a lot of patches from Wirbel (improve log messages, simplify code,
+ prepare for further support of cx88-blackbird devices)
+- fix errors in *.po files
+
+
+2008-05-14 (Dr. Seltsam)
+- Starting with this version, the plugin now supports devices using the
+ pvrusb2 driver. It has been successfully tested with a Hauppauge PVRUSB2
+ Model 29034 Rev. C547. For details see README
+- all include files are now in common.h
+- separate reader.c/h files for cPvrReadThread
+- Delete the readThread for every device now in cPvrDevice::Stop() instead of
+ deleting it later in the destructor.
+ This avoids full ivtv buffer and hopefully improves the shutdown handling.
+- GetTSPacket(): check if tsBuffer and readThread are existing
+- Fix "race condition" while deleting threads which could cause a segfault
+ (patch by andreas_schaefers@gmx.de)
+- additional and extended log messages
+- allow setting of Tuner Audio Mode to be able to record bilingual recordings
+ with both languages
+- improve Tune() using same code as in v4l2-ctl
+- using -fPic in Makefile
+- change test method in Makefile whether VDR has locale support
+- fix enless loop "Can start transfer mode" when switching to a not
+ existing input. The message still appears, but it is now possible to switch
+ to another channel. (vdr will automatically return to the last channel
+ after 2 minutes)
+- update README
+- update channels.conf.sample, includes now radio
+
+
+2007-11-01 (Wirbel + Dr.Seltsam):
+- Makefile changed, i18n.{c,h} removed, now gettext internationalization
+- TEST: new function ParseChannel and adapted SetChannelDevice for testing
+ pluginparampatch Syntax
+- removed cPvrReadThread::ResetCounters(void),
+ cPvrReadThread::SetPaused (int set), PvrSetup.DelayAfterTune and
+ PvrSetup.Force_Encoder_Stop_Start. They are no longer needed, because we now
+ always delete the readThread and stop/start the encoder when switching
+ channels.
+- removed unused ePause and eResume in SetEncoderState.
+- introduced PvrSetup.SliceVBI which allows to turn off embedding VBI
+ (Teletext) data into the mpeg.
+ This could improve stability if you don`t use the osdteletxt-Plugin and have
+ problems with full ivtv buffers.
+ Changing the setting will take effect after a restart.
+- Newer ivtv drivers don`t allow changing some settings
+ V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ
+ V4L2_CID_MPEG_AUDIO_L2_BITRATE
+ V4L2_CID_MPEG_VIDEO_BITRATE_MODE
+ V4L2_CID_MPEG_VIDEO_BITRATE
+ V4L2_CID_MPEG_VIDEO_BITRATE_PEAK
+ while the encoder is running. Each time you change settings in the plugin
+ setup, we now repeat all settings once after the next encoder stop (= during
+ next channel switch)
+- introduced PvrSetup.VideoBitrateFM and renamed PvrSetup.VideoBitrate to
+ PvrSetup.VideoBitrateTV.
+ Different bitrates allow us to avoid unnecessary large files when recording
+ from radio (see also README).
+- removed unnecessary "typedef enum" in setup.h
+
+
+2007-09-02 (Dr. Seltsam):
+- adapted plugin to recent ivtv driver changes. Changing the VBI format,
+ video norm, input or tuner band requires now an encoder stop/start.
+ Basically this is nothing else than the "AntiFlickering workaround" did
+ before (by closing and re-opening the device), so I also renamed it
+ to "Force encoder stop/start".
+- moved Clearing of tsBuffer from OpenDvr to SetChannelDevice.
+ (If a timer starts while you watch a recording, vdr tunes to the desired
+ channel without calling OpenDvr.)
+- a default value of 20 ms for DelayAfterTune seems to be sufficient
+- added a recommendation in README for PVR350 users to enable
+ "Force encoder stop/start"
+- update README
+
+
+2007-05-10 .. 2007-05-23 (Wirbel):
+
+- tried to simplify controls (QueryAllControls, SetControlValue)
+- SetControlValue is now overloaded function
+- separate valSet for FM radio Audio Volume instead of int type
+- added cPlugin::Stop() which stops all threads, see <vdr>/PLUGINS.html
+- added preliminary Patch for vdr-1.5.2 (later 1.5 Versions may need
+ some small adaptions inside channels.conf and plugins source code)
+- new function SetVBImode()
+- fixed internationalization for setup page and mainpage
+- cPvrReadThread::Action() is now checking Running as needed
+ (see <vdr>/threads.h)
+- added cPvrReadThread::ResetCounters(void)
+- cPvrReadThread::PesToTs and cPvrReadThread::ParseProgramStream
+ sligthly changed
+- FM Radio now initialized in cPvrDevice::cPvrDevice
+- new property IVTV_apiversion gives ivtv version number
+- cPvrDevice::Probe rewritten
+- cPvrDevice::OpenDvr now resets all counters: audio, video, text
+- several other improvements
+- fix: 'Channel no available' during records from ext inputs
+- channels with frequency 87500 .. 108000 (87.5MHz .. 108MHz) are now
+ considered as FM radio, regardless of their VPID.
+- thanks to DrSeltsam for excessive testing
+
+
+2007:
+
+- added a first version of romanian i18n (Lucian Muresan
+<lucianm AT users DOT sourceforge DOT net>)
+- re-added main menu control, because it's useful and yet
+optional (Lucian Muresan <lucianm AT users DOT sourceforge DOT net>)
+-removed 3.2 pulldown stuff because it was removed in driver
+-Code Cleanup by Andreas Schaefers
+-fix and improve radio (thanx to Jose Alberto Reguero
+ <jareguero@telefonica.net> )
+-smoother channel switching: use encoder pause before tuning and resume after
+ tuner has fully locked. Thererfore the time between tuning and encoder resume
+ can be set in the menu (WaitAfterTuning). Default value is 50ms.
+
+2006-11-21:
+-added "Anti-Flickering workaround" in the plugin menu. If set to "yes", it
+ will close and re-open the device at each channel switch. This has been tested
+ as being a reliably workaround for the flickering problem that some people
+ have been reported. (see also
+ http://www.vdr-portal.de/board/thread.php?threadid=52013 and
+ http://www.gossamer-threads.com/lists/ivtv/devel/33101 ). Default is "no"
+ The Flickering is solved in newer drivers for cx23416-based cards, but still
+ exist for cx23415 (PVR350 and older revisions of PVR250)
+
+2006-10-08 (Wirbel):
+
+- removed all old ivtv API calls and switched to v4l2 (some of them already
+ were v4l2 api)
+- removed ivtv.h and videodev2.h
+- removed the main menu entry, because it was easier to realize
+- added internationalization (english and german are done, other
+ languages not done but prepared)
+- improved video filter settings
+
+2006-02-09: Version 0.1.1
+
+- fixed detection of pvr card to work with ivtv version 0.4.1 or later with
+kernel 2.4.
+
+
+2005-11-27: Version 0.1.0
+
+- fixed detection of pvr card to work with ivtv version 0.4.1 or later.
+
+
+2005-11-27: Version 0.0.9
+
+- adapted setting of VBI mode to new API used in driver version 0.4.0.
+- removed dynamic setting of VBI embedded mode as this doesn't work when the
+video device is opened.
+
+
+2005-09-04: Version 0.0.8
+
+- Fixed setting of vbi modes.
+
+
+2005-09-04: Version 0.0.7
+
+- It is possible to hide the main menu entry through a setting in setup menu.
+- The time to wait for the ringbuffer to fill with data is now adjustable in
+ setup menu.
+- Now using embedded vbi mode only when the channel has a valid teletext PID.
+ If the PID is 0 then embedded vbi mode is disabled.
+
+
+2005-08-28: Version 0.0.6
+
+- Added setting of vbi teletext mode. Now it should work again with 0.2 and
+ 0.3 drivers.
+- Removed dependency from libdvb from makefile.
+- Added a small OSD window for setting up the picture parameters (brightness,
+ contrast, saturation, hue). It can be reached from the main menu.
+
+
+2005-08-27: Version 0.0.5
+
+- Fixed: memcpy length in last TS packet was wrong (thanks to Christian
+ Cier-Zniewski for reporting).
+- Made PES to TS conversion MPEG compliant, stuffing in last TS packet is now
+ done with adaptaion field. (thanks to Christian Cier-Zniewski for reporting).
+- Static variables of PET to TS conversion are now non-static members of
+ cPvrReadThread. This is needed for multiple card support.
+- Fixed: not switching to new channel when recording starts during watching
+ another analogue channel.
+
+
+2005-08-26: Version 0.0.4
+
+- Switched to a self-written PES to TS conversion. libdvb is no longer needed.
+- Now using vbi embedded mode for reading the teletext data.
+- fixed closing the radio device when switching to a non-tuner input (thanks
+ to Jose Alberto Reguero).
+- Waiting for buffer to fill in GetTsPacket. This speeds up the "hopping" over
+ channels. You can change the kTimeToWaitAfterChannelSwitch value to change
+ the time to wait. 1000 works good for me and slows down things not too much.
+- renewed ivtv.h to be compatible with ivtv 0.3 versions.
+
+
+2005-07-23: Version 0.0.3
+
+- Settings taken in setup menu are now applied after leaving it with OK
+- Now reading video and vbi data in one and the same thread. I hope
+ this improves things a bit.
+- Now immediately returns in SetChannelDevice when the channel is already set.
+- Only reading from vbi device if opening was successful (thanks to steffx
+ for reporting this one).
+
+
+2005-06-13: Version 0.0.2
+
+- The tuner input is now auto-detected (I hope this works for non
+ PVR-250 cards).
+- Added support for other inputs than the tuner, using the "C" parameter
+ of the channel entry. I did not test this here, it should work.
+- Fixed VIDIOC_G_FMT ioctl.
+- Added support for the video norms NTSC, SECAM and PAL, using the "I"
+ parameter of the channel entry.
+- Added support for radio channels, the video PID must be set to zero.
+ I can't test this here, I hope it works.
+- Added setup menu for setting up encoding parameters.
+- Added videodev2.h file from the ivtv driver archive.
+
+
+2005-05-31: Version 0.0.1
+
+- Initial revision.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..bffb464
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,145 @@
+#
+# Makefile for a Video Disk Recorder plugin
+#
+# -- v20071028, Winfried Koehler --
+
+# The official name of this plugin.
+# This name will be used in the '-P...' option of VDR to load the plugin.
+# By default the main source file also carries this name.
+# IMPORTANT: the presence of this macro is important for the Make.config
+# file. So it must be defined, even if it is not used here!
+#
+PLUGIN = pvrinput
+
+### The version number of this plugin (taken from the main source file):
+
+VERSION = $(shell grep 'static const char \*VERSION *=' pvrinput.c | awk '{ print $$6 }' | sed -e 's/[";]//g')
+
+### The C++ compiler and options:
+
+CXX ?= g++
+CXXFLAGS ?= -fPIC -g -O2 -Wall -Woverloaded-virtual -Wno-parentheses
+
+### The directory environment:
+
+DVBDIR = ../../../../DVB
+VDRDIR = ../../..
+LIBDIR = ../../lib
+TMPDIR = /tmp
+
+### Test whether VDR has locale support
+VDRLOCALE = $(shell grep 'I18N_DEFAULT_LOCALE' $(VDRDIR)/i18n.h)
+
+### Make sure that necessary options are included:
+
+-include $(VDRDIR)/Make.global
+
+### Allow user defined options to overwrite defaults:
+
+-include $(VDRDIR)/Make.config
+
+### The version number of VDR's plugin API (taken from VDR's "config.h"):
+
+APIVERSION = $(shell sed -ne '/define APIVERSION/s/^.*"\(.*\)".*$$/\1/p' $(VDRDIR)/config.h)
+
+### The name of the distribution archive:
+
+ARCHIVE = $(PLUGIN)-$(VERSION)
+PACKAGE = vdr-$(ARCHIVE)
+
+### Includes and Defines (add further entries here):
+
+INCLUDES += -I$(VDRDIR)/include -I$(DVBDIR)/include
+
+DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
+
+### The object files (add further files here):
+
+OBJS = pvrinput.o common.o device.o reader.o menu.o setup.o filter.o
+
+### The main target:
+
+all: i18n libvdr-$(PLUGIN).so
+
+### Implicit rules:
+
+%.o: %.c
+ $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) $<
+
+### Dependencies:
+
+MAKEDEP = $(CXX) -MM -MG
+DEPFILE = .dependencies
+$(DEPFILE): Makefile
+ @$(MAKEDEP) $(DEFINES) $(INCLUDES) $(subst i18n.c,,$(OBJS:%.o=%.c)) > $@
+
+-include $(DEPFILE)
+
+### Internationalization (I18N):
+
+PODIR = po
+LOCALEDIR = $(VDRDIR)/locale
+I18Npo = $(wildcard $(PODIR)/*.po)
+I18Nmo = $(addsuffix .mo, $(foreach file, $(I18Npo), $(basename $(file))))
+I18Ndirs = $(notdir $(foreach file, $(I18Npo), $(basename $(file))))
+I18Npot = $(PODIR)/$(PLUGIN).pot
+I18Nvdrmo = vdr-$(PLUGIN).mo
+ifeq ($(strip $(APIVERSION)),1.5.7)
+ I18Nvdrmo = $(PLUGIN).mo
+endif
+
+ifneq ($(strip $(VDRLOCALE)),)
+### do gettext based i18n stuff
+
+%.mo: %.po
+ msgfmt -c -o $@ $<
+
+$(I18Npot): $(subst i18n.c,,$(wildcard *.c))
+ xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --msgid-bugs-address='<see README>' -o $@ $(subst i18n.c,,$(wildcard *.c))
+
+$(I18Npo): $(I18Npot)
+ msgmerge -U --no-wrap --no-location --backup=none -q $@ $<
+
+i18n: $(I18Nmo)
+ @mkdir -p $(LOCALEDIR)
+ for i in $(I18Ndirs); do\
+ mkdir -p $(LOCALEDIR)/$$i/LC_MESSAGES;\
+ cp $(PODIR)/$$i.mo $(LOCALEDIR)/$$i/LC_MESSAGES/$(I18Nvdrmo);\
+ done
+
+i18n.c: ### nothing to do
+
+else ### do i18n.c based i18n stuff
+
+OBJS += i18n.o
+
+i18n: $(@cp $(PODIR)/i18n.h i18n.h)
+ @### nothing to do
+
+i18n.h: i18n.c
+
+### i18n compatibility generator:
+
+i18n.c: $(PODIR)/i18n-template.c po2i18n.pl $(I18Npo)
+ ./po2i18n.pl < $(PODIR)/i18n-template.c > i18n.c
+ @cp $(PODIR)/i18n.h i18n.h
+
+endif
+
+
+### Targets:
+
+libvdr-$(PLUGIN).so: $(OBJS)
+ $(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@
+ @cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION)
+
+dist: clean
+ @-rm -rf $(TMPDIR)/$(ARCHIVE)
+ @mkdir $(TMPDIR)/$(ARCHIVE)
+ @cp -a * $(TMPDIR)/$(ARCHIVE)
+ @tar czf $(PACKAGE).tgz -C $(TMPDIR) $(ARCHIVE)
+ @-rm -rf $(TMPDIR)/$(ARCHIVE)
+ @echo Distribution package created as $(PACKAGE).tgz
+
+clean:
+ @-rm -f $(OBJS) $(DEPFILE) i18n.c i18n.h *.so *.tgz core* *~ $(PODIR)/*.mo $(PODIR)/*.pot
diff --git a/README b/README
new file mode 100644
index 0000000..f8cf736
--- /dev/null
+++ b/README
@@ -0,0 +1,397 @@
+This is a "plugin" for the Video Disk Recorder (VDR).
+
+originally written by: Andreas <andreas.regel@powarman.de>
+(Some parts of the plugin's source are based on the analogtv plugin by
+Andreas Kool.)
+
+Since the ivtv driver API changed in ivtv >= 0.8 a lot of API calls are no
+longer existent/working. Unfortunally the author does no longer maintain this
+plugin (see http://www.vdr-portal.de/board/thread.php?threadid=48772).
+
+This INOFFICIAL version allows to use the plugin with newer ivtv versions,
+but it is completely without any warranty and still very experimental:
+
+-Adapted to ivtv driver 0.8 by "Wirbel" Winfried Koehler
+ <w_koehl@gmx.de>
+-Further development since 2006/2007 by Winfried Koehler and
+ "Dr. Seltsam" Martin Dauskardt (martin.dauskardt@gmx.de).
+-in 2010 "mini73" Lars Hanisch (dvb@flensrocker.de) joined the team
+
+See the file HISTORY for changes.
+See the file COPYING for license information.
+
+
+Description:
+------------
+
+This plugin uses a Hauppauge PVR card as an input device. All cards
+supported by the ivtv or pvrusb2 driver should work. This version of the plugin
+requires ivtv driver version 1.0 or higher. You need very current versions of
+videodev.h and videodev2.h in /usr/include/linux to get the plugin compiled
+
+Supported devices
+-----------------
+All analogue devices supported by the ivtv or pvrusb2-driver should work. This
+means:
+Hauppauge PVR 150, PVR 250, PVR 350, PVR 500
+Hauppauge PVRUSB2, HVR 1900, HVR 1950
+
+The HVR 1900 and HVR 1950 are hybrid devices. Their analogue device can only be
+used when their digital device is not opened. To prevent vdr from opening the
+digital device, there are three possibilities:
+-load pvrusb2 by using the adapter_nr parameter. If you have two other DVB
+ cards (/dev/dvb/adapter0 and /dev/dvb/adapter1) use adapter_nr=3.
+ example: modprobe pvrusb2 adapter_nr=3
+ vdr detects adapter0 and adapter1 and stops searching when there is no device
+ found on adapter2. This way adapter3 will not be opened and pvrinput can use
+ the analogue device.
+-specify the DVB devices vdr shall use by using vdr's -D parameter
+-compile the pvrusb2 driver without DVB support
+
+Altough the HVR 1300 is listed in menu entries, it is not really supported yet.
+
+Support for the HVR 1600 (cx18-driver) is included. Other cx18-based devices could
+be added later.
+
+There is support for the Hauppauge HD PVR (beta-stage).
+
+Patching vdr
+------------
+Starting with this version, pvrinput does no longer support the old channel
+syntax. It now uses only the new channel syntax which is similar like the
+one from iptv. If your vdr version is already patched for the iptv-plugin, you
+don't need the vdr-1.x.x-pluginparam.patch. Otherwise you must apply it,
+no matter if you are using vdr version 1.4, 1.6 or 1.7.x (x < 13).
+
+channels.conf (vdr >= 1.7.13)
+-----------------------------
+With vdr version 1.7.13 the pluginparam-patch was integrated into vdr. With this
+change there has to be some adjustments to the channels.conf.
+The Source ID is now 'V' and the string "PVRINPUT|" must be omitted.
+
+for example:
+RTL:217250:TV:V:0:301+101:300:305:0:12003:1:1089:0
+
+For a description of the possible parameters read the next section.
+
+channels.conf (vdr < 1.7.13)
+----------------------------
+pvrinput now supports a new syntax using the Source Identifier 'P', similar to
+the one from the iptv-plugin. Take the channels.conf_newsyntax.example in
+example dir as a reference for your own channels.conf.
+
+ Source ID: 'P'
+ Video PID: 301 for TV, 0 for Radio
+ Audio PID: 300
+ Teletext PID: 305 (or 0 if not needed)
+ PCR PID: 101
+
+for example:
+RTL:217250:PVRINPUT|TV:P:0:301+101:300:305:0:12003:1:1089:0
+| | | | | | | | | | | |
+| | | | | | | | | | | --> Transport Stream ID
+| | | | | | | | | | | (TID)
+| | | | | | | | | | --> Network ID (NID)
+| | | | | | | | | --> Service ID (SID), the
+| | | | | | | | | combination of SID, NID,
+| | | | | | | | | TID has to be unique.
+| | | | | | | | --> CA identifier, should be 0
+| | | | | | | --> Teletext PID
+| | | | | | --> Audio PID
+| | | | | --> PCR PID
+| | | | --> Video PID (set to 0 for radio stations)
+| | | --> Source 'P'
+| | --> Parameters (see below)
+| --> Frequency (1 for external inputs)
+--> Channel Name (your choice..)
+
+cx18:
+cx18-driven cards are capable of delivering a TS. At the moment the stream type
+is forced to TS, the setting in the menu does only effect ivtv-based cards.
+The PIDs in the TS are the same as used by the plugin's PS-to-TS-repacker, so one
+channel-entry should work for both types of cards.
+
+HD PVR:
+This box sets the PIDs to 4352 for audio, 4113 for video and 4097 for the PCR.
+And it's better to tell vdr the type of video (H.264 has a stream type of 27).
+If you use the digital input of the box, you must switch the audio encoding to AAC even
+if it gets AC3, for the RCA inputs you should set the encoding to AC3, since the vdr seems
+to have diffibulties with handling AAC audio.
+
+for example:
+HD PVR:1:PVRINPUT|COMPONENT:P:0:4113+4097=27:0;4352:0:0:2919:1:0:0
+
+
+NID and TID can be 0. The following method is used by wirbelscan and w_scan
+to create a unique SID:
+
+- for TV/radio: Frequency in MHz * 16 = SID
+ example: 112250 = 112,25 MHz. 112,25 * 16 = 1796
+
+- for external inputs: start numbering with 9001
+
+
+Parameter Description:
+Each Parameter is separated with "|" (vertical bar)
+
+* First Parameter: always "PVRINPUT" (uppercase!). Otherwise pvrinput will
+ ignore this channel.
+* Second Parameter: always one of the following identifiers (uppercase!):
+ * "TV" -> a normal tv channel
+ * "RADIO" -> a radio channel. frequency should be in this case
+ 87500..108000 and vpid = 0
+ * "COMPOSITE0" -> external input, composite in number 0
+ * "COMPOSITE1"
+ * "COMPOSITE2"
+ * "COMPOSITE3"
+ * "COMPOSITE4"
+ * "SVIDEO0" -> external input, S-Video input number 0
+ * "SVIDEO1"
+ * "SVIDEO2"
+ * "SVIDEO3"
+ * "COMPONENT" -> external input, Component input of HD PVR
+
+NOTE: * Some cards will have SVIDEO0 and COMPOSITE0 as first external input,
+ * while other cards may start with SVIDEO1 and COMPOSITE1. This depends
+ * on driver and hardware (ivtv, pvrusb2).
+ * For all channels with external video inputs, frequency should be 1.
+
+* Third and Fourth Parameters: THESE PARAMETERS ARE *OPTIONAL*.
+ One of the following identifiers, uppercase:
+ * "PAL" -> specify PAL channel, this is default.
+ (The ivtv driver sets
+ V4L2_STD_PAL_BG | V4L2_STD_PAL_H)
+ * "SECAM" -> specify Secam channel
+ (the ivtv drivers sets V4L2_STD_SECAM_L).
+ default is PAL
+ * "NTSC" -> specify NTSC channel
+ (the ivtv driver sets V4L2_STD_NTSC_M).
+ default is PAL
+ * "CARD0" -> specify one video device (here: /dev/video0)
+ which should receive this channel.
+ * "CARD1" All other devices will not switch to this channel.
+ * "CARD2" (useful for external video inputs.)
+ * "CARD3" CARD0 is /dev/video0, CARD1 is /dev/video1 and
+ * "CARD4" so on. Be aware, that a full-featured DVB card
+ * "CARD5" or other video devices might also have a
+ * "CARD6" /dev/videoXX. NOTE: if not specified *all* pvrinput
+ * "CARD7" devices will try to receive this channel.
+
+NOTE: You can specify other video standards like PAL_DK, SECAM_DK or NTSC_M_JP.
+ Have a look at cPvrDevice::ParseChannel in device.c
+
+NOTE: /dev/video0../dev/video7 supported only.
+
+OSD main menu
+-------------
+There is a small OSD window for setting up the picture parameters (brightness,
+contrast, saturation, hue). It can be reached from the main menu (if enabled in
+the plugin settings). Use the Up/Down keys to switch between the parameters
+and Left/Right to change a value. Press Ok to save the settings and close the
+window. Menu/Back just closes the window without saving the values.
+
+Radio
+-----
+The PVR150 (some revisions), PVR350, PVR500(first device only),
+PVRUSB2 and obviously some versions of PVR250 have a built-in radio tuner
+which can be used with pvrinput. (The radio tuner of the HVR 1900
+is up to now not supported by the pvrusb2 driver.)
+Use the RADIO parameter in channels.conf to specify a radio channel.
+VPID should be set to 0.
+
+If you use a PVR350 as output device with an older version of the
+pvr350-plugin (prior to version 1.7.0 from 11-2009), you need VPID=301 for
+pvrinput radio channels.
+
+Because the radio audio volume level is much lower, you can set radio and TV
+audio volume separately for TV and FM radio.
+
+vdr-1.6.x
+---------
+There is a bug in vdr 1.6.0 and 1.6.0-1 which leads to segfaults when stopping
+vdr. This is fixed in the VDR maintenance patch 1.6.0-2, so it is highly
+recommended to use both maintenance patches (1.6.0-1 and 1.6.0-2).
+
+vdr-1.7.x
+---------
+For now the 1.7-tree is only supported up to 1.7.12. In 1.7.13 the "plugin-param-
+patch" was integrated into the plain vdr, so there have to be made some adjustments
+in the plugin.
+
+pvrusb2 & channel switching
+----------------------------
+To make channel switching smoother, we need to clear the encoder by stopping it
+and restart it after tuning is done. This allows to start exactly on an i-frame
+of the new channel, without audio/video interferences.
+
+Unlike the ivtv driver, the pvrusb2 driver has no ioctls (driver commands) to do
+this. We can only close and reopen the device, which also stops the encoder.
+Unfortunately it happens randomly that we get a blank screen on the new
+channel. This will only happen on old models (PVRUSB2 model
+29xxx) with saa7115 digitizer chip. The newer models (PVRUSB2 model 24xxx and
+HVR 1900) have a different digitizer.
+
+A newer driver which fixes this problem is available:
+http://www.isely.net/pipermail/pvrusb2/2010-February/002734.html
+
+This patches are in the main v4l-dvb hg and hopefully they make it into 2.6.34.
+
+You could also patch and recompile your pvrusb2 driver in
+a simpler way:
+
+--- v4l-dvb-309f16461cf4-orig/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+2009-12-05 13:34:21.000000000 +0100
++++ v4l-dvb-309f16461cf4-patched/linux/drivers/media/video/pvrusb2/pvrusb2-
+hdw.c 2009-12-24 22:42:49.746899065 +0100
+@@ -4689,6 +4689,7 @@
+ del_timer_sync(&hdw->quiescent_timer);
+ if (hdw->flag_decoder_missed) return 0;
+ if (pvr2_decoder_enable(hdw,!0) < 0) return 0;
++ msleep(300);
+ hdw->state_decoder_quiescent = 0;
+ hdw->state_decoder_run = !0;
+ }
+
+
+pvrusb2 & osdteletext
+----------------------
+The pvrusb2 driver does not support sliced vbi, so the osdteletext-plugin
+won't work.
+
+bilingual broadcastings
+-----------------------
+The driver default audio mode is stereo. According to
+http://v4l2spec.bytesex.org/spec/r12342.htm#TUNER-AUDMODE
+it is now necessary to set the audio mode to V4L2_TUNER_MODE_LANG1_LANG2,
+otherwise you will only get the first language.
+The default mode of the plugin is V4L2_TUNER_MODE_LANG1_LANG2
+(bilingual), which should be well for all broadcastings.
+MythTV also uses this mode.
+
+If you use a PVR350 for playback with the pvr350-plugin, you need version
+2008-05-17 or higher to be able to select the languages. Starting with that
+version, the pvr350-plugin supports SetAudioChannel() and GetAudioChannel().
+
+switching between different PVR devices
+---------------------------------------
+At least with vdr 1.6.0, you can use the femon plugin and switch with
+the "Left" and "Right" keys between the cards. This is useful if you want
+to start a recording from an extern input. With femon you can choose the
+card that is actually connected to an extern video source.
+(Note: you can also configure the card in the channels.conf)
+
+plugin settings
+----------------
+The plugin calls the driver for its default values and sets them. Due to a
+driver bug, this can lead to wrong values. It was fixed for ivtv in v4l-dvb hg in
+July 2008. Have a look at http://www.gossamer-threads.com/lists/ivtv/devel/38637.
+A similar in the pvrusb2 driver was fixed in April 2009.
+
+Therefore it is recommended to check the plugin settings and adjust them if necessary.
+It is especially important to set the Audio sampling rate to 48 KHz.
+
+These are the default values as they should appear in a setup.conf which had no
+pvrinput-entries before:
+
+pvrinput.AspectRatio = 1 //4:3
+pvrinput.AudioBitrate = 10 //224 kBit/s
+pvrinput.AudioSampling = 1 //48 KHz
+pvrinput.AudioVolumeFM = 62535 //100%
+pvrinput.AudioVolumeTVCommon = 62258 //95%
+pvrinput.AudioVolumeTVException = 62258 //95%
+pvrinput.AudioVolumeTVExceptionCard = 8 //AudioVolumeTVCommon for all cards
+pvrinput.BitrateMode = 0 //VBR
+pvrinput.Brightness = 128 //50%
+pvrinput.Contrast = 64 //50%
+pvrinput.FilterChromaMedianBottom = 0 //Chroma Median Filter Bottom = 0
+pvrinput.FilterChromaMedianTop = 255 //Chroma Median Filter Top = 255
+pvrinput.FilterChromaSpatialType = 1 //Chroma Spatial Filter Type = 1D horizontal
+pvrinput.FilterLumaMedianBottom = 0 //Luma Median Filter Bottom = 0
+pvrinput.FilterLumaMedianTop = 255 //Luma Median Filter Top = 255
+pvrinput.FilterLumaSpatialType = 1 //Luma Spatial Filter Type = 1D horizontal
+pvrinput.FilterMedianType = 0 //Median Filter Type = off
+pvrinput.FilterSpatial = 0 //Strength Spatial Filter = 0
+pvrinput.FilterSpatialMode = 0 //Mode Spatial Video Filter = manual
+pvrinput.FilterTemporal = 8 //Strength Temporal Video Filter = 8
+pvrinput.FilterTemporalMode = 0 //Mode Temporal Video Filter = manual
+pvrinput.HDPVR_AudioEncoding = 0 // AAC = 0, AC3 = 1
+pvrinput.HDPVR_AudioInput = 0 // RCA back = 0, RCA front = 1, SPDIF = 2 (needs audio encoding = 0)
+pvrinput.HideMainMenuEntry = 1 //yes (hide main menu entry)
+pvrinput.Hue = 0 //50%
+pvrinput.LogLevel = 2 //errors and info messages
+pvrinput.Saturation = 64 //50%
+pvrinput.SliceVBI = 1 //only for ivtv-based cards: yes (slice VBI teletext)
+pvrinput.StreamType = 0 //V4L2_MPEG_STREAM_TYPE_MPEG2_PS
+pvrinput.TunerAudioMode = 4 //bilingual
+pvrinput.UseOnlyCard = 8 //use all cards
+pvrinput.UseExternChannelSwitchScript = 0 //don't call externchannelswitch.sh
+pvrinput.VideoBitrateTV = 6000 //6 MBit/s
+
+Using filters may increase the picture quality, but the default value of 8
+for the temporal filter may cause ghosting effects. If this is the case,
+try smaller values.
+
+Force the plugin to use a certain card
+--------------------------------------
+By default the plugin will detect and use all supported cards. For testing
+purposes it may be useful to test the behaviour of a certain card. This could
+be done by using the CARD parameter in the channels.conf, but there is
+also an easier way by using the PvrSetup.UseOnlyCard value. A value of 0 to 7
+will force the plugin to use only /dev/videoX, while x is the value of
+PvrSetup.UseOnlyCard. "PvrSetup.UseOnlyCard = 8" means that all detected
+devices will be used.
+Note: Don`t change vdr`s setup.conf while vdr is running, it won`t take effect
+and will be overwritten by vdr when vdr terminates.
+There is also an OSD menu entry to allow setting PvrSetup.UseOnlyCard while
+vdr is running. By default it is not visible to avoid confusion of a common
+user. To use this feature just uncomment "//#define PVR_DEBUG" in the top of
+menu.c before compiling the plugin.
+
+Using Stream type V4L2_MPEG_STREAM_TYPE_MPEG2_DVD (not possible for HD PVR)
+---------------------------------------------------------------------------
+Some users have reported that recordings which were done using this stream type
+work better with the burn plugin or mplex.
+If you want to use this stream, you can use PvrSetup.StreamType=1 by editing
+the setup.conf. There is also a menu entry when compiling as described above.
+
+Adjust different Audio volume levels (not possible for HD PVR)
+--------------------------------------------------------------
+Different cards may have different tuners. As a result the audio volume
+on some cards may be much lower than on others.
+You can specify a common audio volume level which will be used for all cards
+by default.
+An exception audio level can be set for certain cards. You can choose the card
+which shall use the exception audio level by its /dev/videoX number, or by its
+card name.
+(Note: A PVR500 consists of two PVR150)
+
+Using pvrinput and streamdev
+----------------------------
+The TS stream produced by pvrinput does have a PCR now, but only fixed
+PAT/PMT tables if you use a vdr version < 1.7.1. So don't fool around with
+the PIDs...
+VLC won't accept a TS stream without PCR, PAT and PMT. Use PES streaming instead.
+It has been reported that Konqueror and dragonplayer can play a TS stream from
+streamdev even if it has no PCR and no PAT/PMT.
+This problem is still "under investigation"... :-)
+
+externchannelswitch
+-------------------
+You may want to use a Digital Receiver connected to the external inputs of the
+PVR device.
+You can use more than one channels.conf entries for the same input, as long as the
+SID (Service-ID) is unique:
+
+Digibox Channel 1:1:PVRINPUT|SVIDEO1:P:0:301=2:300:305:0:9001:0:0:0
+Digibox Channel 10:1:PVRINPUT|SVIDEO1:P:0:301=2:300:305:0:9010:0:0:0
+Digibox Channel 101:1:PVRINPUT|SVIDEO1:P:0:301=2:300:305:0:9101:0:0:0
+
+Copy the externchannelswitch.sh.example script as externchannelswitch.sh into
+your CONFDIR/pvrinput (e.g. /etc/vdr/pvrinput). When switching to a channel with
+an external input, pvrinput will call this script with three arguments:
+-SID
+-vdr channel number
+-card number (/dev/videoX) of the choosen PVR device
+
+It is up to you what you want to do in this script. For example, you could
+use the lirc irsend command. The scripts contains an exampe for usage of dct6200.
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..979758b
--- /dev/null
+++ b/TODO
@@ -0,0 +1,5 @@
+-add service interface
+-setting the aspect ratio by reading the vbi data
+-directly read TS stream (V4L2_MPEG_STREAM_TYPE_MPEG2_TS) from cx18-based cards instead of using ParseprogramStream
+-generate PCR data to allow using streamdev with TS (currently only PES works)
+
diff --git a/common.c b/common.c
new file mode 100644
index 0000000..1ff6b65
--- /dev/null
+++ b/common.c
@@ -0,0 +1,89 @@
+#include "common.h"
+
+void log(int level, const char * fmt, ...) {
+ char tmpstr[BUFSIZ];
+ char timestr[16];
+ va_list ap;
+ time_t now;
+ struct tm local;
+
+ if (PvrSetup.LogLevel >= level) {
+ va_start(ap, fmt);
+ time(&now);
+ localtime_r(&now, &local);
+ vsnprintf(tmpstr, sizeof(tmpstr), fmt, ap);
+ strftime(timestr, sizeof(timestr), "%H:%M:%S", &local);
+ printf("pvrinput: %s %s\n", timestr, tmpstr);
+ switch (level) {
+ case pvrERROR:
+ esyslog("%s",tmpstr);
+ break;
+ case pvrINFO:
+ isyslog("%s",tmpstr);
+ break;
+ case pvrDEBUG1:
+ case pvrDEBUG2:
+ default:
+ dsyslog("%s",tmpstr);
+ break;
+ }
+ va_end(ap);
+ }
+}
+
+/*
+function IOCTL
+retries the ioctl given six times before giving up,
+improves stability if device/driver is actually busy
+*/
+int IOCTL(int fd, int cmd, void *data) {
+ if (fd <0) {
+ log(pvrERROR, "Error IOCTL %s: %s is not open", cmd, fd);
+ return (-1);
+ }
+ for (int retry = 5; retry >= 0; ) {
+ if (ioctl(fd, cmd, data) != 0) {
+ if (retry){
+ usleep(20000); /* 20msec */
+ retry--;
+ continue;
+ }
+ return -1;
+ }
+ else
+ return 0; /* all went okay :) */
+ }
+ return 0; /* should never reach this */
+}
+
+/*
+This function takes a ivtv V4L2 integer value
+and returns it as rounded 0..100% integer value
+-wirbel-
+*/
+
+int IntVal2Percent(int NumVal, int MinVal, int MaxVal){
+ double t=0;
+ log(pvrDEBUG1, "IntVal2Percent(NumVal=%d, MinVal=%d, MaxVal=%d)\n",
+ NumVal, MinVal, MaxVal);
+ t=(double) (MaxVal - MinVal);
+ t=(NumVal-MinVal)/t;
+ t=100.0*t + 0.5; /* rounding to nearest int) */
+ return (int) t;
+}
+
+/*
+This function takes a 0..100% integer value
+and returns it as rounded ivtv V4L2 integer value
+-wirbel-
+*/
+
+int Percent2IntVal(int Percent, int MinVal, int MaxVal){
+ double t=0;
+ log(pvrDEBUG1, "Percent2IntVal(Percent=%d, MinVal=%d, MaxVal=%d)\n",
+ Percent, MinVal, MaxVal);
+ t=Percent/100.0;
+ t=0.5 + t*(MaxVal-MinVal); /* +0.5 is rounding to int */
+ t=MinVal+t;
+ return (int) t;
+}
diff --git a/common.h b/common.h
new file mode 100644
index 0000000..f3edc04
--- /dev/null
+++ b/common.h
@@ -0,0 +1,47 @@
+#ifndef _PVR_COMMON_H_
+#define _PVR_COMMON_H_
+
+enum eLogLevel { pvrUNUSED, pvrERROR, pvrINFO, pvrDEBUG1, pvrDEBUG2 };
+
+#include <string>
+#include <strings.h>
+#include <linux/types.h>
+#include <linux/videodev.h>
+#include <linux/videodev2.h>
+
+#include <sys/ioctl.h>
+#include <sys/time.h>
+
+#include <stdarg.h>
+#include <time.h>
+#include <stdio.h>
+
+#include <vdr/osd.h>
+#include <vdr/plugin.h>
+#include <vdr/channels.h>
+#include <vdr/sources.h>
+#include <vdr/device.h>
+#include <vdr/plugin.h>
+
+
+#include "setup.h"
+#include "filter.h"
+#include "device.h"
+#include "global.h"
+#include "reader.h"
+#include "pvrinput.h"
+#include "menu.h"
+
+#if VDRVERSNUM < 10507
+#include "i18n.h"
+#endif //VDRVERSNUM < 10507
+
+
+void log(int level, const char * fmt, ...);
+
+int IOCTL(int fd, int cmd, void *data);
+
+int Percent2IntVal(int Percent, int MinVal, int MaxVal);
+int IntVal2Percent(int NumVal, int MinVal, int MaxVal);
+
+#endif
diff --git a/device.c b/device.c
new file mode 100644
index 0000000..30069dd
--- /dev/null
+++ b/device.c
@@ -0,0 +1,1705 @@
+#include "common.h"
+#include <linux/dvb/video.h>
+#include <stdlib.h>
+
+#if VDRVERSNUM > 10712
+#define PVR_SOURCEPARAMS
+#include <vdr/sourceparams.h>
+#endif
+
+char DRIVERNAME[][15] = {
+ "undef", "ivtv", "cx18", "pvrusb2", "cx88_blackbird", "hdpvr"
+};
+
+char CARDNAME[][9] = {
+ "undef", "PVR150", "PVR250", "PVR350", "PVR500#1", "PVR500#2", "HVR1300", "HVR1600", "HVR1900", "HVR1950", "PVRUSB2", "HDPVR"
+};
+
+cPvrDevice * PvrDevices[kMaxPvrDevices];
+
+cString cPvrDevice::externChannelSwitchScript;
+
+#ifdef PVR_SOURCEPARAMS
+class cPvrSourceParam : public cSourceParam {
+private:
+ int param;
+ int input;
+ int standard;
+ int card;
+ cChannel data;
+public:
+ cPvrSourceParam();
+ cString ParametersToString(void) const;
+ void ParseParameters(const char* Parameters);
+ virtual void SetData(cChannel *Channel);
+ virtual void GetData(cChannel *Channel);
+ virtual cOsdItem *GetOsdItem(void);
+
+ static bool IsPvr(int Code);
+
+ static const char sSourceID = 'V';
+ static const uint stPvr = (sSourceID << 24);
+ static const int sNumInputs = 12;
+ static const char* sInputs[];
+ static const int sNumCards = 9;
+ static const char* sCards[];
+ static const int sNumStandards = 31;
+ static const char* sStandards[];
+};
+
+const char* cPvrSourceParam::sInputs[] = {
+ "TV",
+ "RADIO",
+ "COMPOSITE0",
+ "COMPOSITE1",
+ "COMPOSITE2",
+ "COMPOSITE3",
+ "COMPOSITE4",
+ "SVIDEO0",
+ "SVIDEO1",
+ "SVIDEO2",
+ "SVIDEO3",
+ "COMPONENT"
+};
+
+const char* cPvrSourceParam::sCards[] = {
+ "",
+ "CARD0",
+ "CARD1",
+ "CARD2",
+ "CARD3",
+ "CARD4",
+ "CARD5",
+ "CARD6",
+ "CARD7"
+};
+
+const char* cPvrSourceParam::sStandards[] = {
+ "",
+ "PAL",
+ "NTSC",
+ "SECAM",
+ "NTSC_M",
+ "NTSC_M_JP",
+ "NTSC_443",
+ "NTSC_M_KR",
+ "PAL_M",
+ "PAL_N",
+ "PAL_NC",
+ "PAL_B",
+ "PAL_B1",
+ "PAL_G",
+ "PAL_BG",
+ "PAL_D",
+ "PAL_D1",
+ "PAL_K",
+ "PAL_DK",
+ "PAL_H",
+ "PAL_I",
+ "PAL_60",
+ "SECAM_B",
+ "SECAM_D",
+ "SECAM_G",
+ "SECAM_H",
+ "SECAM_K",
+ "SECAM_K1",
+ "SECAM_DK",
+ "SECAM_L",
+ "SECAM_LC"
+};
+
+cPvrSourceParam::cPvrSourceParam()
+:cSourceParam(sSourceID, "analog (pvrinput)")
+{
+ param = 0;
+ input = 0;
+ standard = 0;
+ card = 0;
+}
+
+cString cPvrSourceParam::ParametersToString(void) const
+{
+ if ((standard == 0) && (card == 0))
+ return cString::sprintf("%s", sInputs[input]);
+ if ((standard == 0) && (card != 0))
+ return cString::sprintf("%s|%s", sInputs[input], sCards[card]);
+ if ((standard != 0) && (card == 0))
+ return cString::sprintf("%s|%s", sInputs[input], sStandards[standard]);
+ return cString::sprintf("%s|%s|%s", sInputs[input], sCards[card], sStandards[standard]);
+}
+
+void cPvrSourceParam::ParseParameters(const char* Parameters) {
+ char * Input = NULL;
+ char * optArg[2] = { NULL, NULL };
+ int NumArgs = sscanf(Parameters, "%a[^|]|%a[^|]|%a[^:\n]", &Input, &optArg[0], &optArg[1]);
+ input = 0;
+ card = 0;
+ standard = 0;
+ if (NumArgs >= 1) {
+ for (int i = 0; sInputs[i]; i++) {
+ if (!strcasecmp (Input, sInputs[i])) {
+ input = i;
+ break;
+ }
+ }
+ }
+ for (int opt = 0; opt < 2; opt++) {
+ if (NumArgs >= (opt + 2)) {
+ bool parsed = false;
+ for (int c = 1; sCards[c]; c++) {
+ if (!strcasecmp (optArg[opt], sCards[c])) {
+ card = c;
+ parsed = true;
+ break;
+ }
+ }
+ if (!parsed) {
+ for (int s = 1; sStandards[s]; s++) {
+ if (!strcasecmp (optArg[opt], sStandards[s])) {
+ standard = s;
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+void cPvrSourceParam::SetData(cChannel *Channel)
+{
+ data = *Channel;
+ ParseParameters(data.Parameters());
+ param = 0;
+}
+
+void cPvrSourceParam::GetData(cChannel *Channel)
+{
+ data.SetTransponderData(Channel->Source(), Channel->Frequency(), Channel->Srate(), ParametersToString(), true);
+ *Channel = data;
+}
+
+cOsdItem *cPvrSourceParam::GetOsdItem(void)
+{
+ switch (param++) {
+ case 0: return new cMenuEditStraItem(tr("SourceParam.pvrinput$Input"), &input, sNumInputs, sInputs);
+ case 1: return new cMenuEditStraItem(tr("SourceParam.pvrinput$Card"), &card, sNumCards, sCards);
+ case 2: return new cMenuEditStraItem(tr("SourceParam.pvrinput$Standard"), &standard, sNumStandards, sStandards);
+ default: return NULL;
+ }
+ return NULL;
+}
+
+bool cPvrSourceParam::IsPvr(int Code) {
+ return (Code & cSource::st_Mask) == stPvr;
+}
+#endif
+
+static void cPvrSourceParam_Initialize() {
+#ifdef PVR_SOURCEPARAMS
+ new cPvrSourceParam();
+#endif
+}
+
+cPvrDevice::cPvrDevice(int DeviceNumber)
+: number(DeviceNumber),
+ frequency(-1),
+ CurrentNorm(0), //uint64_t can't be negative
+ CurrentLinesPerFrame(-1),
+ CurrentInput(-1),
+ SupportsSlicedVBI(false),
+ hasDecoder(false),
+ hasTuner(true),
+ streamType(0),
+ dvrOpen(false),
+ delivered(false),
+ isClosing(false),
+ readThreadRunning(false),
+ ChannelSettingsDone(false),
+ FirstChannelSwitch(true),
+ pvrusb2_ready(true),
+ driver(undef),
+ cardname(UNDEF),
+ tsBufferPrefill(0),
+ readThread(0)
+{ log(pvrDEBUG2,"new cPvrDevice (%d)", number);
+ v4l2_fd = mpeg_fd = radio_fd = -1;
+ v4l2_dev = mpeg_dev = radio_dev = -1;
+ vpid = apid = tpid = -1;
+ cString devName;
+ struct v4l2_capability video_vcap;
+ struct v4l2_capability capability;
+ struct v4l2_input input;
+ int i;
+ // put all values here that are set only *once*
+ v4l2_dev = number;
+ devName = cString::sprintf("/dev/video%d", v4l2_dev);
+ v4l2_fd = open(devName, O_RDWR);
+ if (v4l2_fd < 0) {
+ log(pvrERROR, "cPvrDevice::cPvrDevice(): error opening video device %s: %s",
+ *devName, strerror(errno));
+ }
+ memset(&video_vcap, 0, sizeof(video_vcap));
+ IOCTL(v4l2_fd, VIDIOC_QUERYCAP, &video_vcap);
+ log(pvrDEBUG1, "%s = %s", *devName, video_vcap.card);
+ BusID = cString::sprintf("%s", video_vcap.bus_info);
+ log(pvrDEBUG1, "BusID = %s", *BusID);
+ if (!memcmp(video_vcap.driver, "ivtv",4)) driver = ivtv;
+ else if (!memcmp(video_vcap.driver, "cx18",4)) driver = cx18;
+ else if (!memcmp(video_vcap.driver, "pvrusb2",7)) driver = pvrusb2;
+ else if (!memcmp(video_vcap.driver, "cx88_blackbird",14)) driver = cx88_blackbird;
+ else if (!memcmp(video_vcap.driver, "hdpvr",5)) driver = hdpvr;
+ else { driver = undef; log(pvrDEBUG1, "unknown video driver: \"%s\"",video_vcap.driver); }
+ if (!memcmp(video_vcap.card, "Hauppauge WinTV PVR-150",23)) cardname = PVR150;
+ else if (!memcmp(video_vcap.card, "Hauppauge WinTV PVR-250",23)) cardname = PVR250;
+ else if (!memcmp(video_vcap.card, "Hauppauge WinTV PVR-350",23)) cardname = PVR350;
+ else if (!memcmp(video_vcap.card, "WinTV PVR 500 (unit #1)",23)) cardname = PVR500_1;
+ else if (!memcmp(video_vcap.card, "WinTV PVR 500 (unit #2)",23)) cardname = PVR500_2;
+ else if (!memcmp(video_vcap.card, "Hauppauge WinTV-HVR1300",23)) cardname = HVR1300;
+ else if (!memcmp(video_vcap.card, "Hauppauge HVR-1600",18)) cardname = HVR1600;
+ else if (!memcmp(video_vcap.card, "WinTV HVR-1900",14)) cardname = HVR1900;
+ else if (!memcmp(video_vcap.card, "WinTV HVR-1950",14)) cardname = HVR1950;
+ else if (!memcmp(video_vcap.card, "WinTV PVR USB2",14)) cardname = PVRUSB2;
+ else if (!memcmp(video_vcap.card, "Hauppauge HD PVR",16)) cardname = HDPVR;
+ else if (!memcmp(video_vcap.card, "Haupauge HD PVR",15)) cardname = HDPVR; // spelling error in hdpvr
+ else { cardname = UNDEF; log(pvrDEBUG1, "unknown video card: \"%s\"",video_vcap.card); }
+ if (cardname == HVR1300) log(pvrERROR, "HVR 1300 is not really supported yet");
+ driver_apiversion = video_vcap.version;
+ log(pvrDEBUG1, "%s Version 0x%06x", DRIVERNAME[driver], driver_apiversion);
+ if ((video_vcap.capabilities & V4L2_CAP_SLICED_VBI_CAPTURE) && (driver != pvrusb2)) {
+ /*The pvrusb2 driver advertises vbi capability, although it isn't there.
+ This was fixed in v4l-dvb hg in 01/2009 and will hopefully be in Kernel 2.6.30*/
+ SupportsSlicedVBI = true;
+ log(pvrDEBUG1, "%s supports sliced VBI Capture",*devName);
+ }
+ if (video_vcap.capabilities & V4L2_CAP_VIDEO_OUTPUT_OVERLAY) {
+ hasDecoder = true; //can only be a PVR350
+ }
+ for (i=0; i<kMaxPvrDevices; i++) {
+ if (radio_dev<0 && (video_vcap.capabilities & V4L2_CAP_RADIO)) { //searching matching radio dev
+ devName = cString::sprintf("/dev/radio%d", i);
+ radio_fd = open(devName, O_RDWR);
+ if (radio_fd >= 0) {
+ memset(&capability, 0, sizeof(capability));
+ if (IOCTL(radio_fd, VIDIOC_QUERYCAP, &capability) !=0) {
+ log(pvrERROR, "VIDIOC_QUERYCAP failed, %d:%s",
+ errno, strerror(errno));
+ }
+ if (!strncmp(*BusID,(const char *) capability.bus_info, strlen(*BusID)-1)) {
+ radio_dev=i; // store info for later
+ log(pvrDEBUG1, "/dev/radio%d = FM radio dev",radio_dev);
+ }
+ close(radio_fd); // a pvrusb2 will remain on input 3. The bool FirstChannelSwitch will solve this later
+ radio_fd = -1;
+ }
+ }
+ if (mpeg_dev<0 && (driver == cx88_blackbird)) { // the blackbird uses two (!) different devices, search the other one.
+ close(v4l2_fd);
+ v4l2_fd = -1;
+ devName = cString::sprintf("/dev/video%d", i);
+ mpeg_fd = open(devName, O_RDWR);
+ if (mpeg_fd) {
+ memset(&capability, 0, sizeof(capability));
+ IOCTL(mpeg_fd, VIDIOC_QUERYCAP, &capability);
+ if (!strncmp(*BusID ,(const char *) capability.bus_info, strlen(*BusID)-1) &&
+ !strcmp("cx8800",(const char *) capability.driver)) {
+ mpeg_dev = v4l2_dev; //for this driver we found mpeg_dev up to now.
+ v4l2_dev = i; //reassigning, now with correct value.
+ log(pvrDEBUG1, "/dev/video%d = v4l2 dev (analog properties: volume/hue/brightness/inputs..)",v4l2_dev);
+ log(pvrDEBUG1, "/dev/video%d = mpeg dev (MPEG properties: bitrates/frame rate/filters..)",mpeg_dev);
+ }
+ close(mpeg_fd);
+ mpeg_fd = -1;
+ }
+ }
+ } // end device search loop
+ switch (driver) {
+ case ivtv: //ivtv, cx18, pvrusb2 and hdpvr share the same device.
+ case cx18:
+ case pvrusb2:
+ case hdpvr:
+ mpeg_dev = v4l2_dev;
+ mpeg_fd = v4l2_fd;
+ break;
+ case cx88_blackbird:
+ //blackbird: reopen mpeg device. //FIXME: WE SHOULD OPEN V4L2 DEV for inputs/picture properties/volume, mpeg for all other stuff
+ devName = cString::sprintf("/dev/video%d", mpeg_dev);
+ v4l2_fd = open(devName, O_RDWR); //FIXME: FOR NOW THIS IS A WILD MIXTURE.
+ break;
+ default:;
+ }
+ QueryAllControls(); //we have to split in mpeg and v4l2 here.
+ memset(&inputs, -1, sizeof(inputs));
+ numInputs = 0;
+ for (i = 0;; i++) {
+ memset(&input, 0, sizeof(input));
+ input.index = i;
+ if (IOCTL(v4l2_fd, VIDIOC_ENUMINPUT, &input) == -1) {
+ break;
+ }
+ else {
+ log(pvrDEBUG1, "input %d = %s", i, input.name);
+ numInputs++;
+ }
+ if (!memcmp(input.name, "Tuner", 5)) { inputs[eTelevision]=inputs[eRadio]=i; continue; } //ivtv: Radio and TV tuner are same input.
+ else if (!memcmp(input.name, "television", 10)) { inputs[eTelevision]=i; continue; } //pvrusb2
+ else if (!memcmp(input.name, "Television", 10)) { inputs[eTelevision]=i; continue; } //cx88_blackbird
+ else if (!memcmp(input.name, "radio", 5)) { inputs[eRadio] =i; continue; } //pvrusb2
+ else if (!memcmp(input.name, "Composite 0", 11)) { inputs[eComposite0]=i; continue; }
+ else if (!memcmp(input.name, "Composite 1", 11)) { inputs[eComposite1]=i; continue; }
+ else if (!memcmp(input.name, "Composite 2", 11)) { inputs[eComposite2]=i; continue; }
+ else if (!memcmp(input.name, "Composite 3", 11)) { inputs[eComposite3]=i; continue; }
+ else if (!memcmp(input.name, "Composite 4", 11)) { inputs[eComposite4]=i; continue; }
+ else if (!memcmp(input.name, "Composite1", 10)) { inputs[eComposite1]=i; continue; } //cx88_blackbird
+ else if (!memcmp(input.name, "composite", 9)) { inputs[eComposite0]=i; continue; } //pvrusb2
+ else if (!memcmp(input.name, "Composite", 9)) { inputs[eComposite0]=i; continue; } //hdpvr
+ else if (!memcmp(input.name, "S-Video 3", 9)) { inputs[eSVideo3] =i; continue; }
+ else if (!memcmp(input.name, "S-Video 0", 9)) { inputs[eSVideo0] =i; continue; }
+ else if (!memcmp(input.name, "S-Video 1", 9)) { inputs[eSVideo1] =i; continue; }
+ else if (!memcmp(input.name, "S-Video 2", 9)) { inputs[eSVideo2] =i; continue; }
+ else if (!memcmp(input.name, "S-Video", 7)) { inputs[eSVideo0] =i; continue; } //cx88_blackbird & hdpvr
+ else if (!memcmp(input.name, "s-video", 7)) { inputs[eSVideo0] =i; continue; } //pvrusb2
+ else if (!memcmp(input.name, "Component", 9)) { inputs[eComponent] =i; continue; } //hdpvr
+ else log(pvrERROR, "unknown input %s. PLEASE SEND LOG TO MAINTAINER.", input.name);
+ }
+ if (inputs[eTelevision] >= 0)
+ SetInput(inputs[eTelevision]);
+ else if ((driver == hdpvr) && (inputs[eComponent] >= 0)) {
+ hasTuner = false;
+ SetInput(inputs[eComponent]);
+ }
+ else {
+ hasTuner = false;
+ log(pvrERROR, "device has no tuner");
+ }
+ tsBuffer = new cRingBufferLinear(MEGABYTE(PvrSetup.TsBufferSizeMB), TS_SIZE, false, "PVRTS");
+ tsBuffer->SetTimeouts(100, 100);
+ ResetBuffering();
+ GetStandard();
+ if (driver == hdpvr) {
+ SetControlValue(&PvrSetup.HDPVR_AudioEncoding, PvrSetup.HDPVR_AudioEncoding.value);
+ SetAudioInput(PvrSetup.HDPVR_AudioInput);
+ }
+ else {
+ SetControlValue(&PvrSetup.AudioEncoding, V4L2_MPEG_AUDIO_ENCODING_LAYER_2);
+ SetControlValue(&PvrSetup.VideoBitratePeak, 15000000);
+ SetVideoSize(720, CurrentLinesPerFrame == 525 ? 480 : 576);
+ /* the driver will later automatically adjust the height depending on standard changes */
+ }
+ ReInit();
+ StartSectionHandler();
+}
+
+cPvrDevice::~cPvrDevice() {
+#if VDRVERSNUM >= 10600
+ StopSectionHandler();
+#endif
+ cRingBufferLinear * tsBuffer_tmp = tsBuffer;
+ log(pvrDEBUG2,"~cPvrDevice()");
+ tsBuffer = NULL;
+ delete tsBuffer_tmp;
+ close(radio_fd);
+ close(v4l2_fd);
+}
+
+bool cPvrDevice::Probe(int DeviceNumber) {
+ char device[256];
+ struct v4l2_capability vcap;
+ struct v4l2_format vfmt;
+ int v4l2_fd;
+ bool found = false;
+ memset(&vcap, 0, sizeof(vcap));
+ memset(&vfmt, 0, sizeof(vfmt));
+ sprintf(device, "/dev/video%d", DeviceNumber);
+ v4l2_fd = open(device, O_RDONLY);
+ if (v4l2_fd >=0) {
+ IOCTL(v4l2_fd, VIDIOC_QUERYCAP, &vcap);
+ if (!memcmp(vcap.driver, "ivtv",4) ||
+ !memcmp(vcap.driver, "cx18",4) ||
+ !memcmp(vcap.driver, "pvrusb2", 7) ||
+ !memcmp(vcap.driver, "hdpvr", 5))
+ found = true;
+ if (!memcmp(vcap.driver, "cx88_blackbird", 14)) {
+ vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ if (! IOCTL(v4l2_fd, VIDIOC_G_FMT, &vfmt) &&
+ (v4l2_fourcc('M','P','E','G') == vfmt.fmt.pix.pixelformat))
+ found=true;
+ }
+ close(v4l2_fd);
+ if (found) log(pvrINFO, "cPvrDevice::Probe():found %s", vcap.card);
+ return found;
+ }
+ return false;
+}
+
+bool cPvrDevice::Initialize(void) {
+ int found = 0;
+ cPvrSourceParam_Initialize();
+ for (int i = 0; i < kMaxPvrDevices; i++) {
+ PvrDevices[i] = NULL;
+ if (Probe(i)) {
+ PvrDevices[i] = new cPvrDevice(i);
+ found++;
+ }
+ }
+ if (found)
+ log(pvrINFO, "cPvrDevice::Initialize(): found %d PVR device%s", found, found > 1 ? "s" : "");
+ else
+ log(pvrINFO, "cPvrDevice::Initialize(): no PVR device found");
+ externChannelSwitchScript = AddDirectory(cPlugin::ConfigDirectory(PLUGIN_NAME_I18N), "externchannelswitch.sh");
+ return found > 0;
+}
+
+void cPvrDevice::Stop(void) {
+ /* recursively stop all threads inside pvrinputs devices */
+ for (int i = 0; i < kMaxPvrDevices; i++) {
+ if (PvrDevices[i]) {
+ if (PvrDevices[i]->readThread) {
+ log(pvrDEBUG2,"cPvrDevice::Stop() for Device %i", i);
+ PvrDevices[i]->StopReadThread();
+ PvrDevices[i]->SetEncoderState(eStop);
+ PvrDevices[i]->SetVBImode(PvrDevices[i]->CurrentLinesPerFrame, 0);
+ }
+ }
+ }
+}
+
+void cPvrDevice::GetStandard(void) {
+ v4l2_std_id std;
+ if (IOCTL(v4l2_fd, VIDIOC_G_STD, &std) == -1) {
+ log(pvrERROR, "error VIDIOC_G_STD on /dev/video%d (%s): %d:%s", \
+ number, CARDNAME[cardname], errno, strerror(errno));
+ }
+ if (std & V4L2_STD_625_50) {
+ CurrentLinesPerFrame = 625;
+ }
+ else {
+ CurrentLinesPerFrame = 525;
+ }
+ /* the driver will automatically set the height to 576 or 480 on each change */
+ CurrentNorm = std;
+ log(pvrINFO, "cPvrDevice::CurrentNorm=0x%08llx, CurrentLinesPerFrame=%d on /dev/video%d (%s)", \
+ std, CurrentLinesPerFrame, number, CARDNAME[cardname]);
+}
+
+void cPvrDevice::StopReadThread(void) {
+ if (readThreadRunning) {
+ log(pvrDEBUG2,"cPvrDevice::StopReadThread on /dev/video%d (%s): read thread exists, delete it", \
+ number, CARDNAME[cardname]);
+ cPvrReadThread * readThread_tmp = readThread;
+ readThread = NULL;
+ delete readThread_tmp;
+ }
+ else {
+ log(pvrDEBUG2,"cPvrDevice::StopReadThread: no read thread running on /dev/video%d (%s)", \
+ number, CARDNAME[cardname]);
+ }
+}
+
+void cPvrDevice::ReInitAll(void) {
+ log(pvrDEBUG1,"cPvrDevice::ReInitAll");
+ int i;
+ for (i = 0; i < kMaxPvrDevices; i++) {
+ if (PvrDevices[i]) {
+ PvrDevices[i]->ReInit();
+ }
+ }
+}
+
+int cPvrDevice::Count() {
+ int count = 0;
+ for (int i = 0; i < kMaxPvrDevices; i++) {
+ if (PvrDevices[i])
+ count++;
+ }
+ return count;
+}
+
+cPvrDevice * cPvrDevice::Get(int index) {
+ int count = 0;
+ for (int i = 0; i < kMaxPvrDevices; i++) {
+ if (PvrDevices[i]) {
+ if (count == index)
+ return PvrDevices[i];
+ count++;
+ }
+ }
+ return NULL;
+}
+
+void cPvrDevice::ReInit(void) {
+ log(pvrDEBUG1,"cPvrDevice::ReInit /dev/video%d = %s (%s)", number, CARDNAME[cardname], DRIVERNAME[driver]);
+ SetTunerAudioMode(PvrSetup.TunerAudioMode);
+ SetInput(CurrentInput);
+ /* begin new v4l2 ivtv controls */
+ if ((driver == cx18) || (driver == hdpvr))
+ streamType = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
+ else
+ streamType = (PvrSetup.StreamType.value == 0) ? V4L2_MPEG_STREAM_TYPE_MPEG2_PS : V4L2_MPEG_STREAM_TYPE_MPEG2_DVD;
+ SetControlValue(&PvrSetup.StreamType, streamType);
+ SetControlValue(&PvrSetup.AspectRatio, PvrSetup.AspectRatio.value);
+ SetControlValue(&PvrSetup.AudioBitrate, PvrSetup.AudioBitrate.value);
+ SetControlValue(&PvrSetup.AudioSampling, PvrSetup.AudioSampling.value);
+ if (driver == hdpvr) {
+ SetControlValue(&PvrSetup.HDPVR_AudioEncoding, PvrSetup.HDPVR_AudioEncoding.value);
+ SetAudioInput(PvrSetup.HDPVR_AudioInput);
+ }
+ SetControlValue(&PvrSetup.VideoBitrateTV, PvrSetup.VideoBitrateTV.value);
+ SetControlValue(&PvrSetup.BitrateMode, PvrSetup.BitrateMode.value);
+ SetControlValue(&PvrSetup.GopSize, PvrSetup.GopSize.queryctrl.default_value);
+ SetControlValue(&PvrSetup.GopClosure, PvrSetup.GopClosure.queryctrl.default_value);
+ SetControlValue(&PvrSetup.BFrames, PvrSetup.BFrames.queryctrl.default_value);
+ SetControlValue(&PvrSetup.FilterSpatialMode, PvrSetup.FilterSpatialMode.value);
+ SetControlValue(&PvrSetup.FilterSpatial, PvrSetup.FilterSpatial.value);
+ SetControlValue(&PvrSetup.FilterLumaSpatialType, PvrSetup.FilterLumaSpatialType.value);
+ SetControlValue(&PvrSetup.FilterChromaSpatialType, PvrSetup.FilterChromaSpatialType.value);
+ SetControlValue(&PvrSetup.FilterTemporalMode, PvrSetup.FilterTemporalMode.value);
+ SetControlValue(&PvrSetup.FilterTemporal, PvrSetup.FilterTemporal.value);
+ SetControlValue(&PvrSetup.FilterMedianType, PvrSetup.FilterMedianType.value);
+ SetControlValue(&PvrSetup.FilterLumaMedianBottom, PvrSetup.FilterLumaMedianBottom.value);
+ SetControlValue(&PvrSetup.FilterLumaMedianTop, PvrSetup.FilterLumaMedianTop.value);
+ SetControlValue(&PvrSetup.FilterChromaMedianBottom, PvrSetup.FilterChromaMedianBottom.value);
+ SetControlValue(&PvrSetup.FilterChromaMedianTop, PvrSetup.FilterChromaMedianTop.value);
+ SetControlValue(&PvrSetup.Brightness, PvrSetup.Brightness.value);
+ SetControlValue(&PvrSetup.Contrast, PvrSetup.Contrast.value);
+ SetControlValue(&PvrSetup.Saturation, PvrSetup.Saturation.value);
+ SetControlValue(&PvrSetup.Hue, PvrSetup.Hue.value);
+ SetControlValue(&PvrSetup.VideoBitrateTV, PvrSetup.VideoBitrateTV.value);
+ if ((radio_fd >= 0) || (driver == pvrusb2 && CurrentInput == inputs[eRadio])) {
+ SetControlValue(&PvrSetup.AudioVolumeFM, PvrSetup.AudioVolumeFM.value);
+ SetControlValue(&PvrSetup.AudioMute, (int) (PvrSetup.AudioVolumeFM.value == 0));
+ }
+ else { //no radio
+ SetAudioVolumeTV();
+ SetControlValue(&PvrSetup.AudioMute, (int) (PvrSetup.AudioVolumeTVCommon.value == 0));
+ }
+}
+
+bool cPvrDevice::Tune(int freq) {
+ double fac = 16;
+ int freqaux = freq;
+ struct v4l2_frequency vf;
+ if (frequency == freq) return true;
+ if ((EncoderInput == eRadio) || (EncoderInput == eTelevision)) {
+ memset(&vf, 0, sizeof(vf));
+ struct v4l2_tuner tuner;
+ memset(&tuner, 0, sizeof(tuner));
+ if (IOCTL(v4l2_fd, VIDIOC_G_TUNER,&tuner) == 0) {
+ fac = (tuner.capability & V4L2_TUNER_CAP_LOW) ? 16000 : 16;
+ }
+ vf.tuner = 0;
+ vf.type = tuner.type;
+ vf.frequency = (int) ((double) freqaux * fac / 1000.0);
+ if (IOCTL(v4l2_fd, VIDIOC_S_FREQUENCY, &vf) == 0) {
+ log(pvrDEBUG1, "cPvrDevice::Tune(): set Frequency on /dev/video%d (%s) to %.2f MHz (%d)", \
+ number, CARDNAME[cardname], vf.frequency / fac, vf.frequency);
+ }
+ else {
+ log(pvrERROR, "cPvrDevice::Tune(): error on /dev/video%d (%s) tuning to %.2f MHz (%d): %d:%s", \
+ number, CARDNAME[cardname], vf.frequency / fac, vf.frequency, errno, strerror(errno));
+ return false;
+ }
+ }
+ frequency = freq;
+ return true;
+}
+
+bool cPvrDevice::SetInput(int input) {
+ if (input == CurrentInput && !FirstChannelSwitch) return true;
+ log(pvrDEBUG1,"cPvrDevice::SetInput on /dev/video%d (%s) to %d", number, CARDNAME[cardname], input);
+ if (IOCTL(v4l2_fd, VIDIOC_S_INPUT, &input) != 0) {
+ log(pvrERROR, "VIDIOC_S_INPUT failed on /dev/video%d (%s) for input%d, %d:%s",
+ number, CARDNAME[cardname], errno, strerror(errno));
+ return false;
+ }
+#if 1 /* workaround for pvrusb2 driver bug: no audio after switching from radio to TV */
+ if (input == 0 && CurrentInput == 3 && driver == pvrusb2) {
+ usleep(200000); /* 200msec */
+ log(pvrDEBUG2,"cPvrDevice::SetInput on /dev/video%d (%s) again to %d (workaround for driver bug)",
+ number, CARDNAME[cardname], input);
+ IOCTL(v4l2_fd, VIDIOC_S_INPUT, &input); //set input television again
+ }
+#endif
+ CurrentInput=input;
+ if (driver == pvrusb2) {
+ usleep(100000); /* 100msec */
+ if (CurrentInput == inputs[eRadio]) {
+ SetControlValue(&PvrSetup.AudioVolumeFM,
+ PvrSetup.AudioVolumeFM.value);
+ }
+ else { //television or extern
+ SetAudioVolumeTV();
+ }
+ }
+ return true;
+}
+
+bool cPvrDevice::SetAudioInput(int input) {
+ struct v4l2_audio a;
+ a.index = input;
+ log(pvrDEBUG1,"cPvrDevice::SetAudioInput on /dev/video%d (%s) to %d", number, CARDNAME[cardname], input);
+ if (IOCTL(v4l2_fd, VIDIOC_S_AUDIO, &a) != 0) {
+ log(pvrERROR, "VIDIOC_S_AUDIO failed on /dev/video%d (%s) for input%d, %d:%s",
+ number, CARDNAME[cardname], errno, strerror(errno));
+ return false;
+ }
+ return true;
+}
+
+bool cPvrDevice::SetVideoNorm(uint64_t norm) {
+ if (norm == CurrentNorm){
+ return true;
+ }
+ log(pvrDEBUG1, "SetVideoNorm(0x%08llx) for /dev/video%d (%s)", norm, number, CARDNAME[cardname]);
+ if (hasDecoder) {
+ log(pvrDEBUG1, "cPvrDevice::we need to stop the PVR350 decoder");
+ struct video_command cmd;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.cmd = VIDEO_CMD_STOP;
+ cmd.flags = VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY;
+ if (IOCTL(v4l2_fd, VIDEO_COMMAND, &cmd) < 0) {
+ log(pvrERROR, "pvrinput: VIDEO_CMD_STOP error on /dev/video%d=%d:%s", number, strerror(errno));
+ }
+ }
+ if (IOCTL(v4l2_fd, VIDIOC_S_STD, &norm) !=0) {
+ log(pvrERROR, "cPvrDevice::SetVideoNorm() on /dev/video%d (%s) failed, %d:%s", \
+ number, CARDNAME[cardname], errno, strerror(errno));
+ return false;
+ }
+ CurrentNorm=norm;
+ return true;
+}
+
+bool cPvrDevice::SetVideoSize(int width, int height) {
+ log(pvrDEBUG1,"cPvrDevice::SetVideoSize");
+ struct v4l2_format vfmt;
+
+ vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ if (IOCTL(v4l2_fd, VIDIOC_G_FMT, &vfmt) != 0) {
+ log(pvrERROR, "cPvrDevice::SetVideoSize(): VIDIOC_G_FMT failed on /dev/video%d (%s), %d:%s", \
+ number, CARDNAME[cardname], errno, strerror(errno));
+ return false;
+ }
+ vfmt.fmt.pix.width = width;
+ vfmt.fmt.pix.height = height;
+ if (IOCTL(v4l2_fd, VIDIOC_S_FMT, &vfmt) != 0) {
+ log(pvrERROR, "cPvrDevice::SetVideoSize(): VIDIOC_S_FMT failed on /dev/video%d (%s), %d:%s", \
+ number, CARDNAME[cardname], errno, strerror(errno));
+ return false;
+ }
+ return true;
+}
+
+void cPvrDevice::SetTunerAudioMode(int tuneraudiomode) {
+ if (!hasTuner)
+ return;
+ log(pvrDEBUG1, "cPvrDevice::SetTunerAudioMode(%s) on /dev/video%d (%s)", \
+ tuneraudiomode == V4L2_TUNER_MODE_MONO?"mono":
+ tuneraudiomode == V4L2_TUNER_MODE_STEREO?"stereo":
+ tuneraudiomode == V4L2_TUNER_MODE_LANG1?"lang1":
+ tuneraudiomode == V4L2_TUNER_MODE_LANG2?"lang2":"bilingual", \
+ number, CARDNAME[cardname]);
+ struct v4l2_tuner vt;
+ memset(&vt, 0, sizeof(vt));
+ vt.audmode = tuneraudiomode;
+ if (IOCTL(v4l2_fd, VIDIOC_S_TUNER, &vt))
+ log(pvrERROR, "cPvrDevice::SetTunerAudioMode(%d): error %d:%s on /dev/video%d (%s)", \
+ tuneraudiomode, errno, strerror(errno), number, CARDNAME[cardname]);
+}
+
+void cPvrDevice::SetAudioVolumeTV() {
+ log(pvrDEBUG2, "AudioVolumeTVException.value=%d; AudioVolumeTVCommon.value=%d; number=%d, AudioVolumeTVExceptionCard=%d", \
+ PvrSetup.AudioVolumeTVException.value, PvrSetup.AudioVolumeTVCommon.value, number, PvrSetup.AudioVolumeTVExceptionCard);
+ if ((PvrSetup.AudioVolumeTVExceptionCard >= 0 && PvrSetup.AudioVolumeTVExceptionCard <=7) \
+ && (number == PvrSetup.AudioVolumeTVExceptionCard)) { //special value selected for a /dev/videoX number
+ log(pvrDEBUG1, "cPvrDevice::SetAudioVolumeTVException %d for /dev/video%d (%s)", \
+ PvrSetup.AudioVolumeTVException.value, number, CARDNAME[cardname]);
+ SetControlValue(&PvrSetup.AudioVolumeTVException, PvrSetup.AudioVolumeTVException.value);
+ }
+ if (PvrSetup.AudioVolumeTVExceptionCard >= 9 && PvrSetup.AudioVolumeTVExceptionCard <=18) { //special value for card(s) with certain name
+ if ((cardname == PVR150 && PvrSetup.AudioVolumeTVExceptionCard ==9) ||
+ (cardname == PVR250 && PvrSetup.AudioVolumeTVExceptionCard ==10) ||
+ (cardname == PVR350 && PvrSetup.AudioVolumeTVExceptionCard ==11) ||
+ (cardname == PVR500_1 && PvrSetup.AudioVolumeTVExceptionCard ==12) ||
+ (cardname == PVR500_2 && PvrSetup.AudioVolumeTVExceptionCard ==13) ||
+ (cardname == HVR1300 && PvrSetup.AudioVolumeTVExceptionCard ==14) ||
+ (cardname == HVR1600 && PvrSetup.AudioVolumeTVExceptionCard ==15) ||
+ (cardname == HVR1900 && PvrSetup.AudioVolumeTVExceptionCard ==16) ||
+ (cardname == HVR1950 && PvrSetup.AudioVolumeTVExceptionCard ==17) ||
+ (cardname == PVRUSB2 && PvrSetup.AudioVolumeTVExceptionCard ==18) ) {
+ log(pvrDEBUG1, "cPvrDevice::SetAudioVolumeTVException %d for /dev/video%d (%s)", \
+ PvrSetup.AudioVolumeTVException.value, number, CARDNAME[cardname]);
+ SetControlValue(&PvrSetup.AudioVolumeTVException, PvrSetup.AudioVolumeTVException.value);
+ }
+ }
+ else { //no special value (PvrSetup.AudioVolumeTVExceptionCard ==8)
+ log(pvrDEBUG1, "cPvrDevice::SetAudioVolumeTVCommon %d for /dev/video%d (%s)", \
+ PvrSetup.AudioVolumeTVCommon.value, number, CARDNAME[cardname]);
+ SetControlValue(&PvrSetup.AudioVolumeTVCommon, PvrSetup.AudioVolumeTVCommon.value);
+ }
+}
+
+void cPvrDevice::SetEncoderState(eEncState state) {
+ log(pvrDEBUG1, "cPvrDevice::SetEncoderState (%s) for /dev/video%d (%s)", \
+ state==eStop?"Stop":"Start", number, CARDNAME[cardname]);
+ if (driver == ivtv || driver == cx18 || driver == hdpvr) {
+ struct v4l2_encoder_cmd encoderCommand;
+ memset(&encoderCommand, 0, sizeof(encoderCommand));
+ switch(state) {
+ case eStop : encoderCommand.cmd = V4L2_ENC_CMD_STOP; break;
+ case eStart : encoderCommand.cmd = V4L2_ENC_CMD_START; break;
+ }
+ if (IOCTL(v4l2_fd, VIDIOC_ENCODER_CMD, &encoderCommand))
+ log(pvrERROR, "cPvrDevice::SetEncoderState(%s): error %d:%s on /dev/video%d (%s)", \
+ state==eStop?"Stop":"Start", errno, strerror(errno), number, CARDNAME[cardname]);
+ }
+ if (driver == pvrusb2 && state == eStop) {
+ int retry_count = 5;
+ retry:
+ close(v4l2_fd);
+ v4l2_fd = -1;
+ log(pvrDEBUG2, "cPvrDevice::SetEncoderState (eStop): /dev/video%d (%s) is closed", \
+ number, CARDNAME[cardname]);
+ pvrusb2_ready = false;
+ char * devName;
+ if (asprintf(&devName, "/dev/video%d", number) != -1) {
+ v4l2_fd = open(devName, O_RDWR); //reopen for tuning
+ }
+ if (v4l2_fd < 0) {
+ log(pvrERROR, "cPvrDevice::SetEncoderState(eStop): error reopening %s (%s): %d:%s", \
+ CARDNAME[cardname], devName, errno, strerror(errno));
+ free(devName);
+ retry_count--;
+ if (retry_count > 0)
+ goto retry;
+ }
+ else {
+ log(pvrDEBUG2, "cPvrDevice::SetEncoderState (eStop): %s (%s) successfully re-opened", \
+ devName, CARDNAME[cardname]);
+ pvrusb2_ready = true;
+ free(devName);
+ }
+ }
+}
+
+bool cPvrDevice::SetVBImode(int vbiLinesPerFrame, int vbistatus) {
+ if (v4l2_fd >= 0 && SupportsSlicedVBI ) {
+ log(pvrDEBUG1, "SetVBImode(%d, %d) on /dev/video%d (%s)", \
+ vbiLinesPerFrame, vbistatus, number, CARDNAME[cardname]);
+ struct v4l2_format vbifmt;
+ struct v4l2_ext_controls ctrls;
+ struct v4l2_ext_control ctrl;
+ memset(&vbifmt, 0, sizeof(vbifmt));
+ memset(&ctrls, 0, sizeof(ctrls));
+ memset(&ctrl, 0, sizeof(ctrl));
+ ctrl.id = V4L2_CID_MPEG_STREAM_VBI_FMT;
+ ctrl.value = vbistatus;
+ /* 0 = V4L2_MPEG_STREAM_VBI_FMT_NONE, No VBI in the MPEG stream
+ 1 = V4L2_MPEG_STREAM_VBI_FMT_IVTV, VBI in private packets, IVTV format */
+ ctrls.ctrl_class=V4L2_CTRL_CLASS_MPEG;
+ ctrls.controls=&ctrl;
+ ctrls.count=1;
+ if (IOCTL(v4l2_fd, VIDIOC_S_EXT_CTRLS, &ctrls) != 0) {
+ log(pvrERROR, "cPvrDevice::SetVBImode(): error setting vbi mode (ctrls) on /dev/video%d (%s), %d:%s",
+ number, CARDNAME[cardname], errno, strerror(errno));
+ return false;
+ }
+ if (ctrl.value == V4L2_MPEG_STREAM_VBI_FMT_IVTV && vbiLinesPerFrame == 625) {
+ vbifmt.fmt.sliced.service_set = V4L2_SLICED_TELETEXT_B;
+ vbifmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
+ vbifmt.fmt.sliced.reserved[0] = 0;
+ vbifmt.fmt.sliced.reserved[1] = 0;
+
+ if (IOCTL(v4l2_fd, VIDIOC_S_FMT, &vbifmt) < 0) {
+ log(pvrERROR, "cPvrDevice::SetVBImode():error setting vbi mode (fmt) on /dev/video%d (%s), %d:%s",
+ number, CARDNAME[cardname], errno, strerror(errno));
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+bool cPvrDevice::ParseChannel(const cChannel *Channel, int *input, uint64_t *norm, int *LinesPerFrame,
+ int *card, eVideoInputs *EncoderInput, int *apid, int *vpid, int *tpid) const {
+ *card = 999;
+ *norm = CurrentNorm; //make sure we have a value if channels.conf has no optArg for norm
+ *LinesPerFrame = CurrentLinesPerFrame; //see above
+ *input = -1;
+ if (Channel->IsCable() && Channel->Ca() == 0xA1) {
+ Skins.Message(mtError, tr("pvrinput no longer supports old channel syntax!"), 2);
+ log(pvrERROR, "cPvrDevice::pvrinput no longer supports old channel syntax!");
+ }
+#ifdef PVR_SOURCEPARAMS
+ if (cPvrSourceParam::IsPvr(Channel->Source())) {
+ const char * str = Channel->Parameters();
+ const char * PluginId = "PVRINPUT";
+ char * Input = NULL;
+ char * optArg1 = NULL;
+ char * optArg2 = NULL;
+ int NumArgs = 1 + sscanf(str, "%a[^|]|%a[^|]|%a[^:\n]",
+ &Input, &optArg1, &optArg2);
+#else
+ if (Channel->IsPlug()) {
+ const char * str = Channel->PluginParam();
+ char * PluginId = NULL;
+ char * Input = NULL;
+ char * optArg1 = NULL;
+ char * optArg2 = NULL;
+ int NumArgs = sscanf(str, "%a[^|]|%a[^|]|%a[^|]|%a[^:\n]",
+ &PluginId, &Input, &optArg1, &optArg2);
+#endif
+
+ if (NumArgs >= 2) {
+ if (strcasecmp(PluginId, "PVRINPUT")) return false;
+ log(pvrDEBUG1, "cPvrDevice::ParseChannel: using iptv channel syntax.");
+ *vpid = Channel->Vpid();
+ *apid = Channel->Apid(0);
+ *tpid = Channel->Tpid();
+ if (!strcasecmp (Input, "RADIO")) *EncoderInput=eRadio;
+ else if (!strcasecmp (Input, "TV")) *EncoderInput=eTelevision;
+ else if (!strncasecmp(Input, "COMPOSITE",9)) *EncoderInput=eExternalInput;
+ else if (!strncasecmp(Input, "SVIDEO",6)) *EncoderInput=eExternalInput;
+ else if (!strncasecmp(Input, "COMPONENT",9)) *EncoderInput=eExternalInput;
+ else return false;
+ if (!strcasecmp (Input, "TV")) *input = inputs[eTelevision];
+ else if (!strcasecmp (Input, "RADIO")) *input = inputs[eRadio];
+ else if (!strcasecmp (Input, "COMPOSITE0")) *input = inputs[eComposite0];
+ else if (!strcasecmp (Input, "COMPOSITE1")) *input = inputs[eComposite1];
+ else if (!strcasecmp (Input, "COMPOSITE2")) *input = inputs[eComposite2];
+ else if (!strcasecmp (Input, "COMPOSITE3")) *input = inputs[eComposite3];
+ else if (!strcasecmp (Input, "COMPOSITE4")) *input = inputs[eComposite4];
+ else if (!strcasecmp (Input, "COMPOSITE")) *input = inputs[eComposite0];
+ else if (!strcasecmp (Input, "SVIDEO0")) *input = inputs[eSVideo0];
+ else if (!strcasecmp (Input, "SVIDEO1")) *input = inputs[eSVideo1];
+ else if (!strcasecmp (Input, "SVIDEO2")) *input = inputs[eSVideo2];
+ else if (!strcasecmp (Input, "SVIDEO3")) *input = inputs[eSVideo3];
+ else if (!strcasecmp (Input, "SVIDEO")) *input = inputs[eSVideo0];
+ else if (!strcasecmp (Input, "COMPONENT")) *input = inputs[eComponent];
+ else return false; //unknown
+ if (NumArgs > 2) { /* only if optional arg norm or card given */
+ if (!strcasecmp (optArg1, "PAL")) { *norm = V4L2_STD_PAL; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg1, "NTSC" )) { *norm = V4L2_STD_NTSC; *LinesPerFrame = 525; }
+ else if (!strcasecmp (optArg1, "SECAM")) { *norm = V4L2_STD_SECAM; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg1, "NTSC_M")) { *norm = V4L2_STD_NTSC_M; *LinesPerFrame = 525; }
+ else if (!strcasecmp (optArg1, "NTSC_M_JP")) { *norm = V4L2_STD_NTSC_M_JP; *LinesPerFrame = 525; }
+ else if (!strcasecmp (optArg1, "NTSC_443")) { *norm = V4L2_STD_NTSC_443; *LinesPerFrame = 525; }
+ else if (!strcasecmp (optArg1, "NTSC_M_KR")) { *norm = V4L2_STD_NTSC_M_KR; *LinesPerFrame = 525; }
+ else if (!strcasecmp (optArg1, "PAL_M")) { *norm = V4L2_STD_PAL_M; *LinesPerFrame = 525; }
+ else if (!strcasecmp (optArg1, "PAL_N")) { *norm = V4L2_STD_PAL_N; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg1, "PAL_NC")) { *norm = V4L2_STD_PAL_Nc; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg1, "PAL_B")) { *norm = V4L2_STD_PAL_B; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg1, "PAL_B1")) { *norm = V4L2_STD_PAL_B1; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg1, "PAL_G")) { *norm = V4L2_STD_PAL_G; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg1, "PAL_BG")) { *norm = V4L2_STD_PAL_BG; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg1, "PAL_D")) { *norm = V4L2_STD_PAL_D; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg1, "PAL_D1")) { *norm = V4L2_STD_PAL_D1; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg1, "PAL_K")) { *norm = V4L2_STD_PAL_K; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg1, "PAL_DK")) { *norm = V4L2_STD_PAL_DK; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg1, "PAL_H")) { *norm = V4L2_STD_PAL_H; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg1, "PAL_I")) { *norm = V4L2_STD_PAL_I; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg1, "PAL_60")) { *norm = V4L2_STD_PAL_60; *LinesPerFrame = 525; }
+ else if (!strcasecmp (optArg1, "SECAM_B")) { *norm = V4L2_STD_SECAM_B; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg1, "SECAM_D")) { *norm = V4L2_STD_SECAM_D; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg1, "SECAM_G")) { *norm = V4L2_STD_SECAM_G; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg1, "SECAM_H")) { *norm = V4L2_STD_SECAM_H; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg1, "SECAM_K")) { *norm = V4L2_STD_SECAM_K; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg1, "SECAM_K1")) { *norm = V4L2_STD_SECAM_K1; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg1, "SECAM_DK")) { *norm = V4L2_STD_SECAM_DK; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg1, "SECAM_L")) { *norm = V4L2_STD_SECAM_L; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg1, "SECAM_LC")) { *norm = V4L2_STD_SECAM_LC; *LinesPerFrame = 625; }
+ if (!strcasecmp (optArg1, "CARD0")) *card = 0;
+ else if (!strcasecmp (optArg1, "CARD1")) *card = 1;
+ else if (!strcasecmp (optArg1, "CARD2")) *card = 2;
+ else if (!strcasecmp (optArg1, "CARD3")) *card = 3;
+ else if (!strcasecmp (optArg1, "CARD4")) *card = 4;
+ else if (!strcasecmp (optArg1, "CARD5")) *card = 5;
+ else if (!strcasecmp (optArg1, "CARD6")) *card = 6;
+ else if (!strcasecmp (optArg1, "CARD7")) *card = 7;
+ }
+ if (NumArgs > 3) { /* only if optional arg norm or card given */
+ if (!strcasecmp (optArg2, "PAL")) { *norm = V4L2_STD_PAL; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg2, "NTSC" )) { *norm = V4L2_STD_NTSC; *LinesPerFrame = 525; }
+ else if (!strcasecmp (optArg2, "SECAM")) { *norm = V4L2_STD_SECAM; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg2, "NTSC_M")) { *norm = V4L2_STD_NTSC_M; *LinesPerFrame = 525; }
+ else if (!strcasecmp (optArg2, "NTSC_M_JP")) { *norm = V4L2_STD_NTSC_M_JP; *LinesPerFrame = 525; }
+ else if (!strcasecmp (optArg2, "NTSC_443")) { *norm = V4L2_STD_NTSC_443; *LinesPerFrame = 525; }
+ else if (!strcasecmp (optArg2, "NTSC_M_KR")) { *norm = V4L2_STD_NTSC_M_KR; *LinesPerFrame = 525; }
+ else if (!strcasecmp (optArg2, "PAL_M")) { *norm = V4L2_STD_PAL_M; *LinesPerFrame = 525; }
+ else if (!strcasecmp (optArg2, "PAL_N")) { *norm = V4L2_STD_PAL_N; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg2, "PAL_NC")) { *norm = V4L2_STD_PAL_Nc; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg2, "PAL_B")) { *norm = V4L2_STD_PAL_B; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg2, "PAL_B1")) { *norm = V4L2_STD_PAL_B1; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg2, "PAL_G")) { *norm = V4L2_STD_PAL_G; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg2, "PAL_BG")) { *norm = V4L2_STD_PAL_BG; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg2, "PAL_D")) { *norm = V4L2_STD_PAL_D; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg2, "PAL_D1")) { *norm = V4L2_STD_PAL_D1; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg2, "PAL_K")) { *norm = V4L2_STD_PAL_K; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg2, "PAL_DK")) { *norm = V4L2_STD_PAL_DK; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg2, "PAL_H")) { *norm = V4L2_STD_PAL_H; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg2, "PAL_I")) { *norm = V4L2_STD_PAL_I; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg2, "PAL_60")) { *norm = V4L2_STD_PAL_60; *LinesPerFrame = 525; }
+ else if (!strcasecmp (optArg2, "SECAM_B")) { *norm = V4L2_STD_SECAM_B; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg2, "SECAM_D")) { *norm = V4L2_STD_SECAM_D; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg2, "SECAM_G")) { *norm = V4L2_STD_SECAM_G; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg2, "SECAM_H")) { *norm = V4L2_STD_SECAM_H; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg2, "SECAM_K")) { *norm = V4L2_STD_SECAM_K; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg2, "SECAM_K1")) { *norm = V4L2_STD_SECAM_K1; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg2, "SECAM_DK")) { *norm = V4L2_STD_SECAM_DK; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg2, "SECAM_L")) { *norm = V4L2_STD_SECAM_L; *LinesPerFrame = 625; }
+ else if (!strcasecmp (optArg2, "SECAM_LC")) { *norm = V4L2_STD_SECAM_LC; *LinesPerFrame = 625; }
+ if (!strcasecmp (optArg2, "CARD0")) *card = 0;
+ else if (!strcasecmp (optArg2, "CARD1")) *card = 1;
+ else if (!strcasecmp (optArg2, "CARD2")) *card = 2;
+ else if (!strcasecmp (optArg2, "CARD3")) *card = 3;
+ else if (!strcasecmp (optArg2, "CARD4")) *card = 4;
+ else if (!strcasecmp (optArg2, "CARD5")) *card = 5;
+ else if (!strcasecmp (optArg2, "CARD6")) *card = 6;
+ else if (!strcasecmp (optArg2, "CARD7")) *card = 7;
+ }
+ log(pvrDEBUG2, "ParseChannel %s input %d, norm=0x%08llx, card %d",
+ (*EncoderInput==eRadio)?"Radio":(*EncoderInput==eTelevision)?"TV":"Ext",
+ *input,*norm,*card);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool cPvrDevice::SetChannelDevice(const cChannel * Channel, bool LiveView) {
+ log(pvrDEBUG1, "cPvrDevice::SetChannelDevice %d (%s) %3.2fMHz (/dev/video%d = %s)", \
+ Channel->Number(), Channel->Name(), (double) Channel->Frequency()/1000, number, CARDNAME[cardname]);
+ int input, LinesPerFrame, card;
+ uint64_t norm;
+ if (! ParseChannel(Channel,&input,&norm,&LinesPerFrame,&card,&EncoderInput,&apid,&vpid,&tpid))
+ return false;
+
+ if ((Channel->Number() == currentChannel.Number()) && (Channel->Frequency() == frequency) && (input == CurrentInput) && (norm == CurrentNorm))
+ return true;
+ newFrequency = Channel->Frequency();
+ newInput = input;
+ newNorm = norm;
+ newLinesPerFrame = LinesPerFrame;
+ newEncoderInput = EncoderInput;
+ ChannelSettingsDone = false;
+ currentChannel = *Channel;
+ return true;
+}
+
+bool cPvrDevice::SetPid(cPidHandle * Handle, int Type, bool On) {
+ log(pvrDEBUG2, "cPvrDevice::SetPid %d = %s", Handle->pid, On?"On":"Off");
+ return true;
+}
+
+int cPvrDevice::OpenFilter(u_short Pid, u_char Tid, u_char Mask)
+{
+ int handle = sectionHandler.AddFilter(Pid, Tid, Mask);
+ log(pvrDEBUG2, "cPvrDevice::OpenFilter: /dev/video%d (%s) pid = %d, tid = %d, mask = %d, handle = %d",
+ number, CARDNAME[cardname], Pid, Tid, Mask, handle);
+ return handle;
+}
+
+#if VDRVERSNUM >= 10600
+void cPvrDevice::CloseFilter(int Handle)
+{
+ log(pvrDEBUG2, "cPvrDevice::CloseFilter: /dev/video%d (%s) handle = %d",
+ number, CARDNAME[cardname], Handle);
+ sectionHandler.RemoveFilter(Handle);
+}
+#endif
+
+bool cPvrDevice::OpenDvr(void) {
+ log(pvrDEBUG1, "entering cPvrDevice::OpenDvr: Dvr of /dev/video%d (%s) is %s",
+ number, CARDNAME[cardname], (dvrOpen)?"open":"closed");
+ delivered = false;
+ CloseDvr();
+ while (dvrOpen) { //wait until CloseDvr has finnished
+ usleep(40000);
+ log(pvrDEBUG1, "OpenDvr: wait for CloseDvr on /dev/video%d (%s) to finnish", \
+ number, CARDNAME[cardname]);
+ }
+ tsBuffer->Clear();
+ ResetBuffering();
+ if (!dvrOpen) {
+ if (driver == ivtv || driver == cx18) {
+ if (PvrSetup.repeat_ReInitAll_after_next_encoderstop) {
+ ReInitAll(); //some settings require an encoder stop, so we repeat them now
+ PvrSetup.repeat_ReInitAll_after_next_encoderstop = false;
+ }
+ }
+ if (!ChannelSettingsDone) {
+ if (driver == pvrusb2) {
+ while (!pvrusb2_ready) { //re-opening pvrusb2 in SetEncoderState might be in progress
+ usleep(40000);
+ log(pvrDEBUG1, "OpenDvr: wait until /dev/video%d (%s) is ready", \
+ number, CARDNAME[cardname]);
+ }
+ }
+ switch (newEncoderInput) {
+ case eComposite0 ... eComposite4: //no break here, continuing at next case item
+ case eSVideo0 ... eSVideo3: //no break here, continuing at next case item
+ case eComponent: //no break here, continuing at next case item
+ case eExternalInput:
+ {
+ log(pvrDEBUG2,"channel is external input.");
+ if (radio_fd >= 0) {
+ close(radio_fd);
+ radio_fd = -1;
+ usleep(100000); /* 100msec */
+ SetAudioVolumeTV();
+ SetControlValue(&PvrSetup.VideoBitrateTV, \
+ PvrSetup.VideoBitrateTV.value);
+ }
+
+ if (PvrSetup.UseExternChannelSwitchScript) {
+ cString cmd = cString::sprintf("%s %d %d %d", *externChannelSwitchScript, currentChannel.Sid(), currentChannel.Number(), number);
+ log(pvrDEBUG1, "OpenDvr: calling %s", *cmd);
+ if (system(*cmd) < 0) {
+ log(pvrERROR, "OpenDvr: executing %s failed", *cmd);
+ }
+ log(pvrDEBUG1, "OpenDvr: returned from %s", *cmd);
+ }
+
+ if (! SetInput(newInput)) return false;
+ if (! SetVideoNorm(newNorm)) return false;
+ frequency=newFrequency; // since we don't tune: set it here
+ break;
+ }
+ case eRadio :
+ {
+ log(pvrDEBUG2,"channel is FM radio.");
+ switch (driver) {
+ case ivtv:
+ case cx18:
+ if (radio_dev < 0) return false; //no hardware support.
+ if (radio_fd < 0) {
+ char * devName;
+ if (asprintf(&devName, "/dev/radio%d", radio_dev) != -1) {
+ radio_fd = open(devName, O_RDONLY);
+ }
+ if (radio_fd < 0) {
+ log(pvrERROR, "Error opening FM radio device %s: %s",\
+ devName, strerror(errno));
+ return false;
+ }
+ free(devName);
+ usleep(100000); /* 100msec */
+ SetControlValue(&PvrSetup.AudioVolumeFM, \
+ PvrSetup.AudioVolumeFM.value);
+ }
+ break;
+ case pvrusb2:
+ if (! SetInput(inputs[eRadio])) return false;
+ case cx88_blackbird:
+ case hdpvr:
+ break;
+ case undef: log(pvrERROR, "driver is unknown!!"); return false;
+ }
+ if (! Tune(newFrequency)) return false;
+ break;
+ }
+ case eTelevision :
+ {
+ log(pvrDEBUG2,"channel is television.");
+ if ((driver == ivtv) && (radio_fd >= 0)) {
+ close(radio_fd);
+ radio_fd = -1;
+ usleep(100000); /* 100msec */
+ SetAudioVolumeTV();
+ SetControlValue(&PvrSetup.VideoBitrateTV, \
+ PvrSetup.VideoBitrateTV.value);
+ }
+ if (! SetInput(inputs[eTelevision])) return false;
+ if (! SetVideoNorm(newNorm)) return false;
+ if (! SetVBImode(newLinesPerFrame, PvrSetup.SliceVBI)) return false;
+ if (! Tune(newFrequency)) return false;
+ }
+ } //end: switch (newEncoderInput)
+ ChannelSettingsDone = true;
+ FirstChannelSwitch = false;
+ } //end: if ((!ChannelSettingsDone)
+ SetEncoderState(eStart);
+ if (!readThreadRunning) {
+ log(pvrDEBUG2, "cPvrDevice::OpenDvr: create new readThread on /dev/video%d (%s)", \
+ number, CARDNAME[cardname]);
+ readThread = new cPvrReadThread(tsBuffer, this);
+ }
+ } //end: if (!dvrOpen)
+ dvrOpen = true;
+ return true;
+}
+
+void cPvrDevice::CloseDvr(void) {
+ if (isClosing) return;
+ isClosing = true;
+ log(pvrDEBUG2, "entering cPvrDevice::CloseDvr: Dvr of /dev/video%d (%s) is %s", \
+ number, CARDNAME[cardname], (dvrOpen)?"open":"closed");
+ if (dvrOpen) {
+ StopReadThread();
+ SetEncoderState(eStop);
+ SetVBImode(CurrentLinesPerFrame, 0);
+ }
+ dvrOpen = false;
+ isClosing = false;
+}
+
+void cPvrDevice::ResetBuffering() {
+ tsBufferPrefill = (MEGABYTE(PvrSetup.TsBufferSizeMB) * PvrSetup.TsBufferPrefillRatio) / 100;
+ tsBufferPrefill -= (tsBufferPrefill % TS_SIZE);
+ log(pvrDEBUG2, "cPvrDevice::ResetBuffering(): tsBuffer prefill = %d for /dev/video%d (%s)",
+ tsBufferPrefill, number, CARDNAME[cardname]);
+}
+
+bool cPvrDevice::IsBuffering() {
+ int avail = tsBuffer->Available();
+ if (tsBufferPrefill && (avail < tsBufferPrefill)) {
+ log(pvrDEBUG2, "cPvrDevice::IsBuffering(): available = %d, prefill = %d for /dev/video%d (%s)",
+ avail, tsBufferPrefill, number, CARDNAME[cardname]);
+ return true;
+ }
+ tsBufferPrefill = 0;
+ return false;
+}
+
+bool cPvrDevice::GetTSPacket(uchar *&Data) {
+ int Count = 0;
+ if (! tsBuffer ) {
+ log(pvrERROR, "cPvrDevice::GetTSPacket(): no tsBuffer for /dev/video%d (%s)", \
+ number, CARDNAME[cardname]);
+ return false;
+ }
+ if (tsBuffer && readThreadRunning) {
+ if (!IsBuffering()) {
+ if (delivered) {
+ tsBuffer->Del(TS_SIZE);
+ delivered = false;
+ //log(pvrDEBUG2, "cPvrDevice::GetTSPacket(): packet delivered");
+ }
+ uchar *p = tsBuffer->Get(Count);
+ if (p && Count >= TS_SIZE) {
+ if (*p != TS_SYNC_BYTE) {
+ for (int i = 1; i < Count; i++) {
+ if (p[i] == TS_SYNC_BYTE) {
+ Count = i;
+ break;
+ } //end: if
+ } //end: for
+ tsBuffer->Del(Count);
+ log(pvrINFO, "ERROR: cPvrDevice::GetTSPacket(): skipped %d bytes to sync on TS packet\n", Count);
+ return false;
+ }
+ sectionHandler.ProcessTSPacket(p);
+ delivered = true;
+ Data = p;
+ return true;
+ }
+ }
+ cCondWait::SleepMs(10); // reduce cpu load while buffering
+ Data = NULL;
+ return true;
+ }
+ return false;
+}
+
+bool cPvrDevice::ProvidesSource(int Source) const {
+#ifdef PVR_SOURCEPARAMS
+ if (cPvrSourceParam::IsPvr(Source)) {
+#else
+ if (cSource::IsPlug(Source)) {
+#endif
+ log(pvrDEBUG1, "cPvrDevice::ProvidesSource Source=%s -> true",
+ (const char *) cSource::ToString(Source));
+ return true;
+ }
+ return false;
+}
+
+bool cPvrDevice::ProvidesTransponder(const cChannel * Channel) const {
+ return ProvidesSource(Channel->Source());
+}
+
+int cPvrDevice::NumProvidedSystems(void) const
+{
+ return 1;
+}
+
+bool cPvrDevice::ProvidesChannel(const cChannel * Channel, int Priority, \
+ bool * NeedsDetachReceivers) const {
+ bool result = false;
+ bool hasPriority = Priority < 0 || Priority > this->Priority();
+ bool needsDetachReceivers = true;
+ int input, LinesPerFrame, dev;
+ uint64_t norm;
+ eVideoInputs encoderInput; //only dummy
+ int audioPid,videoPid,teletextPid; //only dummy
+ if (! ParseChannel(Channel, &input, &norm, &LinesPerFrame, &dev, &encoderInput, &audioPid, &videoPid, &teletextPid))
+ return false; // non-pvrinput channel or wrong syntax used, silently ignore this one
+ if ((dev < 999) && (number != dev)) {
+ log(pvrDEBUG1, "cPvrDevice::ProvidesChannel %s -> false (this is /dev/video%d, but CARD parameter says /dev/video%d only)",
+ Channel->Name(), number, dev);
+ return false;
+ }
+ if ((PvrSetup.UseOnlyCard >= 0 && PvrSetup.UseOnlyCard <=7) && (number != PvrSetup.UseOnlyCard)) { //select by number
+ log(pvrDEBUG1, "cPvrDevice::ProvidesChannel %s -> false (this is /dev/video%d, but /dev/video%d only was selected in setup)",
+ Channel->Name(), number, PvrSetup.UseOnlyCard);
+ return false;
+ }
+ if (PvrSetup.UseOnlyCard >= 9 && PvrSetup.UseOnlyCard <=19) { //select by Name
+ if ((cardname == PVR150 && PvrSetup.UseOnlyCard !=9) ||
+ (cardname == PVR250 && PvrSetup.UseOnlyCard !=10) ||
+ (cardname == PVR350 && PvrSetup.UseOnlyCard !=11) ||
+ (cardname == PVR500_1 && PvrSetup.UseOnlyCard !=12) ||
+ (cardname == PVR500_2 && PvrSetup.UseOnlyCard !=13) ||
+ (cardname == HVR1300 && PvrSetup.UseOnlyCard !=14) ||
+ (cardname == HVR1600 && PvrSetup.UseOnlyCard !=15) ||
+ (cardname == HVR1900 && PvrSetup.UseOnlyCard !=16) ||
+ (cardname == HVR1950 && PvrSetup.UseOnlyCard !=17) ||
+ (cardname == PVRUSB2 && PvrSetup.UseOnlyCard !=18) ||
+ (cardname == HDPVR && PvrSetup.UseOnlyCard !=19) ) {
+ log(pvrDEBUG1, "cPvrDevice::ProvidesChannel %s -> false (this is %s, but %s only was selected in setup)",
+ Channel->Name(),CARDNAME[cardname],
+ PvrSetup.UseOnlyCard==9?"PVR150": \
+ PvrSetup.UseOnlyCard==10?"PVR250": \
+ PvrSetup.UseOnlyCard==11?"PVR350": \
+ PvrSetup.UseOnlyCard==12?"PVR500#1": \
+ PvrSetup.UseOnlyCard==13?"PVR500#2": \
+ PvrSetup.UseOnlyCard==14?"HVR1300": \
+ PvrSetup.UseOnlyCard==15?"HVR1600": \
+ PvrSetup.UseOnlyCard==16?"HVR1900": \
+ PvrSetup.UseOnlyCard==17?"HVR1950": \
+ PvrSetup.UseOnlyCard==18?"PVRUSB2": \
+ PvrSetup.UseOnlyCard==19?"HDPVR":"UNDEF");
+ return false;
+ }
+ }
+ if (Channel->Frequency() >= 87500 && Channel->Frequency() <= 108000) {
+ if (radio_dev < 0) {
+ log(pvrDEBUG1, "cPvrDevice::ProvidesChannel: /dev/video%d (%s) has no radio", number, CARDNAME[cardname]);
+ return false;
+ }
+ }
+ if ((input < 0) || (input >= numInputs)) {
+ log(pvrERROR, "cPvrDevice::ProvidesChannel: input %d unknown on /dev/video%d (%s)", \
+ input, number, CARDNAME[cardname]);
+ return false;
+ }
+ if ((Priority >= 0) && Receiving(true)) {
+ if ((Channel->Number() == currentChannel.Number()) && (frequency == Channel->Frequency()) && (CurrentInput == input) && (CurrentNorm == norm)) {
+ needsDetachReceivers = false;
+ result = true;
+ log(pvrDEBUG1, "cPvrDevice::ProvidesChannel: %s already set -> true.", Channel->Name());
+ }
+ else
+ result = hasPriority;
+ }
+ else
+ result = hasPriority;
+ if (NeedsDetachReceivers)
+ *NeedsDetachReceivers = needsDetachReceivers;
+ log(pvrDEBUG1, "cPvrDevice::ProvidesChannel: /dev/video%d (%s): Channel %d (%s) %3.2fMHz, -> %s", \
+ number, CARDNAME[cardname], Channel->Number(), Channel->Name(), (double) Channel->Frequency()/1000, \
+ result?"true":"false");
+ log(pvrDEBUG2, "cPvrDevice::ProvidesChannel: /dev/video%d: Receiving()=%s, needsDetachReceivers=%s, Priority=%d, hasPriority=%s", \
+ number, Receiving(true)?"true":"false", needsDetachReceivers?"true":"false", Priority, hasPriority?"true":"false");
+ return result;
+}
+
+/*
+if a card/driver has unsupported controls, it returns false for this
+*/
+bool cPvrDevice::ControlIdIsValid(__u32 ctrlid) {
+ if (driver == hdpvr) {
+ if (/*(ctrlid != V4L2_CID_BRIGHTNESS) // these controls seem to use other values for the HD PVR
+ && (ctrlid != V4L2_CID_CONTRAST) // than the other PVRs (ioctl returns "invalid argument")
+ && (ctrlid != V4L2_CID_SATURATION) // so ignore them for now, since the defaults seem to be ok.
+ && (ctrlid != V4L2_CID_HUE)
+ &&*/ (ctrlid != V4L2_CID_SHARPNESS)
+ && (ctrlid != V4L2_CID_MPEG_AUDIO_ENCODING)
+ && (ctrlid != V4L2_CID_MPEG_VIDEO_ENCODING)
+ && (ctrlid != V4L2_CID_MPEG_VIDEO_BITRATE_MODE)
+ && (ctrlid != V4L2_CID_MPEG_VIDEO_BITRATE)
+ && (ctrlid != V4L2_CID_MPEG_VIDEO_BITRATE_PEAK))
+ return false;
+ }
+ return true;
+}
+
+/*
+Sets a V4L2 control.
+If the value Val is out of range, the ivtv default value will be
+used. The value set to V4L2 will be returned, either Val or the
+default.
+Has to be used *after* calling cPvrDevice::QueryAllControls()
+20070506
+If possible, use THIS function for setting VIDIOC_S_EXT_CTRLS.
+-wirbel-
+*/
+
+int cPvrDevice::SetControlValue(struct valSet * vs, __s32 Val) {
+ if (SetControlValue(vs->ctrl_class, vs->queryctrl.id, Val, vs->queryctrl) == 0) {
+ vs->value = Val;
+ return 0;
+ }
+ else
+ return -1;
+}
+
+/*
+functionality as above, but no valSet needed.
+*/
+
+int cPvrDevice::SetControlValue(__u32 control, __s32 Val) {
+
+__u32 ctrl_class=V4L2_CTRL_CLASS_MPEG;
+struct v4l2_queryctrl * query;
+
+switch (control) {
+ // picture properties
+ case V4L2_CID_BRIGHTNESS: ctrl_class=V4L2_CTRL_CLASS_USER;
+ query=&PvrSetup.Brightness.queryctrl;
+ break;
+ case V4L2_CID_CONTRAST: ctrl_class=V4L2_CTRL_CLASS_USER;
+ query=&PvrSetup.Contrast.queryctrl;
+ break;
+ case V4L2_CID_SATURATION: ctrl_class=V4L2_CTRL_CLASS_USER;
+ query=&PvrSetup.Saturation.queryctrl;
+ break;
+ case V4L2_CID_HUE: ctrl_class=V4L2_CTRL_CLASS_USER;
+ query=&PvrSetup.Hue.queryctrl;
+ break;
+ // Audio
+ case V4L2_CID_AUDIO_VOLUME: ctrl_class=V4L2_CTRL_CLASS_USER;
+ query=&PvrSetup.AudioVolumeTVCommon.queryctrl;
+ break;
+ case V4L2_CID_AUDIO_MUTE: ctrl_class=V4L2_CTRL_CLASS_USER;
+ query=&PvrSetup.AudioMute.queryctrl;
+ break;
+ case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
+ query=&PvrSetup.AudioBitrate.queryctrl;
+ break;
+ case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
+ query=&PvrSetup.AudioSampling.queryctrl;
+ break;
+ case V4L2_CID_MPEG_AUDIO_ENCODING:
+ if (driver == hdpvr)
+ query=&PvrSetup.HDPVR_AudioEncoding.queryctrl;
+ else
+ query=&PvrSetup.AudioEncoding.queryctrl;
+ break;
+ // Video
+ case V4L2_CID_MPEG_VIDEO_BITRATE:
+ query=&PvrSetup.VideoBitrateTV.queryctrl;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
+ query=&PvrSetup.VideoBitratePeak.queryctrl;
+ break;
+ case V4L2_CID_MPEG_VIDEO_ASPECT:
+ query=&PvrSetup.AspectRatio.queryctrl;
+ break;
+ // MPEG
+ case V4L2_CID_MPEG_STREAM_TYPE:
+ query=&PvrSetup.StreamType.queryctrl;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+ query=&PvrSetup.BitrateMode.queryctrl;
+ break;
+ case V4L2_CID_MPEG_VIDEO_B_FRAMES:
+ query=&PvrSetup.BFrames.queryctrl;
+ break;
+ case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+ query=&PvrSetup.GopSize.queryctrl;
+ break;
+ case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
+ query=&PvrSetup.GopClosure.queryctrl;
+ break;
+ // Video Filters
+ case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
+ query=&PvrSetup.FilterSpatialMode.queryctrl;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
+ query=&PvrSetup.FilterSpatial.queryctrl;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
+ query=&PvrSetup.FilterLumaSpatialType.queryctrl;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
+ query=&PvrSetup.FilterChromaSpatialType.queryctrl;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
+ query=&PvrSetup.FilterTemporalMode.queryctrl;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
+ query=&PvrSetup.FilterTemporal.queryctrl;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
+ query=&PvrSetup.FilterMedianType.queryctrl;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
+ query=&PvrSetup.FilterLumaMedianBottom.queryctrl;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
+ query=&PvrSetup.FilterLumaMedianTop.queryctrl;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
+ query=&PvrSetup.FilterChromaMedianBottom.queryctrl;
+ break;
+ case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
+ query=&PvrSetup.FilterChromaMedianTop.queryctrl;
+ break;
+ if (SupportsSlicedVBI) {
+ // VBI
+ case V4L2_CID_MPEG_STREAM_VBI_FMT:
+ query=&PvrSetup.VBIformat.queryctrl;
+ break;
+ }
+ default:
+ log(pvrERROR, "SetControlValue(__u32 control, __s32 Val): ERROR: control %d not included in switch(control)",\
+ control);
+ return -1;
+ }
+
+ return SetControlValue(ctrl_class, control, Val, *query);
+}
+
+
+/*
+Sets a V4L2 control.
+If the value Val is out of range, the ivtv default value will be
+used. The value set to V4L2 will be returned, either Val or the
+default.
+Has to be used *after* calling cPvrDevice::QueryAllControls().
+-wirbel-
+*/
+
+int cPvrDevice::SetControlValue(__u32 control_class, __u32 control, __s32 Val, \
+ struct v4l2_queryctrl queryctrl) {
+
+ struct v4l2_ext_controls ctrls;
+ struct v4l2_ext_control ctrl;
+
+ if (!ControlIdIsValid(queryctrl.id)) // skip known unsupported controls of the driver with "no error"
+ return Val;
+ log (3, "SetControlValue(%s, %d)",queryctrl.name, Val);
+ if ((queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) == V4L2_CTRL_FLAG_DISABLED){
+ log(pvrINFO, " Error: this control is disabled by driver. Skipped.");
+ return Val;
+ }
+ if ((Val>queryctrl.maximum) || (Val<queryctrl.minimum)) {
+ log(pvrINFO, " Info: setting value to default(%d)",queryctrl.default_value);
+ Val=queryctrl.default_value;
+ }
+ ctrl.id = control;
+ ctrl.value = Val;
+
+ ctrls.ctrl_class=control_class;
+ ctrls.controls=&ctrl;
+ ctrls.count=1;
+
+ if (IOCTL(v4l2_fd, VIDIOC_S_EXT_CTRLS, &ctrls) != 0) {
+ log(pvrERROR, "cPvrDevice::SetControlValue(): setting control value %s: %d:%s",
+ queryctrl.name, errno, strerror(errno));
+ }
+ return Val;
+}
+
+
+/*
+Queries the properties of a given valSet
+20070510
+-> Before using function, valSet's queryctrl.id has to be set.
+-wirbel-
+*/
+
+int cPvrDevice::QueryControl(struct valSet * vs) {
+ if (!ControlIdIsValid(vs->queryctrl.id)) // skip known unsupported controls of the driver with "no error"
+ return 0;
+ vs->query_isvalid = false;
+ if (vs->queryctrl.id == 0) {
+ log(pvrERROR, "cPvrDevice::QueryControl(): valSet not initialized.");
+ return -1;
+ }
+ if (IOCTL(v4l2_fd, VIDIOC_QUERYCTRL, &vs->queryctrl) != 0) {
+ log(pvrERROR, "QueryControl(): quering control %d failed.", vs->queryctrl.id);
+ return -1;
+ }
+ vs->query_isvalid = true;
+ return 0;
+}
+
+
+/*
+Queries the properties of all valSets used in SetControlValue
+20070510
+-wirbel-
+*/
+
+bool cPvrDevice::QueryAllControls(void) {
+ int err=0;
+ log(pvrDEBUG1, "QueryAllControls");
+
+ PvrSetup.Brightness.ctrl_class = V4L2_CTRL_CLASS_USER;
+ PvrSetup.Contrast.ctrl_class = V4L2_CTRL_CLASS_USER;
+ PvrSetup.Saturation.ctrl_class = V4L2_CTRL_CLASS_USER;
+ PvrSetup.Hue.ctrl_class = V4L2_CTRL_CLASS_USER;
+ // Audio
+ PvrSetup.AudioVolumeTVCommon.ctrl_class = V4L2_CTRL_CLASS_USER;
+ PvrSetup.AudioVolumeTVException.ctrl_class = V4L2_CTRL_CLASS_USER;
+ PvrSetup.AudioVolumeFM.ctrl_class = V4L2_CTRL_CLASS_USER;
+ PvrSetup.AudioMute.ctrl_class = V4L2_CTRL_CLASS_USER;
+ PvrSetup.AudioBitrate.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+ PvrSetup.AudioSampling.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+ PvrSetup.AudioEncoding.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+ PvrSetup.HDPVR_AudioEncoding.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+ // Video
+ PvrSetup.VideoBitrateTV.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+ PvrSetup.VideoBitratePeak.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+ PvrSetup.AspectRatio.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+ // MPEG
+ PvrSetup.StreamType.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+ PvrSetup.BitrateMode.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+ PvrSetup.BFrames.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+ PvrSetup.GopSize.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+ PvrSetup.GopClosure.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+ // Video Filters
+ PvrSetup.FilterSpatialMode.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+ PvrSetup.FilterSpatial.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+ PvrSetup.FilterLumaSpatialType.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+ PvrSetup.FilterChromaSpatialType.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+ PvrSetup.FilterTemporalMode.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+ PvrSetup.FilterTemporal.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+ PvrSetup.FilterMedianType.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+ PvrSetup.FilterLumaMedianBottom.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+ PvrSetup.FilterLumaMedianTop.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+ PvrSetup.FilterChromaMedianBottom.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+ PvrSetup.FilterChromaMedianTop.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+
+ PvrSetup.Brightness.queryctrl.id = V4L2_CID_BRIGHTNESS;
+ PvrSetup.Contrast.queryctrl.id = V4L2_CID_CONTRAST;
+ PvrSetup.Saturation.queryctrl.id = V4L2_CID_SATURATION;
+ PvrSetup.Hue.queryctrl.id = V4L2_CID_HUE;
+ // Audio
+ PvrSetup.AudioVolumeTVCommon.queryctrl.id = V4L2_CID_AUDIO_VOLUME;
+ PvrSetup.AudioVolumeTVException.queryctrl.id = V4L2_CID_AUDIO_VOLUME;
+ PvrSetup.AudioVolumeFM.queryctrl.id = V4L2_CID_AUDIO_VOLUME;
+ PvrSetup.AudioMute.queryctrl.id = V4L2_CID_AUDIO_MUTE;
+ PvrSetup.AudioBitrate.queryctrl.id = V4L2_CID_MPEG_AUDIO_L2_BITRATE;
+ PvrSetup.AudioSampling.queryctrl.id = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ;
+ PvrSetup.AudioEncoding.queryctrl.id = V4L2_CID_MPEG_AUDIO_ENCODING;
+ PvrSetup.HDPVR_AudioEncoding.queryctrl.id = V4L2_CID_MPEG_AUDIO_ENCODING;
+ // Video
+ PvrSetup.VideoBitrateTV.queryctrl.id = V4L2_CID_MPEG_VIDEO_BITRATE;
+ PvrSetup.VideoBitratePeak.queryctrl.id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK;
+ PvrSetup.AspectRatio.queryctrl.id = V4L2_CID_MPEG_VIDEO_ASPECT;
+ // MPEG
+ PvrSetup.StreamType.queryctrl.id = V4L2_CID_MPEG_STREAM_TYPE;
+ PvrSetup.BitrateMode.queryctrl.id = V4L2_CID_MPEG_VIDEO_BITRATE_MODE;
+ PvrSetup.BFrames.queryctrl.id = V4L2_CID_MPEG_VIDEO_B_FRAMES;
+ PvrSetup.GopSize.queryctrl.id = V4L2_CID_MPEG_VIDEO_GOP_SIZE;
+ PvrSetup.GopClosure.queryctrl.id = V4L2_CID_MPEG_VIDEO_GOP_CLOSURE;
+ // Video Filters
+ PvrSetup.FilterSpatialMode.queryctrl.id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE;
+ PvrSetup.FilterSpatial.queryctrl.id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER;
+ PvrSetup.FilterLumaSpatialType.queryctrl.id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE;
+ PvrSetup.FilterChromaSpatialType.queryctrl.id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE;
+ PvrSetup.FilterTemporalMode.queryctrl.id = V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE;
+ PvrSetup.FilterTemporal.queryctrl.id = V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER;
+ PvrSetup.FilterMedianType.queryctrl.id = V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE;
+ PvrSetup.FilterLumaMedianBottom.queryctrl.id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM;
+ PvrSetup.FilterLumaMedianTop.queryctrl.id = V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP;
+ PvrSetup.FilterChromaMedianBottom.queryctrl.id= V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM;
+ PvrSetup.FilterChromaMedianTop.queryctrl.id = V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP;
+ if (SupportsSlicedVBI) {
+ // VBI
+ PvrSetup.VBIformat.queryctrl.id = V4L2_CID_MPEG_STREAM_VBI_FMT;
+ }
+ /* now quering min, max, default */
+ // picture properties
+ err += QueryControl(&PvrSetup.Brightness);
+ err += QueryControl(&PvrSetup.Contrast);
+ err += QueryControl(&PvrSetup.Saturation);
+ err += QueryControl(&PvrSetup.Hue);
+ // Audio
+ err += QueryControl(&PvrSetup.AudioVolumeTVCommon);
+ err += QueryControl(&PvrSetup.AudioVolumeTVException);
+ err += QueryControl(&PvrSetup.AudioVolumeFM);
+ err += QueryControl(&PvrSetup.AudioMute);
+ err += QueryControl(&PvrSetup.AudioBitrate);
+ err += QueryControl(&PvrSetup.AudioSampling);
+ if (driver == hdpvr)
+ err += QueryControl(&PvrSetup.HDPVR_AudioEncoding);
+ else
+ err += QueryControl(&PvrSetup.AudioEncoding);
+ // Video
+ err += QueryControl(&PvrSetup.VideoBitrateTV);
+ err += QueryControl(&PvrSetup.VideoBitratePeak);
+ err += QueryControl(&PvrSetup.AspectRatio);
+ // MPEG
+ err += QueryControl(&PvrSetup.StreamType);
+ err += QueryControl(&PvrSetup.BitrateMode);
+ err += QueryControl(&PvrSetup.BFrames);
+ err += QueryControl(&PvrSetup.GopSize);
+ err += QueryControl(&PvrSetup.GopClosure);
+ // Video Filters
+ err += QueryControl(&PvrSetup.FilterSpatialMode);
+ err += QueryControl(&PvrSetup.FilterSpatial);
+ err += QueryControl(&PvrSetup.FilterLumaSpatialType);
+ err += QueryControl(&PvrSetup.FilterChromaSpatialType);
+ err += QueryControl(&PvrSetup.FilterTemporalMode);
+ err += QueryControl(&PvrSetup.FilterTemporal);
+ err += QueryControl(&PvrSetup.FilterMedianType);
+ err += QueryControl(&PvrSetup.FilterLumaMedianBottom);
+ err += QueryControl(&PvrSetup.FilterLumaMedianTop);
+ err += QueryControl(&PvrSetup.FilterChromaMedianBottom);
+ err += QueryControl(&PvrSetup.FilterChromaMedianTop);
+ if (SupportsSlicedVBI) {
+ // VBI
+ err += QueryControl(&PvrSetup.VBIformat);
+ }
+ if (err)
+ return false;
+
+ // The following code checks wether a valSet.value is
+ // INVALID_VALUE and if so -> set it to its queryctrl.default_value.
+ // The macro INIT(v) is a abbreviation for the 'if .. then' comparison.
+ #define INIT(v) if (v.value == INVALID_VALUE) v.value=v.queryctrl.default_value
+ // picture properties
+ INIT(PvrSetup.Brightness);
+ INIT(PvrSetup.Contrast);
+ INIT(PvrSetup.Saturation);
+ INIT(PvrSetup.Hue);
+ // Audio
+ if (PvrSetup.AudioVolumeTVCommon.value == INVALID_VALUE)
+ PvrSetup.AudioVolumeTVCommon.value = \
+ (int) (0.95 * PvrSetup.AudioVolumeTVCommon.queryctrl.maximum);
+ if (PvrSetup.AudioVolumeTVException.value == INVALID_VALUE)
+ PvrSetup.AudioVolumeTVException.value = \
+ (int) (0.95 * PvrSetup.AudioVolumeTVException.queryctrl.maximum);
+ if (PvrSetup.AudioVolumeFM.value == INVALID_VALUE)
+ PvrSetup.AudioVolumeFM.value = \
+ PvrSetup.AudioVolumeFM.queryctrl.maximum;
+ INIT(PvrSetup.AudioBitrate);
+ INIT(PvrSetup.AudioSampling);
+ if (driver == hdpvr)
+ INIT(PvrSetup.HDPVR_AudioEncoding);
+ // Video
+ INIT(PvrSetup.VideoBitrateTV);
+ INIT(PvrSetup.AspectRatio);
+ // MPEG
+ INIT(PvrSetup.BitrateMode);
+ INIT(PvrSetup.BFrames);
+ INIT(PvrSetup.GopSize);
+ INIT(PvrSetup.GopClosure);
+ // Video Filters
+ INIT(PvrSetup.FilterSpatialMode);
+ INIT(PvrSetup.FilterSpatial);
+ INIT(PvrSetup.FilterLumaSpatialType);
+ INIT(PvrSetup.FilterChromaSpatialType);
+ INIT(PvrSetup.FilterTemporalMode);
+ INIT(PvrSetup.FilterTemporal);
+ INIT(PvrSetup.FilterMedianType);
+ INIT(PvrSetup.FilterLumaMedianBottom);
+ INIT(PvrSetup.FilterLumaMedianTop);
+ INIT(PvrSetup.FilterChromaMedianBottom);
+ INIT(PvrSetup.FilterChromaMedianTop);
+ return true;
+}
+
diff --git a/device.h b/device.h
new file mode 100644
index 0000000..5524d62
--- /dev/null
+++ b/device.h
@@ -0,0 +1,160 @@
+#ifndef _PVR_DEVICE_H_
+#define _PVR_DEVICE_H_
+
+#include "common.h"
+
+typedef enum { /* enumeration with encoder states */
+ eStop,
+ eStart,
+} eEncState;
+
+typedef enum {
+ eTelevision,
+ eRadio,
+ eSVideo0,
+ eSVideo1,
+ eSVideo2,
+ eSVideo3,
+ eComposite0,
+ eComposite1,
+ eComposite2,
+ eComposite3,
+ eComposite4,
+ eComponent,
+ eExternalInput
+} eVideoInputs;
+
+typedef enum {
+ undef,
+ ivtv,
+ cx18,
+ pvrusb2,
+ cx88_blackbird,
+ hdpvr,
+} eV4l2Driver;
+
+typedef enum {
+ UNDEF,
+ PVR150,
+ PVR250,
+ PVR350,
+ PVR500_1,
+ PVR500_2,
+ HVR1300,
+ HVR1600,
+ HVR1900,
+ HVR1950,
+ PVRUSB2,
+ HDPVR,
+} eV4l2CardName;
+
+class cPvrReadThread;
+
+class cPvrDevice :
+public cDevice
+{
+friend class cPvrReadThread;
+private:
+ static bool Probe(int DeviceNumber);
+
+ static cString externChannelSwitchScript;
+
+public:
+ static bool Initialize(void);
+ static void Stop(void);
+ static void ReInitAll(void);
+ static int Count();
+ static cPvrDevice * Get(int index);
+
+private:
+ int number;
+ int v4l2_fd;
+ int mpeg_fd;
+ int radio_fd;
+ int v4l2_dev;
+ int mpeg_dev;
+ int radio_dev;
+ int inputs[12];
+ int numInputs;
+ int frequency;
+ int vpid;
+ int apid;
+ int tpid;
+ uint64_t CurrentNorm;
+ int CurrentLinesPerFrame;
+ int CurrentInput;
+ int newFrequency;
+ int newInput;
+ uint64_t newNorm;
+ int newLinesPerFrame;
+ int newEncoderInput;
+ cString BusID;
+ eEncState EncoderState;
+ eVideoInputs EncoderInput;
+ int driver_apiversion;
+ bool SupportsSlicedVBI;
+ bool hasDecoder;
+ bool hasTuner;
+ int streamType;
+ bool dvrOpen;
+ bool delivered;
+ bool isClosing;
+ bool readThreadRunning;
+ bool ChannelSettingsDone;
+ bool FirstChannelSwitch;
+ bool pvrusb2_ready;
+ eV4l2Driver driver;
+ eV4l2CardName cardname;
+ cRingBufferLinear * tsBuffer;
+ int tsBufferPrefill;
+ cPvrReadThread * readThread;
+ cChannel currentChannel;
+ cPvrSectionHandler sectionHandler;
+
+protected:
+ virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView);
+ virtual bool SetPid(cPidHandle *Handle, int Type, bool On);
+ virtual int OpenFilter(u_short Pid, u_char Tid, u_char Mask);
+#if VDRVERSNUM >= 10600
+ virtual void CloseFilter(int Handle);
+#endif
+ virtual bool OpenDvr(void);
+ virtual void CloseDvr(void);
+ void ResetBuffering();
+ bool IsBuffering();
+ virtual bool GetTSPacket(uchar *&Data);
+public:
+ cPvrDevice(int DeviceNumber);
+ virtual ~cPvrDevice(void);
+ virtual bool ProvidesSource(int Source) const;
+ virtual bool ProvidesTransponder(const cChannel *Channel) const;
+ virtual bool ProvidesChannel(const cChannel *Channel, int Priority = -1,
+ bool *NeedsDetachReceivers = NULL) const;
+ virtual int NumProvidedSystems(void) const;
+ bool ParseChannel(const cChannel *Channel, int *input, uint64_t *norm, int *LinesPerFrame, int *card,
+ eVideoInputs *EncoderInput, int *apid, int *vpid, int *tpid) const;
+ void ReInit(void);
+ void StopReadThread(void);
+ void GetStandard(void);
+ void TurnOffSlicedVBI(void);
+ bool Tune(int frequency);
+ bool SetInput(int input);
+ bool SetAudioInput(int input);
+ bool SetVideoNorm(uint64_t norm);
+ bool SetVideoSize(int width, int height);
+ void SetTunerAudioMode(int tuneraudiomode);
+ void SetAudioVolumeTV(void);
+ void SetEncoderState(eEncState state);
+ bool SetVBImode(int vbiLinesPerFrame, int vbistatus);
+ bool ControlIdIsValid(__u32 ctrlid);
+ // overloaded function SetControlValue
+ int SetControlValue(__u32 control, __s32 Val);
+ int SetControlValue(struct valSet * vs, __s32 Val);
+ int SetControlValue(__u32 control_class, __u32 control,
+ __s32 Val, struct v4l2_queryctrl queryctrl);
+ int QueryControl(struct valSet * vs);
+ bool QueryAllControls(void);
+ int PutData(const unsigned char * Data, int Count);
+};
+
+#endif
diff --git a/example/README.channel-conv b/example/README.channel-conv
new file mode 100644
index 0000000..3aed6f8
--- /dev/null
+++ b/example/README.channel-conv
@@ -0,0 +1,13 @@
+Converting your existing channels.conf to the new pvrinput syntax is very
+simple. (The following example assumes that your channels.conf is in /etc/vdr and
+that you have copied channel-conv.sh into that directory)
+
+First you need to stop vdr of course.
+
+cd /etc/vdr
+mv channels.conf channels.conf.old
+./channel-conv.sh channels.conf.old channels.conf
+
+If you have timers on pvrinput channels, you have to adjust
+the timers.conf before restarting vdr. The easiest way is to delete all
+entries for pvrinput channels and set new timers after restarting vdr. \ No newline at end of file
diff --git a/example/channel-conv.sh b/example/channel-conv.sh
new file mode 100755
index 0000000..1d0772f
--- /dev/null
+++ b/example/channel-conv.sh
@@ -0,0 +1,81 @@
+#!/bin/bash
+# new syntax needs vdr with iptv patch!
+# have phun, --wirbel 20090526
+
+if [ -z "$2" ] # expecting two args
+then
+ echo "Usage: `basename $0` channels.conf.old channels.conf"
+ echo " "
+ echo "converts existing pvrinput channels.conf to new channels.conf syntax."
+ echo " * first arg is path to old channels.conf"
+ echo " * second arg is path to new channels.conf"
+ echo " "
+ echo "-- MISSING ARGUMENTS. EXITING NOW. --"
+ exit -1
+else
+ OLDFILE=$1
+ NEWFILE=$2
+fi
+
+
+NUM=0
+nsid=0
+need_ext_inputs=0
+
+while IFS=: read name freq param source srate vpid apid tpid caid sid nid tid rid
+do
+ if [ -z "$name" ]; then
+ echo ":"$freq"" >> $NEWFILE
+ continue
+ fi
+
+ if [[ "$caid" == "A1" ]]; then
+
+ if (( freq < 10000 )); then
+ # ext input; *impossible* to convert. skip them now and add new(!) entries at the end of conf.
+ need_ext_inputs=1
+ continue
+ fi
+
+ let "nsid=(500 + freq*16)/1000"
+ echo -n "$name:$freq:PVRINPUT|" >> $NEWFILE
+ if (( freq < 87500 )) || (( freq > 108000 )); then
+ echo -n "TV" >> $NEWFILE
+ norm="PAL"
+ vtest=$(echo $param | grep "I0")
+ if [[ ! -z "$vtest" ]]; then
+ norm="NTSC"
+ fi
+ vtest=$(echo $param | grep "I1")
+ if [[ ! -z "$vtest" ]]; then
+ norm="SECAM"
+ fi
+ echo -n "|$norm:P:0:301:300:305:0:" >> $NEWFILE
+ else
+ echo -n "RADIO:P:0:0:300:0:0:" >> $NEWFILE
+ fi
+ echo "$nsid:$nid:$tid:$rid" >> $NEWFILE
+
+ else
+ # non-pvrinput channel; copy n paste it
+ echo "$name:$freq:$param:$source:$srate:$vpid:$apid:$tpid:$caid:$sid:$nid:$tid:$rid" >> $NEWFILE
+ fi
+
+ NUM=$NUM+1
+done < $OLDFILE # I/O redirection.
+
+
+# create ext inputs if needed; no scanning - just a dumb adding all of them.
+if (( $need_ext_inputs == 1 )); then
+ ext_sid=9000
+ echo -n ":ext analog inputs" >> $NEWFILE && echo "" >> $NEWFILE
+ for (( i=0; i<=4; i++ )); do
+ echo "Composite $i;pvrinput:1:PVRINPUT|COMPOSITE$i:P:0:301:300:0:0:$ext_sid:0:0:0" >> $NEWFILE
+ let "ext_sid=ext_sid+1"
+ done
+ for (( i=0; i<=3; i++ )); do
+ echo "S-Video $i;pvrinput:1:PVRINPUT|SVIDEO$i:P:0:301:300:0:0:$ext_sid:0:0:0" >> $NEWFILE
+ let "ext_sid=ext_sid+1"
+ done
+fi
+
diff --git a/example/channels.conf_newsyntax.example b/example/channels.conf_newsyntax.example
new file mode 100644
index 0000000..f87f71c
--- /dev/null
+++ b/example/channels.conf_newsyntax.example
@@ -0,0 +1,77 @@
+SE2:112250:PVRINPUT|TV:P:0:301:300:305:0:1796:0:0:0
+SE3:119250:PVRINPUT|TV:P:0:301:300:305:0:1908:0:0:0
+SE4:126250:PVRINPUT|TV:P:0:301:300:305:0:2020:0:0:0
+SE5:133250:PVRINPUT|TV:P:0:301:300:305:0:2132:0:0:0
+SE6:140250:PVRINPUT|TV:P:0:301:300:305:0:2244:0:0:0
+SE7:147250:PVRINPUT|TV:P:0:301:300:305:0:2356:0:0:0
+SE8:154250:PVRINPUT|TV:P:0:301:300:305:0:2468:0:0:0
+SE9:161250:PVRINPUT|TV:P:0:301:300:305:0:2580:0:0:0
+SE10:168250:PVRINPUT|TV:P:0:301:300:305:0:2692:0:0:0
+k05:175250:PVRINPUT|TV:P:0:301:300:305:0:2804:0:0:0
+k06:182250:PVRINPUT|TV:P:0:301:300:305:0:2916:0:0:0
+k07:189250:PVRINPUT|TV:P:0:301:300:305:0:3028:0:0:0
+k08:196250:PVRINPUT|TV:P:0:301:300:305:0:3140:0:0:0
+k09:203250:PVRINPUT|TV:P:0:301:300:305:0:3252:0:0:0
+k10:210250:PVRINPUT|TV:P:0:301:300:305:0:3364:0:0:0
+k11:217250:PVRINPUT|TV:P:0:301:300:305:0:3476:0:0:0
+k12:224250:PVRINPUT|TV:P:0:301:300:305:0:3588:0:0:0
+SE11:231250:PVRINPUT|TV:P:0:301:300:305:0:3700:0:0:0
+SE12:238250:PVRINPUT|TV:P:0:301:300:305:0:3812:0:0:0
+SE13:245250:PVRINPUT|TV:P:0:301:300:305:0:3924:0:0:0
+SE14:252250:PVRINPUT|TV:P:0:301:300:305:0:4036:0:0:0
+SE15:259250:PVRINPUT|TV:P:0:301:300:305:0:4148:0:0:0
+SE16:266250:PVRINPUT|TV:P:0:301:300:305:0:4260:0:0:0
+SE17:273250:PVRINPUT|TV:P:0:301:300:305:0:4372:0:0:0
+SE18:280250:PVRINPUT|TV:P:0:301:300:305:0:4484:0:0:0
+SE19:287250:PVRINPUT|TV:P:0:301:300:305:0:4596:0:0:0
+SE20:294250:PVRINPUT|TV:P:0:301:300:305:0:4708:0:0:0
+S21:303250:PVRINPUT|TV:P:0:301:300:305:0:4852:0:0:0
+S22:311250:PVRINPUT|TV:P:0:301:300:305:0:4980:0:0:0
+S23:319250:PVRINPUT|TV:P:0:301:300:305:0:5108:0:0:0
+S24:327250:PVRINPUT|TV:P:0:301:300:305:0:5236:0:0:0
+S25:335250:PVRINPUT|TV:P:0:301:300:305:0:5364:0:0:0
+S26:343250:PVRINPUT|TV:P:0:301:300:305:0:5492:0:0:0
+S27:351250:PVRINPUT|TV:P:0:301:300:305:0:5620:0:0:0
+S28:359250:PVRINPUT|TV:P:0:301:300:305:0:5748:0:0:0
+S29:367250:PVRINPUT|TV:P:0:301:300:305:0:5876:0:0:0
+S30:375250:PVRINPUT|TV:P:0:301:300:305:0:6004:0:0:0
+S35:415250:PVRINPUT|TV:P:0:301:300:305:0:6644:0:0:0
+k21:471250:PVRINPUT|TV:P:0:301:300:305:0:7540:0:0:0
+k22:479250:PVRINPUT|TV:P:0:301:300:305:0:7668:0:0:0
+k23:487250:PVRINPUT|TV:P:0:301:300:305:0:7796:0:0:0
+k24:495250:PVRINPUT|TV:P:0:301:300:305:0:7924:0:0:0
+k25:503250:PVRINPUT|TV:P:0:301:300:305:0:8052:0:0:0
+k26:511250:PVRINPUT|TV:P:0:301:300:305:0:8180:0:0:0
+k27:519250:PVRINPUT|TV:P:0:301:300:305:0:8308:0:0:0
+k28:527250:PVRINPUT|TV:P:0:301:300:305:0:8436:0:0:0
+k29:535250:PVRINPUT|TV:P:0:301:300:305:0:8564:0:0:0
+k30:543250:PVRINPUT|TV:P:0:301:300:305:0:8692:0:0:0
+k31:551250:PVRINPUT|TV:P:0:301:300:305:0:8820:0:0:0
+k32:559250:PVRINPUT|TV:P:0:301:300:305:0:8948:0:0:0
+k33:567250:PVRINPUT|TV:P:0:301:300:305:0:9076:0:0:0
+k34:575250:PVRINPUT|TV:P:0:301:300:305:0:9204:0:0:0
+k35:583250:PVRINPUT|TV:P:0:301:300:305:0:9332:0:0:0
+k36:591250:PVRINPUT|TV:P:0:301:300:305:0:9460:0:0:0
+k37:599250:PVRINPUT|TV:P:0:301:300:305:0:9588:0:0:0
+k38:607250:PVRINPUT|TV:P:0:301:300:305:0:9716:0:0:0
+k39:615250:PVRINPUT|TV:P:0:301:300:305:0:9844:0:0:0
+k40:623250:PVRINPUT|TV:P:0:301:300:305:0:9972:0:0:0
+k41:631250:PVRINPUT|TV:P:0:301:300:305:0:10100:0:0:0
+k42:639250:PVRINPUT|TV:P:0:301:300:305:0:10228:0:0:0
+k43:647250:PVRINPUT|TV:P:0:301:300:305:0:10356:0:0:0
+k44:655250:PVRINPUT|TV:P:0:301:300:305:0:10484:0:0:0
+k45:663250:PVRINPUT|TV:P:0:301:300:305:0:10612:0:0:0
+:external inputs
+S-Video0 Card0:1:PVRINPUT|SVIDEO0|CARD0:P:0:301:300:305:0:9001:0:0:0
+S-Video0 Card1:1:PVRINPUT|SVIDEO0|CARD1:P:0:301:300:305:0:9002:0:0:0
+S-Video1 Card0:1:PVRINPUT|SVIDEO1|CARD0:P:0:301:300:305:0:9004:0:0:0
+S-Video1 Card1:1:PVRINPUT|SVIDEO1|CARD1:P:0:301:300:305:0:9005:0:0:0
+S-Video1 Card2:1:PVRINPUT|SVIDEO1|CARD2:P:0:301:300:305:0:9006:0:0:0
+Composite0 Card0:1:PVRINPUT|COMPOSITE0|CARD0:P:0:301:300:305:0:9007:0:0:0
+Composite0 Card1:1:PVRINPUT|COMPOSITE0|CARD1:P:0:301:300:305:0:9008:0:0:0
+Composite1 Card0:1:PVRINPUT|COMPOSITE1|CARD0:P:0:301:300:305:0:9009:0:0:0
+Composite1 Card1:1:PVRINPUT|COMPOSITE1|CARD1:P:0:301:300:305:0:9010:0:0:0
+:HD PVR
+HD PVR:1:PVRINPUT|COMPONENT:P:0:4113+4097=27:0;4352:0:0:9011:1:0:0
+:radio
+FM 107.6 MHz:107600:PVRINPUT|RADIO:P:0:0:300:305:0:1721:0:0:0
diff --git a/example/externchannelswitch.sh.example b/example/externchannelswitch.sh.example
new file mode 100755
index 0000000..76a57c7
--- /dev/null
+++ b/example/externchannelswitch.sh.example
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+
+# set to true to enable debugging output
+DEBUG="true"
+
+
+declare SID="$1"
+declare VDRCHANNEL="$2"
+declare VIDEONUMBER="$3"
+declare EXTERNCHANNEL
+let "EXTERNCHANNEL = SID % 1000" #last three digits from SID without leading 0
+
+#exec dct6200 "$EXTERNCHANNEL"
+
+if test "$DEBUG" == "true"; then
+ logger -s "DEBUG pvrinput externchannelswitch: Variable SID has value \"$SID\""
+ logger -s "DEBUG pvrinput externchannelswitch: Variable VDRCHANNEL has value \"$VDRCHANNEL\""
+ logger -s "DEBUG pvrinput externchannelswitch: Variable VIDEONUMBER has value \"$VIDEONUMBER\""
+ logger -s "DEBUG pvrinput externchannelswitch: Variable EXTERNCHANNEL has value \"$EXTERNCHANNEL\""
+fi
diff --git a/filter.c b/filter.c
new file mode 100644
index 0000000..880edca
--- /dev/null
+++ b/filter.c
@@ -0,0 +1,105 @@
+#include "common.h"
+
+//#include <unistd.h>
+//#include <fcntl.h>
+//#include <sys/types.h>
+//#include <sys/socket.h>
+
+
+cPvrSectionFilter::cPvrSectionFilter(u_short Pid, u_char Tid, u_char Mask)
+{
+ filterData.pid = Pid;
+ filterData.tid = Tid;
+ filterData.mask = Mask;
+
+ handle[0] = handle[1] = -1;
+ if (socketpair(AF_UNIX, SOCK_DGRAM, 0, handle) != 0) {
+ log(pvrERROR, "cPvrSectionFilter(): can't open socketpair");
+ Close();
+ }
+ else if ((fcntl(handle[0], F_SETFL, O_NONBLOCK) != 0) || (fcntl(handle[1], F_SETFL, O_NONBLOCK) != 0)) {
+ log(pvrERROR, "cPvrSectionFilter(): can't switch socketpair to unblocked mode");
+ Close();
+ }
+}
+
+cPvrSectionFilter::~cPvrSectionFilter(void)
+{
+ Close();
+}
+
+void cPvrSectionFilter::Close(void)
+{
+ int tmp = handle[1];
+ handle[1] = -1;
+ if (tmp >= 0)
+ close(tmp);
+ tmp = handle[0];
+ handle[0] = -1;
+ if (tmp >= 0)
+ close(tmp);
+}
+
+int cPvrSectionFilter::GetHandle() const
+{
+ return handle[0];
+}
+
+cPvrSectionHandler::cPvrSectionHandler()
+{
+}
+
+cPvrSectionHandler::~cPvrSectionHandler()
+{
+ filters.Clear();
+}
+
+int cPvrSectionHandler::AddFilter(u_short Pid, u_char Tid, u_char Mask)
+{
+ cPvrSectionFilter *filter = new cPvrSectionFilter(Pid, Tid, Mask);
+ int handle = filter->GetHandle();
+ if (handle < 0)
+ delete filter;
+ else
+ filters.Add(filter);
+ return handle;
+}
+
+void cPvrSectionHandler::RemoveFilter(int Handle)
+{
+ cPvrSectionFilter *filter = filters.First();
+ while (filter) {
+ if (filter->GetHandle() == Handle) {
+ filters.Del(filter, true);
+ break;
+ }
+ filter = filters.Next(filter);
+ }
+}
+
+void cPvrSectionHandler::ProcessTSPacket(const u_char *Data)
+{
+ if ((filters.Count() == 0) || (Data == 0))
+ return;
+ uint8_t section_len = ((Data[7] & 0x0F) << 8) + Data[7];
+ if (section_len == 0)
+ return;
+ if ((Data[1] & 0x40) == 0)
+ return;
+ u_short pid = ((Data[1] & 0x1F) << 8) + Data[2];
+ u_char tid = Data[5];
+ size_t written = 0;
+ uint8_t section_start = Data[4] + 5;
+ section_len += 3;
+ cPvrSectionFilter *filter = filters.First();
+ while (filter) {
+ if (filter->filterData.Matches(pid, tid)) {
+ //log(pvrDEBUG2, "cPvrSectionHandler::ProcessTSPacket(): pid = %d, tid = %d, len = %d, start = %d",
+ // pid, tid, section_len, section_start);
+ written = write(filter->handle[1], Data + section_start, section_len);
+ if (written != section_len)
+ log(pvrERROR, "cPvrSectionHandler::ProcessTSPacket(): written only %d instead of %d", written, section_len);
+ }
+ filter = filters.Next(filter);
+ }
+}
diff --git a/filter.h b/filter.h
new file mode 100644
index 0000000..2a6b08b
--- /dev/null
+++ b/filter.h
@@ -0,0 +1,34 @@
+#ifndef _PVR_FILTER_H_
+#define _PVR_FILTER_H_
+
+#include <vdr/filter.h>
+
+
+class cPvrSectionFilter : public cListObject {
+ friend class cPvrSectionHandler;
+private:
+ cFilterData filterData;
+ int handle[2]; // first handle will be returned by OpenFilter
+
+public:
+ cPvrSectionFilter(u_short Pid, u_char Tid, u_char Mask);
+ ~cPvrSectionFilter(void);
+
+ void Close(void);
+ int GetHandle() const;
+};
+
+class cPvrSectionHandler {
+private:
+ cList<cPvrSectionFilter> filters;
+
+public:
+ cPvrSectionHandler();
+ ~cPvrSectionHandler();
+
+ int AddFilter(u_short Pid, u_char Tid, u_char Mask);
+ void RemoveFilter(int Handle);
+ void ProcessTSPacket(const u_char *Data);
+};
+
+#endif
diff --git a/global.h b/global.h
new file mode 100644
index 0000000..e5361ba
--- /dev/null
+++ b/global.h
@@ -0,0 +1,11 @@
+#ifndef _PVRINPUT_GLOBAL_H_
+#define _PVRINPUT_GLOBAL_H_
+
+
+
+static const int kMaxPvrDevices = 8;
+
+#define INVALID_VALUE -1000
+
+#endif
+
diff --git a/menu.c b/menu.c
new file mode 100644
index 0000000..4af4b6e
--- /dev/null
+++ b/menu.c
@@ -0,0 +1,714 @@
+/**
+ * pvrinput plugin for the Video Disk Recorder
+ *
+ * menu.c - setup menu class
+ *
+ * (c) 2005 Andreas Regel <andreas.regel AT powarman.de>
+ **/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; *
+ * if not, write to the Free Software Foundation, Inc., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
+ * *
+ ***************************************************************************/
+
+/*uncomment the following line to allow setting of PvrSetup.UseOnlyCard
+and StreamType.value via OSD menu (see README) */
+#define PVR_DEBUG
+
+#include "common.h"
+
+static const char * audioBitrateValues[] = {
+ "32",
+ "48",
+ "56",
+ "64",
+ "80",
+ "96",
+ "112",
+ "128",
+ "160",
+ "192",
+ "224",
+ "256",
+ "320",
+ "384"
+};
+
+static const char * bitrateModes[] = {
+ "VBR",
+ "CBR"
+};
+
+/* order must match the 'audmode' values in videodev2.h */
+static const char * tunerAudioModes[] = {
+ "mono",
+ "stereo",
+ "lang2",
+ "lang1",
+ "bilingual"
+};
+#ifdef PVR_DEBUG
+static const char * useOnlyCard[] = {
+ "/dev/video0",
+ "/dev/video1",
+ "/dev/video2",
+ "/dev/video3",
+ "/dev/video4",
+ "/dev/video5",
+ "/dev/video6",
+ "/dev/video7",
+ "all", // 8
+ "PVR150", // 9
+ "PVR250", //10
+ "PVR350", //11
+ "PVR500#1", //12
+ "PVR500#2", //13
+ "HVR1300", //14
+ "HVR1600", //15
+ "HVR1900", //16
+ "HVR1950", //17
+ "PVRUSB2", //18
+ "HDPVR" //19
+ };
+#endif
+static const char * aspectRatios[] = {
+ "1:1",
+ "4:3",
+ "16:9",
+ "2.21:1"
+};
+#ifdef PVR_DEBUG
+static const char * streamType[] = {
+ "MPEG2 PS",
+ "MPEG2 DVD"
+};
+#endif
+static const char * exceptionVolumeForCard[] = {
+ "/dev/video0",
+ "/dev/video1",
+ "/dev/video2",
+ "/dev/video3",
+ "/dev/video4",
+ "/dev/video5",
+ "/dev/video6",
+ "/dev/video7",
+ "-", // 8
+ "PVR150", // 9
+ "PVR250", //10
+ "PVR350", //11
+ "PVR500#1", //12
+ "PVR500#2", //13
+ "HVR1300", //14
+ "HVR1600", //15
+ "HVR1900", //16
+ "HVR1950", //17
+ "PVRUSB2" //18
+ };
+
+cPvrMenuSetup::cPvrMenuSetup() {
+
+ static const char * FilterModes[2];
+ FilterModes[0]=tr("Setup.pvrinput$manual");
+ FilterModes[1]=tr("Setup.pvrinput$auto");
+
+ static const char * SpatialTypes[5];
+ SpatialTypes[0]=tr("Setup.pvrinput$off");
+ SpatialTypes[1]=tr("Setup.pvrinput$1D horizontal");
+ SpatialTypes[2]=tr("Setup.pvrinput$1D vertical");
+ SpatialTypes[3]=tr("Setup.pvrinput$2D hv separable");
+ SpatialTypes[4]=tr("Setup.pvrinput$2D sym non separable");
+
+ static const char * MedianTypes[5];
+ MedianTypes[0]=tr("Setup.pvrinput$off");
+ MedianTypes[1]=tr("Setup.pvrinput$horizontal");
+ MedianTypes[2]=tr("Setup.pvrinput$vertical");
+ MedianTypes[3]=tr("Setup.pvrinput$horizontal + vertical");
+ MedianTypes[4]=tr("Setup.pvrinput$diagonal");
+
+ static const char * SamplingFreqs[3];
+ SamplingFreqs[0]=tr("Setup.pvrinput$44.1 kHz");
+ SamplingFreqs[1]=tr("Setup.pvrinput$48 kHz");
+ SamplingFreqs[2]=tr("Setup.pvrinput$32 kHz");
+
+ static const char * HDPVR_AudioEncodings[2];
+ HDPVR_AudioEncodings[0]=tr("Setup.pvrinput$AAC");
+ HDPVR_AudioEncodings[1]=tr("Setup.pvrinput$AC3");
+
+ static const char * HDPVR_AudioInputs[3];
+ HDPVR_AudioInputs[0]=tr("Setup.pvrinput$RCA back");
+ HDPVR_AudioInputs[1]=tr("Setup.pvrinput$RCA front");
+ HDPVR_AudioInputs[2]=tr("Setup.pvrinput$SPDIF");
+
+ newPvrSetup = PvrSetup;
+ // videobitrate in setup.conf is 0..27000, but ivtv 0..27000000
+ newPvrSetup.VideoBitrateTV.value =
+ (int) (PvrSetup.VideoBitrateTV.value/1000);
+ newPvrSetup.VideoBitrateTV.queryctrl.minimum =
+ (int) (PvrSetup.VideoBitrateTV.queryctrl.minimum/1000);
+ newPvrSetup.VideoBitrateTV.queryctrl.maximum =
+ (int) (PvrSetup.VideoBitrateTV.queryctrl.maximum/1000);
+
+ newPvrSetup.Brightness.value=IntVal2Percent(PvrSetup.Brightness.value,
+ PvrSetup.Brightness.queryctrl.minimum,
+ PvrSetup.Brightness.queryctrl.maximum);
+
+ newPvrSetup.Contrast.value=IntVal2Percent(PvrSetup.Contrast.value,
+ PvrSetup.Contrast.queryctrl.minimum,
+ PvrSetup.Contrast.queryctrl.maximum);
+
+ newPvrSetup.Saturation.value=IntVal2Percent(PvrSetup.Saturation.value,
+ PvrSetup.Saturation.queryctrl.minimum,
+ PvrSetup.Saturation.queryctrl.maximum);
+
+ newPvrSetup.Hue.value=IntVal2Percent(PvrSetup.Hue.value,
+ PvrSetup.Hue.queryctrl.minimum,
+ PvrSetup.Hue.queryctrl.maximum);
+
+ newPvrSetup.AudioVolumeTVCommon.value=IntVal2Percent(PvrSetup.AudioVolumeTVCommon.value,
+ PvrSetup.AudioVolumeTVCommon.queryctrl.minimum,
+ PvrSetup.AudioVolumeTVCommon.queryctrl.maximum);
+
+ newPvrSetup.AudioVolumeTVException.value=IntVal2Percent(PvrSetup.AudioVolumeTVException.value,
+ PvrSetup.AudioVolumeTVException.queryctrl.minimum,
+ PvrSetup.AudioVolumeTVException.queryctrl.maximum);
+
+ newPvrSetup.AudioVolumeFM.value=IntVal2Percent(PvrSetup.AudioVolumeFM.value,
+ PvrSetup.AudioVolumeFM.queryctrl.minimum,
+ PvrSetup.AudioVolumeFM.queryctrl.maximum);
+
+ Add(new cMenuEditBoolItem(tr("Setup.pvrinput$Hide main menu entry"),
+ &newPvrSetup.HideMainMenuEntry));
+#ifdef PVR_DEBUG
+ Add(new cMenuEditStraItem(tr("Setup.pvrinput$Use only card"),
+ &newPvrSetup.UseOnlyCard, 20, useOnlyCard));
+#endif
+ Add(new cMenuEditIntItem(tr("Setup.pvrinput$Log level"),
+ &newPvrSetup.LogLevel, 0, 4));
+
+ Add(new cMenuEditBoolItem(tr("Setup.pvrinput$Slice VBI Teletext"),
+ &newPvrSetup.SliceVBI));
+
+ Add(new cMenuEditStraItem(tr("Setup.pvrinput$Tuner Audio Mode"),
+ &newPvrSetup.TunerAudioMode, 5, tunerAudioModes));
+
+ Add(new cMenuEditIntItem(tr("Setup.pvrinput$Brightness"),
+ &newPvrSetup.Brightness.value, 0, 100));
+
+ Add(new cMenuEditIntItem(tr("Setup.pvrinput$Contrast"),
+ &newPvrSetup.Contrast.value, 0, 100));
+
+ Add(new cMenuEditIntItem(tr("Setup.pvrinput$Saturation"),
+ &newPvrSetup.Saturation.value, 0, 100));
+
+ Add(new cMenuEditIntItem(tr("Setup.pvrinput$Hue"),
+ &newPvrSetup.Hue.value, 0, 100));
+
+ Add(new cMenuEditIntItem(tr("Setup.pvrinput$Common Audio volume (TV)"),
+ &newPvrSetup.AudioVolumeTVCommon.value, 0, 100));
+
+ Add(new cMenuEditIntItem(tr("Setup.pvrinput$Exception Audio volume (TV)"),
+ &newPvrSetup.AudioVolumeTVException.value, 0, 100));
+
+ Add(new cMenuEditStraItem(tr("Setup.pvrinput$Exception TV Volume for Card"),
+ &newPvrSetup.AudioVolumeTVExceptionCard, 19, exceptionVolumeForCard));
+
+ Add(new cMenuEditIntItem(tr("Setup.pvrinput$Audio radio volume"),
+ &newPvrSetup.AudioVolumeFM.value, 0, 100));
+
+ Add(new cMenuEditStraItem(tr("Setup.pvrinput$Audio bitrate (kbit/s)"),
+ &newPvrSetup.AudioBitrate.value,
+ newPvrSetup.AudioBitrate.queryctrl.maximum + 1, audioBitrateValues));
+
+ Add(new cMenuEditStraItem(tr("Setup.pvrinput$Audio sampling rate"),
+ &newPvrSetup.AudioSampling.value,
+ newPvrSetup.AudioSampling.queryctrl.maximum + 1, SamplingFreqs));
+
+ Add(new cMenuEditStraItem(tr("Setup.pvrinput$HDPVR audio encoding"),
+ &newPvrSetup.HDPVR_AudioEncoding.value, 2, HDPVR_AudioEncodings));
+
+ Add(new cMenuEditStraItem(tr("Setup.pvrinput$HDPVR audio input"),
+ &newPvrSetup.HDPVR_AudioInput, 3, HDPVR_AudioInputs));
+
+ Add(new cMenuEditIntItem(tr("Setup.pvrinput$Video bitrate TV (kbit/s)"),
+ &newPvrSetup.VideoBitrateTV.value,
+ newPvrSetup.VideoBitrateTV.queryctrl.minimum,
+ newPvrSetup.VideoBitrateTV.queryctrl.maximum));
+
+ newPvrSetup.StreamType.value=(newPvrSetup.StreamType.value==0?0:1);
+
+ Add(new cMenuEditStraItem(tr("Setup.pvrinput$Bitrate mode"),
+ &newPvrSetup.BitrateMode.value,
+ newPvrSetup.BitrateMode.queryctrl.maximum + 1, bitrateModes));
+
+ Add(new cMenuEditStraItem(tr("Setup.pvrinput$Aspect ratio"),
+ &newPvrSetup.AspectRatio.value,
+ newPvrSetup.AspectRatio.queryctrl.maximum + 1, aspectRatios));
+#ifdef PVR_DEBUG
+ Add(new cMenuEditStraItem(tr("Setup.pvrinput$Stream type"),
+ &newPvrSetup.StreamType.value, 2, streamType));
+#endif
+ Add(new cMenuEditStraItem(tr("Setup.pvrinput$Mode Spatial Video Filter"),
+ &newPvrSetup.FilterSpatialMode.value,
+ newPvrSetup.FilterSpatialMode.queryctrl.maximum + 1, FilterModes));
+
+ Add(new cMenuEditIntItem(tr("Setup.pvrinput$Strength Spatial Video Filter"),
+ &newPvrSetup.FilterSpatial.value,
+ newPvrSetup.FilterSpatial.queryctrl.minimum,
+ newPvrSetup.FilterSpatial.queryctrl.maximum));
+
+ Add(new cMenuEditStraItem(tr("Setup.pvrinput$Luma Spatial Filter Type"),
+ &newPvrSetup.FilterLumaSpatialType.value,
+ newPvrSetup.FilterLumaSpatialType.queryctrl.maximum + 1, SpatialTypes));
+
+ Add(new cMenuEditStraItem(tr("Setup.pvrinput$Chroma Spatial Filter Type"),
+ &newPvrSetup.FilterChromaSpatialType.value,
+ newPvrSetup.FilterChromaSpatialType.queryctrl.maximum + 1, SpatialTypes));
+
+ Add(new cMenuEditStraItem(tr("Setup.pvrinput$Mode Temporal Video Filter"),
+ &newPvrSetup.FilterTemporalMode.value,
+ newPvrSetup.FilterTemporalMode.queryctrl.maximum + 1, FilterModes));
+
+ Add(new cMenuEditIntItem(tr("Setup.pvrinput$Strength Temporal Video Filter"),
+ &newPvrSetup.FilterTemporal.value,
+ newPvrSetup.FilterTemporal.queryctrl.minimum,
+ newPvrSetup.FilterTemporal.queryctrl.maximum));
+
+ Add(new cMenuEditStraItem(tr("Setup.pvrinput$Median Filter Type"),
+ &newPvrSetup.FilterMedianType.value,
+ newPvrSetup.FilterMedianType.queryctrl.maximum + 1, MedianTypes));
+
+ Add(new cMenuEditIntItem(tr("Setup.pvrinput$Luma Median Filter Bottom"),
+ &newPvrSetup.FilterLumaMedianBottom.value,
+ newPvrSetup.FilterLumaMedianBottom.queryctrl.minimum,
+ newPvrSetup.FilterLumaMedianBottom.queryctrl.maximum));
+
+ Add(new cMenuEditIntItem(tr("Setup.pvrinput$Luma Median Filter Top"),
+ &newPvrSetup.FilterLumaMedianTop.value,
+ newPvrSetup.FilterLumaMedianTop.queryctrl.minimum,
+ newPvrSetup.FilterLumaMedianTop.queryctrl.maximum));
+
+ Add(new cMenuEditIntItem(tr("Setup.pvrinput$Chroma Median Filter Bottom"),
+ &newPvrSetup.FilterChromaMedianBottom.value,
+ newPvrSetup.FilterChromaMedianBottom.queryctrl.minimum,
+ newPvrSetup.FilterChromaMedianBottom.queryctrl.maximum));
+
+ Add(new cMenuEditIntItem(tr("Setup.pvrinput$Chroma Median Filter Top"),
+ &newPvrSetup.FilterChromaMedianTop.value,
+ newPvrSetup.FilterChromaMedianTop.queryctrl.minimum,
+ newPvrSetup.FilterChromaMedianTop.queryctrl.maximum));
+
+ Add(new cMenuEditBoolItem(tr("Setup.pvrinput$use externchannelswitch.sh"),
+ &newPvrSetup.UseExternChannelSwitchScript));
+}
+
+void cPvrMenuSetup::Store() {
+ SetupStore("HideMainMenuEntry",
+ PvrSetup.HideMainMenuEntry = newPvrSetup.HideMainMenuEntry);
+
+ SetupStore("UseOnlyCard",
+ PvrSetup.UseOnlyCard = newPvrSetup.UseOnlyCard);
+
+ SetupStore("LogLevel",
+ PvrSetup.LogLevel = newPvrSetup.LogLevel);
+
+ SetupStore("TunerAudioMode",
+ PvrSetup.TunerAudioMode = newPvrSetup.TunerAudioMode);
+
+ SetupStore("StreamType",
+ PvrSetup.StreamType.value = newPvrSetup.StreamType.value);
+
+ SetupStore("AudioVolumeTVExceptionCard",
+ PvrSetup.AudioVolumeTVExceptionCard = newPvrSetup.AudioVolumeTVExceptionCard);
+
+ SetupStore("HDPVR_AudioInput",
+ PvrSetup.HDPVR_AudioInput = newPvrSetup.HDPVR_AudioInput);
+
+ SetupStore("SliceVBI",
+ PvrSetup.SliceVBI = newPvrSetup.SliceVBI);
+
+ SetupStore("UseExternChannelSwitchScript",
+ PvrSetup.UseExternChannelSwitchScript = newPvrSetup.UseExternChannelSwitchScript);
+
+ /* The following code makes sure that we don't write a zero value
+ into setup.conf, which would happen if it is still INVALID_VALUE
+ because no device is present.
+ The macro SETUPSTORE(n,v) is a abbreviation for the 'if .. then' comparison. */
+ #define SETUPSTORE(n, v) if (v.query_isvalid) SetupStore(n, v.value)
+
+ PvrSetup.Brightness.value = Percent2IntVal(newPvrSetup.Brightness.value,
+ PvrSetup.Brightness.queryctrl.minimum,
+ PvrSetup.Brightness.queryctrl.maximum);
+ SETUPSTORE("Brightness", PvrSetup.Brightness);
+
+ PvrSetup.Contrast.value = Percent2IntVal(newPvrSetup.Contrast.value,
+ PvrSetup.Contrast.queryctrl.minimum,
+ PvrSetup.Contrast.queryctrl.maximum);
+ SETUPSTORE("Contrast", PvrSetup.Contrast);
+
+ PvrSetup.Saturation.value = Percent2IntVal(newPvrSetup.Saturation.value,
+ PvrSetup.Saturation.queryctrl.minimum,
+ PvrSetup.Saturation.queryctrl.maximum);
+ SETUPSTORE("Saturation", PvrSetup.Saturation);
+
+ PvrSetup.Hue.value = Percent2IntVal(newPvrSetup.Hue.value,
+ PvrSetup.Hue.queryctrl.minimum,
+ PvrSetup.Hue.queryctrl.maximum);
+ SETUPSTORE("Hue", PvrSetup.Hue);
+
+ PvrSetup.AudioVolumeTVCommon.value = Percent2IntVal(newPvrSetup.AudioVolumeTVCommon.value,
+ PvrSetup.AudioVolumeTVCommon.queryctrl.minimum,
+ PvrSetup.AudioVolumeTVCommon.queryctrl.maximum);
+ SETUPSTORE("AudioVolumeTVCommon", PvrSetup.AudioVolumeTVCommon);
+
+ PvrSetup.AudioVolumeTVException.value = Percent2IntVal(newPvrSetup.AudioVolumeTVException.value,
+ PvrSetup.AudioVolumeTVException.queryctrl.minimum,
+ PvrSetup.AudioVolumeTVException.queryctrl.maximum);
+ SETUPSTORE("AudioVolumeTVException", PvrSetup.AudioVolumeTVException);
+
+ PvrSetup.AudioVolumeFM.value = Percent2IntVal(newPvrSetup.AudioVolumeFM.value,
+ PvrSetup.AudioVolumeFM.queryctrl.minimum,
+ PvrSetup.AudioVolumeFM.queryctrl.maximum);
+ SETUPSTORE("AudioVolumeFM", PvrSetup.AudioVolumeFM);
+
+ // videobitrate in setup.conf is 0..27000, but ivtv 0..27000000
+ PvrSetup.VideoBitrateTV.value = newPvrSetup.VideoBitrateTV.value * 1000;
+ SETUPSTORE("VideoBitrateTV", newPvrSetup.VideoBitrateTV);
+
+ PvrSetup.AudioBitrate.value = newPvrSetup.AudioBitrate.value;
+ SETUPSTORE("AudioBitrate", PvrSetup.AudioBitrate);
+
+ PvrSetup.AudioSampling.value = newPvrSetup.AudioSampling.value;
+ SETUPSTORE("AudioSampling", PvrSetup.AudioSampling);
+
+ // HDPVR audio encoding in setup.conf is 0..1, but driver needs 3..4
+ // if audio input SPDIF is selected, audio encoding must be AAC
+ if (newPvrSetup.HDPVR_AudioInput == 2)
+ newPvrSetup.HDPVR_AudioEncoding.value = 0;
+ PvrSetup.HDPVR_AudioEncoding.value = newPvrSetup.HDPVR_AudioEncoding.value + 3;
+ SETUPSTORE("HDPVR_AudioEncoding", newPvrSetup.HDPVR_AudioEncoding);
+
+ PvrSetup.BitrateMode.value = newPvrSetup.BitrateMode.value;
+ SETUPSTORE("BitrateMode", PvrSetup.BitrateMode);
+
+ PvrSetup.AspectRatio.value = newPvrSetup.AspectRatio.value;
+ SETUPSTORE("AspectRatio", PvrSetup.AspectRatio);
+
+ PvrSetup.FilterSpatialMode.value = newPvrSetup.FilterSpatialMode.value;
+ SETUPSTORE("FilterSpatialMode", PvrSetup.FilterSpatialMode);
+
+ PvrSetup.FilterSpatial.value = newPvrSetup.FilterSpatial.value;
+ SETUPSTORE("FilterSpatial", PvrSetup.FilterSpatial);
+
+ PvrSetup.FilterLumaSpatialType.value = newPvrSetup.FilterLumaSpatialType.value;
+ SETUPSTORE("FilterLumaSpatialType", PvrSetup.FilterLumaSpatialType);
+
+ PvrSetup.FilterChromaSpatialType.value = newPvrSetup.FilterChromaSpatialType.value;
+ SETUPSTORE("FilterChromaSpatialType", PvrSetup.FilterChromaSpatialType);
+
+ PvrSetup.FilterTemporalMode.value = newPvrSetup.FilterTemporalMode.value;
+ SETUPSTORE("FilterTemporalMode", PvrSetup.FilterTemporalMode);
+
+ PvrSetup.FilterTemporal.value = newPvrSetup.FilterTemporal.value;
+ SETUPSTORE("FilterTemporal", PvrSetup.FilterTemporal);
+
+ PvrSetup.FilterMedianType.value = newPvrSetup.FilterMedianType.value;
+ SETUPSTORE("FilterMedianType", PvrSetup.FilterMedianType);
+
+ PvrSetup.FilterLumaMedianBottom.value = newPvrSetup.FilterLumaMedianBottom.value;
+ SETUPSTORE("FilterLumaMedianBottom", PvrSetup.FilterLumaMedianBottom);
+
+ PvrSetup.FilterLumaMedianTop.value = newPvrSetup.FilterLumaMedianTop.value;
+ SETUPSTORE("FilterLumaMedianTop", PvrSetup.FilterLumaMedianTop);
+
+ PvrSetup.FilterChromaMedianBottom.value = newPvrSetup.FilterChromaMedianBottom.value;
+ SETUPSTORE("FilterChromaMedianBottom", PvrSetup.FilterChromaMedianBottom);
+
+ PvrSetup.FilterChromaMedianTop.value = newPvrSetup.FilterChromaMedianTop.value;
+ SETUPSTORE("FilterChromaMedianTop", PvrSetup.FilterChromaMedianTop);
+
+ cPvrDevice::ReInitAll();
+ PvrSetup.repeat_ReInitAll_after_next_encoderstop = true;
+}
+
+
+cPvrMenuMain::cPvrMenuMain(void)
+: cOsdObject(),
+ border(2),
+ margin(4),
+ mode(ePicPropBrightness)
+ {
+ font = cFont::GetFont(fontOsd);
+ width = Setup.OSDWidth;
+ height = 2 * font->Height() + 3 * border + 4 * margin;
+}
+
+cPvrMenuMain::~cPvrMenuMain() {
+ delete osd;
+}
+
+void cPvrMenuMain::Draw(void) {
+
+static const char * pictureProperties[4] = {
+ tr("Setup.pvrinput$Brightness"),
+ tr("Setup.pvrinput$Contrast"),
+ tr("Setup.pvrinput$Saturation"),
+ tr("Setup.pvrinput$Hue")
+ };
+
+ int titleWidth = font->Width(tr(pictureProperties[mode]))
+ + 2 * border + 2 * margin;
+ int titleHeight = font->Height() + border + 2 * margin;
+ int titleStart = 50;
+ int localvalue = PvrSetup.Brightness.value;
+ int localminimum = PvrSetup.Brightness.queryctrl.minimum;
+ int localmaximum = PvrSetup.Brightness.queryctrl.maximum;
+
+ switch (mode) {
+ case ePicPropBrightness:
+ localvalue = PvrSetup.Brightness.value;
+ localminimum = PvrSetup.Brightness.queryctrl.minimum;
+ localmaximum = PvrSetup.Brightness.queryctrl.maximum;
+ break;
+ case ePicPropContrast:
+ localvalue = PvrSetup.Contrast.value;
+ localminimum = PvrSetup.Contrast.queryctrl.minimum;
+ localmaximum = PvrSetup.Contrast.queryctrl.maximum;
+ break;
+ case ePicPropSaturation:
+ localvalue = PvrSetup.Saturation.value;
+ localminimum = PvrSetup.Saturation.queryctrl.minimum;
+ localmaximum = PvrSetup.Saturation.queryctrl.maximum;
+ break;
+ case ePicPropHue:
+ localvalue = PvrSetup.Hue.value;
+ localminimum = PvrSetup.Hue.queryctrl.minimum;
+ localmaximum = PvrSetup.Hue.queryctrl.maximum;
+ break;
+ }
+ int barWidth = (localvalue - localminimum) * (width - font->Width("100%")
+ - 2 * border - 3 * margin) / (localmaximum - localminimum);
+
+ osd->DrawRectangle(0,
+ 0,
+ width - 1,
+ height - 1,
+ clrTransparent);
+ osd->DrawRectangle(0,
+ titleHeight,
+ width - 1,
+ height - 1,
+ clrBlack);
+ osd->DrawRectangle(titleStart,
+ 0,
+ titleStart + titleWidth - 1,
+ titleHeight - 1,
+ clrBlack);
+ osd->DrawText(titleStart + border + margin,
+ border + margin,
+ tr(pictureProperties[mode]),
+ clrWhite,
+ clrBlack,
+ font);
+ osd->DrawRectangle(titleStart,
+ 0,
+ titleStart + titleWidth - 1,
+ border - 1,
+ clrWhite);
+ osd->DrawRectangle(titleStart,
+ 0,
+ titleStart + border - 1,
+ titleHeight - 1,
+ clrWhite);
+ osd->DrawRectangle(titleStart + titleWidth - border,
+ 0,
+ titleStart + titleWidth - 1,
+ titleHeight - 1,
+ clrWhite);
+ osd->DrawRectangle(0,
+ titleHeight,
+ width - 1,
+ titleHeight + border - 1,
+ clrWhite);
+ osd->DrawRectangle(0,
+ titleHeight,
+ border - 1,
+ height - 1,
+ clrWhite);
+ osd->DrawRectangle(0,
+ height - border,
+ width - 1,
+ height - 1,
+ clrWhite);
+ osd->DrawRectangle(width - border,
+ titleHeight,
+ width - 1,
+ height - 1,
+ clrWhite);
+ char strpercentvalue[4];
+ sprintf(strpercentvalue, "%d%%", IntVal2Percent(localvalue,
+ localminimum, localmaximum));
+ osd->DrawText(width - font->Width("100%") - border - margin - 1,
+ border + margin + titleHeight,
+ strpercentvalue,
+ clrWhite,
+ clrBlack,
+ font,
+ font->Width("100%"),
+ 0,
+ taRight);
+ osd->DrawRectangle(border + margin,
+ border + margin + titleHeight,
+ border + margin + barWidth - 1,
+ height - border - margin - 1,
+ clrWhite);
+ osd->Flush();
+}
+
+void cPvrMenuMain::Show(void) {
+ osd = cOsdProvider::NewOsd(Setup.OSDLeft,
+ Setup.OSDTop + Setup.OSDHeight - height);
+
+ tArea area = { 0, 0, width - 1, height - 1, 4 };
+ if (osd->CanHandleAreas(&area, 1) == oeOk)
+ osd->SetAreas(&area, 1);
+
+ Draw();
+}
+
+eOSState cPvrMenuMain::ProcessKey(eKeys Key) {
+ eOSState state = cOsdObject::ProcessKey(Key);
+ if (state == osUnknown) {
+ switch (Key & ~k_Repeat) {
+ case kUp:
+ mode--;
+ if (mode < ePicPropBrightness)
+ mode = ePicPropHue;
+ Draw();
+ break;
+ case kDown:
+ mode++;
+ if (mode > ePicPropHue)
+ mode = ePicPropBrightness;
+ Draw();
+ break;
+ case kLeft:
+ switch (mode) {
+ case ePicPropBrightness:
+ if (PvrSetup.Brightness.value > PvrSetup.Brightness.queryctrl.minimum) {
+ PvrSetup.Brightness.value--;
+ for (int i=0; i<cPvrDevice::Count(); i++) {
+ cPvrDevice * pvr = cPvrDevice::Get(i);
+ if (pvr) pvr->SetControlValue(&PvrSetup.Brightness,
+ PvrSetup.Brightness.value);
+ }
+ }
+ break;
+ case ePicPropContrast:
+ if (PvrSetup.Contrast.value > PvrSetup.Contrast.queryctrl.minimum) {
+ PvrSetup.Contrast.value--;
+ for (int i=0; i<cPvrDevice::Count(); i++) {
+ cPvrDevice * pvr = cPvrDevice::Get(i);
+ if (pvr) pvr->SetControlValue(&PvrSetup.Contrast,
+ PvrSetup.Contrast.value);
+ }
+ }
+ break;
+ case ePicPropSaturation:
+ if (PvrSetup.Saturation.value > PvrSetup.Saturation.queryctrl.minimum) {
+ PvrSetup.Saturation.value--;
+ for (int i=0; i<cPvrDevice::Count(); i++) {
+ cPvrDevice * pvr = cPvrDevice::Get(i);
+ if (pvr) pvr->SetControlValue(&PvrSetup.Saturation,
+ PvrSetup.Saturation.value);
+ }
+ }
+ break;
+ case ePicPropHue:
+ if (PvrSetup.Hue.value > PvrSetup.Hue.queryctrl.minimum) {
+ PvrSetup.Hue.value--;
+ for (int i=0; i<cPvrDevice::Count(); i++) {
+ cPvrDevice * pvr = cPvrDevice::Get(i);
+ if (pvr) pvr->SetControlValue(&PvrSetup.Hue,
+ PvrSetup.Hue.value);
+ }
+ }
+ break;
+ }
+ Draw();
+ break;
+ case kRight:
+ switch (mode)
+ {
+ case ePicPropBrightness:
+ if (PvrSetup.Brightness.value < PvrSetup.Brightness.queryctrl.maximum) {
+ PvrSetup.Brightness.value++;
+ for (int i=0; i<cPvrDevice::Count(); i++) {
+ cPvrDevice * pvr = cPvrDevice::Get(i);
+ if (pvr) pvr->SetControlValue(&PvrSetup.Brightness,
+ PvrSetup.Brightness.value);
+ }
+ }
+ break;
+ case ePicPropContrast:
+ if (PvrSetup.Contrast.value < PvrSetup.Contrast.queryctrl.maximum) {
+ PvrSetup.Contrast.value++;
+ for (int i=0; i<cPvrDevice::Count(); i++) {
+ cPvrDevice * pvr = cPvrDevice::Get(i);
+ if (pvr) pvr->SetControlValue(&PvrSetup.Contrast,
+ PvrSetup.Contrast.value);
+ }
+ }
+ break;
+ case ePicPropSaturation:
+ if (PvrSetup.Saturation.value < PvrSetup.Saturation.queryctrl.maximum) {
+ PvrSetup.Saturation.value++;
+ for (int i=0; i<cPvrDevice::Count(); i++) {
+ cPvrDevice * pvr = cPvrDevice::Get(i);
+ if (pvr) pvr->SetControlValue(&PvrSetup.Saturation,
+ PvrSetup.Saturation.value);
+ }
+ }
+ break;
+ case ePicPropHue:
+ if (PvrSetup.Hue.value < PvrSetup.Hue.queryctrl.maximum) {
+ PvrSetup.Hue.value++;
+ for (int i=0; i<cPvrDevice::Count(); i++) {
+ cPvrDevice * pvr = cPvrDevice::Get(i);
+ if (pvr) pvr->SetControlValue(&PvrSetup.Hue,
+ PvrSetup.Hue.value);
+ }
+ }
+ break;
+ }
+ Draw();
+ break;
+ case kOk:
+ PluginPvrInput->SetupStore("Brightness", PvrSetup.Brightness.value);
+ PluginPvrInput->SetupStore("Contrast", PvrSetup.Contrast.value);
+ PluginPvrInput->SetupStore("Saturation", PvrSetup.Saturation.value);
+ PluginPvrInput->SetupStore("Hue", PvrSetup.Hue.value);
+ return osEnd;
+ case kBack:
+ return osEnd;
+ default:
+ return state;
+ }
+ state = osContinue;
+ }
+ return state;
+}
+
diff --git a/menu.h b/menu.h
new file mode 100644
index 0000000..7a5cc1c
--- /dev/null
+++ b/menu.h
@@ -0,0 +1,68 @@
+/**
+ * pvrinput plugin for the Video Disk Recorder
+ *
+ * menu.h - setup menu class
+ *
+ * (c) 2005 Andreas Regel <andreas.regel AT powarman.de>
+ **/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; *
+ * if not, write to the Free Software Foundation, Inc., *
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
+ * *
+ ***************************************************************************/
+
+#ifndef _PVRINPUT_MENU_H_
+#define _PVRINPUT_MENU_H_
+
+#include "common.h"
+
+typedef enum {
+ ePicPropBrightness = 0,
+ ePicPropContrast,
+ ePicPropSaturation,
+ ePicPropHue,
+ ePicPropTotalNumber
+} EPicPropety;
+
+class cPvrMenuSetup : public cMenuSetupPage {
+private:
+ cPvrSetup newPvrSetup;
+protected:
+ virtual void Store();
+public:
+ cPvrMenuSetup();
+};
+
+class cPvrMenuMain : public cOsdObject {
+private:
+ cOsd * osd;
+ const cFont * font;
+ int border;
+ int margin;
+ int width;
+ int height;
+ int mode;
+
+ void Draw(void);
+public:
+ cPvrMenuMain(void);
+ virtual ~cPvrMenuMain();
+ virtual void Show(void);
+ virtual eOSState ProcessKey(eKeys Key);
+};
+
+#endif
diff --git a/patches/vdr/vdr-1.4.7-pluginparam.patch b/patches/vdr/vdr-1.4.7-pluginparam.patch
new file mode 100644
index 0000000..42cee49
--- /dev/null
+++ b/patches/vdr/vdr-1.4.7-pluginparam.patch
@@ -0,0 +1,299 @@
+diff -Nru vdr-1.4.7-vanilla/channels.c vdr-1.4.7-pluginparam/channels.c
+--- vdr-1.4.7-vanilla/channels.c 2007-10-27 01:08:39.000000000 +0300
++++ vdr-1.4.7-pluginparam/channels.c 2007-10-27 01:09:05.000000000 +0300
+@@ -166,6 +166,7 @@
+ shortName = strdup("");
+ provider = strdup("");
+ portalName = strdup("");
++ pluginParam = strdup("");
+ memset(&__BeginData__, 0, (char *)&__EndData__ - (char *)&__BeginData__);
+ inversion = INVERSION_AUTO;
+ bandwidth = BANDWIDTH_AUTO;
+@@ -187,6 +188,7 @@
+ shortName = NULL;
+ provider = NULL;
+ portalName = NULL;
++ pluginParam = NULL;
+ schedule = NULL;
+ linkChannels = NULL;
+ refChannel = NULL;
+@@ -215,6 +217,7 @@
+ free(shortName);
+ free(provider);
+ free(portalName);
++ free(pluginParam);
+ }
+
+ cChannel& cChannel::operator= (const cChannel &Channel)
+@@ -223,6 +226,7 @@
+ shortName = strcpyrealloc(shortName, Channel.shortName);
+ provider = strcpyrealloc(provider, Channel.provider);
+ portalName = strcpyrealloc(portalName, Channel.portalName);
++ pluginParam = strcpyrealloc(pluginParam, Channel.pluginParam);
+ memcpy(&__BeginData__, &Channel.__BeginData__, (char *)&Channel.__EndData__ - (char *)&Channel.__BeginData__);
+ return *this;
+ }
+@@ -280,9 +284,26 @@
+ transmission = Channel->transmission;
+ guard = Channel->guard;
+ hierarchy = Channel->hierarchy;
++ if (IsPlug()) pluginParam = strcpyrealloc(pluginParam, Channel->pluginParam);
+ }
+ }
+
++bool cChannel::SetPlugTransponderData(int Source, int Frequency, const char *PluginParam)
++{
++ if (source != Source || frequency != Frequency || (strcmp(pluginParam, PluginParam) != 0)) {
++ if (Number()) {
++ dsyslog("changing transponder data of channel %d from %s:%d:%s to %s:%d:%s", Number(), *cSource::ToString(source), frequency, pluginParam, *cSource::ToString(Source), Frequency, PluginParam);
++ modification |= CHANNELMOD_TRANSP;
++ Channels.SetModified();
++ }
++ source = Source;
++ frequency = Frequency;
++ pluginParam = strcpyrealloc(pluginParam, PluginParam);
++ schedule = NULL;
++ }
++ return true;
++}
++
+ bool cChannel::SetSatTransponderData(int Source, int Frequency, char Polarization, int Srate, int CoderateH)
+ {
+ // Workarounds for broadcaster stupidity:
+@@ -407,6 +428,18 @@
+ }
+ }
+
++void cChannel::SetPluginParam(const char *PluginParam)
++{
++ if (!isempty(PluginParam) && strcmp(pluginParam, PluginParam) != 0) {
++ if (Number()) {
++ dsyslog("changing plugin parameters of channel %d from '%s' to '%s'", Number(), pluginParam, PluginParam);
++ modification |= CHANNELMOD_TRANSP;
++ Channels.SetModified();
++ }
++ pluginParam = strcpyrealloc(pluginParam, PluginParam);
++ }
++}
++
+ #define STRDIFF 0x01
+ #define VALDIFF 0x02
+
+@@ -579,7 +612,7 @@
+ if (isdigit(type))
+ type = 'S';
+ #define ST(s) if (strchr(s, type))
+- char buffer[64];
++ char buffer[256];
+ char *q = buffer;
+ *q = 0;
+ ST(" S ") q += sprintf(q, "%c", polarization);
+@@ -591,6 +624,7 @@
+ ST(" T") q += PrintParameter(q, 'T', MapToUser(transmission, TransmissionValues));
+ ST(" T") q += PrintParameter(q, 'G', MapToUser(guard, GuardValues));
+ ST(" T") q += PrintParameter(q, 'Y', MapToUser(hierarchy, HierarchyValues));
++ ST("P ") snprintf(buffer, sizeof(buffer), "%s", pluginParam);
+ return buffer;
+ }
+
+@@ -612,7 +646,7 @@
+
+ bool cChannel::StringToParameters(const char *s)
+ {
+- while (s && *s) {
++ while (s && *s && !IsPlug()) {
+ switch (toupper(*s)) {
+ case 'B': s = ParseParameter(s, bandwidth, BandwidthValues); break;
+ case 'C': s = ParseParameter(s, coderateH, CoderateValues); break;
+@@ -722,7 +756,7 @@
+ dpids[0] = 0;
+ ok = false;
+ if (parambuf && sourcebuf && vpidbuf && apidbuf) {
+- ok = StringToParameters(parambuf) && (source = cSource::FromString(sourcebuf)) >= 0;
++ ok = ((source = cSource::FromString(sourcebuf)) >= 0) && StringToParameters(parambuf);
+
+ char *p = strchr(vpidbuf, '+');
+ if (p)
+@@ -813,6 +847,7 @@
+ shortName = strcpyrealloc(shortName, p);
+ }
+ name = strcpyrealloc(name, namebuf);
++ if (IsPlug()) pluginParam = strcpyrealloc(pluginParam, parambuf);
+
+ free(parambuf);
+ free(sourcebuf);
+diff -Nru vdr-1.4.7-vanilla/channels.h vdr-1.4.7-pluginparam/channels.h
+--- vdr-1.4.7-vanilla/channels.h 2007-10-27 01:08:39.000000000 +0300
++++ vdr-1.4.7-pluginparam/channels.h 2007-10-27 01:12:37.000000000 +0300
+@@ -114,6 +114,7 @@
+ char *shortName;
+ char *provider;
+ char *portalName;
++ char *pluginParam;
+ int __BeginData__;
+ int frequency; // MHz
+ int source;
+@@ -165,6 +166,7 @@
+ int Frequency(void) const { return frequency; } ///< Returns the actual frequency, as given in 'channels.conf'
+ int Transponder(void) const; ///< Returns the transponder frequency in MHz, plus the polarization in case of sat
+ static int Transponder(int Frequency, char Polarization); ///< builds the transponder from the given Frequency and Polarization
++ const char *PluginParam(void) const { return pluginParam; }
+ int Source(void) const { return source; }
+ int Srate(void) const { return srate; }
+ int Vpid(void) const { return vpid; }
+@@ -198,6 +200,7 @@
+ int Hierarchy(void) const { return hierarchy; }
+ const cLinkChannels* LinkChannels(void) const { return linkChannels; }
+ const cChannel *RefChannel(void) const { return refChannel; }
++ bool IsPlug(void) const { return cSource::IsPlug(source); }
+ bool IsCable(void) const { return cSource::IsCable(source); }
+ bool IsSat(void) const { return cSource::IsSat(source); }
+ bool IsTerr(void) const { return cSource::IsTerr(source); }
+@@ -205,12 +208,14 @@
+ bool HasTimer(void) const;
+ int Modification(int Mask = CHANNELMOD_ALL);
+ void CopyTransponderData(const cChannel *Channel);
++ bool SetPlugTransponderData(int Source, int Frequency, const char *PluginParam);
+ bool SetSatTransponderData(int Source, int Frequency, char Polarization, int Srate, int CoderateH);
+ bool SetCableTransponderData(int Source, int Frequency, int Modulation, int Srate, int CoderateH);
+ bool SetTerrTransponderData(int Source, int Frequency, int Bandwidth, int Modulation, int Hierarchy, int CodeRateH, int CodeRateL, int Guard, int Transmission);
+ void SetId(int Nid, int Tid, int Sid, int Rid = 0);
+ void SetName(const char *Name, const char *ShortName, const char *Provider);
+ void SetPortalName(const char *PortalName);
++ void SetPluginParam(const char *PluginParam);
+ void SetPids(int Vpid, int Ppid, int *Apids, char ALangs[][MAXLANGCODE2], int *Dpids, char DLangs[][MAXLANGCODE2], int Tpid);
+ void SetCaIds(const int *CaIds); // list must be zero-terminated
+ void SetCaDescriptors(int Level);
+diff -Nru vdr-1.4.7-vanilla/config.h vdr-1.4.7-pluginparam/config.h
+--- vdr-1.4.7-vanilla/config.h 2007-10-27 01:08:39.000000000 +0300
++++ vdr-1.4.7-pluginparam/config.h 2007-10-27 01:14:39.000000000 +0300
+@@ -29,6 +29,8 @@
+ #define APIVERSION "1.4.5"
+ #define APIVERSNUM 10405 // Version * 10000 + Major * 100 + Minor
+
++#define PLUGINPARAMPATCHVERSNUM 1
++
+ // When loading plugins, VDR searches them by their APIVERSION, which
+ // may be smaller than VDRVERSION in case there have been no changes to
+ // VDR header files since the last APIVERSION. This allows compiled
+diff -Nru vdr-1.4.7-vanilla/i18n.c vdr-1.4.7-pluginparam/i18n.c
+--- vdr-1.4.7-vanilla/i18n.c 2007-10-27 01:08:39.000000000 +0300
++++ vdr-1.4.7-pluginparam/i18n.c 2007-10-27 01:11:38.000000000 +0300
+@@ -6126,6 +6126,28 @@
+ "Ingen titel",
+ "Bez názvu",
+ },
++ { "Parameters",
++ "",// TODO
++ "",// TODO
++ "",// TODO
++ "",// TODO
++ "",// TODO
++ "",// TODO
++ "",// TODO
++ "Parametrit",
++ "",// TODO
++ "",// TODO
++ "",// TODO
++ "",// TODO
++ "",// TODO
++ "",// TODO
++ "",// TODO
++ "",// TODO
++ "",// TODO
++ "",// TODO
++ "",// TODO
++ "",// TODO
++ },
+ { NULL }
+ };
+
+diff -Nru vdr-1.4.7-vanilla/menu.c vdr-1.4.7-pluginparam/menu.c
+--- vdr-1.4.7-vanilla/menu.c 2007-10-27 01:08:39.000000000 +0300
++++ vdr-1.4.7-pluginparam/menu.c 2007-10-27 01:09:05.000000000 +0300
+@@ -216,6 +216,7 @@
+ cChannel *channel;
+ cChannel data;
+ char name[256];
++ char pluginParam[256];
+ void Setup(void);
+ public:
+ cMenuEditChannel(cChannel *Channel, bool New = false);
+@@ -248,6 +249,7 @@
+
+ // Parameters for all types of sources:
+ strn0cpy(name, data.name, sizeof(name));
++ strn0cpy(pluginParam, data.pluginParam, sizeof(pluginParam));
+ Add(new cMenuEditStrItem( tr("Name"), name, sizeof(name), tr(FileNameChars)));
+ Add(new cMenuEditSrcItem( tr("Source"), &data.source));
+ Add(new cMenuEditIntItem( tr("Frequency"), &data.frequency));
+@@ -276,6 +278,7 @@
+ ST(" T") Add(new cMenuEditMapItem( tr("Transmission"), &data.transmission, TransmissionValues));
+ ST(" T") Add(new cMenuEditMapItem( tr("Guard"), &data.guard, GuardValues));
+ ST(" T") Add(new cMenuEditMapItem( tr("Hierarchy"), &data.hierarchy, HierarchyValues, tr("none")));
++ ST("P ") Add(new cMenuEditStrItem( tr("Parameters"), pluginParam, sizeof(pluginParam), tr(FileNameChars)));
+
+ SetCurrent(Get(current));
+ Display();
+@@ -290,6 +293,7 @@
+ if (Key == kOk) {
+ if (Channels.HasUniqueChannelID(&data, channel)) {
+ data.name = strcpyrealloc(data.name, name);
++ data.pluginParam = strcpyrealloc(data.pluginParam, pluginParam);
+ if (channel) {
+ *channel = data;
+ isyslog("edited channel %d %s", channel->Number(), *data.ToText());
+diff -Nru vdr-1.4.7-vanilla/sources.c vdr-1.4.7-pluginparam/sources.c
+--- vdr-1.4.7-vanilla/sources.c 2007-10-27 01:08:39.000000000 +0300
++++ vdr-1.4.7-pluginparam/sources.c 2007-10-27 01:09:20.000000000 +0300
+@@ -37,6 +37,7 @@
+ char buffer[16];
+ char *q = buffer;
+ switch (Code & st_Mask) {
++ case stPlug: *q++ = 'P'; break;
+ case stCable: *q++ = 'C'; break;
+ case stSat: *q++ = 'S';
+ {
+@@ -56,6 +57,7 @@
+ {
+ int type = stNone;
+ switch (toupper(*s)) {
++ case 'P': type = stPlug; break;
+ case 'C': type = stCable; break;
+ case 'S': type = stSat; break;
+ case 'T': type = stTerr; break;
+diff -Nru vdr-1.4.7-vanilla/sources.conf vdr-1.4.7-pluginparam/sources.conf
+--- vdr-1.4.7-vanilla/sources.conf 2007-10-27 01:08:39.000000000 +0300
++++ vdr-1.4.7-pluginparam/sources.conf 2007-10-27 01:09:20.000000000 +0300
+@@ -188,3 +188,7 @@
+ # Terrestrial
+
+ T Terrestrial
++
++# Plugin
++
++P Plugin
+diff -Nru vdr-1.4.7-vanilla/sources.h vdr-1.4.7-pluginparam/sources.h
+--- vdr-1.4.7-vanilla/sources.h 2007-10-27 01:08:40.000000000 +0300
++++ vdr-1.4.7-pluginparam/sources.h 2007-10-27 01:09:20.000000000 +0300
+@@ -16,10 +16,11 @@
+ public:
+ enum eSourceType {
+ stNone = 0x0000,
++ stPlug = 0x2000,
+ stCable = 0x4000,
+ stSat = 0x8000,
+ stTerr = 0xC000,
+- st_Mask = 0xC000,
++ st_Mask = 0xE000,
+ st_Neg = 0x0800,
+ st_Pos = 0x07FF,
+ };
+@@ -35,6 +36,7 @@
+ static cString ToString(int Code);
+ static int FromString(const char *s);
+ static int FromData(eSourceType SourceType, int Position = 0, bool East = false);
++ static bool IsPlug(int Code) { return (Code & st_Mask) == stPlug; }
+ static bool IsCable(int Code) { return (Code & st_Mask) == stCable; }
+ static bool IsSat(int Code) { return (Code & st_Mask) == stSat; }
+ static bool IsTerr(int Code) { return (Code & st_Mask) == stTerr; }
diff --git a/patches/vdr/vdr-1.6.0-pluginparam.patch b/patches/vdr/vdr-1.6.0-pluginparam.patch
new file mode 100644
index 0000000..583aa20
--- /dev/null
+++ b/patches/vdr/vdr-1.6.0-pluginparam.patch
@@ -0,0 +1,287 @@
+diff -Nru vdr-1.6.0-vanilla/channels.c vdr-1.6.0-pluginparam/channels.c
+--- vdr-1.6.0-vanilla/channels.c 2008-03-27 21:43:25.000000000 +0200
++++ vdr-1.6.0-pluginparam/channels.c 2008-03-27 22:06:47.000000000 +0200
+@@ -166,6 +166,7 @@
+ shortName = strdup("");
+ provider = strdup("");
+ portalName = strdup("");
++ pluginParam = strdup("");
+ memset(&__BeginData__, 0, (char *)&__EndData__ - (char *)&__BeginData__);
+ inversion = INVERSION_AUTO;
+ bandwidth = BANDWIDTH_AUTO;
+@@ -187,6 +188,7 @@
+ shortName = NULL;
+ provider = NULL;
+ portalName = NULL;
++ pluginParam = NULL;
+ schedule = NULL;
+ linkChannels = NULL;
+ refChannel = NULL;
+@@ -215,6 +217,7 @@
+ free(shortName);
+ free(provider);
+ free(portalName);
++ free(pluginParam);
+ }
+
+ cChannel& cChannel::operator= (const cChannel &Channel)
+@@ -223,6 +226,7 @@
+ shortName = strcpyrealloc(shortName, Channel.shortName);
+ provider = strcpyrealloc(provider, Channel.provider);
+ portalName = strcpyrealloc(portalName, Channel.portalName);
++ pluginParam = strcpyrealloc(pluginParam, Channel.pluginParam);
+ memcpy(&__BeginData__, &Channel.__BeginData__, (char *)&Channel.__EndData__ - (char *)&Channel.__BeginData__);
+ return *this;
+ }
+@@ -280,9 +284,26 @@
+ transmission = Channel->transmission;
+ guard = Channel->guard;
+ hierarchy = Channel->hierarchy;
++ if (IsPlug()) pluginParam = strcpyrealloc(pluginParam, Channel->pluginParam);
+ }
+ }
+
++bool cChannel::SetPlugTransponderData(int Source, int Frequency, const char *PluginParam)
++{
++ if (source != Source || frequency != Frequency || (strcmp(pluginParam, PluginParam) != 0)) {
++ if (Number()) {
++ dsyslog("changing transponder data of channel %d from %s:%d:%s to %s:%d:%s", Number(), *cSource::ToString(source), frequency, pluginParam, *cSource::ToString(Source), Frequency, PluginParam);
++ modification |= CHANNELMOD_TRANSP;
++ Channels.SetModified();
++ }
++ source = Source;
++ frequency = Frequency;
++ pluginParam = strcpyrealloc(pluginParam, PluginParam);
++ schedule = NULL;
++ }
++ return true;
++}
++
+ bool cChannel::SetSatTransponderData(int Source, int Frequency, char Polarization, int Srate, int CoderateH)
+ {
+ // Workarounds for broadcaster stupidity:
+@@ -407,6 +428,18 @@
+ }
+ }
+
++void cChannel::SetPluginParam(const char *PluginParam)
++{
++ if (!isempty(PluginParam) && strcmp(pluginParam, PluginParam) != 0) {
++ if (Number()) {
++ dsyslog("changing plugin parameters of channel %d from '%s' to '%s'", Number(), pluginParam, PluginParam);
++ modification |= CHANNELMOD_TRANSP;
++ Channels.SetModified();
++ }
++ pluginParam = strcpyrealloc(pluginParam, PluginParam);
++ }
++}
++
+ #define STRDIFF 0x01
+ #define VALDIFF 0x02
+
+@@ -593,7 +626,7 @@
+ if (isdigit(type))
+ type = 'S';
+ #define ST(s) if (strchr(s, type))
+- char buffer[64];
++ char buffer[256];
+ char *q = buffer;
+ *q = 0;
+ ST(" S ") q += sprintf(q, "%c", polarization);
+@@ -605,6 +638,7 @@
+ ST(" T") q += PrintParameter(q, 'T', MapToUser(transmission, TransmissionValues));
+ ST(" T") q += PrintParameter(q, 'G', MapToUser(guard, GuardValues));
+ ST(" T") q += PrintParameter(q, 'Y', MapToUser(hierarchy, HierarchyValues));
++ ST("P ") snprintf(buffer, sizeof(buffer), "%s", pluginParam);
+ return buffer;
+ }
+
+@@ -626,7 +660,7 @@
+
+ bool cChannel::StringToParameters(const char *s)
+ {
+- while (s && *s) {
++ while (s && *s && !IsPlug()) {
+ switch (toupper(*s)) {
+ case 'B': s = ParseParameter(s, bandwidth, BandwidthValues); break;
+ case 'C': s = ParseParameter(s, coderateH, CoderateValues); break;
+@@ -736,7 +770,7 @@
+ dpids[0] = 0;
+ ok = false;
+ if (parambuf && sourcebuf && vpidbuf && apidbuf) {
+- ok = StringToParameters(parambuf) && (source = cSource::FromString(sourcebuf)) >= 0;
++ ok = ((source = cSource::FromString(sourcebuf)) >= 0) && StringToParameters(parambuf);
+
+ char *p = strchr(vpidbuf, '+');
+ if (p)
+@@ -827,6 +861,7 @@
+ shortName = strcpyrealloc(shortName, p);
+ }
+ name = strcpyrealloc(name, namebuf);
++ if (IsPlug()) pluginParam = strcpyrealloc(pluginParam, parambuf);
+
+ free(parambuf);
+ free(sourcebuf);
+diff -Nru vdr-1.6.0-vanilla/channels.h vdr-1.6.0-pluginparam/channels.h
+--- vdr-1.6.0-vanilla/channels.h 2008-03-27 21:43:25.000000000 +0200
++++ vdr-1.6.0-pluginparam/channels.h 2008-03-27 22:06:47.000000000 +0200
+@@ -114,6 +114,7 @@
+ char *shortName;
+ char *provider;
+ char *portalName;
++ char *pluginParam;
+ int __BeginData__;
+ int frequency; // MHz
+ int source;
+@@ -165,6 +166,7 @@
+ int Frequency(void) const { return frequency; } ///< Returns the actual frequency, as given in 'channels.conf'
+ int Transponder(void) const; ///< Returns the transponder frequency in MHz, plus the polarization in case of sat
+ static int Transponder(int Frequency, char Polarization); ///< builds the transponder from the given Frequency and Polarization
++ const char *PluginParam(void) const { return pluginParam; }
+ int Source(void) const { return source; }
+ int Srate(void) const { return srate; }
+ int Vpid(void) const { return vpid; }
+@@ -199,6 +201,7 @@
+ int Hierarchy(void) const { return hierarchy; }
+ const cLinkChannels* LinkChannels(void) const { return linkChannels; }
+ const cChannel *RefChannel(void) const { return refChannel; }
++ bool IsPlug(void) const { return cSource::IsPlug(source); }
+ bool IsCable(void) const { return cSource::IsCable(source); }
+ bool IsSat(void) const { return cSource::IsSat(source); }
+ bool IsTerr(void) const { return cSource::IsTerr(source); }
+@@ -206,12 +209,14 @@
+ bool HasTimer(void) const;
+ int Modification(int Mask = CHANNELMOD_ALL);
+ void CopyTransponderData(const cChannel *Channel);
++ bool SetPlugTransponderData(int Source, int Frequency, const char *PluginParam);
+ bool SetSatTransponderData(int Source, int Frequency, char Polarization, int Srate, int CoderateH);
+ bool SetCableTransponderData(int Source, int Frequency, int Modulation, int Srate, int CoderateH);
+ bool SetTerrTransponderData(int Source, int Frequency, int Bandwidth, int Modulation, int Hierarchy, int CodeRateH, int CodeRateL, int Guard, int Transmission);
+ void SetId(int Nid, int Tid, int Sid, int Rid = 0);
+ void SetName(const char *Name, const char *ShortName, const char *Provider);
+ void SetPortalName(const char *PortalName);
++ void SetPluginParam(const char *PluginParam);
+ void SetPids(int Vpid, int Ppid, int *Apids, char ALangs[][MAXLANGCODE2], int *Dpids, char DLangs[][MAXLANGCODE2], int *Spids, char SLangs[][MAXLANGCODE2], int Tpid);
+ void SetCaIds(const int *CaIds); // list must be zero-terminated
+ void SetCaDescriptors(int Level);
+diff -Nru vdr-1.6.0-vanilla/config.h vdr-1.6.0-pluginparam/config.h
+--- vdr-1.6.0-vanilla/config.h 2008-03-27 21:43:25.000000000 +0200
++++ vdr-1.6.0-pluginparam/config.h 2008-03-27 22:06:47.000000000 +0200
+@@ -30,6 +30,8 @@
+ #define APIVERSION "1.6.0"
+ #define APIVERSNUM 10600 // Version * 10000 + Major * 100 + Minor
+
++#define PLUGINPARAMPATCHVERSNUM 1
++
+ // When loading plugins, VDR searches them by their APIVERSION, which
+ // may be smaller than VDRVERSION in case there have been no changes to
+ // VDR header files since the last APIVERSION. This allows compiled
+diff -Nru vdr-1.6.0-vanilla/menu.c vdr-1.6.0-pluginparam/menu.c
+--- vdr-1.6.0-vanilla/menu.c 2008-03-27 21:43:25.000000000 +0200
++++ vdr-1.6.0-pluginparam/menu.c 2008-03-27 22:06:47.000000000 +0200
+@@ -253,6 +253,7 @@
+ cChannel *channel;
+ cChannel data;
+ char name[256];
++ char pluginParam[256];
+ void Setup(void);
+ public:
+ cMenuEditChannel(cChannel *Channel, bool New = false);
+@@ -285,6 +286,7 @@
+
+ // Parameters for all types of sources:
+ strn0cpy(name, data.name, sizeof(name));
++ strn0cpy(pluginParam, data.pluginParam, sizeof(pluginParam));
+ Add(new cMenuEditStrItem( tr("Name"), name, sizeof(name)));
+ Add(new cMenuEditSrcItem( tr("Source"), &data.source));
+ Add(new cMenuEditIntItem( tr("Frequency"), &data.frequency));
+@@ -315,6 +317,7 @@
+ ST(" T") Add(new cMenuEditMapItem( tr("Transmission"), &data.transmission, TransmissionValues));
+ ST(" T") Add(new cMenuEditMapItem( tr("Guard"), &data.guard, GuardValues));
+ ST(" T") Add(new cMenuEditMapItem( tr("Hierarchy"), &data.hierarchy, HierarchyValues, tr("none")));
++ ST("P ") Add(new cMenuEditStrItem( tr("Parameters"), pluginParam, sizeof(pluginParam), tr(FileNameChars)));
+
+ SetCurrent(Get(current));
+ Display();
+@@ -329,6 +332,7 @@
+ if (Key == kOk) {
+ if (Channels.HasUniqueChannelID(&data, channel)) {
+ data.name = strcpyrealloc(data.name, name);
++ data.pluginParam = strcpyrealloc(data.pluginParam, pluginParam);
+ if (channel) {
+ *channel = data;
+ isyslog("edited channel %d %s", channel->Number(), *data.ToText());
+diff -Nru vdr-1.6.0-vanilla/po/fi_FI.po vdr-1.6.0-pluginparam/po/fi_FI.po
+--- vdr-1.6.0-vanilla/po/fi_FI.po 2008-03-27 21:43:25.000000000 +0200
++++ vdr-1.6.0-pluginparam/po/fi_FI.po 2008-03-27 22:06:47.000000000 +0200
+@@ -1001,3 +1001,6 @@
+ #, c-format
+ msgid "VDR will shut down in %s minutes"
+ msgstr "VDR sammuu %s minuutin kuluttua"
++
++msgid "Parameters"
++msgstr "Parametrit"
+diff -Nru vdr-1.6.0-vanilla/po/fr_FR.po vdr-1.6.0-pluginparam/po/fr_FR.po
+--- vdr-1.6.0-vanilla/po/fr_FR.po 2008-03-27 21:43:25.000000000 +0200
++++ vdr-1.6.0-pluginparam/po/fr_FR.po 2008-03-27 22:06:47.000000000 +0200
+@@ -1004,3 +1004,6 @@
+ #, c-format
+ msgid "VDR will shut down in %s minutes"
+ msgstr "VDR s'arrêtera dans %s minutes"
++
++msgid "Parameters"
++msgstr "Paramètres"
+diff -Nru vdr-1.6.0-vanilla/sources.c vdr-1.6.0-pluginparam/sources.c
+--- vdr-1.6.0-vanilla/sources.c 2008-03-27 21:43:25.000000000 +0200
++++ vdr-1.6.0-pluginparam/sources.c 2008-03-27 22:06:47.000000000 +0200
+@@ -37,6 +37,7 @@
+ char buffer[16];
+ char *q = buffer;
+ switch (Code & st_Mask) {
++ case stPlug: *q++ = 'P'; break;
+ case stCable: *q++ = 'C'; break;
+ case stSat: *q++ = 'S';
+ {
+@@ -56,6 +57,7 @@
+ {
+ int type = stNone;
+ switch (toupper(*s)) {
++ case 'P': type = stPlug; break;
+ case 'C': type = stCable; break;
+ case 'S': type = stSat; break;
+ case 'T': type = stTerr; break;
+diff -Nru vdr-1.6.0-vanilla/sources.conf vdr-1.6.0-pluginparam/sources.conf
+--- vdr-1.6.0-vanilla/sources.conf 2008-03-27 21:43:25.000000000 +0200
++++ vdr-1.6.0-pluginparam/sources.conf 2008-03-27 22:06:47.000000000 +0200
+@@ -188,3 +188,7 @@
+ # Terrestrial
+
+ T Terrestrial
++
++# Plugin
++
++P Plugin
+diff -Nru vdr-1.6.0-vanilla/sources.h vdr-1.6.0-pluginparam/sources.h
+--- vdr-1.6.0-vanilla/sources.h 2008-03-27 21:43:25.000000000 +0200
++++ vdr-1.6.0-pluginparam/sources.h 2008-03-27 22:06:47.000000000 +0200
+@@ -16,10 +16,11 @@
+ public:
+ enum eSourceType {
+ stNone = 0x0000,
++ stPlug = 0x2000,
+ stCable = 0x4000,
+ stSat = 0x8000,
+ stTerr = 0xC000,
+- st_Mask = 0xC000,
++ st_Mask = 0xE000,
+ st_Neg = 0x0800,
+ st_Pos = 0x07FF,
+ };
+@@ -35,6 +36,7 @@
+ static cString ToString(int Code);
+ static int FromString(const char *s);
+ static int FromData(eSourceType SourceType, int Position = 0, bool East = false);
++ static bool IsPlug(int Code) { return (Code & st_Mask) == stPlug; }
+ static bool IsCable(int Code) { return (Code & st_Mask) == stCable; }
+ static bool IsSat(int Code) { return (Code & st_Mask) == stSat; }
+ static bool IsTerr(int Code) { return (Code & st_Mask) == stTerr; }
diff --git a/patches/vdr/vdr-1.7.9-pluginparam.patch b/patches/vdr/vdr-1.7.9-pluginparam.patch
new file mode 100644
index 0000000..564d5fc
--- /dev/null
+++ b/patches/vdr/vdr-1.7.9-pluginparam.patch
@@ -0,0 +1,287 @@
+diff -Nru vdr-1.7.9-vanilla/channels.c vdr-1.7.9-pluginsparam/channels.c
+--- vdr-1.7.9-vanilla/channels.c 2009-08-23 18:12:32.000000000 +0300
++++ vdr-1.7.9-pluginsparam/channels.c 2009-08-23 18:18:54.000000000 +0300
+@@ -188,6 +188,7 @@
+ shortName = strdup("");
+ provider = strdup("");
+ portalName = strdup("");
++ pluginParam = strdup("");
+ memset(&__BeginData__, 0, (char *)&__EndData__ - (char *)&__BeginData__);
+ inversion = INVERSION_AUTO;
+ bandwidth = 8000000;
+@@ -211,6 +212,7 @@
+ shortName = NULL;
+ provider = NULL;
+ portalName = NULL;
++ pluginParam = NULL;
+ schedule = NULL;
+ linkChannels = NULL;
+ refChannel = NULL;
+@@ -239,6 +241,7 @@
+ free(shortName);
+ free(provider);
+ free(portalName);
++ free(pluginParam);
+ }
+
+ cChannel& cChannel::operator= (const cChannel &Channel)
+@@ -247,6 +250,7 @@
+ shortName = strcpyrealloc(shortName, Channel.shortName);
+ provider = strcpyrealloc(provider, Channel.provider);
+ portalName = strcpyrealloc(portalName, Channel.portalName);
++ pluginParam = strcpyrealloc(pluginParam, Channel.pluginParam);
+ memcpy(&__BeginData__, &Channel.__BeginData__, (char *)&Channel.__EndData__ - (char *)&Channel.__BeginData__);
+ return *this;
+ }
+@@ -306,9 +310,26 @@
+ guard = Channel->guard;
+ hierarchy = Channel->hierarchy;
+ rollOff = Channel->rollOff;
++ if (IsPlug()) pluginParam = strcpyrealloc(pluginParam, Channel->pluginParam);
+ }
+ }
+
++bool cChannel::SetPlugTransponderData(int Source, int Frequency, const char *PluginParam)
++{
++ if (source != Source || frequency != Frequency || (strcmp(pluginParam, PluginParam) != 0)) {
++ if (Number()) {
++ dsyslog("changing transponder data of channel %d from %s:%d:%s to %s:%d:%s", Number(), *cSource::ToString(source), frequency, pluginParam, *cSource::ToString(Source), Frequency, PluginParam);
++ modification |= CHANNELMOD_TRANSP;
++ Channels.SetModified();
++ }
++ source = Source;
++ frequency = Frequency;
++ pluginParam = strcpyrealloc(pluginParam, PluginParam);
++ schedule = NULL;
++ }
++ return true;
++}
++
+ bool cChannel::SetSatTransponderData(int Source, int Frequency, char Polarization, int Srate, int CoderateH, int Modulation, int System, int RollOff)
+ {
+ // Workarounds for broadcaster stupidity:
+@@ -438,6 +459,18 @@
+ }
+ }
+
++void cChannel::SetPluginParam(const char *PluginParam)
++{
++ if (!isempty(PluginParam) && strcmp(pluginParam, PluginParam) != 0) {
++ if (Number()) {
++ dsyslog("changing plugin parameters of channel %d from '%s' to '%s'", Number(), pluginParam, PluginParam);
++ modification |= CHANNELMOD_TRANSP;
++ Channels.SetModified();
++ }
++ pluginParam = strcpyrealloc(pluginParam, PluginParam);
++ }
++}
++
+ #define STRDIFF 0x01
+ #define VALDIFF 0x02
+
+@@ -648,7 +681,7 @@
+ if (isdigit(type))
+ type = 'S';
+ #define ST(s) if (strchr(s, type))
+- char buffer[64];
++ char buffer[256];
+ char *q = buffer;
+ *q = 0;
+ ST(" S ") q += sprintf(q, "%c", polarization);
+@@ -662,6 +695,7 @@
+ ST(" S ") q += PrintParameter(q, 'S', MapToUser(system, SystemValues));
+ ST(" T") q += PrintParameter(q, 'T', MapToUser(transmission, TransmissionValues));
+ ST(" T") q += PrintParameter(q, 'Y', MapToUser(hierarchy, HierarchyValues));
++ ST("P ") snprintf(buffer, sizeof(buffer), "%s", pluginParam);
+ return buffer;
+ }
+
+@@ -690,7 +724,7 @@
+
+ bool cChannel::StringToParameters(const char *s)
+ {
+- while (s && *s) {
++ while (s && *s && !IsPlug()) {
+ switch (toupper(*s)) {
+ case 'A': s = SkipDigits(s); break; // for compatibility with the "multiproto" approach - may be removed in future versions
+ case 'B': s = ParseParameter(s, bandwidth, BandwidthValues); break;
+@@ -808,7 +842,7 @@
+ dpids[0] = 0;
+ ok = false;
+ if (parambuf && sourcebuf && vpidbuf && apidbuf) {
+- ok = StringToParameters(parambuf) && (source = cSource::FromString(sourcebuf)) >= 0;
++ ok = ((source = cSource::FromString(sourcebuf)) >= 0) && StringToParameters(parambuf);
+
+ char *p;
+ if ((p = strchr(vpidbuf, '=')) != NULL) {
+@@ -903,6 +937,7 @@
+ shortName = strcpyrealloc(shortName, p);
+ }
+ name = strcpyrealloc(name, namebuf);
++ if (IsPlug()) pluginParam = strcpyrealloc(pluginParam, parambuf);
+
+ free(parambuf);
+ free(sourcebuf);
+diff -Nru vdr-1.7.9-vanilla/channels.h vdr-1.7.9-pluginsparam/channels.h
+--- vdr-1.7.9-vanilla/channels.h 2009-08-23 18:12:32.000000000 +0300
++++ vdr-1.7.9-pluginsparam/channels.h 2009-08-23 18:18:54.000000000 +0300
+@@ -116,6 +116,7 @@
+ char *shortName;
+ char *provider;
+ char *portalName;
++ char *pluginParam;
+ int __BeginData__;
+ int frequency; // MHz
+ int source;
+@@ -174,6 +175,7 @@
+ int Frequency(void) const { return frequency; } ///< Returns the actual frequency, as given in 'channels.conf'
+ int Transponder(void) const; ///< Returns the transponder frequency in MHz, plus the polarization in case of sat
+ static int Transponder(int Frequency, char Polarization); ///< builds the transponder from the given Frequency and Polarization
++ const char *PluginParam(void) const { return pluginParam; }
+ int Source(void) const { return source; }
+ int Srate(void) const { return srate; }
+ int Vpid(void) const { return vpid; }
+@@ -214,6 +216,7 @@
+ int RollOff(void) const { return rollOff; }
+ const cLinkChannels* LinkChannels(void) const { return linkChannels; }
+ const cChannel *RefChannel(void) const { return refChannel; }
++ bool IsPlug(void) const { return cSource::IsPlug(source); }
+ bool IsCable(void) const { return cSource::IsCable(source); }
+ bool IsSat(void) const { return cSource::IsSat(source); }
+ bool IsTerr(void) const { return cSource::IsTerr(source); }
+@@ -221,12 +224,14 @@
+ bool HasTimer(void) const;
+ int Modification(int Mask = CHANNELMOD_ALL);
+ void CopyTransponderData(const cChannel *Channel);
++ bool SetPlugTransponderData(int Source, int Frequency, const char *PluginParam);
+ bool SetSatTransponderData(int Source, int Frequency, char Polarization, int Srate, int CoderateH, int Modulation, int System, int RollOff);
+ bool SetCableTransponderData(int Source, int Frequency, int Modulation, int Srate, int CoderateH);
+ bool SetTerrTransponderData(int Source, int Frequency, int Bandwidth, int Modulation, int Hierarchy, int CodeRateH, int CodeRateL, int Guard, int Transmission);
+ void SetId(int Nid, int Tid, int Sid, int Rid = 0);
+ void SetName(const char *Name, const char *ShortName, const char *Provider);
+ void SetPortalName(const char *PortalName);
++ void SetPluginParam(const char *PluginParam);
+ void SetPids(int Vpid, int Ppid, int Vtype, int *Apids, char ALangs[][MAXLANGCODE2], int *Dpids, char DLangs[][MAXLANGCODE2], int *Spids, char SLangs[][MAXLANGCODE2], int Tpid);
+ void SetCaIds(const int *CaIds); // list must be zero-terminated
+ void SetCaDescriptors(int Level);
+diff -Nru vdr-1.7.9-vanilla/config.h vdr-1.7.9-pluginsparam/config.h
+--- vdr-1.7.9-vanilla/config.h 2009-08-23 18:12:32.000000000 +0300
++++ vdr-1.7.9-pluginsparam/config.h 2009-08-23 18:18:54.000000000 +0300
+@@ -30,6 +30,8 @@
+ #define APIVERSION "1.7.9"
+ #define APIVERSNUM 10709 // Version * 10000 + Major * 100 + Minor
+
++#define PLUGINPARAMPATCHVERSNUM 1
++
+ // When loading plugins, VDR searches them by their APIVERSION, which
+ // may be smaller than VDRVERSION in case there have been no changes to
+ // VDR header files since the last APIVERSION. This allows compiled
+diff -Nru vdr-1.7.9-vanilla/menu.c vdr-1.7.9-pluginsparam/menu.c
+--- vdr-1.7.9-vanilla/menu.c 2009-08-23 18:12:32.000000000 +0300
++++ vdr-1.7.9-pluginsparam/menu.c 2009-08-23 18:18:54.000000000 +0300
+@@ -190,6 +190,7 @@
+ cChannel *channel;
+ cChannel data;
+ char name[256];
++ char pluginParam[256];
+ void Setup(void);
+ public:
+ cMenuEditChannel(cChannel *Channel, bool New = false);
+@@ -222,6 +223,7 @@
+
+ // Parameters for all types of sources:
+ strn0cpy(name, data.name, sizeof(name));
++ strn0cpy(pluginParam, data.pluginParam, sizeof(pluginParam));
+ Add(new cMenuEditStrItem( tr("Name"), name, sizeof(name)));
+ Add(new cMenuEditSrcItem( tr("Source"), &data.source));
+ Add(new cMenuEditIntItem( tr("Frequency"), &data.frequency));
+@@ -254,6 +256,7 @@
+ ST(" T") Add(new cMenuEditMapItem( tr("Guard"), &data.guard, GuardValues));
+ ST(" T") Add(new cMenuEditMapItem( tr("Hierarchy"), &data.hierarchy, HierarchyValues));
+ ST(" S ") Add(new cMenuEditMapItem( tr("Rolloff"), &data.rollOff, RollOffValues));
++ ST("P ") Add(new cMenuEditStrItem( tr("Parameters"), pluginParam, sizeof(pluginParam), tr(FileNameChars)));
+
+ SetCurrent(Get(current));
+ Display();
+@@ -268,6 +271,7 @@
+ if (Key == kOk) {
+ if (Channels.HasUniqueChannelID(&data, channel)) {
+ data.name = strcpyrealloc(data.name, name);
++ data.pluginParam = strcpyrealloc(data.pluginParam, pluginParam);
+ if (channel) {
+ *channel = data;
+ isyslog("edited channel %d %s", channel->Number(), *data.ToText());
+diff -Nru vdr-1.7.9-vanilla/po/fi_FI.po vdr-1.7.9-pluginsparam/po/fi_FI.po
+--- vdr-1.7.9-vanilla/po/fi_FI.po 2009-08-23 18:12:33.000000000 +0300
++++ vdr-1.7.9-pluginsparam/po/fi_FI.po 2009-08-23 18:18:54.000000000 +0300
+@@ -1025,3 +1025,6 @@
+ #, c-format
+ msgid "VDR will shut down in %s minutes"
+ msgstr "VDR sammuu %s minuutin kuluttua"
++
++msgid "Parameters"
++msgstr "Parametrit"
+diff -Nru vdr-1.7.9-vanilla/po/fr_FR.po vdr-1.7.9-pluginsparam/po/fr_FR.po
+--- vdr-1.7.9-vanilla/po/fr_FR.po 2009-08-23 18:12:33.000000000 +0300
++++ vdr-1.7.9-pluginsparam/po/fr_FR.po 2009-08-23 18:18:54.000000000 +0300
+@@ -1028,3 +1028,6 @@
+ #, c-format
+ msgid "VDR will shut down in %s minutes"
+ msgstr "VDR s'arrêtera dans %s minutes"
++
++msgid "Parameters"
++msgstr "Paramètres"
+diff -Nru vdr-1.7.9-vanilla/sources.c vdr-1.7.9-pluginsparam/sources.c
+--- vdr-1.7.9-vanilla/sources.c 2009-08-23 18:12:32.000000000 +0300
++++ vdr-1.7.9-pluginsparam/sources.c 2009-08-23 18:18:54.000000000 +0300
+@@ -37,6 +37,7 @@
+ char buffer[16];
+ char *q = buffer;
+ switch (Code & st_Mask) {
++ case stPlug: *q++ = 'P'; break;
+ case stCable: *q++ = 'C'; break;
+ case stSat: *q++ = 'S';
+ {
+@@ -56,6 +57,7 @@
+ {
+ int type = stNone;
+ switch (toupper(*s)) {
++ case 'P': type = stPlug; break;
+ case 'C': type = stCable; break;
+ case 'S': type = stSat; break;
+ case 'T': type = stTerr; break;
+diff -Nru vdr-1.7.9-vanilla/sources.conf vdr-1.7.9-pluginsparam/sources.conf
+--- vdr-1.7.9-vanilla/sources.conf 2009-08-23 18:12:32.000000000 +0300
++++ vdr-1.7.9-pluginsparam/sources.conf 2009-08-23 18:18:54.000000000 +0300
+@@ -194,3 +194,7 @@
+ # Terrestrial
+
+ T Terrestrial
++
++# Plugin
++
++P Plugin
+diff -Nru vdr-1.7.9-vanilla/sources.h vdr-1.7.9-pluginsparam/sources.h
+--- vdr-1.7.9-vanilla/sources.h 2009-08-23 18:12:32.000000000 +0300
++++ vdr-1.7.9-pluginsparam/sources.h 2009-08-23 18:18:54.000000000 +0300
+@@ -16,10 +16,11 @@
+ public:
+ enum eSourceType {
+ stNone = 0x0000,
++ stPlug = 0x2000,
+ stCable = 0x4000,
+ stSat = 0x8000,
+ stTerr = 0xC000,
+- st_Mask = 0xC000,
++ st_Mask = 0xE000,
+ st_Neg = 0x0800,
+ st_Pos = 0x07FF,
+ };
+@@ -35,6 +36,7 @@
+ static cString ToString(int Code);
+ static int FromString(const char *s);
+ static int FromData(eSourceType SourceType, int Position = 0, bool East = false);
++ static bool IsPlug(int Code) { return (Code & st_Mask) == stPlug; }
+ static bool IsCable(int Code) { return (Code & st_Mask) == stCable; }
+ static bool IsSat(int Code) { return (Code & st_Mask) == stSat; }
+ static bool IsTerr(int Code) { return (Code & st_Mask) == stTerr; }
diff --git a/po/ca_ES.po b/po/ca_ES.po
new file mode 100644
index 0000000..33bd23b
--- /dev/null
+++ b/po/ca_ES.po
@@ -0,0 +1,194 @@
+# translation of pvrinput.po to
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pvrinput\n"
+"Report-Msgid-Bugs-To: <see README>\n"
+"POT-Creation-Date: 2010-03-07 11:36+0100\n"
+"PO-Revision-Date: 2008-05-24 13:29+0200\n"
+"Last-Translator: root\n"
+"Language-Team: <de@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+
+msgid "SourceParam.pvrinput$Input"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Card"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Standard"
+msgstr ""
+
+msgid "pvrinput no longer supports old channel syntax!"
+msgstr ""
+
+msgid "Setup.pvrinput$manual"
+msgstr ""
+
+msgid "Setup.pvrinput$auto"
+msgstr ""
+
+msgid "Setup.pvrinput$off"
+msgstr ""
+
+msgid "Setup.pvrinput$1D horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$1D vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$2D hv separable"
+msgstr ""
+
+msgid "Setup.pvrinput$2D sym non separable"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal + vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$diagonal"
+msgstr ""
+
+msgid "Setup.pvrinput$44.1 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$48 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$32 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$AAC"
+msgstr ""
+
+msgid "Setup.pvrinput$AC3"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA back"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA front"
+msgstr ""
+
+msgid "Setup.pvrinput$SPDIF"
+msgstr ""
+
+msgid "Setup.pvrinput$Hide main menu entry"
+msgstr ""
+
+msgid "Setup.pvrinput$Use only card"
+msgstr ""
+
+msgid "Setup.pvrinput$Log level"
+msgstr ""
+
+msgid "Setup.pvrinput$Slice VBI Teletext"
+msgstr ""
+
+msgid "Setup.pvrinput$Tuner Audio Mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Brightness"
+msgstr ""
+
+msgid "Setup.pvrinput$Contrast"
+msgstr ""
+
+msgid "Setup.pvrinput$Saturation"
+msgstr ""
+
+msgid "Setup.pvrinput$Hue"
+msgstr ""
+
+msgid "Setup.pvrinput$Common Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception TV Volume for Card"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio radio volume"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio bitrate (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio sampling rate"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio encoding"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio input"
+msgstr ""
+
+msgid "Setup.pvrinput$Video bitrate TV (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Bitrate mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Aspect ratio"
+msgstr ""
+
+msgid "Setup.pvrinput$Stream type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Median Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$use externchannelswitch.sh"
+msgstr ""
+
+msgid "use Hauppauge PVR as input device"
+msgstr ""
+
+msgid "PVR picture settings"
+msgstr ""
+
+msgid "Setup.pvrinput$Not on an analogue channel!"
+msgstr ""
diff --git a/po/cs_CZ.po b/po/cs_CZ.po
new file mode 100644
index 0000000..2be10cd
--- /dev/null
+++ b/po/cs_CZ.po
@@ -0,0 +1,195 @@
+# translation of cs_CZ.po to
+# translation of pvrinput.po to
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: cs_CZ\n"
+"Report-Msgid-Bugs-To: <see README>\n"
+"POT-Creation-Date: 2010-03-07 11:36+0100\n"
+"PO-Revision-Date: 2008-05-24 13:36+0200\n"
+"Last-Translator: root\n"
+"Language-Team: <de@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+
+msgid "SourceParam.pvrinput$Input"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Card"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Standard"
+msgstr ""
+
+msgid "pvrinput no longer supports old channel syntax!"
+msgstr ""
+
+msgid "Setup.pvrinput$manual"
+msgstr ""
+
+msgid "Setup.pvrinput$auto"
+msgstr ""
+
+msgid "Setup.pvrinput$off"
+msgstr ""
+
+msgid "Setup.pvrinput$1D horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$1D vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$2D hv separable"
+msgstr ""
+
+msgid "Setup.pvrinput$2D sym non separable"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal + vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$diagonal"
+msgstr ""
+
+msgid "Setup.pvrinput$44.1 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$48 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$32 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$AAC"
+msgstr ""
+
+msgid "Setup.pvrinput$AC3"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA back"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA front"
+msgstr ""
+
+msgid "Setup.pvrinput$SPDIF"
+msgstr ""
+
+msgid "Setup.pvrinput$Hide main menu entry"
+msgstr ""
+
+msgid "Setup.pvrinput$Use only card"
+msgstr ""
+
+msgid "Setup.pvrinput$Log level"
+msgstr ""
+
+msgid "Setup.pvrinput$Slice VBI Teletext"
+msgstr ""
+
+msgid "Setup.pvrinput$Tuner Audio Mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Brightness"
+msgstr ""
+
+msgid "Setup.pvrinput$Contrast"
+msgstr ""
+
+msgid "Setup.pvrinput$Saturation"
+msgstr ""
+
+msgid "Setup.pvrinput$Hue"
+msgstr ""
+
+msgid "Setup.pvrinput$Common Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception TV Volume for Card"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio radio volume"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio bitrate (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio sampling rate"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio encoding"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio input"
+msgstr ""
+
+msgid "Setup.pvrinput$Video bitrate TV (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Bitrate mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Aspect ratio"
+msgstr ""
+
+msgid "Setup.pvrinput$Stream type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Median Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$use externchannelswitch.sh"
+msgstr ""
+
+msgid "use Hauppauge PVR as input device"
+msgstr ""
+
+msgid "PVR picture settings"
+msgstr ""
+
+msgid "Setup.pvrinput$Not on an analogue channel!"
+msgstr ""
diff --git a/po/da_DK.po b/po/da_DK.po
new file mode 100644
index 0000000..3e5bcf4
--- /dev/null
+++ b/po/da_DK.po
@@ -0,0 +1,194 @@
+# translation of pvrinput.po to
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pvrinput\n"
+"Report-Msgid-Bugs-To: <see README>\n"
+"POT-Creation-Date: 2010-03-07 11:36+0100\n"
+"PO-Revision-Date: 2008-05-24 13:33+0200\n"
+"Last-Translator: root\n"
+"Language-Team: <de@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+
+msgid "SourceParam.pvrinput$Input"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Card"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Standard"
+msgstr ""
+
+msgid "pvrinput no longer supports old channel syntax!"
+msgstr ""
+
+msgid "Setup.pvrinput$manual"
+msgstr ""
+
+msgid "Setup.pvrinput$auto"
+msgstr ""
+
+msgid "Setup.pvrinput$off"
+msgstr ""
+
+msgid "Setup.pvrinput$1D horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$1D vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$2D hv separable"
+msgstr ""
+
+msgid "Setup.pvrinput$2D sym non separable"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal + vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$diagonal"
+msgstr ""
+
+msgid "Setup.pvrinput$44.1 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$48 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$32 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$AAC"
+msgstr ""
+
+msgid "Setup.pvrinput$AC3"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA back"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA front"
+msgstr ""
+
+msgid "Setup.pvrinput$SPDIF"
+msgstr ""
+
+msgid "Setup.pvrinput$Hide main menu entry"
+msgstr ""
+
+msgid "Setup.pvrinput$Use only card"
+msgstr ""
+
+msgid "Setup.pvrinput$Log level"
+msgstr ""
+
+msgid "Setup.pvrinput$Slice VBI Teletext"
+msgstr ""
+
+msgid "Setup.pvrinput$Tuner Audio Mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Brightness"
+msgstr ""
+
+msgid "Setup.pvrinput$Contrast"
+msgstr ""
+
+msgid "Setup.pvrinput$Saturation"
+msgstr ""
+
+msgid "Setup.pvrinput$Hue"
+msgstr ""
+
+msgid "Setup.pvrinput$Common Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception TV Volume for Card"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio radio volume"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio bitrate (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio sampling rate"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio encoding"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio input"
+msgstr ""
+
+msgid "Setup.pvrinput$Video bitrate TV (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Bitrate mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Aspect ratio"
+msgstr ""
+
+msgid "Setup.pvrinput$Stream type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Median Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$use externchannelswitch.sh"
+msgstr ""
+
+msgid "use Hauppauge PVR as input device"
+msgstr ""
+
+msgid "PVR picture settings"
+msgstr ""
+
+msgid "Setup.pvrinput$Not on an analogue channel!"
+msgstr ""
diff --git a/po/de_DE.po b/po/de_DE.po
new file mode 100644
index 0000000..9ba433c
--- /dev/null
+++ b/po/de_DE.po
@@ -0,0 +1,203 @@
+# translation of de_DE.po to
+# pvrinput
+# Copyright (C) 2007 Andreas Regel, Martin Dauskardt, Winfried Köhler
+# This file is distributed under the same license as the PACKAGE package.
+#
+#
+# Andreas Regel, Martin Dauskardt, Winfried Köhler <see README>, 2007.
+# Martin Dauskardt <martin.dauskardt@gmx.de>, 2008.
+msgid ""
+msgstr ""
+"Project-Id-Version: de_DE\n"
+"Report-Msgid-Bugs-To: <see README>\n"
+"POT-Creation-Date: 2010-03-07 11:36+0100\n"
+"PO-Revision-Date: 2009-10-11 22:39+0200\n"
+"Last-Translator: root\n"
+"Language-Team: <de@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-15\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+
+msgid "SourceParam.pvrinput$Input"
+msgstr "Eingang"
+
+msgid "SourceParam.pvrinput$Card"
+msgstr "Karte"
+
+msgid "SourceParam.pvrinput$Standard"
+msgstr "Standard"
+
+msgid "pvrinput no longer supports old channel syntax!"
+msgstr "pvrinput unterstützt alte Kanalsyntax nicht mehr!"
+
+msgid "Setup.pvrinput$manual"
+msgstr "manuell"
+
+msgid "Setup.pvrinput$auto"
+msgstr "auto"
+
+msgid "Setup.pvrinput$off"
+msgstr "aus"
+
+msgid "Setup.pvrinput$1D horizontal"
+msgstr "1D horizontal"
+
+msgid "Setup.pvrinput$1D vertical"
+msgstr "1D vertikal"
+
+msgid "Setup.pvrinput$2D hv separable"
+msgstr "2D hv separat"
+
+msgid "Setup.pvrinput$2D sym non separable"
+msgstr "2D sym kombiniert"
+
+msgid "Setup.pvrinput$horizontal"
+msgstr "horizontal"
+
+msgid "Setup.pvrinput$vertical"
+msgstr "vertikal"
+
+msgid "Setup.pvrinput$horizontal + vertical"
+msgstr "horizontal + vertikal"
+
+msgid "Setup.pvrinput$diagonal"
+msgstr "diagonal"
+
+msgid "Setup.pvrinput$44.1 kHz"
+msgstr "44,1 kHz"
+
+msgid "Setup.pvrinput$48 kHz"
+msgstr "48 kHz"
+
+msgid "Setup.pvrinput$32 kHz"
+msgstr "32 kHz"
+
+msgid "Setup.pvrinput$AAC"
+msgstr "AAC"
+
+msgid "Setup.pvrinput$AC3"
+msgstr "AC3"
+
+msgid "Setup.pvrinput$RCA back"
+msgstr "Cinch (hinten)"
+
+msgid "Setup.pvrinput$RCA front"
+msgstr "Cinch (vorne)"
+
+msgid "Setup.pvrinput$SPDIF"
+msgstr "S/PDIF"
+
+msgid "Setup.pvrinput$Hide main menu entry"
+msgstr "Hauptmenü-Eintrag verstecken"
+
+msgid "Setup.pvrinput$Use only card"
+msgstr "verwende nur Karte"
+
+msgid "Setup.pvrinput$Log level"
+msgstr "Umfang log"
+
+msgid "Setup.pvrinput$Slice VBI Teletext"
+msgstr "Teletext durchschleifen"
+
+msgid "Setup.pvrinput$Tuner Audio Mode"
+msgstr "Tuner Audio Mode"
+
+msgid "Setup.pvrinput$Brightness"
+msgstr "Helligkeit"
+
+msgid "Setup.pvrinput$Contrast"
+msgstr "Kontrast"
+
+msgid "Setup.pvrinput$Saturation"
+msgstr "Sättigung"
+
+msgid "Setup.pvrinput$Hue"
+msgstr "Farbton"
+
+msgid "Setup.pvrinput$Common Audio volume (TV)"
+msgstr "allg. TV-Lautstärke"
+
+msgid "Setup.pvrinput$Exception Audio volume (TV)"
+msgstr "abw. TV Lautstärke"
+
+msgid "Setup.pvrinput$Exception TV Volume for Card"
+msgstr "abw. TV-Lautstärke für Karte"
+
+msgid "Setup.pvrinput$Audio radio volume"
+msgstr "FM Radio Lautstärke"
+
+msgid "Setup.pvrinput$Audio bitrate (kbit/s)"
+msgstr "Audio Bitrate (kbit/s)"
+
+msgid "Setup.pvrinput$Audio sampling rate"
+msgstr "Audio Abtastrate"
+
+msgid "Setup.pvrinput$HDPVR audio encoding"
+msgstr "HDPVR Audio Encoding"
+
+msgid "Setup.pvrinput$HDPVR audio input"
+msgstr "HDPVR Audioeingang"
+
+msgid "Setup.pvrinput$Video bitrate TV (kbit/s)"
+msgstr "Video Bitrate TV (kbit/s)"
+
+msgid "Setup.pvrinput$Bitrate mode"
+msgstr "Bitraten Modus"
+
+msgid "Setup.pvrinput$Aspect ratio"
+msgstr "Seitenverhältnis"
+
+msgid "Setup.pvrinput$Stream type"
+msgstr "Stream Typ"
+
+msgid "Setup.pvrinput$Mode Spatial Video Filter"
+msgstr "Modus Spatial Video Filter"
+
+msgid "Setup.pvrinput$Strength Spatial Video Filter"
+msgstr "Stärke Spatial Video Filter"
+
+msgid "Setup.pvrinput$Luma Spatial Filter Type"
+msgstr "Helligkeit Spatial Filter Typ"
+
+msgid "Setup.pvrinput$Chroma Spatial Filter Type"
+msgstr "Farben Spatial Filter Typ"
+
+msgid "Setup.pvrinput$Mode Temporal Video Filter"
+msgstr "Modus Temporal Video Filter"
+
+msgid "Setup.pvrinput$Strength Temporal Video Filter"
+msgstr "Stärke Temporal Video Filter"
+
+msgid "Setup.pvrinput$Median Filter Type"
+msgstr "Median Filter Typ"
+
+msgid "Setup.pvrinput$Luma Median Filter Bottom"
+msgstr "Luma Median Filter Unten"
+
+msgid "Setup.pvrinput$Luma Median Filter Top"
+msgstr "Luma Median Filter Oben"
+
+msgid "Setup.pvrinput$Chroma Median Filter Bottom"
+msgstr "Chroma Median Filter Unten"
+
+msgid "Setup.pvrinput$Chroma Median Filter Top"
+msgstr "Chroma Median Filter Oben"
+
+msgid "Setup.pvrinput$use externchannelswitch.sh"
+msgstr "benutze externchannelswitch.sh"
+
+msgid "use Hauppauge PVR as input device"
+msgstr "Hauppauge PVR als Eingabegerät "
+
+msgid "PVR picture settings"
+msgstr "PVR Bildeinstellungen "
+
+msgid "Setup.pvrinput$Not on an analogue channel!"
+msgstr "Kein analog empfangener Sender!"
+
+#~ msgid "Setup.pvrinput$PVRUSB2 Stop on Change"
+#~ msgstr "PVRUSB2 Stop bei Kanalwechsel"
+
+#~ msgid "Setup.pvrinput$Video bitrate Radio (kbit/s)"
+#~ msgstr "Video Bitrate Radio (kbit/s)"
diff --git a/po/el_GR.po b/po/el_GR.po
new file mode 100644
index 0000000..3e5bcf4
--- /dev/null
+++ b/po/el_GR.po
@@ -0,0 +1,194 @@
+# translation of pvrinput.po to
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pvrinput\n"
+"Report-Msgid-Bugs-To: <see README>\n"
+"POT-Creation-Date: 2010-03-07 11:36+0100\n"
+"PO-Revision-Date: 2008-05-24 13:33+0200\n"
+"Last-Translator: root\n"
+"Language-Team: <de@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+
+msgid "SourceParam.pvrinput$Input"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Card"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Standard"
+msgstr ""
+
+msgid "pvrinput no longer supports old channel syntax!"
+msgstr ""
+
+msgid "Setup.pvrinput$manual"
+msgstr ""
+
+msgid "Setup.pvrinput$auto"
+msgstr ""
+
+msgid "Setup.pvrinput$off"
+msgstr ""
+
+msgid "Setup.pvrinput$1D horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$1D vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$2D hv separable"
+msgstr ""
+
+msgid "Setup.pvrinput$2D sym non separable"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal + vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$diagonal"
+msgstr ""
+
+msgid "Setup.pvrinput$44.1 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$48 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$32 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$AAC"
+msgstr ""
+
+msgid "Setup.pvrinput$AC3"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA back"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA front"
+msgstr ""
+
+msgid "Setup.pvrinput$SPDIF"
+msgstr ""
+
+msgid "Setup.pvrinput$Hide main menu entry"
+msgstr ""
+
+msgid "Setup.pvrinput$Use only card"
+msgstr ""
+
+msgid "Setup.pvrinput$Log level"
+msgstr ""
+
+msgid "Setup.pvrinput$Slice VBI Teletext"
+msgstr ""
+
+msgid "Setup.pvrinput$Tuner Audio Mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Brightness"
+msgstr ""
+
+msgid "Setup.pvrinput$Contrast"
+msgstr ""
+
+msgid "Setup.pvrinput$Saturation"
+msgstr ""
+
+msgid "Setup.pvrinput$Hue"
+msgstr ""
+
+msgid "Setup.pvrinput$Common Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception TV Volume for Card"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio radio volume"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio bitrate (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio sampling rate"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio encoding"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio input"
+msgstr ""
+
+msgid "Setup.pvrinput$Video bitrate TV (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Bitrate mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Aspect ratio"
+msgstr ""
+
+msgid "Setup.pvrinput$Stream type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Median Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$use externchannelswitch.sh"
+msgstr ""
+
+msgid "use Hauppauge PVR as input device"
+msgstr ""
+
+msgid "PVR picture settings"
+msgstr ""
+
+msgid "Setup.pvrinput$Not on an analogue channel!"
+msgstr ""
diff --git a/po/es_ES.po b/po/es_ES.po
new file mode 100644
index 0000000..807cbab
--- /dev/null
+++ b/po/es_ES.po
@@ -0,0 +1,195 @@
+# translation of es_ES.po to
+# translation of pvrinput.po to
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: es_ES\n"
+"Report-Msgid-Bugs-To: <see README>\n"
+"POT-Creation-Date: 2010-03-07 11:36+0100\n"
+"PO-Revision-Date: 2008-05-24 13:37+0200\n"
+"Last-Translator: root\n"
+"Language-Team: <de@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+
+msgid "SourceParam.pvrinput$Input"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Card"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Standard"
+msgstr ""
+
+msgid "pvrinput no longer supports old channel syntax!"
+msgstr ""
+
+msgid "Setup.pvrinput$manual"
+msgstr ""
+
+msgid "Setup.pvrinput$auto"
+msgstr ""
+
+msgid "Setup.pvrinput$off"
+msgstr ""
+
+msgid "Setup.pvrinput$1D horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$1D vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$2D hv separable"
+msgstr ""
+
+msgid "Setup.pvrinput$2D sym non separable"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal + vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$diagonal"
+msgstr ""
+
+msgid "Setup.pvrinput$44.1 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$48 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$32 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$AAC"
+msgstr ""
+
+msgid "Setup.pvrinput$AC3"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA back"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA front"
+msgstr ""
+
+msgid "Setup.pvrinput$SPDIF"
+msgstr ""
+
+msgid "Setup.pvrinput$Hide main menu entry"
+msgstr ""
+
+msgid "Setup.pvrinput$Use only card"
+msgstr ""
+
+msgid "Setup.pvrinput$Log level"
+msgstr ""
+
+msgid "Setup.pvrinput$Slice VBI Teletext"
+msgstr ""
+
+msgid "Setup.pvrinput$Tuner Audio Mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Brightness"
+msgstr ""
+
+msgid "Setup.pvrinput$Contrast"
+msgstr ""
+
+msgid "Setup.pvrinput$Saturation"
+msgstr ""
+
+msgid "Setup.pvrinput$Hue"
+msgstr ""
+
+msgid "Setup.pvrinput$Common Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception TV Volume for Card"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio radio volume"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio bitrate (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio sampling rate"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio encoding"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio input"
+msgstr ""
+
+msgid "Setup.pvrinput$Video bitrate TV (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Bitrate mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Aspect ratio"
+msgstr ""
+
+msgid "Setup.pvrinput$Stream type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Median Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$use externchannelswitch.sh"
+msgstr ""
+
+msgid "use Hauppauge PVR as input device"
+msgstr ""
+
+msgid "PVR picture settings"
+msgstr ""
+
+msgid "Setup.pvrinput$Not on an analogue channel!"
+msgstr ""
diff --git a/po/et_EE.po b/po/et_EE.po
new file mode 100644
index 0000000..46c1f25
--- /dev/null
+++ b/po/et_EE.po
@@ -0,0 +1,195 @@
+# translation of et_EE.po to
+# translation of pvrinput.po to
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: et_EE\n"
+"Report-Msgid-Bugs-To: <see README>\n"
+"POT-Creation-Date: 2010-03-07 11:36+0100\n"
+"PO-Revision-Date: 2008-05-24 13:37+0200\n"
+"Last-Translator: root\n"
+"Language-Team: <de@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+
+msgid "SourceParam.pvrinput$Input"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Card"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Standard"
+msgstr ""
+
+msgid "pvrinput no longer supports old channel syntax!"
+msgstr ""
+
+msgid "Setup.pvrinput$manual"
+msgstr ""
+
+msgid "Setup.pvrinput$auto"
+msgstr ""
+
+msgid "Setup.pvrinput$off"
+msgstr ""
+
+msgid "Setup.pvrinput$1D horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$1D vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$2D hv separable"
+msgstr ""
+
+msgid "Setup.pvrinput$2D sym non separable"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal + vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$diagonal"
+msgstr ""
+
+msgid "Setup.pvrinput$44.1 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$48 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$32 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$AAC"
+msgstr ""
+
+msgid "Setup.pvrinput$AC3"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA back"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA front"
+msgstr ""
+
+msgid "Setup.pvrinput$SPDIF"
+msgstr ""
+
+msgid "Setup.pvrinput$Hide main menu entry"
+msgstr ""
+
+msgid "Setup.pvrinput$Use only card"
+msgstr ""
+
+msgid "Setup.pvrinput$Log level"
+msgstr ""
+
+msgid "Setup.pvrinput$Slice VBI Teletext"
+msgstr ""
+
+msgid "Setup.pvrinput$Tuner Audio Mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Brightness"
+msgstr ""
+
+msgid "Setup.pvrinput$Contrast"
+msgstr ""
+
+msgid "Setup.pvrinput$Saturation"
+msgstr ""
+
+msgid "Setup.pvrinput$Hue"
+msgstr ""
+
+msgid "Setup.pvrinput$Common Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception TV Volume for Card"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio radio volume"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio bitrate (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio sampling rate"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio encoding"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio input"
+msgstr ""
+
+msgid "Setup.pvrinput$Video bitrate TV (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Bitrate mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Aspect ratio"
+msgstr ""
+
+msgid "Setup.pvrinput$Stream type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Median Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$use externchannelswitch.sh"
+msgstr ""
+
+msgid "use Hauppauge PVR as input device"
+msgstr ""
+
+msgid "PVR picture settings"
+msgstr ""
+
+msgid "Setup.pvrinput$Not on an analogue channel!"
+msgstr ""
diff --git a/po/fi_FI.po b/po/fi_FI.po
new file mode 100644
index 0000000..2dbd747
--- /dev/null
+++ b/po/fi_FI.po
@@ -0,0 +1,195 @@
+# translation of fi_FI.po to
+# translation of pvrinput.po to
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: fi_FI\n"
+"Report-Msgid-Bugs-To: <see README>\n"
+"POT-Creation-Date: 2010-03-07 11:36+0100\n"
+"PO-Revision-Date: 2008-05-24 13:37+0200\n"
+"Last-Translator: root\n"
+"Language-Team: <de@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+
+msgid "SourceParam.pvrinput$Input"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Card"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Standard"
+msgstr ""
+
+msgid "pvrinput no longer supports old channel syntax!"
+msgstr ""
+
+msgid "Setup.pvrinput$manual"
+msgstr ""
+
+msgid "Setup.pvrinput$auto"
+msgstr ""
+
+msgid "Setup.pvrinput$off"
+msgstr ""
+
+msgid "Setup.pvrinput$1D horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$1D vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$2D hv separable"
+msgstr ""
+
+msgid "Setup.pvrinput$2D sym non separable"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal + vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$diagonal"
+msgstr ""
+
+msgid "Setup.pvrinput$44.1 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$48 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$32 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$AAC"
+msgstr ""
+
+msgid "Setup.pvrinput$AC3"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA back"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA front"
+msgstr ""
+
+msgid "Setup.pvrinput$SPDIF"
+msgstr ""
+
+msgid "Setup.pvrinput$Hide main menu entry"
+msgstr ""
+
+msgid "Setup.pvrinput$Use only card"
+msgstr ""
+
+msgid "Setup.pvrinput$Log level"
+msgstr ""
+
+msgid "Setup.pvrinput$Slice VBI Teletext"
+msgstr ""
+
+msgid "Setup.pvrinput$Tuner Audio Mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Brightness"
+msgstr ""
+
+msgid "Setup.pvrinput$Contrast"
+msgstr ""
+
+msgid "Setup.pvrinput$Saturation"
+msgstr ""
+
+msgid "Setup.pvrinput$Hue"
+msgstr ""
+
+msgid "Setup.pvrinput$Common Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception TV Volume for Card"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio radio volume"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio bitrate (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio sampling rate"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio encoding"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio input"
+msgstr ""
+
+msgid "Setup.pvrinput$Video bitrate TV (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Bitrate mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Aspect ratio"
+msgstr ""
+
+msgid "Setup.pvrinput$Stream type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Median Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$use externchannelswitch.sh"
+msgstr ""
+
+msgid "use Hauppauge PVR as input device"
+msgstr ""
+
+msgid "PVR picture settings"
+msgstr ""
+
+msgid "Setup.pvrinput$Not on an analogue channel!"
+msgstr ""
diff --git a/po/fr_FR.po b/po/fr_FR.po
new file mode 100644
index 0000000..1384019
--- /dev/null
+++ b/po/fr_FR.po
@@ -0,0 +1,195 @@
+# translation of fr_FR.po to
+# translation of pvrinput.po to
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: fr_FR\n"
+"Report-Msgid-Bugs-To: <see README>\n"
+"POT-Creation-Date: 2010-03-07 11:36+0100\n"
+"PO-Revision-Date: 2008-05-24 13:38+0200\n"
+"Last-Translator: root\n"
+"Language-Team: <de@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+
+msgid "SourceParam.pvrinput$Input"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Card"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Standard"
+msgstr ""
+
+msgid "pvrinput no longer supports old channel syntax!"
+msgstr ""
+
+msgid "Setup.pvrinput$manual"
+msgstr ""
+
+msgid "Setup.pvrinput$auto"
+msgstr ""
+
+msgid "Setup.pvrinput$off"
+msgstr ""
+
+msgid "Setup.pvrinput$1D horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$1D vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$2D hv separable"
+msgstr ""
+
+msgid "Setup.pvrinput$2D sym non separable"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal + vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$diagonal"
+msgstr ""
+
+msgid "Setup.pvrinput$44.1 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$48 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$32 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$AAC"
+msgstr ""
+
+msgid "Setup.pvrinput$AC3"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA back"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA front"
+msgstr ""
+
+msgid "Setup.pvrinput$SPDIF"
+msgstr ""
+
+msgid "Setup.pvrinput$Hide main menu entry"
+msgstr ""
+
+msgid "Setup.pvrinput$Use only card"
+msgstr ""
+
+msgid "Setup.pvrinput$Log level"
+msgstr ""
+
+msgid "Setup.pvrinput$Slice VBI Teletext"
+msgstr ""
+
+msgid "Setup.pvrinput$Tuner Audio Mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Brightness"
+msgstr ""
+
+msgid "Setup.pvrinput$Contrast"
+msgstr ""
+
+msgid "Setup.pvrinput$Saturation"
+msgstr ""
+
+msgid "Setup.pvrinput$Hue"
+msgstr ""
+
+msgid "Setup.pvrinput$Common Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception TV Volume for Card"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio radio volume"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio bitrate (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio sampling rate"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio encoding"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio input"
+msgstr ""
+
+msgid "Setup.pvrinput$Video bitrate TV (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Bitrate mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Aspect ratio"
+msgstr ""
+
+msgid "Setup.pvrinput$Stream type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Median Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$use externchannelswitch.sh"
+msgstr ""
+
+msgid "use Hauppauge PVR as input device"
+msgstr ""
+
+msgid "PVR picture settings"
+msgstr ""
+
+msgid "Setup.pvrinput$Not on an analogue channel!"
+msgstr ""
diff --git a/po/hr_HR.po b/po/hr_HR.po
new file mode 100644
index 0000000..ee1c4ee
--- /dev/null
+++ b/po/hr_HR.po
@@ -0,0 +1,194 @@
+# translation of pvrinput.po to
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pvrinput\n"
+"Report-Msgid-Bugs-To: <see README>\n"
+"POT-Creation-Date: 2010-03-07 11:36+0100\n"
+"PO-Revision-Date: 2008-05-24 13:38+0200\n"
+"Last-Translator: root\n"
+"Language-Team: <de@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+
+msgid "SourceParam.pvrinput$Input"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Card"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Standard"
+msgstr ""
+
+msgid "pvrinput no longer supports old channel syntax!"
+msgstr ""
+
+msgid "Setup.pvrinput$manual"
+msgstr ""
+
+msgid "Setup.pvrinput$auto"
+msgstr ""
+
+msgid "Setup.pvrinput$off"
+msgstr ""
+
+msgid "Setup.pvrinput$1D horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$1D vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$2D hv separable"
+msgstr ""
+
+msgid "Setup.pvrinput$2D sym non separable"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal + vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$diagonal"
+msgstr ""
+
+msgid "Setup.pvrinput$44.1 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$48 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$32 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$AAC"
+msgstr ""
+
+msgid "Setup.pvrinput$AC3"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA back"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA front"
+msgstr ""
+
+msgid "Setup.pvrinput$SPDIF"
+msgstr ""
+
+msgid "Setup.pvrinput$Hide main menu entry"
+msgstr ""
+
+msgid "Setup.pvrinput$Use only card"
+msgstr ""
+
+msgid "Setup.pvrinput$Log level"
+msgstr ""
+
+msgid "Setup.pvrinput$Slice VBI Teletext"
+msgstr ""
+
+msgid "Setup.pvrinput$Tuner Audio Mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Brightness"
+msgstr ""
+
+msgid "Setup.pvrinput$Contrast"
+msgstr ""
+
+msgid "Setup.pvrinput$Saturation"
+msgstr ""
+
+msgid "Setup.pvrinput$Hue"
+msgstr ""
+
+msgid "Setup.pvrinput$Common Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception TV Volume for Card"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio radio volume"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio bitrate (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio sampling rate"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio encoding"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio input"
+msgstr ""
+
+msgid "Setup.pvrinput$Video bitrate TV (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Bitrate mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Aspect ratio"
+msgstr ""
+
+msgid "Setup.pvrinput$Stream type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Median Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$use externchannelswitch.sh"
+msgstr ""
+
+msgid "use Hauppauge PVR as input device"
+msgstr ""
+
+msgid "PVR picture settings"
+msgstr ""
+
+msgid "Setup.pvrinput$Not on an analogue channel!"
+msgstr ""
diff --git a/po/hu_HU.po b/po/hu_HU.po
new file mode 100644
index 0000000..9bcd226
--- /dev/null
+++ b/po/hu_HU.po
@@ -0,0 +1,194 @@
+# translation of pvrinput.po to
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pvrinput\n"
+"Report-Msgid-Bugs-To: <see README>\n"
+"POT-Creation-Date: 2010-03-07 11:36+0100\n"
+"PO-Revision-Date: 2008-05-24 13:39+0200\n"
+"Last-Translator: root\n"
+"Language-Team: <de@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+
+msgid "SourceParam.pvrinput$Input"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Card"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Standard"
+msgstr ""
+
+msgid "pvrinput no longer supports old channel syntax!"
+msgstr ""
+
+msgid "Setup.pvrinput$manual"
+msgstr ""
+
+msgid "Setup.pvrinput$auto"
+msgstr ""
+
+msgid "Setup.pvrinput$off"
+msgstr ""
+
+msgid "Setup.pvrinput$1D horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$1D vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$2D hv separable"
+msgstr ""
+
+msgid "Setup.pvrinput$2D sym non separable"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal + vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$diagonal"
+msgstr ""
+
+msgid "Setup.pvrinput$44.1 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$48 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$32 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$AAC"
+msgstr ""
+
+msgid "Setup.pvrinput$AC3"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA back"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA front"
+msgstr ""
+
+msgid "Setup.pvrinput$SPDIF"
+msgstr ""
+
+msgid "Setup.pvrinput$Hide main menu entry"
+msgstr ""
+
+msgid "Setup.pvrinput$Use only card"
+msgstr ""
+
+msgid "Setup.pvrinput$Log level"
+msgstr ""
+
+msgid "Setup.pvrinput$Slice VBI Teletext"
+msgstr ""
+
+msgid "Setup.pvrinput$Tuner Audio Mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Brightness"
+msgstr ""
+
+msgid "Setup.pvrinput$Contrast"
+msgstr ""
+
+msgid "Setup.pvrinput$Saturation"
+msgstr ""
+
+msgid "Setup.pvrinput$Hue"
+msgstr ""
+
+msgid "Setup.pvrinput$Common Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception TV Volume for Card"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio radio volume"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio bitrate (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio sampling rate"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio encoding"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio input"
+msgstr ""
+
+msgid "Setup.pvrinput$Video bitrate TV (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Bitrate mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Aspect ratio"
+msgstr ""
+
+msgid "Setup.pvrinput$Stream type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Median Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$use externchannelswitch.sh"
+msgstr ""
+
+msgid "use Hauppauge PVR as input device"
+msgstr ""
+
+msgid "PVR picture settings"
+msgstr ""
+
+msgid "Setup.pvrinput$Not on an analogue channel!"
+msgstr ""
diff --git a/po/i18n-template.c b/po/i18n-template.c
new file mode 100644
index 0000000..6dd223a
--- /dev/null
+++ b/po/i18n-template.c
@@ -0,0 +1,22 @@
+/*
+ * pvrinput: A plugin for the Video Disk Recorder
+ * Copyright (C) 2007 Andreas Regel, Martin Dauskardt, Winfried Koehler
+ * Licence GPL
+ *
+ * See the README file for copyright information and how to reach the author.
+ *
+ * THIS IS A GENERATED FILE; CHANGE LANGUAGE TEXT INSIDE po/ll_LL.po INSTEAD
+ * AND SEND A COPY OF THE FILE TO PLUGINS AUTHOR.
+ *
+ * $Id$
+ */
+
+#include "i18n.h"
+
+#if VDRVERSNUM < 10507
+const tI18nPhrase pvrinput_Phrases[] = {
+// START I18N
+// END I18N
+ { NULL }
+ };
+#endif
diff --git a/po/i18n.h b/po/i18n.h
new file mode 100644
index 0000000..115773e
--- /dev/null
+++ b/po/i18n.h
@@ -0,0 +1,23 @@
+/*
+ * pvrinput: A plugin for the Video Disk Recorder
+ * Copyright (C) 2007 Andreas Regel, Martin Dauskardt, Winfried Koehler
+ * Licence GPL
+ *
+ * See the README file for copyright information and how to reach the author.
+ *
+ * THIS IS A GENERATED FILE; CHANGE LANGUAGE TEXT INSIDE po/ll_LL.po INSTEAD
+ * AND SEND A COPY OF THE FILE TO PLUGINS AUTHOR.
+ *
+ * $Id$
+ */
+
+#ifndef __PVRINPUT_I18N_H
+#define __PVRINPUT_I18N_H
+
+#include <vdr/i18n.h>
+
+#if VDRVERSNUM < 10507
+extern const tI18nPhrase pvrinput_Phrases[];
+#endif
+
+#endif //__PVRINPUT_I18N_H
diff --git a/po/it_IT.po b/po/it_IT.po
new file mode 100644
index 0000000..c94de67
--- /dev/null
+++ b/po/it_IT.po
@@ -0,0 +1,211 @@
+# translation of it_IT.po to
+# translation of pvrinput.po to
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: it_IT\n"
+"Report-Msgid-Bugs-To: <see README>\n"
+"POT-Creation-Date: 2010-03-07 11:36+0100\n"
+"PO-Revision-Date: 2009-10-11 22:40+0200\n"
+"Last-Translator: root\n"
+"Language-Team: <de@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+
+#, fuzzy
+msgid "SourceParam.pvrinput$Input"
+msgstr "Input"
+
+#, fuzzy
+msgid "SourceParam.pvrinput$Card"
+msgstr "Card"
+
+#, fuzzy
+msgid "SourceParam.pvrinput$Standard"
+msgstr "Standard"
+
+msgid "pvrinput no longer supports old channel syntax!"
+msgstr "Sintassi vecchi canali non supportata"
+
+msgid "Setup.pvrinput$manual"
+msgstr "manuale"
+
+msgid "Setup.pvrinput$auto"
+msgstr "automatico"
+
+msgid "Setup.pvrinput$off"
+msgstr "disattivo"
+
+msgid "Setup.pvrinput$1D horizontal"
+msgstr "1D orizzontale"
+
+msgid "Setup.pvrinput$1D vertical"
+msgstr "1D verticale"
+
+msgid "Setup.pvrinput$2D hv separable"
+msgstr "2D hv separabile"
+
+msgid "Setup.pvrinput$2D sym non separable"
+msgstr "2D sym non separabile"
+
+msgid "Setup.pvrinput$horizontal"
+msgstr "orizzontale"
+
+msgid "Setup.pvrinput$vertical"
+msgstr "verticale"
+
+msgid "Setup.pvrinput$horizontal + vertical"
+msgstr "orizzontale e verticale"
+
+msgid "Setup.pvrinput$diagonal"
+msgstr "diagonale"
+
+msgid "Setup.pvrinput$44.1 kHz"
+msgstr "44.1 kHz"
+
+msgid "Setup.pvrinput$48 kHz"
+msgstr "48 kHz"
+
+msgid "Setup.pvrinput$32 kHz"
+msgstr "32 kHz"
+
+#, fuzzy
+msgid "Setup.pvrinput$AAC"
+msgstr "AAC"
+
+#, fuzzy
+msgid "Setup.pvrinput$AC3"
+msgstr "AC3"
+
+#, fuzzy
+msgid "Setup.pvrinput$RCA back"
+msgstr "RCA (back)"
+
+#, fuzzy
+msgid "Setup.pvrinput$RCA front"
+msgstr "RCA (front)"
+
+#, fuzzy
+msgid "Setup.pvrinput$SPDIF"
+msgstr "S/PDIF"
+
+msgid "Setup.pvrinput$Hide main menu entry"
+msgstr "Nascondi voce menu principale"
+
+msgid "Setup.pvrinput$Use only card"
+msgstr "Utilizza solo scheda"
+
+msgid "Setup.pvrinput$Log level"
+msgstr "Livello log"
+
+msgid "Setup.pvrinput$Slice VBI Teletext"
+msgstr "Sezione televideo VBI"
+
+msgid "Setup.pvrinput$Tuner Audio Mode"
+msgstr "Modalità sintonizzatore audio"
+
+msgid "Setup.pvrinput$Brightness"
+msgstr "Luminosità"
+
+msgid "Setup.pvrinput$Contrast"
+msgstr "Contrasto"
+
+msgid "Setup.pvrinput$Saturation"
+msgstr "Saturazione"
+
+msgid "Setup.pvrinput$Hue"
+msgstr "Tonalità"
+
+msgid "Setup.pvrinput$Common Audio volume (TV)"
+msgstr "Volume audio TV generale"
+
+msgid "Setup.pvrinput$Exception Audio volume (TV)"
+msgstr "Volume audio TV specifico"
+
+msgid "Setup.pvrinput$Exception TV Volume for Card"
+msgstr "Volume audio TV specifico per scheda"
+
+msgid "Setup.pvrinput$Audio radio volume"
+msgstr "Volume audio radio"
+
+msgid "Setup.pvrinput$Audio bitrate (kbit/s)"
+msgstr "Codifica audio (kbit/s)"
+
+msgid "Setup.pvrinput$Audio sampling rate"
+msgstr "Codifica campione audio"
+
+#, fuzzy
+msgid "Setup.pvrinput$HDPVR audio encoding"
+msgstr "HDPVR audio encoding"
+
+#, fuzzy
+msgid "Setup.pvrinput$HDPVR audio input"
+msgstr "HDPVR audio input"
+
+msgid "Setup.pvrinput$Video bitrate TV (kbit/s)"
+msgstr "Codifica video TV (kbit/s)"
+
+msgid "Setup.pvrinput$Bitrate mode"
+msgstr "Modalità codifica"
+
+msgid "Setup.pvrinput$Aspect ratio"
+msgstr "Formato video"
+
+msgid "Setup.pvrinput$Stream type"
+msgstr "Stream Tipo"
+
+msgid "Setup.pvrinput$Mode Spatial Video Filter"
+msgstr "Filtro video modalità spaziale"
+
+msgid "Setup.pvrinput$Strength Spatial Video Filter"
+msgstr "Filtro video resistenza spaziale"
+
+msgid "Setup.pvrinput$Luma Spatial Filter Type"
+msgstr "Tipo filtro luma spaziale"
+
+msgid "Setup.pvrinput$Chroma Spatial Filter Type"
+msgstr "Tipo filtro croma spaziale"
+
+msgid "Setup.pvrinput$Mode Temporal Video Filter"
+msgstr "Filtro video modalità temporale"
+
+msgid "Setup.pvrinput$Strength Temporal Video Filter"
+msgstr "Filtro video resistenza temporale"
+
+msgid "Setup.pvrinput$Median Filter Type"
+msgstr "Tipo filtro mediano"
+
+msgid "Setup.pvrinput$Luma Median Filter Bottom"
+msgstr "Filtro inferiore luma mediana"
+
+msgid "Setup.pvrinput$Luma Median Filter Top"
+msgstr "Filtro superiore luma mediana"
+
+msgid "Setup.pvrinput$Chroma Median Filter Bottom"
+msgstr "Filtro inferiore croma mediana"
+
+msgid "Setup.pvrinput$Chroma Median Filter Top"
+msgstr "Filtro superiore croma mediana"
+
+msgid "Setup.pvrinput$use externchannelswitch.sh"
+msgstr ""
+
+msgid "use Hauppauge PVR as input device"
+msgstr "utilizza Hauppauge PVR come periferica ingresso"
+
+msgid "PVR picture settings"
+msgstr "Impostazioni immagine PVR"
+
+msgid "Setup.pvrinput$Not on an analogue channel!"
+msgstr "Non è un canale analogico!"
+
+#~ msgid "Setup.pvrinput$PVRUSB2 Stop on Change"
+#~ msgstr "Ferma PVRUSB2 al cambio"
+
+#~ msgid "Setup.pvrinput$Video bitrate Radio (kbit/s)"
+#~ msgstr "Codifica video radio (kbit/s)"
diff --git a/po/nl_NL.po b/po/nl_NL.po
new file mode 100644
index 0000000..9bcd226
--- /dev/null
+++ b/po/nl_NL.po
@@ -0,0 +1,194 @@
+# translation of pvrinput.po to
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pvrinput\n"
+"Report-Msgid-Bugs-To: <see README>\n"
+"POT-Creation-Date: 2010-03-07 11:36+0100\n"
+"PO-Revision-Date: 2008-05-24 13:39+0200\n"
+"Last-Translator: root\n"
+"Language-Team: <de@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+
+msgid "SourceParam.pvrinput$Input"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Card"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Standard"
+msgstr ""
+
+msgid "pvrinput no longer supports old channel syntax!"
+msgstr ""
+
+msgid "Setup.pvrinput$manual"
+msgstr ""
+
+msgid "Setup.pvrinput$auto"
+msgstr ""
+
+msgid "Setup.pvrinput$off"
+msgstr ""
+
+msgid "Setup.pvrinput$1D horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$1D vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$2D hv separable"
+msgstr ""
+
+msgid "Setup.pvrinput$2D sym non separable"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal + vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$diagonal"
+msgstr ""
+
+msgid "Setup.pvrinput$44.1 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$48 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$32 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$AAC"
+msgstr ""
+
+msgid "Setup.pvrinput$AC3"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA back"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA front"
+msgstr ""
+
+msgid "Setup.pvrinput$SPDIF"
+msgstr ""
+
+msgid "Setup.pvrinput$Hide main menu entry"
+msgstr ""
+
+msgid "Setup.pvrinput$Use only card"
+msgstr ""
+
+msgid "Setup.pvrinput$Log level"
+msgstr ""
+
+msgid "Setup.pvrinput$Slice VBI Teletext"
+msgstr ""
+
+msgid "Setup.pvrinput$Tuner Audio Mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Brightness"
+msgstr ""
+
+msgid "Setup.pvrinput$Contrast"
+msgstr ""
+
+msgid "Setup.pvrinput$Saturation"
+msgstr ""
+
+msgid "Setup.pvrinput$Hue"
+msgstr ""
+
+msgid "Setup.pvrinput$Common Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception TV Volume for Card"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio radio volume"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio bitrate (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio sampling rate"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio encoding"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio input"
+msgstr ""
+
+msgid "Setup.pvrinput$Video bitrate TV (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Bitrate mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Aspect ratio"
+msgstr ""
+
+msgid "Setup.pvrinput$Stream type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Median Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$use externchannelswitch.sh"
+msgstr ""
+
+msgid "use Hauppauge PVR as input device"
+msgstr ""
+
+msgid "PVR picture settings"
+msgstr ""
+
+msgid "Setup.pvrinput$Not on an analogue channel!"
+msgstr ""
diff --git a/po/nn_NO.po b/po/nn_NO.po
new file mode 100644
index 0000000..9bcd226
--- /dev/null
+++ b/po/nn_NO.po
@@ -0,0 +1,194 @@
+# translation of pvrinput.po to
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pvrinput\n"
+"Report-Msgid-Bugs-To: <see README>\n"
+"POT-Creation-Date: 2010-03-07 11:36+0100\n"
+"PO-Revision-Date: 2008-05-24 13:39+0200\n"
+"Last-Translator: root\n"
+"Language-Team: <de@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+
+msgid "SourceParam.pvrinput$Input"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Card"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Standard"
+msgstr ""
+
+msgid "pvrinput no longer supports old channel syntax!"
+msgstr ""
+
+msgid "Setup.pvrinput$manual"
+msgstr ""
+
+msgid "Setup.pvrinput$auto"
+msgstr ""
+
+msgid "Setup.pvrinput$off"
+msgstr ""
+
+msgid "Setup.pvrinput$1D horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$1D vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$2D hv separable"
+msgstr ""
+
+msgid "Setup.pvrinput$2D sym non separable"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal + vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$diagonal"
+msgstr ""
+
+msgid "Setup.pvrinput$44.1 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$48 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$32 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$AAC"
+msgstr ""
+
+msgid "Setup.pvrinput$AC3"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA back"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA front"
+msgstr ""
+
+msgid "Setup.pvrinput$SPDIF"
+msgstr ""
+
+msgid "Setup.pvrinput$Hide main menu entry"
+msgstr ""
+
+msgid "Setup.pvrinput$Use only card"
+msgstr ""
+
+msgid "Setup.pvrinput$Log level"
+msgstr ""
+
+msgid "Setup.pvrinput$Slice VBI Teletext"
+msgstr ""
+
+msgid "Setup.pvrinput$Tuner Audio Mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Brightness"
+msgstr ""
+
+msgid "Setup.pvrinput$Contrast"
+msgstr ""
+
+msgid "Setup.pvrinput$Saturation"
+msgstr ""
+
+msgid "Setup.pvrinput$Hue"
+msgstr ""
+
+msgid "Setup.pvrinput$Common Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception TV Volume for Card"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio radio volume"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio bitrate (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio sampling rate"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio encoding"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio input"
+msgstr ""
+
+msgid "Setup.pvrinput$Video bitrate TV (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Bitrate mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Aspect ratio"
+msgstr ""
+
+msgid "Setup.pvrinput$Stream type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Median Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$use externchannelswitch.sh"
+msgstr ""
+
+msgid "use Hauppauge PVR as input device"
+msgstr ""
+
+msgid "PVR picture settings"
+msgstr ""
+
+msgid "Setup.pvrinput$Not on an analogue channel!"
+msgstr ""
diff --git a/po/pl_PL.po b/po/pl_PL.po
new file mode 100644
index 0000000..1dcbdf4
--- /dev/null
+++ b/po/pl_PL.po
@@ -0,0 +1,194 @@
+# translation of pvrinput.po to
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pvrinput\n"
+"Report-Msgid-Bugs-To: <see README>\n"
+"POT-Creation-Date: 2010-03-07 11:36+0100\n"
+"PO-Revision-Date: 2008-05-24 13:40+0200\n"
+"Last-Translator: root\n"
+"Language-Team: <de@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+
+msgid "SourceParam.pvrinput$Input"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Card"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Standard"
+msgstr ""
+
+msgid "pvrinput no longer supports old channel syntax!"
+msgstr ""
+
+msgid "Setup.pvrinput$manual"
+msgstr ""
+
+msgid "Setup.pvrinput$auto"
+msgstr ""
+
+msgid "Setup.pvrinput$off"
+msgstr ""
+
+msgid "Setup.pvrinput$1D horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$1D vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$2D hv separable"
+msgstr ""
+
+msgid "Setup.pvrinput$2D sym non separable"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal + vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$diagonal"
+msgstr ""
+
+msgid "Setup.pvrinput$44.1 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$48 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$32 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$AAC"
+msgstr ""
+
+msgid "Setup.pvrinput$AC3"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA back"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA front"
+msgstr ""
+
+msgid "Setup.pvrinput$SPDIF"
+msgstr ""
+
+msgid "Setup.pvrinput$Hide main menu entry"
+msgstr ""
+
+msgid "Setup.pvrinput$Use only card"
+msgstr ""
+
+msgid "Setup.pvrinput$Log level"
+msgstr ""
+
+msgid "Setup.pvrinput$Slice VBI Teletext"
+msgstr ""
+
+msgid "Setup.pvrinput$Tuner Audio Mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Brightness"
+msgstr ""
+
+msgid "Setup.pvrinput$Contrast"
+msgstr ""
+
+msgid "Setup.pvrinput$Saturation"
+msgstr ""
+
+msgid "Setup.pvrinput$Hue"
+msgstr ""
+
+msgid "Setup.pvrinput$Common Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception TV Volume for Card"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio radio volume"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio bitrate (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio sampling rate"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio encoding"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio input"
+msgstr ""
+
+msgid "Setup.pvrinput$Video bitrate TV (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Bitrate mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Aspect ratio"
+msgstr ""
+
+msgid "Setup.pvrinput$Stream type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Median Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$use externchannelswitch.sh"
+msgstr ""
+
+msgid "use Hauppauge PVR as input device"
+msgstr ""
+
+msgid "PVR picture settings"
+msgstr ""
+
+msgid "Setup.pvrinput$Not on an analogue channel!"
+msgstr ""
diff --git a/po/pt_PT.po b/po/pt_PT.po
new file mode 100644
index 0000000..1dcbdf4
--- /dev/null
+++ b/po/pt_PT.po
@@ -0,0 +1,194 @@
+# translation of pvrinput.po to
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pvrinput\n"
+"Report-Msgid-Bugs-To: <see README>\n"
+"POT-Creation-Date: 2010-03-07 11:36+0100\n"
+"PO-Revision-Date: 2008-05-24 13:40+0200\n"
+"Last-Translator: root\n"
+"Language-Team: <de@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+
+msgid "SourceParam.pvrinput$Input"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Card"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Standard"
+msgstr ""
+
+msgid "pvrinput no longer supports old channel syntax!"
+msgstr ""
+
+msgid "Setup.pvrinput$manual"
+msgstr ""
+
+msgid "Setup.pvrinput$auto"
+msgstr ""
+
+msgid "Setup.pvrinput$off"
+msgstr ""
+
+msgid "Setup.pvrinput$1D horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$1D vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$2D hv separable"
+msgstr ""
+
+msgid "Setup.pvrinput$2D sym non separable"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal + vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$diagonal"
+msgstr ""
+
+msgid "Setup.pvrinput$44.1 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$48 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$32 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$AAC"
+msgstr ""
+
+msgid "Setup.pvrinput$AC3"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA back"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA front"
+msgstr ""
+
+msgid "Setup.pvrinput$SPDIF"
+msgstr ""
+
+msgid "Setup.pvrinput$Hide main menu entry"
+msgstr ""
+
+msgid "Setup.pvrinput$Use only card"
+msgstr ""
+
+msgid "Setup.pvrinput$Log level"
+msgstr ""
+
+msgid "Setup.pvrinput$Slice VBI Teletext"
+msgstr ""
+
+msgid "Setup.pvrinput$Tuner Audio Mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Brightness"
+msgstr ""
+
+msgid "Setup.pvrinput$Contrast"
+msgstr ""
+
+msgid "Setup.pvrinput$Saturation"
+msgstr ""
+
+msgid "Setup.pvrinput$Hue"
+msgstr ""
+
+msgid "Setup.pvrinput$Common Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception TV Volume for Card"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio radio volume"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio bitrate (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio sampling rate"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio encoding"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio input"
+msgstr ""
+
+msgid "Setup.pvrinput$Video bitrate TV (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Bitrate mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Aspect ratio"
+msgstr ""
+
+msgid "Setup.pvrinput$Stream type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Median Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$use externchannelswitch.sh"
+msgstr ""
+
+msgid "use Hauppauge PVR as input device"
+msgstr ""
+
+msgid "PVR picture settings"
+msgstr ""
+
+msgid "Setup.pvrinput$Not on an analogue channel!"
+msgstr ""
diff --git a/po/ro_RO.po b/po/ro_RO.po
new file mode 100644
index 0000000..b0946e0
--- /dev/null
+++ b/po/ro_RO.po
@@ -0,0 +1,213 @@
+# translation of ro_RO.po to
+# pvrinput
+# Copyright (C) 2007 Andreas Regel, Martin Dauskardt, Winfried Köhler
+# This file is distributed under the same license as the PACKAGE package.
+# Andreas Regel, Martin Dauskardt, Winfried Köhler <see README>, 2007.
+#
+#
+# FILE WAS AUTOMATICALLY GENERATED BY PO_CREATOR,
+# see http://free.pages.at/wirbel4vdr
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: ro_RO\n"
+"Report-Msgid-Bugs-To: <see README>\n"
+"POT-Creation-Date: 2010-03-07 11:36+0100\n"
+"PO-Revision-Date: 2009-06-02 22:59+0200\n"
+"Last-Translator: root\n"
+"Language-Team: <de@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-15\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+
+msgid "SourceParam.pvrinput$Input"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Card"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Standard"
+msgstr ""
+
+msgid "pvrinput no longer supports old channel syntax!"
+msgstr ""
+
+msgid "Setup.pvrinput$manual"
+msgstr ""
+
+msgid "Setup.pvrinput$auto"
+msgstr ""
+
+msgid "Setup.pvrinput$off"
+msgstr "inactiv"
+
+msgid "Setup.pvrinput$1D horizontal"
+msgstr "1D orizontal"
+
+msgid "Setup.pvrinput$1D vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$2D hv separable"
+msgstr "2D hv separat"
+
+msgid "Setup.pvrinput$2D sym non separable"
+msgstr "2D sym inseparabil"
+
+msgid "Setup.pvrinput$horizontal"
+msgstr "orizontal"
+
+msgid "Setup.pvrinput$vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal + vertical"
+msgstr "orizontal + vertical"
+
+msgid "Setup.pvrinput$diagonal"
+msgstr ""
+
+msgid "Setup.pvrinput$44.1 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$48 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$32 kHz"
+msgstr ""
+
+#, fuzzy
+msgid "Setup.pvrinput$AAC"
+msgstr "AAC"
+
+#, fuzzy
+msgid "Setup.pvrinput$AC3"
+msgstr "AC3"
+
+#, fuzzy
+msgid "Setup.pvrinput$RCA back"
+msgstr "RCA (back)"
+
+#, fuzzy
+msgid "Setup.pvrinput$RCA front"
+msgstr "RCA (front)"
+
+#, fuzzy
+msgid "Setup.pvrinput$SPDIF"
+msgstr "S/PDIF"
+
+msgid "Setup.pvrinput$Hide main menu entry"
+msgstr "Ascunde in meniul principal"
+
+msgid "Setup.pvrinput$Use only card"
+msgstr ""
+
+msgid "Setup.pvrinput$Log level"
+msgstr ""
+
+#, fuzzy
+msgid "Setup.pvrinput$Slice VBI Teletext"
+msgstr "Ascunde in meniul principal"
+
+msgid "Setup.pvrinput$Tuner Audio Mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Brightness"
+msgstr "Luminozitate"
+
+msgid "Setup.pvrinput$Contrast"
+msgstr ""
+
+msgid "Setup.pvrinput$Saturation"
+msgstr "Saturatie"
+
+msgid "Setup.pvrinput$Hue"
+msgstr "Nuanta"
+
+msgid "Setup.pvrinput$Common Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception TV Volume for Card"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio radio volume"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio bitrate (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio sampling rate"
+msgstr ""
+
+#, fuzzy
+msgid "Setup.pvrinput$HDPVR audio encoding"
+msgstr "HDPVR audio encoding"
+
+#, fuzzy
+msgid "Setup.pvrinput$HDPVR audio input"
+msgstr "HDPVR audio input"
+
+msgid "Setup.pvrinput$Video bitrate TV (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Bitrate mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Aspect ratio"
+msgstr ""
+
+msgid "Setup.pvrinput$Stream type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Median Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$use externchannelswitch.sh"
+msgstr ""
+
+#, fuzzy
+msgid "use Hauppauge PVR as input device"
+msgstr "dispozitiv receptor Hauppauge PVR"
+
+#, fuzzy
+msgid "PVR picture settings"
+msgstr "Reglaje imagine PVR"
+
+msgid "Setup.pvrinput$Not on an analogue channel!"
+msgstr "Canalul nu este receptionat cu placa PVR!"
+
+#, fuzzy
+#~ msgid "Setup.pvrinput$PVRUSB2 Stop on Change"
+#~ msgstr "2D sym inseparabil"
diff --git a/po/ru_RU.po b/po/ru_RU.po
new file mode 100644
index 0000000..1dcbdf4
--- /dev/null
+++ b/po/ru_RU.po
@@ -0,0 +1,194 @@
+# translation of pvrinput.po to
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pvrinput\n"
+"Report-Msgid-Bugs-To: <see README>\n"
+"POT-Creation-Date: 2010-03-07 11:36+0100\n"
+"PO-Revision-Date: 2008-05-24 13:40+0200\n"
+"Last-Translator: root\n"
+"Language-Team: <de@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+
+msgid "SourceParam.pvrinput$Input"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Card"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Standard"
+msgstr ""
+
+msgid "pvrinput no longer supports old channel syntax!"
+msgstr ""
+
+msgid "Setup.pvrinput$manual"
+msgstr ""
+
+msgid "Setup.pvrinput$auto"
+msgstr ""
+
+msgid "Setup.pvrinput$off"
+msgstr ""
+
+msgid "Setup.pvrinput$1D horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$1D vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$2D hv separable"
+msgstr ""
+
+msgid "Setup.pvrinput$2D sym non separable"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal + vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$diagonal"
+msgstr ""
+
+msgid "Setup.pvrinput$44.1 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$48 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$32 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$AAC"
+msgstr ""
+
+msgid "Setup.pvrinput$AC3"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA back"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA front"
+msgstr ""
+
+msgid "Setup.pvrinput$SPDIF"
+msgstr ""
+
+msgid "Setup.pvrinput$Hide main menu entry"
+msgstr ""
+
+msgid "Setup.pvrinput$Use only card"
+msgstr ""
+
+msgid "Setup.pvrinput$Log level"
+msgstr ""
+
+msgid "Setup.pvrinput$Slice VBI Teletext"
+msgstr ""
+
+msgid "Setup.pvrinput$Tuner Audio Mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Brightness"
+msgstr ""
+
+msgid "Setup.pvrinput$Contrast"
+msgstr ""
+
+msgid "Setup.pvrinput$Saturation"
+msgstr ""
+
+msgid "Setup.pvrinput$Hue"
+msgstr ""
+
+msgid "Setup.pvrinput$Common Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception TV Volume for Card"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio radio volume"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio bitrate (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio sampling rate"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio encoding"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio input"
+msgstr ""
+
+msgid "Setup.pvrinput$Video bitrate TV (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Bitrate mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Aspect ratio"
+msgstr ""
+
+msgid "Setup.pvrinput$Stream type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Median Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$use externchannelswitch.sh"
+msgstr ""
+
+msgid "use Hauppauge PVR as input device"
+msgstr ""
+
+msgid "PVR picture settings"
+msgstr ""
+
+msgid "Setup.pvrinput$Not on an analogue channel!"
+msgstr ""
diff --git a/po/sl_SI.po b/po/sl_SI.po
new file mode 100644
index 0000000..1dcbdf4
--- /dev/null
+++ b/po/sl_SI.po
@@ -0,0 +1,194 @@
+# translation of pvrinput.po to
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pvrinput\n"
+"Report-Msgid-Bugs-To: <see README>\n"
+"POT-Creation-Date: 2010-03-07 11:36+0100\n"
+"PO-Revision-Date: 2008-05-24 13:40+0200\n"
+"Last-Translator: root\n"
+"Language-Team: <de@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+
+msgid "SourceParam.pvrinput$Input"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Card"
+msgstr ""
+
+msgid "SourceParam.pvrinput$Standard"
+msgstr ""
+
+msgid "pvrinput no longer supports old channel syntax!"
+msgstr ""
+
+msgid "Setup.pvrinput$manual"
+msgstr ""
+
+msgid "Setup.pvrinput$auto"
+msgstr ""
+
+msgid "Setup.pvrinput$off"
+msgstr ""
+
+msgid "Setup.pvrinput$1D horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$1D vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$2D hv separable"
+msgstr ""
+
+msgid "Setup.pvrinput$2D sym non separable"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal"
+msgstr ""
+
+msgid "Setup.pvrinput$vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$horizontal + vertical"
+msgstr ""
+
+msgid "Setup.pvrinput$diagonal"
+msgstr ""
+
+msgid "Setup.pvrinput$44.1 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$48 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$32 kHz"
+msgstr ""
+
+msgid "Setup.pvrinput$AAC"
+msgstr ""
+
+msgid "Setup.pvrinput$AC3"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA back"
+msgstr ""
+
+msgid "Setup.pvrinput$RCA front"
+msgstr ""
+
+msgid "Setup.pvrinput$SPDIF"
+msgstr ""
+
+msgid "Setup.pvrinput$Hide main menu entry"
+msgstr ""
+
+msgid "Setup.pvrinput$Use only card"
+msgstr ""
+
+msgid "Setup.pvrinput$Log level"
+msgstr ""
+
+msgid "Setup.pvrinput$Slice VBI Teletext"
+msgstr ""
+
+msgid "Setup.pvrinput$Tuner Audio Mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Brightness"
+msgstr ""
+
+msgid "Setup.pvrinput$Contrast"
+msgstr ""
+
+msgid "Setup.pvrinput$Saturation"
+msgstr ""
+
+msgid "Setup.pvrinput$Hue"
+msgstr ""
+
+msgid "Setup.pvrinput$Common Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception Audio volume (TV)"
+msgstr ""
+
+msgid "Setup.pvrinput$Exception TV Volume for Card"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio radio volume"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio bitrate (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Audio sampling rate"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio encoding"
+msgstr ""
+
+msgid "Setup.pvrinput$HDPVR audio input"
+msgstr ""
+
+msgid "Setup.pvrinput$Video bitrate TV (kbit/s)"
+msgstr ""
+
+msgid "Setup.pvrinput$Bitrate mode"
+msgstr ""
+
+msgid "Setup.pvrinput$Aspect ratio"
+msgstr ""
+
+msgid "Setup.pvrinput$Stream type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Spatial Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Spatial Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Mode Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Strength Temporal Video Filter"
+msgstr ""
+
+msgid "Setup.pvrinput$Median Filter Type"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Luma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Bottom"
+msgstr ""
+
+msgid "Setup.pvrinput$Chroma Median Filter Top"
+msgstr ""
+
+msgid "Setup.pvrinput$use externchannelswitch.sh"
+msgstr ""
+
+msgid "use Hauppauge PVR as input device"
+msgstr ""
+
+msgid "PVR picture settings"
+msgstr ""
+
+msgid "Setup.pvrinput$Not on an analogue channel!"
+msgstr ""
diff --git a/po2i18n.pl b/po2i18n.pl
new file mode 100755
index 0000000..f828022
--- /dev/null
+++ b/po2i18n.pl
@@ -0,0 +1,201 @@
+#!/usr/bin/perl
+#
+# po2i18n - Convert plugin po files in into i18n.c-format
+#
+#
+# this is the README from the po218n source packet:
+###############################################################################
+#
+# po2i18n - Converter for po files
+# Written by: Udo Richter <udo_richter@gmx.de>
+# Project's homepage: http://www.udo-richter.de/vdr/scripts.html#po2i18n
+# http://www.udo-richter.de/vdr/scripts.en.html#po2i18n
+# License: GPL, see file COPYING from original source Packet
+#
+#
+# About
+#--------------------------------------------------------------------------
+#po2i18n is a perl script that generates an i18n.c file compatible to the i18n
+#system of VDR 1.2.0 - VDR 1.5.6, based on the .po files of VDR 1.5.7. This
+#allows plugins to transit to the translation system of VDR 1.5.7 while
+#maintaining compatibility to earlier versions. The script can be used manually
+#or automatically as part of the Makefile.
+#
+#
+#Use
+#--------------------------------------------------------------------------
+#po2i18n.pl is a filter and can be used manually like this:
+#
+# ./po2i18n.pl < i18n-template.c > i18n.c
+#
+#The filter reads all relevant ./po/*.po files and writes the i18n strings
+#into the template file. Strings will be added between the following two lines:
+#
+# // START I18N
+# // END I18N
+#
+#See also the sample i18n.h and i18n-template.c file. Note that the phrases data
+#structure is encapsulated in #if VDRVERSNUM < 10507, so the i18n strings won't
+#be in the plugin file after 1.5.7. The call to RegisterI18n() of your plugin
+#should also be encapsulated like this.
+#
+#po2i18n can also generate the i18n.c file on the fly while compiling. The
+#changes to the Makefile are demonstrated by the included Makefile.diff sample.
+#With these changes, the i18n.c file will be generated on VDR up to 1.5.6, and
+#the whole gettext conversion is skipped. From 1.5.7 on, the i18n-template.c
+#file will be simply copied as a dummy, and the new locale system will run.
+#
+#As a drawback, the automatic .dependencies for i18n.c won't work.
+#
+###############################################################################
+#
+
+use strict;
+use warnings;
+
+my @LANGS = (
+ "en_US",
+ "de_DE",
+ "sl_SI",
+ "it_IT",
+ "nl_NL",
+ "pt_PT",
+ "fr_FR",
+ "nn_NO",
+ "fi_FI",
+ "pl_PL",
+ "es_ES",
+ "el_GR",
+ "sv_SE",
+ "ro_RO",
+ "hu_HU",
+ "ca_ES",
+ "ru_RU",
+ "hr_HR",
+ "et_EE",
+ "da_DK",
+ "cs_CZ",
+ "tr_TR"
+ );
+
+my %VERS = (
+ "en_US" => 10200,
+ "de_DE" => 10200,
+ "sl_SI" => 10200,
+ "it_IT" => 10200,
+ "nl_NL" => 10200,
+ "pt_PT" => 10200,
+ "fr_FR" => 10200,
+ "nn_NO" => 10200,
+ "fi_FI" => 10200,
+ "pl_PL" => 10200,
+ "es_ES" => 10200,
+ "el_GR" => 10200,
+ "sv_SE" => 10200,
+ "ro_RO" => 10200,
+ "hu_HU" => 10200,
+ "ca_ES" => 10200,
+ "ru_RU" => 10302,
+ "hr_HR" => 10307,
+ "et_EE" => 10313,
+ "da_DK" => 10316,
+ "cs_CZ" => 10342,
+ "tr_TR" => 10502
+ );
+
+
+my %strings;
+
+foreach my $lang (@LANGS) { $strings{$lang} = { }; }
+
+
+sub LoadLanguage(*) {
+ my ($lang) = @_;
+
+ if (!open FILE, "<", "po/$lang.po") {
+ return 0;
+ }
+
+ my $msgid = "";
+ my $msgstr = "";
+ my $last = 0; # 0=init, 1=msgid was last, 2=msgstr was last
+
+ while (<FILE>) {
+ chomp;
+ my $line = $_;
+
+ if ($line =~ /^msgid "(.*)"$/) {
+ if ($last eq 2) {
+ $strings{$lang}->{$msgid} = $msgstr;
+ $strings{"en_US"}->{$msgid} = $msgid;
+ }
+ $msgid = $1;
+ $last = 1;
+ } elsif ($line =~ /^msgstr "(.*)"/) {
+ $msgstr = $1;
+ $last = 2;
+ } elsif ($line =~ /^"(.*)"/) {
+ if ($last eq 1) {
+ $msgid = $msgid . $1;
+ } elsif ($last eq 2) {
+ $msgstr = $msgstr . $1;
+ }
+ }
+ }
+ if ($last eq 2) {
+ $strings{$lang}->{$msgid} = $msgstr;
+ $strings{"en_US"}->{$msgid} = $msgid;
+ }
+
+ close FILE;
+}
+
+
+
+foreach my $lang (@LANGS) {
+ LoadLanguage($lang);
+}
+
+my @msgids = sort keys %{$strings{"en_US"}};
+
+
+my $silent = 0;
+
+while (<>) {
+ my $line = $_;
+
+ if ($line =~ /^\/\/ START I18N/) {
+ print "// START I18N - automatically generated by po2i18n.pl\n";
+ for my $msgid (@msgids) {
+ next if $msgid eq "";
+
+ my $head = " { ";
+ my $endif = "";
+ my $versnum = 10200;
+
+ for my $lang (@LANGS) {
+ if ($VERS{$lang} ne $versnum) {
+ $versnum = $VERS{$lang};
+ print $endif;
+ print "#if VDRVERSNUM >= $versnum\n";
+ $endif = "#endif\n";
+ }
+ my $msgstr = $strings{$lang}->{$msgid};
+ $msgstr = "" if !defined $msgstr;
+
+ print "$head\"$msgstr\",\n";
+ $head = " ";
+ }
+ print $endif;
+ print " },\n";
+ }
+ $silent = 1;
+ }
+
+ if (!$silent) { print $line; }
+
+ if ($line =~ /^\/\/ END I18N/) {
+ print "// END I18N - automatically generated by po2i18n.pl\n";
+ $silent = 0;
+ }
+}
diff --git a/pvrinput.c b/pvrinput.c
new file mode 100644
index 0000000..85a3320
--- /dev/null
+++ b/pvrinput.c
@@ -0,0 +1,131 @@
+#include "common.h"
+
+#if VDRVERSNUM < 10713
+#ifndef PLUGINPARAMPATCHVERSNUM
+#error "You must apply the pluginparam patch for VDR!"
+#endif
+#endif
+
+static const char *VERSION = "1.7.1-rc1-9";
+static const char *DESCRIPTION = tr("use Hauppauge PVR as input device");
+static const char *MAINMENUENTRY = tr("PVR picture settings");
+
+
+cPluginPvrInput * PluginPvrInput;
+
+cPluginPvrInput::cPluginPvrInput(void) {
+ PluginPvrInput = this;
+}
+
+cPluginPvrInput::~cPluginPvrInput() {
+ PluginPvrInput = NULL;
+}
+
+const char * cPluginPvrInput::Version(void) {
+ return VERSION;
+}
+
+const char * cPluginPvrInput::Description(void) {
+ return tr(DESCRIPTION);
+}
+
+const char * cPluginPvrInput::CommandLineHelp(void) {
+ return NULL;
+}
+
+bool cPluginPvrInput::ProcessArgs(int argc, char * argv[]) {
+ return true;
+}
+
+bool cPluginPvrInput::Initialize(void) {
+#if VDRVERSNUM < 10507
+ RegisterI18n(pvrinput_Phrases);
+#endif //VDRVERSNUM < 10507
+ return true;
+}
+
+bool cPluginPvrInput::Start(void) {
+/* Start() is called after the primary device and user interface has
+ been set up, but before the main program loop is entered. Is called
+ after Initialize(). */
+ cPvrDevice::Initialize();
+ return true;
+}
+
+void cPluginPvrInput::Stop(void) {
+/* Any threads the plugin may have created shall be stopped
+ in the Stop() function. See VDR/PLUGINS.html */
+ cPvrDevice::Stop();
+};
+
+void cPluginPvrInput::Housekeeping(void) {
+}
+
+const char * cPluginPvrInput::MainMenuEntry(void) {
+ if (PvrSetup.HideMainMenuEntry)
+ return NULL;
+ else
+ return tr(MAINMENUENTRY);
+}
+
+
+cOsdObject * cPluginPvrInput::MainMenuAction(void) {
+ cChannel * channel = Channels.GetByNumber(cDevice::CurrentChannel());
+ if (channel
+#if VDRVERSNUM < 10713
+ && channel->IsPlug()
+#else
+ && (channel->Source() == 'V')
+#endif
+ )
+ return new cPvrMenuMain();
+ Skins.Message(mtError, tr("Setup.pvrinput$Not on an analogue channel!"), 2);
+ return NULL;
+}
+
+cMenuSetupPage * cPluginPvrInput::SetupMenu(void) {
+ return new cPvrMenuSetup();
+}
+
+bool cPluginPvrInput::SetupParse(const char * Name, const char * Value) {
+ if (!strcasecmp(Name, "LogLevel")) PvrSetup.LogLevel = atoi(Value);
+ else if (!strcasecmp(Name, "UseOnlyCard")) PvrSetup.UseOnlyCard = atoi(Value);
+ else if (!strcasecmp(Name, "SliceVBI")) PvrSetup.SliceVBI = atoi(Value);
+ else if (!strcasecmp(Name, "TunerAudioMode")) PvrSetup.TunerAudioMode = atoi(Value);
+ else if (!strcasecmp(Name, "Brightness")) PvrSetup.Brightness.value = atoi(Value);
+ else if (!strcasecmp(Name, "Contrast")) PvrSetup.Contrast.value = atoi(Value);
+ else if (!strcasecmp(Name, "Saturation")) PvrSetup.Saturation.value = atoi(Value);
+ else if (!strcasecmp(Name, "Hue")) PvrSetup.Hue.value = atoi(Value);
+ else if (!strcasecmp(Name, "AudioVolumeTVCommon")) PvrSetup.AudioVolumeTVCommon.value = atoi(Value);
+ else if (!strcasecmp(Name, "AudioVolumeTVException")) PvrSetup.AudioVolumeTVException.value = atoi(Value);
+ else if (!strcasecmp(Name, "AudioVolumeTVExceptionCard")) PvrSetup.AudioVolumeTVExceptionCard = atoi(Value);
+ else if (!strcasecmp(Name, "AudioVolumeFM")) PvrSetup.AudioVolumeFM.value = atoi(Value);
+ else if (!strcasecmp(Name, "AudioSampling")) PvrSetup.AudioSampling.value = atoi(Value);
+ else if (!strcasecmp(Name, "VideoBitrateTV")) PvrSetup.VideoBitrateTV.value = atoi(Value) * 1000;
+ else if (!strcasecmp(Name, "AudioBitrate")) PvrSetup.AudioBitrate.value = atoi(Value);
+ else if (!strcasecmp(Name, "BitrateMode")) PvrSetup.BitrateMode.value = atoi(Value);
+ else if (!strcasecmp(Name, "AspectRatio")) PvrSetup.AspectRatio.value = atoi(Value);
+ else if (!strcasecmp(Name, "StreamType")) PvrSetup.StreamType.value = atoi(Value);
+ else if (!strcasecmp(Name, "FilterSpatialMode")) PvrSetup.FilterSpatialMode.value = atoi(Value);
+ else if (!strcasecmp(Name, "FilterSpatial")) PvrSetup.FilterSpatial.value = atoi(Value);
+ else if (!strcasecmp(Name, "FilterLumaSpatialType")) PvrSetup.FilterLumaSpatialType.value = atoi(Value);
+ else if (!strcasecmp(Name, "FilterChromaSpatialType")) PvrSetup.FilterChromaSpatialType.value = atoi(Value);
+ else if (!strcasecmp(Name, "FilterTemporalMode")) PvrSetup.FilterTemporalMode.value = atoi(Value);
+ else if (!strcasecmp(Name, "FilterTemporal")) PvrSetup.FilterTemporal.value = atoi(Value);
+ else if (!strcasecmp(Name, "FilterMedianType")) PvrSetup.FilterMedianType.value = atoi(Value);
+ else if (!strcasecmp(Name, "FilterLumaMedianBottom")) PvrSetup.FilterLumaMedianBottom.value = atoi(Value);
+ else if (!strcasecmp(Name, "FilterLumaMedianTop")) PvrSetup.FilterLumaMedianTop.value = atoi(Value);
+ else if (!strcasecmp(Name, "FilterChromaMedianBottom")) PvrSetup.FilterChromaMedianBottom.value = atoi(Value);
+ else if (!strcasecmp(Name, "FilterChromaMedianTop")) PvrSetup.FilterChromaMedianTop.value = atoi(Value);
+ else if (!strcasecmp(Name, "HideMainMenuEntry")) PvrSetup.HideMainMenuEntry = atoi(Value);
+ else if (!strcasecmp(Name, "TsBufferSizeMB")) PvrSetup.TsBufferSizeMB = atoi(Value);
+ else if (!strcasecmp(Name, "TsBufferPrefillRatio")) PvrSetup.TsBufferPrefillRatio = atoi(Value);
+ else if (!strcasecmp(Name, "UseExternChannelSwitchScript")) PvrSetup.UseExternChannelSwitchScript = atoi(Value);
+ else if (!strcasecmp(Name, "HDPVR_AudioEncoding")) PvrSetup.HDPVR_AudioEncoding.value = atoi(Value) + 3;
+ else if (!strcasecmp(Name, "HDPVR_AudioInput")) PvrSetup.HDPVR_AudioInput = atoi(Value);
+ else
+ return false;
+ return true;
+}
+
+VDRPLUGINCREATOR(cPluginPvrInput); // Don't touch this!
diff --git a/pvrinput.h b/pvrinput.h
new file mode 100644
index 0000000..991b4ff
--- /dev/null
+++ b/pvrinput.h
@@ -0,0 +1,27 @@
+#ifndef _PVRINPUT_PLUGIN_H_
+#define _PVRINPUT_PLUGIN_H_
+
+#include "common.h"
+
+class cPluginPvrInput : public cPlugin {
+private:
+public:
+ cPluginPvrInput(void);
+ virtual ~cPluginPvrInput();
+ virtual const char * Version(void);
+ virtual const char * Description(void);
+ virtual const char * CommandLineHelp(void);
+ virtual bool ProcessArgs(int argc, char * argv[]);
+ virtual bool Initialize(void);
+ virtual bool Start(void);
+ virtual void Stop(void);
+ virtual void Housekeeping(void);
+ virtual const char * MainMenuEntry(void);
+ virtual cOsdObject * MainMenuAction(void);
+ virtual cMenuSetupPage * SetupMenu(void);
+ virtual bool SetupParse(const char * Name, const char * Value);
+};
+
+extern cPluginPvrInput * PluginPvrInput;
+
+#endif
diff --git a/reader.c b/reader.c
new file mode 100644
index 0000000..6e8be70
--- /dev/null
+++ b/reader.c
@@ -0,0 +1,486 @@
+#include "common.h"
+#include <libsi/si.h>
+
+#define BUFFSIZE_INPUT 4096 * 16
+#define SENDPATPMT_PACKETINTERVAL 500
+
+
+const short kVideoPid = 301;
+const short kAudioPid = 300;
+const short kTeletextPid = 305;
+const short kPCRPid = 101;
+
+const unsigned char kPAT[TS_SIZE] =
+{
+ 0x47, 0x40, 0x00, 0x10, 0x00, 0x00, 0xb0, 0x0d,
+ 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x01, 0xe0,
+ 0x84, 0xcc, 0x32, 0xcc, 0x32, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff
+};
+
+const unsigned char kPMT[TS_SIZE] =
+{
+ 0x47, 0x40, 0x84, 0x10, 0x00, 0x02, 0xb0, 0x22,
+ 0x00, 0x01, 0xc1, 0x00, 0x00, 0xe0, 0x65, 0xf0,
+ 0x00, 0x02, 0xe1, 0x2d, 0xf0, 0x00, 0x04, 0xe1,
+ 0x2c, 0xf0, 0x06, 0x0a, 0x04, 0x00, 0x00, 0x00,
+ 0x01, 0x06, 0xe1, 0x31, 0xf0, 0x00, 0xcc, 0x32,
+ 0xcc, 0x32, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff
+};
+
+const unsigned char kInvTab[256] =
+{
+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+ 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+ 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+ 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+ 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+ 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
+};
+
+cPvrReadThread::cPvrReadThread(cRingBufferLinear * TsBuffer, cPvrDevice* _parent)
+: tsBuffer(TsBuffer),
+ video_counter(0),
+ audio_counter(0),
+ text_counter(0),
+ pcr_counter(0),
+ packet_counter(0),
+ pes_stream_id(0),
+ pes_offset(0),
+ pes_length(0),
+ pes_tmp(0),
+ pes_scr_isvalid(false),
+ pes_scr(0),
+ pes_scr_ext(0)
+{ log(pvrDEBUG1,"cPvrReadThread");
+ parent=_parent;
+ parent->readThreadRunning = true;
+ SetDescription("PvrReadThread of /dev/video%d", _parent->number);
+ Start();
+}
+
+cPvrReadThread::~cPvrReadThread(void) {
+ log(pvrDEBUG2,"~cPvrReadThread");
+ parent->readThreadRunning = false;
+ if (Running())
+ Cancel(3);
+}
+
+int cPvrReadThread::PutData(const unsigned char *Data, int Count) {
+ if (!tsBuffer) {
+ log(pvrINFO,"cPvrReadThread::PutData():Unable to put data into RingBuffer");
+ return 0;
+ }
+ int bytesFree = tsBuffer->Free();
+ if (bytesFree < Count) {
+ log(pvrERROR,"cPvrReadThread::PutData():Unable to put data into RingBuffer, only %d bytes free, need %d", bytesFree, Count);
+ return 0;
+ }
+ int written = tsBuffer->Put(Data, Count);
+ if (written != Count) {
+ log(pvrERROR,"cPvrReadThread::PutData():put incomplete data into RingBuffer, only %d bytes written, wanted %d", written, Count);
+ tsBuffer->ReportOverflow(Count - written);
+ }
+ //log(pvrDEBUG2, "cPvrReadThread::PutData():packet written");
+ return written;
+}
+
+
+void cPvrReadThread::PesToTs(uint8_t * Data, uint32_t Length) {
+ uint8_t stream_id;
+ bool first = true;
+ uint32_t i;
+ const short *pid = &kVideoPid;
+ uint8_t *counter = &video_counter;
+ const short PayloadSize = TS_SIZE - 4;
+ uint32_t Payload_Count = Length / PayloadSize;
+ uint32_t Payload_Rest = Length % PayloadSize;
+ stream_id = Data[3];
+
+ if (packet_counter <= 0) { // time to send PAT and PMT
+ // increase continuity counter
+ pat_buffer[ 3]= (pat_buffer[ 3] & 0xF0) | (((pat_buffer[ 3] & 0x0F) + 1) & 0x0F);
+ pmt_buffer[ 3]= (pmt_buffer[ 3] & 0xF0) | (((pmt_buffer[ 3] & 0x0F) + 1) & 0x0F);
+ PutData(pat_buffer, TS_SIZE);
+ PutData(pmt_buffer, TS_SIZE);
+ packet_counter = SENDPATPMT_PACKETINTERVAL;
+ }
+
+ if (pes_scr_isvalid) { // send PCR packet
+ ts_buffer[0] = TS_SYNC_BYTE;
+ ts_buffer[1] = kPCRPid >> 8;
+ ts_buffer[2] = kPCRPid & 0xFF;
+ ts_buffer[3] = 0x20 | pcr_counter;
+ ts_buffer[4] = 0xB7;
+ ts_buffer[5] = 0x10;
+ ts_buffer[6] = (pes_scr & 0x01FE000000ull) >> 25; // 33 bits SCR base
+ ts_buffer[7] = (pes_scr & 0x01FE0000) >> 17;
+ ts_buffer[8] = (pes_scr & 0x01FE00) >> 9;
+ ts_buffer[9] = (pes_scr & 0x01FE) >> 1;
+ ts_buffer[10] = (pes_scr & 0x01) << 7;
+ ts_buffer[10] |= 0x7E; // 6 bits between SCR and SCR extension
+ ts_buffer[10] |= (pes_scr_ext & 0x0100) >> 8; // 9 bits SCR extension
+ ts_buffer[11] = (pes_scr_ext & 0xFF);
+ memset(ts_buffer + 12, 0xFF, TS_SIZE - 12);
+ PutData(ts_buffer, TS_SIZE);
+ pcr_counter = (pcr_counter + 1) & 15;
+ pes_scr_isvalid = false;
+ }
+
+ switch (stream_id) {
+ case 0xC0 ... 0xEF:
+ if (stream_id < 0xE0) {
+ pid = &kAudioPid;
+ counter = &audio_counter;
+ }
+ for (i = 0; i < Payload_Count; i++) {
+ ts_buffer[0] = TS_SYNC_BYTE;
+ ts_buffer[1] = (first ? 0x40 : 0x00) | (*pid >> 8);
+ ts_buffer[2] = *pid & 0xFF;
+ ts_buffer[3] = 0x10 | *counter;
+ memcpy(ts_buffer + 4, Data + i * PayloadSize, PayloadSize);
+ PutData(ts_buffer, TS_SIZE);
+ packet_counter--;
+ *counter = (*counter + 1) & 15; //uint8_t
+ first = false;
+ } // end: for (i = 0; i < Payload_Count; i++)
+ if (Payload_Rest > 0) {
+ ts_buffer[0] = TS_SYNC_BYTE;
+ ts_buffer[1] = (first ? 0x40 : 0x00) | (*pid >> 8);
+ ts_buffer[2] = *pid & 0xFF;
+ ts_buffer[3] = 0x30 | *counter;
+ ts_buffer[4] = PayloadSize - Payload_Rest - 1;
+ if (ts_buffer[4] > 0) {
+ ts_buffer[5] = 0x00;
+ memset(ts_buffer + 6, 0xFF, ts_buffer[4] - 1);
+ } //end: if (ts_buffer[4] > 0)
+ memcpy(ts_buffer + 5 + ts_buffer[4], Data + i * PayloadSize, Payload_Rest);
+ PutData(ts_buffer, TS_SIZE);
+ packet_counter--;
+ *counter = (*counter + 1) & 15;
+ first = false;
+ } // end: if (Payload_Rest > 0)
+ break; // end: case 0xE0..0xEF:
+ case 0xBD: {
+ uint8_t * payload_data;
+ uint16_t payload_length;
+ uint32_t pos = 0;
+ uint32_t ts_pos = 0;
+ memset(ts_buffer, 0, TS_SIZE);
+ ts_buffer[0] = TS_SYNC_BYTE;
+ ts_buffer[1] = (first ? 0x40 : 0x00) | (kTeletextPid >> 8);
+ ts_buffer[2] = kTeletextPid & 0xFF;
+ ts_buffer[3] = 0x10 | text_counter;
+
+ payload_length = Length - 9 - Data[8];
+ payload_data = Data + 9 + Data[8];
+ if (memcmp(payload_data, "itv0", 4) == 0)
+ pos = 12;
+ else
+ if (memcmp(payload_data, "ITV0", 4) == 0)
+ pos = 4;
+ else
+ return;
+ while (pos + 43 <= payload_length) {
+ if ((payload_data[pos] & 0x0F) == 0x01) { //VBI_TYPE_TELETEXT
+ ts_buffer[4+ts_pos*46] = 0x02; // data_unit_id
+ ts_buffer[5+ts_pos*46] = 0x2C; // data_unit_length
+ ts_buffer[6+ts_pos*46] = 0x00; // field_parity, line_offset
+ ts_buffer[7+ts_pos*46] = 0xE4; // framing_code
+ for (int j = 0; j < 42; j++) {
+ ts_buffer[8 + ts_pos * 46 + j] = kInvTab[payload_data[pos + 1 + j]];
+ }
+ ts_pos++;
+ if (ts_pos == 4) {
+ ts_pos = 0;
+ PutData(ts_buffer, TS_SIZE);
+ first = false;
+ packet_counter--;
+ text_counter = (text_counter + 1) & 15;
+ memset(ts_buffer, 0, TS_SIZE);
+ ts_buffer[0] = TS_SYNC_BYTE;
+ ts_buffer[1] = (first ? 0x40 : 0x00) | (kTeletextPid >> 8);
+ ts_buffer[2] = kTeletextPid & 0xFF;
+ ts_buffer[3] = 0x10 | text_counter;
+ }
+ }
+ pos += 43;
+ }
+ if (ts_pos > 0) {
+ PutData(ts_buffer, TS_SIZE);
+ first = false;
+ packet_counter--;
+ text_counter = (text_counter + 1) & 15;
+ }
+ break; // end: case 0xBD:
+ }
+ } // end: switch (stream_id)
+}
+
+void cPvrReadThread::ParseProgramStream(uint8_t * Data, uint32_t Length) {
+ uint32_t pos = 0;
+ while (pos < Length) {
+ switch(pes_offset) {
+ case 0:
+ case 1:
+ if (Data[pos] == 0x00)
+ pes_offset++;
+ else
+ pes_offset = 0;
+ pos++;
+ break;
+ case 2:
+ if (Data[pos] == 0x01) {
+ pes_offset++;
+ pos++;
+ }
+ else
+ pes_offset = 0;
+ break;
+ case 3:
+ pes_stream_id = Data[pos];
+ pes_offset++;
+ pos++;
+ break;
+ default:
+ switch (pes_stream_id) {
+ case 0xBA:
+ switch (pes_offset) {
+ case 4:
+ pes_scr = (uint64_t)(Data[pos] & 0x38) << 27;
+ pes_scr |= (uint64_t)(Data[pos] & 3) << 28;
+ pes_offset++;
+ pos++;
+ break;
+ case 5:
+ pes_scr |= (uint64_t)(Data[pos]) << 20;
+ pes_offset++;
+ pos++;
+ break;
+ case 6:
+ pes_scr |= (uint64_t)(Data[pos] & 0xf8) << 12;
+ pes_scr |= (uint64_t)(Data[pos] & 3) << 13;
+ pes_offset++;
+ pos++;
+ break;
+ case 7:
+ pes_scr |= (uint64_t)(Data[pos]) << 5;
+ pes_offset++;
+ pos++;
+ break;
+ case 8:
+ pes_scr |= (uint64_t)(Data[pos] & 0xf8) >> 3;
+ pes_scr_ext = (uint64_t)(Data[pos] & 3) << 7;
+ pes_offset++;
+ pos++;
+ break;
+ case 9:
+ pes_scr_ext |= (Data[pos] & 0xfe) >> 1;
+ pes_scr_isvalid = true;
+ pes_offset++;
+ pos++;
+ break;
+ case 10 ... 12:
+ pes_offset++;
+ pos++;
+ break;
+ case 13:
+ pes_tmp = Data[pos] & 7;
+ pes_offset++;
+ pos++;
+ break;
+ default:
+ if (pes_tmp > 0) {
+ pes_tmp--;
+ pos++;
+ }
+ else
+ pes_offset = 0;
+ break;
+ }
+ break;
+ case 0xBB:
+ switch (pes_offset) {
+ case 4 ... 11:
+ pes_offset++;
+ pos++;
+ break;
+ default:
+ if (pes_tmp > 0) {
+ pes_tmp--;
+ pos++;
+ }
+ else
+ if (Data[pos] & 0x80) {
+ pes_tmp = 3;
+ }
+ else {
+ pes_offset = 0;
+ }
+ break;
+ } // end: switch (pes_offset)
+ break; // end: case 0xBB
+ case 0xBD ... 0xEF:
+ switch (pes_offset) {
+ case 4:
+ pes_length = Data[pos] << 8;
+ pes_offset++;
+ pos++;
+ break;
+ case 5:
+ pes_length += Data[pos];
+ pes_buffer[0] = 0x00;
+ pes_buffer[1] = 0x00;
+ pes_buffer[2] = 0x01;
+ pes_buffer[3] = pes_stream_id;
+ pes_buffer[4] = pes_length >> 8;
+ pes_buffer[5] = pes_length & 0xFF;
+ pes_length += 6;
+ pes_offset++;
+ pos++;
+ break;
+ default: {
+ uint32_t rest = pes_length - pes_offset;
+ if (pos + rest <= Length) {
+ memcpy(pes_buffer + pes_offset, Data + pos, rest);
+ pos += rest;
+ PesToTs(pes_buffer, pes_length);
+ pes_offset = 0;
+ }
+ else {
+ memcpy(pes_buffer + pes_offset, Data + pos, Length - pos);
+ pes_offset += Length - pos;
+ pos += Length - pos;
+ }
+ }
+ break;
+ }
+ break;
+ default:
+ // unexpected PES Stream id, most probably garbage data.
+ pes_offset = 0;
+ return;
+ break;
+ } // end: switch (pes_stream_id)
+ } // end: switch(pes_offset)
+ } // end: while (pos < Length)
+}
+
+void cPvrReadThread::Action(void) {
+ unsigned char buffer[BUFFSIZE_INPUT];
+ int r;
+ int retries = 3;
+ log(pvrDEBUG1,"cPvrReadThread::Action(): Entering Action()");
+ // A derived cThread class must check Running()
+ // repeatedly to see whether it's time to stop.
+ // see VDR/thread.h
+ packet_counter = 0;
+ // prepare PAT and PMT
+ if (parent->streamType != V4L2_MPEG_STREAM_TYPE_MPEG2_TS) {
+ memcpy(pat_buffer, kPAT, TS_SIZE);
+ memcpy(pmt_buffer, kPMT, TS_SIZE);
+ int sid = parent->currentChannel.Sid();
+ int tid = parent->currentChannel.Tid();
+ pat_buffer[8] = (tid >> 8) & 0xFF;
+ pat_buffer[9] = tid & 0xFF;
+ pat_buffer[13] = (sid >> 8) & 0xFF;
+ pat_buffer[14] = sid & 0xFF;
+ int crc = SI::CRC32::crc32((const char *)(pat_buffer + 5), 12, 0xFFFFFFFF);
+ pat_buffer[17] = crc >> 24;
+ pat_buffer[18] = crc >> 16;
+ pat_buffer[19] = crc >> 8;
+ pat_buffer[20] = crc;
+ pmt_buffer[8] = (sid >> 8) & 0xFF;
+ pmt_buffer[9] = sid & 0xFF;
+ crc = SI::CRC32::crc32((const char *)(pmt_buffer + 5), 33, 0xFFFFFFFF);
+ pmt_buffer[38] = crc >> 24;
+ pmt_buffer[39] = crc >> 16;
+ pmt_buffer[40] = crc >> 8;
+ pmt_buffer[41] = crc;
+ }
+ retry:
+ while (Running() && parent->readThreadRunning) {
+ r = read(parent->v4l2_fd, buffer, BUFFSIZE_INPUT);
+ if (r < 0) {
+ log(pvrERROR, "cPvrReadThread::Action():error reading from /dev/video%d: %d:%s %s",
+ parent->number, errno, strerror(errno), (--retries > 0) ? " - retrying" : "");
+ if (retries > 0) {
+ usleep(100);
+ goto retry;
+ }
+ break;
+ }
+ if (r > 0) {
+ if (parent->streamType == V4L2_MPEG_STREAM_TYPE_MPEG2_TS)
+ PutData(buffer, r);
+ else
+ ParseProgramStream(buffer, r);
+ }
+ }
+ log(errno ? pvrERROR : pvrDEBUG2, "cPvrReadThread::Action() %s on /dev/video%d ",
+ errno ? "failed" : "stopped", parent->number);
+}
diff --git a/reader.h b/reader.h
new file mode 100644
index 0000000..c7f5f5b
--- /dev/null
+++ b/reader.h
@@ -0,0 +1,37 @@
+#ifndef _PVR_READER_H_
+#define _PVR_READER_H_
+
+#include "common.h"
+
+class cPvrReadThread : public cThread {
+private:
+ cPvrDevice* parent;
+ cRingBufferLinear * tsBuffer;
+ uint8_t pat_buffer[TS_SIZE];
+ uint8_t pmt_buffer[TS_SIZE];
+ uint8_t ts_buffer[TS_SIZE];
+ uint8_t video_counter;
+ uint8_t audio_counter;
+ uint8_t text_counter;
+ uint8_t pcr_counter;
+ int packet_counter;
+ uint8_t pes_buffer[64 * 1024];
+ uint8_t pes_stream_id;
+ uint32_t pes_offset;
+ uint32_t pes_length;
+ uint32_t pes_tmp;
+ bool pes_scr_isvalid;
+ uint64_t pes_scr;
+ uint32_t pes_scr_ext;
+
+ void ParseProgramStream(uint8_t * Data, uint32_t Length);
+ void PesToTs(uint8_t * Data, uint32_t Length);
+ int PutData(const unsigned char * Data, int Count);
+protected:
+ virtual void Action(void);
+public:
+ cPvrReadThread(cRingBufferLinear * TsBuffer, cPvrDevice* _parent);
+ virtual ~cPvrReadThread(void);
+};
+
+#endif
diff --git a/setup.c b/setup.c
new file mode 100644
index 0000000..3019fa1
--- /dev/null
+++ b/setup.c
@@ -0,0 +1,51 @@
+#include "common.h"
+
+cPvrSetup::cPvrSetup(void) {
+ HideMainMenuEntry = 1; // hide main menu entry
+ UseOnlyCard = 8; // Use all cards
+ LogLevel = 2; // errors and info messages
+ TunerAudioMode = 4; // V4L2_TUNER_MODE_LANG1_LANG2
+ StreamType.value = 0; // V4L2_MPEG_STREAM_TYPE_MPEG2_PS;
+ AudioVolumeTVExceptionCard = 8; // AudioVolumeTVCommon for all cards
+ SliceVBI = 1; // Slice VBI data into mpeg stream
+ UseExternChannelSwitchScript = 0; // don't call externchannelswitch.sh on external inputs
+ TsBufferSizeMB = 3; // ring buffer size
+ TsBufferPrefillRatio = 0; // wait with delivering packets to vdr till buffer is filled
+/* first initialization of all v4l2 controls,
+ most values will be re-initialized later one
+ in QueryAllControls. -wirbel-
+*/
+ Brightness.value = INVALID_VALUE; // default value in QueryAllControls
+ Contrast.value = INVALID_VALUE; // default value in QueryAllControls
+ Saturation.value = INVALID_VALUE; // default value in QueryAllControls
+ Hue.value = INVALID_VALUE; // default value in QueryAllControls
+ AudioVolumeTVCommon.value = INVALID_VALUE; // default value in QueryAllControls
+ AudioVolumeTVException.value = INVALID_VALUE; // default value in QueryAllControls
+ AudioVolumeFM.value = INVALID_VALUE; // default value in QueryAllControls
+ AudioSampling.value = INVALID_VALUE; // default value in QueryAllControls
+ AudioMute.value = 0; // not muted.
+ VideoBitrateTV.value = INVALID_VALUE; // default value in QueryAllControls
+ VideoBitratePeak.value = 15000000; // 15Mbit/s
+ AudioBitrate.value = INVALID_VALUE; // default value in QueryAllControls
+ BitrateMode.value = INVALID_VALUE; // default value in QueryAllControls
+ AspectRatio.value = INVALID_VALUE; // default value in QueryAllControls
+ GopSize.value = INVALID_VALUE; // default value in QueryAllControls
+ BFrames.value = INVALID_VALUE; // default value in QueryAllControls
+ GopClosure.value = INVALID_VALUE; // default value in QueryAllControls
+ FilterSpatialMode.value = INVALID_VALUE; // default value in QueryAllControls
+ FilterSpatial.value = INVALID_VALUE; // default value in QueryAllControls
+ FilterLumaSpatialType.value = INVALID_VALUE; // default value in QueryAllControls
+ FilterChromaSpatialType.value = INVALID_VALUE; // default value in QueryAllControls
+ FilterTemporalMode.value = INVALID_VALUE; // default value in QueryAllControls
+ FilterTemporal.value = INVALID_VALUE; // default value in QueryAllControls
+ FilterMedianType.value = INVALID_VALUE; // default value in QueryAllControls
+ FilterLumaMedianBottom.value = INVALID_VALUE; // default value in QueryAllControls
+ FilterLumaMedianTop.value = INVALID_VALUE; // default value in QueryAllControls
+ FilterChromaMedianBottom.value = INVALID_VALUE; // default value in QueryAllControls
+ FilterChromaMedianTop.value = INVALID_VALUE; // default value in QueryAllControls
+
+ HDPVR_AudioEncoding.value = INVALID_VALUE;
+ HDPVR_AudioInput = 0;
+}
+
+cPvrSetup PvrSetup;
diff --git a/setup.h b/setup.h
new file mode 100644
index 0000000..1ba2dd1
--- /dev/null
+++ b/setup.h
@@ -0,0 +1,66 @@
+#ifndef _PVR_SETUP_H_
+#define _PVR_SETUP_H_
+
+#include "common.h"
+
+struct valSet {
+ v4l2_queryctrl queryctrl;
+ int value;
+ __u32 ctrl_class;
+ bool query_isvalid;
+};
+
+class cPvrSetup {
+public:
+ int HideMainMenuEntry;
+ int UseOnlyCard;
+ int LogLevel;
+ int TunerAudioMode;
+ int SliceVBI;
+ int AudioVolumeTVExceptionCard;
+ int UseExternChannelSwitchScript;
+ int TsBufferSizeMB;
+ int TsBufferPrefillRatio;
+ valSet Brightness;
+ valSet Contrast;
+ valSet Saturation;
+ valSet Hue;
+ valSet AudioVolumeTVCommon;
+ valSet AudioVolumeTVException;
+ valSet AudioVolumeFM;
+ valSet AudioMute;
+ valSet AudioSampling;
+ valSet AudioEncoding;
+ valSet StreamType;
+ valSet VideoBitrateTV;
+ valSet VideoBitratePeak;
+ valSet AudioBitrate;
+ valSet BitrateMode;
+ valSet AspectRatio;
+ valSet BFrames;
+ valSet GopSize;
+ valSet GopClosure;
+ valSet FilterSpatialMode;
+ valSet FilterSpatial;
+ valSet FilterLumaSpatialType;
+ valSet FilterChromaSpatialType;
+ valSet FilterTemporalMode;
+ valSet FilterTemporal;
+ valSet FilterMedianType;
+ valSet FilterLumaMedianBottom;
+ valSet FilterLumaMedianTop;
+ valSet FilterChromaMedianBottom;
+ valSet FilterChromaMedianTop;
+ valSet VBIformat;
+
+ valSet HDPVR_AudioEncoding;
+ int HDPVR_AudioInput;
+
+public:
+ cPvrSetup(void);
+ bool repeat_ReInitAll_after_next_encoderstop;
+};
+
+extern cPvrSetup PvrSetup;
+
+#endif