From c024446839241af2fa7d618ce49cc8c1e5693f7f Mon Sep 17 00:00:00 2001 From: Andreas Regel Date: Sat, 31 Jul 2004 23:55:00 +0200 Subject: Release version 0.0.6 - added channel swapping. It is now possible to swap the currently viewed channel with the pip channel by pressing the red key. (thanks to Sascha Volkenandt) - added support for other aspect ratios than 4:3. Image is now correctly scaled and black border is added when necessary. - added automatic frame dropping that always takes the last frame from the ringbuffer. - added -D_GNU_SOURCE to DEFINES in Makefile - fixed a memory leak: missing deletion of frame ringbuffer - fixed a memory leak: missing frame deletion in case of a full ringbuffer - small speedup through just putting relevant frames to ringbuffer - updated finnish translations (thanks to Rolf Ahrenberg) --- HISTORY | 14 +++ Makefile | 3 +- README | 3 +- TODO | 3 - config.c | 149 --------------------------- config.h | 61 ----------- decoder.c | 8 +- decoder.h | 2 +- i18n.c | 96 ++++++++++++++++++ osd.c | 202 +++++++++++++++++++++++++++---------- osd.h | 2 + osdpip.c | 4 +- patches/vdr-1.2.6-256-palette.diff | 16 +-- receiver.c | 12 ++- setup.c | 158 +++++++++++++++++++++++++++++ setup.h | 61 +++++++++++ 16 files changed, 511 insertions(+), 283 deletions(-) delete mode 100644 config.c delete mode 100644 config.h create mode 100644 setup.c create mode 100644 setup.h diff --git a/HISTORY b/HISTORY index f22bc2a..7599aeb 100644 --- a/HISTORY +++ b/HISTORY @@ -1,6 +1,20 @@ VDR Plugin 'osdpip' Revision History ------------------------------------ +2004-08-01: Version 0.0.6 +- added channel swapping. It is now possible to swap the currently viewed + channel with the pip channel by pressing the red key. +- added support for other aspect ratios than 4:3. Image is now correctly + scaled and black border is added when necessary. +- added automatic frame dropping that always takes the last frame from + the ringbuffer. +- added -D_GNU_SOURCE to DEFINES in Makefile +- fixed a memory leak: missing deletion of frame ringbuffer +- fixed a memory leak: missing frame deletion in case of a full ringbuffer +- small speedup through just putting relevant frames to ringbuffer +- updated finnish translations (thanks to Rolf Ahrenberg) + + 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) diff --git a/Makefile b/Makefile index e8ad19a..1fbbde1 100644 --- a/Makefile +++ b/Makefile @@ -44,10 +44,11 @@ PACKAGE = vdr-$(ARCHIVE) INCLUDES += -I$(VDRDIR)/include -I$(DVBDIR)/include -I. -I$(FFMDIR)/libavcodec LIBS = -L$(FFMDIR)/libavcodec -lavcodec DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"' +DEFINES += -D_GNU_SOURCE ### The object files (add further files here): -OBJS = $(PLUGIN).o osd.o receiver.o config.o i18n.o pes.o quantize.o decoder.o +OBJS = $(PLUGIN).o osd.o receiver.o setup.o i18n.o pes.o quantize.o decoder.o ifdef FFMPEG_STATIC DEFINES += -DHAVE_FFMPEG_STATIC diff --git a/README b/README index e1f0646..29ecad0 100644 --- a/README +++ b/README @@ -22,7 +22,7 @@ down now, watching the progress of the previous channel in the box. Quality is not too good yet, and only I-Frames are displayed. The plugin supports four modes: - greyscaled (16 shades of grey) - - greyscaled (128 shades of grey) + - greyscaled (256 shades of grey) - 256 colors with fixed palette - 128 colors with variable palette The first mode works with an ordinary vdr installation. If you want to use the @@ -110,6 +110,7 @@ Controls: Up/Down Switch Channel up/down 1-4,6-9 Move box around like with cursor keys 0 Switch back to PiP channel and exit PiP +Red Swap PiP channel with currently viewed channel Back Exit PiP without switching back Ok Show/hide channel info window diff --git a/TODO b/TODO index 4810f75..7c7bdfe 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,3 @@ - improve fixed palette color quantization -- localization - vdr-like navigation through channels -- support other aspect ratios than 4:3 -- automatic frame drop diff --git a/config.c b/config.c deleted file mode 100644 index dee6136..0000000 --- a/config.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * OSD Picture in Picture plugin for the Video Disk Recorder - * - * See the README file for copyright information and how to reach the author. - */ - -#include - -#include "config.h" - -#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 - -# if MAXNUMCOLORS < 256 -const int kColorDepths = 1; -# 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[] = {NULL, NULL, NULL, NULL, NULL}; // initialized later -const char * InfoPositionItems[] = {NULL, NULL, NULL, NULL, NULL}; // initialized later - -const char * SizeItems[] = { - "120x96", - "160x128", - "200x160", - "240x192", - "280x224", - "320x256", - NULL -}; - -const char * FrameModeItems[] = { - "I", - "I, P", - "I, P, B" -}; - -cOsdPipSetup OsdPipSetup; - -cOsdPipSetup::cOsdPipSetup(void) -{ - XPosition = 50; - YPosition = 50; - CropLeft = 5; - CropRight = 5; - CropTop = 5; - CropBottom = 5; - ColorDepth = kDepthGrey16; - Size = 2; - FrameMode = kFrameModeI; - FrameDrop = 0; - SwapFfmpeg = 1; - ShowInfo = 1; - InfoWidth = 400; - InfoPosition = kInfoBottomLeft; -} - -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, "ColorDepth") == 0) ColorDepth = atoi(Value); - else if (strcmp(Name, "Size") == 0) Size = atoi(Value); - else if (strcmp(Name, "FrameMode") == 0) FrameMode = atoi(Value); - else if (strcmp(Name, "FrameDrop") == 0) FrameDrop = atoi(Value); - else if (strcmp(Name, "SwapFfmpeg") == 0) SwapFfmpeg = atoi(Value); - else if (strcmp(Name, "ShowInfo") == 0) ShowInfo = atoi(Value); - else if (strcmp(Name, "InfoWidth") == 0) InfoWidth = atoi(Value); - else if (strcmp(Name, "InfoPosition") == 0) InfoPosition = atoi(Value); - else return false; - return true; -} - -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("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)); -} - -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("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); -} - diff --git a/config.h b/config.h deleted file mode 100644 index 0a3dab0..0000000 --- a/config.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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_SETUP_H -#define VDR_OSDPIP_SETUP_H - -#include - -const int kDepthGrey16 = 0; -const int kDepthGrey256 = 1; -const int kDepthColor256fix = 2; -const int kDepthColor128var = 3; - -const int kFrameModeI = 0; -const int kFrameModeIP = 1; -const int kFrameModeIPB = 2; - -const int kInfoTopLeft = 0; -const int kInfoTopRight = 1; -const int kInfoBottomLeft = 2; -const int kInfoBottomRight = 3; - -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 ColorDepth; - int Size; - int FrameMode; - int FrameDrop; - int SwapFfmpeg; - int ShowInfo; - int InfoWidth; - int InfoPosition; -}; - -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 diff --git a/decoder.c b/decoder.c index eaa3160..08e5f53 100644 --- a/decoder.c +++ b/decoder.c @@ -8,7 +8,7 @@ #include #include "decoder.h" -#include "config.h" +#include "setup.h" int cDecoder::Open() @@ -98,3 +98,9 @@ int cDecoder::ConvertToRGB() return 0; } +double cDecoder::AspectRatio() +{ + //printf("%d %d %f\n", m_Context->width, m_Context->height, m_Context->aspect_ratio); + return m_Context->aspect_ratio; +} + diff --git a/decoder.h b/decoder.h index d9ca3e7..ecc0adb 100644 --- a/decoder.h +++ b/decoder.h @@ -35,7 +35,7 @@ public: int ConvertToRGB(); AVFrame * PicResample() { return m_PicResample; } AVFrame * PicConvert() { return m_PicConvert; } - float AspectRatio() { return m_Context->aspect_ratio; } + double AspectRatio(); }; #endif // VDR_OSDPIP_DECODER_H diff --git a/i18n.c b/i18n.c index eb9f5a2..04692a9 100644 --- a/i18n.c +++ b/i18n.c @@ -581,6 +581,102 @@ const tI18nPhrase Phrases[] = { # if VDRVERSNUM > 10307 "", // Croatian # endif +#endif + }, + { + "automatic", // English + "automatisch", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "automaattisesti", // Suomi + "", // Polski + "", // Español + "", // Ellinika + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Catala +#if VDRVERSNUM > 10302 + "", // Russian +# if VDRVERSNUM > 10307 + "", // Croatian +# endif +#endif + }, + { + "none", // English + "keine", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "ei", // Suomi + "", // Polski + "", // Español + "", // Ellinika + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Catala +#if VDRVERSNUM > 10302 + "", // Russian +# if VDRVERSNUM > 10307 + "", // Croatian +# endif +#endif + }, + { + "1 frame", // English + "1 Frame", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "1 kehys", // Suomi + "", // Polski + "", // Español + "", // Ellinika + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Catala +#if VDRVERSNUM > 10302 + "", // Russian +# if VDRVERSNUM > 10307 + "", // Croatian +# endif +#endif + }, + { + "2 frames", // English + "2 Frames", // Deutsch + "", // Slovenski + "", // Italiano + "", // Nederlands + "", // Português + "", // Français + "", // Norsk + "2 kehystä", // Suomi + "", // Polski + "", // Español + "", // Ellinika + "", // Svenska + "", // Romaneste + "", // Magyar + "", // Catala +#if VDRVERSNUM > 10302 + "", // Russian +# if VDRVERSNUM > 10307 + "", // Croatian +# endif #endif }, { NULL } diff --git a/osd.c b/osd.c index f441cec..19dc43d 100644 --- a/osd.c +++ b/osd.c @@ -8,7 +8,7 @@ #include "decoder.h" #include "quantize.h" #include "receiver.h" -#include "config.h" +#include "setup.h" #include #include @@ -43,13 +43,10 @@ cOsdPipObject::cOsdPipObject(cDevice *Device, const cChannel *Channel) cOsdPipObject::~cOsdPipObject() { - if (m_Active) - { - m_Active = false; - Cancel(3); - } + Stop(); delete m_Receiver; + delete m_ESBuffer; if (m_Bitmap != NULL) delete m_Bitmap; if (m_BitmapInfo != NULL) @@ -58,39 +55,75 @@ cOsdPipObject::~cOsdPipObject() delete m_Osd; } +void cOsdPipObject::Stop(void) +{ + if (m_Active) + { + m_Active = false; + Cancel(3); + } + m_ESBuffer->Clear(); +} + +void cOsdPipObject::SwapChannels(void) +{ + const cChannel *chan = cDevice::CurrentChannel() != 0 + ? Channels.GetByNumber(cDevice::CurrentChannel()) : NULL; + if (chan) { + Stop(); + Channels.SwitchTo(m_Channel->Number()); + cDevice *dev = cDevice::GetDevice(chan, 1); + if (dev) { + DELETENULL(m_Receiver); + m_Channel = chan; + dev->SwitchChannel(m_Channel, false); + m_Receiver = new cOsdPipReceiver(m_Channel, m_ESBuffer); + dev->AttachReceiver(m_Receiver); + } + Start(); + } +} + void cOsdPipObject::ProcessImage(unsigned char * data, int length) { unsigned int value; unsigned int * outputPalette; unsigned char * outputImage; + int height; - if (OsdPipSetup.FrameMode == kFrameModeI) + if (m_FrameDrop != -1) { - if (m_FrameDrop == OsdPipSetup.FrameDrop) + if (OsdPipSetup.FrameMode == kFrameModeI) { - m_FrameDrop = 0; - } - else - { - m_FrameDrop++; - return; + if (m_FrameDrop == OsdPipSetup.FrameDrop) + { + m_FrameDrop = 0; + } + else + { + m_FrameDrop++; + return; + } } } if (decoder.Decode(data, length) != 0) return; - if (OsdPipSetup.FrameMode == kFrameModeIP || - OsdPipSetup.FrameMode == kFrameModeIPB) + if (m_FrameDrop != -1) { - if (m_FrameDrop == OsdPipSetup.FrameDrop) + if (OsdPipSetup.FrameMode == kFrameModeIP || + OsdPipSetup.FrameMode == kFrameModeIPB) { - m_FrameDrop = 0; - } - else - { - m_FrameDrop++; - return; + if (m_FrameDrop == OsdPipSetup.FrameDrop) + { + m_FrameDrop = 0; + } + else + { + m_FrameDrop++; + return; + } } } @@ -229,30 +262,40 @@ void cOsdPipObject::ProcessImage(unsigned char * data, int length) #endif } - if (decoder.Resample(m_Width, m_Height) != 0) + if (decoder.AspectRatio() > 0.1) + height = (int) ((float) m_Width / decoder.AspectRatio() * 16.0f / 15.0f + 0.5); + else + height = m_Height; + if (decoder.Resample(m_Width, height) != 0) return; int size; - size = m_Width * m_Height; + size = m_Width * height; if (OsdPipSetup.ColorDepth == kDepthGrey16) { -#if VDRVERSNUM < 10307 +#if VDRVERSNUM >= 10307 + m_Bitmap->DrawRectangle(0, 0, m_Width - 1, (m_Height - height) / 2 - 1, m_Palette[0]); + m_Bitmap->DrawRectangle(0, (m_Height + height) / 2, m_Width - 1, m_Height - 1, m_Palette[0]); +#else m_Bitmap->Clear(); + m_Bitmap->Fill(0, 0, m_Width - 1, (m_Height - height) / 2 - 1, clrBlack); + m_Bitmap->Fill(0, (m_Height + height) / 2, m_Width - 1, m_Height - 1, clrBlack); #endif outputImage = decoder.PicResample()->data[0]; - for (int y = 0; y < m_Height; y++) + for (int y = 0; y < height; y++) { for (int x = 0; x < m_Width; x++) { value = outputImage[y * m_Width + x]; - value = value / 16; - value = value * 16; + value = value & 0xF0; + //value = value / 16; + //value = value * 16; value = m_AlphaBase | (value << 16) | (value << 8) | value; #if VDRVERSNUM >= 10307 - m_Bitmap->DrawPixel(x, y, value); + m_Bitmap->DrawPixel(x, y + (m_Height - height) / 2, value); #else - m_Bitmap->SetPixel(x, y, (eDvbColor) value); + m_Bitmap->SetPixel(x, y + (m_Height - height) / 2, (eDvbColor) value); #endif } } @@ -261,17 +304,20 @@ void cOsdPipObject::ProcessImage(unsigned char * data, int length) { outputImage = decoder.PicResample()->data[0]; #if VDRVERSNUM >= 10307 + m_Bitmap->DrawRectangle(0, 0, m_Width - 1, m_Height - 1, m_Palette[0]); for (int i = 0; i < 256; i++) m_Bitmap->SetColor(i, m_Palette[i]); +#else + m_Bitmap->Fill(0, 0, m_Width - 1, m_Height - 1, (eDvbColor) m_Palette[0]); #endif - for (int y = 0; y < m_Height; y++) + for (int y = 0; y < height; y++) { for (int x = 0; x < m_Width; x++) { #if VDRVERSNUM >= 10307 - m_Bitmap->SetIndex(x, y, outputImage[y * m_Width + x]); + m_Bitmap->SetIndex(x, y + (m_Height - height) / 2, outputImage[y * m_Width + x]); #else - m_Bitmap->SetPixel(x, y, (eDvbColor) m_Palette[outputImage[y * m_Width + x]]); + m_Bitmap->SetPixel(x, y + (m_Height - height) / 2, (eDvbColor) m_Palette[outputImage[y * m_Width + x]]); #endif } } @@ -306,17 +352,20 @@ void cOsdPipObject::ProcessImage(unsigned char * data, int length) if (OsdPipSetup.ColorDepth == kDepthColor256fix) { #if VDRVERSNUM >= 10307 + m_Bitmap->DrawRectangle(0, 0, m_Width - 1, m_Height - 1, m_Palette[0]); for (int i = 0; i < 256; i++) m_Bitmap->SetColor(i, m_Palette[i]); +#else + m_Bitmap->Fill(0, 0, m_Width - 1, m_Height - 1, (eDvbColor) m_Palette[0]); #endif - for (int y = 0; y < m_Height; y++) + for (int y = 0; y < height; y++) { for (int x = 0; x < m_Width; x++) { #if VDRVERSNUM >= 10307 - m_Bitmap->SetIndex(x, y, outputImage[y * m_Width + x] + 1); + m_Bitmap->SetIndex(x, y + (m_Height - height) / 2, outputImage[y * m_Width + x] + 1); #else - m_Bitmap->SetPixel(x, y, (eDvbColor) m_Palette[outputImage[y * m_Width + x]]); + m_Bitmap->SetPixel(x, y + (m_Height - height) / 2, (eDvbColor) m_Palette[outputImage[y * m_Width + x]]); #endif } } @@ -329,17 +378,20 @@ void cOsdPipObject::ProcessImage(unsigned char * data, int length) m_Palette[m_PaletteStart + i] |= m_AlphaBase; } - for (int i = 0; i < 256; i++) #if VDRVERSNUM >= 10307 + m_Bitmap->DrawRectangle(0, 0, m_Width - 1, m_Height - 1, m_Palette[0]); + for (int i = 0; i < 256; i++) m_Bitmap->SetColor(i, m_Palette[i]); #else + for (int i = 0; i < 256; i++) m_Bitmap->SetColor(i, (eDvbColor) m_Palette[i]); + m_Bitmap->Fill(0, 0, m_Width - 1, m_Height - 1, (eDvbColor) m_Palette[0]); #endif - for (int y = 0; y < m_Height; y++) + for (int y = 0; y < height; y++) { for (int x = 0; x < m_Width; x++) { - m_Bitmap->SetIndex(x, y, m_PaletteStart + outputImage[y * m_Width + x]); + m_Bitmap->SetIndex(x, y + (m_Height - height) / 2, m_PaletteStart + outputImage[y * m_Width + x]); } } @@ -406,24 +458,45 @@ void cOsdPipObject::Action(void) m_Reset = false; } #endif - frame = m_ESBuffer->Get(); + if (m_FrameDrop == -1) { - if (frame && frame->Count() > 0) + while ((frame = m_ESBuffer->Get()) != NULL) { - pictureType = frame->Index(); - if ((OsdPipSetup.FrameMode == kFrameModeI && pictureType == I_FRAME) || - (OsdPipSetup.FrameMode == kFrameModeIP && (pictureType == I_FRAME || pictureType == P_FRAME)) || - (OsdPipSetup.FrameMode == kFrameModeIPB)) + if (frame->Count() > 0) { - ProcessImage(frame->Data(), frame->Count()); + if (m_ESBuffer->Available() == frame->Count()) + break; + if (OsdPipSetup.FrameMode == kFrameModeIP || + OsdPipSetup.FrameMode == kFrameModeIPB) + { + decoder.Decode(frame->Data(), frame->Count()); + } } m_ESBuffer->Drop(frame); } - else + if (frame) { - if (frame) + pictureType = frame->Index(); + ProcessImage(frame->Data(), frame->Count()); + m_ESBuffer->Drop(frame); + } + } + else + { + frame = m_ESBuffer->Get(); + { + if (frame && frame->Count() > 0) + { + pictureType = frame->Index(); + ProcessImage(frame->Data(), frame->Count()); m_ESBuffer->Drop(frame); - usleep(1); + } + else + { + if (frame) + m_ESBuffer->Drop(frame); + usleep(1); + } } } if (m_ShowTime != 0) @@ -431,8 +504,10 @@ void cOsdPipObject::Action(void) if (m_ShowInfo) { #if VDRVERSNUM >= 10307 + ShowChannelInfo(Channels.GetByNumber(cDevice::ActualDevice()->CurrentChannel())); m_Osd->DrawBitmap(m_InfoX, m_InfoY, *m_BitmapInfo); #else + ShowChannelInfo(Channels.GetByNumber(cDevice::ActualDevice()->CurrentChannel())); m_Osd->SetBitmap(0, 0, *m_BitmapInfo, m_WindowInfo); m_Osd->Show(m_WindowInfo); #endif @@ -481,6 +556,9 @@ eOSState cOsdPipObject::ProcessKey(eKeys Key) case k0: Channels.SwitchTo(m_Channel->Number()); case kBack: return osEnd; + case kRed: SwapChannels(); + break; + case k1...k9: #if VDRVERSNUM >= 10307 switch (Key & ~k_Repeat) { @@ -571,7 +649,9 @@ eOSState cOsdPipObject::ProcessKey(eKeys Key) if (m_ShowTime != 0) { m_ShowTime -= 2; } else { - ShowChannelInfo(Channels.GetByNumber(cDevice::ActualDevice()->CurrentChannel())); + //ShowChannelInfo(Channels.GetByNumber(cDevice::ActualDevice()->CurrentChannel())); + time(&m_ShowTime); + m_ShowInfo = true; } } break; @@ -592,7 +672,11 @@ void cOsdPipObject::ChannelSwitch(const cDevice * device, int channelNumber) if (!m_Ready) return; if (OsdPipSetup.ShowInfo) - ShowChannelInfo(Channels.GetByNumber(device->CurrentChannel())); + { + //ShowChannelInfo(Channels.GetByNumber(device->CurrentChannel())); + time(&m_ShowTime); + m_ShowInfo = true; + } } void cOsdPipObject::ShowChannelInfo(const cChannel * channel, bool show) @@ -665,6 +749,12 @@ void cOsdPipObject::ShowChannelInfo(const cChannel * channel, bool show) if (show) { m_Palette[0] = 0xFD000000; + 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]); + m_Osd->DrawBitmap(m_InfoX, m_InfoY, *m_BitmapInfo); + m_Osd->Flush(); m_Palette[255] = 0xFDFFFFFF; m_BitmapInfo->DrawRectangle(0, 0, OsdPipSetup.InfoWidth - 1, 60 - 1, m_Palette[0]); for (int i = 0; i < 256; i++) @@ -677,17 +767,19 @@ void cOsdPipObject::ShowChannelInfo(const cChannel * channel, bool show) } else { - m_Palette[0] = 0x00000000; + m_Palette[0] = 0xFD000000; 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]); + m_BitmapInfo->DrawRectangle(0, 0, OsdPipSetup.InfoWidth - 1, 30 - 1, m_Palette[255]); + m_BitmapInfo->DrawRectangle(0, 30, OsdPipSetup.InfoWidth - 1, 60 - 1, m_Palette[255]); } } #else if (OsdPipSetup.ColorDepth != kDepthGrey16) - for (int i = 0; i < 256; i++) - m_BitmapInfo->SetColor(i, (eDvbColor) m_Palette[i]); + 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); diff --git a/osd.h b/osd.h index 7388ada..37eb6fb 100644 --- a/osd.h +++ b/osd.h @@ -60,6 +60,8 @@ private: void ProcessImage(unsigned char * data, int length); void ShowChannelInfo(const cChannel * channel, bool show = true); + void Stop(void); + void SwapChannels(void); protected: virtual void Action(void); virtual void ChannelSwitch(const cDevice * device, int channelNumber); diff --git a/osdpip.c b/osdpip.c index 83f4545..076fb26 100644 --- a/osdpip.c +++ b/osdpip.c @@ -14,12 +14,12 @@ extern "C" } #include "osd.h" -#include "config.h" +#include "setup.h" #include "i18n.h" #include -static const char *VERSION = "0.0.5"; +static const char *VERSION = "0.0.6"; static const char *DESCRIPTION = "OSD Picture-in-Picture"; static const char *MAINMENUENTRY = "Picture-in-Picture"; diff --git a/patches/vdr-1.2.6-256-palette.diff b/patches/vdr-1.2.6-256-palette.diff index 1ea1c79..aab4f69 100644 --- a/patches/vdr-1.2.6-256-palette.diff +++ b/patches/vdr-1.2.6-256-palette.diff @@ -81,14 +81,14 @@ } --- 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 +@@ -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. diff --git a/receiver.c b/receiver.c index 56bc624..c813a43 100644 --- a/receiver.c +++ b/receiver.c @@ -6,6 +6,7 @@ #include "receiver.h" #include "pes.h" +#include "setup.h" #include #include @@ -66,7 +67,16 @@ void cOsdPipReceiver::Action(void) if (p) { if (NewPictureType != NO_PICTURE) { - m_ESBuffer->Put(new cFrame(VideoBuffer, VideoBufferPos, ftVideo, CurPictureType)); + if ((OsdPipSetup.FrameMode == kFrameModeI && CurPictureType == I_FRAME) || + (OsdPipSetup.FrameMode == kFrameModeIP && (CurPictureType == I_FRAME || CurPictureType == P_FRAME)) || + (OsdPipSetup.FrameMode == kFrameModeIPB)) + { + cFrame * frame = new cFrame(VideoBuffer, VideoBufferPos, ftVideo, CurPictureType); + if (!m_ESBuffer->Put(frame)) + { + delete frame; + } + } CurPictureType = NewPictureType; VideoBufferPos = 0; } diff --git a/setup.c b/setup.c new file mode 100644 index 0000000..6ddd9d9 --- /dev/null +++ b/setup.c @@ -0,0 +1,158 @@ +/* + * OSD Picture in Picture plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + */ + +#include + +#include "setup.h" + +#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 + +# if MAXNUMCOLORS < 256 +const int kColorDepths = 1; +# 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 kFrameDrops = 4; +const int kInfoPositions = 4; + +const char * ColorDepthItems[] = {NULL, NULL, NULL, NULL, NULL}; // initialized later +const char * InfoPositionItems[] = {NULL, NULL, NULL, NULL, NULL}; // initialized later +const char * FrameDropItems[] = {NULL, NULL, NULL, NULL, NULL}; // initialized later + +const char * SizeItems[] = { + "120x96", + "160x128", + "200x160", + "240x192", + "280x224", + "320x256", + NULL +}; + +const char * FrameModeItems[] = { + "I", + "I, P", + "I, P, B" +}; + +cOsdPipSetup OsdPipSetup; + +cOsdPipSetup::cOsdPipSetup(void) +{ + XPosition = 50; + YPosition = 50; + CropLeft = 5; + CropRight = 5; + CropTop = 5; + CropBottom = 5; + ColorDepth = kDepthGrey16; + Size = 2; + FrameMode = kFrameModeI; + FrameDrop = -1; + SwapFfmpeg = 1; + ShowInfo = 1; + InfoWidth = 400; + InfoPosition = kInfoBottomLeft; +} + +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, "ColorDepth") == 0) ColorDepth = atoi(Value); + else if (strcmp(Name, "Size") == 0) Size = atoi(Value); + else if (strcmp(Name, "FrameMode") == 0) FrameMode = atoi(Value); + else if (strcmp(Name, "FrameDrop") == 0) FrameDrop = atoi(Value); + else if (strcmp(Name, "SwapFfmpeg") == 0) SwapFfmpeg = atoi(Value); + else if (strcmp(Name, "ShowInfo") == 0) ShowInfo = atoi(Value); + else if (strcmp(Name, "InfoWidth") == 0) InfoWidth = atoi(Value); + else if (strcmp(Name, "InfoPosition") == 0) InfoPosition = atoi(Value); + else return false; + return true; +} + +cOsdPipSetupPage::cOsdPipSetupPage(void) +{ + m_NewOsdPipSetup = OsdPipSetup; + m_NewOsdPipSetup.FrameDrop += 1; + + 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"); + + FrameDropItems[0] = tr("automatic"); + FrameDropItems[1] = tr("none"); + FrameDropItems[2] = tr("1 frame"); + FrameDropItems[3] = tr("2 frames"); + + 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 cMenuEditStraItem(tr("Drop frames"), &m_NewOsdPipSetup.FrameDrop, kFrameDrops, FrameDropItems)); + 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)); +} + +cOsdPipSetupPage::~cOsdPipSetupPage() +{ +} + +void cOsdPipSetupPage::Store(void) +{ + OsdPipSetup = m_NewOsdPipSetup; + OsdPipSetup.FrameDrop -= 1; + + 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); +} + diff --git a/setup.h b/setup.h new file mode 100644 index 0000000..0a3dab0 --- /dev/null +++ b/setup.h @@ -0,0 +1,61 @@ +/* + * 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_SETUP_H +#define VDR_OSDPIP_SETUP_H + +#include + +const int kDepthGrey16 = 0; +const int kDepthGrey256 = 1; +const int kDepthColor256fix = 2; +const int kDepthColor128var = 3; + +const int kFrameModeI = 0; +const int kFrameModeIP = 1; +const int kFrameModeIPB = 2; + +const int kInfoTopLeft = 0; +const int kInfoTopRight = 1; +const int kInfoBottomLeft = 2; +const int kInfoBottomRight = 3; + +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 ColorDepth; + int Size; + int FrameMode; + int FrameDrop; + int SwapFfmpeg; + int ShowInfo; + int InfoWidth; + int InfoPosition; +}; + +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 -- cgit v1.2.3