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>
14 void bitstream_init(bitstream *bit, const void *buffer, int size)
16 bit->data = (__u8*) buffer;
22 int bitstream_get(bitstream *bit)
25 bit->avail -= bit->size;
26 val = ((*bit->data) >> bit->avail) & ((1<<bit->size) - 1);
36 static int extract_pts(pts_t &pts, __u8 *pkt)
41 pkt++; // header length
43 if (flags & 0x80) /* PTS present? */
46 pts = ((unsigned long long)(((pkt[0] >> 1) & 7))) << 30;
48 pts |= (pkt[2]>>1) << 15;
57 void eDVBSubtitleParser::subtitle_process_line(subtitle_region *region, subtitle_region_object *object, int line, __u8 *data, int len)
59 int x = object->object_horizontal_position;
60 int y = object->object_vertical_position + line;
61 if (x + len > region->width)
63 // eDebug("[SUB] !!!! XCLIP %d + %d > %d", x, len, region->width);
64 len = region->width - x;
68 if (y >= region->height)
70 // eDebug("[SUB] !!!! YCLIP %d >= %d", y, region->height);
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);
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];
82 int eDVBSubtitleParser::subtitle_process_pixel_data(subtitle_region *region, subtitle_region_object *object, int *linenr, int *linep, __u8 *data)
84 int data_type = *data++;
85 static __u8 line[1920];
91 case 0x10: // 2bit pixel data
92 // eDebug("2bit pixel data!");
93 bitstream_init(&bit, data, 2);
97 int code = bitstream_get(&bit);
104 code = bitstream_get(&bit);
107 code = bitstream_get(&bit);
112 } else if (code == 2)
114 len = bitstream_get(&bit) << 2;
115 len |= bitstream_get(&bit);
117 col = bitstream_get(&bit);
118 } else if (code == 3)
120 len = bitstream_get(&bit) << 6;
121 len |= bitstream_get(&bit) << 4;
122 len |= bitstream_get(&bit) << 2;
123 len |= bitstream_get(&bit);
125 col = bitstream_get(&bit);
135 len = 3 + 4 + bitstream_get(&bit);
137 len = 3 + bitstream_get(&bit);
138 col = bitstream_get(&bit);
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()))
147 line[(*linep)++] = c;
151 while (bit.avail != 8)
153 return bit.consumed + 1;
154 case 0x11: // 4bit pixel data
155 // eDebug("4bit pixel data!");
156 bitstream_init(&bit, data, 4);
160 int code = bitstream_get(&bit);
167 code = bitstream_get(&bit);
170 else if (code == 0xC)
174 } else if (code == 0xD)
181 len = (code & 7) + 2;
182 } else if ((code & 0xC) == 0x8)
184 col = bitstream_get(&bit);
185 len = (code & 3) + 4;
186 } else if (code == 0xE)
188 len = bitstream_get(&bit) + 9;
189 col = bitstream_get(&bit);
190 } else if (code == 0xF)
192 len = bitstream_get(&bit) << 4;
193 len |= bitstream_get(&bit);
195 col = bitstream_get(&bit);
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()))
202 line[(*linep)++] = c;
206 while (bit.avail != 8)
208 return bit.consumed + 1;
209 case 0x12: // 8bit pixel data
210 // eDebug("8bit pixel data!");
211 bitstream_init(&bit, data, 8);
215 int code = bitstream_get(&bit);
222 code = bitstream_get(&bit);
223 if ((code & 0x80) == 0x80)
226 col = bitstream_get(&bit);
227 } else if (code&0x7F)
234 while (len && ((*linep) < m_display_size.width()))
236 line[(*linep)++] = col;
240 return bit.consumed + 1;
242 // eDebugNoNewLine("2 -> 4 bit table: ");
243 bitstream_init(&bit, data, 4);
244 for ( int i=0; i < 4; ++i )
246 map_2_to_4_bit_table[i] = bitstream_get(&bit);
247 // eDebugNoNewLine("%d ", map_2_to_4_bit_table[i]);
250 return bit.consumed + 1;
252 // eDebugNoNewLine("2 -> 8 bit table: ");
253 bitstream_init(&bit, data, 8);
254 for ( int i=0; i < 4; ++i )
256 map_2_to_8_bit_table[i] = bitstream_get(&bit);
257 // eDebugNoNewLine("%d ", map_2_to_8_bit_table[i]);
259 return bit.consumed + 1;
261 // eDebug("4 -> 8 bit table!");
262 bitstream_init(&bit, data, 8);
263 for ( int i=0; i < 16; ++i )
265 map_4_to_8_bit_table[i] = bitstream_get(&bit);
266 // eDebugNoNewLine("%d ", map_4_to_8_bit_table[i]);
268 return bit.consumed + 1;
270 subtitle_process_line(region, object, *linenr, line, *linep);
273 for (i=0; i<m_display_size.width(); ++i)
274 eDebugNoNewLine("%d ", line[i]);
277 (*linenr)+=2; // interlaced
279 // eDebug("[SUB] EOL");
282 eDebug("subtitle_process_pixel_data: invalid data_type %02x", data_type);
288 int eDVBSubtitleParser::subtitle_process_segment(__u8 *segment)
290 int segment_type, page_id, segment_length, processed_length;
291 if (*segment++ != 0x0F)
293 eDebug("out of sync.");
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);
307 // eDebug("page_id %d, segtype %02x", page_id, segment_type);
309 subtitle_page *page, **ppage;
311 page = m_pages; ppage = &m_pages;
315 if (page->page_id == page_id)
321 processed_length = 0;
323 switch (segment_type)
325 case 0x10: // page composition segment
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);
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);
340 // eDebug("page not found");
341 page = new subtitle_page;
342 page->page_regions = 0;
344 page->page_id = page_id;
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)
355 // eDebug("skip data... ");
360 page->state = page_state;
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))
366 while (page->page_regions)
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;
373 while (page->regions)
375 subtitle_region *p = page->regions->next;
376 // eDebug("delete region %d", page->regions->region_id);
377 while(page->regions->objects)
379 // eDebug("delete region object");
380 subtitle_region_object *ob = page->regions->objects->next;
381 delete page->regions->objects;
382 page->regions->objects = ob;
384 delete page->regions;
390 // eDebug("new page.. (%d)", page_state);
392 page->page_time_out = page_time_out;
394 page->page_version_number = page_version_number;
396 subtitle_page_region **r = &page->page_regions;
398 // eDebug("%d / %d data left", processed_length, segment_length);
404 if (processed_length == segment_length && !page->page_regions)
406 // eDebug("no regions in page.. clear screen!!");
407 subtitle_redraw(page->page_id);
410 while (processed_length < segment_length)
412 subtitle_page_region *pr;
414 // append new entry to list
415 pr = new subtitle_page_region;
420 pr->region_id = *segment++; processed_length++;
421 segment++; processed_length++;
423 pr->region_horizontal_address = *segment++ << 8;
424 pr->region_horizontal_address |= *segment++;
425 processed_length += 2;
427 pr->region_vertical_address = *segment++ << 8;
428 pr->region_vertical_address |= *segment++;
429 processed_length += 2;
431 // eDebug("appended active region");
434 if (processed_length != segment_length)
435 eDebug("%d != %d", processed_length, segment_length);
438 case 0x11: // region composition segment
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++;
445 // if we didn't yet received the pcs for this page, drop the region
448 eDebug("ignoring region %x, since page %02x doesn't yet exist.", region_id, page_id);
452 subtitle_region *region, **pregion;
454 region = page->regions; pregion = &page->regions;
459 if (region->region_id == region_id)
461 pregion = ®ion->next;
462 region = region->next;
467 // eDebug("create region !!!!!!!!!!");
468 *pregion = region = new subtitle_region;
470 region->committed = false;
472 else if (region->version_number != version_number)
474 subtitle_region_object *objects = region->objects;
475 // eDebug("unequal version %p %p", objects, objects?objects->next:objects);
478 subtitle_region_object *n = objects->next;
484 // eDebug("no more need of buffer %p", &(*region->buffer));
487 region->committed = false;
492 // eDebug("region %d:%d update", page_id, region_id);
494 region->region_id = region_id;
495 region->version_number = version_number;
497 region->width = *segment++ << 8;
498 region->width |= *segment++;
499 processed_length += 2;
501 region->height = *segment++ << 8;
502 region->height |= *segment++;
503 processed_length += 2;
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));
509 int region_level_of_compatibility, depth;
511 region_level_of_compatibility = (*segment >> 5) & 7;
512 depth = (*segment++ >> 2) & 7;
514 region->depth = (subtitle_region::tDepth) depth;
517 int CLUT_id = *segment++; processed_length++;
519 region->clut_id = CLUT_id;
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;
527 if (!region_fill_flag)
529 region_2bit_pixel_code = region_4bit_pixel_code = region_8bit_pixel_code = 0;
530 region_fill_flag = 1;
533 if (region_fill_flag)
535 // eDebug("region fill buffer %p", &(*region->buffer));
537 memset(region->buffer->surface->data, region_2bit_pixel_code, region->height * region->width);
539 memset(region->buffer->surface->data, region_4bit_pixel_code, region->height * region->width);
541 memset(region->buffer->surface->data, region_8bit_pixel_code, region->height * region->width);
543 eDebug("!!!! invalid depth");
546 // eDebug("region %02x, version %d, %dx%d", region->region_id, region->version_number, region->width, region->height);
549 subtitle_region_object **pobject = ®ion->objects;
551 while (processed_length < segment_length)
553 subtitle_region_object *object;
555 object = new subtitle_region_object;
559 pobject = &object->next;
561 object->object_id = *segment++ << 8;
562 object->object_id |= *segment++; processed_length += 2;
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;
570 object->object_vertical_position = *segment++ << 8;
571 object->object_vertical_position |= *segment++ ;
572 processed_length += 2;
574 if ((object->object_type == 1) || (object->object_type == 2))
576 object->foreground_pixel_value = *segment++;
577 object->background_pixel_value = *segment++;
578 processed_length += 2;
582 if (processed_length != segment_length)
583 eDebug("too less data! (%d < %d)", segment_length, processed_length);
587 case 0x12: // CLUT definition segment
589 int CLUT_id, CLUT_version_number;
590 subtitle_clut *clut, **pclut;
595 // eDebug("CLUT: %02x", *segment);
596 CLUT_id = *segment++;
598 CLUT_version_number = *segment++ >> 4;
599 processed_length += 2;
601 // eDebug("page %d, CLUT %02x, version %d", page->page_id, CLUT_id, CLUT_version_number);
603 clut = page->cluts; pclut = &page->cluts;
607 if (clut->clut_id == CLUT_id)
615 *pclut = clut = new subtitle_clut;
617 clut->clut_id = CLUT_id;
619 else if (clut->CLUT_version_number == CLUT_version_number)
622 clut->CLUT_version_number=CLUT_version_number;
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));
628 // eDebug("new Clut!");
629 while (processed_length < segment_length)
631 int CLUT_entry_id, entry_CLUT_flag, full_range;
632 int v_Y, v_Cr, v_Cb, v_T;
634 CLUT_entry_id = *segment++;
635 full_range = *segment & 1;
636 entry_CLUT_flag = (*segment++ & 0xE0) >> 5;
637 processed_length += 2;
641 // eDebugNoNewLine("f");
646 processed_length += 4;
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;
658 if (entry_CLUT_flag & 1) // 8bit
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;
667 if (entry_CLUT_flag & 2) // 4bit
669 // eDebugNoNewLine("4b");
670 if (CLUT_entry_id < 16)
672 clut->entries_4bit[CLUT_entry_id].Y = v_Y;
673 clut->entries_4bit[CLUT_entry_id].Cr = v_Cr;
674 clut->entries_4bit[CLUT_entry_id].Cb = v_Cb;
675 clut->entries_4bit[CLUT_entry_id].T = v_T;
676 clut->entries_4bit[CLUT_entry_id].valid = 1;
679 eDebug("CLUT entry marked as 4 bit with id %d (>15)", CLUT_entry_id);
681 if (entry_CLUT_flag & 4) // 2bit
683 // eDebugNoNewLine("2b");
684 if (CLUT_entry_id < 4)
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;
693 eDebug("CLUT entry marked as 2 bit with id %d (>3)", CLUT_entry_id);
695 // eDebug(" %04x %02x %02x %02x %02x", CLUT_entry_id, v_Y, v_Cb, v_Cr, v_T);
699 case 0x13: // object data segment
701 int object_id, object_version_number, object_coding_method, non_modifying_color_flag;
703 object_id = *segment++ << 8;
704 object_id |= *segment++;
705 processed_length += 2;
707 object_version_number = *segment >> 4;
708 object_coding_method = (*segment >> 2) & 3;
709 non_modifying_color_flag = (*segment++ >> 1) & 1;
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);
717 subtitle_region_object *object = region->objects;
720 if (object->object_id == object_id)
722 if (object_coding_method == 0)
724 int top_field_data_blocklength, bottom_field_data_blocklength;
725 int i=1, line, linep;
727 top_field_data_blocklength = *segment++ << 8;
728 top_field_data_blocklength |= *segment++;
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;
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;
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;
747 map_4_to_8_bit_table[0] = 0;
749 map_4_to_8_bit_table[i] = i * 0x11;
754 while (i < top_field_data_blocklength)
757 len = subtitle_process_pixel_data(region, object, &line, &linep, segment);
761 processed_length += len;
768 if (bottom_field_data_blocklength)
771 while (i < bottom_field_data_blocklength)
774 len = subtitle_process_pixel_data(region, object, &line, &linep, segment);
778 processed_length += len;
782 else if (top_field_data_blocklength)
783 eDebug("!!!! unimplemented: no bottom field! (%d : %d)", top_field_data_blocklength, bottom_field_data_blocklength);
785 if ((top_field_data_blocklength + bottom_field_data_blocklength) & 1)
787 segment++; processed_length++;
790 else if (object_coding_method == 1)
791 eDebug("---- object_coding_method 1 unsupported!");
793 object = object->next;
795 region = region->next;
799 case 0x14: // display definition segment
801 if (segment_length > 4)
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)
813 if (segment_length > 12)
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;
827 eDebug("display window flag set but display definition segment to short %d!", segment_length);
831 eDebug("display definition segment to short %d!", segment_length);
834 case 0x80: // end of display set segment
836 // eDebug("end of display set segment");
837 subtitle_redraw_all();
840 case 0xFF: // stuffing
843 eDebug("unhandled segment type %02x", segment_type);
846 return segment_length + 6;
849 void eDVBSubtitleParser::subtitle_process_pes(__u8 *pkt, int len)
851 // eDebugNoNewLine("subtitle_process_pes");
852 if (!extract_pts(m_show_time, pkt))
854 // eDebug(" %lld", m_show_time);
860 int hdr_len = *pkt++; len--;
862 pkt+=hdr_len; len-=hdr_len;
866 // eDebug("data identifier is 0x%02x, but not 0x20", *pkt);
869 pkt++; len--; // data identifier
870 *pkt++; len--; // stream id;
874 // eDebug("no data left (%d)", len);
880 while (len && *pkt == 0x0F)
882 int l = subtitle_process_segment(pkt);
889 if (len && *pkt != 0xFF)
890 eDebug("strange data at the end");
893 subtitle_redraw_all();
899 void eDVBSubtitleParser::subtitle_redraw_all()
902 subtitle_page *page = m_pages;
905 if (page->state != 0)
906 subtitle_redraw(page->page_id);
910 subtitle_page *page = m_pages;
911 eDebug("----------- end of display set");
912 eDebug("active pages:");
915 eDebug(" page_id %02x", page->page_id);
916 eDebug(" page_version_number: %d", page->page_version_number);
917 eDebug(" active regions:");
919 subtitle_page_region *region = page->page_regions;
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);
926 region = region->next;
930 subtitle_redraw(page->page_id);
931 eDebug("defined regions:");
932 subtitle_region *region = page->regions;
935 eDebug(" region_id %04x, version %d, %dx%d", region->region_id, region->version_number, region->width, region->height);
937 subtitle_region_object *object = region->objects;
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;
943 region = region->next;
950 void eDVBSubtitleParser::subtitle_reset()
952 while (subtitle_page *page = m_pages)
954 /* free page regions */
955 while (page->page_regions)
957 subtitle_page_region *p = page->page_regions->next;
958 delete page->page_regions;
959 page->page_regions = p;
962 while (page->regions)
964 subtitle_region *region = page->regions;
966 while (region->objects)
968 subtitle_region_object *obj = region->objects;
969 region->objects = obj->next;
975 // eDebug("no more need of buffer 2 %p", &(*region->buffer));
979 page->regions = region->next;
986 subtitle_clut *clut = page->cluts;
987 page->cluts = clut->next;
991 m_pages = page->next;
996 void eDVBSubtitleParser::subtitle_redraw(int page_id)
998 subtitle_page *page = m_pages;
1000 // eDebug("displaying page id %d", page_id);
1004 if (page->page_id == page_id)
1010 // eDebug("page not found");
1014 // eDebug("iterating regions..");
1015 /* iterate all regions in this pcs */
1016 subtitle_page_region *region = page->page_regions;
1018 eDVBSubtitlePage Page;
1019 Page.m_show_time = m_show_time;
1020 for (; region; region=region->next)
1022 // eDebug("region %d", region->region_id);
1023 /* find corresponding region */
1024 subtitle_region *reg = page->regions;
1027 if (reg->region_id == region->region_id)
1035 // eDebug("copy region %d to %d, %d", region->region_id, region->region_horizontal_address, region->region_vertical_address);
1037 int x0 = region->region_horizontal_address;
1038 int y0 = region->region_vertical_address;
1040 if ((x0 < 0) || (y0 < 0))
1042 // eDebug("x0 %d, y0 %d", x0, y0);
1046 /* find corresponding clut */
1047 subtitle_clut *clut = page->cluts;
1050 // eDebug("have %d, want %d", clut->clut_id, main_clut_id);
1051 if (clut->clut_id == reg->clut_id)
1056 int clut_size = reg->buffer->surface->clut.colors = reg->depth == subtitle_region::bpp2 ?
1057 4 : reg->depth == subtitle_region::bpp4 ? 16 : 256;
1059 reg->buffer->surface->clut.data = new gRGB[clut_size];
1060 // eDebug("create clut data for buffer %p", &(*reg->buffer));
1062 gRGB *palette = reg->buffer->surface->clut.data;
1065 // eDebug("no CLUT.. use default");
1067 subtitle_clut_entry *entries=0;
1070 case subtitle_region::bpp2:
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;
1080 case subtitle_region::bpp4: // tested on cyfra... but the map is another in EN300743... dont understand this...
1083 entries = clut->entries_4bit;
1084 memset(palette, 0, 16*sizeof(gRGB));
1085 for (int i=0; i < 16; ++i)
1088 palette[i].a = 0xFF;
1092 palette[i].r = 0x80;
1094 palette[i].g = 0x80;
1096 palette[i].b = 0x80;
1101 palette[i].r = 0xFF;
1103 palette[i].g = 0xFF;
1105 palette[i].b = 0xFF;
1109 case subtitle_region::bpp8: // completely untested.. i never seen 8bit DVB subtitles
1112 entries = clut->entries_8bit;
1113 memset(palette, 0, 256*sizeof(gRGB));
1114 for (int i=0; i < 256; ++i)
1118 case 0: // b1 == 0 && b5 == 0
1119 if (!(i & 14)) // b2 == 0 && b3 == 0 && b4 == 0
1121 if (!(i & 224)) // b6 == 0 && b7 == 0 && b8 == 0
1122 palette[i].a = 0xFF;
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%
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%
1152 case 1: // b1 == 1 && b5 == 0
1155 palette[i].b = 0x80; // 50%
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;
1176 for (int i=0; i<clut_size; ++i)
1178 if (entries && entries[i].valid)
1180 int y = entries[i].Y,
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);
1197 // eDebug("mist %d: y %d cr %d cb %d", i, y, cr, cb);
1201 palette[i].a = 0xFF;
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);
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;
1217 // eDebug("region not found");
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.");
1228 DEFINE_REF(eDVBSubtitleParser);
1230 eDVBSubtitleParser::eDVBSubtitleParser(iDVBDemux *demux)
1231 :m_pages(0), m_display_size(720,576)
1235 if (demux->createPESReader(eApp, m_pes_reader))
1236 eDebug("failed to create dvb subtitle PES reader!");
1238 m_pes_reader->connectRead(slot(*this, &eDVBSubtitleParser::processData), m_read_connection);
1241 eDVBSubtitleParser::~eDVBSubtitleParser()
1246 int eDVBSubtitleParser::stop()
1250 eDebug("disable dvb subtitles");
1251 return m_pes_reader->stop();
1256 int eDVBSubtitleParser::start(int pid, int composition_page_id, int ancillary_page_id)
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);
1269 void eDVBSubtitleParser::connectNewPage(const Slot1<void, const eDVBSubtitlePage&> &slot, ePtr<eConnection> &connection)
1271 connection = new eConnection(this, m_new_subtitle_page.connect(slot));