lib/gdi/font.h/cpp: another try to fix top/bottom reordering for arabic language
[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_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[1920];
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) < m_display_size.width()))
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) < m_display_size.width()))
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) < m_display_size.width()))
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<m_display_size.width(); ++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                                 clut->entries_8bit[CLUT_entry_id].Y = v_Y;
662                                 clut->entries_8bit[CLUT_entry_id].Cr = v_Cr;
663                                 clut->entries_8bit[CLUT_entry_id].Cb = v_Cb;
664                                 clut->entries_8bit[CLUT_entry_id].T = v_T;
665                                 clut->entries_8bit[CLUT_entry_id].valid = 1;
666                         }
667                         if (entry_CLUT_flag & 2) // 4bit
668                         {
669 //                              eDebugNoNewLine("4b");
670                                 if (CLUT_entry_id < 16)
671                                 {
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                                 else
679                                         eDebug("CLUT entry marked as 4 bit with id %d (>15)", CLUT_entry_id);
680                         }
681                         if (entry_CLUT_flag & 4) // 2bit
682                         {
683 //                              eDebugNoNewLine("2b");
684                                 if (CLUT_entry_id < 4)
685                                 {
686                                         clut->entries_2bit[CLUT_entry_id].Y = v_Y;
687                                         clut->entries_2bit[CLUT_entry_id].Cr = v_Cr;
688                                         clut->entries_2bit[CLUT_entry_id].Cb = v_Cb;
689                                         clut->entries_2bit[CLUT_entry_id].T = v_T;
690                                         clut->entries_2bit[CLUT_entry_id].valid = 1;
691                                 }
692                                 else
693                                         eDebug("CLUT entry marked as 2 bit with id %d (>3)", CLUT_entry_id);
694                         }
695 //                      eDebug(" %04x %02x %02x %02x %02x", CLUT_entry_id, v_Y, v_Cb, v_Cr, v_T);
696                 }
697                 break;
698         }
699         case 0x13: // object data segment
700         {
701                 int object_id, object_version_number, object_coding_method, non_modifying_color_flag;
702
703                 object_id  = *segment++ << 8;
704                 object_id |= *segment++;
705                 processed_length += 2;
706
707                 object_version_number = *segment >> 4;
708                 object_coding_method  = (*segment >> 2) & 3;
709                 non_modifying_color_flag = (*segment++ >> 1) & 1;
710                 processed_length++;
711
712 //              eDebug("object id %04x, version %d, object_coding_method %d (page_id %d)", object_id, object_version_number, object_coding_method, page_id);
713                 subtitle_region *region = page->regions;
714 //              eDebug("line for %d:%d", page->page_id, object_id);
715                 while (region)
716                 {
717                         subtitle_region_object *object = region->objects;
718                         while (object)
719                         {
720                                 if (object->object_id == object_id)
721                                 {
722                                         if (object_coding_method == 0)
723                                         {
724                                                 int top_field_data_blocklength, bottom_field_data_blocklength;
725                                                 int i=1, line, linep;
726
727                                                 top_field_data_blocklength  = *segment++ << 8;
728                                                 top_field_data_blocklength |= *segment++;
729
730                                                 bottom_field_data_blocklength  = *segment++ << 8;
731                                                 bottom_field_data_blocklength |= *segment++;
732 //                                              eDebug("%d / %d bytes", top_field_data_blocklength, bottom_field_data_blocklength);
733                                                 processed_length += 4;
734
735                                                 // its working on cyfra channels.. but hmm in EN300743 the default table is 0, 7, 8, 15
736                                                 map_2_to_4_bit_table[0] = 0;
737                                                 map_2_to_4_bit_table[1] = 8;
738                                                 map_2_to_4_bit_table[2] = 7;
739                                                 map_2_to_4_bit_table[3] = 15;
740
741                                                 // this map is realy untested...
742                                                 map_2_to_8_bit_table[0] = 0;
743                                                 map_2_to_8_bit_table[1] = 0x88;
744                                                 map_2_to_8_bit_table[2] = 0x77;
745                                                 map_2_to_8_bit_table[3] = 0xff;
746
747                                                 map_4_to_8_bit_table[0] = 0;
748                                                 for (; i < 16; ++i)
749                                                         map_4_to_8_bit_table[i] = i * 0x11;
750
751                                                 i = 0;
752                                                 line = 0;
753                                                 linep = 0;
754                                                 while (i < top_field_data_blocklength)
755                                                 {
756                                                         int len;
757                                                         len = subtitle_process_pixel_data(region, object, &line, &linep, segment);
758                                                         if (len < 0)
759                                                                 return -1;
760                                                         segment += len;
761                                                         processed_length += len;
762                                                         i += len;
763                                                 }
764
765                                                 line = 1;
766                                                 linep = 0;
767
768                                                 if (bottom_field_data_blocklength)
769                                                 {
770                                                         i = 0;
771                                                         while (i < bottom_field_data_blocklength)
772                                                         {
773                                                                 int len;
774                                                                 len = subtitle_process_pixel_data(region, object, &line, &linep, segment);
775                                                                 if (len < 0)
776                                                                         return -1;
777                                                                 segment += len;
778                                                                         processed_length += len;
779                                                                 i += len;
780                                                         }
781                                                 }
782                                                 else if (top_field_data_blocklength)
783                                                         eDebug("!!!! unimplemented: no bottom field! (%d : %d)", top_field_data_blocklength, bottom_field_data_blocklength);
784
785                                                 if ((top_field_data_blocklength + bottom_field_data_blocklength) & 1)
786                                                 {
787                                                         segment++; processed_length++;
788                                                 }
789                                         }
790                                         else if (object_coding_method == 1)
791                                                 eDebug("---- object_coding_method 1 unsupported!");
792                                 }
793                                 object = object->next;
794                         }
795                         region = region->next;
796                 }
797                 break;
798         }
799         case 0x14: // display definition segment
800         {
801                 if (segment_length > 4)
802                 {
803                         int dds_version_number = segment[0] >> 4;
804                         int display_window_flag = (segment[0] >> 3) & 1;
805                         int display_width = (segment[1] << 8) | (segment[2]);
806                         int display_height = (segment[3] << 8) | (segment[4]);
807 //                      eDebug("version %d, window_flag %d, display_width %d, display_height %d",
808 //                              dds_version_number, display_window_flag, display_width, display_height);
809                         processed_length += 5;
810                         m_display_size = eSize(display_width+1, display_height+1);
811                         if (display_window_flag)
812                         {
813                                 if (segment_length > 12)
814                                 {
815                                         int display_window_horizontal_position_min = (segment[4] << 8) | segment[5];
816                                         int display_window_horizontal_position_max = (segment[6] << 8) | segment[7];
817                                         int display_window_vertical_position_min = (segment[8] << 8) | segment[9];
818                                         int display_window_vertical_position_max = (segment[10] << 8) | segment[11];
819                                         eDebug("NYI hpos min %d, hpos max %d, vpos min %d, vpos max %d",
820                                                 display_window_horizontal_position_min,
821                                                 display_window_horizontal_position_max,
822                                                 display_window_vertical_position_min,
823                                                 display_window_vertical_position_max);
824                                         processed_length += 8;
825                                 }
826                                 else
827                                         eDebug("display window flag set but display definition segment to short %d!", segment_length);
828                         }
829                 }
830                 else
831                         eDebug("display definition segment to short %d!", segment_length);
832                 break;
833         }
834         case 0x80: // end of display set segment
835         {
836 //              eDebug("end of display set segment");
837                 subtitle_redraw_all();
838                 m_seen_eod = true;
839         }
840         case 0xFF: // stuffing
841                 break;
842         default:
843                 eDebug("unhandled segment type %02x", segment_type);
844         }
845
846         return segment_length + 6;
847 }
848
849 void eDVBSubtitleParser::subtitle_process_pes(__u8 *pkt, int len)
850 {
851 //      eDebugNoNewLine("subtitle_process_pes");
852         if (!extract_pts(m_show_time, pkt))
853         {
854 //              eDebug(" %lld", m_show_time);
855                 pkt += 6; len -= 6;
856                 // skip PES header
857                 pkt++; len--;
858                 pkt++; len--;
859
860                 int hdr_len = *pkt++; len--;
861
862                 pkt+=hdr_len; len-=hdr_len;
863
864                 if (*pkt != 0x20)
865                 {
866 //                      eDebug("data identifier is 0x%02x, but not 0x20", *pkt);
867                         return;
868                 }
869                 pkt++; len--; // data identifier
870                 *pkt++; len--; // stream id;
871
872                 if (len <= 0)
873                 {
874 //                      eDebug("no data left (%d)", len);
875                         return;
876                 }
877
878                 m_seen_eod = false;
879
880                 while (len && *pkt == 0x0F)
881                 {
882                         int l = subtitle_process_segment(pkt);
883                         if (l < 0)
884                                 break;
885                         pkt += l;
886                         len -= l;
887                 }
888
889                 if (len && *pkt != 0xFF)
890                         eDebug("strange data at the end");
891
892                 if (!m_seen_eod)
893                         subtitle_redraw_all();
894         }
895 //      else
896 //              eDebug("");
897 }
898
899 void eDVBSubtitleParser::subtitle_redraw_all()
900 {
901 #if 1
902         subtitle_page *page = m_pages;
903         while(page)
904         {
905                 if (page->state != 0)
906                         subtitle_redraw(page->page_id);
907                 page = page->next;
908         }
909 #else
910         subtitle_page *page = m_pages;
911         eDebug("----------- end of display set");
912         eDebug("active pages:");
913         while (page)
914         {
915                 eDebug("  page_id %02x", page->page_id);
916                 eDebug("  page_version_number: %d", page->page_version_number);
917                 eDebug("  active regions:");
918                 {
919                         subtitle_page_region *region = page->page_regions;
920                         while (region)
921                         {
922                                 eDebug("    region_id: %04x", region->region_id);
923                                 eDebug("    region_horizontal_address: %d", region->region_horizontal_address);
924                                 eDebug("    region_vertical_address: %d", region->region_vertical_address);
925
926                                 region = region->next;
927                         }
928                 }
929
930                 subtitle_redraw(page->page_id);
931                 eDebug("defined regions:");
932                 subtitle_region *region = page->regions;
933                 while (region)
934                 {
935                         eDebug("  region_id %04x, version %d, %dx%d", region->region_id, region->version_number, region->width, region->height);
936
937                         subtitle_region_object *object = region->objects;
938                         while (object)
939                         {
940                                 eDebug("  object %02x, type %d, %d:%d", object->object_id, object->object_type, object->object_horizontal_position, object->object_vertical_position);
941                                 object = object->next;
942                         }
943                         region = region->next;
944                 }
945                 page = page->next;
946         }
947 #endif
948 }
949
950 void eDVBSubtitleParser::subtitle_reset()
951 {
952         while (subtitle_page *page = m_pages)
953         {
954                         /* free page regions */
955                 while (page->page_regions)
956                 {
957                         subtitle_page_region *p = page->page_regions->next;
958                         delete page->page_regions;
959                         page->page_regions = p;
960                 }
961                         /* free regions */
962                 while (page->regions)
963                 {
964                         subtitle_region *region = page->regions;
965
966                         while (region->objects)
967                         {
968                                 subtitle_region_object *obj = region->objects;
969                                 region->objects = obj->next;
970                                 delete obj;
971                         }
972
973                         if (region->buffer)
974                         {
975 //                              eDebug("no more need of buffer 2 %p", &(*region->buffer));
976                                 region->buffer=0;
977                         }
978
979                         page->regions = region->next;
980                         delete region;
981                 }
982
983                         /* free CLUTs */
984                 while (page->cluts)
985                 {
986                         subtitle_clut *clut = page->cluts;
987                         page->cluts = clut->next;
988                         delete clut;
989                 }
990
991                 m_pages = page->next;
992                 delete page;
993         }
994 }
995
996 void eDVBSubtitleParser::subtitle_redraw(int page_id)
997 {
998         subtitle_page *page = m_pages;
999
1000 //      eDebug("displaying page id %d", page_id);
1001
1002         while (page)
1003         {
1004                 if (page->page_id == page_id)
1005                         break;
1006                 page = page->next;
1007         }
1008         if (!page)
1009         {
1010 //              eDebug("page not found");
1011                 return;
1012         }
1013
1014 //      eDebug("iterating regions..");
1015                 /* iterate all regions in this pcs */
1016         subtitle_page_region *region = page->page_regions;
1017
1018         eDVBSubtitlePage Page;
1019         Page.m_show_time = m_show_time;
1020         for (; region; region=region->next)
1021         {
1022 //              eDebug("region %d", region->region_id);
1023                         /* find corresponding region */
1024                 subtitle_region *reg = page->regions;
1025                 while (reg)
1026                 {
1027                         if (reg->region_id == region->region_id)
1028                                 break;
1029                         reg = reg->next;
1030                 }
1031                 if (reg)
1032                 {
1033                         if (reg->committed)
1034                                 continue;
1035 //                      eDebug("copy region %d to %d, %d", region->region_id, region->region_horizontal_address, region->region_vertical_address);
1036
1037                         int x0 = region->region_horizontal_address;
1038                         int y0 = region->region_vertical_address;
1039
1040                         if ((x0 < 0) || (y0 < 0))
1041                         {
1042 //                              eDebug("x0 %d, y0 %d", x0, y0);
1043                                 continue;
1044                         }
1045
1046                         /* find corresponding clut */
1047                         subtitle_clut *clut = page->cluts;
1048                         while (clut)
1049                         {
1050 //                              eDebug("have %d, want %d", clut->clut_id, main_clut_id);
1051                                 if (clut->clut_id == reg->clut_id)
1052                                         break;
1053                                 clut = clut->next;
1054                         }
1055
1056                         int clut_size = reg->buffer->surface->clut.colors = reg->depth == subtitle_region::bpp2 ?
1057                                 4 : reg->depth == subtitle_region::bpp4 ? 16 : 256;
1058
1059                         reg->buffer->surface->clut.data = new gRGB[clut_size];
1060 //                      eDebug("create clut data for buffer %p", &(*reg->buffer));
1061
1062                         gRGB *palette = reg->buffer->surface->clut.data;
1063
1064 //                      if (!clut)
1065 //                              eDebug("no CLUT.. use default");
1066
1067                         subtitle_clut_entry *entries=0;
1068                         switch(reg->depth)
1069                         {
1070                                 case subtitle_region::bpp2:
1071 //                                      eDebug("2BPP");
1072                                         if (clut)
1073                                                 entries = clut->entries_2bit;
1074                                         memset(palette, 0, 4 * sizeof(gRGB));
1075                                         // this table is tested on cyfra .. but in EN300743 the table palette[2] and palette[1] is swapped.. i dont understand this ;)
1076                                         palette[0].a = 0xFF;
1077                                         palette[2].r = palette[2].g = palette[2].b = 0xFF;
1078                                         palette[3].r = palette[3].g = palette[3].b = 0x80;
1079                                         break;
1080                                 case subtitle_region::bpp4: // tested on cyfra... but the map is another in EN300743... dont understand this...
1081 //                                      eDebug("4BPP");
1082                                         if (clut)
1083                                                 entries = clut->entries_4bit;
1084                                         memset(palette, 0, 16*sizeof(gRGB));
1085                                         for (int i=0; i < 16; ++i)
1086                                         {
1087                                                 if (!i)
1088                                                         palette[i].a = 0xFF;
1089                                                 else if (i & 8)
1090                                                 {
1091                                                         if (i & 1)
1092                                                                 palette[i].r = 0x80;
1093                                                         if (i & 2)
1094                                                                 palette[i].g = 0x80;
1095                                                         if (i & 4)
1096                                                                 palette[i].b = 0x80;
1097                                                 }
1098                                                 else
1099                                                 {
1100                                                         if (i & 1)
1101                                                                 palette[i].r = 0xFF;
1102                                                         if (i & 2)
1103                                                                 palette[i].g = 0xFF;
1104                                                         if (i & 4)
1105                                                                 palette[i].b = 0xFF;
1106                                                 }
1107                                         }
1108                                         break;
1109                                 case subtitle_region::bpp8:  // completely untested.. i never seen 8bit DVB subtitles
1110 //                                      eDebug("8BPP");
1111                                         if (clut)
1112                                                 entries = clut->entries_8bit;
1113                                         memset(palette, 0, 256*sizeof(gRGB));
1114                                         for (int i=0; i < 256; ++i)
1115                                         {
1116                                                 switch (i & 17)
1117                                                 {
1118                                                 case 0: // b1 == 0 && b5 == 0
1119                                                         if (!(i & 14)) // b2 == 0 && b3 == 0 && b4 == 0
1120                                                         {
1121                                                                 if (!(i & 224)) // b6 == 0 && b7 == 0 && b8 == 0
1122                                                                         palette[i].a = 0xFF;
1123                                                                 else
1124                                                                 {
1125                                                                         if (i & 128) // R = 100% x b8
1126                                                                                 palette[i].r = 0xFF;
1127                                                                         if (i & 64) // G = 100% x b7
1128                                                                                 palette[i].g = 0xFF;
1129                                                                         if (i & 32) // B = 100% x b6
1130                                                                                 palette[i].b = 0xFF;
1131                                                                         palette[i].a = 0xBF; // T = 75%
1132                                                                 }
1133                                                                 break;
1134                                                         }
1135                                                         // fallthrough !!
1136                                                 case 16: // b1 == 0 && b5 == 1
1137                                                         if (i & 128) // R = 33% x b8
1138                                                                 palette[i].r = 0x55;
1139                                                         if (i & 64) // G = 33% x b7
1140                                                                 palette[i].g = 0x55;
1141                                                         if (i & 32) // B = 33% x b6
1142                                                                 palette[i].b = 0x55;
1143                                                         if (i & 8) // R + 66,7% x b4
1144                                                                 palette[i].r += 0xAA;
1145                                                         if (i & 4) // G + 66,7% x b3
1146                                                                 palette[i].g += 0xAA;
1147                                                         if (i & 2) // B + 66,7% x b2
1148                                                                 palette[i].b += 0xAA;
1149                                                         if (i & 16) // needed for fall through from case 0!!
1150                                                                 palette[i].a = 0x80; // T = 50%
1151                                                         break;
1152                                                 case 1: // b1 == 1 && b5 == 0
1153                                                         palette[i].r =
1154                                                         palette[i].g =
1155                                                         palette[i].b = 0x80; // 50%
1156                                                         // fall through!!
1157                                                 case 17: // b1 == 1 && b5 == 1
1158                                                         if (i & 128) // R += 16.7% x b8
1159                                                                 palette[i].r += 0x2A;
1160                                                         if (i & 64) // G += 16.7% x b7
1161                                                                 palette[i].g += 0x2A;
1162                                                         if (i & 32) // B += 16.7% x b6
1163                                                                 palette[i].b += 0x2A;
1164                                                         if (i & 8) // R += 33% x b4
1165                                                                 palette[i].r += 0x55;
1166                                                         if (i & 4) // G += 33% x b3
1167                                                                 palette[i].g += 0x55;
1168                                                         if (i & 2) // B += 33% x b2
1169                                                                 palette[i].b += 0x55;
1170                                                         break;
1171                                                 }
1172                                         }
1173                                         break;
1174                         }
1175
1176                         for (int i=0; i<clut_size; ++i)
1177                         {
1178                                 if (entries && entries[i].valid)
1179                                 {
1180                                         int y = entries[i].Y,
1181                                                 cr = entries[i].Cr,
1182                                                 cb = entries[i].Cb;
1183                                         if (y > 0)
1184                                         {
1185                                                 y -= 16;
1186                                                 cr -= 128;
1187                                                 cb -= 128;
1188                                                 palette[i].r = MAX(MIN(((298 * y            + 460 * cr) / 256), 255), 0);
1189                                                 palette[i].g = MAX(MIN(((298 * y -  55 * cb - 137 * cr) / 256), 255), 0);
1190                                                 palette[i].b = MAX(MIN(((298 * y + 543 * cb           ) / 256), 255), 0);
1191                                                 palette[i].a = (entries[i].T) & 0xFF;
1192 //                                              eDebug("override clut entry %d RGBA %02x%02x%02x%02x", i,
1193 //                                                      palette[i].r, palette[i].g, palette[i].b, palette[i].a);
1194                                         }
1195                                         else
1196                                         {
1197 //                                              eDebug("mist %d: y %d cr %d cb %d", i, y, cr, cb);
1198                                                 palette[i].r = 0;
1199                                                 palette[i].g = 0;
1200                                                 palette[i].b = 0;
1201                                                 palette[i].a = 0xFF;
1202                                         }
1203                                 }
1204 //                              eDebug("%d:%c %02x %02x %02x %02x",
1205 //                                      i, entries && entries[i].valid ? 'O': 'D', palette[i].r, palette[i].g, palette[i].b, palette[i].a);
1206                         }
1207
1208 //                      eDebug("commit buffer %p", &(*reg->buffer));
1209                         eDVBSubtitleRegion Region;
1210                         Region.m_pixmap = reg->buffer;
1211                         Region.m_position.setX(x0);
1212                         Region.m_position.setY(y0);
1213                         Page.m_regions.push_back(Region);
1214                         reg->committed = true;
1215                 }
1216 //              else
1217 //                      eDebug("region not found");
1218         }
1219         Page.m_display_size = m_display_size;
1220         m_new_subtitle_page(Page);
1221         Page.m_regions.clear();
1222 //      eDebug("page timeout is %d", page->page_time_out);
1223 //      Page.m_show_time += (page->page_time_out * 90000);
1224 //      m_new_subtitle_page(Page);
1225 //      eDebug("schon gut.");
1226 }
1227
1228 DEFINE_REF(eDVBSubtitleParser);
1229
1230 eDVBSubtitleParser::eDVBSubtitleParser(iDVBDemux *demux)
1231         :m_pages(0), m_display_size(720,576)
1232 {
1233         setStreamID(0xBD);
1234
1235         if (demux->createPESReader(eApp, m_pes_reader))
1236                 eDebug("failed to create dvb subtitle PES reader!");
1237         else
1238                 m_pes_reader->connectRead(slot(*this, &eDVBSubtitleParser::processData), m_read_connection);
1239 }
1240
1241 eDVBSubtitleParser::~eDVBSubtitleParser()
1242 {
1243         subtitle_reset();
1244 }
1245
1246 int eDVBSubtitleParser::stop()
1247 {
1248         if (m_pes_reader)
1249         {
1250                 eDebug("disable dvb subtitles");
1251                 return m_pes_reader->stop();
1252         }
1253         return -1;
1254 }
1255
1256 int eDVBSubtitleParser::start(int pid, int composition_page_id, int ancillary_page_id)
1257 {
1258         if (m_pes_reader)
1259         {
1260                 eDebug("start dvb subtitles on pid 0x%04x with composition_page_id %d and ancillary_page_id %d",
1261                         pid, composition_page_id, ancillary_page_id);
1262                 m_composition_page_id = composition_page_id;
1263                 m_ancillary_page_id = ancillary_page_id;
1264                 return m_pes_reader->start(pid);
1265         }
1266         return -1;
1267 }
1268
1269 void eDVBSubtitleParser::connectNewPage(const Slot1<void, const eDVBSubtitlePage&> &slot, ePtr<eConnection> &connection)
1270 {
1271         connection = new eConnection(this, m_new_subtitle_page.connect(slot));
1272 }