FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dvbsubdec.c
Go to the documentation of this file.
1 /*
2  * DVB subtitle decoding
3  * Copyright (c) 2005 Ian Caulfield
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "avcodec.h"
23 #include "get_bits.h"
24 #include "bytestream.h"
25 #include "libavutil/colorspace.h"
26 #include "libavutil/opt.h"
27 
28 #define DVBSUB_PAGE_SEGMENT 0x10
29 #define DVBSUB_REGION_SEGMENT 0x11
30 #define DVBSUB_CLUT_SEGMENT 0x12
31 #define DVBSUB_OBJECT_SEGMENT 0x13
32 #define DVBSUB_DISPLAYDEFINITION_SEGMENT 0x14
33 #define DVBSUB_DISPLAY_SEGMENT 0x80
34 
35 #define cm (ff_crop_tab + MAX_NEG_CROP)
36 
37 #ifdef DEBUG
38 #if 0
39 static void png_save(const char *filename, uint8_t *bitmap, int w, int h,
40  uint32_t *rgba_palette)
41 {
42  int x, y, v;
43  FILE *f;
44  char fname[40], fname2[40];
45  char command[1024];
46 
47  snprintf(fname, 40, "%s.ppm", filename);
48 
49  f = fopen(fname, "w");
50  if (!f) {
51  perror(fname);
52  return;
53  }
54  fprintf(f, "P6\n"
55  "%d %d\n"
56  "%d\n",
57  w, h, 255);
58  for(y = 0; y < h; y++) {
59  for(x = 0; x < w; x++) {
60  v = rgba_palette[bitmap[y * w + x]];
61  putc((v >> 16) & 0xff, f);
62  putc((v >> 8) & 0xff, f);
63  putc((v >> 0) & 0xff, f);
64  }
65  }
66  fclose(f);
67 
68 
69  snprintf(fname2, 40, "%s-a.pgm", filename);
70 
71  f = fopen(fname2, "w");
72  if (!f) {
73  perror(fname2);
74  return;
75  }
76  fprintf(f, "P5\n"
77  "%d %d\n"
78  "%d\n",
79  w, h, 255);
80  for(y = 0; y < h; y++) {
81  for(x = 0; x < w; x++) {
82  v = rgba_palette[bitmap[y * w + x]];
83  putc((v >> 24) & 0xff, f);
84  }
85  }
86  fclose(f);
87 
88  snprintf(command, 1024, "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2, fname, filename);
89  system(command);
90 
91  snprintf(command, 1024, "rm %s %s", fname, fname2);
92  system(command);
93 }
94 #endif
95 
96 static void png_save2(const char *filename, uint32_t *bitmap, int w, int h)
97 {
98  int x, y, v;
99  FILE *f;
100  char fname[40], fname2[40];
101  char command[1024];
102 
103  snprintf(fname, sizeof(fname), "%s.ppm", filename);
104 
105  f = fopen(fname, "w");
106  if (!f) {
107  perror(fname);
108  return;
109  }
110  fprintf(f, "P6\n"
111  "%d %d\n"
112  "%d\n",
113  w, h, 255);
114  for(y = 0; y < h; y++) {
115  for(x = 0; x < w; x++) {
116  v = bitmap[y * w + x];
117  putc((v >> 16) & 0xff, f);
118  putc((v >> 8) & 0xff, f);
119  putc((v >> 0) & 0xff, f);
120  }
121  }
122  fclose(f);
123 
124 
125  snprintf(fname2, sizeof(fname2), "%s-a.pgm", filename);
126 
127  f = fopen(fname2, "w");
128  if (!f) {
129  perror(fname2);
130  return;
131  }
132  fprintf(f, "P5\n"
133  "%d %d\n"
134  "%d\n",
135  w, h, 255);
136  for(y = 0; y < h; y++) {
137  for(x = 0; x < w; x++) {
138  v = bitmap[y * w + x];
139  putc((v >> 24) & 0xff, f);
140  }
141  }
142  fclose(f);
143 
144  snprintf(command, sizeof(command), "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2, fname, filename);
145  system(command);
146 
147  snprintf(command, sizeof(command), "rm %s %s", fname, fname2);
148  system(command);
149 }
150 #endif
151 
152 #define RGBA(r,g,b,a) (((unsigned)(a) << 24) | ((r) << 16) | ((g) << 8) | (b))
153 
154 typedef struct DVBSubCLUT {
155  int id;
156  int version;
157 
158  uint32_t clut4[4];
159  uint32_t clut16[16];
160  uint32_t clut256[256];
161 
162  struct DVBSubCLUT *next;
163 } DVBSubCLUT;
164 
166 
167 typedef struct DVBSubObjectDisplay {
170 
171  int x_pos;
172  int y_pos;
173 
174  int fgcolor;
175  int bgcolor;
176 
180 
181 typedef struct DVBSubObject {
182  int id;
183  int version;
184 
185  int type;
186 
188 
190 } DVBSubObject;
191 
192 typedef struct DVBSubRegionDisplay {
194 
195  int x_pos;
196  int y_pos;
197 
200 
201 typedef struct DVBSubRegion {
202  int id;
203  int version;
204 
205  int width;
206  int height;
207  int depth;
208 
209  int clut;
210  int bgcolor;
211 
213  int buf_size;
214  int dirty;
215 
217 
219 } DVBSubRegion;
220 
221 typedef struct DVBSubDisplayDefinition {
222  int version;
223 
224  int x;
225  int y;
226  int width;
227  int height;
229 
230 typedef struct DVBSubContext {
231  AVClass *class;
234 
235  int version;
236  int time_out;
237  int compute_edt; /**< if 1 end display time calculated using pts
238  if 0 (Default) calculated using time out */
239  int64_t prev_start;
243 
246 } DVBSubContext;
247 
248 
249 static DVBSubObject* get_object(DVBSubContext *ctx, int object_id)
250 {
251  DVBSubObject *ptr = ctx->object_list;
252 
253  while (ptr && ptr->id != object_id) {
254  ptr = ptr->next;
255  }
256 
257  return ptr;
258 }
259 
260 static DVBSubCLUT* get_clut(DVBSubContext *ctx, int clut_id)
261 {
262  DVBSubCLUT *ptr = ctx->clut_list;
263 
264  while (ptr && ptr->id != clut_id) {
265  ptr = ptr->next;
266  }
267 
268  return ptr;
269 }
270 
271 static DVBSubRegion* get_region(DVBSubContext *ctx, int region_id)
272 {
273  DVBSubRegion *ptr = ctx->region_list;
274 
275  while (ptr && ptr->id != region_id) {
276  ptr = ptr->next;
277  }
278 
279  return ptr;
280 }
281 
283 {
284  DVBSubObject *object, *obj2, **obj2_ptr;
285  DVBSubObjectDisplay *display, *obj_disp, **obj_disp_ptr;
286 
287  while (region->display_list) {
288  display = region->display_list;
289 
290  object = get_object(ctx, display->object_id);
291 
292  if (object) {
293  obj_disp_ptr = &object->display_list;
294  obj_disp = *obj_disp_ptr;
295 
296  while (obj_disp && obj_disp != display) {
297  obj_disp_ptr = &obj_disp->object_list_next;
298  obj_disp = *obj_disp_ptr;
299  }
300 
301  if (obj_disp) {
302  *obj_disp_ptr = obj_disp->object_list_next;
303 
304  if (!object->display_list) {
305  obj2_ptr = &ctx->object_list;
306  obj2 = *obj2_ptr;
307 
308  while (obj2 != object) {
309  av_assert0(obj2);
310  obj2_ptr = &obj2->next;
311  obj2 = *obj2_ptr;
312  }
313 
314  *obj2_ptr = obj2->next;
315 
316  av_freep(&obj2);
317  }
318  }
319  }
320 
321  region->display_list = display->region_list_next;
322 
323  av_freep(&display);
324  }
325 
326 }
327 
328 static void delete_cluts(DVBSubContext *ctx)
329 {
330  while (ctx->clut_list) {
331  DVBSubCLUT *clut = ctx->clut_list;
332 
333  ctx->clut_list = clut->next;
334 
335  av_freep(&clut);
336  }
337 }
338 
339 static void delete_objects(DVBSubContext *ctx)
340 {
341  while (ctx->object_list) {
342  DVBSubObject *object = ctx->object_list;
343 
344  ctx->object_list = object->next;
345 
346  av_freep(&object);
347  }
348 }
349 
350 static void delete_regions(DVBSubContext *ctx)
351 {
352  while (ctx->region_list) {
353  DVBSubRegion *region = ctx->region_list;
354 
355  ctx->region_list = region->next;
356 
357  delete_region_display_list(ctx, region);
358 
359  av_freep(&region->pbuf);
360  av_freep(&region);
361  }
362 }
363 
365 {
366  int i, r, g, b, a = 0;
367  DVBSubContext *ctx = avctx->priv_data;
368 
369  if (!avctx->extradata || (avctx->extradata_size < 4) || ((avctx->extradata_size % 5 != 0) && (avctx->extradata_size != 4))) {
370  av_log(avctx, AV_LOG_WARNING, "Invalid DVB subtitles stream extradata!\n");
371  ctx->composition_id = -1;
372  ctx->ancillary_id = -1;
373  } else {
374  if (avctx->extradata_size > 5) {
375  av_log(avctx, AV_LOG_WARNING, "Decoding first DVB subtitles sub-stream\n");
376  }
377 
378  ctx->composition_id = AV_RB16(avctx->extradata);
379  ctx->ancillary_id = AV_RB16(avctx->extradata + 2);
380  }
381 
382  ctx->version = -1;
383  ctx->prev_start = AV_NOPTS_VALUE;
384 
385  default_clut.id = -1;
386  default_clut.next = NULL;
387 
388  default_clut.clut4[0] = RGBA( 0, 0, 0, 0);
389  default_clut.clut4[1] = RGBA(255, 255, 255, 255);
390  default_clut.clut4[2] = RGBA( 0, 0, 0, 255);
391  default_clut.clut4[3] = RGBA(127, 127, 127, 255);
392 
393  default_clut.clut16[0] = RGBA( 0, 0, 0, 0);
394  for (i = 1; i < 16; i++) {
395  if (i < 8) {
396  r = (i & 1) ? 255 : 0;
397  g = (i & 2) ? 255 : 0;
398  b = (i & 4) ? 255 : 0;
399  } else {
400  r = (i & 1) ? 127 : 0;
401  g = (i & 2) ? 127 : 0;
402  b = (i & 4) ? 127 : 0;
403  }
404  default_clut.clut16[i] = RGBA(r, g, b, 255);
405  }
406 
407  default_clut.clut256[0] = RGBA( 0, 0, 0, 0);
408  for (i = 1; i < 256; i++) {
409  if (i < 8) {
410  r = (i & 1) ? 255 : 0;
411  g = (i & 2) ? 255 : 0;
412  b = (i & 4) ? 255 : 0;
413  a = 63;
414  } else {
415  switch (i & 0x88) {
416  case 0x00:
417  r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0);
418  g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0);
419  b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0);
420  a = 255;
421  break;
422  case 0x08:
423  r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0);
424  g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0);
425  b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0);
426  a = 127;
427  break;
428  case 0x80:
429  r = 127 + ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0);
430  g = 127 + ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0);
431  b = 127 + ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0);
432  a = 255;
433  break;
434  case 0x88:
435  r = ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0);
436  g = ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0);
437  b = ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0);
438  a = 255;
439  break;
440  }
441  }
442  default_clut.clut256[i] = RGBA(r, g, b, a);
443  }
444 
445  return 0;
446 }
447 
449 {
450  DVBSubContext *ctx = avctx->priv_data;
451  DVBSubRegionDisplay *display;
452 
453  delete_regions(ctx);
454 
455  delete_objects(ctx);
456 
457  delete_cluts(ctx);
458 
460 
461  while (ctx->display_list) {
462  display = ctx->display_list;
463  ctx->display_list = display->next;
464 
465  av_freep(&display);
466  }
467 
468  return 0;
469 }
470 
471 static int dvbsub_read_2bit_string(uint8_t *destbuf, int dbuf_len,
472  const uint8_t **srcbuf, int buf_size,
473  int non_mod, uint8_t *map_table, int x_pos)
474 {
475  GetBitContext gb;
476 
477  int bits;
478  int run_length;
479  int pixels_read = x_pos;
480 
481  init_get_bits(&gb, *srcbuf, buf_size << 3);
482 
483  destbuf += x_pos;
484 
485  while (get_bits_count(&gb) < buf_size << 3 && pixels_read < dbuf_len) {
486  bits = get_bits(&gb, 2);
487 
488  if (bits) {
489  if (non_mod != 1 || bits != 1) {
490  if (map_table)
491  *destbuf++ = map_table[bits];
492  else
493  *destbuf++ = bits;
494  }
495  pixels_read++;
496  } else {
497  bits = get_bits1(&gb);
498  if (bits == 1) {
499  run_length = get_bits(&gb, 3) + 3;
500  bits = get_bits(&gb, 2);
501 
502  if (non_mod == 1 && bits == 1)
503  pixels_read += run_length;
504  else {
505  if (map_table)
506  bits = map_table[bits];
507  while (run_length-- > 0 && pixels_read < dbuf_len) {
508  *destbuf++ = bits;
509  pixels_read++;
510  }
511  }
512  } else {
513  bits = get_bits1(&gb);
514  if (bits == 0) {
515  bits = get_bits(&gb, 2);
516  if (bits == 2) {
517  run_length = get_bits(&gb, 4) + 12;
518  bits = get_bits(&gb, 2);
519 
520  if (non_mod == 1 && bits == 1)
521  pixels_read += run_length;
522  else {
523  if (map_table)
524  bits = map_table[bits];
525  while (run_length-- > 0 && pixels_read < dbuf_len) {
526  *destbuf++ = bits;
527  pixels_read++;
528  }
529  }
530  } else if (bits == 3) {
531  run_length = get_bits(&gb, 8) + 29;
532  bits = get_bits(&gb, 2);
533 
534  if (non_mod == 1 && bits == 1)
535  pixels_read += run_length;
536  else {
537  if (map_table)
538  bits = map_table[bits];
539  while (run_length-- > 0 && pixels_read < dbuf_len) {
540  *destbuf++ = bits;
541  pixels_read++;
542  }
543  }
544  } else if (bits == 1) {
545  if (map_table)
546  bits = map_table[0];
547  else
548  bits = 0;
549  run_length = 2;
550  while (run_length-- > 0 && pixels_read < dbuf_len) {
551  *destbuf++ = bits;
552  pixels_read++;
553  }
554  } else {
555  (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
556  return pixels_read;
557  }
558  } else {
559  if (map_table)
560  bits = map_table[0];
561  else
562  bits = 0;
563  *destbuf++ = bits;
564  pixels_read++;
565  }
566  }
567  }
568  }
569 
570  if (get_bits(&gb, 6))
571  av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n");
572 
573  (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
574 
575  return pixels_read;
576 }
577 
578 static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len,
579  const uint8_t **srcbuf, int buf_size,
580  int non_mod, uint8_t *map_table, int x_pos)
581 {
582  GetBitContext gb;
583 
584  int bits;
585  int run_length;
586  int pixels_read = x_pos;
587 
588  init_get_bits(&gb, *srcbuf, buf_size << 3);
589 
590  destbuf += x_pos;
591 
592  while (get_bits_count(&gb) < buf_size << 3 && pixels_read < dbuf_len) {
593  bits = get_bits(&gb, 4);
594 
595  if (bits) {
596  if (non_mod != 1 || bits != 1) {
597  if (map_table)
598  *destbuf++ = map_table[bits];
599  else
600  *destbuf++ = bits;
601  }
602  pixels_read++;
603  } else {
604  bits = get_bits1(&gb);
605  if (bits == 0) {
606  run_length = get_bits(&gb, 3);
607 
608  if (run_length == 0) {
609  (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
610  return pixels_read;
611  }
612 
613  run_length += 2;
614 
615  if (map_table)
616  bits = map_table[0];
617  else
618  bits = 0;
619 
620  while (run_length-- > 0 && pixels_read < dbuf_len) {
621  *destbuf++ = bits;
622  pixels_read++;
623  }
624  } else {
625  bits = get_bits1(&gb);
626  if (bits == 0) {
627  run_length = get_bits(&gb, 2) + 4;
628  bits = get_bits(&gb, 4);
629 
630  if (non_mod == 1 && bits == 1)
631  pixels_read += run_length;
632  else {
633  if (map_table)
634  bits = map_table[bits];
635  while (run_length-- > 0 && pixels_read < dbuf_len) {
636  *destbuf++ = bits;
637  pixels_read++;
638  }
639  }
640  } else {
641  bits = get_bits(&gb, 2);
642  if (bits == 2) {
643  run_length = get_bits(&gb, 4) + 9;
644  bits = get_bits(&gb, 4);
645 
646  if (non_mod == 1 && bits == 1)
647  pixels_read += run_length;
648  else {
649  if (map_table)
650  bits = map_table[bits];
651  while (run_length-- > 0 && pixels_read < dbuf_len) {
652  *destbuf++ = bits;
653  pixels_read++;
654  }
655  }
656  } else if (bits == 3) {
657  run_length = get_bits(&gb, 8) + 25;
658  bits = get_bits(&gb, 4);
659 
660  if (non_mod == 1 && bits == 1)
661  pixels_read += run_length;
662  else {
663  if (map_table)
664  bits = map_table[bits];
665  while (run_length-- > 0 && pixels_read < dbuf_len) {
666  *destbuf++ = bits;
667  pixels_read++;
668  }
669  }
670  } else if (bits == 1) {
671  if (map_table)
672  bits = map_table[0];
673  else
674  bits = 0;
675  run_length = 2;
676  while (run_length-- > 0 && pixels_read < dbuf_len) {
677  *destbuf++ = bits;
678  pixels_read++;
679  }
680  } else {
681  if (map_table)
682  bits = map_table[0];
683  else
684  bits = 0;
685  *destbuf++ = bits;
686  pixels_read ++;
687  }
688  }
689  }
690  }
691  }
692 
693  if (get_bits(&gb, 8))
694  av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n");
695 
696  (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
697 
698  return pixels_read;
699 }
700 
701 static int dvbsub_read_8bit_string(uint8_t *destbuf, int dbuf_len,
702  const uint8_t **srcbuf, int buf_size,
703  int non_mod, uint8_t *map_table, int x_pos)
704 {
705  const uint8_t *sbuf_end = (*srcbuf) + buf_size;
706  int bits;
707  int run_length;
708  int pixels_read = x_pos;
709 
710  destbuf += x_pos;
711 
712  while (*srcbuf < sbuf_end && pixels_read < dbuf_len) {
713  bits = *(*srcbuf)++;
714 
715  if (bits) {
716  if (non_mod != 1 || bits != 1) {
717  if (map_table)
718  *destbuf++ = map_table[bits];
719  else
720  *destbuf++ = bits;
721  }
722  pixels_read++;
723  } else {
724  bits = *(*srcbuf)++;
725  run_length = bits & 0x7f;
726  if ((bits & 0x80) == 0) {
727  if (run_length == 0) {
728  return pixels_read;
729  }
730 
731  bits = 0;
732  } else {
733  bits = *(*srcbuf)++;
734  }
735  if (non_mod == 1 && bits == 1)
736  pixels_read += run_length;
737  else {
738  if (map_table)
739  bits = map_table[bits];
740  while (run_length-- > 0 && pixels_read < dbuf_len) {
741  *destbuf++ = bits;
742  pixels_read++;
743  }
744  }
745  }
746  }
747 
748  if (*(*srcbuf)++)
749  av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n");
750 
751  return pixels_read;
752 }
753 
754 static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_output)
755 {
756  DVBSubContext *ctx = avctx->priv_data;
757  DVBSubRegionDisplay *display;
758  DVBSubDisplayDefinition *display_def = ctx->display_definition;
759  DVBSubRegion *region;
761  DVBSubCLUT *clut;
762  uint32_t *clut_table;
763  int i;
764  int offset_x=0, offset_y=0;
765  int ret = 0;
766 
767 
768  if (display_def) {
769  offset_x = display_def->x;
770  offset_y = display_def->y;
771  }
772 
773  /* Not touching AVSubtitles again*/
774  if(sub->num_rects) {
775  avpriv_request_sample(ctx, "Different Version of Segment asked Twice\n");
776  return AVERROR_PATCHWELCOME;
777  }
778  for (display = ctx->display_list; display; display = display->next) {
779  region = get_region(ctx, display->region_id);
780  if (region && region->dirty)
781  sub->num_rects++;
782  }
783 
784  if(ctx->compute_edt == 0) {
785  sub->end_display_time = ctx->time_out * 1000;
786  *got_output = 1;
787  } else if (ctx->prev_start != AV_NOPTS_VALUE) {
788  sub->end_display_time = av_rescale_q((sub->pts - ctx->prev_start ), AV_TIME_BASE_Q, (AVRational){ 1, 1000 }) - 1;
789  *got_output = 1;
790  }
791  if (sub->num_rects > 0) {
792 
793  sub->rects = av_mallocz_array(sizeof(*sub->rects), sub->num_rects);
794  if (!sub->rects) {
795  ret = AVERROR(ENOMEM);
796  goto fail;
797  }
798 
799  for(i=0; i<sub->num_rects; i++)
800  sub->rects[i] = av_mallocz(sizeof(*sub->rects[i]));
801 
802  i = 0;
803 
804  for (display = ctx->display_list; display; display = display->next) {
805  region = get_region(ctx, display->region_id);
806 
807  if (!region)
808  continue;
809 
810  if (!region->dirty)
811  continue;
812 
813  rect = sub->rects[i];
814  rect->x = display->x_pos + offset_x;
815  rect->y = display->y_pos + offset_y;
816  rect->w = region->width;
817  rect->h = region->height;
818  rect->nb_colors = (1 << region->depth);
819  rect->type = SUBTITLE_BITMAP;
820  rect->pict.linesize[0] = region->width;
821 
822  clut = get_clut(ctx, region->clut);
823 
824  if (!clut)
825  clut = &default_clut;
826 
827  switch (region->depth) {
828  case 2:
829  clut_table = clut->clut4;
830  break;
831  case 8:
832  clut_table = clut->clut256;
833  break;
834  case 4:
835  default:
836  clut_table = clut->clut16;
837  break;
838  }
839 
840  rect->pict.data[1] = av_mallocz(AVPALETTE_SIZE);
841  if (!rect->pict.data[1]) {
842  ret = AVERROR(ENOMEM);
843  goto fail;
844  }
845  memcpy(rect->pict.data[1], clut_table, (1 << region->depth) * sizeof(uint32_t));
846 
847  rect->pict.data[0] = av_malloc(region->buf_size);
848  if (!rect->pict.data[0]) {
849  ret = AVERROR(ENOMEM);
850  goto fail;
851  }
852 
853  memcpy(rect->pict.data[0], region->pbuf, region->buf_size);
854 
855  i++;
856  }
857  }
858 
859  return 0;
860 fail:
861  if (sub->rects) {
862  for(i=0; i<sub->num_rects; i++) {
863  rect = sub->rects[i];
864  if (rect) {
865  av_freep(&rect->pict.data[0]);
866  av_freep(&rect->pict.data[1]);
867  }
868  av_freep(&sub->rects[i]);
869  }
870  av_freep(&sub->rects);
871  }
872  sub->num_rects = 0;
873  return ret;
874 }
875 
877  const uint8_t *buf, int buf_size, int top_bottom, int non_mod)
878 {
879  DVBSubContext *ctx = avctx->priv_data;
880 
881  DVBSubRegion *region = get_region(ctx, display->region_id);
882  const uint8_t *buf_end = buf + buf_size;
883  uint8_t *pbuf;
884  int x_pos, y_pos;
885  int i;
886 
887  uint8_t map2to4[] = { 0x0, 0x7, 0x8, 0xf};
888  uint8_t map2to8[] = {0x00, 0x77, 0x88, 0xff};
889  uint8_t map4to8[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
890  0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
891  uint8_t *map_table;
892 
893 #if 0
894  av_dlog(avctx, "DVB pixel block size %d, %s field:\n", buf_size,
895  top_bottom ? "bottom" : "top");
896 
897  for (i = 0; i < buf_size; i++) {
898  if (i % 16 == 0)
899  av_dlog(avctx, "0x%8p: ", buf+i);
900 
901  av_dlog(avctx, "%02x ", buf[i]);
902  if (i % 16 == 15)
903  av_dlog(avctx, "\n");
904  }
905 
906  if (i % 16)
907  av_dlog(avctx, "\n");
908 #endif
909 
910  if (!region)
911  return;
912 
913  pbuf = region->pbuf;
914  region->dirty = 1;
915 
916  x_pos = display->x_pos;
917  y_pos = display->y_pos;
918 
919  y_pos += top_bottom;
920 
921  while (buf < buf_end) {
922  if ((*buf!=0xf0 && x_pos >= region->width) || y_pos >= region->height) {
923  av_log(avctx, AV_LOG_ERROR, "Invalid object location! %d-%d %d-%d %02x\n", x_pos, region->width, y_pos, region->height, *buf);
924  return;
925  }
926 
927  switch (*buf++) {
928  case 0x10:
929  if (region->depth == 8)
930  map_table = map2to8;
931  else if (region->depth == 4)
932  map_table = map2to4;
933  else
934  map_table = NULL;
935 
936  x_pos = dvbsub_read_2bit_string(pbuf + (y_pos * region->width),
937  region->width, &buf, buf_end - buf,
938  non_mod, map_table, x_pos);
939  break;
940  case 0x11:
941  if (region->depth < 4) {
942  av_log(avctx, AV_LOG_ERROR, "4-bit pixel string in %d-bit region!\n", region->depth);
943  return;
944  }
945 
946  if (region->depth == 8)
947  map_table = map4to8;
948  else
949  map_table = NULL;
950 
951  x_pos = dvbsub_read_4bit_string(pbuf + (y_pos * region->width),
952  region->width, &buf, buf_end - buf,
953  non_mod, map_table, x_pos);
954  break;
955  case 0x12:
956  if (region->depth < 8) {
957  av_log(avctx, AV_LOG_ERROR, "8-bit pixel string in %d-bit region!\n", region->depth);
958  return;
959  }
960 
961  x_pos = dvbsub_read_8bit_string(pbuf + (y_pos * region->width),
962  region->width, &buf, buf_end - buf,
963  non_mod, NULL, x_pos);
964  break;
965 
966  case 0x20:
967  map2to4[0] = (*buf) >> 4;
968  map2to4[1] = (*buf++) & 0xf;
969  map2to4[2] = (*buf) >> 4;
970  map2to4[3] = (*buf++) & 0xf;
971  break;
972  case 0x21:
973  for (i = 0; i < 4; i++)
974  map2to8[i] = *buf++;
975  break;
976  case 0x22:
977  for (i = 0; i < 16; i++)
978  map4to8[i] = *buf++;
979  break;
980 
981  case 0xf0:
982  x_pos = display->x_pos;
983  y_pos += 2;
984  break;
985  default:
986  av_log(avctx, AV_LOG_INFO, "Unknown/unsupported pixel block 0x%x\n", *(buf-1));
987  }
988  }
989 
990 }
991 
993  const uint8_t *buf, int buf_size)
994 {
995  DVBSubContext *ctx = avctx->priv_data;
996 
997  const uint8_t *buf_end = buf + buf_size;
998  int object_id;
999  DVBSubObject *object;
1000  DVBSubObjectDisplay *display;
1001  int top_field_len, bottom_field_len;
1002 
1003  int coding_method, non_modifying_color;
1004 
1005  object_id = AV_RB16(buf);
1006  buf += 2;
1007 
1008  object = get_object(ctx, object_id);
1009 
1010  if (!object)
1011  return;
1012 
1013  coding_method = ((*buf) >> 2) & 3;
1014  non_modifying_color = ((*buf++) >> 1) & 1;
1015 
1016  if (coding_method == 0) {
1017  top_field_len = AV_RB16(buf);
1018  buf += 2;
1019  bottom_field_len = AV_RB16(buf);
1020  buf += 2;
1021 
1022  if (buf + top_field_len + bottom_field_len > buf_end) {
1023  av_log(avctx, AV_LOG_ERROR, "Field data size too large\n");
1024  return;
1025  }
1026 
1027  for (display = object->display_list; display; display = display->object_list_next) {
1028  const uint8_t *block = buf;
1029  int bfl = bottom_field_len;
1030 
1031  dvbsub_parse_pixel_data_block(avctx, display, block, top_field_len, 0,
1032  non_modifying_color);
1033 
1034  if (bottom_field_len > 0)
1035  block = buf + top_field_len;
1036  else
1037  bfl = top_field_len;
1038 
1039  dvbsub_parse_pixel_data_block(avctx, display, block, bfl, 1,
1040  non_modifying_color);
1041  }
1042 
1043 /* } else if (coding_method == 1) {*/
1044 
1045  } else {
1046  av_log(avctx, AV_LOG_ERROR, "Unknown object coding %d\n", coding_method);
1047  }
1048 
1049 }
1050 
1052  const uint8_t *buf, int buf_size)
1053 {
1054  DVBSubContext *ctx = avctx->priv_data;
1055 
1056  const uint8_t *buf_end = buf + buf_size;
1057  int i, clut_id;
1058  int version;
1059  DVBSubCLUT *clut;
1060  int entry_id, depth , full_range;
1061  int y, cr, cb, alpha;
1062  int r, g, b, r_add, g_add, b_add;
1063 
1064  av_dlog(avctx, "DVB clut packet:\n");
1065 
1066  for (i=0; i < buf_size; i++) {
1067  av_dlog(avctx, "%02x ", buf[i]);
1068  if (i % 16 == 15)
1069  av_dlog(avctx, "\n");
1070  }
1071 
1072  if (i % 16)
1073  av_dlog(avctx, "\n");
1074 
1075  clut_id = *buf++;
1076  version = ((*buf)>>4)&15;
1077  buf += 1;
1078 
1079  clut = get_clut(ctx, clut_id);
1080 
1081  if (!clut) {
1082  clut = av_malloc(sizeof(DVBSubCLUT));
1083 
1084  memcpy(clut, &default_clut, sizeof(DVBSubCLUT));
1085 
1086  clut->id = clut_id;
1087  clut->version = -1;
1088 
1089  clut->next = ctx->clut_list;
1090  ctx->clut_list = clut;
1091  }
1092 
1093  if (clut->version != version) {
1094 
1095  clut->version = version;
1096 
1097  while (buf + 4 < buf_end) {
1098  entry_id = *buf++;
1099 
1100  depth = (*buf) & 0xe0;
1101 
1102  if (depth == 0) {
1103  av_log(avctx, AV_LOG_ERROR, "Invalid clut depth 0x%x!\n", *buf);
1104  return 0;
1105  }
1106 
1107  full_range = (*buf++) & 1;
1108 
1109  if (full_range) {
1110  y = *buf++;
1111  cr = *buf++;
1112  cb = *buf++;
1113  alpha = *buf++;
1114  } else {
1115  y = buf[0] & 0xfc;
1116  cr = (((buf[0] & 3) << 2) | ((buf[1] >> 6) & 3)) << 4;
1117  cb = (buf[1] << 2) & 0xf0;
1118  alpha = (buf[1] << 6) & 0xc0;
1119 
1120  buf += 2;
1121  }
1122 
1123  if (y == 0)
1124  alpha = 0xff;
1125 
1126  YUV_TO_RGB1_CCIR(cb, cr);
1127  YUV_TO_RGB2_CCIR(r, g, b, y);
1128 
1129  av_dlog(avctx, "clut %d := (%d,%d,%d,%d)\n", entry_id, r, g, b, alpha);
1130  if (!!(depth & 0x80) + !!(depth & 0x40) + !!(depth & 0x20) > 1) {
1131  av_dlog(avctx, "More than one bit level marked: %x\n", depth);
1133  return AVERROR_INVALIDDATA;
1134  }
1135 
1136  if (depth & 0x80)
1137  clut->clut4[entry_id] = RGBA(r,g,b,255 - alpha);
1138  else if (depth & 0x40)
1139  clut->clut16[entry_id] = RGBA(r,g,b,255 - alpha);
1140  else if (depth & 0x20)
1141  clut->clut256[entry_id] = RGBA(r,g,b,255 - alpha);
1142  }
1143  }
1144  return 0;
1145 }
1146 
1147 
1149  const uint8_t *buf, int buf_size)
1150 {
1151  DVBSubContext *ctx = avctx->priv_data;
1152 
1153  const uint8_t *buf_end = buf + buf_size;
1154  int region_id, object_id;
1155  int av_unused version;
1156  DVBSubRegion *region;
1157  DVBSubObject *object;
1158  DVBSubObjectDisplay *display;
1159  int fill;
1160 
1161  if (buf_size < 10)
1162  return;
1163 
1164  region_id = *buf++;
1165 
1166  region = get_region(ctx, region_id);
1167 
1168  if (!region) {
1169  region = av_mallocz(sizeof(DVBSubRegion));
1170 
1171  region->id = region_id;
1172  region->version = -1;
1173 
1174  region->next = ctx->region_list;
1175  ctx->region_list = region;
1176  }
1177 
1178  version = ((*buf)>>4) & 15;
1179  fill = ((*buf++) >> 3) & 1;
1180 
1181  region->width = AV_RB16(buf);
1182  buf += 2;
1183  region->height = AV_RB16(buf);
1184  buf += 2;
1185 
1186  if (region->width * region->height != region->buf_size) {
1187  av_free(region->pbuf);
1188 
1189  region->buf_size = region->width * region->height;
1190 
1191  region->pbuf = av_malloc(region->buf_size);
1192 
1193  fill = 1;
1194  region->dirty = 0;
1195  }
1196 
1197  region->depth = 1 << (((*buf++) >> 2) & 7);
1198  if(region->depth<2 || region->depth>8){
1199  av_log(avctx, AV_LOG_ERROR, "region depth %d is invalid\n", region->depth);
1200  region->depth= 4;
1201  }
1202  region->clut = *buf++;
1203 
1204  if (region->depth == 8) {
1205  region->bgcolor = *buf++;
1206  buf += 1;
1207  } else {
1208  buf += 1;
1209 
1210  if (region->depth == 4)
1211  region->bgcolor = (((*buf++) >> 4) & 15);
1212  else
1213  region->bgcolor = (((*buf++) >> 2) & 3);
1214  }
1215 
1216  av_dlog(avctx, "Region %d, (%dx%d)\n", region_id, region->width, region->height);
1217 
1218  if (fill) {
1219  memset(region->pbuf, region->bgcolor, region->buf_size);
1220  av_dlog(avctx, "Fill region (%d)\n", region->bgcolor);
1221  }
1222 
1223  delete_region_display_list(ctx, region);
1224 
1225  while (buf + 5 < buf_end) {
1226  object_id = AV_RB16(buf);
1227  buf += 2;
1228 
1229  object = get_object(ctx, object_id);
1230 
1231  if (!object) {
1232  object = av_mallocz(sizeof(DVBSubObject));
1233 
1234  object->id = object_id;
1235  object->next = ctx->object_list;
1236  ctx->object_list = object;
1237  }
1238 
1239  object->type = (*buf) >> 6;
1240 
1241  display = av_mallocz(sizeof(DVBSubObjectDisplay));
1242 
1243  display->object_id = object_id;
1244  display->region_id = region_id;
1245 
1246  display->x_pos = AV_RB16(buf) & 0xfff;
1247  buf += 2;
1248  display->y_pos = AV_RB16(buf) & 0xfff;
1249  buf += 2;
1250 
1251  if ((object->type == 1 || object->type == 2) && buf+1 < buf_end) {
1252  display->fgcolor = *buf++;
1253  display->bgcolor = *buf++;
1254  }
1255 
1256  display->region_list_next = region->display_list;
1257  region->display_list = display;
1258 
1259  display->object_list_next = object->display_list;
1260  object->display_list = display;
1261  }
1262 }
1263 
1265  const uint8_t *buf, int buf_size, AVSubtitle *sub, int *got_output)
1266 {
1267  DVBSubContext *ctx = avctx->priv_data;
1268  DVBSubRegionDisplay *display;
1269  DVBSubRegionDisplay *tmp_display_list, **tmp_ptr;
1270 
1271  const uint8_t *buf_end = buf + buf_size;
1272  int region_id;
1273  int page_state;
1274  int timeout;
1275  int version;
1276 
1277  if (buf_size < 1)
1278  return;
1279 
1280  timeout = *buf++;
1281  version = ((*buf)>>4) & 15;
1282  page_state = ((*buf++) >> 2) & 3;
1283 
1284  if (ctx->version == version) {
1285  return;
1286  }
1287 
1288  ctx->time_out = timeout;
1289  ctx->version = version;
1290 
1291  av_dlog(avctx, "Page time out %ds, state %d\n", ctx->time_out, page_state);
1292 
1293  if(ctx->compute_edt == 1)
1294  save_subtitle_set(avctx, sub, got_output);
1295 
1296  if (page_state == 1 || page_state == 2) {
1297  delete_regions(ctx);
1298  delete_objects(ctx);
1299  delete_cluts(ctx);
1300  }
1301 
1302  tmp_display_list = ctx->display_list;
1303  ctx->display_list = NULL;
1304 
1305  while (buf + 5 < buf_end) {
1306  region_id = *buf++;
1307  buf += 1;
1308 
1309  display = tmp_display_list;
1310  tmp_ptr = &tmp_display_list;
1311 
1312  while (display && display->region_id != region_id) {
1313  tmp_ptr = &display->next;
1314  display = display->next;
1315  }
1316 
1317  if (!display)
1318  display = av_mallocz(sizeof(DVBSubRegionDisplay));
1319 
1320  display->region_id = region_id;
1321 
1322  display->x_pos = AV_RB16(buf);
1323  buf += 2;
1324  display->y_pos = AV_RB16(buf);
1325  buf += 2;
1326 
1327  *tmp_ptr = display->next;
1328 
1329  display->next = ctx->display_list;
1330  ctx->display_list = display;
1331 
1332  av_dlog(avctx, "Region %d, (%d,%d)\n", region_id, display->x_pos, display->y_pos);
1333  }
1334 
1335  while (tmp_display_list) {
1336  display = tmp_display_list;
1337 
1338  tmp_display_list = display->next;
1339 
1340  av_freep(&display);
1341  }
1342 
1343 }
1344 
1345 
1346 #ifdef DEBUG
1347 static void save_display_set(DVBSubContext *ctx)
1348 {
1349  DVBSubRegion *region;
1350  DVBSubRegionDisplay *display;
1351  DVBSubCLUT *clut;
1352  uint32_t *clut_table;
1353  int x_pos, y_pos, width, height;
1354  int x, y, y_off, x_off;
1355  uint32_t *pbuf;
1356  char filename[32];
1357  static int fileno_index = 0;
1358 
1359  x_pos = -1;
1360  y_pos = -1;
1361  width = 0;
1362  height = 0;
1363 
1364  for (display = ctx->display_list; display; display = display->next) {
1365  region = get_region(ctx, display->region_id);
1366 
1367  if (x_pos == -1) {
1368  x_pos = display->x_pos;
1369  y_pos = display->y_pos;
1370  width = region->width;
1371  height = region->height;
1372  } else {
1373  if (display->x_pos < x_pos) {
1374  width += (x_pos - display->x_pos);
1375  x_pos = display->x_pos;
1376  }
1377 
1378  if (display->y_pos < y_pos) {
1379  height += (y_pos - display->y_pos);
1380  y_pos = display->y_pos;
1381  }
1382 
1383  if (display->x_pos + region->width > x_pos + width) {
1384  width = display->x_pos + region->width - x_pos;
1385  }
1386 
1387  if (display->y_pos + region->height > y_pos + height) {
1388  height = display->y_pos + region->height - y_pos;
1389  }
1390  }
1391  }
1392 
1393  if (x_pos >= 0) {
1394 
1395  pbuf = av_malloc(width * height * 4);
1396 
1397  for (display = ctx->display_list; display; display = display->next) {
1398  region = get_region(ctx, display->region_id);
1399 
1400  x_off = display->x_pos - x_pos;
1401  y_off = display->y_pos - y_pos;
1402 
1403  clut = get_clut(ctx, region->clut);
1404 
1405  if (!clut)
1406  clut = &default_clut;
1407 
1408  switch (region->depth) {
1409  case 2:
1410  clut_table = clut->clut4;
1411  break;
1412  case 8:
1413  clut_table = clut->clut256;
1414  break;
1415  case 4:
1416  default:
1417  clut_table = clut->clut16;
1418  break;
1419  }
1420 
1421  for (y = 0; y < region->height; y++) {
1422  for (x = 0; x < region->width; x++) {
1423  pbuf[((y + y_off) * width) + x_off + x] =
1424  clut_table[region->pbuf[y * region->width + x]];
1425  }
1426  }
1427 
1428  }
1429 
1430  snprintf(filename, sizeof(filename), "dvbs.%d", fileno_index);
1431 
1432  png_save2(filename, pbuf, width, height);
1433 
1434  av_freep(&pbuf);
1435  }
1436 
1437  fileno_index++;
1438 }
1439 #endif
1440 
1442  const uint8_t *buf,
1443  int buf_size)
1444 {
1445  DVBSubContext *ctx = avctx->priv_data;
1446  DVBSubDisplayDefinition *display_def = ctx->display_definition;
1447  int dds_version, info_byte;
1448 
1449  if (buf_size < 5)
1450  return;
1451 
1452  info_byte = bytestream_get_byte(&buf);
1453  dds_version = info_byte >> 4;
1454  if (display_def && display_def->version == dds_version)
1455  return; // already have this display definition version
1456 
1457  if (!display_def) {
1458  display_def = av_mallocz(sizeof(*display_def));
1459  ctx->display_definition = display_def;
1460  }
1461  if (!display_def)
1462  return;
1463 
1464  display_def->version = dds_version;
1465  display_def->x = 0;
1466  display_def->y = 0;
1467  display_def->width = bytestream_get_be16(&buf) + 1;
1468  display_def->height = bytestream_get_be16(&buf) + 1;
1469  if (!avctx->width || !avctx->height) {
1470  avctx->width = display_def->width;
1471  avctx->height = display_def->height;
1472  }
1473 
1474  if (buf_size < 13)
1475  return;
1476 
1477  if (info_byte & 1<<3) { // display_window_flag
1478  display_def->x = bytestream_get_be16(&buf);
1479  display_def->width = bytestream_get_be16(&buf) - display_def->x + 1;
1480  display_def->y = bytestream_get_be16(&buf);
1481  display_def->height = bytestream_get_be16(&buf) - display_def->y + 1;
1482  }
1483 }
1484 
1486  int buf_size, AVSubtitle *sub,int *got_output)
1487 {
1488  DVBSubContext *ctx = avctx->priv_data;
1489 
1490  if(ctx->compute_edt == 0)
1491  save_subtitle_set(avctx, sub, got_output);
1492 #ifdef DEBUG
1493  save_display_set(ctx);
1494 #endif
1495 
1496 }
1497 
1498 static int dvbsub_decode(AVCodecContext *avctx,
1499  void *data, int *data_size,
1500  AVPacket *avpkt)
1501 {
1502  const uint8_t *buf = avpkt->data;
1503  int buf_size = avpkt->size;
1504  DVBSubContext *ctx = avctx->priv_data;
1505  AVSubtitle *sub = data;
1506  const uint8_t *p, *p_end;
1507  int segment_type;
1508  int page_id;
1509  int segment_length;
1510  int i;
1511  int ret = 0;
1512  int got_segment = 0;
1513 
1514  av_dlog(avctx, "DVB sub packet:\n");
1515 
1516  for (i=0; i < buf_size; i++) {
1517  av_dlog(avctx, "%02x ", buf[i]);
1518  if (i % 16 == 15)
1519  av_dlog(avctx, "\n");
1520  }
1521 
1522  if (i % 16)
1523  av_dlog(avctx, "\n");
1524 
1525  if (buf_size <= 6 || *buf != 0x0f) {
1526  av_dlog(avctx, "incomplete or broken packet");
1527  return -1;
1528  }
1529 
1530  p = buf;
1531  p_end = buf + buf_size;
1532 
1533  while (p_end - p >= 6 && *p == 0x0f) {
1534  p += 1;
1535  segment_type = *p++;
1536  page_id = AV_RB16(p);
1537  p += 2;
1538  segment_length = AV_RB16(p);
1539  p += 2;
1540 
1541  if (avctx->debug & FF_DEBUG_STARTCODE) {
1542  av_log(avctx, AV_LOG_DEBUG, "segment_type:%d page_id:%d segment_length:%d\n", segment_type, page_id, segment_length);
1543  }
1544 
1545  if (p_end - p < segment_length) {
1546  av_dlog(avctx, "incomplete or broken packet");
1547  ret = -1;
1548  goto end;
1549  }
1550 
1551  if (page_id == ctx->composition_id || page_id == ctx->ancillary_id ||
1552  ctx->composition_id == -1 || ctx->ancillary_id == -1) {
1553  switch (segment_type) {
1554  case DVBSUB_PAGE_SEGMENT:
1555  dvbsub_parse_page_segment(avctx, p, segment_length, sub, data_size);
1556  got_segment |= 1;
1557  break;
1558  case DVBSUB_REGION_SEGMENT:
1559  dvbsub_parse_region_segment(avctx, p, segment_length);
1560  got_segment |= 2;
1561  break;
1562  case DVBSUB_CLUT_SEGMENT:
1563  ret = dvbsub_parse_clut_segment(avctx, p, segment_length);
1564  if (ret < 0) goto end;
1565  got_segment |= 4;
1566  break;
1567  case DVBSUB_OBJECT_SEGMENT:
1568  dvbsub_parse_object_segment(avctx, p, segment_length);
1569  got_segment |= 8;
1570  break;
1572  dvbsub_parse_display_definition_segment(avctx, p, segment_length);
1573  break;
1575  dvbsub_display_end_segment(avctx, p, segment_length, sub, data_size);
1576  got_segment |= 16;
1577  break;
1578  default:
1579  av_dlog(avctx, "Subtitling segment type 0x%x, page id %d, length %d\n",
1580  segment_type, page_id, segment_length);
1581  break;
1582  }
1583  }
1584 
1585  p += segment_length;
1586  }
1587  // Some streams do not send a display segment but if we have all the other
1588  // segments then we need no further data.
1589  if (got_segment == 15) {
1590  av_log(avctx, AV_LOG_DEBUG, "Missing display_end_segment, emulating\n");
1591  dvbsub_display_end_segment(avctx, p, 0, sub, data_size);
1592  }
1593 
1594 end:
1595  if(ret < 0) {
1596  *data_size = 0;
1597  avsubtitle_free(sub);
1598  return ret;
1599  } else {
1600  if(ctx->compute_edt == 1 )
1601  FFSWAP(int64_t, ctx->prev_start, sub->pts);
1602  }
1603 
1604  return p - buf;
1605 }
1606 
1607 #define DS AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_SUBTITLE_PARAM
1608 static const AVOption options[] = {
1609  {"compute_edt", "compute end of time using pts or timeout", offsetof(DVBSubContext, compute_edt), FF_OPT_TYPE_INT, {.i64 = 0}, 0, 1, DS},
1610  {NULL}
1611 };
1612 static const AVClass dvbsubdec_class = {
1613  .class_name = "DVB Sub Decoder",
1614  .item_name = av_default_item_name,
1615  .option = options,
1616  .version = LIBAVUTIL_VERSION_INT,
1617 };
1618 
1620  .name = "dvbsub",
1621  .long_name = NULL_IF_CONFIG_SMALL("DVB subtitles"),
1622  .type = AVMEDIA_TYPE_SUBTITLE,
1624  .priv_data_size = sizeof(DVBSubContext),
1627  .decode = dvbsub_decode,
1628  .priv_class = &dvbsubdec_class,
1629 };