*/
#include "bitmap.h"
+
+DisplayRegion::DisplayRegion()
+{
+ framewidth=720;
+ frameheight=576;
+ windowx=0;
+ windowy=0;
+ windoww=719;
+ windowh=575;
+}
+
Palette::Palette(UCHAR tBpp)
{
numColours = 0;
#include "defines.h"
#include <vector>
+class DisplayRegion {
+public:
+ DisplayRegion();
+ UINT windowx, windowy,windoww,windowh;
+ UINT framewidth,frameheight;
+};
+
+
+
class Palette
{
public:
\r
}\r
\r
-void Boxx::drawBitmap(UINT x, UINT y, const Bitmap& bm)\r
+void Boxx::drawBitmap(UINT x, UINT y, const Bitmap& bm, const DisplayRegion & region)\r
{\r
- if (parent) parent->drawBitmap(area.x + x, area.y + y, bm);\r
- else if (surface) surface->drawBitmap(x, y, bm);\r
+ if (parent) parent->drawBitmap(area.x + x, area.y + y, bm, region);\r
+ else if (surface) surface->drawBitmap(x, y, bm, region);\r
}\r
\r
void Boxx::drawJpeg(const char *fileName,int x, int y,int *width, int *height)\r
void drawTextCentre(const char* text, int x, int y, const DrawStyle& colour);\r
//Now deprecated\r
//void drawPixel(UINT x, UINT y, const Colour& colour, bool fastdraw=false);\r
- void drawBitmap(UINT x, UINT y, const Bitmap& bm);\r
+ void drawBitmap(UINT x, UINT y, const Bitmap& bm, const DisplayRegion & region);\r
//Now deprecated\r
// void drawPixelAlpha(UINT x, UINT y, const Colour& colour,bool fastdraw=false);\r
int getFontHeight();\r
region->second.palette = clut.getPalette(region->second.palette.getBpp());
}
+DVBSubtitleDisplayDefinition::DVBSubtitleDisplayDefinition()
+{
+ version=0xFF;
+ displaywindow=false;
+}
+
class DVBSubtitleObject
{
private:
; // TODO
break;
}
- case 0x14: // Display definition
- break; // TODO: Ignore now and assume 720x576 per ETSI EN 300 743 V1.2.1
+ case 0x14: {// Display definition
+ if (segmentLength<5) break;
+ UINT ddsversion=(segmentData[0]&0xf0)>>4;
+ if (ddsversion==dds.version) break; // no update ncessary
+ dds.version=ddsversion;
+ dds.displaywindow=!(!(segmentData[0]&0x08));
+ dds.framewidth=(segmentData[1] << 8) + segmentData[2];
+ dds.frameheight=(segmentData[3] << 8) + segmentData[4];
+ if (segmentLength<13) break;
+ if (dds.displaywindow) {
+ dds.windowx=(segmentData[4] << 8) + segmentData[5];
+ dds.windoww=(segmentData[6] << 8) + segmentData[7]-dds.windowx;
+ dds.windowy=(segmentData[8] << 8) + segmentData[9];
+ dds.windowh=(segmentData[10] << 8) + segmentData[11]-dds.windowy;
+ } else {
+ dds.windowx=0;
+ dds.windowy=0;
+ dds.windoww=dds.framewidth;
+ dds.windowh=dds.frameheight;
+ }
+ break;
+ }
case 0x80: // End of display set
finishPage(page);
page.dirty = false;
if (region_iter == page.regions.end()) continue;
Log::getInstance()->log("SUBTITLES", Log::DEBUG, "Clear region %d", i->first);
osd->clearOSDArea(i->second.x, i->second.y,
- region_iter->second.getWidth(), region_iter->second.getHeight());
+ region_iter->second.getWidth(), region_iter->second.getHeight(),dds);
}
}
region_iter = page.regions.find(i->first);
if (region_iter == page.regions.end()) continue;
Log::getInstance()->log("SUBTITLES", Log::DEBUG, "Display region %d", i->first);
- osd->drawOSDBitmap(i->second.x, i->second.y, region_iter->second);
+ osd->drawOSDBitmap(i->second.x, i->second.y, region_iter->second,dds);
}
}
int DVBSubtitles::start()
{
lockInput();
+ dds=DVBSubtitleDisplayDefinition();
running = true;
unlockInput();
return threadStart();
region_iter = page.regions.find(i->first);
if (region_iter == page.regions.end()) continue;
osd->clearOSDArea(i->second.x, i->second.y,
- region_iter->second.getWidth(), region_iter->second.getHeight());
+ region_iter->second.getWidth(), region_iter->second.getHeight(),dds);
}
}
pages.clear();
region_iter = page.regions.find(i->first);
if (region_iter == page.regions.end()) continue;
osd->clearOSDArea(i->second.x, i->second.y,
- region_iter->second.getWidth(), region_iter->second.getHeight());
+ region_iter->second.getWidth(), region_iter->second.getHeight(),dds);
}
}
pages.clear();
void updateRegionPalettes(const DVBSubtitleCLUT&);
};
+class DVBSubtitleDisplayDefinition: public DisplayRegion
+{
+public:
+ DVBSubtitleDisplayDefinition();
+
+ UCHAR version;
+ bool displaywindow;
+
+};
+
class DVBSubtitles : public Thread_TYPE
{
public:
DVBSubtitles(OSDReceiver* tosd = NULL);
- ~DVBSubtitles() {}
+ virtual ~DVBSubtitles() {}
void put(const PESPacket& packet);
int start();
void stop();
UINT pageOnDisplay;
bool decodePacket(const PESPacket&);
void finishPage(const DVBSubtitlePage&);
+ DVBSubtitleDisplayDefinition dds;
bool running;
bool showing;
vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER);\r
vgScale(aspect_correction,1.f);\r
} else {\r
+ VGfloat imagewidth=vgGetParameteri((VGImage) command.target.image, VG_IMAGE_WIDTH);\r
+ VGfloat imageheight=vgGetParameteri((VGImage) command.target.image, VG_IMAGE_HEIGHT);\r
//vgScale(720.f/((float)BACKBUFFER_WIDTH), 576.f/((float)BACKBUFFER_HEIGHT));\r
- vgScale(aspect_correction,1.f);\r
+ float scalex=command.w/imagewidth;\r
+ float scaley=command.h/imageheight;\r
+ //vgScale(command.w/imagewidth,command.h/imageheight);\r
+ vgScale(scalex,scaley);\r
vgSeti(VG_IMAGE_MODE,VG_DRAW_IMAGE_NORMAL);\r
+ //Log::getInstance()->log("OSD", Log::DEBUG, "Draw Image Scale %g %g %g %g %g %g",command.w,imagewidth,command.h,imageheight,scalex,scaley);\r
}\r
\r
\r
vgDestroyPaint((VGPaint)command.param1);\r
return 0;\r
} break;\r
- case OVGcreateImageRGBA: {\r
- return vgCreateImage(VG_sRGBA_8888,command.param1, command.param2,\r
- VG_IMAGE_QUALITY_NONANTIALIASED|\r
- VG_IMAGE_QUALITY_FASTER|VG_IMAGE_QUALITY_BETTER);\r
+ case OVGcreateImagePalette: {\r
+ VGImage input=vgCreateImage(VG_A_8,command.param1, command.param2,\r
+ VG_IMAGE_QUALITY_NONANTIALIASED|\r
+ VG_IMAGE_QUALITY_FASTER|VG_IMAGE_QUALITY_BETTER);\r
+ vgImageSubData(input,command.data,command.param1,\r
+ VG_A_8,0,0,command.param1, command.param2); // upload palettized image data\r
+ VGImage handle=vgCreateImage(VG_sRGBA_8888,command.param1, command.param2,\r
+ VG_IMAGE_QUALITY_NONANTIALIASED|\r
+ VG_IMAGE_QUALITY_FASTER|VG_IMAGE_QUALITY_BETTER);\r
+ VGuint *palette=(VGuint*)malloc(256*sizeof(VGuint));\r
+ VGuint *in_palette=(VGuint*)command.data2;\r
+ for (int i=0;i<256;i++) {\r
+ VGuint color=in_palette[i];\r
+ palette[i]=color<<8 | (color &0xff000000)>>24;\r
+ }\r
+\r
+ vgLookupSingle(handle,input,palette,VG_ALPHA,VG_FALSE,VG_FALSE);\r
+ free(palette);\r
+ vgDestroyImage(input);\r
+\r
+ return handle;\r
} break;\r
case OVGcreateMonoBitmap: {\r
VGImage handle=vgCreateImage(VG_A_1,command.param1, command.param2,\r
return putOpenVGCommand(comm,true);\r
}\r
\r
-ImageIndex OsdOpenVG::createImageRGBA(int width,int height)\r
+ImageIndex OsdOpenVG::createImagePalette(int width,int height,const unsigned char *image_data,const unsigned int*palette_data)\r
{\r
struct OpenVGCommand comm;\r
- comm.task=OVGcreateImageRGBA;\r
+ comm.task=OVGcreateImagePalette;\r
comm.param1=width;\r
comm.param2=height;\r
+ comm.data=image_data;\r
+ comm.data2=palette_data;\r
return putOpenVGCommand(comm,true);\r
}\r
\r
enum OpenVGTask {\r
OVGdestroyImageRef,\r
OVGdestroyPaint,\r
- OVGcreateImageRGBA,\r
+ OVGcreateImagePalette,\r
OVGcreateMonoBitmap,\r
OVGcreateColorRef,\r
OVGimageUploadLine,\r
{\r
enum OpenVGTask task;\r
const void *data;\r
+ const void *data2;\r
unsigned int param1,param2,param3;\r
unsigned int id; //only set an id if you are waiting\r
};\r
void destroyImageRef(ImageIndex index);\r
ImageIndex createJpeg(const char* fileName, int *width,int *height);\r
ImageIndex createMonoBitmap(void *base,int width,int height);\r
- ImageIndex createImageRGBA(int width,int height);\r
+ ImageIndex createImagePalette(int width,int height,const unsigned char *image_data,const unsigned int*palette_data);\r
void destroyStyleRef(unsigned int index);\r
unsigned int createStyleRef(const DrawStyle &c);\r
unsigned int createColorRef(const Colour &c);\r
#define OSDRECEIVER_H
class Bitmap;
+class DisplayRegion;
class OSDReceiver
{
public:
- virtual void drawOSDBitmap(UINT posX, UINT posY, const Bitmap&)=0;
+ virtual void drawOSDBitmap(UINT posX, UINT posY, const Bitmap&, const DisplayRegion& region)=0;
virtual void clearOSD()=0;
- virtual void clearOSDArea(UINT posX, UINT posY, UINT width, UINT height)=0;
+ virtual void clearOSDArea(UINT posX, UINT posY, UINT width, UINT height, const DisplayRegion& region)=0;
};
#endif
return image_handle;\r
}\r
\r
-ImageIndex OsdVector::getImageRGBA(int width,int height)\r
+ImageIndex OsdVector::getImagePalette(int width,int height,const unsigned char *image_data,const unsigned int*palette_data)\r
{\r
ImageIndex image_handle;\r
- image_handle=createImageRGBA(width,height);\r
+ image_handle=createImagePalette(width,height,image_data,palette_data);\r
incImageRef(image_handle);\r
return image_handle;\r
}\r
\r
virtual ImageIndex getJpegRef(const char* fileName, int *width,int *height);\r
virtual ImageIndex getMonoBitmapRef(void *base,int width,int height);\r
- virtual ImageIndex getImageRGBA(int width,int height);\r
+ virtual ImageIndex getImagePalette(int width,int height,const unsigned char *image_data,const unsigned int*palette_data);\r
virtual void imageUploadLine(ImageIndex index,unsigned int j,unsigned int width,void *data)=0;\r
void removeImageRef(const ImageIndex ref);\r
unsigned int getColorRef(const Colour &c); //internally this is the same as getStyleRef\r
virtual void destroyImageRef(ImageIndex index)=0;\r
virtual ImageIndex createJpeg(const char* fileName, int *width,int *height)=0;\r
virtual ImageIndex createMonoBitmap(void *base,int width,int height)=0;\r
- virtual ImageIndex createImageRGBA(int width,int height)=0;\r
+ virtual ImageIndex createImagePalette(int width,int height,const unsigned char *image_data,const unsigned int*palette_data)=0;\r
\r
map<ImageIndex,unsigned int> images_ref;\r
map<void *,ImageIndex> monobitmaps;\r
extern osd_font_t font_helvB18;\r
\r
class Bitmap;\r
+class DisplayRegion;\r
\r
\r
\r
virtual int fillblt(int x, int y, int width, int height, const DrawStyle& c)=0;\r
virtual void drawHorzLine(int x1, int x2, int y, const DrawStyle& c)=0;\r
virtual void drawVertLine(int x, int y1, int y2, const DrawStyle& c)=0;\r
- virtual void drawBitmap(int x, int y, const Bitmap& bm)=0;\r
+ virtual void drawBitmap(int x, int y, const Bitmap& bm,const DisplayRegion & region)=0;\r
virtual void drawPoint(int x, int y, DrawStyle& c, bool fastdraw=false); // This draws a point, must not be a pixel\r
virtual void drawMonoBitmap(UCHAR* base, int dx, int dy, unsigned int height,unsigned int width, Colour& nextColour);\r
virtual int updateToScreen(int sx, int sy, int w, int h, int dx, int dy)=0;\r
fillblt(x, y1, 1, y2-y1, c);
}
-void SurfaceMVP::drawBitmap(int x, int y, const Bitmap& bm)
+void SurfaceMVP::drawBitmap(int x, int y, const Bitmap& bm,const DisplayRegion & region) // region should not matter for SD
{
UINT bmw = bm.getWidth(); UINT bmh = bm.getHeight();
if (bmw == 0 || bmh == 0) return;
fillblt(x, y1, 1, y2-y1, c);\r
}\r
\r
-void SurfaceOpenGL::drawBitmap(int x, int y, const Bitmap& bm)\r
+void SurfaceOpenGL::drawBitmap(int x, int y, const Bitmap& bm,const DisplayRegion & region) //region should not matter for SD\r
{\r
// Temporary code? Draw one pixel at a time using drawPixel()\r
startFastDraw();\r
\r
void drawHorzLine(int x1, int x2, int y, const DrawStyle& c);\r
void drawVertLine(int x, int y1, int y2, const DrawStyle& c);\r
- void drawBitmap(int x, int y, const Bitmap& bm);\r
+ void drawBitmap(int x, int y, const Bitmap& bm,const DisplayRegion & region);\r
int updateToScreen(int sx, int sy, int w, int h, int dx, int dy);\r
void readPixel(int x, int y, unsigned char* r, unsigned char* g, unsigned char* b);\r
void screenShot(const char* fileName);\r
{\r
command_mutex.Lock();\r
ImageIndex image=osd->getJpegRef(fileName,width,height);\r
- commands.push_back(SVGCommand(x,y,*height,*width,image,0));\r
+ commands.push_back(SVGCommand(x,y,*width,*height,image,0));\r
command_mutex.Unlock();\r
}\r
\r
command_mutex.Unlock();\r
}\r
\r
-void SurfaceVector::drawBitmap(int x, int y, const Bitmap& bm)\r
+void SurfaceVector::drawBitmap(int x, int y, const Bitmap& bm,const DisplayRegion & region)\r
{\r
//this is complicated\r
command_mutex.Lock();\r
- ImageIndex image=osd->getImageRGBA(bm.getWidth(),bm.getHeight());\r
- unsigned int * data=(unsigned int*)malloc(sizeof(unsigned int)*bm.getWidth());\r
+/*\r
+ unsigned int * data=(unsigned int*)malloc(sizeof(unsigned int)*bm.getWidth()*bm.getHeight());\r
for (UINT j = 0; j < bm.getHeight(); ++j){\r
for (UINT i = 0; i < bm.getWidth(); ++i)\r
{\r
- data[i]=bm.getColour(i,j);\r
+ data[i+j*bm.getHeight()]=bm.getColour(i,j);\r
}\r
- osd->imageUploadLine(image,j,bm.getWidth(),data);\r
- }\r
- free(data);\r
- commands.push_back(SVGCommand(x,y,bm.getHeight(),bm.getWidth(),image,0));\r
+ }*/\r
+ ImageIndex image=osd->getImagePalette(bm.getWidth(),bm.getHeight(),&(bm.rawData()[0]),\r
+ (const unsigned int*)&bm.palette.getColourVector()[0]); // data is freed by the OSD\r
+ //free(data);\r
+ float tx=x+region.windowx;\r
+ float ty=y+region.windowy;\r
+ float th=bm.getHeight();\r
+ float tw=bm.getWidth();\r
+\r
+ float scalex=720.f/((float) (region.framewidth+1));\r
+ float scaley=576.f/((float) (region.frameheight+1));\r
+ tx*=scalex;\r
+ ty*=scaley;\r
+ tw*=scalex;\r
+ th*=scaley;\r
+ SVGCommand temp=SVGCommand(tx,ty,tw,th,image,0);\r
+ commands.push_back(temp);\r
command_mutex.Unlock();\r
}\r
\r
int fillblt(int x, int y, int width, int height, const DrawStyle& c);\r
void drawHorzLine(int x1, int x2, int y, const DrawStyle& c);\r
void drawVertLine(int x, int y1, int y2, const DrawStyle& c);\r
- void drawBitmap(int x, int y, const Bitmap& bm);\r
+ void drawBitmap(int x, int y, const Bitmap& bm,const DisplayRegion & region);\r
void drawPoint(int x, int y, DrawStyle& c, bool fastdraw=false); // This draws a point, must not be a pixel\r
void drawMonoBitmap(UCHAR* base, int dx, int dy, unsigned int height,unsigned int width, Colour& nextColour);\r
int updateToScreen(int sx, int sy, int w, int h, int dx, int dy);\r
}\r
}\r
\r
-void VVideoLiveTV::drawOSDBitmap(UINT posX, UINT posY, const Bitmap& bm)\r
+void VVideoLiveTV::drawOSDBitmap(UINT posX, UINT posY, const Bitmap& bm, const DisplayRegion& region)\r
{\r
- drawBitmap(posX, posY, bm);\r
+ drawBitmap(posX, posY, bm,region);\r
Region r;\r
r.x = posX; r.y = posY; r.w = bm.getWidth(); r.h = bm.getHeight();\r
boxstack->update(this, &r);\r
boxstack->update(this, &area);\r
}\r
\r
-void VVideoLiveTV::clearOSDArea(UINT posX, UINT posY, UINT width, UINT height)\r
+void VVideoLiveTV::clearOSDArea(UINT posX, UINT posY, UINT width, UINT height, const DisplayRegion& region)\r
{\r
Region r;\r
- r.x = posX; r.y = posY; r.w = width; r.h = height;\r
+ r.x = posX+region.windowx; r.y = posY+region.windowy; r.w = width; r.h = height;\r
+ //now convert to our display\r
+ float scalex=720.f/((float) (region.framewidth+1));\r
+ float scaley=576.f/((float) (region.frameheight+1));\r
+ r.x=floor(scalex*((float)r.x));\r
+ r.y=floor(scaley*((float)r.y));\r
+ r.w=ceil(scalex*((float)r.w));\r
+ r.h=ceil(scaley*((float)r.h));\r
rectangle(r, DrawStyle(0,0,0,0));\r
boxstack->update(this, &r);\r
}\r
void timercall(int ref);
- void drawOSDBitmap(UINT posX, UINT posY, const Bitmap&);
+ void drawOSDBitmap(UINT posX, UINT posY, const Bitmap&, const DisplayRegion& region);
void clearOSD();
- void clearOSDArea(UINT posX, UINT posY, UINT width, UINT height);
+ void clearOSDArea(UINT posX, UINT posY, UINT width, UINT height, const DisplayRegion& region);
private:
BoxStack* boxstack;
}\r
}\r
\r
-void VVideoRec::drawOSDBitmap(UINT posX, UINT posY, const Bitmap& bm)\r
+void VVideoRec::drawOSDBitmap(UINT posX, UINT posY, const Bitmap& bm, const DisplayRegion& region)\r
{\r
- drawBitmap(posX, posY, bm);\r
+ drawBitmap(posX, posY, bm, region);\r
Region r;\r
r.x = posX; r.y = posY; r.w = bm.getWidth(); r.h = bm.getHeight();\r
boxstack->update(this, &r);\r
boxstack->update(this, &area);\r
}\r
\r
-void VVideoRec::clearOSDArea(UINT posX, UINT posY, UINT width, UINT height)\r
+void VVideoRec::clearOSDArea(UINT posX, UINT posY, UINT width, UINT height, const DisplayRegion& region)\r
{\r
Region r;\r
- r.x = posX; r.y = posY; r.w = width; r.h = height;\r
+ r.x = posX+region.windowx; r.y = posY+region.windowy; r.w = width; r.h = height;\r
+ //now convert to our display\r
+ float scalex=720.f/((float) (region.framewidth+1));\r
+ float scaley=576.f/((float) (region.frameheight+1));\r
+ r.x=floor(scalex*((float)r.x));\r
+ r.y=floor(scaley*((float)r.y));\r
+ r.w=ceil(scalex*((float)r.w));\r
+ r.h=ceil(scaley*((float)r.h));\r
+\r
rectangle(r, transparent);\r
boxstack->update(this, &r);\r
}\r
void timercall(int clientReference);
void processMessage(Message* m);
- void drawOSDBitmap(UINT posX, UINT posY, const Bitmap&);
+ void drawOSDBitmap(UINT posX, UINT posY, const Bitmap&, const DisplayRegion& region);
void clearOSD();
- void clearOSDArea(UINT posX, UINT posY, UINT width, UINT height);
+ void clearOSDArea(UINT posX, UINT posY, UINT width, UINT height, const DisplayRegion& region);
void doTeletext();