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 "get_bits.h"
24 #include "internal.h"
25 
26 #include "libavutil/attributes.h"
27 #include "libavutil/colorspace.h"
28 #include "libavutil/opt.h"
29 #include "libavutil/imgutils.h"
30 #include "libavutil/bswap.h"
31 
32 typedef struct DVDSubContext
33 {
34  AVClass *class;
35  uint32_t palette[16];
36  char *palette_str;
37  char *ifo_str;
39  uint8_t colormap[4];
40  uint8_t alpha[256];
41  uint8_t buf[0x10000];
42  int buf_size;
44  uint8_t used_color[256];
45 #ifdef DEBUG
46  int sub_id;
47 #endif
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  0xffff00);
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 
501 #ifdef DEBUG
502 #define ALPHA_MIX(A,BACK,FORE) (((255-(A)) * (BACK) + (A) * (FORE)) / 255)
503 static void ppm_save(const char *filename, uint8_t *bitmap, int w, int h,
504  uint32_t *rgba_palette)
505 {
506  int x, y, alpha;
507  uint32_t v;
508  int back[3] = {0, 255, 0}; /* green background */
509  FILE *f;
510 
511  f = fopen(filename, "w");
512  if (!f) {
513  perror(filename);
514  return;
515  }
516  fprintf(f, "P6\n"
517  "%d %d\n"
518  "%d\n",
519  w, h, 255);
520  for(y = 0; y < h; y++) {
521  for(x = 0; x < w; x++) {
522  v = rgba_palette[bitmap[y * w + x]];
523  alpha = v >> 24;
524  putc(ALPHA_MIX(alpha, back[0], (v >> 16) & 0xff), f);
525  putc(ALPHA_MIX(alpha, back[1], (v >> 8) & 0xff), f);
526  putc(ALPHA_MIX(alpha, back[2], (v >> 0) & 0xff), f);
527  }
528  }
529  fclose(f);
530 }
531 #endif
532 
534  const uint8_t *buf, int buf_size)
535 {
536  DVDSubContext *ctx = avctx->priv_data;
537 
538  av_assert0(buf_size >= 0 && ctx->buf_size <= sizeof(ctx->buf));
539  if (buf_size >= sizeof(ctx->buf) - ctx->buf_size) {
540  av_log(avctx, AV_LOG_WARNING, "Attempt to reconstruct "
541  "too large SPU packets aborted.\n");
542  ctx->buf_size = 0;
543  return AVERROR_INVALIDDATA;
544  }
545  memcpy(ctx->buf + ctx->buf_size, buf, buf_size);
546  ctx->buf_size += buf_size;
547  return 0;
548 }
549 
550 static int dvdsub_decode(AVCodecContext *avctx,
551  void *data, int *data_size,
552  AVPacket *avpkt)
553 {
554  DVDSubContext *ctx = avctx->priv_data;
555  const uint8_t *buf = avpkt->data;
556  int buf_size = avpkt->size;
557  AVSubtitle *sub = data;
558  int appended = 0;
559  int is_menu;
560 
561  if (ctx->buf_size) {
562  int ret = append_to_cached_buf(avctx, buf, buf_size);
563  if (ret < 0) {
564  *data_size = 0;
565  return ret;
566  }
567  buf = ctx->buf;
568  buf_size = ctx->buf_size;
569  appended = 1;
570  }
571 
572  is_menu = decode_dvd_subtitles(ctx, sub, buf, buf_size);
573  if (is_menu == AVERROR(EAGAIN)) {
574  *data_size = 0;
575  return appended ? 0 : append_to_cached_buf(avctx, buf, buf_size);
576  }
577 
578  if (is_menu < 0) {
579  ctx->buf_size = 0;
580  no_subtitle:
581  reset_rects(sub);
582  *data_size = 0;
583 
584  return buf_size;
585  }
586  if (!is_menu && find_smallest_bounding_rectangle(ctx, sub) == 0)
587  goto no_subtitle;
588 
589  if (ctx->forced_subs_only && !(sub->rects[0]->flags & AV_SUBTITLE_FLAG_FORCED))
590  goto no_subtitle;
591 
592 #if defined(DEBUG)
593  {
594  char ppm_name[32];
595 
596  snprintf(ppm_name, sizeof(ppm_name), "/tmp/%05d.ppm", ctx->sub_id++);
597  ff_dlog(NULL, "start=%d ms end =%d ms\n",
598  sub->start_display_time,
599  sub->end_display_time);
600  ppm_save(ppm_name, sub->rects[0]->data[0],
601  sub->rects[0]->w, sub->rects[0]->h, (uint32_t*) sub->rects[0]->data[1]);
602  }
603 #endif
604 
605  ctx->buf_size = 0;
606  *data_size = 1;
607  return buf_size;
608 }
609 
610 static int parse_ifo_palette(DVDSubContext *ctx, char *p)
611 {
612  FILE *ifo;
613  char ifostr[12];
614  uint32_t sp_pgci, pgci, off_pgc, pgc;
615  uint8_t r, g, b, yuv[65], *buf;
616  int i, y, cb, cr, r_add, g_add, b_add;
617  int ret = 0;
618  const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
619 
620  ctx->has_palette = 0;
621  if ((ifo = fopen(p, "r")) == NULL) {
622  av_log(ctx, AV_LOG_WARNING, "Unable to open IFO file \"%s\": %s\n", p, av_err2str(AVERROR(errno)));
623  return AVERROR_EOF;
624  }
625  if (fread(ifostr, 12, 1, ifo) != 1 || memcmp(ifostr, "DVDVIDEO-VTS", 12)) {
626  av_log(ctx, AV_LOG_WARNING, "\"%s\" is not a proper IFO file\n", p);
628  goto end;
629  }
630  if (fseek(ifo, 0xCC, SEEK_SET) == -1) {
631  ret = AVERROR(errno);
632  goto end;
633  }
634  if (fread(&sp_pgci, 4, 1, ifo) == 1) {
635  pgci = av_be2ne32(sp_pgci) * 2048;
636  if (fseek(ifo, pgci + 0x0C, SEEK_SET) == -1) {
637  ret = AVERROR(errno);
638  goto end;
639  }
640  if (fread(&off_pgc, 4, 1, ifo) == 1) {
641  pgc = pgci + av_be2ne32(off_pgc);
642  if (fseek(ifo, pgc + 0xA4, SEEK_SET) == -1) {
643  ret = AVERROR(errno);
644  goto end;
645  }
646  if (fread(yuv, 64, 1, ifo) == 1) {
647  buf = yuv;
648  for(i=0; i<16; i++) {
649  y = *++buf;
650  cr = *++buf;
651  cb = *++buf;
653  YUV_TO_RGB2_CCIR(r, g, b, y);
654  ctx->palette[i] = (r << 16) + (g << 8) + b;
655  buf++;
656  }
657  ctx->has_palette = 1;
658  }
659  }
660  }
661  if (ctx->has_palette == 0) {
662  av_log(ctx, AV_LOG_WARNING, "Failed to read palette from IFO file \"%s\"\n", p);
664  }
665 end:
666  fclose(ifo);
667  return ret;
668 }
669 
671 {
673  char *dataorig, *data;
674  int ret = 1;
675 
676  if (!avctx->extradata || !avctx->extradata_size)
677  return 1;
678 
679  dataorig = data = av_malloc(avctx->extradata_size+1);
680  if (!data)
681  return AVERROR(ENOMEM);
682  memcpy(data, avctx->extradata, avctx->extradata_size);
683  data[avctx->extradata_size] = '\0';
684 
685  for(;;) {
686  int pos = strcspn(data, "\n\r");
687  if (pos==0 && *data==0)
688  break;
689 
690  if (strncmp("palette:", data, 8) == 0) {
691  ctx->has_palette = 1;
692  ff_dvdsub_parse_palette(ctx->palette, data + 8);
693  } else if (strncmp("size:", data, 5) == 0) {
694  int w, h;
695  if (sscanf(data + 5, "%dx%d", &w, &h) == 2) {
696  ret = ff_set_dimensions(avctx, w, h);
697  if (ret < 0)
698  goto fail;
699  }
700  }
701 
702  data += pos;
703  data += strspn(data, "\n\r");
704  }
705 
706 fail:
707  av_free(dataorig);
708  return ret;
709 }
710 
712 {
713  DVDSubContext *ctx = avctx->priv_data;
714  int ret;
715 
716  if ((ret = dvdsub_parse_extradata(avctx)) < 0)
717  return ret;
718 
719  if (ctx->ifo_str)
720  parse_ifo_palette(ctx, ctx->ifo_str);
721  if (ctx->palette_str) {
722  ctx->has_palette = 1;
723  ff_dvdsub_parse_palette(ctx->palette, ctx->palette_str);
724  }
725  if (ctx->has_palette) {
726  int i;
727  av_log(avctx, AV_LOG_DEBUG, "palette:");
728  for(i=0;i<16;i++)
729  av_log(avctx, AV_LOG_DEBUG, " 0x%06"PRIx32, ctx->palette[i]);
730  av_log(avctx, AV_LOG_DEBUG, "\n");
731  }
732 
733  return 1;
734 }
735 
736 static void dvdsub_flush(AVCodecContext *avctx)
737 {
738  DVDSubContext *ctx = avctx->priv_data;
739  ctx->buf_size = 0;
740 }
741 
742 #define OFFSET(field) offsetof(DVDSubContext, field)
743 #define SD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM
744 static const AVOption options[] = {
745  { "palette", "set the global palette", OFFSET(palette_str), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, SD },
746  { "ifo_palette", "obtain the global palette from .IFO file", OFFSET(ifo_str), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, SD },
747  { "forced_subs_only", "Only show forced subtitles", OFFSET(forced_subs_only), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, SD},
748  { NULL }
749 };
750 static const AVClass dvdsub_class = {
751  .class_name = "dvdsubdec",
752  .item_name = av_default_item_name,
753  .option = options,
754  .version = LIBAVUTIL_VERSION_INT,
755 };
756 
758  .name = "dvdsub",
759  .long_name = NULL_IF_CONFIG_SMALL("DVD subtitles"),
760  .type = AVMEDIA_TYPE_SUBTITLE,
762  .priv_data_size = sizeof(DVDSubContext),
763  .init = dvdsub_init,
765  .flush = dvdsub_flush,
766  .priv_class = &dvdsub_class,
767  .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
768 };
AVSubtitle
Definition: avcodec.h:2289
options
static const AVOption options[]
Definition: dvdsubdec.c:744
AVCodec
AVCodec.
Definition: codec.h:202
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
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: internal.h:42
level
uint8_t level
Definition: svq3.c:204
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:2294
opt.h
color
Definition: vf_paletteuse.c:599
cb
static double cb(void *priv, double x, double y)
Definition: vf_geq.c:215
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: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:711
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:26
AVSubtitleRect
Definition: avcodec.h:2261
DVDSubContext::palette_str
char * palette_str
Definition: dvdsubdec.c:36
AVSubtitle::num_rects
unsigned num_rects
Definition: avcodec.h:2293
dvdsub_flush
static void dvdsub_flush(AVCodecContext *avctx)
Definition: dvdsubdec.c:736
get_bits_count
static int get_bits_count(const GetBitContext *s)
Definition: get_bits.h:220
w
uint8_t w
Definition: llviddspenc.c:38
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:373
AVOption
AVOption.
Definition: opt.h:247
DVDSubContext::ifo_str
char * ifo_str
Definition: dvdsubdec.c:37
b
#define b
Definition: input.c:40
data
const char data[16]
Definition: mxf.c:143
DVDSubContext::forced_subs_only
int forced_subs_only
Definition: dvdsubdec.c:43
SD
#define SD
Definition: dvdsubdec.c:743
DVDSubContext::palette
uint32_t palette[16]
Definition: dvdsubdec.c:35
AVSubtitleRect::linesize
int linesize[4]
Definition: avcodec.h:2273
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:660
ff_crop_tab
#define ff_crop_tab
Definition: motionpixels_tablegen.c:26
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
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:380
dvdsub_parse_extradata
static int dvdsub_parse_extradata(AVCodecContext *avctx)
Definition: dvdsubdec.c:670
U
#define U(x)
Definition: vp56_arith.h:37
fail
#define fail()
Definition: checkasm.h:127
GetBitContext
Definition: get_bits.h:62
AVSubtitleRect::x
int x
top left corner of pict, undefined when pict is not set
Definition: avcodec.h:2262
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:533
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
decode
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:485
s
#define s(width, name)
Definition: cbs_vp9.c:257
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:2263
DVDSubContext::buf
uint8_t buf[0x10000]
Definition: dvdsubdec.c:41
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
f
#define f(width, name)
Definition: cbs_vp9.c:255
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:2264
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:32
flush
static void flush(AVCodecContext *avctx)
Definition: aacdec_template.c:593
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:522
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
get_bits1
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:499
AVSubtitleRect::data
uint8_t * data[4]
data+linesize for the bitmap of this subtitle.
Definition: avcodec.h:2272
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:29
DVDSubContext::used_color
uint8_t used_color[256]
Definition: dvdsubdec.c:44
AVPacket::size
int size
Definition: packet.h:374
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
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:92
ff_dvdsub_decoder
const AVCodec ff_dvdsub_decoder
Definition: dvdsubdec.c:757
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:2292
AVSubtitleRect::type
enum AVSubtitleType type
Definition: avcodec.h:2275
dvdsub_class
static const AVClass dvdsub_class
Definition: dvdsubdec.c:750
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:2259
SUBTITLE_BITMAP
@ SUBTITLE_BITMAP
A bitmap, pict will be set.
Definition: avcodec.h:2244
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:2286
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
AVCodecContext::extradata
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:484
AVSubtitleRect::nb_colors
int nb_colors
number of colors in pict, undefined when pict is not set
Definition: avcodec.h:2266
parse_ifo_palette
static int parse_ifo_palette(DVDSubContext *ctx, char *p)
Definition: dvdsubdec.c:610
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:263
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:209
len
int len
Definition: vorbis_enc_data.h:426
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:2265
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:694
pos
unsigned int pos
Definition: spdifenc.c:412
AVCodecContext
main external API structure.
Definition: avcodec.h:383
DVDSubContext::has_palette
int has_palette
Definition: dvdsubdec.c:38
cm
#define cm
Definition: dvbsubdec.c:38
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:86
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
DVDSubContext::colormap
uint8_t colormap[4]
Definition: dvdsubdec.c:39
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
OFFSET
#define OFFSET(field)
Definition: dvdsubdec.c:742
AVPacket
This structure stores compressed data.
Definition: packet.h:350
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:410
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:241
cr
static double cr(void *priv, double x, double y)
Definition: vf_geq.c:216
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
d
d
Definition: ffmpeg_filter.c:153
imgutils.h
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
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:42
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:228
MAX_NEG_CROP
#define MAX_NEG_CROP
Definition: mathops.h:31
dvdsub_decode
static int dvdsub_decode(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
Definition: dvdsubdec.c:550
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
snprintf
#define snprintf
Definition: snprintf.h:34
DVDSubContext::alpha
uint8_t alpha[256]
Definition: dvdsubdec.c:40
AVSubtitle::start_display_time
uint32_t start_display_time
Definition: avcodec.h:2291
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