dvdsubdec.c
Go to the documentation of this file.
1 /*
2  * DVD subtitle decoding
3  * Copyright (c) 2005 Fabrice Bellard
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 #include "avcodec.h"
22 #include "get_bits.h"
23 #include "dsputil.h"
24 #include "libavutil/colorspace.h"
25 #include "libavutil/opt.h"
26 #include "libavutil/imgutils.h"
27 #include "libavutil/avstring.h"
28 
29 //#define DEBUG
30 
31 typedef struct DVDSubContext
32 {
33  AVClass *class;
34  uint32_t palette[16];
35  char *palette_str;
38  uint8_t alpha[256];
40 
41 static void yuv_a_to_rgba(const uint8_t *ycbcr, const uint8_t *alpha, uint32_t *rgba, int num_values)
42 {
43  const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
44  uint8_t r, g, b;
45  int i, y, cb, cr;
46  int r_add, g_add, b_add;
47 
48  for (i = num_values; i > 0; i--) {
49  y = *ycbcr++;
50  cr = *ycbcr++;
51  cb = *ycbcr++;
52  YUV_TO_RGB1_CCIR(cb, cr);
53  YUV_TO_RGB2_CCIR(r, g, b, y);
54  *rgba++ = (*alpha++ << 24) | (r << 16) | (g << 8) | b;
55  }
56 }
57 
58 static int decode_run_2bit(GetBitContext *gb, int *color)
59 {
60  unsigned int v, t;
61 
62  v = 0;
63  for (t = 1; v < t && t <= 0x40; t <<= 2)
64  v = (v << 4) | get_bits(gb, 4);
65  *color = v & 3;
66  if (v < 4) { /* Code for fill rest of line */
67  return INT_MAX;
68  }
69  return v >> 2;
70 }
71 
72 static int decode_run_8bit(GetBitContext *gb, int *color)
73 {
74  int len;
75  int has_run = get_bits1(gb);
76  if (get_bits1(gb))
77  *color = get_bits(gb, 8);
78  else
79  *color = get_bits(gb, 2);
80  if (has_run) {
81  if (get_bits1(gb)) {
82  len = get_bits(gb, 7);
83  if (len == 0)
84  len = INT_MAX;
85  else
86  len += 9;
87  } else
88  len = get_bits(gb, 3) + 2;
89  } else
90  len = 1;
91  return len;
92 }
93 
94 static int decode_rle(uint8_t *bitmap, int linesize, int w, int h,
95  const uint8_t *buf, int start, int buf_size, int is_8bit)
96 {
97  GetBitContext gb;
98  int bit_len;
99  int x, y, len, color;
100  uint8_t *d;
101 
102  bit_len = (buf_size - start) * 8;
103  init_get_bits(&gb, buf + start, bit_len);
104 
105  x = 0;
106  y = 0;
107  d = bitmap;
108  for(;;) {
109  if (get_bits_count(&gb) > bit_len)
110  return -1;
111  if (is_8bit)
112  len = decode_run_8bit(&gb, &color);
113  else
114  len = decode_run_2bit(&gb, &color);
115  len = FFMIN(len, w - x);
116  memset(d + x, color, len);
117  x += len;
118  if (x >= w) {
119  y++;
120  if (y >= h)
121  break;
122  d += linesize;
123  x = 0;
124  /* byte align */
125  align_get_bits(&gb);
126  }
127  }
128  return 0;
129 }
130 
131 static void guess_palette(DVDSubContext* ctx,
132  uint32_t *rgba_palette,
133  uint32_t subtitle_color)
134 {
135  static const uint8_t level_map[4][4] = {
136  // this configuration (full range, lowest to highest) in tests
137  // seemed most common, so assume this
138  {0xff},
139  {0x00, 0xff},
140  {0x00, 0x80, 0xff},
141  {0x00, 0x55, 0xaa, 0xff},
142  };
143  uint8_t color_used[16] = { 0 };
144  int nb_opaque_colors, i, level, j, r, g, b;
145  uint8_t *colormap = ctx->colormap, *alpha = ctx->alpha;
146 
147  if(ctx->has_palette) {
148  for(i = 0; i < 4; i++)
149  rgba_palette[i] = (ctx->palette[colormap[i]] & 0x00ffffff)
150  | ((alpha[i] * 17U) << 24);
151  return;
152  }
153 
154  for(i = 0; i < 4; i++)
155  rgba_palette[i] = 0;
156 
157  nb_opaque_colors = 0;
158  for(i = 0; i < 4; i++) {
159  if (alpha[i] != 0 && !color_used[colormap[i]]) {
160  color_used[colormap[i]] = 1;
161  nb_opaque_colors++;
162  }
163  }
164 
165  if (nb_opaque_colors == 0)
166  return;
167 
168  j = 0;
169  memset(color_used, 0, 16);
170  for(i = 0; i < 4; i++) {
171  if (alpha[i] != 0) {
172  if (!color_used[colormap[i]]) {
173  level = level_map[nb_opaque_colors][j];
174  r = (((subtitle_color >> 16) & 0xff) * level) >> 8;
175  g = (((subtitle_color >> 8) & 0xff) * level) >> 8;
176  b = (((subtitle_color >> 0) & 0xff) * level) >> 8;
177  rgba_palette[i] = b | (g << 8) | (r << 16) | ((alpha[i] * 17) << 24);
178  color_used[colormap[i]] = (i + 1);
179  j++;
180  } else {
181  rgba_palette[i] = (rgba_palette[color_used[colormap[i]] - 1] & 0x00ffffff) |
182  ((alpha[i] * 17) << 24);
183  }
184  }
185  }
186 }
187 
188 #define READ_OFFSET(a) (big_offsets ? AV_RB32(a) : AV_RB16(a))
189 
190 static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header,
191  const uint8_t *buf, int buf_size)
192 {
193  int cmd_pos, pos, cmd, x1, y1, x2, y2, offset1, offset2, next_cmd_pos;
194  int big_offsets, offset_size, is_8bit = 0;
195  const uint8_t *yuv_palette = 0;
196  uint8_t *colormap = ctx->colormap, *alpha = ctx->alpha;
197  int date;
198  int i;
199  int is_menu = 0;
200 
201  if (buf_size < 10)
202  return -1;
203 
204  if (AV_RB16(buf) == 0) { /* HD subpicture with 4-byte offsets */
205  big_offsets = 1;
206  offset_size = 4;
207  cmd_pos = 6;
208  } else {
209  big_offsets = 0;
210  offset_size = 2;
211  cmd_pos = 2;
212  }
213 
214  cmd_pos = READ_OFFSET(buf + cmd_pos);
215 
216  while (cmd_pos > 0 && cmd_pos < buf_size - 2 - offset_size) {
217  date = AV_RB16(buf + cmd_pos);
218  next_cmd_pos = READ_OFFSET(buf + cmd_pos + 2);
219  av_dlog(NULL, "cmd_pos=0x%04x next=0x%04x date=%d\n",
220  cmd_pos, next_cmd_pos, date);
221  pos = cmd_pos + 2 + offset_size;
222  offset1 = -1;
223  offset2 = -1;
224  x1 = y1 = x2 = y2 = 0;
225  while (pos < buf_size) {
226  cmd = buf[pos++];
227  av_dlog(NULL, "cmd=%02x\n", cmd);
228  switch(cmd) {
229  case 0x00:
230  /* menu subpicture */
231  is_menu = 1;
232  break;
233  case 0x01:
234  /* set start date */
235  sub_header->start_display_time = (date << 10) / 90;
236  break;
237  case 0x02:
238  /* set end date */
239  sub_header->end_display_time = (date << 10) / 90;
240  break;
241  case 0x03:
242  /* set colormap */
243  if ((buf_size - pos) < 2)
244  goto fail;
245  colormap[3] = buf[pos] >> 4;
246  colormap[2] = buf[pos] & 0x0f;
247  colormap[1] = buf[pos + 1] >> 4;
248  colormap[0] = buf[pos + 1] & 0x0f;
249  pos += 2;
250  break;
251  case 0x04:
252  /* set alpha */
253  if ((buf_size - pos) < 2)
254  goto fail;
255  alpha[3] = buf[pos] >> 4;
256  alpha[2] = buf[pos] & 0x0f;
257  alpha[1] = buf[pos + 1] >> 4;
258  alpha[0] = buf[pos + 1] & 0x0f;
259  pos += 2;
260  av_dlog(NULL, "alpha=%x%x%x%x\n", alpha[0],alpha[1],alpha[2],alpha[3]);
261  break;
262  case 0x05:
263  case 0x85:
264  if ((buf_size - pos) < 6)
265  goto fail;
266  x1 = (buf[pos] << 4) | (buf[pos + 1] >> 4);
267  x2 = ((buf[pos + 1] & 0x0f) << 8) | buf[pos + 2];
268  y1 = (buf[pos + 3] << 4) | (buf[pos + 4] >> 4);
269  y2 = ((buf[pos + 4] & 0x0f) << 8) | buf[pos + 5];
270  if (cmd & 0x80)
271  is_8bit = 1;
272  av_dlog(NULL, "x1=%d x2=%d y1=%d y2=%d\n", x1, x2, y1, y2);
273  pos += 6;
274  break;
275  case 0x06:
276  if ((buf_size - pos) < 4)
277  goto fail;
278  offset1 = AV_RB16(buf + pos);
279  offset2 = AV_RB16(buf + pos + 2);
280  av_dlog(NULL, "offset1=0x%04x offset2=0x%04x\n", offset1, offset2);
281  pos += 4;
282  break;
283  case 0x86:
284  if ((buf_size - pos) < 8)
285  goto fail;
286  offset1 = AV_RB32(buf + pos);
287  offset2 = AV_RB32(buf + pos + 4);
288  av_dlog(NULL, "offset1=0x%04x offset2=0x%04x\n", offset1, offset2);
289  pos += 8;
290  break;
291 
292  case 0x83:
293  /* HD set palette */
294  if ((buf_size - pos) < 768)
295  goto fail;
296  yuv_palette = buf + pos;
297  pos += 768;
298  break;
299  case 0x84:
300  /* HD set contrast (alpha) */
301  if ((buf_size - pos) < 256)
302  goto fail;
303  for (i = 0; i < 256; i++)
304  alpha[i] = 0xFF - buf[pos+i];
305  pos += 256;
306  break;
307 
308  case 0xff:
309  goto the_end;
310  default:
311  av_dlog(NULL, "unrecognised subpicture command 0x%x\n", cmd);
312  goto the_end;
313  }
314  }
315  the_end:
316  if (offset1 >= 0) {
317  int w, h;
318  uint8_t *bitmap;
319 
320  /* decode the bitmap */
321  w = x2 - x1 + 1;
322  if (w < 0)
323  w = 0;
324  h = y2 - y1;
325  if (h < 0)
326  h = 0;
327  if (w > 0 && h > 0) {
328  if (sub_header->rects != NULL) {
329  for (i = 0; i < sub_header->num_rects; i++) {
330  av_freep(&sub_header->rects[i]->pict.data[0]);
331  av_freep(&sub_header->rects[i]->pict.data[1]);
332  av_freep(&sub_header->rects[i]);
333  }
334  av_freep(&sub_header->rects);
335  sub_header->num_rects = 0;
336  }
337 
338  bitmap = av_malloc(w * h);
339  sub_header->rects = av_mallocz(sizeof(*sub_header->rects));
340  sub_header->rects[0] = av_mallocz(sizeof(AVSubtitleRect));
341  sub_header->num_rects = 1;
342  sub_header->rects[0]->pict.data[0] = bitmap;
343  decode_rle(bitmap, w * 2, w, (h + 1) / 2,
344  buf, offset1, buf_size, is_8bit);
345  decode_rle(bitmap + w, w * 2, w, h / 2,
346  buf, offset2, buf_size, is_8bit);
347  sub_header->rects[0]->pict.data[1] = av_mallocz(AVPALETTE_SIZE);
348  if (is_8bit) {
349  if (yuv_palette == 0)
350  goto fail;
351  sub_header->rects[0]->nb_colors = 256;
352  yuv_a_to_rgba(yuv_palette, alpha, (uint32_t*)sub_header->rects[0]->pict.data[1], 256);
353  } else {
354  sub_header->rects[0]->nb_colors = 4;
355  guess_palette(ctx, (uint32_t*)sub_header->rects[0]->pict.data[1],
356  0xffff00);
357  }
358  sub_header->rects[0]->x = x1;
359  sub_header->rects[0]->y = y1;
360  sub_header->rects[0]->w = w;
361  sub_header->rects[0]->h = h;
362  sub_header->rects[0]->type = SUBTITLE_BITMAP;
363  sub_header->rects[0]->pict.linesize[0] = w;
364  sub_header->rects[0]->flags = is_menu ? AV_SUBTITLE_FLAG_FORCED : 0;
365  }
366  }
367  if (next_cmd_pos < cmd_pos) {
368  av_log(NULL, AV_LOG_ERROR, "Invalid command offset\n");
369  break;
370  }
371  if (next_cmd_pos == cmd_pos)
372  break;
373  cmd_pos = next_cmd_pos;
374  }
375  if (sub_header->num_rects > 0)
376  return is_menu;
377  fail:
378  if (sub_header->rects != NULL) {
379  for (i = 0; i < sub_header->num_rects; i++) {
380  av_freep(&sub_header->rects[i]->pict.data[0]);
381  av_freep(&sub_header->rects[i]->pict.data[1]);
382  av_freep(&sub_header->rects[i]);
383  }
384  av_freep(&sub_header->rects);
385  sub_header->num_rects = 0;
386  }
387  return -1;
388 }
389 
390 static int is_transp(const uint8_t *buf, int pitch, int n,
391  const uint8_t *transp_color)
392 {
393  int i;
394  for(i = 0; i < n; i++) {
395  if (!transp_color[*buf])
396  return 0;
397  buf += pitch;
398  }
399  return 1;
400 }
401 
402 /* return 0 if empty rectangle, 1 if non empty */
404 {
405  uint8_t transp_color[256] = { 0 };
406  int y1, y2, x1, x2, y, w, h, i;
407  uint8_t *bitmap;
408 
409  if (s->num_rects == 0 || s->rects == NULL || s->rects[0]->w <= 0 || s->rects[0]->h <= 0)
410  return 0;
411 
412  for(i = 0; i < s->rects[0]->nb_colors; i++) {
413  if ((((uint32_t*)s->rects[0]->pict.data[1])[i] >> 24) == 0)
414  transp_color[i] = 1;
415  }
416  y1 = 0;
417  while (y1 < s->rects[0]->h && is_transp(s->rects[0]->pict.data[0] + y1 * s->rects[0]->pict.linesize[0],
418  1, s->rects[0]->w, transp_color))
419  y1++;
420  if (y1 == s->rects[0]->h) {
421  av_freep(&s->rects[0]->pict.data[0]);
422  s->rects[0]->w = s->rects[0]->h = 0;
423  return 0;
424  }
425 
426  y2 = s->rects[0]->h - 1;
427  while (y2 > 0 && is_transp(s->rects[0]->pict.data[0] + y2 * s->rects[0]->pict.linesize[0], 1,
428  s->rects[0]->w, transp_color))
429  y2--;
430  x1 = 0;
431  while (x1 < (s->rects[0]->w - 1) && is_transp(s->rects[0]->pict.data[0] + x1, s->rects[0]->pict.linesize[0],
432  s->rects[0]->h, transp_color))
433  x1++;
434  x2 = s->rects[0]->w - 1;
435  while (x2 > 0 && is_transp(s->rects[0]->pict.data[0] + x2, s->rects[0]->pict.linesize[0], s->rects[0]->h,
436  transp_color))
437  x2--;
438  w = x2 - x1 + 1;
439  h = y2 - y1 + 1;
440  bitmap = av_malloc(w * h);
441  if (!bitmap)
442  return 1;
443  for(y = 0; y < h; y++) {
444  memcpy(bitmap + w * y, s->rects[0]->pict.data[0] + x1 + (y1 + y) * s->rects[0]->pict.linesize[0], w);
445  }
446  av_freep(&s->rects[0]->pict.data[0]);
447  s->rects[0]->pict.data[0] = bitmap;
448  s->rects[0]->pict.linesize[0] = w;
449  s->rects[0]->w = w;
450  s->rects[0]->h = h;
451  s->rects[0]->x += x1;
452  s->rects[0]->y += y1;
453  return 1;
454 }
455 
456 #ifdef DEBUG
457 #undef fprintf
458 #undef perror
459 #undef exit
460 static void ppm_save(const char *filename, uint8_t *bitmap, int w, int h,
461  uint32_t *rgba_palette)
462 {
463  int x, y, v;
464  FILE *f;
465 
466  f = fopen(filename, "w");
467  if (!f) {
468  perror(filename);
469  exit(1);
470  }
471  fprintf(f, "P6\n"
472  "%d %d\n"
473  "%d\n",
474  w, h, 255);
475  for(y = 0; y < h; y++) {
476  for(x = 0; x < w; x++) {
477  v = rgba_palette[bitmap[y * w + x]];
478  putc((v >> 16) & 0xff, f);
479  putc((v >> 8) & 0xff, f);
480  putc((v >> 0) & 0xff, f);
481  }
482  }
483  fclose(f);
484 }
485 #endif
486 
487 static int dvdsub_decode(AVCodecContext *avctx,
488  void *data, int *data_size,
489  AVPacket *avpkt)
490 {
491  DVDSubContext *ctx = avctx->priv_data;
492  const uint8_t *buf = avpkt->data;
493  int buf_size = avpkt->size;
494  AVSubtitle *sub = data;
495  int is_menu;
496 
497  is_menu = decode_dvd_subtitles(ctx, sub, buf, buf_size);
498 
499  if (is_menu < 0) {
500  no_subtitle:
501  *data_size = 0;
502 
503  return buf_size;
504  }
505  if (!is_menu && find_smallest_bounding_rectangle(sub) == 0)
506  goto no_subtitle;
507 
508 #if defined(DEBUG)
509  av_dlog(NULL, "start=%d ms end =%d ms\n",
510  sub->start_display_time,
511  sub->end_display_time);
512  ppm_save("/tmp/a.ppm", sub->rects[0]->pict.data[0],
513  sub->rects[0]->w, sub->rects[0]->h, sub->rects[0]->pict.data[1]);
514 #endif
515 
516  *data_size = 1;
517  return buf_size;
518 }
519 
520 static void parse_palette(DVDSubContext *ctx, char *p)
521 {
522  int i;
523 
524  ctx->has_palette = 1;
525  for(i=0;i<16;i++) {
526  ctx->palette[i] = strtoul(p, &p, 16);
527  while(*p == ',' || av_isspace(*p))
528  p++;
529  }
530 }
531 
533 {
534  DVDSubContext *ctx = (DVDSubContext*) avctx->priv_data;
535  char *dataorig, *data;
536 
537  if (!avctx->extradata || !avctx->extradata_size)
538  return 1;
539 
540  dataorig = data = av_malloc(avctx->extradata_size+1);
541  if (!data)
542  return AVERROR(ENOMEM);
543  memcpy(data, avctx->extradata, avctx->extradata_size);
544  data[avctx->extradata_size] = '\0';
545 
546  for(;;) {
547  int pos = strcspn(data, "\n\r");
548  if (pos==0 && *data==0)
549  break;
550 
551  if (strncmp("palette:", data, 8) == 0) {
552  parse_palette(ctx, data + 8);
553  } else if (strncmp("size:", data, 5) == 0) {
554  int w, h;
555  if (sscanf(data + 5, "%dx%d", &w, &h) == 2 &&
556  av_image_check_size(w, h, 0, avctx) >= 0)
557  avcodec_set_dimensions(avctx, w, h);
558  }
559 
560  data += pos;
561  data += strspn(data, "\n\r");
562  }
563 
564  av_free(dataorig);
565  return 1;
566 }
567 
568 static int dvdsub_init(AVCodecContext *avctx)
569 {
570  DVDSubContext *ctx = avctx->priv_data;
571  int ret;
572 
573  if ((ret = dvdsub_parse_extradata(avctx)) < 0)
574  return ret;
575 
576  if (ctx->palette_str)
577  parse_palette(ctx, ctx->palette_str);
578  if (ctx->has_palette) {
579  int i;
580  av_log(avctx, AV_LOG_DEBUG, "palette:");
581  for(i=0;i<16;i++)
582  av_log(avctx, AV_LOG_DEBUG, " 0x%06x", ctx->palette[i]);
583  av_log(avctx, AV_LOG_DEBUG, "\n");
584  }
585 
586  return 1;
587 }
588 
589 #define OFFSET(field) offsetof(DVDSubContext, field)
590 #define VD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM
591 static const AVOption options[] = {
592  { "palette", "set the global palette", OFFSET(palette_str), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, VD },
593  { NULL }
594 };
595 static const AVClass class = {
596  .class_name = "dvdsubdec",
597  .item_name = av_default_item_name,
598  .option = options,
600 };
601 
603  .name = "dvdsub",
604  .type = AVMEDIA_TYPE_SUBTITLE,
606  .priv_data_size = sizeof(DVDSubContext),
607  .init = dvdsub_init,
609  .long_name = NULL_IF_CONFIG_SMALL("DVD subtitles"),
610  .priv_class = &class,
611 };
Definition: start.py:1
uint8_t colormap[4]
Definition: dvdsubdec.c:37
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:205
float v
const char * s
Definition: avisynth_c.h:668
#define ff_cropTbl
int linesize[AV_NUM_DATA_POINTERS]
number of bytes per line
int x
top left corner of pict, undefined when pict is not set
AVOption.
Definition: opt.h:251
av_default_item_name
misc image utilities
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:240
#define YUV_TO_RGB1_CCIR(cb1, cr1)
Definition: colorspace.h:34
uint8_t alpha[256]
Definition: dvdsubdec.c:38
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
#define MAX_NEG_CROP
Definition: dsputil.h:47
void avcodec_set_dimensions(AVCodecContext *s, int width, int height)
int nb_colors
number of colors in pict, undefined when pict is not set
y1
Definition: lab5.m:33
Sinusoidal phase f
Various defines for YUV<->RGB conversion.
x1
Definition: genspecsines3.m:7
av_dlog(ac->avr,"%d samples - audio_convert: %s to %s (%s)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt), use_generic?ac->func_descr_generic:ac->func_descr)
uint32_t palette[16]
Definition: dvdsubdec.c:34
output residual component w
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
AVSubtitleRect ** rects
set threshold d
initialize output if(nPeaks >3)%at least 3 peaks in spectrum for trying to find f0 nf0peaks
int w
width of pict, undefined when pict is not set
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:55
struct DVDSubContext DVDSubContext
uint8_t
AVOptions.
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
Definition: log.c:77
uint8_t * data[AV_NUM_DATA_POINTERS]
#define AVPALETTE_SIZE
Definition: pixfmt.h:33
#define AV_RB32
#define b
Definition: input.c:42
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
uint8_t * data
static int get_bits_count(const GetBitContext *s)
Definition: get_bits.h:193
#define READ_OFFSET(a)
Definition: dvdsubdec.c:188
bitstream reader API header.
int h
height of pict, undefined when pict is not set
#define cm
Definition: dvbsubdec.c:34
#define VD
Definition: dvdsubdec.c:590
Discrete Time axis x
#define U(x)
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:183
int y
top left corner of pict, undefined when pict is not set
#define AV_RB16
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Spectrum Plot time data
const char * r
Definition: vf_curves.c:94
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
const char * name
Name of the codec implementation.
int av_isspace(int c)
Locale-independent conversion of ASCII isspace.
Definition: avstring.c:298
external API header
#define OFFSET(field)
Definition: dvdsubdec.c:589
uint32_t end_display_time
static int decode_run_8bit(GetBitContext *gb, int *color)
Definition: dvdsubdec.c:72
int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx)
Check if the given dimension of an image is valid, meaning that all bytes of the image can be address...
Definition: imgutils.c:231
A bitmap, pict will be set.
#define AV_SUBTITLE_FLAG_FORCED
FFT buffer for g
Definition: stft_peak.m:17
AVPicture pict
data+linesize for the bitmap of this subtitle.
#define FFMIN(a, b)
Definition: common.h:58
ret
Definition: avfilter.c:821
static void yuv_a_to_rgba(const uint8_t *ycbcr, const uint8_t *alpha, uint32_t *rgba, int num_values)
Definition: dvdsubdec.c:41
t
Definition: genspecsines3.m:6
static int is_transp(const uint8_t *buf, int pitch, int n, const uint8_t *transp_color)
Definition: dvdsubdec.c:390
int has_palette
Definition: dvdsubdec.c:36
FIXME Range Coding of cr are level
Definition: snow.txt:367
y2
Definition: lab5.m:34
LIBAVUTIL_VERSION_INT
Definition: eval.c:55
AVCodec ff_dvdsub_decoder
Definition: dvdsubdec.c:602
static void parse_palette(DVDSubContext *ctx, char *p)
Definition: dvdsubdec.c:520
NULL
Definition: eval.c:55
Close file fclose(fid)
FIXME Range Coding of cb
Definition: snow.txt:367
main external API structure.
static const AVOption options[]
Definition: dvdsubdec.c:591
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header, const uint8_t *buf, int buf_size)
Definition: dvdsubdec.c:190
void * buf
Definition: avisynth_c.h:594
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:273
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:73
Describe the class of an AVClass context structure.
Definition: log.h:50
x2
Definition: genspecsines3.m:8
synthesis window for stochastic i
#define YUV_TO_RGB2_CCIR(r, g, b, y1)
Definition: colorspace.h:44
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:379
static int decode_run_2bit(GetBitContext *gb, int *color)
Definition: dvdsubdec.c:58
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer 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.Buffer references ownership and permissions
static int find_smallest_bounding_rectangle(AVSubtitle *s)
Definition: dvdsubdec.c:403
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:162
static int dvdsub_parse_extradata(AVCodecContext *avctx)
Definition: dvdsubdec.c:532
uint32_t start_display_time
static void guess_palette(DVDSubContext *ctx, uint32_t *rgba_palette, uint32_t subtitle_color)
Definition: dvdsubdec.c:131
function y
Definition: D.m:1
DSP utils.
int len
static int dvdsub_decode(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
Definition: dvdsubdec.c:487
static const uint8_t * align_get_bits(GetBitContext *s)
Definition: get_bits.h:418
void INT64 start
Definition: avisynth_c.h:594
static int decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: crystalhd.c:868
static double cr(void *priv, double x, double y)
Definition: vf_geq.c:85
enum AVSubtitleType type
This structure stores compressed data.
static int dvdsub_init(AVCodecContext *avctx)
Definition: dvdsubdec.c:568
char * palette_str
Definition: dvdsubdec.c:35
static int decode_rle(uint8_t *bitmap, int linesize, int w, int h, const uint8_t *buf, int start, int buf_size, int is_8bit)
Definition: dvdsubdec.c:94