diff options
-rw-r--r-- | HISTORY | 8 | ||||
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | README | 21 | ||||
-rw-r--r-- | config.c | 69 | ||||
-rw-r--r-- | config.h | 35 | ||||
-rw-r--r-- | i18n.c | 102 | ||||
-rw-r--r-- | osd.c | 146 | ||||
-rw-r--r-- | osd.h | 4 | ||||
-rw-r--r-- | osdpip.c | 7 |
9 files changed, 345 insertions, 51 deletions
@@ -1,6 +1,14 @@ VDR Plugin 'osdpip' Revision History ------------------------------------ +2004-01-03: Version 0.0.2 + +- Added setup menu +- OSD depth, size and position configurable (see README) +- OSD crop dimensions configurable +- OSD window size is calculated dynamically depending on stream dimensions +- Added translations + 2004-01-02: Version 0.0.1 - Initial revision. @@ -16,7 +16,7 @@ VERSION = $(shell grep 'static const char \*VERSION *=' $(PLUGIN).c | awk '{ pri ### The C++ compiler and options: CXX ?= g++ -CXXFLAGS ?= -O2 -Wall -Woverloaded-virtual +CXXFLAGS ?= -g -O2 -Wall -Woverloaded-virtual ### The directory environment: @@ -46,7 +46,7 @@ DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"' ### The object files (add further files here): -OBJS = $(PLUGIN).o osd.o receiver.o i18n.o \ +OBJS = $(PLUGIN).o osd.o receiver.o config.o i18n.o \ \ remux/tsremux.o remux/ts2ps.o remux/ts2es.o @@ -20,8 +20,21 @@ Description: OSD Picture-in-Picture is a PlugIn that displays the current channel in a small box on the screen (default upper right corner). You can switch up and down now, watching the progress of the previous channel in the box. Quality is -not too good yet, and only I-Frames are displayed. You'll need to upgrade your -VDR to support a 256 color OSD with the provided patching instruction. +not too good yet, and only I-Frames are displayed. +From 0.0.2 on, the plugin supports two modes: grayscaled and 256 colored. If +you want 256 colors, you'll need to upgrade your VDR to support a 256 color OSD +with the provided patching instruction. You can choose the color depth in the +setup menu. If you didn't patch VDR appropriately, you'll only be able to choose +grayscaled mode. +Also by 0.0.2, the plugin has the possibility to choose the PiP size (in the +setup menu in factors of 1/x) and position (by moving it around using number +keys) as well as crop dimensions. + +ATTENTION: To use PiP size factor 2 in 256 color mode, you need to set all crop +values to >50 pixels. + +ATTENTION: To have the position saved, you have to enter the plugin's setup menu +and hit the ok button. Installation: @@ -38,7 +51,7 @@ cd ../.. Now, you have to call your favourite editor to open osdbase.h and jump to line number 16. I don't provide a patch here because some patches already touch that area. Well this one's easy, though. Just increase the number of colors in this -line to 256. +line to 256. If you don't want 256 color support, you can skip this part. #define MAXNUMCOLORS 256 @@ -51,7 +64,7 @@ make [options, if necessary] plugins Controls: Up/Down Switch Channel up/down -1-9 Set Box Position +1-4,6-9 Move box around like with cursor keys 0 Switch back to PiP channel and exit PiP Back Exit PiP without switching back diff --git a/config.c b/config.c new file mode 100644 index 0000000..647a5a3 --- /dev/null +++ b/config.c @@ -0,0 +1,69 @@ +#include "config.h" + +int ColorDepths = (MAXNUMCOLORS == 256 ? 2 : 1); +#if MAXNUMCOLORS < 256 +# warning WARNING: YOU WILL NOT BE ABLE TO USE RGB PIP +#endif + +const char *ColorDepthItems[] = { + "Greyscale", + "256 colors" +}; + +cOsdPipSetup OsdPipSetup; + +cOsdPipSetup::cOsdPipSetup(void) { + XPosition = 20; + YPosition = 20; + CropLeft = 5; + CropRight = 5; + CropTop = 5; + CropBottom = 5; + ZoomFactor = 3; + ColorDepth = (MAXNUMCOLORS == 256 ? 1 : 0); +} + +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); + else if (strcmp(Name, "CropRight") == 0) CropRight = atoi(Value); + else if (strcmp(Name, "CropTop") == 0) CropTop = atoi(Value); + else if (strcmp(Name, "CropBottom") == 0) CropBottom = atoi(Value); + else if (strcmp(Name, "ZoomFactor") == 0) ZoomFactor = atoi(Value); + else if (strcmp(Name, "ColorDepth") == 0) ColorDepth = atoi(Value); + else return false; + return true; +} + +cOsdPipSetupPage::cOsdPipSetupPage(void) { + m_NewOsdPipSetup = OsdPipSetup; + + 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 cMenuEditIntItem(tr("Zoom factor"), &m_NewOsdPipSetup.ZoomFactor, 2, + 4)); + Add(new cMenuEditStraItem(tr("Colordepth"), &m_NewOsdPipSetup.ColorDepth, + ColorDepths, ColorDepthItems)); +} + +cOsdPipSetupPage::~cOsdPipSetupPage() { +} + +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("ZoomFactor", OsdPipSetup.ZoomFactor); + SetupStore("ColorDepth", OsdPipSetup.ColorDepth); +} diff --git a/config.h b/config.h new file mode 100644 index 0000000..6141ab8 --- /dev/null +++ b/config.h @@ -0,0 +1,35 @@ +#ifndef VDR_OSDPIP_SETUP_H +#define VDR_OSDPIP_SETUP_H + +#include <vdr/plugin.h> + +struct cOsdPipSetup { + cOsdPipSetup(void); + + bool SetupParse(const char *Name, const char *Value); + + int XPosition; + int YPosition; + int CropLeft; + int CropRight; + int CropTop; + int CropBottom; + int ZoomFactor; + int ColorDepth; +}; + +extern cOsdPipSetup OsdPipSetup; + +class cOsdPipSetupPage: public cMenuSetupPage { +private: + cOsdPipSetup m_NewOsdPipSetup; + +protected: + virtual void Store(void); + +public: + cOsdPipSetupPage(void); + virtual ~cOsdPipSetupPage(); +}; + +#endif // VDR_OSDPIP_SETUP_H @@ -18,5 +18,107 @@ const tI18nPhrase Phrases[] = { "", // 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 + }, { NULL } }; @@ -1,10 +1,11 @@ #include "osd.h" #include "receiver.h" +#include "config.h" #include <vdr/ringbuffer.h> #include <vdr/remux.h> -const uint palette[256] = { +const uint rgb256[256] = { 0xff000000, 0xff400000, 0xff800000, 0xffc00000, 0xff002000, 0xff402000, 0xff802000, 0xffc02000, 0xff004000, 0xff404000, 0xff804000, 0xffc04000, 0xff006000, 0xff406000, 0xff806000, 0xffc06000, 0xff008000, 0xff408000, @@ -50,14 +51,62 @@ const uint palette[256] = { 0xff00e0e0, 0xff40e0e0, 0xff80e0e0, 0xffc0e0e0, }; +const uint grey256[256] = { + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, + 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff111111, 0xff111111, + 0xff111111, 0xff111111, 0xff111111, 0xff111111, 0xff111111, 0xff111111, + 0xff111111, 0xff111111, 0xff111111, 0xff111111, 0xff111111, 0xff111111, + 0xff111111, 0xff111111, 0xff222222, 0xff222222, 0xff222222, 0xff222222, + 0xff222222, 0xff222222, 0xff222222, 0xff222222, 0xff222222, 0xff222222, + 0xff222222, 0xff222222, 0xff222222, 0xff222222, 0xff222222, 0xff222222, + 0xff333333, 0xff333333, 0xff333333, 0xff333333, 0xff333333, 0xff333333, + 0xff333333, 0xff333333, 0xff333333, 0xff333333, 0xff333333, 0xff333333, + 0xff333333, 0xff333333, 0xff333333, 0xff333333, 0xff444444, 0xff444444, + 0xff444444, 0xff444444, 0xff444444, 0xff444444, 0xff444444, 0xff444444, + 0xff444444, 0xff444444, 0xff444444, 0xff444444, 0xff444444, 0xff444444, + 0xff444444, 0xff444444, 0xff555555, 0xff555555, 0xff555555, 0xff555555, + 0xff555555, 0xff555555, 0xff555555, 0xff555555, 0xff555555, 0xff555555, + 0xff555555, 0xff555555, 0xff555555, 0xff555555, 0xff555555, 0xff555555, + 0xff666666, 0xff666666, 0xff666666, 0xff666666, 0xff666666, 0xff666666, + 0xff666666, 0xff666666, 0xff666666, 0xff666666, 0xff666666, 0xff666666, + 0xff666666, 0xff666666, 0xff666666, 0xff666666, 0xff777777, 0xff777777, + 0xff777777, 0xff777777, 0xff777777, 0xff777777, 0xff777777, 0xff777777, + 0xff777777, 0xff777777, 0xff777777, 0xff777777, 0xff777777, 0xff777777, + 0xff777777, 0xff777777, 0xff888888, 0xff888888, 0xff888888, 0xff888888, + 0xff888888, 0xff888888, 0xff888888, 0xff888888, 0xff888888, 0xff888888, + 0xff888888, 0xff888888, 0xff888888, 0xff888888, 0xff888888, 0xff888888, + 0xff999999, 0xff999999, 0xff999999, 0xff999999, 0xff999999, 0xff999999, + 0xff999999, 0xff999999, 0xff999999, 0xff999999, 0xff999999, 0xff999999, + 0xff999999, 0xff999999, 0xff999999, 0xff999999, 0xffaaaaaa, 0xffaaaaaa, + 0xffaaaaaa, 0xffaaaaaa, 0xffaaaaaa, 0xffaaaaaa, 0xffaaaaaa, 0xffaaaaaa, + 0xffaaaaaa, 0xffaaaaaa, 0xffaaaaaa, 0xffaaaaaa, 0xffaaaaaa, 0xffaaaaaa, + 0xffaaaaaa, 0xffaaaaaa, 0xffbbbbbb, 0xffbbbbbb, 0xffbbbbbb, 0xffbbbbbb, + 0xffbbbbbb, 0xffbbbbbb, 0xffbbbbbb, 0xffbbbbbb, 0xffbbbbbb, 0xffbbbbbb, + 0xffbbbbbb, 0xffbbbbbb, 0xffbbbbbb, 0xffbbbbbb, 0xffbbbbbb, 0xffbbbbbb, + 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffcccccc, + 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffcccccc, + 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffcccccc, 0xffdddddd, 0xffdddddd, + 0xffdddddd, 0xffdddddd, 0xffdddddd, 0xffdddddd, 0xffdddddd, 0xffdddddd, + 0xffdddddd, 0xffdddddd, 0xffdddddd, 0xffdddddd, 0xffdddddd, 0xffdddddd, + 0xffdddddd, 0xffdddddd, 0xffeeeeee, 0xffeeeeee, 0xffeeeeee, 0xffeeeeee, + 0xffeeeeee, 0xffeeeeee, 0xffeeeeee, 0xffeeeeee, 0xffeeeeee, 0xffeeeeee, + 0xffeeeeee, 0xffeeeeee, 0xffeeeeee, 0xffeeeeee, 0xffeeeeee, 0xffeeeeee, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, + 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, +}; + cOsdPipObject::cOsdPipObject(cDevice *Device, const cChannel *Channel): cOsdObject(true) { m_Channel = Channel; m_Osd = NULL; m_ESBuffer = new cRingBufferLinear(MEGABYTE(3), 0, true); - m_Xpos = 25; - m_Ypos = 25; + m_Active = false; + m_Ready = false; + m_Width = m_Height = -1; + m_Bitmap = NULL; Device->SwitchChannel(m_Channel, false); m_Receiver = new cOsdPipReceiver(m_Channel, m_ESBuffer); @@ -71,6 +120,8 @@ cOsdPipObject::~cOsdPipObject() { } delete m_Receiver; + if (m_Bitmap != NULL) + delete m_Bitmap; if (m_Osd != NULL) delete m_Osd; } @@ -85,7 +136,6 @@ void cOsdPipObject::Action(void) { mpeg2_state_t state; while (m_Active) { - cBitmap frame(312, 236, 8); const uchar *block; int recvd; @@ -101,22 +151,41 @@ void cOsdPipObject::Action(void) { break; case STATE_SEQUENCE: + if (!m_Ready) { + m_Width = (info->sequence->width - OsdPipSetup.CropLeft + - OsdPipSetup.CropRight) / OsdPipSetup.ZoomFactor; + m_Height = (info->sequence->height - OsdPipSetup.CropTop + - OsdPipSetup.CropBottom) / OsdPipSetup.ZoomFactor; + m_Window = m_Osd->Create(OsdPipSetup.XPosition, OsdPipSetup.YPosition, + m_Width, m_Height, OsdPipSetup.ColorDepth == 0 ? 4 : 8); + m_Bitmap = new cBitmap(m_Width, m_Height, + OsdPipSetup.ColorDepth == 0 ? 4 : 8); + m_Ready = true; + } mpeg2_convert(handle, mpeg2convert_rgb8, NULL); break; case STATE_SLICE: case STATE_END: case STATE_INVALID_END: - if (info->display_fbuf && (info->display_picture->flags + if (m_Ready && info->display_fbuf && (info->display_picture->flags & PIC_MASK_CODING_TYPE) == PIC_FLAG_CODING_TYPE_I) { - for (int x = 0; x < 312; ++x) { - for (int y = 0; y < 236; ++y) { - uint8_t *ptr = info->display_fbuf->buf[0] + ((50 + y * 2) - * info->sequence->width + (50 + x * 2)); - frame.SetPixel(x, y, (eDvbColor)palette[(int)*ptr]); + int px = OsdPipSetup.CropLeft; + int py = OsdPipSetup.CropRight; + for (int x = 0; x < m_Width; ++x) { + for (int y = 0; y < m_Height; ++y) { + uint8_t idx = info->display_fbuf->buf[0][py + * info->sequence->width + px]; + uint col = OsdPipSetup.ColorDepth == 0 ? grey256[idx] : rgb256[idx]; + + m_Bitmap->SetPixel(x, y, (eDvbColor)col); + py += OsdPipSetup.ZoomFactor; } + px += OsdPipSetup.ZoomFactor; + py = 0; } - m_Osd->SetBitmap(m_Xpos, m_Ypos, frame); + m_Osd->SetBitmap(OsdPipSetup.XPosition, OsdPipSetup.YPosition, + *m_Bitmap); m_Osd->Flush(); } break; @@ -131,11 +200,8 @@ void cOsdPipObject::Action(void) { void cOsdPipObject::Show(void) { m_Osd = cOsd::OpenRaw(0, 0); - m_Window = m_Osd->Create(m_Xpos, m_Ypos, 312, 236, 8, false); - if (m_Osd) { - m_Osd->Clear(); + if (m_Osd) Start(); - } } eOSState cOsdPipObject::ProcessKey(eKeys Key) { @@ -147,44 +213,42 @@ eOSState cOsdPipObject::ProcessKey(eKeys Key) { case k1...k9: switch (Key & ~k_Repeat) { - case k1: - m_Xpos = 25; - m_Ypos = 25; - break; - case k2: - m_Xpos = (Setup.OSDwidth * cOsd::CellWidth()) / 2 - 75; - m_Ypos = 25; + case k1: + if (OsdPipSetup.XPosition > 9) OsdPipSetup.XPosition -= 10; + if (OsdPipSetup.YPosition > 9) OsdPipSetup.YPosition -= 10; break; - case k3: - m_Xpos = (Setup.OSDwidth * cOsd::CellWidth()) - 175; - m_Ypos = 25; + case k2: + if (OsdPipSetup.YPosition > 9) OsdPipSetup.YPosition -= 10; break; - case k4: - m_Xpos = 25; - m_Ypos = (Setup.OSDheight * cOsd::LineHeight()) / 2 - 55; + case k3: + if (OsdPipSetup.XPosition < Setup.OSDwidth * cOsd::CellWidth()) + OsdPipSetup.XPosition += 10; + if (OsdPipSetup.YPosition > 9) OsdPipSetup.YPosition -= 10; break; - case k5: - m_Xpos = (Setup.OSDwidth * cOsd::CellWidth()) / 2 - 75; - m_Ypos = (Setup.OSDheight * cOsd::LineHeight()) / 2 - 55; + case k4: + if (OsdPipSetup.XPosition > 9) OsdPipSetup.XPosition -= 10; break; case k6: - m_Xpos = (Setup.OSDwidth * cOsd::CellWidth()) - 155; - m_Ypos = (Setup.OSDheight * cOsd::LineHeight()) / 2 - 55; + if (OsdPipSetup.XPosition < Setup.OSDwidth * cOsd::CellWidth()) + OsdPipSetup.XPosition += 10; break; case k7: - m_Xpos = 25; - m_Ypos = (Setup.OSDheight * cOsd::LineHeight()) - 105; + if (OsdPipSetup.XPosition > 9) OsdPipSetup.XPosition -= 10; + if (OsdPipSetup.YPosition < Setup.OSDheight * cOsd::LineHeight()) + OsdPipSetup.YPosition += 10; break; - case k8: - m_Xpos = (Setup.OSDwidth * cOsd::CellWidth()) / 2 - 75; - m_Ypos = (Setup.OSDheight * cOsd::LineHeight()) - 105; + case k8: + if (OsdPipSetup.YPosition < Setup.OSDheight * cOsd::LineHeight()) + OsdPipSetup.YPosition += 10; break; case k9: - m_Xpos = (Setup.OSDwidth * cOsd::CellWidth()) - 175; - m_Ypos = (Setup.OSDheight * cOsd::LineHeight()) - 105; + if (OsdPipSetup.XPosition < Setup.OSDwidth * cOsd::CellWidth()) + OsdPipSetup.XPosition += 10; + if (OsdPipSetup.YPosition < Setup.OSDheight * cOsd::LineHeight()) + OsdPipSetup.YPosition += 10; break; } - m_Osd->Relocate(m_Window, m_Xpos, m_Ypos); + m_Osd->Relocate(m_Window, OsdPipSetup.XPosition, OsdPipSetup.YPosition); break; case kUp: @@ -20,9 +20,11 @@ private: cOsdPipReceiver *m_Receiver; const cChannel *m_Channel; tWindowHandle m_Window; + cBitmap *m_Bitmap; bool m_Active; - int m_Xpos, m_Ypos; + bool m_Ready; + int m_Width, m_Height; protected: virtual void Action(void); @@ -7,11 +7,12 @@ */ #include "osd.h" +#include "config.h" #include "i18n.h" #include <vdr/plugin.h> -static const char *VERSION = "0.0.1"; +static const char *VERSION = "0.0.2"; static const char *DESCRIPTION = "OSD Picture-in-Picture"; static const char *MAINMENUENTRY = "Picture-in-Picture"; @@ -75,11 +76,11 @@ cOsdObject *cPluginOsdpip::MainMenuAction(void) { } cMenuSetupPage *cPluginOsdpip::SetupMenu(void) { - return NULL; + return new cOsdPipSetupPage; } bool cPluginOsdpip::SetupParse(const char *Name, const char *Value) { - return false; + return OsdPipSetup.SetupParse(Name, Value); } VDRPLUGINCREATOR(cPluginOsdpip); // Don't touch this! |