diff options
author | Andreas Regel <andreas.regel@powarman.de> | 2004-06-13 23:00:00 +0200 |
---|---|---|
committer | Andreas Regel <andreas.regel@powarman.de> | 2004-06-13 23:00:00 +0200 |
commit | 1df133b2a0565a35c3b07e043bd04b449869a0cb (patch) | |
tree | 7e29cb4b4e7ed2143a96b06a114cf68320ca9a2e | |
parent | 2e17045cd1b8abe771d136cbc3a815b547d32280 (diff) | |
download | vdr-plugin-osdpip-1df133b2a0565a35c3b07e043bd04b449869a0cb.tar.gz vdr-plugin-osdpip-1df133b2a0565a35c3b07e043bd04b449869a0cb.tar.bz2 |
Release version 0.0.5v0.0.5
- added support for VDR version 1.3.7 and later (VDR 1.2.6 is still
supported, no guarantee for 1.3.0-1.3.6)
- no patching required any longer with 1.3.7 and later
- fixed info window colors if palette patch is not applied (VDR up to 1.3.6,
index patch must be applied)
- added german translations
- added finnish translations (thanks to Rolf Ahrenberg)
-rw-r--r-- | HISTORY | 13 | ||||
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | README | 21 | ||||
-rw-r--r-- | TODO | 3 | ||||
-rw-r--r-- | config.c | 129 | ||||
-rw-r--r-- | config.h | 2 | ||||
-rw-r--r-- | decoder.c | 100 | ||||
-rw-r--r-- | decoder.h | 41 | ||||
-rw-r--r-- | i18n.c | 694 | ||||
-rw-r--r-- | osd.c | 542 | ||||
-rw-r--r-- | osd.h | 43 | ||||
-rw-r--r-- | osdpip.c | 81 | ||||
-rw-r--r-- | patches/vdr-1.2.6-256-indexes.diff | 76 | ||||
-rw-r--r-- | patches/vdr-1.2.6-256-palette.diff | 137 | ||||
-rw-r--r-- | patches/vdr-1.2.6-indexes.diff | 85 | ||||
-rw-r--r-- | patches/vdr-1.2.6-palette.diff | 139 | ||||
-rw-r--r-- | patches/vdr-1.2.6.diff | 77 | ||||
-rw-r--r-- | patches/vdr-1.2.6_256.diff | 75 | ||||
-rw-r--r-- | quantize.c | 22 | ||||
-rw-r--r-- | receiver.c | 22 |
20 files changed, 1722 insertions, 582 deletions
@@ -1,11 +1,22 @@ VDR Plugin 'osdpip' Revision History ------------------------------------ +2004-06-13: Version 0.0.5 (written by Andreas Regel) +- added support for VDR version 1.3.7 and later (VDR 1.2.6 is still + supported, no guarantee for 1.3.0-1.3.6) +- no patching required any longer with 1.3.7 and later +- fixed info window colors if palette patch is not applied (VDR up to 1.3.6, + index patch must be applied) +- added german translations +- added finnish translations (thanks to Rolf Ahrenberg) + + 2004-02-04: Version 0.0.4 (written by Andreas Regel) - a second osd window with some information about the viewed channel and event is now shown on screen + 2004-01-24: Version 0.0.3 (written by Andreas Regel) - new TS->ES remuxer: now using VDR's cRemux for TS->PES and some own code @@ -18,6 +29,7 @@ VDR Plugin 'osdpip' Revision History - 128 colors with variable palette using Wu's quantizer (patch needed) - changed osd size setting to 6 configurable values + 2004-01-03: Version 0.0.2 - Added setup menu @@ -26,6 +38,7 @@ VDR Plugin 'osdpip' Revision History - OSD window size is calculated dynamically depending on stream dimensions - Added translations + 2004-01-02: Version 0.0.1 - Initial revision. @@ -47,7 +47,7 @@ DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"' ### The object files (add further files here): -OBJS = $(PLUGIN).o osd.o receiver.o config.o i18n.o pes.o quantize.o +OBJS = $(PLUGIN).o osd.o receiver.o config.o i18n.o pes.o quantize.o decoder.o ifdef FFMPEG_STATIC DEFINES += -DHAVE_FFMPEG_STATIC @@ -65,6 +65,11 @@ have it next to your vdr folder (e.g. as the DXR3 plugin needs it), you have to compile with make FFMPEG_STATIC=1 plugins. Ffmpeg must then be present in a folder (or symlink) called "ffmpeg". +NOTE: Patching VDR is not needed if you are using a VDR version greater than +1.3.7. + +Patching VDR: + NOTE: The next step is not needed if you use the variable color patch provided below that! @@ -75,13 +80,23 @@ line to 256. If you don't want 256 color support, you can skip this part. #define MAXNUMCOLORS 256 +If you want an error free 256 color mode you will have to further modify VDR's +source code using a patch from patches subdirectory. It fixes a bug of all VDR +versions up to 1.3.3. I provide two versions of the patch: +vdr-1.2.6-indexes.diff for a plain VDR installation and +vdr-1.2.6-256-indexes.diff for a version that already has 256 color support. + +To apply this patch call + patch -p1 < PLUGINS/src/osdpip/patches/vdr-1.2.6-indexes.diff +from VDR's source code directory. + If you want variable palette color mode you will have to further modify VDR's source code using a patch from patches subdirectory. I provide two versions of -the patch: vdr-1.2.6.diff for a plain VDR installation and vdr-1.2.6_256.diff -for a version that already has 256 color support. +the patch: vdr-1.2.6-palette.diff for a plain VDR installation and +vdr-1.2.6-256-palette.diff for a version that already has 256 color support. To apply this patch call - patch -p1 < PLUGINS/src/osdpip/patches/vdr-1.2.6.diff + patch -p1 < PLUGINS/src/osdpip/patches/vdr-1.2.6-palette.diff from VDR's source code directory. Now, you have to re-build VDR and Plugins. @@ -1,3 +1,6 @@ - improve fixed palette color quantization - localization - vdr-like navigation through channels +- support other aspect ratios than 4:3 +- automatic frame drop + @@ -4,62 +4,59 @@ * See the README file for copyright information and how to reach the author. */ +#include <vdr/config.h> + #include "config.h" -#if MAXNUMCOLORS < 256 -# warning WARNING: YOU WILL NOT BE ABLE TO USE 256 COLOR PIP -#endif +#if VDRVERSNUM < 10307 +# if MAXNUMCOLORS < 256 +# warning WARNING: YOU WILL NOT BE ABLE TO USE 256 COLOR PIP +# endif -#ifndef VDR_OSDPIP_PATCHED -# warning WARNING: YOU WILL NOT BE ABLE TO USE VARIABLE COLOR PIP -#endif +# ifndef VDR_OSDPIP_PATCHED +# warning WARNING: YOU WILL NOT BE ABLE TO USE VARIABLE COLOR PIP +# endif -#if MAXNUMCOLORS < 256 +# if MAXNUMCOLORS < 256 const int kColorDepths = 1; -#else -# ifndef VDR_OSDPIP_PATCHED -const int kColorDepths = 3; # else +# ifndef VDR_OSDPIP_PATCHED +const int kColorDepths = 3; +# else const int kColorDepths = 4; +# endif # endif +#else +const int kColorDepths = 4; #endif const int kSizes = 6; const int kFrameModes = 3; const int kInfoPositions = 4; -const char *ColorDepthItems[] = { - "Greyscale (16)", - "Greyscale (128)", - "Color (256, fixed)", - "Color (128, variable)" -}; +const char * ColorDepthItems[] = {NULL, NULL, NULL, NULL, NULL}; // initialized later +const char * InfoPositionItems[] = {NULL, NULL, NULL, NULL, NULL}; // initialized later -const char *SizeItems[] = { +const char * SizeItems[] = { "120x96", "160x128", "200x160", "240x192", "280x224", - "320x256" + "320x256", + NULL }; -const char *FrameModeItems[] = { - "I-Frames", - "I-, P-Frames", - "I-, P-, B-Frames" -}; - -const char *InfoPositionItems[] = { - "top left", - "top right", - "bottom left", - "bottom right" +const char * FrameModeItems[] = { + "I", + "I, P", + "I, P, B" }; cOsdPipSetup OsdPipSetup; -cOsdPipSetup::cOsdPipSetup(void) { +cOsdPipSetup::cOsdPipSetup(void) +{ XPosition = 50; YPosition = 50; CropLeft = 5; @@ -76,7 +73,8 @@ cOsdPipSetup::cOsdPipSetup(void) { InfoPosition = kInfoBottomLeft; } -bool cOsdPipSetup::SetupParse(const char *Name, const char *Value) { +bool cOsdPipSetup::SetupParse(const char *Name, const char *Value) +{ if (strcmp(Name, "XPosition") == 0) XPosition = atoi(Value); else if (strcmp(Name, "YPosition") == 0) YPosition = atoi(Value); else if (strcmp(Name, "CropLeft") == 0) CropLeft = atoi(Value); @@ -95,48 +93,57 @@ bool cOsdPipSetup::SetupParse(const char *Name, const char *Value) { return true; } -cOsdPipSetupPage::cOsdPipSetupPage(void) { +cOsdPipSetupPage::cOsdPipSetupPage(void) +{ m_NewOsdPipSetup = OsdPipSetup; + ColorDepthItems[0] = tr("Greyscale (16)"); + ColorDepthItems[1] = tr("Greyscale (256)"); + ColorDepthItems[2] = tr("Color (256, fixed)"); + ColorDepthItems[3] = tr("Color (128, variable)"); + + InfoPositionItems[0] = tr("top left"); + InfoPositionItems[1] = tr("top right"); + InfoPositionItems[2] = tr("bottom left"); + InfoPositionItems[3] = tr("bottom right"); + + Add(new cMenuEditIntItem(tr("X Position"), &m_NewOsdPipSetup.XPosition, 0, 600)); + Add(new cMenuEditIntItem(tr("Y Position"), &m_NewOsdPipSetup.YPosition, 0, 470)); Add(new cMenuEditIntItem(tr("Crop left"), &m_NewOsdPipSetup.CropLeft, 0, 80)); - Add(new cMenuEditIntItem(tr("Crop right"), &m_NewOsdPipSetup.CropRight, 0, - 80)); - Add(new cMenuEditIntItem(tr("Crop at top"), &m_NewOsdPipSetup.CropTop, 0, - 80)); - Add(new cMenuEditIntItem(tr("Crop at bottom"), &m_NewOsdPipSetup.CropBottom, - 0, 80)); - Add(new cMenuEditStraItem(tr("Color depth"), - &m_NewOsdPipSetup.ColorDepth, kColorDepths, ColorDepthItems)); - Add(new cMenuEditStraItem(tr("Size"), - &m_NewOsdPipSetup.Size, kSizes, SizeItems)); - Add(new cMenuEditStraItem(tr("Frames to display"), - &m_NewOsdPipSetup.FrameMode, kFrameModes, FrameModeItems)); + Add(new cMenuEditIntItem(tr("Crop right"), &m_NewOsdPipSetup.CropRight, 0, 80)); + Add(new cMenuEditIntItem(tr("Crop at top"), &m_NewOsdPipSetup.CropTop, 0, 80)); + Add(new cMenuEditIntItem(tr("Crop at bottom"), &m_NewOsdPipSetup.CropBottom, 0, 80)); + Add(new cMenuEditStraItem(tr("Color depth"), &m_NewOsdPipSetup.ColorDepth, kColorDepths, ColorDepthItems)); + Add(new cMenuEditStraItem(tr("Size"), &m_NewOsdPipSetup.Size, kSizes, SizeItems)); + Add(new cMenuEditStraItem(tr("Frames to display"), &m_NewOsdPipSetup.FrameMode, kFrameModes, FrameModeItems)); Add(new cMenuEditIntItem(tr("Drop frames"), &m_NewOsdPipSetup.FrameDrop, 0, 2)); Add(new cMenuEditBoolItem(tr("Swap FFMPEG output"), &m_NewOsdPipSetup.SwapFfmpeg)); Add(new cMenuEditBoolItem(tr("Show info window"), &m_NewOsdPipSetup.ShowInfo)); Add(new cMenuEditIntItem(tr("Info window width"), &m_NewOsdPipSetup.InfoWidth, 200, 600)); - Add(new cMenuEditStraItem(tr("Info window position"), - &m_NewOsdPipSetup.InfoPosition, kInfoPositions, InfoPositionItems)); + Add(new cMenuEditStraItem(tr("Info window position"), &m_NewOsdPipSetup.InfoPosition, kInfoPositions, InfoPositionItems)); } -cOsdPipSetupPage::~cOsdPipSetupPage() { +cOsdPipSetupPage::~cOsdPipSetupPage() +{ } -void cOsdPipSetupPage::Store(void) { +void cOsdPipSetupPage::Store(void) +{ OsdPipSetup = m_NewOsdPipSetup; - SetupStore("XPosition", OsdPipSetup.XPosition); - SetupStore("YPosition", OsdPipSetup.YPosition); - SetupStore("CropLeft", OsdPipSetup.CropLeft); - SetupStore("CropRight", OsdPipSetup.CropRight); - SetupStore("CropTop", OsdPipSetup.CropTop); - SetupStore("CropBottom", OsdPipSetup.CropBottom); - SetupStore("ColorDepth", OsdPipSetup.ColorDepth); - SetupStore("Size", OsdPipSetup.Size); - SetupStore("FrameMode", OsdPipSetup.FrameMode); - SetupStore("FrameDrop", OsdPipSetup.FrameDrop); - SetupStore("SwapFfmpeg", OsdPipSetup.SwapFfmpeg); - SetupStore("ShowInfo", OsdPipSetup.ShowInfo); - SetupStore("InfoWidth", OsdPipSetup.InfoWidth); + SetupStore("XPosition", OsdPipSetup.XPosition); + SetupStore("YPosition", OsdPipSetup.YPosition); + SetupStore("CropLeft", OsdPipSetup.CropLeft); + SetupStore("CropRight", OsdPipSetup.CropRight); + SetupStore("CropTop", OsdPipSetup.CropTop); + SetupStore("CropBottom", OsdPipSetup.CropBottom); + SetupStore("ColorDepth", OsdPipSetup.ColorDepth); + SetupStore("Size", OsdPipSetup.Size); + SetupStore("FrameMode", OsdPipSetup.FrameMode); + SetupStore("FrameDrop", OsdPipSetup.FrameDrop); + SetupStore("SwapFfmpeg", OsdPipSetup.SwapFfmpeg); + SetupStore("ShowInfo", OsdPipSetup.ShowInfo); + SetupStore("InfoWidth", OsdPipSetup.InfoWidth); SetupStore("InfoPosition", OsdPipSetup.InfoPosition); } + @@ -10,7 +10,7 @@ #include <vdr/plugin.h> const int kDepthGrey16 = 0; -const int kDepthGrey128 = 1; +const int kDepthGrey256 = 1; const int kDepthColor256fix = 2; const int kDepthColor128var = 3; diff --git a/decoder.c b/decoder.c new file mode 100644 index 0000000..eaa3160 --- /dev/null +++ b/decoder.c @@ -0,0 +1,100 @@ +/* + * OSD Picture in Picture plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + */ + +#include <stdio.h> +#include <stdlib.h> + +#include "decoder.h" +#include "config.h" + + +int cDecoder::Open() +{ + m_Codec = avcodec_find_decoder(CODEC_ID_MPEG2VIDEO); + if (!m_Codec) + { + printf("codec not found\n"); + return -1; + } + m_Context = avcodec_alloc_context(); + if (avcodec_open(m_Context, m_Codec) < 0) + { + printf("could not open codec\n"); + return -1; + } + m_PicDecoded = avcodec_alloc_frame(); + m_PicResample = avcodec_alloc_frame(); + m_BufferResample = new unsigned char[(400 * 300 * 3) / 2]; // size for YUV 420 + m_PicConvert = avcodec_alloc_frame(); + m_BufferConvert = new unsigned char[400 * 300 * 4]; // size for RGBA32 + + return 0; +} + +int cDecoder::Close() +{ + delete[] m_BufferConvert; + free(m_PicConvert); + delete[] m_BufferResample; + free(m_PicResample); + avcodec_close(m_Context); + free(m_Context); + free(m_PicDecoded); + + return 0; +} + +int cDecoder::Decode(unsigned char * data, int length) +{ + int gotPicture, len; + + len = avcodec_decode_video(m_Context, m_PicDecoded, &gotPicture, data, length); + if (len < 0) + { + printf("Error while decoding frame\n"); + return -1; + } + if (!gotPicture) + { + return -1; + } + + return 0; +} + +int cDecoder::Resample(int width, int height) +{ + ImgReSampleContext * contextResample; + + m_Width = width; + m_Height = height; + contextResample = img_resample_full_init(m_Width, m_Height, + m_Context->width, m_Context->height, + OsdPipSetup.CropTop, OsdPipSetup.CropBottom, + OsdPipSetup.CropLeft, OsdPipSetup.CropRight); + if (!contextResample) { + printf("Error initializing resample context.\n"); + return -1; + } + avpicture_fill((AVPicture *) m_PicResample, m_BufferResample, + PIX_FMT_YUV420P, m_Width, m_Height); + img_resample(contextResample, (AVPicture *) m_PicResample, (AVPicture *) m_PicDecoded); + img_resample_close(contextResample); + + return 0; +} + +int cDecoder::ConvertToRGB() +{ + avpicture_fill((AVPicture *) m_PicConvert, m_BufferConvert, + PIX_FMT_RGBA32, m_Width, m_Height); + img_convert((AVPicture *) m_PicConvert, PIX_FMT_RGBA32, + (AVPicture *) m_PicResample, PIX_FMT_YUV420P, + m_Width, m_Height); + + return 0; +} + diff --git a/decoder.h b/decoder.h new file mode 100644 index 0000000..d9ca3e7 --- /dev/null +++ b/decoder.h @@ -0,0 +1,41 @@ +/* + * OSD Picture in Picture plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + */ + +#ifndef VDR_OSDPIP_DECODER_H +#define VDR_OSDPIP_DECODER_H + +extern "C" +{ +#ifdef HAVE_FFMPEG_STATIC +# include <avcodec.h> +#else +# include <ffmpeg/avcodec.h> +#endif +} + +class cDecoder { +private: + AVCodec * m_Codec; + AVCodecContext * m_Context; + AVFrame * m_PicDecoded; + AVFrame * m_PicResample; + AVFrame * m_PicConvert; + unsigned char * m_BufferResample; + unsigned char * m_BufferConvert; + int m_Width; + int m_Height; +public: + int Open(); + int Close(); + int Decode(unsigned char * data, int length); + int Resample(int width, int height); + int ConvertToRGB(); + AVFrame * PicResample() { return m_PicResample; } + AVFrame * PicConvert() { return m_PicConvert; } + float AspectRatio() { return m_Context->aspect_ratio; } +}; + +#endif // VDR_OSDPIP_DECODER_H @@ -7,124 +7,582 @@ #include "i18n.h" const tI18nPhrase Phrases[] = { - { "Picture-in-Picture", // English - "Bild-in-Bild", // Deutsch - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "", // Suomi - "", // Polski - "", // Español - "", // Ellinika - "", // Svenska - "", // Romaneste - "", // Magyar - "" // Catala - }, - { "Crop left", // English - "Links abschneiden", // Deutsch - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "", // Suomi - "", // Polski - "", // Español - "", // Ellinika - "", // Svenska - "", // Romaneste - "", // Magyar - "" // Catala - }, - { "Crop right", // English - "Rechts abschneiden", // Deutsch - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "", // Suomi - "", // Polski - "", // Español - "", // Ellinika - "", // Svenska - "", // Romaneste - "", // Magyar - "" // Catala - }, - { "Crop at top", // English - "Oben abschneiden", // Deutsch - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "", // Suomi - "", // Polski - "", // Español - "", // Ellinika - "", // Svenska - "", // Romaneste - "", // Magyar - "" // Catala - }, - { "Crop at bottom", // English - "Unten abschneiden", // Deutsch - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "", // Suomi - "", // Polski - "", // Español - "", // Ellinika - "", // Svenska - "", // Romaneste - "", // Magyar - "" // Catala - }, - { "Zoom factor", // English - "Verkleinerungsfaktor", // Deutsch - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "", // Suomi - "", // Polski - "", // Español - "", // Ellinika - "", // Svenska - "", // Romaneste - "", // Magyar - "" // Catala - }, - { "Colordepth", // English - "Farbtiefe", // Deutsch - "", // Slovenski - "", // Italiano - "", // Nederlands - "", // Português - "", // Français - "", // Norsk - "", // Suomi - "", // Polski - "", // Español - "", // Ellinika - "", // Svenska - "", // Romaneste - "", // Magyar - "" // Catala + { + "OSD Picture-in-Picture", // English + "OSD Bild-in-Bild", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Kuva kuvassa -toiminto (OSD)", // Suomi + "", // Polski + "", // Español + "", // Ellinika + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Catala +#if VDRVERSNUM > 10302 + "", // Russian +# if VDRVERSNUM > 10307 + "", // Croatian +# endif +#endif + }, + { + "Picture-in-Picture", // English + "Bild-in-Bild", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Kuva kuvassa", // Suomi + "", // Polski + "", // Español + "", // Ellinika + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Catala +#if VDRVERSNUM > 10302 + "", // Russian +# if VDRVERSNUM > 10307 + "", // Croatian +# endif +#endif + }, + { + "Crop left", // English + "Links abschneiden", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Leikkaa vasemmalta", // Suomi + "", // Polski + "", // Español + "", // Ellinika + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Catala +#if VDRVERSNUM > 10302 + "", // Russian +# if VDRVERSNUM > 10307 + "", // Croatian +# endif +#endif + }, + { + "Crop right", // English + "Rechts abschneiden", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Leikkaa oikealta", // Suomi + "", // Polski + "", // Español + "", // Ellinika + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Catala +#if VDRVERSNUM > 10302 + "", // Russian +# if VDRVERSNUM > 10307 + "", // Croatian +# endif +#endif + }, + { + "Crop at top", // English + "Oben abschneiden", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Leikkaa ylhäältä", // Suomi + "", // Polski + "", // Español + "", // Ellinika + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Catala +#if VDRVERSNUM > 10302 + "", // Russian +# if VDRVERSNUM > 10307 + "", // Croatian +# endif +#endif + }, + { + "Crop at bottom", // English + "Unten abschneiden", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Leikkaa alhaalta", // Suomi + "", // Polski + "", // Español + "", // Ellinika + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Catala +#if VDRVERSNUM > 10302 + "", // Russian +# if VDRVERSNUM > 10307 + "", // Croatian +# endif +#endif + }, + { + "Color depth", // English + "Farbtiefe", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Värisyvyys", // Suomi + "", // Polski + "", // Español + "", // Ellinika + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Catala +#if VDRVERSNUM > 10302 + "", // Russian +# if VDRVERSNUM > 10307 + "", // Croatian +# endif +#endif + }, + { + "Size", // English + "Größe", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Koko", // Suomi + "", // Polski + "", // Español + "", // Ellinika + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Catala +#if VDRVERSNUM > 10302 + "", // Russian +# if VDRVERSNUM > 10307 + "", // Croatian +# endif +#endif + }, + { + "Frames to display", // English + "Darzustellende Bilder", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Näytä kehykset", // Suomi + "", // Polski + "", // Español + "", // Ellinika + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Catala +#if VDRVERSNUM > 10302 + "", // Russian +# if VDRVERSNUM > 10307 + "", // Croatian +# endif +#endif + }, + { + "Drop frames", // English + "Einzelbilder auslassen", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Hylkää kehyksiä", // Suomi + "", // Polski + "", // Español + "", // Ellinika + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Catala +#if VDRVERSNUM > 10302 + "", // Russian +# if VDRVERSNUM > 10307 + "", // Croatian +# endif +#endif + }, + { + "Swap FFMPEG output", // English + "FFMPEG Ausgabe umdrehen", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Invertoi FFMPEG-kuva", // Suomi + "", // Polski + "", // Español + "", // Ellinika + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Catala +#if VDRVERSNUM > 10302 + "", // Russian +# if VDRVERSNUM > 10307 + "", // Croatian +# endif +#endif + }, + { + "Show info window", // English + "Info-Fenster anzeigen", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Näytä kuvatieto", // Suomi + "", // Polski + "", // Español + "", // Ellinika + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Catala +#if VDRVERSNUM > 10302 + "", // Russian +# if VDRVERSNUM > 10307 + "", // Croatian +# endif +#endif + }, + { + "Info window width", // English + "Breite Info-Fenster", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Kuvatiedon leveys", // Suomi + "", // Polski + "", // Español + "", // Ellinika + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Catala +#if VDRVERSNUM > 10302 + "", // Russian +# if VDRVERSNUM > 10307 + "", // Croatian +# endif +#endif + }, + { + "Info window position", // English + "Position Info-Fenster", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Kuvatiedon sijainti", // Suomi + "", // Polski + "", // Español + "", // Ellinika + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Catala +#if VDRVERSNUM > 10302 + "", // Russian +# if VDRVERSNUM > 10307 + "", // Croatian +# endif +#endif + }, + { + "top left", // English + "oben links", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "vasen yläreuna", // Suomi + "", // Polski + "", // Español + "", // Ellinika + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Catala +#if VDRVERSNUM > 10302 + "", // Russian +# if VDRVERSNUM > 10307 + "", // Croatian +# endif +#endif + }, + { + "top right", // English + "oben rechts", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "oikea yläreuna", // Suomi + "", // Polski + "", // Español + "", // Ellinika + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Catala +#if VDRVERSNUM > 10302 + "", // Russian +# if VDRVERSNUM > 10307 + "", // Croatian +# endif +#endif + }, + { + "bottom left", // English + "unten links", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "vasen alareuna", // Suomi + "", // Polski + "", // Español + "", // Ellinika + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Catala +#if VDRVERSNUM > 10302 + "", // Russian +# if VDRVERSNUM > 10307 + "", // Croatian +# endif +#endif + }, + { + "bottom right", // English + "unten rechts", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "oikea alareuna", // Suomi + "", // Polski + "", // Español + "", // Ellinika + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Catala +#if VDRVERSNUM > 10302 + "", // Russian +# if VDRVERSNUM > 10307 + "", // Croatian +# endif +#endif + }, + { + "Greyscale (16)", // English + "16 Graustufen", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "harmaasävy (16)", // Suomi + "", // Polski + "", // Español + "", // Ellinika + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Catala +#if VDRVERSNUM > 10302 + "", // Russian +# if VDRVERSNUM > 10307 + "", // Croatian +# endif +#endif + }, + { + "Greyscale (256)", // English + "256 Graustufen", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "harmaasävy (256)", // Suomi + "", // Polski + "", // Español + "", // Ellinika + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Catala +#if VDRVERSNUM > 10302 + "", // Russian +# if VDRVERSNUM > 10307 + "", // Croatian +# endif +#endif + }, + { + "Color (256, fixed)", // English + "256 Farben (fest)", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "väri (256)", // Suomi + "", // Polski + "", // Español + "", // Ellinika + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Catala +#if VDRVERSNUM > 10302 + "", // Russian +# if VDRVERSNUM > 10307 + "", // Croatian +# endif +#endif + }, + { + "Color (128, variable)", // English + "128 Farben (variabel)", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "väri (128, vaihtuva)", // Suomi + "", // Polski + "", // Español + "", // Ellinika + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Catala +#if VDRVERSNUM > 10302 + "", // Russian +# if VDRVERSNUM > 10307 + "", // Croatian +# endif +#endif + }, + { + "X Position", // English + "X-Position", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Vaakasijainti", // Suomi + "", // Polski + "", // Español + "", // Ellinika + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Catala +#if VDRVERSNUM > 10302 + "", // Russian +# if VDRVERSNUM > 10307 + "", // Croatian +# endif +#endif + }, + { + "Y Position", // English + "Y-Position", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "Pystysijainti", // Suomi + "", // Polski + "", // Español + "", // Ellinika + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Catala +#if VDRVERSNUM > 10302 + "", // Russian +# if VDRVERSNUM > 10307 + "", // Croatian +# endif +#endif }, { NULL } }; + @@ -5,6 +5,7 @@ */ #include "osd.h" +#include "decoder.h" #include "quantize.h" #include "receiver.h" #include "config.h" @@ -12,21 +13,27 @@ #include <vdr/ringbuffer.h> #include <vdr/remux.h> -cOsdPipObject::cOsdPipObject(cDevice *Device, const cChannel *Channel): - cOsdObject(true) { +cOsdPipObject::cOsdPipObject(cDevice *Device, const cChannel *Channel) +: cOsdObject(true) +{ m_Channel = Channel; m_Osd = NULL; m_ESBuffer = new cRingBufferFrame(MEGABYTE(3), true); m_Active = false; m_Ready = false; +#if VDRVERSNUM >= 10307 + m_Reset = true; +#endif m_Width = m_Height = -1; m_Bitmap = NULL; + m_BitmapInfo = NULL; m_ShowTime = 0; m_ShowInfo = false; m_AlphaBase = 0xFF000000; - memset(m_Palette, 0, 1024); + for (int i = 0; i < 256; i++) + m_Palette[i] = 0xFD000000 | i; m_PaletteStart = 1; Device->SwitchChannel(m_Channel, false); @@ -34,8 +41,10 @@ cOsdPipObject::cOsdPipObject(cDevice *Device, const cChannel *Channel): Device->AttachReceiver(m_Receiver); } -cOsdPipObject::~cOsdPipObject() { - if (m_Active) { +cOsdPipObject::~cOsdPipObject() +{ + if (m_Active) + { m_Active = false; Cancel(3); } @@ -43,85 +52,58 @@ cOsdPipObject::~cOsdPipObject() { delete m_Receiver; if (m_Bitmap != NULL) delete m_Bitmap; + if (m_BitmapInfo != NULL) + delete m_BitmapInfo; if (m_Osd != NULL) delete m_Osd; } -int cOsdPipObject::Decode(unsigned char * data, int length) { - int gotPicture, len; - - len = avcodec_decode_video(m_Context, m_PicDecoded, &gotPicture, data, length); - if (len < 0) - { - printf("Error while decoding frame\n"); - return -1; - } - if (!gotPicture) - { - return -1; - } - - return 0; -} - -int cOsdPipObject::Resample() { - ImgReSampleContext * contextResample; - - contextResample = img_resample_full_init(m_Width, m_Height, - m_Context->width, m_Context->height, - OsdPipSetup.CropTop, OsdPipSetup.CropBottom, - OsdPipSetup.CropLeft, OsdPipSetup.CropRight); - if (!contextResample) { - printf("Error initializing resample context.\n"); - return -1; - } - avpicture_fill((AVPicture *) m_PicResample, m_BufferResample, - PIX_FMT_YUV420P, m_Width, m_Height); - img_resample(contextResample, (AVPicture *) m_PicResample, (AVPicture *) m_PicDecoded); - img_resample_close(contextResample); - - return 0; -} - -int cOsdPipObject::ConvertToRGB() { - avpicture_fill((AVPicture *) m_PicConvert, m_BufferConvert, - PIX_FMT_RGBA32, m_Width, m_Height); - img_convert((AVPicture *) m_PicConvert, PIX_FMT_RGBA32, - (AVPicture *) m_PicResample, PIX_FMT_YUV420P, - m_Width, m_Height); - - return 0; -} - -void cOsdPipObject::ProcessImage(unsigned char * data, int length) { +void cOsdPipObject::ProcessImage(unsigned char * data, int length) +{ unsigned int value; unsigned int * outputPalette; unsigned char * outputImage; - if (OsdPipSetup.FrameMode == kFrameModeI) { - if (m_FrameDrop == OsdPipSetup.FrameDrop) { + if (OsdPipSetup.FrameMode == kFrameModeI) + { + if (m_FrameDrop == OsdPipSetup.FrameDrop) + { m_FrameDrop = 0; - } else { + } + else + { m_FrameDrop++; return; } } - if (Decode(data, length) != 0) + if (decoder.Decode(data, length) != 0) return; if (OsdPipSetup.FrameMode == kFrameModeIP || - OsdPipSetup.FrameMode == kFrameModeIPB) { - if (m_FrameDrop == OsdPipSetup.FrameDrop) { + OsdPipSetup.FrameMode == kFrameModeIPB) + { + if (m_FrameDrop == OsdPipSetup.FrameDrop) + { m_FrameDrop = 0; - } else { + } + else + { m_FrameDrop++; return; } } - if (!m_Ready) { - switch (OsdPipSetup.Size) { + if (!m_Ready) + { +#if VDRVERSNUM >= 10307 + if (m_Bitmap != NULL) + delete m_Bitmap; + if (m_BitmapInfo != NULL) + delete m_BitmapInfo; +#endif + switch (OsdPipSetup.Size) + { case 0: m_Width = 120; m_Height = 96; break; case 1: m_Width = 160; m_Height = 128; break; case 2: m_Width = 200; m_Height = 160; break; @@ -129,10 +111,76 @@ void cOsdPipObject::ProcessImage(unsigned char * data, int length) { case 4: m_Width = 280; m_Height = 224; break; case 5: m_Width = 320; m_Height = 256; break; } - if (OsdPipSetup.ShowInfo) { +#if VDRVERSNUM >= 10307 + if (OsdPipSetup.ShowInfo) + { + switch (OsdPipSetup.InfoPosition) + { + case kInfoTopLeft: + m_InfoX = Setup.OSDLeft; + m_InfoY = Setup.OSDTop; + break; + case kInfoTopRight: + m_InfoX = Setup.OSDLeft + Setup.OSDWidth - OsdPipSetup.InfoWidth; + m_InfoY = Setup.OSDTop; + break; + case kInfoBottomLeft: + m_InfoX = Setup.OSDLeft; + m_InfoY = Setup.OSDTop + Setup.OSDHeight - 60; + break; + case kInfoBottomRight: + m_InfoX = Setup.OSDLeft + Setup.OSDWidth - OsdPipSetup.InfoWidth; + m_InfoY = Setup.OSDTop + Setup.OSDHeight - 60; + break; + } + tArea areas[] = + { + { OsdPipSetup.XPosition, OsdPipSetup.YPosition, OsdPipSetup.XPosition + m_Width - 1, OsdPipSetup.YPosition + m_Height - 1, OsdPipSetup.ColorDepth == kDepthGrey16 ? 4 : 8 }, + { m_InfoX, m_InfoY, m_InfoX + OsdPipSetup.InfoWidth - 1, m_InfoY + 60 - 1, OsdPipSetup.ColorDepth == kDepthGrey16 ? 4 : 8 } + }; + if (m_Osd->CanHandleAreas(areas, 2) == oeOk) + m_Osd->SetAreas(areas, 2); + else + m_Osd->SetAreas(areas, 1); + m_Bitmap = new cBitmap(m_Width, m_Height, OsdPipSetup.ColorDepth == kDepthGrey16 ? 4 : 8); + m_BitmapInfo = new cBitmap(OsdPipSetup.InfoWidth, 60, OsdPipSetup.ColorDepth == kDepthGrey16 ? 4 : 8); + } + else + { + tArea areas[] = + { + { OsdPipSetup.XPosition, OsdPipSetup.YPosition, OsdPipSetup.XPosition + m_Width - 1, OsdPipSetup.YPosition + m_Height - 1, OsdPipSetup.ColorDepth == kDepthGrey16 ? 4 : 8 } + }; + m_Osd->SetAreas(areas, 1); + m_Bitmap = new cBitmap(m_Width, m_Height, OsdPipSetup.ColorDepth == kDepthGrey16 ? 4 : 8); + } + + if (OsdPipSetup.ColorDepth == kDepthGrey256) + { + for (int i = 0; i < 256; i++) + m_Palette[i] = m_AlphaBase | (i << 16) | (i << 8) | i; + m_Palette[0] = 0xFD000000; + m_Palette[255] = 0xFDFFFFFF; + } + if (OsdPipSetup.ColorDepth == kDepthColor256fix) + { + for (int i = 0; i < 252; i++) + m_Palette[i + 1] = m_AlphaBase | quantizer->OutputPalette()[i]; + m_Palette[0] = 0xFD000000; + m_Palette[255] = 0xFDFFFFFF; + } + if (OsdPipSetup.ColorDepth == kDepthColor128var) + { + m_Palette[0] = 0xFD000000; + m_Palette[255] = 0xFDFFFFFF; + } +#else + if (OsdPipSetup.ShowInfo) + { int x = 0; int y = 0; - switch (OsdPipSetup.InfoPosition) { + switch (OsdPipSetup.InfoPosition) + { case kInfoTopLeft: x = (720 - (Setup.OSDwidth * cOsd::CellWidth())) / 2; y = (576 - (Setup.OSDheight * cOsd::LineHeight())) / 2; @@ -150,92 +198,96 @@ void cOsdPipObject::ProcessImage(unsigned char * data, int length) { y = (576 + (Setup.OSDheight * cOsd::LineHeight())) / 2 - 60; break; } - m_WindowInfo = m_Osd->Create(x, y, OsdPipSetup.InfoWidth, 60, 1, false, false); - m_BitmapInfo = new cBitmap(OsdPipSetup.InfoWidth, 60, 1, false); -#ifdef VDR_OSDPIP_PATCHED - m_BitmapInfo->SetColor(0, (eDvbColor) 0xFF000000); - m_BitmapInfo->SetColor(1, (eDvbColor) 0xFFFFFFFF); -#endif - ShowChannelInfo(Channels.GetByNumber(cDevice::ActualDevice()->CurrentChannel())); + m_WindowInfo = m_Osd->Create(x, y, OsdPipSetup.InfoWidth, 60, OsdPipSetup.ColorDepth == kDepthGrey16 ? 4 : 8, false, false); + m_BitmapInfo = new cBitmap(OsdPipSetup.InfoWidth, 60, OsdPipSetup.ColorDepth == kDepthGrey16 ? 4 : 8, false); } m_Window = m_Osd->Create(OsdPipSetup.XPosition, OsdPipSetup.YPosition, m_Width, m_Height, OsdPipSetup.ColorDepth == kDepthGrey16 ? 4 : 8, false); m_Bitmap = new cBitmap(m_Width, m_Height, OsdPipSetup.ColorDepth == kDepthGrey16 ? 4 : 8, false); - if (OsdPipSetup.ColorDepth == kDepthGrey128 || - OsdPipSetup.ColorDepth == kDepthColor256fix) { -#ifdef VDR_OSDPIP_PATCHED - m_PaletteLookup[0] = 16; - m_PaletteLookup[255] = 17; - for (int i = 1; i < 17; i++) - m_PaletteLookup[i] = i - 1; - for (int i = 17; i < 255; i++) - m_PaletteLookup[i] = i + 1; -#else + if (OsdPipSetup.ColorDepth == kDepthGrey256 || + OsdPipSetup.ColorDepth == kDepthColor256fix) + { for (int i = 0; i < 256; i++) - m_PaletteLookup[i] = i; -#endif - for (int i = 0; i < 256; i++) { - if (OsdPipSetup.ColorDepth == kDepthGrey128) - m_Palette[m_PaletteLookup[i]] = m_AlphaBase | (i << 16) | (i << 8) | i; + { + if (OsdPipSetup.ColorDepth == kDepthGrey256) + m_Palette[i] = m_AlphaBase | (i << 16) | (i << 8) | i; else - m_Palette[m_PaletteLookup[i]] = m_AlphaBase | quantizer->OutputPalette()[i]; + m_Palette[i] = m_AlphaBase | quantizer->OutputPalette()[i]; } -#ifdef VDR_OSDPIP_PATCHED for (int i = 0; i < 256; i++) + { m_Bitmap->SetColor(i, (eDvbColor) m_Palette[i]); -#endif + m_BitmapInfo->SetColor(i, (eDvbColor) m_Palette[i]); + } } - if (OsdPipSetup.ColorDepth == kDepthColor128var) { - m_PaletteLookup[0] = 16; - m_PaletteLookup[255] = 17; - for (int i = 1; i < 17; i++) - m_PaletteLookup[i] = i - 1; - for (int i = 17; i < 255; i++) - m_PaletteLookup[i] = i + 1; - m_Palette[m_PaletteLookup[0]] = 0xFF000000; - m_Palette[m_PaletteLookup[255]] = 0xFFFFFFFF; + if (OsdPipSetup.ColorDepth == kDepthColor128var) + { + m_Palette[0] = 0xFF000000; + m_Palette[255] = 0xFFFFFFFF; } - m_Ready = true; +#endif } - if (Resample() != 0) + if (decoder.Resample(m_Width, m_Height) != 0) return; int size; size = m_Width * m_Height; - if (OsdPipSetup.ColorDepth == kDepthGrey16) { - outputImage = m_PicResample->data[0]; + if (OsdPipSetup.ColorDepth == kDepthGrey16) + { +#if VDRVERSNUM < 10307 m_Bitmap->Clear(); - for (int y = 0; y < m_Height; y++) { - for (int x = 0; x < m_Width; x++) { +#endif + outputImage = decoder.PicResample()->data[0]; + for (int y = 0; y < m_Height; y++) + { + for (int x = 0; x < m_Width; x++) + { value = outputImage[y * m_Width + x]; value = value / 16; value = value * 16; value = m_AlphaBase | (value << 16) | (value << 8) | value; +#if VDRVERSNUM >= 10307 + m_Bitmap->DrawPixel(x, y, value); +#else m_Bitmap->SetPixel(x, y, (eDvbColor) value); +#endif } } } - if (OsdPipSetup.ColorDepth == kDepthGrey128) { - outputImage = m_PicResample->data[0]; -// m_Bitmap->Clear(); - for (int y = 0; y < m_Height; y++) { - for (int x = 0; x < m_Width; x++) { - m_Bitmap->SetPixel(x, y, (eDvbColor) m_Palette[m_PaletteLookup[outputImage[y * m_Width + x] & 0xFE]]); + if (OsdPipSetup.ColorDepth == kDepthGrey256) + { + outputImage = decoder.PicResample()->data[0]; +#if VDRVERSNUM >= 10307 + for (int i = 0; i < 256; i++) + m_Bitmap->SetColor(i, m_Palette[i]); +#endif + for (int y = 0; y < m_Height; y++) + { + for (int x = 0; x < m_Width; x++) + { +#if VDRVERSNUM >= 10307 + m_Bitmap->SetIndex(x, y, outputImage[y * m_Width + x]); +#else + m_Bitmap->SetPixel(x, y, (eDvbColor) m_Palette[outputImage[y * m_Width + x]]); +#endif } } } if (OsdPipSetup.ColorDepth == kDepthColor256fix || - OsdPipSetup.ColorDepth == kDepthColor128var) { - if (ConvertToRGB() != 0) + OsdPipSetup.ColorDepth == kDepthColor128var) + { + if (decoder.ConvertToRGB() != 0) return; - if (OsdPipSetup.SwapFfmpeg) { - unsigned int * bufPtr = (unsigned int *) m_BufferConvert; + if (OsdPipSetup.SwapFfmpeg) + { + unsigned int * bufPtr = (unsigned int *) decoder.PicConvert()->data[0]; unsigned char red, green, blue, alpha; - for (int i = 0; i < size; i++) { + for (int i = 0; i < size; i++) + { value = *bufPtr; blue = value; green = value >> 8; @@ -247,66 +299,89 @@ void cOsdPipObject::ProcessImage(unsigned char * data, int length) { } } - quantizer->Quantize(m_BufferConvert, size, 127); + quantizer->Quantize(decoder.PicConvert()->data[0], size, 127); outputPalette = quantizer->OutputPalette(); outputImage = quantizer->OutputImage(); - if (OsdPipSetup.ColorDepth == kDepthColor256fix) { -// m_Bitmap->Clear(); - for (int y = 0; y < m_Height; y++) { - for (int x = 0; x < m_Width; x++) { - m_Bitmap->SetPixel(x, y, (eDvbColor) m_Palette[m_PaletteLookup[outputImage[y * m_Width + x]]]); + if (OsdPipSetup.ColorDepth == kDepthColor256fix) + { +#if VDRVERSNUM >= 10307 + for (int i = 0; i < 256; i++) + m_Bitmap->SetColor(i, m_Palette[i]); +#endif + for (int y = 0; y < m_Height; y++) + { + for (int x = 0; x < m_Width; x++) + { +#if VDRVERSNUM >= 10307 + m_Bitmap->SetIndex(x, y, outputImage[y * m_Width + x] + 1); +#else + m_Bitmap->SetPixel(x, y, (eDvbColor) m_Palette[outputImage[y * m_Width + x]]); +#endif } } - } else { + } + else + { for (int i = 0; i < 127; i++) { - m_Palette[m_PaletteLookup[m_PaletteStart + i]] = outputPalette[i]; - m_Palette[m_PaletteLookup[m_PaletteStart + i]] |= m_AlphaBase; + m_Palette[m_PaletteStart + i] = outputPalette[i]; + m_Palette[m_PaletteStart + i] |= m_AlphaBase; } -// m_Bitmap->Clear(); for (int i = 0; i < 256; i++) +#if VDRVERSNUM >= 10307 + m_Bitmap->SetColor(i, m_Palette[i]); +#else m_Bitmap->SetColor(i, (eDvbColor) m_Palette[i]); - for (int y = 0; y < m_Height; y++) { - for (int x = 0; x < m_Width; x++) { - m_Bitmap->SetIndex(x, y, m_PaletteLookup[m_PaletteStart + outputImage[y * m_Width + x]]); +#endif + for (int y = 0; y < m_Height; y++) + { + for (int x = 0; x < m_Width; x++) + { + m_Bitmap->SetIndex(x, y, m_PaletteStart + outputImage[y * m_Width + x]); } } if (m_PaletteStart == 1) + { m_PaletteStart = 128; +#if VDRVERSNUM >= 10307 + m_AlphaBase = 0xFE000000; +#endif + } else + { m_PaletteStart = 1; +#if VDRVERSNUM >= 10307 + m_AlphaBase = 0xFF000000; +#endif + } } } - + if (!m_Ready) + { + if (OsdPipSetup.ShowInfo) + ShowChannelInfo(Channels.GetByNumber(cDevice::ActualDevice()->CurrentChannel())); + m_Ready = true; + } +#if VDRVERSNUM >= 10307 + m_Osd->DrawBitmap(OsdPipSetup.XPosition, OsdPipSetup.YPosition, *m_Bitmap); +#else m_Osd->Clear(); m_Osd->SetBitmap(OsdPipSetup.XPosition, OsdPipSetup.YPosition, - *m_Bitmap); + *m_Bitmap); +#endif m_Osd->Flush(); } -void cOsdPipObject::Action(void) { +void cOsdPipObject::Action(void) +{ m_Active = true; isyslog("osdpip: decoder thread started (pid = %d)", getpid()); - m_Codec = avcodec_find_decoder(CODEC_ID_MPEG1VIDEO); - if (!m_Codec) - { - printf("codec not found\n"); - } - m_Context = avcodec_alloc_context(); - if (avcodec_open(m_Context, m_Codec) < 0) - { - printf("could not open codec\n"); - } - m_PicDecoded = avcodec_alloc_frame(); - m_PicResample = avcodec_alloc_frame(); - m_BufferResample = new unsigned char[(400 * 300 * 3) / 2]; // size for YUV 420 - m_PicConvert = avcodec_alloc_frame(); - m_BufferConvert = new unsigned char[400 * 300 * 4]; // size for RGBA32 + decoder.Open(); if (OsdPipSetup.ColorDepth == kDepthColor128var) quantizer = new cQuantizeWu(); @@ -317,70 +392,135 @@ void cOsdPipObject::Action(void) { int pictureType; m_FrameDrop = OsdPipSetup.FrameDrop; - while (m_Active) { + while (m_Active) + { +#if VDRVERSNUM >= 10307 + if (m_Reset) + { + if (m_Osd) + delete m_Osd; + m_Osd = cOsdProvider::NewOsd(0, 0); + if (!m_Osd) + break; + m_Ready = false; + m_Reset = false; + } +#endif frame = m_ESBuffer->Get(); { - if (frame && frame->Count() > 0) { + if (frame && frame->Count() > 0) + { pictureType = frame->Index(); - if ((OsdPipSetup.FrameMode == kFrameModeI && - pictureType == I_FRAME) || - (OsdPipSetup.FrameMode == kFrameModeIP && - (pictureType == I_FRAME || pictureType == P_FRAME)) || - (OsdPipSetup.FrameMode == kFrameModeIPB)) { + if ((OsdPipSetup.FrameMode == kFrameModeI && pictureType == I_FRAME) || + (OsdPipSetup.FrameMode == kFrameModeIP && (pictureType == I_FRAME || pictureType == P_FRAME)) || + (OsdPipSetup.FrameMode == kFrameModeIPB)) + { ProcessImage(frame->Data(), frame->Count()); } m_ESBuffer->Drop(frame); - } else { + } + else + { if (frame) m_ESBuffer->Drop(frame); usleep(1); } } - if (m_ShowTime != 0) { - if (m_ShowInfo) { - m_Osd->Clear(m_WindowInfo); + if (m_ShowTime != 0) + { + if (m_ShowInfo) + { +#if VDRVERSNUM >= 10307 + m_Osd->DrawBitmap(m_InfoX, m_InfoY, *m_BitmapInfo); +#else m_Osd->SetBitmap(0, 0, *m_BitmapInfo, m_WindowInfo); m_Osd->Show(m_WindowInfo); +#endif m_Osd->Flush(); m_ShowInfo = false; } time_t currentTime; time(¤tTime); if (currentTime - m_ShowTime > 2) { +#if VDRVERSNUM >= 10307 + ShowChannelInfo(Channels.GetByNumber(cDevice::ActualDevice()->CurrentChannel()), false); + m_Osd->DrawBitmap(m_InfoX, m_InfoY, *m_BitmapInfo); + m_Osd->Flush(); +#else m_Osd->Hide(m_WindowInfo); +#endif m_ShowTime = 0; } } } if (OsdPipSetup.ColorDepth == kDepthColor128var || - OsdPipSetup.ColorDepth == kDepthColor256fix) + OsdPipSetup.ColorDepth == kDepthColor256fix) delete quantizer; - delete[] m_BufferConvert; - free(m_PicConvert); - delete[] m_BufferResample; - free(m_PicResample); - avcodec_close(m_Context); - free(m_Context); - free(m_PicDecoded); + decoder.Close(); isyslog("osdpip: decoder thread stopped"); } -void cOsdPipObject::Show(void) { +void cOsdPipObject::Show(void) +{ +#if VDRVERSNUM >= 10307 + Start(); +#else m_Osd = cOsd::OpenRaw(0, 0); if (m_Osd) Start(); +#endif } -eOSState cOsdPipObject::ProcessKey(eKeys Key) { +eOSState cOsdPipObject::ProcessKey(eKeys Key) +{ eOSState state = cOsdObject::ProcessKey(Key); - if (state == osUnknown) { - switch (Key & ~k_Repeat) { + if (state == osUnknown) { + switch (Key & ~k_Repeat) { case k0: Channels.SwitchTo(m_Channel->Number()); case kBack: return osEnd; case k1...k9: +#if VDRVERSNUM >= 10307 + switch (Key & ~k_Repeat) { + case k1: + if (OsdPipSetup.XPosition >= Setup.OSDLeft + 10) OsdPipSetup.XPosition -= 10; + if (OsdPipSetup.YPosition >= Setup.OSDTop + 10) OsdPipSetup.YPosition -= 10; + break; + case k2: + if (OsdPipSetup.YPosition >= Setup.OSDTop + 10) OsdPipSetup.YPosition -= 10; + break; + case k3: + if (OsdPipSetup.XPosition + m_Width <= Setup.OSDLeft + Setup.OSDWidth - 10) + OsdPipSetup.XPosition += 10; + if (OsdPipSetup.YPosition >= Setup.OSDTop + 10) OsdPipSetup.YPosition -= 10; + break; + case k4: + if (OsdPipSetup.XPosition >= Setup.OSDLeft + 10) OsdPipSetup.XPosition -= 10; + break; + case k6: + if (OsdPipSetup.XPosition + m_Width <= Setup.OSDLeft + Setup.OSDWidth - 10) + OsdPipSetup.XPosition += 10; + break; + case k7: + if (OsdPipSetup.XPosition >= Setup.OSDLeft + 10) OsdPipSetup.XPosition -= 10; + if (OsdPipSetup.YPosition + m_Height <= Setup.OSDTop + Setup.OSDHeight - 10) + OsdPipSetup.YPosition += 10; + break; + case k8: + if (OsdPipSetup.YPosition + m_Height <= Setup.OSDTop + Setup.OSDHeight - 10) + OsdPipSetup.YPosition += 10; + break; + case k9: + if (OsdPipSetup.XPosition + m_Width <= Setup.OSDLeft + Setup.OSDWidth - 10) + OsdPipSetup.XPosition += 10; + if (OsdPipSetup.YPosition + m_Height <= Setup.OSDTop + Setup.OSDHeight - 10) + OsdPipSetup.YPosition += 10; + break; + } + m_Reset = true; +#else switch (Key & ~k_Repeat) { case k1: if (OsdPipSetup.XPosition > 9) OsdPipSetup.XPosition -= 10; @@ -418,6 +558,7 @@ eOSState cOsdPipObject::ProcessKey(eKeys Key) { break; } m_Osd->Relocate(m_Window, OsdPipSetup.XPosition, OsdPipSetup.YPosition); +#endif break; case kUp: @@ -436,13 +577,14 @@ eOSState cOsdPipObject::ProcessKey(eKeys Key) { break; default: return state; - } - state = osContinue; - } - return state; + } + state = osContinue; + } + return state; } -void cOsdPipObject::ChannelSwitch(const cDevice * device, int channelNumber) { +void cOsdPipObject::ChannelSwitch(const cDevice * device, int channelNumber) +{ if (device != cDevice::ActualDevice()) return; if (channelNumber == 0) @@ -453,7 +595,8 @@ void cOsdPipObject::ChannelSwitch(const cDevice * device, int channelNumber) { ShowChannelInfo(Channels.GetByNumber(device->CurrentChannel())); } -void cOsdPipObject::ShowChannelInfo(const cChannel * channel) { +void cOsdPipObject::ShowChannelInfo(const cChannel * channel, bool show) +{ char line1[100] = ""; char line2[100] = ""; @@ -471,9 +614,11 @@ void cOsdPipObject::ShowChannelInfo(const cChannel * channel) { presentTitle = present->Title(); if (!isempty(presentTitle)) { sprintf(line2, "%s %s", present->GetTimeString(), presentTitle); +#if VDRVERSNUM < 10307 while (m_Osd->Width(line2) > OsdPipSetup.InfoWidth - 10) { line2[strlen(line2) - 1] = 0; } +#endif } } } @@ -498,11 +643,56 @@ void cOsdPipObject::ShowChannelInfo(const cChannel * channel) { } } #endif - m_BitmapInfo->Clear(); - m_BitmapInfo->Fill(0, 0, OsdPipSetup.InfoWidth, 60, (eDvbColor) 0xFF000000); +#if VDRVERSNUM >= 10307 + if (OsdPipSetup.ColorDepth == kDepthGrey16) + { + if (show) + { + m_BitmapInfo->DrawRectangle(0, 0, OsdPipSetup.InfoWidth - 1, 60 - 1, clrBlack); + const cFont *font = cFont::GetFont(fontOsd); + m_BitmapInfo->DrawText(0, 0, line1, clrWhite, clrBlack, font, OsdPipSetup.InfoWidth, 30); + m_BitmapInfo->DrawText(0, 30, line2, clrWhite, clrBlack, font, OsdPipSetup.InfoWidth, 30); + time(&m_ShowTime); + m_ShowInfo = true; + } + else + { + m_BitmapInfo->DrawRectangle(0, 0, OsdPipSetup.InfoWidth - 1, 60 - 1, clrTransparent); + } + } + else + { + if (show) + { + m_Palette[0] = 0xFD000000; + m_Palette[255] = 0xFDFFFFFF; + m_BitmapInfo->DrawRectangle(0, 0, OsdPipSetup.InfoWidth - 1, 60 - 1, m_Palette[0]); + for (int i = 0; i < 256; i++) + m_BitmapInfo->SetColor(i, m_Palette[i]); + const cFont *font = cFont::GetFont(fontOsd); + m_BitmapInfo->DrawText(0, 0, line1, m_Palette[255], m_Palette[0], font, OsdPipSetup.InfoWidth, 30); + m_BitmapInfo->DrawText(0, 30, line2, m_Palette[255], m_Palette[0], font, OsdPipSetup.InfoWidth, 30); + time(&m_ShowTime); + m_ShowInfo = true; + } + else + { + m_Palette[0] = 0x00000000; + m_Palette[255] = 0x00FFFFFF; + m_BitmapInfo->DrawRectangle(0, 0, OsdPipSetup.InfoWidth - 1, 60 - 1, m_Palette[0]); + for (int i = 0; i < 256; i++) + m_BitmapInfo->SetColor(i, m_Palette[i]); + } + } +#else + if (OsdPipSetup.ColorDepth != kDepthGrey16) + for (int i = 0; i < 256; i++) + m_BitmapInfo->SetColor(i, (eDvbColor) m_Palette[i]); + m_BitmapInfo->Fill(0, 0, OsdPipSetup.InfoWidth, 60, (eDvbColor) 0xFF000000); m_BitmapInfo->Text(0, 0, line1, (eDvbColor) 0xFFFFFFFF, (eDvbColor) 0xFF000000); m_BitmapInfo->Text(0, 30, line2, (eDvbColor) 0xFFFFFFFF, (eDvbColor) 0xFF000000); time(&m_ShowTime); m_ShowInfo = true; +#endif } @@ -7,15 +7,6 @@ #ifndef VDR_OSDPIP_OSD_H #define VDR_OSDPIP_OSD_H -extern "C" -{ -#ifdef HAVE_FFMPEG_STATIC -# include <avcodec.h> -#else -# include <ffmpeg/avcodec.h> -#endif -} - #include <sys/time.h> #include <vdr/osd.h> @@ -23,53 +14,55 @@ extern "C" #include <vdr/status.h> #include <vdr/receiver.h> +#include "decoder.h" + class cRingBufferFrame; class cOsdPipReceiver; class cQuantize; class cOsdPipObject: public cOsdObject, public cThread, public cStatus { private: +#if VDRVERSNUM >= 10307 + cOsd *m_Osd; +#else cOsdBase *m_Osd; + tWindowHandle m_Window; + tWindowHandle m_WindowInfo; +#endif cRingBufferFrame *m_ESBuffer; cOsdPipReceiver *m_Receiver; const cChannel *m_Channel; - tWindowHandle m_Window; cBitmap * m_Bitmap; - tWindowHandle m_WindowInfo; cBitmap * m_BitmapInfo; +#if VDRVERSNUM >= 10307 + int m_InfoX; + int m_InfoY; +#endif time_t m_ShowTime; bool m_ShowInfo; bool m_Active; bool m_Ready; +#if VDRVERSNUM >= 10307 + bool m_Reset; +#endif int m_Width, m_Height; int m_FrameDrop; - AVCodec * m_Codec; - AVCodecContext * m_Context; - AVFrame * m_PicDecoded; - AVFrame * m_PicResample; - AVFrame * m_PicConvert; - unsigned char * m_BufferResample; - unsigned char * m_BufferConvert; - unsigned int m_AlphaBase; unsigned int m_Palette[256]; int m_PaletteStart; - unsigned char m_PaletteLookup[256]; + cDecoder decoder; cQuantize * quantizer; - int Decode(unsigned char * data, int length); - int Resample(); - int ConvertToRGB(); void ProcessImage(unsigned char * data, int length); - void ShowChannelInfo(const cChannel * channel); + void ShowChannelInfo(const cChannel * channel, bool show = true); protected: virtual void Action(void); - virtual void ChannelSwitch(const cDevice * device, int channelNumber); + virtual void ChannelSwitch(const cDevice * device, int channelNumber); public: cOsdPipObject(cDevice *Device, const cChannel *Channel); @@ -7,9 +7,9 @@ extern "C" { #ifdef HAVE_FFMPEG_STATIC -# include <avcodec.h> +# include <avcodec.h> #else -# include <ffmpeg/avcodec.h> +# include <ffmpeg/avcodec.h> #endif } @@ -19,66 +19,75 @@ extern "C" #include <vdr/plugin.h> -static const char *VERSION = "0.0.4"; +static const char *VERSION = "0.0.5"; static const char *DESCRIPTION = "OSD Picture-in-Picture"; static const char *MAINMENUENTRY = "Picture-in-Picture"; -class cPluginOsdpip : public cPlugin { +class cPluginOsdpip : public cPlugin +{ private: public: - cPluginOsdpip(void); - virtual ~cPluginOsdpip(); - virtual const char *Version(void) { return VERSION; } - virtual const char *Description(void) { return DESCRIPTION; } - virtual const char *CommandLineHelp(void); - virtual bool ProcessArgs(int argc, char *argv[]); - virtual bool Initialize(void); - virtual bool Start(void); - virtual void Housekeeping(void); - virtual const char *MainMenuEntry(void) { return tr(MAINMENUENTRY); } - virtual cOsdObject *MainMenuAction(void); - virtual cMenuSetupPage *SetupMenu(void); - virtual bool SetupParse(const char *Name, const char *Value); + cPluginOsdpip(void); + virtual ~cPluginOsdpip(); + virtual const char *Version(void) { return VERSION; } + virtual const char *Description(void) { return tr(DESCRIPTION); } + virtual const char *CommandLineHelp(void); + virtual bool ProcessArgs(int argc, char *argv[]); + virtual bool Initialize(void); + virtual bool Start(void); + virtual void Housekeeping(void); + virtual const char *MainMenuEntry(void) { return tr(MAINMENUENTRY); } + virtual cOsdObject *MainMenuAction(void); + virtual cMenuSetupPage *SetupMenu(void); + virtual bool SetupParse(const char *Name, const char *Value); }; -cPluginOsdpip::cPluginOsdpip(void) { +cPluginOsdpip::cPluginOsdpip(void) +{ } -cPluginOsdpip::~cPluginOsdpip() { +cPluginOsdpip::~cPluginOsdpip() +{ } -const char *cPluginOsdpip::CommandLineHelp(void) { - return NULL; +const char *cPluginOsdpip::CommandLineHelp(void) +{ + return NULL; } -bool cPluginOsdpip::ProcessArgs(int argc, char *argv[]) { - return true; +bool cPluginOsdpip::ProcessArgs(int argc, char *argv[]) +{ + return true; } -bool cPluginOsdpip::Initialize(void) { +bool cPluginOsdpip::Initialize(void) +{ // must be called before using avcodec lib avcodec_init(); // register all the codecs (you can also register only the codec - // you wish to have smaller code) + // you wish to have smaller code) avcodec_register_all(); - return true; + return true; } -bool cPluginOsdpip::Start(void) { +bool cPluginOsdpip::Start(void) +{ RegisterI18n(Phrases); - return true; + return true; } -void cPluginOsdpip::Housekeeping(void) { +void cPluginOsdpip::Housekeeping(void) +{ } -cOsdObject *cPluginOsdpip::MainMenuAction(void) { +cOsdObject *cPluginOsdpip::MainMenuAction(void) +{ const cChannel *chan; cDevice *dev; chan = cDevice::CurrentChannel() != 0 - ? Channels.GetByNumber(cDevice::CurrentChannel()) : NULL; + ? Channels.GetByNumber(cDevice::CurrentChannel()) : NULL; if (chan != NULL) { dev = cDevice::GetDevice(chan, 1); if (dev) @@ -87,12 +96,14 @@ cOsdObject *cPluginOsdpip::MainMenuAction(void) { return NULL; } -cMenuSetupPage *cPluginOsdpip::SetupMenu(void) { - return new cOsdPipSetupPage; +cMenuSetupPage *cPluginOsdpip::SetupMenu(void) +{ + return new cOsdPipSetupPage; } -bool cPluginOsdpip::SetupParse(const char *Name, const char *Value) { - return OsdPipSetup.SetupParse(Name, Value); +bool cPluginOsdpip::SetupParse(const char *Name, const char *Value) +{ + return OsdPipSetup.SetupParse(Name, Value); } VDRPLUGINCREATOR(cPluginOsdpip); // Don't touch this! diff --git a/patches/vdr-1.2.6-256-indexes.diff b/patches/vdr-1.2.6-256-indexes.diff new file mode 100644 index 0000000..5b5b5fa --- /dev/null +++ b/patches/vdr-1.2.6-256-indexes.diff @@ -0,0 +1,76 @@ +--- vdrold/osdbase.c 2004-06-13 13:52:47.000000000 +0200 ++++ vdr-1.2.6/osdbase.c 2004-06-13 13:49:23.000000000 +0200 +@@ -116,7 +116,7 @@ + fontType = fontOsd; + font = NULL; + if (width > 0 && height > 0) { +- bitmap = MALLOC(char, width * height); ++ bitmap = MALLOC(unsigned char, width * height); + if (bitmap) { + Clean(); + memset(bitmap, 0x00, width * height); +@@ -188,7 +188,7 @@ + dirtyY2 = -1; + } + +-void cBitmap::SetIndex(int x, int y, char Index) ++void cBitmap::SetIndex(int x, int y, unsigned char Index) + { + if (bitmap) { + if (0 <= x && x < width && 0 <= y && y < height) { +@@ -269,7 +269,7 @@ + Fill(0, 0, width - 1, height - 1, clrBackground); + } + +-const char *cBitmap::Data(int x, int y) ++const unsigned char *cBitmap::Data(int x, int y) + { + return &bitmap[y * width + x]; + } +@@ -329,7 +329,7 @@ + cBitmap::Text(x, y, s, ColorFg, ColorBg); + } + +-const char *cWindow::Data(int x, int y) ++const unsigned char *cWindow::Data(int x, int y) + { + return cBitmap::Data(x, y); + } +--- vdrold/osdbase.h 2004-06-13 13:52:47.000000000 +0200 ++++ vdr-1.2.6/osdbase.h 2004-06-13 13:48:49.000000000 +0200 +@@ -75,7 +75,7 @@ + private: + cFont *font; + eDvbFont fontType; +- char *bitmap; ++ unsigned char *bitmap; + bool clearWithBackground; + protected: + int width, height; +@@ -86,7 +86,7 @@ + bool ClearWithBackground(void) { return clearWithBackground; } + eDvbFont SetFont(eDvbFont Font); + bool Dirty(int &x1, int &y1, int &x2, int &y2); +- void SetIndex(int x, int y, char Index); ++ void SetIndex(int x, int y, unsigned char Index); + void SetPixel(int x, int y, eDvbColor Color); + void SetBitmap(int x, int y, const cBitmap &Bitmap); + int Width(void) { return width; } +@@ -97,7 +97,7 @@ + void Fill(int x1, int y1, int x2, int y2, eDvbColor Color); + void Clean(void); + void Clear(void); +- const char *Data(int x, int y); ++ const unsigned char *Data(int x, int y); + }; + + #define MAXNUMWINDOWS 7 // OSD windows are counted 1...7 +@@ -122,7 +122,7 @@ + void Fill(int x1, int y1, int x2, int y2, eDvbColor Color); + void SetBitmap(int x, int y, const cBitmap &Bitmap); + void Text(int x, int y, const char *s, eDvbColor ColorFg = clrWhite, eDvbColor ColorBg = clrBackground); +- const char *Data(int x, int y); ++ const unsigned char *Data(int x, int y); + }; + + typedef int tWindowHandle; diff --git a/patches/vdr-1.2.6-256-palette.diff b/patches/vdr-1.2.6-256-palette.diff new file mode 100644 index 0000000..1ea1c79 --- /dev/null +++ b/patches/vdr-1.2.6-256-palette.diff @@ -0,0 +1,137 @@ +--- vdrold/osdbase.c 2004-06-13 13:58:22.000000000 +0200 ++++ vdr-1.2.6/osdbase.c 2004-06-13 14:01:26.000000000 +0200 +@@ -104,6 +104,12 @@ + } + } + ++void cPalette::Replace(const cPalette &Palette) ++{ ++ for (int i = 0; i < Palette.numColors; i++) ++ SetColor(i, Palette.color[i]); ++} ++ + // --- cBitmap --------------------------------------------------------------- + + cBitmap::cBitmap(int Width, int Height, int Bpp, bool ClearWithBackground) +@@ -116,7 +122,7 @@ + fontType = fontOsd; + font = NULL; + if (width > 0 && height > 0) { +- bitmap = MALLOC(char, width * height); ++ bitmap = MALLOC(unsigned char, width * height); + if (bitmap) { + Clean(); + memset(bitmap, 0x00, width * height); +@@ -188,7 +194,7 @@ + dirtyY2 = -1; + } + +-void cBitmap::SetIndex(int x, int y, char Index) ++void cBitmap::SetIndex(int x, int y, unsigned char Index) + { + if (bitmap) { + if (0 <= x && x < width && 0 <= y && y < height) { +@@ -220,6 +226,17 @@ + } + } + ++void cBitmap::SetBitmap256(int x, int y, const cBitmap &Bitmap) ++{ ++ if (bitmap && Bitmap.bitmap) { ++ Replace(Bitmap); ++ for (int ix = 0; ix < Bitmap.width; ix++) { ++ for (int iy = 0; iy < Bitmap.height; iy++) ++ SetIndex(x + ix, y + iy, Bitmap.bitmap[Bitmap.width * iy + ix]); ++ } ++ } ++} ++ + int cBitmap::Width(unsigned char c) + { + return font ? font->Width(c) : -1; +@@ -269,7 +286,7 @@ + Fill(0, 0, width - 1, height - 1, clrBackground); + } + +-const char *cBitmap::Data(int x, int y) ++const unsigned char *cBitmap::Data(int x, int y) + { + return &bitmap[y * width + x]; + } +@@ -317,7 +334,10 @@ + x -= x0; + y -= y0; + } +- cBitmap::SetBitmap(x, y, Bitmap); ++ if (bpp == 8) ++ cBitmap::SetBitmap256(x, y, Bitmap); ++ else ++ cBitmap::SetBitmap(x, y, Bitmap); + } + + void cWindow::Text(int x, int y, const char *s, eDvbColor ColorFg, eDvbColor ColorBg) +@@ -329,7 +349,7 @@ + cBitmap::Text(x, y, s, ColorFg, ColorBg); + } + +-const char *cWindow::Data(int x, int y) ++const unsigned char *cWindow::Data(int x, int y) + { + return cBitmap::Data(x, y); + } +--- vdrold/osdbase.h 2004-06-13 14:05:47.000000000 +0200 ++++ vdr-1.2.6/osdbase.h 2004-06-13 13:59:45.000000000 +0200 +@@ -14,6 +14,7 @@
+ #include "font.h"
+
+ #define MAXNUMCOLORS 256
++#define VDR_OSDPIP_PATCHED
+
+ enum eDvbColor {
+ #ifdef DEBUG_OSD
+@@ -69,13 +70,14 @@ + // stored yet, NumColors will be set to 0 and the function will + // return NULL. + void Take(const cPalette &Palette, tIndexes *Indexes = NULL); ++ void Replace(const cPalette &Palette); + }; + + class cBitmap : public cPalette { + private: + cFont *font; + eDvbFont fontType; +- char *bitmap; ++ unsigned char *bitmap; + bool clearWithBackground; + protected: + int width, height; +@@ -86,9 +88,10 @@ + bool ClearWithBackground(void) { return clearWithBackground; } + eDvbFont SetFont(eDvbFont Font); + bool Dirty(int &x1, int &y1, int &x2, int &y2); +- void SetIndex(int x, int y, char Index); ++ void SetIndex(int x, int y, unsigned char Index); + void SetPixel(int x, int y, eDvbColor Color); + void SetBitmap(int x, int y, const cBitmap &Bitmap); ++ void SetBitmap256(int x, int y, const cBitmap &Bitmap); + int Width(void) { return width; } + int Width(unsigned char c); + int Width(const char *s); +@@ -97,7 +100,7 @@ + void Fill(int x1, int y1, int x2, int y2, eDvbColor Color); + void Clean(void); + void Clear(void); +- const char *Data(int x, int y); ++ const unsigned char *Data(int x, int y); + }; + + #define MAXNUMWINDOWS 7 // OSD windows are counted 1...7 +@@ -122,7 +125,7 @@ + void Fill(int x1, int y1, int x2, int y2, eDvbColor Color); + void SetBitmap(int x, int y, const cBitmap &Bitmap); + void Text(int x, int y, const char *s, eDvbColor ColorFg = clrWhite, eDvbColor ColorBg = clrBackground); +- const char *Data(int x, int y); ++ const unsigned char *Data(int x, int y); + }; + + typedef int tWindowHandle; diff --git a/patches/vdr-1.2.6-indexes.diff b/patches/vdr-1.2.6-indexes.diff new file mode 100644 index 0000000..26ec1be --- /dev/null +++ b/patches/vdr-1.2.6-indexes.diff @@ -0,0 +1,85 @@ +--- vdrold/osdbase.c 2004-06-13 13:52:47.000000000 +0200 ++++ vdr-1.2.6/osdbase.c 2004-06-13 13:49:23.000000000 +0200 +@@ -116,7 +116,7 @@ + fontType = fontOsd; + font = NULL; + if (width > 0 && height > 0) { +- bitmap = MALLOC(char, width * height); ++ bitmap = MALLOC(unsigned char, width * height); + if (bitmap) { + Clean(); + memset(bitmap, 0x00, width * height); +@@ -188,7 +188,7 @@ + dirtyY2 = -1; + } + +-void cBitmap::SetIndex(int x, int y, char Index) ++void cBitmap::SetIndex(int x, int y, unsigned char Index) + { + if (bitmap) { + if (0 <= x && x < width && 0 <= y && y < height) { +@@ -269,7 +269,7 @@ + Fill(0, 0, width - 1, height - 1, clrBackground); + } + +-const char *cBitmap::Data(int x, int y) ++const unsigned char *cBitmap::Data(int x, int y) + { + return &bitmap[y * width + x]; + } +@@ -329,7 +329,7 @@ + cBitmap::Text(x, y, s, ColorFg, ColorBg); + } + +-const char *cWindow::Data(int x, int y) ++const unsigned char *cWindow::Data(int x, int y) + { + return cBitmap::Data(x, y); + } +--- vdrold/osdbase.h 2004-06-13 13:52:47.000000000 +0200 ++++ vdr-1.2.6/osdbase.h 2004-06-13 13:48:49.000000000 +0200 +@@ -13,7 +13,7 @@ + #include <stdio.h> + #include "font.h" + +-#define MAXNUMCOLORS 16 ++#define MAXNUMCOLORS 256 + + enum eDvbColor { + #ifdef DEBUG_OSD +@@ -75,7 +75,7 @@ + private: + cFont *font; + eDvbFont fontType; +- char *bitmap; ++ unsigned char *bitmap; + bool clearWithBackground; + protected: + int width, height; +@@ -86,7 +86,7 @@ + bool ClearWithBackground(void) { return clearWithBackground; } + eDvbFont SetFont(eDvbFont Font); + bool Dirty(int &x1, int &y1, int &x2, int &y2); +- void SetIndex(int x, int y, char Index); ++ void SetIndex(int x, int y, unsigned char Index); + void SetPixel(int x, int y, eDvbColor Color); + void SetBitmap(int x, int y, const cBitmap &Bitmap); + int Width(void) { return width; } +@@ -97,7 +97,7 @@ + void Fill(int x1, int y1, int x2, int y2, eDvbColor Color); + void Clean(void); + void Clear(void); +- const char *Data(int x, int y); ++ const unsigned char *Data(int x, int y); + }; + + #define MAXNUMWINDOWS 7 // OSD windows are counted 1...7 +@@ -122,7 +122,7 @@ + void Fill(int x1, int y1, int x2, int y2, eDvbColor Color); + void SetBitmap(int x, int y, const cBitmap &Bitmap); + void Text(int x, int y, const char *s, eDvbColor ColorFg = clrWhite, eDvbColor ColorBg = clrBackground); +- const char *Data(int x, int y); ++ const unsigned char *Data(int x, int y); + }; + + typedef int tWindowHandle; diff --git a/patches/vdr-1.2.6-palette.diff b/patches/vdr-1.2.6-palette.diff new file mode 100644 index 0000000..46559a9 --- /dev/null +++ b/patches/vdr-1.2.6-palette.diff @@ -0,0 +1,139 @@ +--- vdrold/osdbase.c 2004-06-13 13:58:22.000000000 +0200 ++++ vdr-1.2.6/osdbase.c 2004-06-13 14:01:26.000000000 +0200 +@@ -104,6 +104,12 @@ + } + } + ++void cPalette::Replace(const cPalette &Palette) ++{ ++ for (int i = 0; i < Palette.numColors; i++) ++ SetColor(i, Palette.color[i]); ++} ++ + // --- cBitmap --------------------------------------------------------------- + + cBitmap::cBitmap(int Width, int Height, int Bpp, bool ClearWithBackground) +@@ -116,7 +122,7 @@ + fontType = fontOsd; + font = NULL; + if (width > 0 && height > 0) { +- bitmap = MALLOC(char, width * height); ++ bitmap = MALLOC(unsigned char, width * height); + if (bitmap) { + Clean(); + memset(bitmap, 0x00, width * height); +@@ -188,7 +194,7 @@ + dirtyY2 = -1; + } + +-void cBitmap::SetIndex(int x, int y, char Index) ++void cBitmap::SetIndex(int x, int y, unsigned char Index) + { + if (bitmap) { + if (0 <= x && x < width && 0 <= y && y < height) { +@@ -220,6 +226,17 @@ + } + } + ++void cBitmap::SetBitmap256(int x, int y, const cBitmap &Bitmap) ++{ ++ if (bitmap && Bitmap.bitmap) { ++ Replace(Bitmap); ++ for (int ix = 0; ix < Bitmap.width; ix++) { ++ for (int iy = 0; iy < Bitmap.height; iy++) ++ SetIndex(x + ix, y + iy, Bitmap.bitmap[Bitmap.width * iy + ix]); ++ } ++ } ++} ++ + int cBitmap::Width(unsigned char c) + { + return font ? font->Width(c) : -1; +@@ -269,7 +286,7 @@ + Fill(0, 0, width - 1, height - 1, clrBackground); + } + +-const char *cBitmap::Data(int x, int y) ++const unsigned char *cBitmap::Data(int x, int y) + { + return &bitmap[y * width + x]; + } +@@ -317,7 +334,10 @@ + x -= x0; + y -= y0; + } +- cBitmap::SetBitmap(x, y, Bitmap); ++ if (bpp == 8) ++ cBitmap::SetBitmap256(x, y, Bitmap); ++ else ++ cBitmap::SetBitmap(x, y, Bitmap); + } + + void cWindow::Text(int x, int y, const char *s, eDvbColor ColorFg, eDvbColor ColorBg) +@@ -329,7 +349,7 @@ + cBitmap::Text(x, y, s, ColorFg, ColorBg); + } + +-const char *cWindow::Data(int x, int y) ++const unsigned char *cWindow::Data(int x, int y) + { + return cBitmap::Data(x, y); + } +--- vdrold/osdbase.h 2004-06-13 14:05:47.000000000 +0200 ++++ vdr-1.2.6/osdbase.h 2004-06-13 13:59:45.000000000 +0200 +@@ -13,7 +13,8 @@ + #include <stdio.h> + #include "font.h" + +-#define MAXNUMCOLORS 16 ++#define MAXNUMCOLORS 256 ++#define VDR_OSDPIP_PATCHED + + enum eDvbColor { + #ifdef DEBUG_OSD +@@ -69,13 +70,14 @@ + // stored yet, NumColors will be set to 0 and the function will + // return NULL. + void Take(const cPalette &Palette, tIndexes *Indexes = NULL); ++ void Replace(const cPalette &Palette); + }; + + class cBitmap : public cPalette { + private: + cFont *font; + eDvbFont fontType; +- char *bitmap; ++ unsigned char *bitmap; + bool clearWithBackground; + protected: + int width, height; +@@ -86,9 +88,10 @@ + bool ClearWithBackground(void) { return clearWithBackground; } + eDvbFont SetFont(eDvbFont Font); + bool Dirty(int &x1, int &y1, int &x2, int &y2); +- void SetIndex(int x, int y, char Index); ++ void SetIndex(int x, int y, unsigned char Index); + void SetPixel(int x, int y, eDvbColor Color); + void SetBitmap(int x, int y, const cBitmap &Bitmap); ++ void SetBitmap256(int x, int y, const cBitmap &Bitmap); + int Width(void) { return width; } + int Width(unsigned char c); + int Width(const char *s); +@@ -97,7 +100,7 @@ + void Fill(int x1, int y1, int x2, int y2, eDvbColor Color); + void Clean(void); + void Clear(void); +- const char *Data(int x, int y); ++ const unsigned char *Data(int x, int y); + }; + + #define MAXNUMWINDOWS 7 // OSD windows are counted 1...7 +@@ -122,7 +125,7 @@ + void Fill(int x1, int y1, int x2, int y2, eDvbColor Color); + void SetBitmap(int x, int y, const cBitmap &Bitmap); + void Text(int x, int y, const char *s, eDvbColor ColorFg = clrWhite, eDvbColor ColorBg = clrBackground); +- const char *Data(int x, int y); ++ const unsigned char *Data(int x, int y); + }; + + typedef int tWindowHandle; diff --git a/patches/vdr-1.2.6.diff b/patches/vdr-1.2.6.diff deleted file mode 100644 index 5554889..0000000 --- a/patches/vdr-1.2.6.diff +++ /dev/null @@ -1,77 +0,0 @@ -diff -u vdr-1.2.6/osdbase.c vdr/osdbase.c ---- vdr-1.2.6/osdbase.c 2003-08-24 13:38:27.000000000 +0200 -+++ vdr/osdbase.c 2004-01-13 09:33:21.000000000 +0100 -@@ -104,6 +104,12 @@ - } - } - -+void cPalette::Replace(const cPalette &Palette) -+{ -+ for (int i = 0; i < Palette.numColors; i++) -+ SetColor(i, Palette.color[i]); -+} -+ - // --- cBitmap --------------------------------------------------------------- - - cBitmap::cBitmap(int Width, int Height, int Bpp, bool ClearWithBackground) -@@ -220,6 +226,17 @@ - } - } - -+void cBitmap::SetBitmap256(int x, int y, const cBitmap &Bitmap) -+{ -+ if (bitmap && Bitmap.bitmap) { -+ Replace(Bitmap); -+ for (int ix = 0; ix < Bitmap.width; ix++) { -+ for (int iy = 0; iy < Bitmap.height; iy++) -+ SetIndex(x + ix, y + iy, Bitmap.bitmap[Bitmap.width * iy + ix]); -+ } -+ } -+} -+ - int cBitmap::Width(unsigned char c) - { - return font ? font->Width(c) : -1; -@@ -317,7 +334,10 @@ - x -= x0; - y -= y0; - } -- cBitmap::SetBitmap(x, y, Bitmap); -+ if (bpp == 8) -+ cBitmap::SetBitmap256(x, y, Bitmap); -+ else -+ cBitmap::SetBitmap(x, y, Bitmap); - } - - void cWindow::Text(int x, int y, const char *s, eDvbColor ColorFg, eDvbColor ColorBg) -diff -u vdr-1.2.6/osdbase.h vdr/osdbase.h ---- vdr-1.2.6/osdbase.h 2002-09-08 16:12:41.000000000 +0200 -+++ vdr/osdbase.h 2004-01-13 09:22:24.000000000 +0100 -@@ -13,7 +13,8 @@ - #include <stdio.h> - #include "font.h" - --#define MAXNUMCOLORS 16 -+#define MAXNUMCOLORS 256 -+#define VDR_OSDPIP_PATCHED - - enum eDvbColor { - #ifdef DEBUG_OSD -@@ -69,7 +70,8 @@ - // stored yet, NumColors will be set to 0 and the function will - // return NULL. - void Take(const cPalette &Palette, tIndexes *Indexes = NULL); -- }; -+ void Replace(const cPalette &Palette); -+}; - - class cBitmap : public cPalette { - private: -@@ -89,6 +91,7 @@ - void SetIndex(int x, int y, char Index); - void SetPixel(int x, int y, eDvbColor Color); - void SetBitmap(int x, int y, const cBitmap &Bitmap); -+ void SetBitmap256(int x, int y, const cBitmap &Bitmap); - int Width(void) { return width; } - int Width(unsigned char c); - int Width(const char *s); diff --git a/patches/vdr-1.2.6_256.diff b/patches/vdr-1.2.6_256.diff deleted file mode 100644 index 843bbf5..0000000 --- a/patches/vdr-1.2.6_256.diff +++ /dev/null @@ -1,75 +0,0 @@ -diff -u vdr-1.2.6/osdbase.c vdr/osdbase.c ---- vdr-1.2.6/osdbase.c 2003-08-24 13:38:27.000000000 +0200 -+++ vdr/osdbase.c 2004-01-13 09:33:21.000000000 +0100 -@@ -104,6 +104,12 @@ - } - } - -+void cPalette::Replace(const cPalette &Palette) -+{ -+ for (int i = 0; i < Palette.numColors; i++) -+ SetColor(i, Palette.color[i]); -+} -+ - // --- cBitmap --------------------------------------------------------------- - - cBitmap::cBitmap(int Width, int Height, int Bpp, bool ClearWithBackground) -@@ -220,6 +226,17 @@ - } - } - -+void cBitmap::SetBitmap256(int x, int y, const cBitmap &Bitmap) -+{ -+ if (bitmap && Bitmap.bitmap) { -+ Replace(Bitmap); -+ for (int ix = 0; ix < Bitmap.width; ix++) { -+ for (int iy = 0; iy < Bitmap.height; iy++) -+ SetIndex(x + ix, y + iy, Bitmap.bitmap[Bitmap.width * iy + ix]); -+ } -+ } -+} -+ - int cBitmap::Width(unsigned char c) - { - return font ? font->Width(c) : -1; -@@ -317,7 +334,10 @@ - x -= x0; - y -= y0; - } -- cBitmap::SetBitmap(x, y, Bitmap); -+ if (bpp == 8) -+ cBitmap::SetBitmap256(x, y, Bitmap); -+ else -+ cBitmap::SetBitmap(x, y, Bitmap); - } - - void cWindow::Text(int x, int y, const char *s, eDvbColor ColorFg, eDvbColor ColorBg) -diff -u vdr-1.2.6/osdbase.h vdr/osdbase.h ---- vdr-1.2.6/osdbase.h 2002-09-08 16:12:41.000000000 +0200 -+++ vdr/osdbase.h 2004-01-13 09:22:24.000000000 +0100 -@@ -14,6 +14,7 @@ - #include "font.h" - - #define MAXNUMCOLORS 256 -+#define VDR_OSDPIP_PATCHED - - enum eDvbColor { - #ifdef DEBUG_OSD -@@ -69,7 +70,8 @@ - // stored yet, NumColors will be set to 0 and the function will - // return NULL. - void Take(const cPalette &Palette, tIndexes *Indexes = NULL); -- }; -+ void Replace(const cPalette &Palette); -+}; - - class cBitmap : public cPalette { - private: -@@ -89,6 +91,7 @@ - void SetIndex(int x, int y, char Index); - void SetPixel(int x, int y, eDvbColor Color); - void SetBitmap(int x, int y, const cBitmap &Bitmap); -+ void SetBitmap256(int x, int y, const cBitmap &Bitmap); - int Width(void) { return width; } - int Width(unsigned char c); - int Width(const char *s); @@ -9,8 +9,11 @@ #include <stdio.h> #include <stdlib.h> + +#include <vdr/config.h> #include "quantize.h" + cQuantize::cQuantize() { } @@ -18,8 +21,8 @@ cQuantize::~cQuantize() { } cQuantizeFixed::cQuantizeFixed() { - redLevelCount = 8; - greenLevelCount = 8; + redLevelCount = 7; + greenLevelCount = 9; blueLevelCount = 4; redLevels[0] = 0; @@ -43,8 +46,13 @@ cQuantizeFixed::cQuantizeFixed() { for (int r = 0; r < redLevelCount; r++) { for (int g = 0; g < greenLevelCount; g++) { for (int b = 0; b < blueLevelCount; b++) { +#if VDRVERSNUM >= 10307 + paletteOutput[r * greenLevelCount * blueLevelCount + g * blueLevelCount + b] = + (redLevels[r] << 16) | (greenLevels[g] << 8) | blueLevels[b]; +#else paletteOutput[r * greenLevelCount * blueLevelCount + g * blueLevelCount + b] = (blueLevels[b] << 16) | (greenLevels[g] << 8) | redLevels[r]; +#endif } } } @@ -180,6 +188,15 @@ int cQuantizeWu::Quantize(unsigned char * input, int size, int colors) weight = Vol(&cube[k], wt); if (weight) { +#if VDRVERSNUM >= 10307 +#ifdef NOINVERT + palette[k * 4 + 2] = (Vol(&cube[k], mb) / weight) WEIG; + palette[k * 4 + 0] = (Vol(&cube[k], mr) / weight) WEIG; +#else + palette[k * 4 + 0] = (Vol(&cube[k], mb) / weight) WEIG; + palette[k * 4 + 2] = (Vol(&cube[k], mr) / weight) WEIG; +#endif +#else #ifdef NOINVERT palette[k * 4 + 2] = (Vol(&cube[k], mr) / weight) WEIG; palette[k * 4 + 0] = (Vol(&cube[k], mb) / weight) WEIG; @@ -187,6 +204,7 @@ int cQuantizeWu::Quantize(unsigned char * input, int size, int colors) palette[k * 4 + 0] = (Vol(&cube[k], mr) / weight) WEIG; palette[k * 4 + 2] = (Vol(&cube[k], mb) / weight) WEIG; #endif +#endif palette[k * 4 + 1] = (Vol(&cube[k], mg) / weight) WEIG; } else @@ -12,21 +12,24 @@ #include <vdr/ringbuffer.h> cOsdPipReceiver::cOsdPipReceiver(const cChannel *Channel, - cRingBufferFrame *ESBuffer): - cReceiver(Channel->Ca(), 0, 2, Channel->Vpid(), Channel->Apid1()) { + cRingBufferFrame *ESBuffer): + cReceiver(Channel->Ca(), 0, 2, Channel->Vpid(), Channel->Apid1()) +{ m_TSBuffer = new cRingBufferLinear(MEGABYTE(3), TS_SIZE * 2, true); m_ESBuffer = ESBuffer; m_Remux = new cRemux(Channel->Vpid(), Channel->Apid1(), 0, 0, 0, true); m_Active = false; } -cOsdPipReceiver::~cOsdPipReceiver() { +cOsdPipReceiver::~cOsdPipReceiver() +{ Detach(); delete m_Remux; delete m_TSBuffer; } -void cOsdPipReceiver::Activate(bool On) { +void cOsdPipReceiver::Activate(bool On) +{ if (On) Start(); else if (m_Active) { @@ -35,13 +38,15 @@ void cOsdPipReceiver::Activate(bool On) { } } -void cOsdPipReceiver::Receive(uchar *Data, int Length) { +void cOsdPipReceiver::Receive(uchar *Data, int Length) +{ int put = m_TSBuffer->Put(Data, Length); if (put != Length) esyslog("osdpip: ringbuffer overflow (%d bytes dropped)", Length - put); } -void cOsdPipReceiver::Action(void) { +void cOsdPipReceiver::Action(void) +{ dsyslog("osdpip: receiver thread started (pid=%d)", getpid()); m_Active = true; @@ -51,7 +56,7 @@ void cOsdPipReceiver::Action(void) { unsigned char VideoBuffer[200000]; int VideoBufferPos = 0; - while (m_Active) { + while (m_Active) { int r; const uchar *b = m_TSBuffer->Get(r); if (b) { @@ -77,5 +82,6 @@ void cOsdPipReceiver::Action(void) { usleep(1); // this keeps the CPU load low } - dsyslog("osdpip: receiver thread ended (pid=%d)", getpid()); + dsyslog("osdpip: receiver thread ended (pid=%d)", getpid()); } + |