[vdr-plugin-dvbhddevice] 01/02: Import Upstream version 2.2.0
Tobias Grimm
tiber-guest at moszumanska.debian.org
Sat Jan 7 20:05:19 UTC 2017
This is an automated email from the git hooks/post-receive script.
tiber-guest pushed a commit to branch master
in repository vdr-plugin-dvbhddevice.
commit 457391b6c0a66a463f0a0948ecee7eec6fa81d08
Author: Tobias Grimm <git at e-tobi.net>
Date: Sat Jan 7 20:10:35 2017 +0100
Import Upstream version 2.2.0
---
COPYING | 340 +++++++++++++
HISTORY | 108 ++++
Makefile | 123 +++++
README | 18 +
dvbhddevice.c | 123 +++++
dvbhdffdevice.c | 1133 ++++++++++++++++++++++++++++++++++++++++++
dvbhdffdevice.h | 138 +++++
hdffcmd.c | 401 +++++++++++++++
hdffcmd.h | 100 ++++
hdffosd.c | 844 +++++++++++++++++++++++++++++++
hdffosd.h | 24 +
libhdffcmd/Makefile | 68 +++
libhdffcmd/bitbuffer.c | 79 +++
libhdffcmd/bitbuffer.h | 43 ++
libhdffcmd/hdffcmd.h | 42 ++
libhdffcmd/hdffcmd_av.c | 506 +++++++++++++++++++
libhdffcmd/hdffcmd_av.h | 159 ++++++
libhdffcmd/hdffcmd_base.c | 45 ++
libhdffcmd/hdffcmd_base.h | 55 ++
libhdffcmd/hdffcmd_defs.h | 125 +++++
libhdffcmd/hdffcmd_generic.c | 165 ++++++
libhdffcmd/hdffcmd_generic.h | 36 ++
libhdffcmd/hdffcmd_hdmi.c | 120 +++++
libhdffcmd/hdffcmd_hdmi.h | 72 +++
libhdffcmd/hdffcmd_mux.c | 81 +++
libhdffcmd/hdffcmd_mux.h | 56 +++
libhdffcmd/hdffcmd_osd.c | 720 +++++++++++++++++++++++++++
libhdffcmd/hdffcmd_osd.h | 170 +++++++
libhdffcmd/hdffcmd_remote.c | 67 +++
libhdffcmd/hdffcmd_remote.h | 39 ++
menu.c | 65 +++
menu.h | 29 ++
po/de_DE.po | 128 +++++
po/et_EE.po | 128 +++++
po/fi_FI.po | 128 +++++
po/it_IT.po | 131 +++++
po/uk_UA.po | 129 +++++
setup.c | 476 ++++++++++++++++++
setup.h | 66 +++
39 files changed, 7280 insertions(+)
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..f90922e
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser General
+Public License instead of this License.
diff --git a/HISTORY b/HISTORY
new file mode 100644
index 0000000..532b5e9
--- /dev/null
+++ b/HISTORY
@@ -0,0 +1,108 @@
+VDR Plugin 'dvbhddevice' Revision History
+-----------------------------------------
+
+2009-12-29: Version 0.0.1
+
+- Initial revision.
+
+2010-01-04: Version 0.0.2
+
+- Calling the MakePrimaryDevice() function of the base class to allow
+ the cDevice to stop displaying subtitles.
+- Added support for DVB cards with multiple frontends.
+
+2011-04-17: Version 0.0.3
+
+- Improved trickmodes
+- No transfer mode needed for dolby digital
+- Clear audio and video PID when Clear() ist called to stop audio decoding when jumping to cutting marks
+- Support still frames in H264 format
+- Remote control setup
+- Added analogue video setting, support volume control.
+- Support setting of audio delay.
+- Support setting of audio channel (Stereo, Left, Right)
+- Support setting of audio downmix mode.
+- Playback of PES data is working now.
+- Fall back to MPEG2 stream type when no PMT is available.
+- Added support for PES PCM playback
+- Support HDMI-CEC. (One-Touch Play)
+- Added low level OSD implementation.
+- Added option to select between high level and low level OSD.
+- high level OSD: Implement SaveRegion and RestoreRegion.
+- Fix not working video playback when PCR PID is different from video PID.
+- Fix not working pause when playing H.264 video
+- Improvements in transfer mode, fix audio dropouts or no audio at all
+- Add implementation of CanHandleAreas method to support VDR 1.7.17
+- in cHdffOsdRaw::Flush fix reusing of loop variable i in subloop that lead to OSD update problems
+- Specify container format when starting audio decoding to support PES-DVD containers
+- Added support for True Color OSD
+- Allow to disable true color OSD support via setup option
+
+2011-04-xx: Version 0.0.4
+
+- locally define DVB OSD API extensions to support compiling with original DVB headers
+- Return correct pixel aspect ratio in GetOsdSize
+- Adapt Makefile to changes introduced in recent VDR versions
+
+2012-12-27: Version 0.0.5
+
+- Adapted Makefile to changes introduced in recent VDR versions.
+
+2013-01-12: Version 0.0.6
+
+- Adapted Makefile to changes introduced in recent VDR versions.
+
+2013-01-24: Version 0.0.7
+
+- Fixed cHdffOsd::SetAreas() (didn't clear the OSD).
+
+2013-02-16: Version 0.0.8
+
+- Added missing $(LDFLAGS) to the Makefile (thanks to Ville Skytt�).
+
+2013-02-24: Version 0.0.9
+
+- Updated the Finnish OSD texts (thanks to Rolf Ahrenberg).
+- Updated the Italian OSD texts (thanks to Diego Pierotto).
+- Fixed flashing OSD in "high level OSD" mode in case a menu is open while subtitles
+ are being displayed.
+- Fixed immediately disappearing subtitle track menu when selecting "No subtitles".
+
+2013-03-31: Version 2.0.0
+
+- Official release.
+
+2013-04-11: Version 2.0.1
+
+- Fixed aspect ratio and position of scaled video.
+
+2013-08-23: Version 2.1.1
+
+- Fixed aspect ratio and position of scaled video.
+- Added yellow button in main menu to send CEC TV-Off command.
+
+2013-08-26: Version 2.1.2
+
+- Updated the Finnish OSD texts (thanks to Rolf Ahrenberg).
+
+2014-01-01: Version 2.1.3
+
+- Avoiding unnecessary pkg-config warnings in plugin Makefiles.
+- cDevice::TrickSpeed() now has an additional parameter named Forward.
+
+2014-01-17: Version 2.1.4
+
+- Using PCR based clock recovery in transfer mode.
+
+2014-03-15: Version 2.1.6
+
+- The function cDevice::GetVideoSystem() has been deprecated.
+- Removed old-style video format setting functions.
+
+2015-02-11: Version 2.1.7
+
+- Adapted to the new return value of cOsd::RenderPixmaps().
+
+2015-02-19: Version 2.2.0
+
+- Official release.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..a994e2e
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,123 @@
+#
+# Makefile for a Video Disk Recorder plugin
+#
+
+# 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.
+
+PLUGIN = dvbhddevice
+
+### The version number of this plugin (taken from the main source file):
+
+VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ print $$6 }' | sed -e 's/[";]//g')
+
+### The directory environment:
+
+# Use package data if installed...otherwise assume we're under the VDR source directory:
+PKGCFG = $(if $(VDRDIR),$(shell pkg-config --variable=$(1) $(VDRDIR)/vdr.pc),$(shell PKG_CONFIG_PATH="$$PKG_CONFIG_PATH:../../.." pkg-config --variable=$(1) vdr))
+LIBDIR = $(call PKGCFG,libdir)
+LOCDIR = $(call PKGCFG,locdir)
+PLGCFG = $(call PKGCFG,plgcfg)
+#
+TMPDIR ?= /tmp
+
+### The compiler options:
+
+export CFLAGS = $(call PKGCFG,cflags)
+export CXXFLAGS = $(call PKGCFG,cxxflags)
+
+### The version number of VDR's plugin API:
+
+APIVERSION = $(call PKGCFG,apiversion)
+
+### Allow user defined options to overwrite defaults:
+
+-include $(PLGCFG)
+
+### The name of the distribution archive:
+
+ARCHIVE = $(PLUGIN)-$(VERSION)
+PACKAGE = vdr-$(ARCHIVE)
+
+### The name of the shared object file:
+
+SOFILE = libvdr-$(PLUGIN).so
+
+### Includes and Defines (add further entries here):
+
+INCLUDES +=
+
+DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
+
+### The object files (add further files here):
+
+OBJS = $(PLUGIN).o dvbhdffdevice.o hdffcmd.o hdffosd.o menu.o setup.o
+
+### The main target:
+
+all: $(SOFILE) i18n
+
+### Implicit rules:
+
+%.o: %.c
+ $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
+
+### Dependencies:
+
+MAKEDEP = $(CXX) -MM -MG
+DEPFILE = .dependencies
+$(DEPFILE): Makefile
+ @$(MAKEDEP) $(CXXFLAGS) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@
+
+-include $(DEPFILE)
+
+### Internationalization (I18N):
+
+PODIR = po
+I18Npo = $(wildcard $(PODIR)/*.po)
+I18Nmo = $(addsuffix .mo, $(foreach file, $(I18Npo), $(basename $(file))))
+I18Nmsgs = $(addprefix $(DESTDIR)$(LOCDIR)/, $(addsuffix /LC_MESSAGES/vdr-$(PLUGIN).mo, $(notdir $(foreach file, $(I18Npo), $(basename $(file))))))
+I18Npot = $(PODIR)/$(PLUGIN).pot
+
+%.mo: %.po
+ msgfmt -c -o $@ $<
+
+$(I18Npot): $(wildcard *.c)
+ xgettext -C -cTRANSLATORS --no-wrap --no-location -k -ktr -ktrNOOP --package-name=vdr-$(PLUGIN) --package-version=$(VERSION) --msgid-bugs-address='<see README>' -o $@ `ls $^`
+
+%.po: $(I18Npot)
+ msgmerge -U --no-wrap --no-location --backup=none -q -N $@ $<
+ @touch $@
+
+$(I18Nmsgs): $(DESTDIR)$(LOCDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo
+ install -D -m644 $< $@
+
+.PHONY: i18n
+i18n: $(I18Nmo) $(I18Npot)
+
+install-i18n: $(I18Nmsgs)
+
+### Targets:
+
+$(SOFILE): $(OBJS) libhdffcmd
+ @$(MAKE) --no-print-directory -C libhdffcmd all
+ $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) libhdffcmd/libhdffcmd.a -o $@
+
+install-lib: $(SOFILE)
+ install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION)
+
+install: install-lib install-i18n
+
+dist: $(I18Npo) 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 $(PODIR)/*.mo $(PODIR)/*.pot
+ @-rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~
+ @-$(MAKE) --no-print-directory -C libhdffcmd clean
diff --git a/README b/README
new file mode 100644
index 0000000..5697dea
--- /dev/null
+++ b/README
@@ -0,0 +1,18 @@
+This is a "plugin" for the Video Disk Recorder (VDR).
+
+Written by: Andreas Regel <andreas.regel at gmx.de>
+
+Project's homepage: http://powarman.dyndns.org/hg/dvbhddevice
+
+Latest version available at: http://powarman.dyndns.org/hg/dvbhddevice
+
+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.
+See the file COPYING for more information.
+
+Description:
+
+The 'dvbhddevice' plugin implements the output device for the
+"Full Featured TechnoTrend S2-6400" DVB cards.
diff --git a/dvbhddevice.c b/dvbhddevice.c
new file mode 100644
index 0000000..84902b1
--- /dev/null
+++ b/dvbhddevice.c
@@ -0,0 +1,123 @@
+/*
+ * dvbhddevice.c: A plugin for the Video Disk Recorder
+ *
+ * See the README file for copyright information and how to reach the author.
+ */
+
+#include <getopt.h>
+#include <vdr/plugin.h>
+#include <vdr/shutdown.h>
+#include "dvbhdffdevice.h"
+#include "menu.h"
+#include "setup.h"
+
+static const char *VERSION = "2.2.0";
+static const char *DESCRIPTION = trNOOP("HD Full Featured DVB device");
+static const char *MAINMENUENTRY = "dvbhddevice";
+
+class cPluginDvbhddevice : public cPlugin {
+private:
+ cDvbHdFfDeviceProbe *probe;
+ bool mIsUserInactive;
+public:
+ cPluginDvbhddevice(void);
+ virtual ~cPluginDvbhddevice();
+ virtual const char *Version(void) { return VERSION; }
+ virtual const char *Description(void) { return tr(DESCRIPTION); }
+ virtual void MainThreadHook(void);
+ virtual void Stop(void);
+ virtual const char *MainMenuEntry(void);
+ virtual cOsdObject *MainMenuAction(void);
+ virtual cMenuSetupPage *SetupMenu(void);
+ virtual bool SetupParse(const char *Name, const char *Value);
+ virtual const char *CommandLineHelp(void);
+ virtual bool ProcessArgs(int argc, char *argv[]);
+ };
+
+cPluginDvbhddevice::cPluginDvbhddevice(void)
+: mIsUserInactive(true)
+{
+ probe = new cDvbHdFfDeviceProbe;
+}
+
+cPluginDvbhddevice::~cPluginDvbhddevice()
+{
+ delete probe;
+}
+
+const char *cPluginDvbhddevice::CommandLineHelp(void)
+{
+ return " -o --outputonly do not receive, just use as output device\n";
+}
+
+bool cPluginDvbhddevice::ProcessArgs(int argc, char *argv[])
+{
+ static struct option long_options[] = {
+ { "outputonly", no_argument, NULL, 'o' },
+ { NULL, no_argument, NULL, 0 }
+ };
+
+ int c;
+ while ((c = getopt_long(argc, argv, "o", long_options, NULL)) != -1) {
+ switch (c) {
+ case 'o': probe->SetOutputOnly(true);
+ break;
+ default: return false;
+ }
+ }
+ return true;
+}
+
+void cPluginDvbhddevice::MainThreadHook(void)
+{
+ bool isUserInactive = ShutdownHandler.IsUserInactive();
+ if (isUserInactive != mIsUserInactive)
+ {
+ mIsUserInactive = isUserInactive;
+ if (gHdffSetup.CecEnabled && gHdffSetup.CecTvOn)
+ {
+ HDFF::cHdffCmdIf * hdffCmdIf = cDvbHdFfDevice::GetHdffCmdHandler();
+ if (hdffCmdIf && !mIsUserInactive)
+ {
+ hdffCmdIf->CmdHdmiSendCecCommand(HDFF_CEC_COMMAND_TV_ON);
+ }
+ }
+ }
+}
+
+void cPluginDvbhddevice::Stop(void)
+{
+ if (gHdffSetup.CecEnabled && gHdffSetup.CecTvOff)
+ {
+ HDFF::cHdffCmdIf * hdffCmdIf = cDvbHdFfDevice::GetHdffCmdHandler();
+ if (hdffCmdIf)
+ {
+ hdffCmdIf->CmdHdmiSendCecCommand(HDFF_CEC_COMMAND_TV_OFF);
+ isyslog("HDFF_CEC_COMMAND_TV_OFF");
+ }
+ }
+}
+
+const char *cPluginDvbhddevice::MainMenuEntry(void)
+{
+ return gHdffSetup.HideMainMenu ? NULL : MAINMENUENTRY;
+}
+
+cOsdObject *cPluginDvbhddevice::MainMenuAction(void)
+{
+ HDFF::cHdffCmdIf * hdffCmdIf = cDvbHdFfDevice::GetHdffCmdHandler();
+ return hdffCmdIf ? new cHdffMenu(hdffCmdIf) : NULL;
+}
+
+cMenuSetupPage *cPluginDvbhddevice::SetupMenu(void)
+{
+ HDFF::cHdffCmdIf * hdffCmdIf = cDvbHdFfDevice::GetHdffCmdHandler();
+ return hdffCmdIf ? new cHdffSetupPage(hdffCmdIf) : NULL;
+}
+
+bool cPluginDvbhddevice::SetupParse(const char *Name, const char *Value)
+{
+ return gHdffSetup.SetupParse(Name, Value);
+}
+
+VDRPLUGINCREATOR(cPluginDvbhddevice); // Don't touch this!
diff --git a/dvbhdffdevice.c b/dvbhdffdevice.c
new file mode 100644
index 0000000..60decb7
--- /dev/null
+++ b/dvbhdffdevice.c
@@ -0,0 +1,1133 @@
+/*
+ * dvbhdffdevice.c: The DVB HD Full Featured device interface
+ *
+ * See the README file for copyright information and how to reach the author.
+ */
+
+#include <stdint.h>
+
+#include "dvbhdffdevice.h"
+#include <errno.h>
+#include <limits.h>
+#include <libsi/si.h>
+#include <linux/videodev2.h>
+#include <linux/dvb/audio.h>
+#include <linux/dvb/dmx.h>
+#include <linux/dvb/video.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <vdr/eitscan.h>
+#include <vdr/transfer.h>
+#include "hdffosd.h"
+#include "setup.h"
+
+
+static uchar *YuvToJpeg(uchar *Mem, int Width, int Height, int &Size, int Quality);
+
+
+// --- cDvbHdFfDevice --------------------------------------------------------
+
+int cDvbHdFfDevice::devHdffOffset = -1;
+
+cDvbHdFfDevice::cDvbHdFfDevice(int Adapter, int Frontend, bool OutputOnly)
+:cDvbDevice(Adapter, Frontend)
+{
+ spuDecoder = NULL;
+ audioChannel = 0;
+ playMode = pmNone;
+ mHdffCmdIf = NULL;
+ outputOnly = OutputOnly;
+
+ if (outputOnly) {
+ StopSectionHandler();
+ // cannot close fd_tuner, fd_ca and delete ciAdapter, dvbTuner here - are cDvbDevice private
+ }
+
+ // Devices that are only present on cards with decoders:
+
+ fd_osd = DvbOpen(DEV_DVB_OSD, adapter, frontend, O_RDWR);
+ fd_video = DvbOpen(DEV_DVB_VIDEO, adapter, frontend, O_RDWR | O_NONBLOCK);
+ fd_audio = DvbOpen(DEV_DVB_AUDIO, adapter, frontend, O_RDWR | O_NONBLOCK);
+
+ //TODO missing /dev/video offset calculation
+
+ isHdffPrimary = false;
+ if (devHdffOffset < 0) {
+ devHdffOffset = adapter;
+ isHdffPrimary = true;
+ mHdffCmdIf = new HDFF::cHdffCmdIf(fd_osd);
+
+ uint32_t firmwareVersion = mHdffCmdIf->CmdGetFirmwareVersion(NULL, 0);
+ if (firmwareVersion < 0x401)
+ supportsPcrInTransferMode = false;
+ else
+ supportsPcrInTransferMode = true;
+
+ /* reset some stuff in case the VDR was killed before and had no chance
+ to clean up. */
+ mHdffCmdIf->CmdOsdReset();
+
+ mHdffCmdIf->CmdAvSetVideoSpeed(0, 100);
+ mHdffCmdIf->CmdAvSetAudioSpeed(0, 100);
+
+ mHdffCmdIf->CmdAvEnableVideoAfterStop(0, false);
+ mHdffCmdIf->CmdAvSetPcrPid(0, 0);
+ mHdffCmdIf->CmdAvSetVideoPid(0, 0, HDFF_VIDEO_STREAM_MPEG1);
+ mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF_AUDIO_STREAM_MPEG1);
+
+ ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX);
+ mHdffCmdIf->CmdAvSetDecoderInput(0, 0);
+ mHdffCmdIf->CmdAvEnableSync(0, true);
+ mHdffCmdIf->CmdAvSetPlayMode(0, true);
+ /* reset done */
+
+ mHdffCmdIf->CmdAvSetAudioDelay(gHdffSetup.AudioDelay);
+ mHdffCmdIf->CmdAvSetAudioDownmix((HdffAudioDownmixMode_t) gHdffSetup.AudioDownmix);
+ mHdffCmdIf->CmdAvSetSyncShift(gHdffSetup.AvSyncShift);
+ mHdffCmdIf->CmdMuxSetVideoOut((HdffVideoOut_t) gHdffSetup.AnalogueVideo);
+ mHdffCmdIf->CmdHdmiSetVideoMode(gHdffSetup.GetVideoMode());
+
+ HdffHdmiConfig_t hdmiConfig;
+ memset(&hdmiConfig, 0, sizeof(hdmiConfig));
+ hdmiConfig.TransmitAudio = true;
+ hdmiConfig.ForceDviMode = false;
+ hdmiConfig.CecEnabled = gHdffSetup.CecEnabled;
+ strcpy(hdmiConfig.CecDeviceName, "VDR");
+ hdmiConfig.VideoModeAdaption = (HdffVideoModeAdaption_t) gHdffSetup.VideoModeAdaption;
+ mHdffCmdIf->CmdHdmiConfigure(&hdmiConfig);
+
+ mHdffCmdIf->CmdRemoteSetProtocol((HdffRemoteProtocol_t) gHdffSetup.RemoteProtocol);
+ mHdffCmdIf->CmdRemoteSetAddressFilter(gHdffSetup.RemoteAddress >= 0, gHdffSetup.RemoteAddress);
+ }
+}
+
+cDvbHdFfDevice::~cDvbHdFfDevice()
+{
+ delete spuDecoder;
+ if (isHdffPrimary)
+ {
+ delete mHdffCmdIf;
+ }
+ // We're not explicitly closing any device files here, since this sometimes
+ // caused segfaults. Besides, the program is about to terminate anyway...
+}
+
+void cDvbHdFfDevice::MakePrimaryDevice(bool On)
+{
+ if (On) {
+ new cHdffOsdProvider(mHdffCmdIf);
+
+ gHdffSetup.SetVideoFormat(mHdffCmdIf);
+ }
+ cDvbDevice::MakePrimaryDevice(On);
+}
+
+bool cDvbHdFfDevice::HasDecoder(void) const
+{
+ return isHdffPrimary;
+}
+
+cSpuDecoder *cDvbHdFfDevice::GetSpuDecoder(void)
+{
+ if (!spuDecoder && IsPrimaryDevice())
+ spuDecoder = new cDvbSpuDecoder();
+ return spuDecoder;
+}
+
+uchar *cDvbHdFfDevice::GrabImage(int &Size, bool Jpeg, int Quality, int SizeX, int SizeY)
+{
+ #define BUFFER_SIZE (sizeof(struct v4l2_pix_format) + 1920 * 1080 * 2)
+ int fd;
+ uint8_t * buffer;
+ uint8_t * result = NULL;
+
+ fd = DvbOpen(DEV_DVB_VIDEO, adapter, frontend, O_RDONLY);
+ if (fd < 0) {
+ esyslog("GrabImage: failed open DVB video device");
+ return NULL;
+ }
+
+ buffer = (uint8_t *) malloc(BUFFER_SIZE);
+ if (buffer)
+ {
+ int readBytes;
+
+ readBytes = read(fd, buffer, BUFFER_SIZE);
+ if (readBytes < (int) sizeof(struct v4l2_pix_format))
+ esyslog("GrabImage: failed reading from DVB video device");
+ else {
+ struct v4l2_pix_format * pixfmt;
+ int dataSize;
+
+ pixfmt = (struct v4l2_pix_format *) buffer;
+ dsyslog("GrabImage: Read image of size %d x %d",
+ pixfmt->width, pixfmt->height);
+ dataSize = readBytes - sizeof(struct v4l2_pix_format);
+ if (dataSize < (int) pixfmt->sizeimage)
+ esyslog("GrabImage: image is not complete");
+ else {
+ if (Jpeg) {
+ uint8_t * temp;
+ temp = (uint8_t *) malloc(pixfmt->width * 3 * pixfmt->height);
+ if (temp) {
+ int numPixels = pixfmt->width * pixfmt->height;
+ uint8_t * destData = temp;
+ uint8_t * srcData = buffer + sizeof(struct v4l2_pix_format);
+ while (numPixels > 0)
+ {
+ destData[0] = srcData[1];
+ destData[1] = srcData[0];
+ destData[2] = srcData[2];
+ destData[3] = srcData[3];
+ destData[4] = srcData[0];
+ destData[5] = srcData[2];
+ srcData += 4;
+ destData += 6;
+ numPixels -= 2;
+ }
+ if (Quality < 0)
+ Quality = 100;
+ result = YuvToJpeg(temp, pixfmt->width, pixfmt->height, Size, Quality);
+ free(temp);
+ }
+ }
+ else {
+ // convert to PNM:
+ char buf[32];
+ snprintf(buf, sizeof(buf), "P6\n%d\n%d\n255\n",
+ pixfmt->width, pixfmt->height);
+ int l = strlen(buf);
+ Size = l + pixfmt->width * 3 * pixfmt->height;
+ result = (uint8_t *) malloc(Size);
+ if (result)
+ {
+ memcpy(result, buf, l);
+ uint8_t * destData = result + l;
+ uint8_t * srcData = buffer + sizeof(struct v4l2_pix_format);
+ int numPixels = pixfmt->width * pixfmt->height;
+ while (numPixels > 0)
+ {
+ int cb = srcData[0] - 128;
+ int y1 = srcData[1];
+ int cr = srcData[2] - 128;
+ int y2 = srcData[3];
+ int r;
+ int g;
+ int b;
+
+ r = y1 + (int) (1.402f * cr);
+ g = y1 - (int) (0.344f * cb + 0.714f * cr);
+ b = y1 + (int) (1.772f * cb);
+ destData[0] = r > 255 ? 255 : r < 0 ? 0 : r;
+ destData[1] = g > 255 ? 255 : g < 0 ? 0 : g;
+ destData[2] = b > 255 ? 255 : b < 0 ? 0 : b;
+ r = y2 + (int) (1.402f * cr);
+ g = y2 - (int) (0.344f * cb + 0.714f * cr);
+ b = y2 + (int) (1.772f * cb);
+ destData[3] = r > 255 ? 255 : r < 0 ? 0 : r;
+ destData[4] = g > 255 ? 255 : g < 0 ? 0 : g;
+ destData[5] = b > 255 ? 255 : b < 0 ? 0 : b;
+
+ srcData += 4;
+ destData += 6;
+ numPixels -= 2;
+ }
+ }
+ }
+ }
+ }
+ free(buffer);
+ }
+
+ close(fd);
+
+ return result;
+}
+
+void cDvbHdFfDevice::SetVideoDisplayFormat(eVideoDisplayFormat VideoDisplayFormat)
+{
+ if (gHdffSetup.TvFormat == HDFF_TV_FORMAT_4_BY_3)
+ {
+ switch (VideoDisplayFormat)
+ {
+ case vdfPanAndScan:
+ case vdfCenterCutOut:
+ gHdffSetup.VideoConversion = HDFF_VIDEO_CONVERSION_CENTRE_CUT_OUT;
+ break;
+
+ case vdfLetterBox:
+ gHdffSetup.VideoConversion = HDFF_VIDEO_CONVERSION_LETTERBOX_16_BY_9;
+ break;
+ }
+ gHdffSetup.SetVideoFormat(mHdffCmdIf);
+ }
+ cDevice::SetVideoDisplayFormat(VideoDisplayFormat);
+}
+
+void cDvbHdFfDevice::GetVideoSize(int &Width, int &Height, double &VideoAspect)
+{
+ if (fd_video >= 0) {
+ video_size_t vs;
+ if (ioctl(fd_video, VIDEO_GET_SIZE, &vs) == 0) {
+ Width = vs.w;
+ Height = vs.h;
+ switch (vs.aspect_ratio) {
+ default:
+ case VIDEO_FORMAT_4_3: VideoAspect = 4.0 / 3.0; break;
+ case VIDEO_FORMAT_16_9: VideoAspect = 16.0 / 9.0; break;
+ case VIDEO_FORMAT_221_1: VideoAspect = 2.21; break;
+ }
+ return;
+ }
+ else
+ LOG_ERROR;
+ }
+ cDevice::GetVideoSize(Width, Height, VideoAspect);
+}
+
+void cDvbHdFfDevice::GetOsdSize(int &Width, int &Height, double &PixelAspect)
+{
+ gHdffSetup.GetOsdSize(Width, Height, PixelAspect);
+}
+
+bool cDvbHdFfDevice::SetPid(cPidHandle *Handle, int Type, bool On)
+{
+ //printf("SetPid Type %d, On %d, PID %5d, streamtype %d, handle %d, used %d\n", Type, On, Handle->pid, Handle->streamType, Handle->handle, Handle->used);
+ if (Handle->pid) {
+ dmx_pes_filter_params pesFilterParams;
+ memset(&pesFilterParams, 0, sizeof(pesFilterParams));
+ if (On) {
+ if (Handle->handle < 0) {
+ Handle->handle = DvbOpen(DEV_DVB_DEMUX, adapter, frontend, O_RDWR | O_NONBLOCK, true);
+ if (Handle->handle < 0) {
+ LOG_ERROR;
+ return false;
+ }
+ }
+ if (Type == ptPcr)
+ mHdffCmdIf->CmdAvSetPcrPid(0, Handle->pid);
+ else if (Type == ptVideo) {
+ if (Handle->streamType == 0x1B)
+ mHdffCmdIf->CmdAvSetVideoPid(0, Handle->pid, HDFF_VIDEO_STREAM_H264);
+ else
+ mHdffCmdIf->CmdAvSetVideoPid(0, Handle->pid, HDFF_VIDEO_STREAM_MPEG2);
+ }
+ else if (Type == ptAudio) {
+ if (Handle->streamType == 0x03)
+ mHdffCmdIf->CmdAvSetAudioPid(0, Handle->pid, HDFF_AUDIO_STREAM_MPEG1);
+ else if (Handle->streamType == 0x04)
+ mHdffCmdIf->CmdAvSetAudioPid(0, Handle->pid, HDFF_AUDIO_STREAM_MPEG2);
+ else if (Handle->streamType == SI::AC3DescriptorTag)
+ mHdffCmdIf->CmdAvSetAudioPid(0, Handle->pid, HDFF_AUDIO_STREAM_AC3);
+ else if (Handle->streamType == SI::EnhancedAC3DescriptorTag)
+ mHdffCmdIf->CmdAvSetAudioPid(0, Handle->pid, HDFF_AUDIO_STREAM_EAC3);
+ else if (Handle->streamType == 0x0F)
+ mHdffCmdIf->CmdAvSetAudioPid(0, Handle->pid, HDFF_AUDIO_STREAM_AAC);
+ else if (Handle->streamType == 0x11)
+ mHdffCmdIf->CmdAvSetAudioPid(0, Handle->pid, HDFF_AUDIO_STREAM_HE_AAC);
+ else
+ mHdffCmdIf->CmdAvSetAudioPid(0, Handle->pid, HDFF_AUDIO_STREAM_MPEG1);
+ }
+ if (!(Type <= ptDolby && Handle->used <= 1)) {
+ pesFilterParams.pid = Handle->pid;
+ pesFilterParams.input = DMX_IN_FRONTEND;
+ pesFilterParams.output = DMX_OUT_TS_TAP;
+ pesFilterParams.pes_type= DMX_PES_OTHER;
+ pesFilterParams.flags = DMX_IMMEDIATE_START;
+ if (ioctl(Handle->handle, DMX_SET_PES_FILTER, &pesFilterParams) < 0) {
+ LOG_ERROR;
+ return false;
+ }
+ }
+ }
+ else if (!Handle->used) {
+ CHECK(ioctl(Handle->handle, DMX_STOP));
+ if (Type == ptPcr)
+ mHdffCmdIf->CmdAvSetPcrPid(0, 0);
+ else if (Type == ptVideo)
+ mHdffCmdIf->CmdAvSetVideoPid(0, 0, HDFF_VIDEO_STREAM_MPEG1);
+ else if (Type == ptAudio)
+ mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF_AUDIO_STREAM_MPEG1);
+ else if (Type == ptDolby)
+ mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF_AUDIO_STREAM_AC3);
+ //TODO missing setting to 0x1FFF??? see cDvbDevice::SetPid()
+ close(Handle->handle);
+ Handle->handle = -1;
+ }
+ }
+ return true;
+}
+
+bool cDvbHdFfDevice::ProvidesSource(int Source) const
+{
+ if (outputOnly)
+ return false;
+ return cDvbDevice::ProvidesSource(Source);
+}
+
+int cDvbHdFfDevice::NumProvidedSystems(void) const
+{
+ if (outputOnly)
+ return 0;
+ return cDvbDevice::NumProvidedSystems();
+}
+
+void cDvbHdFfDevice::TurnOffLiveMode(bool LiveView)
+{
+ // Turn off live PIDs:
+
+ DetachAll(pidHandles[ptAudio].pid);
+ DetachAll(pidHandles[ptVideo].pid);
+ DetachAll(pidHandles[ptPcr].pid);
+ DetachAll(pidHandles[ptTeletext].pid);
+ DelPid(pidHandles[ptAudio].pid);
+ DelPid(pidHandles[ptVideo].pid);
+ DelPid(pidHandles[ptPcr].pid, ptPcr);
+ DelPid(pidHandles[ptTeletext].pid);
+ DelPid(pidHandles[ptDolby].pid);
+}
+
+bool cDvbHdFfDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
+{
+ int apid = Channel->Apid(0);
+ int vpid = Channel->Vpid();
+ int dpid = Channel->Dpid(0);
+
+ bool DoTune = !IsTunedToTransponder(Channel);
+
+ bool pidHandlesVideo = vpid && pidHandles[ptVideo].pid == vpid;
+ bool pidHandlesAudio = apid && pidHandles[ptAudio].pid == apid;
+
+ bool TurnOffLivePIDs = DoTune
+ || !IsPrimaryDevice()
+ || LiveView // for a new live view the old PIDs need to be turned off
+ || pidHandlesVideo // for recording the PIDs must be shifted from DMX_PES_AUDIO/VIDEO to DMX_PES_OTHER
+ ;
+
+ bool StartTransferMode = IsPrimaryDevice() && !DoTune
+ && (LiveView && HasPid(vpid ? vpid : apid) && (!pidHandlesVideo || (!pidHandlesAudio && (dpid ? pidHandles[ptAudio].pid != dpid : true)))// the PID is already set as DMX_PES_OTHER
+ || !LiveView && (pidHandlesVideo || pidHandlesAudio) // a recording is going to shift the PIDs from DMX_PES_AUDIO/VIDEO to DMX_PES_OTHER
+ );
+ if (CamSlot() && !ChannelCamRelations.CamDecrypt(Channel->GetChannelID(), CamSlot()->SlotNumber()))
+ StartTransferMode |= LiveView && IsPrimaryDevice() && Channel->Ca() >= CA_ENCRYPTED_MIN;
+
+ //printf("SetChannelDevice Transfer %d, Live %d\n", StartTransferMode, LiveView);
+
+ bool TurnOnLivePIDs = !StartTransferMode && LiveView;
+
+ // Turn off live PIDs if necessary:
+
+ if (TurnOffLivePIDs)
+ TurnOffLiveMode(LiveView);
+
+ // Set the tuner:
+
+ if (!cDvbDevice::SetChannelDevice(Channel, LiveView))
+ return false;
+
+ // PID settings:
+
+ if (TurnOnLivePIDs) {
+ if (!(AddPid(Channel->Ppid(), ptPcr) && AddPid(vpid, ptVideo, Channel->Vtype()) && AddPid(apid ? apid : dpid, ptAudio, apid ? 0 : Channel->Dtype(0)))) {
+ esyslog("ERROR: failed to set PIDs for channel %d on device %d", Channel->Number(), CardIndex() + 1);
+ return false;
+ }
+ }
+ else if (StartTransferMode)
+ cControl::Launch(new cTransferControl(this, Channel));
+
+ return true;
+}
+
+int cDvbHdFfDevice::GetAudioChannelDevice(void)
+{
+ return audioChannel;
+}
+
+void cDvbHdFfDevice::SetAudioChannelDevice(int AudioChannel)
+{
+ mHdffCmdIf->CmdAvSetAudioChannel(AudioChannel);
+ audioChannel = AudioChannel;
+}
+
+void cDvbHdFfDevice::SetVolumeDevice(int Volume)
+{
+ mHdffCmdIf->CmdMuxSetVolume(Volume * 100 / 255);
+}
+
+void cDvbHdFfDevice::SetAudioTrackDevice(eTrackType Type)
+{
+ //printf("SetAudioTrackDevice %d\n", Type);
+ const tTrackId *TrackId = GetTrack(Type);
+ if (TrackId && TrackId->id) {
+ int streamType = 0;
+ cChannel * channel = Channels.GetByNumber(CurrentChannel());
+ if (channel) {
+ if (IS_AUDIO_TRACK(Type))
+ streamType = channel->Atype(Type - ttAudioFirst);
+ else if (IS_DOLBY_TRACK(Type))
+ streamType = channel->Dtype(Type - ttDolbyFirst);
+ }
+ //printf("SetAudioTrackDevice new %d %d, current %d\n", TrackId->id, streamType, pidHandles[ptAudio].pid);
+ if (pidHandles[ptAudio].pid && pidHandles[ptAudio].pid != TrackId->id) {
+ DetachAll(pidHandles[ptAudio].pid);
+ if (CamSlot())
+ CamSlot()->SetPid(pidHandles[ptAudio].pid, false);
+ pidHandles[ptAudio].pid = TrackId->id;
+ pidHandles[ptAudio].streamType = streamType;
+ SetPid(&pidHandles[ptAudio], ptAudio, true);
+ if (CamSlot()) {
+ CamSlot()->SetPid(pidHandles[ptAudio].pid, true);
+ CamSlot()->StartDecrypting();
+ }
+ }
+ }
+}
+
+bool cDvbHdFfDevice::CanReplay(void) const
+{
+ return cDevice::CanReplay();
+}
+
+bool cDvbHdFfDevice::SetPlayMode(ePlayMode PlayMode)
+{
+ if (PlayMode == pmNone) {
+ if (fd_video == -1)
+ fd_video = DvbOpen(DEV_DVB_VIDEO, adapter, frontend, O_RDWR | O_NONBLOCK);
+ if (fd_audio == -1)
+ fd_audio = DvbOpen(DEV_DVB_AUDIO, adapter, frontend, O_RDWR | O_NONBLOCK);
+
+ mHdffCmdIf->CmdAvSetVideoSpeed(0, 100);
+ mHdffCmdIf->CmdAvSetAudioSpeed(0, 100);
+
+ mHdffCmdIf->CmdAvEnableVideoAfterStop(0, false);
+ mHdffCmdIf->CmdAvSetPcrPid(0, 0);
+ mHdffCmdIf->CmdAvSetVideoPid(0, 0, HDFF_VIDEO_STREAM_MPEG1);
+ mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF_AUDIO_STREAM_MPEG1);
+
+ ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX);
+ mHdffCmdIf->CmdAvSetDecoderInput(0, 0);
+ mHdffCmdIf->CmdAvEnableSync(0, true);
+ mHdffCmdIf->CmdAvSetPlayMode(0, true);
+ mHdffCmdIf->CmdAvMuteAudio(0, false);
+ }
+ else {
+ if (playMode == pmNone)
+ TurnOffLiveMode(true);
+
+ if (PlayMode == pmExtern_THIS_SHOULD_BE_AVOIDED)
+ {
+ close(fd_video);
+ fd_video = -1;
+ close(fd_audio);
+ fd_audio = -1;
+ }
+ else
+ {
+ isTransferMode = Transferring() || (cTransferControl::ReceiverDevice() == this);
+ mHdffCmdIf->CmdAvSetPlayMode(1, isTransferMode);
+ mHdffCmdIf->CmdAvSetStc(0, 100000);
+ mHdffCmdIf->CmdAvEnableSync(0, false);
+ mHdffCmdIf->CmdAvEnableVideoAfterStop(0, true);
+
+ playVideoPid = -1;
+ playAudioPid = -1;
+ playPcrPid = -1;
+ audioCounter = 0;
+ videoCounter = 0;
+ freezed = false;
+ trickMode = false;
+ isPlayingVideo = false;
+
+ mHdffCmdIf->CmdAvSetDecoderInput(0, 2);
+ ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY);
+ }
+ }
+ playMode = PlayMode;
+ return true;
+}
+
+int64_t cDvbHdFfDevice::GetSTC(void)
+{
+ if (isPlayingVideo)
+ {
+ if (fd_video >= 0) {
+ uint64_t pts;
+ if (ioctl(fd_video, VIDEO_GET_PTS, &pts) == -1) {
+ esyslog("ERROR: pts %d: %m", CardIndex() + 1);
+ return -1;
+ }
+ //printf("video PTS %lld\n", pts);
+ return pts;
+ }
+ }
+ else
+ {
+ if (fd_audio >= 0) {
+ uint64_t pts;
+ if (ioctl(fd_audio, AUDIO_GET_PTS, &pts) == -1) {
+ esyslog("ERROR: pts %d: %m", CardIndex() + 1);
+ return -1;
+ }
+ //printf("audio PTS %lld\n", pts);
+ return pts;
+ }
+ }
+ return -1;
+}
+
+cRect cDvbHdFfDevice::CanScaleVideo(const cRect &Rect, int Alignment)
+{
+ return Rect;
+}
+
+void cDvbHdFfDevice::ScaleVideo(const cRect &Rect)
+{
+ if (Rect == cRect::Null)
+ {
+ mHdffCmdIf->CmdAvSetVideoWindow(0, false, 0, 0, 0, 0);
+ }
+ else
+ {
+ //printf("ScaleVideo: Rect = %d %d %d %d\n", Rect.X(), Rect.Y(), Rect.Width(), Rect.Height());
+
+ int osdWidth;
+ int osdHeight;
+ double osdPixelAspect;
+
+ GetOsdSize(osdWidth, osdHeight, osdPixelAspect);
+ //printf("ScaleVideo: OsdSize = %d %d %g\n", osdWidth, osdHeight, osdPixelAspect);
+
+ // Convert the video window coordinates in 1/10 percent of the display
+ // resolution.
+ int x = (Rect.X() * 1000 + osdWidth / 2) / osdWidth;
+ int y = (Rect.Y() * 1000 + osdHeight / 2) / osdHeight;
+ int w = (Rect.Width() * 1000 + osdWidth / 2) / osdWidth;
+ int h = (Rect.Height() * 1000 + osdHeight / 2) / osdHeight;
+ //printf("ScaleVideo: Win1 = %d %d %d %d\n", x, y, w, h);
+
+ // fix aspect ratio, reposition video
+ if (w > h) {
+ x += (w - h) / 2;
+ w = h;
+ }
+ else if (w < h) {
+ y += (h - w) / 2;
+ h = w;
+ }
+
+ //printf("ScaleVideo: Win2 = %d %d %d %d\n", x, y, w, h);
+ mHdffCmdIf->CmdAvSetVideoWindow(0, true, x, y, w, h);
+ }
+}
+
+#if (APIVERSNUM >= 20103)
+void cDvbHdFfDevice::TrickSpeed(int Speed, bool Forward)
+#else
+void cDvbHdFfDevice::TrickSpeed(int Speed)
+#endif
+{
+ freezed = false;
+ mHdffCmdIf->CmdAvEnableSync(0, false);
+ mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF_AUDIO_STREAM_MPEG1);
+ playAudioPid = -1;
+ if (Speed > 0)
+ mHdffCmdIf->CmdAvSetVideoSpeed(0, 100 / Speed);
+ trickMode = true;
+}
+
+void cDvbHdFfDevice::Clear(void)
+{
+ CHECK(ioctl(fd_video, VIDEO_CLEAR_BUFFER));
+ mHdffCmdIf->CmdAvSetVideoPid(0, 0, HDFF_VIDEO_STREAM_MPEG1);
+ mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF_AUDIO_STREAM_MPEG1);
+ playVideoPid = -1;
+ playAudioPid = -1;
+ cDevice::Clear();
+}
+
+void cDvbHdFfDevice::Play(void)
+{
+ freezed = false;
+ trickMode = false;
+ if (isPlayingVideo)
+ mHdffCmdIf->CmdAvEnableSync(0, true);
+ mHdffCmdIf->CmdAvSetVideoSpeed(0, 100);
+ mHdffCmdIf->CmdAvSetAudioSpeed(0, 100);
+ mHdffCmdIf->CmdAvMuteAudio(0, false);
+ cDevice::Play();
+}
+
+void cDvbHdFfDevice::Freeze(void)
+{
+ freezed = true;
+ mHdffCmdIf->CmdAvSetVideoSpeed(0, 0);
+ mHdffCmdIf->CmdAvSetAudioSpeed(0, 0);
+ cDevice::Freeze();
+}
+
+void cDvbHdFfDevice::Mute(void)
+{
+ mHdffCmdIf->CmdAvMuteAudio(0, true);
+ cDevice::Mute();
+}
+
+static HdffVideoStreamType_t MapVideoStreamTypes(int Vtype)
+{
+ switch (Vtype) {
+ case 0x01: return HDFF_VIDEO_STREAM_MPEG1;
+ case 0x02: return HDFF_VIDEO_STREAM_MPEG2;
+ case 0x1B: return HDFF_VIDEO_STREAM_H264;
+ default: return HDFF_VIDEO_STREAM_MPEG2; // fallback to MPEG2
+ }
+}
+
+void cDvbHdFfDevice::StillPicture(const uchar *Data, int Length)
+{
+ if (!Data || Length < TS_SIZE)
+ return;
+ if (Data[0] == 0x47) {
+ // TS data
+ cDevice::StillPicture(Data, Length);
+ }
+ else if (Data[0] == 0x00 && Data[1] == 0x00 && Data[2] == 0x01 && (Data[3] & 0xF0) == 0xE0) {
+ // PES data
+ char *buf = MALLOC(char, Length);
+ if (!buf)
+ return;
+ int i = 0;
+ int blen = 0;
+ while (i < Length - 6) {
+ if (Data[i] == 0x00 && Data[i + 1] == 0x00 && Data[i + 2] == 0x01) {
+ int len = Data[i + 4] * 256 + Data[i + 5];
+ if ((Data[i + 3] & 0xF0) == 0xE0) { // video packet
+ // skip PES header
+ int offs = i + 6;
+ // skip header extension
+ if ((Data[i + 6] & 0xC0) == 0x80) {
+ // MPEG-2 PES header
+ if (Data[i + 8] >= Length)
+ break;
+ offs += 3;
+ offs += Data[i + 8];
+ len -= 3;
+ len -= Data[i + 8];
+ if (len < 0 || offs + len > Length)
+ break;
+ }
+ else {
+ // MPEG-1 PES header
+ while (offs < Length && len > 0 && Data[offs] == 0xFF) {
+ offs++;
+ len--;
+ }
+ if (offs <= Length - 2 && len >= 2 && (Data[offs] & 0xC0) == 0x40) {
+ offs += 2;
+ len -= 2;
+ }
+ if (offs <= Length - 5 && len >= 5 && (Data[offs] & 0xF0) == 0x20) {
+ offs += 5;
+ len -= 5;
+ }
+ else if (offs <= Length - 10 && len >= 10 && (Data[offs] & 0xF0) == 0x30) {
+ offs += 10;
+ len -= 10;
+ }
+ else if (offs < Length && len > 0) {
+ offs++;
+ len--;
+ }
+ }
+ if (blen + len > Length) // invalid PES length field
+ break;
+ memcpy(&buf[blen], &Data[offs], len);
+ i = offs + len;
+ blen += len;
+ }
+ else if (Data[i + 3] >= 0xBD && Data[i + 3] <= 0xDF) // other PES packets
+ i += len + 6;
+ else
+ i++;
+ }
+ else
+ i++;
+ }
+ mHdffCmdIf->CmdAvShowStillImage(0, (uint8_t *)buf, blen, MapVideoStreamTypes(PatPmtParser()->Vtype()));
+ free(buf);
+ }
+ else {
+ // non-PES data
+ mHdffCmdIf->CmdAvShowStillImage(0, Data, Length, MapVideoStreamTypes(PatPmtParser()->Vtype()));
+ }
+}
+
+bool cDvbHdFfDevice::Poll(cPoller &Poller, int TimeoutMs)
+{
+ Poller.Add(fd_video, true);
+ return Poller.Poll(TimeoutMs);
+}
+
+bool cDvbHdFfDevice::Flush(int TimeoutMs)
+{
+ //TODO actually this function should wait until all buffered data has been processed by the card, but how?
+ return true;
+}
+
+void cDvbHdFfDevice::BuildTsPacket(uint8_t * TsBuffer, bool PusiSet, uint16_t Pid, uint8_t Counter, const uint8_t * Data, uint32_t Length)
+{
+ TsBuffer[0] = 0x47;
+ TsBuffer[1] = PusiSet ? 0x40 : 0x00;
+ TsBuffer[1] |= Pid >> 8;
+ TsBuffer[2] = Pid & 0xFF;
+ if (Length >= 184)
+ {
+ TsBuffer[3] = 0x10 | Counter;
+ memcpy(TsBuffer + 4, Data, 184);
+ }
+ else
+ {
+ uint8_t adaptationLength;
+
+ TsBuffer[3] = 0x30 | Counter;
+ adaptationLength = 183 - Length;
+ TsBuffer[4] = adaptationLength;
+ if (adaptationLength > 0)
+ {
+ TsBuffer[5] = 0x00;
+ memset(TsBuffer + 6, 0xFF, adaptationLength - 1);
+ }
+ memcpy(TsBuffer + 5 + adaptationLength, Data, Length);
+ }
+}
+
+uint32_t cDvbHdFfDevice::PesToTs(uint8_t * TsBuffer, uint16_t Pid, uint8_t & Counter, const uint8_t * Data, uint32_t Length)
+{
+ uint32_t tsOffset;
+ uint32_t i;
+
+ tsOffset = 0;
+ i = 0;
+ while (Length > 0)
+ {
+ BuildTsPacket(TsBuffer + tsOffset, i == 0, Pid, Counter, Data + i * 184, Length);
+ if (Length >= 184)
+ Length -= 184;
+ else
+ Length = 0;
+ Counter = (Counter + 1) & 15;
+ tsOffset += 188;
+ i++;
+ }
+ return tsOffset;
+}
+
+int cDvbHdFfDevice::PlayVideo(const uchar *Data, int Length)
+{
+ if (freezed)
+ return -1;
+ if (!isPlayingVideo)
+ {
+ mHdffCmdIf->CmdAvEnableSync(0, true);
+ isPlayingVideo = true;
+ }
+
+ // ignore padding PES packets
+ if (Data[3] == 0xBE)
+ return Length;
+
+ //TODO: support greater Length
+ uint8_t tsBuffer[188 * 16];
+ uint32_t tsLength;
+ int pid = 100;
+
+ tsLength = PesToTs(tsBuffer, pid, videoCounter, Data, Length);
+
+ if (pid != playVideoPid) {
+ playVideoPid = pid;
+ mHdffCmdIf->CmdAvSetVideoPid(0, playVideoPid, HDFF_VIDEO_STREAM_MPEG2, true);
+ }
+ if (WriteAllOrNothing(fd_video, tsBuffer, tsLength, 1000, 10) <= 0)
+ Length = 0;
+ return Length;
+}
+
+int cDvbHdFfDevice::PlayAudio(const uchar *Data, int Length, uchar Id)
+{
+ if (freezed)
+ return -1;
+ uint8_t streamId;
+ uint8_t tsBuffer[188 * 16];
+ uint32_t tsLength;
+ HdffAudioStreamType_t streamType = HDFF_AUDIO_STREAM_MPEG1;
+ HdffAvContainerType_t containerType = HDFF_AV_CONTAINER_PES;
+ int pid;
+
+ streamId = Data[3];
+ if (streamId >= 0xC0 && streamId <= 0xDF)
+ {
+ streamType = HDFF_AUDIO_STREAM_MPEG1;
+ }
+ else if (streamId == 0xBD)
+ {
+ const uint8_t * payload = Data + 9 + Data[8];
+ if ((payload[0] & 0xF8) == 0xA0)
+ {
+ containerType = HDFF_AV_CONTAINER_PES_DVD;
+ streamType = HDFF_AUDIO_STREAM_PCM;
+ }
+ else if ((payload[0] & 0xF8) == 0x88)
+ {
+ containerType = HDFF_AV_CONTAINER_PES_DVD;
+ streamType = HDFF_AUDIO_STREAM_DTS;
+ }
+ else if ((payload[0] & 0xF8) == 0x80)
+ {
+ containerType = HDFF_AV_CONTAINER_PES_DVD;
+ streamType = HDFF_AUDIO_STREAM_AC3;
+ }
+ else
+ {
+ streamType = HDFF_AUDIO_STREAM_AC3;
+ }
+ }
+ pid = 200 + (int) streamType;
+ tsLength = PesToTs(tsBuffer, pid, audioCounter, Data, Length);
+
+ if (pid != playAudioPid) {
+ playAudioPid = pid;
+ mHdffCmdIf->CmdAvSetAudioPid(0, playAudioPid, streamType, containerType);
+ }
+ if (WriteAllOrNothing(fd_video, tsBuffer, tsLength, 1000, 10) <= 0)
+ Length = 0;
+ return Length;
+}
+
+int cDvbHdFfDevice::PlayTsVideo(const uchar *Data, int Length)
+{
+ if (freezed)
+ return -1;
+ if (!isPlayingVideo)
+ {
+ mHdffCmdIf->CmdAvEnableSync(0, true);
+ isPlayingVideo = true;
+ }
+
+ int pid = TsPid(Data);
+ if (pid != playVideoPid) {
+ PatPmtParser();
+ if (pid == PatPmtParser()->Vpid()) {
+ playVideoPid = pid;
+ mHdffCmdIf->CmdAvSetVideoPid(0, playVideoPid, MapVideoStreamTypes(PatPmtParser()->Vtype()), true);
+ }
+ }
+ if (isTransferMode && supportsPcrInTransferMode) {
+ if (pid != playPcrPid) {
+ if (pid == PatPmtParser()->Ppid()) {
+ playPcrPid = pid;
+ mHdffCmdIf->CmdAvSetPcrPid(0, playPcrPid);
+ }
+ }
+ }
+ return WriteAllOrNothing(fd_video, Data, Length, 1000, 10);
+}
+
+static HdffAudioStreamType_t MapAudioStreamTypes(int Atype)
+{
+ switch (Atype) {
+ case 0x03: return HDFF_AUDIO_STREAM_MPEG1;
+ case 0x04: return HDFF_AUDIO_STREAM_MPEG2;
+ case SI::AC3DescriptorTag: return HDFF_AUDIO_STREAM_AC3;
+ case SI::EnhancedAC3DescriptorTag: return HDFF_AUDIO_STREAM_EAC3;
+ case 0x0F: return HDFF_AUDIO_STREAM_AAC;
+ case 0x11: return HDFF_AUDIO_STREAM_HE_AAC;
+ default: return HDFF_AUDIO_STREAM_MPEG1;
+ }
+}
+
+int cDvbHdFfDevice::PlayTsAudio(const uchar *Data, int Length)
+{
+ if (freezed)
+ return -1;
+ int pid = TsPid(Data);
+ if (pid != playAudioPid) {
+ playAudioPid = pid;
+ int AudioStreamType = -1;
+ for (int i = 0; PatPmtParser()->Apid(i); i++) {
+ if (playAudioPid == PatPmtParser()->Apid(i)) {
+ AudioStreamType = PatPmtParser()->Atype(i);
+ break;
+ }
+ }
+ if (AudioStreamType < 0) {
+ for (int i = 0; PatPmtParser()->Dpid(i); i++) {
+ if (playAudioPid == PatPmtParser()->Dpid(i)) {
+ AudioStreamType = PatPmtParser()->Dtype(i);
+ break;
+ }
+ }
+ }
+ mHdffCmdIf->CmdAvSetAudioPid(0, playAudioPid, MapAudioStreamTypes(AudioStreamType));
+ }
+ return WriteAllOrNothing(fd_video, Data, Length, 1000, 10);
+}
+
+HDFF::cHdffCmdIf *cDvbHdFfDevice::GetHdffCmdHandler(void)
+{
+ //TODO why not just keep a pointer?
+ if (devHdffOffset >= 0) {
+ cDvbHdFfDevice *device = (cDvbHdFfDevice *)GetDevice(devHdffOffset);
+ if (device)
+ return device->mHdffCmdIf;
+ }
+ return NULL;
+}
+
+// --- cDvbHdFfDeviceProbe ---------------------------------------------------
+
+cDvbHdFfDeviceProbe::cDvbHdFfDeviceProbe(void)
+{
+ outputOnly = false;
+}
+
+bool cDvbHdFfDeviceProbe::Probe(int Adapter, int Frontend)
+{
+ static uint32_t SubsystemIds[] = {
+ 0x13C23009, // Technotrend S2-6400 HDFF development samples
+ 0x13C2300A, // Technotrend S2-6400 HDFF production version
+ 0x00000000
+ };
+ cString FileName;
+ cReadLine ReadLine;
+ FILE *f = NULL;
+ uint32_t SubsystemId = 0;
+ FileName = cString::sprintf("/sys/class/dvb/dvb%d.frontend%d/device/subsystem_vendor", Adapter, Frontend);
+ if ((f = fopen(FileName, "r")) != NULL) {
+ if (char *s = ReadLine.Read(f))
+ SubsystemId = strtoul(s, NULL, 0) << 16;
+ fclose(f);
+ }
+ FileName = cString::sprintf("/sys/class/dvb/dvb%d.frontend%d/device/subsystem_device", Adapter, Frontend);
+ if ((f = fopen(FileName, "r")) != NULL) {
+ if (char *s = ReadLine.Read(f))
+ SubsystemId |= strtoul(s, NULL, 0);
+ fclose(f);
+ }
+ for (uint32_t *sid = SubsystemIds; *sid; sid++) {
+ if (*sid == SubsystemId) {
+ FileName = cString::sprintf("/dev/dvb/adapter%d/osd0", Adapter);
+ int fd = open(FileName, O_RDWR);
+ if (fd != -1) { //TODO treat the second path of the S2-6400 as a budget device
+ close(fd);
+ dsyslog("creating cDvbHdFfDevice%s", outputOnly ? " (output only)" : "");
+ new cDvbHdFfDevice(Adapter, Frontend, outputOnly);
+ return true;
+ }
+ else if (outputOnly) {
+ dsyslog("cDvbHdFfDevice 2nd tuner disabled (outputonly)");
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+
+// --- YuvToJpeg -------------------------------------------------------------
+
+#include <jpeglib.h>
+
+#define JPEGCOMPRESSMEM 4000000
+
+struct tJpegCompressData {
+ int size;
+ uchar *mem;
+ };
+
+static void JpegCompressInitDestination(j_compress_ptr cinfo)
+{
+ tJpegCompressData *jcd = (tJpegCompressData *)cinfo->client_data;
+ if (jcd) {
+ cinfo->dest->free_in_buffer = jcd->size = JPEGCOMPRESSMEM;
+ cinfo->dest->next_output_byte = jcd->mem = MALLOC(uchar, jcd->size);
+ }
+}
+
+static boolean JpegCompressEmptyOutputBuffer(j_compress_ptr cinfo)
+{
+ tJpegCompressData *jcd = (tJpegCompressData *)cinfo->client_data;
+ if (jcd) {
+ int Used = jcd->size;
+ int NewSize = jcd->size + JPEGCOMPRESSMEM;
+ if (uchar *NewBuffer = (uchar *)realloc(jcd->mem, NewSize)) {
+ jcd->size = NewSize;
+ jcd->mem = NewBuffer;
+ }
+ else {
+ esyslog("ERROR: out of memory");
+ return false;
+ }
+ if (jcd->mem) {
+ cinfo->dest->next_output_byte = jcd->mem + Used;
+ cinfo->dest->free_in_buffer = jcd->size - Used;
+ return true;
+ }
+ }
+ return false;
+}
+
+static void JpegCompressTermDestination(j_compress_ptr cinfo)
+{
+ tJpegCompressData *jcd = (tJpegCompressData *)cinfo->client_data;
+ if (jcd) {
+ int Used = cinfo->dest->next_output_byte - jcd->mem;
+ if (Used < jcd->size) {
+ if (uchar *NewBuffer = (uchar *)realloc(jcd->mem, Used)) {
+ jcd->size = Used;
+ jcd->mem = NewBuffer;
+ }
+ else
+ esyslog("ERROR: out of memory");
+ }
+ }
+}
+
+static uchar *YuvToJpeg(uchar *Mem, int Width, int Height, int &Size, int Quality)
+{
+ if (Quality < 0)
+ Quality = 0;
+ else if (Quality > 100)
+ Quality = 100;
+
+ jpeg_destination_mgr jdm;
+
+ jdm.init_destination = JpegCompressInitDestination;
+ jdm.empty_output_buffer = JpegCompressEmptyOutputBuffer;
+ jdm.term_destination = JpegCompressTermDestination;
+
+ struct jpeg_compress_struct cinfo;
+ struct jpeg_error_mgr jerr;
+ cinfo.err = jpeg_std_error(&jerr);
+ jpeg_create_compress(&cinfo);
+ cinfo.dest = &jdm;
+ tJpegCompressData jcd;
+ cinfo.client_data = &jcd;
+ cinfo.image_width = Width;
+ cinfo.image_height = Height;
+ cinfo.input_components = 3;
+ cinfo.in_color_space = JCS_YCbCr;
+
+ jpeg_set_defaults(&cinfo);
+ jpeg_set_quality(&cinfo, Quality, true);
+ jpeg_start_compress(&cinfo, true);
+
+ int rs = Width * 3;
+ JSAMPROW rp[Height];
+ for (int k = 0; k < Height; k++)
+ rp[k] = &Mem[rs * k];
+ jpeg_write_scanlines(&cinfo, rp, Height);
+ jpeg_finish_compress(&cinfo);
+ jpeg_destroy_compress(&cinfo);
+
+ Size = jcd.size;
+ return jcd.mem;
+}
diff --git a/dvbhdffdevice.h b/dvbhdffdevice.h
new file mode 100644
index 0000000..68b7933
--- /dev/null
+++ b/dvbhdffdevice.h
@@ -0,0 +1,138 @@
+/*
+ * dvbhdffdevice.h: The DVB HD Full Featured device interface
+ *
+ * See the README file for copyright information and how to reach the author.
+ */
+
+#ifndef __DVBHDFFDEVICE_H
+#define __DVBHDFFDEVICE_H
+
+#include "hdffcmd.h"
+#include <vdr/dvbdevice.h>
+#include <vdr/dvbspu.h>
+
+/// The cDvbHdFfDevice implements a DVB device which can be accessed through the Linux DVB driver API.
+
+class cDvbHdFfDevice : public cDvbDevice {
+private:
+ int fd_osd, fd_audio, fd_video;
+ bool outputOnly;
+protected:
+ virtual void MakePrimaryDevice(bool On);
+public:
+ static bool Probe(int Adapter, int Frontend);
+ cDvbHdFfDevice(int Adapter, int Frontend, bool OutputOnly);
+ virtual ~cDvbHdFfDevice();
+ virtual bool HasDecoder(void) const;
+
+// SPU facilities
+
+private:
+ cDvbSpuDecoder *spuDecoder;
+public:
+ virtual cSpuDecoder *GetSpuDecoder(void);
+
+// Channel facilities
+
+public:
+ virtual bool ProvidesSource(int Source) const;
+ virtual int NumProvidedSystems(void) const;
+private:
+ void TurnOffLiveMode(bool LiveView);
+protected:
+ virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView);
+
+// PID handle facilities
+
+protected:
+ virtual bool SetPid(cPidHandle *Handle, int Type, bool On);
+
+// Image Grab facilities
+
+public:
+ virtual uchar *GrabImage(int &Size, bool Jpeg = true, int Quality = -1, int SizeX = -1, int SizeY = -1);
+
+// Video format facilities
+
+public:
+ virtual void SetVideoDisplayFormat(eVideoDisplayFormat VideoDisplayFormat);
+ virtual void GetVideoSize(int &Width, int &Height, double &VideoAspect);
+ virtual void GetOsdSize(int &Width, int &Height, double &PixelAspect);
+
+// Track facilities
+
+protected:
+ virtual void SetAudioTrackDevice(eTrackType Type);
+
+// Audio facilities
+
+private:
+ int audioChannel;
+protected:
+ virtual int GetAudioChannelDevice(void);
+ virtual void SetAudioChannelDevice(int AudioChannel);
+ virtual void SetVolumeDevice(int Volume);
+
+// Player facilities
+
+private:
+ int playVideoPid;
+ int playAudioPid;
+ int playPcrPid;
+ bool freezed;
+ bool trickMode;
+ bool isPlayingVideo;
+ bool isTransferMode;
+ bool supportsPcrInTransferMode;
+
+ // Pes2Ts conversion stuff
+ uint8_t videoCounter;
+ uint8_t audioCounter;
+ void BuildTsPacket(uint8_t * TsBuffer, bool PusiSet, uint16_t Pid, uint8_t Counter, const uint8_t * Data, uint32_t Length);
+ uint32_t PesToTs(uint8_t * TsBuffer, uint16_t Pid, uint8_t & Counter, const uint8_t * Data, uint32_t Length);
+
+protected:
+ ePlayMode playMode;
+ virtual bool CanReplay(void) const;
+ virtual bool SetPlayMode(ePlayMode PlayMode);
+ virtual int PlayVideo(const uchar *Data, int Length);
+ virtual int PlayAudio(const uchar *Data, int Length, uchar Id);
+ virtual int PlayTsVideo(const uchar *Data, int Length);
+ virtual int PlayTsAudio(const uchar *Data, int Length);
+public:
+ virtual int64_t GetSTC(void);
+ virtual cRect CanScaleVideo(const cRect &Rect, int Alignment = taCenter);
+ virtual void ScaleVideo(const cRect &Rect = cRect::Null);
+#if (APIVERSNUM >= 20103)
+ virtual void TrickSpeed(int Speed, bool Forward);
+#else
+ virtual void TrickSpeed(int Speed);
+#endif
+ virtual void Clear(void);
+ virtual void Play(void);
+ virtual void Freeze(void);
+ virtual void Mute(void);
+ virtual void StillPicture(const uchar *Data, int Length);
+ virtual bool Poll(cPoller &Poller, int TimeoutMs = 0);
+ virtual bool Flush(int TimeoutMs = 0);
+
+// HDFF specific things
+
+public:
+ static HDFF::cHdffCmdIf *GetHdffCmdHandler(void);
+private:
+ static int devHdffOffset;//TODO
+ bool isHdffPrimary;//TODO implicit!
+ HDFF::cHdffCmdIf *mHdffCmdIf;
+};
+
+class cDvbHdFfDeviceProbe : public cDvbDeviceProbe {
+private:
+ bool outputOnly;
+public:
+ cDvbHdFfDeviceProbe(void);
+ virtual bool Probe(int Adapter, int Frontend);
+ void SetOutputOnly(bool On) { outputOnly = On; }
+ };
+
+#endif //__DVBHDFFDEVICE_H
diff --git a/hdffcmd.c b/hdffcmd.c
new file mode 100644
index 0000000..fd2d598
--- /dev/null
+++ b/hdffcmd.c
@@ -0,0 +1,401 @@
+/*
+ * hdffcmd.c: TODO(short description)
+ *
+ * See the README file for copyright information and how to reach the author.
+ */
+
+#include <stdint.h>
+
+#include "hdffcmd.h"
+#include "libhdffcmd/hdffcmd.h"
+#include <stdio.h>
+#include <string.h>
+#include <vdr/tools.h>
+
+
+namespace HDFF
+{
+
+cHdffCmdIf::cHdffCmdIf(int OsdDev)
+{
+ mOsdDev = OsdDev;
+ if (mOsdDev < 0)
+ {
+ //printf("ERROR: invalid OSD device handle (%d)!\n", mOsdDev);
+ }
+}
+
+cHdffCmdIf::~cHdffCmdIf(void)
+{
+}
+
+
+uint32_t cHdffCmdIf::CmdGetFirmwareVersion(char * pString, uint32_t MaxLength)
+{
+ uint32_t version;
+ int err;
+
+ err = HdffCmdGetFirmwareVersion(mOsdDev, &version, pString, MaxLength);
+ if (err == 0)
+ return version;
+ return 0;
+}
+
+uint32_t cHdffCmdIf::CmdGetInterfaceVersion(char * pString, uint32_t MaxLength)
+{
+ uint32_t version;
+ int err;
+
+ err = HdffCmdGetInterfaceVersion(mOsdDev, &version, pString, MaxLength);
+ if (err == 0)
+ return version;
+ return 0;
+}
+
+uint32_t cHdffCmdIf::CmdGetCopyrights(uint8_t Index, char * pString, uint32_t MaxLength)
+{
+ int err;
+
+ err = HdffCmdGetCopyrights(mOsdDev, Index, pString, MaxLength);
+ if (err == 0)
+ return strlen(pString);
+ return 0;
+}
+
+
+void cHdffCmdIf::CmdAvSetPlayMode(uint8_t PlayMode, bool Realtime)
+{
+ HdffCmdAvSetPlayMode(mOsdDev, PlayMode, Realtime);
+}
+
+void cHdffCmdIf::CmdAvSetVideoPid(uint8_t DecoderIndex, uint16_t VideoPid, HdffVideoStreamType_t StreamType, bool PlaybackMode)
+{
+ //printf("SetVideoPid %d %d\n", VideoPid, StreamType);
+ HdffCmdAvSetVideoPid(mOsdDev, DecoderIndex, VideoPid, StreamType);
+}
+
+void cHdffCmdIf::CmdAvSetAudioPid(uint8_t DecoderIndex, uint16_t AudioPid, HdffAudioStreamType_t StreamType, HdffAvContainerType_t ContainerType)
+{
+ //printf("SetAudioPid %d %d %d\n", AudioPid, StreamType, ContainerType);
+ HdffCmdAvSetAudioPid(mOsdDev, DecoderIndex, AudioPid, StreamType,
+ ContainerType);
+}
+
+void cHdffCmdIf::CmdAvSetPcrPid(uint8_t DecoderIndex, uint16_t PcrPid)
+{
+ //printf("SetPcrPid %d\n", PcrPid);
+ HdffCmdAvSetPcrPid(mOsdDev, DecoderIndex, PcrPid);
+}
+
+void cHdffCmdIf::CmdAvSetTeletextPid(uint8_t DecoderIndex, uint16_t TeletextPid)
+{
+ HdffCmdAvSetTeletextPid(mOsdDev, DecoderIndex, TeletextPid);
+}
+
+void cHdffCmdIf::CmdAvSetVideoWindow(uint8_t DecoderIndex, bool Enable, uint16_t X, uint16_t Y, uint16_t Width, uint16_t Height)
+{
+ HdffCmdAvSetVideoWindow(mOsdDev, DecoderIndex, Enable, X, Y, Width, Height);
+}
+
+void cHdffCmdIf::CmdAvShowStillImage(uint8_t DecoderIndex, const uint8_t * pStillImage, int Size, HdffVideoStreamType_t StreamType)
+{
+ HdffCmdAvShowStillImage(mOsdDev, DecoderIndex, pStillImage, Size,
+ StreamType);
+}
+
+void cHdffCmdIf::CmdAvSetDecoderInput(uint8_t DecoderIndex, uint8_t DemultiplexerIndex)
+{
+ HdffCmdAvSetDecoderInput(mOsdDev, DecoderIndex, DemultiplexerIndex);
+}
+
+void cHdffCmdIf::CmdAvSetDemultiplexerInput(uint8_t DemultiplexerIndex, uint8_t TsInputIndex)
+{
+ HdffCmdAvSetDemultiplexerInput(mOsdDev, DemultiplexerIndex, TsInputIndex);
+}
+
+void cHdffCmdIf::CmdAvSetVideoFormat(uint8_t DecoderIndex, const HdffVideoFormat_t * pVideoFormat)
+{
+ HdffCmdAvSetVideoFormat(mOsdDev, DecoderIndex, pVideoFormat);
+}
+
+void cHdffCmdIf::CmdAvSetVideoOutputMode(uint8_t DecoderIndex, HdffVideoOutputMode_t OutputMode)
+{
+ HdffCmdAvSetVideoOutputMode(mOsdDev, DecoderIndex, OutputMode);
+}
+
+void cHdffCmdIf::CmdAvSetStc(uint8_t DecoderIndex, uint64_t Stc)
+{
+ HdffCmdAvSetStc(mOsdDev, DecoderIndex, Stc);
+}
+
+void cHdffCmdIf::CmdAvFlushBuffer(uint8_t DecoderIndex, bool FlushAudio, bool FlushVideo)
+{
+ HdffCmdAvFlushBuffer(mOsdDev, DecoderIndex, FlushAudio, FlushVideo);
+}
+
+void cHdffCmdIf::CmdAvEnableSync(uint8_t DecoderIndex, bool EnableSync)
+{
+ HdffCmdAvEnableSync(mOsdDev, DecoderIndex, EnableSync, EnableSync);
+}
+
+void cHdffCmdIf::CmdAvSetVideoSpeed(uint8_t DecoderIndex, int32_t Speed)
+{
+ HdffCmdAvSetVideoSpeed(mOsdDev, DecoderIndex, Speed);
+}
+
+void cHdffCmdIf::CmdAvSetAudioSpeed(uint8_t DecoderIndex, int32_t Speed)
+{
+ HdffCmdAvSetAudioSpeed(mOsdDev, DecoderIndex, Speed);
+}
+
+void cHdffCmdIf::CmdAvEnableVideoAfterStop(uint8_t DecoderIndex, bool EnableVideoAfterStop)
+{
+ HdffCmdAvEnableVideoAfterStop(mOsdDev, DecoderIndex, EnableVideoAfterStop);
+}
+
+void cHdffCmdIf::CmdAvSetAudioDelay(int16_t Delay)
+{
+ HdffCmdAvSetAudioDelay(mOsdDev, Delay);
+}
+
+void cHdffCmdIf::CmdAvSetAudioDownmix(HdffAudioDownmixMode_t DownmixMode)
+{
+ HdffCmdAvSetAudioDownmix(mOsdDev, DownmixMode);
+}
+
+void cHdffCmdIf::CmdAvSetAudioChannel(uint8_t AudioChannel)
+{
+ HdffCmdAvSetAudioChannel(mOsdDev, AudioChannel);
+}
+
+void cHdffCmdIf::CmdAvSetSyncShift(int16_t SyncShift)
+{
+ HdffCmdAvSetSyncShift(mOsdDev, SyncShift);
+}
+
+void cHdffCmdIf::CmdAvMuteAudio(uint8_t DecoderIndex, bool Mute)
+{
+ HdffCmdAvMuteAudio(mOsdDev, DecoderIndex, Mute);
+}
+
+void cHdffCmdIf::CmdOsdConfigure(const HdffOsdConfig_t * pConfig)
+{
+ HdffCmdOsdConfigure(mOsdDev, pConfig);
+}
+
+void cHdffCmdIf::CmdOsdReset(void)
+{
+ HdffCmdOsdReset(mOsdDev);
+}
+
+uint32_t cHdffCmdIf::CmdOsdCreateDisplay(uint32_t Width, uint32_t Height, HdffColorType_t ColorType)
+{
+ //printf("CreateDisplay %d %d %d\n", Width, Height, ColorType);
+ uint32_t newDisplay;
+
+ if (HdffCmdOsdCreateDisplay(mOsdDev, Width, Height, ColorType, &newDisplay) == 0)
+ return newDisplay;
+ LOG_ERROR_STR("Error creating display");
+ return HDFF_INVALID_HANDLE;
+}
+
+void cHdffCmdIf::CmdOsdDeleteDisplay(uint32_t hDisplay)
+{
+ //printf("DeleteDisplay\n");
+ HdffCmdOsdDeleteDisplay(mOsdDev, hDisplay);
+}
+
+void cHdffCmdIf::CmdOsdEnableDisplay(uint32_t hDisplay, bool Enable)
+{
+ //printf("EnableDisplay\n");
+ HdffCmdOsdEnableDisplay(mOsdDev, hDisplay, Enable);
+}
+
+void cHdffCmdIf::CmdOsdSetDisplayOutputRectangle(uint32_t hDisplay, uint32_t X, uint32_t Y, uint32_t Width, uint32_t Height)
+{
+ //printf("SetOutputRect %d %d %d %d %d\n", hDisplay, X, Y, Width, Height);
+ HdffCmdOsdSetDisplayOutputRectangle(mOsdDev, hDisplay, X, Y, Width, Height);
+}
+
+void cHdffCmdIf::CmdOsdSetDisplayClippingArea(uint32_t hDisplay, bool Enable, uint32_t X, uint32_t Y, uint32_t Width, uint32_t Height)
+{
+ //printf("SetClippingArea %d %d %d %d %d %d\n", hDisplay, Enable, X, Y, Width, Height);
+ HdffCmdOsdSetDisplayClippingArea(mOsdDev, hDisplay, Enable, X, Y, Width, Height);
+}
+
+void cHdffCmdIf::CmdOsdRenderDisplay(uint32_t hDisplay)
+{
+ //printf("Render %08X\n", hDisplay);
+ HdffCmdOsdRenderDisplay(mOsdDev, hDisplay);
+}
+
+uint32_t cHdffCmdIf::CmdOsdCreatePalette(HdffColorType_t ColorType, HdffColorFormat_t ColorFormat,
+ uint32_t NumColors, const uint32_t * pColors)
+{
+ uint32_t newPalette;
+ int err;
+
+ err = HdffCmdOsdCreatePalette(mOsdDev, ColorType, ColorFormat, NumColors,
+ pColors, &newPalette);
+ if (err == 0)
+ return newPalette;
+ LOG_ERROR_STR("Error creating palette");
+ return HDFF_INVALID_HANDLE;
+}
+
+void cHdffCmdIf::CmdOsdDeletePalette(uint32_t hPalette)
+{
+ HdffCmdOsdDeletePalette(mOsdDev, hPalette);
+}
+
+void cHdffCmdIf::CmdOsdSetDisplayPalette(uint32_t hDisplay, uint32_t hPalette)
+{
+ HdffCmdOsdSetDisplayPalette(mOsdDev, hDisplay, hPalette);
+}
+
+void cHdffCmdIf::CmdOsdSetPaletteColors(uint32_t hPalette, HdffColorFormat_t ColorFormat,
+ uint8_t StartColor, uint32_t NumColors, const uint32_t * pColors)
+{
+ HdffCmdOsdSetPaletteColors(mOsdDev, hPalette, ColorFormat, StartColor,
+ NumColors, pColors);
+}
+
+uint32_t cHdffCmdIf::CmdOsdCreateFontFace(const uint8_t * pFontData, uint32_t DataSize)
+{
+ //printf("CreateFontFace %d\n", DataSize);
+ uint32_t newFontFace;
+ int err;
+
+ err = HdffCmdOsdCreateFontFace(mOsdDev, pFontData, DataSize, &newFontFace);
+ if (err == 0)
+ return newFontFace;
+ LOG_ERROR_STR("Error creating font face");
+ return HDFF_INVALID_HANDLE;
+}
+
+void cHdffCmdIf::CmdOsdDeleteFontFace(uint32_t hFontFace)
+{
+ //printf("DeleteFontFace %08X\n", hFontFace);
+ HdffCmdOsdDeleteFontFace(mOsdDev, hFontFace);
+}
+
+uint32_t cHdffCmdIf::CmdOsdCreateFont(uint32_t hFontFace, uint32_t Size)
+{
+ //printf("CreateFont %d\n", Size);
+ uint32_t newFont;
+ int err;
+
+ err = HdffCmdOsdCreateFont(mOsdDev, hFontFace, Size, &newFont);
+ if (err == 0)
+ return newFont;
+ LOG_ERROR_STR("Error creating font");
+ return HDFF_INVALID_HANDLE;
+}
+
+void cHdffCmdIf::CmdOsdDeleteFont(uint32_t hFont)
+{
+ //printf("DeleteFont %08X\n", hFont);
+ HdffCmdOsdDeleteFont(mOsdDev, hFont);
+}
+
+void cHdffCmdIf::CmdOsdDrawRectangle(uint32_t hDisplay, int X, int Y, int Width, int Height, uint32_t Color)
+{
+ //printf("Rect (%d,%d) %d x %d, %08X\n", X, Y, Width, Height, Color);
+ HdffCmdOsdDrawRectangle(mOsdDev, hDisplay, X, Y, Width, Height, Color);
+}
+
+void cHdffCmdIf::CmdOsdDrawEllipse(uint32_t hDisplay, int CX, int CY, int RadiusX, int RadiusY,
+ uint32_t Color, uint32_t Flags)
+{
+ //printf("Ellipse (%d,%d) %d x %d, %08X, %d\n", CX, CY, RadiusX, RadiusY, Color, Flags);
+ HdffCmdOsdDrawEllipse(mOsdDev, hDisplay, CX, CY, RadiusX, RadiusY, Color, Flags);
+}
+
+void cHdffCmdIf::CmdOsdDrawSlope(uint32_t hDisplay, int X, int Y, int Width, int Height,
+ uint32_t Color, uint32_t Type)
+{
+ //printf("Slope (%d,%d) %d x %d, %08X, %X\n", X, Y, Width, Height, Color, Type);
+ HdffCmdOsdDrawSlope(mOsdDev, hDisplay, X, Y, Width, Height, Color, Type);
+}
+
+void cHdffCmdIf::CmdOsdDrawText(uint32_t hDisplay, uint32_t hFont, int X, int Y, const char * pText, uint32_t Color)
+{
+ //printf("Text %08X (%d,%d), %s, %08X\n", hFont, X, Y, pText, Color);
+ HdffCmdOsdDrawText(mOsdDev, hDisplay, hFont, X, Y, pText, Color);
+}
+
+void cHdffCmdIf::CmdOsdDrawUtf8Text(uint32_t hDisplay, uint32_t hFont, int X, int Y, const char * pText, uint32_t Color)
+{
+ //printf("Text(UTF8) %08X (%d,%d), %s, %08X\n", hFont, X, Y, pText, Color);
+ HdffCmdOsdDrawUtf8Text(mOsdDev, hDisplay, hFont, X, Y, pText, Color);
+}
+
+void cHdffCmdIf::CmdOsdDrawTextW(uint32_t hDisplay, uint32_t hFont, int X, int Y, const uint16_t * pText, uint32_t Color)
+{
+ //printf("TextW %08X (%d,%d), %08X\n", hFont, X, Y, Color);
+ HdffCmdOsdDrawWideText(mOsdDev, hDisplay, hFont, X, Y, pText, Color);
+}
+
+void cHdffCmdIf::CmdOsdDrawBitmap(uint32_t hDisplay, int X, int Y, const uint8_t * pBitmap,
+ int BmpWidth, int BmpHeight, int BmpSize,
+ HdffColorType_t ColorType, uint32_t hPalette)
+{
+ //printf("Bitmap %08X (%d,%d) %d x %d, %08X\n", hDisplay, X, Y, BmpWidth, BmpHeight, hPalette);
+ HdffCmdOsdDrawBitmap(mOsdDev, hDisplay, X, Y, pBitmap, BmpWidth, BmpHeight,
+ BmpSize, ColorType, hPalette);
+}
+
+void cHdffCmdIf::CmdOsdSaveRegion(uint32_t hDisplay, int X, int Y, int Width, int Height)
+{
+ HdffCmdOsdSaveRegion(mOsdDev, hDisplay, X, Y, Width, Height);
+}
+
+void cHdffCmdIf::CmdOsdRestoreRegion(uint32_t hDisplay)
+{
+ HdffCmdOsdRestoreRegion(mOsdDev, hDisplay);
+}
+
+void cHdffCmdIf::CmdMuxSetVideoOut(HdffVideoOut_t VideoOut)
+{
+ HdffCmdMuxSetVideoOut(mOsdDev, VideoOut);
+}
+
+void cHdffCmdIf::CmdMuxSetVolume(uint8_t Volume)
+{
+ HdffCmdMuxSetVolume(mOsdDev, Volume);
+}
+
+void cHdffCmdIf::CmdMuxMuteAudio(bool Mute)
+{
+ HdffCmdMuxMuteAudio(mOsdDev, Mute);
+}
+
+void cHdffCmdIf::CmdHdmiSetVideoMode(HdffVideoMode_t VideoMode)
+{
+ //printf("HdmiSetVideoMode %d\n", VideoMode);
+ HdffCmdHdmiSetVideoMode(mOsdDev, VideoMode);
+}
+
+void cHdffCmdIf::CmdHdmiConfigure(const HdffHdmiConfig_t * pConfig)
+{
+ HdffCmdHdmiConfigure(mOsdDev, pConfig);
+}
+
+void cHdffCmdIf::CmdHdmiSendCecCommand(HdffCecCommand_t Command)
+{
+ HdffCmdHdmiSendCecCommand(mOsdDev, Command);
+}
+
+void cHdffCmdIf::CmdRemoteSetProtocol(HdffRemoteProtocol_t Protocol)
+{
+ //printf("%s %d\n", __func__, Protocol);
+ HdffCmdRemoteSetProtocol(mOsdDev, Protocol);
+}
+
+void cHdffCmdIf::CmdRemoteSetAddressFilter(bool Enable, uint32_t Address)
+{
+ //printf("%s %d %d\n", __func__, Enable, Address);
+ HdffCmdRemoteSetAddressFilter(mOsdDev, Enable, Address);
+}
+
+} // end of namespace
diff --git a/hdffcmd.h b/hdffcmd.h
new file mode 100644
index 0000000..891bc7e
--- /dev/null
+++ b/hdffcmd.h
@@ -0,0 +1,100 @@
+/*
+ * hdffcmd.h: TODO(short description)
+ *
+ * See the README file for copyright information and how to reach the author.
+ */
+
+#ifndef _HDFF_CMD_H_
+#define _HDFF_CMD_H_
+
+#include "libhdffcmd/hdffcmd.h"
+
+namespace HDFF
+{
+
+class cHdffCmdIf
+{
+private:
+ int mOsdDev;
+
+public:
+ cHdffCmdIf(int OsdDev);
+ ~cHdffCmdIf(void);
+
+ uint32_t CmdGetFirmwareVersion(char * pString, uint32_t MaxLength);
+ uint32_t CmdGetInterfaceVersion(char * pString, uint32_t MaxLength);
+ uint32_t CmdGetCopyrights(uint8_t Index, char * pString, uint32_t MaxLength);
+
+ void CmdAvSetPlayMode(uint8_t PlayMode, bool Realtime);
+ void CmdAvSetVideoPid(uint8_t DecoderIndex, uint16_t VideoPid, HdffVideoStreamType_t StreamType, bool PlaybackMode = false);
+ void CmdAvSetAudioPid(uint8_t DecoderIndex, uint16_t AudioPid, HdffAudioStreamType_t StreamType, HdffAvContainerType_t ContainerType = HDFF_AV_CONTAINER_PES);
+ void CmdAvSetPcrPid(uint8_t DecoderIndex, uint16_t PcrPid);
+ void CmdAvSetTeletextPid(uint8_t DecoderIndex, uint16_t TeletextPid);
+ void CmdAvSetVideoWindow(uint8_t DecoderIndex, bool Enable, uint16_t X, uint16_t Y, uint16_t Width, uint16_t Height);
+ void CmdAvShowStillImage(uint8_t DecoderIndex, const uint8_t * pStillImage, int Size, HdffVideoStreamType_t StreamType);
+ void CmdAvSetDecoderInput(uint8_t DecoderIndex, uint8_t DemultiplexerIndex);
+ void CmdAvSetDemultiplexerInput(uint8_t DemultiplexerIndex, uint8_t TsInputIndex);
+ void CmdAvSetVideoFormat(uint8_t DecoderIndex, const HdffVideoFormat_t * pVideoFormat);
+ void CmdAvSetVideoOutputMode(uint8_t DecoderIndex, HdffVideoOutputMode_t OutputMode);
+ void CmdAvSetStc(uint8_t DecoderIndex, uint64_t Stc);
+ void CmdAvFlushBuffer(uint8_t DecoderIndex, bool FlushAudio, bool FlushVideo);
+ void CmdAvEnableSync(uint8_t DecoderIndex, bool EnableSync);
+ void CmdAvSetVideoSpeed(uint8_t DecoderIndex, int32_t Speed);
+ void CmdAvSetAudioSpeed(uint8_t DecoderIndex, int32_t Speed);
+ void CmdAvEnableVideoAfterStop(uint8_t DecoderIndex, bool EnableVideoAfterStop);
+ void CmdAvSetAudioDelay(int16_t Delay);
+ void CmdAvSetAudioDownmix(HdffAudioDownmixMode_t DownmixMode);
+ void CmdAvSetAudioChannel(uint8_t AudioChannel);
+ void CmdAvSetSyncShift(int16_t SyncShift);
+ void CmdAvMuteAudio(uint8_t DecoderIndex, bool Mute);
+
+ void CmdOsdConfigure(const HdffOsdConfig_t * pConfig);
+ void CmdOsdReset(void);
+
+ uint32_t CmdOsdCreateDisplay(uint32_t Width, uint32_t Height, HdffColorType_t ColorType);
+ void CmdOsdDeleteDisplay(uint32_t hDisplay);
+ void CmdOsdEnableDisplay(uint32_t hDisplay, bool Enable);
+ void CmdOsdSetDisplayOutputRectangle(uint32_t hDisplay, uint32_t X, uint32_t Y, uint32_t Width, uint32_t Height);
+ void CmdOsdSetDisplayClippingArea(uint32_t hDisplay, bool Enable, uint32_t X, uint32_t Y, uint32_t Width, uint32_t Height);
+ void CmdOsdRenderDisplay(uint32_t hDisplay);
+
+ uint32_t CmdOsdCreatePalette(HdffColorType_t ColorType, HdffColorFormat_t ColorFormat,
+ uint32_t NumColors, const uint32_t * pColors);
+ void CmdOsdDeletePalette(uint32_t hPalette);
+ void CmdOsdSetDisplayPalette(uint32_t hDisplay, uint32_t hPalette);
+ void CmdOsdSetPaletteColors(uint32_t hPalette, HdffColorFormat_t ColorFormat,
+ uint8_t StartColor, uint32_t NumColors, const uint32_t * pColors);
+
+ uint32_t CmdOsdCreateFontFace(const uint8_t * pFontData, uint32_t DataSize);
+ void CmdOsdDeleteFontFace(uint32_t hFontFace);
+ uint32_t CmdOsdCreateFont(uint32_t hFontFace, uint32_t Size);
+ void CmdOsdDeleteFont(uint32_t hFont);
+
+ void CmdOsdDrawRectangle(uint32_t hDisplay, int X, int Y, int Width, int Height, uint32_t Color);
+ void CmdOsdDrawEllipse(uint32_t hDisplay, int CX, int CY, int RadiusX, int RadiusY,
+ uint32_t Color, uint32_t Flags);
+ void CmdOsdDrawSlope(uint32_t hDisplay, int X, int Y, int Width, int Height, uint32_t Color, uint32_t Type);
+ void CmdOsdDrawText(uint32_t hDisplay, uint32_t hFont, int X, int Y, const char * pText, uint32_t Color);
+ void CmdOsdDrawUtf8Text(uint32_t hDisplay, uint32_t hFont, int X, int Y, const char * pText, uint32_t Color);
+ void CmdOsdDrawTextW(uint32_t hDisplay, uint32_t hFont, int X, int Y, const uint16_t * pText, uint32_t Color);
+ void CmdOsdDrawBitmap(uint32_t hDisplay, int X, int Y, const uint8_t * pBitmap,
+ int BmpWidth, int BmpHeight, int BmpSize,
+ HdffColorType_t ColorType, uint32_t hPalette);
+ void CmdOsdSaveRegion(uint32_t hDisplay, int X, int Y, int Width, int Height);
+ void CmdOsdRestoreRegion(uint32_t hDisplay);
+
+ void CmdMuxSetVideoOut(HdffVideoOut_t VideoOut);
+ void CmdMuxSetVolume(uint8_t Volume);
+ void CmdMuxMuteAudio(bool Mute);
+
+ void CmdHdmiSetVideoMode(HdffVideoMode_t VideoMode);
+ void CmdHdmiConfigure(const HdffHdmiConfig_t * pConfig);
+ void CmdHdmiSendCecCommand(HdffCecCommand_t Command);
+
+ void CmdRemoteSetProtocol(HdffRemoteProtocol_t Protocol);
+ void CmdRemoteSetAddressFilter(bool Enable, uint32_t Address);
+};
+
+} // end of namespace
+
+#endif
diff --git a/hdffosd.c b/hdffosd.c
new file mode 100644
index 0000000..089ffe7
--- /dev/null
+++ b/hdffosd.c
@@ -0,0 +1,844 @@
+/*
+ * hdffosd.c: Implementation of the DVB HD Full Featured On Screen Display
+ *
+ * See the README file for copyright information and how to reach the author.
+ */
+
+#include "hdffosd.h"
+#include <linux/dvb/osd.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include "hdffcmd.h"
+#include "setup.h"
+
+#define MAX_NUM_FONTFACES 8
+#define MAX_NUM_FONTS 8
+#define MAX_BITMAP_SIZE (1024*1024)
+
+typedef struct _tFontFace
+{
+ cString Name;
+ uint32_t Handle;
+} tFontFace;
+
+typedef struct _tFont
+{
+ uint32_t hFontFace;
+ int Size;
+ uint32_t Handle;
+} tFont;
+
+class cHdffOsd : public cOsd
+{
+private:
+ HDFF::cHdffCmdIf * mHdffCmdIf;
+ int mLeft;
+ int mTop;
+ int mDispWidth;
+ int mDispHeight;
+ bool mChanged;
+ uint32_t mDisplay;
+ tFontFace mFontFaces[MAX_NUM_FONTFACES];
+ tFont mFonts[MAX_NUM_FONTS];
+ uint32_t mBitmapPalette;
+ uint32_t mBitmapColors[256];
+
+ bool mSupportsUtf8Text;
+
+protected:
+ virtual void SetActive(bool On);
+public:
+ cHdffOsd(int Left, int Top, HDFF::cHdffCmdIf * pHdffCmdIf, uint Level);
+ virtual ~cHdffOsd();
+ virtual eOsdError CanHandleAreas(const tArea *Areas, int NumAreas);
+ virtual eOsdError SetAreas(const tArea *Areas, int NumAreas);
+ virtual void SaveRegion(int x1, int y1, int x2, int y2);
+ virtual void RestoreRegion(void);
+ virtual void DrawPixel(int x, int y, tColor Color);
+ virtual void DrawBitmap(int x, int y, const cBitmap &Bitmap, tColor ColorFg = 0, tColor ColorBg = 0, bool ReplacePalette = false, bool Overlay = false);
+ virtual void DrawText(int x, int y, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width = 0, int Height = 0, int Alignment = taDefault);
+ virtual void DrawRectangle(int x1, int y1, int x2, int y2, tColor Color);
+ virtual void DrawEllipse(int x1, int y1, int x2, int y2, tColor Color, int Quadrants = 0);
+ virtual void DrawSlope(int x1, int y1, int x2, int y2, tColor Color, int Type);
+ virtual void Flush(void);
+};
+
+cHdffOsd::cHdffOsd(int Left, int Top, HDFF::cHdffCmdIf * pHdffCmdIf, uint Level)
+: cOsd(Left, Top, Level)
+{
+ double pixelAspect;
+ HdffOsdConfig_t config;
+
+ //printf("cHdffOsd %d, %d, %d\n", Left, Top, Level);
+ mHdffCmdIf = pHdffCmdIf;
+ mLeft = Left;
+ mTop = Top;
+ mChanged = false;
+ mBitmapPalette = HDFF_INVALID_HANDLE;
+
+ mSupportsUtf8Text = false;
+ if (mHdffCmdIf->CmdGetFirmwareVersion(NULL, 0) >= 0x309)
+ mSupportsUtf8Text = true;
+
+ memset(&config, 0, sizeof(config));
+ config.FontKerning = true;
+ config.FontAntialiasing = Setup.AntiAlias ? true : false;
+ mHdffCmdIf->CmdOsdConfigure(&config);
+
+ gHdffSetup.GetOsdSize(mDispWidth, mDispHeight, pixelAspect);
+ mDisplay = mHdffCmdIf->CmdOsdCreateDisplay(mDispWidth, mDispHeight, HDFF_COLOR_TYPE_ARGB8888);
+ mHdffCmdIf->CmdOsdSetDisplayOutputRectangle(mDisplay, 0, 0, HDFF_SIZE_FULL_SCREEN, HDFF_SIZE_FULL_SCREEN);
+ for (int i = 0; i < MAX_NUM_FONTFACES; i++)
+ {
+ mFontFaces[i].Name = "";
+ mFontFaces[i].Handle = HDFF_INVALID_HANDLE;
+ }
+ for (int i = 0; i < MAX_NUM_FONTS; i++)
+ {
+ mFonts[i].hFontFace = HDFF_INVALID_HANDLE;
+ mFonts[i].Size = 0;
+ mFonts[i].Handle = HDFF_INVALID_HANDLE;
+ }
+}
+
+cHdffOsd::~cHdffOsd()
+{
+ //printf("~cHdffOsd %d %d\n", mLeft, mTop);
+ if (Active()) {
+ mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, 0, 0, mDispWidth, mDispHeight, 0);
+ mHdffCmdIf->CmdOsdRenderDisplay(mDisplay);
+ }
+ SetActive(false);
+
+ for (int i = 0; i < MAX_NUM_FONTS; i++)
+ {
+ if (mFonts[i].Handle == HDFF_INVALID_HANDLE)
+ break;
+ mHdffCmdIf->CmdOsdDeleteFont(mFonts[i].Handle);
+ }
+ for (int i = 0; i < MAX_NUM_FONTFACES; i++)
+ {
+ if (mFontFaces[i].Handle == HDFF_INVALID_HANDLE)
+ break;
+ mHdffCmdIf->CmdOsdDeleteFontFace(mFontFaces[i].Handle);
+ }
+
+ if (mBitmapPalette != HDFF_INVALID_HANDLE)
+ mHdffCmdIf->CmdOsdDeletePalette(mBitmapPalette);
+ mHdffCmdIf->CmdOsdDeleteDisplay(mDisplay);
+}
+
+eOsdError cHdffOsd::CanHandleAreas(const tArea *Areas, int NumAreas)
+{
+ eOsdError Result = cOsd::CanHandleAreas(Areas, NumAreas);
+ if (Result == oeOk)
+ {
+ for (int i = 0; i < NumAreas; i++)
+ {
+ if (Areas[i].bpp != 1 && Areas[i].bpp != 2 && Areas[i].bpp != 4 && Areas[i].bpp != 8)
+ return oeBppNotSupported;
+ }
+ }
+ return Result;
+}
+
+eOsdError cHdffOsd::SetAreas(const tArea *Areas, int NumAreas)
+{
+ eOsdError error;
+ cBitmap * bitmap;
+
+ for (int i = 0; i < NumAreas; i++)
+ {
+ //printf("SetAreas %d: %d %d %d %d %d\n", i, Areas[i].x1, Areas[i].y1, Areas[i].x2, Areas[i].y2, Areas[i].bpp);
+ }
+ if (Active() && mDisplay != HDFF_INVALID_HANDLE)
+ {
+ mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, 0, 0, mDispWidth, mDispHeight, 0);
+ mHdffCmdIf->CmdOsdRenderDisplay(mDisplay);
+ }
+ error = cOsd::SetAreas(Areas, NumAreas);
+
+ for (int i = 0; (bitmap = GetBitmap(i)) != NULL; i++)
+ {
+ bitmap->Clean();
+ }
+
+ return error;
+}
+
+void cHdffOsd::SetActive(bool On)
+{
+ if (On != Active())
+ {
+ cOsd::SetActive(On);
+ if (On)
+ {
+ if (GetBitmap(0)) // only flush here if there are already bitmaps
+ Flush();
+ }
+ else if (mDisplay != HDFF_INVALID_HANDLE)
+ {
+ mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, 0, 0, mDispWidth, mDispHeight, 0);
+ mHdffCmdIf->CmdOsdRenderDisplay(mDisplay);
+ }
+ }
+}
+
+void cHdffOsd::SaveRegion(int x1, int y1, int x2, int y2)
+{
+ mHdffCmdIf->CmdOsdSaveRegion(mDisplay, mLeft + x1, mTop + y1, x2 - x1 + 1, y2 - y1 + 1);
+ mChanged = true;
+}
+
+void cHdffOsd::RestoreRegion(void)
+{
+ mHdffCmdIf->CmdOsdRestoreRegion(mDisplay);
+ mChanged = true;
+}
+
+void cHdffOsd::DrawPixel(int x, int y, tColor Color)
+{
+ //printf("DrawPixel\n");
+}
+
+void cHdffOsd::DrawBitmap(int x, int y, const cBitmap &Bitmap, tColor ColorFg, tColor ColorBg, bool ReplacePalette, bool Overlay)
+{
+ //printf("DrawBitmap %d %d %d x %d\n", x, y, Bitmap.Width(), Bitmap.Height());
+ int i;
+ int numColors;
+ const tColor * colors = Bitmap.Colors(numColors);
+
+ for (i = 0; i < numColors; i++)
+ {
+ mBitmapColors[i] = colors[i];
+ if (ColorFg || ColorBg)
+ {
+ if (i == 0)
+ mBitmapColors[i] = ColorBg;
+ else if (i == 1)
+ mBitmapColors[i] = ColorFg;
+ }
+ }
+ if (mBitmapPalette == HDFF_INVALID_HANDLE)
+ {
+ mBitmapPalette = mHdffCmdIf->CmdOsdCreatePalette(HDFF_COLOR_TYPE_CLUT8,
+ HDFF_COLOR_FORMAT_ARGB, numColors, mBitmapColors);
+ }
+ else
+ {
+ mHdffCmdIf->CmdOsdSetPaletteColors(mBitmapPalette,
+ HDFF_COLOR_FORMAT_ARGB, 0, numColors, mBitmapColors);
+ }
+ int width = Bitmap.Width();
+ int height = Bitmap.Height();
+ int chunk = MAX_BITMAP_SIZE / width;
+ if (chunk > height)
+ chunk = height;
+ for (int yc = 0; yc < height; yc += chunk)
+ {
+ int hc = chunk;
+ if (yc + hc > height)
+ hc = height - yc;
+ mHdffCmdIf->CmdOsdDrawBitmap(mDisplay, mLeft + x, mTop + y + yc,
+ (uint8_t *) Bitmap.Data(0, yc), width, hc,
+ width * hc, HDFF_COLOR_TYPE_CLUT8, mBitmapPalette);
+ }
+ mChanged = true;
+}
+
+void cHdffOsd::DrawText(int x, int y, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width, int Height, int Alignment)
+{
+ int w = Font->Width(s);
+ int h = Font->Height();
+ int cw = Width ? Width : w;
+ int ch = Height ? Height : h;
+ int i;
+ int size = Font->Size();
+ tFontFace * pFontFace;
+ tFont * pFont;
+
+ if (ColorBg != clrTransparent)
+ mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, mLeft + x, mTop + y, cw, ch, ColorBg);
+
+ if (s == NULL)
+ return;
+
+ pFontFace = NULL;
+ for (i = 0; i < MAX_NUM_FONTFACES; i++)
+ {
+ if (mFontFaces[i].Handle == HDFF_INVALID_HANDLE)
+ break;
+
+ if (strcmp(mFontFaces[i].Name, Font->FontName()) == 0)
+ {
+ pFontFace = &mFontFaces[i];
+ break;
+ }
+ }
+ if (pFontFace == NULL)
+ {
+ if (i < MAX_NUM_FONTFACES)
+ {
+ cString fontFileName = Font->FontName();
+ FILE * fp = fopen(fontFileName, "rb");
+ if (fp)
+ {
+ fseek(fp, 0, SEEK_END);
+ long fileSize = ftell(fp);
+ fseek(fp, 0, SEEK_SET);
+ if (fileSize > 0)
+ {
+ uint8_t * buffer = new uint8_t[fileSize];
+ if (buffer)
+ {
+ if (fread(buffer, fileSize, 1, fp) == 1)
+ {
+ mFontFaces[i].Handle = mHdffCmdIf->CmdOsdCreateFontFace(buffer, fileSize);
+ if (mFontFaces[i].Handle != HDFF_INVALID_HANDLE)
+ {
+ mFontFaces[i].Name = Font->FontName();
+ pFontFace = &mFontFaces[i];
+ }
+ }
+ delete[] buffer;
+ }
+ }
+ fclose(fp);
+ }
+ }
+ }
+ if (pFontFace == NULL)
+ return;
+
+ pFont = NULL;
+ for (i = 0; i < MAX_NUM_FONTS; i++)
+ {
+ if (mFonts[i].Handle == HDFF_INVALID_HANDLE)
+ break;
+
+ if (mFonts[i].hFontFace == pFontFace->Handle
+ && mFonts[i].Size == size)
+ {
+ pFont = &mFonts[i];
+ break;
+ }
+ }
+ if (pFont == NULL)
+ {
+ if (i < MAX_NUM_FONTS)
+ {
+ mFonts[i].Handle = mHdffCmdIf->CmdOsdCreateFont(pFontFace->Handle, size);
+ if (mFonts[i].Handle != HDFF_INVALID_HANDLE)
+ {
+ mFonts[i].hFontFace = pFontFace->Handle;
+ mFonts[i].Size = size;
+ pFont = &mFonts[i];
+ }
+ }
+ }
+ if (pFont == NULL)
+ return;
+
+ mHdffCmdIf->CmdOsdSetDisplayClippingArea(mDisplay, true, mLeft + x, mTop + y, cw, ch);
+
+ if (Width || Height)
+ {
+ if (Width)
+ {
+ if ((Alignment & taLeft) != 0)
+ {
+#if (APIVERSNUM >= 10728)
+ if ((Alignment & taBorder) != 0)
+ x += max(h / TEXT_ALIGN_BORDER, 1);
+#endif
+ }
+ else if ((Alignment & taRight) != 0)
+ {
+ if (w < Width)
+ x += Width - w;
+#if (APIVERSNUM >= 10728)
+ if ((Alignment & taBorder) != 0)
+ x -= max(h / TEXT_ALIGN_BORDER, 1);
+#endif
+ }
+ else
+ { // taCentered
+ if (w < Width)
+ x += (Width - w) / 2;
+ }
+ }
+ if (Height)
+ {
+ if ((Alignment & taTop) != 0)
+ ;
+ else if ((Alignment & taBottom) != 0)
+ {
+ if (h < Height)
+ y += Height - h;
+ }
+ else
+ { // taCentered
+ if (h < Height)
+ y += (Height - h) / 2;
+ }
+ }
+ }
+#if 0
+ if (mSupportsUtf8Text)
+ {
+ mHdffCmdIf->CmdOsdDrawUtf8Text(mDisplay, pFont->Handle, x + mLeft, y + mTop + h, s, ColorFg);
+ }
+ else
+#endif
+ {
+ uint16_t tmp[1000];
+ uint16_t len = 0;
+ while (*s && (len < (sizeof(tmp) - 1)))
+ {
+ int sl = Utf8CharLen(s);
+ uint sym = Utf8CharGet(s, sl);
+ s += sl;
+ tmp[len] = sym;
+ len++;
+ }
+ tmp[len] = 0;
+ mHdffCmdIf->CmdOsdDrawTextW(mDisplay, pFont->Handle, x + mLeft, y + mTop + h, tmp, ColorFg);
+ }
+ mHdffCmdIf->CmdOsdSetDisplayClippingArea(mDisplay, false, 0, 0, 0, 0);
+ mChanged = true;
+}
+
+void cHdffOsd::DrawRectangle(int x1, int y1, int x2, int y2, tColor Color)
+{
+ mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, mLeft + x1, mTop + y1, x2 - x1 + 1, y2 - y1 + 1, Color);
+ mChanged = true;
+}
+
+void cHdffOsd::DrawEllipse(int x1, int y1, int x2, int y2, tColor Color, int Quadrants)
+{
+ uint32_t flags;
+ int cx;
+ int cy;
+ int rx;
+ int ry;
+
+ switch (abs(Quadrants))
+ {
+ case 1:
+ if (Quadrants > 0)
+ flags = HDFF_DRAW_QUARTER_TOP_RIGHT;
+ else
+ flags = HDFF_DRAW_QUARTER_TOP_RIGHT_INVERTED;
+ cx = x1;
+ cy = y2;
+ rx = x2 - x1;
+ ry = y2 - y1;
+ break;
+ case 2:
+ if (Quadrants > 0)
+ flags = HDFF_DRAW_QUARTER_TOP_LEFT;
+ else
+ flags = HDFF_DRAW_QUARTER_TOP_LEFT_INVERTED;
+ cx = x2;
+ cy = y2;
+ rx = x2 - x1;
+ ry = y2 - y1;
+ break;
+ case 3:
+ if (Quadrants > 0)
+ flags = HDFF_DRAW_QUARTER_BOTTOM_LEFT;
+ else
+ flags = HDFF_DRAW_QUARTER_BOTTOM_LEFT_INVERTED;
+ cx = x2;
+ cy = y1;
+ rx = x2 - x1;
+ ry = y2 - y1;
+ break;
+ case 4:
+ if (Quadrants > 0)
+ flags = HDFF_DRAW_QUARTER_BOTTOM_RIGHT;
+ else
+ flags = HDFF_DRAW_QUARTER_BOTTOM_RIGHT_INVERTED;
+ cx = x1;
+ cy = y1;
+ rx = x2 - x1;
+ ry = y2 - y1;
+ break;
+ case 5:
+ flags = HDFF_DRAW_HALF_RIGHT;
+ cx = x1;
+ cy = (y1 + y2) / 2;
+ rx = x2 - x1;
+ ry = (y2 - y1) / 2;
+ break;
+ case 6:
+ flags = HDFF_DRAW_HALF_TOP;
+ cx = (x1 + x2) / 2;
+ cy = y2;
+ rx = (x2 - x1) / 2;
+ ry = y2 - y1;
+ break;
+ case 7:
+ flags = HDFF_DRAW_HALF_LEFT;
+ cx = x2;
+ cy = (y1 + y2) / 2;
+ rx = x2 - x1;
+ ry = (y2 - y1) / 2;
+ break;
+ case 8:
+ flags = HDFF_DRAW_HALF_BOTTOM;
+ cx = (x1 + x2) / 2;
+ cy = y1;
+ rx = (x2 - x1) / 2;
+ ry = y2 - y1;
+ break;
+ default:
+ flags = HDFF_DRAW_FULL;
+ cx = (x1 + x2) / 2;
+ cy = (y1 + y2) / 2;
+ rx = (x2 - x1) / 2;
+ ry = (y2 - y1) / 2;
+ break;
+ }
+ mHdffCmdIf->CmdOsdDrawEllipse(mDisplay, mLeft + cx, mTop + cy, rx, ry, Color, flags);
+ mChanged = true;
+}
+
+void cHdffOsd::DrawSlope(int x1, int y1, int x2, int y2, tColor Color, int Type)
+{
+ //printf("DrawSlope\n");
+ mHdffCmdIf->CmdOsdDrawSlope(mDisplay, mLeft + x1, mTop + y1,
+ x2 - x1 + 1, y2 - y1 + 1, Color, Type);
+ mChanged = true;
+}
+
+void cHdffOsd::Flush(void)
+{
+ if (!Active())
+ return;
+
+ //printf("Flush\n");
+ cBitmap * Bitmap;
+
+ for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++)
+ {
+ int x1;
+ int y1;
+ int x2;
+ int y2;
+
+ if (Bitmap->Dirty(x1, y1, x2, y2))
+ {
+ //printf("dirty %d %d, %d %d\n", x1, y1, x2, y2);
+ DrawBitmap(0, 0, *Bitmap);
+ Bitmap->Clean();
+ }
+ }
+
+ if (!mChanged)
+ return;
+
+ mHdffCmdIf->CmdOsdRenderDisplay(mDisplay);
+
+ mChanged = false;
+}
+
+
+class cHdffOsdRaw : public cOsd
+{
+private:
+ HDFF::cHdffCmdIf * mHdffCmdIf;
+ int mDispWidth;
+ int mDispHeight;
+ bool refresh;
+ uint32_t mDisplay;
+ uint32_t mBitmapPalette;
+ uint32_t mBitmapColors[256];
+
+protected:
+ virtual void SetActive(bool On);
+public:
+ cHdffOsdRaw(int Left, int Top, HDFF::cHdffCmdIf * pHdffCmdIf, uint Level);
+ virtual ~cHdffOsdRaw();
+ virtual eOsdError CanHandleAreas(const tArea *Areas, int NumAreas);
+ virtual eOsdError SetAreas(const tArea *Areas, int NumAreas);
+ virtual void Flush(void);
+};
+
+cHdffOsdRaw::cHdffOsdRaw(int Left, int Top, HDFF::cHdffCmdIf * pHdffCmdIf, uint Level)
+: cOsd(Left, Top, Level)
+{
+ double pixelAspect;
+
+ //printf("cHdffOsdRaw %d, %d, %d\n", Left, Top, Level);
+ mHdffCmdIf = pHdffCmdIf;
+ refresh = true;
+ mBitmapPalette = HDFF_INVALID_HANDLE;
+ mDisplay = HDFF_INVALID_HANDLE;
+
+ gHdffSetup.GetOsdSize(mDispWidth, mDispHeight, pixelAspect);
+}
+
+cHdffOsdRaw::~cHdffOsdRaw()
+{
+ //printf("~cHdffOsdRaw %d %d\n", Left(), Top());
+ if (mDisplay != HDFF_INVALID_HANDLE)
+ {
+ mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, 0, 0, mDispWidth, mDispHeight, 0);
+ mHdffCmdIf->CmdOsdRenderDisplay(mDisplay);
+ }
+ if (mBitmapPalette != HDFF_INVALID_HANDLE)
+ mHdffCmdIf->CmdOsdDeletePalette(mBitmapPalette);
+ mBitmapPalette = HDFF_INVALID_HANDLE;
+ if (mDisplay != HDFF_INVALID_HANDLE)
+ mHdffCmdIf->CmdOsdDeleteDisplay(mDisplay);
+ mDisplay = HDFF_INVALID_HANDLE;
+}
+
+void cHdffOsdRaw::SetActive(bool On)
+{
+ if (On != Active())
+ {
+ cOsd::SetActive(On);
+ if (On)
+ {
+ if (mDisplay == HDFF_INVALID_HANDLE)
+ {
+ mDisplay = mHdffCmdIf->CmdOsdCreateDisplay(mDispWidth, mDispHeight, HDFF_COLOR_TYPE_ARGB8888);
+ if (mDisplay != HDFF_INVALID_HANDLE)
+ mHdffCmdIf->CmdOsdSetDisplayOutputRectangle(mDisplay, 0, 0, HDFF_SIZE_FULL_SCREEN, HDFF_SIZE_FULL_SCREEN);
+ }
+ refresh = true;
+ if (GetBitmap(0)) // only flush here if there are already bitmaps
+ Flush();
+ }
+ else
+ {
+ if (mDisplay != HDFF_INVALID_HANDLE)
+ {
+ mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, 0, 0, mDispWidth, mDispHeight, 0);
+ mHdffCmdIf->CmdOsdRenderDisplay(mDisplay);
+ }
+ if (mBitmapPalette != HDFF_INVALID_HANDLE)
+ mHdffCmdIf->CmdOsdDeletePalette(mBitmapPalette);
+ mBitmapPalette = HDFF_INVALID_HANDLE;
+ if (mDisplay != HDFF_INVALID_HANDLE)
+ mHdffCmdIf->CmdOsdDeleteDisplay(mDisplay);
+ mDisplay = HDFF_INVALID_HANDLE;
+ }
+ }
+}
+
+eOsdError cHdffOsdRaw::CanHandleAreas(const tArea *Areas, int NumAreas)
+{
+ eOsdError Result = cOsd::CanHandleAreas(Areas, NumAreas);
+ if (Result == oeOk)
+ {
+ for (int i = 0; i < NumAreas; i++)
+ {
+ if (Areas[i].bpp != 1 && Areas[i].bpp != 2 && Areas[i].bpp != 4 && Areas[i].bpp != 8
+ && (Areas[i].bpp != 32 || !gHdffSetup.TrueColorOsd))
+ return oeBppNotSupported;
+ }
+ }
+ return Result;
+}
+
+eOsdError cHdffOsdRaw::SetAreas(const tArea *Areas, int NumAreas)
+{
+ for (int i = 0; i < NumAreas; i++)
+ {
+ //printf("SetAreas %d: %d %d %d %d %d\n", i, Areas[i].x1, Areas[i].y1, Areas[i].x2, Areas[i].y2, Areas[i].bpp);
+ }
+ if (mDisplay != HDFF_INVALID_HANDLE)
+ {
+ mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, 0, 0, mDispWidth, mDispHeight, 0);
+ mHdffCmdIf->CmdOsdRenderDisplay(mDisplay);
+ refresh = true;
+ }
+ return cOsd::SetAreas(Areas, NumAreas);
+}
+
+void cHdffOsdRaw::Flush(void)
+{
+ if (!Active() || (mDisplay == HDFF_INVALID_HANDLE))
+ return;
+#ifdef MEASURE_OSD_TIME
+ struct timeval start;
+ struct timeval end;
+ struct timezone timeZone;
+ gettimeofday(&start, &timeZone);
+#endif
+
+ bool render = false;
+ if (IsTrueColor())
+ {
+ uint8_t * buffer = 0;
+ if (gHdffSetup.TrueColorFormat != 0)
+ {
+ buffer = new uint8_t[MAX_BITMAP_SIZE];
+ if (!buffer)
+ return;
+ }
+ LOCK_PIXMAPS;
+#if (APIVERSNUM >= 20110)
+ while (cPixmapMemory *pm = dynamic_cast<cPixmapMemory *>(RenderPixmaps()))
+#else
+ while (cPixmapMemory *pm = RenderPixmaps())
+#endif
+ {
+ int w = pm->ViewPort().Width();
+ int h = pm->ViewPort().Height();
+ int d = w * sizeof(tColor);
+ int Chunk = MAX_BITMAP_SIZE / w / sizeof(tColor);
+ if (Chunk > h)
+ Chunk = h;
+ for (int y = 0; y < h; y += Chunk)
+ {
+ int hc = Chunk;
+ if (y + hc > h)
+ hc = h - y;
+ if (gHdffSetup.TrueColorFormat == 0) // ARGB8888 (32 bit)
+ {
+ mHdffCmdIf->CmdOsdDrawBitmap(mDisplay,
+ Left() + pm->ViewPort().X(), Top() + pm->ViewPort().Y() + y,
+ pm->Data() + y * d, w, hc, hc * d,
+ HDFF_COLOR_TYPE_ARGB8888, HDFF_INVALID_HANDLE);
+ }
+ else if (gHdffSetup.TrueColorFormat == 1) // ARGB8565 (24 bit)
+ {
+ const tColor * pixmapData = (const tColor *) (pm->Data() + y * d);
+ uint8_t * bitmapData = buffer;
+ for (int i = 0; i < hc * w; i++)
+ {
+ bitmapData[2] = (pixmapData[i] & 0xFF000000) >> 24;
+ bitmapData[1] = ((pixmapData[i] & 0x00F80000) >> 16)
+ | ((pixmapData[i] & 0x0000E000) >> 13);
+ bitmapData[0] = ((pixmapData[i] & 0x00001C00) >> 5)
+ | ((pixmapData[i] & 0x000000F8) >> 3);
+ bitmapData += 3;
+ }
+ mHdffCmdIf->CmdOsdDrawBitmap(mDisplay,
+ Left() + pm->ViewPort().X(), Top() + pm->ViewPort().Y() + y,
+ buffer, w, hc, hc * w * 3,
+ HDFF_COLOR_TYPE_ARGB8565, HDFF_INVALID_HANDLE);
+ }
+ else if (gHdffSetup.TrueColorFormat == 2) // ARGB4444 (16 bit)
+ {
+ const tColor * pixmapData = (const tColor *) (pm->Data() + y * d);
+ uint16_t * bitmapData = (uint16_t *) buffer;
+ for (int i = 0; i < hc * w; i++)
+ {
+ bitmapData[i] = ((pixmapData[i] & 0xF0000000) >> 16)
+ | ((pixmapData[i] & 0x00F00000) >> 12)
+ | ((pixmapData[i] & 0x0000F000) >> 8)
+ | ((pixmapData[i] & 0x000000F0) >> 4);
+ }
+ mHdffCmdIf->CmdOsdDrawBitmap(mDisplay,
+ Left() + pm->ViewPort().X(), Top() + pm->ViewPort().Y() + y,
+ buffer, w, hc, hc * w * 2,
+ HDFF_COLOR_TYPE_ARGB4444, HDFF_INVALID_HANDLE);
+ }
+ }
+#if (APIVERSNUM >= 20110)
+ DestroyPixmap(pm);
+#else
+ delete pm;
+#endif
+ render = true;
+ }
+ if (buffer)
+ delete[] buffer;
+ }
+ else
+ {
+ uint8_t * buffer = new uint8_t[MAX_BITMAP_SIZE];
+ if (!buffer)
+ return;
+ cBitmap * bitmap;
+ for (int i = 0; (bitmap = GetBitmap(i)) != NULL; i++)
+ {
+ int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
+ if (refresh || bitmap->Dirty(x1, y1, x2, y2))
+ {
+ if (refresh)
+ {
+ x2 = bitmap->Width() - 1;
+ y2 = bitmap->Height() - 1;
+ }
+ // commit colors:
+ int numColors;
+ const tColor * colors = bitmap->Colors(numColors);
+ if (colors)
+ {
+ for (int c = 0; c < numColors; c++)
+ mBitmapColors[c] = colors[c];
+ if (mBitmapPalette == HDFF_INVALID_HANDLE)
+ {
+ mBitmapPalette = mHdffCmdIf->CmdOsdCreatePalette(HDFF_COLOR_TYPE_CLUT8,
+ HDFF_COLOR_FORMAT_ARGB, numColors, mBitmapColors);
+ }
+ else
+ {
+ mHdffCmdIf->CmdOsdSetPaletteColors(mBitmapPalette,
+ HDFF_COLOR_FORMAT_ARGB, 0, numColors, mBitmapColors);
+ }
+ }
+ // commit modified data:
+ int width = x2 - x1 + 1;
+ int height = y2 - y1 + 1;
+ int chunk = MAX_BITMAP_SIZE / width;
+ if (chunk > height)
+ chunk = height;
+ for (int y = 0; y < height; y += chunk)
+ {
+ int hc = chunk;
+ if (y + hc > height)
+ hc = height - y;
+ for (int r = 0; r < hc; r++)
+ memcpy(buffer + r * width, bitmap->Data(x1, y1 + y + r), width);
+ mHdffCmdIf->CmdOsdDrawBitmap(mDisplay,
+ Left() + bitmap->X0() + x1, Top() + bitmap->Y0() + y1 + y,
+ buffer, width, hc, hc * width,
+ HDFF_COLOR_TYPE_CLUT8, mBitmapPalette);
+ }
+ render = true;
+ }
+ bitmap->Clean();
+ }
+ delete[] buffer;
+ }
+ if (render)
+ {
+ mHdffCmdIf->CmdOsdRenderDisplay(mDisplay);
+#ifdef MEASURE_OSD_TIME
+ gettimeofday(&end, &timeZone);
+ int timeNeeded = end.tv_usec - start.tv_usec;
+ timeNeeded += (end.tv_sec - start.tv_sec) * 1000000;
+ printf("time = %d\n", timeNeeded);
+#endif
+ }
+ refresh = false;
+}
+
+
+
+
+cHdffOsdProvider::cHdffOsdProvider(HDFF::cHdffCmdIf * HdffCmdIf)
+{
+ mHdffCmdIf = HdffCmdIf;
+}
+
+cOsd *cHdffOsdProvider::CreateOsd(int Left, int Top, uint Level)
+{
+ //printf("CreateOsd %d %d %d\n", Left, Top, Level);
+ if (gHdffSetup.HighLevelOsd)
+ return new cHdffOsd(Left, Top, mHdffCmdIf, Level);
+ else
+ return new cHdffOsdRaw(Left, Top, mHdffCmdIf, Level);
+}
+
+bool cHdffOsdProvider::ProvidesTrueColor(void)
+{
+ return gHdffSetup.TrueColorOsd && !gHdffSetup.HighLevelOsd;
+}
diff --git a/hdffosd.h b/hdffosd.h
new file mode 100644
index 0000000..c8eaf46
--- /dev/null
+++ b/hdffosd.h
@@ -0,0 +1,24 @@
+/*
+ * hdffosd.h: Implementation of the DVB HD Full Featured On Screen Display
+ *
+ * See the README file for copyright information and how to reach the author.
+ */
+
+#ifndef _HDFF_OSD_H_
+#define _HDFF_OSD_H_
+
+#include <vdr/osd.h>
+
+#include "hdffcmd.h"
+
+class cHdffOsdProvider : public cOsdProvider
+{
+private:
+ HDFF::cHdffCmdIf * mHdffCmdIf;
+public:
+ cHdffOsdProvider(HDFF::cHdffCmdIf * pHdffCmdIf);
+ virtual cOsd *CreateOsd(int Left, int Top, uint Level);
+ virtual bool ProvidesTrueColor(void);
+};
+
+#endif
diff --git a/libhdffcmd/Makefile b/libhdffcmd/Makefile
new file mode 100644
index 0000000..216cdba
--- /dev/null
+++ b/libhdffcmd/Makefile
@@ -0,0 +1,68 @@
+#
+# Makefile for the HDFF firmware command interface library
+#
+
+VERSION = 0.1.0
+
+INSTALL_PATH ?= /usr/local
+INSTALL_LIB_PATH ?= $(INSTALL_PATH)/lib
+INSTALL_INCLUDE_PATH ?= $(INSTALL_PATH)/include
+
+LIB_NAME = libhdffcmd
+
+LIB_OBJS = bitbuffer.o hdffcmd_av.o hdffcmd_base.o hdffcmd_generic.o \
+ hdffcmd_hdmi.o hdffcmd_mux.o hdffcmd_osd.o hdffcmd_remote.o
+
+LIB_HEADERS = hdffcmd.h hdffcmd_av.h hdffcmd_generic.h hdffcmd_hdmi.h \
+ hdffcmd_mux.h hdffcmd_osd.h hdffcmd_remote.h
+
+LIB_STATIC = $(LIB_NAME).a
+LIB_SHARED = $(LIB_NAME)-$(VERSION).so
+
+CC ?= gcc
+CFLAGS ?= -g -O2 -fPIC -Wall
+AR ?= ar
+ARFLAGS ?= r
+
+### Implicit rules:
+
+%.o: %.c
+ $(CC) $(CFLAGS) -c $(DEFINES) $(INCLUDES) $<
+
+### Dependencies:
+
+MAKEDEP = $(CC) -MM -MG
+DEPFILE = .dependencies
+$(DEPFILE): Makefile
+ @$(MAKEDEP) $(DEFINES) $(INCLUDES) $(LIB_OBJS:%.o=%.c) > $@
+
+-include $(DEPFILE)
+
+### Targets:
+
+all: $(LIB_STATIC) $(LIB_SHARED)
+
+$(LIB_STATIC): $(LIB_OBJS)
+ $(AR) $(ARFLAGS) $(LIB_STATIC) $(LIB_OBJS)
+
+$(LIB_SHARED): $(LIB_OBJS)
+ $(CC) $(CFLAGS) $(LDFLAGS) -fPIC -shared -o $(LIB_SHARED) $(LIB_OBJS)
+ ln -sf $(LIB_SHARED) $(LIB_NAME).so
+
+clean:
+ @-rm -f $(LIB_OBJS) $(DEPFILE) $(LIB_STATIC) $(LIB_NAME)*.so
+
+install: $(LIB_SHARED)
+ chown root $(LIB_SHARED)
+ chgrp root $(LIB_SHARED)
+ chmod 0755 $(LIB_SHARED)
+ cp -f $(LIB_SHARED) $(INSTALL_LIB_PATH)/
+ ln -sf $(LIB_SHARED) $(INSTALL_LIB_PATH)/$(LIB_NAME).so
+ mkdir -p $(INSTALL_INCLUDE_PATH)/libhdffcmd
+ list='$(LIB_HEADERS)'; \
+ for headerfile in $$list; do \
+ cp -f $$headerfile $(INSTALL_INCLUDE_PATH)/libhdffcmd/ ; \
+ chown root $(INSTALL_INCLUDE_PATH)/libhdffcmd/$$headerfile ; \
+ chgrp root $(INSTALL_INCLUDE_PATH)/libhdffcmd/$$headerfile ; \
+ chmod 0644 $(INSTALL_INCLUDE_PATH)/libhdffcmd/$$headerfile ; \
+ done
diff --git a/libhdffcmd/bitbuffer.c b/libhdffcmd/bitbuffer.c
new file mode 100644
index 0000000..b85990d
--- /dev/null
+++ b/libhdffcmd/bitbuffer.c
@@ -0,0 +1,79 @@
+/**********************************************************************
+ *
+ * HDFF firmware command interface library
+ *
+ * Copyright (C) 2011 Andreas Regel
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *********************************************************************/
+
+#include <string.h>
+
+#include "bitbuffer.h"
+
+void BitBuffer_Init(BitBuffer_t * BitBuffer,
+ uint8_t * Data, uint32_t MaxLength)
+{
+ memset(Data, 0, MaxLength);
+ BitBuffer->Data = Data;
+ BitBuffer->MaxLength = MaxLength * 8;
+ BitBuffer->BitPos = 0;
+}
+
+void BitBuffer_SetBits(BitBuffer_t * BitBuffer, int NumBits, uint32_t Data)
+{
+ uint32_t nextBitPos;
+ uint32_t bytePos;
+ uint32_t bitsInByte;
+ int shift;
+
+ if (NumBits <= 0 || NumBits > 32)
+ return;
+
+ nextBitPos = BitBuffer->BitPos + NumBits;
+
+ if (nextBitPos > BitBuffer->MaxLength)
+ return;
+
+ bytePos = BitBuffer->BitPos / 8;
+ bitsInByte = BitBuffer->BitPos % 8;
+
+ BitBuffer->Data[bytePos] &= (uint8_t) (0xFF << (8 - bitsInByte));
+ shift = NumBits - (8 - bitsInByte);
+ if (shift > 0)
+ BitBuffer->Data[bytePos] |= (uint8_t) (Data >> shift);
+ else
+ BitBuffer->Data[bytePos] |= (uint8_t) (Data << (-shift));
+ NumBits -= 8 - bitsInByte;
+ bytePos++;
+ while (NumBits > 0)
+ {
+ shift = NumBits - 8;
+ if (shift > 0)
+ BitBuffer->Data[bytePos] = (uint8_t) (Data >> shift);
+ else
+ BitBuffer->Data[bytePos] = (uint8_t) (Data << (-shift));
+ NumBits -= 8;
+ bytePos++;
+ }
+ BitBuffer->BitPos = nextBitPos;
+}
+
+uint32_t BitBuffer_GetByteLength(BitBuffer_t * BitBuffer)
+{
+ return (BitBuffer->BitPos + 7) / 8;
+}
diff --git a/libhdffcmd/bitbuffer.h b/libhdffcmd/bitbuffer.h
new file mode 100644
index 0000000..5bdc23b
--- /dev/null
+++ b/libhdffcmd/bitbuffer.h
@@ -0,0 +1,43 @@
+/**********************************************************************
+ *
+ * HDFF firmware command interface library
+ *
+ * Copyright (C) 2011 Andreas Regel
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *********************************************************************/
+
+#ifndef BITBUFFER_H
+#define BITBUFFER_H
+
+#include <stdint.h>
+
+typedef struct BitBuffer_t
+{
+ uint8_t * Data;
+ uint32_t MaxLength;
+ uint32_t BitPos;
+} BitBuffer_t;
+
+void BitBuffer_Init(BitBuffer_t * BitBuffer,
+ uint8_t * Data, uint32_t MaxLength);
+
+void BitBuffer_SetBits(BitBuffer_t * BitBuffer, int NumBits, uint32_t Data);
+
+uint32_t BitBuffer_GetByteLength(BitBuffer_t * BitBuffer);
+
+#endif /* BITBUFFER_H */
diff --git a/libhdffcmd/hdffcmd.h b/libhdffcmd/hdffcmd.h
new file mode 100644
index 0000000..8d05782
--- /dev/null
+++ b/libhdffcmd/hdffcmd.h
@@ -0,0 +1,42 @@
+/**********************************************************************
+ *
+ * HDFF firmware command interface library
+ *
+ * Copyright (C) 2011 Andreas Regel
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *********************************************************************/
+
+#ifndef HDFFCMD_H
+#define HDFFCMD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "hdffcmd_av.h"
+#include "hdffcmd_generic.h"
+#include "hdffcmd_hdmi.h"
+#include "hdffcmd_mux.h"
+#include "hdffcmd_osd.h"
+#include "hdffcmd_remote.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HDFFCMD_H */
diff --git a/libhdffcmd/hdffcmd_av.c b/libhdffcmd/hdffcmd_av.c
new file mode 100644
index 0000000..ea17ceb
--- /dev/null
+++ b/libhdffcmd/hdffcmd_av.c
@@ -0,0 +1,506 @@
+/**********************************************************************
+ *
+ * HDFF firmware command interface library
+ *
+ * Copyright (C) 2011 Andreas Regel
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *********************************************************************/
+
+#include <stdint.h>
+#include <string.h>
+#include <sys/ioctl.h>
+
+#include "hdffcmd.h"
+#include "hdffcmd_base.h"
+#include "hdffcmd_defs.h"
+
+
+int HdffCmdAvSetPlayMode(int OsdDevice, uint8_t PlayMode, int Realtime)
+{
+ uint8_t cmdData[8];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND,
+ HDFF_MSG_GROUP_AV_DECODER,
+ HDFF_MSG_AV_SET_PLAY_MODE);
+ BitBuffer_SetBits(&cmdBuf, 1, Realtime ? 1 : 0);
+ BitBuffer_SetBits(&cmdBuf, 7, PlayMode);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdAvSetVideoPid(int OsdDevice, uint8_t DecoderIndex, uint16_t Pid,
+ HdffVideoStreamType_t StreamType)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND,
+ HDFF_MSG_GROUP_AV_DECODER,
+ HDFF_MSG_AV_SET_VIDEO_PID);
+ BitBuffer_SetBits(&cmdBuf, 4, DecoderIndex);
+ BitBuffer_SetBits(&cmdBuf, 4, StreamType);
+ BitBuffer_SetBits(&cmdBuf, 3, 0); // reserved
+ BitBuffer_SetBits(&cmdBuf, 13, Pid);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdAvSetAudioPid(int OsdDevice, uint8_t DecoderIndex, uint16_t Pid,
+ HdffAudioStreamType_t StreamType,
+ HdffAvContainerType_t ContainerType)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND,
+ HDFF_MSG_GROUP_AV_DECODER,
+ HDFF_MSG_AV_SET_AUDIO_PID);
+ BitBuffer_SetBits(&cmdBuf, 4, DecoderIndex);
+ BitBuffer_SetBits(&cmdBuf, 4, StreamType);
+ BitBuffer_SetBits(&cmdBuf, 2, 0); // reserved
+ BitBuffer_SetBits(&cmdBuf, 1, ContainerType);
+ BitBuffer_SetBits(&cmdBuf, 13, Pid);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdAvSetPcrPid(int OsdDevice, uint8_t DecoderIndex, uint16_t Pid)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND,
+ HDFF_MSG_GROUP_AV_DECODER,
+ HDFF_MSG_AV_SET_PCR_PID);
+ BitBuffer_SetBits(&cmdBuf, 4, DecoderIndex);
+ BitBuffer_SetBits(&cmdBuf, 4, 0); // reserved
+ BitBuffer_SetBits(&cmdBuf, 3, 0); // reserved
+ BitBuffer_SetBits(&cmdBuf, 13, Pid);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdAvSetTeletextPid(int OsdDevice, uint8_t DecoderIndex, uint16_t Pid)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND,
+ HDFF_MSG_GROUP_AV_DECODER,
+ HDFF_MSG_AV_SET_TELETEXT_PID);
+ BitBuffer_SetBits(&cmdBuf, 4, DecoderIndex);
+ BitBuffer_SetBits(&cmdBuf, 4, 0); // reserved
+ BitBuffer_SetBits(&cmdBuf, 3, 0); // reserved
+ BitBuffer_SetBits(&cmdBuf, 13, Pid);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdAvSetVideoWindow(int OsdDevice, uint8_t DecoderIndex, int Enable,
+ uint16_t X, uint16_t Y, uint16_t Width,
+ uint16_t Height)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND,
+ HDFF_MSG_GROUP_AV_DECODER,
+ HDFF_MSG_AV_SET_VIDEO_WINDOW);
+ BitBuffer_SetBits(&cmdBuf, 4, DecoderIndex);
+ BitBuffer_SetBits(&cmdBuf, 3, 0); // reserved
+ if (Enable)
+ BitBuffer_SetBits(&cmdBuf, 1, 1);
+ else
+ BitBuffer_SetBits(&cmdBuf, 1, 0);
+ BitBuffer_SetBits(&cmdBuf, 16, X);
+ BitBuffer_SetBits(&cmdBuf, 16, Y);
+ BitBuffer_SetBits(&cmdBuf, 16, Width);
+ BitBuffer_SetBits(&cmdBuf, 16, Height);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdAvShowStillImage(int OsdDevice, uint8_t DecoderIndex,
+ const uint8_t * StillImage, int Size,
+ HdffVideoStreamType_t StreamType)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+ osd_raw_data_t osd_data;
+ int err;
+
+ memset(&osd_data, 0, sizeof(osd_raw_data_t));
+ osd_data.data_buffer = StillImage;
+ osd_data.data_length = Size;
+ err = ioctl(OsdDevice, OSD_RAW_DATA, &osd_data);
+ if (err != 0)
+ return err;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND,
+ HDFF_MSG_GROUP_AV_DECODER,
+ HDFF_MSG_AV_SHOW_STILL_IMAGE);
+ BitBuffer_SetBits(&cmdBuf, 4, DecoderIndex);
+ BitBuffer_SetBits(&cmdBuf, 4, StreamType);
+ BitBuffer_SetBits(&cmdBuf, 16, osd_data.data_handle);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdAvSetDecoderInput(int OsdDevice, uint8_t DecoderIndex,
+ uint8_t DemultiplexerIndex)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND,
+ HDFF_MSG_GROUP_AV_DECODER,
+ HDFF_MSG_AV_SET_DECODER_INPUT);
+ BitBuffer_SetBits(&cmdBuf, 4, DecoderIndex);
+ BitBuffer_SetBits(&cmdBuf, 4, DemultiplexerIndex);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdAvSetDemultiplexerInput(int OsdDevice, uint8_t DemultiplexerIndex,
+ uint8_t TsInputIndex)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND,
+ HDFF_MSG_GROUP_AV_DECODER,
+ HDFF_MSG_AV_SET_DEMULTIPLEXER_INPUT);
+ BitBuffer_SetBits(&cmdBuf, 4, DemultiplexerIndex);
+ BitBuffer_SetBits(&cmdBuf, 4, TsInputIndex);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdAvSetVideoFormat(int OsdDevice, uint8_t DecoderIndex,
+ const HdffVideoFormat_t * VideoFormat)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND,
+ HDFF_MSG_GROUP_AV_DECODER,
+ HDFF_MSG_AV_SET_VIDEO_FORMAT);
+ BitBuffer_SetBits(&cmdBuf, 4, DecoderIndex);
+ BitBuffer_SetBits(&cmdBuf, 1, VideoFormat->AutomaticEnabled ? 1 : 0);
+ BitBuffer_SetBits(&cmdBuf, 1, VideoFormat->AfdEnabled ? 1 : 0);
+ BitBuffer_SetBits(&cmdBuf, 2, VideoFormat->TvFormat);
+ BitBuffer_SetBits(&cmdBuf, 8, VideoFormat->VideoConversion);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdAvSetVideoOutputMode(int OsdDevice, uint8_t DecoderIndex,
+ HdffVideoOutputMode_t OutputMode)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND,
+ HDFF_MSG_GROUP_AV_DECODER,
+ HDFF_MSG_AV_SET_VIDEO_OUTPUT_MODE);
+ BitBuffer_SetBits(&cmdBuf, 8, OutputMode);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdAvSetStc(int OsdDevice, uint8_t DecoderIndex, uint64_t Stc)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND,
+ HDFF_MSG_GROUP_AV_DECODER,
+ HDFF_MSG_AV_SET_STC);
+ BitBuffer_SetBits(&cmdBuf, 4, DecoderIndex);
+ BitBuffer_SetBits(&cmdBuf, 3, 0); // reserved
+ BitBuffer_SetBits(&cmdBuf, 1, (uint32_t) (Stc >> 32));
+ BitBuffer_SetBits(&cmdBuf, 32, (uint32_t) Stc);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdAvFlushBuffer(int OsdDevice, uint8_t DecoderIndex, int FlushAudio,
+ int FlushVideo)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND,
+ HDFF_MSG_GROUP_AV_DECODER,
+ HDFF_MSG_AV_FLUSH_BUFFER);
+ BitBuffer_SetBits(&cmdBuf, 4, DecoderIndex);
+ if (FlushAudio)
+ {
+ BitBuffer_SetBits(&cmdBuf, 1, 1);
+ }
+ else
+ {
+ BitBuffer_SetBits(&cmdBuf, 1, 0);
+ }
+ if (FlushVideo)
+ {
+ BitBuffer_SetBits(&cmdBuf, 1, 1);
+ }
+ else
+ {
+ BitBuffer_SetBits(&cmdBuf, 1, 0);
+ }
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdAvEnableSync(int OsdDevice, uint8_t DecoderIndex, int SyncAudio,
+ int SyncVideo)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND,
+ HDFF_MSG_GROUP_AV_DECODER,
+ HDFF_MSG_AV_ENABLE_SYNC);
+ BitBuffer_SetBits(&cmdBuf, 4, DecoderIndex);
+ BitBuffer_SetBits(&cmdBuf, 1, SyncAudio ? 1 : 0);
+ BitBuffer_SetBits(&cmdBuf, 1, SyncVideo ? 1 : 0);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdAvSetVideoSpeed(int OsdDevice, uint8_t DecoderIndex, int32_t Speed)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND,
+ HDFF_MSG_GROUP_AV_DECODER,
+ HDFF_MSG_AV_SET_VIDEO_SPEED);
+ BitBuffer_SetBits(&cmdBuf, 4, DecoderIndex);
+ BitBuffer_SetBits(&cmdBuf, 4, 0);
+ BitBuffer_SetBits(&cmdBuf, 32, Speed);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdAvSetAudioSpeed(int OsdDevice, uint8_t DecoderIndex, int32_t Speed)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND,
+ HDFF_MSG_GROUP_AV_DECODER,
+ HDFF_MSG_AV_SET_AUDIO_SPEED);
+ BitBuffer_SetBits(&cmdBuf, 4, DecoderIndex);
+ BitBuffer_SetBits(&cmdBuf, 4, 0);
+ BitBuffer_SetBits(&cmdBuf, 32, Speed);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdAvEnableVideoAfterStop(int OsdDevice, uint8_t DecoderIndex,
+ int EnableVideoAfterStop)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND,
+ HDFF_MSG_GROUP_AV_DECODER,
+ HDFF_MSG_AV_ENABLE_VIDEO_AFTER_STOP);
+ BitBuffer_SetBits(&cmdBuf, 4, DecoderIndex);
+ BitBuffer_SetBits(&cmdBuf, 1, EnableVideoAfterStop ? 1 : 0);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdAvSetAudioDelay(int OsdDevice, int16_t Delay)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND,
+ HDFF_MSG_GROUP_AV_DECODER,
+ HDFF_MSG_AV_SET_AUDIO_DELAY);
+ BitBuffer_SetBits(&cmdBuf, 16, Delay);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdAvSetAudioDownmix(int OsdDevice, HdffAudioDownmixMode_t DownmixMode)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND,
+ HDFF_MSG_GROUP_AV_DECODER,
+ HDFF_MSG_AV_SET_AUDIO_DOWNMIX);
+ BitBuffer_SetBits(&cmdBuf, 8, DownmixMode);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdAvSetAudioChannel(int OsdDevice, uint8_t AudioChannel)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND,
+ HDFF_MSG_GROUP_AV_DECODER,
+ HDFF_MSG_AV_SET_AUDIO_CHANNEL);
+ BitBuffer_SetBits(&cmdBuf, 8, AudioChannel);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdAvSetSyncShift(int OsdDevice, int16_t SyncShift)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND,
+ HDFF_MSG_GROUP_AV_DECODER,
+ HDFF_MSG_AV_SET_OPTIONS);
+ BitBuffer_SetBits(&cmdBuf, 1, 1);
+ BitBuffer_SetBits(&cmdBuf, 31, 0); // reserved
+ BitBuffer_SetBits(&cmdBuf, 16, SyncShift);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdAvMuteAudio(int OsdDevice, uint8_t DecoderIndex, int Mute)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND,
+ HDFF_MSG_GROUP_AV_DECODER,
+ HDFF_MSG_AV_MUTE_AUDIO);
+ BitBuffer_SetBits(&cmdBuf, 4, DecoderIndex);
+ BitBuffer_SetBits(&cmdBuf, 1, Mute ? 1 : 0);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdAvMuteVideo(int OsdDevice, uint8_t DecoderIndex, int Mute)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND,
+ HDFF_MSG_GROUP_AV_DECODER,
+ HDFF_MSG_AV_MUTE_VIDEO);
+ BitBuffer_SetBits(&cmdBuf, 4, DecoderIndex);
+ BitBuffer_SetBits(&cmdBuf, 1, Mute ? 1 : 0);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
diff --git a/libhdffcmd/hdffcmd_av.h b/libhdffcmd/hdffcmd_av.h
new file mode 100644
index 0000000..3638141
--- /dev/null
+++ b/libhdffcmd/hdffcmd_av.h
@@ -0,0 +1,159 @@
+/**********************************************************************
+ *
+ * HDFF firmware command interface library
+ *
+ * Copyright (C) 2011 Andreas Regel
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *********************************************************************/
+
+#ifndef HDFFCMD_AV_H
+#define HDFFCMD_AV_H
+
+typedef enum HdffAvContainerType_t
+{
+ HDFF_AV_CONTAINER_PES,
+ HDFF_AV_CONTAINER_PES_DVD
+} HdffAvContainerType_t;
+
+typedef enum HdffAudioStreamType_t
+{
+ HDFF_AUDIO_STREAM_INVALID = -1,
+ HDFF_AUDIO_STREAM_MPEG1 = 0,
+ HDFF_AUDIO_STREAM_MPEG2,
+ HDFF_AUDIO_STREAM_AC3,
+ HDFF_AUDIO_STREAM_AAC,
+ HDFF_AUDIO_STREAM_HE_AAC,
+ HDFF_AUDIO_STREAM_PCM,
+ HDFF_AUDIO_STREAM_EAC3,
+ HDFF_AUDIO_STREAM_DTS
+} HdffAudioStreamType_t;
+
+typedef enum HdffVideoStreamType_t
+{
+ HDFF_VIDEO_STREAM_INVALID = -1,
+ HDFF_VIDEO_STREAM_MPEG1 = 0,
+ HDFF_VIDEO_STREAM_MPEG2,
+ HDFF_VIDEO_STREAM_H264,
+ HDFF_VIDEO_STREAM_MPEG4_ASP,
+ HDFF_VIDEO_STREAM_VC1
+} HdffVideoStreamType_t;
+
+typedef enum HdffTvFormat_t
+{
+ HDFF_TV_FORMAT_4_BY_3,
+ HDFF_TV_FORMAT_16_BY_9
+} HdffTvFormat_t;
+
+typedef enum HdffVideoConversion_t
+{
+ HDFF_VIDEO_CONVERSION_AUTOMATIC,
+ HDFF_VIDEO_CONVERSION_LETTERBOX_16_BY_9,
+ HDFF_VIDEO_CONVERSION_LETTERBOX_14_BY_9,
+ HDFF_VIDEO_CONVERSION_PILLARBOX,
+ HDFF_VIDEO_CONVERSION_CENTRE_CUT_OUT,
+ HDFF_VIDEO_CONVERSION_ALWAYS_16_BY_9,
+ HDFF_VIDEO_CONVERSION_ZOOM_16_BY_9
+} HdffVideoConversion_t;
+
+typedef struct HdffVideoFormat_t
+{
+ int AutomaticEnabled;
+ int AfdEnabled;
+ HdffTvFormat_t TvFormat;
+ HdffVideoConversion_t VideoConversion;
+} HdffVideoFormat_t;
+
+typedef enum HdffVideoOutputMode_t
+{
+ HDFF_VIDEO_OUTPUT_CLONE,
+ HDFF_VIDEO_OUTPUT_HD_ONLY
+} HdffVideoOutputMode_t;
+
+typedef enum HdffAudioDownmixMode_t
+{
+ HDFF_AUDIO_DOWNMIX_OFF,
+ HDFF_AUDIO_DOWNMIX_ANALOG,
+ HDFF_AUDIO_DOWNMIX_ALWAYS,
+ HDFF_AUDIO_DOWNMIX_AUTOMATIC,
+ HDFF_AUDIO_DOWNMIX_HDMI_ONLY
+} HdffAudioDownmixMode_t;
+
+
+int HdffCmdAvSetPlayMode(int OsdDevice, uint8_t PlayMode, int Realtime);
+
+int HdffCmdAvSetVideoPid(int OsdDevice, uint8_t DecoderIndex, uint16_t Pid,
+ HdffVideoStreamType_t StreamType);
+
+int HdffCmdAvSetAudioPid(int OsdDevice, uint8_t DecoderIndex, uint16_t Pid,
+ HdffAudioStreamType_t StreamType,
+ HdffAvContainerType_t ContainerType);
+
+int HdffCmdAvSetPcrPid(int OsdDevice, uint8_t DecoderIndex, uint16_t Pid);
+
+int HdffCmdAvSetTeletextPid(int OsdDevice, uint8_t DecoderIndex, uint16_t Pid);
+
+int HdffCmdAvSetVideoWindow(int OsdDevice, uint8_t DecoderIndex, int Enable,
+ uint16_t X, uint16_t Y, uint16_t Width,
+ uint16_t Height);
+
+int HdffCmdAvShowStillImage(int OsdDevice, uint8_t DecoderIndex,
+ const uint8_t * StillImage, int Size,
+ HdffVideoStreamType_t StreamType);
+
+int HdffCmdAvSetDecoderInput(int OsdDevice, uint8_t DecoderIndex,
+ uint8_t DemultiplexerIndex);
+
+int HdffCmdAvSetDemultiplexerInput(int OsdDevice, uint8_t DemultiplexerIndex,
+ uint8_t TsInputIndex);
+
+int HdffCmdAvSetVideoFormat(int OsdDevice, uint8_t DecoderIndex,
+ const HdffVideoFormat_t * VideoFormat);
+
+int HdffCmdAvSetVideoOutputMode(int OsdDevice, uint8_t DecoderIndex,
+ HdffVideoOutputMode_t OutputMode);
+
+int HdffCmdAvSetStc(int OsdDevice, uint8_t DecoderIndex, uint64_t Stc);
+
+int HdffCmdAvFlushBuffer(int OsdDevice, uint8_t DecoderIndex, int FlushAudio,
+ int FlushVideo);
+
+int HdffCmdAvEnableSync(int OsdDevice, uint8_t DecoderIndex, int SyncAudio,
+ int SyncVideo);
+
+int HdffCmdAvSetVideoSpeed(int OsdDevice, uint8_t DecoderIndex, int32_t Speed);
+
+int HdffCmdAvSetAudioSpeed(int OsdDevice, uint8_t DecoderIndex, int32_t Speed);
+
+int HdffCmdAvEnableVideoAfterStop(int OsdDevice, uint8_t DecoderIndex,
+ int EnableVideoAfterStop);
+
+int HdffCmdAvSetAudioDelay(int OsdDevice, int16_t Delay);
+
+int HdffCmdAvSetAudioDownmix(int OsdDevice,
+ HdffAudioDownmixMode_t DownmixMode);
+
+int HdffCmdAvSetAudioChannel(int OsdDevice, uint8_t AudioChannel);
+
+int HdffCmdAvSetSyncShift(int OsdDevice, int16_t SyncShift);
+
+int HdffCmdAvMuteAudio(int OsdDevice, uint8_t DecoderIndex, int Mute);
+
+int HdffCmdAvMuteVideo(int OsdDevice, uint8_t DecoderIndex, int Mute);
+
+
+#endif /* HDFFCMD_AV_H */
diff --git a/libhdffcmd/hdffcmd_base.c b/libhdffcmd/hdffcmd_base.c
new file mode 100644
index 0000000..ac1ab7e
--- /dev/null
+++ b/libhdffcmd/hdffcmd_base.c
@@ -0,0 +1,45 @@
+/**********************************************************************
+ *
+ * HDFF firmware command interface library
+ *
+ * Copyright (C) 2011 Andreas Regel
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *********************************************************************/
+
+#include "hdffcmd_base.h"
+
+void HdffCmdBuildHeader(BitBuffer_t * MsgBuf, HdffMessageType_t MsgType,
+ HdffMessageGroup_t MsgGroup, HdffMessageId_t MsgId)
+{
+ BitBuffer_SetBits(MsgBuf, 16, 0); // length field will be set later
+ BitBuffer_SetBits(MsgBuf, 6, 0); // reserved
+ BitBuffer_SetBits(MsgBuf, 2, MsgType);
+ BitBuffer_SetBits(MsgBuf, 8, MsgGroup);
+ BitBuffer_SetBits(MsgBuf, 16, MsgId);
+}
+
+uint32_t HdffCmdSetLength(BitBuffer_t * MsgBuf)
+{
+ uint32_t length;
+
+ length = BitBuffer_GetByteLength(MsgBuf) - 2;
+ MsgBuf->Data[0] = (uint8_t) (length >> 8);
+ MsgBuf->Data[1] = (uint8_t) length;
+
+ return length + 2;
+}
diff --git a/libhdffcmd/hdffcmd_base.h b/libhdffcmd/hdffcmd_base.h
new file mode 100644
index 0000000..b6856aa
--- /dev/null
+++ b/libhdffcmd/hdffcmd_base.h
@@ -0,0 +1,55 @@
+/**********************************************************************
+ *
+ * HDFF firmware command interface library
+ *
+ * Copyright (C) 2011 Andreas Regel
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *********************************************************************/
+
+#ifndef HDFFCMD_BASE_H
+#define HDFFCMD_BASE_H
+
+#include <linux/dvb/osd.h>
+
+#if !defined OSD_RAW_CMD
+typedef struct osd_raw_cmd_s {
+ const void *cmd_data;
+ int cmd_len;
+ void *result_data;
+ int result_len;
+} osd_raw_cmd_t;
+
+typedef struct osd_raw_data_s {
+ const void *data_buffer;
+ int data_length;
+ int data_handle;
+} osd_raw_data_t;
+
+#define OSD_RAW_CMD _IOWR('o', 162, osd_raw_cmd_t)
+#define OSD_RAW_DATA _IOWR('o', 163, osd_raw_data_t)
+#endif
+
+#include "bitbuffer.h"
+#include "hdffcmd_defs.h"
+
+void HdffCmdBuildHeader(BitBuffer_t * MsgBuf, HdffMessageType_t MsgType,
+ HdffMessageGroup_t MsgGroup, HdffMessageId_t MsgId);
+
+uint32_t HdffCmdSetLength(BitBuffer_t * MsgBuf);
+
+#endif /* HDFFCMD_BASE_H */
diff --git a/libhdffcmd/hdffcmd_defs.h b/libhdffcmd/hdffcmd_defs.h
new file mode 100644
index 0000000..cae2097
--- /dev/null
+++ b/libhdffcmd/hdffcmd_defs.h
@@ -0,0 +1,125 @@
+/**********************************************************************
+ *
+ * HDFF firmware command interface library
+ *
+ * Copyright (C) 2011 Andreas Regel
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *********************************************************************/
+
+#ifndef HDFFCMD_DEFS_H
+#define HDFFCMD_DEFS_H
+
+typedef enum HdffMessageType_t
+{
+ HDFF_MSG_TYPE_COMMAND,
+ HDFF_MSG_TYPE_ANSWER,
+ HDFF_MSG_TYPE_RESULT,
+ HDFF_MSG_TYPE_EVENT
+} HdffMessageType_t;
+
+typedef enum HdffMessageGroup_t
+{
+ HDFF_MSG_GROUP_GENERIC,
+ HDFF_MSG_GROUP_AV_DECODER,
+ HDFF_MSG_GROUP_AV_MUX,
+ HDFF_MSG_GROUP_FRONTEND,
+ HDFF_MSG_GROUP_OSD,
+ HDFF_MSG_GROUP_HDMI,
+ HDFF_MSG_GROUP_REMOTE_CONTROL
+} HdffMessageGroup_t;
+
+typedef enum HdffMessageId_t
+{
+ HDFF_MSG_GEN_GET_FIRMWARE_VERSION = 0,
+ HDFF_MSG_GEN_GET_INTERFACE_VERSION,
+ HDFF_MSG_GEN_GET_COPYRIGHTS,
+
+ HDFF_MSG_AV_SET_AUDIO_PID = 0,
+ HDFF_MSG_AV_SET_VIDEO_PID,
+ HDFF_MSG_AV_SET_PCR_PID,
+ HDFF_MSG_AV_SET_TELETEXT_PID,
+ HDFF_MSG_AV_SHOW_STILL_IMAGE,
+ HDFF_MSG_AV_SET_VIDEO_WINDOW,
+ HDFF_MSG_AV_SET_DECODER_INPUT,
+ HDFF_MSG_AV_SET_DEMULTIPLEXER_INPUT,
+ HDFF_MSG_AV_SET_VIDEO_FORMAT,
+ HDFF_MSG_AV_SET_VIDEO_OUTPUT_MODE,
+ HDFF_MSG_AV_SET_STC,
+ HDFF_MSG_AV_FLUSH_BUFFER,
+ HDFF_MSG_AV_ENABLE_SYNC,
+ HDFF_MSG_AV_SET_VIDEO_SPEED,
+ HDFF_MSG_AV_SET_AUDIO_SPEED,
+ HDFF_MSG_AV_ENABLE_VIDEO_AFTER_STOP,
+ HDFF_MSG_AV_GET_VIDEO_FORMAT_INFO,
+ HDFF_MSG_AV_SET_AUDIO_DELAY,
+ HDFF_MSG_AV_SET_AUDIO_DOWNMIX,
+ HDFF_MSG_AV_SET_AUDIO_CHANNEL,
+ HDFF_MSG_AV_SET_PLAY_MODE,
+ HDFF_MSG_AV_SET_OPTIONS,
+ HDFF_MSG_AV_MUTE_AUDIO,
+ HDFF_MSG_AV_MUTE_VIDEO,
+
+ HDFF_MSG_MUX_SET_VIDEO_OUT = 0,
+ HDFF_MSG_MUX_SET_SLOW_BLANK,
+ HDFF_MSG_MUX_SET_FAST_BLANK,
+ HDFF_MSG_MUX_SET_VOLUME,
+ HDFF_MSG_MUX_SET_AUDIO_MUTE,
+
+ HDFF_MSG_OSD_CONFIGURE = 0,
+ HDFF_MSG_OSD_RESET,
+ HDFF_MSG_OSD_CREATE_DISPLAY = 10,
+ HDFF_MSG_OSD_DELETE_DISPLAY,
+ HDFF_MSG_OSD_ENABLE_DISPLAY,
+ HDFF_MSG_OSD_SET_DISPLAY_OUTPUT_RECTANGLE,
+ HDFF_MSG_OSD_SET_DISPLAY_CLIPPLING_AREA,
+ HDFF_MSG_OSD_RENDER_DISPLAY,
+ HDFF_MSG_OSD_SAVE_REGION,
+ HDFF_MSG_OSD_RESTORE_REGION,
+ HDFF_MSG_OSD_CREATE_PALETTE = 30,
+ HDFF_MSG_OSD_DELETE_PALETTE,
+ HDFF_MSG_OSD_SET_DISPLAY_PALETTE,
+ HDFF_MSG_OSD_SET_PALETTE_COLORS,
+ HDFF_MSG_OSD_CREATE_FONT_FACE = 50,
+ HDFF_MSG_OSD_DELETE_FONT_FACE,
+ HDFF_MSG_OSD_CREATE_FONT,
+ HDFF_MSG_OSD_DELETE_FONT,
+ HDFF_MSG_OSD_DRAW_PIXEL = 70,
+ HDFF_MSG_OSD_DRAW_RECTANGLE,
+ HDFF_MSG_OSD_DRAW_CIRCLE,
+ HDFF_MSG_OSD_DRAW_ELLIPSE,
+ HDFF_MSG_OSD_DRAW_SLOPE,
+ HDFF_MSG_OSD_DRAW_TEXT,
+ HDFF_MSG_OSD_DRAW_WIDE_TEXT,
+ HDFF_MSG_OSD_DRAW_BITMAP,
+ HDFF_MSG_OSD_DRAW_UTF8_TEXT,
+
+ HDFF_MSG_HDMI_ENABLE_OUTPUT = 0,
+ HDFF_MSG_HDMI_SET_VIDEO_MODE,
+ HDFF_MSG_HDMI_CONFIGURE,
+ HDFF_MSG_HDMI_IS_DISPLAY_CONNECTED,
+ HDFF_MSG_HDMI_GET_DISPLAY_INFO,
+ HDFF_MSG_HDMI_GET_VIDEO_MODE,
+ HDFF_MSG_HDMI_SEND_CEC_COMMAND,
+ HDFF_MSG_HDMI_SEND_RAW_CEC_COMMAND,
+
+ HDFF_MSG_REMOTE_SET_PROTOCOL = 0,
+ HDFF_MSG_REMOTE_SET_ADDRESS_FILTER,
+ HDFF_MSG_REMOTE_KEY_EVENT
+} HdffMessageId_t;
+
+#endif /* HDFFCMD_DEFS_H */
diff --git a/libhdffcmd/hdffcmd_generic.c b/libhdffcmd/hdffcmd_generic.c
new file mode 100644
index 0000000..797abe8
--- /dev/null
+++ b/libhdffcmd/hdffcmd_generic.c
@@ -0,0 +1,165 @@
+/**********************************************************************
+ *
+ * HDFF firmware command interface library
+ *
+ * Copyright (C) 2011 Andreas Regel
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *********************************************************************/
+
+#include <errno.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/ioctl.h>
+
+#include "hdffcmd.h"
+#include "hdffcmd_base.h"
+#include "hdffcmd_defs.h"
+
+int HdffCmdGetFirmwareVersion(int OsdDevice, uint32_t * Version, char * String,
+ uint32_t MaxLength)
+{
+ uint8_t cmdData[8];
+ uint8_t resultData[64];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+ int err;
+
+ if (Version == NULL)
+ return -EINVAL;
+
+ *Version = 0;
+ if (String)
+ String[0] = 0;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ osd_cmd.result_data = resultData;
+ osd_cmd.result_len = sizeof(resultData);
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_GENERIC,
+ HDFF_MSG_GEN_GET_FIRMWARE_VERSION);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ err = ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+ if (err == 0)
+ {
+ if (osd_cmd.result_len > 0)
+ {
+ if (String)
+ {
+ uint8_t textLength = resultData[9];
+ if (textLength >= MaxLength)
+ textLength = MaxLength - 1;
+ memcpy(String, &resultData[10], textLength);
+ String[textLength] = 0;
+ }
+ *Version = (resultData[6] << 16)
+ | (resultData[7] << 8)
+ | resultData[8];
+ }
+ }
+ return err;
+}
+
+int HdffCmdGetInterfaceVersion(int OsdDevice, uint32_t * Version, char * String,
+ uint32_t MaxLength)
+{
+ uint8_t cmdData[8];
+ uint8_t resultData[64];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+ int err;
+
+ if (Version == NULL)
+ return -EINVAL;
+
+ *Version = 0;
+ if (String)
+ String[0] = 0;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ osd_cmd.result_data = resultData;
+ osd_cmd.result_len = sizeof(resultData);
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_GENERIC,
+ HDFF_MSG_GEN_GET_INTERFACE_VERSION);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ err = ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+ if (err == 0)
+ {
+ if (osd_cmd.result_len > 0)
+ {
+ if (String)
+ {
+ uint8_t textLength = resultData[9];
+ if (textLength >= MaxLength)
+ textLength = MaxLength - 1;
+ memcpy(String, &resultData[10], textLength);
+ String[textLength] = 0;
+ }
+ *Version = (resultData[6] << 16)
+ | (resultData[7] << 8)
+ | resultData[8];
+ }
+ }
+ return err;
+}
+
+int HdffCmdGetCopyrights(int OsdDevice, uint8_t Index, char * String,
+ uint32_t MaxLength)
+{
+ uint8_t cmdData[8];
+ uint8_t resultData[280];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+ int err;
+
+ if (String == NULL)
+ return -EINVAL;
+
+ String[0] = 0;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ osd_cmd.result_data = resultData;
+ osd_cmd.result_len = sizeof(resultData);
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_GENERIC,
+ HDFF_MSG_GEN_GET_COPYRIGHTS);
+ BitBuffer_SetBits(&cmdBuf, 8, Index);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ err = ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+ if (err == 0)
+ {
+ if (osd_cmd.result_len > 0)
+ {
+ uint8_t index = resultData[6];
+ uint8_t textLen = resultData[7];
+ if (index == Index && textLen > 0)
+ {
+ if (textLen >= MaxLength)
+ {
+ textLen = MaxLength - 1;
+ }
+ memcpy(String, resultData + 8, textLen);
+ String[textLen] = 0;
+ }
+ }
+ }
+ return err;
+}
diff --git a/libhdffcmd/hdffcmd_generic.h b/libhdffcmd/hdffcmd_generic.h
new file mode 100644
index 0000000..c12b296
--- /dev/null
+++ b/libhdffcmd/hdffcmd_generic.h
@@ -0,0 +1,36 @@
+/**********************************************************************
+ *
+ * HDFF firmware command interface library
+ *
+ * Copyright (C) 2011 Andreas Regel
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *********************************************************************/
+
+#ifndef HDFFCMD_GENERIC_H
+#define HDFFCMD_GENERIC_H
+
+int HdffCmdGetFirmwareVersion(int OsdDevice, uint32_t * Version, char * String,
+ uint32_t MaxLength);
+
+int HdffCmdGetInterfaceVersion(int OsdDevice, uint32_t * Version, char * String,
+ uint32_t MaxLength);
+
+int HdffCmdGetCopyrights(int OsdDevice, uint8_t Index, char * String,
+ uint32_t MaxLength);
+
+#endif /* HDFFCMD_GENERIC_H */
diff --git a/libhdffcmd/hdffcmd_hdmi.c b/libhdffcmd/hdffcmd_hdmi.c
new file mode 100644
index 0000000..de315f8
--- /dev/null
+++ b/libhdffcmd/hdffcmd_hdmi.c
@@ -0,0 +1,120 @@
+/**********************************************************************
+ *
+ * HDFF firmware command interface library
+ *
+ * Copyright (C) 2011 Andreas Regel
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *********************************************************************/
+
+#include <stdint.h>
+#include <string.h>
+#include <sys/ioctl.h>
+
+#include "hdffcmd.h"
+#include "hdffcmd_base.h"
+#include "hdffcmd_defs.h"
+
+
+int HdffCmdHdmiSetVideoMode(int OsdDevice, HdffVideoMode_t VideoMode)
+{
+ uint8_t cmdData[8];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_HDMI,
+ HDFF_MSG_HDMI_SET_VIDEO_MODE);
+ BitBuffer_SetBits(&cmdBuf, 8, VideoMode);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdHdmiConfigure(int OsdDevice, const HdffHdmiConfig_t * Config)
+{
+ uint8_t cmdData[24];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+ size_t nameLen;
+ int i;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_HDMI,
+ HDFF_MSG_HDMI_CONFIGURE);
+ BitBuffer_SetBits(&cmdBuf, 1, Config->TransmitAudio ? 1 : 0);
+ BitBuffer_SetBits(&cmdBuf, 1, Config->ForceDviMode ? 1 : 0);
+ BitBuffer_SetBits(&cmdBuf, 1, Config->CecEnabled ? 1 : 0);
+ BitBuffer_SetBits(&cmdBuf, 3, Config->VideoModeAdaption);
+ BitBuffer_SetBits(&cmdBuf, 6, 0); // reserved
+ nameLen = strlen(Config->CecDeviceName);
+ if (nameLen > 13)
+ nameLen = 13;
+ BitBuffer_SetBits(&cmdBuf, 4, nameLen);
+ for (i = 0; i < nameLen; i++)
+ BitBuffer_SetBits(&cmdBuf, 8, Config->CecDeviceName[i]);
+
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdHdmiSendCecCommand(int OsdDevice, HdffCecCommand_t Command)
+{
+ uint8_t cmdData[8];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_HDMI,
+ HDFF_MSG_HDMI_SEND_CEC_COMMAND);
+ BitBuffer_SetBits(&cmdBuf, 8, Command);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdHdmiSendRawCecCommand(int OsdDevice, uint8_t Destination,
+ uint8_t Opcode, const uint8_t * Operand,
+ uint8_t OperandLength)
+{
+ uint8_t cmdData[24];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+ int i;
+
+ if (OperandLength > 14)
+ OperandLength = 14;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_HDMI,
+ HDFF_MSG_HDMI_SEND_RAW_CEC_COMMAND);
+ BitBuffer_SetBits(&cmdBuf, 4, 0); // reserved
+ BitBuffer_SetBits(&cmdBuf, 4, Destination);
+ BitBuffer_SetBits(&cmdBuf, 8, Opcode);
+ BitBuffer_SetBits(&cmdBuf, 8, OperandLength);
+ for (i = 0; i < OperandLength; i++)
+ BitBuffer_SetBits(&cmdBuf, 8, Operand[i]);
+
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
diff --git a/libhdffcmd/hdffcmd_hdmi.h b/libhdffcmd/hdffcmd_hdmi.h
new file mode 100644
index 0000000..fc79bd9
--- /dev/null
+++ b/libhdffcmd/hdffcmd_hdmi.h
@@ -0,0 +1,72 @@
+/**********************************************************************
+ *
+ * HDFF firmware command interface library
+ *
+ * Copyright (C) 2011 Andreas Regel
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *********************************************************************/
+
+#ifndef HDFFCMD_HDMI_H
+#define HDFFCMD_HDMI_H
+
+
+typedef enum HdffVideoMode_t
+{
+ HDFF_VIDEO_MODE_576P50 = 18,
+ HDFF_VIDEO_MODE_720P50 = 19,
+ HDFF_VIDEO_MODE_1080I50 = 20,
+ HDFF_VIDEO_MODE_576I50 = 22
+} HdffVideoMode_t;
+
+typedef enum HdffVideoModeAdaption_t
+{
+ HDFF_VIDEO_MODE_ADAPT_OFF,
+ HDFF_VIDEO_MODE_ADAPT_FRAME_RATE,
+ HDFF_VIDEO_MODE_ADAPT_ONLY_FOR_HD,
+ HDFF_VIDEO_MODE_ADAPT_ALWAYS
+} HdffVideoModeAdaption_t;
+
+typedef struct HdffHdmiConfig_t
+{
+ int TransmitAudio;
+ int ForceDviMode;
+ int CecEnabled;
+ HdffVideoModeAdaption_t VideoModeAdaption;
+ char CecDeviceName[14];
+} HdffHdmiConfig_t;
+
+typedef enum HdffCecCommand_t
+{
+ HDFF_CEC_COMMAND_TV_ON,
+ HDFF_CEC_COMMAND_TV_OFF,
+ HDFF_CEC_COMMAND_ACTIVE_SOURCE,
+ HDFF_CEC_COMMAND_INACTIVE_SOURCE
+} HdffCecCommand_t;
+
+
+int HdffCmdHdmiSetVideoMode(int OsdDevice, HdffVideoMode_t VideoMode);
+
+int HdffCmdHdmiConfigure(int OsdDevice, const HdffHdmiConfig_t * Config);
+
+int HdffCmdHdmiSendCecCommand(int OsdDevice, HdffCecCommand_t Command);
+
+int HdffCmdHdmiSendRawCecCommand(int OsdDevice, uint8_t Destination,
+ uint8_t Opcode, const uint8_t * Operand,
+ uint8_t OperandLength);
+
+#endif /* HDFFCMD_HDMI_H */
diff --git a/libhdffcmd/hdffcmd_mux.c b/libhdffcmd/hdffcmd_mux.c
new file mode 100644
index 0000000..3698b56
--- /dev/null
+++ b/libhdffcmd/hdffcmd_mux.c
@@ -0,0 +1,81 @@
+/**********************************************************************
+ *
+ * HDFF firmware command interface library
+ *
+ * Copyright (C) 2011 Andreas Regel
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *********************************************************************/
+
+#include <stdint.h>
+#include <string.h>
+#include <sys/ioctl.h>
+
+#include "hdffcmd.h"
+#include "hdffcmd_base.h"
+#include "hdffcmd_defs.h"
+
+
+int HdffCmdMuxSetVideoOut(int OsdDevice, HdffVideoOut_t VideoOut)
+{
+ uint8_t cmdData[8];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_AV_MUX,
+ HDFF_MSG_MUX_SET_VIDEO_OUT);
+ BitBuffer_SetBits(&cmdBuf, 4, VideoOut);
+ BitBuffer_SetBits(&cmdBuf, 4, 0); // reserved
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdMuxSetVolume(int OsdDevice, uint8_t Volume)
+{
+ uint8_t cmdData[8];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_AV_MUX,
+ HDFF_MSG_MUX_SET_VOLUME);
+ BitBuffer_SetBits(&cmdBuf, 8, Volume);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdMuxMuteAudio(int OsdDevice, int Mute)
+{
+ uint8_t cmdData[8];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_AV_MUX,
+ HDFF_MSG_MUX_SET_AUDIO_MUTE);
+ BitBuffer_SetBits(&cmdBuf, 1, Mute);
+ BitBuffer_SetBits(&cmdBuf, 7, 0); // reserved
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
diff --git a/libhdffcmd/hdffcmd_mux.h b/libhdffcmd/hdffcmd_mux.h
new file mode 100644
index 0000000..8821d5f
--- /dev/null
+++ b/libhdffcmd/hdffcmd_mux.h
@@ -0,0 +1,56 @@
+/**********************************************************************
+ *
+ * HDFF firmware command interface library
+ *
+ * Copyright (C) 2011 Andreas Regel
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *********************************************************************/
+
+#ifndef HDFFCMD_MUX_H
+#define HDFFCMD_MUX_H
+
+
+typedef enum HdffVideoOut_t
+{
+ HDFF_VIDEO_OUT_DISABLED,
+ HDFF_VIDEO_OUT_CVBS_RGB,
+ HDFF_VIDEO_OUT_CVBS_YUV,
+ HDFF_VIDEO_OUT_YC
+} HdffVideoOut_t;
+
+typedef enum HdffSlowBlank_t
+{
+ HDFF_SLOW_BLANK_OFF,
+ HDFF_SLOW_BLANK_16_BY_9,
+ HDFF_SLOW_BLANK_4_BY_3
+} HdffSlowBlank_t;
+
+typedef enum HdffFastBlank_t
+{
+ HDFF_FAST_BLANK_CVBS,
+ HDFF_FAST_BLANK_RGB
+} HdffFastBlank_t;
+
+
+int HdffCmdMuxSetVideoOut(int OsdDevice, HdffVideoOut_t VideoOut);
+
+int HdffCmdMuxSetVolume(int OsdDevice, uint8_t Volume);
+
+int HdffCmdMuxMuteAudio(int OsdDevice, int Mute);
+
+#endif /* HDFFCMD_MUX_H */
diff --git a/libhdffcmd/hdffcmd_osd.c b/libhdffcmd/hdffcmd_osd.c
new file mode 100644
index 0000000..cf714a8
--- /dev/null
+++ b/libhdffcmd/hdffcmd_osd.c
@@ -0,0 +1,720 @@
+/**********************************************************************
+ *
+ * HDFF firmware command interface library
+ *
+ * Copyright (C) 2011 Andreas Regel
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *********************************************************************/
+
+#include <stdint.h>
+#include <string.h>
+#include <sys/ioctl.h>
+
+#include "hdffcmd.h"
+#include "hdffcmd_base.h"
+#include "hdffcmd_defs.h"
+
+
+int HdffCmdOsdConfigure(int OsdDevice, const HdffOsdConfig_t * Config)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD,
+ HDFF_MSG_OSD_CONFIGURE);
+ if (Config->FontAntialiasing)
+ {
+ BitBuffer_SetBits(&cmdBuf, 1, 1);
+ }
+ else
+ {
+ BitBuffer_SetBits(&cmdBuf, 1, 0);
+ }
+ if (Config->FontKerning)
+ {
+ BitBuffer_SetBits(&cmdBuf, 1, 1);
+ }
+ else
+ {
+ BitBuffer_SetBits(&cmdBuf, 1, 0);
+ }
+ BitBuffer_SetBits(&cmdBuf, 6, 0); // reserved
+ BitBuffer_SetBits(&cmdBuf, 16, Config->FontDpi);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdOsdReset(int OsdDevice)
+{
+ uint8_t cmdData[8];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD,
+ HDFF_MSG_OSD_RESET);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+
+int HdffCmdOsdCreateDisplay(int OsdDevice, uint16_t Width, uint16_t Height,
+ HdffColorType_t ColorType, uint32_t * NewDisplay)
+{
+ uint8_t cmdData[16];
+ uint8_t resultData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+ int err;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ osd_cmd.result_data = resultData;
+ osd_cmd.result_len = sizeof(resultData);
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD,
+ HDFF_MSG_OSD_CREATE_DISPLAY);
+ BitBuffer_SetBits(&cmdBuf, 16, Width);
+ BitBuffer_SetBits(&cmdBuf, 16, Height);
+ BitBuffer_SetBits(&cmdBuf, 8, ColorType);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ err = ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+ *NewDisplay = HDFF_INVALID_HANDLE;
+ if (err == 0)
+ {
+ if (osd_cmd.result_len > 0)
+ {
+ if (resultData[2] == HDFF_MSG_TYPE_ANSWER)
+ {
+ *NewDisplay = (resultData[6] << 24)
+ | (resultData[7] << 16)
+ | (resultData[8] << 8)
+ | resultData[9];
+ }
+ else
+ err = -1;
+ }
+ }
+ return err;
+}
+
+int HdffCmdOsdDeleteDisplay(int OsdDevice, uint32_t Display)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD,
+ HDFF_MSG_OSD_DELETE_DISPLAY);
+ BitBuffer_SetBits(&cmdBuf, 32, Display);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdOsdEnableDisplay(int OsdDevice, uint32_t Display, int Enable)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD,
+ HDFF_MSG_OSD_ENABLE_DISPLAY);
+ BitBuffer_SetBits(&cmdBuf, 32, Display);
+ if (Enable)
+ {
+ BitBuffer_SetBits(&cmdBuf, 1, 1);
+ }
+ else
+ {
+ BitBuffer_SetBits(&cmdBuf, 1, 0);
+ }
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdOsdSetDisplayOutputRectangle(int OsdDevice, uint32_t Display,
+ uint16_t X, uint16_t Y,
+ uint16_t Width, uint16_t Height)
+{
+ uint8_t cmdData[20];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD,
+ HDFF_MSG_OSD_SET_DISPLAY_OUTPUT_RECTANGLE);
+ BitBuffer_SetBits(&cmdBuf, 32, Display);
+ BitBuffer_SetBits(&cmdBuf, 16, X);
+ BitBuffer_SetBits(&cmdBuf, 16, Y);
+ BitBuffer_SetBits(&cmdBuf, 16, Width);
+ BitBuffer_SetBits(&cmdBuf, 16, Height);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdOsdSetDisplayClippingArea(int OsdDevice, uint32_t Display,
+ int Enable, uint16_t X, uint16_t Y,
+ uint16_t Width, uint16_t Height)
+{
+ uint8_t cmdData[20];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD,
+ HDFF_MSG_OSD_SET_DISPLAY_CLIPPLING_AREA);
+ BitBuffer_SetBits(&cmdBuf, 32, Display);
+ if (Enable)
+ {
+ BitBuffer_SetBits(&cmdBuf, 1, 1);
+ }
+ else
+ {
+ BitBuffer_SetBits(&cmdBuf, 1, 0);
+ }
+ BitBuffer_SetBits(&cmdBuf, 7, 0); // reserved
+ BitBuffer_SetBits(&cmdBuf, 16, X);
+ BitBuffer_SetBits(&cmdBuf, 16, Y);
+ BitBuffer_SetBits(&cmdBuf, 16, Width);
+ BitBuffer_SetBits(&cmdBuf, 16, Height);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdOsdRenderDisplay(int OsdDevice, uint32_t Display)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD,
+ HDFF_MSG_OSD_RENDER_DISPLAY);
+ BitBuffer_SetBits(&cmdBuf, 32, Display);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdOsdSaveRegion(int OsdDevice, uint32_t Display,
+ uint16_t X, uint16_t Y,
+ uint16_t Width, uint16_t Height)
+{
+ uint8_t cmdData[20];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD,
+ HDFF_MSG_OSD_SAVE_REGION);
+ BitBuffer_SetBits(&cmdBuf, 32, Display);
+ BitBuffer_SetBits(&cmdBuf, 16, X);
+ BitBuffer_SetBits(&cmdBuf, 16, Y);
+ BitBuffer_SetBits(&cmdBuf, 16, Width);
+ BitBuffer_SetBits(&cmdBuf, 16, Height);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdOsdRestoreRegion(int OsdDevice, uint32_t Display)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD,
+ HDFF_MSG_OSD_RESTORE_REGION);
+ BitBuffer_SetBits(&cmdBuf, 32, Display);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+
+int HdffCmdOsdCreatePalette(int OsdDevice, HdffColorType_t ColorType,
+ HdffColorFormat_t ColorFormat,
+ uint32_t NumColors, const uint32_t * Colors,
+ uint32_t * NewPalette)
+{
+ uint8_t cmdData[1060];
+ uint8_t resultData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+ int i;
+ int err;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ osd_cmd.result_data = resultData;
+ osd_cmd.result_len = sizeof(resultData);
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD,
+ HDFF_MSG_OSD_CREATE_PALETTE);
+ BitBuffer_SetBits(&cmdBuf, 8, ColorType);
+ BitBuffer_SetBits(&cmdBuf, 8, ColorFormat);
+ if (NumColors > 256)
+ NumColors = 256;
+ BitBuffer_SetBits(&cmdBuf, 8, NumColors == 256 ? 0 : NumColors);
+ for (i = 0; i < NumColors; i++)
+ {
+ BitBuffer_SetBits(&cmdBuf, 32, Colors[i]);
+ }
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ err = ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+ *NewPalette = HDFF_INVALID_HANDLE;
+ if (err == 0)
+ {
+ if (osd_cmd.result_len > 0)
+ {
+ if (resultData[2] == HDFF_MSG_TYPE_ANSWER)
+ {
+ *NewPalette = (resultData[6] << 24)
+ | (resultData[7] << 16)
+ | (resultData[8] << 8)
+ | resultData[9];
+ }
+ else
+ err = -1;
+ }
+ }
+ return err;
+}
+
+int HdffCmdOsdDeletePalette(int OsdDevice, uint32_t Palette)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD,
+ HDFF_MSG_OSD_DELETE_PALETTE);
+ BitBuffer_SetBits(&cmdBuf, 32, Palette);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdOsdSetDisplayPalette(int OsdDevice, uint32_t Display,
+ uint32_t Palette)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD,
+ HDFF_MSG_OSD_SET_DISPLAY_PALETTE);
+ BitBuffer_SetBits(&cmdBuf, 32, Display);
+ BitBuffer_SetBits(&cmdBuf, 32, Palette);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdOsdSetPaletteColors(int OsdDevice, uint32_t Palette,
+ HdffColorFormat_t ColorFormat,
+ uint8_t StartColor, uint32_t NumColors,
+ const uint32_t * Colors)
+{
+ uint8_t cmdData[1060];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+ int i;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD,
+ HDFF_MSG_OSD_SET_PALETTE_COLORS);
+ BitBuffer_SetBits(&cmdBuf, 32, Palette);
+ BitBuffer_SetBits(&cmdBuf, 8, ColorFormat);
+ BitBuffer_SetBits(&cmdBuf, 8, StartColor);
+ if (NumColors > 256)
+ NumColors = 256;
+ BitBuffer_SetBits(&cmdBuf, 8, NumColors == 256 ? 0 : NumColors);
+ for (i = 0; i < NumColors; i++)
+ {
+ BitBuffer_SetBits(&cmdBuf, 32, Colors[i]);
+ }
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdOsdCreateFontFace(int OsdDevice, const uint8_t * FontData,
+ uint32_t DataSize, uint32_t * NewFontFace)
+{
+ uint8_t cmdData[16];
+ uint8_t resultData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+ osd_raw_data_t osd_data;
+ int err;
+
+ *NewFontFace = HDFF_INVALID_HANDLE;
+
+ memset(&osd_data, 0, sizeof(osd_raw_data_t));
+ osd_data.data_buffer = FontData;
+ osd_data.data_length = DataSize;
+ err = ioctl(OsdDevice, OSD_RAW_DATA, &osd_data);
+ if (err != 0)
+ return err;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ osd_cmd.result_data = resultData;
+ osd_cmd.result_len = sizeof(resultData);
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD,
+ HDFF_MSG_OSD_CREATE_FONT_FACE);
+ BitBuffer_SetBits(&cmdBuf, 16, osd_data.data_handle);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ err = ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+ if (err == 0)
+ {
+ if (osd_cmd.result_len > 0)
+ {
+ if (resultData[2] == HDFF_MSG_TYPE_ANSWER)
+ {
+ *NewFontFace = (resultData[6] << 24)
+ | (resultData[7] << 16)
+ | (resultData[8] << 8)
+ | resultData[9];
+ }
+ else
+ err = -1;
+ }
+ }
+ return err;
+}
+
+int HdffCmdOsdDeleteFontFace(int OsdDevice, uint32_t FontFace)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD,
+ HDFF_MSG_OSD_DELETE_FONT_FACE);
+ BitBuffer_SetBits(&cmdBuf, 32, FontFace);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdOsdCreateFont(int OsdDevice, uint32_t FontFace, uint32_t Size,
+ uint32_t * NewFont)
+{
+ uint8_t cmdData[16];
+ uint8_t resultData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+ int err;
+
+ *NewFont = HDFF_INVALID_HANDLE;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ osd_cmd.result_data = resultData;
+ osd_cmd.result_len = sizeof(resultData);
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD,
+ HDFF_MSG_OSD_CREATE_FONT);
+ BitBuffer_SetBits(&cmdBuf, 32, FontFace);
+ BitBuffer_SetBits(&cmdBuf, 32, Size);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ err = ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+ if (err == 0)
+ {
+ if (osd_cmd.result_len > 0)
+ {
+ if (resultData[2] == HDFF_MSG_TYPE_ANSWER)
+ {
+ *NewFont = (resultData[6] << 24)
+ | (resultData[7] << 16)
+ | (resultData[8] << 8)
+ | resultData[9];
+ }
+ else
+ err = -1;
+ }
+ }
+ return err;
+}
+
+int HdffCmdOsdDeleteFont(int OsdDevice, uint32_t Font)
+{
+ uint8_t cmdData[16];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD,
+ HDFF_MSG_OSD_DELETE_FONT);
+ BitBuffer_SetBits(&cmdBuf, 32, Font);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+
+int HdffCmdOsdDrawRectangle(int OsdDevice, uint32_t Display, uint16_t X,
+ uint16_t Y, uint16_t Width, uint16_t Height,
+ uint32_t Color)
+{
+ uint8_t cmdData[24];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD,
+ HDFF_MSG_OSD_DRAW_RECTANGLE);
+ BitBuffer_SetBits(&cmdBuf, 32, Display);
+ BitBuffer_SetBits(&cmdBuf, 16, X);
+ BitBuffer_SetBits(&cmdBuf, 16, Y);
+ BitBuffer_SetBits(&cmdBuf, 16, Width);
+ BitBuffer_SetBits(&cmdBuf, 16, Height);
+ BitBuffer_SetBits(&cmdBuf, 32, Color);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdOsdDrawEllipse(int OsdDevice, uint32_t Display, uint16_t CX,
+ uint16_t CY, uint16_t RadiusX, uint16_t RadiusY,
+ uint32_t Color, uint32_t Flags)
+{
+ uint8_t cmdData[28];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD,
+ HDFF_MSG_OSD_DRAW_ELLIPSE);
+ BitBuffer_SetBits(&cmdBuf, 32, Display);
+ BitBuffer_SetBits(&cmdBuf, 16, CX);
+ BitBuffer_SetBits(&cmdBuf, 16, CY);
+ BitBuffer_SetBits(&cmdBuf, 16, RadiusX);
+ BitBuffer_SetBits(&cmdBuf, 16, RadiusY);
+ BitBuffer_SetBits(&cmdBuf, 32, Color);
+ BitBuffer_SetBits(&cmdBuf, 32, Flags);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdOsdDrawSlope(int OsdDevice, uint32_t Display, uint16_t X,
+ uint16_t Y, uint16_t Width, uint16_t Height,
+ uint32_t Color, uint32_t Type)
+{
+ uint8_t cmdData[28];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD,
+ HDFF_MSG_OSD_DRAW_SLOPE);
+ BitBuffer_SetBits(&cmdBuf, 32, Display);
+ BitBuffer_SetBits(&cmdBuf, 16, X);
+ BitBuffer_SetBits(&cmdBuf, 16, Y);
+ BitBuffer_SetBits(&cmdBuf, 16, Width);
+ BitBuffer_SetBits(&cmdBuf, 16, Height);
+ BitBuffer_SetBits(&cmdBuf, 32, Color);
+ BitBuffer_SetBits(&cmdBuf, 32, Type);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdOsdDrawText(int OsdDevice, uint32_t Display, uint32_t Font,
+ uint16_t X, uint16_t Y, const char * Text,
+ uint32_t Color)
+{
+ uint8_t cmdData[1060];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+ int i;
+ int length;
+
+ length = 0;
+ while (Text[length])
+ {
+ length++;
+ }
+ if (length > 980)
+ length = 980;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD,
+ HDFF_MSG_OSD_DRAW_TEXT);
+ BitBuffer_SetBits(&cmdBuf, 32, Display);
+ BitBuffer_SetBits(&cmdBuf, 32, Font);
+ BitBuffer_SetBits(&cmdBuf, 16, X);
+ BitBuffer_SetBits(&cmdBuf, 16, Y);
+ BitBuffer_SetBits(&cmdBuf, 32, Color);
+ BitBuffer_SetBits(&cmdBuf, 16, length);
+ for (i = 0; i < length; i++)
+ {
+ BitBuffer_SetBits(&cmdBuf, 8, Text[i]);
+ }
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdOsdDrawUtf8Text(int OsdDevice, uint32_t Display, uint32_t Font,
+ uint16_t X, uint16_t Y, const char * Text,
+ uint32_t Color)
+{
+ uint8_t cmdData[1060];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+ int i;
+ int length;
+
+ length = 0;
+ while (Text[length])
+ {
+ length++;
+ }
+ if (length > 980)
+ length = 980;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD,
+ HDFF_MSG_OSD_DRAW_UTF8_TEXT);
+ BitBuffer_SetBits(&cmdBuf, 32, Display);
+ BitBuffer_SetBits(&cmdBuf, 32, Font);
+ BitBuffer_SetBits(&cmdBuf, 16, X);
+ BitBuffer_SetBits(&cmdBuf, 16, Y);
+ BitBuffer_SetBits(&cmdBuf, 32, Color);
+ BitBuffer_SetBits(&cmdBuf, 16, length);
+ for (i = 0; i < length; i++)
+ {
+ BitBuffer_SetBits(&cmdBuf, 8, Text[i]);
+ }
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdOsdDrawWideText(int OsdDevice, uint32_t Display, uint32_t Font,
+ uint16_t X, uint16_t Y, const uint16_t * Text,
+ uint32_t Color)
+{
+ uint8_t cmdData[1060];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+ int i;
+ int length;
+
+ length = 0;
+ while (Text[length])
+ {
+ length++;
+ }
+ if (length > 480)
+ length = 480;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD,
+ HDFF_MSG_OSD_DRAW_WIDE_TEXT);
+ BitBuffer_SetBits(&cmdBuf, 32, Display);
+ BitBuffer_SetBits(&cmdBuf, 32, Font);
+ BitBuffer_SetBits(&cmdBuf, 16, X);
+ BitBuffer_SetBits(&cmdBuf, 16, Y);
+ BitBuffer_SetBits(&cmdBuf, 32, Color);
+ BitBuffer_SetBits(&cmdBuf, 16, length);
+ for (i = 0; i < length; i++)
+ {
+ BitBuffer_SetBits(&cmdBuf, 16, Text[i]);
+ }
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdOsdDrawBitmap(int OsdDevice, uint32_t Display, uint16_t X,
+ uint16_t Y, const uint8_t * Bitmap, uint16_t BmpWidth,
+ uint16_t BmpHeight, uint32_t BmpSize,
+ HdffColorType_t ColorType, uint32_t Palette)
+{
+ uint8_t cmdData[32];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+ osd_raw_data_t osd_data;
+ int err;
+
+ memset(&osd_data, 0, sizeof(osd_raw_data_t));
+ osd_data.data_buffer = Bitmap;
+ osd_data.data_length = BmpSize;
+ err = ioctl(OsdDevice, OSD_RAW_DATA, &osd_data);
+ if (err != 0)
+ return err;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD,
+ HDFF_MSG_OSD_DRAW_BITMAP);
+ BitBuffer_SetBits(&cmdBuf, 32, Display);
+ BitBuffer_SetBits(&cmdBuf, 16, X);
+ BitBuffer_SetBits(&cmdBuf, 16, Y);
+ BitBuffer_SetBits(&cmdBuf, 16, BmpWidth);
+ BitBuffer_SetBits(&cmdBuf, 16, BmpHeight);
+ BitBuffer_SetBits(&cmdBuf, 8, ColorType);
+ BitBuffer_SetBits(&cmdBuf, 6, 0); // reserved
+ BitBuffer_SetBits(&cmdBuf, 2, 0); // uncompressed
+ BitBuffer_SetBits(&cmdBuf, 32, Palette);
+ BitBuffer_SetBits(&cmdBuf, 16, osd_data.data_handle);
+ BitBuffer_SetBits(&cmdBuf, 32, 0);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
diff --git a/libhdffcmd/hdffcmd_osd.h b/libhdffcmd/hdffcmd_osd.h
new file mode 100644
index 0000000..079b754
--- /dev/null
+++ b/libhdffcmd/hdffcmd_osd.h
@@ -0,0 +1,170 @@
+/**********************************************************************
+ *
+ * HDFF firmware command interface library
+ *
+ * Copyright (C) 2011 Andreas Regel
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *********************************************************************/
+
+#ifndef HDFFCMD_OSD_H
+#define HDFFCMD_OSD_H
+
+
+#define HDFF_INVALID_HANDLE 0xFFFFFFFF
+#define HDFF_SCREEN_DISPLAY_HANDLE 0xFFFFFFFE
+
+#define HDFF_POSITION_SCREEN_CENTERED 0xFFFF
+
+#define HDFF_SIZE_FULL_SCREEN 0xFFFF
+#define HDFF_SIZE_SAME_AS_SOURCE 0xFFFE
+
+#define HDFF_FONT_FACE_TIRESIAS 0x00000000
+
+
+typedef struct HdffOsdConfig_t
+{
+ int FontAntialiasing;
+ int FontKerning;
+ uint16_t FontDpi;
+} HdffOsdConfig_t;
+
+typedef enum HdffColorType_t
+{
+ HDFF_COLOR_TYPE_CLUT1,
+ HDFF_COLOR_TYPE_CLUT2,
+ HDFF_COLOR_TYPE_CLUT4,
+ HDFF_COLOR_TYPE_CLUT8,
+ HDFF_COLOR_TYPE_ARGB8888,
+ HDFF_COLOR_TYPE_ARGB8565,
+ HDFF_COLOR_TYPE_ARGB4444,
+ HDFF_COLOR_TYPE_ARGB1555,
+ HDFF_COLOR_TYPE_RGB888,
+ HDFF_COLOR_TYPE_RGB565
+} HdffColorType_t;
+
+typedef enum HdffColorFormat_t
+{
+ HDFF_COLOR_FORMAT_ARGB,
+ HDFF_COLOR_FORMAT_ACBYCR
+} HdffColorFormat_t;
+
+typedef enum HdffDrawingFlags_t
+{
+ HDFF_DRAW_FULL,
+ HDFF_DRAW_HALF_TOP,
+ HDFF_DRAW_HALF_LEFT,
+ HDFF_DRAW_HALF_BOTTOM,
+ HDFF_DRAW_HALF_RIGHT,
+ HDFF_DRAW_QUARTER_TOP_LEFT,
+ HDFF_DRAW_QUARTER_TOP_RIGHT,
+ HDFF_DRAW_QUARTER_BOTTOM_LEFT,
+ HDFF_DRAW_QUARTER_BOTTOM_RIGHT,
+ HDFF_DRAW_QUARTER_TOP_LEFT_INVERTED,
+ HDFF_DRAW_QUARTER_TOP_RIGHT_INVERTED,
+ HDFF_DRAW_QUARTER_BOTTOM_LEFT_INVERTED,
+ HDFF_DRAW_QUARTER_BOTTOM_RIGHT_INVERTED
+} HdffDrawingFlags_t;
+
+
+int HdffCmdOsdConfigure(int OsdDevice, const HdffOsdConfig_t * Config);
+
+int HdffCmdOsdReset(int OsdDevice);
+
+
+int HdffCmdOsdCreateDisplay(int OsdDevice, uint16_t Width, uint16_t Height,
+ HdffColorType_t ColorType, uint32_t * NewDisplay);
+
+int HdffCmdOsdDeleteDisplay(int OsdDevice, uint32_t Display);
+
+int HdffCmdOsdEnableDisplay(int OsdDevice, uint32_t Display, int Enable);
+
+int HdffCmdOsdSetDisplayOutputRectangle(int OsdDevice, uint32_t Display,
+ uint16_t X, uint16_t Y,
+ uint16_t Width, uint16_t Height);
+
+int HdffCmdOsdSetDisplayClippingArea(int OsdDevice, uint32_t Display,
+ int Enable, uint16_t X, uint16_t Y,
+ uint16_t Width, uint16_t Height);
+
+int HdffCmdOsdRenderDisplay(int OsdDevice, uint32_t Display);
+
+int HdffCmdOsdSaveRegion(int OsdDevice, uint32_t Display,
+ uint16_t X, uint16_t Y,
+ uint16_t Width, uint16_t Height);
+
+int HdffCmdOsdRestoreRegion(int OsdDevice, uint32_t Display);
+
+
+int HdffCmdOsdCreatePalette(int OsdDevice, HdffColorType_t ColorType,
+ HdffColorFormat_t ColorFormat,
+ uint32_t NumColors, const uint32_t * Colors,
+ uint32_t * NewPalette);
+
+int HdffCmdOsdDeletePalette(int OsdDevice, uint32_t Palette);
+
+int HdffCmdOsdSetDisplayPalette(int OsdDevice, uint32_t Display,
+ uint32_t Palette);
+
+int HdffCmdOsdSetPaletteColors(int OsdDevice, uint32_t Palette,
+ HdffColorFormat_t ColorFormat,
+ uint8_t StartColor, uint32_t NumColors,
+ const uint32_t * Colors);
+
+
+int HdffCmdOsdCreateFontFace(int OsdDevice, const uint8_t * FontData,
+ uint32_t DataSize, uint32_t * NewFontFace);
+
+int HdffCmdOsdDeleteFontFace(int OsdDevice, uint32_t FontFace);
+
+int HdffCmdOsdCreateFont(int OsdDevice, uint32_t FontFace, uint32_t Size,
+ uint32_t * NewFont);
+
+int HdffCmdOsdDeleteFont(int OsdDevice, uint32_t Font);
+
+
+int HdffCmdOsdDrawRectangle(int OsdDevice, uint32_t Display, uint16_t X,
+ uint16_t Y, uint16_t Width, uint16_t Height,
+ uint32_t Color);
+
+int HdffCmdOsdDrawEllipse(int OsdDevice, uint32_t Display, uint16_t CX,
+ uint16_t CY, uint16_t RadiusX, uint16_t RadiusY,
+ uint32_t Color, uint32_t Flags);
+
+int HdffCmdOsdDrawSlope(int OsdDevice, uint32_t Display, uint16_t X,
+ uint16_t Y, uint16_t Width, uint16_t Height,
+ uint32_t Color, uint32_t Type);
+
+int HdffCmdOsdDrawText(int OsdDevice, uint32_t Display, uint32_t Font,
+ uint16_t X, uint16_t Y, const char * Text,
+ uint32_t Color);
+
+int HdffCmdOsdDrawUtf8Text(int OsdDevice, uint32_t Display, uint32_t Font,
+ uint16_t X, uint16_t Y, const char * Text,
+ uint32_t Color);
+
+int HdffCmdOsdDrawWideText(int OsdDevice, uint32_t Display, uint32_t Font,
+ uint16_t X, uint16_t Y, const uint16_t * Text,
+ uint32_t Color);
+
+int HdffCmdOsdDrawBitmap(int OsdDevice, uint32_t Display, uint16_t X,
+ uint16_t Y, const uint8_t * Bitmap, uint16_t BmpWidth,
+ uint16_t BmpHeight, uint32_t BmpSize,
+ HdffColorType_t ColorType, uint32_t Palette);
+
+
+#endif /* HDFFCMD_OSD_H */
diff --git a/libhdffcmd/hdffcmd_remote.c b/libhdffcmd/hdffcmd_remote.c
new file mode 100644
index 0000000..d9bbe45
--- /dev/null
+++ b/libhdffcmd/hdffcmd_remote.c
@@ -0,0 +1,67 @@
+/**********************************************************************
+ *
+ * HDFF firmware command interface library
+ *
+ * Copyright (C) 2011 Andreas Regel
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *********************************************************************/
+
+#include <stdint.h>
+#include <string.h>
+#include <sys/ioctl.h>
+
+#include "hdffcmd.h"
+#include "hdffcmd_base.h"
+#include "hdffcmd_defs.h"
+
+
+int HdffCmdRemoteSetProtocol(int OsdDevice, HdffRemoteProtocol_t Protocol)
+{
+ uint8_t cmdData[8];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND,
+ HDFF_MSG_GROUP_REMOTE_CONTROL,
+ HDFF_MSG_REMOTE_SET_PROTOCOL);
+ BitBuffer_SetBits(&cmdBuf, 8, Protocol);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
+
+int HdffCmdRemoteSetAddressFilter(int OsdDevice, int Enable, uint32_t Address)
+{
+ uint8_t cmdData[12];
+ BitBuffer_t cmdBuf;
+ osd_raw_cmd_t osd_cmd;
+
+ BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData));
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdData;
+ HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND,
+ HDFF_MSG_GROUP_REMOTE_CONTROL,
+ HDFF_MSG_REMOTE_SET_ADDRESS_FILTER);
+ BitBuffer_SetBits(&cmdBuf, 1, Enable);
+ BitBuffer_SetBits(&cmdBuf, 7, 0); // reserved
+ BitBuffer_SetBits(&cmdBuf, 32, Address);
+ osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf);
+ return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd);
+}
diff --git a/libhdffcmd/hdffcmd_remote.h b/libhdffcmd/hdffcmd_remote.h
new file mode 100644
index 0000000..f2e6b8a
--- /dev/null
+++ b/libhdffcmd/hdffcmd_remote.h
@@ -0,0 +1,39 @@
+/**********************************************************************
+ *
+ * HDFF firmware command interface library
+ *
+ * Copyright (C) 2011 Andreas Regel
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ *********************************************************************/
+
+#ifndef HDFFCMD_REMOTE_H
+#define HDFFCMD_REMOTE_H
+
+typedef enum HdffRemoteProtocol_t
+{
+ HDFF_REMOTE_PROTOCOL_NONE,
+ HDFF_REMOTE_PROTOCOL_RC5,
+ HDFF_REMOTE_PROTOCOL_RC6
+} HdffRemoteProtocol_t;
+
+
+int HdffCmdRemoteSetProtocol(int OsdDevice, HdffRemoteProtocol_t Protocol);
+
+int HdffCmdRemoteSetAddressFilter(int OsdDevice, int Enable, uint32_t Address);
+
+#endif /* HDFFCMD_REMOTE_H */
diff --git a/menu.c b/menu.c
new file mode 100644
index 0000000..fa953fb
--- /dev/null
+++ b/menu.c
@@ -0,0 +1,65 @@
+/*
+ * menu.c: The DVB HD Full Featured device main menu
+ *
+ * See the README file for copyright information and how to reach the author.
+ */
+
+#include "menu.h"
+#include "setup.h"
+
+cHdffMenu::cHdffMenu(HDFF::cHdffCmdIf * pHdffCmdIf)
+: cOsdMenu("dvbhddevice"),
+ mHdffCmdIf(pHdffCmdIf)
+{
+ mVideoConversionItem = new cOsdItem("", osUnknown, false);
+ Add(mVideoConversionItem);
+ SetHelp(tr("Video Conversion"), tr("TV on"), tr("TV off"));
+ SetVideoConversion();
+}
+
+cHdffMenu::~cHdffMenu()
+{
+}
+
+eOSState cHdffMenu::ProcessKey(eKeys key)
+{
+ eOSState state = cOsdMenu::ProcessKey(key);
+ if (state == osUnknown)
+ {
+ switch (key)
+ {
+ case kRed:
+ gHdffSetup.SetNextVideoConversion();
+ SetVideoConversion();
+ break;
+
+ case kGreen:
+ mHdffCmdIf->CmdHdmiSendCecCommand(HDFF_CEC_COMMAND_TV_ON);
+ state = osEnd;
+ break;
+
+ case kYellow:
+ mHdffCmdIf->CmdHdmiSendCecCommand(HDFF_CEC_COMMAND_TV_OFF);
+ state = osEnd;
+ break;
+
+ case kOk:
+ state = osEnd;
+ break;
+
+ default:
+ break;
+ }
+ }
+ return state;
+}
+
+void cHdffMenu::SetVideoConversion(void)
+{
+ gHdffSetup.SetVideoFormat(mHdffCmdIf);
+
+ char str[128];
+ sprintf(str, "%s: %s", tr("Video Conversion"), gHdffSetup.GetVideoConversionString());
+ mVideoConversionItem->SetText(str);
+ Display();
+}
diff --git a/menu.h b/menu.h
new file mode 100644
index 0000000..18b3d99
--- /dev/null
+++ b/menu.h
@@ -0,0 +1,29 @@
+/*
+ * menu.h: The DVB HD Full Featured device main menu
+ *
+ * See the README file for copyright information and how to reach the author.
+ */
+
+#ifndef _HDFF_MENU_H_
+#define _HDFF_MENU_H_
+
+#include <vdr/osd.h>
+#include <vdr/plugin.h>
+
+#include "hdffcmd.h"
+
+class cHdffMenu : public cOsdMenu
+{
+private:
+ HDFF::cHdffCmdIf * mHdffCmdIf;
+
+ cOsdItem * mVideoConversionItem;
+
+ void SetVideoConversion(void);
+public:
+ cHdffMenu(HDFF::cHdffCmdIf * pHdffCmdIf);
+ virtual ~cHdffMenu();
+ virtual eOSState ProcessKey(eKeys Key);
+};
+
+#endif
diff --git a/po/de_DE.po b/po/de_DE.po
new file mode 100644
index 0000000..2bee15e
--- /dev/null
+++ b/po/de_DE.po
@@ -0,0 +1,128 @@
+# VDR plugin language source file
+# Copyright (C) 2015 Andreas Regel
+# This file is distributed under the same license as the dvbhddevice package.
+# Christoph Haubrich <christoph1.haubrich at arcor.de>, 2011
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: vdr-dvbhddevice 2.2.0\n"
+"Report-Msgid-Bugs-To: <see README>\n"
+"POT-Creation-Date: 2014-09-21 14:01+0200\n"
+"PO-Revision-Date: 2011-04-25 21:44+0200\n"
+"Last-Translator: Christoph Haubrich\n"
+"Language-Team: <see README>\n"
+"Language: de\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid "HD Full Featured DVB device"
+msgstr "HD Full Featured DVB device"
+
+msgid "Video Conversion"
+msgstr "Bildanpassung"
+
+msgid "TV on"
+msgstr "TV ein"
+
+msgid "TV off"
+msgstr "TV aus"
+
+msgid "Automatic"
+msgstr "automatisch"
+
+msgid "Letterbox 16/9"
+msgstr "Letterbox 16:9"
+
+msgid "Letterbox 14/9"
+msgstr "Letterbox 14:9"
+
+msgid "Pillarbox"
+msgstr "Pillarbox"
+
+msgid "CentreCutOut"
+msgstr "CentreCutOut"
+
+msgid "Always 16/9"
+msgstr "immer 16:9"
+
+msgid "Zoom 16/9"
+msgstr "Zoome 16:9"
+
+msgid "Off"
+msgstr "aus"
+
+msgid "Frame rate"
+msgstr "passende Framerate"
+
+msgid "HD Only"
+msgstr "nur bei HD"
+
+msgid "Always"
+msgstr "immer"
+
+msgid "Disabled"
+msgstr "abgeschaltet"
+
+msgid "Analogue only"
+msgstr "nur analoge Ausgänge"
+
+msgid "HDMI only"
+msgstr "nur HDMI"
+
+msgid "Follow resolution"
+msgstr "folge Auflösung"
+
+msgid "none"
+msgstr "keins"
+
+msgid "Resolution"
+msgstr "Auflösung"
+
+msgid "Video Mode Adaption"
+msgstr "Auflösungsanpassung"
+
+msgid "TV format"
+msgstr "TV-Format"
+
+msgid "Analogue Video"
+msgstr "Analoges Video"
+
+msgid "Audio Delay (ms)"
+msgstr "Audio Verzögerung (ms)"
+
+msgid "Audio Downmix"
+msgstr "Audio Downmix"
+
+msgid "A/V Sync Shift (ms)"
+msgstr "A/V-Sync Verschiebung (ms)"
+
+msgid "OSD Size"
+msgstr "OSD Größe"
+
+msgid "HDMI CEC"
+msgstr "HDMI CEC"
+
+msgid "CEC: Switch TV on"
+msgstr "CEC: TV einschalten"
+
+msgid "CEC: Switch TV off"
+msgstr "CEC: TV ausschalten"
+
+msgid "Remote Control Protocol"
+msgstr "Fernbedienungsprotokoll"
+
+msgid "Remote Control Address"
+msgstr "Fernbedienungsadresse"
+
+msgid "High Level OSD"
+msgstr "High Level OSD"
+
+msgid "Allow True Color OSD"
+msgstr "Erlaube True Color OSD"
+
+msgid "True Color format"
+msgstr "True Color Format"
+
+msgid "Hide mainmenu entry"
+msgstr "Hauptmenüeintrag verstecken"
diff --git a/po/et_EE.po b/po/et_EE.po
new file mode 100644
index 0000000..b483cfe
--- /dev/null
+++ b/po/et_EE.po
@@ -0,0 +1,128 @@
+# VDR plugin language source file
+# Copyright (C) 2015 Andreas Regel
+# This file is distributed under the same license as the dvbhddevice package.
+# Arthur Konovalov <artlov at gmail.com>, 2015
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: vdr-dvbhddevice 2.2.0\n"
+"Report-Msgid-Bugs-To: <see README>\n"
+"POT-Creation-Date: 2014-09-21 14:01+0200\n"
+"PO-Revision-Date: 2011-04-25 21:44+0200\n"
+"Last-Translator: Arthur Konovalov <artlov at gmail.com>\n"
+"Language-Team: Estonian <vdr at linuxtv.org>\n"
+"Language: et\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid "HD Full Featured DVB device"
+msgstr "Täisfunktsionaalne HD DVB seade"
+
+msgid "Video Conversion"
+msgstr "Video konverteerimine"
+
+msgid "TV on"
+msgstr "TV sisse"
+
+msgid "TV off"
+msgstr "TV välja"
+
+msgid "Automatic"
+msgstr "automaatne"
+
+msgid "Letterbox 16/9"
+msgstr "letterbox 16:9"
+
+msgid "Letterbox 14/9"
+msgstr "letterbox 14:9"
+
+msgid "Pillarbox"
+msgstr "pillarbox"
+
+msgid "CentreCutOut"
+msgstr "center cut out"
+
+msgid "Always 16/9"
+msgstr "alati 16:9"
+
+msgid "Zoom 16/9"
+msgstr "suum 16/9"
+
+msgid "Off"
+msgstr "väljas"
+
+msgid "Frame rate"
+msgstr "kaadrisagedus"
+
+msgid "HD Only"
+msgstr "ainult HD-resolutsioon"
+
+msgid "Always"
+msgstr "alati"
+
+msgid "Disabled"
+msgstr "keelatud"
+
+msgid "Analogue only"
+msgstr "ainult analoog"
+
+msgid "HDMI only"
+msgstr "ainult HDMI"
+
+msgid "Follow resolution"
+msgstr "vastavalt resolutsioonile"
+
+msgid "none"
+msgstr "ei"
+
+msgid "Resolution"
+msgstr "Resolutsioon"
+
+msgid "Video Mode Adaption"
+msgstr "Videorežiimi sobitus"
+
+msgid "TV format"
+msgstr "TV külgsuhe"
+
+msgid "Analogue Video"
+msgstr "Analoogvideo"
+
+msgid "Audio Delay (ms)"
+msgstr "Heli viide (ms)"
+
+msgid "Audio Downmix"
+msgstr "Heli downmix"
+
+msgid "A/V Sync Shift (ms)"
+msgstr "A/V-sünkro nihe (ms)"
+
+msgid "OSD Size"
+msgstr "Ekraanimenüü suurus"
+
+msgid "HDMI CEC"
+msgstr "HDMI CEC"
+
+msgid "CEC: Switch TV on"
+msgstr "CEC: TV sisselülitus"
+
+msgid "CEC: Switch TV off"
+msgstr "CEC: TV väljalülitus"
+
+msgid "Remote Control Protocol"
+msgstr "Kaugjuhtimispuldi protokoll"
+
+msgid "Remote Control Address"
+msgstr "Kaugjuhtimispuldi aadress"
+
+msgid "High Level OSD"
+msgstr "Kõrgema taseme ekraanimenüü"
+
+msgid "Allow True Color OSD"
+msgstr "True Color ekraanimenüü"
+
+msgid "True Color format"
+msgstr "True Color formaat"
+
+msgid "Hide mainmenu entry"
+msgstr "Peita peamenüü valikus"
diff --git a/po/fi_FI.po b/po/fi_FI.po
new file mode 100644
index 0000000..c97827f
--- /dev/null
+++ b/po/fi_FI.po
@@ -0,0 +1,128 @@
+# VDR plugin language source file
+# Copyright (C) 2015 Andreas Regel
+# This file is distributed under the same license as the dvbhddevice package.
+# Christoph Haubrich <christoph1.haubrich at arcor.de>, 2011
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: vdr-dvbhddevice 2.2.0\n"
+"Report-Msgid-Bugs-To: <see README>\n"
+"POT-Creation-Date: 2014-09-21 14:01+0200\n"
+"PO-Revision-Date: 2011-04-25 21:44+0200\n"
+"Last-Translator: Rolf Ahrenberg\n"
+"Language-Team: Finnish <vdr at linuxtv.org>\n"
+"Language: fi\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid "HD Full Featured DVB device"
+msgstr "DVB-laite HD-ulostulolla"
+
+msgid "Video Conversion"
+msgstr "Näyttömuoto"
+
+msgid "TV on"
+msgstr "TV päälle"
+
+msgid "TV off"
+msgstr "TV kiinni"
+
+msgid "Automatic"
+msgstr "automaattinen"
+
+msgid "Letterbox 16/9"
+msgstr "letterbox 16:9"
+
+msgid "Letterbox 14/9"
+msgstr "letterbox 14:9"
+
+msgid "Pillarbox"
+msgstr "pillarbox"
+
+msgid "CentreCutOut"
+msgstr "center cut out"
+
+msgid "Always 16/9"
+msgstr "aina 16:9"
+
+msgid "Zoom 16/9"
+msgstr "zoom 16/9"
+
+msgid "Off"
+msgstr "ei"
+
+msgid "Frame rate"
+msgstr "kuvataajuuden mukaan"
+
+msgid "HD Only"
+msgstr "vain HD-resoluutiolla"
+
+msgid "Always"
+msgstr "aina"
+
+msgid "Disabled"
+msgstr "ei käytössä"
+
+msgid "Analogue only"
+msgstr "vain analoginen"
+
+msgid "HDMI only"
+msgstr "vain HDMI"
+
+msgid "Follow resolution"
+msgstr "resoluution mukaan"
+
+msgid "none"
+msgstr "ei"
+
+msgid "Resolution"
+msgstr "Kuvaresoluutio"
+
+msgid "Video Mode Adaption"
+msgstr "Sovita näyttömoodi"
+
+msgid "TV format"
+msgstr "Näytön kuvasuhde"
+
+msgid "Analogue Video"
+msgstr "Analoginen kuvalähtö"
+
+msgid "Audio Delay (ms)"
+msgstr "Äänen viive (ms)"
+
+msgid "Audio Downmix"
+msgstr "Äänen alasmiksaus"
+
+msgid "A/V Sync Shift (ms)"
+msgstr "A/V-synkronointi (ms)"
+
+msgid "OSD Size"
+msgstr "Kuvaruutunäytön koko"
+
+msgid "HDMI CEC"
+msgstr "Käytä HDMI CEC-toimintoa"
+
+msgid "CEC: Switch TV on"
+msgstr "CEC: Laita TV päälle"
+
+msgid "CEC: Switch TV off"
+msgstr "CEC: Sammuta TV"
+
+msgid "Remote Control Protocol"
+msgstr "Kaukosäätimen protokolla"
+
+msgid "Remote Control Address"
+msgstr "Kaukosäätimen osoite"
+
+msgid "High Level OSD"
+msgstr "Käytä korkean tason kuvaruutunäyttöä"
+
+msgid "Allow True Color OSD"
+msgstr "Salli tosivärit kuvaruutunäytölle"
+
+msgid "True Color format"
+msgstr "Näytä tosivärit muodossa"
+
+msgid "Hide mainmenu entry"
+msgstr "Piilota valinta päävalikosta"
diff --git a/po/it_IT.po b/po/it_IT.po
new file mode 100644
index 0000000..16752a8
--- /dev/null
+++ b/po/it_IT.po
@@ -0,0 +1,131 @@
+# VDR plugin language source file
+# Copyright (C) 2015 Andreas Regel
+# This file is distributed under the same license as the dvbhddevice package.
+# Christoph Haubrich <christoph1.haubrich at arcor.de>, 2011
+# Diego Pierotto <vdr-italian at tiscali.it>, 2013
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: vdr-dvbhddevice 2.2.0\n"
+"Report-Msgid-Bugs-To: <see README>\n"
+"POT-Creation-Date: 2014-09-21 14:01+0200\n"
+"PO-Revision-Date: 2015-02-08 19:48+0100\n"
+"Last-Translator: Diego Pierotto <vdr-italian at tiscali.it>\n"
+"Language-Team: <see README>\n"
+"Language: it\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-SourceCharset: utf-8\n"
+"X-Generator: Poedit 1.5.4\n"
+
+msgid "HD Full Featured DVB device"
+msgstr "Scheda DVB HD Full Featured"
+
+msgid "Video Conversion"
+msgstr "Conversione video"
+
+msgid "TV on"
+msgstr "TV accesa"
+
+msgid "TV off"
+msgstr "TV spenta"
+
+msgid "Automatic"
+msgstr "Automatica"
+
+msgid "Letterbox 16/9"
+msgstr "Letterbox 16:9"
+
+msgid "Letterbox 14/9"
+msgstr "Letterbox 14:9"
+
+msgid "Pillarbox"
+msgstr "Pillarbox"
+
+msgid "CentreCutOut"
+msgstr "CentreCutOut"
+
+msgid "Always 16/9"
+msgstr "Sempre 16:9"
+
+msgid "Zoom 16/9"
+msgstr "Ingrandimento 16/9"
+
+msgid "Off"
+msgstr "Spento"
+
+msgid "Frame rate"
+msgstr "Frame rate"
+
+msgid "HD Only"
+msgstr "Solo HD"
+
+msgid "Always"
+msgstr "Sempre"
+
+msgid "Disabled"
+msgstr "Disabilitata"
+
+msgid "Analogue only"
+msgstr "Solo analogica"
+
+msgid "HDMI only"
+msgstr "Solo HDMI"
+
+msgid "Follow resolution"
+msgstr "Risoluzione seguente"
+
+msgid "none"
+msgstr "nessuna"
+
+msgid "Resolution"
+msgstr "Risoluzione"
+
+msgid "Video Mode Adaption"
+msgstr "Adattamento modalità video"
+
+msgid "TV format"
+msgstr "Formato TV"
+
+msgid "Analogue Video"
+msgstr "Video analogico"
+
+msgid "Audio Delay (ms)"
+msgstr "Ritardo audio (ms)"
+
+msgid "Audio Downmix"
+msgstr "Scala Audio"
+
+msgid "A/V Sync Shift (ms)"
+msgstr "Alterna sincro A/V (ms)"
+
+msgid "OSD Size"
+msgstr "Dimensione OSD"
+
+msgid "HDMI CEC"
+msgstr "HDMI CEC"
+
+msgid "CEC: Switch TV on"
+msgstr "CEC: Passa a TV accesa"
+
+msgid "CEC: Switch TV off"
+msgstr "CEC: Passa a TV spenta"
+
+msgid "Remote Control Protocol"
+msgstr "Protocollo controllo remoto"
+
+msgid "Remote Control Address"
+msgstr "Indirizzo controllo remoto"
+
+msgid "High Level OSD"
+msgstr "OSD alto livello"
+
+msgid "Allow True Color OSD"
+msgstr "Permetti OSD True Color"
+
+msgid "True Color format"
+msgstr "Formato True Color"
+
+msgid "Hide mainmenu entry"
+msgstr "Nascondi voce menu principale"
diff --git a/po/uk_UA.po b/po/uk_UA.po
new file mode 100644
index 0000000..7d43819
--- /dev/null
+++ b/po/uk_UA.po
@@ -0,0 +1,129 @@
+# VDR plugin language source file.
+# Copyright (C) 2015 Andreas Regel
+# This file is distributed under the same license as the dvbhddevice package.
+# Yarema Aka Knedlyk <yupadmin at gmail.com>, 2015
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: vdr-dvbhddevice 2.2.0\n"
+"Report-Msgid-Bugs-To: <see README>\n"
+"POT-Creation-Date: 2015-02-03 13:28+0100\n"
+"PO-Revision-Date: 2015-02-01 23:31+0100\n"
+"Last-Translator: Yarema aka Knedlyk <yupadmin at gmail.com>\n"
+"Language-Team: Ukrainian <vdr at linuxtv.org>\n"
+"Language: uk\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 1.7.3\n"
+
+msgid "HD Full Featured DVB device"
+msgstr "HD Full Featured DVB device"
+
+msgid "Video Conversion"
+msgstr "Конвертація відео"
+
+msgid "TV on"
+msgstr "Вкл ТБ"
+
+msgid "TV off"
+msgstr "Викл ТБ"
+
+msgid "Automatic"
+msgstr "Автоматично"
+
+msgid "Letterbox 16/9"
+msgstr "Конверт 16:9"
+
+msgid "Letterbox 14/9"
+msgstr "Конверт 14:9"
+
+msgid "Pillarbox"
+msgstr "Pillarbox"
+
+msgid "CentreCutOut"
+msgstr "Вірізання від центру"
+
+msgid "Always 16/9"
+msgstr "Завжди 16:9"
+
+msgid "Zoom 16/9"
+msgstr "Допасувати до 16:9"
+
+msgid "Off"
+msgstr "Викл"
+
+msgid "Frame rate"
+msgstr "Частота кадрів"
+
+msgid "HD Only"
+msgstr "Тільки HD"
+
+msgid "Always"
+msgstr "Завжди"
+
+msgid "Disabled"
+msgstr "Відключено"
+
+msgid "Analogue only"
+msgstr "Тільки аналоговий"
+
+msgid "HDMI only"
+msgstr "Тільки HDMI"
+
+msgid "Follow resolution"
+msgstr "Відносно розд. здатн."
+
+msgid "none"
+msgstr "немає"
+
+msgid "Resolution"
+msgstr "Розд. здатність"
+
+msgid "Video Mode Adaption"
+msgstr "Адаптація відео режиму"
+
+msgid "TV format"
+msgstr "Формат ТБ"
+
+msgid "Analogue Video"
+msgstr "Аналогове відео"
+
+msgid "Audio Delay (ms)"
+msgstr "Затримка аудіо (мс)"
+
+msgid "Audio Downmix"
+msgstr "Міксування аудіо"
+
+msgid "A/V Sync Shift (ms)"
+msgstr "А/В зсув синхронізації (мс)"
+
+msgid "OSD Size"
+msgstr "Розмір OSD"
+
+msgid "HDMI CEC"
+msgstr "HDMI CEC"
+
+msgid "CEC: Switch TV on"
+msgstr "CEC: включити ТБ"
+
+msgid "CEC: Switch TV off"
+msgstr "CEC: виключити ТБ"
+
+msgid "Remote Control Protocol"
+msgstr "Протокол пульта"
+
+msgid "Remote Control Address"
+msgstr "Адрес пульта"
+
+msgid "High Level OSD"
+msgstr "High Level OSD"
+
+msgid "Allow True Color OSD"
+msgstr "Включити True Color OSD"
+
+msgid "True Color format"
+msgstr "Формат True Color"
+
+msgid "Hide mainmenu entry"
+msgstr "Приховати в головному меню"
diff --git a/setup.c b/setup.c
new file mode 100644
index 0000000..fd16a48
--- /dev/null
+++ b/setup.c
@@ -0,0 +1,476 @@
+/*
+ * setup.c: Setup for the DVB HD Full Featured On Screen Display
+ *
+ * See the README file for copyright information and how to reach the author.
+ */
+
+#include "setup.h"
+#include "hdffcmd.h"
+
+const int kResolution1080i = 0;
+const int kResolution720p = 1;
+const int kResolution576p = 2;
+const int kResolution576i = 3;
+
+
+cHdffSetup gHdffSetup;
+
+cHdffSetup::cHdffSetup(void)
+{
+ Resolution = kResolution1080i;
+ VideoModeAdaption = HDFF_VIDEO_MODE_ADAPT_OFF;
+ TvFormat = HDFF_TV_FORMAT_16_BY_9;
+ VideoConversion = HDFF_VIDEO_CONVERSION_PILLARBOX;
+ AnalogueVideo = HDFF_VIDEO_OUT_CVBS_YUV;
+ AudioDelay = 0;
+ AudioDownmix = HDFF_AUDIO_DOWNMIX_AUTOMATIC;
+ AvSyncShift = 0;
+ OsdSize = 0;
+ CecEnabled = 1;
+ CecTvOn = 1;
+ CecTvOff = 0;
+ RemoteProtocol = 1;
+ RemoteAddress = -1;
+ HighLevelOsd = 1;
+ TrueColorOsd = 1;
+ TrueColorFormat = 0;
+ HideMainMenu = 0;
+}
+
+bool cHdffSetup::SetupParse(const char *Name, const char *Value)
+{
+ if (strcmp(Name, "Resolution") == 0) Resolution = atoi(Value);
+ else if (strcmp(Name, "VideoModeAdaption") == 0) VideoModeAdaption = atoi(Value);
+ else if (strcmp(Name, "TvFormat") == 0) TvFormat = atoi(Value);
+ else if (strcmp(Name, "VideoConversion") == 0) VideoConversion = atoi(Value);
+ else if (strcmp(Name, "AnalogueVideo") == 0) AnalogueVideo = atoi(Value);
+ else if (strcmp(Name, "AudioDelay") == 0) AudioDelay = atoi(Value);
+ else if (strcmp(Name, "AudioDownmix") == 0) AudioDownmix = atoi(Value);
+ else if (strcmp(Name, "AvSyncShift") == 0) AvSyncShift = atoi(Value);
+ else if (strcmp(Name, "OsdSize") == 0) OsdSize = atoi(Value);
+ else if (strcmp(Name, "CecEnabled") == 0) CecEnabled = atoi(Value);
+ else if (strcmp(Name, "CecTvOn") == 0) CecTvOn = atoi(Value);
+ else if (strcmp(Name, "CecTvOff") == 0) CecTvOff = atoi(Value);
+ else if (strcmp(Name, "RemoteProtocol") == 0) RemoteProtocol = atoi(Value);
+ else if (strcmp(Name, "RemoteAddress") == 0) RemoteAddress = atoi(Value);
+ else if (strcmp(Name, "HighLevelOsd") == 0) HighLevelOsd = atoi(Value);
+ else if (strcmp(Name, "TrueColorOsd") == 0) TrueColorOsd = atoi(Value);
+ else if (strcmp(Name, "TrueColorFormat") == 0) TrueColorFormat = atoi(Value);
+ else if (strcmp(Name, "HideMainMenu") == 0) HideMainMenu = atoi(Value);
+ else return false;
+ return true;
+}
+
+void cHdffSetup::GetOsdSize(int &Width, int &Height, double &PixelAspect)
+{
+ if (OsdSize == 0) {
+ if (Resolution == kResolution1080i) {
+ Width = 1920;
+ Height = 1080;
+ }
+ else if (Resolution == kResolution720p) {
+ Width = 1280;
+ Height = 720;
+ }
+ else {
+ Width = 720;
+ Height = 576;
+ }
+ if (TvFormat == HDFF_TV_FORMAT_16_BY_9)
+ PixelAspect = 16.0 / 9.0;
+ else
+ PixelAspect = 4.0 / 3.0;
+ }
+ else if (OsdSize == 1) {
+ Width = 1920;
+ Height = 1080;
+ PixelAspect = 16.0 / 9.0;
+ }
+ else if (OsdSize == 2) {
+ Width = 1280;
+ Height = 720;
+ PixelAspect = 16.0 / 9.0;
+ }
+ else if (OsdSize == 3) {
+ Width = 1024;
+ Height = 576;
+ PixelAspect = 16.0 / 9.0;
+ }
+ else {
+ Width = 720;
+ Height = 576;
+ PixelAspect = 4.0 / 3.0;
+ }
+ PixelAspect /= double(Width) / Height;
+}
+
+HdffVideoMode_t cHdffSetup::GetVideoMode(void)
+{
+ switch (Resolution)
+ {
+ case kResolution1080i:
+ default:
+ return HDFF_VIDEO_MODE_1080I50;
+ case kResolution720p:
+ return HDFF_VIDEO_MODE_720P50;
+ case kResolution576p:
+ return HDFF_VIDEO_MODE_576P50;
+ case kResolution576i:
+ return HDFF_VIDEO_MODE_576I50;
+ }
+}
+
+void cHdffSetup::SetNextVideoConversion(void)
+{
+ int nextVideoConversion = HDFF_VIDEO_CONVERSION_AUTOMATIC;
+
+ if (TvFormat == HDFF_TV_FORMAT_16_BY_9)
+ {
+ switch (VideoConversion)
+ {
+ case HDFF_VIDEO_CONVERSION_PILLARBOX:
+ nextVideoConversion = HDFF_VIDEO_CONVERSION_CENTRE_CUT_OUT;
+ break;
+ case HDFF_VIDEO_CONVERSION_CENTRE_CUT_OUT:
+ nextVideoConversion = HDFF_VIDEO_CONVERSION_ALWAYS_16_BY_9;
+ break;
+ case HDFF_VIDEO_CONVERSION_ALWAYS_16_BY_9:
+ nextVideoConversion = HDFF_VIDEO_CONVERSION_ZOOM_16_BY_9;
+ break;
+ case HDFF_VIDEO_CONVERSION_ZOOM_16_BY_9:
+ nextVideoConversion = HDFF_VIDEO_CONVERSION_PILLARBOX;
+ break;
+ }
+ }
+ else
+ {
+ switch (VideoConversion)
+ {
+ case HDFF_VIDEO_CONVERSION_LETTERBOX_16_BY_9:
+ nextVideoConversion = HDFF_VIDEO_CONVERSION_LETTERBOX_14_BY_9;
+ break;
+ case HDFF_VIDEO_CONVERSION_LETTERBOX_14_BY_9:
+ nextVideoConversion = HDFF_VIDEO_CONVERSION_CENTRE_CUT_OUT;
+ break;
+ case HDFF_VIDEO_CONVERSION_CENTRE_CUT_OUT:
+ nextVideoConversion = HDFF_VIDEO_CONVERSION_LETTERBOX_16_BY_9;
+ break;
+ }
+ }
+ VideoConversion = nextVideoConversion;
+}
+
+const char * cHdffSetup::GetVideoConversionString(void)
+{
+ switch (VideoConversion)
+ {
+ case HDFF_VIDEO_CONVERSION_AUTOMATIC:
+ default:
+ return tr("Automatic");
+ case HDFF_VIDEO_CONVERSION_LETTERBOX_16_BY_9:
+ return tr("Letterbox 16/9");
+ case HDFF_VIDEO_CONVERSION_LETTERBOX_14_BY_9:
+ return tr("Letterbox 14/9");
+ case HDFF_VIDEO_CONVERSION_PILLARBOX:
+ return tr("Pillarbox");
+ case HDFF_VIDEO_CONVERSION_CENTRE_CUT_OUT:
+ return tr("CentreCutOut");
+ case HDFF_VIDEO_CONVERSION_ALWAYS_16_BY_9:
+ return tr("Always 16/9");
+ case HDFF_VIDEO_CONVERSION_ZOOM_16_BY_9:
+ return tr("Zoom 16/9");
+ }
+}
+
+void cHdffSetup::SetVideoFormat(HDFF::cHdffCmdIf * HdffCmdIf)
+{
+ HdffVideoFormat_t videoFormat;
+
+ videoFormat.AutomaticEnabled = true;
+ videoFormat.AfdEnabled = false;
+ videoFormat.TvFormat = (HdffTvFormat_t) TvFormat;
+ videoFormat.VideoConversion = (HdffVideoConversion_t) VideoConversion;
+ HdffCmdIf->CmdAvSetVideoFormat(0, &videoFormat);
+}
+
+cHdffSetupPage::cHdffSetupPage(HDFF::cHdffCmdIf * pHdffCmdIf)
+{
+ const int kResolutions = 4;
+ const int kVideoModeAdaptions = 4;
+ const int kTvFormats = 2;
+ const int kAnalogueVideos = 4;
+ const int kAudioDownmixes = 5;
+ const int kOsdSizes = 5;
+ const int kRemoteProtocols = 3;
+ const int kTrueColorFormats = 3;
+
+ static const char * ResolutionItems[kResolutions] =
+ {
+ "1080i",
+ "720p",
+ "576p",
+ "576i",
+ };
+
+ static const char * VideoModeAdaptionItems[kVideoModeAdaptions] =
+ {
+ tr("Off"),
+ tr("Frame rate"),
+ tr("HD Only"),
+ tr("Always")
+ };
+
+ static const char * TvFormatItems[kTvFormats] =
+ {
+ "4/3",
+ "16/9",
+ };
+
+ static const char * AnalogueVideoItems[kAnalogueVideos] =
+ {
+ tr("Disabled"),
+ "RGB",
+ "CVBS + YUV",
+ "YC (S-Video)",
+ };
+
+ static const char * AudioDownmixItems[kAudioDownmixes] =
+ {
+ tr("Disabled"),
+ tr("Analogue only"),
+ tr("Always"),
+ tr("Automatic"),
+ tr("HDMI only"),
+ };
+
+ static const char * OsdSizeItems[kOsdSizes] =
+ {
+ tr("Follow resolution"),
+ "1920x1080",
+ "1280x720",
+ "1024x576",
+ "720x576",
+ };
+
+ static const char * RemoteProtocolItems[] =
+ {
+ tr("none"),
+ "RC5",
+ "RC6",
+ };
+
+ static const char * TrueColorFormatItems[kTrueColorFormats] =
+ {
+ "ARGB8888",
+ "ARGB8565",
+ "ARGB4444",
+ };
+
+ mHdffCmdIf = pHdffCmdIf;
+ mNewHdffSetup = gHdffSetup;
+
+ Add(new cMenuEditStraItem(tr("Resolution"), &mNewHdffSetup.Resolution, kResolutions, ResolutionItems));
+ Add(new cMenuEditStraItem(tr("Video Mode Adaption"), &mNewHdffSetup.VideoModeAdaption, kVideoModeAdaptions, VideoModeAdaptionItems));
+ mTvFormatItem = new cMenuEditStraItem(tr("TV format"), &mNewHdffSetup.TvFormat, kTvFormats, TvFormatItems);
+ Add(mTvFormatItem);
+ Add(new cMenuEditStraItem(tr("Analogue Video"), &mNewHdffSetup.AnalogueVideo, kAnalogueVideos, AnalogueVideoItems));
+ Add(new cMenuEditIntItem(tr("Audio Delay (ms)"), &mNewHdffSetup.AudioDelay, 0, 500));
+ Add(new cMenuEditStraItem(tr("Audio Downmix"), &mNewHdffSetup.AudioDownmix, kAudioDownmixes, AudioDownmixItems));
+ Add(new cMenuEditIntItem(tr("A/V Sync Shift (ms)"), &mNewHdffSetup.AvSyncShift, -500, 500));
+ Add(new cMenuEditStraItem(tr("OSD Size"), &mNewHdffSetup.OsdSize, kOsdSizes, OsdSizeItems));
+ Add(new cMenuEditBoolItem(tr("HDMI CEC"), &mNewHdffSetup.CecEnabled));
+ Add(new cMenuEditBoolItem(tr("CEC: Switch TV on"), &mNewHdffSetup.CecTvOn));
+ Add(new cMenuEditBoolItem(tr("CEC: Switch TV off"), &mNewHdffSetup.CecTvOff));
+ Add(new cMenuEditStraItem(tr("Remote Control Protocol"), &mNewHdffSetup.RemoteProtocol, kRemoteProtocols, RemoteProtocolItems));
+ Add(new cMenuEditIntItem(tr("Remote Control Address"), &mNewHdffSetup.RemoteAddress, -1, 31));
+ Add(new cMenuEditBoolItem(tr("High Level OSD"), &mNewHdffSetup.HighLevelOsd));
+ Add(new cMenuEditBoolItem(tr("Allow True Color OSD"), &mNewHdffSetup.TrueColorOsd));
+ Add(new cMenuEditStraItem(tr("True Color format"), &mNewHdffSetup.TrueColorFormat, kTrueColorFormats, TrueColorFormatItems));
+ Add(new cMenuEditBoolItem(tr("Hide mainmenu entry"), &mNewHdffSetup.HideMainMenu));
+
+ mVideoConversion = 0;
+ if (mNewHdffSetup.TvFormat == HDFF_TV_FORMAT_16_BY_9)
+ {
+ switch (mNewHdffSetup.VideoConversion)
+ {
+ case HDFF_VIDEO_CONVERSION_PILLARBOX:
+ mVideoConversion = 0;
+ break;
+ case HDFF_VIDEO_CONVERSION_CENTRE_CUT_OUT:
+ mVideoConversion = 1;
+ break;
+ case HDFF_VIDEO_CONVERSION_ALWAYS_16_BY_9:
+ mVideoConversion = 2;
+ break;
+ case HDFF_VIDEO_CONVERSION_ZOOM_16_BY_9:
+ mVideoConversion = 3;
+ break;
+ }
+ }
+ else
+ {
+ switch (mNewHdffSetup.VideoConversion)
+ {
+ case HDFF_VIDEO_CONVERSION_LETTERBOX_16_BY_9:
+ mVideoConversion = 0;
+ break;
+ case HDFF_VIDEO_CONVERSION_LETTERBOX_14_BY_9:
+ mVideoConversion = 1;
+ break;
+ case HDFF_VIDEO_CONVERSION_CENTRE_CUT_OUT:
+ mVideoConversion = 2;
+ break;
+ }
+ }
+ BuildVideoConversionItem();
+}
+
+cHdffSetupPage::~cHdffSetupPage(void)
+{
+}
+
+void cHdffSetupPage::BuildVideoConversionItem(void)
+{
+ const int kVideoConversions4by3 = 3;
+ const int kVideoConversions16by9 = 4;
+
+ static const char * VideoConversionItems4by3[kVideoConversions4by3] =
+ {
+ tr("Letterbox 16/9"),
+ tr("Letterbox 14/9"),
+ tr("CentreCutOut")
+ };
+
+ static const char * VideoConversionItems16by9[kVideoConversions16by9] =
+ {
+ tr("Pillarbox"),
+ tr("CentreCutOut"),
+ tr("Always 16/9"),
+ tr("Zoom 16/9")
+ };
+
+ cOsdItem * item;
+
+ cList<cOsdItem>::Del(mTvFormatItem->Next());
+ if (mNewHdffSetup.TvFormat == HDFF_TV_FORMAT_16_BY_9)
+ {
+ item = new cMenuEditStraItem(tr("Video Conversion"), &mVideoConversion,
+ kVideoConversions16by9, VideoConversionItems16by9);
+ }
+ else
+ {
+ item = new cMenuEditStraItem(tr("Video Conversion"), &mVideoConversion,
+ kVideoConversions4by3, VideoConversionItems4by3);
+ }
+ Add(item, false, mTvFormatItem);
+}
+
+void cHdffSetupPage::Store(void)
+{
+ if (mNewHdffSetup.TvFormat == HDFF_TV_FORMAT_16_BY_9)
+ {
+ switch (mVideoConversion)
+ {
+ case 0:
+ mNewHdffSetup.VideoConversion = HDFF_VIDEO_CONVERSION_PILLARBOX;
+ break;
+ case 1:
+ mNewHdffSetup.VideoConversion = HDFF_VIDEO_CONVERSION_CENTRE_CUT_OUT;
+ break;
+ case 2:
+ mNewHdffSetup.VideoConversion = HDFF_VIDEO_CONVERSION_ALWAYS_16_BY_9;
+ break;
+ case 3:
+ mNewHdffSetup.VideoConversion = HDFF_VIDEO_CONVERSION_ZOOM_16_BY_9;
+ break;
+ }
+ }
+ else
+ {
+ switch (mVideoConversion)
+ {
+ case 0:
+ mNewHdffSetup.VideoConversion = HDFF_VIDEO_CONVERSION_LETTERBOX_16_BY_9;
+ break;
+ case 1:
+ mNewHdffSetup.VideoConversion = HDFF_VIDEO_CONVERSION_LETTERBOX_14_BY_9;
+ break;
+ case 2:
+ mNewHdffSetup.VideoConversion = HDFF_VIDEO_CONVERSION_CENTRE_CUT_OUT;
+ break;
+ }
+ }
+ SetupStore("Resolution", mNewHdffSetup.Resolution);
+ SetupStore("VideoModeAdaption", mNewHdffSetup.VideoModeAdaption);
+ SetupStore("TvFormat", mNewHdffSetup.TvFormat);
+ SetupStore("VideoConversion", mNewHdffSetup.VideoConversion);
+ SetupStore("AnalogueVideo", mNewHdffSetup.AnalogueVideo);
+ SetupStore("AudioDelay", mNewHdffSetup.AudioDelay);
+ SetupStore("AudioDownmix", mNewHdffSetup.AudioDownmix);
+ SetupStore("AvSyncShift", mNewHdffSetup.AvSyncShift);
+ SetupStore("OsdSize", mNewHdffSetup.OsdSize);
+ SetupStore("CecEnabled", mNewHdffSetup.CecEnabled);
+ SetupStore("CecTvOn", mNewHdffSetup.CecTvOn);
+ SetupStore("CecTvOff", mNewHdffSetup.CecTvOff);
+ SetupStore("RemoteProtocol", mNewHdffSetup.RemoteProtocol);
+ SetupStore("RemoteAddress", mNewHdffSetup.RemoteAddress);
+ SetupStore("HighLevelOsd", mNewHdffSetup.HighLevelOsd);
+ SetupStore("TrueColorOsd", mNewHdffSetup.TrueColorOsd);
+ SetupStore("TrueColorFormat", mNewHdffSetup.TrueColorFormat);
+ SetupStore("HideMainMenu", mNewHdffSetup.HideMainMenu);
+
+ if (mHdffCmdIf)
+ {
+ if (mNewHdffSetup.Resolution != gHdffSetup.Resolution)
+ {
+ mHdffCmdIf->CmdHdmiSetVideoMode(mNewHdffSetup.GetVideoMode());
+ }
+ HdffHdmiConfig_t hdmiConfig;
+
+ mNewHdffSetup.SetVideoFormat(mHdffCmdIf);
+
+ mHdffCmdIf->CmdAvSetAudioDelay(mNewHdffSetup.AudioDelay);
+ mHdffCmdIf->CmdAvSetAudioDownmix((HdffAudioDownmixMode_t) mNewHdffSetup.AudioDownmix);
+ mHdffCmdIf->CmdAvSetSyncShift(mNewHdffSetup.AvSyncShift);
+
+ mHdffCmdIf->CmdMuxSetVideoOut((HdffVideoOut_t) mNewHdffSetup.AnalogueVideo);
+
+ memset(&hdmiConfig, 0, sizeof(hdmiConfig));
+ hdmiConfig.TransmitAudio = true;
+ hdmiConfig.ForceDviMode = false;
+ hdmiConfig.CecEnabled = mNewHdffSetup.CecEnabled;
+ hdmiConfig.VideoModeAdaption = (HdffVideoModeAdaption_t) mNewHdffSetup.VideoModeAdaption;
+ mHdffCmdIf->CmdHdmiConfigure(&hdmiConfig);
+
+ mHdffCmdIf->CmdRemoteSetProtocol((HdffRemoteProtocol_t) mNewHdffSetup.RemoteProtocol);
+ mHdffCmdIf->CmdRemoteSetAddressFilter(mNewHdffSetup.RemoteAddress >= 0, mNewHdffSetup.RemoteAddress);
+ }
+
+ gHdffSetup = mNewHdffSetup;
+}
+
+eOSState cHdffSetupPage::ProcessKey(eKeys key)
+{
+ eOSState state = cMenuSetupPage::ProcessKey(key);
+
+ if (state == osContinue)
+ {
+ cOsdItem * item;
+ switch (key)
+ {
+ case kLeft:
+ case kRight:
+ item = Get(Current());
+ if (item == mTvFormatItem)
+ {
+ mVideoConversion = 0;
+ BuildVideoConversionItem();
+ Display();
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ return state;
+}
diff --git a/setup.h b/setup.h
new file mode 100644
index 0000000..582ee76
--- /dev/null
+++ b/setup.h
@@ -0,0 +1,66 @@
+/*
+ * setup.h: Setup for the DVB HD Full Featured On Screen Display
+ *
+ * See the README file for copyright information and how to reach the author.
+ */
+
+#ifndef _HDFF_SETUP_H_
+#define _HDFF_SETUP_H_
+
+#include <vdr/plugin.h>
+#include "hdffcmd.h"
+
+struct cHdffSetup
+{
+ cHdffSetup(void);
+ bool SetupParse(const char * Name, const char * Value);
+ void GetOsdSize(int &Width, int &Height, double &PixelAspect);
+ HdffVideoMode_t GetVideoMode(void);
+ void SetNextVideoConversion(void);
+ const char * GetVideoConversionString(void);
+ void SetVideoFormat(HDFF::cHdffCmdIf * HdffCmdIf);
+
+ int Resolution;
+ int VideoModeAdaption;
+ int TvFormat;
+ int VideoConversion;
+ int AnalogueVideo;
+ int AudioDelay;
+ int AudioDownmix;
+ int AvSyncShift;
+ int OsdSize;
+ int CecEnabled;
+ int CecTvOn;
+ int CecTvOff;
+ int RemoteProtocol;
+ int RemoteAddress;
+
+ int HighLevelOsd;
+ int TrueColorOsd;
+ int TrueColorFormat;
+
+ int HideMainMenu;
+};
+
+extern cHdffSetup gHdffSetup;
+
+class cHdffSetupPage : public cMenuSetupPage
+{
+private:
+ HDFF::cHdffCmdIf * mHdffCmdIf;
+ cHdffSetup mNewHdffSetup;
+ cOsdItem * mTvFormatItem;
+ int mVideoConversion;
+
+ void BuildVideoConversionItem(void);
+
+protected:
+ virtual void Store(void);
+
+public:
+ cHdffSetupPage(HDFF::cHdffCmdIf * pHdffCmdIf);
+ virtual ~cHdffSetupPage(void);
+ virtual eOSState ProcessKey(eKeys Key);
+};
+
+#endif
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-vdr-dvb/vdr-plugin-dvbhddevice.git
More information about the pkg-vdr-dvb-changes
mailing list