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