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