Code cleanup, still testing

git-svn-id: file:///home/bas/coolstream_public_svn/THIRDPARTY/applications/neutrino-experimental@173 e54a6e83-5905-42d5-8d5c-058d10e6a962
This commit is contained in:
focus
2010-01-17 15:47:34 +00:00
parent 1943d704cb
commit 157d631d5b
7 changed files with 69 additions and 577 deletions

View File

@@ -13,7 +13,6 @@
#include "Debug.hpp"
#include "PacketQueue.hpp"
#include "semaphore.h"
#include "reader_thread.hpp"
#include "dvbsub_thread.hpp"
#include "helpers.hpp"
#include "dvbsubtitle.h"
@@ -43,6 +42,8 @@ static int dvbsub_pid;
static int dvbsub_stopped;
cDvbSubtitleConverter *dvbSubtitleConverter;
void* reader_thread(void *arg);
void* dvbsub_thread(void* arg);
int dvbsub_init() {
int trc;
@@ -215,61 +216,26 @@ void* reader_thread(void * /*arg*/)
break;
}
/* Wait for pes sync */
len = 0;
count = 0;
int tosync = 0;
while (!dvbsub_paused) {
//len = read(fd, &tmp[count], 3-count);
len = dmx->Read(&tmp[count], 3-count, 1000);
//printf("reader: fd = %d, len = %d\n", fd, len);
if(len <= 0)
continue;
else if (len == (3-count)) {
if ( (tmp[0] == 0x00) &&
(tmp[1] == 0x00) &&
(tmp[2] == 0x01)) {
count = 3;
break;
}
tosync += len;
} else {
count += len;
tosync += len;
continue;
}
tmp[0] = tmp[1];
tmp[1] = tmp[2];
count = 2;
} // while (!dvbsub_paused)
if(tosync)
printf("[subtitles] sync after %d bytes\n", tosync);
/* read stream id & length */
while ((count < 6) && !dvbsub_paused) {
//printf("try to read 6-count = %d\n", 6-count);
//len = read(fd, &tmp[count], 6-count);
len = dmx->Read(&tmp[count], 6-count, 1000);
if (len < 0) {
continue;
} else {
count += len;
}
len = dmx->Read(tmp, 6, 1000);
if(len <= 0)
continue;
if(memcmp(tmp, "\x00\x00\x01\xbd", 4)) {
sub_debug.print(Debug::VERBOSE, "[subtitles] bad start code: %02x%02x%02x%02x\n", tmp[0], tmp[1], tmp[2], tmp[3]);
continue;
}
count = 6;
packlen = getbits(tmp, 4*8, 16) + 6;
buf = new uint8_t[packlen];
/* TODO: Throws an exception on out of memory */
/* copy tmp[0..5] => buf[0..5] */
*(uint32_t*)buf = *(uint32_t*)tmp;
((uint16_t*)buf)[2] = ((uint16_t*)tmp)[2];
buf = (uint8_t*) malloc(packlen);
memcpy(buf, tmp, 6);
/* read rest of the packet */
while((count < packlen) && !dvbsub_paused) {
//len = read(fd, buf+count, packlen-count);
len = dmx->Read(buf+count, packlen-count, 1000);
if (len < 0) {
continue;
@@ -277,6 +243,18 @@ void* reader_thread(void * /*arg*/)
count += len;
}
}
#if 0
for(int i = 6; i < packlen - 4; i++) {
if(!memcmp(&buf[i], "\x00\x00\x01\xbd", 4)) {
int plen = getbits(&buf[i], 4*8, 16) + 6;
sub_debug.print(Debug::VERBOSE, "[subtitles] ******************* PES header at %d ?! *******************\n", i);
sub_debug.print(Debug::VERBOSE, "[subtitles] start code: %02x%02x%02x%02x len %d\n", buf[i+0], buf[i+1], buf[i+2], buf[i+3], plen);
free(buf);
continue;
}
}
#endif
if(!dvbsub_paused) {
sub_debug.print(Debug::VERBOSE, "[subtitles] ******************* new packet, len %d buf 0x%x pts-stc diff %lld *******************\n", count, buf, get_pts_stc_delta(get_pts(buf)));
/* Packet now in memory */
@@ -287,7 +265,7 @@ void* reader_thread(void * /*arg*/)
pthread_cond_broadcast(&packetCond);
pthread_mutex_unlock(&packetMutex);
} else {
delete[] buf;
free(buf);
buf=NULL;
}
}
@@ -320,7 +298,6 @@ void* dvbsub_thread(void* /*arg*/)
gettimeofday(&now, NULL);
int ret = 0;
#if 1
now.tv_usec += (timeout == 0) ? 1000000 : timeout; // add the timeout
while (now.tv_usec >= 1000000) { // take care of an overflow
now.tv_sec++;
@@ -338,30 +315,11 @@ void* dvbsub_thread(void* /*arg*/)
if(packet_queue.size() == 0) {
continue;
}
#else
TIMEVAL_TO_TIMESPEC(&now, &restartWait);
restartWait.tv_sec += 1;
if(packet_queue.size() == 0) {
pthread_mutex_lock( &packetMutex );
ret = pthread_cond_timedwait( &packetCond, &packetMutex, &restartWait );
pthread_mutex_unlock( &packetMutex );
}
if (ret == ETIMEDOUT)
{
dvbSubtitleConverter->Action();
continue;
}
else if (ret == EINTR)
{
sub_debug.print(Debug::VERBOSE, "pthread_cond_timedwait fails with %s\n", strerror(errno));
}
#endif
sub_debug.print(Debug::VERBOSE, "PES: Wakeup, queue size %d\n\n", packet_queue.size());
if(dvbsub_paused) {
while(packet_queue.size()) {
packet = packet_queue.pop();
delete[] packet;
free(packet);
}
continue;
}
@@ -372,25 +330,16 @@ void* dvbsub_thread(void* /*arg*/)
}
packlen = (packet[4] << 8 | packet[5]) + 6;
#if 0
/* Get PTS */
pts_dts_flag = getbits(packet, 7*8, 2);
if ((pts_dts_flag == 2) || (pts_dts_flag == 3)) {
pts = (uint64_t)getbits(packet, 9*8+4, 3) << 30; /* PTS[32..30] */
pts |= getbits(packet, 10*8, 15) << 15; /* PTS[29..15] */
pts |= getbits(packet, 12*8, 15); /* PTS[14..0] */
} else {
pts = 0;
}
#endif
pts = get_pts(packet);
dataoffset = packet[8] + 8 + 1;
if (packet[dataoffset] != 0x20) {
sub_debug.print(Debug::VERBOSE, "Not a dvb subtitle packet, discard it (len %d)\n", packlen);
#if 0
for(int i = 0; i < packlen; i++)
printf("%02X ", packet[i]);
printf("\n");
#endif
goto next_round;
}
@@ -412,7 +361,7 @@ void* dvbsub_thread(void* /*arg*/)
timeout = dvbSubtitleConverter->Action();
next_round:
delete[] packet;
free(packet);
}
delete dvbSubtitleConverter;

