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