FFmpeg
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules 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 "codec_internal.h"
26 #include "decode.h"
27 #include "libavutil/colorspace.h"
28 #include "libavutil/imgutils.h"
29 #include "libavutil/mem.h"
30 #include "libavutil/opt.h"
31 #include "libavutil/thread.h"
32 
33 #define DVBSUB_PAGE_SEGMENT 0x10
34 #define DVBSUB_REGION_SEGMENT 0x11
35 #define DVBSUB_CLUT_SEGMENT 0x12
36 #define DVBSUB_OBJECT_SEGMENT 0x13
37 #define DVBSUB_DISPLAYDEFINITION_SEGMENT 0x14
38 #define DVBSUB_END_DISPLAY_SEGMENT 0x80
39 
40 #define cm (ff_crop_tab + MAX_NEG_CROP)
41 
42 #define RGBA(r,g,b,a) (((unsigned)(a) << 24) | ((r) << 16) | ((g) << 8) | (b))
43 
44 typedef struct DVBSubCLUT {
45  int id;
46  int version;
47 
48  uint32_t clut4[4];
49  uint32_t clut16[16];
50  uint32_t clut256[256];
51 
52  struct DVBSubCLUT *next;
53 } DVBSubCLUT;
54 
56 
57 typedef struct DVBSubObjectDisplay {
58  int object_id;
59  int region_id;
60 
61  int x_pos;
62  int y_pos;
63 
64  int fgcolor;
65  int bgcolor;
66 
70 
71 typedef struct DVBSubObject {
72  int id;
73  int version;
74 
75  int type;
76 
78 
79  struct DVBSubObject *next;
80 } DVBSubObject;
81 
82 typedef struct DVBSubRegionDisplay {
83  int region_id;
84 
85  int x_pos;
86  int y_pos;
87 
90 
91 typedef struct DVBSubRegion {
92  int id;
93  int version;
94 
95  int width;
96  int height;
97  int depth;
98 
99  int clut;
100  int bgcolor;
101 
102  uint8_t computed_clut[4*256];
104 
105  uint8_t *pbuf;
106  int buf_size;
107  int dirty;
108 
110 
112 } DVBSubRegion;
113 
114 typedef struct DVBSubDisplayDefinition {
115  int version;
116 
117  int x;
118  int y;
119  int width;
120  int height;
122 
123 typedef struct DVBSubContext {
124  AVClass *class;
127 
128  int version;
129  int time_out;
130  int compute_edt; /**< if 1 end display time calculated using pts
131  if 0 (Default) calculated using time out */
133  int clut_count2[257][256];
139 
142 } DVBSubContext;
143 
144 
145 static DVBSubObject* get_object(DVBSubContext *ctx, int object_id)
146 {
147  DVBSubObject *ptr = ctx->object_list;
148 
149  while (ptr && ptr->id != object_id) {
150  ptr = ptr->next;
151  }
152 
153  return ptr;
154 }
155 
156 static DVBSubCLUT* get_clut(DVBSubContext *ctx, int clut_id)
157 {
158  DVBSubCLUT *ptr = ctx->clut_list;
159 
160  while (ptr && ptr->id != clut_id) {
161  ptr = ptr->next;
162  }
163 
164  return ptr;
165 }
166 
167 static DVBSubRegion* get_region(DVBSubContext *ctx, int region_id)
168 {
169  DVBSubRegion *ptr = ctx->region_list;
170 
171  while (ptr && ptr->id != region_id) {
172  ptr = ptr->next;
173  }
174 
175  return ptr;
176 }
177 
179 {
180  DVBSubObject *object, *obj2, **obj2_ptr;
181  DVBSubObjectDisplay *display, *obj_disp, **obj_disp_ptr;
182 
183  while (region->display_list) {
184  display = region->display_list;
185 
186  object = get_object(ctx, display->object_id);
187 
188  if (object) {
189  obj_disp_ptr = &object->display_list;
190  obj_disp = *obj_disp_ptr;
191 
192  while (obj_disp && obj_disp != display) {
193  obj_disp_ptr = &obj_disp->object_list_next;
194  obj_disp = *obj_disp_ptr;
195  }
196 
197  if (obj_disp) {
198  *obj_disp_ptr = obj_disp->object_list_next;
199 
200  if (!object->display_list) {
201  obj2_ptr = &ctx->object_list;
202  obj2 = *obj2_ptr;
203 
204  while (obj2 != object) {
205  av_assert0(obj2);
206  obj2_ptr = &obj2->next;
207  obj2 = *obj2_ptr;
208  }
209 
210  *obj2_ptr = obj2->next;
211 
212  av_freep(&obj2);
213  }
214  }
215  }
216 
217  region->display_list = display->region_list_next;
218 
219  av_freep(&display);
220  }
221 
222 }
223 
225 {
226  while (ctx->clut_list) {
227  DVBSubCLUT *clut = ctx->clut_list;
228 
229  ctx->clut_list = clut->next;
230 
231  av_freep(&clut);
232  }
233 }
234 
236 {
237  while (ctx->object_list) {
238  DVBSubObject *object = ctx->object_list;
239 
240  ctx->object_list = object->next;
241 
242  av_freep(&object);
243  }
244 }
245 
247 {
248  while (ctx->region_list) {
249  DVBSubRegion *region = ctx->region_list;
250 
251  ctx->region_list = region->next;
252 
254 
255  av_freep(&region->pbuf);
256  av_freep(&region);
257  }
258 }
259 
260 static av_cold void init_default_clut(void)
261 {
262  int i, r, g, b, a = 0;
263 
264  default_clut.id = -1;
266 
267  default_clut.clut4[0] = RGBA( 0, 0, 0, 0);
268  default_clut.clut4[1] = RGBA(255, 255, 255, 255);
269  default_clut.clut4[2] = RGBA( 0, 0, 0, 255);
270  default_clut.clut4[3] = RGBA(127, 127, 127, 255);
271 
272  default_clut.clut16[0] = RGBA( 0, 0, 0, 0);
273  for (i = 1; i < 16; i++) {
274  if (i < 8) {
275  r = (i & 1) ? 255 : 0;
276  g = (i & 2) ? 255 : 0;
277  b = (i & 4) ? 255 : 0;
278  } else {
279  r = (i & 1) ? 127 : 0;
280  g = (i & 2) ? 127 : 0;
281  b = (i & 4) ? 127 : 0;
282  }
283  default_clut.clut16[i] = RGBA(r, g, b, 255);
284  }
285 
286  default_clut.clut256[0] = RGBA( 0, 0, 0, 0);
287  for (i = 1; i < 256; i++) {
288  if (i < 8) {
289  r = (i & 1) ? 255 : 0;
290  g = (i & 2) ? 255 : 0;
291  b = (i & 4) ? 255 : 0;
292  a = 63;
293  } else {
294  switch (i & 0x88) {
295  case 0x00:
296  r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0);
297  g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0);
298  b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0);
299  a = 255;
300  break;
301  case 0x08:
302  r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0);
303  g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0);
304  b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0);
305  a = 127;
306  break;
307  case 0x80:
308  r = 127 + ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0);
309  g = 127 + ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0);
310  b = 127 + ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0);
311  a = 255;
312  break;
313  case 0x88:
314  r = ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0);
315  g = ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0);
316  b = ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0);
317  a = 255;
318  break;
319  }
320  }
321  default_clut.clut256[i] = RGBA(r, g, b, a);
322  }
323 }
324 
326 {
327  static AVOnce init_static_once = AV_ONCE_INIT;
328  DVBSubContext *ctx = avctx->priv_data;
329 
330  if (ctx->substream < 0) {
331  ctx->composition_id = -1;
332  ctx->ancillary_id = -1;
333  } else if (!avctx->extradata || (avctx->extradata_size < 4) || ((avctx->extradata_size % 5 != 0) && (avctx->extradata_size != 4))) {
334  av_log(avctx, AV_LOG_WARNING, "Invalid DVB subtitles stream extradata!\n");
335  ctx->composition_id = -1;
336  ctx->ancillary_id = -1;
337  } else {
338  if (avctx->extradata_size > 5*ctx->substream + 2) {
339  ctx->composition_id = AV_RB16(avctx->extradata + 5*ctx->substream);
340  ctx->ancillary_id = AV_RB16(avctx->extradata + 5*ctx->substream + 2);
341  } else {
342  av_log(avctx, AV_LOG_WARNING, "Selected DVB subtitles sub-stream %d is not available\n", ctx->substream);
343  ctx->composition_id = AV_RB16(avctx->extradata);
344  ctx->ancillary_id = AV_RB16(avctx->extradata + 2);
345  }
346  }
347 
348  ctx->version = -1;
349  ctx->prev_start = AV_NOPTS_VALUE;
350 
351  ff_thread_once(&init_static_once, init_default_clut);
352 
353  return 0;
354 }
355 
357 {
358  DVBSubContext *ctx = avctx->priv_data;
359  DVBSubRegionDisplay *display;
360 
362 
364 
365  delete_cluts(ctx);
366 
367  av_freep(&ctx->display_definition);
368 
369  while (ctx->display_list) {
370  display = ctx->display_list;
371  ctx->display_list = display->next;
372 
373  av_freep(&display);
374  }
375 
376  return 0;
377 }
378 
380  uint8_t *destbuf, int dbuf_len,
381  const uint8_t **srcbuf, int buf_size,
382  int non_mod, uint8_t *map_table, int x_pos)
383 {
384  GetBitContext gb;
385 
386  int bits;
387  int run_length;
388  int pixels_read = x_pos;
389 
390  init_get_bits(&gb, *srcbuf, buf_size << 3);
391 
392  destbuf += x_pos;
393 
394  while (get_bits_count(&gb) < buf_size << 3 && pixels_read < dbuf_len) {
395  bits = get_bits(&gb, 2);
396 
397  if (bits) {
398  if (non_mod != 1 || bits != 1) {
399  if (map_table)
400  *destbuf++ = map_table[bits];
401  else
402  *destbuf++ = bits;
403  }
404  pixels_read++;
405  } else {
406  bits = get_bits1(&gb);
407  if (bits == 1) {
408  run_length = get_bits(&gb, 3) + 3;
409  bits = get_bits(&gb, 2);
410 
411  if (non_mod == 1 && bits == 1)
412  pixels_read += run_length;
413  else {
414  if (map_table)
415  bits = map_table[bits];
416  while (run_length-- > 0 && pixels_read < dbuf_len) {
417  *destbuf++ = bits;
418  pixels_read++;
419  }
420  }
421  } else {
422  bits = get_bits1(&gb);
423  if (bits == 0) {
424  bits = get_bits(&gb, 2);
425  if (bits == 2) {
426  run_length = get_bits(&gb, 4) + 12;
427  bits = get_bits(&gb, 2);
428 
429  if (non_mod == 1 && bits == 1)
430  pixels_read += run_length;
431  else {
432  if (map_table)
433  bits = map_table[bits];
434  while (run_length-- > 0 && pixels_read < dbuf_len) {
435  *destbuf++ = bits;
436  pixels_read++;
437  }
438  }
439  } else if (bits == 3) {
440  run_length = get_bits(&gb, 8) + 29;
441  bits = get_bits(&gb, 2);
442 
443  if (non_mod == 1 && bits == 1)
444  pixels_read += run_length;
445  else {
446  if (map_table)
447  bits = map_table[bits];
448  while (run_length-- > 0 && pixels_read < dbuf_len) {
449  *destbuf++ = bits;
450  pixels_read++;
451  }
452  }
453  } else if (bits == 1) {
454  if (map_table)
455  bits = map_table[0];
456  else
457  bits = 0;
458  run_length = 2;
459  while (run_length-- > 0 && pixels_read < dbuf_len) {
460  *destbuf++ = bits;
461  pixels_read++;
462  }
463  } else {
464  (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
465  return pixels_read;
466  }
467  } else {
468  if (map_table)
469  bits = map_table[0];
470  else
471  bits = 0;
472  *destbuf++ = bits;
473  pixels_read++;
474  }
475  }
476  }
477  }
478 
479  if (get_bits(&gb, 6))
480  av_log(avctx, AV_LOG_ERROR, "line overflow\n");
481 
482  (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
483 
484  return pixels_read;
485 }
486 
487 static int dvbsub_read_4bit_string(AVCodecContext *avctx, uint8_t *destbuf, int dbuf_len,
488  const uint8_t **srcbuf, int buf_size,
489  int non_mod, uint8_t *map_table, int x_pos)
490 {
491  GetBitContext gb;
492 
493  int bits;
494  int run_length;
495  int pixels_read = x_pos;
496 
497  init_get_bits(&gb, *srcbuf, buf_size << 3);
498 
499  destbuf += x_pos;
500 
501  while (get_bits_count(&gb) < buf_size << 3 && pixels_read < dbuf_len) {
502  bits = get_bits(&gb, 4);
503 
504  if (bits) {
505  if (non_mod != 1 || bits != 1) {
506  if (map_table)
507  *destbuf++ = map_table[bits];
508  else
509  *destbuf++ = bits;
510  }
511  pixels_read++;
512  } else {
513  bits = get_bits1(&gb);
514  if (bits == 0) {
515  run_length = get_bits(&gb, 3);
516 
517  if (run_length == 0) {
518  (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
519  return pixels_read;
520  }
521 
522  run_length += 2;
523 
524  if (map_table)
525  bits = map_table[0];
526  else
527  bits = 0;
528 
529  while (run_length-- > 0 && pixels_read < dbuf_len) {
530  *destbuf++ = bits;
531  pixels_read++;
532  }
533  } else {
534  bits = get_bits1(&gb);
535  if (bits == 0) {
536  run_length = get_bits(&gb, 2) + 4;
537  bits = get_bits(&gb, 4);
538 
539  if (non_mod == 1 && bits == 1)
540  pixels_read += run_length;
541  else {
542  if (map_table)
543  bits = map_table[bits];
544  while (run_length-- > 0 && pixels_read < dbuf_len) {
545  *destbuf++ = bits;
546  pixels_read++;
547  }
548  }
549  } else {
550  bits = get_bits(&gb, 2);
551  if (bits == 2) {
552  run_length = get_bits(&gb, 4) + 9;
553  bits = get_bits(&gb, 4);
554 
555  if (non_mod == 1 && bits == 1)
556  pixels_read += run_length;
557  else {
558  if (map_table)
559  bits = map_table[bits];
560  while (run_length-- > 0 && pixels_read < dbuf_len) {
561  *destbuf++ = bits;
562  pixels_read++;
563  }
564  }
565  } else if (bits == 3) {
566  run_length = get_bits(&gb, 8) + 25;
567  bits = get_bits(&gb, 4);
568 
569  if (non_mod == 1 && bits == 1)
570  pixels_read += run_length;
571  else {
572  if (map_table)
573  bits = map_table[bits];
574  while (run_length-- > 0 && pixels_read < dbuf_len) {
575  *destbuf++ = bits;
576  pixels_read++;
577  }
578  }
579  } else if (bits == 1) {
580  if (map_table)
581  bits = map_table[0];
582  else
583  bits = 0;
584  run_length = 2;
585  while (run_length-- > 0 && pixels_read < dbuf_len) {
586  *destbuf++ = bits;
587  pixels_read++;
588  }
589  } else {
590  if (map_table)
591  bits = map_table[0];
592  else
593  bits = 0;
594  *destbuf++ = bits;
595  pixels_read ++;
596  }
597  }
598  }
599  }
600  }
601 
602  if (get_bits(&gb, 8))
603  av_log(avctx, AV_LOG_ERROR, "line overflow\n");
604 
605  (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
606 
607  return pixels_read;
608 }
609 
611  uint8_t *destbuf, int dbuf_len,
612  const uint8_t **srcbuf, int buf_size,
613  int non_mod, uint8_t *map_table, int x_pos)
614 {
615  int bits;
616  int run_length;
617  int pixels_read = x_pos;
618  GetByteContext gb0, *const gb = &gb0;
619 
620  bytestream2_init(gb, *srcbuf, buf_size);
621  destbuf += x_pos;
622 
623  while (bytestream2_get_bytes_left(gb) && pixels_read < dbuf_len) {
624  bits = bytestream2_get_byteu(gb);
625 
626  if (bits) {
627  if (non_mod != 1 || bits != 1) {
628  if (map_table)
629  *destbuf++ = map_table[bits];
630  else
631  *destbuf++ = bits;
632  }
633  pixels_read++;
634  } else {
635  bits = bytestream2_get_byte(gb);
636  run_length = bits & 0x7f;
637  if ((bits & 0x80) == 0) {
638  if (run_length == 0) {
639  *srcbuf += bytestream2_tell(gb);
640  return pixels_read;
641  }
642 
643  bits = 0;
644  } else {
645  bits = bytestream2_get_byte(gb);
646  }
647  if (non_mod == 1 && bits == 1)
648  pixels_read += run_length;
649  else {
650  if (map_table)
651  bits = map_table[bits];
652  while (run_length-- > 0 && pixels_read < dbuf_len) {
653  *destbuf++ = bits;
654  pixels_read++;
655  }
656  }
657  }
658  }
659 
660  if (bytestream2_get_byte(gb))
661  av_log(avctx, AV_LOG_ERROR, "line overflow\n");
662 
663  /* Workaround our own buggy encoder which only put one zero at the end */
664  if (!bytestream2_peek_byte(gb))
665  bytestream2_get_byte(gb);
666 
667  *srcbuf += bytestream2_tell(gb);
668  return pixels_read;
669 }
670 
671 static void compute_default_clut(DVBSubContext *ctx, uint8_t *clut, AVSubtitleRect *rect, int w, int h)
672 {
673  uint8_t list[256] = {0};
674  uint8_t list_inv[256];
675  int counttab[256] = {0};
676  int (*counttab2)[256] = ctx->clut_count2;
677  int count, i, x, y;
678  ptrdiff_t stride = rect->linesize[0];
679 
680  memset(ctx->clut_count2, 0 , sizeof(ctx->clut_count2));
681 
682 #define V(x,y) rect->data[0][(x) + (y)*stride]
683  for (y = 0; y<h; y++) {
684  for (x = 0; x<w; x++) {
685  int v = V(x,y) + 1;
686  int vl = x ? V(x-1,y) + 1 : 0;
687  int vr = x+1<w ? V(x+1,y) + 1 : 0;
688  int vt = y ? V(x,y-1) + 1 : 0;
689  int vb = y+1<h ? V(x,y+1) + 1 : 0;
690  counttab[v-1] += !!((v!=vl) + (v!=vr) + (v!=vt) + (v!=vb));
691  counttab2[vl][v-1] ++;
692  counttab2[vr][v-1] ++;
693  counttab2[vt][v-1] ++;
694  counttab2[vb][v-1] ++;
695  }
696  }
697 #define L(x,y) list[d[(x) + (y)*stride]]
698 
699  for (i = 0; i<256; i++) {
700  counttab2[i+1][i] = 0;
701  }
702  for (i = 0; i<256; i++) {
703  int bestscore = 0;
704  int bestv = 0;
705 
706  for (x = 0; x < 256; x++) {
707  int scorev = 0;
708  if (list[x])
709  continue;
710  scorev += counttab2[0][x];
711  for (y = 0; y < 256; y++) {
712  scorev += list[y] * counttab2[y+1][x];
713  }
714 
715  if (scorev) {
716  int score = 1024LL*scorev / counttab[x];
717  if (score > bestscore) {
718  bestscore = score;
719  bestv = x;
720  }
721  }
722  }
723  if (!bestscore)
724  break;
725  list [ bestv ] = 1;
726  list_inv[ i ] = bestv;
727  }
728 
729  count = FFMAX(i - 1, 1);
730  for (i--; i >= 0; i--) {
731  int v = i * 255 / count;
732  AV_WN32(clut + 4*list_inv[i], RGBA(v/2,v,v/2,v));
733  }
734 }
735 
736 
737 static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_output)
738 {
739  DVBSubContext *ctx = avctx->priv_data;
740  DVBSubRegionDisplay *display;
741  DVBSubDisplayDefinition *display_def = ctx->display_definition;
742  DVBSubRegion *region;
744  const DVBSubCLUT *clut;
745  const uint32_t *clut_table;
746  int i;
747  int offset_x=0, offset_y=0;
748  int ret = 0;
749 
750 
751  if (display_def) {
752  offset_x = display_def->x;
753  offset_y = display_def->y;
754  }
755 
756  /* Not touching AVSubtitles again*/
757  if (sub->num_rects) {
758  avpriv_request_sample(ctx, "Different Version of Segment asked Twice");
759  return AVERROR_PATCHWELCOME;
760  }
761  for (display = ctx->display_list; display; display = display->next) {
762  region = get_region(ctx, display->region_id);
763  if (region && region->dirty)
764  sub->num_rects++;
765  }
766 
767  if (ctx->compute_edt == 0) {
768  sub->end_display_time = ctx->time_out * 1000;
769  *got_output = 1;
770  } else if (ctx->prev_start != AV_NOPTS_VALUE) {
771  sub->end_display_time = av_rescale_q((sub->pts - ctx->prev_start ), AV_TIME_BASE_Q, (AVRational){ 1, 1000 }) - 1;
772  *got_output = 1;
773  }
774  if (sub->num_rects > 0) {
775 
776  sub->rects = av_calloc(sub->num_rects, sizeof(*sub->rects));
777  if (!sub->rects) {
778  ret = AVERROR(ENOMEM);
779  goto fail;
780  }
781 
782  for (i = 0; i < sub->num_rects; i++) {
783  sub->rects[i] = av_mallocz(sizeof(*sub->rects[i]));
784  if (!sub->rects[i]) {
785  ret = AVERROR(ENOMEM);
786  goto fail;
787  }
788  }
789 
790  i = 0;
791 
792  for (display = ctx->display_list; display; display = display->next) {
793  region = get_region(ctx, display->region_id);
794 
795  if (!region)
796  continue;
797 
798  if (!region->dirty)
799  continue;
800 
801  rect = sub->rects[i];
802  rect->x = display->x_pos + offset_x;
803  rect->y = display->y_pos + offset_y;
804  rect->w = region->width;
805  rect->h = region->height;
806  rect->nb_colors = (1 << region->depth);
807  rect->type = SUBTITLE_BITMAP;
808  rect->linesize[0] = region->width;
809 
810  clut = get_clut(ctx, region->clut);
811 
812  if (!clut)
813  clut = &default_clut;
814 
815  switch (region->depth) {
816  case 2:
817  clut_table = clut->clut4;
818  break;
819  case 8:
820  clut_table = clut->clut256;
821  break;
822  case 4:
823  default:
824  clut_table = clut->clut16;
825  break;
826  }
827 
828  rect->data[1] = av_mallocz(AVPALETTE_SIZE);
829  if (!rect->data[1]) {
830  ret = AVERROR(ENOMEM);
831  goto fail;
832  }
833  memcpy(rect->data[1], clut_table, (1 << region->depth) * sizeof(*clut_table));
834 
835  rect->data[0] = av_memdup(region->pbuf, region->buf_size);
836  if (!rect->data[0]) {
837  ret = AVERROR(ENOMEM);
838  goto fail;
839  }
840 
841  if ((clut == &default_clut && ctx->compute_clut < 0) || ctx->compute_clut == 1) {
842  if (!region->has_computed_clut) {
844  region->has_computed_clut = 1;
845  }
846 
847  memcpy(rect->data[1], region->computed_clut, sizeof(region->computed_clut));
848  }
849 
850  i++;
851  }
852  }
853 
854  return 0;
855 fail:
856  if (sub->rects) {
857  for (i=0; i < sub->num_rects; i++) {
858  rect = sub->rects[i];
859  if (rect) {
860  av_freep(&rect->data[0]);
861  av_freep(&rect->data[1]);
862  }
863  av_freep(&sub->rects[i]);
864  }
865  av_freep(&sub->rects);
866  }
867  sub->num_rects = 0;
868  return ret;
869 }
870 
872  const uint8_t *buf, int buf_size, int top_bottom, int non_mod)
873 {
874  DVBSubContext *ctx = avctx->priv_data;
875 
876  DVBSubRegion *region = get_region(ctx, display->region_id);
877  const uint8_t *buf_end = buf + buf_size;
878  uint8_t *pbuf;
879  int x_pos, y_pos;
880  int i;
881 
882  uint8_t map2to4[] = { 0x0, 0x7, 0x8, 0xf};
883  uint8_t map2to8[] = {0x00, 0x77, 0x88, 0xff};
884  uint8_t map4to8[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
885  0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
886  uint8_t *map_table;
887 
888 #if 0
889  ff_dlog(avctx, "DVB pixel block size %d, %s field:\n", buf_size,
890  top_bottom ? "bottom" : "top");
891 
892  for (i = 0; i < buf_size; i++) {
893  if (i % 16 == 0)
894  ff_dlog(avctx, "0x%8p: ", buf+i);
895 
896  ff_dlog(avctx, "%02x ", buf[i]);
897  if (i % 16 == 15)
898  ff_dlog(avctx, "\n");
899  }
900 
901  if (i % 16)
902  ff_dlog(avctx, "\n");
903 #endif
904 
905  if (!region)
906  return;
907 
908  pbuf = region->pbuf;
909  region->dirty = 1;
910 
911  x_pos = display->x_pos;
912  y_pos = display->y_pos;
913 
914  y_pos += top_bottom;
915 
916  while (buf < buf_end) {
917  if ((*buf!=0xf0 && x_pos >= region->width) || y_pos >= region->height) {
918  av_log(avctx, AV_LOG_ERROR, "Invalid object location! %d-%d %d-%d %02x\n", x_pos, region->width, y_pos, region->height, *buf);
919  return;
920  }
921 
922  switch (*buf++) {
923  case 0x10:
924  if (region->depth == 8)
925  map_table = map2to8;
926  else if (region->depth == 4)
927  map_table = map2to4;
928  else
929  map_table = NULL;
930 
931  x_pos = dvbsub_read_2bit_string(avctx, pbuf + (y_pos * region->width),
932  region->width, &buf, buf_end - buf,
933  non_mod, map_table, x_pos);
934  break;
935  case 0x11:
936  if (region->depth < 4) {
937  av_log(avctx, AV_LOG_ERROR, "4-bit pixel string in %d-bit region!\n", region->depth);
938  return;
939  }
940 
941  if (region->depth == 8)
942  map_table = map4to8;
943  else
944  map_table = NULL;
945 
946  x_pos = dvbsub_read_4bit_string(avctx, pbuf + (y_pos * region->width),
947  region->width, &buf, buf_end - buf,
948  non_mod, map_table, x_pos);
949  break;
950  case 0x12:
951  if (region->depth < 8) {
952  av_log(avctx, AV_LOG_ERROR, "8-bit pixel string in %d-bit region!\n", region->depth);
953  return;
954  }
955 
956  x_pos = dvbsub_read_8bit_string(avctx, pbuf + (y_pos * region->width),
957  region->width, &buf, buf_end - buf,
958  non_mod, NULL, x_pos);
959  break;
960 
961  case 0x20:
962  map2to4[0] = (*buf) >> 4;
963  map2to4[1] = (*buf++) & 0xf;
964  map2to4[2] = (*buf) >> 4;
965  map2to4[3] = (*buf++) & 0xf;
966  break;
967  case 0x21:
968  for (i = 0; i < 4; i++)
969  map2to8[i] = *buf++;
970  break;
971  case 0x22:
972  for (i = 0; i < 16; i++)
973  map4to8[i] = *buf++;
974  break;
975 
976  case 0xf0:
977  x_pos = display->x_pos;
978  y_pos += 2;
979  break;
980  default:
981  av_log(avctx, AV_LOG_INFO, "Unknown/unsupported pixel block 0x%x\n", *(buf-1));
982  }
983  }
984 
985  if (ctx->compute_clut != -2)
986  region->has_computed_clut = 0;
987 }
988 
990  const uint8_t *buf, int buf_size)
991 {
992  DVBSubContext *ctx = avctx->priv_data;
993 
994  const uint8_t *buf_end = buf + buf_size;
995  int object_id;
996  DVBSubObject *object;
997  DVBSubObjectDisplay *display;
998  int top_field_len, bottom_field_len;
999 
1000  int coding_method, non_modifying_color;
1001 
1002  object_id = AV_RB16(buf);
1003  buf += 2;
1004 
1005  object = get_object(ctx, object_id);
1006 
1007  if (!object)
1008  return AVERROR_INVALIDDATA;
1009 
1010  coding_method = ((*buf) >> 2) & 3;
1011  non_modifying_color = ((*buf++) >> 1) & 1;
1012 
1013  if (coding_method == 0) {
1014  top_field_len = AV_RB16(buf);
1015  buf += 2;
1016  bottom_field_len = AV_RB16(buf);
1017  buf += 2;
1018 
1019  if (buf + top_field_len + bottom_field_len > buf_end) {
1020  av_log(avctx, AV_LOG_ERROR, "Field data size %d+%d too large\n", top_field_len, bottom_field_len);
1021  return AVERROR_INVALIDDATA;
1022  }
1023 
1024  for (display = object->display_list; display; display = display->object_list_next) {
1025  const uint8_t *block = buf;
1026  int bfl = bottom_field_len;
1027 
1028  dvbsub_parse_pixel_data_block(avctx, display, block, top_field_len, 0,
1029  non_modifying_color);
1030 
1031  if (bottom_field_len > 0)
1032  block = buf + top_field_len;
1033  else
1034  bfl = top_field_len;
1035 
1036  dvbsub_parse_pixel_data_block(avctx, display, block, bfl, 1,
1037  non_modifying_color);
1038  }
1039  } else if (coding_method == 1) {
1040  avpriv_report_missing_feature(avctx, "coded as a string of characters");
1041  return AVERROR_PATCHWELCOME;
1042  } else if (coding_method == 2) {
1043  avpriv_report_missing_feature(avctx, "progressive coding of pixels");
1044  return AVERROR_PATCHWELCOME;
1045  } else {
1046  av_log(avctx, AV_LOG_ERROR, "Unknown object coding %d\n", coding_method);
1047  return AVERROR_INVALIDDATA;
1048  }
1049 
1050  return 0;
1051 }
1052 
1054  const uint8_t *buf, int buf_size)
1055 {
1056  DVBSubContext *ctx = avctx->priv_data;
1057 
1058  const uint8_t *buf_end = buf + buf_size;
1059  int i, clut_id;
1060  int version;
1061  DVBSubCLUT *clut;
1062  int entry_id, depth , full_range;
1063  int y, cr, cb, alpha;
1064  int r, g, b, r_add, g_add, b_add;
1065 
1066  ff_dlog(avctx, "DVB clut packet:\n");
1067 
1068  for (i=0; i < buf_size; i++) {
1069  ff_dlog(avctx, "%02x ", buf[i]);
1070  if (i % 16 == 15)
1071  ff_dlog(avctx, "\n");
1072  }
1073 
1074  if (i % 16)
1075  ff_dlog(avctx, "\n");
1076 
1077  clut_id = *buf++;
1078  version = ((*buf)>>4)&15;
1079  buf += 1;
1080 
1081  clut = get_clut(ctx, clut_id);
1082 
1083  if (!clut) {
1084  clut = av_memdup(&default_clut, sizeof(*clut));
1085  if (!clut)
1086  return AVERROR(ENOMEM);
1087 
1088  clut->id = clut_id;
1089  clut->version = -1;
1090 
1091  clut->next = ctx->clut_list;
1092  ctx->clut_list = clut;
1093  }
1094 
1095  if (clut->version != version) {
1096 
1097  clut->version = version;
1098 
1099  while (buf + 4 < buf_end) {
1100  entry_id = *buf++;
1101 
1102  depth = (*buf) & 0xe0;
1103 
1104  if (depth == 0) {
1105  av_log(avctx, AV_LOG_ERROR, "Invalid clut depth 0x%x!\n", *buf);
1106  }
1107 
1108  full_range = (*buf++) & 1;
1109 
1110  if (full_range) {
1111  y = *buf++;
1112  cr = *buf++;
1113  cb = *buf++;
1114  alpha = *buf++;
1115  } else {
1116  y = buf[0] & 0xfc;
1117  cr = (((buf[0] & 3) << 2) | ((buf[1] >> 6) & 3)) << 4;
1118  cb = (buf[1] << 2) & 0xf0;
1119  alpha = (buf[1] << 6) & 0xc0;
1120 
1121  buf += 2;
1122  }
1123 
1124  if (y == 0)
1125  alpha = 0xff;
1126 
1128  YUV_TO_RGB2_CCIR(r, g, b, y);
1129 
1130  ff_dlog(avctx, "clut %d := (%d,%d,%d,%d)\n", entry_id, r, g, b, alpha);
1131  if (!!(depth & 0x80) + !!(depth & 0x40) + !!(depth & 0x20) > 1) {
1132  ff_dlog(avctx, "More than one bit level marked: %x\n", depth);
1134  return AVERROR_INVALIDDATA;
1135  }
1136 
1137  if (depth & 0x80 && entry_id < 4)
1138  clut->clut4[entry_id] = RGBA(r,g,b,255 - alpha);
1139  else if (depth & 0x40 && entry_id < 16)
1140  clut->clut16[entry_id] = RGBA(r,g,b,255 - alpha);
1141  else if (depth & 0x20)
1142  clut->clut256[entry_id] = RGBA(r,g,b,255 - alpha);
1143  }
1144  }
1145 
1146  return 0;
1147 }
1148 
1149 
1151  const uint8_t *buf, int buf_size)
1152 {
1153  DVBSubContext *ctx = avctx->priv_data;
1154 
1155  const uint8_t *buf_end = buf + buf_size;
1156  int region_id, object_id;
1157  int av_unused version;
1158  DVBSubRegion *region;
1159  DVBSubObject *object;
1160  DVBSubObjectDisplay *display;
1161  int fill;
1162  int ret;
1163 
1164  if (buf_size < 10)
1165  return AVERROR_INVALIDDATA;
1166 
1167  region_id = *buf++;
1168 
1169  region = get_region(ctx, region_id);
1170 
1171  if (!region) {
1172  region = av_mallocz(sizeof(*region));
1173  if (!region)
1174  return AVERROR(ENOMEM);
1175 
1176  region->id = region_id;
1177  region->version = -1;
1178 
1179  region->next = ctx->region_list;
1180  ctx->region_list = region;
1181  }
1182 
1183  version = ((*buf)>>4) & 15;
1184  fill = ((*buf++) >> 3) & 1;
1185 
1186  region->width = AV_RB16(buf);
1187  buf += 2;
1188  region->height = AV_RB16(buf);
1189  buf += 2;
1190 
1191  ret = av_image_check_size2(region->width, region->height, avctx->max_pixels, AV_PIX_FMT_PAL8, 0, avctx);
1192  if (ret >= 0 && region->width * region->height * 2 > 320 * 1024 * 8) {
1194  av_log(avctx, AV_LOG_ERROR, "Pixel buffer memory constraint violated\n");
1195  }
1196  if (ret < 0) {
1197  region->width= region->height= 0;
1198  return ret;
1199  }
1200 
1201  if (region->width * region->height != region->buf_size) {
1202  av_free(region->pbuf);
1203 
1204  region->buf_size = region->width * region->height;
1205 
1206  region->pbuf = av_malloc(region->buf_size);
1207  if (!region->pbuf) {
1208  region->buf_size =
1209  region->width =
1210  region->height = 0;
1211  return AVERROR(ENOMEM);
1212  }
1213 
1214  fill = 1;
1215  region->dirty = 0;
1216  }
1217 
1218  region->depth = 1 << (((*buf++) >> 2) & 7);
1219  if (region->depth < 2 || region->depth > 8) {
1220  av_log(avctx, AV_LOG_ERROR, "region depth %d is invalid\n", region->depth);
1221  region->depth= 4;
1222  }
1223  region->clut = *buf++;
1224 
1225  if (region->depth == 8) {
1226  region->bgcolor = *buf++;
1227  buf += 1;
1228  } else {
1229  buf += 1;
1230 
1231  if (region->depth == 4)
1232  region->bgcolor = (((*buf++) >> 4) & 15);
1233  else
1234  region->bgcolor = (((*buf++) >> 2) & 3);
1235  }
1236 
1237  ff_dlog(avctx, "Region %d, (%dx%d)\n", region_id, region->width, region->height);
1238 
1239  if (fill) {
1240  memset(region->pbuf, region->bgcolor, region->buf_size);
1241  ff_dlog(avctx, "Fill region (%d)\n", region->bgcolor);
1242  }
1243 
1245 
1246  while (buf + 5 < buf_end) {
1247  object_id = AV_RB16(buf);
1248  buf += 2;
1249 
1250  object = get_object(ctx, object_id);
1251 
1252  if (!object) {
1253  object = av_mallocz(sizeof(*object));
1254  if (!object)
1255  return AVERROR(ENOMEM);
1256 
1257  object->id = object_id;
1258  object->next = ctx->object_list;
1259  ctx->object_list = object;
1260  }
1261 
1262  object->type = (*buf) >> 6;
1263 
1264  display = av_mallocz(sizeof(*display));
1265  if (!display)
1266  return AVERROR(ENOMEM);
1267 
1268  display->object_id = object_id;
1269  display->region_id = region_id;
1270 
1271  display->x_pos = AV_RB16(buf) & 0xfff;
1272  buf += 2;
1273  display->y_pos = AV_RB16(buf) & 0xfff;
1274  buf += 2;
1275 
1276  if (display->x_pos >= region->width ||
1277  display->y_pos >= region->height) {
1278  av_log(avctx, AV_LOG_ERROR, "Object outside region\n");
1279  av_free(display);
1280  return AVERROR_INVALIDDATA;
1281  }
1282 
1283  if ((object->type == 1 || object->type == 2) && buf+1 < buf_end) {
1284  display->fgcolor = *buf++;
1285  display->bgcolor = *buf++;
1286  }
1287 
1288  display->region_list_next = region->display_list;
1289  region->display_list = display;
1290 
1291  display->object_list_next = object->display_list;
1292  object->display_list = display;
1293  }
1294 
1295  return 0;
1296 }
1297 
1299  const uint8_t *buf, int buf_size, AVSubtitle *sub, int *got_output)
1300 {
1301  DVBSubContext *ctx = avctx->priv_data;
1302  DVBSubRegionDisplay *display;
1303  DVBSubRegionDisplay *tmp_display_list, **tmp_ptr;
1304 
1305  const uint8_t *buf_end = buf + buf_size;
1306  int region_id;
1307  int page_state;
1308  int timeout;
1309  int version;
1310 
1311  if (buf_size < 1)
1312  return AVERROR_INVALIDDATA;
1313 
1314  timeout = *buf++;
1315  version = ((*buf)>>4) & 15;
1316  page_state = ((*buf++) >> 2) & 3;
1317 
1318  if (ctx->version == version) {
1319  return 0;
1320  }
1321 
1322  ctx->time_out = timeout;
1323  ctx->version = version;
1324 
1325  ff_dlog(avctx, "Page time out %ds, state %d\n", ctx->time_out, page_state);
1326 
1327  if (ctx->compute_edt == 1)
1328  save_subtitle_set(avctx, sub, got_output);
1329 
1330  if (page_state == 1 || page_state == 2) {
1333  delete_cluts(ctx);
1334  }
1335 
1336  tmp_display_list = ctx->display_list;
1337  ctx->display_list = NULL;
1338 
1339  while (buf + 5 < buf_end) {
1340  region_id = *buf++;
1341  buf += 1;
1342 
1343  display = ctx->display_list;
1344  while (display && display->region_id != region_id) {
1345  display = display->next;
1346  }
1347  if (display) {
1348  av_log(avctx, AV_LOG_ERROR, "duplicate region\n");
1349  break;
1350  }
1351 
1352  display = tmp_display_list;
1353  tmp_ptr = &tmp_display_list;
1354 
1355  while (display && display->region_id != region_id) {
1356  tmp_ptr = &display->next;
1357  display = display->next;
1358  }
1359 
1360  if (!display) {
1361  display = av_mallocz(sizeof(*display));
1362  if (!display)
1363  return AVERROR(ENOMEM);
1364  }
1365 
1366  display->region_id = region_id;
1367 
1368  display->x_pos = AV_RB16(buf);
1369  buf += 2;
1370  display->y_pos = AV_RB16(buf);
1371  buf += 2;
1372 
1373  *tmp_ptr = display->next;
1374 
1375  display->next = ctx->display_list;
1376  ctx->display_list = display;
1377 
1378  ff_dlog(avctx, "Region %d, (%d,%d)\n", region_id, display->x_pos, display->y_pos);
1379  }
1380 
1381  while (tmp_display_list) {
1382  display = tmp_display_list;
1383 
1384  tmp_display_list = display->next;
1385 
1386  av_freep(&display);
1387  }
1388 
1389  return 0;
1390 }
1391 
1393  const uint8_t *buf,
1394  int buf_size)
1395 {
1396  DVBSubContext *ctx = avctx->priv_data;
1397  DVBSubDisplayDefinition *display_def = ctx->display_definition;
1398  int dds_version, info_byte;
1399 
1400  if (buf_size < 5)
1401  return AVERROR_INVALIDDATA;
1402 
1403  info_byte = bytestream_get_byte(&buf);
1404  dds_version = info_byte >> 4;
1405  if (display_def && display_def->version == dds_version)
1406  return 0; // already have this display definition version
1407 
1408  if (!display_def) {
1409  display_def = av_mallocz(sizeof(*display_def));
1410  if (!display_def)
1411  return AVERROR(ENOMEM);
1412  ctx->display_definition = display_def;
1413  }
1414 
1415  display_def->version = dds_version;
1416  display_def->x = 0;
1417  display_def->y = 0;
1418  display_def->width = bytestream_get_be16(&buf) + 1;
1419  display_def->height = bytestream_get_be16(&buf) + 1;
1420  if (!avctx->width || !avctx->height) {
1421  int ret = ff_set_dimensions(avctx, display_def->width, display_def->height);
1422  if (ret < 0)
1423  return ret;
1424  }
1425 
1426  if (info_byte & 1<<3) { // display_window_flag
1427  if (buf_size < 13)
1428  return AVERROR_INVALIDDATA;
1429 
1430  display_def->x = bytestream_get_be16(&buf);
1431  display_def->width = bytestream_get_be16(&buf) - display_def->x + 1;
1432  display_def->y = bytestream_get_be16(&buf);
1433  display_def->height = bytestream_get_be16(&buf) - display_def->y + 1;
1434  }
1435 
1436  return 0;
1437 }
1438 
1439 static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf,
1440  int buf_size, AVSubtitle *sub,int *got_output)
1441 {
1442  DVBSubContext *ctx = avctx->priv_data;
1443 
1444  if (ctx->compute_edt == 0)
1445  save_subtitle_set(avctx, sub, got_output);
1446  return 0;
1447 }
1448 
1449 static int dvbsub_decode(AVCodecContext *avctx, AVSubtitle *sub,
1450  int *got_sub_ptr, const AVPacket *avpkt)
1451 {
1452  const uint8_t *buf = avpkt->data;
1453  int buf_size = avpkt->size;
1454  DVBSubContext *ctx = avctx->priv_data;
1455  const uint8_t *p, *p_end;
1456  int segment_type;
1457  int page_id;
1458  int segment_length;
1459  int i;
1460  int ret = 0;
1461  int got_page = 0;
1462  int got_region = 0;
1463  int got_object = 0;
1464  int got_end_display = 0;
1465  int got_displaydef = 0;
1466 
1467  ff_dlog(avctx, "DVB sub packet:\n");
1468 
1469  for (i=0; i < buf_size; i++) {
1470  ff_dlog(avctx, "%02x ", buf[i]);
1471  if (i % 16 == 15)
1472  ff_dlog(avctx, "\n");
1473  }
1474 
1475  if (i % 16)
1476  ff_dlog(avctx, "\n");
1477 
1478  if (buf_size <= 6 || *buf != 0x0f) {
1479  ff_dlog(avctx, "incomplete or broken packet");
1480  return AVERROR_INVALIDDATA;
1481  }
1482 
1483  p = buf;
1484  p_end = buf + buf_size;
1485 
1486  while (p_end - p >= 6 && *p == 0x0f) {
1487  p += 1;
1488  segment_type = *p++;
1489  page_id = AV_RB16(p);
1490  p += 2;
1491  segment_length = AV_RB16(p);
1492  p += 2;
1493 
1494  if (avctx->debug & FF_DEBUG_STARTCODE) {
1495  av_log(avctx, AV_LOG_DEBUG, "segment_type:%d page_id:%d segment_length:%d\n", segment_type, page_id, segment_length);
1496  }
1497 
1498  if (p_end - p < segment_length) {
1499  ff_dlog(avctx, "incomplete or broken packet");
1500  ret = -1;
1501  goto end;
1502  }
1503 
1504  if (page_id == ctx->composition_id || page_id == ctx->ancillary_id ||
1505  ctx->composition_id == -1 || ctx->ancillary_id == -1) {
1506  int ret = 0;
1507  switch (segment_type) {
1508  case DVBSUB_PAGE_SEGMENT:
1509  ret = dvbsub_parse_page_segment(avctx, p, segment_length, sub, got_sub_ptr);
1510  got_page = 1;
1511  break;
1512  case DVBSUB_REGION_SEGMENT:
1513  ret = dvbsub_parse_region_segment(avctx, p, segment_length);
1514  got_region = 1;
1515  break;
1516  case DVBSUB_CLUT_SEGMENT:
1517  ret = dvbsub_parse_clut_segment(avctx, p, segment_length);
1518  if (ret < 0) goto end;
1519  break;
1520  case DVBSUB_OBJECT_SEGMENT:
1521  ret = dvbsub_parse_object_segment(avctx, p, segment_length);
1522  got_object = 1;
1523  break;
1526  segment_length);
1527  got_displaydef = 1;
1528  break;
1530  ret = dvbsub_display_end_segment(avctx, p, segment_length, sub, got_sub_ptr);
1531  got_end_display = 1;
1532  break;
1533  default:
1534  ff_dlog(avctx, "Subtitling segment type 0x%x, page id %d, length %d\n",
1535  segment_type, page_id, segment_length);
1536  break;
1537  }
1538  if (ret < 0)
1539  goto end;
1540  }
1541 
1542  p += segment_length;
1543  }
1544 
1545  // Even though not mandated by the spec, we're imposing a minimum requirement
1546  // for a useful packet to have at least one page, region and object segment.
1547  if (got_page && got_region && got_object) {
1548 
1549  if (!got_displaydef && !avctx->width && !avctx->height) {
1550  // Default from ETSI EN 300 743 V1.3.1 (7.2.1)
1551  avctx->width = 720;
1552  avctx->height = 576;
1553  }
1554 
1555  // Some streams do not send an end-of-display segment but if we have all the other
1556  // segments then we need no further data.
1557  if (!got_end_display) {
1558  av_log(avctx, AV_LOG_DEBUG, "Missing display_end_segment, emulating\n");
1559  dvbsub_display_end_segment(avctx, p, 0, sub, got_sub_ptr);
1560  }
1561  }
1562 end:
1563  if (ret < 0) {
1564  return ret;
1565  } else {
1566  if (ctx->compute_edt == 1)
1567  FFSWAP(int64_t, ctx->prev_start, sub->pts);
1568  }
1569 
1570  return p - buf;
1571 }
1572 
1573 #define DS AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_SUBTITLE_PARAM
1574 #define OFFSET(x) offsetof(DVBSubContext, x)
1575 static const AVOption options[] = {
1576  {"compute_edt", "compute end of time using pts or timeout", OFFSET(compute_edt), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DS},
1577  {"compute_clut", "compute clut when not available(-1) or only once (-2) or always(1) or never(0)", OFFSET(compute_clut), AV_OPT_TYPE_BOOL, {.i64 = -1}, -2, 1, DS},
1578  {"dvb_substream", "", OFFSET(substream), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 63, DS},
1579  {NULL}
1580 };
1581 static const AVClass dvbsubdec_class = {
1582  .class_name = "DVB Sub Decoder",
1583  .item_name = av_default_item_name,
1584  .option = options,
1585  .version = LIBAVUTIL_VERSION_INT,
1586 };
1587 
1589  .p.name = "dvbsub",
1590  CODEC_LONG_NAME("DVB subtitles"),
1591  .p.type = AVMEDIA_TYPE_SUBTITLE,
1592  .p.id = AV_CODEC_ID_DVB_SUBTITLE,
1593  .priv_data_size = sizeof(DVBSubContext),
1597  .p.priv_class = &dvbsubdec_class,
1598 };
DVBSubObjectDisplay::object_id
int object_id
Definition: dvbsubdec.c:58
AVSubtitle
Definition: avcodec.h:2075
DVBSubDisplayDefinition::version
int version
Definition: dvbsubdec.c:115
rect::w
int w
Definition: f_ebur128.c:78
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:203
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
DVBSubRegion::width
int width
Definition: dvbsubdec.c:95
delete_cluts
static void delete_cluts(DVBSubContext *ctx)
Definition: dvbsubdec.c:224
r
const char * r
Definition: vf_curves.c:127
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
AVSubtitle::rects
AVSubtitleRect ** rects
Definition: avcodec.h:2080
opt.h
DVBSubRegionDisplay
Definition: dvbsubdec.c:82
bytestream2_get_bytes_left
static av_always_inline int bytestream2_get_bytes_left(const GetByteContext *g)
Definition: bytestream.h:158
cb
static double cb(void *priv, double x, double y)
Definition: vf_geq.c:247
DVBSUB_END_DISPLAY_SEGMENT
#define DVBSUB_END_DISPLAY_SEGMENT
Definition: dvbsubdec.c:38
GetByteContext
Definition: bytestream.h:33
DVBSubContext::prev_start
int64_t prev_start
Definition: dvbsubdec.c:135
bytestream2_tell
static av_always_inline int bytestream2_tell(const GetByteContext *g)
Definition: bytestream.h:192
thread.h
dvbsubdec_class
static const AVClass dvbsubdec_class
Definition: dvbsubdec.c:1581
get_region
static DVBSubRegion * get_region(DVBSubContext *ctx, int region_id)
Definition: dvbsubdec.c:167
rect
Definition: f_ebur128.c:78
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:263
int64_t
long long int64_t
Definition: coverity.c:34
AVSubtitleRect
Definition: avcodec.h:2048
dvbsub_parse_region_segment
static int dvbsub_parse_region_segment(AVCodecContext *avctx, const uint8_t *buf, int buf_size)
Definition: dvbsubdec.c:1150
AVSubtitle::num_rects
unsigned num_rects
Definition: avcodec.h:2079
rect::y
int y
Definition: f_ebur128.c:78
get_bits_count
static int get_bits_count(const GetBitContext *s)
Definition: get_bits.h:250
DVBSubRegion::clut
int clut
Definition: dvbsubdec.c:99
DVBSubContext::compute_edt
int compute_edt
if 1 end display time calculated using pts if 0 (Default) calculated using time out
Definition: dvbsubdec.c:130
av_unused
#define av_unused
Definition: attributes.h:131
options
static const AVOption options[]
Definition: dvbsubdec.c:1575
w
uint8_t w
Definition: llviddspenc.c:38
AVPacket::data
uint8_t * data
Definition: packet.h:552
DVBSUB_PAGE_SEGMENT
#define DVBSUB_PAGE_SEGMENT
Definition: dvbsubdec.c:33
AVOption
AVOption.
Definition: opt.h:429
b
#define b
Definition: input.c:42
DVBSubObject::display_list
DVBSubObjectDisplay * display_list
Definition: dvbsubdec.c:77
DVBSubObjectDisplay::y_pos
int y_pos
Definition: dvbsubdec.c:62
FFCodec
Definition: codec_internal.h:127
DVBSubDisplayDefinition::x
int x
Definition: dvbsubdec.c:117
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
YUV_TO_RGB1_CCIR
#define YUV_TO_RGB1_CCIR(cb1, cr1)
Definition: colorspace.h:34
delete_objects
static void delete_objects(DVBSubContext *ctx)
Definition: dvbsubdec.c:235
ff_set_dimensions
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
Definition: utils.c:91
DVBSubContext::display_list
DVBSubRegionDisplay * display_list
Definition: dvbsubdec.c:140
init_get_bits
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:512
DVBSubRegionDisplay::x_pos
int x_pos
Definition: dvbsubdec.c:85
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
av_memdup
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
Definition: mem.c:304
compute_default_clut
static void compute_default_clut(DVBSubContext *ctx, uint8_t *clut, AVSubtitleRect *rect, int w, int h)
Definition: dvbsubdec.c:671
close
static av_cold void close(AVCodecParserContext *s)
Definition: apv_parser.c:135
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:333
DVBSubObject::id
int id
Definition: dvbsubdec.c:72
OFFSET
#define OFFSET(x)
Definition: dvbsubdec.c:1574
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
get_object
static DVBSubObject * get_object(DVBSubContext *ctx, int object_id)
Definition: dvbsubdec.c:145
DVBSubRegion::pbuf
uint8_t * pbuf
Definition: dvbsubdec.c:105
fail
#define fail()
Definition: checkasm.h:199
GetBitContext
Definition: get_bits.h:109
DVBSubContext::substream
int substream
Definition: dvbsubdec.c:134
DVBSubRegion::bgcolor
int bgcolor
Definition: dvbsubdec.c:100
DVBSubRegionDisplay::region_id
int region_id
Definition: dvbsubdec.c:83
DVBSubContext::time_out
int time_out
Definition: dvbsubdec.c:129
av_image_check_size2
int av_image_check_size2(unsigned int w, unsigned int h, int64_t max_pixels, enum AVPixelFormat pix_fmt, int log_offset, void *log_ctx)
Check if the given dimension of an image is valid, meaning that all bytes of a plane of an image with...
Definition: imgutils.c:289
AV_CODEC_ID_DVB_SUBTITLE
@ AV_CODEC_ID_DVB_SUBTITLE
Definition: codec_id.h:563
DVBSubContext::region_list
DVBSubRegion * region_list
Definition: dvbsubdec.c:136
colorspace.h
ff_thread_once
static int ff_thread_once(char *control, void(*routine)(void))
Definition: thread.h:205
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
av_cold
#define av_cold
Definition: attributes.h:90
dvbsub_decode
static int dvbsub_decode(AVCodecContext *avctx, AVSubtitle *sub, int *got_sub_ptr, const AVPacket *avpkt)
Definition: dvbsubdec.c:1449
DVBSUB_DISPLAYDEFINITION_SEGMENT
#define DVBSUB_DISPLAYDEFINITION_SEGMENT
Definition: dvbsubdec.c:37
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:515
full_range
bool full_range
Definition: hwcontext_videotoolbox.c:46
V
#define V(x, y)
DVBSubRegion::display_list
DVBSubObjectDisplay * display_list
Definition: dvbsubdec.c:109
g
const char * g
Definition: vf_curves.c:128
bits
uint8_t bits
Definition: vp3data.h:128
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:41
DVBSubObjectDisplay::region_list_next
struct DVBSubObjectDisplay * region_list_next
Definition: dvbsubdec.c:67
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
ctx
AVFormatContext * ctx
Definition: movenc.c:49
decode.h
get_bits.h
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
AVSubtitle::pts
int64_t pts
Same as packet pts, in AV_TIME_BASE.
Definition: avcodec.h:2081
DVBSUB_CLUT_SEGMENT
#define DVBSUB_CLUT_SEGMENT
Definition: dvbsubdec.c:35
AVCodecContext::max_pixels
int64_t max_pixels
The number of pixels per image to maximally accept.
Definition: avcodec.h:1782
DVBSubObjectDisplay::region_id
int region_id
Definition: dvbsubdec.c:59
DVBSubDisplayDefinition::width
int width
Definition: dvbsubdec.c:119
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:326
DVBSubContext::clut_list
DVBSubCLUT * clut_list
Definition: dvbsubdec.c:137
delete_regions
static void delete_regions(DVBSubContext *ctx)
Definition: dvbsubdec.c:246
DVBSUB_OBJECT_SEGMENT
#define DVBSUB_OBJECT_SEGMENT
Definition: dvbsubdec.c:36
DVBSubDisplayDefinition
Definition: dvbsubdec.c:114
save_subtitle_set
static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_output)
Definition: dvbsubdec.c:737
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AV_ONCE_INIT
#define AV_ONCE_INIT
Definition: thread.h:203
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
DVBSubRegion::id
int id
Definition: dvbsubdec.c:92
NULL
#define NULL
Definition: coverity.c:32
DVBSubCLUT
Definition: dvbsubdec.c:44
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
dvbsub_parse_display_definition_segment
static int dvbsub_parse_display_definition_segment(AVCodecContext *avctx, const uint8_t *buf, int buf_size)
Definition: dvbsubdec.c:1392
dvbsub_close_decoder
static av_cold int dvbsub_close_decoder(AVCodecContext *avctx)
Definition: dvbsubdec.c:356
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
dvbsub_parse_clut_segment
static int dvbsub_parse_clut_segment(AVCodecContext *avctx, const uint8_t *buf, int buf_size)
Definition: dvbsubdec.c:1053
AVPALETTE_SIZE
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:241
get_bits1
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:386
dvbsub_parse_pixel_data_block
static void dvbsub_parse_pixel_data_block(AVCodecContext *avctx, DVBSubObjectDisplay *display, const uint8_t *buf, int buf_size, int top_bottom, int non_mod)
Definition: dvbsubdec.c:871
DVBSubCLUT::clut256
uint32_t clut256[256]
Definition: dvbsubdec.c:50
DVBSUB_REGION_SEGMENT
#define DVBSUB_REGION_SEGMENT
Definition: dvbsubdec.c:34
list
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining list
Definition: filter_design.txt:25
options
Definition: swscale.c:43
DVBSubDisplayDefinition::y
int y
Definition: dvbsubdec.c:118
YUV_TO_RGB2_CCIR
#define YUV_TO_RGB2_CCIR(r, g, b, y1)
Definition: colorspace.h:55
DVBSubObject::type
int type
Definition: dvbsubdec.c:75
DVBSubCLUT::clut16
uint32_t clut16[16]
Definition: dvbsubdec.c:49
DVBSubCLUT::next
struct DVBSubCLUT * next
Definition: dvbsubdec.c:52
dvbsub_parse_object_segment
static int dvbsub_parse_object_segment(AVCodecContext *avctx, const uint8_t *buf, int buf_size)
Definition: dvbsubdec.c:989
DVBSubContext::compute_clut
int compute_clut
Definition: dvbsubdec.c:132
AVOnce
#define AVOnce
Definition: thread.h:202
dvbsub_read_2bit_string
static int dvbsub_read_2bit_string(AVCodecContext *avctx, uint8_t *destbuf, int dbuf_len, const uint8_t **srcbuf, int buf_size, int non_mod, uint8_t *map_table, int x_pos)
Definition: dvbsubdec.c:379
DVBSubRegion::next
struct DVBSubRegion * next
Definition: dvbsubdec.c:111
dvbsub_display_end_segment
static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf, int buf_size, AVSubtitle *sub, int *got_output)
Definition: dvbsubdec.c:1439
ff_dlog
#define ff_dlog(a,...)
Definition: tableprint_vlc.h:28
ff_dvbsub_decoder
const FFCodec ff_dvbsub_decoder
Definition: dvbsubdec.c:1588
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:368
AVPacket::size
int size
Definition: packet.h:553
codec_internal.h
AV_WN32
#define AV_WN32(p, v)
Definition: intreadwrite.h:372
init_default_clut
static av_cold void init_default_clut(void)
Definition: dvbsubdec.c:260
DVBSubRegion
Definition: dvbsubdec.c:91
DVBSubRegion::buf_size
int buf_size
Definition: dvbsubdec.c:106
DVBSubCLUT::clut4
uint32_t clut4[4]
Definition: dvbsubdec.c:48
DVBSubObjectDisplay::fgcolor
int fgcolor
Definition: dvbsubdec.c:64
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:247
rect::h
int h
Definition: f_ebur128.c:78
avpriv_report_missing_feature
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
DVBSubContext::display_definition
DVBSubDisplayDefinition * display_definition
Definition: dvbsubdec.c:141
DVBSubObject::version
int version
Definition: dvbsubdec.c:73
AVSubtitle::end_display_time
uint32_t end_display_time
Definition: avcodec.h:2078
DVBSubRegion::dirty
int dirty
Definition: dvbsubdec.c:107
get_clut
static DVBSubCLUT * get_clut(DVBSubContext *ctx, int clut_id)
Definition: dvbsubdec.c:156
FF_COMPLIANCE_NORMAL
#define FF_COMPLIANCE_NORMAL
Definition: defs.h:60
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
xf
#define xf(width, name, var, range_min, range_max, subs,...)
Definition: cbs_av1.c:621
version
version
Definition: libkvazaar.c:315
rect::x
int x
Definition: f_ebur128.c:78
delete_region_display_list
static void delete_region_display_list(DVBSubContext *ctx, DVBSubRegion *region)
Definition: dvbsubdec.c:178
SUBTITLE_BITMAP
@ SUBTITLE_BITMAP
A bitmap, pict will be set.
Definition: avcodec.h:2031
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
DVBSubContext::composition_id
int composition_id
Definition: dvbsubdec.c:125
DVBSubRegion::depth
int depth
Definition: dvbsubdec.c:97
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
DVBSubObject::next
struct DVBSubObject * next
Definition: dvbsubdec.c:79
AVCodecContext::extradata
uint8_t * extradata
Out-of-band global headers that may be used by some codecs.
Definition: avcodec.h:514
DVBSubRegion::height
int height
Definition: dvbsubdec.c:96
DVBSubObjectDisplay::x_pos
int x_pos
Definition: dvbsubdec.c:61
FF_DEBUG_STARTCODE
#define FF_DEBUG_STARTCODE
Definition: avcodec.h:1382
dvbsub_init_decoder
static av_cold int dvbsub_init_decoder(AVCodecContext *avctx)
Definition: dvbsubdec.c:325
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
DVBSubObject
Definition: dvbsubdec.c:71
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:179
AVCodecContext::height
int height
Definition: avcodec.h:592
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
avcodec.h
stride
#define stride
Definition: h264pred_template.c:536
DVBSubRegion::has_computed_clut
int has_computed_clut
Definition: dvbsubdec.c:103
AV_PIX_FMT_PAL8
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:84
DVBSubRegionDisplay::y_pos
int y_pos
Definition: dvbsubdec.c:86
ret
ret
Definition: filter_design.txt:187
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:81
AVCodecContext::strict_std_compliance
int strict_std_compliance
strictly follow the standard (MPEG-4, ...).
Definition: avcodec.h:1357
DVBSubRegion::version
int version
Definition: dvbsubdec.c:93
DVBSubRegion::computed_clut
uint8_t computed_clut[4 *256]
Definition: dvbsubdec.c:102
AVCodecContext
main external API structure.
Definition: avcodec.h:431
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
default_clut
static DVBSubCLUT default_clut
Definition: dvbsubdec.c:55
DVBSubContext::ancillary_id
int ancillary_id
Definition: dvbsubdec.c:126
DVBSubCLUT::version
int version
Definition: dvbsubdec.c:46
DS
#define DS
Definition: dvbsubdec.c:1573
FF_CODEC_DECODE_SUB_CB
#define FF_CODEC_DECODE_SUB_CB(func)
Definition: codec_internal.h:345
AVCodecContext::debug
int debug
debug
Definition: avcodec.h:1374
DVBSubContext::clut_count2
int clut_count2[257][256]
Definition: dvbsubdec.c:133
mem.h
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:37
DVBSubObjectDisplay::object_list_next
struct DVBSubObjectDisplay * object_list_next
Definition: dvbsubdec.c:68
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
DVBSubContext::object_list
DVBSubObject * object_list
Definition: dvbsubdec.c:138
AVPacket
This structure stores compressed data.
Definition: packet.h:529
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:458
DVBSubContext::version
int version
Definition: dvbsubdec.c:128
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
cr
static double cr(void *priv, double x, double y)
Definition: vf_geq.c:248
dvbsub_read_8bit_string
static int dvbsub_read_8bit_string(AVCodecContext *avctx, uint8_t *destbuf, int dbuf_len, const uint8_t **srcbuf, int buf_size, int non_mod, uint8_t *map_table, int x_pos)
Definition: dvbsubdec.c:610
dvbsub_read_4bit_string
static int dvbsub_read_4bit_string(AVCodecContext *avctx, uint8_t *destbuf, int dbuf_len, const uint8_t **srcbuf, int buf_size, int non_mod, uint8_t *map_table, int x_pos)
Definition: dvbsubdec.c:487
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:592
bytestream.h
RGBA
#define RGBA(r, g, b, a)
Definition: dvbsubdec.c:42
imgutils.h
bytestream2_init
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:137
block
The exact code depends on how similar the blocks are and how related they are to the block
Definition: filter_design.txt:207
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
dvbsub_parse_page_segment
static int dvbsub_parse_page_segment(AVCodecContext *avctx, const uint8_t *buf, int buf_size, AVSubtitle *sub, int *got_output)
Definition: dvbsubdec.c:1298
h
h
Definition: vp9dsp_template.c:2070
DVBSubObjectDisplay
Definition: dvbsubdec.c:57
DVBSubObjectDisplay::bgcolor
int bgcolor
Definition: dvbsubdec.c:65
DVBSubCLUT::id
int id
Definition: dvbsubdec.c:45
DVBSubRegionDisplay::next
struct DVBSubRegionDisplay * next
Definition: dvbsubdec.c:88
DVBSubDisplayDefinition::height
int height
Definition: dvbsubdec.c:120
DVBSubContext
Definition: dvbsubdec.c:123
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:98