FFmpeg
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 
22 #include "avcodec.h"
23 #include "codec_internal.h"
24 #include "get_bits.h"
25 #include "internal.h"
26 
27 #include "libavutil/attributes.h"
28 #include "libavutil/colorspace.h"
29 #include "libavutil/opt.h"
30 #include "libavutil/imgutils.h"
31 #include "libavutil/bswap.h"
32 
33 typedef struct DVDSubContext
34 {
35  AVClass *class;
36  uint32_t palette[16];
37  char *palette_str;
38  char *ifo_str;
40  uint8_t colormap[4];
41  uint8_t alpha[256];
42  uint8_t buf[0x10000];
43  int buf_size;
45  uint8_t used_color[256];
47 
48 static void yuv_a_to_rgba(const uint8_t *ycbcr, const uint8_t *alpha, uint32_t *rgba, int num_values)
49 {
50  const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
51  uint8_t r, g, b;
52  int i, y, cb, cr;
53  int r_add, g_add, b_add;
54 
55  for (i = num_values; i > 0; i--) {
56  y = *ycbcr++;
57  cr = *ycbcr++;
58  cb = *ycbcr++;
60  YUV_TO_RGB2_CCIR(r, g, b, y);
61  *rgba++ = ((unsigned)*alpha++ << 24) | (r << 16) | (g << 8) | b;
62  }
63 }
64 
65 static int decode_run_2bit(GetBitContext *gb, int *color)
66 {
67  unsigned int v, t;
68 
69  v = 0;
70  for (t = 1; v < t && t <= 0x40; t <<= 2)
71  v = (v << 4) | get_bits(gb, 4);
72  *color = v & 3;
73  if (v < 4) { /* Code for fill rest of line */
74  return INT_MAX;
75  }
76  return v >> 2;
77 }
78 
79 static int decode_run_8bit(GetBitContext *gb, int *color)
80 {
81  int len;
82  int has_run = get_bits1(gb);
83  *color = get_bits(gb, 2 + 6*get_bits1(gb));
84  if (has_run) {
85  if (get_bits1(gb)) {
86  len = get_bits(gb, 7);
87  if (len == 0)
88  len = INT_MAX;
89  else
90  len += 9;
91  } else
92  len = get_bits(gb, 3) + 2;
93  } else
94  len = 1;
95  return len;
96 }
97 
98 static int decode_rle(uint8_t *bitmap, int linesize, int w, int h, uint8_t used_color[256],
99  const uint8_t *buf, int start, int buf_size, int is_8bit)
100 {
101  GetBitContext gb;
102  int bit_len;
103  int x, y, len, color;
104  uint8_t *d;
105 
106  if (start >= buf_size)
107  return -1;
108 
109  if (w <= 0 || h <= 0)
110  return -1;
111 
112  bit_len = (buf_size - start) * 8;
113  init_get_bits(&gb, buf + start, bit_len);
114 
115  x = 0;
116  y = 0;
117  d = bitmap;
118  for(;;) {
119  if (get_bits_count(&gb) > bit_len)
120  return -1;
121  if (is_8bit)
122  len = decode_run_8bit(&gb, &color);
123  else
124  len = decode_run_2bit(&gb, &color);
125  if (len != INT_MAX && len > w - x)
126  return AVERROR_INVALIDDATA;
127  len = FFMIN(len, w - x);
128  memset(d + x, color, len);
129  used_color[color] = 1;
130  x += len;
131  if (x >= w) {
132  y++;
133  if (y >= h)
134  break;
135  d += linesize;
136  x = 0;
137  /* byte align */
138  align_get_bits(&gb);
139  }
140  }
141  return 0;
142 }
143 
145  uint32_t *rgba_palette,
146  uint32_t subtitle_color)
147 {
148  static const uint8_t level_map[4][4] = {
149  // this configuration (full range, lowest to highest) in tests
150  // seemed most common, so assume this
151  {0xff},
152  {0x00, 0xff},
153  {0x00, 0x80, 0xff},
154  {0x00, 0x55, 0xaa, 0xff},
155  };
156  uint8_t color_used[16] = { 0 };
157  int nb_opaque_colors, i, level, j, r, g, b;
158  uint8_t *colormap = ctx->colormap, *alpha = ctx->alpha;
159 
160  if(ctx->has_palette) {
161  for(i = 0; i < 4; i++)
162  rgba_palette[i] = (ctx->palette[colormap[i]] & 0x00ffffff)
163  | ((alpha[i] * 17U) << 24);
164  return;
165  }
166 
167  for(i = 0; i < 4; i++)
168  rgba_palette[i] = 0;
169 
170  nb_opaque_colors = 0;
171  for(i = 0; i < 4; i++) {
172  if (alpha[i] != 0 && !color_used[colormap[i]]) {
173  color_used[colormap[i]] = 1;
174  nb_opaque_colors++;
175  }
176  }
177 
178  if (nb_opaque_colors == 0)
179  return;
180 
181  j = 0;
182  memset(color_used, 0, 16);
183  for(i = 0; i < 4; i++) {
184  if (alpha[i] != 0) {
185  if (!color_used[colormap[i]]) {
186  level = level_map[nb_opaque_colors - 1][j];
187  r = (((subtitle_color >> 16) & 0xff) * level) >> 8;
188  g = (((subtitle_color >> 8) & 0xff) * level) >> 8;
189  b = (((subtitle_color >> 0) & 0xff) * level) >> 8;
190  rgba_palette[i] = b | (g << 8) | (r << 16) | ((alpha[i] * 17U) << 24);
191  color_used[colormap[i]] = (i + 1);
192  j++;
193  } else {
194  rgba_palette[i] = (rgba_palette[color_used[colormap[i]] - 1] & 0x00ffffff) |
195  ((alpha[i] * 17U) << 24);
196  }
197  }
198  }
199 }
200 
201 static void reset_rects(AVSubtitle *sub_header)
202 {
203  int i;
204 
205  if (sub_header->rects) {
206  for (i = 0; i < sub_header->num_rects; i++) {
207  av_freep(&sub_header->rects[i]->data[0]);
208  av_freep(&sub_header->rects[i]->data[1]);
209  av_freep(&sub_header->rects[i]);
210  }
211  av_freep(&sub_header->rects);
212  sub_header->num_rects = 0;
213  }
214 }
215 
216 #define READ_OFFSET(a) (big_offsets ? AV_RB32(a) : AV_RB16(a))
217 
219  const uint8_t *buf, int buf_size)
220 {
221  int cmd_pos, pos, cmd, x1, y1, x2, y2, next_cmd_pos;
222  int big_offsets, offset_size, is_8bit = 0;
223  const uint8_t *yuv_palette = NULL;
224  uint8_t *colormap = ctx->colormap, *alpha = ctx->alpha;
225  int date;
226  int i;
227  int is_menu = 0;
228  uint32_t size;
229  int64_t offset1, offset2;
230 
231  if (buf_size < 10)
232  return -1;
233 
234  if (AV_RB16(buf) == 0) { /* HD subpicture with 4-byte offsets */
235  big_offsets = 1;
236  offset_size = 4;
237  cmd_pos = 6;
238  } else {
239  big_offsets = 0;
240  offset_size = 2;
241  cmd_pos = 2;
242  }
243 
244  size = READ_OFFSET(buf + (big_offsets ? 2 : 0));
245  cmd_pos = READ_OFFSET(buf + cmd_pos);
246 
247  if (cmd_pos < 0 || cmd_pos > buf_size - 2 - offset_size) {
248  if (cmd_pos > size) {
249  av_log(ctx, AV_LOG_ERROR, "Discarding invalid packet\n");
250  return 0;
251  }
252  return AVERROR(EAGAIN);
253  }
254 
255  while (cmd_pos > 0 && cmd_pos < buf_size - 2 - offset_size) {
256  date = AV_RB16(buf + cmd_pos);
257  next_cmd_pos = READ_OFFSET(buf + cmd_pos + 2);
258  ff_dlog(NULL, "cmd_pos=0x%04x next=0x%04x date=%d\n",
259  cmd_pos, next_cmd_pos, date);
260  pos = cmd_pos + 2 + offset_size;
261  offset1 = -1;
262  offset2 = -1;
263  x1 = y1 = x2 = y2 = 0;
264  while (pos < buf_size) {
265  cmd = buf[pos++];
266  ff_dlog(NULL, "cmd=%02x\n", cmd);
267  switch(cmd) {
268  case 0x00:
269  /* menu subpicture */
270  is_menu = 1;
271  break;
272  case 0x01:
273  /* set start date */
274  sub_header->start_display_time = (date << 10) / 90;
275  break;
276  case 0x02:
277  /* set end date */
278  sub_header->end_display_time = (date << 10) / 90;
279  break;
280  case 0x03:
281  /* set colormap */
282  if ((buf_size - pos) < 2)
283  goto fail;
284  colormap[3] = buf[pos] >> 4;
285  colormap[2] = buf[pos] & 0x0f;
286  colormap[1] = buf[pos + 1] >> 4;
287  colormap[0] = buf[pos + 1] & 0x0f;
288  pos += 2;
289  break;
290  case 0x04:
291  /* set alpha */
292  if ((buf_size - pos) < 2)
293  goto fail;
294  alpha[3] = buf[pos] >> 4;
295  alpha[2] = buf[pos] & 0x0f;
296  alpha[1] = buf[pos + 1] >> 4;
297  alpha[0] = buf[pos + 1] & 0x0f;
298  pos += 2;
299  ff_dlog(NULL, "alpha=%x%x%x%x\n", alpha[0],alpha[1],alpha[2],alpha[3]);
300  break;
301  case 0x05:
302  case 0x85:
303  if ((buf_size - pos) < 6)
304  goto fail;
305  x1 = (buf[pos] << 4) | (buf[pos + 1] >> 4);
306  x2 = ((buf[pos + 1] & 0x0f) << 8) | buf[pos + 2];
307  y1 = (buf[pos + 3] << 4) | (buf[pos + 4] >> 4);
308  y2 = ((buf[pos + 4] & 0x0f) << 8) | buf[pos + 5];
309  if (cmd & 0x80)
310  is_8bit = 1;
311  ff_dlog(NULL, "x1=%d x2=%d y1=%d y2=%d\n", x1, x2, y1, y2);
312  pos += 6;
313  break;
314  case 0x06:
315  if ((buf_size - pos) < 4)
316  goto fail;
317  offset1 = AV_RB16(buf + pos);
318  offset2 = AV_RB16(buf + pos + 2);
319  ff_dlog(NULL, "offset1=0x%04"PRIx64" offset2=0x%04"PRIx64"\n", offset1, offset2);
320  pos += 4;
321  break;
322  case 0x86:
323  if ((buf_size - pos) < 8)
324  goto fail;
325  offset1 = AV_RB32(buf + pos);
326  offset2 = AV_RB32(buf + pos + 4);
327  ff_dlog(NULL, "offset1=0x%04"PRIx64" offset2=0x%04"PRIx64"\n", offset1, offset2);
328  pos += 8;
329  break;
330 
331  case 0x83:
332  /* HD set palette */
333  if ((buf_size - pos) < 768)
334  goto fail;
335  yuv_palette = buf + pos;
336  pos += 768;
337  break;
338  case 0x84:
339  /* HD set contrast (alpha) */
340  if ((buf_size - pos) < 256)
341  goto fail;
342  for (i = 0; i < 256; i++)
343  alpha[i] = 0xFF - buf[pos+i];
344  pos += 256;
345  break;
346 
347  case 0xff:
348  goto the_end;
349  default:
350  ff_dlog(NULL, "unrecognised subpicture command 0x%x\n", cmd);
351  goto the_end;
352  }
353  }
354  the_end:
355  if (offset1 >= buf_size || offset2 >= buf_size)
356  goto fail;
357 
358  if (offset1 >= 0 && offset2 >= 0) {
359  int w, h;
360  uint8_t *bitmap;
361 
362  /* decode the bitmap */
363  w = x2 - x1 + 1;
364  if (w < 0)
365  w = 0;
366  h = y2 - y1 + 1;
367  if (h < 0)
368  h = 0;
369  if (w > 0 && h > 1) {
370  reset_rects(sub_header);
371  memset(ctx->used_color, 0, sizeof(ctx->used_color));
372  sub_header->rects = av_mallocz(sizeof(*sub_header->rects));
373  if (!sub_header->rects)
374  goto fail;
375  sub_header->rects[0] = av_mallocz(sizeof(AVSubtitleRect));
376  if (!sub_header->rects[0])
377  goto fail;
378  sub_header->num_rects = 1;
379  bitmap = sub_header->rects[0]->data[0] = av_malloc(w * h);
380  if (!bitmap)
381  goto fail;
382  if (decode_rle(bitmap, w * 2, w, (h + 1) / 2, ctx->used_color,
383  buf, offset1, buf_size, is_8bit) < 0)
384  goto fail;
385  if (decode_rle(bitmap + w, w * 2, w, h / 2, ctx->used_color,
386  buf, offset2, buf_size, is_8bit) < 0)
387  goto fail;
388  sub_header->rects[0]->data[1] = av_mallocz(AVPALETTE_SIZE);
389  if (!sub_header->rects[0]->data[1])
390  goto fail;
391  if (is_8bit) {
392  if (!yuv_palette)
393  goto fail;
394  sub_header->rects[0]->nb_colors = 256;
395  yuv_a_to_rgba(yuv_palette, alpha,
396  (uint32_t *)sub_header->rects[0]->data[1],
397  256);
398  } else {
399  sub_header->rects[0]->nb_colors = 4;
400  guess_palette(ctx, (uint32_t*)sub_header->rects[0]->data[1],
401  0xffffff);
402  }
403  sub_header->rects[0]->x = x1;
404  sub_header->rects[0]->y = y1;
405  sub_header->rects[0]->w = w;
406  sub_header->rects[0]->h = h;
407  sub_header->rects[0]->type = SUBTITLE_BITMAP;
408  sub_header->rects[0]->linesize[0] = w;
409  sub_header->rects[0]->flags = is_menu ? AV_SUBTITLE_FLAG_FORCED : 0;
410  }
411  }
412  if (next_cmd_pos < cmd_pos) {
413  av_log(ctx, AV_LOG_ERROR, "Invalid command offset\n");
414  break;
415  }
416  if (next_cmd_pos == cmd_pos)
417  break;
418  cmd_pos = next_cmd_pos;
419  }
420  if (sub_header->num_rects > 0)
421  return is_menu;
422  fail:
423  reset_rects(sub_header);
424  return -1;
425 }
426 
427 static int is_transp(const uint8_t *buf, int pitch, int n,
428  const uint8_t *transp_color)
429 {
430  int i;
431  for(i = 0; i < n; i++) {
432  if (!transp_color[*buf])
433  return 0;
434  buf += pitch;
435  }
436  return 1;
437 }
438 
439 /* return 0 if empty rectangle, 1 if non empty */
441 {
442  uint8_t transp_color[256] = { 0 };
443  int y1, y2, x1, x2, y, w, h, i;
444  uint8_t *bitmap;
445  int transparent = 1;
446 
447  if (s->num_rects == 0 || !s->rects || s->rects[0]->w <= 0 || s->rects[0]->h <= 0)
448  return 0;
449 
450  for(i = 0; i < s->rects[0]->nb_colors; i++) {
451  if ((((uint32_t *)s->rects[0]->data[1])[i] >> 24) == 0) {
452  transp_color[i] = 1;
453  } else if (ctx->used_color[i])
454  transparent = 0;
455  }
456  if (transparent)
457  return 0;
458  y1 = 0;
459  while (y1 < s->rects[0]->h && is_transp(s->rects[0]->data[0] + y1 * s->rects[0]->linesize[0],
460  1, s->rects[0]->w, transp_color))
461  y1++;
462  if (y1 == s->rects[0]->h) {
463  av_freep(&s->rects[0]->data[0]);
464  s->rects[0]->w = s->rects[0]->h = 0;
465  return 0;
466  }
467 
468  y2 = s->rects[0]->h - 1;
469  while (y2 > 0 && is_transp(s->rects[0]->data[0] + y2 * s->rects[0]->linesize[0], 1,
470  s->rects[0]->w, transp_color))
471  y2--;
472  x1 = 0;
473  while (x1 < (s->rects[0]->w - 1) && is_transp(s->rects[0]->data[0] + x1, s->rects[0]->linesize[0],
474  s->rects[0]->h, transp_color))
475  x1++;
476  x2 = s->rects[0]->w - 1;
477  while (x2 > 0 && is_transp(s->rects[0]->data[0] + x2, s->rects[0]->linesize[0], s->rects[0]->h,
478  transp_color))
479  x2--;
480  w = x2 - x1 + 1;
481  h = y2 - y1 + 1;
482  bitmap = av_malloc(w * h);
483  if (!bitmap)
484  return 1;
485  for(y = 0; y < h; y++) {
486  memcpy(bitmap + w * y, s->rects[0]->data[0] + x1 + (y1 + y) * s->rects[0]->linesize[0], w);
487  }
488  av_freep(&s->rects[0]->data[0]);
489  s->rects[0]->data[0] = bitmap;
490  s->rects[0]->linesize[0] = w;
491  s->rects[0]->w = w;
492  s->rects[0]->h = h;
493  s->rects[0]->x += x1;
494  s->rects[0]->y += y1;
495 
496  return 1;
497 }
498 
500  const uint8_t *buf, int buf_size)
501 {
502  DVDSubContext *ctx = avctx->priv_data;
503 
504  av_assert0(buf_size >= 0 && ctx->buf_size <= sizeof(ctx->buf));
505  if (buf_size >= sizeof(ctx->buf) - ctx->buf_size) {
506  av_log(avctx, AV_LOG_WARNING, "Attempt to reconstruct "
507  "too large SPU packets aborted.\n");
508  ctx->buf_size = 0;
509  return AVERROR_INVALIDDATA;
510  }
511  memcpy(ctx->buf + ctx->buf_size, buf, buf_size);
512  ctx->buf_size += buf_size;
513  return 0;
514 }
515 
517  int *data_size, const AVPacket *avpkt)
518 {
519  DVDSubContext *ctx = avctx->priv_data;
520  const uint8_t *buf = avpkt->data;
521  int buf_size = avpkt->size;
522  int appended = 0;
523  int is_menu;
524 
525  if (ctx->buf_size) {
526  int ret = append_to_cached_buf(avctx, buf, buf_size);
527  if (ret < 0) {
528  *data_size = 0;
529  return ret;
530  }
531  buf = ctx->buf;
532  buf_size = ctx->buf_size;
533  appended = 1;
534  }
535 
536  is_menu = decode_dvd_subtitles(ctx, sub, buf, buf_size);
537  if (is_menu == AVERROR(EAGAIN)) {
538  *data_size = 0;
539  return appended ? 0 : append_to_cached_buf(avctx, buf, buf_size);
540  }
541 
542  if (is_menu < 0) {
543  ctx->buf_size = 0;
544  no_subtitle:
545  reset_rects(sub);
546  *data_size = 0;
547 
548  return buf_size;
549  }
550  if (!is_menu && find_smallest_bounding_rectangle(ctx, sub) == 0)
551  goto no_subtitle;
552 
553  if (ctx->forced_subs_only && !(sub->rects[0]->flags & AV_SUBTITLE_FLAG_FORCED))
554  goto no_subtitle;
555 
556  ctx->buf_size = 0;
557  *data_size = 1;
558  return buf_size;
559 }
560 
561 static int parse_ifo_palette(DVDSubContext *ctx, char *p)
562 {
563  FILE *ifo;
564  char ifostr[12];
565  uint32_t sp_pgci, pgci, off_pgc, pgc;
566  uint8_t r, g, b, yuv[65], *buf;
567  int i, y, cb, cr, r_add, g_add, b_add;
568  int ret = 0;
569  const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
570 
571  ctx->has_palette = 0;
572  if ((ifo = avpriv_fopen_utf8(p, "r")) == NULL) {
573  av_log(ctx, AV_LOG_WARNING, "Unable to open IFO file \"%s\": %s\n", p, av_err2str(AVERROR(errno)));
574  return AVERROR_EOF;
575  }
576  if (fread(ifostr, 12, 1, ifo) != 1 || memcmp(ifostr, "DVDVIDEO-VTS", 12)) {
577  av_log(ctx, AV_LOG_WARNING, "\"%s\" is not a proper IFO file\n", p);
579  goto end;
580  }
581  if (fseek(ifo, 0xCC, SEEK_SET) == -1) {
582  ret = AVERROR(errno);
583  goto end;
584  }
585  if (fread(&sp_pgci, 4, 1, ifo) == 1) {
586  pgci = av_be2ne32(sp_pgci) * 2048;
587  if (fseek(ifo, pgci + 0x0C, SEEK_SET) == -1) {
588  ret = AVERROR(errno);
589  goto end;
590  }
591  if (fread(&off_pgc, 4, 1, ifo) == 1) {
592  pgc = pgci + av_be2ne32(off_pgc);
593  if (fseek(ifo, pgc + 0xA4, SEEK_SET) == -1) {
594  ret = AVERROR(errno);
595  goto end;
596  }
597  if (fread(yuv, 64, 1, ifo) == 1) {
598  buf = yuv;
599  for(i=0; i<16; i++) {
600  y = *++buf;
601  cr = *++buf;
602  cb = *++buf;
604  YUV_TO_RGB2_CCIR(r, g, b, y);
605  ctx->palette[i] = (r << 16) + (g << 8) + b;
606  buf++;
607  }
608  ctx->has_palette = 1;
609  }
610  }
611  }
612  if (ctx->has_palette == 0) {
613  av_log(ctx, AV_LOG_WARNING, "Failed to read palette from IFO file \"%s\"\n", p);
615  }
616 end:
617  fclose(ifo);
618  return ret;
619 }
620 
622 {
624  char *dataorig, *data;
625  int ret = 1;
626 
627  if (!avctx->extradata || !avctx->extradata_size)
628  return 1;
629 
630  dataorig = data = av_malloc(avctx->extradata_size+1);
631  if (!data)
632  return AVERROR(ENOMEM);
633  memcpy(data, avctx->extradata, avctx->extradata_size);
634  data[avctx->extradata_size] = '\0';
635 
636  for(;;) {
637  int pos = strcspn(data, "\n\r");
638  if (pos==0 && *data==0)
639  break;
640 
641  if (strncmp("palette:", data, 8) == 0) {
642  ctx->has_palette = 1;
643  ff_dvdsub_parse_palette(ctx->palette, data + 8);
644  } else if (strncmp("size:", data, 5) == 0) {
645  int w, h;
646  if (sscanf(data + 5, "%dx%d", &w, &h) == 2) {
647  ret = ff_set_dimensions(avctx, w, h);
648  if (ret < 0)
649  goto fail;
650  }
651  }
652 
653  data += pos;
654  data += strspn(data, "\n\r");
655  }
656 
657 fail:
658  av_free(dataorig);
659  return ret;
660 }
661 
663 {
664  DVDSubContext *ctx = avctx->priv_data;
665  int ret;
666 
667  if ((ret = dvdsub_parse_extradata(avctx)) < 0)
668  return ret;
669 
670  if (ctx->ifo_str)
671  parse_ifo_palette(ctx, ctx->ifo_str);
672  if (ctx->palette_str) {
673  ctx->has_palette = 1;
674  ff_dvdsub_parse_palette(ctx->palette, ctx->palette_str);
675  }
676  if (ctx->has_palette) {
677  int i;
678  av_log(avctx, AV_LOG_DEBUG, "palette:");
679  for(i=0;i<16;i++)
680  av_log(avctx, AV_LOG_DEBUG, " 0x%06"PRIx32, ctx->palette[i]);
681  av_log(avctx, AV_LOG_DEBUG, "\n");
682  }
683 
684  return 1;
685 }
686 
687 static void dvdsub_flush(AVCodecContext *avctx)
688 {
689  DVDSubContext *ctx = avctx->priv_data;
690  ctx->buf_size = 0;
691 }
692 
693 #define OFFSET(field) offsetof(DVDSubContext, field)
694 #define SD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM
695 static const AVOption options[] = {
696  { "palette", "set the global palette", OFFSET(palette_str), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, SD },
697  { "ifo_palette", "obtain the global palette from .IFO file", OFFSET(ifo_str), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, SD },
698  { "forced_subs_only", "Only show forced subtitles", OFFSET(forced_subs_only), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, SD},
699  { NULL }
700 };
701 static const AVClass dvdsub_class = {
702  .class_name = "dvdsubdec",
703  .item_name = av_default_item_name,
704  .option = options,
705  .version = LIBAVUTIL_VERSION_INT,
706 };
707 
709  .p.name = "dvdsub",
710  .p.long_name = NULL_IF_CONFIG_SMALL("DVD subtitles"),
711  .p.type = AVMEDIA_TYPE_SUBTITLE,
712  .p.id = AV_CODEC_ID_DVD_SUBTITLE,
713  .priv_data_size = sizeof(DVDSubContext),
714  .init = dvdsub_init,
716  .flush = dvdsub_flush,
717  .p.priv_class = &dvdsub_class,
718  .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
719 };
AVSubtitle
Definition: avcodec.h:2305
options
static const AVOption options[]
Definition: dvdsubdec.c:695
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:204
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
level
uint8_t level
Definition: svq3.c:206
r
const char * r
Definition: vf_curves.c:116
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:2310
opt.h
color
Definition: vf_paletteuse.c:600
cb
static double cb(void *priv, double x, double y)
Definition: vf_geq.c:239
sub
static float sub(float src0, float src1)
Definition: dnn_backend_native_layer_mathbinary.c:31
READ_OFFSET
#define READ_OFFSET(a)
Definition: dvdsubdec.c:216
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
dvdsub_init
static av_cold int dvdsub_init(AVCodecContext *avctx)
Definition: dvdsubdec.c:662
reset_rects
static void reset_rects(AVSubtitle *sub_header)
Definition: dvdsubdec.c:201
ff_dvdsub_parse_palette
void ff_dvdsub_parse_palette(uint32_t *palette, const char *p)
Definition: dvdsub.c:26
AVSubtitleRect
Definition: avcodec.h:2277
DVDSubContext::palette_str
char * palette_str
Definition: dvdsubdec.c:37
AVSubtitle::num_rects
unsigned num_rects
Definition: avcodec.h:2309
dvdsub_flush
static void dvdsub_flush(AVCodecContext *avctx)
Definition: dvdsubdec.c:687
get_bits_count
static int get_bits_count(const GetBitContext *s)
Definition: get_bits.h:219
w
uint8_t w
Definition: llviddspenc.c:38
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:374
AVOption
AVOption.
Definition: opt.h:251
DVDSubContext::ifo_str
char * ifo_str
Definition: dvdsubdec.c:38
b
#define b
Definition: input.c:34
data
const char data[16]
Definition: mxf.c:143
DVDSubContext::forced_subs_only
int forced_subs_only
Definition: dvdsubdec.c:44
SD
#define SD
Definition: dvdsubdec.c:694
FFCodec
Definition: codec_internal.h:112
DVDSubContext::palette
uint32_t palette[16]
Definition: dvdsubdec.c:36
AVSubtitleRect::linesize
int linesize[4]
Definition: avcodec.h:2289
YUV_TO_RGB1_CCIR
#define YUV_TO_RGB1_CCIR(cb1, cr1)
Definition: colorspace.h:34
init_get_bits
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:649
ff_crop_tab
#define ff_crop_tab
Definition: motionpixels_tablegen.c:26
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
init
static int init
Definition: av_tx.c:47
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:379
dvdsub_parse_extradata
static int dvdsub_parse_extradata(AVCodecContext *avctx)
Definition: dvdsubdec.c:621
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:116
U
#define U(x)
Definition: vp56_arith.h:37
fail
#define fail()
Definition: checkasm.h:131
dvdsub_decode
static int dvdsub_decode(AVCodecContext *avctx, AVSubtitle *sub, int *data_size, const AVPacket *avpkt)
Definition: dvdsubdec.c:516
GetBitContext
Definition: get_bits.h:61
AVSubtitleRect::x
int x
top left corner of pict, undefined when pict is not set
Definition: avcodec.h:2278
find_smallest_bounding_rectangle
static int find_smallest_bounding_rectangle(DVDSubContext *ctx, AVSubtitle *s)
Definition: dvdsubdec.c:440
append_to_cached_buf
static int append_to_cached_buf(AVCodecContext *avctx, const uint8_t *buf, int buf_size)
Definition: dvdsubdec.c:499
colorspace.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:491
s
#define s(width, name)
Definition: cbs_vp9.c:256
g
const char * g
Definition: vf_curves.c:117
AVSubtitleRect::y
int y
top left corner of pict, undefined when pict is not set
Definition: avcodec.h:2279
DVDSubContext::buf
uint8_t buf[0x10000]
Definition: dvdsubdec.c:42
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
ctx
AVFormatContext * ctx
Definition: movenc.c:48
get_bits.h
if
if(ret)
Definition: filter_design.txt:179
av_be2ne32
#define av_be2ne32(x)
Definition: bswap.h:93
AVSubtitleRect::w
int w
width of pict, undefined when pict is not set
Definition: avcodec.h:2280
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
DVDSubContext
Definition: dvdsubdec.c:33
NULL
#define NULL
Definition: coverity.c:32
AVPALETTE_SIZE
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
AV_CODEC_ID_DVD_SUBTITLE
@ AV_CODEC_ID_DVD_SUBTITLE
Definition: codec_id.h:527
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
get_bits1
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:498
AVSubtitleRect::data
uint8_t * data[4]
data+linesize for the bitmap of this subtitle.
Definition: avcodec.h:2288
YUV_TO_RGB2_CCIR
#define YUV_TO_RGB2_CCIR(r, g, b, y1)
Definition: colorspace.h:55
decode_run_2bit
static int decode_run_2bit(GetBitContext *gb, int *color)
Definition: dvdsubdec.c:65
ff_dlog
#define ff_dlog(a,...)
Definition: tableprint_vlc.h:28
DVDSubContext::used_color
uint8_t used_color[256]
Definition: dvdsubdec.c:45
AVPacket::size
int size
Definition: packet.h:375
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
codec_internal.h
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:121
size
int size
Definition: twinvq_data.h:10344
color
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
Definition: log.c:94
AV_RB32
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_RB32
Definition: bytestream.h:96
AVSubtitle::end_display_time
uint32_t end_display_time
Definition: avcodec.h:2308
AVSubtitleRect::type
enum AVSubtitleType type
Definition: avcodec.h:2291
dvdsub_class
static const AVClass dvdsub_class
Definition: dvdsubdec.c:701
decode_rle
static int decode_rle(uint8_t *bitmap, int linesize, int w, int h, uint8_t used_color[256], const uint8_t *buf, int start, int buf_size, int is_8bit)
Definition: dvdsubdec.c:98
attributes.h
AV_SUBTITLE_FLAG_FORCED
#define AV_SUBTITLE_FLAG_FORCED
Definition: avcodec.h:2275
SUBTITLE_BITMAP
@ SUBTITLE_BITMAP
A bitmap, pict will be set.
Definition: avcodec.h:2260
decode_dvd_subtitles
static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header, const uint8_t *buf, int buf_size)
Definition: dvdsubdec.c:218
AVSubtitleRect::flags
int flags
Definition: avcodec.h:2302
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
AVCodecContext::extradata
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:490
AVSubtitleRect::nb_colors
int nb_colors
number of colors in pict, undefined when pict is not set
Definition: avcodec.h:2282
parse_ifo_palette
static int parse_ifo_palette(DVDSubContext *ctx, char *p)
Definition: dvdsubdec.c:561
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
FF_CODEC_CAP_INIT_THREADSAFE
#define FF_CODEC_CAP_INIT_THREADSAFE
The codec does not modify any global variables in the init function, allowing to call the init functi...
Definition: codec_internal.h:31
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:264
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:203
ff_dvdsub_decoder
const FFCodec ff_dvdsub_decoder
Definition: dvdsubdec.c:708
len
int len
Definition: vorbis_enc_data.h:426
avpriv_fopen_utf8
FILE * avpriv_fopen_utf8(const char *path, const char *mode)
Open a file using a UTF-8 filename.
Definition: file_open.c:158
avcodec.h
ret
ret
Definition: filter_design.txt:187
bswap.h
AVSubtitleRect::h
int h
height of pict, undefined when pict is not set
Definition: avcodec.h:2281
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:71
is_transp
static int is_transp(const uint8_t *buf, int pitch, int n, const uint8_t *transp_color)
Definition: dvdsubdec.c:427
align_get_bits
static const uint8_t * align_get_bits(GetBitContext *s)
Definition: get_bits.h:683
pos
unsigned int pos
Definition: spdifenc.c:412
AVCodecContext
main external API structure.
Definition: avcodec.h:389
DVDSubContext::has_palette
int has_palette
Definition: dvdsubdec.c:39
cm
#define cm
Definition: dvbsubdec.c:39
FF_CODEC_DECODE_SUB_CB
#define FF_CODEC_DECODE_SUB_CB(func)
Definition: codec_internal.h:257
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:90
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
DVDSubContext::colormap
uint8_t colormap[4]
Definition: dvdsubdec.c:40
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
OFFSET
#define OFFSET(field)
Definition: dvdsubdec.c:693
AVPacket
This structure stores compressed data.
Definition: packet.h:351
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:416
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:244
cr
static double cr(void *priv, double x, double y)
Definition: vf_geq.c:240
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
d
d
Definition: ffmpeg_filter.c:153
imgutils.h
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
h
h
Definition: vp9dsp_template.c:2038
DVDSubContext::buf_size
int buf_size
Definition: dvdsubdec.c:43
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:229
MAX_NEG_CROP
#define MAX_NEG_CROP
Definition: mathops.h:30
yuv_a_to_rgba
static void yuv_a_to_rgba(const uint8_t *ycbcr, const uint8_t *alpha, uint32_t *rgba, int num_values)
Definition: dvdsubdec.c:48
DVDSubContext::alpha
uint8_t alpha[256]
Definition: dvdsubdec.c:41
AVSubtitle::start_display_time
uint32_t start_display_time
Definition: avcodec.h:2307
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
guess_palette
static void guess_palette(DVDSubContext *ctx, uint32_t *rgba_palette, uint32_t subtitle_color)
Definition: dvdsubdec.c:144
decode_run_8bit
static int decode_run_8bit(GetBitContext *gb, int *color)
Definition: dvdsubdec.c:79