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/base/nconfig.h>
13 #include <lib/gdi/gpixmap.h>
15 void bitstream_init(bitstream *bit, const void *buffer, int size)
17 bit->data = (__u8*) buffer;
23 int bitstream_get(bitstream *bit)
26 bit->avail -= bit->size;
27 val = ((*bit->data) >> bit->avail) & ((1<<bit->size) - 1);
37 static int extract_pts(pts_t &pts, __u8 *pkt)
42 pkt++; // header length
44 if (flags & 0x80) /* PTS present? */
47 pts = ((unsigned long long)(((pkt[0] >> 1) & 7))) << 30;
49 pts |= (pkt[2]>>1) << 15;
58 void eDVBSubtitleParser::subtitle_process_line(subtitle_region *region, subtitle_region_object *object, int line, __u8 *data, int len)
60 bool subcentered = ePythonConfigQuery::getConfigBoolValue("config.subtitles.dvb_subtitles_centered");
61 int x = subcentered ? (region->width - len) /2 : object->object_horizontal_position;
62 int y = object->object_vertical_position + line;
63 if (x + len > region->width)
65 // eDebug("[SUB] !!!! XCLIP %d + %d > %d", x, len, region->width);
66 len = region->width - x;
70 if (y >= region->height)
72 // eDebug("[SUB] !!!! YCLIP %d >= %d", y, region->height);
75 // eDebug("inserting %d bytes (into region %d)", len, region->region_id);
76 // eDebug("put data to buffer %p", &(*region->buffer));
77 if (subcentered && region->region_id && line < 3)
79 for (int i = 0; i < len; i++)
85 memcpy((__u8*)region->buffer->surface->data + region->buffer->surface->stride * y + x, data, len);
88 static int map_2_to_4_bit_table[4];
89 static int map_2_to_8_bit_table[4];
90 static int map_4_to_8_bit_table[16];
92 int eDVBSubtitleParser::subtitle_process_pixel_data(subtitle_region *region, subtitle_region_object *object, int *linenr, int *linep, __u8 *data)
94 int data_type = *data++;
95 static __u8 line[1920];
101 case 0x10: // 2bit pixel data
102 // eDebug("2bit pixel data!");
103 bitstream_init(&bit, data, 2);
107 int code = bitstream_get(&bit);
114 code = bitstream_get(&bit);
117 code = bitstream_get(&bit);
122 } else if (code == 2)
124 len = bitstream_get(&bit) << 2;
125 len |= bitstream_get(&bit);
127 col = bitstream_get(&bit);
128 } else if (code == 3)
130 len = bitstream_get(&bit) << 6;
131 len |= bitstream_get(&bit) << 4;
132 len |= bitstream_get(&bit) << 2;
133 len |= bitstream_get(&bit);
135 col = bitstream_get(&bit);
145 len = 3 + 4 + bitstream_get(&bit);
147 len = 3 + bitstream_get(&bit);
148 col = bitstream_get(&bit);
151 uint8_t c = region->depth == subtitle_region::bpp4 ?
152 map_2_to_4_bit_table[col] :
153 region->depth == subtitle_region::bpp8 ?
154 map_2_to_8_bit_table[col] : col;
155 while (len && ((*linep) < m_display_size.width()))
157 line[(*linep)++] = c;
161 while (bit.avail != 8)
163 return bit.consumed + 1;
164 case 0x11: // 4bit pixel data
165 // eDebug("4bit pixel data!");
166 bitstream_init(&bit, data, 4);
170 int code = bitstream_get(&bit);
177 code = bitstream_get(&bit);
180 else if (code == 0xC)
184 } else if (code == 0xD)
191 len = (code & 7) + 2;
192 } else if ((code & 0xC) == 0x8)
194 col = bitstream_get(&bit);
195 len = (code & 3) + 4;
196 } else if (code == 0xE)
198 len = bitstream_get(&bit) + 9;
199 col = bitstream_get(&bit);
200 } else if (code == 0xF)
202 len = bitstream_get(&bit) << 4;
203 len |= bitstream_get(&bit);
205 col = bitstream_get(&bit);
208 uint8_t c = region->depth == subtitle_region::bpp8 ?
209 map_4_to_8_bit_table[col] : col;
210 while (len && ((*linep) < m_display_size.width()))
212 line[(*linep)++] = c;
216 while (bit.avail != 8)
218 return bit.consumed + 1;
219 case 0x12: // 8bit pixel data
220 // eDebug("8bit pixel data!");
221 bitstream_init(&bit, data, 8);
225 int code = bitstream_get(&bit);
232 code = bitstream_get(&bit);
233 if ((code & 0x80) == 0x80)
236 col = bitstream_get(&bit);
237 } else if (code&0x7F)
244 while (len && ((*linep) < m_display_size.width()))
246 line[(*linep)++] = col;
250 return bit.consumed + 1;
252 // eDebugNoNewLine("2 -> 4 bit table: ");
253 bitstream_init(&bit, data, 4);
254 for ( int i=0; i < 4; ++i )
256 map_2_to_4_bit_table[i] = bitstream_get(&bit);
257 // eDebugNoNewLine("%d ", map_2_to_4_bit_table[i]);
260 return bit.consumed + 1;
262 // eDebugNoNewLine("2 -> 8 bit table: ");
263 bitstream_init(&bit, data, 8);
264 for ( int i=0; i < 4; ++i )
266 map_2_to_8_bit_table[i] = bitstream_get(&bit);
267 // eDebugNoNewLine("%d ", map_2_to_8_bit_table[i]);
269 return bit.consumed + 1;
271 // eDebug("4 -> 8 bit table!");
272 bitstream_init(&bit, data, 8);
273 for ( int i=0; i < 16; ++i )
275 map_4_to_8_bit_table[i] = bitstream_get(&bit);
276 // eDebugNoNewLine("%d ", map_4_to_8_bit_table[i]);
278 return bit.consumed + 1;
280 subtitle_process_line(region, object, *linenr, line, *linep);
283 for (i=0; i<m_display_size.width(); ++i)
284 eDebugNoNewLine("%d ", line[i]);
287 (*linenr)+=2; // interlaced
289 // eDebug("[SUB] EOL");
292 eDebug("subtitle_process_pixel_data: invalid data_type %02x", data_type);
298 int eDVBSubtitleParser::subtitle_process_segment(__u8 *segment)
300 int segment_type, page_id, segment_length, processed_length;
301 if (*segment++ != 0x0F)
303 eDebug("out of sync.");
306 segment_type = *segment++;
307 page_id = *segment++ << 8;
308 page_id |= *segment++;
309 segment_length = *segment++ << 8;
310 segment_length |= *segment++;
311 if (segment_type == 0xFF)
312 return segment_length + 6;
313 if (page_id != m_composition_page_id && page_id != m_ancillary_page_id)
314 return segment_length + 6;
315 // eDebug("have %d bytes of segment data", segment_length);
317 // eDebug("page_id %d, segtype %02x", page_id, segment_type);
319 subtitle_page *page, **ppage;
321 page = m_pages; ppage = &m_pages;
325 if (page->page_id == page_id)
331 processed_length = 0;
333 switch (segment_type)
335 case 0x10: // page composition segment
337 int page_time_out = *segment++; processed_length++;
338 int page_version_number = *segment >> 4;
339 int page_state = (*segment >> 2) & 0x3;
340 // eDebug("pcs with %d bytes data (%d:%d:%d)", segment_length, page_id, page_version_number, page_state);
344 // eDebug("page time out: %d", page_time_out);
345 // eDebug("page_version_number: %d" ,page_version_number);
346 // eDebug("page_state: %d", page_state);
350 // eDebug("page not found");
351 page = new subtitle_page;
352 page->page_regions = 0;
354 page->page_id = page_id;
360 if (page->pcs_size != segment_length)
361 page->page_version_number = -1;
362 // if no update, just skip this data.
363 if (page->page_version_number == page_version_number)
365 // eDebug("skip data... ");
370 page->state = page_state;
372 // eDebug("page updated: old: %d, new: %d", page->page_version_number, page_version_number);
373 // when acquisition point or mode change: remove all displayed pages.
374 if ((page_state == 1) || (page_state == 2))
376 while (page->page_regions)
378 subtitle_page_region *p = page->page_regions->next;
379 // eDebug("delete page_region %d", page->page_regions->region_id);
380 delete page->page_regions;
381 page->page_regions = p;
383 while (page->regions)
385 subtitle_region *p = page->regions->next;
386 // eDebug("delete region %d", page->regions->region_id);
387 while(page->regions->objects)
389 // eDebug("delete region object");
390 subtitle_region_object *ob = page->regions->objects->next;
391 delete page->regions->objects;
392 page->regions->objects = ob;
394 delete page->regions;
400 // eDebug("new page.. (%d)", page_state);
402 page->page_time_out = page_time_out;
404 page->page_version_number = page_version_number;
406 subtitle_page_region **r = &page->page_regions;
408 // eDebug("%d / %d data left", processed_length, segment_length);
414 if (processed_length == segment_length && !page->page_regions)
416 // eDebug("no regions in page.. clear screen!!");
417 subtitle_redraw(page->page_id);
420 while (processed_length < segment_length)
422 subtitle_page_region *pr;
424 // append new entry to list
425 pr = new subtitle_page_region;
430 pr->region_id = *segment++; processed_length++;
431 segment++; processed_length++;
433 pr->region_horizontal_address = *segment++ << 8;
434 pr->region_horizontal_address |= *segment++;
435 processed_length += 2;
437 pr->region_vertical_address = *segment++ << 8;
438 pr->region_vertical_address |= *segment++;
439 processed_length += 2;
441 // eDebug("appended active region");
444 if (processed_length != segment_length)
445 eDebug("%d != %d", processed_length, segment_length);
448 case 0x11: // region composition segment
450 int region_id = *segment++; processed_length++;
451 int version_number = *segment >> 4;
452 int region_fill_flag = (*segment >> 3) & 1;
453 segment++; processed_length++;
455 // if we didn't yet received the pcs for this page, drop the region
458 eDebug("ignoring region %x, since page %02x doesn't yet exist.", region_id, page_id);
462 subtitle_region *region, **pregion;
464 region = page->regions; pregion = &page->regions;
469 if (region->region_id == region_id)
471 pregion = ®ion->next;
472 region = region->next;
477 // eDebug("create region !!!!!!!!!!");
478 *pregion = region = new subtitle_region;
480 region->committed = false;
482 else if (region->version_number != version_number)
484 subtitle_region_object *objects = region->objects;
485 // eDebug("unequal version %p %p", objects, objects?objects->next:objects);
488 subtitle_region_object *n = objects->next;
494 // eDebug("no more need of buffer %p", &(*region->buffer));
497 region->committed = false;
502 // eDebug("region %d:%d update", page_id, region_id);
504 region->region_id = region_id;
505 region->version_number = version_number;
507 region->width = *segment++ << 8;
508 region->width |= *segment++;
509 processed_length += 2;
511 region->height = *segment++ << 8;
512 region->height |= *segment++;
513 processed_length += 2;
515 region->buffer = new gPixmap(eSize(region->width, region->height), 8, 1);
516 memset(region->buffer->surface->data, 0, region->height * region->buffer->surface->stride);
517 // eDebug("new buffer %p", &(*region->buffer));
519 int region_level_of_compatibility, depth;
521 region_level_of_compatibility = (*segment >> 5) & 7;
522 depth = (*segment++ >> 2) & 7;
524 region->depth = (subtitle_region::tDepth) depth;
527 int CLUT_id = *segment++; processed_length++;
529 region->clut_id = CLUT_id;
531 int region_8bit_pixel_code, region_4bit_pixel_code, region_2bit_pixel_code;
532 region_8bit_pixel_code = *segment++; processed_length++;
533 region_4bit_pixel_code = *segment >> 4;
534 region_2bit_pixel_code = (*segment++ >> 2) & 3;
537 if (!region_fill_flag)
539 region_2bit_pixel_code = region_4bit_pixel_code = region_8bit_pixel_code = 0;
540 region_fill_flag = 1;
543 if (region_fill_flag)
545 // eDebug("region fill buffer %p", &(*region->buffer));
547 memset(region->buffer->surface->data, region_2bit_pixel_code, region->height * region->width);
549 memset(region->buffer->surface->data, region_4bit_pixel_code, region->height * region->width);
551 memset(region->buffer->surface->data, region_8bit_pixel_code, region->height * region->width);
553 eDebug("!!!! invalid depth");
556 // eDebug("region %02x, version %d, %dx%d", region->region_id, region->version_number, region->width, region->height);
559 subtitle_region_object **pobject = ®ion->objects;
561 while (processed_length < segment_length)
563 subtitle_region_object *object;
565 object = new subtitle_region_object;
569 pobject = &object->next;
571 object->object_id = *segment++ << 8;
572 object->object_id |= *segment++; processed_length += 2;
574 object->object_type = *segment >> 6;
575 object->object_provider_flag = (*segment >> 4) & 3;
576 object->object_horizontal_position = (*segment++ & 0xF) << 8;
577 object->object_horizontal_position |= *segment++;
578 processed_length += 2;
580 object->object_vertical_position = *segment++ << 8;
581 object->object_vertical_position |= *segment++ ;
582 processed_length += 2;
584 if ((object->object_type == 1) || (object->object_type == 2))
586 object->foreground_pixel_value = *segment++;
587 object->background_pixel_value = *segment++;
588 processed_length += 2;
592 if (processed_length != segment_length)
593 eDebug("too less data! (%d < %d)", segment_length, processed_length);
597 case 0x12: // CLUT definition segment
599 int CLUT_id, CLUT_version_number;
600 subtitle_clut *clut, **pclut;
605 // eDebug("CLUT: %02x", *segment);
606 CLUT_id = *segment++;
608 CLUT_version_number = *segment++ >> 4;
609 processed_length += 2;
611 // eDebug("page %d, CLUT %02x, version %d", page->page_id, CLUT_id, CLUT_version_number);
613 clut = page->cluts; pclut = &page->cluts;
617 if (clut->clut_id == CLUT_id)
625 *pclut = clut = new subtitle_clut;
627 clut->clut_id = CLUT_id;
629 else if (clut->CLUT_version_number == CLUT_version_number)
632 clut->CLUT_version_number=CLUT_version_number;
634 memset(clut->entries_2bit, 0, sizeof(clut->entries_2bit));
635 memset(clut->entries_4bit, 0, sizeof(clut->entries_4bit));
636 memset(clut->entries_8bit, 0, sizeof(clut->entries_8bit));
638 // eDebug("new Clut!");
639 while (processed_length < segment_length)
641 int CLUT_entry_id, entry_CLUT_flag, full_range;
642 int v_Y, v_Cr, v_Cb, v_T;
644 CLUT_entry_id = *segment++;
645 full_range = *segment & 1;
646 entry_CLUT_flag = (*segment++ & 0xE0) >> 5;
647 processed_length += 2;
651 // eDebugNoNewLine("f");
656 processed_length += 4;
659 // eDebugNoNewLine(" ");
660 v_Y = *segment & 0xFC;
661 v_Cr = (*segment++ & 3) << 6;
662 v_Cr |= (*segment & 0xC0) >> 2;
663 v_Cb = (*segment & 0x3C) << 2;
664 v_T = (*segment++ & 3) << 6;
665 processed_length += 2;
668 if (entry_CLUT_flag & 1) // 8bit
670 // eDebugNoNewLine("8b");
671 clut->entries_8bit[CLUT_entry_id].Y = v_Y;
672 clut->entries_8bit[CLUT_entry_id].Cr = v_Cr;
673 clut->entries_8bit[CLUT_entry_id].Cb = v_Cb;
674 clut->entries_8bit[CLUT_entry_id].T = v_T;
675 clut->entries_8bit[CLUT_entry_id].valid = 1;
677 if (entry_CLUT_flag & 2) // 4bit
679 // eDebugNoNewLine("4b");
680 if (CLUT_entry_id < 16)
682 clut->entries_4bit[CLUT_entry_id].Y = v_Y;
683 clut->entries_4bit[CLUT_entry_id].Cr = v_Cr;
684 clut->entries_4bit[CLUT_entry_id].Cb = v_Cb;
685 clut->entries_4bit[CLUT_entry_id].T = v_T;
686 clut->entries_4bit[CLUT_entry_id].valid = 1;
689 eDebug("CLUT entry marked as 4 bit with id %d (>15)", CLUT_entry_id);
691 if (entry_CLUT_flag & 4) // 2bit
693 // eDebugNoNewLine("2b");
694 if (CLUT_entry_id < 4)
696 clut->entries_2bit[CLUT_entry_id].Y = v_Y;
697 clut->entries_2bit[CLUT_entry_id].Cr = v_Cr;
698 clut->entries_2bit[CLUT_entry_id].Cb = v_Cb;
699 clut->entries_2bit[CLUT_entry_id].T = v_T;
700 clut->entries_2bit[CLUT_entry_id].valid = 1;
703 eDebug("CLUT entry marked as 2 bit with id %d (>3)", CLUT_entry_id);
705 // eDebug(" %04x %02x %02x %02x %02x", CLUT_entry_id, v_Y, v_Cb, v_Cr, v_T);
709 case 0x13: // object data segment
711 int object_id, object_version_number, object_coding_method, non_modifying_color_flag;
713 object_id = *segment++ << 8;
714 object_id |= *segment++;
715 processed_length += 2;
717 object_version_number = *segment >> 4;
718 object_coding_method = (*segment >> 2) & 3;
719 non_modifying_color_flag = (*segment++ >> 1) & 1;
722 // eDebug("object id %04x, version %d, object_coding_method %d (page_id %d)", object_id, object_version_number, object_coding_method, page_id);
723 subtitle_region *region = page->regions;
724 // eDebug("line for %d:%d", page->page_id, object_id);
727 subtitle_region_object *object = region->objects;
730 if (object->object_id == object_id)
732 if (object_coding_method == 0)
734 int top_field_data_blocklength, bottom_field_data_blocklength;
735 int i=1, line, linep;
737 top_field_data_blocklength = *segment++ << 8;
738 top_field_data_blocklength |= *segment++;
740 bottom_field_data_blocklength = *segment++ << 8;
741 bottom_field_data_blocklength |= *segment++;
742 // eDebug("%d / %d bytes", top_field_data_blocklength, bottom_field_data_blocklength);
743 processed_length += 4;
745 // its working on cyfra channels.. but hmm in EN300743 the default table is 0, 7, 8, 15
746 map_2_to_4_bit_table[0] = 0;
747 map_2_to_4_bit_table[1] = 8;
748 map_2_to_4_bit_table[2] = 7;
749 map_2_to_4_bit_table[3] = 15;
751 // this map is realy untested...
752 map_2_to_8_bit_table[0] = 0;
753 map_2_to_8_bit_table[1] = 0x88;
754 map_2_to_8_bit_table[2] = 0x77;
755 map_2_to_8_bit_table[3] = 0xff;
757 map_4_to_8_bit_table[0] = 0;
759 map_4_to_8_bit_table[i] = i * 0x11;
764 while (i < top_field_data_blocklength)
767 len = subtitle_process_pixel_data(region, object, &line, &linep, segment);
771 processed_length += len;
778 if (bottom_field_data_blocklength)
781 while (i < bottom_field_data_blocklength)
784 len = subtitle_process_pixel_data(region, object, &line, &linep, segment);
788 processed_length += len;
792 else if (top_field_data_blocklength)
793 eDebug("!!!! unimplemented: no bottom field! (%d : %d)", top_field_data_blocklength, bottom_field_data_blocklength);
795 if ((top_field_data_blocklength + bottom_field_data_blocklength) & 1)
797 segment++; processed_length++;
800 else if (object_coding_method == 1)
801 eDebug("---- object_coding_method 1 unsupported!");
803 object = object->next;
805 region = region->next;
809 case 0x14: // display definition segment
811 if (segment_length > 4)
813 int dds_version_number = segment[0] >> 4;
814 int display_window_flag = (segment[0] >> 3) & 1;
815 int display_width = (segment[1] << 8) | (segment[2]);
816 int display_height = (segment[3] << 8) | (segment[4]);
817 // eDebug("version %d, window_flag %d, display_width %d, display_height %d",
818 // dds_version_number, display_window_flag, display_width, display_height);
819 processed_length += 5;
820 m_display_size = eSize(display_width+1, display_height+1);
821 if (display_window_flag)
823 if (segment_length > 12)
825 int display_window_horizontal_position_min = (segment[4] << 8) | segment[5];
826 int display_window_horizontal_position_max = (segment[6] << 8) | segment[7];
827 int display_window_vertical_position_min = (segment[8] << 8) | segment[9];
828 int display_window_vertical_position_max = (segment[10] << 8) | segment[11];
829 eDebug("NYI hpos min %d, hpos max %d, vpos min %d, vpos max %d",
830 display_window_horizontal_position_min,
831 display_window_horizontal_position_max,
832 display_window_vertical_position_min,
833 display_window_vertical_position_max);
834 processed_length += 8;
837 eDebug("display window flag set but display definition segment to short %d!", segment_length);
841 eDebug("display definition segment to short %d!", segment_length);
844 case 0x80: // end of display set segment
846 // eDebug("end of display set segment");
847 subtitle_redraw_all();
850 case 0xFF: // stuffing
853 eDebug("unhandled segment type %02x", segment_type);
856 return segment_length + 6;
859 void eDVBSubtitleParser::subtitle_process_pes(__u8 *pkt, int len)
861 // eDebugNoNewLine("subtitle_process_pes");
862 if (!extract_pts(m_show_time, pkt))
864 // eDebug(" %lld", m_show_time);
870 int hdr_len = *pkt++; len--;
872 pkt+=hdr_len; len-=hdr_len;
876 // eDebug("data identifier is 0x%02x, but not 0x20", *pkt);
879 pkt++; len--; // data identifier
880 *pkt++; len--; // stream id;
884 // eDebug("no data left (%d)", len);
890 while (len && *pkt == 0x0F)
892 int l = subtitle_process_segment(pkt);
899 if (len && *pkt != 0xFF)
900 eDebug("strange data at the end");
903 subtitle_redraw_all();
909 void eDVBSubtitleParser::subtitle_redraw_all()
912 subtitle_page *page = m_pages;
915 if (page->state != 0)
916 subtitle_redraw(page->page_id);
920 subtitle_page *page = m_pages;
921 eDebug("----------- end of display set");
922 eDebug("active pages:");
925 eDebug(" page_id %02x", page->page_id);
926 eDebug(" page_version_number: %d", page->page_version_number);
927 eDebug(" active regions:");
929 subtitle_page_region *region = page->page_regions;
932 eDebug(" region_id: %04x", region->region_id);
933 eDebug(" region_horizontal_address: %d", region->region_horizontal_address);
934 eDebug(" region_vertical_address: %d", region->region_vertical_address);
936 region = region->next;
940 subtitle_redraw(page->page_id);
941 eDebug("defined regions:");
942 subtitle_region *region = page->regions;
945 eDebug(" region_id %04x, version %d, %dx%d", region->region_id, region->version_number, region->width, region->height);
947 subtitle_region_object *object = region->objects;
950 eDebug(" object %02x, type %d, %d:%d", object->object_id, object->object_type, object->object_horizontal_position, object->object_vertical_position);
951 object = object->next;
953 region = region->next;
960 void eDVBSubtitleParser::subtitle_reset()
962 while (subtitle_page *page = m_pages)
964 /* free page regions */
965 while (page->page_regions)
967 subtitle_page_region *p = page->page_regions->next;
968 delete page->page_regions;
969 page->page_regions = p;
972 while (page->regions)
974 subtitle_region *region = page->regions;
976 while (region->objects)
978 subtitle_region_object *obj = region->objects;
979 region->objects = obj->next;
985 // eDebug("no more need of buffer 2 %p", &(*region->buffer));
989 page->regions = region->next;
996 subtitle_clut *clut = page->cluts;
997 page->cluts = clut->next;
1001 m_pages = page->next;
1006 void eDVBSubtitleParser::subtitle_redraw(int page_id)
1008 subtitle_page *page = m_pages;
1010 // eDebug("displaying page id %d", page_id);
1014 if (page->page_id == page_id)
1020 // eDebug("page not found");
1024 // eDebug("iterating regions..");
1025 /* iterate all regions in this pcs */
1026 subtitle_page_region *region = page->page_regions;
1028 eDVBSubtitlePage Page;
1029 Page.m_show_time = m_show_time;
1030 for (; region; region=region->next)
1032 // eDebug("region %d", region->region_id);
1033 /* find corresponding region */
1034 subtitle_region *reg = page->regions;
1037 if (reg->region_id == region->region_id)
1045 // eDebug("copy region %d to %d, %d", region->region_id, region->region_horizontal_address, region->region_vertical_address);
1047 int x0 = region->region_horizontal_address;
1048 int y0 = region->region_vertical_address;
1050 if ((x0 < 0) || (y0 < 0))
1052 // eDebug("x0 %d, y0 %d", x0, y0);
1056 /* find corresponding clut */
1057 subtitle_clut *clut = page->cluts;
1060 // eDebug("have %d, want %d", clut->clut_id, main_clut_id);
1061 if (clut->clut_id == reg->clut_id)
1066 int clut_size = reg->buffer->surface->clut.colors = reg->depth == subtitle_region::bpp2 ?
1067 4 : reg->depth == subtitle_region::bpp4 ? 16 : 256;
1069 reg->buffer->surface->clut.data = new gRGB[clut_size];
1070 // eDebug("create clut data for buffer %p", &(*reg->buffer));
1072 gRGB *palette = reg->buffer->surface->clut.data;
1075 // eDebug("no CLUT.. use default");
1077 subtitle_clut_entry *entries=0;
1080 case subtitle_region::bpp2:
1083 entries = clut->entries_2bit;
1084 memset(palette, 0, 4 * sizeof(gRGB));
1085 // this table is tested on cyfra .. but in EN300743 the table palette[2] and palette[1] is swapped.. i dont understand this ;)
1086 palette[0].a = 0xFF;
1087 palette[2].r = palette[2].g = palette[2].b = 0xFF;
1088 palette[3].r = palette[3].g = palette[3].b = 0x80;
1090 case subtitle_region::bpp4: // tested on cyfra... but the map is another in EN300743... dont understand this...
1093 entries = clut->entries_4bit;
1094 memset(palette, 0, 16*sizeof(gRGB));
1095 for (int i=0; i < 16; ++i)
1098 palette[i].a = 0xFF;
1102 palette[i].r = 0x80;
1104 palette[i].g = 0x80;
1106 palette[i].b = 0x80;
1111 palette[i].r = 0xFF;
1113 palette[i].g = 0xFF;
1115 palette[i].b = 0xFF;
1119 case subtitle_region::bpp8: // completely untested.. i never seen 8bit DVB subtitles
1122 entries = clut->entries_8bit;
1123 memset(palette, 0, 256*sizeof(gRGB));
1124 for (int i=0; i < 256; ++i)
1128 case 0: // b1 == 0 && b5 == 0
1129 if (!(i & 14)) // b2 == 0 && b3 == 0 && b4 == 0
1131 if (!(i & 224)) // b6 == 0 && b7 == 0 && b8 == 0
1132 palette[i].a = 0xFF;
1135 if (i & 128) // R = 100% x b8
1136 palette[i].r = 0xFF;
1137 if (i & 64) // G = 100% x b7
1138 palette[i].g = 0xFF;
1139 if (i & 32) // B = 100% x b6
1140 palette[i].b = 0xFF;
1141 palette[i].a = 0xBF; // T = 75%
1146 case 16: // b1 == 0 && b5 == 1
1147 if (i & 128) // R = 33% x b8
1148 palette[i].r = 0x55;
1149 if (i & 64) // G = 33% x b7
1150 palette[i].g = 0x55;
1151 if (i & 32) // B = 33% x b6
1152 palette[i].b = 0x55;
1153 if (i & 8) // R + 66,7% x b4
1154 palette[i].r += 0xAA;
1155 if (i & 4) // G + 66,7% x b3
1156 palette[i].g += 0xAA;
1157 if (i & 2) // B + 66,7% x b2
1158 palette[i].b += 0xAA;
1159 if (i & 16) // needed for fall through from case 0!!
1160 palette[i].a = 0x80; // T = 50%
1162 case 1: // b1 == 1 && b5 == 0
1165 palette[i].b = 0x80; // 50%
1167 case 17: // b1 == 1 && b5 == 1
1168 if (i & 128) // R += 16.7% x b8
1169 palette[i].r += 0x2A;
1170 if (i & 64) // G += 16.7% x b7
1171 palette[i].g += 0x2A;
1172 if (i & 32) // B += 16.7% x b6
1173 palette[i].b += 0x2A;
1174 if (i & 8) // R += 33% x b4
1175 palette[i].r += 0x55;
1176 if (i & 4) // G += 33% x b3
1177 palette[i].g += 0x55;
1178 if (i & 2) // B += 33% x b2
1179 palette[i].b += 0x55;
1186 int bgopacity = ePythonConfigQuery::getConfigIntValue("config.subtitles.subtitle_bgopacity");
1187 int fontcolor = ePythonConfigQuery::getConfigIntValue("config.subtitles.subtitle_fontcolor");
1188 for (int i=0; i<clut_size; ++i)
1190 if (entries && entries[i].valid)
1192 int y = entries[i].Y,
1201 if (fontcolor == FONTCOLOR_WHITE || fontcolor == FONTCOLOR_BLACK)
1207 palette[i].r = MAX(MIN(((298 * y + 460 * cr) / 256), 255), 0);
1208 palette[i].g = MAX(MIN(((298 * y - 55 * cb - 137 * cr) / 256), 255), 0);
1209 palette[i].b = MAX(MIN(((298 * y + 543 * cb ) / 256), 255), 0);
1212 case FONTCOLOR_YELLOW:
1215 case FONTCOLOR_GREEN:
1219 case FONTCOLOR_CYAN:
1222 case FONTCOLOR_BLUE:
1226 case FONTCOLOR_MAGNETA:
1233 case FONTCOLOR_BLACK:
1234 palette[i].r = 255 - palette[i].r;
1235 palette[i].g = 255 - palette[i].g;
1236 palette[i].b = 255 - palette[i].b;
1244 if (palette[i].r || palette[i].g || palette[i].b)
1245 palette[i].a = (entries[i].T) & 0xFF;
1247 palette[i].a = bgopacity;
1252 if (fontcolor == FONTCOLOR_BLACK)
1256 if (255 - palette[i].r || 255 - palette[i].g || 255 - palette[i].b)
1257 palette[i].a = (entries[i].T) & 0xFF;
1259 palette[i].a = bgopacity;
1265 // eDebug("override clut entry %d RGBA %02x%02x%02x%02x", i,
1266 // palette[i].r, palette[i].g, palette[i].b, palette[i].a);
1270 // eDebug("mist %d: y %d cr %d cb %d", i, y, cr, cb);
1274 palette[i].a = 0xFF;
1277 // eDebug("%d:%c %02x %02x %02x %02x",
1278 // i, entries && entries[i].valid ? 'O': 'D', palette[i].r, palette[i].g, palette[i].b, palette[i].a);
1281 // eDebug("commit buffer %p", &(*reg->buffer));
1282 eDVBSubtitleRegion Region;
1283 Region.m_pixmap = reg->buffer;
1284 Region.m_position.setX(x0);
1285 Region.m_position.setY(y0);
1286 Page.m_regions.push_back(Region);
1287 reg->committed = true;
1290 // eDebug("region not found");
1292 Page.m_display_size = m_display_size;
1293 m_new_subtitle_page(Page);
1294 Page.m_regions.clear();
1295 // eDebug("page timeout is %d", page->page_time_out);
1296 // Page.m_show_time += (page->page_time_out * 90000);
1297 // m_new_subtitle_page(Page);
1298 // eDebug("schon gut.");
1301 DEFINE_REF(eDVBSubtitleParser);
1303 eDVBSubtitleParser::eDVBSubtitleParser(iDVBDemux *demux)
1304 :m_pages(0), m_display_size(720,576)
1308 if (demux->createPESReader(eApp, m_pes_reader))
1309 eDebug("failed to create dvb subtitle PES reader!");
1311 m_pes_reader->connectRead(slot(*this, &eDVBSubtitleParser::processData), m_read_connection);
1314 eDVBSubtitleParser::~eDVBSubtitleParser()
1319 int eDVBSubtitleParser::stop()
1323 eDebug("disable dvb subtitles");
1324 return m_pes_reader->stop();
1329 int eDVBSubtitleParser::start(int pid, int composition_page_id, int ancillary_page_id)
1333 eDebug("start dvb subtitles on pid 0x%04x with composition_page_id %d and ancillary_page_id %d",
1334 pid, composition_page_id, ancillary_page_id);
1335 m_composition_page_id = composition_page_id;
1336 m_ancillary_page_id = ancillary_page_id;
1337 return m_pes_reader->start(pid);
1342 void eDVBSubtitleParser::connectNewPage(const Slot1<void, const eDVBSubtitlePage&> &slot, ePtr<eConnection> &connection)
1344 connection = new eConnection(this, m_new_subtitle_page.connect(slot));