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/opt.h"
25 #include "libavutil/avstring.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 "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  uint16_t byte_count;
88  char **fonts;
91  int frame_height;
93 
94 typedef struct {
95  void (*encode)(MovTextContext *s);
96 } Box;
97 
99 {
100  s->count = 0;
101  s->style_attributes_temp = s->d;
102 }
103 
105 {
106  if ((s->box_flags & STYL_BOX) && s->count) {
107  uint8_t buf[12], *p = buf;
108 
109  bytestream_put_be32(&p, s->count * STYLE_RECORD_SIZE + SIZE_ADD);
110  bytestream_put_be32(&p, MKBETAG('s','t','y','l'));
111  bytestream_put_be16(&p, s->count);
112  /*The above three attributes are hard coded for now
113  but will come from ASS style in the future*/
114  av_bprint_append_any(&s->buffer, buf, 10);
115  for (unsigned j = 0; j < s->count; j++) {
116  const StyleBox *style = &s->style_attributes[j];
117 
118  p = buf;
119  bytestream_put_be16(&p, style->style_start);
120  bytestream_put_be16(&p, style->style_end);
121  bytestream_put_be16(&p, style->style_fontID);
122  bytestream_put_byte(&p, style->style_flag);
123  bytestream_put_byte(&p, style->style_fontsize);
124  bytestream_put_be32(&p, style->style_color);
125 
126  av_bprint_append_any(&s->buffer, buf, 12);
127  }
128  }
130 }
131 
133 {
134  if (s->box_flags & HLIT_BOX) {
135  uint8_t buf[12], *p = buf;
136 
137  bytestream_put_be32(&p, 12);
138  bytestream_put_be32(&p, MKBETAG('h','l','i','t'));
139  bytestream_put_be16(&p, s->hlit.start);
140  bytestream_put_be16(&p, s->hlit.end);
141 
142  av_bprint_append_any(&s->buffer, buf, 12);
143  }
144 }
145 
147 {
148  if (s->box_flags & HCLR_BOX) {
149  uint8_t buf[12], *p = buf;
150 
151  bytestream_put_be32(&p, 12);
152  bytestream_put_be32(&p, MKBETAG('h','c','l','r'));
153  bytestream_put_be32(&p, s->hclr.color);
154 
155  av_bprint_append_any(&s->buffer, buf, 12);
156  }
157 }
158 
159 static const Box box_types[] = {
160  { encode_styl },
161  { encode_hlit },
162  { encode_hclr },
163 };
164 
165 const static size_t box_count = FF_ARRAY_ELEMS(box_types);
166 
168 {
169  MovTextContext *s = avctx->priv_data;
170 
171  ff_ass_split_free(s->ass_ctx);
172  av_freep(&s->style_attributes);
173  av_freep(&s->fonts);
174  av_bprint_finalize(&s->buffer, NULL);
175  return 0;
176 }
177 
179 {
180  ASS *ass;
181  ASSStyle *style;
182  int i, j;
183  uint32_t back_color = 0;
184  int font_names_total_len = 0;
185  MovTextContext *s = avctx->priv_data;
186  uint8_t buf[30], *p = buf;
187 
188  // 0x00, 0x00, 0x00, 0x00, // uint32_t displayFlags
189  // 0x01, // int8_t horizontal-justification
190  // 0xFF, // int8_t vertical-justification
191  // 0x00, 0x00, 0x00, 0x00, // uint8_t background-color-rgba[4]
192  // BoxRecord {
193  // 0x00, 0x00, // int16_t top
194  // 0x00, 0x00, // int16_t left
195  // 0x00, 0x00, // int16_t bottom
196  // 0x00, 0x00, // int16_t right
197  // };
198  // StyleRecord {
199  // 0x00, 0x00, // uint16_t startChar
200  // 0x00, 0x00, // uint16_t endChar
201  // 0x00, 0x01, // uint16_t font-ID
202  // 0x00, // uint8_t face-style-flags
203  // 0x12, // uint8_t font-size
204  // 0xFF, 0xFF, 0xFF, 0xFF, // uint8_t text-color-rgba[4]
205  // };
206  // FontTableBox {
207  // 0x00, 0x00, 0x00, 0x12, // uint32_t size
208  // 'f', 't', 'a', 'b', // uint8_t name[4]
209  // 0x00, 0x01, // uint16_t entry-count
210  // FontRecord {
211  // 0x00, 0x01, // uint16_t font-ID
212  // 0x05, // uint8_t font-name-length
213  // 'S', 'e', 'r', 'i', 'f',// uint8_t font[font-name-length]
214  // };
215  // };
216 
217  // Populate sample description from ASS header
218  ass = (ASS*)s->ass_ctx;
219  // Compute font scaling factor based on (optionally) provided
220  // output video height and ASS script play_res_y
221  if (s->frame_height && ass->script_info.play_res_y)
222  s->font_scale_factor = (double)s->frame_height / ass->script_info.play_res_y;
223  else
224  s->font_scale_factor = 1;
225 
226  style = ff_ass_style_get(s->ass_ctx, "Default");
227  if (!style && ass->styles_count) {
228  style = &ass->styles[0];
229  }
230  s->d.style_fontID = DEFAULT_STYLE_FONT_ID;
231  s->d.style_fontsize = DEFAULT_STYLE_FONTSIZE;
232  s->d.style_color = DEFAULT_STYLE_COLOR;
233  s->d.style_flag = DEFAULT_STYLE_FLAG;
234  if (style) {
235  s->d.style_fontsize = FONTSIZE_SCALE(s, style->font_size);
236  s->d.style_color = BGR_TO_RGB(style->primary_color & 0xffffff) << 8 |
237  255 - ((uint32_t)style->primary_color >> 24);
238  s->d.style_flag = (!!style->bold * STYLE_FLAG_BOLD) |
239  (!!style->italic * STYLE_FLAG_ITALIC) |
240  (!!style->underline * STYLE_FLAG_UNDERLINE);
241  back_color = (BGR_TO_RGB(style->back_color & 0xffffff) << 8) |
242  (255 - ((uint32_t)style->back_color >> 24));
243  }
244 
245  bytestream_put_be32(&p, 0); // displayFlags
246  bytestream_put_be16(&p, 0x01FF); // horizontal/vertical justification (2x int8_t)
247  bytestream_put_be32(&p, back_color);
248  bytestream_put_be64(&p, 0); // BoxRecord - 4xint16_t: top, left, bottom, right
249  // StyleRecord {
250  bytestream_put_be16(&p, s->d.style_start);
251  bytestream_put_be16(&p, s->d.style_end);
252  bytestream_put_be16(&p, s->d.style_fontID);
253  bytestream_put_byte(&p, s->d.style_flag);
254  bytestream_put_byte(&p, s->d.style_fontsize);
255  bytestream_put_be32(&p, s->d.style_color);
256  // };
257  av_bprint_append_any(&s->buffer, buf, 30);
258 
259  // Build font table
260  // We can't build a complete font table since that would require
261  // scanning all dialogs first. But we can at least fill in what
262  // is avaiable in the ASS header
263  if (style && ass->styles_count) {
264  // Find unique font names
265  if (style->font_name) {
266  av_dynarray_add(&s->fonts, &s->font_count, style->font_name);
267  font_names_total_len += strlen(style->font_name);
268  }
269  for (i = 0; i < ass->styles_count; i++) {
270  int found = 0;
271  if (!ass->styles[i].font_name)
272  continue;
273  for (j = 0; j < s->font_count; j++) {
274  if (!strcmp(s->fonts[j], ass->styles[i].font_name)) {
275  found = 1;
276  break;
277  }
278  }
279  if (!found) {
280  av_dynarray_add(&s->fonts, &s->font_count,
281  ass->styles[i].font_name);
282  font_names_total_len += strlen(ass->styles[i].font_name);
283  }
284  }
285  } else
286  av_dynarray_add(&s->fonts, &s->font_count, (char*)"Serif");
287 
288  // FontTableBox {
289  p = buf;
290  bytestream_put_be32(&p, SIZE_ADD + 3 * s->font_count + font_names_total_len); // Size
291  bytestream_put_be32(&p, MKBETAG('f','t','a','b'));
292  bytestream_put_be16(&p, s->font_count);
293 
294  av_bprint_append_any(&s->buffer, buf, 10);
295  // FontRecord {
296  for (i = 0; i < s->font_count; i++) {
297  size_t len = strlen(s->fonts[i]);
298 
299  p = buf;
300  bytestream_put_be16(&p, i + 1); //fontID
301  bytestream_put_byte(&p, len);
302 
303  av_bprint_append_any(&s->buffer, buf, 3);
304  av_bprint_append_any(&s->buffer, s->fonts[i], len);
305  }
306  // };
307  // };
308 
309  if (!av_bprint_is_complete(&s->buffer)) {
310  return AVERROR(ENOMEM);
311  }
312 
313  avctx->extradata_size = s->buffer.len;
315  if (!avctx->extradata) {
316  return AVERROR(ENOMEM);
317  }
318 
319  memcpy(avctx->extradata, s->buffer.str, avctx->extradata_size);
320  av_bprint_clear(&s->buffer);
321 
322  return 0;
323 }
324 
326 {
327  int ret;
328  MovTextContext *s = avctx->priv_data;
329  s->avctx = avctx;
330 
332 
333  s->ass_ctx = ff_ass_split(avctx->subtitle_header);
334  if (!s->ass_ctx)
335  return AVERROR_INVALIDDATA;
337  if (ret < 0)
338  return ret;
339 
340  return 0;
341 }
342 
343 // Start a new style box if needed
345 {
346  // there's an existing style entry
347  if (s->style_attributes_temp.style_start == s->text_pos)
348  // Still at same text pos, use same entry
349  return 1;
350  if (s->style_attributes_temp.style_flag != s->d.style_flag ||
351  s->style_attributes_temp.style_color != s->d.style_color ||
352  s->style_attributes_temp.style_fontID != s->d.style_fontID ||
353  s->style_attributes_temp.style_fontsize != s->d.style_fontsize) {
354  StyleBox *tmp;
355 
356  // last style != defaults, end the style entry and start a new one
357  if (s->count + 1 > FFMIN(SIZE_MAX / sizeof(*s->style_attributes), UINT16_MAX) ||
358  !(tmp = av_fast_realloc(s->style_attributes,
359  &s->style_attributes_bytes_allocated,
360  (s->count + 1) * sizeof(*s->style_attributes)))) {
362  av_bprint_clear(&s->buffer);
363  s->box_flags &= ~STYL_BOX;
364  return 0;
365  }
366  s->style_attributes = tmp;
367  s->style_attributes_temp.style_end = s->text_pos;
368  s->style_attributes[s->count++] = s->style_attributes_temp;
369  s->box_flags |= STYL_BOX;
370  s->style_attributes_temp = s->d;
371  s->style_attributes_temp.style_start = s->text_pos;
372  } else { // style entry matches defaults, drop entry
373  s->style_attributes_temp = s->d;
374  s->style_attributes_temp.style_start = s->text_pos;
375  }
376  return 1;
377 }
378 
379 static uint8_t mov_text_style_to_flag(const char style)
380 {
381  uint8_t style_flag = 0;
382 
383  switch (style){
384  case 'b':
385  style_flag = STYLE_FLAG_BOLD;
386  break;
387  case 'i':
388  style_flag = STYLE_FLAG_ITALIC;
389  break;
390  case 'u':
391  style_flag = STYLE_FLAG_UNDERLINE;
392  break;
393  }
394  return style_flag;
395 }
396 
397 static void mov_text_style_set(MovTextContext *s, uint8_t style_flags)
398 {
399  if (!((s->style_attributes_temp.style_flag & style_flags) ^ style_flags)) {
400  // setting flags that that are already set
401  return;
402  }
403  if (mov_text_style_start(s))
404  s->style_attributes_temp.style_flag |= style_flags;
405 }
406 
407 static void mov_text_style_cb(void *priv, const char style, int close)
408 {
409  MovTextContext *s = priv;
410  uint8_t style_flag = mov_text_style_to_flag(style);
411 
412  if (!!(s->style_attributes_temp.style_flag & style_flag) != close) {
413  // setting flag that is already set
414  return;
415  }
416  if (mov_text_style_start(s)) {
417  if (!close)
418  s->style_attributes_temp.style_flag |= style_flag;
419  else
420  s->style_attributes_temp.style_flag &= ~style_flag;
421  }
422 }
423 
424 static void mov_text_color_set(MovTextContext *s, uint32_t color)
425 {
426  if ((s->style_attributes_temp.style_color & 0xffffff00) == color) {
427  // color hasn't changed
428  return;
429  }
430  if (mov_text_style_start(s))
431  s->style_attributes_temp.style_color = (color & 0xffffff00) |
432  (s->style_attributes_temp.style_color & 0xff);
433 }
434 
435 static void mov_text_color_cb(void *priv, unsigned int color, unsigned int color_id)
436 {
437  MovTextContext *s = priv;
438 
439  color = BGR_TO_RGB(color) << 8;
440  if (color_id == 1) { //primary color changes
442  } else if (color_id == 2) { //secondary color changes
443  if (!(s->box_flags & HCLR_BOX))
444  // Highlight alpha not set yet, use current primary alpha
445  s->hclr.color = s->style_attributes_temp.style_color;
446  if (!(s->box_flags & HLIT_BOX) || s->hlit.start == s->text_pos) {
447  s->box_flags |= HCLR_BOX;
448  s->box_flags |= HLIT_BOX;
449  s->hlit.start = s->text_pos;
450  s->hclr.color = color | (s->hclr.color & 0xFF);
451  }
452  else //close tag
453  s->hlit.end = s->text_pos;
454  /* If there are more than one secondary color changes in ASS,
455  take start of first section and end of last section. Movtext
456  allows only one highlight box per sample.
457  */
458  }
459  // Movtext does not support changes to other color_id (outline, background)
460 }
461 
462 static void mov_text_alpha_set(MovTextContext *s, uint8_t alpha)
463 {
464  if ((s->style_attributes_temp.style_color & 0xff) == alpha) {
465  // color hasn't changed
466  return;
467  }
468  if (mov_text_style_start(s))
469  s->style_attributes_temp.style_color =
470  (s->style_attributes_temp.style_color & 0xffffff00) | alpha;
471 }
472 
473 static void mov_text_alpha_cb(void *priv, int alpha, int alpha_id)
474 {
475  MovTextContext *s = priv;
476 
477  alpha = 255 - alpha;
478  if (alpha_id == 1) // primary alpha changes
480  else if (alpha_id == 2) { //secondary alpha changes
481  if (!(s->box_flags & HCLR_BOX))
482  // Highlight color not set yet, use current primary color
483  s->hclr.color = s->style_attributes_temp.style_color;
484  if (!(s->box_flags & HLIT_BOX) || s->hlit.start == s->text_pos) {
485  s->box_flags |= HCLR_BOX;
486  s->box_flags |= HLIT_BOX;
487  s->hlit.start = s->text_pos;
488  s->hclr.color = (s->hclr.color & 0xffffff00) | alpha;
489  }
490  else //close tag
491  s->hlit.end = s->text_pos;
492  }
493  // Movtext does not support changes to other alpha_id (outline, background)
494 }
495 
496 static uint16_t find_font_id(MovTextContext *s, const char *name)
497 {
498  int i;
499  for (i = 0; i < s->font_count; i++) {
500  if (!strcmp(name, s->fonts[i]))
501  return i + 1;
502  }
503  return 1;
504 }
505 
506 static void mov_text_font_name_set(MovTextContext *s, const char *name)
507 {
508  int fontID = find_font_id(s, name);
509  if (s->style_attributes_temp.style_fontID == fontID) {
510  // color hasn't changed
511  return;
512  }
513  if (mov_text_style_start(s))
514  s->style_attributes_temp.style_fontID = fontID;
515 }
516 
517 static void mov_text_font_name_cb(void *priv, const char *name)
518 {
520 }
521 
523 {
525  if (s->style_attributes_temp.style_fontsize == size) {
526  // color hasn't changed
527  return;
528  }
529  if (mov_text_style_start(s))
530  s->style_attributes_temp.style_fontsize = size;
531 }
532 
533 static void mov_text_font_size_cb(void *priv, int size)
534 {
536 }
537 
538 static void mov_text_end_cb(void *priv)
539 {
540  // End of text, close any open style record
542 }
543 
545 {
546  uint8_t style_flags, alpha;
547  uint32_t color;
548 
549  if (style) {
550  style_flags = (!!style->bold * STYLE_FLAG_BOLD) |
551  (!!style->italic * STYLE_FLAG_ITALIC) |
552  (!!style->underline * STYLE_FLAG_UNDERLINE);
553  mov_text_style_set(s, style_flags);
554  color = BGR_TO_RGB(style->primary_color & 0xffffff) << 8;
556  alpha = 255 - ((uint32_t)style->primary_color >> 24);
560  } else {
561  // End current style record, go back to defaults
563  }
564 }
565 
567 {
568  ASSStyle *style = ff_ass_style_get(s->ass_ctx, dialog->style);
569 
570  s->ass_dialog_style = style;
571  mov_text_ass_style_set(s, style);
572 }
573 
574 static void mov_text_cancel_overrides_cb(void *priv, const char *style_name)
575 {
576  MovTextContext *s = priv;
577  ASSStyle *style;
578 
579  if (!style_name || !*style_name)
580  style = s->ass_dialog_style;
581  else
582  style= ff_ass_style_get(s->ass_ctx, style_name);
583 
584  mov_text_ass_style_set(s, style);
585 }
586 
587 static uint16_t utf8_strlen(const char *text, int len)
588 {
589  uint16_t i = 0, ret = 0;
590  while (i < len) {
591  char c = text[i];
592  if ((c & 0x80) == 0)
593  i += 1;
594  else if ((c & 0xE0) == 0xC0)
595  i += 2;
596  else if ((c & 0xF0) == 0xE0)
597  i += 3;
598  else if ((c & 0xF8) == 0xF0)
599  i += 4;
600  else
601  return 0;
602  ret++;
603  }
604  return ret;
605 }
606 
607 static void mov_text_text_cb(void *priv, const char *text, int len)
608 {
609  uint16_t utf8_len = utf8_strlen(text, len);
610  MovTextContext *s = priv;
611  av_bprint_append_data(&s->buffer, text, len);
612  // If it's not utf-8, just use the byte length
613  s->text_pos += utf8_len ? utf8_len : len;
614  s->byte_count += len;
615 }
616 
617 static void mov_text_new_line_cb(void *priv, int forced)
618 {
619  MovTextContext *s = priv;
620  av_bprint_append_data(&s->buffer, "\n", 1);
621  s->text_pos += 1;
622  s->byte_count += 1;
623 }
624 
627  .new_line = mov_text_new_line_cb,
628  .style = mov_text_style_cb,
629  .color = mov_text_color_cb,
630  .alpha = mov_text_alpha_cb,
631  .font_name = mov_text_font_name_cb,
632  .font_size = mov_text_font_size_cb,
633  .cancel_overrides = mov_text_cancel_overrides_cb,
634  .end = mov_text_end_cb,
635 };
636 
637 static int mov_text_encode_frame(AVCodecContext *avctx, unsigned char *buf,
638  int bufsize, const AVSubtitle *sub)
639 {
640  MovTextContext *s = avctx->priv_data;
641  ASSDialog *dialog;
642  int i, length;
643  size_t j;
644 
645  s->byte_count = 0;
646  s->text_pos = 0;
647  s->count = 0;
648  s->box_flags = 0;
649  for (i = 0; i < sub->num_rects; i++) {
650  const char *ass = sub->rects[i]->ass;
651 
652  if (sub->rects[i]->type != SUBTITLE_ASS) {
653  av_log(avctx, AV_LOG_ERROR, "Only SUBTITLE_ASS type supported.\n");
654  return AVERROR(EINVAL);
655  }
656 
657  dialog = ff_ass_split_dialog2(s->ass_ctx, ass);
658  if (!dialog)
659  return AVERROR(ENOMEM);
660  mov_text_dialog(s, dialog);
662  ff_ass_free_dialog(&dialog);
663 
664  for (j = 0; j < box_count; j++) {
665  box_types[j].encode(s);
666  }
667  }
668 
669  AV_WB16(buf, s->byte_count);
670  buf += 2;
671 
672  if (!av_bprint_is_complete(&s->buffer)) {
673  length = AVERROR(ENOMEM);
674  goto exit;
675  }
676 
677  if (!s->buffer.len) {
678  length = 0;
679  goto exit;
680  }
681 
682  if (s->buffer.len > bufsize - 3) {
683  av_log(avctx, AV_LOG_ERROR, "Buffer too small for ASS event.\n");
684  length = AVERROR_BUFFER_TOO_SMALL;
685  goto exit;
686  }
687 
688  memcpy(buf, s->buffer.str, s->buffer.len);
689  length = s->buffer.len + 2;
690 
691 exit:
692  av_bprint_clear(&s->buffer);
693  return length;
694 }
695 
696 #define OFFSET(x) offsetof(MovTextContext, x)
697 #define FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_SUBTITLE_PARAM
698 static const AVOption options[] = {
699  { "height", "Frame height, usually video height", OFFSET(frame_height), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGS },
700  { NULL },
701 };
702 
704  .class_name = "MOV text enoder",
705  .item_name = av_default_item_name,
706  .option = options,
707  .version = LIBAVUTIL_VERSION_INT,
708 };
709 
711  .name = "mov_text",
712  .long_name = NULL_IF_CONFIG_SMALL("3GPP Timed Text subtitle"),
713  .type = AVMEDIA_TYPE_SUBTITLE,
714  .id = AV_CODEC_ID_MOV_TEXT,
715  .priv_data_size = sizeof(MovTextContext),
716  .priv_class = &mov_text_encoder_class,
718  .encode_sub = mov_text_encode_frame,
719  .close = mov_text_encode_close,
721 };
AVSubtitle
Definition: avcodec.h:2283
AVCodec
AVCodec.
Definition: codec.h:197
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:204
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
FF_CODEC_CAP_INIT_THREADSAFE
#define FF_CODEC_CAP_INIT_THREADSAFE
The codec does not modify any global variables in the init function, allowing to call the init functi...
Definition: internal.h:42
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
Box::encode
void(* encode)(MovTextContext *s)
Definition: movtextenc.c:95
MovTextContext::avctx
AVCodecContext * avctx
Definition: movtextenc.c:73
StyleBox::style_start
uint16_t style_start
Definition: movtextdec.c:76
init
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:31
ASSCodesCallbacks
Set of callback functions corresponding to each override codes that can be encountered in a "Dialogue...
Definition: ass_split.h:154
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
opt.h
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:234
mov_text_dialog
static void mov_text_dialog(MovTextContext *s, ASSDialog *dialog)
Definition: movtextenc.c:566
color
Definition: vf_paletteuse.c:583
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:68
sub
static float sub(float src0, float src1)
Definition: dnn_backend_native_layer_mathbinary.c:31
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:574
StyleBox::style_fontID
uint16_t style_fontID
Definition: movtextdec.c:85
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:26
internal.h
AVOption
AVOption.
Definition: opt.h:247
mov_text_font_name_set
static void mov_text_font_name_set(MovTextContext *s, const char *name)
Definition: movtextenc.c:506
options
static const AVOption options[]
Definition: movtextenc.c:698
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
AVCodecContext::subtitle_header
uint8_t * subtitle_header
Header containing style information for text subtitles.
Definition: avcodec.h:1679
mov_text_encode_init
static av_cold int mov_text_encode_init(AVCodecContext *avctx)
Definition: movtextenc.c:325
HighlightBox
Definition: movtextdec.c:88
MovTextContext::font_scale_factor
double font_scale_factor
Definition: movtextenc.c:90
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:157
box_count
const static size_t box_count
Definition: movtextenc.c:165
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:696
mov_text_color_set
static void mov_text_color_set(MovTextContext *s, uint32_t color)
Definition: movtextenc.c:424
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:703
SUBTITLE_ASS
@ SUBTITLE_ASS
Formatted text, the ass field must be set by the decoder and is authoritative.
Definition: avcodec.h:2250
ASSStyle::font_name
char * font_name
font face (case sensitive)
Definition: ass_split.h:41
mov_text_font_size_set
static void mov_text_font_size_set(MovTextContext *s, int size)
Definition: movtextenc.c:522
Box
Definition: movtextdec.c:118
mov_text_alpha_set
static void mov_text_alpha_set(MovTextContext *s, uint8_t alpha)
Definition: movtextenc.c:462
StyleBox
Definition: movtextdec.c:75
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:435
AVERROR_BUFFER_TOO_SMALL
#define AVERROR_BUFFER_TOO_SMALL
Buffer too small.
Definition: error.h:53
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
ass.h
ff_ass_free_dialog
void ff_ass_free_dialog(ASSDialog **dialogp)
Free a dialogue obtained from ff_ass_split_dialog2().
Definition: ass_split.c:434
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
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:607
mov_text_style_start
static int mov_text_style_start(MovTextContext *s)
Definition: movtextenc.c:344
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:481
box_types
static const Box box_types[]
Definition: movtextenc.c:159
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:484
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:257
mov_text_cleanup
static void mov_text_cleanup(MovTextContext *s)
Definition: movtextenc.c:98
STYLE_FLAG_UNDERLINE
#define STYLE_FLAG_UNDERLINE
Definition: movtextenc.c:36
MovTextContext::fonts
char ** fonts
Definition: movtextenc.c:88
FLAGS
#define FLAGS
Definition: movtextenc.c:697
ff_ass_split_dialog2
ASSDialog * ff_ass_split_dialog2(ASSSplitContext *ctx, const char *buf)
Split one ASS Dialogue line from a string buffer.
Definition: ass_split.c:446
MovTextContext::font_count
int font_count
Definition: movtextenc.c:89
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: movtextdec.c:77
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
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:405
AV_CODEC_ID_MOV_TEXT
@ AV_CODEC_ID_MOV_TEXT
Definition: codec_id.h:525
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:235
ASSSplitContext
This struct can be casted to ASS to access to the split data.
Definition: ass_split.c:199
ff_ass_split
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:376
utf8_strlen
static uint16_t utf8_strlen(const char *text, int len)
Definition: movtextenc.c:587
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:379
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:185
ASSStyle::underline
int underline
whether text is underlined (1) or not (0)
Definition: ass_split.h:49
ff_ass_split_free
void ff_ass_split_free(ASSSplitContext *ctx)
Free all the memory allocated for an ASSSplitContext.
Definition: ass_split.c:483
DEFAULT_STYLE_COLOR
#define DEFAULT_STYLE_COLOR
Definition: movtextenc.c:46
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:116
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:316
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:104
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:92
mov_text_style_set
static void mov_text_style_set(MovTextContext *s, uint8_t style_flags)
Definition: movtextenc.c:397
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
encode
static void encode(AVCodecContext *ctx, AVFrame *frame, AVPacket *pkt, FILE *output)
Definition: encode_audio.c:95
DEFAULT_STYLE_FONTSIZE
#define DEFAULT_STYLE_FONTSIZE
Definition: movtextenc.c:45
MovTextContext::style_attributes_temp
StyleBox style_attributes_temp
Definition: movtextenc.c:80
StyleBox::style_flag
uint8_t style_flag
Definition: movtextdec.c:78
mov_text_encode_close
static int mov_text_encode_close(AVCodecContext *avctx)
Definition: movtextenc.c:167
find_font_id
static uint16_t find_font_id(MovTextContext *s, const char *name)
Definition: movtextenc.c:496
mov_text_font_name_cb
static void mov_text_font_name_cb(void *priv, const char *name)
Definition: movtextenc.c:517
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
ff_movtext_encoder
const AVCodec ff_movtext_encoder
Definition: movtextenc.c:710
SIZE_ADD
#define SIZE_ADD
Definition: movtextenc.c:38
mov_text_callbacks
static const ASSCodesCallbacks mov_text_callbacks
Definition: movtextenc.c:625
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:591
encode_sample_description
static int encode_sample_description(AVCodecContext *avctx)
Definition: movtextenc.c:178
STYLE_RECORD_SIZE
#define STYLE_RECORD_SIZE
Definition: movtextenc.c:37
i
int i
Definition: input.c:406
AVCodecContext::extradata
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:480
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: internal.h:50
STYLE_FLAG_BOLD
#define STYLE_FLAG_BOLD
Definition: movtextenc.c:34
common.h
MovTextContext::byte_count
uint16_t byte_count
Definition: movtextenc.c:87
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:637
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:243
encode_hlit
static void encode_hlit(MovTextContext *s)
Definition: movtextenc.c:132
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:204
mov_text_new_line_cb
static void mov_text_new_line_cb(void *priv, int forced)
Definition: movtextenc.c:617
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:538
avcodec.h
encode_hclr
static void encode_hclr(MovTextContext *s)
Definition: movtextenc.c:146
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:71
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
AVCodecContext
main external API structure.
Definition: avcodec.h:379
av_bprint_clear
void av_bprint_clear(AVBPrint *buf)
Reset the string to "" but keep internal allocated data.
Definition: bprint.c:226
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:224
mov_text_font_size_cb
static void mov_text_font_size_cb(void *priv, int size)
Definition: movtextenc.c:533
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:93
mem.h
mov_text_style_cb
static void mov_text_style_cb(void *priv, const char style, int close)
Definition: movtextenc.c:407
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:406
mov_text_ass_style_set
static void mov_text_ass_style_set(MovTextContext *s, ASSStyle *style)
Definition: movtextenc.c:544
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:28
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:496
HighlightBox::start
uint16_t start
Definition: movtextenc.c:63
avstring.h
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:473
MovTextContext::buffer
AVBPrint buffer
Definition: movtextenc.c:81
MovTextContext
Definition: movtextdec.c:101
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:159
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