diff options
author | Klaus Schmidinger <Klaus (dot) Schmidinger (at) tvdr (dot) de> | 2010-01-06 13:34:00 +0100 |
---|---|---|
committer | Klaus Schmidinger <Klaus (dot) Schmidinger (at) tvdr (dot) de> | 2010-01-06 13:34:00 +0100 |
commit | 939081e274d0a9868e5ba9a7951666ad508afb96 (patch) | |
tree | e79853c0ab397e609897a8f9dfc731231ce0aee4 /PLUGINS/src/dvbsddevice/dvbsdffosd.c | |
parent | ea01358b3bca9d55402ba632c95cdd6458abfdb3 (diff) | |
download | vdr-patch-lnbsharing-939081e274d0a9868e5ba9a7951666ad508afb96.tar.gz vdr-patch-lnbsharing-939081e274d0a9868e5ba9a7951666ad508afb96.tar.bz2 |
Version 1.7.11vdr-1.7.11
- Fixed resetting the file size when regenerating the index file.
- The new function cDevice::PatPmtParser() can be used in derived devices to access
the PAT/PMT of the currently replayed material.
- Updated the Italian OSD texts (thanks to Diego Pierotto).
- The PCR pid in generated PMTs is now set to 0x1FFF ("no PCR pid") in
cPatPmtGenerator::GeneratePmt(), because VDR doesn't record the PCR pid.
- Updated the Estonian OSD texts (thanks to Arthur Konovalov).
- The 'sky' plugin is no longer part of the VDR source.
- Improved SPU handling on devices with limited OSD capabilities (thanks to
Matthieu Castet).
- Several code modifications to avoid compiler warnings (thanks to Winfried Köhler).
- Added stream type 11172 AUDIO to cPatPmtParser::ParsePmt() (thanks to Johann
Friedrichs).
- Removed debug output of '-' from cTransfer::Receive().
- Added defines for large files to the 'newplugin' script (reported by Udo Richter).
- Removed the workaround for short channel names of "Kabel Deutschland", because
apparently they now have their data according to the DVB standard (thanks to
Johann Friedrichs).
- Some fixes to dvbspu.[hc] (thanks to Johann Friedrichs).
- Fixed a busy loop when moving editing marks (thanks to Johann Friedrichs).
- Updated sources.conf (thanks to Derek Kelly).
- Modified cCharSetConv so that it can be used to convert from "whatever VDR uses"
to a given code (thanks to Joachim Wilke).
- Channel names containing commas are now handled correctly in channels.conf.
If a channel's short name contains a comma, it is replaced with a '.'.
- cDevice now logs the device number when a new device is created.
- Fixed handling STREAMTYPE_11172_AUDIO in cPatPmtParser::ParsePmt().
- cParsePatPmt now has functions to retrieve the audio, dolby and subtitle pids.
- cPatFilter::Process() now only stores CA descriptors for video and audio pids
(thanks to Francesco Saverio Schiavarelli for reporting a problem with channels
that have some encrypted components that VDR doesn't use).
- cDevice::AddPid() now stores the stream type of the given pid (thanks to Andreas
Regel).
- Added cFont::FontName() and cFont::Size() (thanks to Andreas Regel).
- cPatPmtParser now also stores the audio stream types.
- The support for full featured DVB cards of the TT/FuSi design has been moved
into the new plugin 'dvbsddevice'. On systems that use such a card as their
primary device, this plugin now needs to be loaded when running VDR in order
to view live or recorded video. If the plugin is not loaded, the card will
be treated like a budget DVB card, and there will be no OSD or viewing
capability.
- Fixed handling the "CA PMT" generation (revised a change not mentioned in version
1.7.9's changes, which caused a malfunction with Conax and Viaccess CAMs).
- Fixed stopping subtitle display when switching the primary device (thanks to
Anssi Hannula).
IMPORTANT NOTE TO PLUGIN AUTHORS: a plugin that implements a derived cDevice
class that can replay video must now call the MakePrimaryDevice() function of
its base class.
- Fixed compiler warnings "format not a string literal and no format arguments"
in some syslog calls (thanks to Rolf Ahrenberg).
- The new command line options --edit and --genindex can be used to edit a
recording or generate its index without actually starting the entire VDR
(based on a patch from Helmut Auer).
- Improved the description of the transponder parameters in vdr.5 (thanks to
Winfried Köhler).
- Avoiding setting the video stream type to 2 if the vpid is 0 (problem reported
by Arthur Konovalov).
- Implemented handling the "Content Descriptor" (based on a patch from Rolf
Ahrenberg). The 'classic', 'sttng' and 'curses' skins display the textual
representation of the content descriptors as "genre". The epg.data file stores
the genre using the tag character 'G'.
- Implemented handling the "Parental Rating Descriptor" (based on a patch from Rolf
Ahrenberg). The 'classic', 'sttng' and 'curses' skins display the parental
rating (if given) in their event displays. The epg.data file stores
the parental rating using the tag character 'R'.
IMPORTANT NOTE: if VDR doesn't display a parental rating, this does not
necessarily mean that the given programme is suitable for all audiences!
- Rearranged cEvent members to minimize memory waste.
- After a CLRE command, no further EPG processing is now done for 10 seconds,
so that data sent with subsequent PUTE commands doesn't interfere with data
from the broadcasters (suggested by Helmut Auer).
- Added support for DVB cards with multiple fontends. Note that this only
works for DVB cards where each frontend can be used independently of all
the others on the same adapter.
- Fixed plugin arguments corruption with glibc 2.11 on x86_64 (thanks to
Anssi Hannula).
Diffstat (limited to 'PLUGINS/src/dvbsddevice/dvbsdffosd.c')
-rw-r--r-- | PLUGINS/src/dvbsddevice/dvbsdffosd.c | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/PLUGINS/src/dvbsddevice/dvbsdffosd.c b/PLUGINS/src/dvbsddevice/dvbsdffosd.c new file mode 100644 index 0000000..4ff8db9 --- /dev/null +++ b/PLUGINS/src/dvbsddevice/dvbsdffosd.c @@ -0,0 +1,213 @@ +/* + * dvbsdffosd.c: Implementation of the DVB SD Full Featured On Screen Display + * + * See the README file for copyright information and how to reach the author. + * + * $Id: dvbsdffosd.c 2.1 2009/12/29 11:52:48 kls Exp $ + */ + +#include "dvbsdffosd.h" +#include <linux/dvb/osd.h> +#include <signal.h> +#include <sys/ioctl.h> +#include <sys/unistd.h> +#include "vdr/tools.h" + +// --- cDvbSdFfOsd ----------------------------------------------------------- + +#define MAXNUMWINDOWS 7 // OSD windows are counted 1...7 +#define MAXOSDMEMORY 92000 // number of bytes available to the OSD (for unmodified DVB cards) + +class cDvbSdFfOsd : public cOsd { +private: + int osdDev; + int osdMem; + bool shown; + void Cmd(OSD_Command cmd, int color = 0, int x0 = 0, int y0 = 0, int x1 = 0, int y1 = 0, const void *data = NULL); +protected: + virtual void SetActive(bool On); +public: + cDvbSdFfOsd(int Left, int Top, int OsdDev, uint Level); + virtual ~cDvbSdFfOsd(); + virtual eOsdError CanHandleAreas(const tArea *Areas, int NumAreas); + virtual eOsdError SetAreas(const tArea *Areas, int NumAreas); + virtual void Flush(void); + }; + +cDvbSdFfOsd::cDvbSdFfOsd(int Left, int Top, int OsdDev, uint Level) +:cOsd(Left, Top, Level) +{ + osdDev = OsdDev; + shown = false; + if (osdDev < 0) + esyslog("ERROR: invalid OSD device handle (%d)!", osdDev); + else { + osdMem = MAXOSDMEMORY; +#ifdef OSD_CAP_MEMSIZE + // modified DVB cards may have more OSD memory: + osd_cap_t cap; + cap.cmd = OSD_CAP_MEMSIZE; + if (ioctl(osdDev, OSD_GET_CAPABILITY, &cap) == 0) + osdMem = cap.val; +#endif + } +} + +cDvbSdFfOsd::~cDvbSdFfOsd() +{ + SetActive(false); +} + +void cDvbSdFfOsd::SetActive(bool On) +{ + if (On != Active()) { + cOsd::SetActive(On); + if (On) { + // must clear all windows here to avoid flashing effects - doesn't work if done + // in Flush() only for the windows that are actually used... + for (int i = 0; i < MAXNUMWINDOWS; i++) { + Cmd(OSD_SetWindow, 0, i + 1); + Cmd(OSD_Clear); + } + if (GetBitmap(0)) // only flush here if there are already bitmaps + Flush(); + } + else if (shown) { + cBitmap *Bitmap; + for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) { + Cmd(OSD_SetWindow, 0, i + 1); + Cmd(OSD_Close); + } + shown = false; + } + } +} + +eOsdError cDvbSdFfOsd::CanHandleAreas(const tArea *Areas, int NumAreas) +{ + eOsdError Result = cOsd::CanHandleAreas(Areas, NumAreas); + if (Result == oeOk) { + if (NumAreas > MAXNUMWINDOWS) + return oeTooManyAreas; + int TotalMemory = 0; + for (int i = 0; i < NumAreas; i++) { + if (Areas[i].bpp != 1 && Areas[i].bpp != 2 && Areas[i].bpp != 4 && Areas[i].bpp != 8) + return oeBppNotSupported; + if ((Areas[i].Width() & (8 / Areas[i].bpp - 1)) != 0) + return oeWrongAlignment; + if (Areas[i].Width() < 1 || Areas[i].Height() < 1 || Areas[i].Width() > 720 || Areas[i].Height() > 576) + return oeWrongAreaSize; + TotalMemory += Areas[i].Width() * Areas[i].Height() / (8 / Areas[i].bpp); + } + if (TotalMemory > osdMem) + return oeOutOfMemory; + } + return Result; +} + +eOsdError cDvbSdFfOsd::SetAreas(const tArea *Areas, int NumAreas) +{ + if (shown) { + cBitmap *Bitmap; + for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) { + Cmd(OSD_SetWindow, 0, i + 1); + Cmd(OSD_Close); + } + shown = false; + } + return cOsd::SetAreas(Areas, NumAreas); +} + +void cDvbSdFfOsd::Cmd(OSD_Command cmd, int color, int x0, int y0, int x1, int y1, const void *data) +{ + if (osdDev >= 0) { + osd_cmd_t dc; + dc.cmd = cmd; + dc.color = color; + dc.x0 = x0; + dc.y0 = y0; + dc.x1 = x1; + dc.y1 = y1; + dc.data = (void *)data; + ioctl(osdDev, OSD_SEND_CMD, &dc); + } +} + +void cDvbSdFfOsd::Flush(void) +{ + if (!Active()) + return; + cBitmap *Bitmap; + for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) { + Cmd(OSD_SetWindow, 0, i + 1); + if (!shown) + Cmd(OSD_Open, Bitmap->Bpp(), Left() + Bitmap->X0(), Top() + Bitmap->Y0(), Left() + Bitmap->X0() + Bitmap->Width() - 1, Top() + Bitmap->Y0() + Bitmap->Height() - 1, (void *)1); // initially hidden! + int x1 = 0, y1 = 0, x2 = 0, y2 = 0; + if (!shown || Bitmap->Dirty(x1, y1, x2, y2)) { + if (!shown) { + x1 = y1 = 0; + x2 = Bitmap->Width() - 1; + y2 = Bitmap->Height() - 1; + } + //TODO Workaround: apparently the bitmap sent to the driver always has to be a multiple + //TODO of 8 bits wide, and (dx * dy) also has to be a multiple of 8. + //TODO Fix driver (should be able to handle any size bitmaps!) + while ((x1 > 0 || x2 < Bitmap->Width() - 1) && ((x2 - x1) & 7) != 7) { + if (x2 < Bitmap->Width() - 1) + x2++; + else if (x1 > 0) + x1--; + } + //TODO "... / 2" <==> Bpp??? + while ((y1 > 0 || y2 < Bitmap->Height() - 1) && (((x2 - x1 + 1) * (y2 - y1 + 1) / 2) & 7) != 0) { + if (y2 < Bitmap->Height() - 1) + y2++; + else if (y1 > 0) + y1--; + } + while ((x1 > 0 || x2 < Bitmap->Width() - 1) && (((x2 - x1 + 1) * (y2 - y1 + 1) / 2) & 7) != 0) { + if (x2 < Bitmap->Width() - 1) + x2++; + else if (x1 > 0) + x1--; + } + // commit colors: + int NumColors; + const tColor *Colors = Bitmap->Colors(NumColors); + if (Colors) { + //TODO this should be fixed in the driver! + tColor colors[NumColors]; + for (int i = 0; i < NumColors; i++) { + // convert AARRGGBB to AABBGGRR (the driver expects the colors the wrong way): + colors[i] = (Colors[i] & 0xFF000000) | ((Colors[i] & 0x0000FF) << 16) | (Colors[i] & 0x00FF00) | ((Colors[i] & 0xFF0000) >> 16); + } + Colors = colors; + //TODO end of stuff that should be fixed in the driver + Cmd(OSD_SetPalette, 0, NumColors - 1, 0, 0, 0, Colors); + } + // commit modified data: + Cmd(OSD_SetBlock, Bitmap->Width(), x1, y1, x2, y2, Bitmap->Data(x1, y1)); + } + Bitmap->Clean(); + } + if (!shown) { + // Showing the windows in a separate loop to avoid seeing them come up one after another + for (int i = 0; (Bitmap = GetBitmap(i)) != NULL; i++) { + Cmd(OSD_SetWindow, 0, i + 1); + Cmd(OSD_MoveWindow, 0, Left() + Bitmap->X0(), Top() + Bitmap->Y0()); + } + shown = true; + } +} + +// --- cDvbOsdProvider ------------------------------------------------------- + +cDvbOsdProvider::cDvbOsdProvider(int OsdDev) +{ + osdDev = OsdDev; +} + +cOsd *cDvbOsdProvider::CreateOsd(int Left, int Top, uint Level) +{ + return new cDvbSdFfOsd(Left, Top, osdDev, Level); +} |