FFmpeg  3.4.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/avstring.h"
25 #include "libavutil/common.h"
26 #include "libavutil/bprint.h"
27 #include "libavutil/intreadwrite.h"
28 #include "libavutil/mem.h"
29 
30 #define STYLE_FLAG_BOLD (1<<0)
31 #define STYLE_FLAG_ITALIC (1<<1)
32 #define STYLE_FLAG_UNDERLINE (1<<2)
33 
34 #define BOX_SIZE_INITIAL 40
35 
36 #define STYL_BOX (1<<0)
37 #define HLIT_BOX (1<<1)
38 #define HCLR_BOX (1<<2)
39 #define TWRP_BOX (1<<3)
40 
41 #define BOTTOM_LEFT 1
42 #define BOTTOM_CENTER 2
43 #define BOTTOM_RIGHT 3
44 #define MIDDLE_LEFT 4
45 #define MIDDLE_CENTER 5
46 #define MIDDLE_RIGHT 6
47 #define TOP_LEFT 7
48 #define TOP_CENTER 8
49 #define TOP_RIGHT 9
50 
51 typedef struct {
52  char *font;
53  int fontsize;
54  int color;
56  int bold;
57  int italic;
58  int underline;
59  int alignment;
61 
62 typedef struct {
63  uint16_t fontID;
64  char *font;
65 } FontRecord;
66 
67 typedef struct {
68  uint16_t style_start;
69  uint16_t style_end;
72  uint16_t style_fontID;
73 } StyleBox;
74 
75 typedef struct {
76  uint16_t hlit_start;
77  uint16_t hlit_end;
78 } HighlightBox;
79 
80 typedef struct {
81  uint8_t hlit_color[4];
83 
84 typedef struct {
86 } TextWrapBox;
87 
88 typedef struct {
98  uint16_t style_entries, ftab_entries;
99  uint64_t tracksize;
100  int size_var;
101  int count_s, count_f;
104 
105 typedef struct {
106  uint32_t type;
107  size_t base_size;
108  int (*decode)(const uint8_t *tsmb, MovTextContext *m, AVPacket *avpkt);
109 } Box;
110 
112 {
113  int i;
114  if (m->box_flags & STYL_BOX) {
115  for(i = 0; i < m->count_s; i++) {
116  av_freep(&m->s[i]);
117  }
118  av_freep(&m->s);
119  m->count_s = 0;
120  m->style_entries = 0;
121  }
122 }
123 
125 {
126  int i;
127  if (m->ftab_temp)
128  av_freep(&m->ftab_temp->font);
129  av_freep(&m->ftab_temp);
130  if (m->ftab) {
131  for(i = 0; i < m->count_f; i++) {
132  av_freep(&m->ftab[i]->font);
133  av_freep(&m->ftab[i]);
134  }
135  }
136  av_freep(&m->ftab);
137 }
138 
140 {
141  uint8_t *tx3g_ptr = avctx->extradata;
142  int i, box_size, font_length;
143  int8_t v_align, h_align;
144  int style_fontID;
145  StyleBox s_default;
146 
147  m->count_f = 0;
148  m->ftab_entries = 0;
149  box_size = BOX_SIZE_INITIAL; /* Size till ftab_entries */
150  if (avctx->extradata_size < box_size)
151  return -1;
152 
153  // Display Flags
154  tx3g_ptr += 4;
155  // Alignment
156  h_align = *tx3g_ptr++;
157  v_align = *tx3g_ptr++;
158  if (h_align == 0) {
159  if (v_align == 0)
160  m->d.alignment = TOP_LEFT;
161  if (v_align == 1)
162  m->d.alignment = MIDDLE_LEFT;
163  if (v_align == -1)
164  m->d.alignment = BOTTOM_LEFT;
165  }
166  if (h_align == 1) {
167  if (v_align == 0)
168  m->d.alignment = TOP_CENTER;
169  if (v_align == 1)
171  if (v_align == -1)
173  }
174  if (h_align == -1) {
175  if (v_align == 0)
176  m->d.alignment = TOP_RIGHT;
177  if (v_align == 1)
178  m->d.alignment = MIDDLE_RIGHT;
179  if (v_align == -1)
180  m->d.alignment = BOTTOM_RIGHT;
181  }
182  // Background Color
183  m->d.back_color = AV_RB24(tx3g_ptr);
184  tx3g_ptr += 4;
185  // BoxRecord
186  tx3g_ptr += 8;
187  // StyleRecord
188  tx3g_ptr += 4;
189  // fontID
190  style_fontID = AV_RB16(tx3g_ptr);
191  tx3g_ptr += 2;
192  // face-style-flags
193  s_default.style_flag = *tx3g_ptr++;
194  m->d.bold = s_default.style_flag & STYLE_FLAG_BOLD;
195  m->d.italic = s_default.style_flag & STYLE_FLAG_ITALIC;
196  m->d.underline = s_default.style_flag & STYLE_FLAG_UNDERLINE;
197  // fontsize
198  m->d.fontsize = *tx3g_ptr++;
199  // Primary color
200  m->d.color = AV_RB24(tx3g_ptr);
201  tx3g_ptr += 4;
202  // FontRecord
203  // FontRecord Size
204  tx3g_ptr += 4;
205  // ftab
206  tx3g_ptr += 4;
207 
208  m->ftab_entries = AV_RB16(tx3g_ptr);
209  tx3g_ptr += 2;
210 
211  for (i = 0; i < m->ftab_entries; i++) {
212 
213  box_size += 3;
214  if (avctx->extradata_size < box_size) {
216  m->ftab_entries = 0;
217  return -1;
218  }
219  m->ftab_temp = av_mallocz(sizeof(*m->ftab_temp));
220  if (!m->ftab_temp) {
222  return AVERROR(ENOMEM);
223  }
224  m->ftab_temp->fontID = AV_RB16(tx3g_ptr);
225  tx3g_ptr += 2;
226  font_length = *tx3g_ptr++;
227 
228  box_size = box_size + font_length;
229  if (avctx->extradata_size < box_size) {
231  m->ftab_entries = 0;
232  return -1;
233  }
234  m->ftab_temp->font = av_malloc(font_length + 1);
235  if (!m->ftab_temp->font) {
237  return AVERROR(ENOMEM);
238  }
239  memcpy(m->ftab_temp->font, tx3g_ptr, font_length);
240  m->ftab_temp->font[font_length] = '\0';
241  av_dynarray_add(&m->ftab, &m->count_f, m->ftab_temp);
242  if (!m->ftab) {
244  return AVERROR(ENOMEM);
245  }
246  m->ftab_temp = NULL;
247  tx3g_ptr = tx3g_ptr + font_length;
248  }
249  for (i = 0; i < m->ftab_entries; i++) {
250  if (style_fontID == m->ftab[i]->fontID)
251  m->d.font = m->ftab[i]->font;
252  }
253  return 0;
254 }
255 
256 static int decode_twrp(const uint8_t *tsmb, MovTextContext *m, AVPacket *avpkt)
257 {
258  m->box_flags |= TWRP_BOX;
259  m->w.wrap_flag = *tsmb++;
260  return 0;
261 }
262 
263 static int decode_hlit(const uint8_t *tsmb, MovTextContext *m, AVPacket *avpkt)
264 {
265  m->box_flags |= HLIT_BOX;
266  m->h.hlit_start = AV_RB16(tsmb);
267  tsmb += 2;
268  m->h.hlit_end = AV_RB16(tsmb);
269  tsmb += 2;
270  return 0;
271 }
272 
273 static int decode_hclr(const uint8_t *tsmb, MovTextContext *m, AVPacket *avpkt)
274 {
275  m->box_flags |= HCLR_BOX;
276  memcpy(m->c.hlit_color, tsmb, 4);
277  tsmb += 4;
278  return 0;
279 }
280 
281 static int decode_styl(const uint8_t *tsmb, MovTextContext *m, AVPacket *avpkt)
282 {
283  int i;
284  int style_entries = AV_RB16(tsmb);
285  tsmb += 2;
286  // A single style record is of length 12 bytes.
287  if (m->tracksize + m->size_var + 2 + style_entries * 12 > avpkt->size)
288  return -1;
289 
290  m->style_entries = style_entries;
291 
292  m->box_flags |= STYL_BOX;
293  for(i = 0; i < m->style_entries; i++) {
294  m->s_temp = av_malloc(sizeof(*m->s_temp));
295  if (!m->s_temp) {
296  mov_text_cleanup(m);
297  return AVERROR(ENOMEM);
298  }
299  m->s_temp->style_start = AV_RB16(tsmb);
300  tsmb += 2;
301  m->s_temp->style_end = AV_RB16(tsmb);
302 
303  if ( m->s_temp->style_end < m->s_temp->style_start
304  || (m->count_s && m->s_temp->style_start < m->s[m->count_s - 1]->style_end)) {
305  av_freep(&m->s_temp);
306  mov_text_cleanup(m);
307  return AVERROR(ENOMEM);
308  }
309 
310  tsmb += 2;
311  m->s_temp->style_fontID = AV_RB16(tsmb);
312  tsmb += 2;
313  m->s_temp->style_flag = AV_RB8(tsmb);
314  tsmb++;
315  m->s_temp->fontsize = AV_RB8(tsmb);
316  av_dynarray_add(&m->s, &m->count_s, m->s_temp);
317  if(!m->s) {
318  mov_text_cleanup(m);
319  return AVERROR(ENOMEM);
320  }
321  tsmb++;
322  // text-color-rgba
323  tsmb += 4;
324  }
325  return 0;
326 }
327 
328 static const Box box_types[] = {
329  { MKBETAG('s','t','y','l'), 2, decode_styl },
330  { MKBETAG('h','l','i','t'), 4, decode_hlit },
331  { MKBETAG('h','c','l','r'), 4, decode_hclr },
332  { MKBETAG('t','w','r','p'), 1, decode_twrp }
333 };
334 
335 const static size_t box_count = FF_ARRAY_ELEMS(box_types);
336 
337 static int text_to_ass(AVBPrint *buf, const char *text, const char *text_end,
338  MovTextContext *m)
339 {
340  int i = 0;
341  int j = 0;
342  int text_pos = 0;
343 
344  if (text < text_end && m->box_flags & TWRP_BOX) {
345  if (m->w.wrap_flag == 1) {
346  av_bprintf(buf, "{\\q1}"); /* End of line wrap */
347  } else {
348  av_bprintf(buf, "{\\q2}"); /* No wrap */
349  }
350  }
351 
352  while (text < text_end) {
353  if (m->box_flags & STYL_BOX) {
354  for (i = 0; i < m->style_entries; i++) {
355  if (m->s[i]->style_flag && text_pos == m->s[i]->style_end) {
356  av_bprintf(buf, "{\\r}");
357  }
358  }
359  for (i = 0; i < m->style_entries; i++) {
360  if (m->s[i]->style_flag && text_pos == m->s[i]->style_start) {
361  if (m->s[i]->style_flag & STYLE_FLAG_BOLD)
362  av_bprintf(buf, "{\\b1}");
363  if (m->s[i]->style_flag & STYLE_FLAG_ITALIC)
364  av_bprintf(buf, "{\\i1}");
365  if (m->s[i]->style_flag & STYLE_FLAG_UNDERLINE)
366  av_bprintf(buf, "{\\u1}");
367  av_bprintf(buf, "{\\fs%d}", m->s[i]->fontsize);
368  for (j = 0; j < m->ftab_entries; j++) {
369  if (m->s[i]->style_fontID == m->ftab[j]->fontID)
370  av_bprintf(buf, "{\\fn%s}", m->ftab[j]->font);
371  }
372  }
373  }
374  }
375  if (m->box_flags & HLIT_BOX) {
376  if (text_pos == m->h.hlit_start) {
377  /* If hclr box is present, set the secondary color to the color
378  * specified. Otherwise, set primary color to white and secondary
379  * color to black. These colors will come from TextSampleModifier
380  * boxes in future and inverse video technique for highlight will
381  * be implemented.
382  */
383  if (m->box_flags & HCLR_BOX) {
384  av_bprintf(buf, "{\\2c&H%02x%02x%02x&}", m->c.hlit_color[2],
385  m->c.hlit_color[1], m->c.hlit_color[0]);
386  } else {
387  av_bprintf(buf, "{\\1c&H000000&}{\\2c&HFFFFFF&}");
388  }
389  }
390  if (text_pos == m->h.hlit_end) {
391  if (m->box_flags & HCLR_BOX) {
392  av_bprintf(buf, "{\\2c&H000000&}");
393  } else {
394  av_bprintf(buf, "{\\1c&HFFFFFF&}{\\2c&H000000&}");
395  }
396  }
397  }
398 
399  switch (*text) {
400  case '\r':
401  break;
402  case '\n':
403  av_bprintf(buf, "\\N");
404  break;
405  default:
406  av_bprint_chars(buf, *text, 1);
407  break;
408  }
409  text++;
410  text_pos++;
411  }
412 
413  return 0;
414 }
415 
416 static int mov_text_init(AVCodecContext *avctx) {
417  /*
418  * TODO: Handle the default text style.
419  * NB: Most players ignore styles completely, with the result that
420  * it's very common to find files where the default style is broken
421  * and respecting it results in a worse experience than ignoring it.
422  */
423  int ret;
424  MovTextContext *m = avctx->priv_data;
425  ret = mov_text_tx3g(avctx, m);
426  if (ret == 0) {
427  return ff_ass_subtitle_header(avctx, m->d.font, m->d.fontsize, m->d.color,
428  m->d.back_color, m->d.bold, m->d.italic,
430  m->d.alignment);
431  } else
432  return ff_ass_subtitle_header_default(avctx);
433 }
434 
436  void *data, int *got_sub_ptr, AVPacket *avpkt)
437 {
438  AVSubtitle *sub = data;
439  MovTextContext *m = avctx->priv_data;
440  int ret;
441  AVBPrint buf;
442  char *ptr = avpkt->data;
443  char *end;
444  int text_length, tsmb_type, ret_tsmb;
445  uint64_t tsmb_size;
446  const uint8_t *tsmb;
447 
448  if (!ptr || avpkt->size < 2)
449  return AVERROR_INVALIDDATA;
450 
451  /*
452  * A packet of size two with value zero is an empty subtitle
453  * used to mark the end of the previous non-empty subtitle.
454  * We can just drop them here as we have duration information
455  * already. If the value is non-zero, then it's technically a
456  * bad packet.
457  */
458  if (avpkt->size == 2)
459  return AV_RB16(ptr) == 0 ? 0 : AVERROR_INVALIDDATA;
460 
461  /*
462  * The first two bytes of the packet are the length of the text string
463  * In complex cases, there are style descriptors appended to the string
464  * so we can't just assume the packet size is the string size.
465  */
466  text_length = AV_RB16(ptr);
467  end = ptr + FFMIN(2 + text_length, avpkt->size);
468  ptr += 2;
469 
470  mov_text_cleanup(m);
471 
472  tsmb_size = 0;
473  m->tracksize = 2 + text_length;
474  m->style_entries = 0;
475  m->box_flags = 0;
476  m->count_s = 0;
477  // Note that the spec recommends lines be no longer than 2048 characters.
479  if (text_length + 2 != avpkt->size) {
480  while (m->tracksize + 8 <= avpkt->size) {
481  // A box is a minimum of 8 bytes.
482  tsmb = ptr + m->tracksize - 2;
483  tsmb_size = AV_RB32(tsmb);
484  tsmb += 4;
485  tsmb_type = AV_RB32(tsmb);
486  tsmb += 4;
487 
488  if (tsmb_size == 1) {
489  if (m->tracksize + 16 > avpkt->size)
490  break;
491  tsmb_size = AV_RB64(tsmb);
492  tsmb += 8;
493  m->size_var = 16;
494  } else
495  m->size_var = 8;
496  //size_var is equal to 8 or 16 depending on the size of box
497 
498  if (tsmb_size == 0) {
499  av_log(avctx, AV_LOG_ERROR, "tsmb_size is 0\n");
500  return AVERROR_INVALIDDATA;
501  }
502 
503  if (tsmb_size > avpkt->size - m->tracksize)
504  break;
505 
506  for (size_t i = 0; i < box_count; i++) {
507  if (tsmb_type == box_types[i].type) {
508  if (m->tracksize + m->size_var + box_types[i].base_size > avpkt->size)
509  break;
510  ret_tsmb = box_types[i].decode(tsmb, m, avpkt);
511  if (ret_tsmb == -1)
512  break;
513  }
514  }
515  m->tracksize = m->tracksize + tsmb_size;
516  }
517  text_to_ass(&buf, ptr, end, m);
518  mov_text_cleanup(m);
519  } else
520  text_to_ass(&buf, ptr, end, m);
521 
522  ret = ff_ass_add_rect(sub, buf.str, m->readorder++, 0, NULL, NULL);
523  av_bprint_finalize(&buf, NULL);
524  if (ret < 0)
525  return ret;
526  *got_sub_ptr = sub->num_rects > 0;
527  return avpkt->size;
528 }
529 
531 {
532  MovTextContext *m = avctx->priv_data;
534  mov_text_cleanup(m);
535  return 0;
536 }
537 
538 static void mov_text_flush(AVCodecContext *avctx)
539 {
540  MovTextContext *m = avctx->priv_data;
541  if (!(avctx->flags2 & AV_CODEC_FLAG2_RO_FLUSH_NOOP))
542  m->readorder = 0;
543 }
544 
546  .name = "mov_text",
547  .long_name = NULL_IF_CONFIG_SMALL("3GPP Timed Text subtitle"),
548  .type = AVMEDIA_TYPE_SUBTITLE,
549  .id = AV_CODEC_ID_MOV_TEXT,
550  .priv_data_size = sizeof(MovTextContext),
551  .init = mov_text_init,
553  .close = mov_text_decode_close,
555 };
uint64_t tracksize
Definition: movtextdec.c:99
#define AV_RB8(x)
Definition: intreadwrite.h:400
#define NULL
Definition: coverity.c:32
#define BOTTOM_RIGHT
Definition: movtextdec.c:43
#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:91
static const size_t box_count
Definition: movtextdec.c:335
#define TOP_LEFT
Definition: movtextdec.c:47
static int decode_twrp(const uint8_t *tsmb, MovTextContext *m, AVPacket *avpkt)
Definition: movtextdec.c:256
static void flush(AVCodecContext *avctx)
#define ASS_DEFAULT_BORDERSTYLE
Definition: ass.h:43
Memory handling functions.
int ff_ass_subtitle_header(AVCodecContext *avctx, const char *font, int font_size, int 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
char * font
Definition: movtextdec.c:64
uint8_t wrap_flag
Definition: movtextdec.c:85
#define AV_RB64
Definition: intreadwrite.h:164
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
int size
Definition: avcodec.h:1680
uint16_t style_fontID
Definition: movtextdec.c:72
#define AV_RB24
Definition: intreadwrite.h:64
StyleBox * s_temp
Definition: movtextdec.c:90
unsigned num_rects
Definition: avcodec.h:4132
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:101
FontRecord * ftab_temp
Definition: movtextdec.c:94
uint8_t hlit_color[4]
Definition: movtextdec.c:81
AVCodec.
Definition: avcodec.h:3739
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:42
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:235
uint16_t style_entries
Definition: movtextdec.c:98
uint8_t
#define av_malloc(s)
#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:80
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1876
const char data[16]
Definition: mxf.c:90
static int mov_text_init(AVCodecContext *avctx)
Definition: movtextdec.c:416
static void mov_text_cleanup(MovTextContext *m)
Definition: movtextdec.c:111
uint8_t * data
Definition: avcodec.h:1679
#define STYL_BOX
Definition: movtextdec.c:36
#define AV_CODEC_FLAG2_RO_FLUSH_NOOP
Do not reset ASS ReadOrder field on flush (subtitles decoding)
Definition: avcodec.h:984
#define av_log(a,...)
#define STYLE_FLAG_UNDERLINE
Definition: movtextdec.c:32
MovTextDefault d
Definition: movtextdec.c:96
uint16_t hlit_start
Definition: movtextdec.c:76
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
TextWrapBox w
Definition: movtextdec.c:95
#define AV_BPRINT_SIZE_UNLIMITED
uint8_t style_flag
Definition: movtextdec.c:70
#define AV_RB16
Definition: intreadwrite.h:53
#define AVERROR(e)
Definition: error.h:43
static const Box box_types[]
Definition: movtextdec.c:328
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:181
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:222
const char * name
Name of the codec implementation.
Definition: avcodec.h:3746
#define TWRP_BOX
Definition: movtextdec.c:39
static void mov_text_flush(AVCodecContext *avctx)
Definition: movtextdec.c:538
#define STYLE_FLAG_ITALIC
Definition: movtextdec.c:31
uint8_t box_flags
Definition: movtextdec.c:97
#define HLIT_BOX
Definition: movtextdec.c:37
#define FFMIN(a, b)
Definition: common.h:96
uint16_t hlit_end
Definition: movtextdec.c:77
uint32_t type
Definition: movtextdec.c:106
uint16_t style_start
Definition: movtextdec.c:68
#define FF_ARRAY_ELEMS(a)
static int decode_hlit(const uint8_t *tsmb, MovTextContext *m, AVPacket *avpkt)
Definition: movtextdec.c:263
int(* decode)(const uint8_t *tsmb, MovTextContext *m, AVPacket *avpkt)
Definition: movtextdec.c:108
#define TOP_RIGHT
Definition: movtextdec.c:49
HilightcolorBox c
Definition: movtextdec.c:92
Libavcodec external API header.
uint16_t ftab_entries
Definition: movtextdec.c:98
uint16_t style_end
Definition: movtextdec.c:69
main external API structure.
Definition: avcodec.h:1761
void * buf
Definition: avisynth_c.h:690
#define BOTTOM_CENTER
Definition: movtextdec.c:42
int extradata_size
Definition: avcodec.h:1877
size_t base_size
Definition: movtextdec.c:107
StyleBox ** s
Definition: movtextdec.c:89
#define BOX_SIZE_INITIAL
Definition: movtextdec.c:34
static int decode_hclr(const uint8_t *tsmb, MovTextContext *m, AVPacket *avpkt)
Definition: movtextdec.c:273
#define STYLE_FLAG_BOLD
Definition: movtextdec.c:30
#define MIDDLE_CENTER
Definition: movtextdec.c:45
uint16_t fontID
Definition: movtextdec.c:63
int
#define BOTTOM_LEFT
Definition: movtextdec.c:41
common internal and external API header
static int decode_styl(const uint8_t *tsmb, MovTextContext *m, AVPacket *avpkt)
Definition: movtextdec.c:281
uint8_t fontsize
Definition: movtextdec.c:71
static int mov_text_decode_close(AVCodecContext *avctx)
Definition: movtextdec.c:530
AVCodec ff_movtext_decoder
Definition: movtextdec.c:545
#define MKBETAG(a, b, c, d)
Definition: common.h:343
void * priv_data
Definition: avcodec.h:1803
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:294
static void mov_text_cleanup_ftab(MovTextContext *m)
Definition: movtextdec.c:124
int flags2
AV_CODEC_FLAG2_*.
Definition: avcodec.h:1863
#define HCLR_BOX
Definition: movtextdec.c:38
#define av_freep(p)
#define MIDDLE_RIGHT
Definition: movtextdec.c:46
#define MIDDLE_LEFT
Definition: movtextdec.c:44
FontRecord ** ftab
Definition: movtextdec.c:93
#define TOP_CENTER
Definition: movtextdec.c:48
static int mov_text_decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, AVPacket *avpkt)
Definition: movtextdec.c:435
This structure stores compressed data.
Definition: avcodec.h:1656
static int mov_text_tx3g(AVCodecContext *avctx, MovTextContext *m)
Definition: movtextdec.c:139
static int text_to_ass(AVBPrint *buf, const char *text, const char *text_end, MovTextContext *m)
Definition: movtextdec.c:337
void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
Append char c n times to a print buffer.
Definition: bprint.c:140