FFmpeg
movtextdec.c
Go to the documentation of this file.
1 /*
2  * 3GPP TS 26.245 Timed Text decoder
3  * Copyright (c) 2012 Philip Langdale <philipl@overt.org>
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 "ass.h"
24 #include "libavutil/opt.h"
25 #include "libavutil/avstring.h"
26 #include "libavutil/common.h"
27 #include "libavutil/bprint.h"
28 #include "libavutil/intreadwrite.h"
29 #include "libavutil/mem.h"
30 #include "bytestream.h"
31 #include "internal.h"
32 
33 #define STYLE_FLAG_BOLD (1<<0)
34 #define STYLE_FLAG_ITALIC (1<<1)
35 #define STYLE_FLAG_UNDERLINE (1<<2)
36 
37 #define BOX_SIZE_INITIAL 40
38 
39 #define STYL_BOX (1<<0)
40 #define HLIT_BOX (1<<1)
41 #define HCLR_BOX (1<<2)
42 #define TWRP_BOX (1<<3)
43 
44 #define BOTTOM_LEFT 1
45 #define BOTTOM_CENTER 2
46 #define BOTTOM_RIGHT 3
47 #define MIDDLE_LEFT 4
48 #define MIDDLE_CENTER 5
49 #define MIDDLE_RIGHT 6
50 #define TOP_LEFT 7
51 #define TOP_CENTER 8
52 #define TOP_RIGHT 9
53 
54 #define RGB_TO_BGR(c) (((c) & 0xff) << 16 | ((c) & 0xff00) | (((c) >> 16) & 0xff))
55 
56 typedef struct {
57  uint16_t font_id;
58  char *font;
59 } FontRecord;
60 
61 typedef struct {
62  uint16_t start;
63  uint16_t end;
64  uint8_t flags;
65  uint8_t bold;
66  uint8_t italic;
67  uint8_t underline;
68  int color;
69  uint8_t alpha;
70  uint8_t fontsize;
71  uint16_t font_id;
72 } StyleBox;
73 
74 typedef struct {
76  const char *font;
78  uint8_t back_alpha;
79  int alignment;
81 
82 typedef struct {
83  uint16_t hlit_start;
84  uint16_t hlit_end;
85 } HighlightBox;
86 
87 typedef struct {
88  uint8_t hlit_color[4];
90 
91 typedef struct {
92  uint8_t wrap_flag;
93 } TextWrapBox;
94 
95 typedef struct {
96  AVClass *class;
103  uint8_t box_flags;
104  uint16_t style_entries, ftab_entries;
109 
110 typedef struct {
111  uint32_t type;
112  unsigned base_size;
113  int (*decode)(const uint8_t *tsmb, MovTextContext *m, uint64_t size);
114 } Box;
115 
117 {
118  if (m->box_flags & STYL_BOX) {
119  av_freep(&m->s);
120  m->style_entries = 0;
121  }
122 }
123 
125 {
126  for (unsigned i = 0; i < m->ftab_entries; i++)
127  av_freep(&m->ftab[i].font);
128  av_freep(&m->ftab);
129  m->ftab_entries = 0;
130 }
131 
132 static void mov_text_parse_style_record(StyleBox *style, const uint8_t **ptr)
133 {
134  // fontID
135  style->font_id = bytestream_get_be16(ptr);
136  // face-style-flags
137  style->flags = bytestream_get_byte(ptr);
138  style->bold = !!(style->flags & STYLE_FLAG_BOLD);
139  style->italic = !!(style->flags & STYLE_FLAG_ITALIC);
140  style->underline = !!(style->flags & STYLE_FLAG_UNDERLINE);
141  // fontsize
142  style->fontsize = bytestream_get_byte(ptr);
143  // Primary color
144  style->color = bytestream_get_be24(ptr);
145  style->color = RGB_TO_BGR(style->color);
146  style->alpha = bytestream_get_byte(ptr);
147 }
148 
150 {
151  const uint8_t *tx3g_ptr = avctx->extradata;
152  int i, j = -1, font_length, remaining = avctx->extradata_size - BOX_SIZE_INITIAL;
153  int8_t v_align, h_align;
154  unsigned ftab_entries;
155 
156  m->ftab_entries = 0;
157  if (remaining < 0)
158  return -1;
159 
160  // Display Flags
161  tx3g_ptr += 4;
162  // Alignment
163  h_align = bytestream_get_byte(&tx3g_ptr);
164  v_align = bytestream_get_byte(&tx3g_ptr);
165  if (h_align == 0) {
166  if (v_align == 0)
167  m->d.alignment = TOP_LEFT;
168  if (v_align == 1)
169  m->d.alignment = MIDDLE_LEFT;
170  if (v_align == -1)
171  m->d.alignment = BOTTOM_LEFT;
172  }
173  if (h_align == 1) {
174  if (v_align == 0)
175  m->d.alignment = TOP_CENTER;
176  if (v_align == 1)
178  if (v_align == -1)
180  }
181  if (h_align == -1) {
182  if (v_align == 0)
183  m->d.alignment = TOP_RIGHT;
184  if (v_align == 1)
185  m->d.alignment = MIDDLE_RIGHT;
186  if (v_align == -1)
187  m->d.alignment = BOTTOM_RIGHT;
188  }
189  // Background Color
190  m->d.back_color = bytestream_get_be24(&tx3g_ptr);
192  m->d.back_alpha = bytestream_get_byte(&tx3g_ptr);
193  // BoxRecord
194  tx3g_ptr += 8;
195  // StyleRecord
196  tx3g_ptr += 4;
197  mov_text_parse_style_record(&m->d.style, &tx3g_ptr);
198  // FontRecord
199  // FontRecord Size
200  tx3g_ptr += 4;
201  // ftab
202  tx3g_ptr += 4;
203 
204  // In case of broken header, init default font
205  m->d.font = ASS_DEFAULT_FONT;
206 
207  ftab_entries = bytestream_get_be16(&tx3g_ptr);
208  if (!ftab_entries)
209  return 0;
210  remaining -= 3 * ftab_entries;
211  if (remaining < 0)
212  return AVERROR_INVALIDDATA;
213  m->ftab = av_calloc(ftab_entries, sizeof(*m->ftab));
214  if (!m->ftab)
215  return AVERROR(ENOMEM);
216  m->ftab_entries = ftab_entries;
217 
218  for (i = 0; i < m->ftab_entries; i++) {
219  m->ftab[i].font_id = bytestream_get_be16(&tx3g_ptr);
220  if (m->ftab[i].font_id == m->d.style.font_id)
221  j = i;
222  font_length = bytestream_get_byte(&tx3g_ptr);
223 
224  remaining -= font_length;
225  if (remaining < 0) {
227  return -1;
228  }
229  m->ftab[i].font = av_malloc(font_length + 1);
230  if (!m->ftab[i].font) {
232  return AVERROR(ENOMEM);
233  }
234  bytestream_get_buffer(&tx3g_ptr, m->ftab[i].font, font_length);
235  m->ftab[i].font[font_length] = '\0';
236  }
237  if (j >= 0)
238  m->d.font = m->ftab[j].font;
239  return 0;
240 }
241 
242 static int decode_twrp(const uint8_t *tsmb, MovTextContext *m, uint64_t size)
243 {
244  m->box_flags |= TWRP_BOX;
245  m->w.wrap_flag = bytestream_get_byte(&tsmb);
246  return 0;
247 }
248 
249 static int decode_hlit(const uint8_t *tsmb, MovTextContext *m, uint64_t size)
250 {
251  m->box_flags |= HLIT_BOX;
252  m->h.hlit_start = bytestream_get_be16(&tsmb);
253  m->h.hlit_end = bytestream_get_be16(&tsmb);
254  return 0;
255 }
256 
257 static int decode_hclr(const uint8_t *tsmb, MovTextContext *m, uint64_t size)
258 {
259  m->box_flags |= HCLR_BOX;
260  bytestream_get_buffer(&tsmb, m->c.hlit_color, 4);
261  return 0;
262 }
263 
264 static int styles_equivalent(const StyleBox *a, const StyleBox *b)
265 {
266 #define CMP(field) ((a)->field == (b)->field)
267  return CMP(bold) && CMP(italic) && CMP(underline) && CMP(color) &&
268  CMP(alpha) && CMP(fontsize) && CMP(font_id);
269 #undef CMP
270 }
271 
272 static int decode_styl(const uint8_t *tsmb, MovTextContext *m, uint64_t size)
273 {
274  int i;
275  int style_entries = bytestream_get_be16(&tsmb);
276  StyleBox *tmp;
277 
278  // A single style record is of length 12 bytes.
279  if (2 + style_entries * 12 > size)
280  return -1;
281 
282  tmp = av_realloc_array(m->s, style_entries, sizeof(*m->s));
283  if (!tmp)
284  return AVERROR(ENOMEM);
285  m->s = tmp;
286  m->style_entries = style_entries;
287 
288  m->box_flags |= STYL_BOX;
289  for(i = 0; i < m->style_entries; i++) {
290  StyleBox *style = &m->s[i];
291 
292  style->start = bytestream_get_be16(&tsmb);
293  style->end = bytestream_get_be16(&tsmb);
294  if (style->end < style->start ||
295  (i && style->start < m->s[i - 1].end)) {
296  mov_text_cleanup(m);
297  return AVERROR_INVALIDDATA;
298  }
299  if (style->start == style->end) {
300  /* Skip this style as it applies to no character */
301  tsmb += 8;
302  m->style_entries--;
303  i--;
304  continue;
305  }
306 
307  mov_text_parse_style_record(style, &tsmb);
308  if (styles_equivalent(style, &m->d.style)) {
309  /* Skip this style as it is equivalent to the default style */
310  m->style_entries--;
311  i--;
312  continue;
313  } else if (i && style->start == style[-1].end &&
314  styles_equivalent(style, &style[-1])) {
315  /* Merge the two adjacent styles */
316  style[-1].end = style->end;
317  m->style_entries--;
318  i--;
319  continue;
320  }
321  }
322  return 0;
323 }
324 
325 static const Box box_types[] = {
326  { MKBETAG('s','t','y','l'), 2, decode_styl },
327  { MKBETAG('h','l','i','t'), 4, decode_hlit },
328  { MKBETAG('h','c','l','r'), 4, decode_hclr },
329  { MKBETAG('t','w','r','p'), 1, decode_twrp }
330 };
331 
332 const static size_t box_count = FF_ARRAY_ELEMS(box_types);
333 
334 // Return byte length of the UTF-8 sequence starting at text[0]. 0 on error.
335 static int get_utf8_length_at(const char *text, const char *text_end)
336 {
337  const char *start = text;
338  int err = 0;
339  uint32_t c;
340  GET_UTF8(c, text < text_end ? (uint8_t)*text++ : (err = 1, 0), goto error;);
341  if (err)
342  goto error;
343  return text - start;
344 error:
345  return 0;
346 }
347 
348 static int text_to_ass(AVBPrint *buf, const char *text, const char *text_end,
349  AVCodecContext *avctx)
350 {
351  MovTextContext *m = avctx->priv_data;
352  const StyleBox *const default_style = &m->d.style;
353  int i = 0;
354  int text_pos = 0;
355  int entry = 0;
356  int color = default_style->color;
357 
358  if (text < text_end && m->box_flags & TWRP_BOX) {
359  if (m->w.wrap_flag == 1) {
360  av_bprintf(buf, "{\\q1}"); /* End of line wrap */
361  } else {
362  av_bprintf(buf, "{\\q2}"); /* No wrap */
363  }
364  }
365 
366  while (text < text_end) {
367  int len;
368 
369  if ((m->box_flags & STYL_BOX) && entry < m->style_entries) {
370  const StyleBox *style = &m->s[entry];
371  if (text_pos == style->end) {
372  av_bprintf(buf, "{\\r}");
373  color = default_style->color;
374  entry++;
375  style++;
376  }
377  if (entry < m->style_entries && text_pos == style->start) {
378  if (style->bold ^ default_style->bold)
379  av_bprintf(buf, "{\\b%d}", style->bold);
380  if (style->italic ^ default_style->italic)
381  av_bprintf(buf, "{\\i%d}", style->italic);
382  if (style->underline ^ default_style->underline)
383  av_bprintf(buf, "{\\u%d}", style->underline);
384  if (style->fontsize != default_style->fontsize)
385  av_bprintf(buf, "{\\fs%d}", style->fontsize);
386  if (style->font_id != default_style->font_id)
387  for (i = 0; i < m->ftab_entries; i++) {
388  if (style->font_id == m->ftab[i].font_id)
389  av_bprintf(buf, "{\\fn%s}", m->ftab[i].font);
390  }
391  if (default_style->color != style->color) {
392  color = style->color;
393  av_bprintf(buf, "{\\1c&H%X&}", color);
394  }
395  if (default_style->alpha != style->alpha)
396  av_bprintf(buf, "{\\1a&H%02X&}", 255 - style->alpha);
397  }
398  }
399  if (m->box_flags & HLIT_BOX) {
400  if (text_pos == m->h.hlit_start) {
401  /* If hclr box is present, set the secondary color to the color
402  * specified. Otherwise, set primary color to white and secondary
403  * color to black. These colors will come from TextSampleModifier
404  * boxes in future and inverse video technique for highlight will
405  * be implemented.
406  */
407  if (m->box_flags & HCLR_BOX) {
408  av_bprintf(buf, "{\\2c&H%02x%02x%02x&}", m->c.hlit_color[2],
409  m->c.hlit_color[1], m->c.hlit_color[0]);
410  } else {
411  av_bprintf(buf, "{\\1c&H000000&}{\\2c&HFFFFFF&}");
412  }
413  }
414  if (text_pos == m->h.hlit_end) {
415  if (m->box_flags & HCLR_BOX) {
416  av_bprintf(buf, "{\\2c&H%X&}", default_style->color);
417  } else {
418  av_bprintf(buf, "{\\1c&H%X&}{\\2c&H%X&}",
419  color, default_style->color);
420  }
421  }
422  }
423 
424  len = get_utf8_length_at(text, text_end);
425  if (len < 1) {
426  av_log(avctx, AV_LOG_ERROR, "invalid UTF-8 byte in subtitle\n");
427  len = 1;
428  }
429  switch (*text) {
430  case '\r':
431  break;
432  case '\n':
433  av_bprintf(buf, "\\N");
434  break;
435  default:
436  av_bprint_append_data(buf, text, len);
437  break;
438  }
439  text += len;
440  text_pos++;
441  }
442 
443  return 0;
444 }
445 
446 static int mov_text_init(AVCodecContext *avctx) {
447  /*
448  * TODO: Handle the default text style.
449  * NB: Most players ignore styles completely, with the result that
450  * it's very common to find files where the default style is broken
451  * and respecting it results in a worse experience than ignoring it.
452  */
453  int ret;
454  MovTextContext *m = avctx->priv_data;
455  ret = mov_text_tx3g(avctx, m);
456  if (ret == 0) {
457  const StyleBox *const default_style = &m->d.style;
458  if (!m->frame_width || !m->frame_height) {
461  }
462  return ff_ass_subtitle_header_full(avctx,
463  m->frame_width, m->frame_height,
464  m->d.font, default_style->fontsize,
465  (255U - default_style->alpha) << 24 | default_style->color,
466  (255U - default_style->alpha) << 24 | default_style->color,
467  (255U - m->d.back_alpha) << 24 | m->d.back_color,
468  (255U - m->d.back_alpha) << 24 | m->d.back_color,
469  default_style->bold, default_style->italic, default_style->underline,
471  } else
472  return ff_ass_subtitle_header_default(avctx);
473 }
474 
476  void *data, int *got_sub_ptr, AVPacket *avpkt)
477 {
478  AVSubtitle *sub = data;
479  MovTextContext *m = avctx->priv_data;
480  int ret;
481  AVBPrint buf;
482  const char *ptr = avpkt->data, *end;
483  int text_length;
484  size_t i;
485 
486  if (!ptr || avpkt->size < 2)
487  return AVERROR_INVALIDDATA;
488 
489  /*
490  * A packet of size two with value zero is an empty subtitle
491  * used to mark the end of the previous non-empty subtitle.
492  * We can just drop them here as we have duration information
493  * already. If the value is non-zero, then it's technically a
494  * bad packet.
495  */
496  if (avpkt->size == 2)
497  return AV_RB16(ptr) == 0 ? 0 : AVERROR_INVALIDDATA;
498 
499  /*
500  * The first two bytes of the packet are the length of the text string
501  * In complex cases, there are style descriptors appended to the string
502  * so we can't just assume the packet size is the string size.
503  */
504  text_length = AV_RB16(ptr);
505  end = ptr + FFMIN(2 + text_length, avpkt->size);
506  ptr += 2;
507 
508  mov_text_cleanup(m);
509 
510  m->style_entries = 0;
511  m->box_flags = 0;
512  // Note that the spec recommends lines be no longer than 2048 characters.
514  if (text_length + 2 < avpkt->size) {
515  const uint8_t *tsmb = end;
516  const uint8_t *const tsmb_end = avpkt->data + avpkt->size;
517  // A box is a minimum of 8 bytes.
518  while (tsmb_end - tsmb >= 8) {
519  uint64_t tsmb_size = bytestream_get_be32(&tsmb);
520  uint32_t tsmb_type = bytestream_get_be32(&tsmb);
521  int size_var, ret_tsmb;
522 
523  if (tsmb_size == 1) {
524  if (tsmb_end - tsmb < 8)
525  break;
526  tsmb_size = bytestream_get_be64(&tsmb);
527  size_var = 16;
528  } else
529  size_var = 8;
530  //size_var is equal to 8 or 16 depending on the size of box
531 
532  if (tsmb_size < size_var) {
533  av_log(avctx, AV_LOG_ERROR, "tsmb_size invalid\n");
534  return AVERROR_INVALIDDATA;
535  }
536  tsmb_size -= size_var;
537 
538  if (tsmb_end - tsmb < tsmb_size)
539  break;
540 
541  for (i = 0; i < box_count; i++) {
542  if (tsmb_type == box_types[i].type) {
543  if (tsmb_size < box_types[i].base_size)
544  break;
545  ret_tsmb = box_types[i].decode(tsmb, m, tsmb_size);
546  if (ret_tsmb == -1)
547  break;
548  }
549  }
550  tsmb += tsmb_size;
551  }
552  text_to_ass(&buf, ptr, end, avctx);
553  mov_text_cleanup(m);
554  } else
555  text_to_ass(&buf, ptr, end, avctx);
556 
557  ret = ff_ass_add_rect(sub, buf.str, m->readorder++, 0, NULL, NULL);
558  av_bprint_finalize(&buf, NULL);
559  if (ret < 0)
560  return ret;
561  *got_sub_ptr = sub->num_rects > 0;
562  return avpkt->size;
563 }
564 
566 {
567  MovTextContext *m = avctx->priv_data;
569  mov_text_cleanup(m);
570  return 0;
571 }
572 
573 static void mov_text_flush(AVCodecContext *avctx)
574 {
575  MovTextContext *m = avctx->priv_data;
576  if (!(avctx->flags2 & AV_CODEC_FLAG2_RO_FLUSH_NOOP))
577  m->readorder = 0;
578 }
579 
580 #define OFFSET(x) offsetof(MovTextContext, x)
581 #define FLAGS AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_SUBTITLE_PARAM
582 static const AVOption options[] = {
583  { "width", "Frame width, usually video width", OFFSET(frame_width), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGS },
584  { "height", "Frame height, usually video height", OFFSET(frame_height), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGS },
585  { NULL },
586 };
587 
589  .class_name = "MOV text decoder",
590  .item_name = av_default_item_name,
591  .option = options,
592  .version = LIBAVUTIL_VERSION_INT,
593 };
594 
596  .name = "mov_text",
597  .long_name = NULL_IF_CONFIG_SMALL("3GPP Timed Text subtitle"),
598  .type = AVMEDIA_TYPE_SUBTITLE,
599  .id = AV_CODEC_ID_MOV_TEXT,
600  .priv_data_size = sizeof(MovTextContext),
601  .priv_class = &mov_text_decoder_class,
602  .init = mov_text_init,
604  .close = mov_text_decode_close,
606  .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
607 };
mov_text_tx3g
static int mov_text_tx3g(AVCodecContext *avctx, MovTextContext *m)
Definition: movtextdec.c:149
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:31
AVSubtitle
Definition: avcodec.h:2289
AVCodec
AVCodec.
Definition: codec.h:202
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:204
MovTextDefault::back_alpha
uint8_t back_alpha
Definition: movtextdec.c:78
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
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
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
BOTTOM_RIGHT
#define BOTTOM_RIGHT
Definition: movtextdec.c:46
HCLR_BOX
#define HCLR_BOX
Definition: movtextdec.c:41
ff_ass_subtitle_header_default
int ff_ass_subtitle_header_default(AVCodecContext *avctx)
Generate a suitable AVCodecContext.subtitle_header for SUBTITLE_ASS with default style.
Definition: ass.c:96
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:234
MovTextContext::s
StyleBox * s
Definition: movtextdec.c:97
color
Definition: vf_paletteuse.c:599
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:68
MIDDLE_LEFT
#define MIDDLE_LEFT
Definition: movtextdec.c:47
sub
static float sub(float src0, float src1)
Definition: dnn_backend_native_layer_mathbinary.c:31
StyleBox::end
uint16_t end
Definition: movtextdec.c:63
MovTextContext::frame_height
int frame_height
Definition: movtextdec.c:107
Box::base_size
unsigned base_size
Definition: movtextdec.c:112
MovTextContext::w
TextWrapBox w
Definition: movtextdec.c:101
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:26
ff_ass_add_rect
int ff_ass_add_rect(AVSubtitle *sub, const char *dialog, int readorder, int layer, const char *style, const char *speaker)
Add an ASS dialog to a subtitle.
Definition: ass.c:117
internal.h
OFFSET
#define OFFSET(x)
Definition: movtextdec.c:580
AVPacket::data
uint8_t * data
Definition: packet.h:373
AVOption
AVOption.
Definition: opt.h:247
b
#define b
Definition: input.c:40
data
const char data[16]
Definition: mxf.c:143
mov_text_parse_style_record
static void mov_text_parse_style_record(StyleBox *style, const uint8_t **ptr)
Definition: movtextdec.c:132
ASS_DEFAULT_BORDERSTYLE
#define ASS_DEFAULT_BORDERSTYLE
Definition: ass.h:43
HighlightBox
Definition: movtextdec.c:82
av_bprint_append_data
void av_bprint_append_data(AVBPrint *buf, const char *data, unsigned size)
Append data to a print buffer.
Definition: bprint.c:157
StyleBox::flags
uint8_t flags
Definition: movtextdec.c:64
options
static const AVOption options[]
Definition: movtextdec.c:582
box_count
const static size_t box_count
Definition: movtextdec.c:332
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
MovTextDefault::back_color
int back_color
Definition: movtextdec.c:77
init
static int init
Definition: av_tx.c:47
StyleBox::bold
uint8_t bold
Definition: movtextdec.c:65
FontRecord::font
char * font
Definition: movtextdec.c:58
Box
Definition: movtextdec.c:110
U
#define U(x)
Definition: vp56_arith.h:37
StyleBox
Definition: movtextdec.c:61
StyleBox::color
int color
Definition: movtextdec.c:68
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
get_utf8_length_at
static int get_utf8_length_at(const char *text, const char *text_end)
Definition: movtextdec.c:335
MovTextDefault::alignment
int alignment
Definition: movtextdec.c:79
Box::decode
int(* decode)(const uint8_t *tsmb, MovTextContext *m, uint64_t size)
Definition: movtextdec.c:113
box_types
static const Box box_types[]
Definition: movtextdec.c:325
MovTextDefault::font
const char * font
Definition: movtextdec.c:76
ass.h
GET_UTF8
#define GET_UTF8(val, GET_BYTE, ERROR)
Convert a UTF-8 character (up to 4 bytes) to its 32-bit UCS-4 encoded form.
Definition: common.h:470
mov_text_init
static int mov_text_init(AVCodecContext *avctx)
Definition: movtextdec.c:446
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
ASS_DEFAULT_FONT
#define ASS_DEFAULT_FONT
Definition: ass.h:35
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
STYLE_FLAG_UNDERLINE
#define STYLE_FLAG_UNDERLINE
Definition: movtextdec.c:35
STYL_BOX
#define STYL_BOX
Definition: movtextdec.c:39
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
TWRP_BOX
#define TWRP_BOX
Definition: movtextdec.c:42
mov_text_flush
static void mov_text_flush(AVCodecContext *avctx)
Definition: movtextdec.c:573
intreadwrite.h
mov_text_decoder_class
static const AVClass mov_text_decoder_class
Definition: movtextdec.c:588
FLAGS
#define FLAGS
Definition: movtextdec.c:581
MovTextContext::ftab_entries
uint16_t ftab_entries
Definition: movtextdec.c:104
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:224
MovTextContext::readorder
int readorder
Definition: movtextdec.c:105
HLIT_BOX
#define HLIT_BOX
Definition: movtextdec.c:40
ff_ass_subtitle_header_full
int ff_ass_subtitle_header_full(AVCodecContext *avctx, int play_res_x, int play_res_y, const char *font, int font_size, int primary_color, int secondary_color, int outline_color, int back_color, int bold, int italic, int underline, int border_style, int alignment)
Generate a suitable AVCodecContext.subtitle_header for SUBTITLE_ASS.
Definition: ass.c:28
mov_text_cleanup
static void mov_text_cleanup(MovTextContext *m)
Definition: movtextdec.c:116
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
MovTextContext::ftab
FontRecord * ftab
Definition: movtextdec.c:100
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
flush
static void flush(AVCodecContext *avctx)
Definition: aacdec_template.c:593
NULL
#define NULL
Definition: coverity.c:32
text_to_ass
static int text_to_ass(AVBPrint *buf, const char *text, const char *text_end, AVCodecContext *avctx)
Definition: movtextdec.c:348
STYLE_FLAG_ITALIC
#define STYLE_FLAG_ITALIC
Definition: movtextdec.c:34
AV_CODEC_ID_MOV_TEXT
@ AV_CODEC_ID_MOV_TEXT
Definition: codec_id.h:527
TextWrapBox
Definition: movtextdec.c:91
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
ASS_DEFAULT_PLAYRESY
#define ASS_DEFAULT_PLAYRESY
Definition: ass.h:29
StyleBox::fontsize
uint8_t fontsize
Definition: movtextdec.c:70
MovTextContext::frame_width
int frame_width
Definition: movtextdec.c:106
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
AVCodecContext::flags2
int flags2
AV_CODEC_FLAG2_*.
Definition: avcodec.h:470
CMP
#define CMP(field)
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
BOTTOM_CENTER
#define BOTTOM_CENTER
Definition: movtextdec.c:45
StyleBox::italic
uint8_t italic
Definition: movtextdec.c:66
MovTextContext::c
HilightcolorBox c
Definition: movtextdec.c:99
size
int size
Definition: twinvq_data.h:10344
ASS_DEFAULT_PLAYRESX
#define ASS_DEFAULT_PLAYRESX
Definition: ass.h:28
MKBETAG
#define MKBETAG(a, b, c, d)
Definition: macros.h:56
Box::type
uint32_t type
Definition: movtextdec.c:111
TextWrapBox::wrap_flag
uint8_t wrap_flag
Definition: movtextdec.c:92
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
MovTextContext::d
MovTextDefault d
Definition: movtextdec.c:102
decode_hclr
static int decode_hclr(const uint8_t *tsmb, MovTextContext *m, uint64_t size)
Definition: movtextdec.c:257
decode_styl
static int decode_styl(const uint8_t *tsmb, MovTextContext *m, uint64_t size)
Definition: movtextdec.c:272
decode_hlit
static int decode_hlit(const uint8_t *tsmb, MovTextContext *m, uint64_t size)
Definition: movtextdec.c:249
StyleBox::start
uint16_t start
Definition: movtextdec.c:62
bprint.h
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
decode_twrp
static int decode_twrp(const uint8_t *tsmb, MovTextContext *m, uint64_t size)
Definition: movtextdec.c:242
common.h
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:209
len
int len
Definition: vorbis_enc_data.h:426
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:271
TOP_RIGHT
#define TOP_RIGHT
Definition: movtextdec.c:52
avcodec.h
bytestream_get_buffer
static av_always_inline unsigned int bytestream_get_buffer(const uint8_t **b, uint8_t *dst, unsigned int size)
Definition: bytestream.h:363
MovTextContext::h
HighlightBox h
Definition: movtextdec.c:98
StyleBox::underline
uint8_t underline
Definition: movtextdec.c:67
STYLE_FLAG_BOLD
#define STYLE_FLAG_BOLD
Definition: movtextdec.c:33
ret
ret
Definition: filter_design.txt:187
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
MovTextDefault::style
StyleBox style
Definition: movtextdec.c:75
MIDDLE_CENTER
#define MIDDLE_CENTER
Definition: movtextdec.c:48
MovTextContext::box_flags
uint8_t box_flags
Definition: movtextdec.c:103
av_bprintf
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:93
HighlightBox::hlit_start
uint16_t hlit_start
Definition: movtextdec.c:83
AVCodecContext
main external API structure.
Definition: avcodec.h:383
MovTextDefault
Definition: movtextdec.c:74
HighlightBox::hlit_end
uint16_t hlit_end
Definition: movtextdec.c:84
MIDDLE_RIGHT
#define MIDDLE_RIGHT
Definition: movtextdec.c:49
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:224
styles_equivalent
static int styles_equivalent(const StyleBox *a, const StyleBox *b)
Definition: movtextdec.c:264
BOX_SIZE_INITIAL
#define BOX_SIZE_INITIAL
Definition: movtextdec.c:37
mov_text_cleanup_ftab
static void mov_text_cleanup_ftab(MovTextContext *m)
Definition: movtextdec.c:124
HilightcolorBox
Definition: movtextdec.c:87
FontRecord::font_id
uint16_t font_id
Definition: movtextdec.c:57
mem.h
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
AVPacket
This structure stores compressed data.
Definition: packet.h:350
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:410
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
MovTextContext::style_entries
uint16_t style_entries
Definition: movtextdec.c:104
ff_movtext_decoder
const AVCodec ff_movtext_decoder
Definition: movtextdec.c:595
bytestream.h
BOTTOM_LEFT
#define BOTTOM_LEFT
Definition: movtextdec.c:44
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
TOP_LEFT
#define TOP_LEFT
Definition: movtextdec.c:50
StyleBox::font_id
uint16_t font_id
Definition: movtextdec.c:71
mov_text_decode_frame
static int mov_text_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, AVPacket *avpkt)
Definition: movtextdec.c:475
avstring.h
mov_text_decode_close
static int mov_text_decode_close(AVCodecContext *avctx)
Definition: movtextdec.c:565
AV_CODEC_FLAG2_RO_FLUSH_NOOP
#define AV_CODEC_FLAG2_RO_FLUSH_NOOP
Do not reset ASS ReadOrder field on flush (subtitles decoding)
Definition: avcodec.h:327
int
int
Definition: ffmpeg_filter.c:153
FontRecord
Definition: movtextdec.c:56
TOP_CENTER
#define TOP_CENTER
Definition: movtextdec.c:51
RGB_TO_BGR
#define RGB_TO_BGR(c)
Definition: movtextdec.c:54
HilightcolorBox::hlit_color
uint8_t hlit_color[4]
Definition: movtextdec.c:88
StyleBox::alpha
uint8_t alpha
Definition: movtextdec.c:69
MovTextContext
Definition: movtextdec.c:95
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