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