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