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&}",
448  RGB_TO_BGR(color), RGB_TO_BGR(m->d.color));
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 };
uint64_t tracksize
Definition: movtextdec.c:111
#define OFFSET(x)
Definition: movtextdec.c:616
#define AV_RB8(x)
Definition: intreadwrite.h:395
#define NULL
Definition: coverity.c:32
#define BOTTOM_RIGHT
Definition: movtextdec.c:44
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:94
HighlightBox h
Definition: movtextdec.c:103
static const size_t box_count
Definition: movtextdec.c:359
#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
#define TOP_LEFT
Definition: movtextdec.c:48
static int decode_twrp(const uint8_t *tsmb, MovTextContext *m, AVPacket *avpkt)
Definition: movtextdec.c:275
AVOption.
Definition: opt.h:246
static void flush(AVCodecContext *avctx)
#define ASS_DEFAULT_BORDERSTYLE
Definition: ass.h:43
uint8_t back_alpha
Definition: movtextdec.c:61
static const AVOption options[]
Definition: movtextdec.c:618
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
Memory handling functions.
char * font
Definition: movtextdec.c:70
uint8_t wrap_flag
Definition: movtextdec.c:96
#define AV_RB64
Definition: intreadwrite.h:164
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
uint8_t italic
Definition: movtextdec.c:63
int size
Definition: packet.h:356
uint16_t style_fontID
Definition: movtextdec.c:83
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
#define AV_RB24
Definition: intreadwrite.h:64
StyleBox * s_temp
Definition: movtextdec.c:102
unsigned num_rects
Definition: avcodec.h:2698
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
FontRecord * ftab_temp
Definition: movtextdec.c:106
uint8_t hlit_color[4]
Definition: movtextdec.c:92
static void error(const char *err)
AVCodec.
Definition: codec.h:190
uint8_t bold
Definition: movtextdec.c:77
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:235
uint16_t style_entries
Definition: movtextdec.c:110
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
uint8_t
#define av_malloc(s)
AVOptions.
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
#define AV_RB32
Definition: intreadwrite.h:130
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
int ff_ass_subtitle_header_default(AVCodecContext *avctx)
Generate a suitable AVCodecContext.subtitle_header for SUBTITLE_ASS with default style.
Definition: ass.c:97
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:627
uint8_t underline
Definition: movtextdec.c:79
uint8_t alpha
Definition: movtextdec.c:59
const char data[16]
Definition: mxf.c:91
static int get_utf8_length_at(const char *text, const char *text_end)
Definition: movtextdec.c:362
static int mov_text_init(AVCodecContext *avctx)
Definition: movtextdec.c:477
static void mov_text_cleanup(MovTextContext *m)
Definition: movtextdec.c:125
uint8_t * data
Definition: packet.h:355
#define STYL_BOX
Definition: movtextdec.c:37
#define AV_CODEC_FLAG2_RO_FLUSH_NOOP
Do not reset ASS ReadOrder field on flush (subtitles decoding)
Definition: avcodec.h:388
uint8_t italic
Definition: movtextdec.c:78
#define av_log(a,...)
#define STYLE_FLAG_UNDERLINE
Definition: movtextdec.c:33
#define ASS_DEFAULT_PLAYRESY
Definition: ass.h:29
MovTextDefault d
Definition: movtextdec.c:108
uint16_t hlit_start
Definition: movtextdec.c:87
#define U(x)
Definition: vp56_arith.h:37
uint8_t underline
Definition: movtextdec.c:64
static const AVClass mov_text_decoder_class
Definition: movtextdec.c:624
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
TextWrapBox w
Definition: movtextdec.c:107
#define AV_BPRINT_SIZE_UNLIMITED
uint8_t style_flag
Definition: movtextdec.c:76
#define AV_RB16
Definition: intreadwrite.h:53
#define AVERROR(e)
Definition: error.h:43
#define ASS_DEFAULT_FONT
Definition: ass.h:35
static const Box box_types[]
Definition: movtextdec.c:352
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
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
static int text_to_ass(AVBPrint *buf, const char *text, const char *text_end, AVCodecContext *avctx)
Definition: movtextdec.c:375
const char * name
Name of the codec implementation.
Definition: codec.h:197
#define TWRP_BOX
Definition: movtextdec.c:40
static void mov_text_flush(AVCodecContext *avctx)
Definition: movtextdec.c:609
#define FLAGS
Definition: movtextdec.c:617
#define STYLE_FLAG_ITALIC
Definition: movtextdec.c:32
uint8_t box_flags
Definition: movtextdec.c:109
#define HLIT_BOX
Definition: movtextdec.c:38
#define FFMIN(a, b)
Definition: common.h:96
int color
Definition: movtextdec.c:80
uint16_t hlit_end
Definition: movtextdec.c:88
uint32_t type
Definition: movtextdec.c:120
uint16_t style_start
Definition: movtextdec.c:74
#define FF_ARRAY_ELEMS(a)
static int decode_hlit(const uint8_t *tsmb, MovTextContext *m, AVPacket *avpkt)
Definition: movtextdec.c:282
int(* decode)(const uint8_t *tsmb, MovTextContext *m, AVPacket *avpkt)
Definition: movtextdec.c:122
#define TOP_RIGHT
Definition: movtextdec.c:50
HilightcolorBox c
Definition: movtextdec.c:104
Libavcodec external API header.
uint16_t ftab_entries
Definition: movtextdec.c:110
uint16_t style_end
Definition: movtextdec.c:75
main external API structure.
Definition: avcodec.h:526
#define BOTTOM_CENTER
Definition: movtextdec.c:43
int extradata_size
Definition: avcodec.h:628
Describe the class of an AVClass context structure.
Definition: log.h:67
size_t base_size
Definition: movtextdec.c:121
StyleBox ** s
Definition: movtextdec.c:101
cl_device_type type
#define BOX_SIZE_INITIAL
Definition: movtextdec.c:35
static int decode_hclr(const uint8_t *tsmb, MovTextContext *m, AVPacket *avpkt)
Definition: movtextdec.c:292
#define STYLE_FLAG_BOLD
Definition: movtextdec.c:31
#define MIDDLE_CENTER
Definition: movtextdec.c:46
uint16_t fontID
Definition: movtextdec.c:69
int
#define BOTTOM_LEFT
Definition: movtextdec.c:42
common internal and external API header
static int decode_styl(const uint8_t *tsmb, MovTextContext *m, AVPacket *avpkt)
Definition: movtextdec.c:300
uint8_t fontsize
Definition: movtextdec.c:82
static double c[64]
static int mov_text_decode_close(AVCodecContext *avctx)
Definition: movtextdec.c:601
AVCodec ff_movtext_decoder
Definition: movtextdec.c:631
#define MKBETAG(a, b, c, d)
Definition: common.h:407
uint8_t bold
Definition: movtextdec.c:62
void * priv_data
Definition: avcodec.h:553
const char * font
Definition: movtextdec.c:56
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
static void mov_text_cleanup_ftab(MovTextContext *m)
Definition: movtextdec.c:138
int len
int flags2
AV_CODEC_FLAG2_*.
Definition: avcodec.h:613
#define HCLR_BOX
Definition: movtextdec.c:39
#define av_freep(p)
#define MIDDLE_RIGHT
Definition: movtextdec.c:47
#define MIDDLE_LEFT
Definition: movtextdec.c:45
FontRecord ** ftab
Definition: movtextdec.c:105
#define RGB_TO_BGR(c)
Definition: movtextdec.c:52
#define TOP_CENTER
Definition: movtextdec.c:49
uint8_t fontsize
Definition: movtextdec.c:57
static int mov_text_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, AVPacket *avpkt)
Definition: movtextdec.c:505
#define ASS_DEFAULT_PLAYRESX
Definition: ass.h:28
This structure stores compressed data.
Definition: packet.h:332
uint8_t alpha
Definition: movtextdec.c:81
static int mov_text_tx3g(AVCodecContext *avctx, MovTextContext *m)
Definition: movtextdec.c:153
uint16_t fontID
Definition: movtextdec.c:55
void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
Append char c n times to a print buffer.
Definition: bprint.c:140