047e76d43ee8cd7ec27f93208433a2846c2cd600
[vuplus_dvbapp] / lib / dvb / subtitle.cpp
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <fcntl.h>
4 #include <memory.h>
5 #include <time.h>
6
7 #include <asm/types.h>
8 #include <lib/dvb/idemux.h>
9 #include <lib/dvb/subtitle.h>
10 #include <lib/base/smartptr.h>
11 #include <lib/base/eerror.h>
12 #include <lib/gdi/gpixmap.h>
13
14 void bitstream_init(bitstream *bit, const void *buffer, int size)
15 {
16         bit->data = (__u8*) buffer;
17         bit->size = size;
18         bit->avail = 8;
19         bit->consumed = 0;
20 }
21
22 int bitstream_get(bitstream *bit)
23 {
24         int val;
25         bit->avail -= bit->size;
26         val = ((*bit->data) >> bit->avail) & ((1<<bit->size) - 1);
27         if (!bit->avail)
28         {
29                 bit->data++;
30                 bit->consumed++;
31                 bit->avail = 8;
32         }
33         return val;
34 }
35
36 static int extract_pts(pts_t &pts, __u8 *pkt)
37 {
38         pkt += 7;
39         int flags = *pkt++;
40
41         pkt++; // header length
42
43         if (flags & 0x80) /* PTS present? */
44         {
45                         /* damn gcc bug */
46                 pts  = ((unsigned long long)(((pkt[0] >> 1) & 7))) << 30;
47                 pts |=   pkt[1] << 22;
48                 pts |=  (pkt[2]>>1) << 15;
49                 pts |=   pkt[3] << 7;
50                 pts |=  (pkt[5]>>1);
51
52                 return 0;
53         } else
54                 return -1;
55 }
56
57 void eDVBSubtitleParser::subtitle_process_line(subtitle_region *region, subtitle_region_object *object, int line, __u8 *data, int len)
58 {
59         int x = object->object_horizontal_position;
60         int y = object->object_vertical_position + line;
61         if (x + len > region->width)
62         {
63 //              eDebug("[SUB] !!!! XCLIP %d + %d > %d", x, len, region->width);
64                 len = region->width - x;
65         }
66         if (len < 0)
67                 return;
68         if (y >= region->height)
69         {
70 //              eDebug("[SUB] !!!! YCLIP %d >= %d", y, region->height);
71                 return;
72         }
73 //      eDebug("inserting %d bytes (into region %d)", len, region->region_id);
74 //      eDebug("put data to buffer %p", &(*region->buffer));
75         memcpy((__u8*)region->buffer->surface->data + region->buffer->surface->stride * y + x, data, len);
76 }
77
78 static int map_2_to_4_bit_table[4];
79 static int map_2_to_8_bit_table[4];
80 static int map_4_to_8_bit_table[16];
81
82 int eDVBSubtitleParser::subtitle_process_pixel_data(subtitle_region *region, subtitle_region_object *object, int *linenr, int *linep, __u8 *data)
83 {
84         int data_type = *data++;
85         static __u8 line[720];
86
87         bitstream bit;
88         bit.size=0;
89         switch (data_type)
90         {
91         case 0x10: // 2bit pixel data
92 //              eDebug("2bit pixel data!");
93                 bitstream_init(&bit, data, 2);
94                 while (1)
95                 {
96                         int len=0, col=0;
97                         int code = bitstream_get(&bit);
98                         if (code)
99                         {
100                                 col = code;
101                                 len = 1;
102                         } else
103                         {
104                                 code = bitstream_get(&bit);
105                                 if (!code)
106                                 {
107                                         code = bitstream_get(&bit);
108                                         if (code == 1)
109                                         {
110                                                 col = 0;
111                                                 len = 2;
112                                         } else if (code == 2)
113                                         {
114                                                 len = bitstream_get(&bit) << 2;
115                                                 len |= bitstream_get(&bit);
116                                                 len += 12;
117                                                 col = bitstream_get(&bit);
118                                         } else if (code == 3)
119                                         {
120                                                 len = bitstream_get(&bit) << 6;
121                                                 len |= bitstream_get(&bit) << 4;
122                                                 len |= bitstream_get(&bit) << 2;
123                                                 len |= bitstream_get(&bit);
124                                                 len += 29;
125                                                 col = bitstream_get(&bit);
126                                         } else
127                                                 break;
128                                 } else if (code==1)
129                                 {
130                                         col = 0;
131                                         len = 1;
132                                 } else if (code&2)
133                                 {
134                                         if (code&1)
135                                                 len = 3 + 4 + bitstream_get(&bit);
136                                         else
137                                                 len = 3 + bitstream_get(&bit);
138                                         col = bitstream_get(&bit);
139                                 }
140                         }
141                         uint8_t c = region->depth == subtitle_region::bpp4 ?
142                                 map_2_to_4_bit_table[col] :
143                                 region->depth == subtitle_region::bpp8 ?
144                                 map_2_to_8_bit_table[col] : col;
145                         while (len && ((*linep) < 720))
146                         {
147                                 line[(*linep)++] = c;
148                                 len--;
149                         }
150                 }
151                 while (bit.avail != 8)
152                         bitstream_get(&bit);
153                 return bit.consumed + 1;
154         case 0x11: // 4bit pixel data
155 //              eDebug("4bit pixel data!");
156                 bitstream_init(&bit, data, 4);
157                 while (1)
158                 {
159                         int len=0, col=0;
160                         int code = bitstream_get(&bit);
161                         if (code)
162                         {
163                                 col = code;
164                                 len = 1;
165                         } else
166                         {
167                                 code = bitstream_get(&bit);
168                                 if (!code)
169                                         break;
170                                 else if (code == 0xC)
171                                 {
172                                         col = 0;
173                                         len = 1;
174                                 } else if (code == 0xD)
175                                 {
176                                         col = 0;
177                                         len = 2;
178                                 } else if (code < 8)
179                                 {
180                                         col = 0;
181                                         len = (code & 7) + 2;
182                                 } else if ((code & 0xC) == 0x8)
183                                 {
184                                         col = bitstream_get(&bit);
185                                         len = (code & 3) + 4;
186                                 } else if (code == 0xE)
187                                 {
188                                         len = bitstream_get(&bit) + 9;
189                                         col = bitstream_get(&bit);
190                                 } else if (code == 0xF)
191                                 {
192                                         len  = bitstream_get(&bit) << 4;
193                                         len |= bitstream_get(&bit);
194                                         len += 25;
195                                         col  = bitstream_get(&bit);
196                                 }
197                         }
198                         uint8_t c = region->depth == subtitle_region::bpp8 ?
199                                 map_4_to_8_bit_table[col] : col;
200                         while (len && ((*linep) < 720))
201                         {
202                                 line[(*linep)++] = c;
203                                 len--;
204                         }
205                 }
206                 while (bit.avail != 8)
207                         bitstream_get(&bit);
208                 return bit.consumed + 1;
209         case 0x12: // 8bit pixel data
210 //              eDebug("8bit pixel data!");
211                 bitstream_init(&bit, data, 8);
212                 while(1)
213                 {
214                         int len=0, col=0;
215                         int code = bitstream_get(&bit);
216                         if (code)
217                         {
218                                 col = code;
219                                 len = 1;
220                         } else
221                         {
222                                 code = bitstream_get(&bit);
223                                 if ((code & 0x80) == 0x80)
224                                 {
225                                         len = code&0x7F;
226                                         col = bitstream_get(&bit);
227                                 } else if (code&0x7F)
228                                 {
229                                         len = code&0x7F;
230                                         col = 0;
231                                 } else
232                                         break;
233                         }
234                         while (len && ((*linep) < 720))
235                         {
236                                 line[(*linep)++] = col;
237                                 len--;
238                         }
239                 }
240                 return bit.consumed + 1;
241         case 0x20:
242 //              eDebugNoNewLine("2 -> 4 bit table: ");
243                 bitstream_init(&bit, data, 4);
244                 for ( int i=0; i < 4; ++i )
245                 {
246                         map_2_to_4_bit_table[i] = bitstream_get(&bit);
247 //                      eDebugNoNewLine("%d ", map_2_to_4_bit_table[i]);
248                 }
249                 eDebug("");
250                 return bit.consumed + 1;
251         case 0x21:
252 //              eDebugNoNewLine("2 -> 8 bit table: ");
253                 bitstream_init(&bit, data, 8);
254                 for ( int i=0; i < 4; ++i )
255                 {
256                         map_2_to_8_bit_table[i] = bitstream_get(&bit);
257 //                      eDebugNoNewLine("%d ", map_2_to_8_bit_table[i]);
258                 }
259                 return bit.consumed + 1;
260         case 0x22:
261 //              eDebug("4 -> 8 bit table!");
262                 bitstream_init(&bit, data, 8);
263                 for ( int i=0; i < 16; ++i )
264                 {
265                         map_4_to_8_bit_table[i] = bitstream_get(&bit);
266 //                      eDebugNoNewLine("%d ", map_4_to_8_bit_table[i]);
267                 }
268                 return bit.consumed + 1;
269         case 0xF0:
270                 subtitle_process_line(region, object, *linenr, line, *linep);
271 /*              {
272                         int i;
273                         for (i=0; i<720; ++i)
274                                 eDebugNoNewLine("%d ", line[i]);
275                         eDebug("");
276                 } */
277                 (*linenr)+=2; // interlaced
278                 *linep = 0;
279 //              eDebug("[SUB] EOL");
280                 return 1;
281         default:
282                 eDebug("subtitle_process_pixel_data: invalid data_type %02x", data_type);
283                 return -1;
284         }
285         return 0;
286 }
287
288 int eDVBSubtitleParser::subtitle_process_segment(__u8 *segment)
289 {
290         int segment_type, page_id, segment_length, processed_length;
291         if (*segment++ !=  0x0F)
292         {
293                 eDebug("out of sync.");
294                 return -1;
295         }
296         segment_type = *segment++;
297         page_id  = *segment++ << 8;
298         page_id |= *segment++;
299         segment_length  = *segment++ << 8;
300         segment_length |= *segment++;
301         if (segment_type == 0xFF)
302                 return segment_length + 6;
303         if (page_id != m_composition_page_id && page_id != m_ancillary_page_id)
304                 return segment_length + 6;
305 //      eDebug("have %d bytes of segment data", segment_length);
306
307 //      eDebug("page_id %d, segtype %02x", page_id, segment_type);
308
309         subtitle_page *page, **ppage;
310
311         page = m_pages; ppage = &m_pages;
312
313         while (page)
314         {
315                 if (page->page_id == page_id)
316                         break;
317                 ppage = &page->next;
318                 page = page->next;
319         }
320
321         processed_length = 0;
322
323         switch (segment_type)
324         {
325         case 0x10: // page composition segment
326         {
327                 int page_time_out = *segment++; processed_length++;
328                 int page_version_number = *segment >> 4;
329                 int page_state = (*segment >> 2) & 0x3;
330 //              eDebug("pcs with %d bytes data (%d:%d:%d)", segment_length, page_id, page_version_number, page_state);
331                 segment++;
332                 processed_length++;
333
334 //              eDebug("page time out: %d", page_time_out);
335 //              eDebug("page_version_number: %d" ,page_version_number);
336 //              eDebug("page_state: %d", page_state);
337
338                 if (!page)
339                 {
340 //                      eDebug("page not found");
341                         page = new subtitle_page;
342                         page->page_regions = 0;
343                         page->regions = 0;
344                         page->page_id = page_id;
345                         page->cluts = 0;
346                         page->next = 0;
347                         *ppage = page;
348                 } else
349                 {
350                         if (page->pcs_size != segment_length)
351                                 page->page_version_number = -1;
352                                 // if no update, just skip this data.
353                         if (page->page_version_number == page_version_number)
354                         {
355 //                              eDebug("skip data... ");
356                                 break;
357                         }
358                 }
359
360                 page->state = page_state;
361
362 //              eDebug("page updated: old: %d, new: %d", page->page_version_number, page_version_number);
363                         // when acquisition point or mode change: remove all displayed pages.
364                 if ((page_state == 1) || (page_state == 2))
365                 {
366                         while (page->page_regions)
367                         {
368                                 subtitle_page_region *p = page->page_regions->next;
369 //                              eDebug("delete page_region %d", page->page_regions->region_id);
370                                 delete page->page_regions;
371                                 page->page_regions = p;
372                         }
373                         while (page->regions)
374                         {
375                                 subtitle_region *p = page->regions->next;
376 //                              eDebug("delete region %d", page->regions->region_id);
377                                 while(page->regions->objects)
378                                 {
379 //                                      eDebug("delete region object");
380                                         subtitle_region_object *ob = page->regions->objects->next;
381                                         delete page->regions->objects;
382                                         page->regions->objects = ob;
383                                 }
384                                 delete page->regions;
385                                 page->regions = p;
386                         }
387
388                 }
389
390 //              eDebug("new page.. (%d)", page_state);
391
392                 page->page_time_out = page_time_out;
393
394                 page->page_version_number = page_version_number;
395
396                 subtitle_page_region **r = &page->page_regions;
397
398 //              eDebug("%d  / %d data left", processed_length, segment_length);
399
400                         // go to last entry
401                 while (*r)
402                         r = &(*r)->next;
403
404                 if (processed_length == segment_length && !page->page_regions)
405                 {
406 //                      eDebug("no regions in page.. clear screen!!");
407                         subtitle_redraw(page->page_id);
408                 }
409
410                 while (processed_length < segment_length)
411                 {
412                         subtitle_page_region *pr;
413
414                                 // append new entry to list
415                         pr = new subtitle_page_region;
416                         pr->next = 0;
417                         *r = pr;
418                         r = &pr->next;
419
420                         pr->region_id = *segment++; processed_length++;
421                         segment++; processed_length++;
422
423                         pr->region_horizontal_address  = *segment++ << 8;
424                         pr->region_horizontal_address |= *segment++;
425                         processed_length += 2;
426
427                         pr->region_vertical_address  = *segment++ << 8;
428                         pr->region_vertical_address |= *segment++;
429                         processed_length += 2;
430
431 //                      eDebug("appended active region");
432                 }
433
434                 if (processed_length != segment_length)
435                         eDebug("%d != %d", processed_length, segment_length);
436                 break;
437         }
438         case 0x11: // region composition segment
439         {
440                 int region_id = *segment++; processed_length++;
441                 int version_number = *segment >> 4;
442                 int region_fill_flag = (*segment >> 3) & 1;
443                 segment++; processed_length++;
444
445                         // if we didn't yet received the pcs for this page, drop the region
446                 if (!page)
447                 {
448                         eDebug("ignoring region %x, since page %02x doesn't yet exist.", region_id, page_id);
449                         break;
450                 }
451
452                 subtitle_region *region, **pregion;
453
454                 region = page->regions; pregion = &page->regions;
455
456                 while (region)
457                 {
458                         fflush(stdout);
459                         if (region->region_id == region_id)
460                                 break;
461                         pregion = &region->next;
462                         region = region->next;
463                 }
464
465                 if (!region)
466                 {
467 //                      eDebug("create region !!!!!!!!!!");
468                         *pregion = region = new subtitle_region;
469                         region->next = 0;
470                         region->committed = false;
471                 }
472                 else if (region->version_number != version_number)
473                 {
474                         subtitle_region_object *objects = region->objects;
475 //                      eDebug("unequal version %p %p", objects, objects?objects->next:objects);
476                         while (objects)
477                         {
478                                 subtitle_region_object *n = objects->next;
479                                 delete objects;
480                                 objects = n;
481                         }
482                         if (region->buffer)
483                         {
484 //                              eDebug("no more need of buffer %p", &(*region->buffer));
485                                 region->buffer=0;
486                         }
487                         region->committed = false;
488                 }
489                 else
490                         break;
491
492 //              eDebug("region %d:%d update", page_id, region_id);
493
494                 region->region_id = region_id;
495                 region->version_number = version_number;
496
497                 region->width  = *segment++ << 8;
498                 region->width |= *segment++;
499                 processed_length += 2;
500
501                 region->height  = *segment++ << 8;
502                 region->height |= *segment++;
503                 processed_length += 2;
504
505                 region->buffer = new gPixmap(eSize(region->width, region->height), 8, 1);
506                 memset(region->buffer->surface->data, 0, region->height * region->buffer->surface->stride);
507 //              eDebug("new buffer %p", &(*region->buffer));
508
509                 int region_level_of_compatibility, depth;
510
511                 region_level_of_compatibility = (*segment >> 5) & 7;
512                 depth = (*segment++ >> 2) & 7;
513
514                 region->depth = (subtitle_region::tDepth) depth;
515                 processed_length++;
516
517                 int CLUT_id = *segment++; processed_length++;
518
519                 region->clut_id = CLUT_id;
520
521                 int region_8bit_pixel_code, region_4bit_pixel_code, region_2bit_pixel_code;
522                 region_8bit_pixel_code = *segment++; processed_length++;
523                 region_4bit_pixel_code = *segment >> 4;
524                 region_2bit_pixel_code = (*segment++ >> 2) & 3;
525                 processed_length++;
526
527                 if (!region_fill_flag)
528                 {
529                         region_2bit_pixel_code = region_4bit_pixel_code = region_8bit_pixel_code = 0;
530                         region_fill_flag = 1;
531                 }
532
533                 if (region_fill_flag)
534                 {
535 //                      eDebug("region fill buffer %p", &(*region->buffer));
536                         if (depth == 1)
537                                 memset(region->buffer->surface->data, region_2bit_pixel_code, region->height * region->width);
538                         else if (depth == 2)
539                                 memset(region->buffer->surface->data, region_4bit_pixel_code, region->height * region->width);
540                         else if (depth == 3)
541                                 memset(region->buffer->surface->data, region_8bit_pixel_code, region->height * region->width);
542                         else
543                                 eDebug("!!!! invalid depth");
544                 }
545
546 //              eDebug("region %02x, version %d, %dx%d", region->region_id, region->version_number, region->width, region->height);
547
548                 region->objects = 0;
549                 subtitle_region_object **pobject = &region->objects;
550
551                 while (processed_length < segment_length)
552                 {
553                         subtitle_region_object *object;
554
555                         object = new subtitle_region_object;
556
557                         *pobject = object;
558                         object->next = 0;
559                         pobject = &object->next;
560
561                         object->object_id  = *segment++ << 8;
562                         object->object_id |= *segment++; processed_length += 2;
563
564                         object->object_type = *segment >> 6;
565                         object->object_provider_flag = (*segment >> 4) & 3;
566                         object->object_horizontal_position  = (*segment++ & 0xF) << 8;
567                         object->object_horizontal_position |= *segment++;
568                         processed_length += 2;
569
570                         object->object_vertical_position  = *segment++ << 8;
571                         object->object_vertical_position |= *segment++ ;
572                         processed_length += 2;
573
574                         if ((object->object_type == 1) || (object->object_type == 2))
575                         {
576                                 object->foreground_pixel_value = *segment++;
577                                 object->background_pixel_value = *segment++;
578                                 processed_length += 2;
579                         }
580                 }
581
582                 if (processed_length != segment_length)
583                         eDebug("too less data! (%d < %d)", segment_length, processed_length);
584
585                 break;
586         }
587         case 0x12: // CLUT definition segment
588         {
589                 int CLUT_id, CLUT_version_number;
590                 subtitle_clut *clut, **pclut;
591
592                 if (!page)
593                         break;
594
595 //              eDebug("CLUT: %02x", *segment);
596                 CLUT_id = *segment++;
597
598                 CLUT_version_number = *segment++ >> 4;
599                 processed_length += 2;
600
601 //              eDebug("page %d, CLUT %02x, version %d", page->page_id, CLUT_id, CLUT_version_number);
602
603                 clut = page->cluts; pclut = &page->cluts;
604
605                 while (clut)
606                 {
607                         if (clut->clut_id == CLUT_id)
608                                 break;
609                         pclut = &clut->next;
610                         clut = clut->next;
611                 }
612
613                 if (!clut)
614                 {
615                         *pclut = clut = new subtitle_clut;
616                         clut->next = 0;
617                         clut->clut_id = CLUT_id;
618                 }
619                 else if (clut->CLUT_version_number == CLUT_version_number)
620                         break;
621
622                 clut->CLUT_version_number=CLUT_version_number;
623
624                 memset(clut->entries_2bit, 0, sizeof(clut->entries_2bit));
625                 memset(clut->entries_4bit, 0, sizeof(clut->entries_4bit));
626                 memset(clut->entries_8bit, 0, sizeof(clut->entries_8bit));
627
628 //              eDebug("new Clut!");
629                 while (processed_length < segment_length)
630                 {
631                         int CLUT_entry_id, entry_CLUT_flag, full_range;
632                         int v_Y, v_Cr, v_Cb, v_T;
633
634                         CLUT_entry_id = *segment++;
635                         full_range = *segment & 1;
636                         entry_CLUT_flag = (*segment++ & 0xE0) >> 5;
637                         processed_length += 2;
638
639                         if (full_range)
640                         {
641 //                              eDebugNoNewLine("f");
642                                 v_Y  = *segment++;
643                                 v_Cr = *segment++;
644                                 v_Cb = *segment++;
645                                 v_T  = *segment++;
646                                 processed_length += 4;
647                         } else
648                         {
649 //                              eDebugNoNewLine(" ");
650                                 v_Y   = *segment & 0xFC;
651                                 v_Cr  = (*segment++ & 3) << 6;
652                                 v_Cr |= (*segment & 0xC0) >> 2;
653                                 v_Cb  = (*segment & 0x3C) << 2;
654                                 v_T   = (*segment++ & 3) << 6;
655                                 processed_length += 2;
656                         }
657
658                         if (entry_CLUT_flag & 1) // 8bit
659                         {
660 //                              eDebugNoNewLine("8b");
661                                 ASSERT(CLUT_entry_id < 256);
662                                 clut->entries_8bit[CLUT_entry_id].Y = v_Y;
663                                 clut->entries_8bit[CLUT_entry_id].Cr = v_Cr;
664                                 clut->entries_8bit[CLUT_entry_id].Cb = v_Cb;
665                                 clut->entries_8bit[CLUT_entry_id].T = v_T;
666                                 clut->entries_8bit[CLUT_entry_id].valid = 1;
667                         }
668                         if (entry_CLUT_flag & 2) // 4bit
669                         {
670 //                              eDebugNoNewLine("4b");
671                                 ASSERT(CLUT_entry_id < 16);
672                                 clut->entries_4bit[CLUT_entry_id].Y = v_Y;
673                                 clut->entries_4bit[CLUT_entry_id].Cr = v_Cr;
674                                 clut->entries_4bit[CLUT_entry_id].Cb = v_Cb;
675                                 clut->entries_4bit[CLUT_entry_id].T = v_T;
676                                 clut->entries_4bit[CLUT_entry_id].valid = 1;
677                         }
678                         if (entry_CLUT_flag & 4) // 2bit
679                         {
680 //                              eDebugNoNewLine("2b");
681                                 ASSERT(CLUT_entry_id < 4);
682                                 clut->entries_2bit[CLUT_entry_id].Y = v_Y;
683                                 clut->entries_2bit[CLUT_entry_id].Cr = v_Cr;
684                                 clut->entries_2bit[CLUT_entry_id].Cb = v_Cb;
685                                 clut->entries_2bit[CLUT_entry_id].T = v_T;
686                                 clut->entries_2bit[CLUT_entry_id].valid = 1;
687                         }
688 //                      eDebug(" %04x %02x %02x %02x %02x", CLUT_entry_id, v_Y, v_Cb, v_Cr, v_T);
689                 }
690                 break;
691         }
692         case 0x13: // object data segment
693         {
694                 int object_id, object_version_number, object_coding_method, non_modifying_color_flag;
695
696                 object_id  = *segment++ << 8;
697                 object_id |= *segment++;
698                 processed_length += 2;
699
700                 object_version_number = *segment >> 4;
701                 object_coding_method  = (*segment >> 2) & 3;
702                 non_modifying_color_flag = (*segment++ >> 1) & 1;
703                 processed_length++;
704
705 //              eDebug("object id %04x, version %d, object_coding_method %d (page_id %d)", object_id, object_version_number, object_coding_method, page_id);
706                 subtitle_region *region = page->regions;
707 //              eDebug("line for %d:%d", page->page_id, object_id);
708                 while (region)
709                 {
710                         subtitle_region_object *object = region->objects;
711                         while (object)
712                         {
713                                 if (object->object_id == object_id)
714                                 {
715                                         if (object_coding_method == 0)
716                                         {
717                                                 int top_field_data_blocklength, bottom_field_data_blocklength;
718                                                 int i=1, line, linep;
719
720                                                 top_field_data_blocklength  = *segment++ << 8;
721                                                 top_field_data_blocklength |= *segment++;
722
723                                                 bottom_field_data_blocklength  = *segment++ << 8;
724                                                 bottom_field_data_blocklength |= *segment++;
725 //                                              eDebug("%d / %d bytes", top_field_data_blocklength, bottom_field_data_blocklength);
726                                                 processed_length += 4;
727
728                                                 // its working on cyfra channels.. but hmm in EN300743 the default table is 0, 7, 8, 15
729                                                 map_2_to_4_bit_table[0] = 0;
730                                                 map_2_to_4_bit_table[1] = 8;
731                                                 map_2_to_4_bit_table[2] = 7;
732                                                 map_2_to_4_bit_table[3] = 15;
733
734                                                 // this map is realy untested...
735                                                 map_2_to_8_bit_table[0] = 0;
736                                                 map_2_to_8_bit_table[1] = 0x88;
737                                                 map_2_to_8_bit_table[2] = 0x77;
738                                                 map_2_to_8_bit_table[3] = 0xff;
739
740                                                 map_4_to_8_bit_table[0] = 0;
741                                                 for (; i < 16; ++i)
742                                                         map_4_to_8_bit_table[i] = i * 0x11;
743
744                                                 i = 0;
745                                                 line = 0;
746                                                 linep = 0;
747                                                 while (i < top_field_data_blocklength)
748                                                 {
749                                                         int len;
750                                                         len = subtitle_process_pixel_data(region, object, &line, &linep, segment);
751                                                         if (len < 0)
752                                                                 return -1;
753                                                         segment += len;
754                                                         processed_length += len;
755                                                         i += len;
756                                                 }
757
758                                                 line = 1;
759                                                 linep = 0;
760
761                                                 if (bottom_field_data_blocklength)
762                                                 {
763                                                         i = 0;
764                                                         while (i < bottom_field_data_blocklength)
765                                                         {
766                                                                 int len;
767                                                                 len = subtitle_process_pixel_data(region, object, &line, &linep, segment);
768                                                                 if (len < 0)
769                                                                         return -1;
770                                                                 segment += len;
771                                                                         processed_length += len;
772                                                                 i += len;
773                                                         }
774                                                 }
775                                                 else if (top_field_data_blocklength)
776                                                         eDebug("!!!! unimplemented: no bottom field! (%d : %d)", top_field_data_blocklength, bottom_field_data_blocklength);
777
778                                                 if ((top_field_data_blocklength + bottom_field_data_blocklength) & 1)
779                                                 {
780                                                         segment++; processed_length++;
781                                                 }
782                                         }
783                                         else if (object_coding_method == 1)
784                                                 eDebug("---- object_coding_method 1 unsupported!");
785                                 }
786                                 object = object->next;
787                         }
788                         region = region->next;
789                 }
790                 break;
791         }
792         case 0x14: // display definition segment
793         {
794                 if (segment_length > 4)
795                 {
796                         int dds_version_number = segment[0] >> 4;
797                         int display_window_flag = (segment[0] >> 3) & 1;
798                         int display_width = (segment[1] << 8) | (segment[2]);
799                         int display_height = (segment[3] << 8) | (segment[4]);
800 //                      eDebug("version %d, window_flag %d, display_width %d, display_height %d",
801 //                              dds_version_number, display_window_flag, display_width, display_height);
802                         processed_length += 5;
803                         m_display_size = eSize(display_width+1, display_height+1);
804                         if (display_window_flag)
805                         {
806                                 if (segment_length > 12)
807                                 {
808                                         int display_window_horizontal_position_min = (segment[4] << 8) | segment[5];
809                                         int display_window_horizontal_position_max = (segment[6] << 8) | segment[7];
810                                         int display_window_vertical_position_min = (segment[8] << 8) | segment[9];
811                                         int display_window_vertical_position_max = (segment[10] << 8) | segment[11];
812                                         eDebug("NYI hpos min %d, hpos max %d, vpos min %d, vpos max %d",
813                                                 display_window_horizontal_position_min,
814                                                 display_window_horizontal_position_max,
815                                                 display_window_vertical_position_min,
816                                                 display_window_vertical_position_max);
817                                         processed_length += 8;
818                                 }
819                                 else
820                                         eDebug("display window flag set but display definition segment to short %d!", segment_length);
821                         }
822                 }
823                 else
824                         eDebug("display definition segment to short %d!", segment_length);
825                 break;
826         }
827         case 0x80: // end of display set segment
828         {
829 //              eDebug("end of display set segment");
830                 subtitle_redraw_all();
831                 m_seen_eod = true;
832         }
833         case 0xFF: // stuffing
834                 break;
835         default:
836                 eDebug("unhandled segment type %02x", segment_type);
837         }
838
839         return segment_length + 6;
840 }
841
842 void eDVBSubtitleParser::subtitle_process_pes(__u8 *pkt, int len)
843 {
844 //      eDebugNoNewLine("subtitle_process_pes");
845         if (!extract_pts(m_show_time, pkt))
846         {
847 //              eDebug(" %lld", m_show_time);
848                 pkt += 6; len -= 6;
849                 // skip PES header
850                 pkt++; len--;
851                 pkt++; len--;
852
853                 int hdr_len = *pkt++; len--;
854
855                 pkt+=hdr_len; len-=hdr_len;
856
857                 if (*pkt != 0x20)
858                 {
859 //                      eDebug("data identifier is 0x%02x, but not 0x20", *pkt);
860                         return;
861                 }
862                 pkt++; len--; // data identifier
863                 *pkt++; len--; // stream id;
864
865                 if (len <= 0)
866                 {
867 //                      eDebug("no data left (%d)", len);
868                         return;
869                 }
870
871                 m_seen_eod = false;
872
873                 while (len && *pkt == 0x0F)
874                 {
875                         int l = subtitle_process_segment(pkt);
876                         if (l < 0)
877                                 break;
878                         pkt += l;
879                         len -= l;
880                 }
881
882                 if (len && *pkt != 0xFF)
883                         eDebug("strange data at the end");
884
885                 if (!m_seen_eod)
886                         subtitle_redraw_all();
887         }
888 //      else
889 //              eDebug("");
890 }
891
892 void eDVBSubtitleParser::subtitle_redraw_all()
893 {
894 #if 1
895         subtitle_page *page = m_pages;
896         while(page)
897         {
898                 if (page->state != 0)
899                         subtitle_redraw(page->page_id);
900                 page = page->next;
901         }
902 #else
903         subtitle_page *page = m_pages;
904         eDebug("----------- end of display set");
905         eDebug("active pages:");
906         while (page)
907         {
908                 eDebug("  page_id %02x", page->page_id);
909                 eDebug("  page_version_number: %d", page->page_version_number);
910                 eDebug("  active regions:");
911                 {
912                         subtitle_page_region *region = page->page_regions;
913                         while (region)
914                         {
915                                 eDebug("    region_id: %04x", region->region_id);
916                                 eDebug("    region_horizontal_address: %d", region->region_horizontal_address);
917                                 eDebug("    region_vertical_address: %d", region->region_vertical_address);
918
919                                 region = region->next;
920                         }
921                 }
922
923                 subtitle_redraw(page->page_id);
924                 eDebug("defined regions:");
925                 subtitle_region *region = page->regions;
926                 while (region)
927                 {
928                         eDebug("  region_id %04x, version %d, %dx%d", region->region_id, region->version_number, region->width, region->height);
929
930                         subtitle_region_object *object = region->objects;
931                         while (object)
932                         {
933                                 eDebug("  object %02x, type %d, %d:%d", object->object_id, object->object_type, object->object_horizontal_position, object->object_vertical_position);
934                                 object = object->next;
935                         }
936                         region = region->next;
937                 }
938                 page = page->next;
939         }
940 #endif
941 }
942
943 void eDVBSubtitleParser::subtitle_reset()
944 {
945         while (subtitle_page *page = m_pages)
946         {
947                         /* free page regions */
948                 while (page->page_regions)
949                 {
950                         subtitle_page_region *p = page->page_regions->next;
951                         delete page->page_regions;
952                         page->page_regions = p;
953                 }
954                         /* free regions */
955                 while (page->regions)
956                 {
957                         subtitle_region *region = page->regions;
958
959                         while (region->objects)
960                         {
961                                 subtitle_region_object *obj = region->objects;
962                                 region->objects = obj->next;
963                                 delete obj;
964                         }
965
966                         if (region->buffer)
967                         {
968 //                              eDebug("no more need of buffer 2 %p", &(*region->buffer));
969                                 region->buffer=0;
970                         }
971
972                         page->regions = region->next;
973                         delete region;
974                 }
975
976                         /* free CLUTs */
977                 while (page->cluts)
978                 {
979                         subtitle_clut *clut = page->cluts;
980                         page->cluts = clut->next;
981                         delete clut;
982                 }
983
984                 m_pages = page->next;
985                 delete page;
986         }
987 }
988
989 void eDVBSubtitleParser::subtitle_redraw(int page_id)
990 {
991         subtitle_page *page = m_pages;
992
993 //      eDebug("displaying page id %d", page_id);
994
995         while (page)
996         {
997                 if (page->page_id == page_id)
998                         break;
999                 page = page->next;
1000         }
1001         if (!page)
1002         {
1003 //              eDebug("page not found");
1004                 return;
1005         }
1006
1007 //      eDebug("iterating regions..");
1008                 /* iterate all regions in this pcs */
1009         subtitle_page_region *region = page->page_regions;
1010
1011         eDVBSubtitlePage Page;
1012         Page.m_show_time = m_show_time;
1013         for (; region; region=region->next)
1014         {
1015 //              eDebug("region %d", region->region_id);
1016                         /* find corresponding region */
1017                 subtitle_region *reg = page->regions;
1018                 while (reg)
1019                 {
1020                         if (reg->region_id == region->region_id)
1021                                 break;
1022                         reg = reg->next;
1023                 }
1024                 if (reg)
1025                 {
1026                         if (reg->committed)
1027                                 continue;
1028 //                      eDebug("copy region %d to %d, %d", region->region_id, region->region_horizontal_address, region->region_vertical_address);
1029
1030                         int x0 = region->region_horizontal_address;
1031                         int y0 = region->region_vertical_address;
1032
1033                         if ((x0 < 0) || (y0 < 0))
1034                         {
1035 //                              eDebug("x0 %d, y0 %d", x0, y0);
1036                                 continue;
1037                         }
1038
1039                         /* find corresponding clut */
1040                         subtitle_clut *clut = page->cluts;
1041                         while (clut)
1042                         {
1043 //                              eDebug("have %d, want %d", clut->clut_id, main_clut_id);
1044                                 if (clut->clut_id == reg->clut_id)
1045                                         break;
1046                                 clut = clut->next;
1047                         }
1048
1049                         int clut_size = reg->buffer->surface->clut.colors = reg->depth == subtitle_region::bpp2 ?
1050                                 4 : reg->depth == subtitle_region::bpp4 ? 16 : 256;
1051
1052                         reg->buffer->surface->clut.data = new gRGB[clut_size];
1053 //                      eDebug("create clut data for buffer %p", &(*reg->buffer));
1054
1055                         gRGB *palette = reg->buffer->surface->clut.data;
1056
1057 //                      if (!clut)
1058 //                              eDebug("no CLUT.. use default");
1059
1060                         subtitle_clut_entry *entries=0;
1061                         switch(reg->depth)
1062                         {
1063                                 case subtitle_region::bpp2:
1064 //                                      eDebug("2BPP");
1065                                         if (clut)
1066                                                 entries = clut->entries_2bit;
1067                                         memset(palette, 0, 4 * sizeof(gRGB));
1068                                         // this table is tested on cyfra .. but in EN300743 the table palette[2] and palette[1] is swapped.. i dont understand this ;)
1069                                         palette[0].a = 0xFF;
1070                                         palette[2].r = palette[2].g = palette[2].b = 0xFF;
1071                                         palette[3].r = palette[3].g = palette[3].b = 0x80;
1072                                         break;
1073                                 case subtitle_region::bpp4: // tested on cyfra... but the map is another in EN300743... dont understand this...
1074 //                                      eDebug("4BPP");
1075                                         if (clut)
1076                                                 entries = clut->entries_4bit;
1077                                         memset(palette, 0, 16*sizeof(gRGB));
1078                                         for (int i=0; i < 16; ++i)
1079                                         {
1080                                                 if (!i)
1081                                                         palette[i].a = 0xFF;
1082                                                 else if (i & 8)
1083                                                 {
1084                                                         if (i & 1)
1085                                                                 palette[i].r = 0x80;
1086                                                         if (i & 2)
1087                                                                 palette[i].g = 0x80;
1088                                                         if (i & 4)
1089                                                                 palette[i].b = 0x80;
1090                                                 }
1091                                                 else
1092                                                 {
1093                                                         if (i & 1)
1094                                                                 palette[i].r = 0xFF;
1095                                                         if (i & 2)
1096                                                                 palette[i].g = 0xFF;
1097                                                         if (i & 4)
1098                                                                 palette[i].b = 0xFF;
1099                                                 }
1100                                         }
1101                                         break;
1102                                 case subtitle_region::bpp8:  // completely untested.. i never seen 8bit DVB subtitles
1103 //                                      eDebug("8BPP");
1104                                         if (clut)
1105                                                 entries = clut->entries_8bit;
1106                                         memset(palette, 0, 256*sizeof(gRGB));
1107                                         for (int i=0; i < 256; ++i)
1108                                         {
1109                                                 switch (i & 17)
1110                                                 {
1111                                                 case 0: // b1 == 0 && b5 == 0
1112                                                         if (!(i & 14)) // b2 == 0 && b3 == 0 && b4 == 0
1113                                                         {
1114                                                                 if (!(i & 224)) // b6 == 0 && b7 == 0 && b8 == 0
1115                                                                         palette[i].a = 0xFF;
1116                                                                 else
1117                                                                 {
1118                                                                         if (i & 128) // R = 100% x b8
1119                                                                                 palette[i].r = 0xFF;
1120                                                                         if (i & 64) // G = 100% x b7
1121                                                                                 palette[i].g = 0xFF;
1122                                                                         if (i & 32) // B = 100% x b6
1123                                                                                 palette[i].b = 0xFF;
1124                                                                         palette[i].a = 0xBF; // T = 75%
1125                                                                 }
1126                                                                 break;
1127                                                         }
1128                                                         // fallthrough !!
1129                                                 case 16: // b1 == 0 && b5 == 1
1130                                                         if (i & 128) // R = 33% x b8
1131                                                                 palette[i].r = 0x55;
1132                                                         if (i & 64) // G = 33% x b7
1133                                                                 palette[i].g = 0x55;
1134                                                         if (i & 32) // B = 33% x b6
1135                                                                 palette[i].b = 0x55;
1136                                                         if (i & 8) // R + 66,7% x b4
1137                                                                 palette[i].r += 0xAA;
1138                                                         if (i & 4) // G + 66,7% x b3
1139                                                                 palette[i].g += 0xAA;
1140                                                         if (i & 2) // B + 66,7% x b2
1141                                                                 palette[i].b += 0xAA;
1142                                                         if (i & 16) // needed for fall through from case 0!!
1143                                                                 palette[i].a = 0x80; // T = 50%
1144                                                         break;
1145                                                 case 1: // b1 == 1 && b5 == 0
1146                                                         palette[i].r =
1147                                                         palette[i].g =
1148                                                         palette[i].b = 0x80; // 50%
1149                                                         // fall through!!
1150                                                 case 17: // b1 == 1 && b5 == 1
1151                                                         if (i & 128) // R += 16.7% x b8
1152                                                                 palette[i].r += 0x2A;
1153                                                         if (i & 64) // G += 16.7% x b7
1154                                                                 palette[i].g += 0x2A;
1155                                                         if (i & 32) // B += 16.7% x b6
1156                                                                 palette[i].b += 0x2A;
1157                                                         if (i & 8) // R += 33% x b4
1158                                                                 palette[i].r += 0x55;
1159                                                         if (i & 4) // G += 33% x b3
1160                                                                 palette[i].g += 0x55;
1161                                                         if (i & 2) // B += 33% x b2
1162                                                                 palette[i].b += 0x55;
1163                                                         break;
1164                                                 }
1165                                         }
1166                                         break;
1167                         }
1168
1169                         for (int i=0; i<clut_size; ++i)
1170                         {
1171                                 if (entries && entries[i].valid)
1172                                 {
1173                                         int y = entries[i].Y,
1174                                                 cr = entries[i].Cr,
1175                                                 cb = entries[i].Cb;
1176                                         if (y > 0)
1177                                         {
1178                                                 y -= 16;
1179                                                 cr -= 128;
1180                                                 cb -= 128;
1181                                                 palette[i].r = MAX(MIN(((298 * y            + 460 * cr) / 256), 255), 0);
1182                                                 palette[i].g = MAX(MIN(((298 * y -  55 * cb - 137 * cr) / 256), 255), 0);
1183                                                 palette[i].b = MAX(MIN(((298 * y + 543 * cb           ) / 256), 255), 0);
1184                                                 palette[i].a = (entries[i].T) & 0xFF;
1185 //                                              eDebug("override clut entry %d RGBA %02x%02x%02x%02x", i,
1186 //                                                      palette[i].r, palette[i].g, palette[i].b, palette[i].a);
1187                                         }
1188                                         else
1189                                         {
1190 //                                              eDebug("mist %d: y %d cr %d cb %d", i, y, cr, cb);
1191                                                 palette[i].r = 0;
1192                                                 palette[i].g = 0;
1193                                                 palette[i].b = 0;
1194                                                 palette[i].a = 0xFF;
1195                                         }
1196                                 }
1197 //                              eDebug("%d:%c %02x %02x %02x %02x",
1198 //                                      i, entries && entries[i].valid ? 'O': 'D', palette[i].r, palette[i].g, palette[i].b, palette[i].a);
1199                         }
1200
1201 //                      eDebug("commit buffer %p", &(*reg->buffer));
1202                         eDVBSubtitleRegion Region;
1203                         Region.m_pixmap = reg->buffer;
1204                         Region.m_position.setX(x0);
1205                         Region.m_position.setY(y0);
1206                         Page.m_regions.push_back(Region);
1207                         reg->committed = true;
1208                 }
1209 //              else
1210 //                      eDebug("region not found");
1211         }
1212         Page.m_display_size = m_display_size;
1213         m_new_subtitle_page(Page);
1214         Page.m_regions.clear();
1215 //      eDebug("page timeout is %d", page->page_time_out);
1216 //      Page.m_show_time += (page->page_time_out * 90000);
1217 //      m_new_subtitle_page(Page);
1218 //      eDebug("schon gut.");
1219 }
1220
1221 DEFINE_REF(eDVBSubtitleParser);
1222
1223 eDVBSubtitleParser::eDVBSubtitleParser(iDVBDemux *demux)
1224         :m_pages(0), m_display_size(720,576)
1225 {
1226         setStreamID(0xBD);
1227
1228         if (demux->createPESReader(eApp, m_pes_reader))
1229                 eDebug("failed to create dvb subtitle PES reader!");
1230         else
1231                 m_pes_reader->connectRead(slot(*this, &eDVBSubtitleParser::processData), m_read_connection);
1232 }
1233
1234 eDVBSubtitleParser::~eDVBSubtitleParser()
1235 {
1236         subtitle_reset();
1237 }
1238
1239 int eDVBSubtitleParser::stop()
1240 {
1241         if (m_pes_reader)
1242         {
1243                 eDebug("disable dvb subtitles");
1244                 return m_pes_reader->stop();
1245         }
1246         return -1;
1247 }
1248
1249 int eDVBSubtitleParser::start(int pid, int composition_page_id, int ancillary_page_id)
1250 {
1251         if (m_pes_reader)
1252         {
1253                 eDebug("start dvb subtitles on pid 0x%04x with composition_page_id %d and ancillary_page_id %d",
1254                         pid, composition_page_id, ancillary_page_id);
1255                 m_composition_page_id = composition_page_id;
1256                 m_ancillary_page_id = ancillary_page_id;
1257                 return m_pes_reader->start(pid);
1258         }
1259         return -1;
1260 }
1261
1262 void eDVBSubtitleParser::connectNewPage(const Slot1<void, const eDVBSubtitlePage&> &slot, ePtr<eConnection> &connection)
1263 {
1264         connection = new eConnection(this, m_new_subtitle_page.connect(slot));
1265 }