vdr  2.4.1
dvbsubtitle.c
Go to the documentation of this file.
1 /*
2  * dvbsubtitle.c: DVB subtitles
3  *
4  * See the main source file 'vdr.c' for copyright information and
5  * how to reach the author.
6  *
7  * Original author: Marco Schluessler <marco@lordzodiac.de>
8  * With some input from the "subtitles plugin" by Pekka Virtanen <pekka.virtanen@sci.fi>
9  *
10  * $Id: dvbsubtitle.c 4.1 2015/03/25 12:37:08 kls Exp $
11  */
12 
13 #include "dvbsubtitle.h"
14 #define __STDC_FORMAT_MACROS // Required for format specifiers
15 #include <inttypes.h>
16 #include "device.h"
17 #include "libsi/si.h"
18 
19 #define PAGE_COMPOSITION_SEGMENT 0x10
20 #define REGION_COMPOSITION_SEGMENT 0x11
21 #define CLUT_DEFINITION_SEGMENT 0x12
22 #define OBJECT_DATA_SEGMENT 0x13
23 #define DISPLAY_DEFINITION_SEGMENT 0x14
24 #define DISPARITY_SIGNALING_SEGMENT 0x15 // DVB BlueBook A156
25 #define END_OF_DISPLAY_SET_SEGMENT 0x80
26 #define STUFFING_SEGMENT 0xFF
27 
28 #define PGS_PALETTE_SEGMENT 0x14
29 #define PGS_OBJECT_SEGMENT 0x15
30 #define PGS_PRESENTATION_SEGMENT 0x16
31 #define PGS_WINDOW_SEGMENT 0x17
32 #define PGS_DISPLAY_SEGMENT 0x80
33 
34 // Set these to 'true' for debug output, which is written into the file dbg-log.htm
35 // in the current working directory. The HTML file shows the actual bitmaps (dbg-nnn.jpg)
36 // used to display the subtitles.
37 static bool DebugNormal = false; // shows pages, regions and objects
38 static bool DebugVerbose = false; // shows everything
45 static bool DebugPixel = DebugVerbose;
46 static bool DebugCluts = DebugVerbose;
47 static bool DebugOutput = DebugVerbose;
48 
49 #define dbgdisplay(a...) if (DebugDisplay) SD.WriteHtml(a)
50 #define dbgpages(a...) if (DebugPages) SD.WriteHtml(a)
51 #define dbgregions(a...) if (DebugRegions) SD.WriteHtml(a)
52 #define dbgobjects(a...) if (DebugObjects) SD.WriteHtml(a)
53 #define dbgconverter(a...) if (DebugConverter) SD.WriteHtml(a)
54 #define dbgsegments(a...) if (DebugSegments) SD.WriteHtml(a)
55 #define dbgpixel(a...) if (DebugPixel) SD.WriteHtml(a)
56 #define dbgcluts(a...) if (DebugCluts) SD.WriteHtml(a)
57 #define dbgoutput(a...) if (DebugOutput) SD.WriteHtml(a)
58 
59 #define DBGMAXBITMAPS 100 // debug output will be stopped after this many bitmaps
60 #define DBGBITMAPWIDTH 400
61 
62 #define FIX_SUBTITLE_VERSION_BROADCASTER_STUPIDITY // some don't properly handle version numbers, which renders them useless because subtitles are not displayed
63 
64 // --- cSubtitleDebug --------------------------------------------------------
65 
67 private:
69  int imgCnt;
70  int64_t firstPts;
71  bool newFile;
72  double factor;
73 public:
74  cSubtitleDebug(void) { Reset(); }
75  void Reset(void);
76  bool Active(void) { return imgCnt < DBGMAXBITMAPS; }
77  int64_t FirstPts(void) { return firstPts; }
78  void SetFirstPts(int64_t FirstPts) { if (firstPts < 0) firstPts = FirstPts; }
79  void SetFactor(double Factor) { factor = Factor; }
80  cString WriteJpeg(const cBitmap *Bitmap, int MaxX = 0, int MaxY = 0);
81  void WriteHtml(const char *Format, ...);
82  };
83 
85 {
86  imgCnt = 0;
87  firstPts = -1;
88  newFile = true;
89  factor = 1.0;
90 }
91 
92 cString cSubtitleDebug::WriteJpeg(const cBitmap *Bitmap, int MaxX, int MaxY)
93 {
94  if (!Active())
95  return NULL;
96  cMutexLock MutexLock(&mutex);
97  cBitmap *Scaled = Bitmap->Scaled(factor, factor, true);
98  int w = MaxX ? int(round(MaxX * factor)) : Scaled->Width();
99  int h = MaxY ? int(round(MaxY * factor)) : Scaled->Height();
100  uchar mem[w * h * 3];
101  for (int x = 0; x < w; x++) {
102  for (int y = 0; y < h; y++) {
103  tColor c = Scaled->GetColor(x, y);
104  int o = (y * w + x) * 3;
105  mem[o++] = (c & 0x00FF0000) >> 16;
106  mem[o++] = (c & 0x0000FF00) >> 8;
107  mem[o] = (c & 0x000000FF);
108  }
109  }
110  delete Scaled;
111  int Size = 0;
112  uchar *Jpeg = RgbToJpeg(mem, w, h, Size);
113  cString ImgName = cString::sprintf("dbg-%03d.jpg", imgCnt++);
114  int f = open(ImgName, O_WRONLY | O_CREAT, DEFFILEMODE);
115  if (f >= 0) {
116  if (write(f, Jpeg, Size) < 0)
117  LOG_ERROR_STR(*ImgName);
118  close(f);
119  }
120  free(Jpeg);
121  return ImgName;
122 }
123 
124 void cSubtitleDebug::WriteHtml(const char *Format, ...)
125 {
126  if (!Active())
127  return;
128  cMutexLock MutexLock(&mutex);
129  if (FILE *f = fopen("dbg-log.htm", newFile ? "w" : "a")) {
130  va_list ap;
131  va_start(ap, Format);
132  vfprintf(f, Format, ap);
133  va_end(ap);
134  fclose(f);
135  newFile = false;
136  }
137 }
138 
140 
141 // --- cSubtitleClut ---------------------------------------------------------
142 
143 class cSubtitleClut : public cListObject {
144 private:
145  int clutId;
150  tColor yuv2rgb(int Y, int Cb, int Cr);
151  void SetColor(int Bpp, int Index, tColor Color);
152 public:
153  cSubtitleClut(int ClutId);
154  void Parse(cBitStream &bs);
155  void ParsePgs(cBitStream &bs);
156  int ClutId(void) { return clutId; }
157  int ClutVersionNumber(void) { return clutVersionNumber; }
158  const cPalette *GetPalette(int Bpp);
159  };
160 
162 :palette2(2)
163 ,palette4(4)
164 ,palette8(8)
165 {
166  int a = 0, r = 0, g = 0, b = 0;
167  clutId = ClutId;
168  clutVersionNumber = -1;
169  // ETSI EN 300 743 10.3: 4-entry CLUT default contents
170  palette2.SetColor(0, ArgbToColor( 0, 0, 0, 0));
171  palette2.SetColor(1, ArgbToColor(255, 255, 255, 255));
172  palette2.SetColor(2, ArgbToColor(255, 0, 0, 0));
173  palette2.SetColor(3, ArgbToColor(255, 127, 127, 127));
174  // ETSI EN 300 743 10.2: 16-entry CLUT default contents
175  palette4.SetColor(0, ArgbToColor(0, 0, 0, 0));
176  for (int i = 1; i < 16; ++i) {
177  if (i < 8) {
178  r = (i & 1) ? 255 : 0;
179  g = (i & 2) ? 255 : 0;
180  b = (i & 4) ? 255 : 0;
181  }
182  else {
183  r = (i & 1) ? 127 : 0;
184  g = (i & 2) ? 127 : 0;
185  b = (i & 4) ? 127 : 0;
186  }
187  palette4.SetColor(i, ArgbToColor(255, r, g, b));
188  }
189  // ETSI EN 300 743 10.1: 256-entry CLUT default contents
190  palette8.SetColor(0, ArgbToColor(0, 0, 0, 0));
191  for (int i = 1; i < 256; ++i) {
192  if (i < 8) {
193  r = (i & 1) ? 255 : 0;
194  g = (i & 2) ? 255 : 0;
195  b = (i & 4) ? 255 : 0;
196  a = 63;
197  }
198  else {
199  switch (i & 0x88) {
200  case 0x00:
201  r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0);
202  g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0);
203  b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0);
204  a = 255;
205  break;
206  case 0x08:
207  r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0);
208  g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0);
209  b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0);
210  a = 127;
211  break;
212  case 0x80:
213  r = 127 + ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0);
214  g = 127 + ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0);
215  b = 127 + ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0);
216  a = 255;
217  break;
218  case 0x88:
219  r = ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0);
220  g = ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0);
221  b = ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0);
222  a = 255;
223  break;
224  }
225  }
226  palette8.SetColor(i, ArgbToColor(a, r, g, b));
227  }
228 }
229 
231 {
232  int Version = bs.GetBits(4);
233 #ifndef FIX_SUBTITLE_VERSION_BROADCASTER_STUPIDITY
234  if (clutVersionNumber == Version)
235  return; // no update
236 #endif
237  clutVersionNumber = Version;
238  bs.SkipBits(4); // reserved
239  dbgcluts("<b>clut</b> id %d version %d<br>\n", clutId, clutVersionNumber);
240  while (!bs.IsEOF()) {
241  uchar clutEntryId = bs.GetBits(8);
242  bool entryClut2Flag = bs.GetBit();
243  bool entryClut4Flag = bs.GetBit();
244  bool entryClut8Flag = bs.GetBit();
245  bs.SkipBits(4); // reserved
246  uchar yval;
247  uchar crval;
248  uchar cbval;
249  uchar tval;
250  if (bs.GetBit()) { // full_range_flag
251  yval = bs.GetBits(8);
252  crval = bs.GetBits(8);
253  cbval = bs.GetBits(8);
254  tval = bs.GetBits(8);
255  }
256  else {
257  yval = bs.GetBits(6) << 2;
258  crval = bs.GetBits(4) << 4;
259  cbval = bs.GetBits(4) << 4;
260  tval = bs.GetBits(2) << 6;
261  }
262  tColor value = 0;
263  if (yval) {
264  value = yuv2rgb(yval, cbval, crval);
265  value |= ((10 - (clutEntryId ? Setup.SubtitleFgTransparency : Setup.SubtitleBgTransparency)) * (255 - tval) / 10) << 24;
266  }
267  dbgcluts("%2d %d %d %d %08X<br>\n", clutEntryId, entryClut2Flag ? 2 : 0, entryClut4Flag ? 4 : 0, entryClut8Flag ? 8 : 0, value);
268  if (entryClut2Flag)
269  SetColor(2, clutEntryId, value);
270  if (entryClut4Flag)
271  SetColor(4, clutEntryId, value);
272  if (entryClut8Flag)
273  SetColor(8, clutEntryId, value);
274  }
275 }
276 
278 {
279  int Version = bs.GetBits(8);
280  if (clutVersionNumber == Version)
281  return; // no update
282  clutVersionNumber = Version;
283  dbgcluts("<b>clut</b> id %d version %d<br>\n", clutId, clutVersionNumber);
284  for (int i = 0; i < 256; ++i)
285  SetColor(8, i, ArgbToColor(0, 0, 0, 0));
286  while (!bs.IsEOF()) {
287  uchar clutEntryId = bs.GetBits(8);
288  uchar yval = bs.GetBits(8);
289  uchar crval = bs.GetBits(8);
290  uchar cbval = bs.GetBits(8);
291  uchar tval = bs.GetBits(8);
292  tColor value = 0;
293  if (yval) {
294  value = yuv2rgb(yval, cbval, crval);
295  value |= ((10 - (clutEntryId ? Setup.SubtitleFgTransparency : Setup.SubtitleBgTransparency)) * tval / 10) << 24;
296  }
297  dbgcluts("%2d %08X<br>\n", clutEntryId, value);
298  SetColor(8, clutEntryId, value);
299  }
300 }
301 
302 tColor cSubtitleClut::yuv2rgb(int Y, int Cb, int Cr)
303 {
304  int Ey, Epb, Epr;
305  int Eg, Eb, Er;
306 
307  Ey = (Y - 16);
308  Epb = (Cb - 128);
309  Epr = (Cr - 128);
310  /* ITU-R 709 */
311  Er = constrain((298 * Ey + 460 * Epr) / 256, 0, 255);
312  Eg = constrain((298 * Ey - 55 * Epb - 137 * Epr) / 256, 0, 255);
313  Eb = constrain((298 * Ey + 543 * Epb ) / 256, 0, 255);
314 
315  return (Er << 16) | (Eg << 8) | Eb;
316 }
317 
318 void cSubtitleClut::SetColor(int Bpp, int Index, tColor Color)
319 {
320  switch (Bpp) {
321  case 2: palette2.SetColor(Index, Color); break;
322  case 4: palette4.SetColor(Index, Color); break;
323  case 8: palette8.SetColor(Index, Color); break;
324  default: esyslog("ERROR: wrong Bpp in cSubtitleClut::SetColor(%d, %d, %08X)", Bpp, Index, Color);
325  }
326 }
327 
329 {
330  switch (Bpp) {
331  case 2: return &palette2;
332  case 4: return &palette4;
333  case 8: return &palette8;
334  default: esyslog("ERROR: wrong Bpp in cSubtitleClut::GetPalette(%d)", Bpp);
335  }
336  return &palette8;
337 }
338 
339 // --- cSubtitleObject -------------------------------------------------------
340 
341 class cSubtitleObject : public cListObject {
342 private:
343  int objectId;
349  int topIndex;
352  char *txtData;
354  void DrawLine(cBitmap *Bitmap, int x, int y, tIndex Index, int Length);
355  bool Decode2BppCodeString(cBitmap *Bitmap, int px, int py, cBitStream *bs, int&x, int y, const uint8_t *MapTable);
356  bool Decode4BppCodeString(cBitmap *Bitmap, int px, int py, cBitStream *bs, int&x, int y, const uint8_t *MapTable);
357  bool Decode8BppCodeString(cBitmap *Bitmap, int px, int py, cBitStream *bs, int&x, int y);
358  bool DecodePgsCodeString(cBitmap *Bitmap, int px, int py, cBitStream *bs, int&x, int y);
359  void DecodeSubBlock(cBitmap *Bitmap, int px, int py, const uchar *Data, int Length, bool Even);
360  void DecodeCharacterString(const uchar *Data, int NumberOfCodes);
361 public:
364  void Parse(cBitStream &bs);
365  void ParsePgs(cBitStream &bs);
366  int ObjectId(void) { return objectId; }
370  void Render(cBitmap *Bitmap, int px, int py, tIndex IndexFg, tIndex IndexBg);
371  };
372 
374 {
375  objectId = ObjectId;
376  objectVersionNumber = -1;
377  objectCodingMethod = -1;
378  nonModifyingColorFlag = false;
379  topLength = 0;
380  botLength = 0;
381  topIndex = 0;
382  topData = NULL;
383  botData = NULL;
384  txtData = NULL;
385  lineHeight = 26; // configurable subtitling font size?
386 }
387 
389 {
390  free(topData);
391  free(botData);
392  free(txtData);
393 }
394 
396 {
397  int Version = bs.GetBits(4);
398 #ifndef FIX_SUBTITLE_VERSION_BROADCASTER_STUPIDITY
399  if (objectVersionNumber == Version)
400  return; // no update
401 #endif
402  objectVersionNumber = Version;
403  objectCodingMethod = bs.GetBits(2);
405  bs.SkipBit(); // reserved
406  dbgobjects("<b>object</b> id %d version %d method %d modify %d", objectId, objectVersionNumber, objectCodingMethod, nonModifyingColorFlag); // no "<br>\n" here, DecodeCharacterString() may add data
407  if (objectCodingMethod == 0) { // coding of pixels
408  topLength = bs.GetBits(16);
409  botLength = bs.GetBits(16);
410  free(topData);
411  if ((topData = MALLOC(uchar, topLength)) != NULL)
412  memcpy(topData, bs.GetData(), topLength);
413  else
414  topLength = 0;
415  free(botData);
416  if ((botData = MALLOC(uchar, botLength)) != NULL)
417  memcpy(botData, bs.GetData() + topLength, botLength);
418  else
419  botLength = 0;
420  bs.WordAlign();
421  }
422  else if (objectCodingMethod == 1) { // coded as a string of characters
423  int numberOfCodes = bs.GetBits(8);
424  DecodeCharacterString(bs.GetData(), numberOfCodes);
425  }
426  dbgobjects("<br>\n");
427  if (DebugObjects) {
428  // We can't get the actual clut here, so we use a default one. This may lead to
429  // funny colors, but we just want to get a rough idea of what's in the object, anyway.
430  cSubtitleClut Clut(0);
431  cBitmap b(1920, 1080, 8);
432  b.Replace(*Clut.GetPalette(b.Bpp()));
433  b.Clean();
434  Render(&b, 0, 0, 0, 1);
435  int x1, y1, x2, y2;
436  if (b.Dirty(x1, y1, x2, y2)) {
437  cString ImgName = SD.WriteJpeg(&b, x2, y2);
438  dbgobjects("<img src=\"%s\"><br>\n", *ImgName);
439  }
440  }
441 }
442 
444 {
445  int Version = bs.GetBits(8);
446  if (objectVersionNumber == Version)
447  return; // no update
448  objectVersionNumber = Version;
449  objectCodingMethod = 0;
450  int sequenceDescriptor = bs.GetBits(8);
451  if (!(sequenceDescriptor & 0x80) && topData != NULL) {
452  memcpy(topData + topIndex, bs.GetData(), (bs.Length() - bs.Index()) / 8);
453  topIndex += (bs.Length() - bs.Index()) / 8;
454  return;
455  }
456  topLength = bs.GetBits(24) - 4 + 1; // exclude width / height, add sub block type
457  bs.SkipBits(32);
458  if ((topData = MALLOC(uchar, topLength)) != NULL) {
459  topData[topIndex++] = 0xFF; // PGS end of line
460  memcpy(topData + 1, bs.GetData(), (bs.Length() - bs.Index()) / 8);
461  topIndex += (bs.Length() - bs.Index()) / 8 + 1;
462  }
463  dbgobjects("<b>object</b> id %d version %d method %d modify %d", objectId, objectVersionNumber, objectCodingMethod, nonModifyingColorFlag);
464 }
465 
466 void cSubtitleObject::DecodeCharacterString(const uchar *Data, int NumberOfCodes)
467 {
468  // "ETSI EN 300 743 V1.3.1 (2006-11)", chapter 7.2.5 "Object data segment" specifies
469  // character_code to be a 16-bit index number into the character table identified
470  // in the subtitle_descriptor. However, the "subtitling_descriptor" <sic> according to
471  // "ETSI EN 300 468 V1.13.1 (2012-04)" doesn't contain a "character table identifier".
472  // It only contains a three letter language code, without any specification as to how
473  // this is related to a specific character table.
474  // Apparently the first "code" in textual subtitles contains the character table
475  // identifier, and all codes are 8-bit only. So let's first make Data a string of
476  // 8-bit characters:
477  if (NumberOfCodes > 0) {
478  char txt[NumberOfCodes + 1];
479  for (int i = 0; i < NumberOfCodes; i++)
480  txt[i] = Data[i * 2 + 1];
481  txt[NumberOfCodes] = 0;
482  bool singleByte;
483  const uchar *from = (uchar *)txt;
484  int len = NumberOfCodes;
485  const char *CharacterTable = SI::getCharacterTable(from, len, &singleByte);
486  dbgobjects(" table %s single %d raw '%s'", CharacterTable, singleByte, from);
487  cCharSetConv conv(CharacterTable, cCharSetConv::SystemCharacterTable());
488  const char *s = conv.Convert((const char *)from);
489  dbgobjects(" conv '%s'", s);
490  free(txtData);
491  txtData = strdup(s);
492  }
493 }
494 
495 void cSubtitleObject::DecodeSubBlock(cBitmap *Bitmap, int px, int py, const uchar *Data, int Length, bool Even)
496 {
497  int x = 0;
498  int y = Even ? 0 : 1;
499  uint8_t map2to4[ 4] = { 0x00, 0x07, 0x08, 0x0F };
500  uint8_t map2to8[ 4] = { 0x00, 0x77, 0x88, 0xFF };
501  uint8_t map4to8[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
502  const uint8_t *mapTable = NULL;
503  cBitStream bs(Data, Length * 8);
504  while (!bs.IsEOF()) {
505  switch (bs.GetBits(8)) {
506  case 0x10:
507  dbgpixel("2-bit / pixel code string<br>\n");
508  switch (Bitmap->Bpp()) {
509  case 8: mapTable = map2to8; break;
510  case 4: mapTable = map2to4; break;
511  default: mapTable = NULL; break;
512  }
513  while (Decode2BppCodeString(Bitmap, px, py, &bs, x, y, mapTable) && !bs.IsEOF())
514  ;
515  bs.ByteAlign();
516  break;
517  case 0x11:
518  dbgpixel("4-bit / pixel code string<br>\n");
519  switch (Bitmap->Bpp()) {
520  case 8: mapTable = map4to8; break;
521  default: mapTable = NULL; break;
522  }
523  while (Decode4BppCodeString(Bitmap, px, py, &bs, x, y, mapTable) && !bs.IsEOF())
524  ;
525  bs.ByteAlign();
526  break;
527  case 0x12:
528  dbgpixel("8-bit / pixel code string<br>\n");
529  while (Decode8BppCodeString(Bitmap, px, py, &bs, x, y) && !bs.IsEOF())
530  ;
531  break;
532  case 0x20:
533  dbgpixel("sub block 2 to 4 map<br>\n");
534  for (int i = 0; i < 4; ++i)
535  map2to4[i] = bs.GetBits(4);
536  break;
537  case 0x21:
538  dbgpixel("sub block 2 to 8 map<br>\n");
539  for (int i = 0; i < 4; ++i)
540  map2to8[i] = bs.GetBits(8);
541  break;
542  case 0x22:
543  dbgpixel("sub block 4 to 8 map<br>\n");
544  for (int i = 0; i < 16; ++i)
545  map4to8[i] = bs.GetBits(8);
546  break;
547  case 0xF0:
548  dbgpixel("end of object line<br>\n");
549  x = 0;
550  y += 2;
551  break;
552  case 0xFF:
553  dbgpixel("PGS code string, including EOLs<br>\n");
554  while (DecodePgsCodeString(Bitmap, px, py, &bs, x, y) && !bs.IsEOF()) {
555  x = 0;
556  y++;
557  }
558  break;
559  default: dbgpixel("unknown sub block %s %d<br>\n", __FUNCTION__, __LINE__);
560  }
561  }
562 }
563 
564 void cSubtitleObject::DrawLine(cBitmap *Bitmap, int x, int y, tIndex Index, int Length)
565 {
566  if (nonModifyingColorFlag && Index == 1)
567  return;
568  for (int pos = x; pos < x + Length; pos++)
569  Bitmap->SetIndex(pos, y, Index);
570 }
571 
572 bool cSubtitleObject::Decode2BppCodeString(cBitmap *Bitmap, int px, int py, cBitStream *bs, int &x, int y, const uint8_t *MapTable)
573 {
574  int rl = 0;
575  int color = 0;
576  uchar code = bs->GetBits(2);
577  if (code) {
578  color = code;
579  rl = 1;
580  }
581  else if (bs->GetBit()) { // switch_1
582  rl = bs->GetBits(3) + 3;
583  color = bs->GetBits(2);
584  }
585  else if (bs->GetBit()) // switch_2
586  rl = 1; //color 0
587  else {
588  switch (bs->GetBits(2)) { // switch_3
589  case 0:
590  return false;
591  case 1:
592  rl = 2; //color 0
593  break;
594  case 2:
595  rl = bs->GetBits(4) + 12;
596  color = bs->GetBits(2);
597  break;
598  case 3:
599  rl = bs->GetBits(8) + 29;
600  color = bs->GetBits(2);
601  break;
602  default: ;
603  }
604  }
605  if (MapTable)
606  color = MapTable[color];
607  DrawLine(Bitmap, px + x, py + y, color, rl);
608  x += rl;
609  return true;
610 }
611 
612 bool cSubtitleObject::Decode4BppCodeString(cBitmap *Bitmap, int px, int py, cBitStream *bs, int &x, int y, const uint8_t *MapTable)
613 {
614  int rl = 0;
615  int color = 0;
616  uchar code = bs->GetBits(4);
617  if (code) {
618  color = code;
619  rl = 1;
620  }
621  else if (bs->GetBit() == 0) { // switch_1
622  code = bs->GetBits(3);
623  if (code)
624  rl = code + 2; //color 0
625  else
626  return false;
627  }
628  else if (bs->GetBit() == 0) { // switch_2
629  rl = bs->GetBits(2) + 4;
630  color = bs->GetBits(4);
631  }
632  else {
633  switch (bs->GetBits(2)) { // switch_3
634  case 0: // color 0
635  rl = 1;
636  break;
637  case 1: // color 0
638  rl = 2;
639  break;
640  case 2:
641  rl = bs->GetBits(4) + 9;
642  color = bs->GetBits(4);
643  break;
644  case 3:
645  rl = bs->GetBits(8) + 25;
646  color = bs->GetBits(4);
647  break;
648  }
649  }
650  if (MapTable)
651  color = MapTable[color];
652  DrawLine(Bitmap, px + x, py + y, color, rl);
653  x += rl;
654  return true;
655 }
656 
657 bool cSubtitleObject::Decode8BppCodeString(cBitmap *Bitmap, int px, int py, cBitStream *bs, int &x, int y)
658 {
659  int rl = 0;
660  int color = 0;
661  uchar code = bs->GetBits(8);
662  if (code) {
663  color = code;
664  rl = 1;
665  }
666  else if (bs->GetBit()) {
667  rl = bs->GetBits(7);
668  color = bs->GetBits(8);
669  }
670  else {
671  code = bs->GetBits(7);
672  if (code)
673  rl = code; // color 0
674  else
675  return false;
676  }
677  DrawLine(Bitmap, px + x, py + y, color, rl);
678  x += rl;
679  return true;
680 }
681 
682 bool cSubtitleObject::DecodePgsCodeString(cBitmap *Bitmap, int px, int py, cBitStream *bs, int &x, int y)
683 {
684  while (!bs->IsEOF()) {
685  int color = bs->GetBits(8);
686  int rl = 1;
687  if (!color) {
688  int flags = bs->GetBits(8);
689  rl = flags & 0x3f;
690  if (flags & 0x40)
691  rl = (rl << 8) + bs->GetBits(8);
692  color = flags & 0x80 ? bs->GetBits(8) : 0;
693  }
694  if (rl > 0) {
695  DrawLine(Bitmap, px + x, py + y, color, rl);
696  x += rl;
697  }
698  else if (!rl)
699  return true;
700  }
701  return false;
702 }
703 
704 void cSubtitleObject::Render(cBitmap *Bitmap, int px, int py, tIndex IndexFg, tIndex IndexBg)
705 {
706  if (objectCodingMethod == 0) { // coding of pixels
707  DecodeSubBlock(Bitmap, px, py, topData, topLength, true);
708  if (botLength)
709  DecodeSubBlock(Bitmap, px, py, botData, botLength, false);
710  else
711  DecodeSubBlock(Bitmap, px, py, topData, topLength, false);
712  }
713  else if (objectCodingMethod == 1) { // coded as a string of characters
714  if (txtData) {
715  //TODO couldn't we draw the text directly into Bitmap?
717  cBitmap tmp(font->Width(txtData), font->Height(), Bitmap->Bpp());
718  double factor = (double)lineHeight / font->Height();
719  tmp.DrawText(0, 0, txtData, Bitmap->Color(IndexFg), Bitmap->Color(IndexBg), font);
720  cBitmap *scaled = tmp.Scaled(factor, factor, true);
721  Bitmap->DrawBitmap(px, py, *scaled);
722  delete scaled;
723  delete font;
724  }
725  }
726 }
727 
728 // --- cSubtitleObjects ------------------------------------------------------
729 
730 class cSubtitleObjects : public cList<cSubtitleObject> {
731 public:
732  cSubtitleObject *GetObjectById(int ObjectId, bool New = false);
733  };
734 
736 {
737  for (cSubtitleObject *so = First(); so; so = Next(so)) {
738  if (so->ObjectId() == ObjectId)
739  return so;
740  }
741  if (!New)
742  return NULL;
743  cSubtitleObject *Object = new cSubtitleObject(ObjectId);
744  Add(Object);
745  return Object;
746 }
747 
748 // --- cSubtitleObjectRef ----------------------------------------------------
749 
751 protected:
752  int objectId;
759 public:
760  cSubtitleObjectRef(void);
762  int ObjectId(void) { return objectId; }
763  int ObjectType(void) { return objectType; }
769  };
770 
772 {
773  objectId = 0;
774  objectType = 0;
775  objectProviderFlag = 0;
780 }
781 
783 {
784  objectId = bs.GetBits(16);
785  objectType = bs.GetBits(2);
786  objectProviderFlag = bs.GetBits(2);
788  bs.SkipBits(4); // reserved
790  if (objectType == 0x01 || objectType == 0x02) {
793  }
794  else {
797  }
798  dbgregions("<b>objectref</b> id %d type %d flag %d x %d y %d fg %d bg %d<br>\n", objectId, objectType, objectProviderFlag, objectHorizontalPosition, objectVerticalPosition, foregroundPixelCode, backgroundPixelCode);
799 }
800 
801 // --- cSubtitleObjectRefPgs - PGS variant of cSubtitleObjectRef -------------
802 
804 private:
805  int windowId;
807  int cropX;
808  int cropY;
809  int cropW;
810  int cropH;
811 public:
813 };
814 
817 {
818  objectId = bs.GetBits(16);
819  windowId = bs.GetBits(8);
820  compositionFlag = bs.GetBits(8);
821  bs.SkipBits(32); // skip absolute position, object is aligned to region
822  if ((compositionFlag & 0x80) != 0) {
823  cropX = bs.GetBits(16);
824  cropY = bs.GetBits(16);
825  cropW = bs.GetBits(16);
826  cropH = bs.GetBits(16);
827  }
828  else
829  cropX = cropY = cropW = cropH = 0;
830  dbgregions("<b>objectrefPgs</b> id %d flag %d x %d y %d cropX %d cropY %d cropW %d cropH %d<br>\n", objectId, compositionFlag, objectHorizontalPosition, objectVerticalPosition, cropX, cropY, cropW, cropH);
831 }
832 
833 // --- cSubtitleRegion -------------------------------------------------------
834 
835 class cSubtitleRegion : public cListObject {
836 private:
837  int regionId;
844  int clutId;
849 public:
851  void Parse(cBitStream &bs);
852  void ParsePgs(cBitStream &bs);
853  void SetDimensions(int Width, int Height);
854  int RegionId(void) { return regionId; }
856  bool RegionFillFlag(void) { return regionFillFlag; }
857  int RegionWidth(void) { return regionWidth; }
858  int RegionHeight(void) { return regionHeight; }
860  int RegionDepth(void) { return regionDepth; }
861  int ClutId(void) { return clutId; }
862  void Render(cBitmap *Bitmap, cSubtitleObjects *Objects);
863  };
864 
866 {
867  regionId = RegionId;
868  regionVersionNumber = -1;
869  regionFillFlag = false;
870  regionWidth = 0;
871  regionHeight = 0;
873  regionDepth = 0;
874  clutId = -1;
878 }
879 
881 {
882  int Version = bs.GetBits(4);
883 #ifndef FIX_SUBTITLE_VERSION_BROADCASTER_STUPIDITY
884  if (regionVersionNumber == Version)
885  return; // no update
886 #endif
887  regionVersionNumber = Version;
888  regionFillFlag = bs.GetBit();
889  bs.SkipBits(3); // reserved
890  regionWidth = bs.GetBits(16);
891  regionHeight = bs.GetBits(16);
892  regionLevelOfCompatibility = 1 << bs.GetBits(3); // stored as "number of bits per pixel"
893  regionDepth = 1 << bs.GetBits(3); // stored as "number of bits per pixel"
894  bs.SkipBits(2); // reserved
895  clutId = bs.GetBits(8);
899  bs.SkipBits(2); // reserved
900  dbgregions("<b>region</b> id %d version %d fill %d width %d height %d level %d depth %d clutId %d<br>\n", regionId, regionVersionNumber, regionFillFlag, regionWidth, regionHeight, regionLevelOfCompatibility, regionDepth, clutId);
901  // no objectRefs.Clear() here!
902  while (!bs.IsEOF())
904 }
905 
907 {
908  regionDepth = 8;
909  bs.SkipBits(8); // skip palette update flag
910  clutId = bs.GetBits(8);
911  dbgregions("<b>region</b> id %d version %d clutId %d<br>\n", regionId, regionVersionNumber, clutId);
912  int objects = bs.GetBits(8);
913  while (objects--)
915 }
916 
917 void cSubtitleRegion::SetDimensions(int Width, int Height)
918 {
919  regionWidth = Width;
920  regionHeight = Height;
921  dbgregions("<b>region</b> id %d width %d height %d<br>\n", regionId, regionWidth, regionHeight);
922 }
923 
925 {
926  if (regionFillFlag) {
927  switch (Bitmap->Bpp()) {
928  case 2: Bitmap->Fill(region2bitPixelCode); break;
929  case 4: Bitmap->Fill(region4bitPixelCode); break;
930  case 8: Bitmap->Fill(region8bitPixelCode); break;
931  default: dbgregions("unknown bpp %d (%s %d)<br>\n", Bitmap->Bpp(), __FUNCTION__, __LINE__);
932  }
933  }
934  for (cSubtitleObjectRef *sor = objectRefs.First(); sor; sor = objectRefs.Next(sor)) {
935  if (cSubtitleObject *so = Objects->GetObjectById(sor->ObjectId())) {
936  so->Render(Bitmap, sor->ObjectHorizontalPosition(), sor->ObjectVerticalPosition(), sor->ForegroundPixelCode(), sor->BackgroundPixelCode());
937  }
938  }
939 }
940 
941 // --- cSubtitleRegionRef ----------------------------------------------------
942 
944 private:
945  int regionId;
948 public:
949  cSubtitleRegionRef(int id, int x, int y);
951  int RegionId(void) { return regionId; }
954  };
955 
957 {
958  regionId = id;
961  dbgpages("<b>regionref</b> id %d tx %d y %d<br>\n", regionId, regionHorizontalAddress, regionVerticalAddress);
962 }
964 {
965  regionId = bs.GetBits(8);
966  bs.SkipBits(8); // reserved
969  dbgpages("<b>regionref</b> id %d tx %d y %d<br>\n", regionId, regionHorizontalAddress, regionVerticalAddress);
970 }
971 
972 // --- cDvbSubtitlePage ------------------------------------------------------
973 
975 private:
976  int pageId;
980  int64_t pts;
981  bool pending;
986 public:
988  void Parse(int64_t Pts, cBitStream &bs);
989  void ParsePgs(int64_t Pts, cBitStream &bs);
990  int PageId(void) { return pageId; }
991  int PageTimeout(void) { return pageTimeout; }
992  int PageVersionNumber(void) { return pageVersionNumber; }
993  int PageState(void) { return pageState; }
994  int64_t Pts(void) const { return pts; }
995  bool Pending(void) { return pending; }
996  cSubtitleObjects *Objects(void) { return &objects; }
997  tArea *GetAreas(int &NumAreas, double FactorX, double FactorY);
998  cSubtitleObject *GetObjectById(int ObjectId, bool New = false);
999  cSubtitleClut *GetClutById(int ClutId, bool New = false);
1000  cSubtitleRegion *GetRegionById(int RegionId, bool New = false);
1001  cSubtitleRegionRef *GetRegionRefByIndex(int RegionRefIndex) { return regionRefs.Get(RegionRefIndex); }
1003  void SetPending(bool Pending) { pending = Pending; }
1004  };
1005 
1007 {
1008  pageId = PageId;
1009  pageTimeout = 0;
1010  pageVersionNumber = -1;
1011  pageState = -1;
1012  pts = -1;
1013  pending = false;
1014 }
1015 
1016 void cDvbSubtitlePage::Parse(int64_t Pts, cBitStream &bs)
1017 {
1018  if (Pts >= 0)
1019  pts = Pts;
1020  pageTimeout = bs.GetBits(8);
1021  int Version = bs.GetBits(4);
1022 #ifndef FIX_SUBTITLE_VERSION_BROADCASTER_STUPIDITY
1023  if (pageVersionNumber == Version)
1024  return; // no update
1025 #endif
1026  pageVersionNumber = Version;
1027  pageState = bs.GetBits(2);
1028  switch (pageState) {
1029  case 0: // normal case - page update
1030  break;
1031  case 1: // acquisition point - page refresh
1032  regions.Clear();
1033  objects.Clear();
1034  break;
1035  case 2: // mode change - new page
1036  regions.Clear();
1037  cluts.Clear();
1038  objects.Clear();
1039  break;
1040  case 3: // reserved
1041  break;
1042  default: dbgpages("unknown page state: %d<br>\n", pageState);
1043  }
1044  bs.SkipBits(2); // reserved
1045  dbgpages("<hr>\n<b>page</b> id %d version %d pts %" PRId64 " timeout %d state %d<br>\n", pageId, pageVersionNumber, pts, pageTimeout, pageState);
1046  regionRefs.Clear();
1047  while (!bs.IsEOF())
1049  pending = true;
1050 }
1051 
1053 {
1054  if (Pts >= 0)
1055  pts = Pts;
1056  pageTimeout = 60000;
1057  int Version = bs.GetBits(16);
1058  if (pageVersionNumber == Version)
1059  return;
1060  pageVersionNumber = Version;
1061  pageState = bs.GetBits(2);
1062  switch (pageState) {
1063  case 0: // normal case - page update
1064  regions.Clear();
1065  break;
1066  case 1: // acquisition point - page refresh
1067  case 2: // epoch start - new page
1068  case 3: // epoch continue - new page
1069  regions.Clear();
1070  cluts.Clear();
1071  objects.Clear();
1072  break;
1073  default: dbgpages("unknown page state: %d<br>\n", pageState);
1074  }
1075  bs.SkipBits(6);
1076  dbgpages("<hr>\n<b>page</b> id %d version %d pts %" PRId64 " timeout %d state %d<br>\n", pageId, pageVersionNumber, pts, pageTimeout, pageState);
1077  regionRefs.Clear();
1078  pending = true;
1079 }
1080 
1081 tArea *cDvbSubtitlePage::GetAreas(int &NumAreas, double FactorX, double FactorY)
1082 {
1083  if (regions.Count() > 0) {
1084  NumAreas = regionRefs.Count();
1085  tArea *Areas = new tArea[NumAreas];
1086  tArea *a = Areas;
1087  for (cSubtitleRegionRef *srr = regionRefs.First(); srr; srr = regionRefs.Next(srr)) {
1088  if (cSubtitleRegion *sr = GetRegionById(srr->RegionId())) {
1089  a->x1 = int(round(FactorX * srr->RegionHorizontalAddress()));
1090  a->y1 = int(round(FactorY * srr->RegionVerticalAddress()));
1091  a->x2 = int(round(FactorX * (srr->RegionHorizontalAddress() + sr->RegionWidth() - 1)));
1092  a->y2 = int(round(FactorY * (srr->RegionVerticalAddress() + sr->RegionHeight() - 1)));
1093  a->bpp = sr->RegionDepth();
1094  while ((a->Width() & 3) != 0)
1095  a->x2++; // aligns width to a multiple of 4, so 2, 4 and 8 bpp will work
1096  }
1097  else
1098  a->x1 = a->y1 = a->x2 = a->y2 = a->bpp = 0;
1099  a++;
1100  }
1101  return Areas;
1102  }
1103  NumAreas = 0;
1104  return NULL;
1105 }
1106 
1108 {
1109  for (cSubtitleClut *sc = cluts.First(); sc; sc = cluts.Next(sc)) {
1110  if (sc->ClutId() == ClutId)
1111  return sc;
1112  }
1113  if (!New)
1114  return NULL;
1115  cSubtitleClut *Clut = new cSubtitleClut(ClutId);
1116  cluts.Add(Clut);
1117  return Clut;
1118 }
1119 
1121 {
1122  for (cSubtitleRegion *sr = regions.First(); sr; sr = regions.Next(sr)) {
1123  if (sr->RegionId() == RegionId)
1124  return sr;
1125  }
1126  if (!New)
1127  return NULL;
1128  cSubtitleRegion *Region = new cSubtitleRegion(RegionId);
1129  regions.Add(Region);
1130  return Region;
1131 }
1132 
1134 {
1135  return objects.GetObjectById(ObjectId, New);
1136 }
1137 
1138 // --- cDvbSubtitleAssembler -------------------------------------------------
1139 
1141 private:
1143  int length;
1144  int pos;
1145  int size;
1146  bool Realloc(int Size);
1147 public:
1148  cDvbSubtitleAssembler(void);
1149  virtual ~cDvbSubtitleAssembler();
1150  void Reset(void);
1151  unsigned char *Get(int &Length);
1152  void Put(const uchar *Data, int Length);
1153  };
1154 
1156 {
1157  data = NULL;
1158  size = 0;
1159  Reset();
1160 }
1161 
1163 {
1164  free(data);
1165 }
1166 
1168 {
1169  length = 0;
1170  pos = 0;
1171 }
1172 
1174 {
1175  if (Size > size) {
1176  Size = max(Size, 2048);
1177  if (uchar *NewBuffer = (uchar *)realloc(data, Size)) {
1178  size = Size;
1179  data = NewBuffer;
1180  }
1181  else {
1182  esyslog("ERROR: can't allocate memory for subtitle assembler");
1183  length = 0;
1184  size = 0;
1185  free(data);
1186  data = NULL;
1187  return false;
1188  }
1189  }
1190  return true;
1191 }
1192 
1193 unsigned char *cDvbSubtitleAssembler::Get(int &Length)
1194 {
1195  if (length > pos + 5) {
1196  Length = (data[pos + 4] << 8) + data[pos + 5] + 6;
1197  if (length >= pos + Length) {
1198  unsigned char *result = data + pos;
1199  pos += Length;
1200  return result;
1201  }
1202  }
1203  return NULL;
1204 }
1205 
1206 void cDvbSubtitleAssembler::Put(const uchar *Data, int Length)
1207 {
1208  if (Length && Realloc(length + Length)) {
1209  memcpy(data + length, Data, Length);
1210  length += Length;
1211  }
1212 }
1213 
1214 // --- cDvbSubtitleBitmaps ---------------------------------------------------
1215 
1217 private:
1218  int state;
1219  int64_t pts;
1220  int timeout;
1223  double osdFactorX;
1224  double osdFactorY;
1226 public:
1227  cDvbSubtitleBitmaps(int State, int64_t Pts, int Timeout, tArea *Areas, int NumAreas, double OsdFactorX, double OsdFactorY);
1229  int State(void) { return state; }
1230  int64_t Pts(void) { return pts; }
1231  int Timeout(void) { return timeout; }
1232  void AddBitmap(cBitmap *Bitmap);
1233  bool HasBitmaps(void) { return bitmaps.Size(); }
1234  void Draw(cOsd *Osd);
1235  void DbgDump(int WindowWidth, int WindowHeight);
1236  };
1237 
1238 cDvbSubtitleBitmaps::cDvbSubtitleBitmaps(int State, int64_t Pts, int Timeout, tArea *Areas, int NumAreas, double OsdFactorX, double OsdFactorY)
1239 {
1240  state = State;
1241  pts = Pts;
1242  timeout = Timeout;
1243  areas = Areas;
1244  numAreas = NumAreas;
1245  osdFactorX = OsdFactorX;
1246  osdFactorY = OsdFactorY;
1247 }
1248 
1250 {
1251  delete[] areas;
1252  for (int i = 0; i < bitmaps.Size(); i++)
1253  delete bitmaps[i];
1254 }
1255 
1257 {
1258  bitmaps.Append(Bitmap);
1259 }
1260 
1262 {
1263  bool Scale = !(DoubleEqual(osdFactorX, 1.0) && DoubleEqual(osdFactorY, 1.0));
1264  bool AntiAlias = true;
1265  if (Scale && osdFactorX > 1.0 || osdFactorY > 1.0) {
1266  // Upscaling requires 8bpp:
1267  int Bpp[MAXOSDAREAS];
1268  for (int i = 0; i < numAreas; i++) {
1269  Bpp[i] = areas[i].bpp;
1270  areas[i].bpp = 8;
1271  }
1272  if (Osd->CanHandleAreas(areas, numAreas) != oeOk) {
1273  for (int i = 0; i < numAreas; i++)
1274  areas[i].bpp = Bpp[i];
1275  AntiAlias = false;
1276  }
1277  }
1278  if (State() == 0 || Osd->SetAreas(areas, numAreas) == oeOk) {
1279  for (int i = 0; i < bitmaps.Size(); i++) {
1280  cBitmap *b = bitmaps[i];
1281  Osd->DrawScaledBitmap(int(round(b->X0() * osdFactorX)), int(round(b->Y0() * osdFactorY)), *b, osdFactorX, osdFactorY, AntiAlias);
1282  }
1283  Osd->Flush();
1284  }
1285 }
1286 
1287 void cDvbSubtitleBitmaps::DbgDump(int WindowWidth, int WindowHeight)
1288 {
1289  if (!SD.Active())
1290  return;
1291  SD.SetFirstPts(Pts());
1292  double STC = double(cDevice::PrimaryDevice()->GetSTC() - SD.FirstPts()) / 90000;
1293  double Start = double(Pts() - SD.FirstPts()) / 90000;
1294  double Duration = Timeout();
1295  double End = Start + Duration;
1296  cBitmap Bitmap(WindowWidth, WindowHeight, 8);
1297 #define DBGBACKGROUND 0xA0A0A0
1298  Bitmap.DrawRectangle(0, 0, WindowWidth - 1, WindowHeight - 1, DBGBACKGROUND);
1299  for (int i = 0; i < bitmaps.Size(); i++) {
1300  cBitmap *b = bitmaps[i];
1301  Bitmap.DrawBitmap(b->X0(), b->Y0(), *b);
1302  }
1303  cString ImgName = SD.WriteJpeg(&Bitmap);
1304 #define BORDER //" border=1"
1305  SD.WriteHtml("<p>%s<br>", State() == 0 ? "page update" : State() == 1 ? "page refresh" : State() == 2 ? "new page" : "???");
1306  SD.WriteHtml("<table" BORDER "><tr><td>");
1307  SD.WriteHtml("%.2f", STC);
1308  SD.WriteHtml("</td><td>");
1309  SD.WriteHtml("<img src=\"%s\">", *ImgName);
1310  SD.WriteHtml("</td><td style=\"height:100%%\"><table" BORDER " style=\"height:100%%\">");
1311  SD.WriteHtml("<tr><td valign=top><b>%.2f</b></td></tr>", Start);
1312  SD.WriteHtml("<tr><td valign=middle>%.2f</td></tr>", Duration);
1313  SD.WriteHtml("<tr><td valign=bottom>%.2f</td></tr>", End);
1314  SD.WriteHtml("</table></td>");
1315  SD.WriteHtml("</tr></table>\n");
1316 }
1317 
1318 // --- cDvbSubtitleConverter -------------------------------------------------
1319 
1321 
1323 :cThread("subtitle converter")
1324 {
1326  osd = NULL;
1327  frozen = false;
1328  ddsVersionNumber = -1;
1329  displayWidth = windowWidth = 720;
1330  displayHeight = windowHeight = 576;
1335  SD.Reset();
1336  Start();
1337 }
1338 
1340 {
1341  Cancel(3);
1342  delete dvbSubtitleAssembler;
1343  delete osd;
1344  delete bitmaps;
1345  delete pages;
1346 }
1347 
1349 {
1350  setupLevel++;
1351 }
1352 
1354 {
1355  dbgconverter("converter reset -----------------------<br>\n");
1357  Lock();
1358  pages->Clear();
1359  bitmaps->Clear();
1360  DELETENULL(osd);
1361  frozen = false;
1362  ddsVersionNumber = -1;
1363  displayWidth = windowWidth = 720;
1364  displayHeight = windowHeight = 576;
1367  Unlock();
1368 }
1369 
1371 {
1372  if (Data && Length > 8) {
1373  int PayloadOffset = PesPayloadOffset(Data);
1374  int SubstreamHeaderLength = 4;
1375  bool ResetSubtitleAssembler = Data[PayloadOffset + 3] == 0x00;
1376 
1377  // Compatibility mode for old subtitles plugin:
1378  if ((Data[7] & 0x01) && (Data[PayloadOffset - 3] & 0x81) == 0x01 && Data[PayloadOffset - 2] == 0x81) {
1379  PayloadOffset--;
1380  SubstreamHeaderLength = 1;
1381  ResetSubtitleAssembler = Data[8] >= 5;
1382  }
1383 
1384  if (Length > PayloadOffset + SubstreamHeaderLength) {
1385  int64_t pts = PesHasPts(Data) ? PesGetPts(Data) : -1;
1386  if (pts >= 0)
1387  dbgconverter("converter PTS: %" PRId64 "<br>\n", pts);
1388  const uchar *data = Data + PayloadOffset + SubstreamHeaderLength; // skip substream header
1389  int length = Length - PayloadOffset - SubstreamHeaderLength; // skip substream header
1390  if (ResetSubtitleAssembler)
1392 
1393  if (length > 3) {
1394  if (data[0] == 0x20 && data[1] == 0x00 && data[2] == 0x0F)
1395  dvbSubtitleAssembler->Put(data + 2, length - 2);
1396  else
1397  dvbSubtitleAssembler->Put(data, length);
1398 
1399  int Count;
1400  while (true) {
1401  unsigned char *b = dvbSubtitleAssembler->Get(Count);
1402  if (b && b[0] == 0x0F) {
1403  if (ExtractSegment(b, Count, pts) == -1)
1404  break;
1405  }
1406  else
1407  break;
1408  }
1409  }
1410  }
1411  return Length;
1412  }
1413  return 0;
1414 }
1415 
1416 int cDvbSubtitleConverter::Convert(const uchar *Data, int Length)
1417 {
1418  if (Data && Length > 8) {
1419  int PayloadOffset = PesPayloadOffset(Data);
1420  if (Length > PayloadOffset) {
1421  int64_t pts = PesHasPts(Data) ? PesGetPts(Data) : -1;
1422  if (pts >= 0)
1423  dbgconverter("converter PTS: %" PRId64 "<br>\n", pts);
1424  const uchar *data = Data + PayloadOffset;
1425  int length = Length - PayloadOffset;
1426  if (length > 0) {
1427  if (length > 2 && data[0] == 0x20 && data[1] == 0x00 && data[2] == 0x0F) {
1428  data += 2;
1429  length -= 2;
1430  }
1431  const uchar *b = data;
1432  while (length > 0) {
1433  if (b[0] == STUFFING_SEGMENT)
1434  break;
1435  int n;
1436  if (b[0] == 0x0F)
1437  n = ExtractSegment(b, length, pts);
1438  else
1439  n = ExtractPgsSegment(b, length, pts);
1440  if (n < 0)
1441  break;
1442  b += n;
1443  length -= n;
1444  }
1445  }
1446  }
1447  return Length;
1448  }
1449  return 0;
1450 }
1451 
1452 #define LimitTo32Bit(n) ((n) & 0x00000000FFFFFFFFL)
1453 
1455 {
1456  int LastSetupLevel = setupLevel;
1457  cTimeMs Timeout;
1458  while (Running()) {
1459  int WaitMs = 100;
1460  if (!frozen) {
1461  LOCK_THREAD;
1462  if (osd) {
1463  int NewSetupLevel = setupLevel;
1464  if (Timeout.TimedOut() || LastSetupLevel != NewSetupLevel) {
1465  dbgoutput("closing osd<br>\n");
1466  DELETENULL(osd);
1467  }
1468  LastSetupLevel = NewSetupLevel;
1469  }
1470  for (cDvbSubtitleBitmaps *sb = bitmaps->First(); sb; sb = bitmaps->Next(sb)) {
1471  // Calculate the Delta between the STC (the current timestamp of the video)
1472  // and the bitmap's PTS (the timestamp when the bitmap shall be presented).
1473  // A negative Delta means that the bitmap will be presented in the future:
1474  int64_t STC = cDevice::PrimaryDevice()->GetSTC();
1475  int64_t Delta = LimitTo32Bit(STC) - LimitTo32Bit(sb->Pts()); // some devices only deliver 32 bits
1476  if (Delta > (int64_t(1) << 31))
1477  Delta -= (int64_t(1) << 32);
1478  else if (Delta < -((int64_t(1) << 31) - 1))
1479  Delta += (int64_t(1) << 32);
1480  Delta /= 90; // STC and PTS are in 1/90000s
1481  if (Delta >= 0) { // found a bitmap that shall be displayed...
1482  if (Delta < sb->Timeout() * 1000) { // ...and has not timed out yet
1483  if (!sb->HasBitmaps()) {
1484  Timeout.Set();
1485  WaitMs = 0;
1486  }
1487  else if (AssertOsd()) {
1488  dbgoutput("showing bitmap #%d of %d<br>\n", sb->Index() + 1, bitmaps->Count());
1489  sb->Draw(osd);
1490  Timeout.Set(sb->Timeout() * 1000);
1491  dbgconverter("PTS: %" PRId64 " STC: %" PRId64 " (%" PRId64 ") timeout: %d<br>\n", sb->Pts(), STC, Delta, sb->Timeout());
1492  }
1493  }
1494  else
1495  WaitMs = 0; // bitmap already timed out, so try next one immediately
1496  dbgoutput("deleting bitmap #%d of %d<br>\n", sb->Index() + 1, bitmaps->Count());
1497  bitmaps->Del(sb);
1498  break;
1499  }
1500  }
1501  }
1502  cCondWait::SleepMs(WaitMs);
1503  }
1504 }
1505 
1507 {
1508  int OsdWidth, OsdHeight;
1509  double OsdAspect;
1510  int VideoWidth, VideoHeight;
1511  double VideoAspect;
1512  cDevice::PrimaryDevice()->GetOsdSize(OsdWidth, OsdHeight, OsdAspect);
1513  cDevice::PrimaryDevice()->GetVideoSize(VideoWidth, VideoHeight, VideoAspect);
1514  if (OsdWidth == displayWidth && OsdHeight == displayHeight) {
1515  osdFactorX = osdFactorY = 1.0;
1516  osdDeltaX = osdDeltaY = 0;
1517  }
1518  else {
1519  osdFactorX = osdFactorY = min(double(OsdWidth) / displayWidth, double(OsdHeight) / displayHeight);
1520  osdDeltaX = (OsdWidth - displayWidth * osdFactorX) / 2;
1521  osdDeltaY = (OsdHeight - displayHeight * osdFactorY) / 2;
1522  }
1523 }
1524 
1526 {
1527  LOCK_THREAD;
1528  if (!osd) {
1529  SetOsdData();
1531  }
1532  return osd != NULL;
1533 }
1534 
1536 {
1537  for (cDvbSubtitlePage *sp = pages->First(); sp; sp = pages->Next(sp)) {
1538  if (sp->PageId() == PageId)
1539  return sp;
1540  }
1541  if (!New)
1542  return NULL;
1543  cDvbSubtitlePage *Page = new cDvbSubtitlePage(PageId);
1544  pages->Add(Page);
1545  return Page;
1546 }
1547 
1548 int cDvbSubtitleConverter::ExtractSegment(const uchar *Data, int Length, int64_t Pts)
1549 {
1550  cBitStream bs(Data, Length * 8);
1551  if (Length > 5 && bs.GetBits(8) == 0x0F) { // sync byte
1552  int segmentType = bs.GetBits(8);
1553  if (segmentType == STUFFING_SEGMENT)
1554  return -1;
1555  LOCK_THREAD;
1556  cDvbSubtitlePage *page = GetPageById(bs.GetBits(16), true);
1557  int segmentLength = bs.GetBits(16);
1558  if (!bs.SetLength(bs.Index() + segmentLength * 8))
1559  return -1;
1560  switch (segmentType) {
1561  case PAGE_COMPOSITION_SEGMENT: {
1562  if (page->Pending()) {
1563  dbgsegments("END_OF_DISPLAY_SET_SEGMENT (simulated)<br>\n");
1564  FinishPage(page);
1565  }
1566  dbgsegments("PAGE_COMPOSITION_SEGMENT<br>\n");
1567  page->Parse(Pts, bs);
1569  break;
1570  }
1572  dbgsegments("REGION_COMPOSITION_SEGMENT<br>\n");
1573  cSubtitleRegion *region = page->GetRegionById(bs.GetBits(8), true);
1574  region->Parse(bs);
1575  break;
1576  }
1577  case CLUT_DEFINITION_SEGMENT: {
1578  dbgsegments("CLUT_DEFINITION_SEGMENT<br>\n");
1579  cSubtitleClut *clut = page->GetClutById(bs.GetBits(8), true);
1580  clut->Parse(bs);
1581  break;
1582  }
1583  case OBJECT_DATA_SEGMENT: {
1584  dbgsegments("OBJECT_DATA_SEGMENT<br>\n");
1585  cSubtitleObject *object = page->GetObjectById(bs.GetBits(16), true);
1586  object->Parse(bs);
1587  break;
1588  }
1590  dbgsegments("DISPLAY_DEFINITION_SEGMENT<br>\n");
1591  int version = bs.GetBits(4);
1592 #ifndef FIX_SUBTITLE_VERSION_BROADCASTER_STUPIDITY
1593  if (version == ddsVersionNumber)
1594  break; // no update
1595 #endif
1596  bool displayWindowFlag = bs.GetBit();
1599  bs.SkipBits(3); // reserved
1600  displayWidth = windowWidth = bs.GetBits(16) + 1;
1601  displayHeight = windowHeight = bs.GetBits(16) + 1;
1602  if (displayWindowFlag) {
1603  windowHorizontalOffset = bs.GetBits(16); // displayWindowHorizontalPositionMinimum
1604  windowWidth = bs.GetBits(16) - windowHorizontalOffset + 1; // displayWindowHorizontalPositionMaximum
1605  windowVerticalOffset = bs.GetBits(16); // displayWindowVerticalPositionMinimum
1606  windowHeight = bs.GetBits(16) - windowVerticalOffset + 1; // displayWindowVerticalPositionMaximum
1607  }
1608  SetOsdData();
1609  ddsVersionNumber = version;
1610  dbgdisplay("<b>display</b> version %d flag %d width %d height %d ofshor %d ofsver %d<br>\n", ddsVersionNumber, displayWindowFlag, windowWidth, windowHeight, windowHorizontalOffset, windowVerticalOffset);
1611  break;
1612  }
1614  dbgsegments("DISPARITY_SIGNALING_SEGMENT<br>\n");
1615  bs.SkipBits(4); // dss_version_number
1616  bool disparity_shift_update_sequence_page_flag = bs.GetBit();
1617  bs.SkipBits(3); // reserved
1618  bs.SkipBits(8); // page_default_disparity_shift
1619  if (disparity_shift_update_sequence_page_flag) {
1620  bs.SkipBits(8); // disparity_shift_update_sequence_length
1621  bs.SkipBits(24); // interval_duration[23..0]
1622  int division_period_count = bs.GetBits(8);
1623  for (int i = 0; i < division_period_count; ++i) {
1624  bs.SkipBits(8); // interval_count
1625  bs.SkipBits(8); // disparity_shift_update_integer_part
1626  }
1627  }
1628  while (!bs.IsEOF()) {
1629  bs.SkipBits(8); // region_id
1630  bool disparity_shift_update_sequence_region_flag = bs.GetBit();
1631  bs.SkipBits(5); // reserved
1632  int number_of_subregions_minus_1 = bs.GetBits(2);
1633  for (int i = 0; i <= number_of_subregions_minus_1; ++i) {
1634  if (number_of_subregions_minus_1 > 0) {
1635  bs.SkipBits(16); // subregion_horizontal_position
1636  bs.SkipBits(16); // subregion_width
1637  }
1638  bs.SkipBits(8); // subregion_disparity_shift_integer_part
1639  bs.SkipBits(4); // subregion_disparity_shift_fractional_part
1640  bs.SkipBits(4); // reserved
1641  if (disparity_shift_update_sequence_region_flag) {
1642  bs.SkipBits(8); // disparity_shift_update_sequence_length
1643  bs.SkipBits(24); // interval_duration[23..0]
1644  int division_period_count = bs.GetBits(8);
1645  for (int i = 0; i < division_period_count; ++i) {
1646  bs.SkipBits(8); // interval_count
1647  bs.SkipBits(8); // disparity_shift_update_integer_part
1648  }
1649  }
1650  }
1651  }
1652  break;
1653  }
1655  dbgsegments("END_OF_DISPLAY_SET_SEGMENT<br>\n");
1656  FinishPage(page);
1657  page->SetPending(false);
1658  break;
1659  }
1660  default:
1661  dbgsegments("*** unknown segment type: %02X<br>\n", segmentType);
1662  }
1663  return bs.Length() / 8;
1664  }
1665  return -1;
1666 }
1667 
1668 int cDvbSubtitleConverter::ExtractPgsSegment(const uchar *Data, int Length, int64_t Pts)
1669 {
1670  cBitStream bs(Data, Length * 8);
1671  if (Length >= 3) {
1672  int segmentType = bs.GetBits(8);
1673  int segmentLength = bs.GetBits(16);
1674  if (!bs.SetLength(bs.Index() + segmentLength * 8))
1675  return -1;
1676  LOCK_THREAD;
1677  cDvbSubtitlePage *page = GetPageById(0, true);
1678  switch (segmentType) {
1679  case PGS_PRESENTATION_SEGMENT: {
1680  if (page->Pending()) {
1681  dbgsegments("PGS_DISPLAY_SEGMENT (simulated)<br>\n");
1682  FinishPage(page);
1683  }
1684  dbgsegments("PGS_PRESENTATION_SEGMENT<br>\n");
1685  displayWidth = windowWidth = bs.GetBits(16);
1686  displayHeight = windowHeight = bs.GetBits(16);
1687  bs.SkipBits(8);
1688  page->ParsePgs(Pts, bs);
1690  cSubtitleRegion *region = page->GetRegionById(0, true);
1691  region->ParsePgs(bs);
1692  break;
1693  }
1694  case PGS_WINDOW_SEGMENT: {
1695  bs.SkipBits(16);
1696  int regionHorizontalAddress = bs.GetBits(16);
1697  int regionVerticalAddress = bs.GetBits(16);
1698  int regionWidth = bs.GetBits(16);
1699  int regionHeight = bs.GetBits(16);
1700  cSubtitleRegion *region = page->GetRegionById(0, true);
1701  region->SetDimensions(regionWidth, regionHeight);
1702  page->AddRegionRef(new cSubtitleRegionRef(0, regionHorizontalAddress, regionVerticalAddress));
1703  dbgsegments("PGS_WINDOW_SEGMENT<br>\n");
1704  break;
1705  }
1706  case PGS_PALETTE_SEGMENT: {
1707  dbgsegments("PGS_PALETTE_SEGMENT<br>\n");
1708  cSubtitleClut *clut = page->GetClutById(bs.GetBits(8), true);
1709  clut->ParsePgs(bs);
1710  break;
1711  }
1712  case PGS_OBJECT_SEGMENT: {
1713  dbgsegments("PGS_OBJECT_SEGMENT<br>\n");
1714  cSubtitleObject *object = page->GetObjectById(bs.GetBits(16), true);
1715  object->ParsePgs(bs);
1716  break;
1717  }
1718  case PGS_DISPLAY_SEGMENT: {
1719  dbgsegments("PGS_DISPLAY_SEGMENT<br>\n");
1720  FinishPage(page);
1721  page->SetPending(false);
1722  break;
1723  }
1724  default:
1725  dbgsegments("*** unknown segment type: %02X<br>\n", segmentType);
1726  return -1;
1727  }
1728  return bs.Length() / 8;
1729  }
1730  return -1;
1731 }
1732 
1734 {
1735  if (!AssertOsd())
1736  return;
1737  int NumAreas;
1738  tArea *Areas = Page->GetAreas(NumAreas, osdFactorX, osdFactorY);
1739  int Bpp = 8;
1740  bool Reduced = false;
1741  while (osd && osd->CanHandleAreas(Areas, NumAreas) != oeOk) {
1742  dbgoutput("CanHandleAreas: %d<br>\n", osd->CanHandleAreas(Areas, NumAreas));
1743  int HalfBpp = Bpp / 2;
1744  if (HalfBpp >= 2) {
1745  for (int i = 0; i < NumAreas; i++) {
1746  if (Areas[i].bpp >= Bpp) {
1747  Areas[i].bpp = HalfBpp;
1748  Reduced = true;
1749  }
1750  }
1751  Bpp = HalfBpp;
1752  }
1753  else
1754  return; // unable to draw bitmaps
1755  }
1756  cDvbSubtitleBitmaps *Bitmaps = new cDvbSubtitleBitmaps(Page->PageState(), Page->Pts(), Page->PageTimeout(), Areas, NumAreas, osdFactorX, osdFactorY);
1757  bitmaps->Add(Bitmaps);
1758  for (int i = 0; i < NumAreas; i++) {
1759  if (cSubtitleRegionRef *srr = Page->GetRegionRefByIndex(i)) {
1760  if (cSubtitleRegion *sr = Page->GetRegionById(srr->RegionId())) {
1761  if (cSubtitleClut *clut = Page->GetClutById(sr->ClutId())) {
1762  cBitmap *bm = new cBitmap(sr->RegionWidth(), sr->RegionHeight(), sr->RegionDepth());
1763  bm->Replace(*clut->GetPalette(sr->RegionDepth()));
1764  sr->Render(bm, Page->Objects());
1765  if (Reduced) {
1766  if (sr->RegionDepth() != Areas[i].bpp) {
1767  if (sr->RegionLevelOfCompatibility() <= Areas[i].bpp) {
1768  //TODO this is untested - didn't have any such subtitle stream
1769  cSubtitleClut *Clut = Page->GetClutById(sr->ClutId());
1770  dbgregions("reduce region %d bpp %d level %d area bpp %d<br>\n", sr->RegionId(), sr->RegionDepth(), sr->RegionLevelOfCompatibility(), Areas[i].bpp);
1771  bm->ReduceBpp(*Clut->GetPalette(sr->RegionDepth()));
1772  }
1773  else {
1774  dbgregions("condense region %d bpp %d level %d area bpp %d<br>\n", sr->RegionId(), sr->RegionDepth(), sr->RegionLevelOfCompatibility(), Areas[i].bpp);
1775  bm->ShrinkBpp(Areas[i].bpp);
1776  }
1777  }
1778  }
1779  bm->SetOffset(srr->RegionHorizontalAddress(), srr->RegionVerticalAddress());
1780  Bitmaps->AddBitmap(bm);
1781  }
1782  }
1783  }
1784  }
1785  if (DebugPages)
1786  Bitmaps->DbgDump(windowWidth, windowHeight);
1787 }
cDvbSubtitlePage::Pts
int64_t Pts(void) const
Definition: dvbsubtitle.c:994
REGION_COMPOSITION_SEGMENT
#define REGION_COMPOSITION_SEGMENT
Definition: dvbsubtitle.c:20
cDvbSubtitleConverter::osdDeltaX
int osdDeltaX
Definition: dvbsubtitle.h:36
cBitStream::SetLength
bool SetLength(int Length)
Definition: tools.c:1438
cDvbSubtitlePage::ParsePgs
void ParsePgs(int64_t Pts, cBitStream &bs)
Definition: dvbsubtitle.c:1052
DBGBACKGROUND
#define DBGBACKGROUND
cCharSetConv::SystemCharacterTable
static const char * SystemCharacterTable(void)
Definition: tools.h:172
cDvbSubtitleConverter::cDvbSubtitleConverter
cDvbSubtitleConverter(void)
Definition: dvbsubtitle.c:1322
cSubtitleRegionRef::regionId
int regionId
Definition: dvbsubtitle.c:945
cSubtitleClut::clutId
int clutId
Definition: dvbsubtitle.c:145
cDvbSubtitlePage::cluts
cList< cSubtitleClut > cluts
Definition: dvbsubtitle.c:983
cSubtitleObject::Decode2BppCodeString
bool Decode2BppCodeString(cBitmap *Bitmap, int px, int py, cBitStream *bs, int &x, int y, const uint8_t *MapTable)
Definition: dvbsubtitle.c:572
cPalette::Bpp
int Bpp(void) const
Definition: osd.h:111
cBitStream::IsEOF
bool IsEOF(void) const
Definition: tools.h:362
cSubtitleRegion::region2bitPixelCode
int region2bitPixelCode
Definition: dvbsubtitle.c:847
cDvbSubtitleConverter::SetupChanged
static void SetupChanged(void)
Definition: dvbsubtitle.c:1348
cDvbSubtitlePage::pageTimeout
int pageTimeout
Definition: dvbsubtitle.c:977
cOsdProvider::NewOsd
static cOsd * NewOsd(int Left, int Top, uint Level=OSD_LEVEL_DEFAULT)
Returns a pointer to a newly created cOsd object, which will be located at the given coordinates.
Definition: osd.c:2017
cDvbSubtitleConverter::ddsVersionNumber
int ddsVersionNumber
Definition: dvbsubtitle.h:29
cString::sprintf
static cString sprintf(const char *fmt,...) __attribute__((format(printf
Definition: tools.c:1127
tColor
uint32_t tColor
Definition: font.h:29
cSubtitleRegion
Definition: dvbsubtitle.c:835
cBitStream::GetBit
int GetBit(void)
Definition: tools.c:1407
cDvbSubtitleBitmaps::timeout
int timeout
Definition: dvbsubtitle.c:1220
cSubtitleClut::palette2
cPalette palette2
Definition: dvbsubtitle.c:147
PGS_OBJECT_SEGMENT
#define PGS_OBJECT_SEGMENT
Definition: dvbsubtitle.c:29
cBitmap::SetIndex
void SetIndex(int x, int y, tIndex Index)
Sets the index at the given coordinates to Index.
Definition: osd.c:500
cSetup::SubtitleOffset
int SubtitleOffset
Definition: config.h:288
cSubtitleClut::clutVersionNumber
int clutVersionNumber
Definition: dvbsubtitle.c:146
cSubtitleRegion::regionWidth
int regionWidth
Definition: dvbsubtitle.c:840
PAGE_COMPOSITION_SEGMENT
#define PAGE_COMPOSITION_SEGMENT
Definition: dvbsubtitle.c:19
cListObject::Index
int Index(void) const
Definition: tools.c:2072
cSubtitleDebug::SetFirstPts
void SetFirstPts(int64_t FirstPts)
Definition: dvbsubtitle.c:78
cDvbSubtitlePage::cDvbSubtitlePage
cDvbSubtitlePage(int PageId)
Definition: dvbsubtitle.c:1006
cSubtitleObjectRef::backgroundPixelCode
int backgroundPixelCode
Definition: dvbsubtitle.c:758
cDvbSubtitleBitmaps::State
int State(void)
Definition: dvbsubtitle.c:1229
oeOk
@ oeOk
Definition: osd.h:44
tIndex
uint8_t tIndex
Definition: font.h:31
cDvbSubtitleBitmaps::AddBitmap
void AddBitmap(cBitmap *Bitmap)
Definition: dvbsubtitle.c:1256
cDvbSubtitleConverter::pages
cList< cDvbSubtitlePage > * pages
Definition: dvbsubtitle.h:40
cDvbSubtitleConverter::osdFactorY
double osdFactorY
Definition: dvbsubtitle.h:39
cDvbSubtitleConverter::ExtractPgsSegment
int ExtractPgsSegment(const uchar *Data, int Length, int64_t Pts)
Definition: dvbsubtitle.c:1668
cSubtitleClut::ClutVersionNumber
int ClutVersionNumber(void)
Definition: dvbsubtitle.c:157
cDvbSubtitlePage::regionRefs
cList< cSubtitleRegionRef > regionRefs
Definition: dvbsubtitle.c:985
DISPLAY_DEFINITION_SEGMENT
#define DISPLAY_DEFINITION_SEGMENT
Definition: dvbsubtitle.c:23
cDvbSubtitleAssembler::data
uchar * data
Definition: dvbsubtitle.c:1142
cBitmap::Fill
void Fill(tIndex Index)
Fills the bitmap data with the given Index.
Definition: osd.c:515
cSubtitleDebug::SetFactor
void SetFactor(double Factor)
Definition: dvbsubtitle.c:79
cSubtitleObjects
Definition: dvbsubtitle.c:730
dbgregions
#define dbgregions(a...)
Definition: dvbsubtitle.c:51
cSubtitleObjectRef::ObjectVerticalPosition
int ObjectVerticalPosition(void)
Definition: dvbsubtitle.c:766
cSubtitleObjectRefPgs
Definition: dvbsubtitle.c:803
tArea::x2
int x2
Definition: osd.h:299
cDvbSubtitleConverter::osdFactorX
double osdFactorX
Definition: dvbsubtitle.h:38
cBitStream::GetData
const uint8_t * GetData(void) const
Definition: tools.h:366
cSubtitleObject::topLength
int topLength
Definition: dvbsubtitle.c:347
cSubtitleObject::NonModifyingColorFlag
bool NonModifyingColorFlag(void)
Definition: dvbsubtitle.c:369
cOsd
The cOsd class is the interface to the "On Screen Display".
Definition: osd.h:724
cBitmap::Width
int Width(void) const
Definition: osd.h:188
cDvbSubtitleConverter::bitmaps
cList< cDvbSubtitleBitmaps > * bitmaps
Definition: dvbsubtitle.h:41
cSubtitleRegion::ParsePgs
void ParsePgs(cBitStream &bs)
Definition: dvbsubtitle.c:906
cDvbSubtitleConverter::Convert
int Convert(const uchar *Data, int Length)
Definition: dvbsubtitle.c:1416
DebugSegments
static bool DebugSegments
Definition: dvbsubtitle.c:44
cSubtitleObjectRef::ObjectId
int ObjectId(void)
Definition: dvbsubtitle.c:762
constrain
T constrain(T v, T l, T h)
Definition: tools.h:68
cDvbSubtitleBitmaps::HasBitmaps
bool HasBitmaps(void)
Definition: dvbsubtitle.c:1233
cSubtitleRegion::clutId
int clutId
Definition: dvbsubtitle.c:844
cSubtitleDebug::Active
bool Active(void)
Definition: dvbsubtitle.c:76
cDvbSubtitleAssembler::Get
unsigned char * Get(int &Length)
Definition: dvbsubtitle.c:1193
cSubtitleObjectRef::objectId
int objectId
Definition: dvbsubtitle.c:752
cDvbSubtitleConverter::setupLevel
static int setupLevel
Definition: dvbsubtitle.h:25
cSubtitleObject::lineHeight
int lineHeight
Definition: dvbsubtitle.c:353
cSubtitleObjectRefPgs::windowId
int windowId
Definition: dvbsubtitle.c:805
cSubtitleObject
Definition: dvbsubtitle.c:341
cDvbSubtitlePage::PageTimeout
int PageTimeout(void)
Definition: dvbsubtitle.c:991
dbgpages
#define dbgpages(a...)
Definition: dvbsubtitle.c:50
cSubtitleObject::DecodeCharacterString
void DecodeCharacterString(const uchar *Data, int NumberOfCodes)
Definition: dvbsubtitle.c:466
cSubtitleRegionRef::regionVerticalAddress
int regionVerticalAddress
Definition: dvbsubtitle.c:947
cBitmap::Scaled
cBitmap * Scaled(double FactorX, double FactorY, bool AntiAlias=false) const
Creates a copy of this bitmap, scaled by the given factors.
Definition: osd.c:838
cBitmap::DrawRectangle
void DrawRectangle(int x1, int y1, int x2, int y2, tColor Color)
Draws a filled rectangle defined by the upper left (x1, y1) and lower right (x2, y2) corners with the...
Definition: osd.c:611
cDvbSubtitleBitmaps::state
int state
Definition: dvbsubtitle.c:1218
cSubtitleObjectRef::foregroundPixelCode
int foregroundPixelCode
Definition: dvbsubtitle.c:757
cThread::Unlock
void Unlock(void)
Definition: thread.h:95
cSetup::FontOsdSize
int FontOsdSize
Definition: config.h:334
cListBase::Count
int Count(void) const
Definition: tools.h:590
cListBase::Add
void Add(cListObject *Object, cListObject *After=NULL)
Definition: tools.c:2152
cSubtitleObject::ObjectId
int ObjectId(void)
Definition: dvbsubtitle.c:366
ArgbToColor
tColor ArgbToColor(uint8_t A, uint8_t R, uint8_t G, uint8_t B)
Definition: osd.h:58
dbgsegments
#define dbgsegments(a...)
Definition: dvbsubtitle.c:54
cSubtitleObject::ParsePgs
void ParsePgs(cBitStream &bs)
Definition: dvbsubtitle.c:443
cBitmap::DrawText
void DrawText(int x, int y, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font, int Width=0, int Height=0, int Alignment=taDefault)
Draws the given string at coordinates (x, y) with the given foreground and background color and font.
Definition: osd.c:562
dbgoutput
#define dbgoutput(a...)
Definition: dvbsubtitle.c:57
cDvbSubtitleConverter::~cDvbSubtitleConverter
virtual ~cDvbSubtitleConverter()
Definition: dvbsubtitle.c:1339
cDvbSubtitlePage
Definition: dvbsubtitle.c:974
DebugVerbose
static bool DebugVerbose
Definition: dvbsubtitle.c:38
cSubtitleObjectRef::BackgroundPixelCode
int BackgroundPixelCode(void)
Definition: dvbsubtitle.c:768
cFont
Definition: font.h:37
cPalette
Definition: osd.h:88
cSubtitleRegion::regionDepth
int regionDepth
Definition: dvbsubtitle.c:843
cSubtitleDebug::firstPts
int64_t firstPts
Definition: dvbsubtitle.c:70
cThread::Cancel
void Cancel(int WaitSeconds=0)
Cancels the thread by first setting 'running' to false, so that the Action() loop can finish in an or...
Definition: thread.c:354
cSubtitleClut
Definition: dvbsubtitle.c:143
cCharSetConv
Definition: tools.h:149
cMutexLock
Definition: thread.h:141
cBitStream::GetBits
uint32_t GetBits(int n)
Definition: tools.c:1416
cSubtitleObjectRefPgs::compositionFlag
int compositionFlag
Definition: dvbsubtitle.c:806
cSubtitleObject::Render
void Render(cBitmap *Bitmap, int px, int py, tIndex IndexFg, tIndex IndexBg)
Definition: dvbsubtitle.c:704
cSubtitleObject::DecodePgsCodeString
bool DecodePgsCodeString(cBitmap *Bitmap, int px, int py, cBitStream *bs, int &x, int y)
Definition: dvbsubtitle.c:682
END_OF_DISPLAY_SET_SEGMENT
#define END_OF_DISPLAY_SET_SEGMENT
Definition: dvbsubtitle.c:25
STUFFING_SEGMENT
#define STUFFING_SEGMENT
Definition: dvbsubtitle.c:26
tArea::bpp
int bpp
Definition: osd.h:300
Setup
cSetup Setup
Definition: config.c:372
device.h
cDvbSubtitleBitmaps::~cDvbSubtitleBitmaps
~cDvbSubtitleBitmaps()
Definition: dvbsubtitle.c:1249
DELETENULL
void DELETENULL(T *&p)
Definition: tools.h:49
cSubtitleObject::nonModifyingColorFlag
bool nonModifyingColorFlag
Definition: dvbsubtitle.c:346
cSubtitleDebug
Definition: dvbsubtitle.c:66
cDvbSubtitleBitmaps::osdFactorX
double osdFactorX
Definition: dvbsubtitle.c:1223
cDvbSubtitleBitmaps::Timeout
int Timeout(void)
Definition: dvbsubtitle.c:1231
cDvbSubtitleConverter::windowWidth
int windowWidth
Definition: dvbsubtitle.h:34
cDvbSubtitleBitmaps::cDvbSubtitleBitmaps
cDvbSubtitleBitmaps(int State, int64_t Pts, int Timeout, tArea *Areas, int NumAreas, double OsdFactorX, double OsdFactorY)
Definition: dvbsubtitle.c:1238
cSubtitleRegion::RegionHeight
int RegionHeight(void)
Definition: dvbsubtitle.c:858
cSubtitleRegion::region8bitPixelCode
int region8bitPixelCode
Definition: dvbsubtitle.c:845
cVector< cBitmap * >
cDvbSubtitleBitmaps::bitmaps
cVector< cBitmap * > bitmaps
Definition: dvbsubtitle.c:1225
cDvbSubtitleBitmaps::osdFactorY
double osdFactorY
Definition: dvbsubtitle.c:1224
cDvbSubtitlePage::PageState
int PageState(void)
Definition: dvbsubtitle.c:993
cTimeMs::Set
void Set(int Ms=0)
Definition: tools.c:774
SI::getCharacterTable
const char * getCharacterTable(const unsigned char *&buffer, int &length, bool *isSingleByte)
Definition: si.c:364
cSubtitleRegion::regionId
int regionId
Definition: dvbsubtitle.c:837
cSubtitleObjectRef::ObjectProviderFlag
int ObjectProviderFlag(void)
Definition: dvbsubtitle.c:764
cDvbSubtitleBitmaps::Pts
int64_t Pts(void)
Definition: dvbsubtitle.c:1230
cSubtitleDebug::WriteHtml
void WriteHtml(const char *Format,...)
Definition: dvbsubtitle.c:124
cBitStream::SkipBit
void SkipBit(void)
Definition: tools.h:361
LimitTo32Bit
#define LimitTo32Bit(n)
Definition: dvbsubtitle.c:1452
cDvbSubtitleConverter::displayHeight
int displayHeight
Definition: dvbsubtitle.h:31
cDvbSubtitleConverter::FinishPage
void FinishPage(cDvbSubtitlePage *Page)
Definition: dvbsubtitle.c:1733
cSubtitleObject::objectVersionNumber
int objectVersionNumber
Definition: dvbsubtitle.c:344
cDvbSubtitleAssembler
Definition: dvbsubtitle.c:1140
dbgdisplay
#define dbgdisplay(a...)
Definition: dvbsubtitle.c:49
cSubtitleObjectRefPgs::cSubtitleObjectRefPgs
cSubtitleObjectRefPgs(cBitStream &bs)
Definition: dvbsubtitle.c:815
OBJECT_DATA_SEGMENT
#define OBJECT_DATA_SEGMENT
Definition: dvbsubtitle.c:22
cMutex
Definition: thread.h:67
cSubtitleObject::DrawLine
void DrawLine(cBitmap *Bitmap, int x, int y, tIndex Index, int Length)
Definition: dvbsubtitle.c:564
DebugNormal
static bool DebugNormal
Definition: dvbsubtitle.c:37
cSubtitleObjectRefPgs::cropH
int cropH
Definition: dvbsubtitle.c:810
cSubtitleRegionRef::RegionVerticalAddress
int RegionVerticalAddress(void)
Definition: dvbsubtitle.c:953
cSubtitleDebug::newFile
bool newFile
Definition: dvbsubtitle.c:71
cSubtitleObject::objectId
int objectId
Definition: dvbsubtitle.c:343
DoubleEqual
bool DoubleEqual(double a, double b)
Definition: tools.h:95
cSubtitleClut::ClutId
int ClutId(void)
Definition: dvbsubtitle.c:156
cBitmap::Clean
void Clean(void)
Marks the dirty area as clean.
Definition: osd.c:354
cListBase::Del
void Del(cListObject *Object, bool DeleteObject=true)
Definition: tools.c:2184
dbgconverter
#define dbgconverter(a...)
Definition: dvbsubtitle.c:53
cSubtitleObject::ObjectVersionNumber
int ObjectVersionNumber(void)
Definition: dvbsubtitle.c:367
cDvbSubtitleAssembler::Reset
void Reset(void)
Definition: dvbsubtitle.c:1167
cSubtitleRegion::RegionWidth
int RegionWidth(void)
Definition: dvbsubtitle.c:857
cListObject
Definition: tools.h:493
cDvbSubtitlePage::SetPending
void SetPending(bool Pending)
Definition: dvbsubtitle.c:1003
cSubtitleClut::Parse
void Parse(cBitStream &bs)
Definition: dvbsubtitle.c:230
cSubtitleObjectRef::ForegroundPixelCode
int ForegroundPixelCode(void)
Definition: dvbsubtitle.c:767
PGS_PRESENTATION_SEGMENT
#define PGS_PRESENTATION_SEGMENT
Definition: dvbsubtitle.c:30
cBitmap
Definition: osd.h:169
tArea::x1
int x1
Definition: osd.h:299
cSubtitleObjects::GetObjectById
cSubtitleObject * GetObjectById(int ObjectId, bool New=false)
Definition: dvbsubtitle.c:735
cThread::Lock
void Lock(void)
Definition: thread.h:94
cDvbSubtitleConverter::SetOsdData
void SetOsdData(void)
Definition: dvbsubtitle.c:1506
DebugPixel
static bool DebugPixel
Definition: dvbsubtitle.c:45
PGS_WINDOW_SEGMENT
#define PGS_WINDOW_SEGMENT
Definition: dvbsubtitle.c:31
cDvbSubtitleConverter::osd
cOsd * osd
Definition: dvbsubtitle.h:27
DebugRegions
static bool DebugRegions
Definition: dvbsubtitle.c:41
cSubtitleObjectRefPgs::cropW
int cropW
Definition: dvbsubtitle.c:809
cSubtitleDebug::WriteJpeg
cString WriteJpeg(const cBitmap *Bitmap, int MaxX=0, int MaxY=0)
Definition: dvbsubtitle.c:92
cSubtitleRegion::RegionDepth
int RegionDepth(void)
Definition: dvbsubtitle.c:860
cFont::Height
virtual int Height(void) const =0
Returns the height of this font in pixel (all characters have the same height).
DebugOutput
static bool DebugOutput
Definition: dvbsubtitle.c:47
cSubtitleRegion::RegionFillFlag
bool RegionFillFlag(void)
Definition: dvbsubtitle.c:856
uchar
unsigned char uchar
Definition: tools.h:31
cCharSetConv::Convert
const char * Convert(const char *From, char *To=NULL, size_t ToLength=0)
Converts the given Text from FromCode to ToCode (as set in the constructor).
Definition: tools.c:991
cListBase::Clear
virtual void Clear(void)
Definition: tools.c:2229
cDvbSubtitlePage::pts
int64_t pts
Definition: dvbsubtitle.c:980
cSubtitleObjectRef::objectHorizontalPosition
int objectHorizontalPosition
Definition: dvbsubtitle.c:755
cBitmap::X0
int X0(void) const
Definition: osd.h:186
cDvbSubtitlePage::pageId
int pageId
Definition: dvbsubtitle.c:976
DebugDisplay
static bool DebugDisplay
Definition: dvbsubtitle.c:39
cDvbSubtitleAssembler::~cDvbSubtitleAssembler
virtual ~cDvbSubtitleAssembler()
Definition: dvbsubtitle.c:1162
cSubtitleRegion::regionHeight
int regionHeight
Definition: dvbsubtitle.c:841
cSubtitleObject::txtData
char * txtData
Definition: dvbsubtitle.c:352
tArea
Definition: osd.h:298
CLUT_DEFINITION_SEGMENT
#define CLUT_DEFINITION_SEGMENT
Definition: dvbsubtitle.c:21
cSubtitleObjectRef::objectProviderFlag
int objectProviderFlag
Definition: dvbsubtitle.c:754
cDvbSubtitleConverter::Reset
void Reset(void)
Definition: dvbsubtitle.c:1353
cSubtitleObject::Parse
void Parse(cBitStream &bs)
Definition: dvbsubtitle.c:395
cSubtitleObjectRefPgs::cropY
int cropY
Definition: dvbsubtitle.c:808
cTimeMs
Definition: tools.h:369
cSetup::SubtitleBgTransparency
int SubtitleBgTransparency
Definition: config.h:289
DBGMAXBITMAPS
#define DBGMAXBITMAPS
Definition: dvbsubtitle.c:59
cSubtitleObject::objectCodingMethod
int objectCodingMethod
Definition: dvbsubtitle.c:345
PGS_PALETTE_SEGMENT
#define PGS_PALETTE_SEGMENT
Definition: dvbsubtitle.c:28
cDvbSubtitlePage::GetRegionRefByIndex
cSubtitleRegionRef * GetRegionRefByIndex(int RegionRefIndex)
Definition: dvbsubtitle.c:1001
cDvbSubtitlePage::pageState
int pageState
Definition: dvbsubtitle.c:979
cVector::Size
int Size(void) const
Definition: tools.h:717
cSubtitleRegionRef::cSubtitleRegionRef
cSubtitleRegionRef(int id, int x, int y)
Definition: dvbsubtitle.c:956
cList
Definition: tools.h:594
cDvbSubtitlePage::Objects
cSubtitleObjects * Objects(void)
Definition: dvbsubtitle.c:996
cSubtitleObject::topIndex
int topIndex
Definition: dvbsubtitle.c:349
cDvbSubtitlePage::PageId
int PageId(void)
Definition: dvbsubtitle.c:990
cPalette::SetColor
void SetColor(int Index, tColor Color)
Sets the palette entry at Index to Color.
Definition: osd.c:172
cDvbSubtitleBitmaps
Definition: dvbsubtitle.c:1216
DBGBITMAPWIDTH
#define DBGBITMAPWIDTH
Definition: dvbsubtitle.c:60
DebugPages
static bool DebugPages
Definition: dvbsubtitle.c:40
cBitmap::DrawBitmap
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 ...
Definition: osd.c:533
cDvbSubtitlePage::Parse
void Parse(int64_t Pts, cBitStream &bs)
Definition: dvbsubtitle.c:1016
cDvbSubtitleConverter::dvbSubtitleAssembler
cDvbSubtitleAssembler * dvbSubtitleAssembler
Definition: dvbsubtitle.h:26
dbgobjects
#define dbgobjects(a...)
Definition: dvbsubtitle.c:52
cDvbSubtitleConverter::GetPageById
cDvbSubtitlePage * GetPageById(int PageId, bool New=false)
Definition: dvbsubtitle.c:1535
BORDER
#define BORDER
cDvbSubtitleConverter::windowHorizontalOffset
int windowHorizontalOffset
Definition: dvbsubtitle.h:32
SD
static cSubtitleDebug SD
Definition: dvbsubtitle.c:139
cDvbSubtitleConverter::windowHeight
int windowHeight
Definition: dvbsubtitle.h:35
cSubtitleObject::~cSubtitleObject
~cSubtitleObject()
Definition: dvbsubtitle.c:388
cSubtitleDebug::cSubtitleDebug
cSubtitleDebug(void)
Definition: dvbsubtitle.c:74
dbgcluts
#define dbgcluts(a...)
Definition: dvbsubtitle.c:56
MALLOC
#define MALLOC(type, size)
Definition: tools.h:47
cSubtitleObjectRef::cSubtitleObjectRef
cSubtitleObjectRef(void)
Definition: dvbsubtitle.c:771
cSubtitleRegionRef::RegionId
int RegionId(void)
Definition: dvbsubtitle.c:951
cDvbSubtitleAssembler::length
int length
Definition: dvbsubtitle.c:1143
cString
Definition: tools.h:176
dvbsubtitle.h
dbgpixel
#define dbgpixel(a...)
Definition: dvbsubtitle.c:55
cSubtitleDebug::imgCnt
int imgCnt
Definition: dvbsubtitle.c:69
OSD_LEVEL_SUBTITLES
#define OSD_LEVEL_SUBTITLES
Definition: osd.h:22
cDvbSubtitlePage::PageVersionNumber
int PageVersionNumber(void)
Definition: dvbsubtitle.c:992
cSubtitleRegion::Render
void Render(cBitmap *Bitmap, cSubtitleObjects *Objects)
Definition: dvbsubtitle.c:924
cBitmap::Y0
int Y0(void) const
Definition: osd.h:187
cOsd::SetAreas
virtual eOsdError SetAreas(const tArea *Areas, int NumAreas)
Sets the sub-areas to the given areas.
Definition: osd.c:1831
RgbToJpeg
uchar * RgbToJpeg(uchar *Mem, int Width, int Height, int &Size, int Quality)
Converts the given Memory to a JPEG image and returns a pointer to the resulting image.
Definition: tools.c:1298
DebugObjects
static bool DebugObjects
Definition: dvbsubtitle.c:42
cSubtitleRegion::RegionId
int RegionId(void)
Definition: dvbsubtitle.c:854
cSubtitleRegion::objectRefs
cList< cSubtitleObjectRef > objectRefs
Definition: dvbsubtitle.c:848
cListBase::Get
const cListObject * Get(int Index) const
Definition: tools.c:2259
cSubtitleObjectRef::objectVerticalPosition
int objectVerticalPosition
Definition: dvbsubtitle.c:756
cSubtitleRegion::regionFillFlag
bool regionFillFlag
Definition: dvbsubtitle.c:839
cDvbSubtitleBitmaps::Draw
void Draw(cOsd *Osd)
Definition: dvbsubtitle.c:1261
cDvbSubtitlePage::regions
cList< cSubtitleRegion > regions
Definition: dvbsubtitle.c:984
cSubtitleObject::ObjectCodingMethod
int ObjectCodingMethod(void)
Definition: dvbsubtitle.c:368
cBitmap::ReduceBpp
void ReduceBpp(const cPalette &Palette)
Reduces the color depth of the bitmap to that of the given Palette.
Definition: osd.c:765
cSubtitleObjectRef::objectType
int objectType
Definition: dvbsubtitle.c:753
cDvbSubtitlePage::objects
cSubtitleObjects objects
Definition: dvbsubtitle.c:982
cDvbSubtitlePage::Pending
bool Pending(void)
Definition: dvbsubtitle.c:995
cThread
Definition: thread.h:79
cDvbSubtitleBitmaps::pts
int64_t pts
Definition: dvbsubtitle.c:1219
cFont::CreateFont
static cFont * CreateFont(const char *Name, int CharHeight, int CharWidth=0)
Creates a new font object with the given Name and makes its characters CharHeight pixels high.
Definition: font.c:428
cSubtitleObjectRefPgs::cropX
int cropX
Definition: dvbsubtitle.c:807
cBitmap::Dirty
bool Dirty(int &x1, int &y1, int &x2, int &y2)
Tells whether there is a dirty area and returns the bounding rectangle of that area (relative to the ...
Definition: osd.c:342
cDvbSubtitleConverter::ConvertFragments
int ConvertFragments(const uchar *Data, int Length)
Definition: dvbsubtitle.c:1370
cCondWait::SleepMs
static void SleepMs(int TimeoutMs)
Creates a cCondWait object and uses it to sleep for TimeoutMs milliseconds, immediately giving up the...
Definition: thread.c:72
cSubtitleRegion::cSubtitleRegion
cSubtitleRegion(int RegionId)
Definition: dvbsubtitle.c:865
cDvbSubtitlePage::GetClutById
cSubtitleClut * GetClutById(int ClutId, bool New=false)
Definition: dvbsubtitle.c:1107
cDvbSubtitlePage::pending
bool pending
Definition: dvbsubtitle.c:981
LOCK_THREAD
#define LOCK_THREAD
Definition: thread.h:167
cDvbSubtitleAssembler::Put
void Put(const uchar *Data, int Length)
Definition: dvbsubtitle.c:1206
cSubtitleClut::SetColor
void SetColor(int Bpp, int Index, tColor Color)
Definition: dvbsubtitle.c:318
MAXOSDAREAS
#define MAXOSDAREAS
Definition: osd.h:711
cDvbSubtitlePage::GetAreas
tArea * GetAreas(int &NumAreas, double FactorX, double FactorY)
Definition: dvbsubtitle.c:1081
cDvbSubtitleAssembler::pos
int pos
Definition: dvbsubtitle.c:1144
cBitStream
Definition: tools.h:347
cSubtitleRegion::regionVersionNumber
int regionVersionNumber
Definition: dvbsubtitle.c:838
cSubtitleRegionRef
Definition: dvbsubtitle.c:943
cTimeMs::TimedOut
bool TimedOut(void) const
Definition: tools.c:779
cBitStream::Length
int Length(void) const
Definition: tools.h:364
cOsd::DrawScaledBitmap
virtual void DrawScaledBitmap(int x, int y, const cBitmap &Bitmap, double FactorX, double FactorY, bool AntiAlias=false)
Sets the pixels in the OSD with the data from the given Bitmap, putting the upper left corner of the ...
Definition: osd.c:1943
cBitStream::ByteAlign
void ByteAlign(void)
Definition: tools.c:1424
max
T max(T a, T b)
Definition: tools.h:60
cDvbSubtitleBitmaps::numAreas
int numAreas
Definition: dvbsubtitle.c:1222
cDvbSubtitleConverter::windowVerticalOffset
int windowVerticalOffset
Definition: dvbsubtitle.h:33
cSubtitleDebug::Reset
void Reset(void)
Definition: dvbsubtitle.c:84
cSubtitleObjectRef::ObjectHorizontalPosition
int ObjectHorizontalPosition(void)
Definition: dvbsubtitle.c:765
cDvbSubtitlePage::GetRegionById
cSubtitleRegion * GetRegionById(int RegionId, bool New=false)
Definition: dvbsubtitle.c:1120
cBitmap::Height
int Height(void) const
Definition: osd.h:189
cSubtitleClut::palette8
cPalette palette8
Definition: dvbsubtitle.c:149
cSubtitleClut::cSubtitleClut
cSubtitleClut(int ClutId)
Definition: dvbsubtitle.c:161
cSubtitleClut::GetPalette
const cPalette * GetPalette(int Bpp)
Definition: dvbsubtitle.c:328
cSubtitleObjectRef
Definition: dvbsubtitle.c:750
cDvbSubtitleConverter::Action
virtual void Action(void)
A derived cThread class must implement the code it wants to execute as a separate thread in this func...
Definition: dvbsubtitle.c:1454
si.h
cSubtitleDebug::factor
double factor
Definition: dvbsubtitle.c:72
cOsd::CanHandleAreas
virtual eOsdError CanHandleAreas(const tArea *Areas, int NumAreas)
Checks whether the OSD can display the given set of sub-areas.
Definition: osd.c:1809
DebugConverter
static bool DebugConverter
Definition: dvbsubtitle.c:43
cDvbSubtitleConverter::osdDeltaY
int osdDeltaY
Definition: dvbsubtitle.h:37
cSubtitleObject::botData
uchar * botData
Definition: dvbsubtitle.c:351
cFont::Width
virtual int Width(void) const =0
Returns the original character width as requested when the font was created, or 0 if the default widt...
cList< cSubtitleObject >::Next
const cSubtitleObject * Next(const cSubtitleObject *Object) const
< Returns the element immediately before Object in this list, or NULL if Object is the first element ...
Definition: tools.h:613
cDvbSubtitleConverter::AssertOsd
bool AssertOsd(void)
Definition: dvbsubtitle.c:1525
cDvbSubtitleConverter::frozen
bool frozen
Definition: dvbsubtitle.h:28
cDvbSubtitleConverter::ExtractSegment
int ExtractSegment(const uchar *Data, int Length, int64_t Pts)
Definition: dvbsubtitle.c:1548
cThread::Start
void bool Start(void)
Sets the description of this thread, which will be used when logging starting or stopping of the thre...
Definition: thread.c:304
cBitStream::SkipBits
void SkipBits(int n)
Definition: tools.h:360
min
T min(T a, T b)
Definition: tools.h:59
cVector::Append
virtual void Append(T Data)
Definition: tools.h:737
tArea::y1
int y1
Definition: osd.h:299
cSubtitleObject::cSubtitleObject
cSubtitleObject(int ObjectId)
Definition: dvbsubtitle.c:373
cBitStream::WordAlign
void WordAlign(void)
Definition: tools.c:1431
tArea::Width
int Width(void) const
Definition: osd.h:301
cSubtitleRegion::SetDimensions
void SetDimensions(int Width, int Height)
Definition: dvbsubtitle.c:917
cDvbSubtitleAssembler::cDvbSubtitleAssembler
cDvbSubtitleAssembler(void)
Definition: dvbsubtitle.c:1155
cSubtitleRegion::regionLevelOfCompatibility
int regionLevelOfCompatibility
Definition: dvbsubtitle.c:842
cSubtitleDebug::FirstPts
int64_t FirstPts(void)
Definition: dvbsubtitle.c:77
cSubtitleRegion::ClutId
int ClutId(void)
Definition: dvbsubtitle.c:861
cSubtitleClut::ParsePgs
void ParsePgs(cBitStream &bs)
Definition: dvbsubtitle.c:277
cDvbSubtitleBitmaps::areas
tArea * areas
Definition: dvbsubtitle.c:1221
PesGetPts
int64_t PesGetPts(const uchar *p)
Definition: remux.h:199
cDvbSubtitleConverter::displayWidth
int displayWidth
Definition: dvbsubtitle.h:30
cDvbSubtitleBitmaps::DbgDump
void DbgDump(int WindowWidth, int WindowHeight)
Definition: dvbsubtitle.c:1287
DebugCluts
static bool DebugCluts
Definition: dvbsubtitle.c:46
cPalette::Replace
void Replace(const cPalette &Palette)
Replaces the colors of this palette with the colors from the given palette.
Definition: osd.c:208
cSubtitleRegionRef::RegionHorizontalAddress
int RegionHorizontalAddress(void)
Definition: dvbsubtitle.c:952
PGS_DISPLAY_SEGMENT
#define PGS_DISPLAY_SEGMENT
Definition: dvbsubtitle.c:32
cOsd::Flush
virtual void Flush(void)
Actually commits all data to the OSD hardware.
Definition: osd.c:1993
cSubtitleObjectRef::ObjectType
int ObjectType(void)
Definition: dvbsubtitle.c:763
cSubtitleRegion::RegionVersionNumber
int RegionVersionNumber(void)
Definition: dvbsubtitle.c:855
cSubtitleRegion::Parse
void Parse(cBitStream &bs)
Definition: dvbsubtitle.c:880
PesPayloadOffset
int PesPayloadOffset(const uchar *p)
Definition: remux.h:184
cSubtitleClut::palette4
cPalette palette4
Definition: dvbsubtitle.c:148
cSetup::FontOsd
char FontOsd[MAXFONTNAME]
Definition: config.h:328
DISPARITY_SIGNALING_SEGMENT
#define DISPARITY_SIGNALING_SEGMENT
Definition: dvbsubtitle.c:24
cSubtitleRegion::region4bitPixelCode
int region4bitPixelCode
Definition: dvbsubtitle.c:846
cSubtitleObject::Decode8BppCodeString
bool Decode8BppCodeString(cBitmap *Bitmap, int px, int py, cBitStream *bs, int &x, int y)
Definition: dvbsubtitle.c:657
cDvbSubtitleAssembler::size
int size
Definition: dvbsubtitle.c:1145
cSubtitleClut::yuv2rgb
tColor yuv2rgb(int Y, int Cb, int Cr)
Definition: dvbsubtitle.c:302
esyslog
#define esyslog(a...)
Definition: tools.h:35
cDvbSubtitlePage::AddRegionRef
void AddRegionRef(cSubtitleRegionRef *rf)
Definition: dvbsubtitle.c:1002
cSubtitleRegion::RegionLevelOfCompatibility
int RegionLevelOfCompatibility(void)
Definition: dvbsubtitle.c:859
cDvbSubtitlePage::GetObjectById
cSubtitleObject * GetObjectById(int ObjectId, bool New=false)
Definition: dvbsubtitle.c:1133
LOG_ERROR_STR
#define LOG_ERROR_STR(s)
Definition: tools.h:40
PesHasPts
bool PesHasPts(const uchar *p)
Definition: remux.h:189
tArea::y2
int y2
Definition: osd.h:299
cDvbSubtitleAssembler::Realloc
bool Realloc(int Size)
Definition: dvbsubtitle.c:1173
cBitmap::ShrinkBpp
void ShrinkBpp(int NewBpp)
Shrinks the color depth of the bitmap to NewBpp by keeping only the 2^NewBpp most frequently used col...
Definition: osd.c:796
cSubtitleObject::Decode4BppCodeString
bool Decode4BppCodeString(cBitmap *Bitmap, int px, int py, cBitStream *bs, int &x, int y, const uint8_t *MapTable)
Definition: dvbsubtitle.c:612
cSetup::SubtitleFgTransparency
int SubtitleFgTransparency
Definition: config.h:289
cBitStream::Index
int Index(void) const
Definition: tools.h:365
cSubtitleObject::DecodeSubBlock
void DecodeSubBlock(cBitmap *Bitmap, int px, int py, const uchar *Data, int Length, bool Even)
Definition: dvbsubtitle.c:495
cSubtitleRegionRef::regionHorizontalAddress
int regionHorizontalAddress
Definition: dvbsubtitle.c:946
cDvbSubtitlePage::pageVersionNumber
int pageVersionNumber
Definition: dvbsubtitle.c:978
cSubtitleDebug::mutex
cMutex mutex
Definition: dvbsubtitle.c:68
cSubtitleObject::botLength
int botLength
Definition: dvbsubtitle.c:348
cSubtitleObject::topData
uchar * topData
Definition: dvbsubtitle.c:350