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