diff options
102 files changed, 4608 insertions, 1621 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS index be533c1..c3456a2 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -1117,6 +1117,9 @@ Rolf Ahrenberg <rahrenbe@cc.hut.fi> for making the Audio and Subtitles options available through the Green and Yellow keys in the Setup/DVB menu for making the Recordings menu display the length (in hours:minutes) of each recording + for fixing handling DVB subtitles and implementing decoding textual DVB subtitles + for adding file name and line number to LOG_ERROR_STR() + for replacing all calls to sleep() with cCondWait::SleepMs() Ralf Klueber <ralf.klueber@vodafone.com> for reporting a bug in cutting a recording if there is only a single editing mark @@ -1632,6 +1635,7 @@ Arthur Konovalov <artlov@gmail.com> for reporting problems with CAMs when checking the CAM status too frequently for reporting references to old *.vdr file names in MANUAL for reporting that the video stream type was set to 2 even if the vpid was 0 + for updates to 'sources.conf' Milos Kapoun <m.kapoun@cra.cz> for suggesting to skip code table info in SI data @@ -1868,6 +1872,8 @@ Luca Olivetti <luca@ventoso.org> "repeat" keypresses very fast for reporting a broken entry 'A111.1W' in sources.conf for translating OSD texts to the Spanish and Catalan language + for fixing scaling subtitles in case the primary device's GetVideoSize() function + doesn't return actual values Mikko Salo <mikko.salo@ppe.inet.fi> for suggesting to make the setup option "DVB/Video display format" available only @@ -1918,6 +1924,11 @@ Ville Skytt <ville.skytta@iki.fi> for fixing the Language header of the Serbian translation file for using pkg-config to get fribidi, freetype and fontconfig cflags and libs for making the Makefile also install the include files + for fixing a crash when deleting a recording while cutting it + for fixing several spelling errors + for adding generating a pkg-config file to the Makefile + for removing the '.pl' suffix from all scripts (thanks to Ville Skytt). + for changing the default location for the LIRC socket to /var/run/lirc/lircd Steffen Beyer <cpunk@reactor.de> for fixing setting the colored button help after deleting a recording in case the next @@ -2244,6 +2255,7 @@ Christoph Haubrich <christoph1.haubrich@arcor.de> for reporting that Setup.InitialChannel was dereferenced without checking for NULL for suggesting to implement a function to determine the length of a recording's index file + for fixing setting the start time of an edited recording Pekka Mauno <pekka.mauno@iki.fi> for fixing cSchedule::GetFollowingEvent() in case there is currently no present @@ -2659,6 +2671,8 @@ Stephan Austermhle <au@hcsd.de> Lars Hanisch <dvb@flensrocker.de> for suggesting to assign the source character 'V' to "Analog Video" + for a patch that was used to implement SCR (Satellite Channel Routing) + for implementing the SVDRP command 'UPDR' Alex Lasnier <alex@fepg.org> for adding tuning support for ATSC devices @@ -2774,3 +2788,7 @@ Frank Niederwipper <f.niederwipper@gmail.com> Chris Mayo <aklhfex@gmail.com> for reporting a problem with detecting frames on radio channels + +Dominic Evans <oldmanuk@gmail.com> + for making the SVDRP command LSTC accepts channel IDs + for adding cap_net_raw to the capabilities that are not dropped @@ -6742,3 +6742,41 @@ Video Disk Recorder Revision History Detecting frames in case the Picture Start Code or Access Unit Delimiter extends over TS packet boundaries is now done by locally skipping TS packets in cFrameDetector. + +2011-12-04: Version 1.7.22 + +- Fixed scaling subtitles in case the primary device's GetVideoSize() function doesn't + return actual values (thanks to Luca Olivetti). +- The DiSEqC codes are now copied in the call to cDiseqc::Execute(). +- VDR now supports "Satellite Channel Routing" (SCR) according to EN50494 (based on + the "unicable" patch from Lars Hanisch). + Since "Unicable" is a registered trademark and stands for only one of many + implementations of SCR, the following changes have been made compared to the patch, + which need to be taken into account by people who have set up their system using + the patch: + - The 'U' parameter in the diseqc.conf file has been changed to 'S' ("Scr"). + - The configuration file name has been changed from "unicable.conf" to "scr.conf". +- Updated sources.conf (thanks to Arthur Konovalov). +- The SVDRP command LSTC now also accepts channel IDs (thanks to Dominic Evans). +- Fixed handling DVB subtitles and implemented decoding textual DVB subtitles (thanks + to Rolf Ahrenberg). +- Added cap_net_raw to the capabilities that are not dropped (thanks to Dominic Evans). +- Fixed setting the start time of an edited recording (thanks to Christoph Haubrich). +- Temporarily switching free devices to transponders in order to have their running + status updated is now done by marking the devices as "occupied" for a certain + amount of time. +- The new setup options "LNB/Device n connected to sat cable" can be used to define + which DVB-S devices are connected to the same sat cable and are therefore "bonded". + This obsoletes the LNBSHARE patch. Users of the LNBSHARE patch will need to newly + set up their sat devices with the above options. +- Fixed a crash when deleting a recording while cutting it (thanks to Ville Skytt). +- Fixed several spelling errors (thanks to Ville Skytt). +- The new SVDRP command UPDR can be used to trigger an update of the list of + recordings (thanks to Lars Hanisch). +- Added generating a pkg-config file to the Makefile (thanks to Ville Skytt). +- Removed the '.pl' suffix from all scripts (thanks to Ville Skytt). +- Changed the default location for the LIRC socket to /var/run/lirc/lircd (thanks + to Ville Skytt). +- Added file name and line number to LOG_ERROR_STR() (thanks to Rolf Ahrenberg). +- Replaced all calls to sleep() with cCondWait::SleepMs() (thanks to Rolf Ahrenberg). +- Fixed a crash with malformed SI data (patch from vdr-portal). @@ -386,6 +386,23 @@ accessed using DiSEqC, you have to go to the "Setup" menu and set the "DiSEqC" parameter to "on". You also need to set up the file 'diseqc.conf' to properly access your DiSEqC equipment (see man vdr(5) for details). +A special form of DiSEqC is used to connect several receivers to one signal +source using only a single cable. This method, known as "Satellite Channel Routing" +according to EN50494 (aka "Unicable(TM)", "OLT(TM)", "SatCR", "Single Cable +Distribution", "Channel Stacking System" or "Single Cable Interface") uses +the file "scr.conf" to specify which SCR channels use which user band frequency. + +If DVB-S devices need to be connected to the same satellite cable, but no +"Satellite Channel Routing" is available, they can be set to be "bonded" in +the Setup/LNB menu. Bonded devices can only be tuned to the same polarization +and frequency band, which reduces the number of potentially receivable channels. + +Note that it doesn't make sense to use "Satellite Channel Routing" and +"Device Bonding" at the same time with the same devices. If you use either +of these methods, it is necessary that your devices are always created in the +same sequence when the drivers are loaded. You may need to configure some +proper "udev" rules to make sure this happens. + Running VDR with DVB-C (cable) or DVB-T (terrestrial): ------------------------------------------------------ @@ -732,12 +732,18 @@ Version 1.6 LNB: + Use DiSEqC = no Generally turns DiSEqC support on or off. + SLOF = 11700 The switching frequency (in MHz) between low and high LOF Low LNB frequency = 9750 The LNB's low and high local oscillator frequencies High LNB frequency = 10600 (in MHz, these have no meaning for DVB-C receivers) - Use DiSEqC = no Generally turns DiSEqC support on or off. + Device n connected to sat cable = own + Defines whether DVB-S device n has its own satellite cable, + or is "bonded" with another device. All DVB-S devices that + are connected to the same sat cable must be set to the same + number here. CAM: diff --git a/Make.config.template b/Make.config.template index 1fc8227..0de5bb9 100644 --- a/Make.config.template +++ b/Make.config.template @@ -6,7 +6,7 @@ # See the main source file 'vdr.c' for copyright information and # how to reach the author. # -# $Id: Make.config.template 2.3 2011/03/13 13:41:12 kls Exp $ +# $Id: Make.config.template 2.4 2011/12/04 14:41:00 kls Exp $ ### The C compiler and options: @@ -35,7 +35,7 @@ CONFDIR = $(VIDEODIR) ### The remote control: -LIRC_DEVICE = /dev/lircd +LIRC_DEVICE = /var/run/lirc/lircd RCU_DEVICE = /dev/ttyS1 ## Define if you want vdr to not run as root @@ -4,7 +4,7 @@ # See the main source file 'vdr.c' for copyright information and # how to reach the author. # -# $Id: Makefile 2.18 2011/05/21 12:21:40 kls Exp $ +# $Id: Makefile 2.22 2011/12/04 14:41:00 kls Exp $ .DELETE_ON_ERROR: @@ -33,6 +33,8 @@ CONFDIR = $(VIDEODIR) DOXYGEN = /usr/bin/doxygen DOXYFILE = Doxyfile +PCDIR ?= $(firstword $(subst :, , ${PKG_CONFIG_PATH}:$(shell pkg-config --variable=pc_path pkg-config):$(PREFIX)/lib/pkgconfig)) + include Make.global -include Make.config @@ -60,7 +62,7 @@ DEFINES += -DBIDI LIBS += $(shell pkg-config --libs fribidi) endif -LIRC_DEVICE ?= /dev/lircd +LIRC_DEVICE ?= /var/run/lirc/lircd RCU_DEVICE ?= /dev/ttyS1 DEFINES += -DLIRC_DEVICE=\"$(LIRC_DEVICE)\" -DRCU_DEVICE=\"$(RCU_DEVICE)\" @@ -77,7 +79,7 @@ DEFINES += -DLOCDIR=\"$(LOCDIR)\" VDRVERSION = $(shell sed -ne '/define VDRVERSION/s/^.*"\(.*\)".*$$/\1/p' config.h) APIVERSION = $(shell sed -ne '/define APIVERSION/s/^.*"\(.*\)".*$$/\1/p' config.h) -all: vdr i18n +all: vdr i18n vdr.pc # Implicit rules: @@ -103,6 +105,25 @@ vdr: $(OBJS) $(SILIB) $(SILIB): $(MAKE) -C $(LSIDIR) all +# pkg-config file: + +vdr.pc: Makefile Make.global + @echo "bindir=$(BINDIR)" > $@ + @echo "includedir=$(INCDIR)" >> $@ + @echo "configdir=$(CONFDIR)" >> $@ + @echo "videodir=$(VIDEODIR)" >> $@ + @echo "plugindir=$(PLUGINLIBDIR)" >> $@ + @echo "localedir=$(LOCDIR)" >> $@ + @echo "apiversion=$(APIVERSION)" >> $@ + @echo "cflags=$(CXXFLAGS) $(DEFINES) -I\$${includedir}" >> $@ + @echo "plugincflags=\$${cflags} -fPIC" >> $@ + @echo "" >> $@ + @echo "Name: VDR" >> $@ + @echo "Description: Video Disk Recorder" >> $@ + @echo "URL: http://www.tvdr.de/" >> $@ + @echo "Version: $(VDRVERSION)" >> $@ + @echo "Cflags: \$${cflags}" >> $@ + # Internationalization (I18N): PODIR = po @@ -163,13 +184,13 @@ clean-plugins: # Install the files: -install: install-bin install-conf install-doc install-plugins install-i18n install-includes +install: install-bin install-conf install-doc install-plugins install-i18n install-includes install-pc # VDR binary: install-bin: vdr @mkdir -p $(DESTDIR)$(BINDIR) - @cp --remove-destination vdr svdrpsend.pl $(DESTDIR)$(BINDIR) + @cp --remove-destination vdr svdrpsend $(DESTDIR)$(BINDIR) # Configuration files: @@ -200,6 +221,14 @@ install-includes: include-dir @mkdir -p $(DESTDIR)$(INCDIR) @cp -pLR include/vdr include/libsi $(DESTDIR)$(INCDIR) +# pkg-config file: + +install-pc: vdr.pc + if [ -n "$(PCDIR)" ] ; then \ + mkdir -p $(DESTDIR)$(PCDIR) ; \ + cp vdr.pc $(DESTDIR)$(PCDIR) ; \ + fi + # Source documentation: srcdoc: @@ -212,7 +241,7 @@ srcdoc: clean: $(MAKE) -C $(LSIDIR) clean - -rm -f $(OBJS) $(DEPFILE) vdr core* *~ + -rm -f $(OBJS) $(DEPFILE) vdr vdr.pc core* *~ -rm -rf $(LOCALEDIR) $(PODIR)/*.mo $(PODIR)/*.pot -rm -rf include -rm -rf srcdoc diff --git a/PLUGINS/src/dvbhddevice/Makefile b/PLUGINS/src/dvbhddevice/Makefile index 91fdfce..09ca4ad 100644 --- a/PLUGINS/src/dvbhddevice/Makefile +++ b/PLUGINS/src/dvbhddevice/Makefile @@ -1,7 +1,7 @@ # # Makefile for a Video Disk Recorder plugin # -# $Id: Makefile 1.8 2011/05/21 12:25:33 kls Exp $ +# $Id: Makefile 1.9 2011/12/04 15:30:21 kls Exp $ # The official name of this plugin. # This name will be used in the '-P...' option of VDR to load the plugin. @@ -98,8 +98,9 @@ i18n: $(I18Nmsgs) $(I18Npot) ### Targets: -libvdr-$(PLUGIN).so: $(OBJS) - $(CXX) $(CXXFLAGS) -shared $(OBJS) -o $@ +libvdr-$(PLUGIN).so: $(OBJS) libhdffcmd + $(MAKE) -C libhdffcmd all + $(CXX) $(CXXFLAGS) -shared $(OBJS) libhdffcmd/libhdffcmd.a -o $@ @cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION) dist: $(I18Npo) clean @@ -112,3 +113,4 @@ dist: $(I18Npo) clean clean: @-rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~ $(PODIR)/*.mo $(PODIR)/*.pot + $(MAKE) -C libhdffcmd clean diff --git a/PLUGINS/src/dvbhddevice/dvbhdffdevice.c b/PLUGINS/src/dvbhddevice/dvbhdffdevice.c index ff3f953..101558d 100644 --- a/PLUGINS/src/dvbhddevice/dvbhdffdevice.c +++ b/PLUGINS/src/dvbhddevice/dvbhdffdevice.c @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: dvbhdffdevice.c 1.33 2011/08/27 09:32:18 kls Exp $ + * $Id: dvbhdffdevice.c 1.35 2011/12/04 15:30:42 kls Exp $ */ #include "dvbhdffdevice.h" @@ -47,18 +47,18 @@ cDvbHdFfDevice::cDvbHdFfDevice(int Adapter, int Frontend) 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->CmdAvSetAudioDownmix((HdffAudioDownmixMode_t) gHdffSetup.AudioDownmix); + mHdffCmdIf->CmdMuxSetVideoOut((HdffVideoOut_t) gHdffSetup.AnalogueVideo); mHdffCmdIf->CmdHdmiSetVideoMode(gHdffSetup.GetVideoMode()); - HDFF::tHdmiConfig hdmiConfig; + HdffHdmiConfig_t hdmiConfig; hdmiConfig.TransmitAudio = true; hdmiConfig.ForceDviMode = false; hdmiConfig.CecEnabled = gHdffSetup.CecEnabled; - hdmiConfig.VideoModeAdaption = (HDFF::eVideoModeAdaption) gHdffSetup.VideoModeAdaption; + hdmiConfig.VideoModeAdaption = (HdffVideoModeAdaption_t) gHdffSetup.VideoModeAdaption; mHdffCmdIf->CmdHdmiConfigure(&hdmiConfig); if (gHdffSetup.CecEnabled) - mHdffCmdIf->CmdHdmiSendCecCommand(HDFF::cecCommandTvOn); - mHdffCmdIf->CmdRemoteSetProtocol((HDFF::eRemoteProtocol) gHdffSetup.RemoteProtocol); + mHdffCmdIf->CmdHdmiSendCecCommand(HDFF_CEC_COMMAND_TV_ON); + mHdffCmdIf->CmdRemoteSetProtocol((HdffRemoteProtocol_t) gHdffSetup.RemoteProtocol); mHdffCmdIf->CmdRemoteSetAddressFilter(gHdffSetup.RemoteAddress >= 0, gHdffSetup.RemoteAddress); } @@ -109,11 +109,11 @@ void cDvbHdFfDevice::SetVideoDisplayFormat(eVideoDisplayFormat VideoDisplayForma void cDvbHdFfDevice::SetVideoFormat(bool VideoFormat16_9) { - HDFF::tVideoFormat videoFormat; + HdffVideoFormat_t videoFormat; videoFormat.AutomaticEnabled = true; videoFormat.AfdEnabled = true; - videoFormat.TvFormat = (HDFF::eTvFormat) gHdffSetup.TvFormat; - videoFormat.VideoConversion = (HDFF::eVideoConversion) gHdffSetup.VideoConversion; + videoFormat.TvFormat = (HdffTvFormat_t) gHdffSetup.TvFormat; + videoFormat.VideoConversion = (HdffVideoConversion_t) gHdffSetup.VideoConversion; mHdffCmdIf->CmdAvSetVideoFormat(0, &videoFormat); } @@ -184,14 +184,14 @@ bool cDvbHdFfDevice::SetPid(cPidHandle *Handle, int Type, bool On) mHdffCmdIf->CmdAvSetPcrPid(0, Handle->pid); else if (Type == ptVideo) { if (Handle->streamType == 0x1B) - mHdffCmdIf->CmdAvSetVideoPid(0, Handle->pid, HDFF::videoStreamH264); + mHdffCmdIf->CmdAvSetVideoPid(0, Handle->pid, HDFF_VIDEO_STREAM_H264); else - mHdffCmdIf->CmdAvSetVideoPid(0, Handle->pid, HDFF::videoStreamMpeg2); + mHdffCmdIf->CmdAvSetVideoPid(0, Handle->pid, HDFF_VIDEO_STREAM_MPEG2); } else if (Type == ptAudio) - mHdffCmdIf->CmdAvSetAudioPid(0, Handle->pid, HDFF::audioStreamMpeg1); + mHdffCmdIf->CmdAvSetAudioPid(0, Handle->pid, HDFF_AUDIO_STREAM_MPEG1); else if (Type == ptDolby) - mHdffCmdIf->CmdAvSetAudioPid(0, Handle->pid, HDFF::audioStreamAc3); + mHdffCmdIf->CmdAvSetAudioPid(0, Handle->pid, HDFF_AUDIO_STREAM_AC3); if (!(Type <= ptDolby && Handle->used <= 1)) { pesFilterParams.pid = Handle->pid; pesFilterParams.input = DMX_IN_FRONTEND; @@ -209,11 +209,11 @@ bool cDvbHdFfDevice::SetPid(cPidHandle *Handle, int Type, bool On) if (Type == ptPcr) mHdffCmdIf->CmdAvSetPcrPid(0, 0); else if (Type == ptVideo) - mHdffCmdIf->CmdAvSetVideoPid(0, 0, HDFF::videoStreamMpeg2); + mHdffCmdIf->CmdAvSetVideoPid(0, 0, HDFF_VIDEO_STREAM_MPEG1); else if (Type == ptAudio) - mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF::audioStreamMpeg1); + mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF_AUDIO_STREAM_MPEG1); else if (Type == ptDolby) - mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF::audioStreamAc3); + mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF_AUDIO_STREAM_AC3); //TODO missing setting to 0x1FFF??? see cDvbDevice::SetPid() close(Handle->handle); Handle->handle = -1; @@ -351,10 +351,13 @@ bool cDvbHdFfDevice::CanReplay(void) const bool cDvbHdFfDevice::SetPlayMode(ePlayMode PlayMode) { if (PlayMode == pmNone) { + mHdffCmdIf->CmdAvSetVideoSpeed(0, 100); + mHdffCmdIf->CmdAvSetAudioSpeed(0, 100); + mHdffCmdIf->CmdAvEnableVideoAfterStop(0, false); mHdffCmdIf->CmdAvSetPcrPid(0, 0); - mHdffCmdIf->CmdAvSetVideoPid(0, 0, HDFF::videoStreamMpeg2); - mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF::audioStreamMpeg1); + mHdffCmdIf->CmdAvSetVideoPid(0, 0, HDFF_VIDEO_STREAM_MPEG1); + mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF_AUDIO_STREAM_MPEG1); ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX); mHdffCmdIf->CmdAvSetDecoderInput(0, 0); @@ -374,6 +377,8 @@ bool cDvbHdFfDevice::SetPlayMode(ePlayMode PlayMode) playAudioPid = -1; audioCounter = 0; videoCounter = 0; + freezed = false; + trickMode = false; mHdffCmdIf->CmdAvSetDecoderInput(0, 2); ioctl(fd_video, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY); @@ -405,18 +410,20 @@ int64_t cDvbHdFfDevice::GetSTC(void) void cDvbHdFfDevice::TrickSpeed(int Speed) { + freezed = false; mHdffCmdIf->CmdAvEnableSync(0, false); - mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF::audioStreamMpeg1); + mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF_AUDIO_STREAM_MPEG1); playAudioPid = -1; if (Speed > 0) mHdffCmdIf->CmdAvSetVideoSpeed(0, 100 / Speed); + trickMode = true; } void cDvbHdFfDevice::Clear(void) { CHECK(ioctl(fd_video, VIDEO_CLEAR_BUFFER)); - mHdffCmdIf->CmdAvSetVideoPid(0, 0, HDFF::videoStreamMpeg1); - mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF::audioStreamMpeg1); + mHdffCmdIf->CmdAvSetVideoPid(0, 0, HDFF_VIDEO_STREAM_MPEG1); + mHdffCmdIf->CmdAvSetAudioPid(0, 0, HDFF_AUDIO_STREAM_MPEG1); playVideoPid = -1; playAudioPid = -1; cDevice::Clear(); @@ -424,6 +431,8 @@ void cDvbHdFfDevice::Clear(void) void cDvbHdFfDevice::Play(void) { + freezed = false; + trickMode = false; mHdffCmdIf->CmdAvEnableSync(0, true); mHdffCmdIf->CmdAvSetVideoSpeed(0, 100); mHdffCmdIf->CmdAvSetAudioSpeed(0, 100); @@ -432,6 +441,7 @@ void cDvbHdFfDevice::Play(void) void cDvbHdFfDevice::Freeze(void) { + freezed = true; mHdffCmdIf->CmdAvSetVideoSpeed(0, 0); mHdffCmdIf->CmdAvSetAudioSpeed(0, 0); cDevice::Freeze(); @@ -443,13 +453,13 @@ void cDvbHdFfDevice::Mute(void) cDevice::Mute(); } -static HDFF::eVideoStreamType MapVideoStreamTypes(int Vtype) +static HdffVideoStreamType_t 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 + case 0x01: return HDFF_VIDEO_STREAM_MPEG1; + case 0x02: return HDFF_VIDEO_STREAM_MPEG2; + case 0x1B: return HDFF_VIDEO_STREAM_H264; + default: return HDFF_VIDEO_STREAM_MPEG2; // fallback to MPEG2 } } @@ -594,6 +604,8 @@ uint32_t cDvbHdFfDevice::PesToTs(uint8_t * TsBuffer, uint16_t Pid, uint8_t & Cou int cDvbHdFfDevice::PlayVideo(const uchar *Data, int Length) { + if (freezed) + return -1; //TODO: support greater Length uint8_t tsBuffer[188 * 16]; uint32_t tsLength; @@ -603,7 +615,7 @@ int cDvbHdFfDevice::PlayVideo(const uchar *Data, int Length) if (pid != playVideoPid) { playVideoPid = pid; - mHdffCmdIf->CmdAvSetVideoPid(0, playVideoPid, HDFF::videoStreamMpeg2, true); + mHdffCmdIf->CmdAvSetVideoPid(0, playVideoPid, HDFF_VIDEO_STREAM_MPEG2, true); } if (WriteAllOrNothing(fd_video, tsBuffer, tsLength, 1000, 10) <= 0) Length = 0; @@ -612,39 +624,43 @@ int cDvbHdFfDevice::PlayVideo(const uchar *Data, int Length) int cDvbHdFfDevice::PlayAudio(const uchar *Data, int Length, uchar Id) { + if (freezed) + return -1; + if (trickMode) + return Length; uint8_t streamId; uint8_t tsBuffer[188 * 16]; uint32_t tsLength; - HDFF::eAudioStreamType streamType = HDFF::audioStreamMpeg1; - HDFF::eAVContainerType containerType = HDFF::avContainerPes; + HdffAudioStreamType_t streamType = HDFF_AUDIO_STREAM_MPEG1; + HdffAvContainerType_t containerType = HDFF_AV_CONTAINER_PES; int pid; streamId = Data[3]; if (streamId >= 0xC0 && streamId <= 0xDF) { - streamType = HDFF::audioStreamMpeg1; + streamType = HDFF_AUDIO_STREAM_MPEG1; } else if (streamId == 0xBD) { const uint8_t * payload = Data + 9 + Data[8]; if ((payload[0] & 0xF8) == 0xA0) { - containerType = HDFF::avContainerPesDvd; - streamType = HDFF::audioStreamPcm; + containerType = HDFF_AV_CONTAINER_PES_DVD; + streamType = HDFF_AUDIO_STREAM_PCM; } else if ((payload[0] & 0xF8) == 0x88) { - containerType = HDFF::avContainerPesDvd; - streamType = HDFF::audioStreamDts; + containerType = HDFF_AV_CONTAINER_PES_DVD; + streamType = HDFF_AUDIO_STREAM_DTS; } else if ((payload[0] & 0xF8) == 0x80) { - containerType = HDFF::avContainerPesDvd; - streamType = HDFF::audioStreamAc3; + containerType = HDFF_AV_CONTAINER_PES_DVD; + streamType = HDFF_AUDIO_STREAM_AC3; } else { - streamType = HDFF::audioStreamAc3; + streamType = HDFF_AUDIO_STREAM_AC3; } } pid = 200 + (int) streamType; @@ -661,6 +677,8 @@ int cDvbHdFfDevice::PlayAudio(const uchar *Data, int Length, uchar Id) int cDvbHdFfDevice::PlayTsVideo(const uchar *Data, int Length) { + if (freezed) + return -1; int pid = TsPid(Data); if (pid != playVideoPid) { PatPmtParser(); @@ -672,21 +690,25 @@ int cDvbHdFfDevice::PlayTsVideo(const uchar *Data, int Length) return WriteAllOrNothing(fd_video, Data, Length, 1000, 10); } -static HDFF::eAudioStreamType MapAudioStreamTypes(int Atype) +static HdffAudioStreamType_t 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 + case 0x03: return HDFF_AUDIO_STREAM_MPEG1; + case 0x04: return HDFF_AUDIO_STREAM_MPEG2; + case SI::AC3DescriptorTag: return HDFF_AUDIO_STREAM_AC3; + case SI::EnhancedAC3DescriptorTag: return HDFF_AUDIO_STREAM_EAC3; + case 0x0F: return HDFF_AUDIO_STREAM_AAC; + case 0x11: return HDFF_AUDIO_STREAM_HE_AAC; + default: return HDFF_AUDIO_STREAM_MPEG1; } } int cDvbHdFfDevice::PlayTsAudio(const uchar *Data, int Length) { + if (freezed) + return -1; + if (trickMode) + return Length; int pid = TsPid(Data); if (pid != playAudioPid) { playAudioPid = pid; diff --git a/PLUGINS/src/dvbhddevice/dvbhdffdevice.h b/PLUGINS/src/dvbhddevice/dvbhdffdevice.h index 4dcfb6a..439ec9b 100644 --- a/PLUGINS/src/dvbhddevice/dvbhdffdevice.h +++ b/PLUGINS/src/dvbhddevice/dvbhdffdevice.h @@ -3,7 +3,7 @@ * * 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 $ + * $Id: dvbhdffdevice.h 1.7 2011/09/10 10:17:32 kls Exp $ */ #ifndef __DVBHDFFDEVICE_H @@ -79,6 +79,8 @@ protected: private: int playVideoPid; int playAudioPid; + bool freezed; + bool trickMode; // Pes2Ts conversion stuff uint8_t videoCounter; diff --git a/PLUGINS/src/dvbhddevice/hdffcmd.c b/PLUGINS/src/dvbhddevice/hdffcmd.c index 60ad70e..957f2c7 100644 --- a/PLUGINS/src/dvbhddevice/hdffcmd.c +++ b/PLUGINS/src/dvbhddevice/hdffcmd.c @@ -3,34 +3,15 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: hdffcmd.c 1.21 2011/08/27 09:34:18 kls Exp $ + * $Id: hdffcmd.c 1.22 2011/12/04 15:31:03 kls Exp $ */ #include "hdffcmd.h" -#include <linux/dvb/osd.h> +#include "libhdffcmd/hdffcmd.h" #include <stdio.h> #include <string.h> -#include <sys/ioctl.h> #include <vdr/tools.h> -#if !defined OSD_RAW_CMD -typedef struct osd_raw_cmd_s { - const void *cmd_data; - int cmd_len; - void *result_data; - int result_len; -} osd_raw_cmd_t; - -typedef struct osd_raw_data_s { - const void *data_buffer; - int data_length; - int data_handle; -} osd_raw_data_t; - -#define OSD_RAW_CMD _IOWR('o', 162, osd_raw_cmd_t) -#define OSD_RAW_DATA _IOWR('o', 163, osd_raw_data_t) -#endif - namespace HDFF { @@ -48,1093 +29,347 @@ 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]; - } + uint32_t version; + int err; + + err = HdffCmdGetFirmwareVersion(mOsdDev, &version, pString, MaxLength); + if (err == 0) + return version; return 0; } uint32_t cHdffCmdIf::CmdGetInterfaceVersion(char * pString, uint32_t MaxLength) { - 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]; - } + uint32_t version; + int err; + + err = HdffCmdGetInterfaceVersion(mOsdDev, &version, pString, MaxLength); + if (err == 0) + return version; return 0; } uint32_t cHdffCmdIf::CmdGetCopyrights(uint8_t Index, char * pString, uint32_t MaxLength) { - 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; - } - } + int err; + + err = HdffCmdGetCopyrights(mOsdDev, Index, pString, MaxLength); + if (err == 0) + return strlen(pString); 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); + HdffCmdAvSetPlayMode(mOsdDev, PlayMode, Realtime); } -void cHdffCmdIf::CmdAvSetVideoPid(uint8_t DecoderIndex, uint16_t VideoPid, eVideoStreamType StreamType, bool PlaybackMode) +void cHdffCmdIf::CmdAvSetVideoPid(uint8_t DecoderIndex, uint16_t VideoPid, HdffVideoStreamType_t 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); + HdffCmdAvSetVideoPid(mOsdDev, DecoderIndex, VideoPid, StreamType); } -void cHdffCmdIf::CmdAvSetAudioPid(uint8_t DecoderIndex, uint16_t AudioPid, eAudioStreamType StreamType, eAVContainerType ContainerType) +void cHdffCmdIf::CmdAvSetAudioPid(uint8_t DecoderIndex, uint16_t AudioPid, HdffAudioStreamType_t StreamType, HdffAvContainerType_t 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); + HdffCmdAvSetAudioPid(mOsdDev, DecoderIndex, AudioPid, StreamType, + ContainerType); } 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); + HdffCmdAvSetPcrPid(mOsdDev, DecoderIndex, PcrPid); } 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); + HdffCmdAvSetTeletextPid(mOsdDev, DecoderIndex, TeletextPid); } 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); + HdffCmdAvSetVideoWindow(mOsdDev, DecoderIndex, Enable, X, Y, Width, Height); } -void cHdffCmdIf::CmdAvShowStillImage(uint8_t DecoderIndex, const uint8_t * pStillImage, int Size, eVideoStreamType StreamType) +void cHdffCmdIf::CmdAvShowStillImage(uint8_t DecoderIndex, const uint8_t * pStillImage, int Size, HdffVideoStreamType_t 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); + HdffCmdAvShowStillImage(mOsdDev, DecoderIndex, pStillImage, Size, + StreamType); } 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); + HdffCmdAvSetDecoderInput(mOsdDev, DecoderIndex, DemultiplexerIndex); } 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); + HdffCmdAvSetDemultiplexerInput(mOsdDev, DemultiplexerIndex, TsInputIndex); } -void cHdffCmdIf::CmdAvSetVideoFormat(uint8_t DecoderIndex, const tVideoFormat * pVideoFormat) +void cHdffCmdIf::CmdAvSetVideoFormat(uint8_t DecoderIndex, const HdffVideoFormat_t * 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); + HdffCmdAvSetVideoFormat(mOsdDev, DecoderIndex, pVideoFormat); } -void cHdffCmdIf::CmdAvSetVideoOutputMode(uint8_t DecoderIndex, eVideoOutputMode OutputMode) +void cHdffCmdIf::CmdAvSetVideoOutputMode(uint8_t DecoderIndex, HdffVideoOutputMode_t 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); + HdffCmdAvSetVideoOutputMode(mOsdDev, DecoderIndex, OutputMode); } 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); + HdffCmdAvSetStc(mOsdDev, DecoderIndex, Stc); } 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); + HdffCmdAvFlushBuffer(mOsdDev, DecoderIndex, FlushAudio, FlushVideo); } 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); + HdffCmdAvEnableSync(mOsdDev, DecoderIndex, EnableSync, EnableSync); } 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); + HdffCmdAvSetVideoSpeed(mOsdDev, DecoderIndex, Speed); } 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); + HdffCmdAvSetAudioSpeed(mOsdDev, DecoderIndex, Speed); } 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); + HdffCmdAvEnableVideoAfterStop(mOsdDev, DecoderIndex, EnableVideoAfterStop); } 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); + HdffCmdAvSetAudioDelay(mOsdDev, Delay); } -void cHdffCmdIf::CmdAvSetAudioDownmix(eDownmixMode DownmixMode) +void cHdffCmdIf::CmdAvSetAudioDownmix(HdffAudioDownmixMode_t 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); + HdffCmdAvSetAudioDownmix(mOsdDev, DownmixMode); } 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); + HdffCmdAvSetAudioChannel(mOsdDev, AudioChannel); } -void cHdffCmdIf::CmdOsdConfigure(const tOsdConfig * pConfig) +void cHdffCmdIf::CmdOsdConfigure(const HdffOsdConfig_t * 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); + HdffCmdOsdConfigure(mOsdDev, pConfig); } 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); + HdffCmdOsdReset(mOsdDev); } -uint32_t cHdffCmdIf::CmdOsdCreateDisplay(uint32_t Width, uint32_t Height, eColorType ColorType) +uint32_t cHdffCmdIf::CmdOsdCreateDisplay(uint32_t Width, uint32_t Height, HdffColorType_t 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; + uint32_t newDisplay; + + if (HdffCmdOsdCreateDisplay(mOsdDev, Width, Height, ColorType, &newDisplay) == 0) + return newDisplay; + return HDFF_INVALID_HANDLE; } 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); + HdffCmdOsdDeleteDisplay(mOsdDev, hDisplay); } 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); + HdffCmdOsdEnableDisplay(mOsdDev, hDisplay, Enable); } void cHdffCmdIf::CmdOsdSetDisplayOutputRectangle(uint32_t hDisplay, uint32_t X, uint32_t Y, uint32_t Width, uint32_t Height) { //printf("SetOutputRect %d %d %d %d %d\n", hDisplay, X, Y, Width, Height); - 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); + HdffCmdOsdSetDisplayOutputRectangle(mOsdDev, hDisplay, X, Y, Width, Height); } void cHdffCmdIf::CmdOsdSetDisplayClippingArea(uint32_t hDisplay, bool Enable, uint32_t X, uint32_t Y, uint32_t Width, uint32_t Height) { //printf("SetClippingArea %d %d %d %d %d %d\n", hDisplay, Enable, X, Y, Width, Height); - 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); + HdffCmdOsdSetDisplayClippingArea(mOsdDev, hDisplay, Enable, X, Y, Width, Height); } 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); + HdffCmdOsdRenderDisplay(mOsdDev, hDisplay); } -uint32_t cHdffCmdIf::CmdOsdCreatePalette(eColorType ColorType, eColorFormat ColorFormat, +uint32_t cHdffCmdIf::CmdOsdCreatePalette(HdffColorType_t ColorType, HdffColorFormat_t 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; + uint32_t newPalette; + int err; + + err = HdffCmdOsdCreatePalette(mOsdDev, ColorType, ColorFormat, NumColors, + pColors, &newPalette); + if (err == 0) + return newPalette; + return HDFF_INVALID_HANDLE; } 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); + HdffCmdOsdDeletePalette(mOsdDev, hPalette); } 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); + HdffCmdOsdSetDisplayPalette(mOsdDev, hDisplay, hPalette); } -void cHdffCmdIf::CmdOsdSetPaletteColors(uint32_t hPalette, eColorFormat ColorFormat, +void cHdffCmdIf::CmdOsdSetPaletteColors(uint32_t hPalette, HdffColorFormat_t 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); + HdffCmdOsdSetPaletteColors(mOsdDev, hPalette, ColorFormat, StartColor, + NumColors, pColors); } 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; + uint32_t newFontFace; + int err; + + err = HdffCmdOsdCreateFontFace(mOsdDev, pFontData, DataSize, &newFontFace); + if (err == 0) + return newFontFace; + return HDFF_INVALID_HANDLE; } 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); + HdffCmdOsdDeleteFontFace(mOsdDev, hFontFace); } 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; + uint32_t newFont; + int err; + + err = HdffCmdOsdCreateFont(mOsdDev, hFontFace, Size, &newFont); + if (err == 0) + return newFont; + return HDFF_INVALID_HANDLE; } 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); + HdffCmdOsdDeleteFont(mOsdDev, hFont); } void cHdffCmdIf::CmdOsdDrawRectangle(uint32_t hDisplay, int X, int Y, int Width, int Height, uint32_t Color) { //printf("Rect (%d,%d) %d x %d, %08X\n", X, Y, Width, Height, Color); - 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); + HdffCmdOsdDrawRectangle(mOsdDev, hDisplay, X, Y, Width, Height, Color); } void cHdffCmdIf::CmdOsdDrawEllipse(uint32_t hDisplay, int CX, int CY, int RadiusX, int RadiusY, uint32_t Color, uint32_t Flags) { //printf("Ellipse (%d,%d) %d x %d, %08X, %d\n", CX, CY, RadiusX, RadiusY, Color, Flags); - 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); + HdffCmdOsdDrawEllipse(mOsdDev, hDisplay, CX, CY, RadiusX, RadiusY, Color, Flags); } 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); + HdffCmdOsdDrawText(mOsdDev, hDisplay, hFont, X, Y, pText, Color); } void cHdffCmdIf::CmdOsdDrawTextW(uint32_t hDisplay, uint32_t hFont, int X, int Y, const uint16_t * pText, uint32_t Color) { //printf("TextW %08X (%d,%d), %08X\n", hFont, X, Y, Color); - 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); + HdffCmdOsdDrawWideText(mOsdDev, hDisplay, hFont, X, Y, pText, Color); } void cHdffCmdIf::CmdOsdDrawBitmap(uint32_t hDisplay, int X, int Y, const uint8_t * pBitmap, int BmpWidth, int BmpHeight, int BmpSize, - eColorType ColorType, uint32_t hPalette) + HdffColorType_t 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); + HdffCmdOsdDrawBitmap(mOsdDev, hDisplay, X, Y, pBitmap, BmpWidth, BmpHeight, + BmpSize, ColorType, hPalette); } void cHdffCmdIf::CmdOsdSaveRegion(uint32_t hDisplay, int X, int Y, int Width, int Height) { - 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); + HdffCmdOsdSaveRegion(mOsdDev, hDisplay, X, Y, Width, Height); } 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); + HdffCmdOsdRestoreRegion(mOsdDev, hDisplay); } -void cHdffCmdIf::CmdMuxSetVideoOut(eVideoOut VideoOut) +void cHdffCmdIf::CmdMuxSetVideoOut(HdffVideoOut_t 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); + HdffCmdMuxSetVideoOut(mOsdDev, VideoOut); } 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); + HdffCmdMuxSetVolume(mOsdDev, Volume); } 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); + HdffCmdMuxMuteAudio(mOsdDev, Mute); } -void cHdffCmdIf::CmdHdmiSetVideoMode(eHdmiVideoMode VideoMode) +void cHdffCmdIf::CmdHdmiSetVideoMode(HdffVideoMode_t 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); + HdffCmdHdmiSetVideoMode(mOsdDev, VideoMode); } -void cHdffCmdIf::CmdHdmiConfigure(const tHdmiConfig * pConfig) +void cHdffCmdIf::CmdHdmiConfigure(const HdffHdmiConfig_t * 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); - } - cmdBuf.SetBits(3, (uint32_t) pConfig->VideoModeAdaption); - osd_cmd.cmd_len = CmdSetLength(cmdBuf); - ioctl(mOsdDev, OSD_RAW_CMD, &osd_cmd); + HdffCmdHdmiConfigure(mOsdDev, pConfig); } -void cHdffCmdIf::CmdHdmiSendCecCommand(eCecCommand Command) +void cHdffCmdIf::CmdHdmiSendCecCommand(HdffCecCommand_t 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); + HdffCmdHdmiSendCecCommand(mOsdDev, Command); } -void cHdffCmdIf::CmdRemoteSetProtocol(eRemoteProtocol Protocol) +void cHdffCmdIf::CmdRemoteSetProtocol(HdffRemoteProtocol_t 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); + HdffCmdRemoteSetProtocol(mOsdDev, Protocol); } 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); + HdffCmdRemoteSetAddressFilter(mOsdDev, Enable, Address); } } // end of namespace diff --git a/PLUGINS/src/dvbhddevice/hdffcmd.h b/PLUGINS/src/dvbhddevice/hdffcmd.h index cd641eb..142f65f 100644 --- a/PLUGINS/src/dvbhddevice/hdffcmd.h +++ b/PLUGINS/src/dvbhddevice/hdffcmd.h @@ -3,14 +3,14 @@ * * 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 $ + * $Id: hdffcmd.h 1.18 2011/12/04 15:31:23 kls Exp $ */ #ifndef _HDFF_CMD_H_ #define _HDFF_CMD_H_ #include "bitbuffer.h" -#include "hdffmsgdef.h" +#include "libhdffcmd/hdffcmd.h" namespace HDFF { @@ -20,9 +20,6 @@ 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); @@ -32,16 +29,16 @@ public: 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 CmdAvSetVideoPid(uint8_t DecoderIndex, uint16_t VideoPid, HdffVideoStreamType_t StreamType, bool PlaybackMode = false); + void CmdAvSetAudioPid(uint8_t DecoderIndex, uint16_t AudioPid, HdffAudioStreamType_t StreamType, HdffAvContainerType_t ContainerType = HDFF_AV_CONTAINER_PES); void CmdAvSetPcrPid(uint8_t DecoderIndex, uint16_t PcrPid); void CmdAvSetTeletextPid(uint8_t DecoderIndex, uint16_t TeletextPid); void CmdAvSetVideoWindow(uint8_t DecoderIndex, bool Enable, uint16_t X, uint16_t Y, uint16_t Width, uint16_t Height); - void CmdAvShowStillImage(uint8_t DecoderIndex, const uint8_t * pStillImage, int Size, eVideoStreamType StreamType); + void CmdAvShowStillImage(uint8_t DecoderIndex, const uint8_t * pStillImage, int Size, HdffVideoStreamType_t StreamType); void CmdAvSetDecoderInput(uint8_t DecoderIndex, uint8_t DemultiplexerIndex); void CmdAvSetDemultiplexerInput(uint8_t DemultiplexerIndex, uint8_t TsInputIndex); - void CmdAvSetVideoFormat(uint8_t DecoderIndex, const tVideoFormat * pVideoFormat); - void CmdAvSetVideoOutputMode(uint8_t DecoderIndex, eVideoOutputMode OutputMode); + void CmdAvSetVideoFormat(uint8_t DecoderIndex, const HdffVideoFormat_t * pVideoFormat); + void CmdAvSetVideoOutputMode(uint8_t DecoderIndex, HdffVideoOutputMode_t OutputMode); void CmdAvSetStc(uint8_t DecoderIndex, uint64_t Stc); void CmdAvFlushBuffer(uint8_t DecoderIndex, bool FlushAudio, bool FlushVideo); void CmdAvEnableSync(uint8_t DecoderIndex, bool EnableSync); @@ -49,24 +46,24 @@ public: 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 CmdAvSetAudioDownmix(HdffAudioDownmixMode_t DownmixMode); void CmdAvSetAudioChannel(uint8_t AudioChannel); - void CmdOsdConfigure(const tOsdConfig * pConfig); + void CmdOsdConfigure(const HdffOsdConfig_t * pConfig); void CmdOsdReset(void); - uint32_t CmdOsdCreateDisplay(uint32_t Width, uint32_t Height, eColorType ColorType); + uint32_t CmdOsdCreateDisplay(uint32_t Width, uint32_t Height, HdffColorType_t ColorType); void CmdOsdDeleteDisplay(uint32_t hDisplay); void CmdOsdEnableDisplay(uint32_t hDisplay, bool Enable); void CmdOsdSetDisplayOutputRectangle(uint32_t hDisplay, uint32_t X, uint32_t Y, uint32_t Width, uint32_t Height); void CmdOsdSetDisplayClippingArea(uint32_t hDisplay, bool Enable, uint32_t X, uint32_t Y, uint32_t Width, uint32_t Height); void CmdOsdRenderDisplay(uint32_t hDisplay); - uint32_t CmdOsdCreatePalette(eColorType ColorType, eColorFormat ColorFormat, + uint32_t CmdOsdCreatePalette(HdffColorType_t ColorType, HdffColorFormat_t ColorFormat, uint32_t NumColors, const uint32_t * pColors); void CmdOsdDeletePalette(uint32_t hPalette); void CmdOsdSetDisplayPalette(uint32_t hDisplay, uint32_t hPalette); - void CmdOsdSetPaletteColors(uint32_t hPalette, eColorFormat ColorFormat, + void CmdOsdSetPaletteColors(uint32_t hPalette, HdffColorFormat_t ColorFormat, uint8_t StartColor, uint32_t NumColors, const uint32_t * pColors); uint32_t CmdOsdCreateFontFace(const uint8_t * pFontData, uint32_t DataSize); @@ -81,19 +78,19 @@ public: 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); + HdffColorType_t ColorType, uint32_t hPalette); void CmdOsdSaveRegion(uint32_t hDisplay, int X, int Y, int Width, int Height); void CmdOsdRestoreRegion(uint32_t hDisplay); - void CmdMuxSetVideoOut(eVideoOut VideoOut); + void CmdMuxSetVideoOut(HdffVideoOut_t VideoOut); void CmdMuxSetVolume(uint8_t Volume); void CmdMuxMuteAudio(bool Mute); - void CmdHdmiSetVideoMode(eHdmiVideoMode VideoMode); - void CmdHdmiConfigure(const tHdmiConfig * pConfig); - void CmdHdmiSendCecCommand(eCecCommand Command); + void CmdHdmiSetVideoMode(HdffVideoMode_t VideoMode); + void CmdHdmiConfigure(const HdffHdmiConfig_t * pConfig); + void CmdHdmiSendCecCommand(HdffCecCommand_t Command); - void CmdRemoteSetProtocol(eRemoteProtocol Protocol); + void CmdRemoteSetProtocol(HdffRemoteProtocol_t Protocol); void CmdRemoteSetAddressFilter(bool Enable, uint32_t Address); }; diff --git a/PLUGINS/src/dvbhddevice/hdffosd.c b/PLUGINS/src/dvbhddevice/hdffosd.c index 90d6897..a492275 100644 --- a/PLUGINS/src/dvbhddevice/hdffosd.c +++ b/PLUGINS/src/dvbhddevice/hdffosd.c @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: hdffosd.c 1.10 2011/05/15 14:47:29 kls Exp $ + * $Id: hdffosd.c 1.12 2011/12/04 15:31:41 kls Exp $ */ #include "hdffosd.h" @@ -71,7 +71,7 @@ cHdffOsd::cHdffOsd(int Left, int Top, HDFF::cHdffCmdIf * pHdffCmdIf, uint Level) : cOsd(Left, Top, Level) { double pixelAspect; - HDFF::tOsdConfig config; + HdffOsdConfig_t config; //printf("cHdffOsd %d, %d, %d\n", Left, Top, Level); mHdffCmdIf = pHdffCmdIf; @@ -80,24 +80,24 @@ cHdffOsd::cHdffOsd(int Left, int Top, HDFF::cHdffCmdIf * pHdffCmdIf, uint Level) shown = false; mChanged = false; mBitmapModified = false; - mBitmapPalette = InvalidHandle; + mBitmapPalette = HDFF_INVALID_HANDLE; 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); + mDisplay = mHdffCmdIf->CmdOsdCreateDisplay(mDispWidth, mDispHeight, HDFF_COLOR_TYPE_ARGB8888); + mHdffCmdIf->CmdOsdSetDisplayOutputRectangle(mDisplay, 0, 0, HDFF_SIZE_FULL_SCREEN, HDFF_SIZE_FULL_SCREEN); for (int i = 0; i < MAX_NUM_FONTFACES; i++) { mFontFaces[i].Name = ""; - mFontFaces[i].Handle = InvalidHandle; + mFontFaces[i].Handle = HDFF_INVALID_HANDLE; } for (int i = 0; i < MAX_NUM_FONTS; i++) { - mFonts[i].hFontFace = InvalidHandle; + mFonts[i].hFontFace = HDFF_INVALID_HANDLE; mFonts[i].Size = 0; - mFonts[i].Handle = InvalidHandle; + mFonts[i].Handle = HDFF_INVALID_HANDLE; } } @@ -108,18 +108,18 @@ cHdffOsd::~cHdffOsd() for (int i = 0; i < MAX_NUM_FONTS; i++) { - if (mFonts[i].Handle == InvalidHandle) + if (mFonts[i].Handle == HDFF_INVALID_HANDLE) break; mHdffCmdIf->CmdOsdDeleteFont(mFonts[i].Handle); } for (int i = 0; i < MAX_NUM_FONTFACES; i++) { - if (mFontFaces[i].Handle == InvalidHandle) + if (mFontFaces[i].Handle == HDFF_INVALID_HANDLE) break; mHdffCmdIf->CmdOsdDeleteFontFace(mFontFaces[i].Handle); } - if (mBitmapPalette != InvalidHandle) + if (mBitmapPalette != HDFF_INVALID_HANDLE) mHdffCmdIf->CmdOsdDeletePalette(mBitmapPalette); mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, 0, 0, mDispWidth, mDispHeight, 0); mHdffCmdIf->CmdOsdRenderDisplay(mDisplay); @@ -220,19 +220,19 @@ void cHdffOsd::DrawBitmap(int x, int y, const cBitmap &Bitmap, tColor ColorFg, t mBitmapColors[i] = ColorFg; } } - if (mBitmapPalette == InvalidHandle) + if (mBitmapPalette == HDFF_INVALID_HANDLE) { - mBitmapPalette = mHdffCmdIf->CmdOsdCreatePalette(HDFF::colorTypeClut8, - HDFF::colorFormatARGB, numColors, mBitmapColors); + mBitmapPalette = mHdffCmdIf->CmdOsdCreatePalette(HDFF_COLOR_TYPE_CLUT8, + HDFF_COLOR_FORMAT_ARGB, numColors, mBitmapColors); } else { mHdffCmdIf->CmdOsdSetPaletteColors(mBitmapPalette, - HDFF::colorFormatARGB, 0, numColors, mBitmapColors); + HDFF_COLOR_FORMAT_ARGB, 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); + Bitmap.Width() * Bitmap.Height(), HDFF_COLOR_TYPE_CLUT8, mBitmapPalette); #if 0 uint32_t * tmpBitmap = new uint32_t[Bitmap.Width() * Bitmap.Height()]; for (int ix = 0; ix < Bitmap.Width(); ix++) @@ -284,7 +284,7 @@ void cHdffOsd::DrawText(int x, int y, const char *s, tColor ColorFg, tColor Colo pFontFace = NULL; for (i = 0; i < MAX_NUM_FONTFACES; i++) { - if (mFontFaces[i].Handle == InvalidHandle) + if (mFontFaces[i].Handle == HDFF_INVALID_HANDLE) break; if (strcmp(mFontFaces[i].Name, Font->FontName()) == 0) @@ -312,7 +312,7 @@ void cHdffOsd::DrawText(int x, int y, const char *s, tColor ColorFg, tColor Colo if (fread(buffer, fileSize, 1, fp) == 1) { mFontFaces[i].Handle = mHdffCmdIf->CmdOsdCreateFontFace(buffer, fileSize); - if (mFontFaces[i].Handle != InvalidHandle) + if (mFontFaces[i].Handle != HDFF_INVALID_HANDLE) { mFontFaces[i].Name = Font->FontName(); pFontFace = &mFontFaces[i]; @@ -331,7 +331,7 @@ void cHdffOsd::DrawText(int x, int y, const char *s, tColor ColorFg, tColor Colo pFont = NULL; for (i = 0; i < MAX_NUM_FONTS; i++) { - if (mFonts[i].Handle == InvalidHandle) + if (mFonts[i].Handle == HDFF_INVALID_HANDLE) break; if (mFonts[i].hFontFace == pFontFace->Handle @@ -346,7 +346,7 @@ void cHdffOsd::DrawText(int x, int y, const char *s, tColor ColorFg, tColor Colo if (i < MAX_NUM_FONTS) { mFonts[i].Handle = mHdffCmdIf->CmdOsdCreateFont(pFontFace->Handle, size); - if (mFonts[i].Handle != InvalidHandle) + if (mFonts[i].Handle != HDFF_INVALID_HANDLE) { mFonts[i].hFontFace = pFontFace->Handle; mFonts[i].Size = size; @@ -435,9 +435,9 @@ void cHdffOsd::DrawEllipse(int x1, int y1, int x2, int y2, tColor Color, int Qua { case 1: if (Quadrants > 0) - flags = HDFF::drawQuarterTopRight; + flags = HDFF_DRAW_QUARTER_TOP_RIGHT; else - flags = HDFF::drawQuarterTopRightInverted; + flags = HDFF_DRAW_QUARTER_TOP_RIGHT_INVERTED; cx = x1; cy = y2; rx = x2 - x1; @@ -445,9 +445,9 @@ void cHdffOsd::DrawEllipse(int x1, int y1, int x2, int y2, tColor Color, int Qua break; case 2: if (Quadrants > 0) - flags = HDFF::drawQuarterTopLeft; + flags = HDFF_DRAW_QUARTER_TOP_LEFT; else - flags = HDFF::drawQuarterTopLeftInverted; + flags = HDFF_DRAW_QUARTER_TOP_LEFT_INVERTED; cx = x2; cy = y2; rx = x2 - x1; @@ -455,9 +455,9 @@ void cHdffOsd::DrawEllipse(int x1, int y1, int x2, int y2, tColor Color, int Qua break; case 3: if (Quadrants > 0) - flags = HDFF::drawQuarterBottomLeft; + flags = HDFF_DRAW_QUARTER_BOTTOM_LEFT; else - flags = HDFF::drawQuarterBottomLeftInverted; + flags = HDFF_DRAW_QUARTER_BOTTOM_LEFT_INVERTED; cx = x2; cy = y1; rx = x2 - x1; @@ -465,44 +465,44 @@ void cHdffOsd::DrawEllipse(int x1, int y1, int x2, int y2, tColor Color, int Qua break; case 4: if (Quadrants > 0) - flags = HDFF::drawQuarterBottomRight; + flags = HDFF_DRAW_QUARTER_BOTTOM_RIGHT; else - flags = HDFF::drawQuarterBottomRightInverted; + flags = HDFF_DRAW_QUARTER_BOTTOM_RIGHT_INVERTED; cx = x1; cy = y1; rx = x2 - x1; ry = y2 - y1; break; case 5: - flags = HDFF::drawHalfRight; + flags = HDFF_DRAW_HALF_RIGHT; cx = x1; cy = (y1 + y2) / 2; rx = x2 - x1; ry = (y2 - y1) / 2; break; case 6: - flags = HDFF::drawHalfTop; + flags = HDFF_DRAW_HALF_TOP; cx = (x1 + x2) / 2; cy = y2; rx = (x2 - x1) / 2; ry = y2 - y1; break; case 7: - flags = HDFF::drawHalfLeft; + flags = HDFF_DRAW_HALF_LEFT; cx = x2; cy = (y1 + y2) / 2; rx = x2 - x1; ry = (y2 - y1) / 2; break; case 8: - flags = HDFF::drawHalfBottom; + flags = HDFF_DRAW_HALF_BOTTOM; cx = (x1 + x2) / 2; cy = y1; rx = (x2 - x1) / 2; ry = y2 - y1; break; default: - flags = HDFF::drawFull; + flags = HDFF_DRAW_FULL; cx = (x1 + x2) / 2; cy = (y1 + y2) / 2; rx = (x2 - x1) / 2; @@ -552,7 +552,7 @@ private: HDFF::cHdffCmdIf * mHdffCmdIf; int mDispWidth; int mDispHeight; - bool shown; + bool refresh; uint32_t mDisplay; uint32_t mBitmapPalette; uint32_t mBitmapColors[256]; @@ -575,24 +575,27 @@ cHdffOsdRaw::cHdffOsdRaw(int Left, int Top, HDFF::cHdffCmdIf * pHdffCmdIf, uint //printf("cHdffOsdRaw %d, %d, %d\n", Left, Top, Level); mHdffCmdIf = pHdffCmdIf; - shown = false; - mBitmapPalette = InvalidHandle; + refresh = true; + mBitmapPalette = HDFF_INVALID_HANDLE; + mDisplay = HDFF_INVALID_HANDLE; 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) + if (mDisplay != HDFF_INVALID_HANDLE) + { + mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, 0, 0, mDispWidth, mDispHeight, 0); + mHdffCmdIf->CmdOsdRenderDisplay(mDisplay); + } + if (mBitmapPalette != HDFF_INVALID_HANDLE) mHdffCmdIf->CmdOsdDeletePalette(mBitmapPalette); - mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, 0, 0, mDispWidth, mDispHeight, 0); - mHdffCmdIf->CmdOsdRenderDisplay(mDisplay); - mHdffCmdIf->CmdOsdDeleteDisplay(mDisplay); + mBitmapPalette = HDFF_INVALID_HANDLE; + if (mDisplay != HDFF_INVALID_HANDLE) + mHdffCmdIf->CmdOsdDeleteDisplay(mDisplay); + mDisplay = HDFF_INVALID_HANDLE; } void cHdffOsdRaw::SetActive(bool On) @@ -602,14 +605,29 @@ void cHdffOsdRaw::SetActive(bool On) cOsd::SetActive(On); if (On) { + if (mDisplay == HDFF_INVALID_HANDLE) + { + mDisplay = mHdffCmdIf->CmdOsdCreateDisplay(mDispWidth, mDispHeight, HDFF_COLOR_TYPE_ARGB8888); + if (mDisplay != HDFF_INVALID_HANDLE) + mHdffCmdIf->CmdOsdSetDisplayOutputRectangle(mDisplay, 0, 0, HDFF_SIZE_FULL_SCREEN, HDFF_SIZE_FULL_SCREEN); + } + refresh = true; if (GetBitmap(0)) // only flush here if there are already bitmaps Flush(); } - else if (shown) + else { - mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, 0, 0, mDispWidth, mDispHeight, 0); - mHdffCmdIf->CmdOsdRenderDisplay(mDisplay); - shown = false; + if (mDisplay != HDFF_INVALID_HANDLE) + { + mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, 0, 0, mDispWidth, mDispHeight, 0); + mHdffCmdIf->CmdOsdRenderDisplay(mDisplay); + } + if (mBitmapPalette != HDFF_INVALID_HANDLE) + mHdffCmdIf->CmdOsdDeletePalette(mBitmapPalette); + mBitmapPalette = HDFF_INVALID_HANDLE; + if (mDisplay != HDFF_INVALID_HANDLE) + mHdffCmdIf->CmdOsdDeleteDisplay(mDisplay); + mDisplay = HDFF_INVALID_HANDLE; } } } @@ -635,18 +653,18 @@ eOsdError cHdffOsdRaw::SetAreas(const tArea *Areas, int NumAreas) { //printf("SetAreas %d: %d %d %d %d %d\n", i, Areas[i].x1, Areas[i].y1, Areas[i].x2, Areas[i].y2, Areas[i].bpp); } - if (shown) + if (mDisplay != HDFF_INVALID_HANDLE) { mHdffCmdIf->CmdOsdDrawRectangle(mDisplay, 0, 0, mDispWidth, mDispHeight, 0); mHdffCmdIf->CmdOsdRenderDisplay(mDisplay); - shown = false; + refresh = true; } return cOsd::SetAreas(Areas, NumAreas); } void cHdffOsdRaw::Flush(void) { - if (!Active()) + if (!Active() || (mDisplay == HDFF_INVALID_HANDLE)) return; //struct timeval start; //struct timeval end; @@ -673,7 +691,7 @@ void cHdffOsdRaw::Flush(void) mHdffCmdIf->CmdOsdDrawBitmap(mDisplay, Left() + pm->ViewPort().X(), Top() + pm->ViewPort().Y() + y, pm->Data() + y * d, w, hc, hc * d, - HDFF::colorTypeARGB8888, InvalidHandle); + HDFF_COLOR_TYPE_ARGB8888, HDFF_INVALID_HANDLE); } delete pm; render = true; @@ -688,9 +706,9 @@ void cHdffOsdRaw::Flush(void) 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 (refresh || bitmap->Dirty(x1, y1, x2, y2)) { - if (!shown) + if (refresh) { x2 = bitmap->Width() - 1; y2 = bitmap->Height() - 1; @@ -702,15 +720,15 @@ void cHdffOsdRaw::Flush(void) { for (int c = 0; c < numColors; c++) mBitmapColors[c] = colors[c]; - if (mBitmapPalette == InvalidHandle) + if (mBitmapPalette == HDFF_INVALID_HANDLE) { - mBitmapPalette = mHdffCmdIf->CmdOsdCreatePalette(HDFF::colorTypeClut8, - HDFF::colorFormatARGB, numColors, mBitmapColors); + mBitmapPalette = mHdffCmdIf->CmdOsdCreatePalette(HDFF_COLOR_TYPE_CLUT8, + HDFF_COLOR_FORMAT_ARGB, numColors, mBitmapColors); } else { mHdffCmdIf->CmdOsdSetPaletteColors(mBitmapPalette, - HDFF::colorFormatARGB, 0, numColors, mBitmapColors); + HDFF_COLOR_FORMAT_ARGB, 0, numColors, mBitmapColors); } } // commit modified data: @@ -729,7 +747,7 @@ void cHdffOsdRaw::Flush(void) mHdffCmdIf->CmdOsdDrawBitmap(mDisplay, Left() + bitmap->X0() + x1, Top() + bitmap->Y0() + y1 + y, buffer, width, hc, hc * width, - HDFF::colorTypeClut8, mBitmapPalette); + HDFF_COLOR_TYPE_CLUT8, mBitmapPalette); } render = true; } @@ -745,7 +763,7 @@ void cHdffOsdRaw::Flush(void) //timeNeeded += (end.tv_sec - start.tv_sec) * 1000000; //printf("time = %d\n", timeNeeded); } - shown = true; + refresh = false; } diff --git a/PLUGINS/src/dvbhddevice/libhdffcmd/Makefile b/PLUGINS/src/dvbhddevice/libhdffcmd/Makefile new file mode 100644 index 0000000..f9c068a --- /dev/null +++ b/PLUGINS/src/dvbhddevice/libhdffcmd/Makefile @@ -0,0 +1,75 @@ +# +# Makefile for the HDFF firmware command interface library +# + +VERSION = 0.1.0 + +ifndef $(INSTALL_PATH) + INSTALL_PATH=/usr/local +endif + +ifndef $(INSTALL_LIB_PATH) + INSTALL_LIB_PATH=$(INSTALL_PATH)/lib +endif + +ifndef $(INSTALL_INCLUDE_PATH) + INSTALL_INCLUDE_PATH=$(INSTALL_PATH)/include +endif + +LIB_NAME = libhdffcmd + +LIB_OBJS = bitbuffer.o hdffcmd_av.o hdffcmd_base.o hdffcmd_generic.o \ + hdffcmd_hdmi.o hdffcmd_mux.o hdffcmd_osd.o hdffcmd_remote.o + +LIB_HEADERS = hdffcmd.h hdffcmd_av.h hdffcmd_generic.h hdffcmd_hdmi.h \ + hdffcmd_mux.h hdffcmd_osd.h hdffcmd_remote.h + +LIB_STATIC = $(LIB_NAME).a +LIB_SHARED = $(LIB_NAME)-$(VERSION).so + +CC = gcc +CFLAGS = -g -O2 -fPIC -Wall +AR = ar -r + +### Implicit rules: + +%.o: %.c + $(CC) $(CFLAGS) -c $(DEFINES) $(INCLUDES) $< + +# Dependencies: + +MAKEDEP = $(CC) -MM -MG +DEPFILE = .dependencies +$(DEPFILE): Makefile + @$(MAKEDEP) $(DEFINES) $(INCLUDES) $(OBJS:%.o=%.c) > $@ + +-include $(DEPFILE) + +### Targets: + +all: $(LIB_STATIC) $(LIB_SHARED) + +$(LIB_STATIC): $(LIB_OBJS) + $(AR) $(LIB_STATIC) $(LIB_OBJS) + +$(LIB_SHARED): $(LIB_OBJS) + $(CC) -fPIC -shared -o $(LIB_SHARED) $(LIB_OBJS) + ln -sf $(LIB_SHARED) $(LIB_NAME).so + +clean: + rm -f $(LIB_OBJS) $(DEPFILE) $(LIB_STATIC) $(LIB_NAME)*.so + +install: $(LIB_SHARED) + chown root $(LIB_SHARED) + chgrp root $(LIB_SHARED) + chmod 0755 $(LIB_SHARED) + cp -f $(LIB_SHARED) $(INSTALL_LIB_PATH)/ + ln -sf $(LIB_SHARED) $(INSTALL_LIB_PATH)/$(LIB_NAME).so + mkdir -p $(INSTALL_INCLUDE_PATH)/libhdffcmd + list='$(LIB_HEADERS)'; \ + for headerfile in $$list; do \ + cp -f $$headerfile $(INSTALL_INCLUDE_PATH)/libhdffcmd/ ; \ + chown root $(INSTALL_INCLUDE_PATH)/libhdffcmd/$$headerfile ; \ + chgrp root $(INSTALL_INCLUDE_PATH)/libhdffcmd/$$headerfile ; \ + chmod 0644 $(INSTALL_INCLUDE_PATH)/libhdffcmd/$$headerfile ; \ + done diff --git a/PLUGINS/src/dvbhddevice/libhdffcmd/bitbuffer.c b/PLUGINS/src/dvbhddevice/libhdffcmd/bitbuffer.c new file mode 100644 index 0000000..b85990d --- /dev/null +++ b/PLUGINS/src/dvbhddevice/libhdffcmd/bitbuffer.c @@ -0,0 +1,79 @@ +/********************************************************************** + * + * HDFF firmware command interface library + * + * Copyright (C) 2011 Andreas Regel + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + *********************************************************************/ + +#include <string.h> + +#include "bitbuffer.h" + +void BitBuffer_Init(BitBuffer_t * BitBuffer, + uint8_t * Data, uint32_t MaxLength) +{ + memset(Data, 0, MaxLength); + BitBuffer->Data = Data; + BitBuffer->MaxLength = MaxLength * 8; + BitBuffer->BitPos = 0; +} + +void BitBuffer_SetBits(BitBuffer_t * BitBuffer, int NumBits, uint32_t Data) +{ + uint32_t nextBitPos; + uint32_t bytePos; + uint32_t bitsInByte; + int shift; + + if (NumBits <= 0 || NumBits > 32) + return; + + nextBitPos = BitBuffer->BitPos + NumBits; + + if (nextBitPos > BitBuffer->MaxLength) + return; + + bytePos = BitBuffer->BitPos / 8; + bitsInByte = BitBuffer->BitPos % 8; + + BitBuffer->Data[bytePos] &= (uint8_t) (0xFF << (8 - bitsInByte)); + shift = NumBits - (8 - bitsInByte); + if (shift > 0) + BitBuffer->Data[bytePos] |= (uint8_t) (Data >> shift); + else + BitBuffer->Data[bytePos] |= (uint8_t) (Data << (-shift)); + NumBits -= 8 - bitsInByte; + bytePos++; + while (NumBits > 0) + { + shift = NumBits - 8; + if (shift > 0) + BitBuffer->Data[bytePos] = (uint8_t) (Data >> shift); + else + BitBuffer->Data[bytePos] = (uint8_t) (Data << (-shift)); + NumBits -= 8; + bytePos++; + } + BitBuffer->BitPos = nextBitPos; +} + +uint32_t BitBuffer_GetByteLength(BitBuffer_t * BitBuffer) +{ + return (BitBuffer->BitPos + 7) / 8; +} diff --git a/PLUGINS/src/dvbhddevice/libhdffcmd/bitbuffer.h b/PLUGINS/src/dvbhddevice/libhdffcmd/bitbuffer.h new file mode 100644 index 0000000..5bdc23b --- /dev/null +++ b/PLUGINS/src/dvbhddevice/libhdffcmd/bitbuffer.h @@ -0,0 +1,43 @@ +/********************************************************************** + * + * HDFF firmware command interface library + * + * Copyright (C) 2011 Andreas Regel + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + *********************************************************************/ + +#ifndef BITBUFFER_H +#define BITBUFFER_H + +#include <stdint.h> + +typedef struct BitBuffer_t +{ + uint8_t * Data; + uint32_t MaxLength; + uint32_t BitPos; +} BitBuffer_t; + +void BitBuffer_Init(BitBuffer_t * BitBuffer, + uint8_t * Data, uint32_t MaxLength); + +void BitBuffer_SetBits(BitBuffer_t * BitBuffer, int NumBits, uint32_t Data); + +uint32_t BitBuffer_GetByteLength(BitBuffer_t * BitBuffer); + +#endif /* BITBUFFER_H */ diff --git a/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd.h b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd.h new file mode 100644 index 0000000..8d05782 --- /dev/null +++ b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd.h @@ -0,0 +1,42 @@ +/********************************************************************** + * + * HDFF firmware command interface library + * + * Copyright (C) 2011 Andreas Regel + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + *********************************************************************/ + +#ifndef HDFFCMD_H +#define HDFFCMD_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "hdffcmd_av.h" +#include "hdffcmd_generic.h" +#include "hdffcmd_hdmi.h" +#include "hdffcmd_mux.h" +#include "hdffcmd_osd.h" +#include "hdffcmd_remote.h" + +#ifdef __cplusplus +} +#endif + +#endif /* HDFFCMD_H */ diff --git a/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_av.c b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_av.c new file mode 100644 index 0000000..413f3e2 --- /dev/null +++ b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_av.c @@ -0,0 +1,451 @@ +/********************************************************************** + * + * HDFF firmware command interface library + * + * Copyright (C) 2011 Andreas Regel + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + *********************************************************************/ + +#include <stdint.h> +#include <string.h> +#include <sys/ioctl.h> + +#include "hdffcmd.h" +#include "hdffcmd_base.h" +#include "hdffcmd_defs.h" + + +int HdffCmdAvSetPlayMode(int OsdDevice, uint8_t PlayMode, int Realtime) +{ + uint8_t cmdData[8]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, + HDFF_MSG_GROUP_AV_DECODER, + HDFF_MSG_AV_SET_PLAY_MODE); + BitBuffer_SetBits(&cmdBuf, 1, Realtime ? 1 : 0); + BitBuffer_SetBits(&cmdBuf, 7, PlayMode); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdAvSetVideoPid(int OsdDevice, uint8_t DecoderIndex, uint16_t Pid, + HdffVideoStreamType_t StreamType) +{ + uint8_t cmdData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, + HDFF_MSG_GROUP_AV_DECODER, + HDFF_MSG_AV_SET_VIDEO_PID); + BitBuffer_SetBits(&cmdBuf, 4, DecoderIndex); + BitBuffer_SetBits(&cmdBuf, 4, StreamType); + BitBuffer_SetBits(&cmdBuf, 3, 0); // reserved + BitBuffer_SetBits(&cmdBuf, 13, Pid); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdAvSetAudioPid(int OsdDevice, uint8_t DecoderIndex, uint16_t Pid, + HdffAudioStreamType_t StreamType, + HdffAvContainerType_t ContainerType) +{ + uint8_t cmdData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, + HDFF_MSG_GROUP_AV_DECODER, + HDFF_MSG_AV_SET_AUDIO_PID); + BitBuffer_SetBits(&cmdBuf, 4, DecoderIndex); + BitBuffer_SetBits(&cmdBuf, 4, StreamType); + BitBuffer_SetBits(&cmdBuf, 2, 0); // reserved + BitBuffer_SetBits(&cmdBuf, 1, ContainerType); + BitBuffer_SetBits(&cmdBuf, 13, Pid); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdAvSetPcrPid(int OsdDevice, uint8_t DecoderIndex, uint16_t Pid) +{ + uint8_t cmdData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, + HDFF_MSG_GROUP_AV_DECODER, + HDFF_MSG_AV_SET_PCR_PID); + BitBuffer_SetBits(&cmdBuf, 4, DecoderIndex); + BitBuffer_SetBits(&cmdBuf, 4, 0); // reserved + BitBuffer_SetBits(&cmdBuf, 3, 0); // reserved + BitBuffer_SetBits(&cmdBuf, 13, Pid); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdAvSetTeletextPid(int OsdDevice, uint8_t DecoderIndex, uint16_t Pid) +{ + uint8_t cmdData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, + HDFF_MSG_GROUP_AV_DECODER, + HDFF_MSG_AV_SET_TELETEXT_PID); + BitBuffer_SetBits(&cmdBuf, 4, DecoderIndex); + BitBuffer_SetBits(&cmdBuf, 4, 0); // reserved + BitBuffer_SetBits(&cmdBuf, 3, 0); // reserved + BitBuffer_SetBits(&cmdBuf, 13, Pid); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdAvSetVideoWindow(int OsdDevice, uint8_t DecoderIndex, int Enable, + uint16_t X, uint16_t Y, uint16_t Width, + uint16_t Height) +{ + uint8_t cmdData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, + HDFF_MSG_GROUP_AV_DECODER, + HDFF_MSG_AV_SET_VIDEO_WINDOW); + BitBuffer_SetBits(&cmdBuf, 4, DecoderIndex); + BitBuffer_SetBits(&cmdBuf, 3, 0); // reserved + if (Enable) + BitBuffer_SetBits(&cmdBuf, 1, 1); + else + BitBuffer_SetBits(&cmdBuf, 1, 0); + BitBuffer_SetBits(&cmdBuf, 16, X); + BitBuffer_SetBits(&cmdBuf, 16, Y); + BitBuffer_SetBits(&cmdBuf, 16, Width); + BitBuffer_SetBits(&cmdBuf, 16, Height); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdAvShowStillImage(int OsdDevice, uint8_t DecoderIndex, + const uint8_t * StillImage, int Size, + HdffVideoStreamType_t StreamType) +{ + uint8_t cmdData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + osd_raw_data_t osd_data; + int err; + + memset(&osd_data, 0, sizeof(osd_raw_data_t)); + osd_data.data_buffer = StillImage; + osd_data.data_length = Size; + err = ioctl(OsdDevice, OSD_RAW_DATA, &osd_data); + if (err != 0) + return err; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, + HDFF_MSG_GROUP_AV_DECODER, + HDFF_MSG_AV_SHOW_STILL_IMAGE); + BitBuffer_SetBits(&cmdBuf, 4, DecoderIndex); + BitBuffer_SetBits(&cmdBuf, 4, StreamType); + BitBuffer_SetBits(&cmdBuf, 16, osd_data.data_handle); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdAvSetDecoderInput(int OsdDevice, uint8_t DecoderIndex, + uint8_t DemultiplexerIndex) +{ + uint8_t cmdData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, + HDFF_MSG_GROUP_AV_DECODER, + HDFF_MSG_AV_SET_DECODER_INPUT); + BitBuffer_SetBits(&cmdBuf, 4, DecoderIndex); + BitBuffer_SetBits(&cmdBuf, 4, DemultiplexerIndex); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdAvSetDemultiplexerInput(int OsdDevice, uint8_t DemultiplexerIndex, + uint8_t TsInputIndex) +{ + uint8_t cmdData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, + HDFF_MSG_GROUP_AV_DECODER, + HDFF_MSG_AV_SET_DEMULTIPLEXER_INPUT); + BitBuffer_SetBits(&cmdBuf, 4, DemultiplexerIndex); + BitBuffer_SetBits(&cmdBuf, 4, TsInputIndex); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdAvSetVideoFormat(int OsdDevice, uint8_t DecoderIndex, + const HdffVideoFormat_t * VideoFormat) +{ + uint8_t cmdData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, + HDFF_MSG_GROUP_AV_DECODER, + HDFF_MSG_AV_SET_VIDEO_FORMAT); + BitBuffer_SetBits(&cmdBuf, 4, DecoderIndex); + BitBuffer_SetBits(&cmdBuf, 1, VideoFormat->AutomaticEnabled ? 1 : 0); + BitBuffer_SetBits(&cmdBuf, 1, VideoFormat->AfdEnabled ? 1 : 0); + BitBuffer_SetBits(&cmdBuf, 2, VideoFormat->TvFormat); + BitBuffer_SetBits(&cmdBuf, 8, VideoFormat->VideoConversion); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdAvSetVideoOutputMode(int OsdDevice, uint8_t DecoderIndex, + HdffVideoOutputMode_t OutputMode) +{ + uint8_t cmdData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, + HDFF_MSG_GROUP_AV_DECODER, + HDFF_MSG_AV_SET_VIDEO_OUTPUT_MODE); + BitBuffer_SetBits(&cmdBuf, 8, OutputMode); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdAvSetStc(int OsdDevice, uint8_t DecoderIndex, uint64_t Stc) +{ + uint8_t cmdData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, + HDFF_MSG_GROUP_AV_DECODER, + HDFF_MSG_AV_SET_STC); + BitBuffer_SetBits(&cmdBuf, 4, DecoderIndex); + BitBuffer_SetBits(&cmdBuf, 3, 0); // reserved + BitBuffer_SetBits(&cmdBuf, 1, (uint32_t) (Stc >> 32)); + BitBuffer_SetBits(&cmdBuf, 32, (uint32_t) Stc); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdAvFlushBuffer(int OsdDevice, uint8_t DecoderIndex, int FlushAudio, + int FlushVideo) +{ + uint8_t cmdData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, + HDFF_MSG_GROUP_AV_DECODER, + HDFF_MSG_AV_FLUSH_BUFFER); + BitBuffer_SetBits(&cmdBuf, 4, DecoderIndex); + if (FlushAudio) + { + BitBuffer_SetBits(&cmdBuf, 1, 1); + } + else + { + BitBuffer_SetBits(&cmdBuf, 1, 0); + } + if (FlushVideo) + { + BitBuffer_SetBits(&cmdBuf, 1, 1); + } + else + { + BitBuffer_SetBits(&cmdBuf, 1, 0); + } + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdAvEnableSync(int OsdDevice, uint8_t DecoderIndex, int SyncAudio, + int SyncVideo) +{ + uint8_t cmdData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, + HDFF_MSG_GROUP_AV_DECODER, + HDFF_MSG_AV_ENABLE_SYNC); + BitBuffer_SetBits(&cmdBuf, 4, DecoderIndex); + BitBuffer_SetBits(&cmdBuf, 1, SyncAudio ? 1 : 0); + BitBuffer_SetBits(&cmdBuf, 1, SyncVideo ? 1 : 0); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdAvSetVideoSpeed(int OsdDevice, uint8_t DecoderIndex, int32_t Speed) +{ + uint8_t cmdData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, + HDFF_MSG_GROUP_AV_DECODER, + HDFF_MSG_AV_SET_VIDEO_SPEED); + BitBuffer_SetBits(&cmdBuf, 4, DecoderIndex); + BitBuffer_SetBits(&cmdBuf, 4, 0); + BitBuffer_SetBits(&cmdBuf, 32, Speed); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdAvSetAudioSpeed(int OsdDevice, uint8_t DecoderIndex, int32_t Speed) +{ + uint8_t cmdData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, + HDFF_MSG_GROUP_AV_DECODER, + HDFF_MSG_AV_SET_AUDIO_SPEED); + BitBuffer_SetBits(&cmdBuf, 4, DecoderIndex); + BitBuffer_SetBits(&cmdBuf, 4, 0); + BitBuffer_SetBits(&cmdBuf, 32, Speed); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdAvEnableVideoAfterStop(int OsdDevice, uint8_t DecoderIndex, + int EnableVideoAfterStop) +{ + uint8_t cmdData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, + HDFF_MSG_GROUP_AV_DECODER, + HDFF_MSG_AV_ENABLE_VIDEO_AFTER_STOP); + BitBuffer_SetBits(&cmdBuf, 4, DecoderIndex); + BitBuffer_SetBits(&cmdBuf, 1, EnableVideoAfterStop ? 1 : 0); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdAvSetAudioDelay(int OsdDevice, int16_t Delay) +{ + uint8_t cmdData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, + HDFF_MSG_GROUP_AV_DECODER, + HDFF_MSG_AV_SET_AUDIO_DELAY); + BitBuffer_SetBits(&cmdBuf, 16, Delay); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdAvSetAudioDownmix(int OsdDevice, HdffAudioDownmixMode_t DownmixMode) +{ + uint8_t cmdData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, + HDFF_MSG_GROUP_AV_DECODER, + HDFF_MSG_AV_SET_AUDIO_DOWNMIX); + BitBuffer_SetBits(&cmdBuf, 8, DownmixMode); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdAvSetAudioChannel(int OsdDevice, uint8_t AudioChannel) +{ + uint8_t cmdData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, + HDFF_MSG_GROUP_AV_DECODER, + HDFF_MSG_AV_SET_AUDIO_CHANNEL); + BitBuffer_SetBits(&cmdBuf, 8, AudioChannel); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} diff --git a/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_av.h b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_av.h new file mode 100644 index 0000000..7c2189b --- /dev/null +++ b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_av.h @@ -0,0 +1,151 @@ +/********************************************************************** + * + * HDFF firmware command interface library + * + * Copyright (C) 2011 Andreas Regel + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + *********************************************************************/ + +#ifndef HDFFCMD_AV_H +#define HDFFCMD_AV_H + +typedef enum HdffAvContainerType_t +{ + HDFF_AV_CONTAINER_PES, + HDFF_AV_CONTAINER_PES_DVD +} HdffAvContainerType_t; + +typedef enum HdffAudioStreamType_t +{ + HDFF_AUDIO_STREAM_INVALID = -1, + HDFF_AUDIO_STREAM_MPEG1 = 0, + HDFF_AUDIO_STREAM_MPEG2, + HDFF_AUDIO_STREAM_AC3, + HDFF_AUDIO_STREAM_AAC, + HDFF_AUDIO_STREAM_HE_AAC, + HDFF_AUDIO_STREAM_PCM, + HDFF_AUDIO_STREAM_EAC3, + HDFF_AUDIO_STREAM_DTS +} HdffAudioStreamType_t; + +typedef enum HdffVideoStreamType_t +{ + HDFF_VIDEO_STREAM_INVALID = -1, + HDFF_VIDEO_STREAM_MPEG1 = 0, + HDFF_VIDEO_STREAM_MPEG2, + HDFF_VIDEO_STREAM_H264, + HDFF_VIDEO_STREAM_MPEG4_ASP, + HDFF_VIDEO_STREAM_VC1 +} HdffVideoStreamType_t; + +typedef enum HdffTvFormat_t +{ + HDFF_TV_FORMAT_4_BY_3, + HDFF_TV_FORMAT_16_BY_9 +} HdffTvFormat_t; + +typedef enum HdffVideoConversion_t +{ + HDFF_VIDEO_CONVERSION_AUTOMATIC, + HDFF_VIDEO_CONVERSION_LETTERBOX_16_BY_9, + HDFF_VIDEO_CONVERSION_LETTERBOX_14_BY_9, + HDFF_VIDEO_CONVERSION_PILLARBOX, + HDFF_VIDEO_CONVERSION_CENTRE_CUT_OUT, + HDFF_VIDEO_CONVERSION_ALWAYS_16_BY_9 +} HdffVideoConversion_t; + +typedef struct HdffVideoFormat_t +{ + int AutomaticEnabled; + int AfdEnabled; + HdffTvFormat_t TvFormat; + HdffVideoConversion_t VideoConversion; +} HdffVideoFormat_t; + +typedef enum HdffVideoOutputMode_t +{ + HDFF_VIDEO_OUTPUT_CLONE, + HDFF_VIDEO_OUTPUT_HD_ONLY +} HdffVideoOutputMode_t; + +typedef enum HdffAudioDownmixMode_t +{ + HDFF_AUDIO_DOWNMIX_OFF, + HDFF_AUDIO_DOWNMIX_ANALOG, + HDFF_AUDIO_DOWNMIX_ALWAYS, + HDFF_AUDIO_DOWNMIX_AUTOMATIC, + HDFF_AUDIO_DOWNMIX_HDMI_ONLY +} HdffAudioDownmixMode_t; + + +int HdffCmdAvSetPlayMode(int OsdDevice, uint8_t PlayMode, int Realtime); + +int HdffCmdAvSetVideoPid(int OsdDevice, uint8_t DecoderIndex, uint16_t Pid, + HdffVideoStreamType_t StreamType); + +int HdffCmdAvSetAudioPid(int OsdDevice, uint8_t DecoderIndex, uint16_t Pid, + HdffAudioStreamType_t StreamType, + HdffAvContainerType_t ContainerType); + +int HdffCmdAvSetPcrPid(int OsdDevice, uint8_t DecoderIndex, uint16_t Pid); + +int HdffCmdAvSetTeletextPid(int OsdDevice, uint8_t DecoderIndex, uint16_t Pid); + +int HdffCmdAvSetVideoWindow(int OsdDevice, uint8_t DecoderIndex, int Enable, + uint16_t X, uint16_t Y, uint16_t Width, + uint16_t Height); + +int HdffCmdAvShowStillImage(int OsdDevice, uint8_t DecoderIndex, + const uint8_t * StillImage, int Size, + HdffVideoStreamType_t StreamType); + +int HdffCmdAvSetDecoderInput(int OsdDevice, uint8_t DecoderIndex, + uint8_t DemultiplexerIndex); + +int HdffCmdAvSetDemultiplexerInput(int OsdDevice, uint8_t DemultiplexerIndex, + uint8_t TsInputIndex); + +int HdffCmdAvSetVideoFormat(int OsdDevice, uint8_t DecoderIndex, + const HdffVideoFormat_t * VideoFormat); + +int HdffCmdAvSetVideoOutputMode(int OsdDevice, uint8_t DecoderIndex, + HdffVideoOutputMode_t OutputMode); + +int HdffCmdAvSetStc(int OsdDevice, uint8_t DecoderIndex, uint64_t Stc); + +int HdffCmdAvFlushBuffer(int OsdDevice, uint8_t DecoderIndex, int FlushAudio, + int FlushVideo); + +int HdffCmdAvEnableSync(int OsdDevice, uint8_t DecoderIndex, int SyncAudio, + int SyncVideo); + +int HdffCmdAvSetVideoSpeed(int OsdDevice, uint8_t DecoderIndex, int32_t Speed); + +int HdffCmdAvSetAudioSpeed(int OsdDevice, uint8_t DecoderIndex, int32_t Speed); + +int HdffCmdAvEnableVideoAfterStop(int OsdDevice, uint8_t DecoderIndex, + int EnableVideoAfterStop); + +int HdffCmdAvSetAudioDelay(int OsdDevice, int16_t Delay); + +int HdffCmdAvSetAudioDownmix(int OsdDevice, + HdffAudioDownmixMode_t DownmixMode); + +int HdffCmdAvSetAudioChannel(int OsdDevice, uint8_t AudioChannel); + +#endif /* HDFFCMD_AV_H */ diff --git a/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_base.c b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_base.c new file mode 100644 index 0000000..ac1ab7e --- /dev/null +++ b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_base.c @@ -0,0 +1,45 @@ +/********************************************************************** + * + * HDFF firmware command interface library + * + * Copyright (C) 2011 Andreas Regel + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + *********************************************************************/ + +#include "hdffcmd_base.h" + +void HdffCmdBuildHeader(BitBuffer_t * MsgBuf, HdffMessageType_t MsgType, + HdffMessageGroup_t MsgGroup, HdffMessageId_t MsgId) +{ + BitBuffer_SetBits(MsgBuf, 16, 0); // length field will be set later + BitBuffer_SetBits(MsgBuf, 6, 0); // reserved + BitBuffer_SetBits(MsgBuf, 2, MsgType); + BitBuffer_SetBits(MsgBuf, 8, MsgGroup); + BitBuffer_SetBits(MsgBuf, 16, MsgId); +} + +uint32_t HdffCmdSetLength(BitBuffer_t * MsgBuf) +{ + uint32_t length; + + length = BitBuffer_GetByteLength(MsgBuf) - 2; + MsgBuf->Data[0] = (uint8_t) (length >> 8); + MsgBuf->Data[1] = (uint8_t) length; + + return length + 2; +} diff --git a/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_base.h b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_base.h new file mode 100644 index 0000000..b6856aa --- /dev/null +++ b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_base.h @@ -0,0 +1,55 @@ +/********************************************************************** + * + * HDFF firmware command interface library + * + * Copyright (C) 2011 Andreas Regel + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + *********************************************************************/ + +#ifndef HDFFCMD_BASE_H +#define HDFFCMD_BASE_H + +#include <linux/dvb/osd.h> + +#if !defined OSD_RAW_CMD +typedef struct osd_raw_cmd_s { + const void *cmd_data; + int cmd_len; + void *result_data; + int result_len; +} osd_raw_cmd_t; + +typedef struct osd_raw_data_s { + const void *data_buffer; + int data_length; + int data_handle; +} osd_raw_data_t; + +#define OSD_RAW_CMD _IOWR('o', 162, osd_raw_cmd_t) +#define OSD_RAW_DATA _IOWR('o', 163, osd_raw_data_t) +#endif + +#include "bitbuffer.h" +#include "hdffcmd_defs.h" + +void HdffCmdBuildHeader(BitBuffer_t * MsgBuf, HdffMessageType_t MsgType, + HdffMessageGroup_t MsgGroup, HdffMessageId_t MsgId); + +uint32_t HdffCmdSetLength(BitBuffer_t * MsgBuf); + +#endif /* HDFFCMD_BASE_H */ diff --git a/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_defs.h b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_defs.h new file mode 100644 index 0000000..8b24d7b --- /dev/null +++ b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_defs.h @@ -0,0 +1,120 @@ +/********************************************************************** + * + * HDFF firmware command interface library + * + * Copyright (C) 2011 Andreas Regel + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + *********************************************************************/ + +#ifndef HDFFCMD_DEFS_H +#define HDFFCMD_DEFS_H + +typedef enum HdffMessageType_t +{ + HDFF_MSG_TYPE_COMMAND, + HDFF_MSG_TYPE_ANSWER, + HDFF_MSG_TYPE_RESULT, + HDFF_MSG_TYPE_EVENT +} HdffMessageType_t; + +typedef enum HdffMessageGroup_t +{ + HDFF_MSG_GROUP_GENERIC, + HDFF_MSG_GROUP_AV_DECODER, + HDFF_MSG_GROUP_AV_MUX, + HDFF_MSG_GROUP_FRONTEND, + HDFF_MSG_GROUP_OSD, + HDFF_MSG_GROUP_HDMI, + HDFF_MSG_GROUP_REMOTE_CONTROL +} HdffMessageGroup_t; + +typedef enum HdffMessageId_t +{ + HDFF_MSG_GEN_GET_FIRMWARE_VERSION = 0, + HDFF_MSG_GEN_GET_INTERFACE_VERSION, + HDFF_MSG_GEN_GET_COPYRIGHTS, + + HDFF_MSG_AV_SET_AUDIO_PID = 0, + HDFF_MSG_AV_SET_VIDEO_PID, + HDFF_MSG_AV_SET_PCR_PID, + HDFF_MSG_AV_SET_TELETEXT_PID, + HDFF_MSG_AV_SHOW_STILL_IMAGE, + HDFF_MSG_AV_SET_VIDEO_WINDOW, + HDFF_MSG_AV_SET_DECODER_INPUT, + HDFF_MSG_AV_SET_DEMULTIPLEXER_INPUT, + HDFF_MSG_AV_SET_VIDEO_FORMAT, + HDFF_MSG_AV_SET_VIDEO_OUTPUT_MODE, + HDFF_MSG_AV_SET_STC, + HDFF_MSG_AV_FLUSH_BUFFER, + HDFF_MSG_AV_ENABLE_SYNC, + HDFF_MSG_AV_SET_VIDEO_SPEED, + HDFF_MSG_AV_SET_AUDIO_SPEED, + HDFF_MSG_AV_ENABLE_VIDEO_AFTER_STOP, + HDFF_MSG_AV_GET_VIDEO_FORMAT_INFO, + HDFF_MSG_AV_SET_AUDIO_DELAY, + HDFF_MSG_AV_SET_AUDIO_DOWNMIX, + HDFF_MSG_AV_SET_AUDIO_CHANNEL, + HDFF_MSG_AV_SET_PLAY_MODE, + + HDFF_MSG_MUX_SET_VIDEO_OUT = 0, + HDFF_MSG_MUX_SET_SLOW_BLANK, + HDFF_MSG_MUX_SET_FAST_BLANK, + HDFF_MSG_MUX_SET_VOLUME, + HDFF_MSG_MUX_SET_AUDIO_MUTE, + + HDFF_MSG_OSD_CONFIGURE = 0, + HDFF_MSG_OSD_RESET, + HDFF_MSG_OSD_CREATE_DISPLAY = 10, + HDFF_MSG_OSD_DELETE_DISPLAY, + HDFF_MSG_OSD_ENABLE_DISPLAY, + HDFF_MSG_OSD_SET_DISPLAY_OUTPUT_RECTANGLE, + HDFF_MSG_OSD_SET_DISPLAY_CLIPPLING_AREA, + HDFF_MSG_OSD_RENDER_DISPLAY, + HDFF_MSG_OSD_SAVE_REGION, + HDFF_MSG_OSD_RESTORE_REGION, + HDFF_MSG_OSD_CREATE_PALETTE = 30, + HDFF_MSG_OSD_DELETE_PALETTE, + HDFF_MSG_OSD_SET_DISPLAY_PALETTE, + HDFF_MSG_OSD_SET_PALETTE_COLORS, + HDFF_MSG_OSD_CREATE_FONT_FACE = 50, + HDFF_MSG_OSD_DELETE_FONT_FACE, + HDFF_MSG_OSD_CREATE_FONT, + HDFF_MSG_OSD_DELETE_FONT, + HDFF_MSG_OSD_DRAW_PIXEL = 70, + HDFF_MSG_OSD_DRAW_RECTANGLE, + HDFF_MSG_OSD_DRAW_CIRCLE, + HDFF_MSG_OSD_DRAW_ELLIPSE, + HDFF_MSG_OSD_DRAW_SLOPE, + HDFF_MSG_OSD_DRAW_TEXT, + HDFF_MSG_OSD_DRAW_WIDE_TEXT, + HDFF_MSG_OSD_DRAW_BITMAP, + + HDFF_MSG_HDMI_ENABLE_OUTPUT = 0, + HDFF_MSG_HDMI_SET_VIDEO_MODE, + HDFF_MSG_HDMI_CONFIGURE, + HDFF_MSG_HDMI_IS_DISPLAY_CONNECTED, + HDFF_MSG_HDMI_GET_DISPLAY_INFO, + HDFF_MSG_HDMI_GET_VIDEO_MODE, + HDFF_MSG_HDMI_SEND_CEC_COMMAND, + + HDFF_MSG_REMOTE_SET_PROTOCOL = 0, + HDFF_MSG_REMOTE_SET_ADDRESS_FILTER, + HDFF_MSG_REMOTE_KEY_EVENT +} HdffMessageId_t; + +#endif /* HDFFCMD_DEFS_H */ diff --git a/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_generic.c b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_generic.c new file mode 100644 index 0000000..f72a7d3 --- /dev/null +++ b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_generic.c @@ -0,0 +1,147 @@ +/********************************************************************** + * + * HDFF firmware command interface library + * + * Copyright (C) 2011 Andreas Regel + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + *********************************************************************/ + +#include <stdint.h> +#include <string.h> +#include <sys/ioctl.h> + +#include "hdffcmd.h" +#include "hdffcmd_base.h" +#include "hdffcmd_defs.h" + +int HdffCmdGetFirmwareVersion(int OsdDevice, uint32_t * Version, char * String, + uint32_t MaxLength) +{ + uint8_t cmdData[8]; + uint8_t resultData[64]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + int err; + + *Version = 0; + String[0] = 0; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + osd_cmd.result_data = resultData; + osd_cmd.result_len = sizeof(resultData); + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_GENERIC, + HDFF_MSG_GEN_GET_FIRMWARE_VERSION); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + err = ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); + if (err == 0) + { + if (osd_cmd.result_len > 0) + { + uint8_t textLength = resultData[9]; + if (textLength >= MaxLength) + textLength = MaxLength - 1; + memcpy(String, &resultData[10], textLength); + String[textLength] = 0; + *Version = (resultData[6] << 16) + | (resultData[7] << 8) + | resultData[8]; + } + } + return err; +} + +int HdffCmdGetInterfaceVersion(int OsdDevice, uint32_t * Version, char * String, + uint32_t MaxLength) +{ + uint8_t cmdData[8]; + uint8_t resultData[64]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + int err; + + *Version = 0; + String[0] = 0; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + osd_cmd.result_data = resultData; + osd_cmd.result_len = sizeof(resultData); + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_GENERIC, + HDFF_MSG_GEN_GET_INTERFACE_VERSION); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + err = ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); + if (err == 0) + { + if (osd_cmd.result_len > 0) + { + uint8_t textLength = resultData[9]; + if (textLength >= MaxLength) + textLength = MaxLength - 1; + memcpy(String, &resultData[10], textLength); + String[textLength] = 0; + *Version = (resultData[6] << 16) + | (resultData[7] << 8) + | resultData[8]; + } + } + return err; +} + +int HdffCmdGetCopyrights(int OsdDevice, uint8_t Index, char * String, + uint32_t MaxLength) +{ + uint8_t cmdData[8]; + uint8_t resultData[280]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + int err; + + String[0] = 0; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + osd_cmd.result_data = resultData; + osd_cmd.result_len = sizeof(resultData); + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_GENERIC, + HDFF_MSG_GEN_GET_COPYRIGHTS); + BitBuffer_SetBits(&cmdBuf, 8, Index); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + err = ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); + if (err == 0) + { + if (osd_cmd.result_len > 0) + { + uint8_t index = resultData[6]; + uint8_t textLen = resultData[7]; + if (index == Index && textLen > 0) + { + if (textLen >= MaxLength) + { + textLen = MaxLength - 1; + } + memcpy(String, resultData + 8, textLen); + String[textLen] = 0; + } + } + } + return err; +} diff --git a/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_generic.h b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_generic.h new file mode 100644 index 0000000..c12b296 --- /dev/null +++ b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_generic.h @@ -0,0 +1,36 @@ +/********************************************************************** + * + * HDFF firmware command interface library + * + * Copyright (C) 2011 Andreas Regel + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + *********************************************************************/ + +#ifndef HDFFCMD_GENERIC_H +#define HDFFCMD_GENERIC_H + +int HdffCmdGetFirmwareVersion(int OsdDevice, uint32_t * Version, char * String, + uint32_t MaxLength); + +int HdffCmdGetInterfaceVersion(int OsdDevice, uint32_t * Version, char * String, + uint32_t MaxLength); + +int HdffCmdGetCopyrights(int OsdDevice, uint8_t Index, char * String, + uint32_t MaxLength); + +#endif /* HDFFCMD_GENERIC_H */ diff --git a/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_hdmi.c b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_hdmi.c new file mode 100644 index 0000000..42b82b5 --- /dev/null +++ b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_hdmi.c @@ -0,0 +1,82 @@ +/********************************************************************** + * + * HDFF firmware command interface library + * + * Copyright (C) 2011 Andreas Regel + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + *********************************************************************/ + +#include <stdint.h> +#include <string.h> +#include <sys/ioctl.h> + +#include "hdffcmd.h" +#include "hdffcmd_base.h" +#include "hdffcmd_defs.h" + + +int HdffCmdHdmiSetVideoMode(int OsdDevice, HdffVideoMode_t VideoMode) +{ + uint8_t cmdData[8]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_HDMI, + HDFF_MSG_HDMI_SET_VIDEO_MODE); + BitBuffer_SetBits(&cmdBuf, 8, VideoMode); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdHdmiConfigure(int OsdDevice, const HdffHdmiConfig_t * Config) +{ + uint8_t cmdData[8]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_HDMI, + HDFF_MSG_HDMI_CONFIGURE); + BitBuffer_SetBits(&cmdBuf, 1, Config->TransmitAudio ? 1 : 0); + BitBuffer_SetBits(&cmdBuf, 1, Config->ForceDviMode ? 1 : 0); + BitBuffer_SetBits(&cmdBuf, 1, Config->CecEnabled ? 1 : 0); + BitBuffer_SetBits(&cmdBuf, 3, Config->VideoModeAdaption); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdHdmiSendCecCommand(int OsdDevice, HdffCecCommand_t Command) +{ + uint8_t cmdData[8]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_HDMI, + HDFF_MSG_HDMI_SEND_CEC_COMMAND); + BitBuffer_SetBits(&cmdBuf, 8, Command); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} diff --git a/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_hdmi.h b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_hdmi.h new file mode 100644 index 0000000..16e375f --- /dev/null +++ b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_hdmi.h @@ -0,0 +1,67 @@ +/********************************************************************** + * + * HDFF firmware command interface library + * + * Copyright (C) 2011 Andreas Regel + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + *********************************************************************/ + +#ifndef HDFFCMD_HDMI_H +#define HDFFCMD_HDMI_H + + +typedef enum HdffVideoMode_t +{ + HDFF_VIDEO_MODE_576P50 = 18, + HDFF_VIDEO_MODE_720P50 = 19, + HDFF_VIDEO_MODE_1080I50 = 20, + HDFF_VIDEO_MODE_576I50 = 22 +} HdffVideoMode_t; + +typedef enum HdffVideoModeAdaption_t +{ + HDFF_VIDEO_MODE_ADAPT_OFF, + HDFF_VIDEO_MODE_ADAPT_FRAME_RATE, + HDFF_VIDEO_MODE_ADAPT_ONLY_FOR_HD, + HDFF_VIDEO_MODE_ADAPT_ALWAYS +} HdffVideoModeAdaption_t; + +typedef struct HdffHdmiConfig_t +{ + int TransmitAudio; + int ForceDviMode; + int CecEnabled; + HdffVideoModeAdaption_t VideoModeAdaption; +} HdffHdmiConfig_t; + +typedef enum HdffCecCommand_t +{ + HDFF_CEC_COMMAND_TV_ON, + HDFF_CEC_COMMAND_TV_OFF, + HDFF_CEC_COMMAND_TV_ACTIVE_SOURCE, + HDFF_CEC_COMMAND_TV_INACTIVE_SOURCE +} HdffCecCommand_t; + + +int HdffCmdHdmiSetVideoMode(int OsdDevice, HdffVideoMode_t VideoMode); + +int HdffCmdHdmiConfigure(int OsdDevice, const HdffHdmiConfig_t * Config); + +int HdffCmdHdmiSendCecCommand(int OsdDevice, HdffCecCommand_t Command); + +#endif /* HDFFCMD_HDMI_H */ diff --git a/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_mux.c b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_mux.c new file mode 100644 index 0000000..3698b56 --- /dev/null +++ b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_mux.c @@ -0,0 +1,81 @@ +/********************************************************************** + * + * HDFF firmware command interface library + * + * Copyright (C) 2011 Andreas Regel + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + *********************************************************************/ + +#include <stdint.h> +#include <string.h> +#include <sys/ioctl.h> + +#include "hdffcmd.h" +#include "hdffcmd_base.h" +#include "hdffcmd_defs.h" + + +int HdffCmdMuxSetVideoOut(int OsdDevice, HdffVideoOut_t VideoOut) +{ + uint8_t cmdData[8]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_AV_MUX, + HDFF_MSG_MUX_SET_VIDEO_OUT); + BitBuffer_SetBits(&cmdBuf, 4, VideoOut); + BitBuffer_SetBits(&cmdBuf, 4, 0); // reserved + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdMuxSetVolume(int OsdDevice, uint8_t Volume) +{ + uint8_t cmdData[8]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_AV_MUX, + HDFF_MSG_MUX_SET_VOLUME); + BitBuffer_SetBits(&cmdBuf, 8, Volume); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdMuxMuteAudio(int OsdDevice, int Mute) +{ + uint8_t cmdData[8]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_AV_MUX, + HDFF_MSG_MUX_SET_AUDIO_MUTE); + BitBuffer_SetBits(&cmdBuf, 1, Mute); + BitBuffer_SetBits(&cmdBuf, 7, 0); // reserved + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} diff --git a/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_mux.h b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_mux.h new file mode 100644 index 0000000..8821d5f --- /dev/null +++ b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_mux.h @@ -0,0 +1,56 @@ +/********************************************************************** + * + * HDFF firmware command interface library + * + * Copyright (C) 2011 Andreas Regel + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + *********************************************************************/ + +#ifndef HDFFCMD_MUX_H +#define HDFFCMD_MUX_H + + +typedef enum HdffVideoOut_t +{ + HDFF_VIDEO_OUT_DISABLED, + HDFF_VIDEO_OUT_CVBS_RGB, + HDFF_VIDEO_OUT_CVBS_YUV, + HDFF_VIDEO_OUT_YC +} HdffVideoOut_t; + +typedef enum HdffSlowBlank_t +{ + HDFF_SLOW_BLANK_OFF, + HDFF_SLOW_BLANK_16_BY_9, + HDFF_SLOW_BLANK_4_BY_3 +} HdffSlowBlank_t; + +typedef enum HdffFastBlank_t +{ + HDFF_FAST_BLANK_CVBS, + HDFF_FAST_BLANK_RGB +} HdffFastBlank_t; + + +int HdffCmdMuxSetVideoOut(int OsdDevice, HdffVideoOut_t VideoOut); + +int HdffCmdMuxSetVolume(int OsdDevice, uint8_t Volume); + +int HdffCmdMuxMuteAudio(int OsdDevice, int Mute); + +#endif /* HDFFCMD_MUX_H */ diff --git a/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_osd.c b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_osd.c new file mode 100644 index 0000000..a80051f --- /dev/null +++ b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_osd.c @@ -0,0 +1,637 @@ +/********************************************************************** + * + * HDFF firmware command interface library + * + * Copyright (C) 2011 Andreas Regel + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + *********************************************************************/ + +#include <stdint.h> +#include <string.h> +#include <sys/ioctl.h> + +#include "hdffcmd.h" +#include "hdffcmd_base.h" +#include "hdffcmd_defs.h" + + +int HdffCmdOsdConfigure(int OsdDevice, const HdffOsdConfig_t * Config) +{ + uint8_t cmdData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD, + HDFF_MSG_OSD_CONFIGURE); + if (Config->FontAntialiasing) + { + BitBuffer_SetBits(&cmdBuf, 1, 1); + } + else + { + BitBuffer_SetBits(&cmdBuf, 1, 0); + } + if (Config->FontKerning) + { + BitBuffer_SetBits(&cmdBuf, 1, 1); + } + else + { + BitBuffer_SetBits(&cmdBuf, 1, 0); + } + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdOsdReset(int OsdDevice) +{ + uint8_t cmdData[8]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD, + HDFF_MSG_OSD_RESET); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + + +int HdffCmdOsdCreateDisplay(int OsdDevice, uint16_t Width, uint16_t Height, + HdffColorType_t ColorType, uint32_t * NewDisplay) +{ + uint8_t cmdData[16]; + uint8_t resultData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + int err; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + osd_cmd.result_data = resultData; + osd_cmd.result_len = sizeof(resultData); + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD, + HDFF_MSG_OSD_CREATE_DISPLAY); + BitBuffer_SetBits(&cmdBuf, 16, Width); + BitBuffer_SetBits(&cmdBuf, 16, Height); + BitBuffer_SetBits(&cmdBuf, 8, ColorType); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + err = ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); + *NewDisplay = HDFF_INVALID_HANDLE; + if (err == 0) + { + if (osd_cmd.result_len > 0) + { + *NewDisplay = (resultData[6] << 24) + | (resultData[7] << 16) + | (resultData[8] << 8) + | resultData[9]; + } + } + return err; +} + +int HdffCmdOsdDeleteDisplay(int OsdDevice, uint32_t Display) +{ + uint8_t cmdData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD, + HDFF_MSG_OSD_DELETE_DISPLAY); + BitBuffer_SetBits(&cmdBuf, 32, Display); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdOsdEnableDisplay(int OsdDevice, uint32_t Display, int Enable) +{ + uint8_t cmdData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD, + HDFF_MSG_OSD_ENABLE_DISPLAY); + BitBuffer_SetBits(&cmdBuf, 32, Display); + if (Enable) + { + BitBuffer_SetBits(&cmdBuf, 1, 1); + } + else + { + BitBuffer_SetBits(&cmdBuf, 1, 0); + } + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdOsdSetDisplayOutputRectangle(int OsdDevice, uint32_t Display, + uint16_t X, uint16_t Y, + uint16_t Width, uint16_t Height) +{ + uint8_t cmdData[20]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD, + HDFF_MSG_OSD_SET_DISPLAY_OUTPUT_RECTANGLE); + BitBuffer_SetBits(&cmdBuf, 32, Display); + BitBuffer_SetBits(&cmdBuf, 16, X); + BitBuffer_SetBits(&cmdBuf, 16, Y); + BitBuffer_SetBits(&cmdBuf, 16, Width); + BitBuffer_SetBits(&cmdBuf, 16, Height); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdOsdSetDisplayClippingArea(int OsdDevice, uint32_t Display, + int Enable, uint16_t X, uint16_t Y, + uint16_t Width, uint16_t Height) +{ + uint8_t cmdData[20]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD, + HDFF_MSG_OSD_SET_DISPLAY_CLIPPLING_AREA); + BitBuffer_SetBits(&cmdBuf, 32, Display); + if (Enable) + { + BitBuffer_SetBits(&cmdBuf, 1, 1); + } + else + { + BitBuffer_SetBits(&cmdBuf, 1, 0); + } + BitBuffer_SetBits(&cmdBuf, 7, 0); // reserved + BitBuffer_SetBits(&cmdBuf, 16, X); + BitBuffer_SetBits(&cmdBuf, 16, Y); + BitBuffer_SetBits(&cmdBuf, 16, Width); + BitBuffer_SetBits(&cmdBuf, 16, Height); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdOsdRenderDisplay(int OsdDevice, uint32_t Display) +{ + uint8_t cmdData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD, + HDFF_MSG_OSD_RENDER_DISPLAY); + BitBuffer_SetBits(&cmdBuf, 32, Display); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdOsdSaveRegion(int OsdDevice, uint32_t Display, + uint16_t X, uint16_t Y, + uint16_t Width, uint16_t Height) +{ + uint8_t cmdData[20]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD, + HDFF_MSG_OSD_SAVE_REGION); + BitBuffer_SetBits(&cmdBuf, 32, Display); + BitBuffer_SetBits(&cmdBuf, 16, X); + BitBuffer_SetBits(&cmdBuf, 16, Y); + BitBuffer_SetBits(&cmdBuf, 16, Width); + BitBuffer_SetBits(&cmdBuf, 16, Height); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdOsdRestoreRegion(int OsdDevice, uint32_t Display) +{ + uint8_t cmdData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD, + HDFF_MSG_OSD_RESTORE_REGION); + BitBuffer_SetBits(&cmdBuf, 32, Display); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + + +int HdffCmdOsdCreatePalette(int OsdDevice, HdffColorType_t ColorType, + HdffColorFormat_t ColorFormat, + uint32_t NumColors, const uint32_t * Colors, + uint32_t * NewPalette) +{ + uint8_t cmdData[1060]; + uint8_t resultData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + int i; + int err; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + osd_cmd.result_data = resultData; + osd_cmd.result_len = sizeof(resultData); + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD, + HDFF_MSG_OSD_CREATE_PALETTE); + BitBuffer_SetBits(&cmdBuf, 8, ColorType); + BitBuffer_SetBits(&cmdBuf, 8, ColorFormat); + if (NumColors > 256) + NumColors = 256; + BitBuffer_SetBits(&cmdBuf, 8, NumColors == 256 ? 0 : NumColors); + for (i = 0; i < NumColors; i++) + { + BitBuffer_SetBits(&cmdBuf, 32, Colors[i]); + } + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + err = ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); + *NewPalette = HDFF_INVALID_HANDLE; + if (err == 0) + { + if (osd_cmd.result_len > 0) + { + *NewPalette = (resultData[6] << 24) + | (resultData[7] << 16) + | (resultData[8] << 8) + | resultData[9]; + } + } + return err; +} + +int HdffCmdOsdDeletePalette(int OsdDevice, uint32_t Palette) +{ + uint8_t cmdData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD, + HDFF_MSG_OSD_DELETE_PALETTE); + BitBuffer_SetBits(&cmdBuf, 32, Palette); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdOsdSetDisplayPalette(int OsdDevice, uint32_t Display, + uint32_t Palette) +{ + uint8_t cmdData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD, + HDFF_MSG_OSD_SET_DISPLAY_PALETTE); + BitBuffer_SetBits(&cmdBuf, 32, Display); + BitBuffer_SetBits(&cmdBuf, 32, Palette); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdOsdSetPaletteColors(int OsdDevice, uint32_t Palette, + HdffColorFormat_t ColorFormat, + uint8_t StartColor, uint32_t NumColors, + const uint32_t * Colors) +{ + uint8_t cmdData[1060]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + int i; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD, + HDFF_MSG_OSD_SET_PALETTE_COLORS); + BitBuffer_SetBits(&cmdBuf, 32, Palette); + BitBuffer_SetBits(&cmdBuf, 8, ColorFormat); + BitBuffer_SetBits(&cmdBuf, 8, StartColor); + if (NumColors > 256) + NumColors = 256; + BitBuffer_SetBits(&cmdBuf, 8, NumColors == 256 ? 0 : NumColors); + for (i = 0; i < NumColors; i++) + { + BitBuffer_SetBits(&cmdBuf, 32, Colors[i]); + } + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdOsdCreateFontFace(int OsdDevice, const uint8_t * FontData, + uint32_t DataSize, uint32_t * NewFontFace) +{ + uint8_t cmdData[16]; + uint8_t resultData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + osd_raw_data_t osd_data; + int err; + + *NewFontFace = HDFF_INVALID_HANDLE; + + memset(&osd_data, 0, sizeof(osd_raw_data_t)); + osd_data.data_buffer = FontData; + osd_data.data_length = DataSize; + err = ioctl(OsdDevice, OSD_RAW_DATA, &osd_data); + if (err != 0) + return err; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + osd_cmd.result_data = resultData; + osd_cmd.result_len = sizeof(resultData); + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD, + HDFF_MSG_OSD_CREATE_FONT_FACE); + BitBuffer_SetBits(&cmdBuf, 16, osd_data.data_handle); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + err = ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); + if (err == 0) + { + if (osd_cmd.result_len > 0) + { + *NewFontFace = (resultData[6] << 24) + | (resultData[7] << 16) + | (resultData[8] << 8) + | resultData[9]; + } + } + return err; +} + +int HdffCmdOsdDeleteFontFace(int OsdDevice, uint32_t FontFace) +{ + uint8_t cmdData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD, + HDFF_MSG_OSD_DELETE_FONT_FACE); + BitBuffer_SetBits(&cmdBuf, 32, FontFace); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdOsdCreateFont(int OsdDevice, uint32_t FontFace, uint32_t Size, + uint32_t * NewFont) +{ + uint8_t cmdData[16]; + uint8_t resultData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + int err; + + *NewFont = HDFF_INVALID_HANDLE; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + osd_cmd.result_data = resultData; + osd_cmd.result_len = sizeof(resultData); + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD, + HDFF_MSG_OSD_CREATE_FONT); + BitBuffer_SetBits(&cmdBuf, 32, FontFace); + BitBuffer_SetBits(&cmdBuf, 32, Size); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + err = ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); + if (err == 0) + { + if (osd_cmd.result_len > 0) + { + *NewFont = (resultData[6] << 24) + | (resultData[7] << 16) + | (resultData[8] << 8) + | resultData[9]; + } + } + return err; +} + +int HdffCmdOsdDeleteFont(int OsdDevice, uint32_t Font) +{ + uint8_t cmdData[16]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD, + HDFF_MSG_OSD_DELETE_FONT); + BitBuffer_SetBits(&cmdBuf, 32, Font); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + + +int HdffCmdOsdDrawRectangle(int OsdDevice, uint32_t Display, uint16_t X, + uint16_t Y, uint16_t Width, uint16_t Height, + uint32_t Color) +{ + uint8_t cmdData[24]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD, + HDFF_MSG_OSD_DRAW_RECTANGLE); + BitBuffer_SetBits(&cmdBuf, 32, Display); + BitBuffer_SetBits(&cmdBuf, 16, X); + BitBuffer_SetBits(&cmdBuf, 16, Y); + BitBuffer_SetBits(&cmdBuf, 16, Width); + BitBuffer_SetBits(&cmdBuf, 16, Height); + BitBuffer_SetBits(&cmdBuf, 32, Color); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdOsdDrawEllipse(int OsdDevice, uint32_t Display, uint16_t CX, + uint16_t CY, uint16_t RadiusX, uint16_t RadiusY, + uint32_t Color, uint32_t Flags) +{ + uint8_t cmdData[28]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD, + HDFF_MSG_OSD_DRAW_ELLIPSE); + BitBuffer_SetBits(&cmdBuf, 32, Display); + BitBuffer_SetBits(&cmdBuf, 16, CX); + BitBuffer_SetBits(&cmdBuf, 16, CY); + BitBuffer_SetBits(&cmdBuf, 16, RadiusX); + BitBuffer_SetBits(&cmdBuf, 16, RadiusY); + BitBuffer_SetBits(&cmdBuf, 32, Color); + BitBuffer_SetBits(&cmdBuf, 32, Flags); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdOsdDrawText(int OsdDevice, uint32_t Display, uint32_t Font, + uint16_t X, uint16_t Y, const char * Text, + uint32_t Color) +{ + uint8_t cmdData[1060]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + int i; + int length; + + length = 0; + while (Text[length]) + { + length++; + } + if (length > 980) + length = 980; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD, + HDFF_MSG_OSD_DRAW_TEXT); + BitBuffer_SetBits(&cmdBuf, 32, Display); + BitBuffer_SetBits(&cmdBuf, 32, Font); + BitBuffer_SetBits(&cmdBuf, 16, X); + BitBuffer_SetBits(&cmdBuf, 16, Y); + BitBuffer_SetBits(&cmdBuf, 32, Color); + BitBuffer_SetBits(&cmdBuf, 16, length); + for (i = 0; i < length; i++) + { + BitBuffer_SetBits(&cmdBuf, 8, Text[i]); + } + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdOsdDrawWideText(int OsdDevice, uint32_t Display, uint32_t Font, + uint16_t X, uint16_t Y, const uint16_t * Text, + uint32_t Color) +{ + uint8_t cmdData[1060]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + int i; + int length; + + length = 0; + while (Text[length]) + { + length++; + } + if (length > 480) + length = 480; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD, + HDFF_MSG_OSD_DRAW_WIDE_TEXT); + BitBuffer_SetBits(&cmdBuf, 32, Display); + BitBuffer_SetBits(&cmdBuf, 32, Font); + BitBuffer_SetBits(&cmdBuf, 16, X); + BitBuffer_SetBits(&cmdBuf, 16, Y); + BitBuffer_SetBits(&cmdBuf, 32, Color); + BitBuffer_SetBits(&cmdBuf, 16, length); + for (i = 0; i < length; i++) + { + BitBuffer_SetBits(&cmdBuf, 16, Text[i]); + } + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdOsdDrawBitmap(int OsdDevice, uint32_t Display, uint16_t X, + uint16_t Y, const uint8_t * Bitmap, uint16_t BmpWidth, + uint16_t BmpHeight, uint32_t BmpSize, + HdffColorType_t ColorType, uint32_t Palette) +{ + uint8_t cmdData[32]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + osd_raw_data_t osd_data; + int err; + + memset(&osd_data, 0, sizeof(osd_raw_data_t)); + osd_data.data_buffer = Bitmap; + osd_data.data_length = BmpSize; + err = ioctl(OsdDevice, OSD_RAW_DATA, &osd_data); + if (err != 0) + return err; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, HDFF_MSG_GROUP_OSD, + HDFF_MSG_OSD_DRAW_BITMAP); + BitBuffer_SetBits(&cmdBuf, 32, Display); + BitBuffer_SetBits(&cmdBuf, 16, X); + BitBuffer_SetBits(&cmdBuf, 16, Y); + BitBuffer_SetBits(&cmdBuf, 16, BmpWidth); + BitBuffer_SetBits(&cmdBuf, 16, BmpHeight); + BitBuffer_SetBits(&cmdBuf, 8, ColorType); + BitBuffer_SetBits(&cmdBuf, 6, 0); // reserved + BitBuffer_SetBits(&cmdBuf, 2, 0); // uncompressed + BitBuffer_SetBits(&cmdBuf, 32, Palette); + BitBuffer_SetBits(&cmdBuf, 16, osd_data.data_handle); + BitBuffer_SetBits(&cmdBuf, 32, 0); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} diff --git a/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_osd.h b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_osd.h new file mode 100644 index 0000000..5c13559 --- /dev/null +++ b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_osd.h @@ -0,0 +1,161 @@ +/********************************************************************** + * + * HDFF firmware command interface library + * + * Copyright (C) 2011 Andreas Regel + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + *********************************************************************/ + +#ifndef HDFFCMD_OSD_H +#define HDFFCMD_OSD_H + + +#define HDFF_INVALID_HANDLE 0xFFFFFFFF +#define HDFF_SCREEN_DISPLAY_HANDLE 0xFFFFFFFE + +#define HDFF_POSITION_SCREEN_CENTERED 0xFFFF + +#define HDFF_SIZE_FULL_SCREEN 0xFFFF +#define HDFF_SIZE_SAME_AS_SOURCE 0xFFFE + +#define HDFF_FONT_FACE_TIRESIAS 0x00000000 + + +typedef struct HdffOsdConfig_t +{ + int FontAntialiasing; + int FontKerning; +} HdffOsdConfig_t; + +typedef enum HdffColorType_t +{ + HDFF_COLOR_TYPE_CLUT1, + HDFF_COLOR_TYPE_CLUT2, + HDFF_COLOR_TYPE_CLUT4, + HDFF_COLOR_TYPE_CLUT8, + HDFF_COLOR_TYPE_ARGB8888, + HDFF_COLOR_TYPE_ARGB8565, + HDFF_COLOR_TYPE_ARGB4444, + HDFF_COLOR_TYPE_ARGB1555, + HDFF_COLOR_TYPE_RGB888, + HDFF_COLOR_TYPE_RGB565 +} HdffColorType_t; + +typedef enum HdffColorFormat_t +{ + HDFF_COLOR_FORMAT_ARGB, + HDFF_COLOR_FORMAT_ACBYCR +} HdffColorFormat_t; + +typedef enum HdffDrawingFlags_t +{ + HDFF_DRAW_FULL, + HDFF_DRAW_HALF_TOP, + HDFF_DRAW_HALF_LEFT, + HDFF_DRAW_HALF_BOTTOM, + HDFF_DRAW_HALF_RIGHT, + HDFF_DRAW_QUARTER_TOP_LEFT, + HDFF_DRAW_QUARTER_TOP_RIGHT, + HDFF_DRAW_QUARTER_BOTTOM_LEFT, + HDFF_DRAW_QUARTER_BOTTOM_RIGHT, + HDFF_DRAW_QUARTER_TOP_LEFT_INVERTED, + HDFF_DRAW_QUARTER_TOP_RIGHT_INVERTED, + HDFF_DRAW_QUARTER_BOTTOM_LEFT_INVERTED, + HDFF_DRAW_QUARTER_BOTTOM_RIGHT_INVERTED +} HdffDrawingFlags_t; + + +int HdffCmdOsdConfigure(int OsdDevice, const HdffOsdConfig_t * Config); + +int HdffCmdOsdReset(int OsdDevice); + + +int HdffCmdOsdCreateDisplay(int OsdDevice, uint16_t Width, uint16_t Height, + HdffColorType_t ColorType, uint32_t * NewDisplay); + +int HdffCmdOsdDeleteDisplay(int OsdDevice, uint32_t Display); + +int HdffCmdOsdEnableDisplay(int OsdDevice, uint32_t Display, int Enable); + +int HdffCmdOsdSetDisplayOutputRectangle(int OsdDevice, uint32_t Display, + uint16_t X, uint16_t Y, + uint16_t Width, uint16_t Height); + +int HdffCmdOsdSetDisplayClippingArea(int OsdDevice, uint32_t Display, + int Enable, uint16_t X, uint16_t Y, + uint16_t Width, uint16_t Height); + +int HdffCmdOsdRenderDisplay(int OsdDevice, uint32_t Display); + +int HdffCmdOsdSaveRegion(int OsdDevice, uint32_t Display, + uint16_t X, uint16_t Y, + uint16_t Width, uint16_t Height); + +int HdffCmdOsdRestoreRegion(int OsdDevice, uint32_t Display); + + +int HdffCmdOsdCreatePalette(int OsdDevice, HdffColorType_t ColorType, + HdffColorFormat_t ColorFormat, + uint32_t NumColors, const uint32_t * Colors, + uint32_t * NewPalette); + +int HdffCmdOsdDeletePalette(int OsdDevice, uint32_t Palette); + +int HdffCmdOsdSetDisplayPalette(int OsdDevice, uint32_t Display, + uint32_t Palette); + +int HdffCmdOsdSetPaletteColors(int OsdDevice, uint32_t Palette, + HdffColorFormat_t ColorFormat, + uint8_t StartColor, uint32_t NumColors, + const uint32_t * Colors); + + +int HdffCmdOsdCreateFontFace(int OsdDevice, const uint8_t * FontData, + uint32_t DataSize, uint32_t * NewFontFace); + +int HdffCmdOsdDeleteFontFace(int OsdDevice, uint32_t FontFace); + +int HdffCmdOsdCreateFont(int OsdDevice, uint32_t FontFace, uint32_t Size, + uint32_t * NewFont); + +int HdffCmdOsdDeleteFont(int OsdDevice, uint32_t Font); + + +int HdffCmdOsdDrawRectangle(int OsdDevice, uint32_t Display, uint16_t X, + uint16_t Y, uint16_t Width, uint16_t Height, + uint32_t Color); + +int HdffCmdOsdDrawEllipse(int OsdDevice, uint32_t Display, uint16_t CX, + uint16_t CY, uint16_t RadiusX, uint16_t RadiusY, + uint32_t Color, uint32_t Flags); + +int HdffCmdOsdDrawText(int OsdDevice, uint32_t Display, uint32_t Font, + uint16_t X, uint16_t Y, const char * Text, + uint32_t Color); + +int HdffCmdOsdDrawWideText(int OsdDevice, uint32_t Display, uint32_t Font, + uint16_t X, uint16_t Y, const uint16_t * Text, + uint32_t Color); + +int HdffCmdOsdDrawBitmap(int OsdDevice, uint32_t Display, uint16_t X, + uint16_t Y, const uint8_t * Bitmap, uint16_t BmpWidth, + uint16_t BmpHeight, uint32_t BmpSize, + HdffColorType_t ColorType, uint32_t Palette); + + +#endif /* HDFFCMD_OSD_H */ diff --git a/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_remote.c b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_remote.c new file mode 100644 index 0000000..d9bbe45 --- /dev/null +++ b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_remote.c @@ -0,0 +1,67 @@ +/********************************************************************** + * + * HDFF firmware command interface library + * + * Copyright (C) 2011 Andreas Regel + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + *********************************************************************/ + +#include <stdint.h> +#include <string.h> +#include <sys/ioctl.h> + +#include "hdffcmd.h" +#include "hdffcmd_base.h" +#include "hdffcmd_defs.h" + + +int HdffCmdRemoteSetProtocol(int OsdDevice, HdffRemoteProtocol_t Protocol) +{ + uint8_t cmdData[8]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, + HDFF_MSG_GROUP_REMOTE_CONTROL, + HDFF_MSG_REMOTE_SET_PROTOCOL); + BitBuffer_SetBits(&cmdBuf, 8, Protocol); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} + +int HdffCmdRemoteSetAddressFilter(int OsdDevice, int Enable, uint32_t Address) +{ + uint8_t cmdData[12]; + BitBuffer_t cmdBuf; + osd_raw_cmd_t osd_cmd; + + BitBuffer_Init(&cmdBuf, cmdData, sizeof(cmdData)); + memset(&osd_cmd, 0, sizeof(osd_raw_cmd_t)); + osd_cmd.cmd_data = cmdData; + HdffCmdBuildHeader(&cmdBuf, HDFF_MSG_TYPE_COMMAND, + HDFF_MSG_GROUP_REMOTE_CONTROL, + HDFF_MSG_REMOTE_SET_ADDRESS_FILTER); + BitBuffer_SetBits(&cmdBuf, 1, Enable); + BitBuffer_SetBits(&cmdBuf, 7, 0); // reserved + BitBuffer_SetBits(&cmdBuf, 32, Address); + osd_cmd.cmd_len = HdffCmdSetLength(&cmdBuf); + return ioctl(OsdDevice, OSD_RAW_CMD, &osd_cmd); +} diff --git a/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_remote.h b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_remote.h new file mode 100644 index 0000000..f2e6b8a --- /dev/null +++ b/PLUGINS/src/dvbhddevice/libhdffcmd/hdffcmd_remote.h @@ -0,0 +1,39 @@ +/********************************************************************** + * + * HDFF firmware command interface library + * + * Copyright (C) 2011 Andreas Regel + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + *********************************************************************/ + +#ifndef HDFFCMD_REMOTE_H +#define HDFFCMD_REMOTE_H + +typedef enum HdffRemoteProtocol_t +{ + HDFF_REMOTE_PROTOCOL_NONE, + HDFF_REMOTE_PROTOCOL_RC5, + HDFF_REMOTE_PROTOCOL_RC6 +} HdffRemoteProtocol_t; + + +int HdffCmdRemoteSetProtocol(int OsdDevice, HdffRemoteProtocol_t Protocol); + +int HdffCmdRemoteSetAddressFilter(int OsdDevice, int Enable, uint32_t Address); + +#endif /* HDFFCMD_REMOTE_H */ diff --git a/PLUGINS/src/dvbhddevice/po/fi_FI.po b/PLUGINS/src/dvbhddevice/po/fi_FI.po index db8ef0b..48abaf5 100644 --- a/PLUGINS/src/dvbhddevice/po/fi_FI.po +++ b/PLUGINS/src/dvbhddevice/po/fi_FI.po @@ -20,13 +20,13 @@ msgid "HD Full Featured DVB device" msgstr "DVB-laite HD-ulostulolla" msgid "Off" -msgstr "" +msgstr "ei" msgid "Frame rate" -msgstr "" +msgstr "kuvataajuuden mukaan" msgid "HD Only" -msgstr "" +msgstr "vain HD-resoluutiolla" msgid "Always" msgstr "aina" @@ -68,7 +68,7 @@ msgid "Resolution" msgstr "Kuvaresoluutio" msgid "Video Mode Adaption" -msgstr "" +msgstr "Sovita näyttömoodi" msgid "TV format" msgstr "Näytön kuvasuhde" diff --git a/PLUGINS/src/dvbhddevice/setup.c b/PLUGINS/src/dvbhddevice/setup.c index 6e41860..cb476a8 100644 --- a/PLUGINS/src/dvbhddevice/setup.c +++ b/PLUGINS/src/dvbhddevice/setup.c @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: setup.c 1.13 2011/08/27 09:35:35 kls Exp $ + * $Id: setup.c 1.14 2011/12/04 15:31:58 kls Exp $ */ #include "setup.h" @@ -20,12 +20,12 @@ cHdffSetup gHdffSetup; cHdffSetup::cHdffSetup(void) { Resolution = kResolution1080i; - VideoModeAdaption = HDFF::videoModeAdaptOff; - TvFormat = HDFF::tvFormat16by9; - VideoConversion = HDFF::videoConversionPillarbox; - AnalogueVideo = HDFF::videoOutCvbsYuv; + VideoModeAdaption = HDFF_VIDEO_MODE_ADAPT_OFF; + TvFormat = HDFF_TV_FORMAT_16_BY_9; + VideoConversion = HDFF_VIDEO_CONVERSION_PILLARBOX; + AnalogueVideo = HDFF_VIDEO_OUT_CVBS_YUV; AudioDelay = 0; - AudioDownmix = HDFF::downmixAutomatic; + AudioDownmix = HDFF_AUDIO_DOWNMIX_AUTOMATIC; OsdSize = 0; CecEnabled = 1; RemoteProtocol = 1; @@ -68,7 +68,7 @@ void cHdffSetup::GetOsdSize(int &Width, int &Height, double &PixelAspect) Width = 720; Height = 576; } - if (TvFormat == HDFF::tvFormat16by9) + if (TvFormat == HDFF_TV_FORMAT_16_BY_9) PixelAspect = 16.0 / 9.0; else PixelAspect = 4.0 / 3.0; @@ -96,19 +96,19 @@ void cHdffSetup::GetOsdSize(int &Width, int &Height, double &PixelAspect) PixelAspect /= double(Width) / Height; } -HDFF::eHdmiVideoMode cHdffSetup::GetVideoMode(void) +HdffVideoMode_t cHdffSetup::GetVideoMode(void) { switch (Resolution) { case kResolution1080i: default: - return HDFF::videoMode1080i50; + return HDFF_VIDEO_MODE_1080I50; case kResolution720p: - return HDFF::videoMode720p50; + return HDFF_VIDEO_MODE_720P50; case kResolution576p: - return HDFF::videoMode576p50; + return HDFF_VIDEO_MODE_576P50; case kResolution576i: - return HDFF::videoMode576i50; + return HDFF_VIDEO_MODE_576I50; } } @@ -233,27 +233,27 @@ void cHdffSetupPage::Store(void) { mHdffCmdIf->CmdHdmiSetVideoMode(mNewHdffSetup.GetVideoMode()); } - HDFF::tVideoFormat videoFormat; - HDFF::tHdmiConfig hdmiConfig; + HdffVideoFormat_t videoFormat; + HdffHdmiConfig_t hdmiConfig; videoFormat.AutomaticEnabled = true; videoFormat.AfdEnabled = true; - videoFormat.TvFormat = (HDFF::eTvFormat) mNewHdffSetup.TvFormat; - videoFormat.VideoConversion = (HDFF::eVideoConversion) mNewHdffSetup.VideoConversion; + videoFormat.TvFormat = (HdffTvFormat_t) mNewHdffSetup.TvFormat; + videoFormat.VideoConversion = (HdffVideoConversion_t) mNewHdffSetup.VideoConversion; mHdffCmdIf->CmdAvSetVideoFormat(0, &videoFormat); mHdffCmdIf->CmdAvSetAudioDelay(mNewHdffSetup.AudioDelay); - mHdffCmdIf->CmdAvSetAudioDownmix((HDFF::eDownmixMode) mNewHdffSetup.AudioDownmix); + mHdffCmdIf->CmdAvSetAudioDownmix((HdffAudioDownmixMode_t) mNewHdffSetup.AudioDownmix); - mHdffCmdIf->CmdMuxSetVideoOut((HDFF::eVideoOut) mNewHdffSetup.AnalogueVideo); + mHdffCmdIf->CmdMuxSetVideoOut((HdffVideoOut_t) mNewHdffSetup.AnalogueVideo); hdmiConfig.TransmitAudio = true; hdmiConfig.ForceDviMode = false; hdmiConfig.CecEnabled = mNewHdffSetup.CecEnabled; - hdmiConfig.VideoModeAdaption = (HDFF::eVideoModeAdaption) mNewHdffSetup.VideoModeAdaption; + hdmiConfig.VideoModeAdaption = (HdffVideoModeAdaption_t) mNewHdffSetup.VideoModeAdaption; mHdffCmdIf->CmdHdmiConfigure(&hdmiConfig); - mHdffCmdIf->CmdRemoteSetProtocol((HDFF::eRemoteProtocol) mNewHdffSetup.RemoteProtocol); + mHdffCmdIf->CmdRemoteSetProtocol((HdffRemoteProtocol_t) mNewHdffSetup.RemoteProtocol); mHdffCmdIf->CmdRemoteSetAddressFilter(mNewHdffSetup.RemoteAddress >= 0, mNewHdffSetup.RemoteAddress); } diff --git a/PLUGINS/src/dvbhddevice/setup.h b/PLUGINS/src/dvbhddevice/setup.h index c3fe7a6..964105e 100644 --- a/PLUGINS/src/dvbhddevice/setup.h +++ b/PLUGINS/src/dvbhddevice/setup.h @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: setup.h 1.9 2011/08/27 09:36:02 kls Exp $ + * $Id: setup.h 1.10 2011/12/04 15:32:13 kls Exp $ */ #ifndef _HDFF_SETUP_H_ @@ -17,7 +17,7 @@ struct cHdffSetup cHdffSetup(void); bool SetupParse(const char * Name, const char * Value); void GetOsdSize(int &Width, int &Height, double &PixelAspect); - HDFF::eHdmiVideoMode GetVideoMode(void); + HdffVideoMode_t GetVideoMode(void); int Resolution; int VideoModeAdaption; diff --git a/PLUGINS/src/pictures/HISTORY b/PLUGINS/src/pictures/HISTORY index 964ab2e..b63a81b 100644 --- a/PLUGINS/src/pictures/HISTORY +++ b/PLUGINS/src/pictures/HISTORY @@ -55,3 +55,7 @@ VDR Plugin 'pictures' Revision History - The pic2mpg script now generates HD images (thanks to Andre Weidemann for his support in using convert/ffmpeg). The old SD version is still available as pic2mpg-sd. + +2011-11-02: + +- Fixed handling images that are rotated by 180 degrees in pic2mpg. diff --git a/PLUGINS/src/pictures/pic2mpg b/PLUGINS/src/pictures/pic2mpg index 190ec26..17a8791 100755 --- a/PLUGINS/src/pictures/pic2mpg +++ b/PLUGINS/src/pictures/pic2mpg @@ -7,7 +7,7 @@ # # See the README file for copyright information and how to reach the author. # -# $Id: pic2mpg 2.2 2011/08/14 13:34:15 kls Exp $ +# $Id: pic2mpg 2.3 2011/11/02 17:20:37 kls Exp $ use File::Path; use File::Spec; @@ -124,7 +124,7 @@ sub ConvertFile return if (!defined $PICTYPES{$Type}); my $Exif = ImageInfo($Pict); my $Orientation = $$Exif{"Orientation"}; - my ($Degrees) = $Orientation =~ /Rotate ([0-9]+) /; + my ($Degrees) = $Orientation =~ /Rotate ([0-9]+)/; my $Rotate = $Degrees ? "-rotate $Degrees" : ""; print "orientation = '$Orientation' -> rotation = $Rotate\n" if ($Detailed); $Pict = EscapeMeta($Pict); @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: ci.h 2.0 2007/01/03 12:49:10 kls Exp $ + * $Id: ci.h 2.1 2011/12/04 13:38:17 kls Exp $ */ #ifndef __CI_H @@ -220,7 +220,7 @@ public: ///< CAM is currently not decrypting anything. If there is already a ///< channel being decrypted, a call to CanDecrypt() checks whether the ///< CAM can also decrypt the given channel. Only CAMs that have replied - ///< to the inital QUERY will perform this check at all. CAMs that never + ///< to the initial QUERY will perform this check at all. CAMs that never ///< replied to the initial QUERY are assumed not to be able to handle ///< more than one channel at a time. void StartDecrypting(void); @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.c 2.15 2011/08/20 09:12:05 kls Exp $ + * $Id: config.c 2.16 2011/12/03 15:21:30 kls Exp $ */ #include "config.h" @@ -63,6 +63,69 @@ bool cSVDRPhost::Accepts(in_addr_t Address) return (Address & mask) == (addr.s_addr & mask); } +// --- cSatCableNumbers ------------------------------------------------------ + +cSatCableNumbers::cSatCableNumbers(int Size, const char *s) +{ + size = Size; + array = MALLOC(int, size); + memset(array, size * sizeof(int), 0); + FromString(s); +} + +cSatCableNumbers::~cSatCableNumbers() +{ + free(array); +} + +bool cSatCableNumbers::FromString(const char *s) +{ + char *t; + int i = 0; + const char *p = s; + while (p && *p) { + int n = strtol(p, &t, 10); + if (t != p) { + if (i < size) + array[i++] = n; + else { + esyslog("ERROR: too many sat cable numbers in '%s'", s); + return false; + } + } + else { + esyslog("ERROR: invalid sat cable number in '%s'", s); + return false; + } + p = skipspace(t); + } + for ( ; i < size; i++) + array[i] = 0; + return true; +} + +cString cSatCableNumbers::ToString(void) +{ + cString s(""); + for (int i = 0; i < size; i++) { + s = cString::sprintf("%s%d ", *s, array[i]); + } + return s; +} + +int cSatCableNumbers::FirstDeviceIndex(int DeviceIndex) const +{ + if (0 <= DeviceIndex && DeviceIndex < size) { + if (int CableNr = array[DeviceIndex]) { + for (int i = 0; i < size; i++) { + if (i < DeviceIndex && array[i] == CableNr) + return i; + } + } + } + return -1; +} + // --- cNestedItem ----------------------------------------------------------- cNestedItem::cNestedItem(const char *Text, bool WithSubItems) @@ -396,6 +459,7 @@ cSetup::cSetup(void) CurrentVolume = MAXVOLUME; CurrentDolby = 0; InitialChannel = ""; + DeviceBondings = ""; InitialVolume = -1; ChannelsWrap = 0; EmergencyExit = 1; @@ -405,6 +469,7 @@ cSetup& cSetup::operator= (const cSetup &s) { memcpy(&__BeginData__, &s.__BeginData__, (char *)&s.__EndData__ - (char *)&s.__BeginData__); InitialChannel = s.InitialChannel; + DeviceBondings = s.DeviceBondings; return *this; } @@ -589,6 +654,7 @@ bool cSetup::Parse(const char *Name, const char *Value) else if (!strcasecmp(Name, "CurrentDolby")) CurrentDolby = atoi(Value); else if (!strcasecmp(Name, "InitialChannel")) InitialChannel = Value; else if (!strcasecmp(Name, "InitialVolume")) InitialVolume = atoi(Value); + else if (!strcasecmp(Name, "DeviceBondings")) DeviceBondings = Value; else if (!strcasecmp(Name, "ChannelsWrap")) ChannelsWrap = atoi(Value); else if (!strcasecmp(Name, "EmergencyExit")) EmergencyExit = atoi(Value); else @@ -685,6 +751,7 @@ bool cSetup::Save(void) Store("CurrentDolby", CurrentDolby); Store("InitialChannel", InitialChannel); Store("InitialVolume", InitialVolume); + Store("DeviceBondings", DeviceBondings); Store("ChannelsWrap", ChannelsWrap); Store("EmergencyExit", EmergencyExit); @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.h 2.34 2011/08/20 08:51:47 kls Exp $ + * $Id: config.h 2.36 2011/12/03 14:19:52 kls Exp $ */ #ifndef __CONFIG_H @@ -22,13 +22,13 @@ // VDR's own version number: -#define VDRVERSION "1.7.21" -#define VDRVERSNUM 10721 // Version * 10000 + Major * 100 + Minor +#define VDRVERSION "1.7.22" +#define VDRVERSNUM 10722 // Version * 10000 + Major * 100 + Minor // The plugin API's version number: -#define APIVERSION "1.7.21" -#define APIVERSNUM 10721 // Version * 10000 + Major * 100 + Minor +#define APIVERSION "1.7.22" +#define APIVERSNUM 10722 // Version * 10000 + Major * 100 + Minor // When loading plugins, VDR searches them by their APIVERSION, which // may be smaller than VDRVERSION in case there have been no changes to @@ -61,6 +61,25 @@ public: bool Accepts(in_addr_t Address); }; +class cSatCableNumbers { +private: + int size; + int *array; +public: + cSatCableNumbers(int Size, const char *s = NULL); + ~cSatCableNumbers(); + int Size(void) const { return size; } + int *Array(void) { return array; } + bool FromString(const char *s); + cString ToString(void); + int FirstDeviceIndex(int DeviceIndex) const; + ///< Returns the first device index (starting at 0) that uses the same + ///< sat cable number as the device with the given DeviceIndex. + ///< If the given device does not use the same sat cable as any other device, + ///< or if the resulting value would be the same as DeviceIndex, + ///< or if DeviceIndex is out of range, -1 is returned. + }; + template<class T> class cConfig : public cList<T> { private: char *fileName; @@ -292,6 +311,7 @@ public: int EmergencyExit; int __EndData__; cString InitialChannel; + cString DeviceBondings; cSetup(void); cSetup& operator= (const cSetup &s); bool Load(const char *FileName); @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: cutter.c 2.8 2011/08/21 11:08:08 kls Exp $ + * $Id: cutter.c 2.10 2011/12/04 12:55:53 kls Exp $ */ #include "cutter.h" @@ -100,7 +100,8 @@ void cCuttingThread::Action(void) if (fromIndex->Get(Index++, &FileNumber, &FileOffset, &Independent, &Length)) { if (FileNumber != CurrentFileNumber) { fromFile = fromFileName->SetOffset(FileNumber, FileOffset); - fromFile->SetReadAhead(MEGABYTE(20)); + if (fromFile) + fromFile->SetReadAhead(MEGABYTE(20)); CurrentFileNumber = FileNumber; } if (fromFile) { @@ -210,7 +211,7 @@ bool cCutter::Start(const char *FileName) cRecording Recording(FileName); cMarks FromMarks; - FromMarks.Load(FileName); + FromMarks.Load(FileName, Recording.FramesPerSecond(), Recording.IsPesRecording()); if (cMark *First = FromMarks.First()) Recording.SetStartTime(Recording.Start() + (int(First->Position() / Recording.FramesPerSecond() + 30) / 60) * 60); @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: device.c 2.42 2011/08/26 12:56:00 kls Exp $ + * $Id: device.c 2.44 2011/10/16 14:36:43 kls Exp $ */ #include "device.h" @@ -95,6 +95,8 @@ cDevice::cDevice(void) camSlot = NULL; startScrambleDetection = 0; + occupiedTimeout = 0; + player = NULL; isPlayingVideo = false; ClrAvailableTracks(); @@ -638,14 +640,14 @@ const cChannel *cDevice::GetCurrentlyTunedTransponder(void) const return NULL; } -bool cDevice::IsTunedToTransponder(const cChannel *Channel) +bool cDevice::IsTunedToTransponder(const cChannel *Channel) const { return false; } -bool cDevice::MaySwitchTransponder(void) +bool cDevice::MaySwitchTransponder(const cChannel *Channel) const { - return !Receiving(true) && !(pidHandles[ptAudio].pid || pidHandles[ptVideo].pid || pidHandles[ptDolby].pid); + return time(NULL) > occupiedTimeout && !Receiving(true) && !(pidHandles[ptAudio].pid || pidHandles[ptVideo].pid || pidHandles[ptDolby].pid); } bool cDevice::SwitchChannel(const cChannel *Channel, bool LiveView) @@ -786,6 +788,18 @@ void cDevice::ForceTransferMode(void) } } +int cDevice::Occupied(void) const +{ + int Seconds = occupiedTimeout - time(NULL); + return Seconds > 0 ? Seconds : 0; +} + +void cDevice::SetOccupied(int Seconds) +{ + if (Seconds >= 0) + occupiedTimeout = time(NULL) + min(Seconds, MAXOCCUPIEDTIMEOUT); +} + bool cDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) { return false; @@ -1474,6 +1488,7 @@ int cDevice::PlayTs(const uchar *Data, int Length, bool VideoOnly) int cDevice::Priority(void) const { int priority = IsPrimaryDevice() ? Setup.PrimaryLimit - 1 : DEFAULTPRIORITY; + cMutexLock MutexLock(&mutexReceiver); for (int i = 0; i < MAXRECEIVERS; i++) { if (receiver[i]) priority = max(receiver[i]->priority, priority); @@ -1488,6 +1503,7 @@ bool cDevice::Ready(void) bool cDevice::Receiving(bool CheckAny) const { + cMutexLock MutexLock(&mutexReceiver); for (int i = 0; i < MAXRECEIVERS; i++) { if (receiver[i] && (CheckAny || receiver[i]->priority >= 0)) // cReceiver with priority < 0 doesn't count return true; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: device.h 2.27 2011/08/26 12:52:29 kls Exp $ + * $Id: device.h 2.30 2011/12/04 13:38:17 kls Exp $ */ #ifndef __DEVICE_H @@ -30,6 +30,7 @@ #define MAXRECEIVERS 16 // the maximum number of receivers per device #define MAXVOLUME 255 #define VOLUMEDELTA 5 // used to increase/decrease the volume +#define MAXOCCUPIEDTIMEOUT 99 // max. time (in seconds) a device may be occupied enum eSetChannelResult { scrOk, scrNotAvailable, scrNoTransfer, scrFailed }; @@ -220,6 +221,8 @@ public: // Channel facilities +private: + time_t occupiedTimeout; protected: static int currentChannel; public: @@ -272,12 +275,14 @@ public: ///< This is not one of the channels in the global cChannels list, but rather ///< a local copy. The result may be NULL if the device is not tuned to any ///< transponder. - virtual bool IsTunedToTransponder(const cChannel *Channel); + virtual bool IsTunedToTransponder(const cChannel *Channel) const; ///< Returns true if this device is currently tuned to the given Channel's ///< transponder. - virtual bool MaySwitchTransponder(void); - ///< Returns true if it is ok to switch the transponder on this device, - ///< without disturbing any other activities. + virtual bool MaySwitchTransponder(const cChannel *Channel) const; + ///< Returns true if it is ok to switch to the Channel's transponder on this + ///< device, without disturbing any other activities. If an occupied timeout + ///< has been set for this device, and that timeout has not yet expired, + ///< this function returns false, bool SwitchChannel(const cChannel *Channel, bool LiveView); ///< Switches the device to the given Channel, initiating transfer mode ///< if necessary. @@ -300,6 +305,16 @@ public: ///< channel number while replaying. void ForceTransferMode(void); ///< Forces the device into transfermode for the current channel. + int Occupied(void) const; + ///< Returns the number of seconds this device is still occupied for. + void SetOccupied(int Seconds); + ///< Sets the occupied timeout for this device to the given number of + ///< Seconds, This can be used to tune a device to a particular transponder + ///< and make sure it will stay there for a certain amount of time, for + ///< instance to collect EPG data. This function shall only be called + ///< after the device has been successfully tuned to the requested transponder. + ///< Seconds will be silently limited to MAXOCCUPIEDTIMEOUT. Values less than + ///< 0 will be silently ignored. virtual bool HasLock(int TimeoutMs = 0); ///< Returns true if the device has a lock on the requested transponder. ///< Default is true, a specific device implementation may return false @@ -457,7 +472,7 @@ protected: ///< Sets the current subtitle track to the given value. public: void ClrAvailableTracks(bool DescriptionsOnly = false, bool IdsOnly = false); - ///< Clears the list of currently availabe tracks. If DescriptionsOnly + ///< Clears the list of currently available tracks. If DescriptionsOnly ///< is true, only the track descriptions will be cleared. With IdsOnly ///< set to true only the ids will be cleared. IdsOnly is only taken ///< into account if DescriptionsOnly is false. @@ -650,10 +665,10 @@ public: ///< Returns true if the device itself or any of the file handles in ///< Poller is ready for further action. ///< If TimeoutMs is not zero, the device will wait up to the given number - ///< of milleseconds before returning in case it can't accept any data. + ///< of milliseconds before returning in case it can't accept any data. virtual bool Flush(int TimeoutMs = 0); ///< Returns true if the device's output buffers are empty, i. e. any - ///< data which was bufferd so far has been processed. + ///< data which was buffered so far has been processed. ///< If TimeoutMs is not zero, the device will wait up to the given ///< number of milliseconds before returning in case there is still ///< data in the buffers. @@ -697,7 +712,7 @@ public: // Receiver facilities private: - cMutex mutexReceiver; + mutable cMutex mutexReceiver; cReceiver *receiver[MAXRECEIVERS]; public: int Priority(void) const; @@ -726,7 +741,7 @@ public: ///< Detaches the given receiver from this device. void DetachAll(int Pid); ///< Detaches all receivers from this device for this pid. - void DetachAllReceivers(void); + virtual void DetachAllReceivers(void); ///< Detaches all receivers from this device. }; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: diseqc.c 2.5 2011/08/06 10:32:18 kls Exp $ + * $Id: diseqc.c 2.9 2011/09/17 14:13:31 kls Exp $ */ #include "diseqc.h" @@ -12,6 +12,81 @@ #include "sources.h" #include "thread.h" +static bool ParseDeviceNumbers(const char *s, int &Devices) +{ + if (*s && s[strlen(s) - 1] == ':') { + const char *p = s; + while (*p && *p != ':') { + char *t = NULL; + int d = strtol(p, &t, 10); + p = t; + if (0 < d && d < 31) + Devices |= (1 << d - 1); + else { + esyslog("ERROR: invalid device number %d in '%s'", d, s); + return false; + } + } + } + return true; +} + +// --- cScr ------------------------------------------------------------------ + +cScr::cScr(void) +{ + devices = 0; + channel = -1; + userBand = 0; + pin = -1; + used = false; +} + +bool cScr::Parse(const char *s) +{ + if (!ParseDeviceNumbers(s, devices)) + return false; + if (devices) + return true; + bool result = false; + int fields = sscanf(s, "%d %u %d", &channel, &userBand, &pin); + if (fields == 2 || fields == 3) { + if (channel >= 0 && channel < 8) { + result = true; + if (fields == 3 && (pin < 0 || pin > 255)) { + esyslog("Error: invalid SCR pin '%d'", pin); + result = false; + } + } + else + esyslog("Error: invalid SCR channel '%d'", channel); + } + return result; +} + +// --- cScrs ----------------------------------------------------------------- + +cScrs Scrs; + +cScr *cScrs::GetUnused(int Device) +{ + cMutexLock MutexLock(&mutex); + int Devices = 0; + for (cScr *p = First(); p; p = Next(p)) { + if (p->Devices()) { + Devices = p->Devices(); + continue; + } + if (Devices && !(Devices & (1 << Device - 1))) + continue; + if (!p->Used()) { + p->SetUsed(true); + return p; + } + } + return NULL; +} + // --- cDiseqc --------------------------------------------------------------- cDiseqc::cDiseqc(void) @@ -21,9 +96,9 @@ cDiseqc::cDiseqc(void) slof = 0; polarization = 0; lof = 0; + scrBank = -1; commands = NULL; parsing = false; - numCodes = 0; } cDiseqc::~cDiseqc() @@ -33,23 +108,12 @@ cDiseqc::~cDiseqc() bool cDiseqc::Parse(const char *s) { + if (!ParseDeviceNumbers(s, devices)) + return false; + if (devices) + return true; bool result = false; char *sourcebuf = NULL; - if (*s && s[strlen(s) - 1] == ':') { - const char *p = s; - while (*p && *p != ':') { - char *t = NULL; - int d = strtol(p, &t, 10); - p = t; - if (0 < d && d < 32) - devices |= (1 << d - 1); - else { - esyslog("ERROR: invalid device number %d in '%s'", d, s); - return false; - } - } - return true; - } int fields = sscanf(s, "%a[^ ] %d %c %d %a[^\n]", &sourcebuf, &slof, &polarization, &lof, &commands); if (fields == 4) commands = NULL; //XXX Apparently sscanf() doesn't work correctly if the last %a argument results in an empty string @@ -60,7 +124,7 @@ bool cDiseqc::Parse(const char *s) if (polarization == 'V' || polarization == 'H' || polarization == 'L' || polarization == 'R') { parsing = true; const char *CurrentAction = NULL; - while (Execute(&CurrentAction) != daNone) + while (Execute(&CurrentAction, NULL, NULL, NULL, NULL) != daNone) ; parsing = false; result = !commands || !*CurrentAction; @@ -75,6 +139,31 @@ bool cDiseqc::Parse(const char *s) return result; } +uint cDiseqc::SetScrFrequency(uint SatFrequency, const cScr *Scr, uint8_t *Codes) const +{ + uint t = SatFrequency == 0 ? 0 : (SatFrequency + Scr->UserBand() + 2) / 4 - 350; // '+ 2' together with '/ 4' results in rounding! + if (t < 1024 && Scr->Channel() >= 0 && Scr->Channel() < 8) { + Codes[3] = t >> 8 | (t == 0 ? 0 : scrBank << 2) | Scr->Channel() << 5; + Codes[4] = t; + if (t) + return (t + 350) * 4 - SatFrequency; + } + return 0; +} + +int cDiseqc::SetScrPin(const cScr *Scr, uint8_t *Codes) const +{ + if (Scr->Pin() >= 0 && Scr->Pin() <= 255) { + Codes[2] = 0x5C; + Codes[5] = Scr->Pin(); + return 6; + } + else { + Codes[2] = 0x5A; + return 5; + } +} + const char *cDiseqc::Wait(const char *s) const { char *p = NULL; @@ -89,7 +178,25 @@ const char *cDiseqc::Wait(const char *s) const return NULL; } -const char *cDiseqc::Codes(const char *s) const +const char *cDiseqc::GetScrBank(const char *s) const +{ + char *p = NULL; + errno = 0; + int n = strtol(s, &p, 10); + if (!errno && p != s && n >= 0 && n < 8) { + if (parsing) { + if (scrBank < 0) + scrBank = n; + else + esyslog("ERROR: more than one scr bank in '%s'", s - 1); + } + return p; + } + esyslog("ERROR: more than one scr bank in '%s'", s - 1); + return NULL; +} + +const char *cDiseqc::GetCodes(const char *s, uchar *Codes, uint8_t *MaxCodes) const { const char *e = strchr(s, ']'); if (e) { @@ -101,9 +208,13 @@ const char *cDiseqc::Codes(const char *s) const char *p; int n = strtol(t, &p, 16); if (!errno && p != t && 0 <= n && n <= 255) { - if (!parsing) { - codes[NumCodes++] = uchar(n); - numCodes = NumCodes; + if (Codes) { + if (NumCodes < *MaxCodes) + Codes[NumCodes++] = uchar(n); + else { + esyslog("ERROR: too many codes in code sequence '%s'", s - 1); + return NULL; + } } t = skipspace(p); } @@ -117,6 +228,8 @@ const char *cDiseqc::Codes(const char *s) const return NULL; } } + if (MaxCodes) + *MaxCodes = NumCodes; return e + 1; } else @@ -124,7 +237,7 @@ const char *cDiseqc::Codes(const char *s) const return NULL; } -cDiseqc::eDiseqcActions cDiseqc::Execute(const char **CurrentAction) const +cDiseqc::eDiseqcActions cDiseqc::Execute(const char **CurrentAction, uchar *Codes, uint8_t *MaxCodes, const cScr *Scr, uint *Frequency) const { if (!*CurrentAction) *CurrentAction = commands; @@ -138,7 +251,16 @@ cDiseqc::eDiseqcActions cDiseqc::Execute(const char **CurrentAction) const case 'A': return daMiniA; case 'B': return daMiniB; case 'W': *CurrentAction = Wait(*CurrentAction); break; - case '[': *CurrentAction = Codes(*CurrentAction); return *CurrentAction ? daCodes : daNone; + case 'S': *CurrentAction = GetScrBank(*CurrentAction); break; + case '[': *CurrentAction = GetCodes(*CurrentAction, Codes, MaxCodes); + if (*CurrentAction) { + if (Scr && Frequency) { + *Frequency = SetScrFrequency(*Frequency, Scr, Codes); + *MaxCodes = SetScrPin(Scr, Codes); + } + return daCodes; + } + break; default: return daNone; } } @@ -149,7 +271,7 @@ cDiseqc::eDiseqcActions cDiseqc::Execute(const char **CurrentAction) const cDiseqcs Diseqcs; -const cDiseqc *cDiseqcs::Get(int Device, int Source, int Frequency, char Polarization) const +const cDiseqc *cDiseqcs::Get(int Device, int Source, int Frequency, char Polarization, const cScr **Scr) const { int Devices = 0; for (const cDiseqc *p = First(); p; p = Next(p)) { @@ -159,8 +281,16 @@ const cDiseqc *cDiseqcs::Get(int Device, int Source, int Frequency, char Polariz } if (Devices && !(Devices & (1 << Device - 1))) continue; - if (p->Source() == Source && p->Slof() > Frequency && p->Polarization() == toupper(Polarization)) + if (p->Source() == Source && p->Slof() > Frequency && p->Polarization() == toupper(Polarization)) { + if (p->IsScr() && Scr && !*Scr) { + *Scr = Scrs.GetUnused(Device); + if (*Scr) + dsyslog("SCR %d assigned to device %d", (*Scr)->Channel(), Device); + else + esyslog("ERROR: no free SCR entry available for device %d", Device); + } return p; + } } return NULL; } diff --git a/diseqc.conf b/diseqc.conf index c9ab3ad..2895c43 100644 --- a/diseqc.conf +++ b/diseqc.conf @@ -18,6 +18,7 @@ # V voltage high (18V) # A mini A # B mini B +# Sn Satellite channel routing code sequence for bank n follows # Wnn wait nn milliseconds (nn may be any positive integer number) # [xx ...] hex code sequence (max. 6) # @@ -75,3 +76,15 @@ S13.0E 99999 H 10600 t V W15 [E0 10 38 F7] W15 B W15 T # S19.2E 99999 H 10560 t v # S19.2E 12110 V 11080 t v # S19.2E 99999 V 10720 t v +# +# SCR (Satellite Channel Routing): +# +# S19.2E 11700 V 9750 t V W10 S0 [E0 10 5A 00 00] W10 v +# S19.2E 99999 V 10600 t V W10 S1 [E0 10 5A 00 00] W10 v +# S19.2E 11700 H 9750 t V W10 S2 [E0 10 5A 00 00] W10 v +# S19.2E 99999 H 10600 t V W10 S3 [E0 10 5A 00 00] W10 v +# +# S13.0E 11700 V 9750 t V W10 S4 [E0 10 5A 00 00] W10 v +# S13.0E 99999 V 10600 t V W10 S5 [E0 10 5A 00 00] W10 v +# S13.0E 11700 H 9750 t V W10 S6 [E0 10 5A 00 00] W10 v +# S13.0E 99999 H 10600 t V W10 S7 [E0 10 5A 00 00] W10 v @@ -4,13 +4,41 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: diseqc.h 2.2 2011/05/22 10:35:38 kls Exp $ + * $Id: diseqc.h 2.5 2011/09/17 13:15:17 kls Exp $ */ #ifndef __DISEQC_H #define __DISEQC_H #include "config.h" +#include "thread.h" + +class cScr : public cListObject { +private: + int devices; + int channel; + uint userBand; + int pin; + bool used; +public: + cScr(void); + bool Parse(const char *s); + int Devices(void) const { return devices; } + int Channel(void) const { return channel; } + uint UserBand(void) const { return userBand; } + int Pin(void) const { return pin; } + bool Used(void) const { return used; } + void SetUsed(bool Used) { used = Used; } + }; + +class cScrs : public cConfig<cScr> { +private: + cMutex mutex; +public: + cScr *GetUnused(int Device); + }; + +extern cScrs Scrs; class cDiseqc : public cListObject { public: @@ -22,6 +50,7 @@ public: daVoltage18, daMiniA, daMiniB, + daScr, daCodes, }; enum { MaxDiseqcCodes = 6 }; @@ -31,36 +60,53 @@ private: int slof; char polarization; int lof; + mutable int scrBank; char *commands; bool parsing; - mutable uchar codes[MaxDiseqcCodes]; - mutable int numCodes; + uint SetScrFrequency(uint SatFrequency, const cScr *Scr, uint8_t *Codes) const; + int SetScrPin(const cScr *Scr, uint8_t *Codes) const; const char *Wait(const char *s) const; - const char *Codes(const char *s) const; + const char *GetScrBank(const char *s) const; + const char *GetCodes(const char *s, uchar *Codes = NULL, uint8_t *MaxCodes = NULL) const; public: cDiseqc(void); ~cDiseqc(); bool Parse(const char *s); - eDiseqcActions Execute(const char **CurrentAction) const; - // Parses the DiSEqC commands and returns the appropriate action code - // with every call. CurrentAction must be the address of a character pointer, - // which is initialized to NULL. This pointer is used internally while parsing - // the commands and shall not be modified once Execute() has been called with - // it. Call Execute() repeatedly (always providing the same CurrentAction pointer) - // until it returns daNone. After a successful execution of all commands - // *CurrentAction points to the value 0x00. + eDiseqcActions Execute(const char **CurrentAction, uchar *Codes, uint8_t *MaxCodes, const cScr *Scr, uint *Frequency) const; + ///< Parses the DiSEqC commands and returns the appropriate action code + ///< with every call. CurrentAction must be the address of a character pointer, + ///< which is initialized to NULL. This pointer is used internally while parsing + ///< the commands and shall not be modified once Execute() has been called with + ///< it. Call Execute() repeatedly (always providing the same CurrentAction pointer) + ///< until it returns daNone. After a successful execution of all commands + ///< *CurrentAction points to the value 0x00. + ///< If the current action consists of sending code bytes to the device, those + ///< bytes will be copied into Codes. MaxCodes must be initialized to the maximum + ///< number of bytes Codes can handle, and will be set to the actual number of + ///< bytes copied to Codes upon return. + ///< If this DiSEqC entry requires SCR, the given Scr will be used. This must + ///< be a pointer returned from a previous call to cDiseqcs::Get(). + ///< Frequency must be the frequency the tuner will be tuned to, and will be + ///< set to the proper SCR frequency upon return (if SCR is used). int Devices(void) const { return devices; } int Source(void) const { return source; } int Slof(void) const { return slof; } char Polarization(void) const { return polarization; } int Lof(void) const { return lof; } + bool IsScr() const { return scrBank >= 0; } const char *Commands(void) const { return commands; } - const uchar *Codes(int &NumCodes) const { NumCodes = numCodes; return numCodes ? codes : NULL; } }; class cDiseqcs : public cConfig<cDiseqc> { public: - const cDiseqc *Get(int Device, int Source, int Frequency, char Polarization) const; + const cDiseqc *Get(int Device, int Source, int Frequency, char Polarization, const cScr **Scr) const; + ///< Selects a DiSEqC entry suitable for the given Device and tuning parameters. + ///< If this DiSEqC entry requires SCR and the given *Scr is NULL + ///< a free one will be selected from the Scrs and a pointer to that will + ///< be returned in Scr. The caller shall memorize that pointer and reuse it in + ///< subsequent calls. + ///< Scr may be NULL for checking whether there is any DiSEqC entry for the + ///< given transponder. }; extern cDiseqcs Diseqcs; diff --git a/dvbdevice.c b/dvbdevice.c index a97f274..163fce3 100644 --- a/dvbdevice.c +++ b/dvbdevice.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbdevice.c 2.43 2011/08/26 12:57:34 kls Exp $ + * $Id: dvbdevice.c 2.48 2011/12/03 15:24:27 kls Exp $ */ #include "dvbdevice.h" @@ -32,6 +32,8 @@ #define ATSC_TUNE_TIMEOUT 9000 //ms #define ATSC_LOCK_TIMEOUT 2000 //ms +#define SCR_RANDOM_TIMEOUT 500 // ms (add random value up to this when tuning SCR device to avoid lockups) + // --- DVB Parameter Maps ---------------------------------------------------- const tDvbParameterMap InversionValues[] = { @@ -257,8 +259,9 @@ bool cDvbTransponderParameters::Parse(const char *s) class cDvbTuner : public cThread { private: + static cMutex bondMutex; enum eTunerStatus { tsIdle, tsSet, tsTuned, tsLocked }; - int device; + const cDvbDevice *device; int fd_frontend; int adapter, frontend; uint32_t subsystemId; @@ -267,28 +270,41 @@ private: time_t lastTimeoutReport; fe_delivery_system frontendType; cChannel channel; - const char *diseqcCommands; + const cDiseqc *lastDiseqc; + const cScr *scr; eTunerStatus tunerStatus; cMutex mutex; cCondVar locked; cCondVar newSet; + cDvbTuner *bondedTuner; + bool bondedMaster; + bool bondedMasterFailed; + cString GetBondingParams(const cChannel *Channel = NULL) const; void ClearEventQueue(void) const; bool GetFrontendStatus(fe_status_t &Status) const; + void ExecuteDiseqc(const cDiseqc *Diseqc, unsigned int *Frequency); + void ResetToneAndVoltage(void); bool SetFrontend(void); virtual void Action(void); public: - cDvbTuner(int Device, int Fd_Frontend, int Adapter, int Frontend, fe_delivery_system FrontendType); + cDvbTuner(const cDvbDevice *Device, int Fd_Frontend, int Adapter, int Frontend, fe_delivery_system FrontendType); virtual ~cDvbTuner(); + bool Bond(cDvbTuner *Tuner); + void UnBond(void); + bool BondingOk(const cChannel *Channel, bool ConsiderOccupied = false) const; + cDvbTuner *GetBondedMaster(void); const cChannel *GetTransponder(void) const { return &channel; } uint32_t SubsystemId(void) const { return subsystemId; } bool IsTunedTo(const cChannel *Channel) const; - void Set(const cChannel *Channel); + void SetChannel(const cChannel *Channel); bool Locked(int TimeoutMs = 0); int GetSignalStrength(void) const; int GetSignalQuality(void) const; }; -cDvbTuner::cDvbTuner(int Device, int Fd_Frontend, int Adapter, int Frontend, fe_delivery_system FrontendType) +cMutex cDvbTuner::bondMutex; + +cDvbTuner::cDvbTuner(const cDvbDevice *Device, int Fd_Frontend, int Adapter, int Frontend, fe_delivery_system FrontendType) { device = Device; fd_frontend = Fd_Frontend; @@ -299,10 +315,14 @@ cDvbTuner::cDvbTuner(int Device, int Fd_Frontend, int Adapter, int Frontend, fe_ tuneTimeout = 0; lockTimeout = 0; lastTimeoutReport = 0; - diseqcCommands = NULL; + lastDiseqc = NULL; + scr = NULL; tunerStatus = tsIdle; + bondedTuner = NULL; + bondedMaster = false; + bondedMasterFailed = false; if (frontendType == SYS_DVBS || frontendType == SYS_DVBS2) - CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); // must explicitly turn on LNB power + ResetToneAndVoltage(); // must explicitly turn on LNB power SetDescription("tuner on frontend %d/%d", adapter, frontend); Start(); } @@ -313,6 +333,116 @@ cDvbTuner::~cDvbTuner() newSet.Broadcast(); locked.Broadcast(); Cancel(3); + UnBond(); + /* looks like this irritates the SCR switch, so let's leave it out for now + if (lastDiseqc && lastDiseqc->IsScr()) { + unsigned int Frequency = 0; + ExecuteDiseqc(lastDiseqc, &Frequency); + } + */ +} + +bool cDvbTuner::Bond(cDvbTuner *Tuner) +{ + cMutexLock MutexLock(&bondMutex); + if (!bondedTuner) { + if ((frontendType == SYS_DVBS || frontendType == SYS_DVBS2) && (Tuner->frontendType == SYS_DVBS || Tuner->frontendType == SYS_DVBS2)) { + ResetToneAndVoltage(); + bondedMaster = false; // makes sure we don't disturb an existing master + bondedTuner = Tuner->bondedTuner ? Tuner->bondedTuner : Tuner; + Tuner->bondedTuner = this; + dsyslog("tuner %d/%d bonded with tuner %d/%d", adapter, frontend, bondedTuner->adapter, bondedTuner->frontend); + return true; + } + else + esyslog("ERROR: can't bond tuner %d/%d with tuner %d/%d (only DVB-S(2) tuners can be bonded)", adapter, frontend, Tuner->adapter, Tuner->frontend); + } + else + esyslog("ERROR: tuner %d/%d already bonded with tuner %d/%d, can't bond with tuner %d/%d", adapter, frontend, bondedTuner->adapter, bondedTuner->frontend, Tuner->adapter, Tuner->frontend); + return false; +} + +void cDvbTuner::UnBond(void) +{ + cMutexLock MutexLock(&bondMutex); + if (cDvbTuner *t = bondedTuner) { + dsyslog("tuner %d/%d unbonded from tuner %d/%d", adapter, frontend, bondedTuner->adapter, bondedTuner->frontend); + while (t->bondedTuner != this) + t = t->bondedTuner; + if (t == bondedTuner) + t->bondedTuner = NULL; + else + t->bondedTuner = bondedTuner; + bondedMaster = false; // another one will automatically become master whenever necessary + bondedTuner = NULL; + } +} + +cString cDvbTuner::GetBondingParams(const cChannel *Channel) const +{ + if (!Channel) + Channel = &channel; + cDvbTransponderParameters dtp(Channel->Parameters()); + if (Setup.DiSEqC) { + if (const cDiseqc *diseqc = Diseqcs.Get(device->CardIndex() + 1, Channel->Source(), Channel->Frequency(), dtp.Polarization(), NULL)) + return diseqc->Commands(); + } + else { + bool ToneOff = Channel->Frequency() < (unsigned int)Setup.LnbSLOF; + bool VoltOff = dtp.Polarization() == 'V' || dtp.Polarization() == 'R'; + return cString::sprintf("%c %c", ToneOff ? 't' : 'T', VoltOff ? 'v' : 'V'); + } + return ""; +} + +bool cDvbTuner::BondingOk(const cChannel *Channel, bool ConsiderOccupied) const +{ + cMutexLock MutexLock(&bondMutex); + if (cDvbTuner *t = bondedTuner) { + cString BondingParams = GetBondingParams(Channel); + do { + if (t->device->Receiving() || t->tunerStatus != tsIdle && (t->device == cDevice::ActualDevice() || ConsiderOccupied && t->device->Occupied())) { + if (strcmp(BondingParams, t->GetBondingParams()) != 0) + return false; + } + t = t->bondedTuner; + } while (t != bondedTuner); + } + return true; +} + +cDvbTuner *cDvbTuner::GetBondedMaster(void) +{ + if (!bondedTuner) + return this; // an unbonded tuner is always "master" + cMutexLock MutexLock(&bondMutex); + if (bondedMaster) { + if (!bondedMasterFailed) + return this; + else + bondedMaster = false; + } + // This tuner is bonded, but it's not the master, so let's see if there is a master at all: + if (cDvbTuner *t = bondedTuner) { + while (t != this) { + if (t->bondedMaster) + return t; + t = t->bondedTuner; + } + } + // None of the other bonded tuners is master, so make this one the master: + cDvbTuner *t = this; + if (bondedMasterFailed) { + // This one has failed, so switch to the next one: + t = bondedTuner; + t->bondedMasterFailed = false; + cMutexLock MutexLock(&t->mutex); + t->channel = channel; + t->tunerStatus = tsSet; + } + t->bondedMaster = true; + dsyslog("tuner %d/%d is now bonded master", t->adapter, t->frontend); + return t; } bool cDvbTuner::IsTunedTo(const cChannel *Channel) const @@ -325,14 +455,34 @@ bool cDvbTuner::IsTunedTo(const cChannel *Channel) const return strcmp(channel.Parameters(), Channel->Parameters()) == 0; } -void cDvbTuner::Set(const cChannel *Channel) +void cDvbTuner::SetChannel(const cChannel *Channel) { - cMutexLock MutexLock(&mutex); - if (!IsTunedTo(Channel)) - tunerStatus = tsSet; - channel = *Channel; - lastTimeoutReport = 0; - newSet.Broadcast(); + if (Channel) { + if (bondedTuner) { + cMutexLock MutexLock(&bondMutex); + cDvbTuner *BondedMaster = GetBondedMaster(); + if (BondedMaster == this) { + if (strcmp(GetBondingParams(Channel), GetBondingParams()) != 0) { + // switching to a completely different band, so set all others to idle: + for (cDvbTuner *t = bondedTuner; t && t != this; t = t->bondedTuner) + t->SetChannel(NULL); + } + } + else if (!BondedMaster->device->Receiving()) + BondedMaster->SetChannel(Channel); + } + cMutexLock MutexLock(&mutex); + if (!IsTunedTo(Channel)) + tunerStatus = tsSet; + channel = *Channel; + lastTimeoutReport = 0; + newSet.Broadcast(); + } + else { + cMutexLock MutexLock(&mutex); + tunerStatus = tsIdle; + ResetToneAndVoltage(); + } } bool cDvbTuner::Locked(int TimeoutMs) @@ -482,6 +632,36 @@ static unsigned int FrequencyToHz(unsigned int f) return f; } +void cDvbTuner::ExecuteDiseqc(const cDiseqc *Diseqc, unsigned int *Frequency) +{ + struct dvb_diseqc_master_cmd cmd; + const char *CurrentAction = NULL; + for (;;) { + cmd.msg_len = sizeof(cmd.msg); + cDiseqc::eDiseqcActions da = Diseqc->Execute(&CurrentAction, cmd.msg, &cmd.msg_len, scr, Frequency); + if (da == cDiseqc::daNone) + break; + switch (da) { + case cDiseqc::daToneOff: CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); break; + case cDiseqc::daToneOn: CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_ON)); break; + case cDiseqc::daVoltage13: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); break; + case cDiseqc::daVoltage18: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); break; + case cDiseqc::daMiniA: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A)); break; + case cDiseqc::daMiniB: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break; + case cDiseqc::daCodes: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd)); break; + default: esyslog("ERROR: unknown diseqc command %d", da); + } + } + if (scr) + ResetToneAndVoltage(); // makes sure we don't block the bus! +} + +void cDvbTuner::ResetToneAndVoltage(void) +{ + CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); + CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); +} + bool cDvbTuner::SetFrontend(void) { #define MAXFRONTENDCMDS 16 @@ -509,36 +689,18 @@ bool cDvbTuner::SetFrontend(void) if (frontendType == SYS_DVBS || frontendType == SYS_DVBS2) { unsigned int frequency = channel.Frequency(); if (Setup.DiSEqC) { - const cDiseqc *diseqc = Diseqcs.Get(device, channel.Source(), channel.Frequency(), dtp.Polarization()); - if (diseqc) { - if (diseqc->Commands() && (!diseqcCommands || strcmp(diseqcCommands, diseqc->Commands()) != 0)) { - cDiseqc::eDiseqcActions da; - for (const char *CurrentAction = NULL; (da = diseqc->Execute(&CurrentAction)) != cDiseqc::daNone; ) { - switch (da) { - case cDiseqc::daNone: break; - case cDiseqc::daToneOff: CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); break; - case cDiseqc::daToneOn: CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_ON)); break; - case cDiseqc::daVoltage13: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); break; - case cDiseqc::daVoltage18: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); break; - case cDiseqc::daMiniA: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A)); break; - case cDiseqc::daMiniB: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break; - case cDiseqc::daCodes: { - int n = 0; - const uchar *codes = diseqc->Codes(n); - if (codes) { - struct dvb_diseqc_master_cmd cmd; - cmd.msg_len = min(n, int(sizeof(cmd.msg))); - memcpy(cmd.msg, codes, cmd.msg_len); - CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd)); - } - } - break; - default: esyslog("ERROR: unknown diseqc command %d", da); - } - } - diseqcCommands = diseqc->Commands(); - } + if (const cDiseqc *diseqc = Diseqcs.Get(device->CardIndex() + 1, channel.Source(), frequency, dtp.Polarization(), &scr)) { frequency -= diseqc->Lof(); + if (diseqc != lastDiseqc || diseqc->IsScr()) { + if (GetBondedMaster() == this) { + ExecuteDiseqc(diseqc, &frequency); + if (frequency == 0) + return false; + } + else + ResetToneAndVoltage(); + lastDiseqc = diseqc; + } } else { esyslog("ERROR: no DiSEqC parameters found for channel %d", channel.Number()); @@ -555,7 +717,11 @@ bool cDvbTuner::SetFrontend(void) frequency -= Setup.LnbFrequHi; tone = SEC_TONE_ON; } - int volt = (dtp.Polarization() == 'v' || dtp.Polarization() == 'V' || dtp.Polarization() == 'r' || dtp.Polarization() == 'R') ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18; + int volt = (dtp.Polarization() == 'V' || dtp.Polarization() == 'R') ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18; + if (GetBondedMaster() != this) { + tone = SEC_TONE_OFF; + volt = SEC_VOLTAGE_13; + } CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, volt)); CHECK(ioctl(fd_frontend, FE_SET_TONE, tone)); } @@ -652,22 +818,25 @@ void cDvbTuner::Action(void) break; case tsSet: tunerStatus = SetFrontend() ? tsTuned : tsIdle; - Timer.Set(tuneTimeout); + Timer.Set(tuneTimeout + (scr ? rand() % SCR_RANDOM_TIMEOUT : 0)); continue; case tsTuned: if (Timer.TimedOut()) { tunerStatus = tsSet; - diseqcCommands = NULL; + lastDiseqc = NULL; if (time(NULL) - lastTimeoutReport > 60) { // let's not get too many of these isyslog("frontend %d/%d timed out while tuning to channel %d, tp %d", adapter, frontend, channel.Number(), channel.Transponder()); lastTimeoutReport = time(NULL); } + cMutexLock MutexLock(&bondMutex); + if (bondedTuner && bondedMaster) + bondedMasterFailed = true; // give an other tuner a chance in case the sat cable was disconnected continue; } case tsLocked: if (Status & FE_REINIT) { tunerStatus = tsSet; - diseqcCommands = NULL; + lastDiseqc = NULL; isyslog("frontend %d/%d was reinitialized", adapter, frontend); lastTimeoutReport = 0; continue; @@ -757,6 +926,7 @@ cOsdItem *cDvbSourceParam::GetOsdItem(void) // --- cDvbDevice ------------------------------------------------------------ int cDvbDevice::setTransferModeForDolbyDigital = 1; +cMutex cDvbDevice::bondMutex; const char *DeliverySystems[] = { "UNDEFINED", @@ -786,6 +956,8 @@ cDvbDevice::cDvbDevice(int Adapter, int Frontend) dvbTuner = NULL; frontendType = SYS_UNDEFINED; numProvidedSystems = 0; + bondedDevice = NULL; + needsDetachBondedReceivers = false; // Devices that are present on all card types: @@ -835,7 +1007,7 @@ cDvbDevice::cDvbDevice(int Adapter, int Frontend) else p = (char *)"unknown modulations"; isyslog("frontend %d/%d provides %s with %s (\"%s\")", adapter, frontend, DeliverySystems[frontendType], p, frontendInfo.name); - dvbTuner = new cDvbTuner(CardIndex() + 1, fd_frontend, adapter, frontend, frontendType); + dvbTuner = new cDvbTuner(this, fd_frontend, adapter, frontend, frontendType); } } else @@ -849,6 +1021,7 @@ cDvbDevice::~cDvbDevice() StopSectionHandler(); delete dvbTuner; delete ciAdapter; + UnBond(); // We're not explicitly closing any device files here, since this sometimes // caused segfaults. Besides, the program is about to terminate anyway... } @@ -940,6 +1113,104 @@ bool cDvbDevice::Ready(void) return true; } +bool cDvbDevice::BondDevices(const char *Bondings) +{ + UnBondDevices(); + if (Bondings) { + cSatCableNumbers SatCableNumbers(MAXDEVICES, Bondings); + for (int i = 0; i < cDevice::NumDevices(); i++) { + int d = SatCableNumbers.FirstDeviceIndex(i); + if (d >= 0) { + int ErrorDevice = 0; + if (cDevice *Device1 = cDevice::GetDevice(i)) { + if (cDevice *Device2 = cDevice::GetDevice(d)) { + if (cDvbDevice *DvbDevice1 = dynamic_cast<cDvbDevice *>(Device1)) { + if (cDvbDevice *DvbDevice2 = dynamic_cast<cDvbDevice *>(Device2)) { + if (!DvbDevice2->Bond(DvbDevice1)) + return false; // Bond() has already logged the error + } + else + ErrorDevice = d + 1; + } + else + ErrorDevice = i + 1; + if (ErrorDevice) { + esyslog("ERROR: device '%d' in device bondings '%s' is not a cDvbDevice", ErrorDevice, Bondings); + return false; + } + } + else + ErrorDevice = d + 1; + } + else + ErrorDevice = i + 1; + if (ErrorDevice) { + esyslog("ERROR: unknown device '%d' in device bondings '%s'", ErrorDevice, Bondings); + return false; + } + } + } + } + return true; +} + +void cDvbDevice::UnBondDevices(void) +{ + for (int i = 0; i < cDevice::NumDevices(); i++) { + if (cDvbDevice *d = dynamic_cast<cDvbDevice *>(cDevice::GetDevice(i))) + d->UnBond(); + } +} + +bool cDvbDevice::Bond(cDvbDevice *Device) +{ + cMutexLock MutexLock(&bondMutex); + if (!bondedDevice) { + if (Device != this) { + if ((frontendType == SYS_DVBS || frontendType == SYS_DVBS2) && (Device->frontendType == SYS_DVBS || Device->frontendType == SYS_DVBS2)) { + if (dvbTuner && Device->dvbTuner && dvbTuner->Bond(Device->dvbTuner)) { + bondedDevice = Device->bondedDevice ? Device->bondedDevice : Device; + Device->bondedDevice = this; + dsyslog("device %d bonded with device %d", CardIndex() + 1, bondedDevice->CardIndex() + 1); + return true; + } + } + else + esyslog("ERROR: can't bond device %d with device %d (only DVB-S(2) devices can be bonded)", CardIndex() + 1, Device->CardIndex() + 1); + } + else + esyslog("ERROR: can't bond device %d with itself", CardIndex() + 1); + } + else + esyslog("ERROR: device %d already bonded with device %d, can't bond with device %d", CardIndex() + 1, bondedDevice->CardIndex() + 1, Device->CardIndex() + 1); + return false; +} + +void cDvbDevice::UnBond(void) +{ + cMutexLock MutexLock(&bondMutex); + if (cDvbDevice *d = bondedDevice) { + if (dvbTuner) + dvbTuner->UnBond(); + dsyslog("device %d unbonded from device %d", CardIndex() + 1, bondedDevice->CardIndex() + 1); + while (d->bondedDevice != this) + d = d->bondedDevice; + if (d == bondedDevice) + d->bondedDevice = NULL; + else + d->bondedDevice = bondedDevice; + bondedDevice = NULL; + } +} + +bool cDvbDevice::BondingOk(const cChannel *Channel, bool ConsiderOccupied) const +{ + cMutexLock MutexLock(&bondMutex); + if (bondedDevice) + return dvbTuner && dvbTuner->BondingOk(Channel, ConsiderOccupied); + return true; +} + bool cDvbDevice::HasCi(void) { return ciAdapter; @@ -1042,7 +1313,7 @@ bool cDvbDevice::ProvidesTransponder(const cChannel *Channel) const dtp.Modulation() == PSK_8 && !(frontendInfo.caps & FE_CAN_TURBO_FEC) && dtp.System() == SYS_DVBS) // "turbo fec" is a non standard FEC used by North American broadcasters - this is a best guess to determine this condition return false; // requires modulation system which frontend doesn't provide if (!cSource::IsSat(Channel->Source()) || - !Setup.DiSEqC || Diseqcs.Get(CardIndex() + 1, Channel->Source(), Channel->Frequency(), dtp.Polarization())) + (!Setup.DiSEqC || Diseqcs.Get(CardIndex() + 1, Channel->Source(), Channel->Frequency(), dtp.Polarization(), NULL))) return DeviceHooksProvidesTransponder(Channel); return false; } @@ -1052,28 +1323,44 @@ bool cDvbDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool *Ne bool result = false; bool hasPriority = Priority < 0 || Priority > this->Priority(); bool needsDetachReceivers = false; + needsDetachBondedReceivers = false; if (dvbTuner && ProvidesTransponder(Channel)) { result = hasPriority; - if (Priority >= 0 && Receiving(true)) { - if (dvbTuner->IsTunedTo(Channel)) { - if (Channel->Vpid() && !HasPid(Channel->Vpid()) || Channel->Apid(0) && !HasPid(Channel->Apid(0))) { - if (CamSlot() && Channel->Ca() >= CA_ENCRYPTED_MIN) { - if (CamSlot()->CanDecrypt(Channel)) + if (Priority >= 0) { + if (Receiving(true)) { + if (dvbTuner->IsTunedTo(Channel)) { + if (Channel->Vpid() && !HasPid(Channel->Vpid()) || Channel->Apid(0) && !HasPid(Channel->Apid(0))) { + if (CamSlot() && Channel->Ca() >= CA_ENCRYPTED_MIN) { + if (CamSlot()->CanDecrypt(Channel)) + result = true; + else + needsDetachReceivers = true; + } + else if (!IsPrimaryDevice()) result = true; else - needsDetachReceivers = true; + result = Priority >= Setup.PrimaryLimit; } - else if (!IsPrimaryDevice()) - result = true; else - result = Priority >= Setup.PrimaryLimit; + result = !IsPrimaryDevice() || Priority >= Setup.PrimaryLimit; } else - result = !IsPrimaryDevice() || Priority >= Setup.PrimaryLimit; + needsDetachReceivers = true; + } + if (result) { + if (!BondingOk(Channel)) { + // This device is bonded, so we need to check the priorities of the others: + for (cDvbDevice *d = bondedDevice; d && d != this; d = d->bondedDevice) { + if (d->Priority() >= Priority) { + result = false; + break; + } + } + needsDetachBondedReceivers = true; + needsDetachReceivers = true; + } } - else - needsDetachReceivers = true; } } if (NeedsDetachReceivers) @@ -1106,15 +1393,20 @@ const cChannel *cDvbDevice::GetCurrentlyTunedTransponder(void) const return dvbTuner ? dvbTuner->GetTransponder() : NULL; } -bool cDvbDevice::IsTunedToTransponder(const cChannel *Channel) +bool cDvbDevice::IsTunedToTransponder(const cChannel *Channel) const { return dvbTuner ? dvbTuner->IsTunedTo(Channel) : false; } +bool cDvbDevice::MaySwitchTransponder(const cChannel *Channel) const +{ + return BondingOk(Channel, true) && cDevice::MaySwitchTransponder(Channel); +} + bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) { if (dvbTuner) - dvbTuner->Set(Channel); + dvbTuner->SetChannel(Channel); return true; } @@ -1156,6 +1448,17 @@ bool cDvbDevice::GetTSPacket(uchar *&Data) return false; } +void cDvbDevice::DetachAllReceivers(void) +{ + cMutexLock MutexLock(&bondMutex); + cDvbDevice *d = this; + do { + d->cDevice::DetachAllReceivers(); + d = d->bondedDevice; + } while (d && d != this && needsDetachBondedReceivers); + needsDetachBondedReceivers = false; +} + // --- cDvbDeviceProbe ------------------------------------------------------- cList<cDvbDeviceProbe> DvbDeviceProbes; diff --git a/dvbdevice.h b/dvbdevice.h index e1842b7..2072ab2 100644 --- a/dvbdevice.h +++ b/dvbdevice.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbdevice.h 2.16 2011/08/26 12:55:45 kls Exp $ + * $Id: dvbdevice.h 2.18 2011/12/04 13:38:17 kls Exp $ */ #ifndef __DVBDEVICE_H @@ -122,10 +122,40 @@ private: int numProvidedSystems; fe_delivery_system frontendType; int fd_dvr, fd_ca; + static cMutex bondMutex; + cDvbDevice *bondedDevice; + mutable bool needsDetachBondedReceivers; public: cDvbDevice(int Adapter, int Frontend); virtual ~cDvbDevice(); virtual bool Ready(void); + static bool BondDevices(const char *Bondings); + ///< Bonds the devices as defined in the given Bondings string. + ///< A bonding is a sequence of device numbers (starting at 1), + ///< separated by '+' characters. Several bondings are separated by + ///< commas, as in "1+2,3+4+5". + ///< Returns false if an error occurred. + static void UnBondDevices(void); + ///< Unbonds all devices. + bool Bond(cDvbDevice *Device); + ///< Bonds this device with the given Device, making both of them use + ///< the same satellite cable and LNB. Only DVB-S(2) devices can be + ///< bonded. When this function is called, the calling device must + ///< not be bonded to any other device. The given Device, however, + ///< may already be bonded to an other device. That way several devices + ///< can be bonded together. + ///< Returns true if the bonding was successful. + void UnBond(void); + ///< Removes this device from any bonding it might have with other + ///< devices. If this device is not bonded with any other device, + ///< nothing happens. + bool BondingOk(const cChannel *Channel, bool ConsiderOccupied = false) const; + ///< Returns true if this device is either not bonded to any other + ///< device, or the given Channel is on the same satellite, polarization + ///< and band as those the bonded devices are tuned to (if any). + ///< If ConsiderOccupied is true, any bonded devices that are currently + ///< occupied but not otherwise receiving will cause this function to + ///< return false. // Common Interface facilities: @@ -145,7 +175,8 @@ public: virtual int SignalStrength(void) const; virtual int SignalQuality(void) const; virtual const cChannel *GetCurrentlyTunedTransponder(void) const; - virtual bool IsTunedToTransponder(const cChannel *Channel); + virtual bool IsTunedToTransponder(const cChannel *Channel) const; + virtual bool MaySwitchTransponder(const cChannel *Channel) const; protected: virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView); public: @@ -172,7 +203,7 @@ public: protected: static int setTransferModeForDolbyDigital; public: - static void SetTransferModeForDolbyDigital(int Mode); // needs to be here for backwards compatibilty + static void SetTransferModeForDolbyDigital(int Mode); // needs to be here for backwards compatibility ///< Controls how the DVB device handles Transfer Mode when replaying ///< Dolby Digital audio. ///< 0 = don't set "audio bypass" in driver/firmware, don't force Transfer Mode @@ -187,6 +218,7 @@ protected: virtual bool OpenDvr(void); virtual void CloseDvr(void); virtual bool GetTSPacket(uchar *&Data); + virtual void DetachAllReceivers(void); }; // A plugin that implements a DVB device derived from cDvbDevice needs to create diff --git a/dvbsubtitle.c b/dvbsubtitle.c index 43d072d..272950f 100644 --- a/dvbsubtitle.c +++ b/dvbsubtitle.c @@ -7,7 +7,7 @@ * Original author: Marco Schller <marco@lordzodiac.de> * With some input from the "subtitle plugin" by Pekka Virtanen <pekka.virtanen@sci.fi> * - * $Id: dvbsubtitle.c 2.18 2011/08/13 13:33:00 kls Exp $ + * $Id: dvbsubtitle.c 2.20 2011/09/18 11:23:15 kls Exp $ */ @@ -15,13 +15,18 @@ #define __STDC_FORMAT_MACROS // Required for format specifiers #include <inttypes.h> #include "device.h" +#include "libsi/si.h" -#define PAGE_COMPOSITION_SEGMENT 0x10 -#define REGION_COMPOSITION_SEGMENT 0x11 -#define CLUT_DEFINITION_SEGMENT 0x12 -#define OBJECT_DATA_SEGMENT 0x13 -#define DISPLAY_DEFINITION_SEGMENT 0x14 -#define END_OF_DISPLAY_SET_SEGMENT 0x80 +//#define FINISHPAGE_HACK + +#define PAGE_COMPOSITION_SEGMENT 0x10 +#define REGION_COMPOSITION_SEGMENT 0x11 +#define CLUT_DEFINITION_SEGMENT 0x12 +#define OBJECT_DATA_SEGMENT 0x13 +#define DISPLAY_DEFINITION_SEGMENT 0x14 +#define DISPARITY_SIGNALING_SEGMENT 0x15 // DVB BlueBook A156 +#define END_OF_DISPLAY_SET_SEGMENT 0x80 +#define STUFFING_SEGMENT 0xFF // Set these to 'true' for debug output: static bool DebugConverter = false; @@ -61,8 +66,68 @@ cSubtitleClut::cSubtitleClut(int ClutId) ,palette4(4) ,palette8(8) { + int a = 0, r = 0, g = 0, b = 0; clutId = ClutId; version = -1; + // ETSI EN 300 743 10.3: 4-entry CLUT default contents + palette2.SetColor(0, ArgbToColor( 0, 0, 0, 0)); + palette2.SetColor(1, ArgbToColor(255, 255, 255, 255)); + palette2.SetColor(2, ArgbToColor(255, 0, 0, 0)); + palette2.SetColor(3, ArgbToColor(255, 127, 127, 127)); + // ETSI EN 300 743 10.2: 16-entry CLUT default contents + palette4.SetColor(0, ArgbToColor(0, 0, 0, 0)); + for (int i = 1; i < 16; ++i) { + if (i < 8) { + r = (i & 1) ? 255 : 0; + g = (i & 2) ? 255 : 0; + b = (i & 4) ? 255 : 0; + } + else { + r = (i & 1) ? 127 : 0; + g = (i & 2) ? 127 : 0; + b = (i & 4) ? 127 : 0; + } + palette4.SetColor(i, ArgbToColor(255, r, g, b)); + } + // ETSI EN 300 743 10.1: 256-entry CLUT default contents + palette8.SetColor(0, ArgbToColor(0, 0, 0, 0)); + for (int i = 1; i < 256; ++i) { + if (i < 8) { + r = (i & 1) ? 255 : 0; + g = (i & 2) ? 255 : 0; + b = (i & 4) ? 255 : 0; + a = 63; + } + else { + switch (i & 0x88) { + case 0x00: + r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0); + g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0); + b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0); + a = 255; + break; + case 0x08: + r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0); + g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0); + b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0); + a = 127; + break; + case 0x80: + r = 127 + ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0); + g = 127 + ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0); + b = 127 + ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0); + a = 255; + break; + case 0x88: + r = ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0); + g = ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0); + b = ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0); + a = 255; + break; + } + } + palette8.SetColor(i, ArgbToColor(a, r, g, b)); + } } void cSubtitleClut::SetColor(int Bpp, int Index, tColor Color) @@ -94,29 +159,33 @@ private: int version; int codingMethod; bool nonModifyingColorFlag; - int nibblePos; - uchar backgroundColor; - uchar foregroundColor; + uchar backgroundPixelCode; + uchar foregroundPixelCode; int providerFlag; int px; int py; cBitmap *bitmap; + char textData[Utf8BufSize(256)]; // number of character codes is an 8-bit field void DrawLine(int x, int y, tIndex Index, int Length); - uchar Get2Bits(const uchar *Data, int &Index); - uchar Get4Bits(const uchar *Data, int &Index); - bool Decode2BppCodeString(const uchar *Data, int &Index, int&x, int y); - bool Decode4BppCodeString(const uchar *Data, int &Index, int&x, int y); - bool Decode8BppCodeString(const uchar *Data, int &Index, int&x, int y); + bool Decode2BppCodeString(cBitStream *bs, int&x, int y, const uint8_t *MapTable); + bool Decode4BppCodeString(cBitStream *bs, int&x, int y, const uint8_t *MapTable); + bool Decode8BppCodeString(cBitStream *bs, int&x, int y); public: cSubtitleObject(int ObjectId, cBitmap *Bitmap); int ObjectId(void) { return objectId; } int Version(void) { return version; } int CodingMethod(void) { return codingMethod; } + uchar BackgroundPixelCode(void) { return backgroundPixelCode; } + uchar ForegroundPixelCode(void) { return foregroundPixelCode; } + const char *TextData(void) { return &textData[0]; } + int X(void) { return px; } + int Y(void) { return py; } bool NonModifyingColorFlag(void) { return nonModifyingColorFlag; } + void DecodeCharacterString(const uchar *Data, int NumberOfCodes); void DecodeSubBlock(const uchar *Data, int Length, bool Even); void SetVersion(int Version) { version = Version; } - void SetBackgroundColor(uchar BackgroundColor) { backgroundColor = BackgroundColor; } - void SetForegroundColor(uchar ForegroundColor) { foregroundColor = ForegroundColor; } + void SetBackgroundPixelCode(uchar BackgroundPixelCode) { backgroundPixelCode = BackgroundPixelCode; } + void SetForegroundPixelCode(uchar ForegroundPixelCode) { foregroundPixelCode = ForegroundPixelCode; } void SetNonModifyingColorFlag(bool NonModifyingColorFlag) { nonModifyingColorFlag = NonModifyingColorFlag; } void SetCodingMethod(int CodingMethod) { codingMethod = CodingMethod; } void SetPosition(int x, int y) { px = x; py = y; } @@ -129,59 +198,105 @@ cSubtitleObject::cSubtitleObject(int ObjectId, cBitmap *Bitmap) version = -1; codingMethod = -1; nonModifyingColorFlag = false; - nibblePos = 0; - backgroundColor = 0; - foregroundColor = 0; + backgroundPixelCode = 0; + foregroundPixelCode = 0; providerFlag = -1; px = py = 0; bitmap = Bitmap; + memset(textData, 0, sizeof(textData)); +} + +void cSubtitleObject::DecodeCharacterString(const uchar *Data, int NumberOfCodes) +{ + if (NumberOfCodes > 0) { + bool singleByte; + const uchar *from = &Data[1]; + int len = NumberOfCodes * 2 - 1; + cCharSetConv conv(SI::getCharacterTable(from, len, &singleByte)); + if (singleByte) { + char txt[NumberOfCodes + 1]; + char *p = txt; + for (int i = 2; i < NumberOfCodes; ++i) { + char c = Data[i * 2 + 1] & 0xFF; + if (c == 0) + break; + if (' ' <= c && c <= '~' || c == '\n' || 0xA0 <= c) + *(p++) = c; + else if (c == 0x8A) + *(p++) = '\n'; + } + *p = 0; + const char *s = conv.Convert(txt); + Utf8Strn0Cpy(textData, s, Utf8StrLen(s)); + } + else { + // TODO: add proper multibyte support for "UTF-16", "EUC-KR", "GB2312", "GBK", "UTF-8" + } + } } void cSubtitleObject::DecodeSubBlock(const uchar *Data, int Length, bool Even) { int x = 0; int y = Even ? 0 : 1; - for (int index = 0; index < Length; ) { - switch (Data[index++]) { - case 0x10: { - nibblePos = 8; - while (Decode2BppCodeString(Data, index, x, y) && index < Length) - ; - if (!nibblePos) - index++; - break; - } - case 0x11: { - nibblePos = 4; - while (Decode4BppCodeString(Data, index, x, y) && index < Length) - ; - if (!nibblePos) - index++; - break; - } - case 0x12: - while (Decode8BppCodeString(Data, index, x, y) && index < Length) - ; - break; - case 0x20: //TODO - dbgobjects("sub block 2 to 4 map\n"); - index += 4; - break; - case 0x21: //TODO - dbgobjects("sub block 2 to 8 map\n"); - index += 4; - break; - case 0x22: //TODO - dbgobjects("sub block 4 to 8 map\n"); - index += 16; - break; - case 0xF0: - x = 0; - y += 2; - break; - default: dbgobjects("unknown sub block %s %d\n", __FUNCTION__, __LINE__); + uint8_t map2to4[ 4] = { 0x00, 0x07, 0x08, 0x0F }; + uint8_t map2to8[ 4] = { 0x00, 0x77, 0x88, 0xFF }; + uint8_t map4to8[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }; + const uint8_t *mapTable = NULL; + cBitStream bs(Data, Length * 8); + while (!bs.IsEOF()) { + switch (bs.GetBits(8)) { + case 0x10: + dbgobjects("2-bit / pixel code string\n"); + switch (bitmap->Bpp()) { + case 8: mapTable = map2to8; break; + case 4: mapTable = map2to4; break; + default: mapTable = NULL; break; + } + while (Decode2BppCodeString(&bs, x, y, mapTable) && !bs.IsEOF()) + ; + bs.ByteAlign(); + break; + case 0x11: + dbgobjects("4-bit / pixel code string\n"); + switch (bitmap->Bpp()) { + case 8: mapTable = map4to8; break; + default: mapTable = NULL; break; + } + while (Decode4BppCodeString(&bs, x, y, mapTable) && !bs.IsEOF()) + ; + bs.ByteAlign(); + break; + case 0x12: + dbgobjects("8-bit / pixel code string\n"); + while (Decode8BppCodeString(&bs, x, y) && !bs.IsEOF()) + ; + break; + case 0x20: + dbgobjects("sub block 2 to 4 map\n"); + map2to4[0] = bs.GetBits(4); + map2to4[1] = bs.GetBits(4); + map2to4[2] = bs.GetBits(4); + map2to4[3] = bs.GetBits(4); + break; + case 0x21: + dbgobjects("sub block 2 to 8 map\n"); + for (int i = 0; i < 4; ++i) + map2to8[i] = bs.GetBits(8); + break; + case 0x22: + dbgobjects("sub block 4 to 8 map\n"); + for (int i = 0; i < 16; ++i) + map4to8[i] = bs.GetBits(8); + break; + case 0xF0: + dbgobjects("end of object line\n"); + x = 0; + y += 2; + break; + default: dbgobjects("unknown sub block %s %d\n", __FUNCTION__, __LINE__); + } } - } } void cSubtitleObject::DrawLine(int x, int y, tIndex Index, int Length) @@ -194,136 +309,110 @@ void cSubtitleObject::DrawLine(int x, int y, tIndex Index, int Length) bitmap->SetIndex(pos, y, Index); } -uchar cSubtitleObject::Get2Bits(const uchar *Data, int &Index) -{ - uchar result = Data[Index]; - if (!nibblePos) { - Index++; - nibblePos = 8; - } - nibblePos -= 2; - return (result >> nibblePos) & 0x03; -} - -uchar cSubtitleObject::Get4Bits(const uchar *Data, int &Index) -{ - uchar result = Data[Index]; - if (!nibblePos) { - Index++; - nibblePos = 4; - } - else { - result >>= 4; - nibblePos -= 4; - } - return result & 0x0F; -} - -bool cSubtitleObject::Decode2BppCodeString(const uchar *Data, int &Index, int &x, int y) +bool cSubtitleObject::Decode2BppCodeString(cBitStream *bs, int &x, int y, const uint8_t *MapTable) { int rl = 0; int color = 0; - uchar code = Get2Bits(Data, Index); + uchar code = bs->GetBits(2); if (code) { color = code; rl = 1; } + else if (bs->GetBit()) { // switch_1 + rl = bs->GetBits(3) + 3; + color = bs->GetBits(2); + } + else if (bs->GetBit()) // switch_2 + rl = 1; //color 0 else { - code = Get2Bits(Data, Index); - if (code & 2) { // switch_1 - rl = ((code & 1) << 2) + Get2Bits(Data, Index) + 3; - color = Get2Bits(Data, Index); - } - else if (code & 1) - rl = 1; //color 0 - else { - code = Get2Bits(Data, Index); - switch (code & 3) { //switch_3 - case 0: - return false; - case 1: - rl = 2; //color 0 - break; - case 2: - rl = (Get2Bits(Data, Index) << 2) + Get2Bits(Data, Index) + 12; - color = Get2Bits(Data, Index); - break; - case 3: - rl = (Get2Bits(Data, Index) << 6) + (Get2Bits(Data, Index) << 4) + (Get2Bits(Data, Index) << 2) + Get2Bits(Data, Index) + 29; - color = Get2Bits(Data, Index); - break; - default: ; - } - } + switch (bs->GetBits(2)) { // switch_3 + case 0: + return false; + case 1: + rl = 2; //color 0 + break; + case 2: + rl = bs->GetBits(4) + 12; + color = bs->GetBits(2); + break; + case 3: + rl = bs->GetBits(8) + 29; + color = bs->GetBits(2); + break; + default: ; + } } + if (MapTable) + color = MapTable[color]; DrawLine(x, y, color, rl); x += rl; return true; } -bool cSubtitleObject::Decode4BppCodeString(const uchar *Data, int &Index, int &x, int y) +bool cSubtitleObject::Decode4BppCodeString(cBitStream *bs, int &x, int y, const uint8_t *MapTable) { int rl = 0; int color = 0; - uchar code = Get4Bits(Data, Index); + uchar code = bs->GetBits(4); if (code) { color = code; rl = 1; } + else if (bs->GetBit() == 0) { // switch_1 + code = bs->GetBits(3); + if (code) + rl = code + 2; //color 0 + else + return false; + } + else if (bs->GetBit() == 0) { // switch_2 + rl = bs->GetBits(2) + 4; + color = bs->GetBits(4); + } else { - code = Get4Bits(Data, Index); - if (code & 8) { // switch_1 - if (code & 4) { //switch_2 - switch (code & 3) { //switch_3 - case 0: // color 0 - rl = 1; - break; - case 1: // color 0 - rl = 2; - break; - case 2: - rl = Get4Bits(Data, Index) + 9; - color = Get4Bits(Data, Index); - break; - case 3: - rl = (Get4Bits(Data, Index) << 4) + Get4Bits(Data, Index) + 25; - color = Get4Bits(Data, Index); - break; - default: ; - } - } - else { - rl = (code & 3) + 4; - color = Get4Bits(Data, Index); - } - } - else { // color 0 - if (!code) - return false; - rl = code + 2; - } + switch (bs->GetBits(2)) { // switch_3 + case 0: // color 0 + rl = 1; + break; + case 1: // color 0 + rl = 2; + break; + case 2: + rl = bs->GetBits(4) + 9; + color = bs->GetBits(4); + break; + case 3: + rl = bs->GetBits(8) + 25; + color = bs->GetBits(4); + break; + } } + if (MapTable) + color = MapTable[color]; DrawLine(x, y, color, rl); x += rl; return true; } -bool cSubtitleObject::Decode8BppCodeString(const uchar *Data, int &Index, int &x, int y) +bool cSubtitleObject::Decode8BppCodeString(cBitStream *bs, int &x, int y) { int rl = 0; int color = 0; - uchar code = Data[Index++]; + uchar code = bs->GetBits(8); if (code) { color = code; rl = 1; } + else if (bs->GetBit()) { + rl = bs->GetBits(7); + color = bs->GetBits(8); + } else { - code = Data[Index++]; - rl = code & 0x63; - if (code & 0x80) - color = Data[Index++]; - else if (!rl) - return false; //else color 0 + code = bs->GetBits(7); + if (code) + rl = code; // color 0 + else + return false; } DrawLine(x, y, color, rl); x += rl; @@ -340,6 +429,7 @@ private: int horizontalAddress; int verticalAddress; int level; + int lineHeight; cList<cSubtitleObject> objects; public: cSubtitleRegion(int RegionId); @@ -358,6 +448,7 @@ public: void SetDepth(int Depth); void SetHorizontalAddress(int HorizontalAddress) { horizontalAddress = HorizontalAddress; } void SetVerticalAddress(int VerticalAddress) { verticalAddress = VerticalAddress; } + void UpdateTextData(cSubtitleClut *Clut); }; cSubtitleRegion::cSubtitleRegion(int RegionId) @@ -369,6 +460,7 @@ cSubtitleRegion::cSubtitleRegion(int RegionId) horizontalAddress = 0; verticalAddress = 0; level = 0; + lineHeight = 26; // configurable subtitling font size } void cSubtitleRegion::FillRegion(tIndex Index) @@ -394,6 +486,22 @@ cSubtitleObject *cSubtitleRegion::GetObjectById(int ObjectId, bool New) return result; } +void cSubtitleRegion::UpdateTextData(cSubtitleClut *Clut) +{ + const cPalette *palette = Clut ? Clut->GetPalette(Depth()) : NULL; + for (cSubtitleObject *so = objects.First(); so && palette; so = objects.Next(so)) { + if (Utf8StrLen(so->TextData()) > 0) { + const cFont *font = cFont::GetFont(fontOsd); + cBitmap *tmp = new cBitmap(font->Width(so->TextData()), font->Height(), Depth()); + double factor = (double)lineHeight / font->Height(); + tmp->DrawText(0, 0, so->TextData(), palette->Color(so->ForegroundPixelCode()), palette->Color(so->BackgroundPixelCode()), font); + tmp = tmp->Scaled(factor, factor, true); + DrawBitmap(so->X(), so->Y(), *tmp); + DELETENULL(tmp); + } + } +} + void cSubtitleRegion::SetLevel(int Level) { if (Level > 0 && Level < 4) @@ -887,7 +995,7 @@ void cDvbSubtitleConverter::SetOsdData(void) double VideoAspect; cDevice::PrimaryDevice()->GetOsdSize(OsdWidth, OsdHeight, OsdAspect); cDevice::PrimaryDevice()->GetVideoSize(VideoWidth, VideoHeight, VideoAspect); - if (OsdWidth == displayWidth && OsdHeight == displayHeight) { + if (OsdWidth == displayWidth && OsdHeight == displayHeight || VideoWidth == 0) { osdFactorX = osdFactorY = 1.0; osdDeltaX = osdDeltaY = 0; } @@ -907,12 +1015,15 @@ bool cDvbSubtitleConverter::AssertOsd(void) int cDvbSubtitleConverter::ExtractSegment(const uchar *Data, int Length, int64_t Pts) { - if (Length > 5 && Data[0] == 0x0F) { - int segmentLength = (Data[4] << 8) + Data[5] + 6; - if (segmentLength > Length) + cBitStream bs(Data, Length * 8); + if (Length > 5 && bs.GetBits(8) == 0x0F) { // sync byte + int segmentType = bs.GetBits(8); + if (segmentType == STUFFING_SEGMENT) + return -1; + int pageId = bs.GetBits(16); + int segmentLength = bs.GetBits(16); + if (!bs.SetLength(bs.Index() + segmentLength * 8)) return -1; - int segmentType = Data[1]; - int pageId = (Data[2] << 8) + Data[3]; cDvbSubtitlePage *page = NULL; LOCK_THREAD; for (cDvbSubtitlePage *sp = pages->First(); sp; sp = pages->Next(sp)) { @@ -931,154 +1042,170 @@ int cDvbSubtitleConverter::ExtractSegment(const uchar *Data, int Length, int64_t switch (segmentType) { case PAGE_COMPOSITION_SEGMENT: { dbgsegments("PAGE_COMPOSITION_SEGMENT\n"); - int pageVersion = (Data[6 + 1] & 0xF0) >> 4; + int pageTimeout = bs.GetBits(8); + int pageVersion = bs.GetBits(4); if (pageVersion == page->Version()) break; // no update page->SetVersion(pageVersion); - page->SetTimeout(Data[6]); - page->SetState((Data[6 + 1] & 0x0C) >> 2); + page->SetTimeout(pageTimeout); + page->SetState(bs.GetBits(2)); page->regions.Clear(); + bs.SkipBits(2); // reserved dbgpages("Update page id %d version %d pts %"PRId64" timeout %d state %d\n", pageId, page->Version(), page->Pts(), page->Timeout(), page->State()); - for (int i = 6 + 2; i < segmentLength; i += 6) { - cSubtitleRegion *region = page->GetRegionById(Data[i], true); - region->SetHorizontalAddress((Data[i + 2] << 8) + Data[i + 3]); - region->SetVerticalAddress((Data[i + 4] << 8) + Data[i + 5]); - } + while (!bs.IsEOF()) { + cSubtitleRegion *region = page->GetRegionById(bs.GetBits(8), true); + bs.SkipBits(8); // reserved + region->SetHorizontalAddress(bs.GetBits(16)); + region->SetVerticalAddress(bs.GetBits(16)); + } break; } case REGION_COMPOSITION_SEGMENT: { dbgsegments("REGION_COMPOSITION_SEGMENT\n"); - cSubtitleRegion *region = page->GetRegionById(Data[6]); + cSubtitleRegion *region = page->GetRegionById(bs.GetBits(8)); if (!region) break; - int regionVersion = (Data[6 + 1] & 0xF0) >> 4; + int regionVersion = bs.GetBits(4); if (regionVersion == region->Version()) break; // no update region->SetVersion(regionVersion); - bool regionFillFlag = (Data[6 + 1] & 0x08) >> 3; - int regionWidth = (Data[6 + 2] << 8) | Data[6 + 3]; + bool regionFillFlag = bs.GetBit(); + bs.SkipBits(3); // reserved + int regionWidth = bs.GetBits(16); if (regionWidth < 1) regionWidth = 1; - int regionHeight = (Data[6 + 4] << 8) | Data[6 + 5]; + int regionHeight = bs.GetBits(16); if (regionHeight < 1) regionHeight = 1; region->SetSize(regionWidth, regionHeight); - region->SetLevel((Data[6 + 6] & 0xE0) >> 5); - region->SetDepth((Data[6 + 6] & 0x1C) >> 2); - region->SetClutId(Data[6 + 7]); + region->SetLevel(bs.GetBits(3)); + region->SetDepth(bs.GetBits(3)); + bs.SkipBits(2); // reserved + region->SetClutId(bs.GetBits(8)); dbgregions("Region pageId %d id %d version %d fill %d width %d height %d level %d depth %d clutId %d\n", pageId, region->RegionId(), region->Version(), regionFillFlag, regionWidth, regionHeight, region->Level(), region->Depth(), region->ClutId()); + int region8bitPixelCode = bs.GetBits(8); + int region4bitPixelCode = bs.GetBits(4); + int region2bitPixelCode = bs.GetBits(2); + bs.SkipBits(2); // reserved if (regionFillFlag) { switch (region->Bpp()) { - case 2: region->FillRegion((Data[6 + 9] & 0x0C) >> 2); break; - case 4: region->FillRegion((Data[6 + 9] & 0xF0) >> 4); break; - case 8: region->FillRegion(Data[6 + 8]); break; + case 2: region->FillRegion(region8bitPixelCode); break; + case 4: region->FillRegion(region4bitPixelCode); break; + case 8: region->FillRegion(region2bitPixelCode); break; default: dbgregions("unknown bpp %d (%s %d)\n", region->Bpp(), __FUNCTION__, __LINE__); } } - for (int i = 6 + 10; i < segmentLength; i += 6) { - cSubtitleObject *object = region->GetObjectById((Data[i] << 8) | Data[i + 1], true); - int objectType = (Data[i + 2] & 0xC0) >> 6; - object->SetCodingMethod(objectType); - object->SetProviderFlag((Data[i + 2] & 0x30) >> 4); - int objectHorizontalPosition = ((Data[i + 2] & 0x0F) << 8) | Data[i + 3]; - int objectVerticalPosition = ((Data[i + 4] & 0x0F) << 8) | Data[i + 5]; - object->SetPosition(objectHorizontalPosition, objectVerticalPosition); - if (objectType == 0x01 || objectType == 0x02) { - object->SetForegroundColor(Data[i + 6]); - object->SetBackgroundColor(Data[i + 7]); - i += 2; - } - } + while (!bs.IsEOF()) { + cSubtitleObject *object = region->GetObjectById(bs.GetBits(16), true); + int objectType = bs.GetBits(2); + object->SetCodingMethod(objectType); + object->SetProviderFlag(bs.GetBits(2)); + int objectHorizontalPosition = bs.GetBits(12); + bs.SkipBits(4); // reserved + int objectVerticalPosition = bs.GetBits(12); + object->SetPosition(objectHorizontalPosition, objectVerticalPosition); + if (objectType == 0x01 || objectType == 0x02) { + object->SetForegroundPixelCode(bs.GetBits(8)); + object->SetBackgroundPixelCode(bs.GetBits(8)); + } + } break; } case CLUT_DEFINITION_SEGMENT: { dbgsegments("CLUT_DEFINITION_SEGMENT\n"); - cSubtitleClut *clut = page->GetClutById(Data[6], true); - int clutVersion = (Data[6 + 1] & 0xF0) >> 4; + cSubtitleClut *clut = page->GetClutById(bs.GetBits(8), true); + int clutVersion = bs.GetBits(4); if (clutVersion == clut->Version()) break; // no update clut->SetVersion(clutVersion); + bs.SkipBits(4); // reserved dbgcluts("Clut pageId %d id %d version %d\n", pageId, clut->ClutId(), clut->Version()); - for (int i = 6 + 2; i < segmentLength; i += 2) { - uchar clutEntryId = Data[i]; - bool fullRangeFlag = Data[i + 1] & 1; - uchar yval; - uchar crval; - uchar cbval; - uchar tval; - if (fullRangeFlag) { - yval = Data[i + 2]; - crval = Data[i + 3]; - cbval = Data[i + 4]; - tval = Data[i + 5]; - } - else { - yval = Data[i + 2] & 0xFC; - crval = (Data[i + 2] & 0x03) << 6; - crval |= (Data[i + 3] & 0xC0) >> 2; - cbval = (Data[i + 3] & 0x3C) << 2; - tval = (Data[i + 3] & 0x03) << 6; - } - tColor value = 0; - if (yval) { - value = yuv2rgb(yval, cbval, crval); - value |= ((10 - (clutEntryId ? Setup.SubtitleFgTransparency : Setup.SubtitleBgTransparency)) * (255 - tval) / 10) << 24; - } - int EntryFlags = Data[i + 1]; - dbgcluts("%2d %d %d %d %08X\n", clutEntryId, (EntryFlags & 0x80) ? 2 : 0, (EntryFlags & 0x40) ? 4 : 0, (EntryFlags & 0x20) ? 8 : 0, value); - if ((EntryFlags & 0x80) != 0) - clut->SetColor(2, clutEntryId, value); - if ((EntryFlags & 0x40) != 0) - clut->SetColor(4, clutEntryId, value); - if ((EntryFlags & 0x20) != 0) - clut->SetColor(8, clutEntryId, value); - i += fullRangeFlag ? 4 : 2; - } + while (!bs.IsEOF()) { + uchar clutEntryId = bs.GetBits(8); + bool entryClut2Flag = bs.GetBit(); + bool entryClut4Flag = bs.GetBit(); + bool entryClut8Flag = bs.GetBit(); + bs.SkipBits(4); // reserved + uchar yval; + uchar crval; + uchar cbval; + uchar tval; + if (bs.GetBit()) { // full_range_flag + yval = bs.GetBits(8); + crval = bs.GetBits(8); + cbval = bs.GetBits(8); + tval = bs.GetBits(8); + } + else { + yval = bs.GetBits(6) << 2; + crval = bs.GetBits(4) << 4; + cbval = bs.GetBits(4) << 4; + tval = bs.GetBits(2) << 6; + } + tColor value = 0; + if (yval) { + value = yuv2rgb(yval, cbval, crval); + value |= ((10 - (clutEntryId ? Setup.SubtitleFgTransparency : Setup.SubtitleBgTransparency)) * (255 - tval) / 10) << 24; + } + dbgcluts("%2d %d %d %d %08X\n", clutEntryId, entryClut2Flag ? 2 : 0, entryClut4Flag ? 4 : 0, entryClut8Flag ? 8 : 0, value); + if (entryClut2Flag) + clut->SetColor(2, clutEntryId, value); + if (entryClut4Flag) + clut->SetColor(4, clutEntryId, value); + if (entryClut8Flag) + clut->SetColor(8, clutEntryId, value); + } dbgcluts("\n"); page->UpdateRegionPalette(clut); break; } case OBJECT_DATA_SEGMENT: { dbgsegments("OBJECT_DATA_SEGMENT\n"); - cSubtitleObject *object = page->GetObjectById((Data[6] << 8) | Data[6 + 1]); + cSubtitleObject *object = page->GetObjectById(bs.GetBits(16)); if (!object) break; - int objectVersion = (Data[6 + 2] & 0xF0) >> 4; + int objectVersion = bs.GetBits(4); if (objectVersion == object->Version()) break; // no update object->SetVersion(objectVersion); - int codingMethod = (Data[6 + 2] & 0x0C) >> 2; - object->SetNonModifyingColorFlag(Data[6 + 2] & 0x01); + int codingMethod = bs.GetBits(2); + object->SetNonModifyingColorFlag(bs.GetBit()); + bs.SkipBit(); // reserved dbgobjects("Object pageId %d id %d version %d method %d modify %d\n", pageId, object->ObjectId(), object->Version(), object->CodingMethod(), object->NonModifyingColorFlag()); if (codingMethod == 0) { // coding of pixels - int i = 6 + 3; - int topFieldLength = (Data[i] << 8) | Data[i + 1]; - int bottomFieldLength = (Data[i + 2] << 8) | Data[i + 3]; - object->DecodeSubBlock(Data + i + 4, topFieldLength, true); + int topFieldLength = bs.GetBits(16); + int bottomFieldLength = bs.GetBits(16); + object->DecodeSubBlock(bs.GetData(), topFieldLength, true); if (bottomFieldLength) - object->DecodeSubBlock(Data + i + 4 + topFieldLength, bottomFieldLength, false); + object->DecodeSubBlock(bs.GetData() + topFieldLength, bottomFieldLength, false); else - object->DecodeSubBlock(Data + i + 4, topFieldLength, false); + object->DecodeSubBlock(bs.GetData(), topFieldLength, false); + bs.WordAlign(); } else if (codingMethod == 1) { // coded as a string of characters - //TODO implement textual subtitles + int numberOfCodes = bs.GetBits(8); + object->DecodeCharacterString(bs.GetData(), numberOfCodes); } +#ifdef FINISHPAGE_HACK + FinishPage(page); // flush to OSD right away +#endif break; } case DISPLAY_DEFINITION_SEGMENT: { dbgsegments("DISPLAY_DEFINITION_SEGMENT\n"); - int version = (Data[6] & 0xF0) >> 4; + int version = bs.GetBits(4); if (version != ddsVersionNumber) { - int displayWindowFlag = (Data[6] & 0x08) >> 3; + bool displayWindowFlag = bs.GetBit(); windowHorizontalOffset = 0; windowVerticalOffset = 0; - displayWidth = windowWidth = ((Data[7] << 8) | Data[8]) + 1; - displayHeight = windowHeight = ((Data[9] << 8) | Data[10]) + 1; - if (displayWindowFlag) { - windowHorizontalOffset = (Data[11] << 8) | Data[12]; // displayWindowHorizontalPositionMinimum - windowWidth = ((Data[13] << 8) | Data[14]) - windowHorizontalOffset + 1; // displayWindowHorizontalPositionMaximum - windowVerticalOffset = (Data[15] << 8) | Data[16]; // displayWindowVerticalPositionMinimum - windowHeight = ((Data[17] << 8) | Data[18]) - windowVerticalOffset + 1; // displayWindowVerticalPositionMaximum + bs.SkipBits(3); // reserved + displayWidth = windowWidth = bs.GetBits(16) + 1; + displayHeight = windowHeight = bs.GetBits(16) + 1; + if (displayWindowFlag) { + windowHorizontalOffset = bs.GetBits(16); // displayWindowHorizontalPositionMinimum + windowWidth = bs.GetBits(16) - windowHorizontalOffset + 1; // displayWindowHorizontalPositionMaximum + windowVerticalOffset = bs.GetBits(16); // displayWindowVerticalPositionMinimum + windowHeight = bs.GetBits(16) - windowVerticalOffset + 1; // displayWindowVerticalPositionMaximum } SetOsdData(); SetupChanged(); @@ -1086,15 +1213,56 @@ int cDvbSubtitleConverter::ExtractSegment(const uchar *Data, int Length, int64_t } break; } + case DISPARITY_SIGNALING_SEGMENT: { + dbgsegments("DISPARITY_SIGNALING_SEGMENT\n"); + bs.SkipBits(4); // dss_version_number + bool disparity_shift_update_sequence_page_flag = bs.GetBit(); + bs.SkipBits(3); // reserved + bs.SkipBits(8); // page_default_disparity_shift + if (disparity_shift_update_sequence_page_flag) { + bs.SkipBits(8); // disparity_shift_update_sequence_length + bs.SkipBits(24); // interval_duration[23..0] + int division_period_count = bs.GetBits(8); + for (int i = 0; i < division_period_count; ++i) { + bs.SkipBits(8); // interval_count + bs.SkipBits(8); // disparity_shift_update_integer_part + } + } + while (!bs.IsEOF()) { + bs.SkipBits(8); // region_id + bool disparity_shift_update_sequence_region_flag = bs.GetBit(); + bs.SkipBits(5); // reserved + int number_of_subregions_minus_1 = bs.GetBits(2); + for (int i = 0; i <= number_of_subregions_minus_1; ++i) { + if (number_of_subregions_minus_1 > 0) { + bs.SkipBits(16); // subregion_horizontal_position + bs.SkipBits(16); // subregion_width + } + bs.SkipBits(8); // subregion_disparity_shift_integer_part + bs.SkipBits(4); // subregion_disparity_shift_fractional_part + bs.SkipBits(4); // reserved + if (disparity_shift_update_sequence_region_flag) { + bs.SkipBits(8); // disparity_shift_update_sequence_length + bs.SkipBits(24); // interval_duration[23..0] + int division_period_count = bs.GetBits(8); + for (int i = 0; i < division_period_count; ++i) { + bs.SkipBits(8); // interval_count + bs.SkipBits(8); // disparity_shift_update_integer_part + } + } + } + } + break; + } case END_OF_DISPLAY_SET_SEGMENT: { dbgsegments("END_OF_DISPLAY_SET_SEGMENT\n"); FinishPage(page); - } break; + } default: dbgsegments("*** unknown segment type: %02X\n", segmentType); } - return segmentLength; + return bs.Length() / 8; } return -1; } @@ -1143,6 +1311,7 @@ void cDvbSubtitleConverter::FinishPage(cDvbSubtitlePage *Page) cDvbSubtitleBitmaps *Bitmaps = new cDvbSubtitleBitmaps(Page->Pts(), Page->Timeout(), Areas, NumAreas, osdFactorX, osdFactorY); bitmaps->Add(Bitmaps); for (cSubtitleRegion *sr = Page->regions.First(); sr; sr = Page->regions.Next(sr)) { + sr->UpdateTextData(Page->GetClutById(sr->ClutId())); int posX = sr->HorizontalAddress(); int posY = sr->VerticalAddress(); if (sr->Width() > 0 && sr->Height() > 0) { @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: eitscan.c 2.4 2011/08/26 16:16:46 kls Exp $ + * $Id: eitscan.c 2.5 2011/09/25 14:58:55 kls Exp $ */ #include "eitscan.h" @@ -150,7 +150,7 @@ void cEITScanner::Process(void) if (!Channel->Ca() || Channel->Ca() == Device->DeviceNumber() + 1 || Channel->Ca() >= CA_ENCRYPTED_MIN) { if (Device->ProvidesTransponder(Channel)) { if (!Device->Receiving()) { - bool MaySwitchTransponder = Device->MaySwitchTransponder(); + bool MaySwitchTransponder = Device->MaySwitchTransponder(Channel); if (MaySwitchTransponder || Device->ProvidesTransponderExclusively(Channel) && now - lastActivity > Setup.EPGScanTimeout * 3600) { if (!MaySwitchTransponder) { if (Device == cDevice::ActualDevice() && !currentChannel) { @@ -7,12 +7,12 @@ # plus an 'index.htm' file. All output files are written into the current # directory. # -# Usage: epg2html.pl < /video/epg.data +# Usage: epg2html < /video/epg.data # # See the main source file 'vdr.c' for copyright information and # how to reach the author. # -# $Id: epg2html.pl 2.0 2006/04/17 12:19:08 kls Exp $ +# $Id: epg2html 2.1 2011/12/04 14:17:35 kls Exp $ @Index = (); @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: font.h 2.5 2011/01/14 16:22:03 kls Exp $ + * $Id: font.h 2.6 2011/12/04 13:38:17 kls Exp $ */ #ifndef __FONT_H @@ -51,7 +51,7 @@ public: virtual int Height(void) const = 0; ///< Returns the height of this font in pixel (all characters have the same height). int Height(const char *s) const { return Height(); } - ///< Returns the height of this font in pixel (obsolete, just for backwards compatibilty). + ///< Returns the height of this font in pixel (obsolete, just for backwards compatibility). virtual void DrawText(cBitmap *Bitmap, int x, int y, const char *s, tColor ColorFg, tColor ColorBg, int Width) const = 0; ///< Draws the given text into the Bitmap at position (x, y) with the given colors. ///< The text will not exceed the given Width (if > 0), and will end with a complete character. diff --git a/i18n-to-gettext.pl b/i18n-to-gettext index 29d9345..6932fd2 100755 --- a/i18n-to-gettext.pl +++ b/i18n-to-gettext @@ -5,12 +5,12 @@ # Extracts all texts from the file i18n.c and creates language # specific *.po files. # -# Usage: i18n-to-gettext.pl +# Usage: i18n-to-gettext # # See the main source file 'vdr.c' for copyright information and # how to reach the author. # -# $Id: i18n-to-gettext.pl 2.1 2009/10/18 14:07:49 kls Exp $ +# $Id: i18n-to-gettext 2.2 2011/12/04 14:17:35 kls Exp $ # How to convert an actual plugin: # diff --git a/interface.c b/interface.c index 64bf975..2bfa6c3 100644 --- a/interface.c +++ b/interface.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: interface.c 2.0 2008/02/10 15:49:15 kls Exp $ + * $Id: interface.c 2.1 2011/12/04 14:52:38 kls Exp $ */ #include "interface.h" @@ -79,7 +79,7 @@ bool cInterface::QueryKeys(cRemote *Remote, cSkinDisplayMenu *DisplayMenu) DisplayMenu->SetItem(tr("RC code detected!"), 4, false, false); DisplayMenu->SetItem(tr("Do not press any key..."), 5, false, false); DisplayMenu->Flush(); - sleep(3); + cCondWait::SleepMs(3000); DisplayMenu->SetItem("", 4, false, false); DisplayMenu->SetItem("", 5, false, false); diff --git a/libsi/Makefile b/libsi/Makefile index 37be2f6..b24eb31 100644 --- a/libsi/Makefile +++ b/libsi/Makefile @@ -1,7 +1,7 @@ # # Makefile for a libsi # -# $Id: Makefile 2.1 2010/11/07 13:31:05 kls Exp $ +# $Id: Makefile 2.2 2011/12/04 14:18:38 kls Exp $ ### The C++ compiler and options: @@ -52,4 +52,4 @@ clean: dist: tar cvzf libsi.tar.gz -C .. libsi/util.c libsi/si.c libsi/section.c libsi/descriptor.c \ - libsi/util.h libsi/si.h libsi/section.h libsi/descriptor.h libsi/headers.h libsi/Makefile libsi/gendescr.pl + libsi/util.h libsi/si.h libsi/section.h libsi/descriptor.h libsi/headers.h libsi/Makefile libsi/gendescr diff --git a/libsi/gendescr.pl b/libsi/gendescr index d28890f..8af5c69 100755 --- a/libsi/gendescr.pl +++ b/libsi/gendescr @@ -1,6 +1,6 @@ #!/usr/bin/perl -# $Id: gendescr.pl 2.0 2003/12/13 10:40:53 kls Exp $ +# $Id: gendescr 2.0 2003/12/13 10:40:53 kls Exp $ print "Name (ohne ...Descriptor):"; $name=<STDIN>; @@ -6,7 +6,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: si.c 2.4 2011/06/15 21:26:00 kls Exp $ + * $Id: si.c 2.5 2011/12/04 15:06:18 kls Exp $ * * ***************************************************************************/ @@ -206,6 +206,8 @@ void DescriptorGroup::Add(GroupDescriptor *d) { array[i]=0; } else if (length != d->getLastDescriptorNumber()+1) return; //avoid crash in case of misuse + if (length <= d->getDescriptorNumber()) + return; // see http://www.vdr-portal.de/board60-linux/board14-betriebssystem/board69-c-t-vdr/p1025777-segfault-mit-vdr-1-7-21/#post1025777 array[d->getDescriptorNumber()]=d; } @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.c 2.32 2011/08/27 11:05:33 kls Exp $ + * $Id: menu.c 2.34 2011/12/04 14:52:38 kls Exp $ */ #include "menu.h" @@ -2885,6 +2885,7 @@ eOSState cMenuSetupDVB::ProcessKey(eKeys Key) class cMenuSetupLNB : public cMenuSetupBase { private: + cSatCableNumbers satCableNumbers; void Setup(void); public: cMenuSetupLNB(void); @@ -2892,7 +2893,9 @@ public: }; cMenuSetupLNB::cMenuSetupLNB(void) +:satCableNumbers(MAXDEVICES) { + satCableNumbers.FromString(data.DeviceBondings); SetSection(tr("LNB")); Setup(); } @@ -2910,6 +2913,18 @@ void cMenuSetupLNB::Setup(void) Add(new cMenuEditIntItem( tr("Setup.LNB$High LNB frequency (MHz)"), &data.LnbFrequHi)); } + int NumSatDevices = 0; + for (int i = 0; i < cDevice::NumDevices(); i++) { + if (cDevice::GetDevice(i)->ProvidesSource(cSource::stSat)) + NumSatDevices++; + } + if (NumSatDevices > 1) { + for (int i = 0; i < cDevice::NumDevices(); i++) { + if (cDevice::GetDevice(i)->ProvidesSource(cSource::stSat)) + Add(new cMenuEditIntItem(cString::sprintf(tr("Setup.LNB$Device %d connected to sat cable"), i + 1), &satCableNumbers.Array()[i], 0, NumSatDevices, tr("Setup.LNB$own"))); + } + } + SetCurrent(Get(current)); Display(); } @@ -2917,10 +2932,18 @@ void cMenuSetupLNB::Setup(void) eOSState cMenuSetupLNB::ProcessKey(eKeys Key) { int oldDiSEqC = data.DiSEqC; + bool DeviceBondingsChanged = false; + if (Key == kOk) { + cString NewDeviceBondings = satCableNumbers.ToString(); + DeviceBondingsChanged = strcmp(data.DeviceBondings, NewDeviceBondings) != 0; + data.DeviceBondings = NewDeviceBondings; + } eOSState state = cMenuSetupBase::ProcessKey(Key); if (Key != kNone && data.DiSEqC != oldDiSEqC) Setup(); + else if (DeviceBondingsChanged) + cDvbDevice::BondDevices(data.DeviceBondings); return state; } @@ -4185,7 +4208,7 @@ bool cRecordControl::GetEvent(void) } if (seconds == 0) dsyslog("waiting for EPG info..."); - sleep(1); + cCondWait::SleepMs(1000); } dsyslog("no EPG info available"); return false; @@ -4295,11 +4318,11 @@ bool cRecordControls::PauseLiveVideo(void) Skins.Message(mtStatus, tr("Pausing live video...")); cReplayControl::SetRecording(NULL, NULL); // make sure the new cRecordControl will set cReplayControl::LastReplayed() if (Start(NULL, true)) { - sleep(2); // allow recorded file to fill up enough to start replaying + cCondWait::SleepMs(2000); // allow recorded file to fill up enough to start replaying cReplayControl *rc = new cReplayControl; cControl::Launch(rc); cControl::Attach(); - sleep(1); // allow device to replay some frames, so we have a picture + cCondWait::SleepMs(1000); // allow device to replay some frames, so we have a picture Skins.Message(mtStatus, NULL); rc->ProcessKey(kPause); // pause, allowing replay mode display return true; @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: osd.h 2.14 2011/08/15 09:22:50 kls Exp $ + * $Id: osd.h 2.15 2011/12/04 13:38:17 kls Exp $ */ #ifndef __OSD_H @@ -496,7 +496,7 @@ public: ///< In order to allow devices that can handle only a limited number of layers, ///< the Layer parameter must be less than 8 (MAXPIXMAPLAYERS). ///< ViewPort defines the rectangle in which this pixmap will be rendered on - ///< the OSD. If no DrawPort ist given, it defaults to the same size as the + ///< the OSD. If no DrawPort is given, it defaults to the same size as the ///< ViewPort, with its upper left corner set to (0, 0). ///< All drawing operations will be executed relative to the origin of the ///< DrawPort rectangle, and will be clipped to the size of this rectangle. @@ -566,7 +566,7 @@ public: ///< Sets the pixmap's draw port to the given Point. ///< Only the origin point of the draw port can be modified, its size is fixed. ///< By default, setting a new draw port point results in marking the relevant - ///< part of the view port as "drity". If Dirty is set to false, the view port + ///< part of the view port as "dirty". If Dirty is set to false, the view port ///< will not be marked as dirty. This is mainly used to implement the Pan() ///< function. ///< If a derived class reimplements this function, it needs to call the base @@ -701,7 +701,7 @@ public: /// reimplement all necessary cPixmap functions and do the rendering /// itself ("high level mode"). /// If an OSD provides a "high level mode", it shall also provide a "raw mode" -/// in order to verify proper operation. The plugin that impements the OSD +/// in order to verify proper operation. The plugin that implements the OSD /// shall offer a configuration switch in its setup. class cOsd { @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: pat.h 2.1 2009/06/14 11:14:00 kls Exp $ + * $Id: pat.h 2.2 2011/12/04 13:38:17 kls Exp $ */ #ifndef __PAT_H @@ -39,7 +39,7 @@ int GetCaDescriptors(int Source, int Transponder, int ServiceId, const int *CaSy ///< are copied that match one of the given CA system IDs. ///< \return Returns the number of bytes copied into Data (0 if no CA descriptors are ///< available), or -1 if BufSize was too small to hold all CA descriptors. - ///< The return value in StreamFlag tells whether these CA descriptors are to be used + ///< The return value tells whether these CA descriptors are to be used ///< for the individual streams. #endif //__PAT_H @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.7.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2011-08-27 11:54+0200\n" +"POT-Creation-Date: 2011-12-03 16:25+0100\n" "PO-Revision-Date: 2008-10-16 11:16-0400\n" "Last-Translator: Osama Alrawab <alrawab@hotmail.com>\n" "Language-Team: Arabic <ar@li.org>\n" @@ -983,6 +983,13 @@ msgstr "التردد المنخفض للاقط م هرتز" msgid "Setup.LNB$High LNB frequency (MHz)" msgstr "التردد المرتفع للاقط م هرتز" +#, c-format +msgid "Setup.LNB$Device %d connected to sat cable" +msgstr "" + +msgid "Setup.LNB$own" +msgstr "" + msgid "CAM reset" msgstr "اعادة تشغيل الكامة" diff --git a/po/ca_ES.po b/po/ca_ES.po index b104fea..d609cda 100644 --- a/po/ca_ES.po +++ b/po/ca_ES.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2011-08-27 11:54+0200\n" +"POT-Creation-Date: 2011-12-03 16:25+0100\n" "PO-Revision-Date: 2008-03-02 19:02+0100\n" "Last-Translator: Luca Olivetti <luca@ventoso.org>\n" "Language-Team: Catalan <vdr@linuxtv.org>\n" @@ -965,6 +965,13 @@ msgstr "Freqncia LNB baixa (MHz)" msgid "Setup.LNB$High LNB frequency (MHz)" msgstr "Freqncia LNB alta (MHz)" +#, c-format +msgid "Setup.LNB$Device %d connected to sat cable" +msgstr "" + +msgid "Setup.LNB$own" +msgstr "" + msgid "CAM reset" msgstr "Reiniciar CAM" diff --git a/po/cs_CZ.po b/po/cs_CZ.po index bcafac7..eef8257 100644 --- a/po/cs_CZ.po +++ b/po/cs_CZ.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.7.14\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2011-08-27 11:54+0200\n" +"POT-Creation-Date: 2011-12-03 16:25+0100\n" "PO-Revision-Date: 2010-05-06 11:00+0200\n" "Last-Translator: Radek Šťastný <dedkus@gmail.com>\n" "Language-Team: Czech <vdr@linuxtv.org>\n" @@ -964,6 +964,13 @@ msgstr "Dolní frekvence LNB (MHz)" msgid "Setup.LNB$High LNB frequency (MHz)" msgstr "Horní frekvence LNB (MHz)" +#, c-format +msgid "Setup.LNB$Device %d connected to sat cable" +msgstr "" + +msgid "Setup.LNB$own" +msgstr "" + msgid "CAM reset" msgstr "Reset CAMu" diff --git a/po/da_DK.po b/po/da_DK.po index 81b11eb..db6b398 100644 --- a/po/da_DK.po +++ b/po/da_DK.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2011-08-27 11:54+0200\n" +"POT-Creation-Date: 2011-12-03 16:25+0100\n" "PO-Revision-Date: 2007-08-12 14:17+0200\n" "Last-Translator: Mogens Elneff <mogens@elneff.dk>\n" "Language-Team: Danish <vdr@linuxtv.org>\n" @@ -962,6 +962,13 @@ msgstr "Nedre LNB frekvens (MHz)" msgid "Setup.LNB$High LNB frequency (MHz)" msgstr "vre LNB frekvens (MHz)" +#, c-format +msgid "Setup.LNB$Device %d connected to sat cable" +msgstr "" + +msgid "Setup.LNB$own" +msgstr "" + msgid "CAM reset" msgstr "CAM nulstil" diff --git a/po/de_DE.po b/po/de_DE.po index 6d5b822..4a475d7 100644 --- a/po/de_DE.po +++ b/po/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2011-08-27 11:54+0200\n" +"POT-Creation-Date: 2011-12-03 16:25+0100\n" "PO-Revision-Date: 2010-01-16 16:46+0100\n" "Last-Translator: Klaus Schmidinger <kls@tvdr.de>\n" "Language-Team: German <vdr@linuxtv.org>\n" @@ -962,6 +962,13 @@ msgstr "Untere LNB-Frequenz (MHz)" msgid "Setup.LNB$High LNB frequency (MHz)" msgstr "Obere LNB-Frequenz (MHz)" +#, c-format +msgid "Setup.LNB$Device %d connected to sat cable" +msgstr "Device %d angeschlossen an Sat-Kabel" + +msgid "Setup.LNB$own" +msgstr "eigenes" + msgid "CAM reset" msgstr "CAM zurckgesetzt" diff --git a/po/el_GR.po b/po/el_GR.po index 9756ea7..64300f0 100644 --- a/po/el_GR.po +++ b/po/el_GR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2011-08-27 11:54+0200\n" +"POT-Creation-Date: 2011-12-03 16:25+0100\n" "PO-Revision-Date: 2007-08-12 14:17+0200\n" "Last-Translator: Dimitrios Dimitrakos <mail@dimitrios.de>\n" "Language-Team: Greek <vdr@linuxtv.org>\n" @@ -962,6 +962,13 @@ msgstr " LNB- (MHz)" msgid "Setup.LNB$High LNB frequency (MHz)" msgstr " LNB- (MHz)" +#, c-format +msgid "Setup.LNB$Device %d connected to sat cable" +msgstr "" + +msgid "Setup.LNB$own" +msgstr "" + msgid "CAM reset" msgstr "" diff --git a/po/es_ES.po b/po/es_ES.po index 193e75e..288ad69 100644 --- a/po/es_ES.po +++ b/po/es_ES.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2011-08-27 11:54+0200\n" +"POT-Creation-Date: 2011-12-03 16:25+0100\n" "PO-Revision-Date: 2008-03-02 19:02+0100\n" "Last-Translator: Luca Olivetti <luca@ventoso.org>\n" "Language-Team: Spanish <vdr@linuxtv.org>\n" @@ -963,6 +963,13 @@ msgstr "Frecuencia inferior del LNB (MHz)" msgid "Setup.LNB$High LNB frequency (MHz)" msgstr "Frecuencia superior del LNB (MHz)" +#, c-format +msgid "Setup.LNB$Device %d connected to sat cable" +msgstr "" + +msgid "Setup.LNB$own" +msgstr "" + msgid "CAM reset" msgstr "Reset CAM" diff --git a/po/et_EE.po b/po/et_EE.po index 49794dd..c12f31f 100644 --- a/po/et_EE.po +++ b/po/et_EE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2011-08-27 11:54+0200\n" +"POT-Creation-Date: 2011-12-03 16:25+0100\n" "PO-Revision-Date: 2007-08-12 14:17+0200\n" "Last-Translator: Arthur Konovalov <artlov@gmail.com>\n" "Language-Team: Estonian <vdr@linuxtv.org>\n" @@ -962,6 +962,13 @@ msgstr "LO LNB sagedus (MHz)" msgid "Setup.LNB$High LNB frequency (MHz)" msgstr "HI LNB sagedus (MHz)" +#, c-format +msgid "Setup.LNB$Device %d connected to sat cable" +msgstr "" + +msgid "Setup.LNB$own" +msgstr "" + msgid "CAM reset" msgstr "CAM taaskivitamine" diff --git a/po/fi_FI.po b/po/fi_FI.po index b093e88..d0d1225 100644 --- a/po/fi_FI.po +++ b/po/fi_FI.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2011-08-27 11:54+0200\n" +"POT-Creation-Date: 2011-12-03 16:25+0100\n" "PO-Revision-Date: 2007-08-15 15:52+0200\n" "Last-Translator: Rolf Ahrenberg <rahrenbe@cc.hut.fi>\n" "Language-Team: Finnish <vdr@linuxtv.org>\n" @@ -965,6 +965,13 @@ msgstr "LNB-alataajuus (MHz)" msgid "Setup.LNB$High LNB frequency (MHz)" msgstr "LNB-ylätaajuus (MHz)" +#, c-format +msgid "Setup.LNB$Device %d connected to sat cable" +msgstr "" + +msgid "Setup.LNB$own" +msgstr "" + msgid "CAM reset" msgstr "CAM nollaus" diff --git a/po/fr_FR.po b/po/fr_FR.po index b5c5120..5f8b411 100644 --- a/po/fr_FR.po +++ b/po/fr_FR.po @@ -13,7 +13,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2011-08-27 11:54+0200\n" +"POT-Creation-Date: 2011-12-03 16:25+0100\n" "PO-Revision-Date: 2008-02-27 18:14+0100\n" "Last-Translator: Jean-Claude Repetto <jc@repetto.org>\n" "Language-Team: French <vdr@linuxtv.org>\n" @@ -968,6 +968,13 @@ msgstr "Frquence basse LNB (MHz)" msgid "Setup.LNB$High LNB frequency (MHz)" msgstr "Frquence haute LNB (MHz)" +#, c-format +msgid "Setup.LNB$Device %d connected to sat cable" +msgstr "" + +msgid "Setup.LNB$own" +msgstr "" + msgid "CAM reset" msgstr "CAM remis zro" diff --git a/po/hr_HR.po b/po/hr_HR.po index ed519a2..681cb79 100644 --- a/po/hr_HR.po +++ b/po/hr_HR.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2011-08-27 11:54+0200\n" +"POT-Creation-Date: 2011-12-03 16:25+0100\n" "PO-Revision-Date: 2008-03-17 19:00+0100\n" "Last-Translator: Adrian Caval <anrxc@sysphere.org>\n" "Language-Team: Croatian <vdr@linuxtv.org>\n" @@ -964,6 +964,13 @@ msgstr "Donja LNB frekv. (MHz)" msgid "Setup.LNB$High LNB frequency (MHz)" msgstr "Gornja LNB frekv. (MHz)" +#, c-format +msgid "Setup.LNB$Device %d connected to sat cable" +msgstr "" + +msgid "Setup.LNB$own" +msgstr "" + msgid "CAM reset" msgstr "Ponovno pokreni CAM" diff --git a/po/hu_HU.po b/po/hu_HU.po index 17b905f..bebf6ef 100644 --- a/po/hu_HU.po +++ b/po/hu_HU.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2011-08-27 11:54+0200\n" +"POT-Creation-Date: 2011-12-03 16:25+0100\n" "PO-Revision-Date: 2007-12-01 21:42+0200\n" "Last-Translator: Istvn Fley <ifuley@tigercomp.ro>\n" "Language-Team: Hungarian <vdr@linuxtv.org>\n" @@ -965,6 +965,13 @@ msgstr "Als LNB-frekvencia (MHZ)" msgid "Setup.LNB$High LNB frequency (MHz)" msgstr "Fels LNB-frekvencia (MHZ)" +#, c-format +msgid "Setup.LNB$Device %d connected to sat cable" +msgstr "" + +msgid "Setup.LNB$own" +msgstr "" + msgid "CAM reset" msgstr "CAM jraindts" diff --git a/po/it_IT.po b/po/it_IT.po index 501300e..6015881 100644 --- a/po/it_IT.po +++ b/po/it_IT.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2011-08-27 11:54+0200\n" +"POT-Creation-Date: 2011-12-03 16:25+0100\n" "PO-Revision-Date: 2010-06-13 00:30+0100\n" "Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n" "Language-Team: Italian <vdr@linuxtv.org>\n" @@ -969,6 +969,13 @@ msgstr "Freq LO LNB (MHz)" msgid "Setup.LNB$High LNB frequency (MHz)" msgstr "Freq HI LNB (MHz)" +#, c-format +msgid "Setup.LNB$Device %d connected to sat cable" +msgstr "" + +msgid "Setup.LNB$own" +msgstr "" + msgid "CAM reset" msgstr "Reimposta la CAM" diff --git a/po/lt_LT.po b/po/lt_LT.po index 6cb1faa..53d2422 100644 --- a/po/lt_LT.po +++ b/po/lt_LT.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.7.16\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2011-08-27 11:54+0200\n" +"POT-Creation-Date: 2011-12-03 16:25+0100\n" "PO-Revision-Date: 2010-10-30 11:55+0200\n" "Last-Translator: Valdemaras Pipiras <varas@ambernet.lt>\n" "Language-Team: Lithuanian <vdr@linuxtv.org>\n" @@ -962,6 +962,13 @@ msgstr "Žemasis LNB dažnis (MHz)" msgid "Setup.LNB$High LNB frequency (MHz)" msgstr "Aukštasis LNB dažnis (MHz)" +#, c-format +msgid "Setup.LNB$Device %d connected to sat cable" +msgstr "" + +msgid "Setup.LNB$own" +msgstr "" + msgid "CAM reset" msgstr "Dekodavimo modulis (CAM) perkrautas" diff --git a/po/mk_MK.po b/po/mk_MK.po index 0d22563..5fa3634 100644 --- a/po/mk_MK.po +++ b/po/mk_MK.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR-1.7.14\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2011-08-27 11:54+0200\n" +"POT-Creation-Date: 2011-12-03 16:25+0100\n" "PO-Revision-Date: 2010-03-11 00:54+0100\n" "Last-Translator: Dimitar Petrovski <dimeptr@gmail.com>\n" "Language-Team: Macedonian <en@li.org>\n" @@ -963,6 +963,13 @@ msgstr "Долна LNB фрекфенција (MHz)" msgid "Setup.LNB$High LNB frequency (MHz)" msgstr "Форна LNB фрекфенција (MHz)" +#, c-format +msgid "Setup.LNB$Device %d connected to sat cable" +msgstr "" + +msgid "Setup.LNB$own" +msgstr "" + msgid "CAM reset" msgstr "Рестартирај CAM" diff --git a/po/nl_NL.po b/po/nl_NL.po index ae2b85e..65aaba7 100644 --- a/po/nl_NL.po +++ b/po/nl_NL.po @@ -11,7 +11,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2011-08-27 11:54+0200\n" +"POT-Creation-Date: 2011-12-03 16:25+0100\n" "PO-Revision-Date: 2008-02-26 17:20+0100\n" "Last-Translator: Johan Schuring <johan.schuring@vetteblei.nl>\n" "Language-Team: Dutch <vdr@linuxtv.org>\n" @@ -966,6 +966,13 @@ msgstr "Laagste LNB frequentie (MHz)" msgid "Setup.LNB$High LNB frequency (MHz)" msgstr "Hoogste LNB frequentie (MHz)" +#, c-format +msgid "Setup.LNB$Device %d connected to sat cable" +msgstr "" + +msgid "Setup.LNB$own" +msgstr "" + msgid "CAM reset" msgstr "CAM herstarten" diff --git a/po/nn_NO.po b/po/nn_NO.po index 8ec8dfb..a8ea942 100644 --- a/po/nn_NO.po +++ b/po/nn_NO.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2011-08-27 11:54+0200\n" +"POT-Creation-Date: 2011-12-03 16:25+0100\n" "PO-Revision-Date: 2007-08-12 14:17+0200\n" "Last-Translator: Truls Slevigen <truls@slevigen.no>\n" "Language-Team: Norwegian Nynorsk <vdr@linuxtv.org>\n" @@ -963,6 +963,13 @@ msgstr "LO-frekvens i lavbndet (MHz)" msgid "Setup.LNB$High LNB frequency (MHz)" msgstr "LO-frekvens i hybndet (MHz)" +#, c-format +msgid "Setup.LNB$Device %d connected to sat cable" +msgstr "" + +msgid "Setup.LNB$own" +msgstr "" + msgid "CAM reset" msgstr "" diff --git a/po/pl_PL.po b/po/pl_PL.po index a5c1b47..94ba692 100644 --- a/po/pl_PL.po +++ b/po/pl_PL.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2011-08-27 11:54+0200\n" +"POT-Creation-Date: 2011-12-03 16:25+0100\n" "PO-Revision-Date: 2008-03-09 12:59+0100\n" "Last-Translator: Michael Rakowski <mrak@gmx.de>\n" "Language-Team: Polish <vdr@linuxtv.org>\n" @@ -963,6 +963,13 @@ msgstr "Dolna czstotliwo LNB (MHz)" msgid "Setup.LNB$High LNB frequency (MHz)" msgstr "Grna czstotliwo LNB (MHz)" +#, c-format +msgid "Setup.LNB$Device %d connected to sat cable" +msgstr "" + +msgid "Setup.LNB$own" +msgstr "" + msgid "CAM reset" msgstr "CAM zresetowany" diff --git a/po/pt_PT.po b/po/pt_PT.po index c443312..272ab75 100644 --- a/po/pt_PT.po +++ b/po/pt_PT.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.7.15\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2011-08-27 11:54+0200\n" +"POT-Creation-Date: 2011-12-03 16:25+0100\n" "PO-Revision-Date: 2010-03-28 22:49+0100\n" "Last-Translator: Cris Silva <hudokkow@gmail.com>\n" "Language-Team: Portuguese <vdr@linuxtv.org>\n" @@ -963,6 +963,13 @@ msgstr "Frequncia baixa do LNB (MHz)" msgid "Setup.LNB$High LNB frequency (MHz)" msgstr "Frequncia alta do LNB (MHz)" +#, c-format +msgid "Setup.LNB$Device %d connected to sat cable" +msgstr "" + +msgid "Setup.LNB$own" +msgstr "" + msgid "CAM reset" msgstr "Reiniciar CAM" diff --git a/po/ro_RO.po b/po/ro_RO.po index f8c5a1e..414ade1 100644 --- a/po/ro_RO.po +++ b/po/ro_RO.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.7.12\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2011-08-27 11:54+0200\n" +"POT-Creation-Date: 2011-12-03 16:25+0100\n" "PO-Revision-Date: 2011-03-10 23:52+0100\n" "Last-Translator: Lucian Muresan <lucianm@users.sourceforge.net>\n" "Language-Team: Romanian <vdr@linuxtv.org>\n" @@ -965,6 +965,13 @@ msgstr "Frecvn LNB inferioar (Mhz)" msgid "Setup.LNB$High LNB frequency (MHz)" msgstr "Frecvn LNB superioar (MHz)" +#, c-format +msgid "Setup.LNB$Device %d connected to sat cable" +msgstr "" + +msgid "Setup.LNB$own" +msgstr "" + msgid "CAM reset" msgstr "Resetare CAM" diff --git a/po/ru_RU.po b/po/ru_RU.po index e683b8b..a4eaca5 100644 --- a/po/ru_RU.po +++ b/po/ru_RU.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2011-08-27 11:54+0200\n" +"POT-Creation-Date: 2011-12-03 16:25+0100\n" "PO-Revision-Date: 2008-12-15 14:37+0100\n" "Last-Translator: Oleg Roitburd <oleg@roitburd.de>\n" "Language-Team: Russian <vdr@linuxtv.org>\n" @@ -963,6 +963,13 @@ msgstr " ()" msgid "Setup.LNB$High LNB frequency (MHz)" msgstr " ()" +#, c-format +msgid "Setup.LNB$Device %d connected to sat cable" +msgstr "" + +msgid "Setup.LNB$own" +msgstr "" + msgid "CAM reset" msgstr "CAM " diff --git a/po/sk_SK.po b/po/sk_SK.po index 46edef5..176673f 100644 --- a/po/sk_SK.po +++ b/po/sk_SK.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.7.16\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2011-08-27 11:54+0200\n" +"POT-Creation-Date: 2011-12-03 16:25+0100\n" "PO-Revision-Date: 2011-02-15 16:29+0100\n" "Last-Translator: Milan Hrala <hrala.milan@gmail.com>\n" "Language-Team: Slovak <vdr@linuxtv.org>\n" @@ -962,6 +962,13 @@ msgstr "Doln frekvencia LNB (MHz)" msgid "Setup.LNB$High LNB frequency (MHz)" msgstr "Horn frekvencia LNB (MHz)" +#, c-format +msgid "Setup.LNB$Device %d connected to sat cable" +msgstr "" + +msgid "Setup.LNB$own" +msgstr "" + msgid "CAM reset" msgstr "Resetnutie CAMu" diff --git a/po/sl_SI.po b/po/sl_SI.po index 89c6923..696e953 100644 --- a/po/sl_SI.po +++ b/po/sl_SI.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2011-08-27 11:54+0200\n" +"POT-Creation-Date: 2011-12-03 16:25+0100\n" "PO-Revision-Date: 2008-02-28 19:44+0100\n" "Last-Translator: Matjaz Thaler <matjaz.thaler@guest.arnes.si>\n" "Language-Team: Slovenian <vdr@linuxtv.org>\n" @@ -963,6 +963,13 @@ msgstr "Spodnja LNB-frek. (MHz)" msgid "Setup.LNB$High LNB frequency (MHz)" msgstr "Zgornja LNB-frek. (MHz)" +#, c-format +msgid "Setup.LNB$Device %d connected to sat cable" +msgstr "" + +msgid "Setup.LNB$own" +msgstr "" + msgid "CAM reset" msgstr "Reset CAM-a" diff --git a/po/sr_SR.po b/po/sr_SR.po index 45d354b..62c07d3 100644 --- a/po/sr_SR.po +++ b/po/sr_SR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.7.1\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2011-08-27 11:54+0200\n" +"POT-Creation-Date: 2011-12-03 16:25+0100\n" "PO-Revision-Date: 2011-01-09 15:57+0100\n" "Last-Translator: Milan Cvijanovi <elcom_cvijo@hotmail.com>\n" "Language-Team: Serbian <vdr@linuxtv.org>\n" @@ -981,6 +981,13 @@ msgstr "Donja LNB frekv. (MHz)" msgid "Setup.LNB$High LNB frequency (MHz)" msgstr "Gornja LNB frekv. (MHz)" +#, c-format +msgid "Setup.LNB$Device %d connected to sat cable" +msgstr "" + +msgid "Setup.LNB$own" +msgstr "" + msgid "CAM reset" msgstr "Ponovno pokreni CAM" diff --git a/po/sv_SE.po b/po/sv_SE.po index 150f95e..ae6d72f 100644 --- a/po/sv_SE.po +++ b/po/sv_SE.po @@ -10,7 +10,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2011-08-27 11:54+0200\n" +"POT-Creation-Date: 2011-12-03 16:25+0100\n" "PO-Revision-Date: 2008-03-12 18:25+0100\n" "Last-Translator: Magnus Andersson <svankan@bahnhof.se>\n" "Language-Team: Swedish <vdr@linuxtv.org>\n" @@ -965,6 +965,13 @@ msgstr "Undre LNB frekvens (MHz)" msgid "Setup.LNB$High LNB frequency (MHz)" msgstr "vre LNB frekvens (MHz)" +#, c-format +msgid "Setup.LNB$Device %d connected to sat cable" +msgstr "" + +msgid "Setup.LNB$own" +msgstr "" + msgid "CAM reset" msgstr "CAM omstart" diff --git a/po/tr_TR.po b/po/tr_TR.po index 194943b..946ab42 100644 --- a/po/tr_TR.po +++ b/po/tr_TR.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2011-08-27 11:54+0200\n" +"POT-Creation-Date: 2011-12-03 16:25+0100\n" "PO-Revision-Date: 2008-02-28 00:33+0100\n" "Last-Translator: Oktay Yolgeen <oktay_73@yahoo.de>\n" "Language-Team: Turkish <vdr@linuxtv.org>\n" @@ -962,6 +962,13 @@ msgstr "Alt LNB frekans (MHz)" msgid "Setup.LNB$High LNB frequency (MHz)" msgstr "st LNB frekans (MHz)" +#, c-format +msgid "Setup.LNB$Device %d connected to sat cable" +msgstr "" + +msgid "Setup.LNB$own" +msgstr "" + msgid "CAM reset" msgstr "CAM sfrland" diff --git a/po/uk_UA.po b/po/uk_UA.po index 433ec70..c383af8 100644 --- a/po/uk_UA.po +++ b/po/uk_UA.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.7.7\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2011-08-27 11:54+0200\n" +"POT-Creation-Date: 2011-12-03 16:25+0100\n" "PO-Revision-Date: 2010-04-25 16:35+0200\n" "Last-Translator: Yarema aka Knedlyk <yupadmin@gmail.com>\n" "Language-Team: Ukrainian <vdr@linuxtv.org>\n" @@ -962,6 +962,13 @@ msgstr "Нижня частота конвертера (МГц)" msgid "Setup.LNB$High LNB frequency (MHz)" msgstr "Верхня частота конвертера (МГц)" +#, c-format +msgid "Setup.LNB$Device %d connected to sat cable" +msgstr "" + +msgid "Setup.LNB$own" +msgstr "" + msgid "CAM reset" msgstr "Перезавантаження CAM" diff --git a/po/zh_CN.po b/po/zh_CN.po index c28fe88..43a5ea5 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: VDR 1.6.0\n" "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" -"POT-Creation-Date: 2011-08-27 11:54+0200\n" +"POT-Creation-Date: 2011-12-03 16:25+0100\n" "PO-Revision-Date: 2009-09-23 23:50+0800\n" "Last-Translator: Nan Feng <nfgx@21cn.com>\n" "Language-Team: Chinese (simplified) <vdr@linuxtv.org>\n" @@ -965,6 +965,13 @@ msgstr "低本振频率 (MHz)" msgid "Setup.LNB$High LNB frequency (MHz)" msgstr "高本振频率 (MHz)" +#, c-format +msgid "Setup.LNB$Device %d connected to sat cable" +msgstr "" + +msgid "Setup.LNB$own" +msgstr "" + msgid "CAM reset" msgstr "CAM重置" @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: receiver.h 2.1 2010/01/30 10:25:19 kls Exp $ + * $Id: receiver.h 2.2 2011/12/04 13:38:17 kls Exp $ */ #ifndef __RECEIVER_H @@ -56,7 +56,7 @@ public: bool AddPid(int Pid); ///< Adds the given Pid to the list of PIDs of this receiver. bool AddPids(const int *Pids); - ///< Adds the given izero terminated list of Pids to the list of PIDs of this + ///< Adds the given zero terminated list of Pids to the list of PIDs of this ///< receiver. bool AddPids(int Pid1, int Pid2, int Pid3 = 0, int Pid4 = 0, int Pid5 = 0, int Pid6 = 0, int Pid7 = 0, int Pid8 = 0, int Pid9 = 0); ///< Adds the given Pids to the list of PIDs of this receiver. diff --git a/recording.c b/recording.c index bea7eb6..6b11fbd 100644 --- a/recording.c +++ b/recording.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: recording.c 2.38 2011/09/04 09:32:25 kls Exp $ + * $Id: recording.c 2.39 2011/12/04 13:51:44 kls Exp $ */ #include "recording.h" @@ -1162,7 +1162,7 @@ void cRecordings::TouchUpdate(void) bool needsUpdate = NeedsUpdate(); TouchFile(UpdateFileName()); if (!needsUpdate) - lastUpdate = time(NULL); // make sure we don't tigger ourselves + lastUpdate = time(NULL); // make sure we don't trigger ourselves } bool cRecordings::NeedsUpdate(void) diff --git a/recording.h b/recording.h index 37979ec..d3dbd1d 100644 --- a/recording.h +++ b/recording.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: recording.h 2.25 2011/08/21 13:10:39 kls Exp $ + * $Id: recording.h 2.26 2011/12/04 13:38:17 kls Exp $ */ #ifndef __RECORDING_H @@ -176,7 +176,7 @@ public: ///< Triggers an update of the list of recordings, which will run ///< as a separate thread if Wait is false. If Wait is true, the ///< function returns only after the update has completed. - ///< Returns true if Wait is true and there is anyting in the list + ///< Returns true if Wait is true and there is anything in the list ///< of recordings, false otherwise. void TouchUpdate(void); ///< Touches the '.update' file in the video directory, so that other @@ -292,7 +292,7 @@ public: bool IsStillRecording(void); void Delete(void); static int GetLength(const char *FileName, bool IsPesRecording = false); - ///< Calculates the recording length (numer of frames) without actually reading the index file. + ///< Calculates the recording length (number of frames) without actually reading the index file. ///< Returns -1 in case of error. }; diff --git a/ringbuffer.h b/ringbuffer.h index 83281b2..d234502 100644 --- a/ringbuffer.h +++ b/ringbuffer.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: ringbuffer.h 2.2 2009/11/08 11:52:25 kls Exp $ + * $Id: ringbuffer.h 2.3 2011/12/04 13:38:17 kls Exp $ */ #ifndef __RINGBUFFER_H @@ -85,7 +85,7 @@ public: ///< \return Returns the number of bytes actually read and stored, or ///< an error value from the actual read() call. int Read(cUnbufferedFile *File, int Max = 0); - ///< Like Read(int FileHandle, int Max), but reads fom a cUnbufferedFile). + ///< Like Read(int FileHandle, int Max), but reads from a cUnbufferedFile). int Put(const uchar *Data, int Count); ///< Puts at most Count bytes of Data into the ring buffer. ///< \return Returns the number of bytes actually stored. diff --git a/scr.conf b/scr.conf new file mode 100644 index 0000000..61e09f1 --- /dev/null +++ b/scr.conf @@ -0,0 +1,24 @@ +# SCR (Satellite Channel Routing) configuration for VDR +# +# Format: +# +# channel frequency [pin] +# +# channel: SCR channel index (0-7) +# frequency: frequency of the SCR channel ("user band") +# pin: optional pin of the SCR channel (0-255) +# +# A line containing space separated integer numbers, terminated with a ':', +# defines that any following lines apply only to the given list +# of device numbers. +# +# Examples: + +# 0 1284 +# 1 1400 +# 2 1516 +# 3 1632 +# 4 1748 +# 5 1864 +# 6 1980 +# 7 2096 @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: skins.h 2.0 2008/02/17 11:30:56 kls Exp $ + * $Id: skins.h 2.1 2011/12/04 13:38:17 kls Exp $ */ #ifndef __SKINS_H @@ -148,7 +148,7 @@ public: ///< Sets the Total number of items in the currently displayed list, and the ///< Offset of the first item that is currently displayed (the skin knows how ///< many items it can display at once, see MaxItems()). This can be used to - ///< display a scollbar. + ///< display a scrollbar. virtual void SetEvent(const cEvent *Event) = 0; ///< Sets the Event that shall be displayed, using the entire central area ///< of the menu. The Event's 'description' shall be displayed using a diff --git a/sources.conf b/sources.conf index 751d919..8c352fd 100644 --- a/sources.conf +++ b/sources.conf @@ -19,174 +19,165 @@ # Europe -S3E Telecom 2C -S4E Eurobird 4 -S4.8E Sirius 4 +S3E Eutelsat 3A & Rascom 1R +S4E Eurobird 4A +S4.8E Astra 4A S7E Eutelsat W3A -S9E Eurobird 9 -S10E Eutelsat W1 -S13E Hotbird 6/7A/8 -S16E Eutelsat W2 -S19.2E Astra F/G/H/KR/L -S21.0E Afristar 1 +S9E Eurobird 9A +S10E Eutelsat W2A +S13E Hotbird 6/8/9 +S16E Eutelsat W2M & Eurobird 16A +S19.2E Astra 1H/1KR/1L/1M/2C S21.6E Eutelsat W6 -S23.5E Astra 1E/3A +S23.5E Astra 3A/3B S25.5E Eurobird 2 -S26E Badr 3/4/6 -S28.2E Astra 2D/A/B -S28.5E Eurobird 1 & Astra 2A/B/C/D -S30.5E Arabsat 2B -S31.5E Astra 1D/5A -S33E Eurobird 3 & Intelsat 802 -S36E Eutelsat W4 & Sesat +S26E Badr 4/5/6 +S28.2E Astra 2A/2B/2D +S28.5E Eurobird 1 +S30.5E Arabsat 5A +S31.5E Astra 1G +S33E Eurobird 3 & Intelsat New Dawn +S36E Eutelsat W4/W7 S38E Paksat 1 S39E Hellas Sat 2 S40E Express AM1 S42E Turksat 2A/3A S45E Intelsat 12 S49E Yamal 202 -S53E Express AM 22 -S55E Insat 3E +S53E Express AM22 +S55E Insat 3E S56E Bonum 1 -S57E NSS 703 +S57E NSS 12 S60E Intelsat 904 S62E Intelsat 902 S64E Intelsat 906 -S66E Intelsat 704 +S66E Intelsat 17 S68.5E Intelsat 7/10 S70.5E Eutelsat W5 -S72E Intelsat 4 +S72E Intelsat 709 # Asia -S74E Insat 3C/4CR & Edusat -S75E ABS 1 -S76.5E Telstar 10 -S78.5E Thaicom 2/5 -S80E Express AM2 -S83E Insat 2E/3B/4A -S85.2E Intelsat 709 -S87.5E Chinastar 1 -S88E ST 1 +S74E Insat 3C/4CR +S75E ABS 1A +S76.5E Apstar 2R +S78.5E Thaicom 5 +S80E Express AM2/MD1 +S83E Insat 2E/4A +S85.2E Intelsat 15 +S87.5E Chinasat 5A +S88E ST 1/2 S90E Yamal 201 -S91.5E Measat 1 +S91.5E Measat 3/3A S92.2E Chinasat 9 S93.5E Insat 3A/4B S95E NSS 6 -S96.5E Express AM 33 -S98.5E Protostar 1 -S100.5E Asiasat 2 +S96.5E Express AM33 +S100.5E Asiasat 5 S103E Express A2 -S105E Asiastar S105.5E Asiasat 3S -S107.7E Cakrawarta 1 -S108E Telkom 1 & NSS 11 -S110E N-Sat 110 & BSAT 1A/2A -S110.5E Sinosat 1 -S113E Palapa C2 & Koreasat 2 -S116E Koreasat 3 +S108.2E Telkom 1 & NSS 11 & SES 7 +S110E N-Sat 110 & BSAT 2C/3A +S110.5E Chinasat 10 +S113E Palapa D & Koreasat 5 +S116E Koreasat 6 S118E Telkom 2 -S120E Thaicom 1A S122.2E Asiasat 4 -S124E JCSAT 4a -S125E Sinosat 3 -S128E JCSAT 3 -S132E Vinasat 1 & JCSAT5a +S124E JCSAT 4A +S125E Chinasat 6A +S128E JCSAT RA +S132E Vinasat 1 & JCSAT5A S134E Apstar 6 S138E Telstar 18 -S140E Express AM 3 -S144E Superbird C -S146E Agila 2 -S148E Measat 2 -S150E JCSAT R +S140E Express AM3 +S144E Superbird C2 +S146E ABS 5 +S150E JCSAT 1B S152E Optus D2 S154E JCSAT 2A -S156E Optus C1 -S158E Superbird A +S156E Optus C1/D3 S160E Optus D1 S162E Superbird B2 S164E Optus B3 S166E Intelsat 8 -S169E Intelsat 2 +S169E Intelsat 5 S172E GE 23 S180E Intelsat 701 -S177W NSS 5 +S177W NSS 9 # Atlantic -S1W Thor 3/5 & Intelsat 10-02 -S4W Amos 1/2/3 +S1W Thor 5/6 & Intelsat 10-02 +S4W Amos 2/3 S5W Atlantic Bird 3 -S7W Nilesat 101/102 & Atlantic Bird 4 +S7W Nilesat 101/102/201 & Atlantic Bird 4A S8W Telecom 2D & Atlantic Bird 2 -S11W Express A3 +S11W Express AM44 S12.5W Atlantic Bird 1 S14W Express A4 S15W Telstar 12 S18W Intelsat 901 -S20W Intelsat 603 +S20W NSS 5 S22W NSS 7 S24.5W Intelsat 905 S27.5W Intelsat 907 -S30W Hispasat 1C/1D -S31.5W Intelsat 801 +S30W Hispasat 1C/1D/1E +S31.5W Intelsat 25 S34.5W Intelsat 903 -S37.5W NSS 10 +S37.5W NSS 10 & Telstar 11N S40.5W NSS 806 -S43W Intelsat 3R/11 -S45W Intelsat 1R -S50W Intelsat 705 +S43W Intelsat 11 +S45W Intelsat 14 +S50W Intelsat 1R S53W Intelsat 707 S55.5W Intelsat 805 -S58W Intelsat 9 -S61W Amazonas +S58W Intelsat 9/16 +S61W Amazonas 1/2 # America -S61.5W Echostar 3 & Rainbow 1 -S63W Estrelo de Sul 1 +S61.5W Echostar 12/15 +S63W Telstar 14R S65W Star One C1 S70W Star One C2 -S72W Nahuel 1 & AMC 6 -S72.5W DirecTV 1R & Echostar 6 +S72W AMC 6 +S72.5W DirecTV 1R & Nimiq 5 S74W Horizons 2 -S77W Echostar 4 & Galaxy 4R -S79W AMC5 -S82W Nimiq 2 +S77W Echostar 1/8 +S79W AMC 2/5 +S82W Nimiq 4 S83W AMC 9 -S84W Brasilsat B3/4 +S84W Brasilsat B4 S85W AMC 16 S85.1W XM 3 -S87W AMC3 +S87W AMC 3 S89W Galaxy 28 -S91W Galaxy 11/17 & Nimiq 1 -S92W Brasilsat B2 -S93W Galaxy 26 +S91W Galaxy 17 & Nimiq 1 +S93W Galaxy 25 S95W Galaxy 3C -S97W Galaxy 25 +S97W Galaxy 19 S99W Galaxy 16 S99.2W Spaceway 2 & DirecTV 11 -S101W DirecTV 4S/8 & AMC 2/4 -S103W AMC1 -S105W AMC15/18 +S101W DirecTV 4S/8 & SES 1 +S103W AMC 1 +S105W AMC 15/18 S107.3W Anik F1/F1R -S110W DirecTV 5 & Echostar 8/10 +S110W DirecTV 5 & Echostar 10/11 S111.1W Anik F2 S113W SatMex 6 S116.8W SatMex 5 S118.8W Anik F3 -S119W Echostar 7 & DirecTV 7S -S121W Echostar 9 & Galaxy 23 +S119W Echostar 14 & DirecTV 7S +S121W Echostar 9/Galaxy 23 S123W Galaxy 18 -S125W Galaxy 14 +S125W Galaxy 14 & AMC 21 S127W Galaxy 13/Horizons 1 -S129W Ciel 2 & Galaxy 27 +S129W Ciel 2 S131W AMC 11 -S133W Galaxy15 +S133W Galaxy 13/15 S135W AMC 10 S137W AMC 7 S139W AMC 8 -S148W Echostar 1/2 # Cable diff --git a/summary2info.pl b/summary2info index 6976024..fc633f9 100755 --- a/summary2info.pl +++ b/summary2info @@ -5,12 +5,12 @@ # Converts all 'summary.vdr' files in the video directory to the # 'info.vdr' format as used from VDR version 1.3.25 upward. # -# Usage: summary2info.pl /video +# Usage: summary2info /video # # See the main source file 'vdr.c' for copyright information and # how to reach the author. # -# $Id: summary2info.pl 2.0 2006/04/17 12:19:24 kls Exp $ +# $Id: summary2info 2.1 2011/12/04 14:17:35 kls Exp $ $VideoDir = $ARGV[0] || die "please provide the name of the video directory\n"; @@ -10,7 +10,7 @@ * and interact with the Video Disk Recorder - or write a full featured * graphical interface that sits on top of an SVDRP connection. * - * $Id: svdrp.c 2.10 2011/08/27 10:43:18 kls Exp $ + * $Id: svdrp.c 2.12 2011/12/04 13:58:33 kls Exp $ */ #include "svdrp.h" @@ -224,7 +224,7 @@ const char *HelpPages[] = { " valid key names is given. If more than one key is given, they are\n" " entered into the remote control queue in the given sequence. There\n" " can be up to 31 keys.", - "LSTC [ :groups | <number> | <name> ]\n" + "LSTC [ :groups | <number> | <name> | <id> ]\n" " List channels. Without option, all channels are listed. Otherwise\n" " only the given channel is listed. If a name is given, all channels\n" " containing the given string as part of their name are listed.\n" @@ -315,6 +315,9 @@ const char *HelpPages[] = { " Updates a timer. Settings must be in the same format as returned\n" " by the LSTT command. If a timer with the same channel, day, start\n" " and stop time does not yet exists, it will be created.", + "UPDR\n" + " Initiates a re-read of the recordings directory, which is the SVDRP\n" + " equivalent to 'touch .update'.", "VOLU [ <number> | + | - | mute ]\n" " Set the audio volume to the given number (which is limited to the range\n" " 0...255). If the special options '+' or '-' are given, the volume will\n" @@ -948,16 +951,18 @@ void cSVDRP::CmdLSTC(const char *Option) Reply(501, "Channel \"%s\" not defined", Option); } else { - cChannel *next = NULL; - for (cChannel *channel = Channels.First(); channel; channel = Channels.Next(channel)) { - if (!channel->GroupSep()) { - if (strcasestr(channel->Name(), Option)) { - if (next) - Reply(-250, "%d %s", next->Number(), *next->ToText()); - next = channel; - } - } - } + cChannel *next = Channels.GetByChannelID(tChannelID::FromString(Option)); + if (!next) { + for (cChannel *channel = Channels.First(); channel; channel = Channels.Next(channel)) { + if (!channel->GroupSep()) { + if (strcasestr(channel->Name(), Option)) { + if (next) + Reply(-250, "%d %s", next->Number(), *next->ToText()); + next = channel; + } + } + } + } if (next) Reply(250, "%d %s", next->Number(), *next->ToText()); else @@ -1557,6 +1562,12 @@ void cSVDRP::CmdUPDT(const char *Option) Reply(501, "Missing timer settings"); } +void cSVDRP::CmdUPDR(const char *Option) +{ + Recordings.Update(false); + Reply(250, "Re-read of recordings directory triggered"); +} + void cSVDRP::CmdVOLU(const char *Option) { if (*Option) { @@ -1627,6 +1638,7 @@ void cSVDRP::Execute(char *Cmd) else if (CMD("REMO")) CmdREMO(s); else if (CMD("SCAN")) CmdSCAN(s); else if (CMD("STAT")) CmdSTAT(s); + else if (CMD("UPDR")) CmdUPDR(s); else if (CMD("UPDT")) CmdUPDT(s); else if (CMD("VOLU")) CmdVOLU(s); else if (CMD("QUIT")) Close(true); @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: svdrp.h 2.0 2007/04/30 12:28:28 kls Exp $ + * $Id: svdrp.h 2.1 2011/12/04 13:51:44 kls Exp $ */ #ifndef __SVDRP_H @@ -82,6 +82,7 @@ private: void CmdSCAN(const char *Option); void CmdSTAT(const char *Option); void CmdUPDT(const char *Option); + void CmdUPDR(const char *Option); void CmdVOLU(const char *Option); void Execute(char *Cmd); public: @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: tools.c 2.17 2011/08/15 13:35:23 kls Exp $ + * $Id: tools.c 2.19 2011/12/04 14:52:38 kls Exp $ */ #include "tools.h" @@ -1196,6 +1196,47 @@ const char *cBase64Encoder::NextLine(void) return NULL; } +// --- cBitStream ------------------------------------------------------------ + +int cBitStream::GetBit(void) +{ + if (index >= length) + return 1; + int r = (data[index >> 3] >> (7 - (index & 7))) & 1; + ++index; + return r; +} + +uint32_t cBitStream::GetBits(int n) +{ + uint32_t r = 0; + while (n--) + r |= GetBit() << n; + return r; +} + +void cBitStream::ByteAlign(void) +{ + int n = index % 8; + if (n > 0) + SkipBits(8 - n); +} + +void cBitStream::WordAlign(void) +{ + int n = index % 16; + if (n > 0) + SkipBits(16 - n); +} + +bool cBitStream::SetLength(int Length) +{ + if (Length > length) + return false; + length = Length; + return true; +} + // --- cReadLine ------------------------------------------------------------- cReadLine::cReadLine(void) @@ -1748,7 +1789,7 @@ bool cLockFile::Lock(int WaitSeconds) break; } if (WaitSeconds) - sleep(1); + cCondWait::SleepMs(1000); } } while (f < 0 && time(NULL) < Timeout); } @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: tools.h 2.11 2011/08/15 14:13:42 kls Exp $ + * $Id: tools.h 2.14 2011/12/04 14:48:03 kls Exp $ */ #ifndef __TOOLS_H @@ -36,7 +36,7 @@ extern int SysLogLevel; #define dsyslog(a...) void( (SysLogLevel > 2) ? syslog_with_tid(LOG_ERR, a) : void() ) #define LOG_ERROR esyslog("ERROR (%s,%d): %m", __FILE__, __LINE__) -#define LOG_ERROR_STR(s) esyslog("ERROR: %s: %m", s) +#define LOG_ERROR_STR(s) esyslog("ERROR (%s,%d): %s: %m", __FILE__, __LINE__, s) #define SECSINDAY 86400 @@ -108,7 +108,7 @@ int Utf8StrLen(const char *s); ///< Returns the number of UTF-8 symbols formed by the given string of ///< character bytes. char *Utf8Strn0Cpy(char *Dest, const char *Src, int n); - ///< Copies at most n character bytes from Src to Dst, making sure that the + ///< Copies at most n character bytes from Src to Dest, making sure that the ///< resulting copy ends with a complete UTF-8 symbol. The copy is guaranteed ///< to be zero terminated. ///< Returns a pointer to Dest. @@ -210,7 +210,7 @@ int64_t StrToNum(const char *s); ///< The numerical part of the string may be followed by one of the letters ///< K, M, G or T to abbreviate Kilo-, Mega-, Giga- or Terabyte, respectively ///< (based on 1024). Everything after the first non-numeric character is - ///< silently ignored, as are any characters other than the ones mentionend here. + ///< silently ignored, as are any characters other than the ones mentioned here. cString itoa(int n); cString AddDirectory(const char *DirName, const char *FileName); bool EntriesOnSameFileSystem(const char *File1, const char *File2); @@ -266,6 +266,28 @@ public: ///< is called, or until the object is destroyed. }; +class cBitStream { +private: + const uint8_t *data; + int length; // in bits + int index; // in bits +public: + cBitStream(const uint8_t *Data, int Length) : data(Data), length(Length), index(0) {} + ~cBitStream() {} + int GetBit(void); + uint32_t GetBits(int n); + void ByteAlign(void); + void WordAlign(void); + bool SetLength(int Length); + void SkipBits(int n) { index += n; } + void SkipBit(void) { SkipBits(1); } + bool IsEOF(void) const { return index >= length; } + void Reset(void) { index = 0; } + int Length(void) const { return length; } + int Index(void) const { return (IsEOF() ? length : index); } + const uint8_t *GetData(void) const { return (IsEOF() ? NULL : data + (index / 8)); } + }; + class cTimeMs { private: uint64_t begin; @@ -8,7 +8,7 @@ .\" License as specified in the file COPYING that comes with the .\" vdr distribution. .\" -.\" $Id: vdr.1 2.6 2011/08/15 12:28:54 kls Exp $ +.\" $Id: vdr.1 2.7 2011/12/04 14:41:00 kls Exp $ .\" .TH vdr 1 "10 Feb 2008" "1.6" "Video Disk Recorder" .SH NAME @@ -120,7 +120,7 @@ Each of them will apply to the \fB\-P\fR options following it. .TP .BI \-\-lirc[= path ] Use a LIRC remote control device. -If \fIpath\fR is omitted, vdr uses \fI/dev/lircd\fR. +If \fIpath\fR is omitted, vdr uses \fI/var/run/lirc/lircd\fR. .TP .BI \-\-localedir= dir Search for locale files in \fIdir\fR (default is ./locale). @@ -8,7 +8,7 @@ .\" License as specified in the file COPYING that comes with the .\" vdr distribution. .\" -.\" $Id: vdr.5 2.23 2011/08/21 14:06:50 kls Exp $ +.\" $Id: vdr.5 2.26 2011/09/25 13:51:34 kls Exp $ .\" .TH vdr 5 "10 Feb 2008" "1.6" "Video Disk Recorder Files" .SH NAME @@ -450,7 +450,8 @@ Note that there should be a last entry with the value \fB99999\fR for each satel which covers the upper frequency range. The third parameter defines the polarization to which this entry applies. It can -be either \fBH\fR for horizontal or \fBV\fR for vertical. +be either \fBH\fR for horizontal, \fBV\fR for vertical, \fBL\fR for circular left +or \fBR\fR for circular right. The fourth parameter specifies the "local oscillator frequency" (lof) of the LNB to use for the given frequency range. This number will be subtracted from the @@ -467,6 +468,7 @@ l l. \fBV\fR@voltage high (18V) \fBA\fR@mini A \fBB\fR@mini B +\fBSn\fR@Satellite channel routing code sequence for bank n follows \fBWnn\fR@wait nn milliseconds (nn may be any positive integer number) \fB[xx ...]\fR@hex code sequence (max. 6) .TE @@ -484,6 +486,46 @@ to receive the satellites following thereafter. In this case, only the devices 1, 2 and 4 would be able to receive any satellites following this line and up to the next such line, or the end of the file. Devices may be listed more than once. +.SS SATELLITE CHANNEL ROUTING (SCR) +The file \fIscr.conf\fR contains the channel definitions of the SCR device in use. +The format is + +channel frequency [pin] + +where channel is the SCR device's channel index (0-7), frequency is the user band +frequency of the given channel, and pin is an optional pin number (0-255). The +actual values are device specific and can be found in the SCR device's manual. + +Examples: + +0 1284 +.br +1 1400 +.br +2 1516 +.br +3 1632 +.br +4 1748 +.br +5 1864 +.br +6 1980 +.br +7 2096 + +By default it is assumed that the SCR configurations apply to all devices, and +each device will pick one. If you have several SCR sat cables connected to one +VDR machine, or if you want to explicitly assign the SCR channels to your devices, +lines of the form + +\fB1 2 4:\fR + +may be inserted in the \fIscr.conf\fR file, defining the devices that are allowed +to use the SCR channels thereafter. In this case, only the devices +1, 2 and 4 would be allowed to use the SCR channels following this line and up +to the next such line, or the end of the file. If a device is listed more than +once, only its first appearance counts. .SS REMOTE CONTROL KEYS The file \fIremote.conf\fR contains the key assignments for all remote control units. Each line consists of one key assignment in the following format: @@ -22,7 +22,7 @@ * * The project's page is at http://www.tvdr.de * - * $Id: vdr.c 2.23 2011/08/15 12:42:39 kls Exp $ + * $Id: vdr.c 2.27 2011/12/03 15:35:09 kls Exp $ */ #include <getopt.h> @@ -116,7 +116,7 @@ static bool SetUser(const char *UserName, bool UserDump)//XXX name? static bool DropCaps(void) { // drop all capabilities except selected ones - cap_t caps = cap_from_text("= cap_sys_nice,cap_sys_time=ep"); + cap_t caps = cap_from_text("= cap_sys_nice,cap_sys_time,cap_net_raw=ep"); if (!caps) { fprintf(stderr, "vdr: cap_from_text failed: %s\n", strerror(errno)); return false; @@ -598,6 +598,7 @@ int main(int argc, char *argv[]) Setup.Load(AddDirectory(ConfigDirectory, "setup.conf")); Sources.Load(AddDirectory(ConfigDirectory, "sources.conf"), true, true); Diseqcs.Load(AddDirectory(ConfigDirectory, "diseqc.conf"), true, Setup.DiSEqC); + Scrs.Load(AddDirectory(ConfigDirectory, "scr.conf"), true); Channels.Load(AddDirectory(ConfigDirectory, "channels.conf"), false, true); Timers.Load(AddDirectory(ConfigDirectory, "timers.conf")); Commands.Load(AddDirectory(ConfigDirectory, "commands.conf")); @@ -638,6 +639,7 @@ int main(int argc, char *argv[]) // DVB interfaces: cDvbDevice::Initialize(); + cDvbDevice::BondDevices(Setup.DeviceBondings); // Initialize plugins: @@ -859,7 +861,6 @@ int main(int argc, char *argv[]) static time_t LastTimerCheck = 0; if (Now - LastTimerCheck > TIMERCHECKDELTA) { // don't do this too often InhibitEpgScan = false; - static time_t DeviceUsed[MAXDEVICES] = { 0 }; for (cTimer *Timer = Timers.First(); Timer; Timer = Timers.Next(Timer)) { bool InVpsMargin = false; bool NeedsTransponder = false; @@ -899,19 +900,17 @@ int main(int argc, char *argv[]) Device = d; break; } - bool timeout = Now - DeviceUsed[d->DeviceNumber()] > TIMERDEVICETIMEOUT; // only check other devices if they have been left alone for a while - if (d->MaySwitchTransponder()) { + if (d->MaySwitchTransponder(Timer->Channel())) { DeviceAvailable = true; // avoids using the actual device below - if (timeout) - Device = d; // only check other devices if they have been left alone for a while + Device = d; } - else if (timeout && !Device && InVpsMargin && !d->Receiving() && d->ProvidesTransponderExclusively(Timer->Channel())) + else if (!d->Occupied() && !Device && InVpsMargin && !d->Receiving() && d->ProvidesTransponderExclusively(Timer->Channel())) Device = d; // use this one only if no other with less impact can be found } } if (!Device && InVpsMargin && !DeviceAvailable) { cDevice *d = cDevice::ActualDevice(); - if (!d->Receiving() && d->ProvidesTransponder(Timer->Channel()) && Now - DeviceUsed[d->DeviceNumber()] > TIMERDEVICETIMEOUT) + if (!d->Receiving() && d->ProvidesTransponder(Timer->Channel()) && !d->Occupied()) Device = d; // use the actual device as a last resort } // Switch the device to the transponder: @@ -920,8 +919,8 @@ int main(int argc, char *argv[]) if (Device == cDevice::ActualDevice() && !Device->IsPrimaryDevice()) cDevice::PrimaryDevice()->StopReplay(); // stop transfer mode dsyslog("switching device %d to channel %d", Device->DeviceNumber() + 1, Timer->Channel()->Number()); - Device->SwitchChannel(Timer->Channel(), false); - DeviceUsed[Device->DeviceNumber()] = Now; + if (Device->SwitchChannel(Timer->Channel(), false)) + Device->SetOccupied(TIMERDEVICETIMEOUT); } if (cDevice::PrimaryDevice()->HasDecoder() && !cDevice::PrimaryDevice()->HasProgramme()) { // the previous SwitchChannel() has switched away the current live channel |