FFmpeg
movtextdec.c
Go to the documentation of this file.
1 /*
2  * 3GPP TS 26.245 Timed Text decoder
3  * Copyright (c) 2012 Philip Langdale <philipl@overt.org>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "avcodec.h"
23 #include "ass.h"
24 #include "libavutil/opt.h"
25 #include "libavutil/avstring.h"
26 #include "libavutil/common.h"
27 #include "libavutil/bprint.h"
28 #include "libavutil/intreadwrite.h"
29 #include "libavutil/mem.h"
30 
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 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:248
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
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
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
GLint GLenum type
Definition: opengl_enc.c:104
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
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:237
static void error(const char *err)
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:87
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
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
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
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
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:87
uint8_t underline
Definition: movtextdec.c:79
uint8_t alpha
Definition: movtextdec.c:59
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 AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
TextWrapBox w
Definition: movtextdec.c:107
#define AV_BPRINT_SIZE_UNLIMITED
uint8_t style_flag
Definition: movtextdec.c:76
#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:153
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: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
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_WB16 unsigned int_TMPL AV_RB8
Definition: bytestream.h:87
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.
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_RB24
Definition: bytestream.h:87
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
#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
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_RB64
Definition: bytestream.h:87
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 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:310
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
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
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
int i
Definition: input.c:406
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