FFmpeg
dvdsubenc.c
Go to the documentation of this file.
1 /*
2  * DVD subtitle encoding
3  * Copyright (c) 2005 Wolfram Gloger
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 #include "avcodec.h"
22 #include "bytestream.h"
23 #include "codec_internal.h"
24 #include "dvdsub.h"
25 #include "libavutil/avassert.h"
26 #include "libavutil/bprint.h"
27 #include "libavutil/imgutils.h"
28 #include "libavutil/opt.h"
29 
30 typedef struct {
31  AVClass *class;
32  uint32_t global_palette[16];
33  char *palette_str;
36 
37 // ncnt is the nibble counter
38 #define PUTNIBBLE(val)\
39 do {\
40  if (ncnt++ & 1)\
41  *q++ = bitbuf | ((val) & 0x0f);\
42  else\
43  bitbuf = (val) << 4;\
44 } while(0)
45 
46 static void dvd_encode_rle(uint8_t **pq,
47  const uint8_t *bitmap, int linesize,
48  int w, int h,
49  const int cmap[256])
50 {
51  uint8_t *q;
52  unsigned int bitbuf = 0;
53  int ncnt;
54  int x, y, len, color;
55 
56  q = *pq;
57 
58  for (y = 0; y < h; ++y) {
59  ncnt = 0;
60  for(x = 0; x < w; x += len) {
61  color = bitmap[x];
62  for (len=1; x+len < w; ++len)
63  if (bitmap[x+len] != color)
64  break;
65  color = cmap[color];
66  av_assert0(color < 4);
67  if (len < 0x04) {
68  PUTNIBBLE((len << 2)|color);
69  } else if (len < 0x10) {
70  PUTNIBBLE(len >> 2);
71  PUTNIBBLE((len << 2)|color);
72  } else if (len < 0x40) {
73  PUTNIBBLE(0);
74  PUTNIBBLE(len >> 2);
75  PUTNIBBLE((len << 2)|color);
76  } else if (x+len == w) {
77  PUTNIBBLE(0);
78  PUTNIBBLE(0);
79  PUTNIBBLE(0);
81  } else {
82  if (len > 0xff)
83  len = 0xff;
84  PUTNIBBLE(0);
85  PUTNIBBLE(len >> 6);
86  PUTNIBBLE(len >> 2);
87  PUTNIBBLE((len << 2)|color);
88  }
89  }
90  /* end of line */
91  if (ncnt & 1)
92  PUTNIBBLE(0);
93  bitmap += linesize;
94  }
95 
96  *pq = q;
97 }
98 
99 static int color_distance(uint32_t a, uint32_t b)
100 {
101  int r = 0, d, i;
102  int alpha_a = 8, alpha_b = 8;
103 
104  for (i = 24; i >= 0; i -= 8) {
105  d = alpha_a * (int)((a >> i) & 0xFF) -
106  alpha_b * (int)((b >> i) & 0xFF);
107  r += d * d;
108  alpha_a = a >> 28;
109  alpha_b = b >> 28;
110  }
111  return r;
112 }
113 
114 /**
115  * Count colors used in a rectangle, quantizing alpha and grouping by
116  * nearest global palette entry.
117  */
118 static void count_colors(AVCodecContext *avctx, unsigned hits[33],
119  const AVSubtitleRect *r)
120 {
121  DVDSubtitleContext *dvdc = avctx->priv_data;
122  unsigned count[256] = { 0 };
123  uint32_t *palette = (uint32_t *)r->data[1];
124  uint32_t color;
125  int x, y, i, j, match, d, best_d, av_uninit(best_j);
126  uint8_t *p = r->data[0];
127 
128  for (y = 0; y < r->h; y++) {
129  for (x = 0; x < r->w; x++)
130  count[*(p++)]++;
131  p += r->linesize[0] - r->w;
132  }
133  for (i = 0; i < 256; i++) {
134  if (!count[i]) /* avoid useless search */
135  continue;
136  color = palette[i];
137  /* 0: transparent, 1-16: semi-transparent, 17-33 opaque */
138  match = color < 0x33000000 ? 0 : color < 0xCC000000 ? 1 : 17;
139  if (match) {
140  best_d = INT_MAX;
141  for (j = 0; j < 16; j++) {
142  d = color_distance(0xFF000000 | color,
143  0xFF000000 | dvdc->global_palette[j]);
144  if (d < best_d) {
145  best_d = d;
146  best_j = j;
147  }
148  }
149  match += best_j;
150  }
151  hits[match] += count[i];
152  }
153 }
154 
155 static void select_palette(AVCodecContext *avctx, int out_palette[4],
156  int out_alpha[4], unsigned hits[33])
157 {
158  DVDSubtitleContext *dvdc = avctx->priv_data;
159  int i, j, bright, mult;
160  uint32_t color;
161  int selected[4] = { 0 };
162  uint32_t pseudopal[33] = { 0 };
163  uint32_t refcolor[3] = { 0x00000000, 0xFFFFFFFF, 0xFF000000 };
164 
165  /* Bonus for transparent: if the rectangle fits tightly the text, the
166  background color can be quite rare, but it would be ugly without it */
167  hits[0] *= 16;
168  /* Bonus for bright colors */
169  for (i = 0; i < 16; i++) {
170  if (!(hits[1 + i] + hits[17 + i]))
171  continue; /* skip unused colors to gain time */
172  color = dvdc->global_palette[i];
173  bright = 0;
174  for (j = 0; j < 3; j++, color >>= 8)
175  bright += (color & 0xFF) < 0x40 || (color & 0xFF) >= 0xC0;
176  mult = 2 + FFMIN(bright, 2);
177  hits[ 1 + i] *= mult;
178  hits[17 + i] *= mult;
179  }
180 
181  /* Select four most frequent colors */
182  for (i = 0; i < 4; i++) {
183  for (j = 0; j < 33; j++)
184  if (hits[j] > hits[selected[i]])
185  selected[i] = j;
186  hits[selected[i]] = 0;
187  }
188 
189  /* Order the colors like in most DVDs:
190  0: background, 1: foreground, 2: outline */
191  for (i = 0; i < 16; i++) {
192  pseudopal[ 1 + i] = 0x80000000 | dvdc->global_palette[i];
193  pseudopal[17 + i] = 0xFF000000 | dvdc->global_palette[i];
194  }
195  for (i = 0; i < 3; i++) {
196  int best_d = color_distance(refcolor[i], pseudopal[selected[i]]);
197  for (j = i + 1; j < 4; j++) {
198  int d = color_distance(refcolor[i], pseudopal[selected[j]]);
199  if (d < best_d) {
200  FFSWAP(int, selected[i], selected[j]);
201  best_d = d;
202  }
203  }
204  }
205 
206  /* Output */
207  for (i = 0; i < 4; i++) {
208  out_palette[i] = selected[i] ? (selected[i] - 1) & 0xF : 0;
209  out_alpha [i] = !selected[i] ? 0 : selected[i] < 17 ? 0x80 : 0xFF;
210  }
211 }
212 
213 static void build_color_map(AVCodecContext *avctx, int cmap[],
214  const uint32_t palette[],
215  const int out_palette[], unsigned int const out_alpha[])
216 {
217  DVDSubtitleContext *dvdc = avctx->priv_data;
218  int i, j, d, best_d;
219  uint32_t pseudopal[4];
220 
221  for (i = 0; i < 4; i++)
222  pseudopal[i] = (out_alpha[i] << 24) |
223  dvdc->global_palette[out_palette[i]];
224  for (i = 0; i < 256; i++) {
225  best_d = INT_MAX;
226  for (j = 0; j < 4; j++) {
227  d = color_distance(pseudopal[j], palette[i]);
228  if (d < best_d) {
229  cmap[i] = j;
230  best_d = d;
231  }
232  }
233  }
234 }
235 
236 static void copy_rectangle(AVSubtitleRect *dst, AVSubtitleRect *src, int cmap[])
237 {
238  int x, y;
239  uint8_t *p, *q;
240 
241  p = src->data[0];
242  q = dst->data[0] + (src->x - dst->x) +
243  (src->y - dst->y) * dst->linesize[0];
244  for (y = 0; y < src->h; y++) {
245  for (x = 0; x < src->w; x++)
246  *(q++) = cmap[*(p++)];
247  p += src->linesize[0] - src->w;
248  q += dst->linesize[0] - src->w;
249  }
250 }
251 
253  uint8_t *outbuf, int outbuf_size,
254  const AVSubtitle *h)
255 {
256  DVDSubtitleContext *dvdc = avctx->priv_data;
257  uint8_t *q, *qq;
258  int offset1, offset2;
259  int i, rects = h->num_rects, ret;
260  unsigned global_palette_hits[33] = { 0 };
261  int cmap[256];
262  int out_palette[4];
263  int out_alpha[4];
264  AVSubtitleRect vrect;
265  uint8_t *vrect_data = NULL;
266  int x2, y2;
267  int forced = 0;
268 
269  if (rects == 0 || !h->rects)
270  return AVERROR(EINVAL);
271  for (i = 0; i < rects; i++)
272  if (h->rects[i]->type != SUBTITLE_BITMAP) {
273  av_log(avctx, AV_LOG_ERROR, "Bitmap subtitle required\n");
274  return AVERROR(EINVAL);
275  }
276  /* Mark this subtitle forced if any of the rectangles is forced. */
277  for (i = 0; i < rects; i++)
278  if ((h->rects[i]->flags & AV_SUBTITLE_FLAG_FORCED) != 0) {
279  forced = 1;
280  break;
281  }
282 
283  vrect = *h->rects[0];
284 
285  if (rects > 1) {
286  /* DVD subtitles can have only one rectangle: build a virtual
287  rectangle containing all actual rectangles.
288  The data of the rectangles will be copied later, when the palette
289  is decided, because the rectangles may have different palettes. */
290  int xmin = h->rects[0]->x, xmax = xmin + h->rects[0]->w;
291  int ymin = h->rects[0]->y, ymax = ymin + h->rects[0]->h;
292  for (i = 1; i < rects; i++) {
293  xmin = FFMIN(xmin, h->rects[i]->x);
294  ymin = FFMIN(ymin, h->rects[i]->y);
295  xmax = FFMAX(xmax, h->rects[i]->x + h->rects[i]->w);
296  ymax = FFMAX(ymax, h->rects[i]->y + h->rects[i]->h);
297  }
298  vrect.x = xmin;
299  vrect.y = ymin;
300  vrect.w = xmax - xmin;
301  vrect.h = ymax - ymin;
302  if ((ret = av_image_check_size(vrect.w, vrect.h, 0, avctx)) < 0)
303  return ret;
304 
305  /* Count pixels outside the virtual rectangle as transparent */
306  global_palette_hits[0] = vrect.w * vrect.h;
307  for (i = 0; i < rects; i++)
308  global_palette_hits[0] -= h->rects[i]->w * h->rects[i]->h;
309  }
310 
311  for (i = 0; i < rects; i++)
312  count_colors(avctx, global_palette_hits, h->rects[i]);
313  select_palette(avctx, out_palette, out_alpha, global_palette_hits);
314 
315  if (rects > 1) {
316  if (!(vrect_data = av_calloc(vrect.w, vrect.h)))
317  return AVERROR(ENOMEM);
318  vrect.data [0] = vrect_data;
319  vrect.linesize[0] = vrect.w;
320  for (i = 0; i < rects; i++) {
321  build_color_map(avctx, cmap, (uint32_t *)h->rects[i]->data[1],
322  out_palette, out_alpha);
323  copy_rectangle(&vrect, h->rects[i], cmap);
324  }
325  for (i = 0; i < 4; i++)
326  cmap[i] = i;
327  } else {
328  build_color_map(avctx, cmap, (uint32_t *)h->rects[0]->data[1],
329  out_palette, out_alpha);
330  }
331 
332  av_log(avctx, AV_LOG_DEBUG, "Selected palette:");
333  for (i = 0; i < 4; i++)
334  av_log(avctx, AV_LOG_DEBUG, " 0x%06"PRIx32"@@%02x (0x%x,0x%x)",
335  dvdc->global_palette[out_palette[i]], out_alpha[i],
336  out_palette[i], out_alpha[i] >> 4);
337  av_log(avctx, AV_LOG_DEBUG, "\n");
338 
339  // encode data block
340  q = outbuf + 4;
341  offset1 = q - outbuf;
342  // worst case memory requirement: 1 nibble per pixel..
343  if ((q - outbuf) + vrect.w * vrect.h / 2 + 17 + 21 > outbuf_size) {
344  av_log(NULL, AV_LOG_ERROR, "dvd_subtitle too big\n");
346  goto fail;
347  }
348  dvd_encode_rle(&q, vrect.data[0], vrect.w * 2,
349  vrect.w, (vrect.h + 1) >> 1, cmap);
350  offset2 = q - outbuf;
351  dvd_encode_rle(&q, vrect.data[0] + vrect.w, vrect.w * 2,
352  vrect.w, vrect.h >> 1, cmap);
353 
354  if (dvdc->even_rows_fix && (vrect.h & 1)) {
355  // Work-around for some players that want the height to be even.
356  vrect.h++;
357  *q++ = 0x00; // 0x00 0x00 == empty row, i.e. fully transparent
358  *q++ = 0x00;
359  }
360 
361  // set data packet size
362  qq = outbuf + 2;
363  bytestream_put_be16(&qq, q - outbuf);
364 
365  // send start display command
366  bytestream_put_be16(&q, (h->start_display_time*90) >> 10);
367  bytestream_put_be16(&q, (q - outbuf) /*- 2 */ + 8 + 12 + 2);
368  *q++ = 0x03; // palette - 4 nibbles
369  *q++ = (out_palette[3] << 4) | out_palette[2];
370  *q++ = (out_palette[1] << 4) | out_palette[0];
371  *q++ = 0x04; // alpha - 4 nibbles
372  *q++ = (out_alpha[3] & 0xF0) | (out_alpha[2] >> 4);
373  *q++ = (out_alpha[1] & 0xF0) | (out_alpha[0] >> 4);
374 
375  // 12 bytes per rect
376  x2 = vrect.x + vrect.w - 1;
377  y2 = vrect.y + vrect.h - 1;
378 
379  if ((avctx->width > 0 && x2 > avctx->width) ||
380  (avctx->height > 0 && y2 > avctx->height)) {
381  av_log(avctx, AV_LOG_ERROR, "canvas_size(%d:%d) is too small(%d:%d) for render\n",
382  avctx->width, avctx->height, x2, y2);
383  ret = AVERROR(EINVAL);
384  goto fail;
385  }
386  *q++ = 0x05;
387  // x1 x2 -> 6 nibbles
388  *q++ = vrect.x >> 4;
389  *q++ = (vrect.x << 4) | ((x2 >> 8) & 0xf);
390  *q++ = x2;
391  // y1 y2 -> 6 nibbles
392  *q++ = vrect.y >> 4;
393  *q++ = (vrect.y << 4) | ((y2 >> 8) & 0xf);
394  *q++ = y2;
395 
396  *q++ = 0x06;
397  // offset1, offset2
398  bytestream_put_be16(&q, offset1);
399  bytestream_put_be16(&q, offset2);
400 
401  *q++ = forced ? 0x00 : 0x01; // start command
402  *q++ = 0xff; // terminating command
403 
404  // send stop display command last
405  bytestream_put_be16(&q, (h->end_display_time*90) >> 10);
406  bytestream_put_be16(&q, (q - outbuf) - 2 /*+ 4*/);
407  *q++ = 0x02; // set end
408  *q++ = 0xff; // terminating command
409 
410  qq = outbuf;
411  bytestream_put_be16(&qq, q - outbuf);
412 
413  av_log(NULL, AV_LOG_DEBUG, "subtitle_packet size=%"PTRDIFF_SPECIFIER"\n", q - outbuf);
414  ret = q - outbuf;
415 
416 fail:
417  av_free(vrect_data);
418  return ret;
419 }
420 
421 static int bprint_to_extradata(AVCodecContext *avctx, struct AVBPrint *buf)
422 {
423  int ret;
424  char *str;
425 
426  ret = av_bprint_finalize(buf, &str);
427  if (ret < 0)
428  return ret;
429  if (!av_bprint_is_complete(buf)) {
430  av_free(str);
431  return AVERROR(ENOMEM);
432  }
433 
434  avctx->extradata = str;
435  /* Note: the string is NUL terminated (so extradata can be read as a
436  * string), but the ending character is not accounted in the size (in
437  * binary formats you are likely not supposed to mux that character). When
438  * extradata is copied, it is also padded with AV_INPUT_BUFFER_PADDING_SIZE
439  * zeros. */
440  avctx->extradata_size = buf->len;
441  return 0;
442 }
443 
444 static int dvdsub_init(AVCodecContext *avctx)
445 {
446  DVDSubtitleContext *dvdc = avctx->priv_data;
447  static const uint32_t default_palette[16] = {
448  0x000000, 0x0000FF, 0x00FF00, 0xFF0000,
449  0xFFFF00, 0xFF00FF, 0x00FFFF, 0xFFFFFF,
450  0x808000, 0x8080FF, 0x800080, 0x80FF80,
451  0x008080, 0xFF8080, 0x555555, 0xAAAAAA,
452  };
453  AVBPrint extradata;
454  int i, ret;
455 
456  av_assert0(sizeof(dvdc->global_palette) == sizeof(default_palette));
457  if (dvdc->palette_str) {
459  } else {
460  memcpy(dvdc->global_palette, default_palette, sizeof(dvdc->global_palette));
461  }
462 
464  if (avctx->width && avctx->height)
465  av_bprintf(&extradata, "size: %dx%d\n", avctx->width, avctx->height);
466  av_bprintf(&extradata, "palette:");
467  for (i = 0; i < 16; i++)
468  av_bprintf(&extradata, " %06"PRIx32"%c",
469  dvdc->global_palette[i] & 0xFFFFFF, i < 15 ? ',' : '\n');
470 
471  ret = bprint_to_extradata(avctx, &extradata);
472  if (ret < 0)
473  return ret;
474 
475  return 0;
476 }
477 
478 static int dvdsub_encode(AVCodecContext *avctx,
479  unsigned char *buf, int buf_size,
480  const AVSubtitle *sub)
481 {
482  //DVDSubtitleContext *s = avctx->priv_data;
483  int ret;
484 
485  ret = encode_dvd_subtitles(avctx, buf, buf_size, sub);
486  return ret;
487 }
488 
489 #define OFFSET(x) offsetof(DVDSubtitleContext, x)
490 #define SE AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_ENCODING_PARAM
491 static const AVOption options[] = {
492  {"palette", "set the global palette", OFFSET(palette_str), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, SE },
493  {"even_rows_fix", "Make number of rows even (workaround for some players)", OFFSET(even_rows_fix), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, SE},
494  { NULL },
495 };
496 
497 static const AVClass dvdsubenc_class = {
498  .class_name = "VOBSUB subtitle encoder",
499  .item_name = av_default_item_name,
500  .option = options,
501  .version = LIBAVUTIL_VERSION_INT,
502 };
503 
505  .p.name = "dvdsub",
506  CODEC_LONG_NAME("DVD subtitles"),
507  .p.type = AVMEDIA_TYPE_SUBTITLE,
508  .p.id = AV_CODEC_ID_DVD_SUBTITLE,
509  .init = dvdsub_init,
511  .p.priv_class = &dvdsubenc_class,
512  .priv_data_size = sizeof(DVDSubtitleContext),
513 };
AVSubtitle
Definition: avcodec.h:2227
options
static const AVOption options[]
Definition: dvdsubenc.c:491
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:204
av_bprint_is_complete
static int av_bprint_is_complete(const AVBPrint *buf)
Test if the print buffer is complete (not truncated).
Definition: bprint.h:218
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
opt.h
dvdsubenc_class
static const AVClass dvdsubenc_class
Definition: dvdsubenc.c:497
copy_rectangle
static void copy_rectangle(AVSubtitleRect *dst, AVSubtitleRect *src, int cmap[])
Definition: dvdsubenc.c:236
color
Definition: vf_paletteuse.c:511
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
ff_dvdsub_parse_palette
void ff_dvdsub_parse_palette(uint32_t *palette, const char *p)
Definition: dvdsub.c:27
AVSubtitleRect
Definition: avcodec.h:2200
w
uint8_t w
Definition: llviddspenc.c:38
AVOption
AVOption.
Definition: opt.h:346
b
#define b
Definition: input.c:41
DVDSubtitleContext::global_palette
uint32_t global_palette[16]
Definition: dvdsubenc.c:32
FFCodec
Definition: codec_internal.h:127
AVSubtitleRect::linesize
int linesize[4]
Definition: avcodec.h:2212
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
count_colors
static void count_colors(AVCodecContext *avctx, unsigned hits[33], const AVSubtitleRect *r)
Count colors used in a rectangle, quantizing alpha and grouping by nearest global palette entry.
Definition: dvdsubenc.c:118
PUTNIBBLE
#define PUTNIBBLE(val)
Definition: dvdsubenc.c:38
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
fail
#define fail()
Definition: checkasm.h:179
select_palette
static void select_palette(AVCodecContext *avctx, int out_palette[4], int out_alpha[4], unsigned hits[33])
Definition: dvdsubenc.c:155
AVSubtitleRect::x
int x
top left corner of pict, undefined when pict is not set
Definition: avcodec.h:2201
AV_BPRINT_SIZE_AUTOMATIC
#define AV_BPRINT_SIZE_AUTOMATIC
AVERROR_BUFFER_TOO_SMALL
#define AVERROR_BUFFER_TOO_SMALL
Buffer too small.
Definition: error.h:53
bprint_to_extradata
static int bprint_to_extradata(AVCodecContext *avctx, struct AVBPrint *buf)
Definition: dvdsubenc.c:421
mult
static int16_t mult(Float11 *f1, Float11 *f2)
Definition: g726.c:60
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
encode_dvd_subtitles
static int encode_dvd_subtitles(AVCodecContext *avctx, uint8_t *outbuf, int outbuf_size, const AVSubtitle *h)
Definition: dvdsubenc.c:252
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:524
AVSubtitleRect::y
int y
top left corner of pict, undefined when pict is not set
Definition: avcodec.h:2202
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
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:272
DVDSubtitleContext::palette_str
char * palette_str
Definition: dvdsubenc.c:33
AVSubtitleRect::w
int w
width of pict, undefined when pict is not set
Definition: avcodec.h:2203
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
PTRDIFF_SPECIFIER
#define PTRDIFF_SPECIFIER
Definition: internal.h:140
NULL
#define NULL
Definition: coverity.c: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
AVSubtitleRect::data
uint8_t * data[4]
data+linesize for the bitmap of this subtitle.
Definition: avcodec.h:2211
dvdsub_encode
static int dvdsub_encode(AVCodecContext *avctx, unsigned char *buf, int buf_size, const AVSubtitle *sub)
Definition: dvdsubenc.c:478
FF_CODEC_ENCODE_SUB_CB
#define FF_CODEC_ENCODE_SUB_CB(func)
Definition: codec_internal.h:299
DVDSubtitleContext
Definition: dvdsubenc.c:30
build_color_map
static void build_color_map(AVCodecContext *avctx, int cmap[], const uint32_t palette[], const int out_palette[], unsigned int const out_alpha[])
Definition: dvdsubenc.c:213
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:240
codec_internal.h
color
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
Definition: log.c:94
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
AV_SUBTITLE_FLAG_FORCED
#define AV_SUBTITLE_FLAG_FORCED
Definition: avcodec.h:2198
SUBTITLE_BITMAP
@ SUBTITLE_BITMAP
A bitmap, pict will be set.
Definition: avcodec.h:2183
bprint.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
dvd_encode_rle
static void dvd_encode_rle(uint8_t **pq, const uint8_t *bitmap, int linesize, int w, int h, const int cmap[256])
Definition: dvdsubenc.c:46
AVCodecContext::extradata
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:523
color_distance
static int color_distance(uint32_t a, uint32_t b)
Definition: dvdsubenc.c:99
SE
#define SE
Definition: dvdsubenc.c:490
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:194
len
int len
Definition: vorbis_enc_data.h:426
AVCodecContext::height
int height
Definition: avcodec.h:618
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:262
avcodec.h
av_uninit
#define av_uninit(x)
Definition: attributes.h:154
ret
ret
Definition: filter_design.txt:187
AVSubtitleRect::h
int h
height of pict, undefined when pict is not set
Definition: avcodec.h:2204
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
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
av_bprintf
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:99
AVCodecContext
main external API structure.
Definition: avcodec.h:445
dvdsub_init
static int dvdsub_init(AVCodecContext *avctx)
Definition: dvdsubenc.c:444
ff_dvdsub_encoder
const FFCodec ff_dvdsub_encoder
Definition: dvdsubenc.c:504
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:472
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:251
DVDSubtitleContext::even_rows_fix
int even_rows_fix
Definition: dvdsubenc.c:34
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
d
d
Definition: ffmpeg_filter.c:409
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:618
bytestream.h
imgutils.h
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
h
h
Definition: vp9dsp_template.c:2038
av_image_check_size
int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx)
Check if the given dimension of an image is valid, meaning that all bytes of the image can be address...
Definition: imgutils.c:318
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:239
OFFSET
#define OFFSET(x)
Definition: dvdsubenc.c:489
int
int
Definition: ffmpeg_filter.c:409
dvdsub.h