FFmpeg
movtextenc.c
Go to the documentation of this file.
1 /*
2  * 3GPP TS 26.245 Timed Text encoder
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 <stdarg.h>
23 #include "avcodec.h"
24 #include "libavutil/attributes.h"
25 #include "libavutil/opt.h"
26 #include "libavutil/intreadwrite.h"
27 #include "libavutil/mem.h"
28 #include "libavutil/common.h"
29 #include "ass_split.h"
30 #include "ass.h"
31 #include "bytestream.h"
32 #include "codec_internal.h"
33 
34 #define STYLE_FLAG_BOLD (1<<0)
35 #define STYLE_FLAG_ITALIC (1<<1)
36 #define STYLE_FLAG_UNDERLINE (1<<2)
37 #define STYLE_RECORD_SIZE 12
38 #define SIZE_ADD 10
39 
40 #define STYL_BOX (1<<0)
41 #define HLIT_BOX (1<<1)
42 #define HCLR_BOX (1<<2)
43 
44 #define DEFAULT_STYLE_FONT_ID 0x01
45 #define DEFAULT_STYLE_FONTSIZE 0x12
46 #define DEFAULT_STYLE_COLOR 0xffffffff
47 #define DEFAULT_STYLE_FLAG 0x00
48 
49 #define BGR_TO_RGB(c) (((c) & 0xff) << 16 | ((c) & 0xff00) | (((uint32_t)(c) >> 16) & 0xff))
50 #define FONTSIZE_SCALE(s,fs) ((fs) * (s)->font_scale_factor + 0.5)
51 #define av_bprint_append_any(buf, data, size) av_bprint_append_data(buf, ((const char*)data), size)
52 
53 typedef struct {
54  uint16_t style_start;
55  uint16_t style_end;
56  uint8_t style_flag;
57  uint16_t style_fontID;
58  uint8_t style_fontsize;
59  uint32_t style_color;
60 } StyleBox;
61 
62 typedef struct {
63  uint16_t start;
64  uint16_t end;
65 } HighlightBox;
66 
67 typedef struct {
68  uint32_t color;
70 
71 typedef struct {
72  AVClass *class;
74 
78  unsigned count;
81  AVBPrint buffer;
84  uint8_t box_flags;
86  uint16_t text_pos;
87  char **fonts;
90  int frame_height;
92 
93 typedef struct {
94  void (*encode)(MovTextContext *s);
95 } Box;
96 
98 {
99  s->count = 0;
100  s->style_attributes_temp = s->d;
101 }
102 
104 {
105  if ((s->box_flags & STYL_BOX) && s->count) {
106  uint8_t buf[12], *p = buf;
107 
108  bytestream_put_be32(&p, s->count * STYLE_RECORD_SIZE + SIZE_ADD);
109  bytestream_put_be32(&p, MKBETAG('s','t','y','l'));
110  bytestream_put_be16(&p, s->count);
111  /*The above three attributes are hard coded for now
112  but will come from ASS style in the future*/
113  av_bprint_append_any(&s->buffer, buf, 10);
114  for (unsigned j = 0; j < s->count; j++) {
115  const StyleBox *style = &s->style_attributes[j];
116 
117  p = buf;
118  bytestream_put_be16(&p, style->style_start);
119  bytestream_put_be16(&p, style->style_end);
120  bytestream_put_be16(&p, style->style_fontID);
121  bytestream_put_byte(&p, style->style_flag);
122  bytestream_put_byte(&p, style->style_fontsize);
123  bytestream_put_be32(&p, style->style_color);
124 
125  av_bprint_append_any(&s->buffer, buf, 12);
126  }
127  }
129 }
130 
132 {
133  if (s->box_flags & HLIT_BOX) {
134  uint8_t buf[12], *p = buf;
135 
136  bytestream_put_be32(&p, 12);
137  bytestream_put_be32(&p, MKBETAG('h','l','i','t'));
138  bytestream_put_be16(&p, s->hlit.start);
139  bytestream_put_be16(&p, s->hlit.end);
140 
141  av_bprint_append_any(&s->buffer, buf, 12);
142  }
143 }
144 
146 {
147  if (s->box_flags & HCLR_BOX) {
148  uint8_t buf[12], *p = buf;
149 
150  bytestream_put_be32(&p, 12);
151  bytestream_put_be32(&p, MKBETAG('h','c','l','r'));
152  bytestream_put_be32(&p, s->hclr.color);
153 
154  av_bprint_append_any(&s->buffer, buf, 12);
155  }
156 }
157 
158 static const Box box_types[] = {
159  { encode_styl },
160  { encode_hlit },
161  { encode_hclr },
162 };
163 
164 const static size_t box_count = FF_ARRAY_ELEMS(box_types);
165 
167 {
168  MovTextContext *s = avctx->priv_data;
169 
170  ff_ass_split_free(s->ass_ctx);
171  av_freep(&s->style_attributes);
172  av_freep(&s->fonts);
173  return 0;
174 }
175 
177 {
178  ASS *ass;
179  ASSStyle *style;
180  int i, j;
181  uint32_t back_color = 0;
182  int font_names_total_len = 0;
183  MovTextContext *s = avctx->priv_data;
184  uint8_t buf[30], *p = buf;
185  int ret;
186 
187  av_bprint_init(&s->buffer, 0, INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE + 1);
188 
189  // 0x00, 0x00, 0x00, 0x00, // uint32_t displayFlags
190  // 0x01, // int8_t horizontal-justification
191  // 0xFF, // int8_t vertical-justification
192  // 0x00, 0x00, 0x00, 0x00, // uint8_t background-color-rgba[4]
193  // BoxRecord {
194  // 0x00, 0x00, // int16_t top
195  // 0x00, 0x00, // int16_t left
196  // 0x00, 0x00, // int16_t bottom
197  // 0x00, 0x00, // int16_t right
198  // };
199  // StyleRecord {
200  // 0x00, 0x00, // uint16_t startChar
201  // 0x00, 0x00, // uint16_t endChar
202  // 0x00, 0x01, // uint16_t font-ID
203  // 0x00, // uint8_t face-style-flags
204  // 0x12, // uint8_t font-size
205  // 0xFF, 0xFF, 0xFF, 0xFF, // uint8_t text-color-rgba[4]
206  // };
207  // FontTableBox {
208  // 0x00, 0x00, 0x00, 0x12, // uint32_t size
209  // 'f', 't', 'a', 'b', // uint8_t name[4]
210  // 0x00, 0x01, // uint16_t entry-count
211  // FontRecord {
212  // 0x00, 0x01, // uint16_t font-ID
213  // 0x05, // uint8_t font-name-length
214  // 'S', 'e', 'r', 'i', 'f',// uint8_t font[font-name-length]
215  // };
216  // };
217 
218  // Populate sample description from ASS header
219  ass = (ASS*)s->ass_ctx;
220  // Compute font scaling factor based on (optionally) provided
221  // output video height and ASS script play_res_y
222  if (s->frame_height && ass->script_info.play_res_y)
223  s->font_scale_factor = (double)s->frame_height / ass->script_info.play_res_y;
224  else
225  s->font_scale_factor = 1;
226 
227  style = ff_ass_style_get(s->ass_ctx, "Default");
228  if (!style && ass->styles_count) {
229  style = &ass->styles[0];
230  }
231  s->d.style_fontID = DEFAULT_STYLE_FONT_ID;
232  s->d.style_fontsize = DEFAULT_STYLE_FONTSIZE;
233  s->d.style_color = DEFAULT_STYLE_COLOR;
234  s->d.style_flag = DEFAULT_STYLE_FLAG;
235  if (style) {
236  s->d.style_fontsize = FONTSIZE_SCALE(s, style->font_size);
237  s->d.style_color = BGR_TO_RGB(style->primary_color & 0xffffff) << 8 |
238  255 - ((uint32_t)style->primary_color >> 24);
239  s->d.style_flag = (!!style->bold * STYLE_FLAG_BOLD) |
240  (!!style->italic * STYLE_FLAG_ITALIC) |
241  (!!style->underline * STYLE_FLAG_UNDERLINE);
242  back_color = (BGR_TO_RGB(style->back_color & 0xffffff) << 8) |
243  (255 - ((uint32_t)style->back_color >> 24));
244  }
245 
246  bytestream_put_be32(&p, 0); // displayFlags
247  bytestream_put_be16(&p, 0x01FF); // horizontal/vertical justification (2x int8_t)
248  bytestream_put_be32(&p, back_color);
249  bytestream_put_be64(&p, 0); // BoxRecord - 4xint16_t: top, left, bottom, right
250  // StyleRecord {
251  bytestream_put_be16(&p, s->d.style_start);
252  bytestream_put_be16(&p, s->d.style_end);
253  bytestream_put_be16(&p, s->d.style_fontID);
254  bytestream_put_byte(&p, s->d.style_flag);
255  bytestream_put_byte(&p, s->d.style_fontsize);
256  bytestream_put_be32(&p, s->d.style_color);
257  // };
258  av_bprint_append_any(&s->buffer, buf, 30);
259 
260  // Build font table
261  // We can't build a complete font table since that would require
262  // scanning all dialogs first. But we can at least fill in what
263  // is available in the ASS header
264  if (style && ass->styles_count) {
265  // Find unique font names
266  if (style->font_name) {
267  av_dynarray_add(&s->fonts, &s->font_count, style->font_name);
268  font_names_total_len += strlen(style->font_name);
269  }
270  for (i = 0; i < ass->styles_count; i++) {
271  int found = 0;
272  if (!ass->styles[i].font_name)
273  continue;
274  for (j = 0; j < s->font_count; j++) {
275  if (!strcmp(s->fonts[j], ass->styles[i].font_name)) {
276  found = 1;
277  break;
278  }
279  }
280  if (!found) {
281  av_dynarray_add(&s->fonts, &s->font_count,
282  ass->styles[i].font_name);
283  font_names_total_len += strlen(ass->styles[i].font_name);
284  }
285  }
286  } else
287  av_dynarray_add(&s->fonts, &s->font_count, (char*)"Serif");
288 
289  // FontTableBox {
290  p = buf;
291  bytestream_put_be32(&p, SIZE_ADD + 3 * s->font_count + font_names_total_len); // Size
292  bytestream_put_be32(&p, MKBETAG('f','t','a','b'));
293  bytestream_put_be16(&p, s->font_count);
294 
295  av_bprint_append_any(&s->buffer, buf, 10);
296  // FontRecord {
297  for (i = 0; i < s->font_count; i++) {
298  size_t len = strlen(s->fonts[i]);
299 
300  p = buf;
301  bytestream_put_be16(&p, i + 1); //fontID
302  bytestream_put_byte(&p, len);
303 
304  av_bprint_append_any(&s->buffer, buf, 3);
305  av_bprint_append_any(&s->buffer, s->fonts[i], len);
306  }
307  // };
308  // };
309 
310  if (!av_bprint_is_complete(&s->buffer)) {
311  ret = AVERROR(ENOMEM);
312  goto fail;
313  }
314 
315  avctx->extradata_size = s->buffer.len;
317  if (!avctx->extradata) {
318  ret = AVERROR(ENOMEM);
319  goto fail;
320  }
321 
322  memcpy(avctx->extradata, s->buffer.str, avctx->extradata_size);
323  ret = 0;
324 fail:
325  av_bprint_finalize(&s->buffer, NULL);
326 
327  return ret;
328 }
329 
331 {
332  int ret;
333  MovTextContext *s = avctx->priv_data;
334  s->avctx = avctx;
335 
336  s->ass_ctx = ff_ass_split(avctx->subtitle_header);
337  if (!s->ass_ctx)
338  return AVERROR_INVALIDDATA;
340  if (ret < 0)
341  return ret;
342 
343  return 0;
344 }
345 
346 // Start a new style box if needed
348 {
349  // there's an existing style entry
350  if (s->style_attributes_temp.style_start == s->text_pos)
351  // Still at same text pos, use same entry
352  return 1;
353  if (s->style_attributes_temp.style_flag != s->d.style_flag ||
354  s->style_attributes_temp.style_color != s->d.style_color ||
355  s->style_attributes_temp.style_fontID != s->d.style_fontID ||
356  s->style_attributes_temp.style_fontsize != s->d.style_fontsize) {
357  StyleBox *tmp;
358 
359  // last style != defaults, end the style entry and start a new one
360  if (s->count + 1 > FFMIN(SIZE_MAX / sizeof(*s->style_attributes), UINT16_MAX) ||
361  !(tmp = av_fast_realloc(s->style_attributes,
362  &s->style_attributes_bytes_allocated,
363  (s->count + 1) * sizeof(*s->style_attributes)))) {
365  av_bprint_clear(&s->buffer);
366  s->box_flags &= ~STYL_BOX;
367  return 0;
368  }
369  s->style_attributes = tmp;
370  s->style_attributes_temp.style_end = s->text_pos;
371  s->style_attributes[s->count++] = s->style_attributes_temp;
372  s->box_flags |= STYL_BOX;
373  s->style_attributes_temp = s->d;
374  s->style_attributes_temp.style_start = s->text_pos;
375  } else { // style entry matches defaults, drop entry
376  s->style_attributes_temp = s->d;
377  s->style_attributes_temp.style_start = s->text_pos;
378  }
379  return 1;
380 }
381 
382 static uint8_t mov_text_style_to_flag(const char style)
383 {
384  uint8_t style_flag = 0;
385 
386  switch (style){
387  case 'b':
388  style_flag = STYLE_FLAG_BOLD;
389  break;
390  case 'i':
391  style_flag = STYLE_FLAG_ITALIC;
392  break;
393  case 'u':
394  style_flag = STYLE_FLAG_UNDERLINE;
395  break;
396  }
397  return style_flag;
398 }
399 
400 static void mov_text_style_set(MovTextContext *s, uint8_t style_flags)
401 {
402  if (!((s->style_attributes_temp.style_flag & style_flags) ^ style_flags)) {
403  // setting flags that that are already set
404  return;
405  }
406  if (mov_text_style_start(s))
407  s->style_attributes_temp.style_flag |= style_flags;
408 }
409 
410 static void mov_text_style_cb(void *priv, const char style, int close)
411 {
412  MovTextContext *s = priv;
413  uint8_t style_flag = mov_text_style_to_flag(style);
414 
415  if (!!(s->style_attributes_temp.style_flag & style_flag) != close) {
416  // setting flag that is already set
417  return;
418  }
419  if (mov_text_style_start(s)) {
420  if (!close)
421  s->style_attributes_temp.style_flag |= style_flag;
422  else
423  s->style_attributes_temp.style_flag &= ~style_flag;
424  }
425 }
426 
427 static void mov_text_color_set(MovTextContext *s, uint32_t color)
428 {
429  if ((s->style_attributes_temp.style_color & 0xffffff00) == color) {
430  // color hasn't changed
431  return;
432  }
433  if (mov_text_style_start(s))
434  s->style_attributes_temp.style_color = (color & 0xffffff00) |
435  (s->style_attributes_temp.style_color & 0xff);
436 }
437 
438 static void mov_text_color_cb(void *priv, unsigned int color, unsigned int color_id)
439 {
440  MovTextContext *s = priv;
441 
442  color = BGR_TO_RGB(color) << 8;
443  if (color_id == 1) { //primary color changes
445  } else if (color_id == 2) { //secondary color changes
446  if (!(s->box_flags & HCLR_BOX))
447  // Highlight alpha not set yet, use current primary alpha
448  s->hclr.color = s->style_attributes_temp.style_color;
449  if (!(s->box_flags & HLIT_BOX) || s->hlit.start == s->text_pos) {
450  s->box_flags |= HCLR_BOX;
451  s->box_flags |= HLIT_BOX;
452  s->hlit.start = s->text_pos;
453  s->hclr.color = color | (s->hclr.color & 0xFF);
454  }
455  else //close tag
456  s->hlit.end = s->text_pos;
457  /* If there are more than one secondary color changes in ASS,
458  take start of first section and end of last section. Movtext
459  allows only one highlight box per sample.
460  */
461  }
462  // Movtext does not support changes to other color_id (outline, background)
463 }
464 
465 static void mov_text_alpha_set(MovTextContext *s, uint8_t alpha)
466 {
467  if ((s->style_attributes_temp.style_color & 0xff) == alpha) {
468  // color hasn't changed
469  return;
470  }
471  if (mov_text_style_start(s))
472  s->style_attributes_temp.style_color =
473  (s->style_attributes_temp.style_color & 0xffffff00) | alpha;
474 }
475 
476 static void mov_text_alpha_cb(void *priv, int alpha, int alpha_id)
477 {
478  MovTextContext *s = priv;
479 
480  alpha = 255 - alpha;
481  if (alpha_id == 1) // primary alpha changes
483  else if (alpha_id == 2) { //secondary alpha changes
484  if (!(s->box_flags & HCLR_BOX))
485  // Highlight color not set yet, use current primary color
486  s->hclr.color = s->style_attributes_temp.style_color;
487  if (!(s->box_flags & HLIT_BOX) || s->hlit.start == s->text_pos) {
488  s->box_flags |= HCLR_BOX;
489  s->box_flags |= HLIT_BOX;
490  s->hlit.start = s->text_pos;
491  s->hclr.color = (s->hclr.color & 0xffffff00) | alpha;
492  }
493  else //close tag
494  s->hlit.end = s->text_pos;
495  }
496  // Movtext does not support changes to other alpha_id (outline, background)
497 }
498 
499 static uint16_t find_font_id(MovTextContext *s, const char *name)
500 {
501  if (!name)
502  return 1;
503 
504  for (int i = 0; i < s->font_count; i++) {
505  if (!strcmp(name, s->fonts[i]))
506  return i + 1;
507  }
508  return 1;
509 }
510 
511 static void mov_text_font_name_set(MovTextContext *s, const char *name)
512 {
513  int fontID = find_font_id(s, name);
514  if (s->style_attributes_temp.style_fontID == fontID) {
515  // color hasn't changed
516  return;
517  }
518  if (mov_text_style_start(s))
519  s->style_attributes_temp.style_fontID = fontID;
520 }
521 
522 static void mov_text_font_name_cb(void *priv, const char *name)
523 {
525 }
526 
528 {
530  if (s->style_attributes_temp.style_fontsize == size) {
531  // color hasn't changed
532  return;
533  }
534  if (mov_text_style_start(s))
535  s->style_attributes_temp.style_fontsize = size;
536 }
537 
538 static void mov_text_font_size_cb(void *priv, int size)
539 {
541 }
542 
543 static void mov_text_end_cb(void *priv)
544 {
545  // End of text, close any open style record
547 }
548 
550 {
551  uint8_t style_flags, alpha;
552  uint32_t color;
553 
554  if (style) {
555  style_flags = (!!style->bold * STYLE_FLAG_BOLD) |
556  (!!style->italic * STYLE_FLAG_ITALIC) |
557  (!!style->underline * STYLE_FLAG_UNDERLINE);
558  mov_text_style_set(s, style_flags);
559  color = BGR_TO_RGB(style->primary_color & 0xffffff) << 8;
561  alpha = 255 - ((uint32_t)style->primary_color >> 24);
565  } else {
566  // End current style record, go back to defaults
568  }
569 }
570 
572 {
573  ASSStyle *style = ff_ass_style_get(s->ass_ctx, dialog->style);
574 
575  s->ass_dialog_style = style;
576  mov_text_ass_style_set(s, style);
577 }
578 
579 static void mov_text_cancel_overrides_cb(void *priv, const char *style_name)
580 {
581  MovTextContext *s = priv;
582  ASSStyle *style;
583 
584  if (!style_name || !*style_name)
585  style = s->ass_dialog_style;
586  else
587  style= ff_ass_style_get(s->ass_ctx, style_name);
588 
589  mov_text_ass_style_set(s, style);
590 }
591 
592 static unsigned utf8_strlen(const char *text, int len)
593 {
594  unsigned i = 0, ret = 0;
595  while (i < len) {
596  char c = text[i];
597  if ((c & 0x80) == 0)
598  i += 1;
599  else if ((c & 0xE0) == 0xC0)
600  i += 2;
601  else if ((c & 0xF0) == 0xE0)
602  i += 3;
603  else if ((c & 0xF8) == 0xF0)
604  i += 4;
605  else
606  return 0;
607  ret++;
608  }
609  return ret;
610 }
611 
612 static void mov_text_text_cb(void *priv, const char *text, int len)
613 {
614  unsigned utf8_len = utf8_strlen(text, len);
615  MovTextContext *s = priv;
616  av_bprint_append_data(&s->buffer, text, len);
617  // If it's not utf-8, just use the byte length
618  s->text_pos += utf8_len ? utf8_len : len;
619 }
620 
621 static void mov_text_new_line_cb(void *priv, int forced)
622 {
623  MovTextContext *s = priv;
624  s->text_pos += 1;
625  av_bprint_chars(&s->buffer, '\n', 1);
626 }
627 
630  .new_line = mov_text_new_line_cb,
631  .style = mov_text_style_cb,
632  .color = mov_text_color_cb,
633  .alpha = mov_text_alpha_cb,
634  .font_name = mov_text_font_name_cb,
635  .font_size = mov_text_font_size_cb,
636  .cancel_overrides = mov_text_cancel_overrides_cb,
637  .end = mov_text_end_cb,
638 };
639 
640 static int mov_text_encode_frame(AVCodecContext *avctx, unsigned char *buf,
641  int bufsize, const AVSubtitle *sub)
642 {
643  MovTextContext *s = avctx->priv_data;
644  ASSDialog *dialog;
645  int i, length;
646 
647  if (bufsize < 3)
648  goto too_small;
649 
650  s->text_pos = 0;
651  s->count = 0;
652  s->box_flags = 0;
653 
654  av_bprint_init_for_buffer(&s->buffer, buf + 2, bufsize - 2);
655  for (i = 0; i < sub->num_rects; i++) {
656  const char *ass = sub->rects[i]->ass;
657 
658  if (sub->rects[i]->type != SUBTITLE_ASS) {
659  av_log(avctx, AV_LOG_ERROR, "Only SUBTITLE_ASS type supported.\n");
660  return AVERROR(EINVAL);
661  }
662 
663  dialog = ff_ass_split_dialog(s->ass_ctx, ass);
664  if (!dialog)
665  return AVERROR(ENOMEM);
666  mov_text_dialog(s, dialog);
668  ff_ass_free_dialog(&dialog);
669  }
670 
671  if (s->buffer.len > UINT16_MAX)
672  return AVERROR(ERANGE);
673  AV_WB16(buf, s->buffer.len);
674 
675  for (size_t j = 0; j < box_count; j++)
676  box_types[j].encode(s);
677 
678  if (!s->buffer.len)
679  return 0;
680 
681  if (!av_bprint_is_complete(&s->buffer)) {
682 too_small:
683  av_log(avctx, AV_LOG_ERROR, "Buffer too small for ASS event.\n");
685  }
686 
687  length = s->buffer.len + 2;
688 
689  return length;
690 }
691 
692 #define OFFSET(x) offsetof(MovTextContext, x)
693 #define FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_SUBTITLE_PARAM
694 static const AVOption options[] = {
695  { "height", "Frame height, usually video height", OFFSET(frame_height), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGS },
696  { NULL },
697 };
698 
700  .class_name = "MOV text enoder",
701  .item_name = av_default_item_name,
702  .option = options,
703  .version = LIBAVUTIL_VERSION_INT,
704 };
705 
707  .p.name = "mov_text",
708  CODEC_LONG_NAME("3GPP Timed Text subtitle"),
709  .p.type = AVMEDIA_TYPE_SUBTITLE,
710  .p.id = AV_CODEC_ID_MOV_TEXT,
711  .priv_data_size = sizeof(MovTextContext),
712  .p.priv_class = &mov_text_encoder_class,
713  .init = mov_text_encode_init,
715  .close = mov_text_encode_close,
716  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
717 };
AVSubtitle
Definition: avcodec.h:2082
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:203
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
MovTextContext::avctx
AVCodecContext * avctx
Definition: movtextenc.c:73
StyleBox::style_start
uint16_t style_start
Definition: movtextenc.c:54
FF_CODEC_CAP_INIT_CLEANUP
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: codec_internal.h:42
utf8_strlen
static unsigned utf8_strlen(const char *text, int len)
Definition: movtextenc.c:592
ASSCodesCallbacks
Set of callback functions corresponding to each override codes that can be encountered in a "Dialogue...
Definition: ass_split.h:138
av_bprint_is_complete
static int av_bprint_is_complete(const AVBPrint *buf)
Test if the print buffer is complete (not truncated).
Definition: bprint.h:218
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
AVSubtitle::rects
AVSubtitleRect ** rects
Definition: avcodec.h:2087
opt.h
mov_text_dialog
static void mov_text_dialog(MovTextContext *s, ASSDialog *dialog)
Definition: movtextenc.c:571
color
Definition: vf_paletteuse.c:513
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
MovTextContext::d
StyleBox d
Definition: movtextenc.c:85
mov_text_cancel_overrides_cb
static void mov_text_cancel_overrides_cb(void *priv, const char *style_name)
Definition: movtextenc.c:579
AVSubtitle::num_rects
unsigned num_rects
Definition: avcodec.h:2086
StyleBox::style_fontID
uint16_t style_fontID
Definition: movtextenc.c:57
ff_ass_split_dialog
ASSDialog * ff_ass_split_dialog(ASSSplitContext *ctx, const char *buf)
Split one ASS Dialogue line from a string buffer.
Definition: ass_split.c:433
AVOption
AVOption.
Definition: opt.h:429
mov_text_font_name_set
static void mov_text_font_name_set(MovTextContext *s, const char *name)
Definition: movtextenc.c:511
options
static const AVOption options[]
Definition: movtextenc.c:694
ASS::styles
ASSStyle * styles
array of split out styles
Definition: ass_split.h:92
ASSStyle::font_size
int font_size
font height
Definition: ass_split.h:42
FFCodec
Definition: codec_internal.h:127
AVCodecContext::subtitle_header
uint8_t * subtitle_header
Definition: avcodec.h:1739
mov_text_encode_init
static av_cold int mov_text_encode_init(AVCodecContext *avctx)
Definition: movtextenc.c:330
HighlightBox
Definition: movtextdec.c:82
MovTextContext::font_scale_factor
double font_scale_factor
Definition: movtextenc.c:89
box_count
const static size_t box_count
Definition: movtextenc.c:164
ASSDialog::style
char * style
name of the ASSStyle to use with this dialog
Definition: ass_split.h:76
OFFSET
#define OFFSET(x)
Definition: movtextenc.c:692
mov_text_color_set
static void mov_text_color_set(MovTextContext *s, uint32_t color)
Definition: movtextenc.c:427
DEFAULT_STYLE_FONT_ID
#define DEFAULT_STYLE_FONT_ID
Definition: movtextenc.c:44
mov_text_encoder_class
static const AVClass mov_text_encoder_class
Definition: movtextenc.c:699
SUBTITLE_ASS
@ SUBTITLE_ASS
Formatted text, the ass field must be set by the decoder and is authoritative.
Definition: avcodec.h:2050
ASSStyle::font_name
char * font_name
font face (case sensitive)
Definition: ass_split.h:41
close
static av_cold void close(AVCodecParserContext *s)
Definition: apv_parser.c:135
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
av_bprint_init_for_buffer
void av_bprint_init_for_buffer(AVBPrint *buf, char *buffer, unsigned size)
Init a print buffer using a pre-existing buffer.
Definition: bprint.c:85
mov_text_font_size_set
static void mov_text_font_size_set(MovTextContext *s, int size)
Definition: movtextenc.c:527
Box
Definition: movtextdec.c:110
mov_text_alpha_set
static void mov_text_alpha_set(MovTextContext *s, uint8_t alpha)
Definition: movtextenc.c:465
fail
#define fail()
Definition: checkasm.h:200
StyleBox
Definition: movtextdec.c:61
ass_split.h
mov_text_color_cb
static void mov_text_color_cb(void *priv, unsigned int color, unsigned int color_id)
Definition: movtextenc.c:438
AVERROR_BUFFER_TOO_SMALL
#define AVERROR_BUFFER_TOO_SMALL
Buffer too small.
Definition: error.h:53
ff_ass_split_free
av_cold void ff_ass_split_free(ASSSplitContext *ctx)
Free all the memory allocated for an ASSSplitContext.
Definition: ass_split.c:470
FONTSIZE_SCALE
#define FONTSIZE_SCALE(s, fs)
Definition: movtextenc.c:50
HilightcolorBox::color
uint32_t color
Definition: movtextenc.c:68
STYL_BOX
#define STYL_BOX
Definition: movtextenc.c:40
AVSubtitleRect::ass
char * ass
0 terminated ASS/SSA compatible event line.
Definition: avcodec.h:2079
ass.h
ff_ass_free_dialog
void ff_ass_free_dialog(ASSDialog **dialogp)
Free a dialogue obtained from ff_ass_split_dialog().
Definition: ass_split.c:421
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
mov_text_text_cb
static void mov_text_text_cb(void *priv, const char *text, int len)
Definition: movtextenc.c:612
mov_text_style_start
static int mov_text_style_start(MovTextContext *s)
Definition: movtextenc.c:347
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:515
box_types
static const Box box_types[]
Definition: movtextenc.c:158
av_fast_realloc
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition: mem.c:497
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
mov_text_cleanup
static void mov_text_cleanup(MovTextContext *s)
Definition: movtextenc.c:97
STYLE_FLAG_UNDERLINE
#define STYLE_FLAG_UNDERLINE
Definition: movtextenc.c:36
MovTextContext::fonts
char ** fonts
Definition: movtextenc.c:87
FLAGS
#define FLAGS
Definition: movtextenc.c:693
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:331
tmp
static uint8_t tmp[40]
Definition: aes_ctr.c:52
MovTextContext::font_count
int font_count
Definition: movtextenc.c:88
if
if(ret)
Definition: filter_design.txt:179
ASSScriptInfo::play_res_y
int play_res_y
video height that ASS coords are referring to
Definition: ass_split.h:32
STYLE_FLAG_ITALIC
#define STYLE_FLAG_ITALIC
Definition: movtextenc.c:35
HLIT_BOX
#define HLIT_BOX
Definition: movtextenc.c:41
ASS
structure containing the whole split ASS data
Definition: ass_split.h:90
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
StyleBox::style_end
uint16_t style_end
Definition: movtextenc.c:55
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
NULL
#define NULL
Definition: coverity.c:32
MovTextContext::style_attributes
StyleBox * style_attributes
Definition: movtextenc.c:77
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:401
AV_CODEC_ID_MOV_TEXT
@ AV_CODEC_ID_MOV_TEXT
Definition: codec_id.h:567
ASSStyle::primary_color
int primary_color
color that a subtitle will normally appear in
Definition: ass_split.h:43
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:241
options
Definition: swscale.c:43
FF_CODEC_ENCODE_SUB_CB
#define FF_CODEC_ENCODE_SUB_CB(func)
Definition: codec_internal.h:362
ASSSplitContext
This struct can be casted to ASS to access to the split data.
Definition: ass_split.c:205
double
double
Definition: af_crystalizer.c:132
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
ASSStyle
fields extracted from the [V4(+) Styles] section
Definition: ass_split.h:39
mov_text_style_to_flag
static uint8_t mov_text_style_to_flag(const char style)
Definition: movtextenc.c:382
ASSStyle::underline
int underline
whether text is underlined (1) or not (0)
Definition: ass_split.h:49
DEFAULT_STYLE_COLOR
#define DEFAULT_STYLE_COLOR
Definition: movtextenc.c:46
av_dynarray_add
void av_dynarray_add(void *tab_ptr, int *nb_ptr, void *elem)
Add the pointer to an element to a dynamic array.
Definition: mem.c:329
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:235
codec_internal.h
ASSDialog::text
char * text
actual text which will be displayed as a subtitle, can include style override control codes (see ff_a...
Definition: ass_split.h:82
encode_styl
static void encode_styl(MovTextContext *s)
Definition: movtextenc.c:103
HighlightBox::end
uint16_t end
Definition: movtextenc.c:64
size
int size
Definition: twinvq_data.h:10344
color
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
Definition: log.c:97
mov_text_style_set
static void mov_text_style_set(MovTextContext *s, uint8_t style_flags)
Definition: movtextenc.c:400
ASSStyle::italic
int italic
whether text is italic (1) or not (0)
Definition: ass_split.h:48
MKBETAG
#define MKBETAG(a, b, c, d)
Definition: macros.h:56
MovTextContext::ass_dialog_style
ASSStyle * ass_dialog_style
Definition: movtextenc.c:76
AVSubtitleRect::type
enum AVSubtitleType type
Definition: avcodec.h:2070
encode
static void encode(AVCodecContext *ctx, AVFrame *frame, AVPacket *pkt, FILE *output)
Definition: encode_audio.c:94
DEFAULT_STYLE_FONTSIZE
#define DEFAULT_STYLE_FONTSIZE
Definition: movtextenc.c:45
MovTextContext::style_attributes_temp
StyleBox style_attributes_temp
Definition: movtextenc.c:80
attributes.h
StyleBox::style_flag
uint8_t style_flag
Definition: movtextenc.c:56
find_font_id
static uint16_t find_font_id(MovTextContext *s, const char *name)
Definition: movtextenc.c:499
mov_text_font_name_cb
static void mov_text_font_name_cb(void *priv, const char *name)
Definition: movtextenc.c:522
MovTextContext::count
unsigned count
Definition: movtextenc.c:78
ASSStyle::back_color
int back_color
color of the subtitle outline or shadow
Definition: ass_split.h:46
SIZE_ADD
#define SIZE_ADD
Definition: movtextenc.c:38
mov_text_callbacks
static const ASSCodesCallbacks mov_text_callbacks
Definition: movtextenc.c:628
ff_ass_style_get
ASSStyle * ff_ass_style_get(ASSSplitContext *ctx, const char *style)
Find an ASSStyle structure by its name.
Definition: ass_split.c:578
encode_sample_description
static int encode_sample_description(AVCodecContext *avctx)
Definition: movtextenc.c:176
STYLE_RECORD_SIZE
#define STYLE_RECORD_SIZE
Definition: movtextenc.c:37
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVCodecContext::extradata
uint8_t * extradata
Out-of-band global headers that may be used by some codecs.
Definition: avcodec.h:514
STYLE_FLAG_BOLD
#define STYLE_FLAG_BOLD
Definition: movtextenc.c:34
mov_text_encode_close
static av_cold int mov_text_encode_close(AVCodecContext *avctx)
Definition: movtextenc.c:166
common.h
StyleBox::style_color
uint32_t style_color
Definition: movtextenc.c:59
MovTextContext::hlit
HighlightBox hlit
Definition: movtextenc.c:82
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
mov_text_encode_frame
static int mov_text_encode_frame(AVCodecContext *avctx, unsigned char *buf, int bufsize, const AVSubtitle *sub)
Definition: movtextenc.c:640
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
encode_hlit
static void encode_hlit(MovTextContext *s)
Definition: movtextenc.c:131
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:179
mov_text_new_line_cb
static void mov_text_new_line_cb(void *priv, int forced)
Definition: movtextenc.c:621
ASS::styles_count
int styles_count
number of ASSStyle in the styles array
Definition: ass_split.h:93
len
int len
Definition: vorbis_enc_data.h:426
mov_text_end_cb
static void mov_text_end_cb(void *priv)
Definition: movtextenc.c:543
avcodec.h
encode_hclr
static void encode_hclr(MovTextContext *s)
Definition: movtextenc.c:145
ret
ret
Definition: filter_design.txt:187
BGR_TO_RGB
#define BGR_TO_RGB(c)
Definition: movtextenc.c:49
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:81
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
AVCodecContext
main external API structure.
Definition: avcodec.h:431
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
av_bprint_clear
void av_bprint_clear(AVBPrint *buf)
Reset the string to "" but keep internal allocated data.
Definition: bprint.c:227
mov_text_font_size_cb
static void mov_text_font_size_cb(void *priv, int size)
Definition: movtextenc.c:538
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
ASSDialog
fields extracted from the [Events] section
Definition: ass_split.h:71
MovTextContext::style_attributes_bytes_allocated
unsigned style_attributes_bytes_allocated
Definition: movtextenc.c:79
StyleBox::style_fontsize
uint8_t style_fontsize
Definition: movtextenc.c:58
av_bprint_append_any
#define av_bprint_append_any(buf, data, size)
Definition: movtextenc.c:51
MovTextContext::text_pos
uint16_t text_pos
Definition: movtextenc.c:86
HilightcolorBox
Definition: movtextdec.c:87
mem.h
mov_text_style_cb
static void mov_text_style_cb(void *priv, const char style, int close)
Definition: movtextenc.c:410
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:458
mov_text_ass_style_set
static void mov_text_ass_style_set(MovTextContext *s, ASSStyle *style)
Definition: movtextenc.c:549
MovTextContext::hclr
HilightcolorBox hclr
Definition: movtextenc.c:83
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
bytestream.h
DEFAULT_STYLE_FLAG
#define DEFAULT_STYLE_FLAG
Definition: movtextenc.c:47
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
ff_ass_split_override_codes
int ff_ass_split_override_codes(const ASSCodesCallbacks *callbacks, void *priv, const char *buf)
Split override codes out of a ASS "Dialogue" Text field.
Definition: ass_split.c:483
ff_movtext_encoder
const FFCodec ff_movtext_encoder
Definition: movtextenc.c:706
av_bprint_chars
void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
Append char c n times to a print buffer.
Definition: bprint.c:130
HighlightBox::start
uint16_t start
Definition: movtextenc.c:63
ff_ass_split
av_cold ASSSplitContext * ff_ass_split(const char *buf)
Split a full ASS file or a ASS header from a string buffer and store the split structure in a newly a...
Definition: ass_split.c:382
av_bprint_append_data
void av_bprint_append_data(AVBPrint *buf, const char *data, unsigned size)
Append data to a print buffer.
Definition: bprint.c:148
MovTextContext::ass_ctx
ASSSplitContext * ass_ctx
Definition: movtextenc.c:75
mov_text_alpha_cb
static void mov_text_alpha_cb(void *priv, int alpha, int alpha_id)
Definition: movtextenc.c:476
MovTextContext::buffer
AVBPrint buffer
Definition: movtextenc.c:81
MovTextContext
Definition: movtextdec.c:95
ASSStyle::bold
int bold
whether text is bold (1) or not (0)
Definition: ass_split.h:47
ASSCodesCallbacks::text
void(* text)(void *priv, const char *text, int len)
Definition: ass_split.h:143
HCLR_BOX
#define HCLR_BOX
Definition: movtextenc.c:42
ASS::script_info
ASSScriptInfo script_info
general information about the SSA script
Definition: ass_split.h:91