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