summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Gmeiner <christian.gmeiner@gmail.com>2009-09-11 20:42:43 +0200
committerChristian Gmeiner <christian.gmeiner@gmail.com>2009-09-11 20:42:43 +0200
commit06c128bde24c94665cd25ce97804fb5f11fc2a73 (patch)
tree994a0215caf4ce071b6757ac9ae7300b95773050
parent2db5f8766093aeef873d8d2d1e47df8f3deddfc4 (diff)
downloadvdr-plugin-dxr3-06c128bde24c94665cd25ce97804fb5f11fc2a73.tar.gz
vdr-plugin-dxr3-06c128bde24c94665cd25ce97804fb5f11fc2a73.tar.bz2
make use of spu regions and add rle4color method
-rw-r--r--spuencoder.c98
-rw-r--r--spuencoder.h9
2 files changed, 106 insertions, 1 deletions
diff --git a/spuencoder.c b/spuencoder.c
index bb88f4c..13b4832 100644
--- a/spuencoder.c
+++ b/spuencoder.c
@@ -79,6 +79,9 @@ void cSpuEncoder::encode(cBitmap *bmap, int top, int left)
memset(rleData.bottom, 0, sizeof(rleData.bottom));
memset(spu, 0, sizeof(spu));
+ // free previouse used regions
+ clearRegions();
+
// get needed informations about used colors
colors = bitmap->Colors(numColors);
@@ -87,6 +90,20 @@ void cSpuEncoder::encode(cBitmap *bmap, int top, int left)
// generate and upload color palette
generateColorPalette();
+ // add one region
+ cSpuRegion *reg = new cSpuRegion();
+
+ for (int i = 0; i < numColors; i++) {
+ reg->addColIndex(bitmap->Index(colors[i]));
+ }
+
+ regions.push(reg);
+
+ dsyslog("[dxr3-spuencoder] rle data");
+
+ // encode whole bitmap with rle and store top and bottom lines
+ rle4colors();
+
// as we have only small space for all our spu data, we do here
// a little trick. If we run out of space, when using
// top and odd bottom, we try to use two times the top lines.
@@ -104,6 +121,10 @@ void cSpuEncoder::encode(cBitmap *bmap, int top, int left)
// make a try with only even lines
generateSpuData(false);
}
+
+ // we are ready to send generated spu data
+ dsyslog("[dxr3-spuencoder] spu packet size %d (bytes). %d left", written, (MAX_SPU_DATA - written));
+ cDxr3Interface::instance()->WriteSpu((uchar *)&spu, written);
}
void cSpuEncoder::writeNibble(uint8_t val)
@@ -219,3 +240,80 @@ void cSpuEncoder::generateSpuData(bool topAndBottom) throw (char const* )
spu[0] = written >> 8;
spu[1] = written & 0xff;
}
+
+void cSpuEncoder::clearRegions()
+{
+ while (!regions.empty()) {
+ cSpuRegion *reg = regions.front();
+ delete reg;
+ regions.pop();
+ }
+}
+
+void cSpuEncoder::rle4colors()
+{
+ int len;
+ p = rleData.top;
+
+ // first encode all top lines (0, 2, 4, ...) followed by
+ // all bottom lines (1, 3, 5, ...)
+
+ for (int i = 0; i < 2; i++) {
+
+ nholder = 0;
+ ncnt = 0;
+ written = 0;
+
+ if (i == 1) {
+ p = rleData.bottom;
+ }
+
+ for (int y = (0 + i); y < bitmap->Height(); y += 2) {
+
+ for (int x = 0; x < bitmap->Width(); x += len) {
+ tIndex color = *(bitmap->Data(x, y));
+
+ for (len = 1; x+len < bitmap->Width(); ++len) {
+ if (*(bitmap->Data(x+len, y)) != color) {
+ break;
+ }
+ }
+
+ if (len < 0x04) {
+ writeNibble((len << 2) | color);
+ } else if (len < 0x10) {
+ writeNibble(len >> 2);
+ writeNibble((len << 2) | color);
+ } else if (len < 0x40) {
+ writeNibble(0);
+ writeNibble(len >> 2);
+ writeNibble((len << 2) | color);
+ } else if (x + len == bitmap->Width()) {
+ writeNibble(0);
+ writeNibble(0);
+ writeNibble(0);
+ writeNibble(color);
+ } else {
+ if (len > 0xff) {
+ len = 0xff;
+ }
+ writeNibble(0);
+ writeNibble(len >> 6);
+ writeNibble(len >> 2);
+ writeNibble((len << 2) | color);
+ }
+ }
+
+ // end of line
+ if (ncnt & 1) {
+ writeNibble(0);
+ }
+ }
+
+ if (i == 0) {
+ rleData.topLen = written;
+ } else {
+ rleData.bottomLen = written;
+ }
+ }
+}
diff --git a/spuencoder.h b/spuencoder.h
index 42a4d34..dbeb833 100644
--- a/spuencoder.h
+++ b/spuencoder.h
@@ -29,9 +29,11 @@
#include <stdint.h>
#include <vdr/osd.h>
+#include <queue>
#include "dxr3singleton.h"
+#include "spuregion.h"
-static const int MAX_SPU_DATA = 65220; // TODO vaidate this value
+static const int MAX_SPU_DATA = 65220; // TODO validate this value
struct sRle {
uint8_t top[MAX_SPU_DATA];
@@ -56,6 +58,7 @@ private:
int32_t written; // how much data are written
sRle rleData; // storage for encoded data
+ std::queue<cSpuRegion *> regions;
int numColors; // len of tColor array of current bitmap
const tColor* colors; // pointer to tColor array from current bitmap
@@ -65,6 +68,10 @@ private:
void writeNibble(uint8_t val);
void generateColorPalette();
void generateSpuData(bool topAndBottom) throw (char const* );
+
+ void clearRegions();
+
+ void rle4colors();
};
#endif // SPUENCODER_H