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  assert(obj2);
310  obj2_ptr = &obj2->next;
311  obj2 = *obj2_ptr;
312  }
313 
314  *obj2_ptr = obj2->next;
315 
316  av_free(obj2);
317  }
318  }
319  }
320 
321  region->display_list = display->region_list_next;
322 
323  av_free(display);
324  }
325 
326 }
327 
328 static void delete_cluts(DVBSubContext *ctx)
329 {
330  DVBSubCLUT *clut;
331 
332  while (ctx->clut_list) {
333  clut = ctx->clut_list;
334 
335  ctx->clut_list = clut->next;
336 
337  av_free(clut);
338  }
339 }
340 
341 static void delete_objects(DVBSubContext *ctx)
342 {
343  DVBSubObject *object;
344 
345  while (ctx->object_list) {
346  object = ctx->object_list;
347 
348  ctx->object_list = object->next;
349 
350  av_free(object);
351  }
352 }
353 
354 static void delete_regions(DVBSubContext *ctx)
355 {
356  DVBSubRegion *region;
357 
358  while (ctx->region_list) {
359  region = ctx->region_list;
360 
361  ctx->region_list = region->next;
362 
363  delete_region_display_list(ctx, region);
364 
365  av_free(region->pbuf);
366  av_free(region);
367  }
368 }
369 
371 {
372  int i, r, g, b, a = 0;
373  DVBSubContext *ctx = avctx->priv_data;
374 
375  if (!avctx->extradata || (avctx->extradata_size < 4) || ((avctx->extradata_size % 5 != 0) && (avctx->extradata_size != 4))) {
376  av_log(avctx, AV_LOG_WARNING, "Invalid DVB subtitles stream extradata!\n");
377  ctx->composition_id = -1;
378  ctx->ancillary_id = -1;
379  } else {
380  if (avctx->extradata_size > 5) {
381  av_log(avctx, AV_LOG_WARNING, "Decoding first DVB subtitles sub-stream\n");
382  }
383 
384  ctx->composition_id = AV_RB16(avctx->extradata);
385  ctx->ancillary_id = AV_RB16(avctx->extradata + 2);
386  }
387 
388  ctx->version = -1;
389  ctx->prev_start = AV_NOPTS_VALUE;
390 
391  default_clut.id = -1;
392  default_clut.next = NULL;
393 
394  default_clut.clut4[0] = RGBA( 0, 0, 0, 0);
395  default_clut.clut4[1] = RGBA(255, 255, 255, 255);
396  default_clut.clut4[2] = RGBA( 0, 0, 0, 255);
397  default_clut.clut4[3] = RGBA(127, 127, 127, 255);
398 
399  default_clut.clut16[0] = RGBA( 0, 0, 0, 0);
400  for (i = 1; i < 16; i++) {
401  if (i < 8) {
402  r = (i & 1) ? 255 : 0;
403  g = (i & 2) ? 255 : 0;
404  b = (i & 4) ? 255 : 0;
405  } else {
406  r = (i & 1) ? 127 : 0;
407  g = (i & 2) ? 127 : 0;
408  b = (i & 4) ? 127 : 0;
409  }
410  default_clut.clut16[i] = RGBA(r, g, b, 255);
411  }
412 
413  default_clut.clut256[0] = RGBA( 0, 0, 0, 0);
414  for (i = 1; i < 256; i++) {
415  if (i < 8) {
416  r = (i & 1) ? 255 : 0;
417  g = (i & 2) ? 255 : 0;
418  b = (i & 4) ? 255 : 0;
419  a = 63;
420  } else {
421  switch (i & 0x88) {
422  case 0x00:
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 = 255;
427  break;
428  case 0x08:
429  r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0);
430  g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0);
431  b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0);
432  a = 127;
433  break;
434  case 0x80:
435  r = 127 + ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0);
436  g = 127 + ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0);
437  b = 127 + ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0);
438  a = 255;
439  break;
440  case 0x88:
441  r = ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0);
442  g = ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0);
443  b = ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0);
444  a = 255;
445  break;
446  }
447  }
448  default_clut.clut256[i] = RGBA(r, g, b, a);
449  }
450 
451  return 0;
452 }
453 
455 {
456  DVBSubContext *ctx = avctx->priv_data;
457  DVBSubRegionDisplay *display;
458 
459  delete_regions(ctx);
460 
461  delete_objects(ctx);
462 
463  delete_cluts(ctx);
464 
466 
467  while (ctx->display_list) {
468  display = ctx->display_list;
469  ctx->display_list = display->next;
470 
471  av_free(display);
472  }
473 
474  return 0;
475 }
476 
477 static int dvbsub_read_2bit_string(uint8_t *destbuf, int dbuf_len,
478  const uint8_t **srcbuf, int buf_size,
479  int non_mod, uint8_t *map_table, int x_pos)
480 {
481  GetBitContext gb;
482 
483  int bits;
484  int run_length;
485  int pixels_read = x_pos;
486 
487  init_get_bits(&gb, *srcbuf, buf_size << 3);
488 
489  destbuf += x_pos;
490 
491  while (get_bits_count(&gb) < buf_size << 3 && pixels_read < dbuf_len) {
492  bits = get_bits(&gb, 2);
493 
494  if (bits) {
495  if (non_mod != 1 || bits != 1) {
496  if (map_table)
497  *destbuf++ = map_table[bits];
498  else
499  *destbuf++ = bits;
500  }
501  pixels_read++;
502  } else {
503  bits = get_bits1(&gb);
504  if (bits == 1) {
505  run_length = get_bits(&gb, 3) + 3;
506  bits = get_bits(&gb, 2);
507 
508  if (non_mod == 1 && bits == 1)
509  pixels_read += run_length;
510  else {
511  if (map_table)
512  bits = map_table[bits];
513  while (run_length-- > 0 && pixels_read < dbuf_len) {
514  *destbuf++ = bits;
515  pixels_read++;
516  }
517  }
518  } else {
519  bits = get_bits1(&gb);
520  if (bits == 0) {
521  bits = get_bits(&gb, 2);
522  if (bits == 2) {
523  run_length = get_bits(&gb, 4) + 12;
524  bits = get_bits(&gb, 2);
525 
526  if (non_mod == 1 && bits == 1)
527  pixels_read += run_length;
528  else {
529  if (map_table)
530  bits = map_table[bits];
531  while (run_length-- > 0 && pixels_read < dbuf_len) {
532  *destbuf++ = bits;
533  pixels_read++;
534  }
535  }
536  } else if (bits == 3) {
537  run_length = get_bits(&gb, 8) + 29;
538  bits = get_bits(&gb, 2);
539 
540  if (non_mod == 1 && bits == 1)
541  pixels_read += run_length;
542  else {
543  if (map_table)
544  bits = map_table[bits];
545  while (run_length-- > 0 && pixels_read < dbuf_len) {
546  *destbuf++ = bits;
547  pixels_read++;
548  }
549  }
550  } else if (bits == 1) {
551  if (map_table)
552  bits = map_table[0];
553  else
554  bits = 0;
555  run_length = 2;
556  while (run_length-- > 0 && pixels_read < dbuf_len) {
557  *destbuf++ = bits;
558  pixels_read++;
559  }
560  } else {
561  (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
562  return pixels_read;
563  }
564  } else {
565  if (map_table)
566  bits = map_table[0];
567  else
568  bits = 0;
569  *destbuf++ = bits;
570  pixels_read++;
571  }
572  }
573  }
574  }
575 
576  if (get_bits(&gb, 6))
577  av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n");
578 
579  (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
580 
581  return pixels_read;
582 }
583 
584 static int dvbsub_read_4bit_string(uint8_t *destbuf, int dbuf_len,
585  const uint8_t **srcbuf, int buf_size,
586  int non_mod, uint8_t *map_table, int x_pos)
587 {
588  GetBitContext gb;
589 
590  int bits;
591  int run_length;
592  int pixels_read = x_pos;
593 
594  init_get_bits(&gb, *srcbuf, buf_size << 3);
595 
596  destbuf += x_pos;
597 
598  while (get_bits_count(&gb) < buf_size << 3 && pixels_read < dbuf_len) {
599  bits = get_bits(&gb, 4);
600 
601  if (bits) {
602  if (non_mod != 1 || bits != 1) {
603  if (map_table)
604  *destbuf++ = map_table[bits];
605  else
606  *destbuf++ = bits;
607  }
608  pixels_read++;
609  } else {
610  bits = get_bits1(&gb);
611  if (bits == 0) {
612  run_length = get_bits(&gb, 3);
613 
614  if (run_length == 0) {
615  (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
616  return pixels_read;
617  }
618 
619  run_length += 2;
620 
621  if (map_table)
622  bits = map_table[0];
623  else
624  bits = 0;
625 
626  while (run_length-- > 0 && pixels_read < dbuf_len) {
627  *destbuf++ = bits;
628  pixels_read++;
629  }
630  } else {
631  bits = get_bits1(&gb);
632  if (bits == 0) {
633  run_length = get_bits(&gb, 2) + 4;
634  bits = get_bits(&gb, 4);
635 
636  if (non_mod == 1 && bits == 1)
637  pixels_read += run_length;
638  else {
639  if (map_table)
640  bits = map_table[bits];
641  while (run_length-- > 0 && pixels_read < dbuf_len) {
642  *destbuf++ = bits;
643  pixels_read++;
644  }
645  }
646  } else {
647  bits = get_bits(&gb, 2);
648  if (bits == 2) {
649  run_length = get_bits(&gb, 4) + 9;
650  bits = get_bits(&gb, 4);
651 
652  if (non_mod == 1 && bits == 1)
653  pixels_read += run_length;
654  else {
655  if (map_table)
656  bits = map_table[bits];
657  while (run_length-- > 0 && pixels_read < dbuf_len) {
658  *destbuf++ = bits;
659  pixels_read++;
660  }
661  }
662  } else if (bits == 3) {
663  run_length = get_bits(&gb, 8) + 25;
664  bits = get_bits(&gb, 4);
665 
666  if (non_mod == 1 && bits == 1)
667  pixels_read += run_length;
668  else {
669  if (map_table)
670  bits = map_table[bits];
671  while (run_length-- > 0 && pixels_read < dbuf_len) {
672  *destbuf++ = bits;
673  pixels_read++;
674  }
675  }
676  } else if (bits == 1) {
677  if (map_table)
678  bits = map_table[0];
679  else
680  bits = 0;
681  run_length = 2;
682  while (run_length-- > 0 && pixels_read < dbuf_len) {
683  *destbuf++ = bits;
684  pixels_read++;
685  }
686  } else {
687  if (map_table)
688  bits = map_table[0];
689  else
690  bits = 0;
691  *destbuf++ = bits;
692  pixels_read ++;
693  }
694  }
695  }
696  }
697  }
698 
699  if (get_bits(&gb, 8))
700  av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n");
701 
702  (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
703 
704  return pixels_read;
705 }
706 
707 static int dvbsub_read_8bit_string(uint8_t *destbuf, int dbuf_len,
708  const uint8_t **srcbuf, int buf_size,
709  int non_mod, uint8_t *map_table, int x_pos)
710 {
711  const uint8_t *sbuf_end = (*srcbuf) + buf_size;
712  int bits;
713  int run_length;
714  int pixels_read = x_pos;
715 
716  destbuf += x_pos;
717 
718  while (*srcbuf < sbuf_end && pixels_read < dbuf_len) {
719  bits = *(*srcbuf)++;
720 
721  if (bits) {
722  if (non_mod != 1 || bits != 1) {
723  if (map_table)
724  *destbuf++ = map_table[bits];
725  else
726  *destbuf++ = bits;
727  }
728  pixels_read++;
729  } else {
730  bits = *(*srcbuf)++;
731  run_length = bits & 0x7f;
732  if ((bits & 0x80) == 0) {
733  if (run_length == 0) {
734  return pixels_read;
735  }
736 
737  if (map_table)
738  bits = map_table[0];
739  else
740  bits = 0;
741  while (run_length-- > 0 && pixels_read < dbuf_len) {
742  *destbuf++ = bits;
743  pixels_read++;
744  }
745  } else {
746  bits = *(*srcbuf)++;
747 
748  if (non_mod == 1 && bits == 1)
749  pixels_read += run_length;
750  if (map_table)
751  bits = map_table[bits];
752  else while (run_length-- > 0 && pixels_read < dbuf_len) {
753  *destbuf++ = bits;
754  pixels_read++;
755  }
756  }
757  }
758  }
759 
760  if (*(*srcbuf)++)
761  av_log(0, AV_LOG_ERROR, "DVBSub error: line overflow\n");
762 
763  return pixels_read;
764 }
765 
766 static void save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_output)
767 {
768  DVBSubContext *ctx = avctx->priv_data;
769  DVBSubRegionDisplay *display;
770  DVBSubDisplayDefinition *display_def = ctx->display_definition;
771  DVBSubRegion *region;
773  DVBSubCLUT *clut;
774  uint32_t *clut_table;
775  int i;
776  int offset_x=0, offset_y=0;
777 
778 
779  if (display_def) {
780  offset_x = display_def->x;
781  offset_y = display_def->y;
782  }
783 
784  /* Not touching AVSubtitles again*/
785  if(sub->num_rects) {
786  avpriv_request_sample(ctx, "Different Version of Segment asked Twice\n");
787  return;
788  }
789  for (display = ctx->display_list; display; display = display->next) {
790  region = get_region(ctx, display->region_id);
791  if (region && region->dirty)
792  sub->num_rects++;
793  }
794 
795  if(ctx->compute_edt == 0) {
796  sub->end_display_time = ctx->time_out * 1000;
797  *got_output = 1;
798  } else if (ctx->prev_start != AV_NOPTS_VALUE) {
799  sub->end_display_time = av_rescale_q((sub->pts - ctx->prev_start ), AV_TIME_BASE_Q, (AVRational){ 1, 1000 }) - 1;
800  *got_output = 1;
801  }
802  if (sub->num_rects > 0) {
803 
804  sub->rects = av_mallocz_array(sizeof(*sub->rects), sub->num_rects);
805  for(i=0; i<sub->num_rects; i++)
806  sub->rects[i] = av_mallocz(sizeof(*sub->rects[i]));
807 
808  i = 0;
809 
810  for (display = ctx->display_list; display; display = display->next) {
811  region = get_region(ctx, display->region_id);
812 
813  if (!region)
814  continue;
815 
816  if (!region->dirty)
817  continue;
818 
819  rect = sub->rects[i];
820  rect->x = display->x_pos + offset_x;
821  rect->y = display->y_pos + offset_y;
822  rect->w = region->width;
823  rect->h = region->height;
824  rect->nb_colors = (1 << region->depth);
825  rect->type = SUBTITLE_BITMAP;
826  rect->pict.linesize[0] = region->width;
827 
828  clut = get_clut(ctx, region->clut);
829 
830  if (!clut)
831  clut = &default_clut;
832 
833  switch (region->depth) {
834  case 2:
835  clut_table = clut->clut4;
836  break;
837  case 8:
838  clut_table = clut->clut256;
839  break;
840  case 4:
841  default:
842  clut_table = clut->clut16;
843  break;
844  }
845 
846  rect->pict.data[1] = av_mallocz(AVPALETTE_SIZE);
847  memcpy(rect->pict.data[1], clut_table, (1 << region->depth) * sizeof(uint32_t));
848 
849  rect->pict.data[0] = av_malloc(region->buf_size);
850  memcpy(rect->pict.data[0], region->pbuf, region->buf_size);
851 
852  i++;
853  }
854  }
855 }
856 
858  const uint8_t *buf, int buf_size, int top_bottom, int non_mod)
859 {
860  DVBSubContext *ctx = avctx->priv_data;
861 
862  DVBSubRegion *region = get_region(ctx, display->region_id);
863  const uint8_t *buf_end = buf + buf_size;
864  uint8_t *pbuf;
865  int x_pos, y_pos;
866  int i;
867 
868  uint8_t map2to4[] = { 0x0, 0x7, 0x8, 0xf};
869  uint8_t map2to8[] = {0x00, 0x77, 0x88, 0xff};
870  uint8_t map4to8[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
871  0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
872  uint8_t *map_table;
873 
874 #if 0
875  av_dlog(avctx, "DVB pixel block size %d, %s field:\n", buf_size,
876  top_bottom ? "bottom" : "top");
877 
878  for (i = 0; i < buf_size; i++) {
879  if (i % 16 == 0)
880  av_dlog(avctx, "0x%8p: ", buf+i);
881 
882  av_dlog(avctx, "%02x ", buf[i]);
883  if (i % 16 == 15)
884  av_dlog(avctx, "\n");
885  }
886 
887  if (i % 16)
888  av_dlog(avctx, "\n");
889 #endif
890 
891  if (!region)
892  return;
893 
894  pbuf = region->pbuf;
895  region->dirty = 1;
896 
897  x_pos = display->x_pos;
898  y_pos = display->y_pos;
899 
900  y_pos += top_bottom;
901 
902  while (buf < buf_end) {
903  if ((*buf!=0xf0 && x_pos >= region->width) || y_pos >= region->height) {
904  av_log(avctx, AV_LOG_ERROR, "Invalid object location! %d-%d %d-%d %02x\n", x_pos, region->width, y_pos, region->height, *buf);
905  return;
906  }
907 
908  switch (*buf++) {
909  case 0x10:
910  if (region->depth == 8)
911  map_table = map2to8;
912  else if (region->depth == 4)
913  map_table = map2to4;
914  else
915  map_table = NULL;
916 
917  x_pos = dvbsub_read_2bit_string(pbuf + (y_pos * region->width),
918  region->width, &buf, buf_end - buf,
919  non_mod, map_table, x_pos);
920  break;
921  case 0x11:
922  if (region->depth < 4) {
923  av_log(avctx, AV_LOG_ERROR, "4-bit pixel string in %d-bit region!\n", region->depth);
924  return;
925  }
926 
927  if (region->depth == 8)
928  map_table = map4to8;
929  else
930  map_table = NULL;
931 
932  x_pos = dvbsub_read_4bit_string(pbuf + (y_pos * region->width),
933  region->width, &buf, buf_end - buf,
934  non_mod, map_table, x_pos);
935  break;
936  case 0x12:
937  if (region->depth < 8) {
938  av_log(avctx, AV_LOG_ERROR, "8-bit pixel string in %d-bit region!\n", region->depth);
939  return;
940  }
941 
942  x_pos = dvbsub_read_8bit_string(pbuf + (y_pos * region->width),
943  region->width, &buf, buf_end - buf,
944  non_mod, NULL, x_pos);
945  break;
946 
947  case 0x20:
948  map2to4[0] = (*buf) >> 4;
949  map2to4[1] = (*buf++) & 0xf;
950  map2to4[2] = (*buf) >> 4;
951  map2to4[3] = (*buf++) & 0xf;
952  break;
953  case 0x21:
954  for (i = 0; i < 4; i++)
955  map2to8[i] = *buf++;
956  break;
957  case 0x22:
958  for (i = 0; i < 16; i++)
959  map4to8[i] = *buf++;
960  break;
961 
962  case 0xf0:
963  x_pos = display->x_pos;
964  y_pos += 2;
965  break;
966  default:
967  av_log(avctx, AV_LOG_INFO, "Unknown/unsupported pixel block 0x%x\n", *(buf-1));
968  }
969  }
970 
971 }
972 
974  const uint8_t *buf, int buf_size)
975 {
976  DVBSubContext *ctx = avctx->priv_data;
977 
978  const uint8_t *buf_end = buf + buf_size;
979  int object_id;
980  DVBSubObject *object;
981  DVBSubObjectDisplay *display;
982  int top_field_len, bottom_field_len;
983 
984  int coding_method, non_modifying_color;
985 
986  object_id = AV_RB16(buf);
987  buf += 2;
988 
989  object = get_object(ctx, object_id);
990 
991  if (!object)
992  return;
993 
994  coding_method = ((*buf) >> 2) & 3;
995  non_modifying_color = ((*buf++) >> 1) & 1;
996 
997  if (coding_method == 0) {
998  top_field_len = AV_RB16(buf);
999  buf += 2;
1000  bottom_field_len = AV_RB16(buf);
1001  buf += 2;
1002 
1003  if (buf + top_field_len + bottom_field_len > buf_end) {
1004  av_log(avctx, AV_LOG_ERROR, "Field data size too large\n");
1005  return;
1006  }
1007 
1008  for (display = object->display_list; display; display = display->object_list_next) {
1009  const uint8_t *block = buf;
1010  int bfl = bottom_field_len;
1011 
1012  dvbsub_parse_pixel_data_block(avctx, display, block, top_field_len, 0,
1013  non_modifying_color);
1014 
1015  if (bottom_field_len > 0)
1016  block = buf + top_field_len;
1017  else
1018  bfl = top_field_len;
1019 
1020  dvbsub_parse_pixel_data_block(avctx, display, block, bfl, 1,
1021  non_modifying_color);
1022  }
1023 
1024 /* } else if (coding_method == 1) {*/
1025 
1026  } else {
1027  av_log(avctx, AV_LOG_ERROR, "Unknown object coding %d\n", coding_method);
1028  }
1029 
1030 }
1031 
1033  const uint8_t *buf, int buf_size)
1034 {
1035  DVBSubContext *ctx = avctx->priv_data;
1036 
1037  const uint8_t *buf_end = buf + buf_size;
1038  int i, clut_id;
1039  int version;
1040  DVBSubCLUT *clut;
1041  int entry_id, depth , full_range;
1042  int y, cr, cb, alpha;
1043  int r, g, b, r_add, g_add, b_add;
1044 
1045  av_dlog(avctx, "DVB clut packet:\n");
1046 
1047  for (i=0; i < buf_size; i++) {
1048  av_dlog(avctx, "%02x ", buf[i]);
1049  if (i % 16 == 15)
1050  av_dlog(avctx, "\n");
1051  }
1052 
1053  if (i % 16)
1054  av_dlog(avctx, "\n");
1055 
1056  clut_id = *buf++;
1057  version = ((*buf)>>4)&15;
1058  buf += 1;
1059 
1060  clut = get_clut(ctx, clut_id);
1061 
1062  if (!clut) {
1063  clut = av_malloc(sizeof(DVBSubCLUT));
1064 
1065  memcpy(clut, &default_clut, sizeof(DVBSubCLUT));
1066 
1067  clut->id = clut_id;
1068  clut->version = -1;
1069 
1070  clut->next = ctx->clut_list;
1071  ctx->clut_list = clut;
1072  }
1073 
1074  if (clut->version != version) {
1075 
1076  clut->version = version;
1077 
1078  while (buf + 4 < buf_end) {
1079  entry_id = *buf++;
1080 
1081  depth = (*buf) & 0xe0;
1082 
1083  if (depth == 0) {
1084  av_log(avctx, AV_LOG_ERROR, "Invalid clut depth 0x%x!\n", *buf);
1085  return 0;
1086  }
1087 
1088  full_range = (*buf++) & 1;
1089 
1090  if (full_range) {
1091  y = *buf++;
1092  cr = *buf++;
1093  cb = *buf++;
1094  alpha = *buf++;
1095  } else {
1096  y = buf[0] & 0xfc;
1097  cr = (((buf[0] & 3) << 2) | ((buf[1] >> 6) & 3)) << 4;
1098  cb = (buf[1] << 2) & 0xf0;
1099  alpha = (buf[1] << 6) & 0xc0;
1100 
1101  buf += 2;
1102  }
1103 
1104  if (y == 0)
1105  alpha = 0xff;
1106 
1107  YUV_TO_RGB1_CCIR(cb, cr);
1108  YUV_TO_RGB2_CCIR(r, g, b, y);
1109 
1110  av_dlog(avctx, "clut %d := (%d,%d,%d,%d)\n", entry_id, r, g, b, alpha);
1111  if (!!(depth & 0x80) + !!(depth & 0x40) + !!(depth & 0x20) > 1) {
1112  av_dlog(avctx, "More than one bit level marked: %x\n", depth);
1114  return AVERROR_INVALIDDATA;
1115  }
1116 
1117  if (depth & 0x80)
1118  clut->clut4[entry_id] = RGBA(r,g,b,255 - alpha);
1119  else if (depth & 0x40)
1120  clut->clut16[entry_id] = RGBA(r,g,b,255 - alpha);
1121  else if (depth & 0x20)
1122  clut->clut256[entry_id] = RGBA(r,g,b,255 - alpha);
1123  }
1124  }
1125  return 0;
1126 }
1127 
1128 
1130  const uint8_t *buf, int buf_size)
1131 {
1132  DVBSubContext *ctx = avctx->priv_data;
1133 
1134  const uint8_t *buf_end = buf + buf_size;
1135  int region_id, object_id;
1136  int av_unused version;
1137  DVBSubRegion *region;
1138  DVBSubObject *object;
1139  DVBSubObjectDisplay *display;
1140  int fill;
1141 
1142  if (buf_size < 10)
1143  return;
1144 
1145  region_id = *buf++;
1146 
1147  region = get_region(ctx, region_id);
1148 
1149  if (!region) {
1150  region = av_mallocz(sizeof(DVBSubRegion));
1151 
1152  region->id = region_id;
1153  region->version = -1;
1154 
1155  region->next = ctx->region_list;
1156  ctx->region_list = region;
1157  }
1158 
1159  version = ((*buf)>>4) & 15;
1160  fill = ((*buf++) >> 3) & 1;
1161 
1162  region->width = AV_RB16(buf);
1163  buf += 2;
1164  region->height = AV_RB16(buf);
1165  buf += 2;
1166 
1167  if (region->width * region->height != region->buf_size) {
1168  av_free(region->pbuf);
1169 
1170  region->buf_size = region->width * region->height;
1171 
1172  region->pbuf = av_malloc(region->buf_size);
1173 
1174  fill = 1;
1175  region->dirty = 0;
1176  }
1177 
1178  region->depth = 1 << (((*buf++) >> 2) & 7);
1179  if(region->depth<2 || region->depth>8){
1180  av_log(avctx, AV_LOG_ERROR, "region depth %d is invalid\n", region->depth);
1181  region->depth= 4;
1182  }
1183  region->clut = *buf++;
1184 
1185  if (region->depth == 8) {
1186  region->bgcolor = *buf++;
1187  buf += 1;
1188  } else {
1189  buf += 1;
1190 
1191  if (region->depth == 4)
1192  region->bgcolor = (((*buf++) >> 4) & 15);
1193  else
1194  region->bgcolor = (((*buf++) >> 2) & 3);
1195  }
1196 
1197  av_dlog(avctx, "Region %d, (%dx%d)\n", region_id, region->width, region->height);
1198 
1199  if (fill) {
1200  memset(region->pbuf, region->bgcolor, region->buf_size);
1201  av_dlog(avctx, "Fill region (%d)\n", region->bgcolor);
1202  }
1203 
1204  delete_region_display_list(ctx, region);
1205 
1206  while (buf + 5 < buf_end) {
1207  object_id = AV_RB16(buf);
1208  buf += 2;
1209 
1210  object = get_object(ctx, object_id);
1211 
1212  if (!object) {
1213  object = av_mallocz(sizeof(DVBSubObject));
1214 
1215  object->id = object_id;
1216  object->next = ctx->object_list;
1217  ctx->object_list = object;
1218  }
1219 
1220  object->type = (*buf) >> 6;
1221 
1222  display = av_mallocz(sizeof(DVBSubObjectDisplay));
1223 
1224  display->object_id = object_id;
1225  display->region_id = region_id;
1226 
1227  display->x_pos = AV_RB16(buf) & 0xfff;
1228  buf += 2;
1229  display->y_pos = AV_RB16(buf) & 0xfff;
1230  buf += 2;
1231 
1232  if ((object->type == 1 || object->type == 2) && buf+1 < buf_end) {
1233  display->fgcolor = *buf++;
1234  display->bgcolor = *buf++;
1235  }
1236 
1237  display->region_list_next = region->display_list;
1238  region->display_list = display;
1239 
1240  display->object_list_next = object->display_list;
1241  object->display_list = display;
1242  }
1243 }
1244 
1246  const uint8_t *buf, int buf_size, AVSubtitle *sub, int *got_output)
1247 {
1248  DVBSubContext *ctx = avctx->priv_data;
1249  DVBSubRegionDisplay *display;
1250  DVBSubRegionDisplay *tmp_display_list, **tmp_ptr;
1251 
1252  const uint8_t *buf_end = buf + buf_size;
1253  int region_id;
1254  int page_state;
1255  int timeout;
1256  int version;
1257 
1258  if (buf_size < 1)
1259  return;
1260 
1261  timeout = *buf++;
1262  version = ((*buf)>>4) & 15;
1263  page_state = ((*buf++) >> 2) & 3;
1264 
1265  if (ctx->version == version) {
1266  return;
1267  }
1268 
1269  ctx->time_out = timeout;
1270  ctx->version = version;
1271 
1272  av_dlog(avctx, "Page time out %ds, state %d\n", ctx->time_out, page_state);
1273 
1274  if(ctx->compute_edt == 1)
1275  save_subtitle_set(avctx, sub, got_output);
1276 
1277  if (page_state == 1 || page_state == 2) {
1278  delete_regions(ctx);
1279  delete_objects(ctx);
1280  delete_cluts(ctx);
1281  }
1282 
1283  tmp_display_list = ctx->display_list;
1284  ctx->display_list = NULL;
1285 
1286  while (buf + 5 < buf_end) {
1287  region_id = *buf++;
1288  buf += 1;
1289 
1290  display = tmp_display_list;
1291  tmp_ptr = &tmp_display_list;
1292 
1293  while (display && display->region_id != region_id) {
1294  tmp_ptr = &display->next;
1295  display = display->next;
1296  }
1297 
1298  if (!display)
1299  display = av_mallocz(sizeof(DVBSubRegionDisplay));
1300 
1301  display->region_id = region_id;
1302 
1303  display->x_pos = AV_RB16(buf);
1304  buf += 2;
1305  display->y_pos = AV_RB16(buf);
1306  buf += 2;
1307 
1308  *tmp_ptr = display->next;
1309 
1310  display->next = ctx->display_list;
1311  ctx->display_list = display;
1312 
1313  av_dlog(avctx, "Region %d, (%d,%d)\n", region_id, display->x_pos, display->y_pos);
1314  }
1315 
1316  while (tmp_display_list) {
1317  display = tmp_display_list;
1318 
1319  tmp_display_list = display->next;
1320 
1321  av_free(display);
1322  }
1323 
1324 }
1325 
1326 
1327 #ifdef DEBUG
1328 static void save_display_set(DVBSubContext *ctx)
1329 {
1330  DVBSubRegion *region;
1331  DVBSubRegionDisplay *display;
1332  DVBSubCLUT *clut;
1333  uint32_t *clut_table;
1334  int x_pos, y_pos, width, height;
1335  int x, y, y_off, x_off;
1336  uint32_t *pbuf;
1337  char filename[32];
1338  static int fileno_index = 0;
1339 
1340  x_pos = -1;
1341  y_pos = -1;
1342  width = 0;
1343  height = 0;
1344 
1345  for (display = ctx->display_list; display; display = display->next) {
1346  region = get_region(ctx, display->region_id);
1347 
1348  if (x_pos == -1) {
1349  x_pos = display->x_pos;
1350  y_pos = display->y_pos;
1351  width = region->width;
1352  height = region->height;
1353  } else {
1354  if (display->x_pos < x_pos) {
1355  width += (x_pos - display->x_pos);
1356  x_pos = display->x_pos;
1357  }
1358 
1359  if (display->y_pos < y_pos) {
1360  height += (y_pos - display->y_pos);
1361  y_pos = display->y_pos;
1362  }
1363 
1364  if (display->x_pos + region->width > x_pos + width) {
1365  width = display->x_pos + region->width - x_pos;
1366  }
1367 
1368  if (display->y_pos + region->height > y_pos + height) {
1369  height = display->y_pos + region->height - y_pos;
1370  }
1371  }
1372  }
1373 
1374  if (x_pos >= 0) {
1375 
1376  pbuf = av_malloc(width * height * 4);
1377 
1378  for (display = ctx->display_list; display; display = display->next) {
1379  region = get_region(ctx, display->region_id);
1380 
1381  x_off = display->x_pos - x_pos;
1382  y_off = display->y_pos - y_pos;
1383 
1384  clut = get_clut(ctx, region->clut);
1385 
1386  if (!clut)
1387  clut = &default_clut;
1388 
1389  switch (region->depth) {
1390  case 2:
1391  clut_table = clut->clut4;
1392  break;
1393  case 8:
1394  clut_table = clut->clut256;
1395  break;
1396  case 4:
1397  default:
1398  clut_table = clut->clut16;
1399  break;
1400  }
1401 
1402  for (y = 0; y < region->height; y++) {
1403  for (x = 0; x < region->width; x++) {
1404  pbuf[((y + y_off) * width) + x_off + x] =
1405  clut_table[region->pbuf[y * region->width + x]];
1406  }
1407  }
1408 
1409  }
1410 
1411  snprintf(filename, sizeof(filename), "dvbs.%d", fileno_index);
1412 
1413  png_save2(filename, pbuf, width, height);
1414 
1415  av_free(pbuf);
1416  }
1417 
1418  fileno_index++;
1419 }
1420 #endif
1421 
1423  const uint8_t *buf,
1424  int buf_size)
1425 {
1426  DVBSubContext *ctx = avctx->priv_data;
1427  DVBSubDisplayDefinition *display_def = ctx->display_definition;
1428  int dds_version, info_byte;
1429 
1430  if (buf_size < 5)
1431  return;
1432 
1433  info_byte = bytestream_get_byte(&buf);
1434  dds_version = info_byte >> 4;
1435  if (display_def && display_def->version == dds_version)
1436  return; // already have this display definition version
1437 
1438  if (!display_def) {
1439  display_def = av_mallocz(sizeof(*display_def));
1440  ctx->display_definition = display_def;
1441  }
1442  if (!display_def)
1443  return;
1444 
1445  display_def->version = dds_version;
1446  display_def->x = 0;
1447  display_def->y = 0;
1448  display_def->width = bytestream_get_be16(&buf) + 1;
1449  display_def->height = bytestream_get_be16(&buf) + 1;
1450  if (!avctx->width || !avctx->height) {
1451  avctx->width = display_def->width;
1452  avctx->height = display_def->height;
1453  }
1454 
1455  if (buf_size < 13)
1456  return;
1457 
1458  if (info_byte & 1<<3) { // display_window_flag
1459  display_def->x = bytestream_get_be16(&buf);
1460  display_def->width = bytestream_get_be16(&buf) - display_def->x + 1;
1461  display_def->y = bytestream_get_be16(&buf);
1462  display_def->height = bytestream_get_be16(&buf) - display_def->y + 1;
1463  }
1464 }
1465 
1467  int buf_size, AVSubtitle *sub,int *got_output)
1468 {
1469  DVBSubContext *ctx = avctx->priv_data;
1470 
1471  if(ctx->compute_edt == 0)
1472  save_subtitle_set(avctx, sub, got_output);
1473 #ifdef DEBUG
1474  save_display_set(ctx);
1475 #endif
1476 
1477 }
1478 
1479 static int dvbsub_decode(AVCodecContext *avctx,
1480  void *data, int *data_size,
1481  AVPacket *avpkt)
1482 {
1483  const uint8_t *buf = avpkt->data;
1484  int buf_size = avpkt->size;
1485  DVBSubContext *ctx = avctx->priv_data;
1486  AVSubtitle *sub = data;
1487  const uint8_t *p, *p_end;
1488  int segment_type;
1489  int page_id;
1490  int segment_length;
1491  int i;
1492  int ret = 0;
1493  int got_segment = 0;
1494 
1495  av_dlog(avctx, "DVB sub packet:\n");
1496 
1497  for (i=0; i < buf_size; i++) {
1498  av_dlog(avctx, "%02x ", buf[i]);
1499  if (i % 16 == 15)
1500  av_dlog(avctx, "\n");
1501  }
1502 
1503  if (i % 16)
1504  av_dlog(avctx, "\n");
1505 
1506  if (buf_size <= 6 || *buf != 0x0f) {
1507  av_dlog(avctx, "incomplete or broken packet");
1508  return -1;
1509  }
1510 
1511  p = buf;
1512  p_end = buf + buf_size;
1513 
1514  while (p_end - p >= 6 && *p == 0x0f) {
1515  p += 1;
1516  segment_type = *p++;
1517  page_id = AV_RB16(p);
1518  p += 2;
1519  segment_length = AV_RB16(p);
1520  p += 2;
1521 
1522  if (avctx->debug & FF_DEBUG_STARTCODE) {
1523  av_log(avctx, AV_LOG_DEBUG, "segment_type:%d page_id:%d segment_length:%d\n", segment_type, page_id, segment_length);
1524  }
1525 
1526  if (p_end - p < segment_length) {
1527  av_dlog(avctx, "incomplete or broken packet");
1528  ret = -1;
1529  goto end;
1530  }
1531 
1532  if (page_id == ctx->composition_id || page_id == ctx->ancillary_id ||
1533  ctx->composition_id == -1 || ctx->ancillary_id == -1) {
1534  switch (segment_type) {
1535  case DVBSUB_PAGE_SEGMENT:
1536  dvbsub_parse_page_segment(avctx, p, segment_length, sub, data_size);
1537  got_segment |= 1;
1538  break;
1539  case DVBSUB_REGION_SEGMENT:
1540  dvbsub_parse_region_segment(avctx, p, segment_length);
1541  got_segment |= 2;
1542  break;
1543  case DVBSUB_CLUT_SEGMENT:
1544  ret = dvbsub_parse_clut_segment(avctx, p, segment_length);
1545  if (ret < 0) goto end;
1546  got_segment |= 4;
1547  break;
1548  case DVBSUB_OBJECT_SEGMENT:
1549  dvbsub_parse_object_segment(avctx, p, segment_length);
1550  got_segment |= 8;
1551  break;
1553  dvbsub_parse_display_definition_segment(avctx, p, segment_length);
1554  break;
1556  dvbsub_display_end_segment(avctx, p, segment_length, sub, data_size);
1557  got_segment |= 16;
1558  break;
1559  default:
1560  av_dlog(avctx, "Subtitling segment type 0x%x, page id %d, length %d\n",
1561  segment_type, page_id, segment_length);
1562  break;
1563  }
1564  }
1565 
1566  p += segment_length;
1567  }
1568  // Some streams do not send a display segment but if we have all the other
1569  // segments then we need no further data.
1570  if (got_segment == 15) {
1571  av_log(avctx, AV_LOG_DEBUG, "Missing display_end_segment, emulating\n");
1572  dvbsub_display_end_segment(avctx, p, 0, sub, data_size);
1573  }
1574 
1575 end:
1576  if(ret < 0) {
1577  *data_size = 0;
1578  avsubtitle_free(sub);
1579  return ret;
1580  } else {
1581  if(ctx->compute_edt == 1 )
1582  FFSWAP(int64_t, ctx->prev_start, sub->pts);
1583  }
1584 
1585  return p - buf;
1586 }
1587 
1588 #define DS AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_SUBTITLE_PARAM
1589 static const AVOption options[] = {
1590  {"compute_edt", "compute end of time using pts or timeout", offsetof(DVBSubContext, compute_edt), FF_OPT_TYPE_INT, {.i64 = 0}, 0, 1, DS},
1591  {NULL}
1592 };
1593 static const AVClass dvbsubdec_class = {
1594  .class_name = "DVB Sub Decoder",
1595  .item_name = av_default_item_name,
1596  .option = options,
1597  .version = LIBAVUTIL_VERSION_INT,
1598 };
1599 
1601  .name = "dvbsub",
1602  .long_name = NULL_IF_CONFIG_SMALL("DVB subtitles"),
1603  .type = AVMEDIA_TYPE_SUBTITLE,
1605  .priv_data_size = sizeof(DVBSubContext),
1608  .decode = dvbsub_decode,
1609  .priv_class = &dvbsubdec_class,
1610 };