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 (x2 > avctx->width || y2 > avctx->height) {
380  av_log(avctx, AV_LOG_ERROR, "canvas_size(%d:%d) is too small(%d:%d) for render\n",
381  avctx->width, avctx->height, x2, y2);
382  ret = AVERROR(EINVAL);;
383  goto fail;
384  }
385  *q++ = 0x05;
386  // x1 x2 -> 6 nibbles
387  *q++ = vrect.x >> 4;
388  *q++ = (vrect.x << 4) | ((x2 >> 8) & 0xf);
389  *q++ = x2;
390  // y1 y2 -> 6 nibbles
391  *q++ = vrect.y >> 4;
392  *q++ = (vrect.y << 4) | ((y2 >> 8) & 0xf);
393  *q++ = y2;
394 
395  *q++ = 0x06;
396  // offset1, offset2
397  bytestream_put_be16(&q, offset1);
398  bytestream_put_be16(&q, offset2);
399 
400  *q++ = forced ? 0x00 : 0x01; // start command
401  *q++ = 0xff; // terminating command
402 
403  // send stop display command last
404  bytestream_put_be16(&q, (h->end_display_time*90) >> 10);
405  bytestream_put_be16(&q, (q - outbuf) - 2 /*+ 4*/);
406  *q++ = 0x02; // set end
407  *q++ = 0xff; // terminating command
408 
409  qq = outbuf;
410  bytestream_put_be16(&qq, q - outbuf);
411 
412  av_log(NULL, AV_LOG_DEBUG, "subtitle_packet size=%"PTRDIFF_SPECIFIER"\n", q - outbuf);
413  ret = q - outbuf;
414 
415 fail:
416  av_free(vrect_data);
417  return ret;
418 }
419 
420 static int bprint_to_extradata(AVCodecContext *avctx, struct AVBPrint *buf)
421 {
422  int ret;
423  char *str;
424 
425  ret = av_bprint_finalize(buf, &str);
426  if (ret < 0)
427  return ret;
428  if (!av_bprint_is_complete(buf)) {
429  av_free(str);
430  return AVERROR(ENOMEM);
431  }
432 
433  avctx->extradata = str;
434  /* Note: the string is NUL terminated (so extradata can be read as a
435  * string), but the ending character is not accounted in the size (in
436  * binary formats you are likely not supposed to mux that character). When
437  * extradata is copied, it is also padded with AV_INPUT_BUFFER_PADDING_SIZE
438  * zeros. */
439  avctx->extradata_size = buf->len;
440  return 0;
441 }
442 
443 static int dvdsub_init(AVCodecContext *avctx)
444 {
445  DVDSubtitleContext *dvdc = avctx->priv_data;
446  static const uint32_t default_palette[16] = {
447  0x000000, 0x0000FF, 0x00FF00, 0xFF0000,
448  0xFFFF00, 0xFF00FF, 0x00FFFF, 0xFFFFFF,
449  0x808000, 0x8080FF, 0x800080, 0x80FF80,
450  0x008080, 0xFF8080, 0x555555, 0xAAAAAA,
451  };
452  AVBPrint extradata;
453  int i, ret;
454 
455  av_assert0(sizeof(dvdc->global_palette) == sizeof(default_palette));
456  if (dvdc->palette_str) {
458  } else {
459  memcpy(dvdc->global_palette, default_palette, sizeof(dvdc->global_palette));
460  }
461 
463  if (avctx->width && avctx->height)
464  av_bprintf(&extradata, "size: %dx%d\n", avctx->width, avctx->height);
465  av_bprintf(&extradata, "palette:");
466  for (i = 0; i < 16; i++)
467  av_bprintf(&extradata, " %06"PRIx32"%c",
468  dvdc->global_palette[i] & 0xFFFFFF, i < 15 ? ',' : '\n');
469 
470  ret = bprint_to_extradata(avctx, &extradata);
471  if (ret < 0)
472  return ret;
473 
474  return 0;
475 }
476 
477 static int dvdsub_encode(AVCodecContext *avctx,
478  unsigned char *buf, int buf_size,
479  const AVSubtitle *sub)
480 {
481  //DVDSubtitleContext *s = avctx->priv_data;
482  int ret;
483 
484  ret = encode_dvd_subtitles(avctx, buf, buf_size, sub);
485  return ret;
486 }
487 
488 #define OFFSET(x) offsetof(DVDSubtitleContext, x)
489 #define SE AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_ENCODING_PARAM
490 static const AVOption options[] = {
491  {"palette", "set the global palette", OFFSET(palette_str), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, SE },
492  {"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},
493  { NULL },
494 };
495 
496 static const AVClass dvdsubenc_class = {
497  .class_name = "VOBSUB subtitle encoder",
498  .item_name = av_default_item_name,
499  .option = options,
500  .version = LIBAVUTIL_VERSION_INT,
501 };
502 
504  .p.name = "dvdsub",
505  CODEC_LONG_NAME("DVD subtitles"),
506  .p.type = AVMEDIA_TYPE_SUBTITLE,
507  .p.id = AV_CODEC_ID_DVD_SUBTITLE,
508  .init = dvdsub_init,
510  .p.priv_class = &dvdsubenc_class,
511  .priv_data_size = sizeof(DVDSubtitleContext),
512 };
AVSubtitle
Definition: avcodec.h:2308
options
static const AVOption options[]
Definition: dvdsubenc.c:490
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h: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
opt.h
dvdsubenc_class
static const AVClass dvdsubenc_class
Definition: dvdsubenc.c:496
copy_rectangle
static void copy_rectangle(AVSubtitleRect *dst, AVSubtitleRect *src, int cmap[])
Definition: dvdsubenc.c:236
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:235
color
Definition: vf_paletteuse.c:601
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
sub
static float sub(float src0, float src1)
Definition: dnn_backend_native_layer_mathbinary.c:31
ff_dvdsub_parse_palette
void ff_dvdsub_parse_palette(uint32_t *palette, const char *p)
Definition: dvdsub.c:27
AVSubtitleRect
Definition: avcodec.h:2280
w
uint8_t w
Definition: llviddspenc.c:38
AVOption
AVOption.
Definition: opt.h:251
b
#define b
Definition: input.c:41
DVDSubtitleContext::global_palette
uint32_t global_palette[16]
Definition: dvdsubenc.c:32
FFCodec
Definition: codec_internal.h:119
AVSubtitleRect::linesize
int linesize[4]
Definition: avcodec.h:2292
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:123
fail
#define fail()
Definition: checkasm.h:133
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:2281
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:420
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:500
AVSubtitleRect::y
int y
top left corner of pict, undefined when pict is not set
Definition: avcodec.h:2282
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
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:264
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:2283
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:149
NULL
#define NULL
Definition: coverity.c:32
AV_CODEC_ID_DVD_SUBTITLE
@ AV_CODEC_ID_DVD_SUBTITLE
Definition: codec_id.h:538
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:2291
dvdsub_encode
static int dvdsub_encode(AVCodecContext *avctx, unsigned char *buf, int buf_size, const AVSubtitle *sub)
Definition: dvdsubenc.c:477
FF_CODEC_ENCODE_SUB_CB
#define FF_CODEC_ENCODE_SUB_CB(func)
Definition: codec_internal.h:310
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:185
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
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:2278
SUBTITLE_BITMAP
@ SUBTITLE_BITMAP
A bitmap, pict will be set.
Definition: avcodec.h:2263
bprint.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
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:499
color_distance
static int color_distance(uint32_t a, uint32_t b)
Definition: dvdsubenc.c:99
SE
#define SE
Definition: dvdsubenc.c:489
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:211
len
int len
Definition: vorbis_enc_data.h:426
AVCodecContext::height
int height
Definition: avcodec.h:571
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:272
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:2284
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:94
AVCodecContext
main external API structure.
Definition: avcodec.h:398
dvdsub_init
static int dvdsub_init(AVCodecContext *avctx)
Definition: dvdsubenc.c:443
ff_dvdsub_encoder
const FFCodec ff_dvdsub_encoder
Definition: dvdsubenc.c:503
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:425
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:244
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:156
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:571
bytestream.h
convert_header.str
string str
Definition: convert_header.py:20
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:229
OFFSET
#define OFFSET(x)
Definition: dvdsubenc.c:488
int
int
Definition: ffmpeg_filter.c:156
dvdsub.h