vdr  2.2.0
dvbspu.c
Go to the documentation of this file.
1 /*
2  * SPU decoder for DVB devices
3  *
4  * Copyright (C) 2001.2002 Andreas Schultz <aschultz@warp10.net>
5  *
6  * This code is distributed under the terms and conditions of the
7  * GNU GENERAL PUBLIC LICENSE. See the file COPYING for details.
8  *
9  * parts of this file are derived from the OMS program.
10  *
11  * $Id: dvbspu.c 3.0 2013/02/22 15:25:16 kls Exp $
12  */
13 
14 #include "dvbspu.h"
15 #include <assert.h>
16 #include <string.h>
17 #include <inttypes.h>
18 #include <math.h>
19 
20 /*
21  * cDvbSpubitmap:
22  *
23  * this is a bitmap of the full screen and two palettes
24  * the normal palette for the background and the highlight palette
25  *
26  * Inputs:
27  * - a SPU rle encoded image on creation, which will be decoded into
28  * the full screen indexed bitmap
29  *
30  * Output:
31  * - a minimal sized cDvbSpuBitmap a given palette, the indexed bitmap
32  * will be scanned to get the smallest possible resulting bitmap considering
33  * transparencies
34  */
35 
36 // #define SPUDEBUG
37 
38 #ifdef SPUDEBUG
39 #define DEBUG(format, args...) printf (format, ## args)
40 #else
41 #define DEBUG(format, args...)
42 #endif
43 
44 // --- cDvbSpuPalette---------------------------------------------------------
45 
46 void cDvbSpuPalette::setPalette(const uint32_t * pal)
47 {
48  for (int i = 0; i < 16; i++)
49  palette[i] = yuv2rgb(pal[i]);
50 }
51 
52 // --- cDvbSpuBitmap ---------------------------------------------------------
53 
54 #define setMin(a, b) if (a > b) a = b
55 #define setMax(a, b) if (a < b) a = b
56 
57 // DVD SPU bitmaps cover max. 720 x 576 - this sizes the SPU bitmap
58 #define spuXres 720
59 #define spuYres 576
60 
61 #define revRect(r1, r2) { r1.x1 = r2.x2; r1.y1 = r2.y2; r1.x2 = r2.x1; r1.y2 = r2.y1; }
62 
64  uint8_t * fodd, uint8_t * eodd,
65  uint8_t * feven, uint8_t * eeven)
66 {
67  size.x1 = max(size.x1, 0);
68  size.y1 = max(size.y1, 0);
69  size.x2 = min(size.x2, spuXres - 1);
70  size.y2 = min(size.y2, spuYres - 1);
71 
72  bmpsize = size;
73  revRect(minsize[0], size);
74  revRect(minsize[1], size);
75  revRect(minsize[2], size);
76  revRect(minsize[3], size);
77 
78  int MemSize = spuXres * spuYres * sizeof(uint8_t);
79  bmp = new uint8_t[MemSize];
80 
81  if (bmp)
82  memset(bmp, 0, MemSize);
83  putFieldData(0, fodd, eodd);
84  putFieldData(1, feven, eeven);
85 }
86 
88 {
89  delete[]bmp;
90 }
91 
93  const cDvbSpuPalette & pal,
94  sDvbSpuRect & size) const
95 {
96  int h = size.height();
97  int w = size.width();
98 
99  if (size.y1 + h >= spuYres)
100  h = spuYres - size.y1 - 1;
101  if (size.x1 + w >= spuXres)
102  w = spuXres - size.x1 - 1;
103 
104  if (w & 0x03)
105  w += 4 - (w & 0x03);
106 
107  cBitmap *ret = new cBitmap(w, h, 2);
108 
109  // set the palette
110  for (int i = 0; i < 4; i++) {
111  uint32_t color =
112  pal.getColor(paldescr[i].index, paldescr[i].trans);
113  ret->SetColor(i, (tColor) color);
114  }
115 
116  // set the content
117  if (bmp) {
118  for (int yp = 0; yp < h; yp++) {
119  for (int xp = 0; xp < w; xp++) {
120  uint8_t idx = bmp[(size.y1 + yp) * spuXres + size.x1 + xp];
121  ret->SetIndex(xp, yp, idx);
122  }
123  }
124  }
125  return ret;
126 }
127 
128 // find the minimum non-transparent area
130  sDvbSpuRect & size) const
131 {
132  bool ret = false;
133  for (int i = 0; i < 4; i++) {
134  if (paldescr[i].trans != 0) {
135  if (!ret)
136  size = minsize[i];
137  else {
138  setMin(size.x1, minsize[i].x1);
139  setMin(size.y1, minsize[i].y1);
140  setMax(size.x2, minsize[i].x2);
141  setMax(size.y2, minsize[i].y2);
142  }
143  ret = true;
144  }
145  }
146  if (ret)
147  DEBUG("MinSize: (%d, %d) x (%d, %d)\n",
148  size.x1, size.y1, size.x2, size.y2);
149  if (size.x1 > size.x2 || size.y1 > size.y2)
150  return false;
151 
152  return ret;
153 }
154 
155 void cDvbSpuBitmap::putPixel(int xp, int yp, int len, uint8_t colorid)
156 {
157  if (bmp)
158  memset(bmp + spuXres * yp + xp, colorid, len);
159  setMin(minsize[colorid].x1, xp);
160  setMin(minsize[colorid].y1, yp);
161  setMax(minsize[colorid].x2, xp + len - 1);
162  setMax(minsize[colorid].y2, yp);
163 }
164 
165 static uint8_t getBits(uint8_t * &data, uint8_t & bitf)
166 {
167  uint8_t ret = *data;
168  if (bitf)
169  ret >>= 4;
170  else
171  data++;
172  bitf ^= 1;
173 
174  return (ret & 0xf);
175 }
176 
177 void cDvbSpuBitmap::putFieldData(int field, uint8_t * data, uint8_t * endp)
178 {
179  int xp = bmpsize.x1;
180  int yp = bmpsize.y1 + field;
181  uint8_t bitf = 1;
182 
183  while (data < endp) {
184  uint16_t vlc = getBits(data, bitf);
185  if (vlc < 0x0004) {
186  vlc = (vlc << 4) | getBits(data, bitf);
187  if (vlc < 0x0010) {
188  vlc = (vlc << 4) | getBits(data, bitf);
189  if (vlc < 0x0040) {
190  vlc = (vlc << 4) | getBits(data, bitf);
191  }
192  }
193  }
194 
195  uint8_t color = vlc & 0x03;
196  int len = vlc >> 2;
197 
198  // if len == 0 -> end sequence - fill to end of line
199  len = len ? len : bmpsize.x2 - xp + 1;
200  putPixel(xp, yp, len, color);
201  xp += len;
202 
203  if (xp > bmpsize.x2) {
204  // nextLine
205  if (!bitf)
206  data++;
207  bitf = 1;
208  xp = bmpsize.x1;
209  yp += 2;
210  if (yp > bmpsize.y2)
211  return;
212  }
213  }
214 }
215 
216 // --- cDvbSpuDecoder---------------------------------------------------------
217 
218 #define CMD_SPU_MENU 0x00
219 #define CMD_SPU_SHOW 0x01
220 #define CMD_SPU_HIDE 0x02
221 #define CMD_SPU_SET_PALETTE 0x03
222 #define CMD_SPU_SET_ALPHA 0x04
223 #define CMD_SPU_SET_SIZE 0x05
224 #define CMD_SPU_SET_PXD_OFFSET 0x06
225 #define CMD_SPU_CHG_COLCON 0x07
226 #define CMD_SPU_EOF 0xff
227 
228 #define spuU32(i) ((spu[i] << 8) + spu[i+1])
229 
231 {
232  clean = true;
233  scaleMode = eSpuNormal;
234  spu = NULL;
235  osd = NULL;
236  spubmp = NULL;
237  allowedShow = false;
238 }
239 
241 {
242  delete spubmp;
243  delete spu;
244  delete osd;
245 }
246 
247 // SPUs must be scaled if screensize is not 720x576
248 
250 {
251  int Width = spuXres;
252  int Height = spuYres;
253  int OsdWidth = 0;
254  int OsdHeight = 0;
255  double VideoAspect;
256  cDevice::PrimaryDevice()->GetOsdSize(OsdWidth, OsdHeight, VideoAspect);
257  DEBUG("dvbspu SetSpuScaling OsdSize %d x %d\n", OsdWidth, OsdHeight);
258  if (!OsdWidth) { // guess correct size
259  if (Setup.OSDWidth <= 720 || Setup.OSDHeight <= 576)
260  xscaling = yscaling = 1.0;
261  else if (Setup.OSDWidth <= 1280 || Setup.OSDHeight <= 720) {
262  xscaling = 1280.0 / Width;
263  yscaling = 720.0 / Height;
264  }
265  else {
266  xscaling = 1920.0 / Width;
267  yscaling = 1080.0/ Height;
268  }
269  }
270  else {
271  xscaling = (double)OsdWidth / Width;
272  yscaling = (double)OsdHeight / Height;
273  }
274  DEBUG("dvbspu xscaling = %f yscaling = %f\n", xscaling, yscaling);
275 }
276 
277 void cDvbSpuDecoder::processSPU(uint32_t pts, uint8_t * buf, bool AllowedShow)
278 {
279  setTime(pts);
280 
281  DEBUG("SPU pushData: pts: %d\n", pts);
282 
283  delete spubmp;
284  spubmp = NULL;
285  delete[]spu;
286  spu = buf;
287  spupts = pts;
288 
289  DCSQ_offset = cmdOffs();
290  prev_DCSQ_offset = 0;
291 
292  clean = true;
293  allowedShow = AllowedShow;
294 }
295 
297 {
298  scaleMode = ScaleMode;
299 }
300 
301 void cDvbSpuDecoder::setPalette(uint32_t * pal)
302 {
303  palette.setPalette(pal);
304 }
305 
306 void cDvbSpuDecoder::setHighlight(uint16_t sx, uint16_t sy,
307  uint16_t ex, uint16_t ey,
308  uint32_t palette)
309 {
310  aDvbSpuPalDescr pld;
311  for (int i = 0; i < 4; i++) {
312  pld[i].index = 0xf & (palette >> (16 + 4 * i));
313  pld[i].trans = 0xf & (palette >> (4 * i));
314  }
315 
316  bool ne = hlpsize.x1 != sx || hlpsize.y1 != sy ||
317  hlpsize.x2 != ex || hlpsize.y2 != ey ||
318  pld[0] != hlpDescr[0] || pld[1] != hlpDescr[1] ||
319  pld[2] != hlpDescr[2] || pld[3] != hlpDescr[3];
320 
321  if (ne) {
322  DEBUG("setHighlight: %d,%d x %d,%d\n", sx, sy, ex, ey);
323  hlpsize.x1 = sx;
324  hlpsize.y1 = sy;
325  hlpsize.x2 = ex;
326  hlpsize.y2 = ey;
327  memcpy(hlpDescr, pld, sizeof(aDvbSpuPalDescr));
328  highlight = true;
329  clean = false;
330  Draw(); // we have to trigger Draw() here
331  }
332 }
333 
335 {
336  clean &= !highlight;
337  highlight = false;
338  hlpsize.x1 = -1;
339  hlpsize.y1 = -1;
340  hlpsize.x2 = -1;
341  hlpsize.y2 = -1;
342 }
343 
345 {
346  sDvbSpuRect size;
347  if (fgbmp && bgbmp) {
348  size.x1 = min(fgsize.x1, bgsize.x1);
349  size.y1 = min(fgsize.y1, bgsize.y1);
350  size.x2 = max(fgsize.x2, bgsize.x2);
351  size.y2 = max(fgsize.y2, bgsize.y2);
352  }
353  else if (fgbmp) {
354  size.x1 = fgsize.x1;
355  size.y1 = fgsize.y1;
356  size.x2 = fgsize.x2;
357  size.y2 = fgsize.y2;
358  }
359  else if (bgbmp) {
360  size.x1 = bgsize.x1;
361  size.y1 = bgsize.y1;
362  size.x2 = bgsize.x2;
363  size.y2 = bgsize.y2;
364  }
365  else {
366  size.x1 = 0;
367  size.y1 = 0;
368  size.x2 = 0;
369  size.y2 = 0;
370  }
371  return size;
372 }
373 
375 {
376  int col = 1;
377  for (int i = 0; i < 4; i++) {
378  if (paldescr[i].trans != 0) {
379  col++;
380  }
381  }
382  return col > 2 ? 2 : 1;
383 }
384 
386 {
387  int fgbpp = 0;
388  int bgbpp = 0;
389  int ret;
390  if (fgbmp) {
391  fgbpp = spubmp->getMinBpp(hlpDescr);
392  }
393  if (bgbmp) {
394  bgbpp = spubmp->getMinBpp(palDescr);
395  }
396  ret = fgbpp + bgbpp;
397  if (ret > 2)
398  ret = 4;
399  return ret;
400 }
401 
403 {
404  cMutexLock MutexLock(&mutex);
405  if (!spubmp) {
406  Hide();
407  return;
408  }
409  sDvbSpuRect bgsize;
410  sDvbSpuRect drawsize;
411  sDvbSpuRect bgdrawsize;
412  cBitmap *fg = NULL;
413  cBitmap *bg = NULL;
414  cBitmap *tmp = NULL;
415 
416  SetSpuScaling(); // always set current scaling, size could have changed
417 
418  if (highlight) {
419  tmp = spubmp->getBitmap(hlpDescr, palette, hlpsize);
420  fg = tmp->Scaled(xscaling, yscaling, true);
421  drawsize.x1 = hlpsize.x1 * xscaling;
422  drawsize.y1 = hlpsize.y1 * yscaling;
423  drawsize.x2 = drawsize.x1 + fg->Width();
424  drawsize.y2 = drawsize.y1 + fg->Height();
425  }
426 
427  if (spubmp->getMinSize(palDescr, bgsize)) {
428  tmp = spubmp->getBitmap(palDescr, palette, bgsize);
429  bg = tmp->Scaled(xscaling, yscaling, true);
430  bgdrawsize.x1 = bgsize.x1 * xscaling;
431  bgdrawsize.y1 = bgsize.y1 * yscaling;
432  bgdrawsize.x2 = bgdrawsize.x1 + bg->Width();
433  bgdrawsize.y2 = bgdrawsize.y1 + bg->Height();
434  }
435 
436  if (osd) // always rewrite OSD
437  Hide();
438 
439  if (osd == NULL) {
440  restricted_osd = false;
441  osd = cOsdProvider::NewOsd(0, 0);
442 
443  sDvbSpuRect areaSize = CalcAreaSize(drawsize, fg, bgdrawsize, bg); // combine
444  tArea Area = { areaSize.x1, areaSize.y1, areaSize.x2, areaSize.y2, 4 };
445  if (osd->CanHandleAreas(&Area, 1) != oeOk) {
446  DEBUG("dvbspu CanHandleAreas (%d,%d)x(%d,%d), 4 failed\n", areaSize.x1, areaSize.y1, areaSize.x2, areaSize.y2);
447  restricted_osd = true;
448  }
449  else
450  osd->SetAreas(&Area, 1);
451  }
452  if (restricted_osd) {
453  sDvbSpuRect hlsize;
454  bool setarea = false;
455  /* reduce fg area */
456  if (fg) {
457  spubmp->getMinSize(hlpDescr,hlsize);
458  /* clip to the highligh area */
459  setMax(hlsize.x1, hlpsize.x1);
460  setMax(hlsize.y1, hlpsize.y1);
461  setMin(hlsize.x2, hlpsize.x2);
462  setMin(hlsize.y2, hlpsize.y2);
463  if (hlsize.x1 > hlsize.x2 || hlsize.y1 > hlsize.y2)
464  hlsize.x1 = hlsize.x2 = hlsize.y1 = hlsize.y2 = 0;
465  /* resize scaled fg */
466  drawsize.x1=hlsize.x1 * xscaling;
467  drawsize.y1=hlsize.y1 * yscaling;
468  drawsize.x2=hlsize.x2 * xscaling;
469  drawsize.y2=hlsize.y2 * yscaling;
470  }
471  sDvbSpuRect areaSize = CalcAreaSize(drawsize, fg, bgdrawsize, bg);
472 
473 #define DIV(a, b) (a/b)?:1
474  for (int d = 1; !setarea && d <= 2; d++) {
475 
476  /* first try old behaviour */
477  tArea Area = { areaSize.x1, areaSize.y1, areaSize.x2, areaSize.y2, DIV(CalcAreaBpp(fg, bg), d) };
478 
479  if ((Area.Width() & 7) != 0)
480  Area.x2 += 8 - (Area.Width() & 7);
481 
482  if (osd->CanHandleAreas(&Area, 1) == oeOk &&
483  osd->SetAreas(&Area, 1) == oeOk)
484  setarea = true;
485 
486  /* second try to split area if there is both area */
487  if (!setarea && fg && bg) {
488  tArea Area_Both [2] = {
489  { bgdrawsize.x1, bgdrawsize.y1, bgdrawsize.x2, bgdrawsize.y2, DIV(CalcAreaBpp(0, bg), d) },
490  { drawsize.x1, drawsize.y1, drawsize.x2, drawsize.y2, DIV(CalcAreaBpp(fg, 0), d) }
491  };
492  if (!Area_Both[0].Intersects(Area_Both[1])) {
493  /* there is no intersection. We can try with split areas */
494  if ((Area_Both[0].Width() & 7) != 0)
495  Area_Both[0].x2 += 8 - (Area_Both[0].Width() & 7);
496  if ((Area_Both[1].Width() & 7) != 0)
497  Area_Both[1].x2 += 8 - (Area_Both[1].Width() & 7);
498  if (osd->CanHandleAreas(Area_Both, 2) == oeOk &&
499  osd->SetAreas(Area_Both, 2) == oeOk)
500  setarea = true;
501  }
502  }
503  }
504  if (setarea)
505  DEBUG("dvbspu: reduced AreaSize (%d, %d) (%d, %d) Bpp %d\n", areaSize.x1, areaSize.y1, areaSize.x2, areaSize.y2, (fg && bg) ? 4 : 2);
506  else
507  dsyslog("dvbspu: reduced AreaSize (%d, %d) (%d, %d) Bpp %d failed", areaSize.x1, areaSize.y1, areaSize.x2, areaSize.y2, (fg && bg) ? 4 : 2);
508  }
509 
510  /* we could draw use DrawPixel on osd */
511  if (bg || fg) {
512  if (bg)
513  osd->DrawBitmap(bgdrawsize.x1, bgdrawsize.y1, *bg);
514  if (fg)
515  osd->DrawBitmap(drawsize.x1, drawsize.y1, *fg);
516  delete fg;
517  delete bg;
518  delete tmp;
519 
520  osd->Flush();
521  }
522 
523  clean = true;
524 }
525 
527 {
528  cMutexLock MutexLock(&mutex);
529  delete osd;
530  osd = NULL;
531 }
532 
534 {
535  Hide();
536 
537  delete spubmp;
538  spubmp = NULL;
539 
540  delete[]spu;
541  spu = NULL;
542 
543  clearHighlight();
544  clean = true;
545 }
546 
547 int cDvbSpuDecoder::setTime(uint32_t pts)
548 {
549  if (!spu)
550  return 0;
551 
552  if (!clean)
553  Draw();
554 
555  while (DCSQ_offset != prev_DCSQ_offset) { /* Display Control Sequences */
556  int i = DCSQ_offset;
557  state = spNONE;
558 
559  uint32_t exec_time = spupts + spuU32(i) * 1024;
560  if ((pts != 0) && (exec_time > pts))
561  return 0;
562  DEBUG("offs = %d, rel = %d, time = %d, pts = %d, diff = %d\n",
563  i, spuU32(i) * 1024, exec_time, pts, exec_time - pts);
564 
565  if (pts != 0) {
566  uint16_t feven = 0;
567  uint16_t fodd = 0;
568 
569  i += 2;
570 
571  prev_DCSQ_offset = DCSQ_offset;
572  DCSQ_offset = spuU32(i);
573  DEBUG("offs = %d, DCSQ = %d, prev_DCSQ = %d\n",
574  i, DCSQ_offset, prev_DCSQ_offset);
575  i += 2;
576 
577  while (spu[i] != CMD_SPU_EOF) { // Command Sequence
578  switch (spu[i]) {
579  case CMD_SPU_SHOW: // show subpicture
580  DEBUG("\tshow subpicture\n");
581  state = spSHOW;
582  i++;
583  break;
584 
585  case CMD_SPU_HIDE: // hide subpicture
586  DEBUG("\thide subpicture\n");
587  state = spHIDE;
588  i++;
589  break;
590 
591  case CMD_SPU_SET_PALETTE: // CLUT
592  palDescr[0].index = spu[i + 2] & 0xf;
593  palDescr[1].index = spu[i + 2] >> 4;
594  palDescr[2].index = spu[i + 1] & 0xf;
595  palDescr[3].index = spu[i + 1] >> 4;
596  i += 3;
597  break;
598 
599  case CMD_SPU_SET_ALPHA: // transparency palette
600  palDescr[0].trans = spu[i + 2] & 0xf;
601  palDescr[1].trans = spu[i + 2] >> 4;
602  palDescr[2].trans = spu[i + 1] & 0xf;
603  palDescr[3].trans = spu[i + 1] >> 4;
604  i += 3;
605  break;
606 
607  case CMD_SPU_SET_SIZE: // image coordinates
608  size.x1 = (spu[i + 1] << 4) | (spu[i + 2] >> 4);
609  size.x2 = ((spu[i + 2] & 0x0f) << 8) | spu[i + 3];
610 
611  size.y1 = (spu[i + 4] << 4) | (spu[i + 5] >> 4);
612  size.y2 = ((spu[i + 5] & 0x0f) << 8) | spu[i + 6];
613 
614  DEBUG("\t(%d, %d) x (%d, %d)\n",
615  size.x1, size.y1, size.x2, size.y2);
616  i += 7;
617  break;
618 
619  case CMD_SPU_SET_PXD_OFFSET: // image 1 / image 2 offsets
620  fodd = spuU32(i + 1);
621  feven = spuU32(i + 3);
622  DEBUG("\todd = %d even = %d\n", fodd, feven);
623  i += 5;
624  break;
625 
626  case CMD_SPU_CHG_COLCON: {
627  int size = spuU32(i + 1);
628  i += 1 + size;
629  }
630  break;
631 
632  case CMD_SPU_MENU:
633  DEBUG("\tspu menu\n");
634  state = spMENU;
635 
636  i++;
637  break;
638 
639  default:
640  esyslog("invalid sequence in control header (%.2x)",
641  spu[i]);
642  Empty();
643  return 0;
644  }
645  }
646  if (fodd != 0 && feven != 0) {
647  Hide();
648  delete spubmp;
649  spubmp = new cDvbSpuBitmap(size, spu + fodd, spu + feven,
650  spu + feven, spu + cmdOffs());
651  }
652  } else if (!clean)
653  state = spSHOW;
654 
655  if ((state == spSHOW && allowedShow) || state == spMENU)
656  Draw();
657 
658  if (state == spHIDE)
659  Hide();
660 
661  if (pts == 0)
662  return 0;
663  }
664 
665  return 1;
666 }
uint32_t yuv2rgb(uint32_t yuv_color)
Definition: dvbspu.h:162
#define setMin(a, b)
Definition: dvbspu.c:54
#define dsyslog(a...)
Definition: tools.h:36
#define CMD_SPU_HIDE
Definition: dvbspu.c:220
sDvbSpuRect CalcAreaSize(sDvbSpuRect fgsize, cBitmap *fgbmp, sDvbSpuRect bgsize, cBitmap *bgbmp)
Definition: dvbspu.c:344
#define spuU32(i)
Definition: dvbspu.c:228
uint8_t index
Definition: dvbspu.h:24
void Empty(void)
Definition: dvbspu.c:533
#define DIV(a, b)
uint32_t palette[16]
Definition: dvbspu.h:57
cDvbSpuDecoder()
Definition: dvbspu.c:230
void Hide(void)
Definition: dvbspu.c:526
#define esyslog(a...)
Definition: tools.h:34
#define CMD_SPU_MENU
Definition: dvbspu.c:218
#define CMD_SPU_CHG_COLCON
Definition: dvbspu.c:225
T max(T a, T b)
Definition: tools.h:55
#define DEBUG(format, args...)
Definition: dvbspu.c:41
virtual void GetOsdSize(int &Width, int &Height, double &PixelAspect)
Returns the Width, Height and PixelAspect ratio the OSD should use to best fit the resolution of the ...
Definition: device.c:442
#define CMD_SPU_SHOW
Definition: dvbspu.c:219
int getMinBpp(const aDvbSpuPalDescr paldescr)
Definition: dvbspu.c:374
T min(T a, T b)
Definition: tools.h:54
~cDvbSpuDecoder()
Definition: dvbspu.c:240
Definition: osd.h:169
int Width(void) const
Definition: osd.h:188
int x1
Definition: dvbspu.h:33
void setHighlight(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint32_t palette)
Definition: dvbspu.c:306
#define CMD_SPU_SET_PXD_OFFSET
Definition: dvbspu.c:224
#define setMax(a, b)
Definition: dvbspu.c:55
int Width(void) const
Definition: osd.h:301
#define revRect(r1, r2)
Definition: dvbspu.c:61
void SetSpuScaling(void)
Definition: dvbspu.c:249
int y1
Definition: dvbspu.h:33
int Height(void) const
Definition: osd.h:189
int CalcAreaBpp(cBitmap *fgbmp, cBitmap *bgbmp)
Definition: dvbspu.c:385
~cDvbSpuBitmap()
Definition: dvbspu.c:87
void setPalette(const uint32_t *pal)
Definition: dvbspu.c:46
struct sDvbSpuPalDescr aDvbSpuPalDescr[4]
int x2
Definition: osd.h:299
#define CMD_SPU_SET_ALPHA
Definition: dvbspu.c:222
void putFieldData(int field, uint8_t *data, uint8_t *endp)
Definition: dvbspu.c:177
int y2
Definition: dvbspu.h:34
cSetup Setup
Definition: config.c:373
void clearHighlight(void)
Definition: dvbspu.c:334
bool getMinSize(const aDvbSpuPalDescr paldescr, sDvbSpuRect &size) const
Definition: dvbspu.c:129
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
int width() const
Definition: dvbspu.h:39
void SetColor(int Index, tColor Color)
Sets the palette entry at Index to Color.
Definition: osd.c:172
#define CMD_SPU_SET_PALETTE
Definition: dvbspu.c:221
cDvbSpuBitmap(sDvbSpuRect size, uint8_t *fodd, uint8_t *eodd, uint8_t *feven, uint8_t *eeven)
Definition: dvbspu.c:63
void processSPU(uint32_t pts, uint8_t *buf, bool AllowedShow)
Definition: dvbspu.c:277
Definition: osd.h:298
static uint8_t getBits(uint8_t *&data, uint8_t &bitf)
Definition: dvbspu.c:165
static cDevice * PrimaryDevice(void)
Returns the primary device.
Definition: device.h:137
void setScaleMode(cSpuDecoder::eScaleMode ScaleMode)
Definition: dvbspu.c:296
int height() const
Definition: dvbspu.h:42
uint32_t getColor(uint8_t idx, uint8_t trans) const
Definition: dvbspu.h:203
#define CMD_SPU_SET_SIZE
Definition: dvbspu.c:223
Definition: osd.h:44
void Draw(void)
Definition: dvbspu.c:402
#define CMD_SPU_EOF
Definition: dvbspu.c:226
int OSDHeight
Definition: config.h:319
#define spuYres
Definition: dvbspu.c:59
int OSDWidth
Definition: config.h:319
#define spuXres
Definition: dvbspu.c:58
void putPixel(int xp, int yp, int len, uint8_t colorid)
Definition: dvbspu.c:155
void setPalette(uint32_t *pal)
Definition: dvbspu.c:301
void SetIndex(int x, int y, tIndex Index)
Sets the index at the given coordinates to Index.
Definition: osd.c:500
int setTime(uint32_t pts)
Definition: dvbspu.c:547
int x2
Definition: dvbspu.h:34
cBitmap * getBitmap(const aDvbSpuPalDescr paldescr, const cDvbSpuPalette &pal, sDvbSpuRect &size) const
Definition: dvbspu.c:92
eScaleMode
Definition: spu.h:21
uint32_t tColor
Definition: font.h:29
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:2006