View File

@@ -1,8 +0,0 @@
#ifndef DVBSUB_THREAD_HPP_
#define DVBSUB_THREAD_HPP_
#include <inttypes.h>
void* dvbsub_thread(void* arg);
#endif

View File

@@ -30,6 +30,9 @@ static bool DebugConverter = true;
#define dbgconverter(a...) if (DebugConverter) sub_debug.print(Debug::VERBOSE, a)
extern unsigned char *simple_resize (unsigned char *orgin, int ox, int oy, int dx, int dy);
extern unsigned char *color_average_resize (unsigned char *orgin, int ox, int oy, int dx, int dy);
// --- cDvbSubtitleBitmaps ---------------------------------------------------
class cDvbSubtitleBitmaps : public cListObject
@@ -38,24 +41,20 @@ class cDvbSubtitleBitmaps : public cListObject
int64_t pts;
int timeout;
AVSubtitle sub;
// int min_x, min_y, max_x, max_y;
public:
cDvbSubtitleBitmaps(int64_t Pts);
~cDvbSubtitleBitmaps();
int64_t Pts(void) { return pts; }
int Timeout(void) { return sub.end_display_time; }
void Draw();
void Clear(void);
void Draw(int &min_x, int &min_y, int &max_x, int &max_y);
int Count(void) { return sub.num_rects; };
AVSubtitle * GetSub(void) { return &sub; };
};
cDvbSubtitleBitmaps::cDvbSubtitleBitmaps(int64_t pPts)
{
pts = pPts;
// max_x = max_y = 0;
// min_x = min_y = 0xFFFF;
//dbgconverter("cDvbSubtitleBitmaps::new: PTS: %lld\n", pts);
pts = pPts;
}
cDvbSubtitleBitmaps::~cDvbSubtitleBitmaps()
@@ -63,35 +62,20 @@ cDvbSubtitleBitmaps::~cDvbSubtitleBitmaps()
dbgconverter("cDvbSubtitleBitmaps::delete: PTS: %lld rects %d\n", pts, Count());
int i;
//return; //FIXME !
if(sub.rects) {
for (i = 0; i < Count(); i++)
{
av_freep(&sub.rects[i]->pict.data[0]);
av_freep(&sub.rects[i]->pict.data[1]);
av_freep(&sub.rects[i]);
}
for (i = 0; i < Count(); i++)
{
av_freep(&sub.rects[i]->pict.data[0]);
av_freep(&sub.rects[i]->pict.data[1]);
av_freep(&sub.rects[i]);
av_free(sub.rects);
}
av_free(sub.rects);
memset(&sub, 0, sizeof(AVSubtitle));
}
static int min_x = 0xFFFF, min_y = 0xFFFF;
static int max_x = 0, max_y = 0;
void cDvbSubtitleBitmaps::Clear()
{
dbgconverter("cDvbSubtitleBitmaps::Clear: x=% d y= %d, w= %d, h= %d\n", min_x, min_y, max_x-min_x, max_y-min_y);
if(max_x && max_y) {
CFrameBuffer::getInstance()->paintBackgroundBoxRel (min_x, min_y-10, max_x-min_x, max_y-min_y+10);
//CFrameBuffer::getInstance()->paintBackground();
//max_x = max_y = 0;
//min_x = min_y = 0xFFFF;
}
}
void cDvbSubtitleBitmaps::Draw()
void cDvbSubtitleBitmaps::Draw(int &min_x, int &min_y, int &max_x, int &max_y)
{
int i;
int stride = CFrameBuffer::getInstance()->getScreenWidth(true);
@@ -100,14 +84,13 @@ void cDvbSubtitleBitmaps::Draw()
int yend = CFrameBuffer::getInstance()->getScreenY() + CFrameBuffer::getInstance()->getScreenHeight();
uint32_t *sublfb = CFrameBuffer::getInstance()->getFrameBufferPointer();
dbgconverter("cDvbSubtitleBitmaps::Draw: %d bitmaps, x= %d, width= %d end=%d stride %d\n", sub.num_rects, xs, wd, yend, stride);
//if(Count())
Clear(); //FIXME should we clear for new bitmaps set ?
dbgconverter("cDvbSubtitleBitmaps::Draw: %d bitmaps, x= %d, width= %d yend=%d stride %d\n", Count(), xs, wd, yend, stride);
for (i = 0; i < Count(); i++) {
/* center on screen */
int xoff = xs + (wd - sub.rects[i]->w) / 2;
/* int xoff = xs + (wd - sub.rects[i]->w) / 2;*/
int xdiff = (wd > 720) ? ((wd - 720) / 2) : 0;
int xoff = sub.rects[i]->x + xs + xdiff; // 720 - (720 - x) = orig offset;
/* move to screen bottom */
int yoff = (yend - (576 - sub.rects[i]->y)) * stride;
int ys = yend - (576 - sub.rects[i]->y);
@@ -171,6 +154,12 @@ cDvbSubtitleConverter::cDvbSubtitleConverter(void)
av_log_set_level(99);
if(DebugConverter)
av_log_set_level(AV_LOG_INFO);
min_x = CFrameBuffer::getInstance()->getScreenWidth();
min_y = CFrameBuffer::getInstance()->getScreenHeight();
max_x = CFrameBuffer::getInstance()->getScreenX();
max_y = CFrameBuffer::getInstance()->getScreenY();
Timeout.Set(0xFFFF*1000);
}
cDvbSubtitleConverter::~cDvbSubtitleConverter()
@@ -195,32 +184,32 @@ void cDvbSubtitleConverter::Pause(bool pause)
if(!running)
return;
Lock();
running = false;
Clear();
running = false;
Unlock();
Reset();
} else {
Reset();
running = true;
}
}
void cDvbSubtitleConverter::Clear(void)
{
if(max_x && max_y) {
dbgconverter("cDvbSubtitleConverter::Clear: x=% d y= %d, w= %d, h= %d\n", min_x, min_y, max_x-min_x, max_y-min_y);
CFrameBuffer::getInstance()->paintBackgroundBoxRel (min_x, min_y-10, max_x-min_x, max_y-min_y+10);
dbgconverter("cDvbSubtitleConverter::Clear: x=% d y= %d, w= %d, h= %d\n", min_x, min_y, max_x-min_x, max_y-min_y);
if(running && (max_x-min_x > 0) && (max_y-min_y > 0)) {
CFrameBuffer::getInstance()->paintBackgroundBoxRel (min_x, min_y, max_x-min_x, max_y-min_y);
//CFrameBuffer::getInstance()->paintBackground();
//max_x = max_y = 0;
//min_x = min_y = 0xFFFF;
}
}
void cDvbSubtitleConverter::Reset(void)
{
dbgconverter("Converter reset -----------------------\n");
Lock();
bitmaps->Clear();
Unlock();
dbgconverter("Converter reset -----------------------\n");
Lock();
bitmaps->Clear();
Unlock();
Timeout.Set(0xFFFF*1000);
}
int cDvbSubtitleConverter::Convert(const uchar *Data, int Length, int64_t pts)
@@ -243,11 +232,11 @@ int cDvbSubtitleConverter::Convert(const uchar *Data, int Length, int64_t pts)
avpkt.data = (uint8_t*) Data;
avpkt.size = Length;
dbgconverter("cDvbSubtitleConverter::Convert: sub %x pkt %x\n", sub, &avpkt);
dbgconverter("cDvbSubtitleConverter::Convert: sub %x pkt %x pts %lld\n", sub, &avpkt, pts);
//avctx->sub_id = (anc_page << 16) | comp_page; //FIXME not patched ffmpeg needs this !
avcodec_decode_subtitle2(avctx, sub, &got_subtitle, &avpkt);
dbgconverter("cDvbSubtitleConverter::Convert: subs ? %s, %d bitmaps\n", got_subtitle? "yes" : "no", sub->num_rects);
dbgconverter("cDvbSubtitleConverter::Convert: pts %lld subs ? %s, %d bitmaps\n", pts, got_subtitle? "yes" : "no", sub->num_rects);
if(got_subtitle) {
if(DebugConverter) {
@@ -274,7 +263,6 @@ void dvbsub_get_stc(int64_t * STC);
int cDvbSubtitleConverter::Action(void)
{
static cTimeMs Timeout(0xFFFF*1000);
int WaitMs = WAITMS;
if (!running)
@@ -299,7 +287,8 @@ int cDvbSubtitleConverter::Action(void)
if (Delta <= SHOW_DELTA) {
dbgconverter("cDvbSubtitleConverter::Action: Got %d bitmaps, showing #%d\n", bitmaps->Count(), sb->Index() + 1);
if (running) {
sb->Draw();
Clear();
sb->Draw(min_x, min_y, max_x, max_y);
Timeout.Set(sb->Timeout());
}
if(sb->Count())

View File

@@ -33,6 +33,8 @@ private:
cList<cDvbSubtitleBitmaps> *bitmaps;
AVCodecContext * avctx;
AVCodec * avcodec;
int min_x, min_y, max_x, max_y;
cTimeMs Timeout;
public:
cDvbSubtitleConverter(void);
virtual ~cDvbSubtitleConverter();

View File

@@ -1,287 +0,0 @@
/*
* osd.c: Abstract On Screen Display layer
*
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: osd.cpp,v 1.1 2009/02/23 19:46:44 rhabarber1848 Exp $
*/
#include "dvbsubtitle.h"
//#include "device.h"
#define PAGE_COMPOSITION_SEGMENT 0x10
#define REGION_COMPOSITION_SEGMENT 0x11
#define CLUT_DEFINITION_SEGMENT 0x12
#define OBJECT_DATA_SEGMENT 0x13
#define END_OF_DISPLAY_SET_SEGMENT 0x80
// --- cPalette --------------------------------------------------------------
cPalette::cPalette(int pBpp)
{
SetBpp(pBpp);
SetAntiAliasGranularity(10, 10);
}
void cPalette::SetAntiAliasGranularity(uint FixedColors, uint BlendColors)
{
if (FixedColors >= MAXNUMCOLORS || BlendColors == 0)
antiAliasGranularity = MAXNUMCOLORS - 1;
else {
int ColorsForBlending = MAXNUMCOLORS - FixedColors;
int ColorsPerBlend = ColorsForBlending / BlendColors + 2; // +2 = the full foreground and background colors, which are amoung the fixed colors
antiAliasGranularity = double(MAXNUMCOLORS - 1) / (ColorsPerBlend - 1);
}
}
void cPalette::Reset(void)
{
numColors = 0;
modified = false;
}
int cPalette::Index(tColor pColor)
{
// Check if color is already defined:
for (int i = 0; i < numColors; i++) {
if (color[i] == pColor)
return i;
}
// No exact color, try a close one:
int i = ClosestColor(pColor, 4);
if (i >= 0)
return i;
// No close one, try to define a new one:
if (numColors < maxColors) {
color[numColors++] = pColor;
modified = true;
return numColors - 1;
}
// Out of colors, so any close color must do:
return ClosestColor(pColor);
}
void cPalette::SetBpp(int pBpp)
{
bpp = pBpp;
maxColors = 1 << bpp;
Reset();
}
void cPalette::SetColor(int pIndex, tColor pColor)
{
if (pIndex < maxColors) {
if (numColors <= pIndex) {
numColors = pIndex + 1;
modified = true;
}
else
modified |= color[pIndex] != pColor;
color[pIndex] = pColor;
}
}
const tColor *cPalette::Colors(int &NumColors) const
{
NumColors = numColors;
return numColors ? color : NULL;
}
void cPalette::Take(const cPalette &Palette, tIndexes *Indexes, tColor ColorFg, tColor ColorBg)
{
for (int i = 0; i < Palette.numColors; i++) {
tColor pColor = Palette.color[i];
if (ColorFg || ColorBg) {
switch (i) {
case 0: pColor = ColorBg; break;
case 1: pColor = ColorFg; break;
}
}
int n = Index(pColor);
if (Indexes)
(*Indexes)[i] = n;
}
}
void cPalette::Replace(const cPalette &Palette)
{
for (int i = 0; i < Palette.numColors; i++)
SetColor(i, Palette.color[i]);
numColors = Palette.numColors;
antiAliasGranularity = Palette.antiAliasGranularity;
}
tColor cPalette::Blend(tColor ColorFg, tColor ColorBg, uint8_t Level) const
{
if (antiAliasGranularity > 0)
Level = uint8_t(int(Level / antiAliasGranularity + 0.5) * antiAliasGranularity);
int Af = (ColorFg & 0xFF000000) >> 24;
int Rf = (ColorFg & 0x00FF0000) >> 16;
int Gf = (ColorFg & 0x0000FF00) >> 8;
int Bf = (ColorFg & 0x000000FF);
int Ab = (ColorBg & 0xFF000000) >> 24;
int Rb = (ColorBg & 0x00FF0000) >> 16;
int Gb = (ColorBg & 0x0000FF00) >> 8;
int Bb = (ColorBg & 0x000000FF);
int A = (Ab + (Af - Ab) * Level / 0xFF) & 0xFF;
int R = (Rb + (Rf - Rb) * Level / 0xFF) & 0xFF;
int G = (Gb + (Gf - Gb) * Level / 0xFF) & 0xFF;
int B = (Bb + (Bf - Bb) * Level / 0xFF) & 0xFF;
return (A << 24) | (R << 16) | (G << 8) | B;
}
int cPalette::ClosestColor(tColor pColor, int MaxDiff) const
{
int n = 0;
int d = INT_MAX;
int A1 = (pColor & 0xFF000000) >> 24;
int R1 = (pColor & 0x00FF0000) >> 16;
int G1 = (pColor & 0x0000FF00) >> 8;
int B1 = (pColor & 0x000000FF);
for (int i = 0; i < numColors; i++) {
int A2 = (color[i] & 0xFF000000) >> 24;
int R2 = (color[i] & 0x00FF0000) >> 16;
int G2 = (color[i] & 0x0000FF00) >> 8;
int B2 = (color[i] & 0x000000FF);
int diff = (abs(A1 - A2) << 1) + (abs(R1 - R2) << 1) + (abs(G1 - G2) << 1) + (abs(B1 - B2) << 1);
if (diff < d) {
d = diff;
n = i;
}
}
return d <= MaxDiff ? n : -1;
}
cBitmap::cBitmap(int pWidth, int pHeight, int pBpp, int pX0, int pY0)
:cPalette(pBpp)
{
bitmap = NULL;
x0 = pX0;
y0 = pY0;
SetSize(pWidth, pHeight);
}
cBitmap::~cBitmap()
{
free(bitmap);
}
void cBitmap::SetIndex(int x, int y, tIndex pIndex)
{
if (bitmap) {
if (0 <= x && x < width && 0 <= y && y < height) {
if (bitmap[width * y + x] != pIndex) {
bitmap[width * y + x] = pIndex;
if (dirtyX1 > x) dirtyX1 = x;
if (dirtyY1 > y) dirtyY1 = y;
if (dirtyX2 < x) dirtyX2 = x;
if (dirtyY2 < y) dirtyY2 = y;
}
}
}
}
void cBitmap::SetSize(int pWidth, int pHeight)
{
if (bitmap && pWidth == width && pHeight == height)
return;
width = pWidth;
height = pHeight;
free(bitmap);
bitmap = NULL;
dirtyX1 = 0;
dirtyY1 = 0;
dirtyX2 = width - 1;
dirtyY2 = height - 1;
if (width > 0 && height > 0) {
bitmap = MALLOC(tIndex, width * height);
if (bitmap)
memset(bitmap, 0x00, width * height);
else
esyslog("ERROR: can't allocate bitmap!");
}
else
esyslog("ERROR: invalid bitmap parameters (%d, %d)!", width, height);
}
void cBitmap::DrawBitmap(int x, int y, const cBitmap &Bitmap, tColor ColorFg, tColor ColorBg, bool ReplacePalette, bool Overlay)
{
if (bitmap && Bitmap.bitmap && Intersects(x, y, x + Bitmap.Width() - 1, y + Bitmap.Height() - 1)) {
if (Covers(x, y, x + Bitmap.Width() - 1, y + Bitmap.Height() - 1))
Reset();
x -= x0;
y -= y0;
if (ReplacePalette && Covers(x + x0, y + y0, x + x0 + Bitmap.Width() - 1, y + y0 + Bitmap.Height() - 1)) {
Replace(Bitmap);
for (int ix = 0; ix < Bitmap.width; ix++) {
for (int iy = 0; iy < Bitmap.height; iy++) {
if (!Overlay || Bitmap.bitmap[Bitmap.width * iy + ix] != 0)
SetIndex(x + ix, y + iy, Bitmap.bitmap[Bitmap.width * iy + ix]);
}
}
}
else {
tIndexes Indexes;
Take(Bitmap, &Indexes, ColorFg, ColorBg);
for (int ix = 0; ix < Bitmap.width; ix++) {
for (int iy = 0; iy < Bitmap.height; iy++) {
if (!Overlay || Bitmap.bitmap[Bitmap.width * iy + ix] != 0)
SetIndex(x + ix, y + iy, Indexes[int(Bitmap.bitmap[Bitmap.width * iy + ix])]);
}
}
}
}
}
bool cBitmap::Contains(int x, int y) const
{
x -= x0;
y -= y0;
return 0 <= x && x < width && 0 <= y && y < height;
}
bool cBitmap::Covers(int x1, int y1, int x2, int y2) const
{
x1 -= x0;
y1 -= y0;
x2 -= x0;
y2 -= y0;
return x1 <= 0 && y1 <= 0 && x2 >= width - 1 && y2 >= height - 1;
}
bool cBitmap::Intersects(int x1, int y1, int x2, int y2) const
{
x1 -= x0;
y1 -= y0;
x2 -= x0;
y2 -= y0;
return !(x2 < 0 || x1 >= width || y2 < 0 || y1 >= height);
}
bool cBitmap::Dirty(int &x1, int &y1, int &x2, int &y2)
{
if (dirtyX2 >= 0) {
x1 = dirtyX1;
y1 = dirtyY1;
x2 = dirtyX2;
y2 = dirtyY2;
return true;
}
return false;
}
void cBitmap::Clean(void)
{
dirtyX1 = width;
dirtyY1 = height;
dirtyX2 = -1;
dirtyY2 = -1;
}
const tIndex *cBitmap::Data(int x, int y)
{
return &bitmap[y * width + x];
}

View File

@@ -1,147 +0,0 @@
/*
* osd.h: Abstract On Screen Display layer
*
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* Original author: Marco Schl<68><6C>ler <marco@lordzodiac.de>
*
* $Id: osd.h,v 1.1 2009/02/23 19:46:44 rhabarber1848 Exp $
*/
#ifndef __OSD_H
#define __OSD_H
#include "tools.h"
#include <limits.h>
#define MAXNUMCOLORS 256
typedef uint32_t tColor;
typedef unsigned char tIndex;
class cPalette {
private:
tColor color[MAXNUMCOLORS];
int bpp;
int maxColors, numColors;
bool modified;
double antiAliasGranularity;
protected:
typedef tIndex tIndexes[MAXNUMCOLORS];
public:
cPalette(int Bpp = 8);
///< Initializes the palette with the given color depth.
void SetAntiAliasGranularity(uint FixedColors, uint BlendColors);
///< Allows the system to optimize utilization of the limited color
///< palette entries when generating blended colors for anti-aliasing.
///< FixedColors is the maximum number of colors used, and BlendColors
///< is the maximum number of foreground/background color combinations
///< used with anti-aliasing. If this function is not called with
///< useful values, the palette may be filled up with many shades of
///< a single color combination, and may not be able to serve all
///< requested colors. By default the palette assumes there will be
///< 10 fixed colors and 10 color combinations.
int Bpp(void) const { return bpp; }
void Reset(void);
///< Resets the palette, making it contain no colors.
int Index(tColor Color);
///< Returns the index of the given Color (the first color has index 0).
///< If Color is not yet contained in this palette, it will be added if
///< there is a free slot. If the color can't be added to this palette,
///< the closest existing color will be returned.
tColor Color(int pIndex) const { return pIndex < maxColors ? color[pIndex] : 0; }
///< Returns the color at the given Index. If Index is outside the valid
///< range, 0 will be returned.
void SetBpp(int Bpp);
///< Sets the color depth of this palette to the given value.
///< The palette contents will be reset, so that it contains no colors.
void SetColor(int Index, tColor Color);
///< Sets the palette entry at Index to Color. If Index is larger than
///< the number of currently used entries in this palette, the entries
///< in between will have undefined values.
const tColor *Colors(int &NumColors) const;
///< Returns a pointer to the complete color table and stores the
///< number of valid entries in NumColors. If no colors have been
///< stored yet, NumColors will be set to 0 and the function will
///< return NULL.
void Take(const cPalette &Palette, tIndexes *Indexes = NULL, tColor ColorFg = 0, tColor ColorBg = 0);
///< Takes the colors from the given Palette and adds them to this palette,
///< using existing entries if possible. If Indexes is given, it will be
///< filled with the index values that each color of Palette has in this
///< palette. If either of ColorFg or ColorBg is not zero, the first color
///< in Palette will be taken as ColorBg, and the second color will become
///< ColorFg.
void Replace(const cPalette &Palette);
///< Replaces the colors of this palette with the colors from the given
///< palette.
tColor Blend(tColor ColorFg, tColor ColorBg, uint8_t Level) const;
///< Determines a color that consists of a linear blend between ColorFg
///< and ColorBg. If Level is 0, the result is ColorBg, if it is 255,
///< the result is ColorFg. If SetAntiAliasGranularity() has been called previously,
///< Level will be mapped to a limited range of levels that allow to make best
///< use of the palette entries.
int ClosestColor(tColor Color, int MaxDiff = INT_MAX) const;
///< Returns the index of a color in this palette that is closest to the given
///< Color. MaxDiff can be used to control the maximum allowed color difference.
///< If no color with a maximum difference of MaxDiff can be found, -1 will
///< be returned. With the default value of INT_MAX, there will always be
///< a valid color index returned, but the color may be completely different.
};
class cBitmap : public cPalette {
private:
tIndex *bitmap;
int x0, y0;
int width, height;
int dirtyX1, dirtyY1, dirtyX2, dirtyY2;
public:
cBitmap(int Width, int Height, int Bpp, int X0 = 0, int Y0 = 0);
///< Creates a bitmap with the given Width, Height and color depth (Bpp).
///< X0 and Y0 define the offset at which this bitmap will be located on the OSD.
///< All coordinates given in the other functions will be relative to
///< this offset (unless specified otherwise).
cBitmap(const char *FileName);
///< Creates a bitmap and loads an XPM image from the given file.
virtual ~cBitmap();
int X0(void) const { return x0; }
int Y0(void) const { return y0; }
int Width(void) const { return width; }
int Height(void) const { return height; }
void SetSize(int Width, int Height);
///< Sets the size of this bitmap to the given values. Any previous
///< contents of the bitmap will be lost. If Width and Height are the same
///< as the current values, nothing will happen and the bitmap remains
///< unchanged.
void SetIndex(int x, int y, tIndex Index);
///< Sets the index at the given coordinates to Index.
///< Coordinates are relative to the bitmap's origin.
void DrawBitmap(int x, int y, const cBitmap &Bitmap, tColor ColorFg = 0, tColor ColorBg = 0, bool ReplacePalette = false, bool Overlay = false);
///< Sets the pixels in this bitmap with the data from the given
///< Bitmap, putting the upper left corner of the Bitmap at (x, y).
///< If ColorFg or ColorBg is given, the first palette entry of the Bitmap
///< will be mapped to ColorBg and the second palette entry will be mapped to
///< ColorFg (palette indexes are defined so that 0 is the background and
///< 1 is the foreground color). ReplacePalette controls whether the target
///< area shall have its palette replaced with the one from Bitmap.
///< If Overlay is true, any pixel in Bitmap that has color index 0 will
///< not overwrite the corresponding pixel in the target area.
const tIndex *Data(int x, int y);
///< Returns the address of the index byte at the given coordinates.
bool Contains(int x, int y) const;
bool Covers(int x1, int y1, int x2, int y2) const;
bool Intersects(int x1, int y1, int x2, int y2) const;
bool Dirty(int &x1, int &y1, int &x2, int &y2);
void Clean(void);
};
struct tArea {
int x1, y1, x2, y2;
int bpp;
int Width(void) const { return x2 - x1 + 1; }
int Height(void) const { return y2 - y1 + 1; }
bool Intersects(const tArea &Area) const { return !(x2 < Area.x1 || x1 > Area.x2 || y2 < Area.y1 || y1 > Area.y2); }
};
#endif //__OSD_H

View File

@@ -1,6 +0,0 @@
#ifndef READER_THREAD_HPP_
#define READER_THREAD_HPP_
void* reader_thread(void *arg);
#endif