1 /*
2 * Copyright (C) 2010-2020 the xine project
3 *
4 * This file is part of xine, a free video player.
5 *
6 * xine is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * xine is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 *
20 * DVB Subtitle decoder (ETS 300 743)
21 * (c) 2004 Mike Lampard <mlampard@users.sourceforge.net>
22 * based on the application dvbsub by Dave Chapman
23 *
24 * TODO:
25 * - Implement support for teletext based subtitles
26 */
27
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #include <time.h>
33 #include <pthread.h>
34 #include <errno.h>
35
36 /*#define LOG*/
37 #define LOG_MODULE "spudvb"
38
39 #include <xine/xine_internal.h>
40 #include <xine/spu.h>
41 #include <xine/osd.h>
42
43 #include "xine-engine/bswap.h"
44
45 #define MAX_REGIONS 16
46
47 #define SPU_MAX_WIDTH 1920
48 #define SPU_MAX_HEIGHT 1080
49
50 /* sparse_array - handle large arrays efficiently when only a few entries are used */
51
52 typedef struct {
53 uint32_t key, value;
54 } sparse_array_entry_t;
55
56 typedef struct {
57 uint32_t sorted_entries, used_entries, max_entries;
58 sparse_array_entry_t *entries;
59 } sparse_array_t;
60
sparse_array_new(sparse_array_t * sa)61 static void sparse_array_new (sparse_array_t *sa) {
62 sa->sorted_entries =
63 sa->used_entries =
64 sa->max_entries = 0;
65 sa->entries = NULL;
66 }
67
sparse_array_delete(sparse_array_t * sa)68 static void sparse_array_delete (sparse_array_t *sa) {
69 sa->sorted_entries =
70 sa->used_entries =
71 sa->max_entries = 0;
72 _x_freep (&sa->entries);
73 }
74
_sparse_array_find(sparse_array_t * sa,uint32_t key,uint32_t * pos)75 static int _sparse_array_find (sparse_array_t *sa, uint32_t key, uint32_t *pos) {
76 uint32_t b = 0, m, e = sa->sorted_entries, l = e, k;
77 while (1) {
78 m = (b + e) >> 1;
79 if (m == l)
80 break;
81 l = m;
82 k = sa->entries[m].key;
83 if (k > key)
84 e = m;
85 else if (k < key)
86 b = m;
87 else {
88 *pos = m;
89 return 1;
90 }
91 }
92 *pos = e;
93 return 0;
94 }
95
_sparse_array_sort(sparse_array_t * sa)96 static void _sparse_array_sort (sparse_array_t *sa) {
97 uint32_t left = sa->max_entries - sa->used_entries;
98 /* move unsorted part to end of buf */
99 uint32_t i = left + sa->sorted_entries;
100 memmove (sa->entries + i, sa->entries + sa->sorted_entries,
101 (sa->used_entries - sa->sorted_entries) * sizeof (sparse_array_entry_t));
102 /* iterate it */
103 while (i < sa->max_entries) {
104 uint32_t j, pos, startkey, stopkey, lastkey;
105 startkey = sa->entries[i].key;
106 if (_sparse_array_find (sa, startkey, &pos)) {
107 /* eliminate duplicate */
108 sa->entries[pos].value = sa->entries[i].value;
109 i++;
110 continue;
111 }
112 /* find sorted range */
113 stopkey = pos < sa->sorted_entries ? sa->entries[pos].key : 0xffffffff;
114 lastkey = startkey;
115 for (j = i + 1; j < sa->max_entries; j++) {
116 uint32_t thiskey = sa->entries[j].key;
117 if ((thiskey <= lastkey) || (thiskey >= stopkey))
118 break;
119 lastkey = thiskey;
120 }
121 j -= i;
122 if (j > left)
123 j = left;
124 /* insert it */
125 if (pos < sa->sorted_entries)
126 memmove (sa->entries + pos + j, sa->entries + pos,
127 (sa->sorted_entries - pos) * sizeof (sparse_array_entry_t));
128 memcpy (sa->entries + pos, sa->entries + i, j * sizeof (sparse_array_entry_t));
129 sa->sorted_entries += j;
130 i += j;
131 }
132 sa->used_entries = sa->sorted_entries;
133 lprintf ("sparse_array_sort: %u entries\n", (unsigned int)sa->used_entries);
134 }
135
sparse_array_set(sparse_array_t * sa,uint32_t key,uint32_t value)136 static int sparse_array_set (sparse_array_t *sa, uint32_t key, uint32_t value) {
137 /* give some room for later sorting too */
138 if (!sa->entries || (sa->used_entries + 8 >= sa->max_entries)) {
139 uint32_t n = sa->max_entries + 128;
140 sparse_array_entry_t *se = realloc (sa->entries, n * sizeof (sparse_array_entry_t));
141 if (!se)
142 return 0;
143 sa->max_entries = n;
144 sa->entries = se;
145 }
146 sa->entries[sa->used_entries].key = key;
147 sa->entries[sa->used_entries++].value = value;
148 return 1;
149 }
150
sparse_array_get(sparse_array_t * sa,uint32_t key,uint32_t * value)151 static int sparse_array_get (sparse_array_t *sa, uint32_t key, uint32_t *value) {
152 uint32_t pos;
153 if (sa->sorted_entries != sa->used_entries)
154 _sparse_array_sort (sa);
155 if (!_sparse_array_find (sa, key, &pos))
156 return 0;
157 *value = sa->entries[pos].value;
158 return 1;
159 }
160
sparse_array_unset(sparse_array_t * sa,uint32_t key,uint32_t mask)161 static void sparse_array_unset (sparse_array_t *sa, uint32_t key, uint32_t mask) {
162 sparse_array_entry_t *here = sa->entries, *p = NULL, *q = sa->entries;
163 uint32_t i, n = 0;
164 if (sa->sorted_entries != sa->used_entries)
165 _sparse_array_sort (sa);
166 key &= mask;
167 for (i = sa->used_entries; i > 0; i--) {
168 if ((here->key & mask) == key) {
169 if (p) {
170 n = here - p;
171 if (n && (p != q))
172 memmove (q, p, n * sizeof (sparse_array_entry_t));
173 p = NULL;
174 q += n;
175 }
176 } else {
177 if (!p)
178 p = here;
179 }
180 here++;
181 }
182 if (p) {
183 n = here - p;
184 if (n && (p != q))
185 memmove (q, p, n * sizeof (sparse_array_entry_t));
186 q += n;
187 }
188 sa->sorted_entries =
189 sa->used_entries = q - sa->entries;
190 }
191
192 /* ! sparse_array */
193
194 typedef struct {
195 uint16_t x, y;
196 unsigned char is_visible;
197 } visible_region_t;
198
199 typedef struct {
200 uint8_t page_time_out;
201 uint8_t page_version_number;
202 uint8_t page_state;
203 uint16_t page_id;
204 visible_region_t regions[MAX_REGIONS];
205 } page_t;
206
207 typedef struct {
208 uint8_t version_number;
209 uint8_t empty;
210 uint8_t depth;
211 uint8_t CLUT_id;
212 uint16_t width, height;
213 unsigned char *img;
214 osd_object_t *osd;
215 } region_t;
216
217 typedef union {
218 clut_t c;
219 uint32_t u32;
220 } clut_union_t;
221
222 typedef struct {
223 uint8_t version_number;
224 uint8_t windowed;
225 uint16_t width;
226 uint16_t height;
227 /* window, TODO */
228 /* uint16_t x0, x1, y0, y1; */
229 } dds_t;
230
231 typedef struct {
232 /* dvbsub stuff */
233 int x;
234 int y;
235 unsigned int curr_obj;
236 unsigned int curr_reg[64];
237 uint8_t *buf;
238 int i;
239 int i_bits;
240 int compat_depth;
241 unsigned int max_regions;
242 page_t page;
243 dds_t dds;
244 region_t regions[MAX_REGIONS];
245 clut_union_t colours[MAX_REGIONS*256];
246 unsigned char trans[MAX_REGIONS*256];
247 struct {
248 unsigned char lut24[4], lut28[4], lut48[16];
249 } lut[MAX_REGIONS];
250 sparse_array_t object_pos;
251 } dvbsub_func_t;
252
253 typedef struct dvb_spu_decoder_s {
254 spu_decoder_t spu_decoder;
255
256 xine_stream_t *stream;
257
258 spu_dvb_descriptor_t spu_descriptor;
259
260 /* dvbsub_osd_mutex should be locked around all calls to this->osd_renderer->show()
261 and this->osd_renderer->hide() */
262 pthread_mutex_t dvbsub_osd_mutex;
263
264 char *pes_pkt_wrptr;
265 unsigned int pes_pkt_size;
266
267 int64_t vpts;
268
269 pthread_t dvbsub_timer_thread;
270 struct timespec dvbsub_hide_timeout;
271 pthread_cond_t dvbsub_restart_timeout;
272 dvbsub_func_t dvbsub;
273 int show;
274
275 char pes_pkt[65 * 1024];
276
277 } dvb_spu_decoder_t;
278
reset_clut(dvbsub_func_t * dvbsub)279 static void reset_clut (dvbsub_func_t *dvbsub)
280 {
281 // XXX This function is called only from spudec_reset().
282 // - would it be enough to just zero out these entries as when opening the decoder ... ?
283 unsigned int i, r;
284 unsigned char default_trans[256];
285 clut_t default_clut[256];
286
287 #define YUVA(r, g, b, a) (clut_t) { COMPUTE_V(r, g, b), COMPUTE_U(r, g, b), COMPUTE_V(r, g, b), a }
288 #define GETBIT(s, v1, v2, tr) \
289 r = s + ((i & 1) ? v1 : 0) + ((i & 0x10) ? v2 : 0); \
290 g = s + ((i & 2) ? v1 : 0) + ((i & 0x20) ? v2 : 0); \
291 b = s + ((i & 4) ? v1 : 0) + ((i & 0x40) ? v2 : 0); \
292 a = tr
293
294 default_clut[0] = YUVA(0, 0, 0, 0);
295 for (i = 1; i < 256; i++) {
296 uint8_t r, g, b, a;
297 if (i < 8) {
298 GETBIT(0, 255, 0, 63);
299 } else switch (i & 0x88) {
300 case 0x00: GETBIT( 0, 85, 170, 255); break;
301 case 0x08: GETBIT( 0, 85, 170, 127); break;
302 case 0x80: GETBIT(127, 43, 85, 255); break;
303 default : GETBIT( 0, 43, 85, 255); break;
304 }
305 default_trans[i] = a;
306 default_clut[i] = YUVA(r, g, b, a);
307 }
308
309 /* Reset the colour LUTs */
310 for (r = 0; r < MAX_REGIONS; ++r)
311 {
312 memcpy (dvbsub->colours + r * 256, default_clut, sizeof (default_clut));
313 memcpy (dvbsub->trans + r * 256, default_trans, sizeof (default_trans));
314 }
315
316 /* Reset the colour index LUTs */
317 for (r = 0; r < MAX_REGIONS; ++r)
318 {
319 dvbsub->lut[r].lut24[0] = 0x0;
320 dvbsub->lut[r].lut24[1] = 0x7;
321 dvbsub->lut[r].lut24[2] = 0x8;
322 dvbsub->lut[r].lut24[3] = 0xF;
323 dvbsub->lut[r].lut28[0] = 0x00;
324 dvbsub->lut[r].lut28[1] = 0x77;
325 dvbsub->lut[r].lut28[2] = 0x88;
326 dvbsub->lut[r].lut28[3] = 0xFF;
327 for (i = 0; i < 16; ++i)
328 dvbsub->lut[r].lut48[i] = i | i << 4;
329 }
330 }
331
update_region(region_t * reg,int region_id,int region_width,int region_height,int fill,int fill_color)332 static void update_region (region_t *reg, int region_id, int region_width, int region_height, int fill, int fill_color)
333 {
334 /* reject invalid sizes and set some limits ! */
335 if ( region_width<=0 || region_height<=0 || region_width>SPU_MAX_WIDTH || region_height>SPU_MAX_HEIGHT ) {
336 _x_freep( ®->img );
337 lprintf("rejected region %d = %dx%d\n", region_id, region_width, region_height );
338 return;
339 }
340
341 if ( reg->width*reg->height<region_width*region_height ) {
342 lprintf("update size of region %d = %dx%d\n", region_id, region_width, region_height);
343 _x_freep( ®->img );
344 }
345
346 if ( !reg->img ) {
347 if ( !(reg->img = calloc(1, region_width * region_height)) ) {
348 lprintf( "can't allocate mem for region %d\n", region_id );
349 return;
350 }
351 fill = 1;
352 }
353
354 if ( fill ) {
355 memset( reg->img, fill_color, region_width*region_height );
356 reg->empty = 1;
357 lprintf("FILL REGION %d\n", region_id);
358 }
359 reg->width = region_width;
360 reg->height = region_height;
361 }
362
363
do_plot(region_t * reg,int x,int y,unsigned char pixel)364 static void do_plot (region_t *reg, int x, int y, unsigned char pixel)
365 {
366 unsigned int i;
367
368 i = (y * reg->width) + x;
369 /* do some clipping */
370 if (i < reg->width * reg->height) {
371 reg->img[i] = pixel;
372 reg->empty = 0;
373 }
374 }
375
plot(dvbsub_func_t * dvbsub,int r,unsigned int run_length,unsigned char pixel)376 static void plot (dvbsub_func_t *dvbsub, int r, unsigned int run_length, unsigned char pixel)
377 {
378 int x2 = dvbsub->x + run_length;
379
380 while (dvbsub->x < x2) {
381 do_plot (&dvbsub->regions[r], dvbsub->x, dvbsub->y, pixel);
382 dvbsub->x++;
383 }
384 }
385
lookup_lut(const dvbsub_func_t * dvbsub,int r)386 static const uint8_t *lookup_lut (const dvbsub_func_t *dvbsub, int r)
387 {
388 static const uint8_t identity_lut[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
389
390 switch (dvbsub->compat_depth)
391 {
392 case 012: return dvbsub->lut[r].lut24;
393 case 013: return dvbsub->lut[r].lut28;
394 case 023: return dvbsub->lut[r].lut48;
395 default: return identity_lut;
396 }
397 }
398
next_datum(dvbsub_func_t * dvbsub,int width)399 static unsigned char next_datum (dvbsub_func_t *dvbsub, int width)
400 {
401 unsigned char x = 0;
402
403 if (!dvbsub->i_bits)
404 dvbsub->i_bits = 8;
405
406 if (dvbsub->i_bits < width)
407 {
408 /* need to read from more than one byte; split it up */
409 width -= dvbsub->i_bits;
410 x = dvbsub->buf[dvbsub->i++] & ((1 << dvbsub->i_bits) - 1);
411 dvbsub->i_bits = 8;
412 return x << width | next_datum (dvbsub, width);
413 }
414
415 dvbsub->i_bits = (dvbsub->i_bits - width) & 7;
416 x = (dvbsub->buf[dvbsub->i] >> dvbsub->i_bits) & ((1 << width) - 1);
417
418 if (!dvbsub->i_bits)
419 ++dvbsub->i;
420
421 return x;
422 }
423
decode_2bit_pixel_code_string(dvbsub_func_t * dvbsub,int r,int n)424 static void decode_2bit_pixel_code_string (dvbsub_func_t *dvbsub, int r, int n)
425 {
426 int j;
427 const uint8_t *lut = lookup_lut (dvbsub, r);
428
429 dvbsub->i_bits = 0;
430 j = dvbsub->i + n;
431
432 while (dvbsub->i < j)
433 {
434 unsigned int next_bits = next_datum (dvbsub, 2);
435 unsigned int run_length;
436
437 if (next_bits)
438 {
439 /* single pixel */
440 plot (dvbsub, r, 1, lut[next_bits]);
441 continue;
442 }
443
444 /* switch 1 */
445 if (next_datum (dvbsub, 1) == 0)
446 {
447 /* run length, 3 to 10 pixels, colour given */
448 run_length = next_datum (dvbsub, 3);
449 plot (dvbsub, r, run_length + 3, lut[next_datum (dvbsub, 2)]);
450 continue;
451 }
452
453 /* switch 2 */
454 if (next_datum (dvbsub, 1) == 1)
455 {
456 /* single pixel, colour 0 */
457 plot (dvbsub, r, 1, lut[0]);
458 continue;
459 }
460
461 /* switch 3 */
462 switch (next_datum (dvbsub, 2))
463 {
464 case 0: /* end-of-string */
465 j = dvbsub->i; /* set the while cause FALSE */
466 break;
467 case 1: /* two pixels, colour 0 */
468 plot (dvbsub, r, 2, lut[0]);
469 break;
470 case 2: /* run length, 12 to 27 pixels (4-bit), colour given */
471 run_length = next_datum (dvbsub, 4);
472 plot (dvbsub, r, run_length + 12, lut[next_datum (dvbsub, 2)]);
473 break;
474 case 3: /* run length, 29 to 284 pixels (8-bit), colour given */
475 run_length = next_datum (dvbsub, 8);
476 plot (dvbsub, r, run_length + 29, lut[next_datum (dvbsub, 2)]);
477 }
478 }
479
480 if (dvbsub->i_bits) {
481 dvbsub->i++;
482 dvbsub->i_bits = 0;
483 }
484 }
485
decode_4bit_pixel_code_string(dvbsub_func_t * dvbsub,int r,int n)486 static void decode_4bit_pixel_code_string (dvbsub_func_t *dvbsub, int r, int n)
487 {
488 int j;
489 const uint8_t *lut = lookup_lut (dvbsub, r);
490
491 dvbsub->i_bits = 0;
492 j = dvbsub->i + n;
493
494 while (dvbsub->i < j)
495 {
496 unsigned int next_bits = next_datum (dvbsub, 4);
497 unsigned int run_length;
498
499 if (next_bits)
500 {
501 /* single pixel */
502 plot (dvbsub, r, 1, lut[next_bits]);
503 continue;
504 }
505
506 /* switch 1 */
507 if (next_datum (dvbsub, 1) == 0)
508 {
509 run_length = next_datum (dvbsub, 3);
510 if (!run_length)
511 /* end-of-string */
512 break;
513
514 /* run length, 3 to 9 pixels, colour 0 */
515 plot (dvbsub, r, run_length + 2, lut[0]);
516 continue;
517 }
518
519 /* switch 2 */
520 if (next_datum (dvbsub, 1) == 0)
521 {
522 /* run length, 4 to 7 pixels, colour given */
523 run_length = next_datum (dvbsub, 2);
524 plot (dvbsub, r, run_length + 4, lut[next_datum (dvbsub, 4)]);
525 continue;
526 }
527
528 /* switch 3 */
529 switch (next_datum (dvbsub, 2))
530 {
531 case 0: /* single pixel, colour 0 */
532 plot (dvbsub, r, 1, lut[0]);
533 break;
534 case 1: /* two pixels, colour 0 */
535 plot (dvbsub, r, 2, lut[0]);
536 break;
537 case 2: /* run length, 9 to 24 pixels (4-bit), colour given */
538 run_length = next_datum (dvbsub, 4);
539 plot (dvbsub, r, run_length + 9, lut[next_datum (dvbsub, 4)]);
540 break;
541 case 3: /* run length, 25 to 280 pixels (8-bit), colour given */
542 run_length = next_datum (dvbsub, 8);
543 plot (dvbsub, r, run_length + 25, lut[next_datum (dvbsub, 4)]);
544 }
545 }
546
547 if (dvbsub->i_bits) {
548 dvbsub->i++;
549 dvbsub->i_bits = 0;
550 }
551 }
552
decode_8bit_pixel_code_string(dvbsub_func_t * dvbsub,int r,int n)553 static void decode_8bit_pixel_code_string (dvbsub_func_t *dvbsub, int r, int n)
554 {
555 int j;
556
557 j = dvbsub->i + n;
558
559 while (dvbsub->i < j)
560 {
561 unsigned int next_bits = dvbsub->buf[dvbsub->i++];
562 unsigned int run_length;
563
564 if (next_bits)
565 {
566 /* single pixel */
567 plot (dvbsub, r, 1, next_bits);
568 continue;
569 }
570
571 /* switch 1 */
572 run_length = dvbsub->buf[dvbsub->i] & 127;
573
574 if (dvbsub->buf[dvbsub->i++] & 128)
575 {
576 /* run length, 3 to 127 pixels, colour given */
577 if (run_length > 2)
578 plot (dvbsub, r, run_length + 4, dvbsub->buf[dvbsub->i++]);
579 continue;
580 }
581
582 if (!run_length)
583 /* end-of-string */
584 break;
585
586 /* run length, 1 to 127 pixels, colour 0 */
587 plot (dvbsub, r, run_length + 2, 0);
588 }
589 }
590
set_clut(dvbsub_func_t * dvbsub,int CLUT_id,int CLUT_entry_id,int Y_value,int Cr_value,int Cb_value,int T_value)591 static void set_clut(dvbsub_func_t *dvbsub, int CLUT_id,int CLUT_entry_id,int Y_value, int Cr_value, int Cb_value, int T_value) {
592
593 if ((CLUT_id>=MAX_REGIONS) || (CLUT_entry_id>255)) {
594 return;
595 }
596
597 dvbsub->colours[(CLUT_id*256)+CLUT_entry_id].c.y = Y_value;
598 dvbsub->colours[(CLUT_id*256)+CLUT_entry_id].c.cr = Cr_value;
599 dvbsub->colours[(CLUT_id*256)+CLUT_entry_id].c.cb = Cb_value;
600 dvbsub->colours[(CLUT_id*256)+CLUT_entry_id].c.foo = T_value;
601 }
602
process_CLUT_definition_segment(dvbsub_func_t * dvbsub)603 static void process_CLUT_definition_segment(dvbsub_func_t *dvbsub) {
604 int /*page_id,*/
605 segment_length,
606 CLUT_id/*,
607 CLUT_version_number*/;
608
609 int CLUT_entry_id,
610 /*CLUT_flag_8_bit,*/
611 /*CLUT_flag_4_bit,*/
612 /*CLUT_flag_2_bit,*/
613 full_range_flag,
614 Y_value,
615 Cr_value,
616 Cb_value,
617 T_value;
618
619 int j;
620
621 /*page_id=(dvbsub->buf[dvbsub->i]<<8)|dvbsub->buf[dvbsub->i+1];*/ dvbsub->i+=2;
622 segment_length=(dvbsub->buf[dvbsub->i]<<8)|dvbsub->buf[dvbsub->i+1]; dvbsub->i+=2;
623 j=dvbsub->i+segment_length;
624
625 CLUT_id=dvbsub->buf[dvbsub->i++];
626 lprintf ("process_CLUT_definition_segment: CLUT_id %d\n", CLUT_id);
627 /*CLUT_version_number=(dvbsub->buf[dvbsub->i]&0xf0)>>4;*/
628 dvbsub->i++;
629
630 while (dvbsub->i < j) {
631 CLUT_entry_id=dvbsub->buf[dvbsub->i++];
632
633 /*CLUT_flag_2_bit=(dvbsub->buf[dvbsub->i]&0x80)>>7;*/
634 /*CLUT_flag_4_bit=(dvbsub->buf[dvbsub->i]&0x40)>>6;*/
635 /*CLUT_flag_8_bit=(dvbsub->buf[dvbsub->i]&0x20)>>5;*/
636 full_range_flag=dvbsub->buf[dvbsub->i]&1;
637 dvbsub->i++;
638
639 if (full_range_flag==1) {
640 Y_value=dvbsub->buf[dvbsub->i++];
641 Cr_value=dvbsub->buf[dvbsub->i++];
642 Cb_value=dvbsub->buf[dvbsub->i++];
643 T_value=dvbsub->buf[dvbsub->i++];
644 } else {
645 Y_value = dvbsub->buf[dvbsub->i] & 0xfc;
646 Cr_value = (dvbsub->buf[dvbsub->i] << 6 | dvbsub->buf[dvbsub->i + 1] >> 2) & 0xf0;
647 Cb_value = (dvbsub->buf[dvbsub->i + 1] << 2) & 0xf0;
648 T_value = (dvbsub->buf[dvbsub->i + 1] & 3) * 0x55; /* expand only this one to full range! */
649 dvbsub->i+=2;
650 }
651 set_clut(dvbsub, CLUT_id,CLUT_entry_id,Y_value,Cr_value,Cb_value,T_value);
652 }
653 }
654
process_pixel_data_sub_block(dvbsub_func_t * dvbsub,int r,unsigned int pos,int ofs,int n)655 static void process_pixel_data_sub_block (dvbsub_func_t *dvbsub, int r, unsigned int pos, int ofs, int n)
656 {
657 int data_type;
658 int j;
659
660 j = dvbsub->i + n;
661
662 dvbsub->x = pos >> 16;
663 dvbsub->y = (pos & 0xffff) + ofs;
664 while (dvbsub->i < j) {
665 data_type = dvbsub->buf[dvbsub->i++];
666
667 switch (data_type) {
668 case 0:
669 dvbsub->i++;
670 case 0x10:
671 decode_2bit_pixel_code_string (dvbsub, r, n - 1);
672 break;
673 case 0x11:
674 decode_4bit_pixel_code_string (dvbsub, r, n - 1);
675 break;
676 case 0x12:
677 decode_8bit_pixel_code_string (dvbsub, r, n - 1);
678 break;
679 case 0x20: /* 2-to-4bit colour index map */
680 /* should this be implemented since we have an 8-bit overlay? */
681 dvbsub->lut[r].lut24[0] = dvbsub->buf[dvbsub->i ] >> 4;
682 dvbsub->lut[r].lut24[1] = dvbsub->buf[dvbsub->i ] & 0x0f;
683 dvbsub->lut[r].lut24[2] = dvbsub->buf[dvbsub->i + 1] >> 4;
684 dvbsub->lut[r].lut24[3] = dvbsub->buf[dvbsub->i + 1] & 0x0f;
685 dvbsub->i += 2;
686 break;
687 case 0x21: /* 2-to-8bit colour index map */
688 memcpy (dvbsub->lut[r].lut28, dvbsub->buf + dvbsub->i, 4);
689 dvbsub->i += 4;
690 break;
691 case 0x22:
692 memcpy (dvbsub->lut[r].lut48, dvbsub->buf + dvbsub->i, 16);
693 dvbsub->i += 16;
694 break;
695 case 0xf0:
696 dvbsub->x = pos >> 16;
697 dvbsub->y += 2;
698 break;
699 default:
700 lprintf ("unimplemented data_type %02x in pixel_data_sub_block\n", data_type);
701 }
702 }
703
704 dvbsub->i = j;
705 }
706
process_page_composition_segment(dvbsub_func_t * dvbsub)707 static void process_page_composition_segment (dvbsub_func_t *dvbsub)
708 {
709 int segment_length;
710 unsigned int region_id, region_x, region_y;
711
712 dvbsub->page.page_id = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1];
713 dvbsub->i += 2;
714 segment_length = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1];
715 dvbsub->i += 2;
716
717 int j = dvbsub->i + segment_length;
718
719 dvbsub->page.page_time_out = dvbsub->buf[dvbsub->i++];
720 if ( dvbsub->page.page_time_out>6 ) /* some timeout are insane, e.g. 65s ! */
721 dvbsub->page.page_time_out = 6;
722
723 int version = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4;
724 if ( version == dvbsub->page.page_version_number )
725 return;
726 dvbsub->page.page_version_number = version;
727 dvbsub->page.page_state = (dvbsub->buf[dvbsub->i] & 0x0c) >> 2;
728 dvbsub->i++;
729
730 unsigned int r;
731 for (r=0; r<dvbsub->max_regions; r++) { /* reset */
732 dvbsub->page.regions[r].is_visible = 0;
733 }
734
735 while (dvbsub->i < j) {
736 region_id = dvbsub->buf[dvbsub->i++];
737 dvbsub->i++; /* reserved */
738 region_x = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1];
739 dvbsub->i += 2;
740 region_y = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1];
741 dvbsub->i += 2;
742 lprintf ("process_page_composition_segment: page_id %d, region_id %d, x %d, y %d\n",
743 dvbsub->page.page_id, region_id, region_x, region_y);
744 if (region_id >= MAX_REGIONS)
745 continue;
746 if (region_id >= dvbsub->max_regions)
747 dvbsub->max_regions = region_id + 1;
748
749 dvbsub->page.regions[region_id].x = region_x;
750 dvbsub->page.regions[region_id].y = region_y;
751 dvbsub->page.regions[region_id].is_visible = 1;
752 }
753 }
754
755
process_region_composition_segment(dvbsub_func_t * dvbsub)756 static void process_region_composition_segment (dvbsub_func_t *dvbsub)
757 {
758 unsigned int segment_length,
759 region_id,
760 region_version_number,
761 region_fill_flag, region_width, region_height, region_level_of_compatibility, region_depth, CLUT_id,
762 /*region_8_bit_pixel_code,*/ region_4_bit_pixel_code /*, region_2_bit_pixel_code*/;
763 unsigned int object_id, object_type, /*object_provider_flag,*/ object_x, object_y /*, foreground_pixel_code, background_pixel_code*/;
764 int j;
765
766 dvbsub->page.page_id = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1];
767 dvbsub->i += 2;
768 segment_length = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1];
769 dvbsub->i += 2;
770 j = dvbsub->i + segment_length;
771
772 region_id = dvbsub->buf[dvbsub->i++];
773 region_version_number = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4;
774 region_fill_flag = (dvbsub->buf[dvbsub->i] & 0x08) >> 3;
775 dvbsub->i++;
776 region_width = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1];
777 dvbsub->i += 2;
778 region_height = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1];
779 dvbsub->i += 2;
780 region_level_of_compatibility = (dvbsub->buf[dvbsub->i] & 0xe0) >> 5;
781 region_depth = (dvbsub->buf[dvbsub->i] & 0x1c) >> 2;
782 dvbsub->compat_depth = region_level_of_compatibility << 3 | region_depth;
783 dvbsub->i++;
784 CLUT_id = dvbsub->buf[dvbsub->i++];
785 /*region_8_bit_pixel_code = dvbsub->buf[*/dvbsub->i++/*]*/;
786 region_4_bit_pixel_code = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4;
787 /*region_2_bit_pixel_code = (dvbsub->buf[dvbsub->i] & 0x0c) >> 2;*/
788 dvbsub->i++;
789 lprintf ("process_region_composition_segment: region_id %d (%d x %d)\n", region_id, region_width, region_height);
790
791 if(region_id>=MAX_REGIONS)
792 return;
793
794 if (region_id >= dvbsub->max_regions)
795 dvbsub->max_regions = region_id + 1;
796
797 if ( dvbsub->regions[region_id].version_number == region_version_number )
798 return;
799
800 dvbsub->regions[region_id].version_number = region_version_number;
801
802 /* Check if region size has changed and fill background. */
803 update_region (&dvbsub->regions[region_id], region_id, region_width, region_height, region_fill_flag, region_4_bit_pixel_code);
804 if ( CLUT_id<MAX_REGIONS )
805 dvbsub->regions[region_id].CLUT_id = CLUT_id;
806
807 sparse_array_unset (&dvbsub->object_pos, region_id << 16, 0xff0000);
808
809 while (dvbsub->i < j) {
810 object_id = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1];
811 dvbsub->i += 2;
812 object_type = (dvbsub->buf[dvbsub->i] & 0xc0) >> 6;
813 /*object_provider_flag = (dvbsub->buf[dvbsub->i] & 0x30) >> 4;*/
814 object_x = ((dvbsub->buf[dvbsub->i] & 0x0f) << 8) | dvbsub->buf[dvbsub->i + 1];
815 dvbsub->i += 2;
816 object_y = ((dvbsub->buf[dvbsub->i] & 0x0f) << 8) | dvbsub->buf[dvbsub->i + 1];
817 dvbsub->i += 2;
818
819 sparse_array_set (&dvbsub->object_pos, (region_id << 16) | object_id, (object_x << 16) | object_y);
820
821 if ((object_type == 0x01) || (object_type == 0x02)) {
822 /*foreground_pixel_code = dvbsub->buf[*/dvbsub->i++/*]*/;
823 /*background_pixel_code = dvbsub->buf[*/dvbsub->i++/*]*/;
824 }
825 }
826
827 }
828
process_object_data_segment(dvbsub_func_t * dvbsub)829 static void process_object_data_segment (dvbsub_func_t *dvbsub)
830 {
831 unsigned int /*segment_length,*/ object_id/*, object_version_number*/, object_coding_method/*, non_modifying_colour_flag*/;
832
833 int top_field_data_block_length, bottom_field_data_block_length;
834
835 int old_i;
836 unsigned int r;
837
838 dvbsub->page.page_id = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1];
839 dvbsub->i += 2;
840 /*segment_length = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1];*/
841 dvbsub->i += 2;
842
843 object_id = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1];
844 dvbsub->i += 2;
845 dvbsub->curr_obj = object_id;
846 /*object_version_number = (dvbsub->buf[dvbsub->i] & 0xf0) >> 4;*/
847 object_coding_method = (dvbsub->buf[dvbsub->i] & 0x0c) >> 2;
848 /*non_modifying_colour_flag = (dvbsub->buf[dvbsub->i] & 0x02) >> 1;*/
849 dvbsub->i++;
850
851 old_i = dvbsub->i;
852 for (r = 0; r < dvbsub->max_regions; r++) {
853
854 /* If this object is in this region... */
855 if (dvbsub->regions[r].img) {
856 uint32_t pos;
857 if (sparse_array_get (&dvbsub->object_pos, (r << 16) | object_id, &pos)) {
858 dvbsub->i = old_i;
859 if (object_coding_method == 0) {
860 top_field_data_block_length = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1];
861 dvbsub->i += 2;
862 bottom_field_data_block_length = (dvbsub->buf[dvbsub->i] << 8) | dvbsub->buf[dvbsub->i + 1];
863 dvbsub->i += 2;
864
865 process_pixel_data_sub_block (dvbsub, r, pos, 0, top_field_data_block_length);
866
867 if (bottom_field_data_block_length == 0)
868 {
869 /* handle bottom field == top field */
870 bottom_field_data_block_length = top_field_data_block_length;
871 dvbsub->i = old_i + 4;
872 }
873
874 process_pixel_data_sub_block (dvbsub, r, pos, 1, bottom_field_data_block_length);
875 }
876 }
877 }
878 }
879 }
880
process_display_definition_segment(dvbsub_func_t * dvbsub)881 static void process_display_definition_segment(dvbsub_func_t *dvbsub)
882 {
883 unsigned int version_number, segment_length;
884 uint8_t *buf = &dvbsub->buf[dvbsub->i];
885
886 /*page_id = _X_BE_16(buf); */
887 segment_length = _X_BE_16(buf + 2);
888 buf += 4;
889
890 if (segment_length < 5)
891 return;
892
893 version_number = (buf[0] >> 4);
894
895 /* Check version number */
896 if (version_number == dvbsub->dds.version_number)
897 return;
898
899 dvbsub->dds.version_number = version_number;
900 dvbsub->dds.windowed = (buf[0] & 0x08) >> 3;
901
902 dvbsub->dds.width = _X_BE_16(buf + 1) + 1;
903 dvbsub->dds.height = _X_BE_16(buf + 3) + 1;
904
905 lprintf("display_definition_segment: %ux%u, windowed=%u\n",
906 dvbsub->dds.width, dvbsub->dds.height, dvbsub->dds.windowed);
907
908 if (dvbsub->dds.windowed) {
909 #if 0
910 if (segment_length < 13)
911 return;
912 /* TODO: window currently disabled (no samples) */
913 dvbsub->dds.x0 = _X_BE_16(buf + 5);
914 dvbsub->dds.x1 = _X_BE_16(buf + 7);
915 dvbsub->dds.y0 = _X_BE_16(buf + 9);
916 dvbsub->dds.y1 = _X_BE_16(buf + 11);
917
918 lprintf("display_definition_segment: window (%u,%u)-(%u,%u)\n",
919 dvbsub->dds.x0, dvbsub->dds.y0, dvbsub->dds.x1, dvbsub->dds.y1,
920 #endif
921 }
922 }
923
924 /*
925 *
926 */
927
unlock_mutex_cancellation_func(void * mutex_gen)928 static void unlock_mutex_cancellation_func(void *mutex_gen)
929 {
930 pthread_mutex_t *mutex = (pthread_mutex_t*) mutex_gen;
931 pthread_mutex_unlock(mutex);
932 }
933
_hide_overlays_locked(dvb_spu_decoder_t * this)934 static void _hide_overlays_locked(dvb_spu_decoder_t *this)
935 {
936 unsigned int i;
937 for (i = 0; i < this->dvbsub.max_regions; i++) {
938 if (this->dvbsub.regions[i].osd) {
939 this->stream->osd_renderer->hide( this->dvbsub.regions[i].osd, 0 );
940 }
941 }
942 }
943
944 /* Thread routine that checks for subtitle timeout periodically.
945 To avoid unexpected subtitle hiding, calls to this->stream->osd_renderer->show()
946 should be in blocks like:
947
948 pthread_mutex_lock(&this->dvbsub_osd_mutex);
949 this->stream->osd_renderer->show(...);
950 this->dvbsub_hide_timeout.tv_sec = time(NULL) + timeout value;
951 pthread_cond_signal(&this->dvbsub_restart_timeout);
952 pthread_mutex_unlock(&this->dvbsub_osd_mutex);
953
954 This ensures that the timeout is changed with the lock held, and
955 that the thread is signalled to pick up the new timeout.
956 */
dvbsub_timer_func(void * this_gen)957 static void* dvbsub_timer_func(void *this_gen)
958 {
959 dvb_spu_decoder_t *this = (dvb_spu_decoder_t *) this_gen;
960 pthread_mutex_lock(&this->dvbsub_osd_mutex);
961
962 /* If we're cancelled via pthread_cancel, unlock the mutex */
963 pthread_cleanup_push(unlock_mutex_cancellation_func, &this->dvbsub_osd_mutex);
964
965 while(1)
966 {
967 /* Record the current timeout, and wait - note that pthread_cond_timedwait
968 will unlock the mutex on entry, and lock it on exit */
969 struct timespec timeout = this->dvbsub_hide_timeout;
970 int result = pthread_cond_timedwait(&this->dvbsub_restart_timeout,
971 &this->dvbsub_osd_mutex,
972 &this->dvbsub_hide_timeout);
973 if(result == ETIMEDOUT &&
974 timeout.tv_sec == this->dvbsub_hide_timeout.tv_sec &&
975 timeout.tv_nsec == this->dvbsub_hide_timeout.tv_nsec)
976 {
977 /* We timed out, and no-one changed the timeout underneath us.
978 Hide the OSD, then wait until we're signalled. */
979 lprintf("thread hiding\n");
980 _hide_overlays_locked(this);
981
982 pthread_cond_wait(&this->dvbsub_restart_timeout, &this->dvbsub_osd_mutex);
983 }
984 }
985
986 pthread_cleanup_pop(1);
987 return NULL;
988 }
989
update_osd(dvb_spu_decoder_t * this,region_t * reg)990 static void update_osd(dvb_spu_decoder_t *this, region_t *reg)
991 {
992 if ( !reg->img ) {
993 if ( reg->osd ) {
994 pthread_mutex_lock( &this->dvbsub_osd_mutex );
995 this->stream->osd_renderer->free_object( reg->osd );
996 reg->osd = NULL;
997 pthread_mutex_unlock( &this->dvbsub_osd_mutex );
998 }
999 return;
1000 }
1001
1002 if ( reg->osd ) {
1003 if ( reg->width!=reg->osd->width || reg->height!=reg->osd->height ) {
1004 pthread_mutex_lock( &this->dvbsub_osd_mutex );
1005 this->stream->osd_renderer->free_object( reg->osd );
1006 reg->osd = NULL;
1007 pthread_mutex_unlock( &this->dvbsub_osd_mutex );
1008 }
1009 }
1010
1011 if ( !reg->osd )
1012 reg->osd = this->stream->osd_renderer->new_object( this->stream->osd_renderer, reg->width, reg->height );
1013 }
1014
downscale_region_image(region_t * reg,unsigned char * dest,int dest_width)1015 static void downscale_region_image( region_t *reg, unsigned char *dest, int dest_width )
1016 {
1017 float i, k, inc=reg->width/(float)dest_width;
1018 int j;
1019 for ( j=0; j<reg->height; j++ ) {
1020 for ( i=0,k=0; i<reg->width && k<dest_width; i+=inc,k++ ) {
1021 dest[(j*dest_width)+(int)k] = reg->img[(j*reg->width)+(int)i];
1022 }
1023 }
1024 }
1025
recalculate_trans(dvb_spu_decoder_t * this)1026 static void recalculate_trans (dvb_spu_decoder_t *this)
1027 {
1028 dvbsub_func_t *const dvbsub = &this->dvbsub;
1029 xine_spu_opacity_t opacity;
1030 unsigned int i;
1031
1032 _x_spu_get_opacity (this->stream->xine, &opacity);
1033 for (i = 0; i < dvbsub->max_regions * 256; ++i) {
1034 /* ETSI-300-743 says "full transparency if Y == 0". */
1035 if (dvbsub->colours[i].c.y == 0)
1036 dvbsub->trans[i] = 0;
1037 else {
1038 int v = _x_spu_calculate_opacity (&dvbsub->colours[i].c, dvbsub->colours[i].c.foo, &opacity);
1039 dvbsub->trans[i] = v * 14 / 255 + 1;
1040 }
1041 }
1042 }
1043
draw_subtitles(dvb_spu_decoder_t * this)1044 static void draw_subtitles (dvb_spu_decoder_t * this)
1045 {
1046 unsigned int r;
1047 int display=0;
1048 int64_t dum;
1049 int dest_width=0, dest_height;
1050 int max_x = 0, max_y = 0;
1051
1052 this->stream->video_out->status(this->stream->video_out, NULL, &dest_width, &dest_height, &dum);
1053 if ( !dest_width || !dest_height )
1054 return;
1055
1056 /* render all regions onto the page */
1057
1058 for (r = 0; r < this->dvbsub.max_regions; r++) {
1059 if (this->dvbsub.page.regions[r].is_visible) {
1060 /* additional safety for broken HD streams without DDS ... */
1061 int x2 = this->dvbsub.page.regions[r].x + this->dvbsub.regions[r].width;
1062 int y2 = this->dvbsub.page.regions[r].y + this->dvbsub.regions[r].height;
1063 max_x = (max_x < x2) ? x2 : max_x;
1064 max_y = (max_y < y2) ? y2 : max_y;
1065 display++;
1066 }
1067 }
1068 if ( !display )
1069 return;
1070
1071 for (r = 0; r < this->dvbsub.max_regions; r++) {
1072 region_t *reg = &this->dvbsub.regions[r];
1073 if (reg->img) {
1074 if (this->dvbsub.page.regions[r].is_visible && !reg->empty) {
1075 uint8_t *tmp = NULL;
1076 const uint8_t *img = reg->img;
1077 int img_width = reg->width;
1078
1079 update_osd( this, reg );
1080 if (!reg->osd)
1081 continue;
1082 /* clear osd */
1083 this->stream->osd_renderer->clear( reg->osd );
1084 if (reg->width > dest_width && !(this->stream->video_out->get_capabilities(this->stream->video_out) & VO_CAP_CUSTOM_EXTENT_OVERLAY)) {
1085 lprintf("downscaling region, width %d->%d\n", reg->width, dest_width);
1086 tmp = malloc(dest_width*576);
1087 if (tmp) {
1088 downscale_region_image(reg, tmp, dest_width);
1089 img = tmp;
1090 img_width = dest_width;
1091 }
1092 }
1093 /* All DVB subs I have seen so far use same color matrix as main video. */
1094 _X_SET_CLUT_CM (&this->dvbsub.colours[reg->CLUT_id * 256].u32, 4);
1095 this->stream->osd_renderer->set_palette( reg->osd,
1096 &this->dvbsub.colours[reg->CLUT_id * 256].u32,
1097 &this->dvbsub.trans[reg->CLUT_id * 256]);
1098 lprintf("draw region %d: %dx%d\n", r, img_width, reg->height);
1099 this->stream->osd_renderer->draw_bitmap( reg->osd, img, 0, 0, img_width, reg->height, NULL );
1100 free(tmp);
1101 }
1102 }
1103 }
1104
1105 pthread_mutex_lock(&this->dvbsub_osd_mutex);
1106 lprintf("this->vpts=%"PRId64"\n",this->vpts);
1107 for (r = 0; r < this->dvbsub.max_regions; r++) {
1108 region_t *reg = &this->dvbsub.regions[r];
1109 lprintf("region=%d, visible=%d, osd=%d, empty=%d\n",
1110 r, this->dvbsub.page.regions[r].is_visible, reg->osd ? 1 : 0, reg->empty );
1111 if (this->dvbsub.page.regions[r].is_visible && reg->osd && !reg->empty ) {
1112 if (max_x <= this->dvbsub.dds.width && max_y <= this->dvbsub.dds.height)
1113 this->stream->osd_renderer->set_extent(reg->osd, this->dvbsub.dds.width, this->dvbsub.dds.height);
1114 this->stream->osd_renderer->set_position( reg->osd, this->dvbsub.page.regions[r].x, this->dvbsub.page.regions[r].y );
1115 this->stream->osd_renderer->show( reg->osd, this->vpts );
1116 lprintf("show region = %d\n",r);
1117 }
1118 else {
1119 if (reg->osd) {
1120 this->stream->osd_renderer->hide( reg->osd, this->vpts );
1121 lprintf("hide region = %d\n",r);
1122 }
1123 }
1124 }
1125 this->dvbsub_hide_timeout.tv_nsec = 0;
1126 this->dvbsub_hide_timeout.tv_sec = time(NULL) + this->dvbsub.page.page_time_out;
1127 lprintf("page_time_out %d\n",this->dvbsub.page.page_time_out);
1128 pthread_cond_signal(&this->dvbsub_restart_timeout);
1129 pthread_mutex_unlock(&this->dvbsub_osd_mutex);
1130 }
1131
_hide_overlays(dvb_spu_decoder_t * this)1132 static void _hide_overlays(dvb_spu_decoder_t *this)
1133 {
1134 pthread_mutex_lock(&this->dvbsub_osd_mutex);
1135 _hide_overlays_locked(this);
1136 pthread_mutex_unlock(&this->dvbsub_osd_mutex);
1137 }
1138
1139 /*
1140 *
1141 */
1142
spudec_decode_data(spu_decoder_t * this_gen,buf_element_t * buf)1143 static void spudec_decode_data (spu_decoder_t * this_gen, buf_element_t * buf)
1144 {
1145 dvb_spu_decoder_t *this = (dvb_spu_decoder_t *) this_gen;
1146 int new_i;
1147 /*int data_identifier, subtitle_stream_id;*/
1148 int segment_length, segment_type;
1149
1150 if((buf->type & 0xffff0000)!=BUF_SPU_DVB)
1151 return;
1152
1153 if (buf->decoder_flags & BUF_FLAG_SPECIAL) {
1154 if (buf->decoder_info[1] == BUF_SPECIAL_SPU_DVB_DESCRIPTOR) {
1155 if (buf->decoder_info[2] == 0) {
1156 /* Hide the osd - note that if the timeout thread times out, it'll rehide, which is harmless */
1157 _hide_overlays(this);
1158 }
1159 else {
1160 if (buf->decoder_info[2] < sizeof(this->spu_descriptor)) {
1161 xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": too small spu_descriptor, ignoring\n");
1162 } else {
1163 if (buf->decoder_info[2] > sizeof(this->spu_descriptor))
1164 xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": too large spu_descriptor\n");
1165 memcpy (&this->spu_descriptor, buf->decoder_info_ptr[2], sizeof(this->spu_descriptor));
1166 }
1167 }
1168 }
1169 return;
1170 }
1171
1172 /* accumulate data */
1173 if (buf->decoder_info[2]) {
1174
1175 this->pes_pkt_wrptr = this->pes_pkt;
1176 this->pes_pkt_size = buf->decoder_info[2];
1177
1178 xine_fast_memcpy (this->pes_pkt, buf->content, buf->size);
1179 this->pes_pkt_wrptr += buf->size;
1180 memset (this->pes_pkt_wrptr, 0xff, sizeof(this->pes_pkt) - buf->size);
1181
1182 this->vpts = 0;
1183
1184 /* set DDS default (SD resolution) */
1185 this->dvbsub.dds.version_number = 0xff;
1186 this->dvbsub.dds.width = 720;
1187 this->dvbsub.dds.height = 576;
1188 this->dvbsub.dds.windowed = 0;
1189 }
1190 else {
1191 if (this->pes_pkt_wrptr != this->pes_pkt) {
1192 xine_fast_memcpy (this->pes_pkt_wrptr, buf->content, buf->size);
1193 this->pes_pkt_wrptr += buf->size;
1194 }
1195 }
1196
1197 /* don't ask metronom for a vpts but rather do the calculation
1198 * because buf->pts could be too far in future and metronom won't accept
1199 * further backwards pts (see metronom_got_spu_packet) */
1200 if (buf->pts > 0) {
1201 metronom_t *metronom = this->stream->metronom;
1202 int64_t vpts_offset = metronom->get_option( metronom, METRONOM_VPTS_OFFSET );
1203 int64_t spu_offset = metronom->get_option( metronom, METRONOM_SPU_OFFSET );
1204 int64_t vpts = (int64_t)(buf->pts)+vpts_offset+spu_offset;
1205 metronom_clock_t *clock = this->stream->xine->clock;
1206 int64_t curvpts = clock->get_current_time( clock );
1207 /* if buf->pts is unreliable, show page asap (better than nothing) */
1208 lprintf("spu_vpts=%"PRId64" - current_vpts=%"PRId64"\n", vpts, curvpts);
1209 if ( vpts<=curvpts || (vpts-curvpts)>(5*90000) )
1210 this->vpts = 0;
1211 else
1212 this->vpts = vpts;
1213 }
1214
1215 /* completely ignore pts since it makes a lot of problems with various providers */
1216 /* this->vpts = 0; */
1217
1218 /* process the pes section */
1219
1220 this->dvbsub.buf = this->pes_pkt;
1221 this->dvbsub.i = 2;
1222 /*data_identifier = this->dvbsub->buf[0]*/
1223 /*subtitle_stream_id = this->dvbsub->buf[1]*/
1224
1225 while (this->dvbsub.i <= (int)this->pes_pkt_size) {
1226 /* SUBTITLING SEGMENT */
1227 const uint8_t *buf = this->dvbsub.buf;
1228 this->dvbsub.i++;
1229 segment_type = buf[this->dvbsub.i++];
1230
1231 this->dvbsub.page.page_id = (buf[this->dvbsub.i] << 8) | buf[this->dvbsub.i + 1];
1232 segment_length = (buf[this->dvbsub.i + 2] << 8) | buf[this->dvbsub.i + 3];
1233 new_i = this->dvbsub.i + segment_length + 4;
1234
1235 /* only process complete segments */
1236 if(new_i > (this->pes_pkt_wrptr - this->pes_pkt))
1237 break;
1238 /* verify we've the right segment */
1239 if (this->dvbsub.page.page_id == this->spu_descriptor.comp_page_id) {
1240 /* SEGMENT_DATA_FIELD */
1241 switch (segment_type & 0xff) {
1242 case 0x10:
1243 process_page_composition_segment (&this->dvbsub);
1244 break;
1245 case 0x11:
1246 process_region_composition_segment (&this->dvbsub);
1247 break;
1248 case 0x12:
1249 process_CLUT_definition_segment(&this->dvbsub);
1250 break;
1251 case 0x13:
1252 process_object_data_segment (&this->dvbsub);
1253 break;
1254 case 0x14:
1255 process_display_definition_segment(&this->dvbsub);
1256 break;
1257 case 0x80: /* Page is now completely rendered */
1258 recalculate_trans(this);
1259 draw_subtitles( this );
1260 break;
1261 case 0xFF: /* stuffing */
1262 break;
1263 default:
1264 return;
1265 break;
1266 }
1267 }
1268 this->dvbsub.i = new_i;
1269 }
1270 }
1271
spudec_reset(spu_decoder_t * this_gen)1272 static void spudec_reset (spu_decoder_t * this_gen)
1273 {
1274 dvb_spu_decoder_t *this = (dvb_spu_decoder_t *) this_gen;
1275 unsigned int i;
1276
1277 /* Hide the osd - if the timeout thread times out, it'll rehide harmlessly */
1278 _hide_overlays(this);
1279
1280 for ( i=0; i<MAX_REGIONS; i++ ) {
1281 this->dvbsub.regions[i].version_number = 0xff;
1282 }
1283 this->dvbsub.page.page_version_number = 0xff;
1284 reset_clut (&this->dvbsub);
1285 }
1286
spudec_discontinuity(spu_decoder_t * this_gen)1287 static void spudec_discontinuity (spu_decoder_t * this_gen)
1288 {
1289 /* do nothing */
1290 (void)this_gen;
1291 }
1292
spudec_dispose_stopped(dvb_spu_decoder_t * this)1293 static void spudec_dispose_stopped (dvb_spu_decoder_t * this)
1294 {
1295 unsigned int i;
1296
1297 pthread_mutex_destroy(&this->dvbsub_osd_mutex);
1298 pthread_cond_destroy(&this->dvbsub_restart_timeout);
1299
1300 for ( i=0; i<MAX_REGIONS; i++ ) {
1301 _x_freep( &this->dvbsub.regions[i].img );
1302 if ( this->dvbsub.regions[i].osd )
1303 this->stream->osd_renderer->free_object( this->dvbsub.regions[i].osd );
1304 }
1305
1306 sparse_array_delete (&this->dvbsub.object_pos);
1307
1308 free (this);
1309 }
1310
spudec_dispose(spu_decoder_t * this_gen)1311 static void spudec_dispose (spu_decoder_t * this_gen)
1312 {
1313 dvb_spu_decoder_t *this = (dvb_spu_decoder_t *) this_gen;
1314
1315 pthread_cancel(this->dvbsub_timer_thread);
1316 pthread_join(this->dvbsub_timer_thread, NULL);
1317
1318 spudec_dispose_stopped(this);
1319 }
1320
dvb_spu_class_open_plugin(spu_decoder_class_t * class_gen,xine_stream_t * stream)1321 static spu_decoder_t *dvb_spu_class_open_plugin (spu_decoder_class_t * class_gen, xine_stream_t * stream)
1322 {
1323 dvb_spu_decoder_t *this;
1324 unsigned int i;
1325
1326 (void)class_gen;
1327 this = calloc(1, sizeof (dvb_spu_decoder_t));
1328 if (!this)
1329 return NULL;
1330
1331 this->spu_decoder.decode_data = spudec_decode_data;
1332 this->spu_decoder.reset = spudec_reset;
1333 this->spu_decoder.discontinuity = spudec_discontinuity;
1334 this->spu_decoder.dispose = spudec_dispose;
1335 this->spu_decoder.get_interact_info = NULL;
1336 this->spu_decoder.set_button = NULL;
1337
1338 this->stream = stream;
1339
1340 pthread_mutex_init(&this->dvbsub_osd_mutex, NULL);
1341 pthread_cond_init(&this->dvbsub_restart_timeout, NULL);
1342
1343 #ifndef HAVE_ZERO_SAFE_MEM
1344 for (i = 0; i < MAX_REGIONS; i++) {
1345 this->dvbsub.regions[i].img = NULL;
1346 this->dvbsub.regions[i].osd = NULL;
1347 }
1348 #endif
1349
1350 {
1351 xine_spu_opacity_t opacity;
1352 const clut_t black = { 0, 0, 0, 0 };
1353 int t;
1354
1355 _x_spu_get_opacity (this->stream->xine, &opacity);
1356 t = _x_spu_calculate_opacity (&black, 0, &opacity);
1357
1358 for (i = 0; i < MAX_REGIONS * 256; i++)
1359 this->dvbsub.colours[i].c.foo = t;
1360 }
1361
1362 sparse_array_new (&this->dvbsub.object_pos);
1363
1364 this->dvbsub_hide_timeout.tv_nsec = 0;
1365 this->dvbsub_hide_timeout.tv_sec = time(NULL);
1366
1367 if (pthread_create(&this->dvbsub_timer_thread, NULL, dvbsub_timer_func, this)) {
1368 xprintf (stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": pthread_create() failed\n");
1369 spudec_dispose_stopped(this);
1370 return NULL;
1371 }
1372
1373 for (i = 0; i < MAX_REGIONS; i++) {
1374 this->dvbsub.regions[i].version_number = 0xff;
1375 }
1376 this->dvbsub.page.page_version_number = 0xff;
1377
1378 return &this->spu_decoder;
1379 }
1380
init_spu_decoder_plugin(xine_t * xine,const void * data)1381 static void *init_spu_decoder_plugin (xine_t * xine, const void *data)
1382 {
1383 (void)xine;
1384 (void)data;
1385 static const spu_decoder_class_t decode_dvb_spu_class = {
1386 .open_plugin = dvb_spu_class_open_plugin,
1387 .identifier = "spudvb",
1388 .description = N_("DVB subtitle decoder plugin"),
1389 .dispose = NULL,
1390 };
1391 return (void *)&decode_dvb_spu_class;
1392 }
1393
1394
1395 /* plugin catalog information */
1396 static const uint32_t supported_types[] = { BUF_SPU_DVB, 0 };
1397
1398 static const decoder_info_t spudec_info = {
1399 .supported_types = supported_types,
1400 .priority = 1,
1401 };
1402
1403 const plugin_info_t xine_plugin_info[] EXPORTED = {
1404 /* type, API, "name", version, special_info, init_function */
1405 {PLUGIN_SPU_DECODER, 17, "spudvb", XINE_VERSION_CODE, &spudec_info,
1406 &init_spu_decoder_plugin},
1407 {PLUGIN_NONE, 0, NULL, 0, NULL, NULL}
1408 };
1409