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