diff options
-rw-r--r-- | dxr3colormanager.c | 394 | ||||
-rw-r--r-- | dxr3colormanager.h | 134 | ||||
-rw-r--r-- | dxr3interface_spu_encoder.c | 620 | ||||
-rw-r--r-- | dxr3interface_spu_encoder.h | 125 |
4 files changed, 0 insertions, 1273 deletions
diff --git a/dxr3colormanager.c b/dxr3colormanager.c deleted file mode 100644 index e34332a..0000000 --- a/dxr3colormanager.c +++ /dev/null @@ -1,394 +0,0 @@ -/*************************************************************************** - dxr3colormanager.c - description - ------------------- - begin : Tue Oct 22 2002 - copyright : (C) 2002 by Stefan Schluenss - email : vdr@schluenss.de - ***************************************************************************/ - -/* - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -/** - * Background: - * Each encoded pixel in the SPU could have one of the values 0,1,2,3. * - * These values - - Pixelvalue Maps - to index - 0 --> 4 --> - - - * The SPU data definition allows highlighting of rectangular areas. They * - * are defined by a starting and ending row. Whithin these rows one could * - * define a starting column for using a new color palette mapping. This * - * mapping will be used til the end of the line or up to the next column * - * defintion. - * Look at the picture below: - * - Row Col=5 Col=16 - n-2 ............................... - n-1 ............................... - n .....-------------------------- <- Highligh region starts here - .....| 6,3,1,2 | 0,2,8,9 - .....| 6,3,1,2 | 0,2,8,9 - .....| 6,3,1,2 | 0,2,8,9 - n+4 .....-------------------------- <- Highligh region ends here - n+5 ............................... - n+6 ............................... - - In the above example one region (from n to n+4) is defined with two * - highlight sections - one from column 5 up to 15 and the second from 16 * - til the end of the line. -**/ - -#include "dxr3colormanager.h" -#include <vdr/tools.h> - -// ================================== -//! constructor -cColorManager::cColorManager() -{ - NrOfRegions = -1; - for(int i = 0; i < MAX_NO_OF_REGIONS; i++) - hlr[i] = NULL; -} - -// ================================== -cColorManager::~cColorManager() -{ - for (int i = 0; i < NrOfRegions; i++) - { - if (hlr[i]) - { - delete(hlr[i]); - } - } -} - -// ================================== -// Opens a new highlight region -void cColorManager::OpenRegion(int y) -{ - // Calling method (cColorManager::EncodeColors) - // already checks MAX_NO_OF_REGIONS - curRegion = new yRegion(); - curRegion->Y1 = y; - NrOfRegions++; - hlr[NrOfRegions] = curRegion; - NewSection(0); //there's always at least a section -} - -// ================================== -// Closes the spu-highlight region -void cColorManager::CloseRegion(int y) -{ - curRegion->Y2 = y; -} - -// ================================== -void cColorManager::EncodeColors(int width, int height, unsigned char* map, - unsigned char* dmap) -{ - unsigned char color; - unsigned char oldcolor = 0xFF; - unsigned char ColorIndex; - int mapoffset = 0; - - OpenRegion(0); - for (int y = 0; y < height; ++y) - { - oldcolor = 0xFF; - FirstSection(); - for(int x = 0; x < width; ++x) - { - if (x > curSection->X2) - { - oldcolor = 0xFF; - NextSection(); - } - color = map[mapoffset + x]; - if (color == oldcolor) - dmap[mapoffset + x] = ColorIndex; - else - { - // try to map the color in the current region - if (AddColor(x, y, color, ColorIndex)) - { - // store as the highlight region index - dmap[mapoffset + x] = ColorIndex; - } - else - { - CloseRegion(y - 1); - if (NrOfRegions <= MAX_NO_OF_REGIONS - 1) - { - // retry with another region - OpenRegion(y); - x = -1; - oldcolor = 0xFF; - } - else - { - esyslog("dxr3: colormanager: too many regions (%d)" - " - giving up", NrOfRegions); - return; - } - } - } - } - mapoffset += width; - } - // close the last highlight region - CloseRegion(height); - -//#define colordebug -#ifdef colordebug - { - FILE *fp; - fp = fopen("OSD.dump","w+"); - u_char *pippo = dmap; - u_char *pippo2 = map; - int curregion = 0; - int cursection = 0; - - - for (int dumpy = 0; dumpy < height; dumpy++) - { - if(curregion < NrOfRegions) - { - if(hlr[curregion]->Y1 == dumpy) - { - fprintf(fp, "%i", hlr[curregion]->N); - for (int sec = 0; sec < hlr[curregion]->N; sec++) - fprintf(fp, ",%i", hlr[curregion]->Section[sec]->X1); - for (int dumpx = 0; dumpx < width; dumpx++) - fprintf(fp, "="); - fprintf(fp, "\n"); - curregion++; - } - } - - cursection = 0; - for (int dumpx = 0; dumpx < width; dumpx++) - { - if (curregion < NrOfRegions) - { - if (cursection < hlr[curregion]->N) - { - if (hlr[curregion]->Section[cursection]->X1 == dumpx) - { - fprintf(fp, "|"); - cursection++; - } - } - } - fprintf(fp, "%01X", *pippo2 & 0xF); - pippo2++; - } - fprintf(fp, "\n"); - - cursection = 0; - for (int dumpx = 0; dumpx < width; dumpx++) - { - if(curregion < NrOfRegions) - { - if (cursection < hlr[curregion]->N) - { - if (hlr[curregion]->Section[cursection]->X1 == dumpx) - { - fprintf(fp, "|"); - cursection++; - } - } - } - fprintf(fp, "%01X", *pippo & 0xF); - pippo++; - } - fprintf(fp, "\n"); - } - fclose(fp); - printf("**** dumped\n"); - } -#endif -} - -// ================================== -unsigned char cColorManager::AddColor(int x, int y, unsigned char color, - unsigned char &ColorIndex) { - - if (!curSection->HasColor(color, ColorIndex)) - { - // this color is new for this section - if (curSection->AllColorsUsed(curRegion->Y1==y)) - { - // no more free colors - if (y != curRegion->Y1) - { - // terminate region - return(0); - } - NewSection(x); - } - // and add new color - ColorIndex = curSection->AddColor(color); - } - return(1); -} - -// ================================== -void cColorManager::FirstSection(void) -{ - curSectionIndex = 0; - curSection = curRegion->Section[0]; -} - -// ================================== -void cColorManager::NextSection(void) -{ - curSectionIndex++; - if (curSectionIndex < curRegion->N) - curSection=curRegion->Section[curSectionIndex]; - // it shouldn't happen - else esyslog("dxr3: colormanager: ran out of sections"); -} - -// ================================== -// convert into SPU - hope is correct description -unsigned char* cColorManager::GetSpuData(int& len) -{ - if (NrOfRegions >= 0) - { - int ptr = 0; - spudata[ptr++] = 0x07; // CHG_COLCON command - spudata[ptr++] = 0x00; // total size of parameter area - spudata[ptr++] = 0x00; // will be filled later - - - for(int i = 0; i <= NrOfRegions;i++) - { - spudata[ptr++] = (hlr[i]->Y1 >> 8) & 0x0f; - spudata[ptr++] = (hlr[i]->Y1 & 0xff); - spudata[ptr++] = (((hlr[i]->N) & 0x0f) << 4) | ((hlr[i]->Y2 >> 8) & 0x0f); - spudata[ptr++] = (hlr[i]->Y2 & 0xff); - - for(int c = 0; c < hlr[i]->N; c++) - { - spudata[ptr++] = hlr[i]->Section[c]->X1 >> 8; - spudata[ptr++] = hlr[i]->Section[c]->X1 & 0xff; - spudata[ptr++] = (hlr[i]->Section[c]->Colors[3] << 4) | (hlr[i]->Section[c]->Colors[2] & 0x0F); - spudata[ptr++] = (hlr[i]->Section[c]->Colors[1] << 4) | (hlr[i]->Section[c]->Colors[0] & 0x0F); - - spudata[ptr++] = (hlr[i]->Section[c]->Opac[3] << 4) | hlr[i]->Section[c]->Opac[2]; - spudata[ptr++] = (hlr[i]->Section[c]->Opac[1] << 4) | hlr[i]->Section[c]->Opac[0]; - } - } - spudata[ptr++] = 0x0f; // termination of parameter block - spudata[ptr++] = 0xff; - spudata[ptr++] = 0xff; - spudata[ptr++] = 0xff; - int size = ptr - 1; - spudata[1] = size >> 8; - spudata[2] = size & 0xff; - - len = ptr; - } - else - { - len = 0; - } - -#if OSD_SPU_CM_DUMP - FILE *fp; - fp = fopen("CM.dump", "a+"); - fprintf(fp, "len:%03d ", len); - for (int i = 0; i < len; i++) - fprintf(fp, "%02X", *(spudata + i)); - fprintf(fp, "\n"); - fclose(fp); -#endif - - return(spudata); -} - -// ================================== -void cColorManager::NewSection(int x) -{ - int N = curRegion->N; - if (N >= MAX_NO_OF_SECTIONS - 1) { - //esyslog("dxr3: colormanager: bummer, too many sections (%d)," - // " reusing last one", N); - return; // reuse last section, not optimal but there's no other way out - } - curSection = new xSection(x); - curRegion->Section[N] = curSection; - if (N > 0) - curRegion->Section[N-1]->X2 = x - 1; - (curRegion->N)++; - curSectionIndex = N; -} - -// ================================== -xSection::xSection(int x) -{ - X1 = x; - X2 = 32767; - NrOfColors = 0; - for (int i = 0; i < 4; i++) - { - Opac[i] = 0xFF; - Colors[i] = 0; - } -} - -// ================================== -unsigned char xSection::AddColor(unsigned int color) -{ - unsigned char ColorIndex = 0; - - if (NrOfColors <= 3) - { - Colors[NrOfColors] = color; - Opac[NrOfColors] = color >> 4; - ColorIndex = NrOfColors; - NrOfColors++; - } - return(ColorIndex); -} - -// ================================== -bool xSection::HasColor(unsigned int color, unsigned char &ColorIndex) -{ - for(int i = 0; i < NrOfColors; i++) - { - if (Colors[i] == color) - { - ColorIndex = i; - return (true); - } - } - return(false); -} - -// Local variables: -// mode: c++ -// c-file-style: "stroustrup" -// c-file-offsets: ((inline-open . 0)) -// tab-width: 4; -// indent-tabs-mode: nil -// End: diff --git a/dxr3colormanager.h b/dxr3colormanager.h deleted file mode 100644 index 4f95c02..0000000 --- a/dxr3colormanager.h +++ /dev/null @@ -1,134 +0,0 @@ -/*************************************************************************** - dxr3colormanager.h - description - ------------------- - begin : Tue Oct 22 2002 - copyright : (C) 2002 by Stefan Schluenss - email : vdr@schluenss.de - ***************************************************************************/ - -/* - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#ifndef _DXR3COLORMANAGER_H_ -#define _DXR3COLORMANAGER_H_ -/* -// ================================== -struct rectangular_area -{ - rectangular_area() : - m_startrow(0), m_endrow(0), m_startcol(0), m_endcol(0) {} - -private: - size_t m_startrow; - size_t m_endrow; - size_t m_startcol; - size_t m_endcol; - - unsigned int Colors[4]; - unsigned int Opac[4]; -} -*/ - -/**SPU-ColorManager - *@author Stefan Schluenss - */ - -#define OSD_SPU_CM_DUMP 0 - -#define MAX_NO_OF_SECTIONS 15 -#define MAX_NO_OF_REGIONS 100 - - -// ================================== -class xSection -{ -public: - xSection(int x); - bool HasColor(unsigned int color, unsigned char &ColorIndex); - unsigned char AddColor(unsigned int color); - bool AllColorsUsed(bool FirstLine) { - //DIAG("AllColorsUsed: %d\n",NrOfColors); - return(NrOfColors >= (FirstLine ? 3 : 4)); - }; - int X1; - int X2; - int NrOfColors; - unsigned int Colors[4]; - unsigned int Opac[4]; -}; - -// ================================== -class yRegion -{ -public: - yRegion() : Y1(0), Y2(0), N(0) {} - - /** No descriptions */ - void AddSection(int first, int last, unsigned int color, - unsigned int opac); - int Y1; - int Y2; - int N; - - xSection* Section[MAX_NO_OF_SECTIONS]; -}; - -// ================================== -class cColorManager -{ -public: - cColorManager(); - ~cColorManager(); - - void EncodeColors(int width, int height, unsigned char* smap, - unsigned char* dmap); - - /** Sets a new color on the OSD */ - unsigned char AddColor(int x, int y, unsigned char color, - unsigned char &ColorIndex); - - /** Encodes the color information as highlight spu data */ - unsigned char* GetSpuData(int &len); - -private: - yRegion *hlr[MAX_NO_OF_REGIONS]; - yRegion *curRegion; - int NrOfRegions; - unsigned char spudata[(4+6*MAX_NO_OF_SECTIONS)*MAX_NO_OF_REGIONS+7]; - xSection *curSection; - int curSectionIndex; - - /** Opens a new highlight region */ - void OpenRegion(int y); - /** Closes the spu-highlight region */ - void CloseRegion(int y); - - void NewSection(int x); - void FirstSection(void); - void NextSection(void); -}; - -#endif /*_DXR3COLORMANAGER_H_*/ - -// Local variables: -// mode: c++ -// c-file-style: "stroustrup" -// c-file-offsets: ((inline-open . 0)) -// tab-width: 4; -// indent-tabs-mode: nil -// End: diff --git a/dxr3interface_spu_encoder.c b/dxr3interface_spu_encoder.c deleted file mode 100644 index acf7c72..0000000 --- a/dxr3interface_spu_encoder.c +++ /dev/null @@ -1,620 +0,0 @@ -/* - * dxr3interface_spu_encoder.c - encodes an OSD bitmap as subpicture - * - * Assimilated and adapted by - * Stefan Schluenss <dxr3_osd@schluenss.de> - * Nov. 2002 - * - * Based on the subpicture encoding routines from MPlayer and - * the information given by - * Samuel Hocevar - * Michel Lespinasse - * and http://members.aol.com/mpucoder/DVD/spu.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#include "dxr3interface_spu_encoder.h" -#include "dxr3tools.h" - -/* - ToDo: - - cSPUEncoder::encode_do_row: FIXME: watch this space for EOL -*/ - - -#ifdef USE_XINE_SCALER -/*======================================================================= - * - * Scaling functions taken from the xine plugin - * - */ - -#include <math.h> -#include <signal.h> -#include <string> -#include <vdr/plugin.h> - -namespace XineScaler -{ - - template <const int yInc = 1, class T = int> - class cBresenham - { - const int m_dx; - const int m_dy; - - int m_eps; - T m_y; - - public: - cBresenham(const int dy, const int dx, const int eps, T const y0 = 0) - : m_dx(dx), m_dy(dy), m_eps(eps - m_dx), m_y(y0) - { - } - - int eps() const - { - return m_eps; - } - - T step() - { - m_eps += m_dy; - while (m_eps >= 0) - { - m_eps -= m_dx; - m_y += yInc; - } - return m_y; - } - - T step(int n) - { - if (n <= 0) - return m_y; - while (--n > 0) - step(); - return step(); - } - - T stepRelative(int n = 1) - { - T const y = m_y; - return step(n) - y; - } - }; - - static uint8_t *ScaleBitmapLQ(const uint8_t *src, uint8_t *dest, int x0, - int y0, int w, int h, int ws, int hs, int x1, - int y1, int w1, int h1, - const uint8_t transparentIndex) - { - uint8_t *const screen = new uint8_t[ OSDHEIGHT * OSDWIDTH ]; - { - int x1 = x0 + w; - int y1 = y0 + h; - int x2 = OSDWIDTH; - int y2 = OSDHEIGHT; - - if (x1 > x2) - x1 = x2; - - if (y1 > y2) - y1 = y2; - - uint8_t *dst = screen; - - for (int y = 0; y < y0; y++) - { - for (int x = 0; x < x2; x++) - *dst++ = transparentIndex; - } - - for (int y = y0; y < y1; y++) - { - for (int x = 0; x < x0; x++) - *dst++ = transparentIndex; - - for (int x = x0; x < x1; x++) - *dst++ = *src++; - - for (int x = x1; x < x2; x++) - *dst++ = transparentIndex; - } - - for (int y = y1; y < y2; y++) - { - for (int x = 0; x < x2; x++) - *dst++ = transparentIndex; - } - } - - uint8_t *scaled = dest; //new uint8_t[ hs * ws ]; - { - int x2 = x1 + w1; - int y2 = y1 + h1; - - if (x2 > ws) - { - x2 = ws; - w1 = x2 - x1; - if (w1 < 0) - w1 = 0; - } - - if (y2 > hs) - { - y2 = hs; - h1 = y2 - y1; - if (h1 < 0) - h1 = 0; - } - - cBresenham<OSDWIDTH, uint8_t *> yyBh(2 * OSDHEIGHT, 2 * hs, hs, screen); - uint8_t *screen0 = yyBh.step(y1); //(((2 * y1 + 1) * OSDHEIGHT / hs) / 2); - - cBresenham<> xxBh0(2 * OSDWIDTH, 2 * ws, ws); - xxBh0.step(x1); //(((2 * x1 + 1) * OSDWIDTH / ws) / 2); - - uint8_t *scaled0 = scaled + y1 * OSDWIDTH; //ws; ****** - - for (int y = y1; y < y2; y++) - { - cBresenham<> xxBh(xxBh0); - int xxx = xxBh.step(0); //(((2 * x1 + 1) * OSDWIDTH / ws) / 2); - - uint8_t *screen00 = screen0 + xxx; - uint8_t *scaled00 = scaled0 + x1; - - for (int x = x1; x < x2; x++) - { - *scaled00++ = *screen00; - screen00 += xxBh.stepRelative(); - } - - scaled0 += OSDWIDTH; //ws; ******* - screen0 = yyBh.step(); - } - } - - delete [] screen; - return scaled; - } - -} - -/*======================================================================= - * - * End of scaling functions taken from the xine plugin - * - */ -#endif /* USE_XINE_SCALER */ - -// ================================== -cSPUEncoder::cSPUEncoder() -{ - // clear osd - memset(OSD_Screen, 0x00, OSDWIDTH * OSDHEIGHT); - memset(OSD_Screen2, 0x00, OSDWIDTH * OSDHEIGHT); - memset(OSD_Screen3, 0x00, OSDWIDTH * OSDHEIGHT); - - // set active area to 0 - //m_x0 = m_x1 = m_y0 = m_y1 = 0; -} - - -//======================================== -//Sets the palette indexes to use for one -//window taking into account the global -//palette (with colors needed by all windows) - -void cSPUEncoder::SetPalette(int numWindow, cPalette* commonPalette, - cPalette* windowPalette) -{ - int NumColors; - const tColor *Colors = windowPalette->Colors(NumColors); - if (Colors) - { - for (int i = 0; i < NumColors; i++) - { - int idx = commonPalette->Index(Colors[i] & 0x00FFFFFF); - int opacity = ((Colors[i] & 0xFF000000) >> 24) * 0xF / 0xFF; - bitmapcolor[numWindow][i] = (opacity<<4) | idx; - } - } -} - -//======================================== -//Clears the OSD bitmap - -void cSPUEncoder::Clear(void) -{ - memset(OSD_Screen, 0, sizeof(OSD_Screen)); -} - -//============================================================= -//Sets the spu palette and flushes the OSD content into the spu -int cSPUEncoder::Flush(cPalette *Palette) -{ - int NumColors; - const tColor *Colors = Palette->Colors(NumColors); - if (Colors) - { - unsigned int palcolors[16]; - for (int i = 0; i < NumColors; i++) - { - // convert AARRGGBB to AABBGGRR (the driver expected the the - // colors the wrong way, so does Rgb2YCrCb and friends) - unsigned int color = ((Colors[i] & 0x0000FF) << 16) - | (Colors[i] & 0x00FF00) | ((Colors[i] & 0xFF0000) >> 16); - palcolors[i] = Tools::Rgb2YCrCb(color); - } - cDxr3Interface::instance()->SetPalette(palcolors); - } - - // calculate osd size (actually dead code) - CalculateActiveOsdArea(); - - m_encodeddata.count = 0; - EncodePixelbufRle(0, 0, OSDWIDTH, OSDHEIGHT-1, OSD_Screen, 0, - &m_encodeddata); - -// dsyslog("dxr3: cSPUEncoder::Flush: OSD data size: %d", -// m_encodeddata.count); - - if (m_encodeddata.count <= DATASIZE) - { - cDxr3Interface::instance()->WriteSpu((uint8_t*) &m_encodeddata, - m_encodeddata.count); - return 0; - } - else - { - esyslog("dxr3: spu: warning: SPU data size (%d) exceeds limit (%d)", - m_encodeddata.count, DATASIZE); - return -1; - } -} - -// ================================== -// stamps window content into full osd bitmap -void cSPUEncoder::CopyBlockIntoOSD(int numWindow, int linewidth, int x0, - int y0, int x1, int y1, const tIndex *data) -{ - tIndex *cp; - const tIndex *sp = data; - - if (x1 >= OSDWIDTH) - x1 = OSDWIDTH - 1; - if (y1 >= OSDHEIGHT) - y1 = OSDHEIGHT - 1; - cp = &OSD_Screen[y0 * OSDWIDTH + x0]; - - for (int y = y0; y <= y1; y++) - { - for (int x = x0; x <= x1; x++) - { - *(cp++) = bitmapcolor[numWindow][*(sp++) & 0x0f]; - } - cp += OSDWIDTH - (x1 - x0 + 1); - sp += linewidth - (x1 - x0 + 1); - } -} - -// ================================== -// taken from mplayer (spuenc.c) -void cSPUEncoder::EncodePixelbufRle(int x, int y, int w, int h, u_char *inbuf, - int stride, encodedata *ed) -{ - pixbuf pb; - int i, row; - pb.x = w; - pb.y = h; - -#ifdef USE_XINE_SCALER - int ws = cDxr3Interface::instance()->GetHorizontalSize(); - int hs = cDxr3Interface::instance()->GetVerticalSize(); - if (ws < 720 || hs < 576) - inbuf = XineScaler::ScaleBitmapLQ(inbuf, OSD_Screen2, 0, 0, OSDWIDTH, - OSDHEIGHT, ws, hs, 0, 0, ws, hs, - 0 /* clrTransparent */); -#else - if (cDxr3Interface::Instance().GetHorizontalSize() < 700) - { - double fac = (double)OSDWIDTH / (double)OSDWIDTH2; - ScaleOSD(fac, inbuf, 10); - inbuf = OSD_Screen2; - } -#endif /* USE_XINE_SCALER */ - - m_ColorManager = new cColorManager(); - - // Encode colors into highlight regions - m_ColorManager->EncodeColors(w, h, inbuf, OSD_Screen3); - inbuf = OSD_Screen3; - - pb.pixels = inbuf; - ed->count = 4; - ed->nibblewaiting = 0; - - row = 0; - for (i = 0; i < pb.y; i++) - { - encode_do_row(ed, &pb, row); - row += 2; - if (row > pb.y) - { - row = 1; - ed->oddstart = ed->count; - } - } - encode_do_control(x, y, ed, &pb); - - delete m_ColorManager; -} - -#ifndef USE_XINE_SCALER -// ================================== -void cSPUEncoder::ScaleOSD(double fac, unsigned char* buf, - unsigned char NumColors) -{ - int y, x, s, d; - unsigned char dline[2 * OSDWIDTH + 10]; - - memset(OSD_Screen2, 0x00, OSDWIDTH * OSDHEIGHT); - - if (cDxr3Interface::Instance().GetHorizontalSize() < 470) - { - for (y = 0; y < OSDHEIGHT; y++) - for (s = 0, d = 0; d < OSDWIDTH; s++, d += 2) - OSD_Screen2[y * OSDWIDTH + s] = buf[y * OSDWIDTH + d]; - } - else - { - for (y = 0; y < OSDHEIGHT; y++) - { - memset(dline, 0, 2 * OSDWIDTH + 10); - - for (s = 0, d = 0; s < OSDWIDTH; s++, d += 2) - { - // stretch line to double width to 1440 - dline[d] = buf[y * OSDWIDTH + s]; - } - - for (d = 1; d < (2 * OSDWIDTH); d += 2) - { - dline[d] = dline[d + 1]; - } - - for (s = 0, x = 0; x < OSDWIDTH2; x++, s += 3) - { - // now take every third pixel (1440/3=480) - OSD_Screen2[y * OSDWIDTH + x] = dline[s]; - } - } - } -} -#endif /* not USE_XINE_SCALER */ - -// ================================== -// taken from mplayer (spuenc.c) -void cSPUEncoder::encode_put_nibble(encodedata* ed, u_char nibble) -{ - if (ed->nibblewaiting) - { - ed->data[ed->count++] |= nibble; - ed->nibblewaiting = 0; - } - else - { - ed->data[ed->count] = nibble << 4; - ed->nibblewaiting = 1; - } -} - -// ================================== -// taken from mplayer (spuenc.c) -void cSPUEncoder::encode_pixels(encodedata* ed, int color, int number) -{ - if (number > 3) - { - if (number > 15) - { - encode_put_nibble(ed, 0); - if (number > 63) - { - encode_put_nibble(ed, (number & 0xC0) >> 6); - } - } - encode_put_nibble(ed, (number & 0x3C) >> 2); - } - encode_put_nibble(ed, ((number & 0xF) << 2) | color); -} - -// ================================== -// taken from mplayer (spuenc.c) -void cSPUEncoder::encode_eol(encodedata* ed) -{ - if (ed->nibblewaiting) - { - ed->count++; - ed->nibblewaiting = 0; - } - ed->data[ed->count++] = 0x00; - ed->data[ed->count++] = 0x00; -} - -// ================================== -// taken from mplayer (spuenc.c) -void cSPUEncoder::encode_do_row(encodedata* ed, pixbuf* pb, int row) -{ - int i = 0; - u_char* pix = pb->pixels + row * pb->x; - int color = *pix & 0x03; - int n = 0; /* the number of pixels of this color */ - - while (i++ < pb->x) - { - /* FIXME: watch this space for EOL */ - if ((*pix & 0x03) != color || n == 255) - { - encode_pixels(ed, color, n); - color = *pix & 0x03; - n = 1; - } - else - { - n++; - } - pix++; - } - - /* this small optimization: (n>63) can save up to two bytes per line - * I wonder if this is compatible with all the hardware... */ - if (color == 0 && n > 63) - { - encode_eol(ed); - } - else - { - encode_pixels(ed, color, n); - } - - if (ed->nibblewaiting) - { - ed->count++; - ed->nibblewaiting = 0; - } -} - -// ================================== -// taken from mplayer (spuenc.c) -void cSPUEncoder::encode_do_control(int x, int y, encodedata* ed, pixbuf* pb) -{ - int controlstart = ed->count; - int x1; - int i; - u_int top, left, bottom, right; - - top = y; //this forces the first bit to be visible on a TV - left = x; //you could actually pass in x/y and do some nice - - bottom = top + pb->y - 1; - right = left + pb->x - 1; - - /* start at x0+2*/ - i = controlstart; - - x1 = (i); //marker for last command block address - - /* display duration... */ - ed->data[i++] = 0x00; - ed->data[i++] = 0x00; //duration before turn on command occurs (will not be used) - - /* x1 */ - ed->data[i++] = x1 >> 8; //since this is the last command block, this - ed->data[i++] = x1 & 0xff; //points back to itself - - /* 0x00: force displaying */ - ed->data[i++] = 0x00; - - /* 0x03: palette info */ - ed->data[i++] = 0x03; - ed->data[i++] = 0x01; - ed->data[i++] = 0x23; - - /* 0x04: transparency info (reversed) */ - ed->data[i++] = 0x04; // SET_CONTR - ed->data[i++] = 0xFF; - ed->data[i++] = 0x70; - - /* 0x05: coordinates */ - ed->data[i++] = 0x05; // SET_DAREA - ed->data[i++] = left >> 4; - ed->data[i++] = ((left & 0xf) << 4) + (right >> 8); - ed->data[i++] = (right & 0xff); - ed->data[i++] = top >> 4; - ed->data[i++] = ((top&0xf) << 4) + (bottom >> 8); - ed->data[i++] = (bottom&0xff); - - /* 0x06: both fields' offsets */ - ed->data[i++] = 0x06; // SET_DSPXA - ed->data[i++] = 0x00; - ed->data[i++] = 0x04; - ed->data[i++] = ed->oddstart >> 8; - ed->data[i++] = ed->oddstart & 0xff; - - int len; - unsigned char *spudata; - - spudata = m_ColorManager->GetSpuData(len); - //check that the highlight regions data wont overflow the buffer - if (i + len + 2 > DATASIZE) - { - ed->count = DATASIZE + 1; - return; - } - - for (int si = 0; si < len; si++) - { - ed->data[i++] = *(spudata + si); - } - - /* 0xFF: end sequence */ - ed->data[i++]= 0xFF; - if (! i&1) - { - ed->data[i++]= 0xff; - } - - /* x0 */ - ed->data[2] = (controlstart) >> 8; - ed->data[3] = (controlstart) & 0xff; - - /* packet size */ - ed->data[0] = i >> 8; - ed->data[1] = i & 0xff; - - ed->count = i; -} - -// ================================== -// we _only_ write usefull data -void cSPUEncoder::CalculateActiveOsdArea() -{ - // reset - //m_x0 = m_x1 = m_y0 = m_y1 = 0; - - // calculate - /* - for (int i = 1; i < 8; i++) - { - m_x0 = max(m_x0, m_windows[i].x0); - m_x1 = max(m_x1, m_windows[i].y0); - m_y0 = max(m_y0, m_windows[i].x1); - m_y1 = max(m_y1, m_windows[i].y1); - } - */ -} - -// Local variables: -// mode: c++ -// c-file-style: "stroustrup" -// c-file-offsets: ((inline-open . 0)) -// tab-width: 4; -// indent-tabs-mode: nil -// End: diff --git a/dxr3interface_spu_encoder.h b/dxr3interface_spu_encoder.h deleted file mode 100644 index a05d626..0000000 --- a/dxr3interface_spu_encoder.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * dxr3interface_spu_encoder.h - encodes an OSD bitmap as subpicture - * - * Assimilated and adapted by - * Stefan Schluenss <dxr3_osd@schluenss.de> - * Nov. 2002 - * - * Based on the subpicture encoding routines from MPlayer and - * the information given by - * Samuel Hocevar - * Michel Lespinasse - * and http://members.aol.com/mpucoder/DVD/spu.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ - -#ifndef _DXR3_INTERFACE_SPU_ENCODER_ -#define _DXR3_INTERFACE_SPU_ENCODER_ - -#include <vdr/osd.h> -#include "dxr3colormanager.h" -#include "dxr3interface.h" - -// ================================== -#define MAXWINDOWS 8 -#define DATASIZE 53220 -#define OSDWIDTH 720 -#define OSDWIDTH2 480 -#define OSDHEIGHT 576 - -// ================================== -// used to get active osd area -struct sRectal -{ - sRectal() : x0(0), x1(0), y0(0), y1(0) {} - - size_t x0; - size_t x1; - size_t y0; - size_t y1; -}; - -// ================================== -struct pixbuf -{ - int x, y; - u_int rgb[4]; - u_char* pixels; -}; - -// ================================== -struct encodedata -{ - u_char data[DATASIZE]; - int count; // the count of bytes written - int oddstart; - int nibblewaiting; -}; - -// ================================== -class cSPUEncoder : public Singleton<cSPUEncoder> -{ -public: - cSPUEncoder(); - ~cSPUEncoder() {} - - int Flush(cPalette *Palette); - void CopyBlockIntoOSD(int numWindow, int linewidth, - int x0,int y0, int x1, int y1, const tIndex *data); - void SetPalette(int numWindow, cPalette* commonPalette, - cPalette* windowPalette); - void Clear(void); - -private: - cSPUEncoder(cSPUEncoder&); // no copy constructor - - // helper functions - void EncodePixelbufRle(int x, int y, int w, int h, - u_char *inbuf, int stride, encodedata *ed); -#ifndef USE_XINE_SCALER - void ScaleOSD(double fac, unsigned char* buf, unsigned char NumColors=4); -#endif - void encode_put_nibble(encodedata* ed, u_char nibble); - void encode_pixels(encodedata* ed, int color, int number); - void encode_eol(encodedata* ed); - void encode_do_row(encodedata* ed, pixbuf* pb, int row); - void encode_do_control(int x,int y, encodedata* ed, pixbuf* pb); - - void CalculateActiveOsdArea(); - - int bitmapcolor[8][16]; - cColorManager* m_ColorManager; - encodedata m_encodeddata; - - // our osd :) - u_char OSD_Screen[OSDWIDTH * OSDHEIGHT]; - u_char OSD_Screen2[OSDWIDTH * OSDHEIGHT]; - u_char OSD_Screen3[OSDWIDTH * OSDHEIGHT]; - - // 'active' osd sizes - sRectal m_active_osd; -}; - -#endif /*_DXR3_INTERFACE_SPU_ENCODER_*/ - -// Local variables: -// mode: c++ -// c-file-style: "stroustrup" -// c-file-offsets: ((inline-open . 0)) -// tab-width: 4; -// indent-tabs-mode: nil -// End: |