summaryrefslogtreecommitdiff
path: root/PLUGINS/src/dvbhddevice
diff options
context:
space:
mode:
Diffstat (limited to 'PLUGINS/src/dvbhddevice')
-rw-r--r--PLUGINS/src/dvbhddevice/COPYING340
-rw-r--r--PLUGINS/src/dvbhddevice/HISTORY16
-rw-r--r--PLUGINS/src/dvbhddevice/Makefile114
-rw-r--r--PLUGINS/src/dvbhddevice/README18
-rw-r--r--PLUGINS/src/dvbhddevice/bitbuffer.c97
-rw-r--r--PLUGINS/src/dvbhddevice/bitbuffer.h31
-rw-r--r--PLUGINS/src/dvbhddevice/dvbhddevice.c48
-rw-r--r--PLUGINS/src/dvbhddevice/dvbhdffdevice.c760
-rw-r--r--PLUGINS/src/dvbhddevice/dvbhdffdevice.h123
-rw-r--r--PLUGINS/src/dvbhddevice/hdffcmd.c1120
-rw-r--r--PLUGINS/src/dvbhddevice/hdffcmd.h102
-rw-r--r--PLUGINS/src/dvbhddevice/hdffmsgdef.h304
-rw-r--r--PLUGINS/src/dvbhddevice/hdffosd.c755
-rw-r--r--PLUGINS/src/dvbhddevice/hdffosd.h26
-rw-r--r--PLUGINS/src/dvbhddevice/setup.c252
-rw-r--r--PLUGINS/src/dvbhddevice/setup.h53
16 files changed, 4159 insertions, 0 deletions
diff --git a/PLUGINS/src/dvbhddevice/COPYING b/PLUGINS/src/dvbhddevice/COPYING
new file mode 100644
index 0000000..f90922e
--- /dev/null
+++ b/PLUGINS/src/dvbhddevice/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/PLUGINS/src/dvbhddevice/HISTORY b/PLUGINS/src/dvbhddevice/HISTORY
new file mode 100644
index 0000000..aa788fd
--- /dev/null
+++ b/PLUGINS/src/dvbhddevice/HISTORY
@@ -0,0 +1,16 @@
+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
+
+- Added support for TrueColor OSD.
diff --git a/PLUGINS/src/dvbhddevice/Makefile b/PLUGINS/src/dvbhddevice/Makefile
new file mode 100644
index 0000000..ea1b9d1
--- /dev/null
+++ b/PLUGINS/src/dvbhddevice/Makefile
@@ -0,0 +1,114 @@
+#
+# Makefile for a Video Disk Recorder plugin
+#
+# $Id: Makefile 1.7 2011/04/17 11:40:55 kls Exp $
+
+# The official name of this plugin.
+# This name will be used in the '-P...' option of VDR to load the plugin.
+# By default the main source file also carries this name.
+# IMPORTANT: the presence of this macro is important for the Make.config
+# file. So it must be defined, even if it is not used here!
+#
+PLUGIN = 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 C++ compiler and options:
+
+CXX ?= g++
+CXXFLAGS ?= -g -O3 -Wall -Woverloaded-virtual -Wno-parentheses
+
+### The directory environment:
+
+VDRDIR = ../../..
+LIBDIR = ../../lib
+TMPDIR = /tmp
+
+### Make sure that necessary options are included:
+
+include $(VDRDIR)/Make.global
+
+### Allow user defined options to overwrite defaults:
+
+-include $(VDRDIR)/Make.config
+
+### The version number of VDR's plugin API (taken from VDR's "config.h"):
+
+APIVERSION = $(shell sed -ne '/define APIVERSION/s/^.*"\(.*\)".*$$/\1/p' $(VDRDIR)/config.h)
+
+### The name of the distribution archive:
+
+ARCHIVE = $(PLUGIN)-$(VERSION)
+PACKAGE = vdr-$(ARCHIVE)
+
+### Includes and Defines (add further entries here):
+
+INCLUDES += -I$(VDRDIR)/include
+
+DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
+
+### The object files (add further files here):
+
+OBJS = $(PLUGIN).o bitbuffer.o dvbhdffdevice.o hdffcmd.o hdffosd.o setup.o
+
+### The main target:
+
+all: libvdr-$(PLUGIN).so i18n
+
+### Implicit rules:
+
+%.o: %.c
+ $(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) $<
+
+### Dependencies:
+
+MAKEDEP = $(CXX) -MM -MG
+DEPFILE = .dependencies
+$(DEPFILE): Makefile
+ @$(MAKEDEP) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@
+
+-include $(DEPFILE)
+
+### Internationalization (I18N):
+
+PODIR = po
+LOCALEDIR = $(VDRDIR)/locale
+I18Npo = $(wildcard $(PODIR)/*.po)
+I18Nmsgs = $(addprefix $(LOCALEDIR)/, $(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 --package-version=$(VDRVERSION) --msgid-bugs-address='<see README>' -o $@ $^
+
+%.po: $(I18Npot)
+ msgmerge -U --no-wrap --no-location --backup=none -q $@ $<
+ @touch $@
+
+$(I18Nmsgs): $(LOCALEDIR)/%/LC_MESSAGES/vdr-$(PLUGIN).mo: $(PODIR)/%.mo
+ @mkdir -p $(dir $@)
+ cp $< $@
+
+.PHONY: i18n
+i18n: $(I18Nmsgs) $(I18Npot)
+
+### Targets:
+
+libvdr-$(PLUGIN).so: $(OBJS)
+ $(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@
+ @cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION)
+
+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 $(OBJS) $(DEPFILE) *.so *.tgz core* *~ $(PODIR)/*.mo $(PODIR)/*.pot
diff --git a/PLUGINS/src/dvbhddevice/README b/PLUGINS/src/dvbhddevice/README
new file mode 100644
index 0000000..5697dea
--- /dev/null
+++ b/PLUGINS/src/dvbhddevice/README
@@ -0,0 +1,18 @@
+This is a "plugin" for the Video Disk Recorder (VDR).
+
+Written by: Andreas Regel <andreas.regel@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/PLUGINS/src/dvbhddevice/bitbuffer.c b/PLUGINS/src/dvbhddevice/bitbuffer.c
new file mode 100644
index 0000000..244b85e
--- /dev/null
+++ b/PLUGINS/src/dvbhddevice/bitbuffer.c
@@ -0,0 +1,97 @@
+/*
+ * bitbuffer.c: TODO(short description)
+ *
+ * See the README file for copyright information and how to reach the author.
+ *
+ * $Id: bitbuffer.c 1.1 2009/12/29 14:29:20 kls Exp $
+ */
+
+#include "bitbuffer.h"
+#include <stdlib.h>
+
+cBitBuffer::cBitBuffer(uint32_t MaxLength)
+{
+ mData = NULL;
+ mMaxLength = 0;
+ mBitPos = 0;
+
+ if (MaxLength <= 0x10000)
+ {
+ mData = new uint8_t[MaxLength];
+ if (mData)
+ {
+ mMaxLength = MaxLength * 8;
+ }
+ }
+}
+
+cBitBuffer::~cBitBuffer(void)
+{
+ if (mData)
+ delete[] mData;
+}
+
+uint8_t * cBitBuffer::GetData(void)
+{
+ return mData;
+}
+
+uint32_t cBitBuffer::GetMaxLength(void)
+{
+ return mMaxLength / 8;
+}
+
+uint32_t cBitBuffer::GetBits(int NumBits)
+{
+ return 0;
+}
+
+void cBitBuffer::SetBits(int NumBits, uint32_t Data)
+{
+ uint32_t nextBitPos;
+ uint32_t bytePos;
+ uint32_t bitsInByte;
+ int shift;
+
+ if (NumBits <= 0 || NumBits > 32)
+ return;
+
+ nextBitPos = mBitPos + NumBits;
+
+ if (nextBitPos > mMaxLength)
+ return;
+
+ bytePos = mBitPos / 8;
+ bitsInByte = mBitPos % 8;
+
+ mData[bytePos] &= (uint8_t) (0xFF << (8 - bitsInByte));
+ shift = NumBits - (8 - bitsInByte);
+ if (shift > 0)
+ mData[bytePos] |= (uint8_t) (Data >> shift);
+ else
+ mData[bytePos] |= (uint8_t) (Data << (-shift));
+ NumBits -= 8 - bitsInByte;
+ bytePos++;
+ while (NumBits > 0)
+ {
+ shift = NumBits - 8;
+ if (shift > 0)
+ mData[bytePos] = (uint8_t) (Data >> shift);
+ else
+ mData[bytePos] = (uint8_t) (Data << (-shift));
+ NumBits -= 8;
+ bytePos++;
+ }
+ mBitPos = nextBitPos;
+}
+
+uint32_t cBitBuffer::GetByteLength(void)
+{
+ return (mBitPos + 7) / 8;
+}
+
+void cBitBuffer::SetDataByte(uint32_t Position, uint8_t Data)
+{
+ if (Position < mMaxLength)
+ mData[Position] = Data;
+}
diff --git a/PLUGINS/src/dvbhddevice/bitbuffer.h b/PLUGINS/src/dvbhddevice/bitbuffer.h
new file mode 100644
index 0000000..e7b3650
--- /dev/null
+++ b/PLUGINS/src/dvbhddevice/bitbuffer.h
@@ -0,0 +1,31 @@
+/*
+ * bitbuffer.h: TODO(short description)
+ *
+ * See the README file for copyright information and how to reach the author.
+ *
+ * $Id: bitbuffer.h 1.1 2009/12/29 14:27:03 kls Exp $
+ */
+
+#ifndef _HDFF_BITBUFFER_H_
+#define _HDFF_BITBUFFER_H_
+
+#include <stdint.h>
+
+class cBitBuffer
+{
+private:
+ uint8_t * mData;
+ uint32_t mMaxLength;
+ uint32_t mBitPos;
+public:
+ cBitBuffer(uint32_t MaxLength);
+ ~cBitBuffer(void);
+ uint8_t * GetData(void);
+ uint32_t GetMaxLength(void);
+ uint32_t GetBits(int NumBits);
+ void SetBits(int NumBits, uint32_t Data);
+ uint32_t GetByteLength(void);
+ void SetDataByte(uint32_t Position, uint8_t Data);
+};
+
+#endif
diff --git a/PLUGINS/src/dvbhddevice/dvbhddevice.c b/PLUGINS/src/dvbhddevice/dvbhddevice.c
new file mode 100644
index 0000000..d639922
--- /dev/null
+++ b/PLUGINS/src/dvbhddevice/dvbhddevice.c
@@ -0,0 +1,48 @@
+/*
+ * dvbhddevice.c: A plugin for the Video Disk Recorder
+ *
+ * See the README file for copyright information and how to reach the author.
+ *
+ * $Id: dvbhddevice.c 1.12 2011/04/17 11:20:22 kls Exp $
+ */
+
+#include <vdr/plugin.h>
+#include "dvbhdffdevice.h"
+#include "setup.h"
+
+static const char *VERSION = "0.0.3";
+static const char *DESCRIPTION = "HD Full Featured DVB device";
+
+class cPluginDvbhddevice : public cPlugin {
+private:
+ cDvbHdFfDeviceProbe *probe;
+public:
+ cPluginDvbhddevice(void);
+ virtual ~cPluginDvbhddevice();
+ virtual const char *Version(void) { return VERSION; }
+ virtual const char *Description(void) { return DESCRIPTION; }
+ virtual cMenuSetupPage *SetupMenu(void);
+ virtual bool SetupParse(const char *Name, const char *Value);
+ };
+
+cPluginDvbhddevice::cPluginDvbhddevice(void)
+{
+ probe = new cDvbHdFfDeviceProbe;
+}
+
+cPluginDvbhddevice::~cPluginDvbhddevice()
+{
+ delete probe;
+}
+
+cMenuSetupPage *cPluginDvbhddevice::SetupMenu(void)
+{
+ return new cHdffSetupPage(cDvbHdFfDevice::GetHdffCmdHandler());
+}
+
+bool cPluginDvbhddevice::SetupParse(const char *Name, const char *Value)
+{
+ return gHdffSetup.SetupParse(Name, Value);
+}
+
+VDRPLUGINCREATOR(cPluginDvbhddevice); // Don't touch this!
diff --git a/PLUGINS/src/dvbhddevice/dvbhdffdevice.c b/PLUGINS/src/dvbhddevice/dvbhdffdevice.c
new file mode 100644
index 0000000..9263009
--- /dev/null
+++ b/PLUGINS/src/dvbhddevice/dvbhdffdevice.c
@@ -0,0 +1,760 @@
+/*
+ * dvbhdffdevice.c: The DVB HD Full Featured device interface
+ *
+ * See the README file for copyright information and how to reach the author.
+ *
+ * $Id: dvbhdffdevice.c 1.29 2011/04/17 11:20:22 kls Exp $
+ */
+
+#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"
+
+// --- cDvbHdFfDevice ----------------------------------------------------------
+
+int cDvbHdFfDevice::devHdffOffset = -1;
+
+cDvbHdFfDevice::cDvbHdFfDevice(int Adapter, int Frontend)
+:cDvbDevice(Adapter, Frontend)
+{
+ spuDecoder = NULL;
+ audioChannel = 0;
+ playMode = pmNone;
+ mHdffCmdIf = NULL;
+
+ // 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);
+ mHdffCmdIf->CmdAvSetAudioDelay(gHdffSetup.AudioDelay);
+ mHdffCmdIf->CmdAvSetAudioDownmix((HDFF::eDownmixMode) gHdffSetup.AudioDownmix);
+ mHdffCmdIf->CmdMuxSetVideoOut((HDFF::eVideoOut) gHdffSetup.AnalogueVideo);
+ mHdffCmdIf->CmdHdmiSetVideoMode(gHdffSetup.GetVideoMode());
+ HDFF::tHdmiConfig hdmiConfig;
+ hdmiConfig.TransmitAudio = true;
+ hdmiConfig.ForceDviMode = false;
+ hdmiConfig.CecEnabled = gHdffSetup.CecEnabled;
+ mHdffCmdIf->CmdHdmiConfigure(&hdmiConfig);
+ if (gHdffSetup.CecEnabled)
+ mHdffCmdIf->CmdHdmiSendCecCommand(HDFF::cecCommandTvOn);
+ mHdffCmdIf->CmdRemoteSetProtocol((HDFF::eRemoteProtocol) gHdffSetup.RemoteProtocol);
+ mHdffCmdIf->CmdRemoteSetAddressFilter(gHdffSetup.RemoteAddress >= 0, gHdffSetup.RemoteAddress);
+ }
+
+ // Video format:
+
+ SetVideoFormat(Setup.VideoFormat);
+}
+
+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);
+ 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)
+{
+ //TODO
+ return NULL;
+}
+
+void cDvbHdFfDevice::SetVideoDisplayFormat(eVideoDisplayFormat VideoDisplayFormat)
+{
+ //TODO???
+ cDevice::SetVideoDisplayFormat(VideoDisplayFormat);
+}
+
+void cDvbHdFfDevice::SetVideoFormat(bool VideoFormat16_9)
+{
+ HDFF::tVideoFormat videoFormat;
+ videoFormat.AutomaticEnabled = true;
+ videoFormat.AfdEnabled = true;
+ videoFormat.TvFormat = (HDFF::eTvFormat) gHdffSetup.TvFormat;
+ videoFormat.VideoConversion = (HDFF::eVideoConversion) gHdffSetup.VideoConversion;
+ mHdffCmdIf->CmdAvSetVideoFormat(0, &videoFormat);
+}
+
+eVideoSystem cDvbHdFfDevice::GetVideoSystem(void)
+{
+ eVideoSystem VideoSystem = vsPAL;
+ if (fd_video >= 0) {
+ video_size_t vs;
+ if (ioctl(fd_video, VIDEO_GET_SIZE, &vs) == 0) {
+ if (vs.h == 480 || vs.h == 240)
+ VideoSystem = vsNTSC;
+ }
+ else
+ LOG_ERROR;
+ }
+ return VideoSystem;
+}
+
+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);
+}
+
+/*TODO obsolete?
+bool cDvbHdFfDevice::SetAudioBypass(bool On)
+{
+ if (setTransferModeForDolbyDigital != 1)
+ return false;
+ return ioctl(fd_audio, AUDIO_SET_BYPASS_MODE, On) == 0;
+}
+TODO*/
+
+bool cDvbHdFfDevice::SetPid(cPidHandle *Handle, int Type, bool On)
+{
+ 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::videoStreamH264);
+ else
+ mHdffCmdIf->CmdAvSetVideoPid(0, Handle->pid, HDFF::videoStreamMpeg2);
+ }
+ else if (Type == ptAudio)
+ mHdffCmdIf->CmdAvSetAudioPid(0, Handle->pid, HDFF::audioStreamMpeg1);
+ else if (Type == ptDolby)
+ mHdffCmdIf->CmdAvSetAudioPid(0, Handle->pid, HDFF::audioStreamAc3);
+ 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::videoStreamMpeg2);
+ else if (Type == ptAudio)
+ mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF::audioStreamMpeg1);
+ else if (Type == ptDolby)
+ mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF::audioStreamAc3);
+ //TODO missing setting to 0x1FFF??? see cDvbDevice::SetPid()
+ close(Handle->handle);
+ Handle->handle = -1;
+ }
+ }
+ return true;
+}
+
+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 = pidHandles[ptVideo].pid == vpid;
+ bool pidHandlesAudio = 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;
+
+ bool TurnOnLivePIDs = !StartTransferMode && LiveView;
+
+ // Turn off live PIDs if necessary:
+
+ if (TurnOffLivePIDs)
+ TurnOffLiveMode(LiveView);
+
+ // Set the tuner:
+
+ if (!cDvbDevice::SetChannelDevice(Channel, LiveView))
+ return false;
+
+ // If this channel switch was requested by the EITScanner we don't wait for
+ // a lock and don't set any live PIDs (the EITScanner will wait for the lock
+ // by itself before setting any filters):
+
+ if (EITScanner.UsesDevice(this)) //XXX
+ return true;
+
+ // PID settings:
+
+ if (TurnOnLivePIDs) {
+ //SetAudioBypass(false);//TODO obsolete?
+ if (!(AddPid(Channel->Ppid(), ptPcr) && AddPid(vpid, ptVideo, Channel->Vtype()) && AddPid(apid, ptAudio))) {
+ esyslog("ERROR: failed to set PIDs for channel %d on device %d", Channel->Number(), CardIndex() + 1);
+ return false;
+ }
+ if (IsPrimaryDevice())
+ AddPid(Channel->Tpid(), ptTeletext);//TODO obsolete?
+ }
+ 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::SetDigitalAudioDevice(bool On)
+{
+ // not needed
+}
+
+void cDvbHdFfDevice::SetAudioTrackDevice(eTrackType Type)
+{
+ //printf("SetAudioTrackDevice %d\n", Type);
+ const tTrackId *TrackId = GetTrack(Type);
+ if (TrackId && TrackId->id) {
+ if (IS_AUDIO_TRACK(Type)) {
+ 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;
+ SetPid(&pidHandles[ptAudio], ptAudio, true);
+ if (CamSlot()) {
+ CamSlot()->SetPid(pidHandles[ptAudio].pid, true);
+ CamSlot()->StartDecrypting();
+ }
+ }
+ }
+ else if (IS_DOLBY_TRACK(Type)) {
+ pidHandles[ptDolby].pid = TrackId->id;
+ SetPid(&pidHandles[ptDolby], ptDolby, true);
+ }
+ }
+}
+
+bool cDvbHdFfDevice::CanReplay(void) const
+{
+ return cDevice::CanReplay();
+}
+
+bool cDvbHdFfDevice::SetPlayMode(ePlayMode PlayMode)
+{
+ if (PlayMode == pmNone) {
+ mHdffCmdIf->CmdAvEnableVideoAfterStop(0, false);
+ mHdffCmdIf->CmdAvSetPcrPid(0, 0);
+ mHdffCmdIf->CmdAvSetVideoPid(0, 0, HDFF::videoStreamMpeg2);
+ mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF::audioStreamMpeg1);
+
+ ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX);
+ mHdffCmdIf->CmdAvSetDecoderInput(0, 0);
+ mHdffCmdIf->CmdAvEnableSync(0, true);
+ mHdffCmdIf->CmdAvSetPlayMode(0, true);
+ }
+ else {
+ if (playMode == pmNone)
+ TurnOffLiveMode(true);
+
+ mHdffCmdIf->CmdAvSetPlayMode(1, Transferring());
+ mHdffCmdIf->CmdAvSetStc(0, 100000);
+ mHdffCmdIf->CmdAvEnableSync(0, true);
+ mHdffCmdIf->CmdAvEnableVideoAfterStop(0, true);
+
+ playVideoPid = -1;
+ playAudioPid = -1;
+ audioCounter = 0;
+ videoCounter = 0;
+
+ mHdffCmdIf->CmdAvSetDecoderInput(0, 2);
+ ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY);
+ }
+ playMode = PlayMode;
+ return true;
+}
+
+int64_t cDvbHdFfDevice::GetSTC(void)
+{
+ 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;
+ }
+ return pts;
+ }
+ 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;
+ }
+ return pts;
+ }
+ return -1;
+}
+
+void cDvbHdFfDevice::TrickSpeed(int Speed)
+{
+ mHdffCmdIf->CmdAvEnableSync(0, false);
+ mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF::audioStreamMpeg1);
+ playAudioPid = -1;
+ if (Speed > 0)
+ mHdffCmdIf->CmdAvSetVideoSpeed(0, 100 / Speed);
+}
+
+void cDvbHdFfDevice::Clear(void)
+{
+ CHECK(ioctl(fd_video, VIDEO_CLEAR_BUFFER));
+ mHdffCmdIf->CmdAvSetVideoPid(0, 0, HDFF::videoStreamMpeg1);
+ mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF::audioStreamMpeg1);
+ playVideoPid = -1;
+ playAudioPid = -1;
+ cDevice::Clear();
+}
+
+void cDvbHdFfDevice::Play(void)
+{
+ mHdffCmdIf->CmdAvEnableSync(0, true);
+ mHdffCmdIf->CmdAvSetVideoSpeed(0, 100);
+ mHdffCmdIf->CmdAvSetAudioSpeed(0, 100);
+ cDevice::Play();
+}
+
+void cDvbHdFfDevice::Freeze(void)
+{
+ mHdffCmdIf->CmdAvSetVideoSpeed(0, 0);
+ mHdffCmdIf->CmdAvSetAudioSpeed(0, 0);
+ cDevice::Freeze();
+}
+
+void cDvbHdFfDevice::Mute(void)
+{
+ //TODO???
+ cDevice::Mute();
+}
+
+static HDFF::eVideoStreamType MapVideoStreamTypes(int Vtype)
+{
+ switch (Vtype) {
+ case 0x01: return HDFF::videoStreamMpeg1;
+ case 0x02: return HDFF::videoStreamMpeg2;
+ case 0x1B: return HDFF::videoStreamH264;
+ default: return HDFF::videoStreamMpeg2; // 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)
+{
+ //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::videoStreamMpeg2, true);
+ }
+ if (WriteAllOrNothing(fd_video, tsBuffer, tsLength, 1000, 10) <= 0)
+ Length = 0;
+ return Length;
+}
+
+int cDvbHdFfDevice::PlayAudio(const uchar *Data, int Length, uchar Id)
+{
+ uint8_t streamId;
+ uint8_t tsBuffer[188 * 16];
+ uint32_t tsLength;
+ HDFF::eAudioStreamType streamType = HDFF::audioStreamMpeg1;
+ HDFF::eAVContainerType containerType = HDFF::avContainerPes;
+ int pid;
+
+ streamId = Data[3];
+ if (streamId >= 0xC0 && streamId <= 0xDF)
+ {
+ streamType = HDFF::audioStreamMpeg1;
+ }
+ else if (streamId == 0xBD)
+ {
+ const uint8_t * payload = Data + 9 + Data[8];
+ if ((payload[0] & 0xF8) == 0xA0)
+ {
+ containerType = HDFF::avContainerPesDvd;
+ streamType = HDFF::audioStreamPcm;
+ }
+ else if ((payload[0] & 0xF8) == 0x88)
+ {
+ containerType = HDFF::avContainerPesDvd;
+ streamType = HDFF::audioStreamDts;
+ }
+ else if ((payload[0] & 0xF8) == 0x80)
+ {
+ containerType = HDFF::avContainerPesDvd;
+ streamType = HDFF::audioStreamAc3;
+ }
+ else
+ {
+ streamType = HDFF::audioStreamAc3;
+ }
+ }
+ 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)
+{
+ int pid = TsPid(Data);
+ if (pid != playVideoPid) {
+ PatPmtParser();
+ if (pid == PatPmtParser()->Vpid()) {
+ playVideoPid = pid;
+ mHdffCmdIf->CmdAvSetVideoPid(0, playVideoPid, MapVideoStreamTypes(PatPmtParser()->Vtype()), true);
+ }
+ }
+ return WriteAllOrNothing(fd_video, Data, Length, 1000, 10);
+}
+
+static HDFF::eAudioStreamType MapAudioStreamTypes(int Atype)
+{
+ switch (Atype) {
+ case 0x03: return HDFF::audioStreamMpeg1;
+ case 0x04: return HDFF::audioStreamMpeg2;
+ case SI::AC3DescriptorTag: return HDFF::audioStreamAc3;
+ case SI::EnhancedAC3DescriptorTag: return HDFF::audioStreamEAc3;
+ case 0x0F: return HDFF::audioStreamAac;
+ case 0x11: return HDFF::audioStreamHeAac;
+ default: return HDFF::audioStreamMaxValue; // there is no HDFF::audioStreamNone
+ }
+}
+
+int cDvbHdFfDevice::PlayTsAudio(const uchar *Data, int Length)
+{
+ 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 ---------------------------------------------------
+
+bool cDvbHdFfDeviceProbe::Probe(int Adapter, int Frontend)
+{
+ static uint32_t SubsystemIds[] = {
+ 0x13C23009, // Technotrend S2-6400 HDFF
+ 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");
+ new cDvbHdFfDevice(Adapter, Frontend);
+ return true;
+ }
+ }
+ }
+ return false;
+}
diff --git a/PLUGINS/src/dvbhddevice/dvbhdffdevice.h b/PLUGINS/src/dvbhddevice/dvbhdffdevice.h
new file mode 100644
index 0000000..4dcfb6a
--- /dev/null
+++ b/PLUGINS/src/dvbhddevice/dvbhdffdevice.h
@@ -0,0 +1,123 @@
+/*
+ * dvbhdffdevice.h: The DVB HD Full Featured device interface
+ *
+ * See the README file for copyright information and how to reach the author.
+ *
+ * $Id: dvbhdffdevice.h 1.6 2010/03/13 11:18:13 kls Exp $
+ */
+
+#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;
+protected:
+ virtual void MakePrimaryDevice(bool On);
+public:
+ static bool Probe(int Adapter, int Frontend);
+ cDvbHdFfDevice(int Adapter, int Frontend);
+ virtual ~cDvbHdFfDevice();
+ virtual bool HasDecoder(void) const;
+
+// SPU facilities
+
+private:
+ cDvbSpuDecoder *spuDecoder;
+public:
+ virtual cSpuDecoder *GetSpuDecoder(void);
+
+// Channel facilities
+
+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 SetVideoFormat(bool VideoFormat16_9);
+ virtual eVideoSystem GetVideoSystem(void);
+ 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);
+ virtual void SetDigitalAudioDevice(bool On);
+
+// Player facilities
+
+private:
+ int playVideoPid;
+ int playAudioPid;
+
+ // 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 void TrickSpeed(int Speed);
+ 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 {
+public:
+ virtual bool Probe(int Adapter, int Frontend);
+ };
+
+#endif //__DVBHDFFDEVICE_H
diff --git a/PLUGINS/src/dvbhddevice/hdffcmd.c b/PLUGINS/src/dvbhddevice/hdffcmd.c
new file mode 100644
index 0000000..ecd26ed
--- /dev/null
+++ b/PLUGINS/src/dvbhddevice/hdffcmd.c
@@ -0,0 +1,1120 @@
+/*
+ * hdffcmd.c: TODO(short description)
+ *
+ * See the README file for copyright information and how to reach the author.
+ *
+ * $Id: hdffcmd.c 1.19 2011/04/17 11:20:22 kls Exp $
+ */
+
+#include "hdffcmd.h"
+#include <linux/dvb/osd.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.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)
+{
+}
+
+void cHdffCmdIf::CmdBuildHeader(cBitBuffer & MsgBuf, eMessageType MsgType, eMessageGroup MsgGroup, eMessageId MsgId)
+{
+ MsgBuf.SetBits(16, 0); // length field will be set later
+ MsgBuf.SetBits(6, 0); // reserved
+ MsgBuf.SetBits(2, MsgType);
+ MsgBuf.SetBits(8, MsgGroup);
+ MsgBuf.SetBits(16, MsgId);
+}
+
+uint32_t cHdffCmdIf::CmdSetLength(cBitBuffer & MsgBuf)
+{
+ uint32_t length;
+
+ length = MsgBuf.GetByteLength() - 2;
+ MsgBuf.SetDataByte(0, (uint8_t) (length >> 8));
+ MsgBuf.SetDataByte(1, (uint8_t) length);
+
+ return length + 2;
+}
+
+
+uint32_t cHdffCmdIf::CmdGetFirmwareVersion(char * pString, uint32_t MaxLength)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ cBitBuffer resBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ osd_cmd.result_data = resBuf.GetData();
+ osd_cmd.result_len = resBuf.GetMaxLength();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupGeneric, msgGenGetFirmwareVersion);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+ if (osd_cmd.result_len > 0)
+ {
+ uint8_t * result = resBuf.GetData();
+ uint8_t textLength = result[9];
+ if (textLength >= MaxLength)
+ textLength = MaxLength - 1;
+ memcpy(pString, &result[10], textLength);
+ pString[textLength] = 0;
+ return (result[6] << 16) | (result[7] << 8) | result[8];
+ }
+ return 0;
+}
+
+uint32_t cHdffCmdIf::CmdGetInterfaceVersion(char * pString, uint32_t MaxLength)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ cBitBuffer resBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ osd_cmd.result_data = resBuf.GetData();
+ osd_cmd.result_len = resBuf.GetMaxLength();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupGeneric, msgGenGetInterfaceVersion);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+ if (osd_cmd.result_len > 0)
+ {
+ uint8_t * result = resBuf.GetData();
+ uint8_t textLength = result[9];
+ if (textLength >= MaxLength)
+ textLength = MaxLength - 1;
+ memcpy(pString, &result[10], textLength);
+ pString[textLength] = 0;
+ return (result[6] << 16) | (result[7] << 8) | result[8];
+ }
+ return 0;
+}
+
+uint32_t cHdffCmdIf::CmdGetCopyrights(uint8_t Index, char * pString, uint32_t MaxLength)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ cBitBuffer resBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ osd_cmd.result_data = resBuf.GetData();
+ osd_cmd.result_len = resBuf.GetMaxLength();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupGeneric, msgGenGetCopyrights);
+ cmdBuf.SetBits(8, Index);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+ if (osd_cmd.result_len > 0)
+ {
+ uint8_t * result = resBuf.GetData();
+ uint8_t index = result[6];
+ uint8_t textLen = result[7];
+ if (index == Index && textLen > 0)
+ {
+ if (textLen >= MaxLength)
+ {
+ textLen = MaxLength - 1;
+ }
+ memcpy(pString, result + 8, textLen);
+ pString[textLen] = 0;
+ return textLen;
+ }
+ }
+ return 0;
+}
+
+
+void cHdffCmdIf::CmdAvSetPlayMode(uint8_t PlayMode, bool Realtime)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupAvDec, msgAvSetPlayMode);
+ cmdBuf.SetBits(1, Realtime ? 1 : 0);
+ cmdBuf.SetBits(7, PlayMode);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdAvSetVideoPid(uint8_t DecoderIndex, uint16_t VideoPid, eVideoStreamType StreamType, bool PlaybackMode)
+{
+ //printf("SetVideoPid %d %d\n", VideoPid, StreamType);
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupAvDec, msgAvSetVideoPid);
+ cmdBuf.SetBits(4, DecoderIndex);
+ cmdBuf.SetBits(4, StreamType);
+ cmdBuf.SetBits(1, PlaybackMode ? 1 : 0);
+ cmdBuf.SetBits(15, VideoPid);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdAvSetAudioPid(uint8_t DecoderIndex, uint16_t AudioPid, eAudioStreamType StreamType, eAVContainerType ContainerType)
+{
+ //printf("SetAudioPid %d %d %d\n", AudioPid, StreamType, ContainerType);
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupAvDec, msgAvSetAudioPid);
+ cmdBuf.SetBits(4, DecoderIndex);
+ cmdBuf.SetBits(4, StreamType);
+ cmdBuf.SetBits(2, 0); // reserved
+ cmdBuf.SetBits(1, ContainerType);
+ cmdBuf.SetBits(13, AudioPid);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdAvSetPcrPid(uint8_t DecoderIndex, uint16_t PcrPid)
+{
+ //printf("SetPcrPid %d\n", PcrPid);
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupAvDec, msgAvSetPcrPid);
+ cmdBuf.SetBits(4, DecoderIndex);
+ cmdBuf.SetBits(4, 0); // reserved
+ cmdBuf.SetBits(16, PcrPid);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdAvSetTeletextPid(uint8_t DecoderIndex, uint16_t TeletextPid)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupAvDec, msgAvSetTeletextPid);
+ cmdBuf.SetBits(4, DecoderIndex);
+ cmdBuf.SetBits(4, 0); // reserved
+ cmdBuf.SetBits(16, TeletextPid);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdAvSetVideoWindow(uint8_t DecoderIndex, bool Enable, uint16_t X, uint16_t Y, uint16_t Width, uint16_t Height)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupAvDec, msgAvSetVideoWindow);
+ cmdBuf.SetBits(4, DecoderIndex);
+ cmdBuf.SetBits(3, 0); // reserved
+ if (Enable)
+ cmdBuf.SetBits(1, 1);
+ else
+ cmdBuf.SetBits(1, 0);
+ cmdBuf.SetBits(16, X);
+ cmdBuf.SetBits(16, Y);
+ cmdBuf.SetBits(16, Width);
+ cmdBuf.SetBits(16, Height);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdAvShowStillImage(uint8_t DecoderIndex, const uint8_t * pStillImage, int Size, eVideoStreamType StreamType)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+ osd_raw_data_t osd_data;
+
+ memset(&osd_data, 0, sizeof(osd_raw_data_t));
+ osd_data.data_buffer = (void *) pStillImage;
+ osd_data.data_length = Size;
+ ioctl(mOsdDev, OSD_RAW_DATA, &osd_data);
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupAvDec, msgAvShowStillImage);
+ cmdBuf.SetBits(4, DecoderIndex);
+ cmdBuf.SetBits(4, StreamType);
+ cmdBuf.SetBits(16, osd_data.data_handle);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdAvSetDecoderInput(uint8_t DecoderIndex, uint8_t DemultiplexerIndex)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupAvDec, msgAvSetDecoderInput);
+ cmdBuf.SetBits(4, DecoderIndex);
+ cmdBuf.SetBits(4, DemultiplexerIndex);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdAvSetDemultiplexerInput(uint8_t DemultiplexerIndex, uint8_t TsInputIndex)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupAvDec, msgAvSetDemultiplexerInput);
+ cmdBuf.SetBits(4, DemultiplexerIndex);
+ cmdBuf.SetBits(4, TsInputIndex);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdAvSetVideoFormat(uint8_t DecoderIndex, const tVideoFormat * pVideoFormat)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupAvDec, msgAvSetVideoFormat);
+ cmdBuf.SetBits(4, DecoderIndex);
+ if (pVideoFormat->AutomaticEnabled)
+ {
+ cmdBuf.SetBits(1, 1);
+ }
+ else
+ {
+ cmdBuf.SetBits(1, 0);
+ }
+ if (pVideoFormat->AfdEnabled)
+ {
+ cmdBuf.SetBits(1, 1);
+ }
+ else
+ {
+ cmdBuf.SetBits(1, 0);
+ }
+ cmdBuf.SetBits(2, pVideoFormat->TvFormat);
+ cmdBuf.SetBits(8, pVideoFormat->VideoConversion);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdAvSetVideoOutputMode(uint8_t DecoderIndex, eVideoOutputMode OutputMode)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupAvDec, msgAvSetVideoOutputMode);
+ cmdBuf.SetBits(8, OutputMode);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdAvSetStc(uint8_t DecoderIndex, uint64_t Stc)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupAvDec, msgAvSetStc);
+ cmdBuf.SetBits(4, DecoderIndex);
+ cmdBuf.SetBits(3, 0); // reserved
+ cmdBuf.SetBits(1, (uint32_t) (Stc >> 32));
+ cmdBuf.SetBits(32, (uint32_t) Stc);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdAvFlushBuffer(uint8_t DecoderIndex, bool FlushAudio, bool FlushVideo)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupAvDec, msgAvFlushBuffer);
+ cmdBuf.SetBits(4, DecoderIndex);
+ if (FlushAudio)
+ {
+ cmdBuf.SetBits(1, 1);
+ }
+ else
+ {
+ cmdBuf.SetBits(1, 0);
+ }
+ if (FlushVideo)
+ {
+ cmdBuf.SetBits(1, 1);
+ }
+ else
+ {
+ cmdBuf.SetBits(1, 0);
+ }
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdAvEnableSync(uint8_t DecoderIndex, bool EnableSync)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupAvDec, msgAvEnableSync);
+ cmdBuf.SetBits(4, DecoderIndex);
+ if (EnableSync)
+ {
+ cmdBuf.SetBits(1, 1);
+ cmdBuf.SetBits(1, 1);
+ }
+ else
+ {
+ cmdBuf.SetBits(1, 0);
+ cmdBuf.SetBits(1, 0);
+ }
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdAvSetVideoSpeed(uint8_t DecoderIndex, int32_t Speed)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupAvDec, msgAvSetVideoSpeed);
+ cmdBuf.SetBits(4, DecoderIndex);
+ cmdBuf.SetBits(4, 0);
+ cmdBuf.SetBits(32, Speed);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdAvSetAudioSpeed(uint8_t DecoderIndex, int32_t Speed)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupAvDec, msgAvSetAudioSpeed);
+ cmdBuf.SetBits(4, DecoderIndex);
+ cmdBuf.SetBits(4, 0);
+ cmdBuf.SetBits(32, Speed);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdAvEnableVideoAfterStop(uint8_t DecoderIndex, bool EnableVideoAfterStop)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupAvDec, msgAvEnableVideoAfterStop);
+ cmdBuf.SetBits(4, DecoderIndex);
+ if (EnableVideoAfterStop)
+ {
+ cmdBuf.SetBits(1, 1);
+ }
+ else
+ {
+ cmdBuf.SetBits(1, 0);
+ }
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdAvSetAudioDelay(int16_t Delay)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupAvDec, msgAvSetAudioDelay);
+ cmdBuf.SetBits(16, Delay);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdAvSetAudioDownmix(eDownmixMode DownmixMode)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupAvDec, msgAvSetAudioDownmix);
+ cmdBuf.SetBits(8, DownmixMode);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdAvSetAudioChannel(uint8_t AudioChannel)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupAvDec, msgAvSetAudioChannel);
+ cmdBuf.SetBits(8, AudioChannel);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+
+void cHdffCmdIf::CmdOsdConfigure(const tOsdConfig * pConfig)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupOsd, msgOsdConfigure);
+ if (pConfig->FontAntialiasing)
+ {
+ cmdBuf.SetBits(1, 1);
+ }
+ else
+ {
+ cmdBuf.SetBits(1, 0);
+ }
+ if (pConfig->FontKerning)
+ {
+ cmdBuf.SetBits(1, 1);
+ }
+ else
+ {
+ cmdBuf.SetBits(1, 0);
+ }
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdOsdReset(void)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupOsd, msgOsdReset);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+uint32_t cHdffCmdIf::CmdOsdCreateDisplay(uint32_t Width, uint32_t Height, eColorType ColorType)
+{
+ //printf("CreateDisplay %d %d %d\n", Width, Height, ColorType);
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ cBitBuffer resBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ osd_cmd.result_data = resBuf.GetData();
+ osd_cmd.result_len = resBuf.GetMaxLength();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupOsd, msgOsdCreateDisplay);
+ cmdBuf.SetBits(16, Width);
+ cmdBuf.SetBits(16, Height);
+ cmdBuf.SetBits(8, ColorType);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+ if (osd_cmd.result_len > 0)
+ {
+ uint8_t * result = resBuf.GetData();
+ return (result[6] << 24) | (result[7] << 16) | (result[8] << 8) | result[9];
+ }
+ return InvalidHandle;
+}
+
+void cHdffCmdIf::CmdOsdDeleteDisplay(uint32_t hDisplay)
+{
+ //printf("DeleteDisplay\n");
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupOsd, msgOsdDeleteDisplay);
+ cmdBuf.SetBits(32, hDisplay);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdOsdEnableDisplay(uint32_t hDisplay, bool Enable)
+{
+ //printf("EnableDisplay\n");
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupOsd, msgOsdEnableDisplay);
+ cmdBuf.SetBits(32, hDisplay);
+ if (Enable)
+ {
+ cmdBuf.SetBits(1, 1);
+ }
+ else
+ {
+ cmdBuf.SetBits(1, 0);
+ }
+ cmdBuf.SetBits(7, 0); // reserved
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+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);
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupOsd, msgOsdSetDisplayOutputRectangle);
+ cmdBuf.SetBits(32, hDisplay);
+ cmdBuf.SetBits(16, X);
+ cmdBuf.SetBits(16, Y);
+ cmdBuf.SetBits(16, Width);
+ cmdBuf.SetBits(16, Height);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+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);
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupOsd, msgOsdSetDisplayClippingArea);
+ cmdBuf.SetBits(32, hDisplay);
+ if (Enable)
+ {
+ cmdBuf.SetBits(1, 1);
+ }
+ else
+ {
+ cmdBuf.SetBits(1, 0);
+ }
+ cmdBuf.SetBits(7, 0); // reserved
+ cmdBuf.SetBits(16, X);
+ cmdBuf.SetBits(16, Y);
+ cmdBuf.SetBits(16, Width);
+ cmdBuf.SetBits(16, Height);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdOsdRenderDisplay(uint32_t hDisplay)
+{
+ //printf("Render\n");
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupOsd, msgOsdRenderDisplay);
+ cmdBuf.SetBits(32, hDisplay);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+uint32_t cHdffCmdIf::CmdOsdCreatePalette(eColorType ColorType, eColorFormat ColorFormat,
+ uint32_t NumColors, const uint32_t * pColors)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ cBitBuffer resBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+ uint32_t i;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ osd_cmd.result_data = resBuf.GetData();
+ osd_cmd.result_len = resBuf.GetMaxLength();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupOsd, msgOsdCreatePalette);
+ cmdBuf.SetBits(8, ColorType);
+ cmdBuf.SetBits(8, ColorFormat);
+ if (NumColors > 256)
+ NumColors = 256;
+ cmdBuf.SetBits(8, NumColors == 256 ? 0 : NumColors);
+ for (i = 0; i < NumColors; i++)
+ {
+ cmdBuf.SetBits(32, pColors[i]);
+ }
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+ if (osd_cmd.result_len > 0)
+ {
+ uint8_t * result = resBuf.GetData();
+ return (result[6] << 24) | (result[7] << 16) | (result[8] << 8) | result[9];
+ }
+ return InvalidHandle;
+}
+
+void cHdffCmdIf::CmdOsdDeletePalette(uint32_t hPalette)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupOsd, msgOsdDeletePalette);
+ cmdBuf.SetBits(32, hPalette);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdOsdSetDisplayPalette(uint32_t hDisplay, uint32_t hPalette)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupOsd, msgOsdSetDisplayPalette);
+ cmdBuf.SetBits(32, hDisplay);
+ cmdBuf.SetBits(32, hPalette);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdOsdSetPaletteColors(uint32_t hPalette, eColorFormat ColorFormat,
+ uint8_t StartColor, uint32_t NumColors, const uint32_t * pColors)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+ uint32_t i;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupOsd, msgOsdSetPaletteColors);
+ cmdBuf.SetBits(32, hPalette);
+ cmdBuf.SetBits(8, ColorFormat);
+ cmdBuf.SetBits(8, StartColor);
+ if (NumColors > 256)
+ NumColors = 256;
+ cmdBuf.SetBits(8, NumColors == 256 ? 0 : NumColors);
+ for (i = 0; i < NumColors; i++)
+ {
+ cmdBuf.SetBits(32, pColors[i]);
+ }
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+uint32_t cHdffCmdIf::CmdOsdCreateFontFace(const uint8_t * pFontData, uint32_t DataSize)
+{
+ //printf("CreateFontFace %d\n", DataSize);
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ cBitBuffer resBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+ osd_raw_data_t osd_data;
+
+ memset(&osd_data, 0, sizeof(osd_raw_data_t));
+ osd_data.data_buffer = pFontData;
+ osd_data.data_length = DataSize;
+ ioctl(mOsdDev, OSD_RAW_DATA, &osd_data);
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ osd_cmd.result_data = resBuf.GetData();
+ osd_cmd.result_len = resBuf.GetMaxLength();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupOsd, msgOsdCreateFontFace);
+ cmdBuf.SetBits(16, osd_data.data_handle);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+ if (osd_cmd.result_len > 0)
+ {
+ uint8_t * result = resBuf.GetData();
+ return (result[6] << 24) | (result[7] << 16) | (result[8] << 8) | result[9];
+ }
+ return InvalidHandle;
+}
+
+void cHdffCmdIf::CmdOsdDeleteFontFace(uint32_t hFontFace)
+{
+ //printf("DeleteFontFace %08X\n", hFontFace);
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupOsd, msgOsdDeleteFontFace);
+ cmdBuf.SetBits(32, hFontFace);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+uint32_t cHdffCmdIf::CmdOsdCreateFont(uint32_t hFontFace, uint32_t Size)
+{
+ //printf("CreateFont %d\n", Size);
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ cBitBuffer resBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ osd_cmd.result_data = resBuf.GetData();
+ osd_cmd.result_len = resBuf.GetMaxLength();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupOsd, msgOsdCreateFont);
+ cmdBuf.SetBits(32, hFontFace);
+ cmdBuf.SetBits(32, Size);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+ if (osd_cmd.result_len > 0)
+ {
+ uint8_t * result = resBuf.GetData();
+ return (result[6] << 24) | (result[7] << 16) | (result[8] << 8) | result[9];
+ }
+ return InvalidHandle;
+}
+
+void cHdffCmdIf::CmdOsdDeleteFont(uint32_t hFont)
+{
+ //printf("DeleteFont %08X\n", hFont);
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupOsd, msgOsdDeleteFont);
+ cmdBuf.SetBits(32, hFont);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+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);
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupOsd, msgOsdDrawRectangle);
+ cmdBuf.SetBits(32, hDisplay);
+ cmdBuf.SetBits(16, X);
+ cmdBuf.SetBits(16, Y);
+ cmdBuf.SetBits(16, Width);
+ cmdBuf.SetBits(16, Height);
+ cmdBuf.SetBits(32, Color);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+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);
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupOsd, msgOsdDrawEllipse);
+ cmdBuf.SetBits(32, hDisplay);
+ cmdBuf.SetBits(16, CX);
+ cmdBuf.SetBits(16, CY);
+ cmdBuf.SetBits(16, RadiusX);
+ cmdBuf.SetBits(16, RadiusY);
+ cmdBuf.SetBits(32, Color);
+ cmdBuf.SetBits(32, Flags);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+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);
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+ int i;
+ int length;
+
+ length = 0;
+ while (pText[length])
+ {
+ length++;
+ }
+ if (length > 980)
+ length = 980;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupOsd, msgOsdDrawText);
+ cmdBuf.SetBits(32, hDisplay);
+ cmdBuf.SetBits(32, hFont);
+ cmdBuf.SetBits(16, X);
+ cmdBuf.SetBits(16, Y);
+ cmdBuf.SetBits(32, Color);
+ cmdBuf.SetBits(16, length);
+ for (i = 0; i < length; i++)
+ {
+ cmdBuf.SetBits(8, pText[i]);
+ }
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+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);
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+ int i;
+ int length;
+
+ length = 0;
+ while (pText[length])
+ {
+ length++;
+ }
+ if (length > 480)
+ length = 480;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupOsd, msgOsdDrawTextW);
+ cmdBuf.SetBits(32, hDisplay);
+ cmdBuf.SetBits(32, hFont);
+ cmdBuf.SetBits(16, X);
+ cmdBuf.SetBits(16, Y);
+ cmdBuf.SetBits(32, Color);
+ cmdBuf.SetBits(16, length);
+ for (i = 0; i < length; i++)
+ {
+ cmdBuf.SetBits(16, pText[i]);
+ }
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdOsdDrawBitmap(uint32_t hDisplay, int X, int Y, const uint8_t * pBitmap,
+ int BmpWidth, int BmpHeight, int BmpSize,
+ eColorType ColorType, uint32_t hPalette)
+{
+ //printf("Bitmap (%d,%d) %d x %d\n", X, Y, BmpWidth, BmpHeight);
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+ osd_raw_data_t osd_data;
+
+ memset(&osd_data, 0, sizeof(osd_raw_data_t));
+ osd_data.data_buffer = pBitmap;
+ osd_data.data_length = BmpSize;
+ ioctl(mOsdDev, OSD_RAW_DATA, &osd_data);
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupOsd, msgOsdDrawBitmap);
+ cmdBuf.SetBits(32, hDisplay);
+ cmdBuf.SetBits(16, X);
+ cmdBuf.SetBits(16, Y);
+ cmdBuf.SetBits(16, BmpWidth);
+ cmdBuf.SetBits(16, BmpHeight);
+ cmdBuf.SetBits(8, ColorType);
+ cmdBuf.SetBits(6, 0); // reserved
+ cmdBuf.SetBits(2, 0); // uncompressed
+ cmdBuf.SetBits(32, hPalette);
+ cmdBuf.SetBits(16, osd_data.data_handle);
+ cmdBuf.SetBits(32, 0);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdOsdSaveRegion(uint32_t hDisplay, int X, int Y, int Width, int Height)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupOsd, msgOsdSaveRegion);
+ cmdBuf.SetBits(32, hDisplay);
+ cmdBuf.SetBits(16, X);
+ cmdBuf.SetBits(16, Y);
+ cmdBuf.SetBits(16, Width);
+ cmdBuf.SetBits(16, Height);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdOsdRestoreRegion(uint32_t hDisplay)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupOsd, msgOsdRestoreRegion);
+ cmdBuf.SetBits(32, hDisplay);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdMuxSetVideoOut(eVideoOut VideoOut)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupAvMux, msgMuxSetVideoOut);
+ cmdBuf.SetBits(4, VideoOut);
+ cmdBuf.SetBits(4, 0); // reserved
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdMuxSetVolume(uint8_t Volume)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupAvMux, msgMuxSetVolume);
+ cmdBuf.SetBits(8, Volume);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdMuxMuteAudio(bool Mute)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupAvMux, msgMuxSetAudioMute);
+ cmdBuf.SetBits(1, Mute);
+ cmdBuf.SetBits(7, 0); // reserved
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdHdmiSetVideoMode(eHdmiVideoMode VideoMode)
+{
+ //printf("HdmiSetVideoMode %d\n", VideoMode);
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupHdmi, msgHdmiSetVideoMode);
+ cmdBuf.SetBits(8, VideoMode);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdHdmiConfigure(const tHdmiConfig * pConfig)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupHdmi, msgHdmiConfigure);
+ if (pConfig->TransmitAudio)
+ {
+ cmdBuf.SetBits(1, 1);
+ }
+ else
+ {
+ cmdBuf.SetBits(1, 0);
+ }
+ if (pConfig->ForceDviMode)
+ {
+ cmdBuf.SetBits(1, 1);
+ }
+ else
+ {
+ cmdBuf.SetBits(1, 0);
+ }
+ if (pConfig->CecEnabled)
+ {
+ cmdBuf.SetBits(1, 1);
+ }
+ else
+ {
+ cmdBuf.SetBits(1, 0);
+ }
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdHdmiSendCecCommand(eCecCommand Command)
+{
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupHdmi, msgHdmiSendCecCommand);
+ cmdBuf.SetBits(8, Command);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdRemoteSetProtocol(eRemoteProtocol Protocol)
+{
+ //printf("%s %d\n", __func__, Protocol);
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupRemoteControl, msgRemoteSetProtocol);
+ cmdBuf.SetBits(8, Protocol);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+void cHdffCmdIf::CmdRemoteSetAddressFilter(bool Enable, uint32_t Address)
+{
+ //printf("%s %d %d\n", __func__, Enable, Address);
+ cBitBuffer cmdBuf(MAX_CMD_LEN);
+ osd_raw_cmd_t osd_cmd;
+
+ memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t));
+ osd_cmd.cmd_data = cmdBuf.GetData();
+ CmdBuildHeader(cmdBuf, msgTypeCommand, msgGroupRemoteControl, msgRemoteSetAddressFilter);
+ cmdBuf.SetBits(1, Enable);
+ cmdBuf.SetBits(7, 0); // reserved
+ cmdBuf.SetBits(32, Address);
+ osd_cmd.cmd_len = CmdSetLength(cmdBuf);
+ ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd);
+}
+
+} // end of namespace
diff --git a/PLUGINS/src/dvbhddevice/hdffcmd.h b/PLUGINS/src/dvbhddevice/hdffcmd.h
new file mode 100644
index 0000000..cd641eb
--- /dev/null
+++ b/PLUGINS/src/dvbhddevice/hdffcmd.h
@@ -0,0 +1,102 @@
+/*
+ * hdffcmd.h: TODO(short description)
+ *
+ * See the README file for copyright information and how to reach the author.
+ *
+ * $Id: hdffcmd.h 1.17 2011/04/17 11:20:22 kls Exp $
+ */
+
+#ifndef _HDFF_CMD_H_
+#define _HDFF_CMD_H_
+
+#include "bitbuffer.h"
+#include "hdffmsgdef.h"
+
+namespace HDFF
+{
+
+class cHdffCmdIf
+{
+private:
+ int mOsdDev;
+
+ void CmdBuildHeader(cBitBuffer & MsgBuf, eMessageType MsgType, eMessageGroup MsgGroup, eMessageId MsgId);
+ uint32_t CmdSetLength(cBitBuffer & MsgBuf);
+
+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, eVideoStreamType StreamType, bool PlaybackMode = false);
+ void CmdAvSetAudioPid(uint8_t DecoderIndex, uint16_t AudioPid, eAudioStreamType StreamType, eAVContainerType ContainerType = avContainerPes);
+ 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, eVideoStreamType StreamType);
+ void CmdAvSetDecoderInput(uint8_t DecoderIndex, uint8_t DemultiplexerIndex);
+ void CmdAvSetDemultiplexerInput(uint8_t DemultiplexerIndex, uint8_t TsInputIndex);
+ void CmdAvSetVideoFormat(uint8_t DecoderIndex, const tVideoFormat * pVideoFormat);
+ void CmdAvSetVideoOutputMode(uint8_t DecoderIndex, eVideoOutputMode 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(eDownmixMode DownmixMode);
+ void CmdAvSetAudioChannel(uint8_t AudioChannel);
+
+ void CmdOsdConfigure(const tOsdConfig * pConfig);
+ void CmdOsdReset(void);
+
+ uint32_t CmdOsdCreateDisplay(uint32_t Width, uint32_t Height, eColorType 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(eColorType ColorType, eColorFormat 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, eColorFormat 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 CmdOsdDrawText(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,
+ eColorType ColorType, uint32_t hPalette);
+ void CmdOsdSaveRegion(uint32_t hDisplay, int X, int Y, int Width, int Height);
+ void CmdOsdRestoreRegion(uint32_t hDisplay);
+
+ void CmdMuxSetVideoOut(eVideoOut VideoOut);
+ void CmdMuxSetVolume(uint8_t Volume);
+ void CmdMuxMuteAudio(bool Mute);
+
+ void CmdHdmiSetVideoMode(eHdmiVideoMode VideoMode);
+ void CmdHdmiConfigure(const tHdmiConfig * pConfig);
+ void CmdHdmiSendCecCommand(eCecCommand Command);
+
+ void CmdRemoteSetProtocol(eRemoteProtocol Protocol);
+ void CmdRemoteSetAddressFilter(bool Enable, uint32_t Address);
+};
+
+} // end of namespace
+
+#endif
diff --git a/PLUGINS/src/dvbhddevice/hdffmsgdef.h b/PLUGINS/src/dvbhddevice/hdffmsgdef.h
new file mode 100644
index 0000000..a6c3f4b
--- /dev/null
+++ b/PLUGINS/src/dvbhddevice/hdffmsgdef.h
@@ -0,0 +1,304 @@
+/*
+ * hdffmsgdef.h: TODO(short description)
+ *
+ * See the README file for copyright information and how to reach the author.
+ *
+ * $Id: hdffmsgdef.h 1.12 2011/04/17 11:20:22 kls Exp $
+ */
+
+#ifndef _HDFF_MSGDEF_H_
+#define _HDFF_MSGDEF_H_
+
+#define MAX_CMD_LEN 1536
+
+namespace HDFF
+{
+
+typedef enum _eMessageType
+{
+ msgTypeCommand,
+ msgTypeAnswer,
+ msgTypeResult,
+ msgTypeEvent
+} eMessageType;
+
+typedef enum _eMessageGroup
+{
+ msgGroupGeneric,
+ msgGroupAvDec,
+ msgGroupAvMux,
+ msgGroupFrontend,
+ msgGroupOsd,
+ msgGroupHdmi,
+ msgGroupRemoteControl
+} eMessageGroup;
+
+typedef enum _eMessageId
+{
+ msgGenGetFirmwareVersion = 0,
+ msgGenGetInterfaceVersion,
+ msgGenGetCopyrights,
+
+ msgAvSetAudioPid = 0,
+ msgAvSetVideoPid,
+ msgAvSetPcrPid,
+ msgAvSetTeletextPid,
+ msgAvShowStillImage,
+ msgAvSetVideoWindow,
+ msgAvSetDecoderInput,
+ msgAvSetDemultiplexerInput,
+ msgAvSetVideoFormat,
+ msgAvSetVideoOutputMode,
+ msgAvSetStc,
+ msgAvFlushBuffer,
+ msgAvEnableSync,
+ msgAvSetVideoSpeed,
+ msgAvSetAudioSpeed,
+ msgAvEnableVideoAfterStop,
+ msgAvGetVideoFormatInfo,
+ msgAvSetAudioDelay,
+ msgAvSetAudioDownmix,
+ msgAvSetAudioChannel,
+ msgAvSetPlayMode,
+
+ msgMuxSetVideoOut = 0,
+ msgMuxSetSlowBlank,
+ msgMuxSetFastBlank,
+ msgMuxSetVolume,
+ msgMuxSetAudioMute,
+
+ msgOsdConfigure = 0,
+ msgOsdReset,
+ msgOsdCreateDisplay = 10,
+ msgOsdDeleteDisplay,
+ msgOsdEnableDisplay,
+ msgOsdSetDisplayOutputRectangle,
+ msgOsdSetDisplayClippingArea,
+ msgOsdRenderDisplay,
+ msgOsdSaveRegion,
+ msgOsdRestoreRegion,
+ msgOsdCreatePalette = 30,
+ msgOsdDeletePalette,
+ msgOsdSetDisplayPalette,
+ msgOsdSetPaletteColors,
+ msgOsdCreateFontFace = 50,
+ msgOsdDeleteFontFace,
+ msgOsdCreateFont,
+ msgOsdDeleteFont,
+ msgOsdDrawPixel = 70,
+ msgOsdDrawRectangle,
+ msgOsdDrawCircle,
+ msgOsdDrawEllipse,
+ msgOsdDrawSlope,
+ msgOsdDrawText,
+ msgOsdDrawTextW,
+ msgOsdDrawBitmap,
+
+ msgHdmiEnableOutput = 0,
+ msgHdmiSetVideoMode,
+ msgHdmiConfigure,
+ msgHdmiIsDisplayConnected,
+ msgHdmiGetDisplayInfo,
+ msgHdmiGetVideoMode,
+ msgHdmiSendCecCommand,
+
+ msgRemoteSetProtocol = 0,
+ msgRemoteSetAddressFilter,
+ msgRemoteKeyEvent
+} eMessageId;
+
+
+// AvDec definitions
+
+typedef enum _eAVContainerType
+{
+ avContainerPes,
+ avContainerPesDvd,
+ avContainerMaxValue
+} eAVContainerType;
+
+typedef enum _eAudioStreamType
+{
+ audioStreamMpeg1,
+ audioStreamMpeg2,
+ audioStreamAc3,
+ audioStreamAac,
+ audioStreamHeAac,
+ audioStreamPcm,
+ audioStreamEAc3,
+ audioStreamDts,
+ audioStreamMaxValue
+} eAudioStreamType;
+
+typedef enum _eVideoStreamType
+{
+ videoStreamMpeg1,
+ videoStreamMpeg2,
+ videoStreamH264,
+ videoStreamMpeg4Asp,
+ videoStreamVc1,
+ videoStreamMaxValue
+} eVideoStreamType;
+
+
+typedef enum _eTvFormat
+{
+ tvFormat4by3,
+ tvFormat16by9,
+ tvFormatMaxValue
+} eTvFormat;
+
+typedef enum _eVideoConversion
+{
+ videoConversionAutomatic,
+ videoConversionLetterbox16by9,
+ videoConversionLetterbox14by9,
+ videoConversionPillarbox,
+ videoConversionCentreCutOut,
+ videoConversionAlways16by9,
+ videoConversionMaxValue
+} eVideoConversion;
+
+typedef struct _tVideoFormat
+{
+ bool AutomaticEnabled;
+ bool AfdEnabled;
+ eTvFormat TvFormat;
+ eVideoConversion VideoConversion;
+} tVideoFormat;
+
+typedef enum _eVideoOutputMode
+{
+ videoOutputClone,
+ videoOutputDualView,
+ videoOutputMaxValue
+} eVideoOutputMode;
+
+typedef enum _eDownmixMode
+{
+ downmixOff,
+ downmixAnalog,
+ downmixAlways,
+ downmixAutomatic,
+ downmixHdmi
+} eDownmixMode;
+
+// AvMux definitions
+
+typedef enum _eVideoOut
+{
+ videoOutDisabled,
+ videoOutRgb,
+ videoOutCvbsYuv,
+ videoOutYc,
+ videoOutMaxValue
+} eVideoOut;
+
+typedef enum _eSlowBlank
+{
+ slowBlankOff,
+ slowBlank16by9,
+ slowBlank4by3,
+ slowBlankMaxValue
+} eSlowBlank;
+
+typedef enum _eFastBlank
+{
+ fastBlankCvbs,
+ fastBlankRgb,
+ fastBlankMaxValue
+} eFastBlank;
+
+
+// OSD definitions
+
+#define InvalidHandle 0xFFFFFFFF
+#define ScreenDisplayHandle 0xFFFFFFFE
+
+#define PositionScreenCentered 0xFFFF
+
+#define SizeFullScreen 0xFFFF
+#define SizeSameAsSource 0xFFFE
+
+#define FontFaceTiresias 0x00000000
+
+typedef enum _eColorType
+{
+ colorTypeClut1,
+ colorTypeClut2,
+ colorTypeClut4,
+ colorTypeClut8,
+ colorTypeARGB8888,
+ colorTypeARGB8565,
+ colorTypeARGB4444,
+ colorTypeARGB1555,
+} eColorType;
+
+typedef enum _eColorFormat
+{
+ colorFormatARGB,
+ colorFormatACbYCr,
+} eColorFormat;
+
+typedef enum _eDrawingFlags
+{
+ drawFull,
+ drawHalfTop,
+ drawHalfLeft,
+ drawHalfBottom,
+ drawHalfRight,
+ drawQuarterTopLeft,
+ drawQuarterTopRight,
+ drawQuarterBottomLeft,
+ drawQuarterBottomRight,
+ drawQuarterTopLeftInverted,
+ drawQuarterTopRightInverted,
+ drawQuarterBottomLeftInverted,
+ drawQuarterBottomRightInverted
+} eDrawingFlags;
+
+typedef struct _tOsdConfig
+{
+ bool FontAntialiasing;
+ bool FontKerning;
+} tOsdConfig;
+
+// HDMI definitions
+
+typedef enum _eHdmiVideoMode
+{
+ videoMode576p50 = 18,
+ videoMode720p50 = 19,
+ videoMode1080i50 = 20,
+ videoMode576i50 = 22,
+ videoModeMaxValue
+} eHdmiVideoMode;
+
+typedef enum _eCecCommand
+{
+ cecCommandTvOn,
+ cecCommandTvOff,
+ cecCommandActiveSource,
+ cecCommandInactiveSource
+} eCecCommand;
+
+typedef struct _tHdmiConfig
+{
+ bool TransmitAudio;
+ bool ForceDviMode;
+ bool CecEnabled;
+} tHdmiConfig;
+
+// Remote control definitions
+
+typedef enum _eRemoteProtocol
+{
+ remoteProtocolNone,
+ remoteProtocolRc5,
+ remoteProtocolRc6,
+ remoteProtocolMaxValue
+} eRemoteProtocol;
+
+} // end of namespace
+
+#endif
diff --git a/PLUGINS/src/dvbhddevice/hdffosd.c b/PLUGINS/src/dvbhddevice/hdffosd.c
new file mode 100644
index 0000000..254f2af
--- /dev/null
+++ b/PLUGINS/src/dvbhddevice/hdffosd.c
@@ -0,0 +1,755 @@
+/*
+ * 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.
+ *
+ * $Id: hdffosd.c 1.9 2011/04/17 11:20:22 kls Exp $
+ */
+
+#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 shown;
+ bool mChanged;
+ bool mBitmapModified;
+ uint32_t mDisplay;
+ tFontFace mFontFaces[MAX_NUM_FONTFACES];
+ tFont mFonts[MAX_NUM_FONTS];
+ uint32_t mBitmapPalette;
+ uint32_t mBitmapColors[256];
+ uint32_t mBitmapNumColors;
+
+protected:
+ virtual void SetActive(bool On);
+public:
+ cHdffOsd(int Left, int Top, HDFF::cHdffCmdIf * pHdffCmdIf, uint Level);
+ virtual ~cHdffOsd();
+ cBitmap *GetBitmap(int Area);
+ 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;
+ HDFF::tOsdConfig config;
+
+ //printf("cHdffOsd %d, %d, %d\n", Left, Top, Level);
+ mHdffCmdIf = pHdffCmdIf;
+ mLeft = Left;
+ mTop = Top;
+ shown = false;
+ mChanged = false;
+ mBitmapModified = false;
+ mBitmapPalette = InvalidHandle;
+ config.FontKerning = false;
+ config.FontAntialiasing = Setup.AntiAlias ? true : false;
+ mHdffCmdIf->CmdOsdConfigure(&config);
+
+ gHdffSetup.GetOsdSize(mDispWidth, mDispHeight, pixelAspect);
+ mDisplay = mHdffCmdIf->CmdOsdCreateDisplay(mDispWidth, mDispHeight, HDFF::colorTypeARGB8888);
+ mHdffCmdIf->CmdOsdSetDisplayOutputRectangle(mDisplay, 0, 0, SizeFullScreen, SizeFullScreen);
+ for (int i = 0; i < MAX_NUM_FONTFACES; i++)
+ {
+ mFontFaces[i].Name = "";
+ mFontFaces[i].Handle = InvalidHandle;
+ }
+ for (int i = 0; i < MAX_NUM_FONTS; i++)
+ {
+ mFonts[i].hFontFace = InvalidHandle;
+ mFonts[i].Size = 0;
+ mFonts[i].Handle = InvalidHandle;
+ }
+}
+
+cHdffOsd::~cHdffOsd()
+{
+ //printf("~cHdffOsd %d %d\n", mLeft, mTop);
+ SetActive(false);
+
+ for (int i = 0; i < MAX_NUM_FONTS; i++)
+ {
+ if (mFonts[i].Handle == InvalidHandle)
+ break;
+ mHdffCmdIf->CmdOsdDeleteFont(mFonts[i].Handle);
+ }
+ for (int i = 0; i < MAX_NUM_FONTFACES; i++)
+ {
+ if (mFontFaces[i].Handle == InvalidHandle)
+ break;
+ mHdffCmdIf->CmdOsdDeleteFontFace(mFontFaces[i].Handle);
+ }
+
+ if (mBitmapPalette != InvalidHandle)
+ mHdffCmdIf->CmdOsdDeletePalette(mBitmapPalette);
+ mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, 0, 0, mDispWidth, mDispHeight, 0);
+ mHdffCmdIf->CmdOsdRenderDisplay(mDisplay);
+ mHdffCmdIf->CmdOsdDeleteDisplay(mDisplay);
+}
+
+cBitmap * cHdffOsd::GetBitmap(int Area)
+{
+ //printf("GetBitmap %d\n", Area);
+ mChanged = true;
+ mBitmapModified = true;
+ return cOsd::GetBitmap(Area);
+}
+
+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)
+{
+ 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);
+ }
+ mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, 0, 0, mDispWidth, mDispHeight, 0);
+ mHdffCmdIf->CmdOsdRenderDisplay(mDisplay);
+ return cOsd::SetAreas(Areas, NumAreas);
+}
+
+void cHdffOsd::SetActive(bool On)
+{
+ if (On != Active())
+ {
+ cOsd::SetActive(On);
+ if (On)
+ {
+ }
+ else if (shown)
+ {
+ shown = false;
+ }
+ }
+}
+
+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;
+ mBitmapModified = false;
+}
+
+void cHdffOsd::RestoreRegion(void)
+{
+ mHdffCmdIf->CmdOsdRestoreRegion(mDisplay);
+ mChanged = true;
+ mBitmapModified = false;
+}
+
+void cHdffOsd::DrawPixel(int x, int y, tColor Color)
+{
+ //printf("DrawPixel\n");
+ mBitmapModified = false;
+}
+
+void cHdffOsd::DrawBitmap(int x, int y, const cBitmap &Bitmap, tColor ColorFg, tColor ColorBg, bool ReplacePalette, bool Overlay)
+{
+ //printf("DrawBitmap %d %d %d\n", x, y, Overlay);
+ 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 == InvalidHandle)
+ {
+ mBitmapPalette = mHdffCmdIf->CmdOsdCreatePalette(HDFF::colorTypeClut8,
+ HDFF::colorFormatARGB, numColors, mBitmapColors);
+ }
+ else
+ {
+ mHdffCmdIf->CmdOsdSetPaletteColors(mBitmapPalette,
+ HDFF::colorFormatARGB, 0, numColors, mBitmapColors);
+ }
+ mHdffCmdIf->CmdOsdDrawBitmap(mDisplay, mLeft + x, mTop + y,
+ (uint8_t *) Bitmap.Data(0, 0), Bitmap.Width(), Bitmap.Height(),
+ Bitmap.Width() * Bitmap.Height(), HDFF::colorTypeClut8, mBitmapPalette);
+#if 0
+ uint32_t * tmpBitmap = new uint32_t[Bitmap.Width() * Bitmap.Height()];
+ for (int ix = 0; ix < Bitmap.Width(); ix++)
+ {
+ for (int iy = 0; iy < Bitmap.Height(); iy++)
+ {
+ const tIndex * pixel = Bitmap.Data(ix, iy);
+ tColor color = Bitmap.Color(*pixel);
+ if (!Overlay || *pixel != 0)
+ {
+ if (ColorFg || ColorBg)
+ {
+ if (*pixel == 0)
+ color = ColorBg;
+ else if (*pixel == 1)
+ color = ColorFg;
+ }
+ tmpBitmap[Bitmap.Width() * iy + ix] = color;
+ }
+ }
+ }
+ mHdffCmdIf->CmdOsdDrawBitmap(mDisplay, mLeft + x, mTop + y,
+ (uint8_t *) tmpBitmap, Bitmap.Width(), Bitmap.Height(),
+ Bitmap.Width() * Bitmap.Height() * 4, HDFF::colorTypeARGB8888, InvalidHandle);
+ delete[] tmpBitmap;
+#endif
+ mChanged = true;
+ mBitmapModified = false;
+}
+
+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 limit = 0;
+ 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 == InvalidHandle)
+ 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 != InvalidHandle)
+ {
+ 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 == InvalidHandle)
+ 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 != InvalidHandle)
+ {
+ 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)
+ {
+ limit = x + cw;// - mLeft;
+ if (Width)
+ {
+ if ((Alignment & taLeft) != 0)
+ ;
+ else if ((Alignment & taRight) != 0)
+ {
+ if (w < Width)
+ x += Width - w;
+ }
+ 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;
+ }
+ }
+ }
+ //x -= mLeft;
+ //y -= mTop;
+ {
+ 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->CmdOsdDrawText(mDisplay, pFont->Handle, x + mLeft, y + mTop + h - 7, s, ColorFg);
+ mHdffCmdIf->CmdOsdSetDisplayClippingArea(mDisplay, false, 0, 0, 0, 0);
+ //Font->DrawText(this, x, y, s, ColorFg, ColorBg, limit);
+ mChanged = true;
+ mBitmapModified = false;
+}
+
+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;
+ mBitmapModified = false;
+}
+
+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::drawQuarterTopRight;
+ else
+ flags = HDFF::drawQuarterTopRightInverted;
+ cx = x1;
+ cy = y2;
+ rx = x2 - x1;
+ ry = y2 - y1;
+ break;
+ case 2:
+ if (Quadrants > 0)
+ flags = HDFF::drawQuarterTopLeft;
+ else
+ flags = HDFF::drawQuarterTopLeftInverted;
+ cx = x2;
+ cy = y2;
+ rx = x2 - x1;
+ ry = y2 - y1;
+ break;
+ case 3:
+ if (Quadrants > 0)
+ flags = HDFF::drawQuarterBottomLeft;
+ else
+ flags = HDFF::drawQuarterBottomLeftInverted;
+ cx = x2;
+ cy = y1;
+ rx = x2 - x1;
+ ry = y2 - y1;
+ break;
+ case 4:
+ if (Quadrants > 0)
+ flags = HDFF::drawQuarterBottomRight;
+ else
+ flags = HDFF::drawQuarterBottomRightInverted;
+ cx = x1;
+ cy = y1;
+ rx = x2 - x1;
+ ry = y2 - y1;
+ break;
+ case 5:
+ flags = HDFF::drawHalfRight;
+ cx = x1;
+ cy = (y1 + y2) / 2;
+ rx = x2 - x1;
+ ry = (y2 - y1) / 2;
+ break;
+ case 6:
+ flags = HDFF::drawHalfTop;
+ cx = (x1 + x2) / 2;
+ cy = y2;
+ rx = (x2 - x1) / 2;
+ ry = y2 - y1;
+ break;
+ case 7:
+ flags = HDFF::drawHalfLeft;
+ cx = x2;
+ cy = (y1 + y2) / 2;
+ rx = x2 - x1;
+ ry = (y2 - y1) / 2;
+ break;
+ case 8:
+ flags = HDFF::drawHalfBottom;
+ cx = (x1 + x2) / 2;
+ cy = y1;
+ rx = (x2 - x1) / 2;
+ ry = y2 - y1;
+ break;
+ default:
+ flags = HDFF::drawFull;
+ 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;
+ mBitmapModified = false;
+}
+
+void cHdffOsd::DrawSlope(int x1, int y1, int x2, int y2, tColor Color, int Type)
+{
+ //printf("DrawSlope\n");
+ mChanged = true;
+ mBitmapModified = false;
+}
+
+void cHdffOsd::Flush(void)
+{
+ if (!Active())
+ return;
+
+ if (!mChanged)
+ return;
+
+ //printf("Flush\n");
+ if (mBitmapModified)
+ {
+ cBitmap *Bitmap;
+ for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++)
+ {
+ DrawBitmap(0, 0, *Bitmap);
+ }
+ }
+
+ mHdffCmdIf->CmdOsdRenderDisplay(mDisplay);
+
+ mChanged = false;
+ mBitmapModified = false;
+}
+
+
+class cHdffOsdRaw : public cOsd
+{
+private:
+ HDFF::cHdffCmdIf * mHdffCmdIf;
+ int mDispWidth;
+ int mDispHeight;
+ bool shown;
+ uint32_t mDisplay;
+ uint32_t mBitmapPalette;
+ uint32_t mBitmapColors[256];
+ uint32_t mBitmapNumColors;
+
+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;
+ shown = false;
+ mBitmapPalette = InvalidHandle;
+
+ gHdffSetup.GetOsdSize(mDispWidth, mDispHeight, pixelAspect);
+ mDisplay = mHdffCmdIf->CmdOsdCreateDisplay(mDispWidth, mDispHeight, HDFF::colorTypeARGB8888);
+ mHdffCmdIf->CmdOsdSetDisplayOutputRectangle(mDisplay, 0, 0, SizeFullScreen, SizeFullScreen);
+}
+
+cHdffOsdRaw::~cHdffOsdRaw()
+{
+ //printf("~cHdffOsdRaw %d %d\n", Left(), Top());
+ SetActive(false);
+
+ if (mBitmapPalette != InvalidHandle)
+ mHdffCmdIf->CmdOsdDeletePalette(mBitmapPalette);
+ mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, 0, 0, mDispWidth, mDispHeight, 0);
+ mHdffCmdIf->CmdOsdRenderDisplay(mDisplay);
+ mHdffCmdIf->CmdOsdDeleteDisplay(mDisplay);
+}
+
+void cHdffOsdRaw::SetActive(bool On)
+{
+ if (On != Active())
+ {
+ cOsd::SetActive(On);
+ if (On)
+ {
+ }
+ else if (shown)
+ {
+ shown = false;
+ }
+ }
+}
+
+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);
+ }
+ mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, 0, 0, mDispWidth, mDispHeight, 0);
+ mHdffCmdIf->CmdOsdRenderDisplay(mDisplay);
+ return cOsd::SetAreas(Areas, NumAreas);
+}
+
+void cHdffOsdRaw::Flush(void)
+{
+ if (!Active())
+ return;
+ //struct timeval start;
+ //struct timeval end;
+ //struct timezone timeZone;
+ //gettimeofday(&start, &timeZone);
+
+ bool render = false;
+ if (IsTrueColor())
+ {
+ LOCK_PIXMAPS;
+ while (cPixmapMemory *pm = RenderPixmaps())
+ {
+ 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;
+ mHdffCmdIf->CmdOsdDrawBitmap(mDisplay,
+ Left() + pm->ViewPort().X(), Top() + pm->ViewPort().Y() + y,
+ pm->Data() + y * d, w, hc, hc * d,
+ HDFF::colorTypeARGB8888, InvalidHandle);
+ }
+ delete pm;
+ render = true;
+ }
+ }
+ 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 (!shown || bitmap->Dirty(x1, y1, x2, y2))
+ {
+ if (!shown)
+ {
+ 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 == InvalidHandle)
+ {
+ mBitmapPalette = mHdffCmdIf->CmdOsdCreatePalette(HDFF::colorTypeClut8,
+ HDFF::colorFormatARGB, numColors, mBitmapColors);
+ }
+ else
+ {
+ mHdffCmdIf->CmdOsdSetPaletteColors(mBitmapPalette,
+ HDFF::colorFormatARGB, 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::colorTypeClut8, mBitmapPalette);
+ }
+ render = true;
+ }
+ bitmap->Clean();
+ }
+ delete[] buffer;
+ }
+ if (render)
+ {
+ mHdffCmdIf->CmdOsdRenderDisplay(mDisplay);
+ //gettimeofday(&end, &timeZone);
+ //int timeNeeded = end.tv_usec - start.tv_usec;
+ //timeNeeded += (end.tv_sec - start.tv_sec) * 1000000;
+ //printf("time = %d\n", timeNeeded);
+ }
+ shown = true;
+}
+
+
+
+
+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/PLUGINS/src/dvbhddevice/hdffosd.h b/PLUGINS/src/dvbhddevice/hdffosd.h
new file mode 100644
index 0000000..533897e
--- /dev/null
+++ b/PLUGINS/src/dvbhddevice/hdffosd.h
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ *
+ * $Id: hdffosd.h 1.2 2011/01/30 15:27:48 kls Exp $
+ */
+
+#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/PLUGINS/src/dvbhddevice/setup.c b/PLUGINS/src/dvbhddevice/setup.c
new file mode 100644
index 0000000..3cb69b1
--- /dev/null
+++ b/PLUGINS/src/dvbhddevice/setup.c
@@ -0,0 +1,252 @@
+/*
+ * 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.
+ *
+ * $Id: setup.c 1.11 2011/04/17 11:45:17 kls Exp $
+ */
+
+#include "setup.h"
+#include "hdffcmd.h"
+
+const int kResolutions = 4;
+const int kTvFormats = 2;
+const int kVideoConversions = 6;
+const int kAnalogueVideos = 4;
+const int kAudioDownmixes = 5;
+const int kOsdSizes = 5;
+const int kRemoteProtocols = 3;
+
+const int kResolution1080i = 0;
+const int kResolution720p = 1;
+const int kResolution576p = 2;
+const int kResolution576i = 3;
+
+static const char * ResolutionItems[] =
+{
+ "1080i",
+ "720p",
+ "576p",
+ "576i",
+ NULL
+};
+
+static const char * TvFormatItems[] =
+{
+ "4/3",
+ "16/9",
+ NULL
+};
+
+static const char * VideoConversionItems[] =
+{
+ "Automatic",
+ "Letterbox 16/9",
+ "Letterbox 14/9",
+ "Pillarbox",
+ "CentreCutOut",
+ "Always 16/9",
+ NULL
+};
+
+static const char * AnalogueVideoItems[] =
+{
+ "Disabled",
+ "RGB",
+ "CVBS + YUV",
+ "YC (S-Video)",
+ NULL
+};
+
+static const char * AudioDownmixItems[] =
+{
+ "Disabled",
+ "Analogue only",
+ "Always",
+ "Automatic",
+ "HDMI only",
+ NULL
+};
+
+static const char * OsdSizeItems[] =
+{
+ "Follow resolution",
+ "1920x1080",
+ "1280x720",
+ "1024x576",
+ "720x576",
+ NULL
+};
+
+static const char * RemoteProtocolItems[] =
+{
+ "none",
+ "RC5",
+ "RC6",
+ NULL
+};
+
+cHdffSetup gHdffSetup;
+
+cHdffSetup::cHdffSetup(void)
+{
+ Resolution = kResolution1080i;
+ TvFormat = HDFF::tvFormat16by9;
+ VideoConversion = HDFF::videoConversionPillarbox;
+ AnalogueVideo = HDFF::videoOutCvbsYuv;
+ AudioDelay = 0;
+ AudioDownmix = HDFF::downmixAutomatic;
+ OsdSize = 0;
+ CecEnabled = 1;
+ RemoteProtocol = 1;
+ RemoteAddress = -1;
+ HighLevelOsd = 1;
+ TrueColorOsd = 1;
+}
+
+bool cHdffSetup::SetupParse(const char *Name, const char *Value)
+{
+ if (strcmp(Name, "Resolution") == 0) Resolution = 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, "OsdSize") == 0) OsdSize = atoi(Value);
+ else if (strcmp(Name, "CecEnabled") == 0) CecEnabled = 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 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::tvFormat16by9)
+ 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;
+}
+
+HDFF::eHdmiVideoMode cHdffSetup::GetVideoMode(void)
+{
+ switch (Resolution)
+ {
+ case kResolution1080i:
+ default:
+ return HDFF::videoMode1080i50;
+ case kResolution720p:
+ return HDFF::videoMode720p50;
+ case kResolution576p:
+ return HDFF::videoMode576p50;
+ case kResolution576i:
+ return HDFF::videoMode576i50;
+ }
+}
+
+cHdffSetupPage::cHdffSetupPage(HDFF::cHdffCmdIf * pHdffCmdIf)
+{
+ mHdffCmdIf = pHdffCmdIf;
+ mNewHdffSetup = gHdffSetup;
+
+ Add(new cMenuEditStraItem("Resolution", &mNewHdffSetup.Resolution, kResolutions, ResolutionItems));
+ Add(new cMenuEditStraItem("TV format", &mNewHdffSetup.TvFormat, kTvFormats, TvFormatItems));
+ Add(new cMenuEditStraItem("Video Conversion", &mNewHdffSetup.VideoConversion, kVideoConversions, VideoConversionItems));
+ Add(new cMenuEditStraItem("Analogue Video", &mNewHdffSetup.AnalogueVideo, kAnalogueVideos, AnalogueVideoItems));
+ Add(new cMenuEditIntItem("Audio Delay (ms)", &mNewHdffSetup.AudioDelay, 0, 500));
+ Add(new cMenuEditStraItem("Audio Downmix", &mNewHdffSetup.AudioDownmix, kAudioDownmixes, AudioDownmixItems));
+ Add(new cMenuEditStraItem("Osd Size", &mNewHdffSetup.OsdSize, kOsdSizes, OsdSizeItems));
+ Add(new cMenuEditBoolItem("HDMI CEC", &mNewHdffSetup.CecEnabled));
+ Add(new cMenuEditStraItem("Remote Control Protocol", &mNewHdffSetup.RemoteProtocol, kRemoteProtocols, RemoteProtocolItems));
+ Add(new cMenuEditIntItem("Remote Control Address", &mNewHdffSetup.RemoteAddress, -1, 31));
+ Add(new cMenuEditBoolItem("High Level OSD", &mNewHdffSetup.HighLevelOsd));
+ Add(new cMenuEditBoolItem("Allow True Color OSD", &mNewHdffSetup.TrueColorOsd));
+}
+
+cHdffSetupPage::~cHdffSetupPage(void)
+{
+}
+
+void cHdffSetupPage::Store(void)
+{
+ SetupStore("Resolution", mNewHdffSetup.Resolution);
+ SetupStore("TvFormat", mNewHdffSetup.TvFormat);
+ SetupStore("VideoConversion", mNewHdffSetup.VideoConversion);
+ SetupStore("AnalogueVideo", mNewHdffSetup.AnalogueVideo);
+ SetupStore("AudioDelay", mNewHdffSetup.AudioDelay);
+ SetupStore("AudioDownmix", mNewHdffSetup.AudioDownmix);
+ SetupStore("OsdSize", mNewHdffSetup.OsdSize);
+ SetupStore("CecEnabled", mNewHdffSetup.CecEnabled);
+ SetupStore("RemoteProtocol", mNewHdffSetup.RemoteProtocol);
+ SetupStore("RemoteAddress", mNewHdffSetup.RemoteAddress);
+ SetupStore("HighLevelOsd", mNewHdffSetup.HighLevelOsd);
+ SetupStore("TrueColorOsd", mNewHdffSetup.TrueColorOsd);
+
+ if (mHdffCmdIf)
+ {
+ if (mNewHdffSetup.Resolution != gHdffSetup.Resolution)
+ {
+ mHdffCmdIf->CmdHdmiSetVideoMode(mNewHdffSetup.GetVideoMode());
+ }
+ HDFF::tVideoFormat videoFormat;
+ HDFF::tHdmiConfig hdmiConfig;
+
+ videoFormat.AutomaticEnabled = true;
+ videoFormat.AfdEnabled = true;
+ videoFormat.TvFormat = (HDFF::eTvFormat) mNewHdffSetup.TvFormat;
+ videoFormat.VideoConversion = (HDFF::eVideoConversion) mNewHdffSetup.VideoConversion;
+ mHdffCmdIf->CmdAvSetVideoFormat(0, &videoFormat);
+
+ mHdffCmdIf->CmdAvSetAudioDelay(mNewHdffSetup.AudioDelay);
+ mHdffCmdIf->CmdAvSetAudioDownmix((HDFF::eDownmixMode) mNewHdffSetup.AudioDownmix);
+
+ mHdffCmdIf->CmdMuxSetVideoOut((HDFF::eVideoOut) mNewHdffSetup.AnalogueVideo);
+
+ hdmiConfig.TransmitAudio = true;
+ hdmiConfig.ForceDviMode = false;
+ hdmiConfig.CecEnabled = mNewHdffSetup.CecEnabled;
+ mHdffCmdIf->CmdHdmiConfigure(&hdmiConfig);
+
+ mHdffCmdIf->CmdRemoteSetProtocol((HDFF::eRemoteProtocol) mNewHdffSetup.RemoteProtocol);
+ mHdffCmdIf->CmdRemoteSetAddressFilter(mNewHdffSetup.RemoteAddress >= 0, mNewHdffSetup.RemoteAddress);
+ }
+
+ gHdffSetup = mNewHdffSetup;
+}
diff --git a/PLUGINS/src/dvbhddevice/setup.h b/PLUGINS/src/dvbhddevice/setup.h
new file mode 100644
index 0000000..07c9d1a
--- /dev/null
+++ b/PLUGINS/src/dvbhddevice/setup.h
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ *
+ * $Id: setup.h 1.8 2011/04/17 11:20:22 kls Exp $
+ */
+
+#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);
+ HDFF::eHdmiVideoMode GetVideoMode(void);
+
+ int Resolution;
+ int TvFormat;
+ int VideoConversion;
+ int AnalogueVideo;
+ int AudioDelay;
+ int AudioDownmix;
+ int OsdSize;
+ int CecEnabled;
+ int RemoteProtocol;
+ int RemoteAddress;
+
+ int HighLevelOsd;
+ int TrueColorOsd;
+};
+
+extern cHdffSetup gHdffSetup;
+
+class cHdffSetupPage : public cMenuSetupPage
+{
+private:
+ HDFF::cHdffCmdIf * mHdffCmdIf;
+ cHdffSetup mNewHdffSetup;
+
+protected:
+ virtual void Store(void);
+
+public:
+ cHdffSetupPage(HDFF::cHdffCmdIf * pHdffCmdIf);
+ virtual ~cHdffSetupPage(void);
+};
+
+#endif