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/avassert.h"
26 #include "libavutil/avstring.h"
27 #include "libavutil/intreadwrite.h"
28 #include "libavutil/mem.h"
29 #include "libavutil/common.h"
30 #include "ass_split.h"
31 #include "ass.h"
32 #include "bytestream.h"
33 #include "internal.h"
34 
35 #define STYLE_FLAG_BOLD (1<<0)
36 #define STYLE_FLAG_ITALIC (1<<1)
37 #define STYLE_FLAG_UNDERLINE (1<<2)
38 #define STYLE_RECORD_SIZE 12
39 #define SIZE_ADD 10
40 
41 #define STYL_BOX (1<<0)
42 #define HLIT_BOX (1<<1)
43 #define HCLR_BOX (1<<2)
44 
45 #define DEFAULT_STYLE_FONT_ID 0x01
46 #define DEFAULT_STYLE_FONTSIZE 0x12
47 #define DEFAULT_STYLE_COLOR 0xffffffff
48 #define DEFAULT_STYLE_FLAG 0x00
49 
50 #define BGR_TO_RGB(c) (((c) & 0xff) << 16 | ((c) & 0xff00) | (((uint32_t)(c) >> 16) & 0xff))
51 #define FONTSIZE_SCALE(s,fs) ((fs) * (s)->font_scale_factor + 0.5)
52 #define av_bprint_append_any(buf, data, size) av_bprint_append_data(buf, ((const char*)data), size)
53 
54 typedef struct {
55  uint16_t style_start;
56  uint16_t style_end;
57  uint8_t style_flag;
58  uint16_t style_fontID;
60  uint32_t style_color;
61 } StyleBox;
62 
63 typedef struct {
64  uint16_t start;
65  uint16_t end;
66 } HighlightBox;
67 
68 typedef struct {
69  uint32_t color;
71 
72 typedef struct {
73  AVClass *class;
75 
79  unsigned count;
82  AVBPrint buffer;
85  uint8_t box_flags;
87  uint16_t text_pos;
88  uint16_t byte_count;
89  char **fonts;
92  int frame_height;
94 
95 typedef struct {
97 } Box;
98 
100 {
101  s->count = 0;
102  s->style_attributes_temp = s->d;
103 }
104 
106 {
107  if ((s->box_flags & STYL_BOX) && s->count) {
108  uint8_t buf[12], *p = buf;
109 
110  bytestream_put_be32(&p, s->count * STYLE_RECORD_SIZE + SIZE_ADD);
111  bytestream_put_be32(&p, MKBETAG('s','t','y','l'));
112  bytestream_put_be16(&p, s->count);
113  /*The above three attributes are hard coded for now
114  but will come from ASS style in the future*/
115  av_bprint_append_any(&s->buffer, buf, 10);
116  for (unsigned j = 0; j < s->count; j++) {
117  const StyleBox *style = &s->style_attributes[j];
118 
119  p = buf;
120  bytestream_put_be16(&p, style->style_start);
121  bytestream_put_be16(&p, style->style_end);
122  bytestream_put_be16(&p, style->style_fontID);
123  bytestream_put_byte(&p, style->style_flag);
124  bytestream_put_byte(&p, style->style_fontsize);
125  bytestream_put_be32(&p, style->style_color);
126 
127  av_bprint_append_any(&s->buffer, buf, 12);
128  }
129  }
130  mov_text_cleanup(s);
131 }
132 
134 {
135  if (s->box_flags & HLIT_BOX) {
136  uint8_t buf[12], *p = buf;
137 
138  bytestream_put_be32(&p, 12);
139  bytestream_put_be32(&p, MKBETAG('h','l','i','t'));
140  bytestream_put_be16(&p, s->hlit.start);
141  bytestream_put_be16(&p, s->hlit.end);
142 
143  av_bprint_append_any(&s->buffer, buf, 12);
144  }
145 }
146 
148 {
149  if (s->box_flags & HCLR_BOX) {
150  uint8_t buf[12], *p = buf;
151 
152  bytestream_put_be32(&p, 12);
153  bytestream_put_be32(&p, MKBETAG('h','c','l','r'));
154  bytestream_put_be32(&p, s->hclr.color);
155 
156  av_bprint_append_any(&s->buffer, buf, 12);
157  }
158 }
159 
160 static const Box box_types[] = {
161  { encode_styl },
162  { encode_hlit },
163  { encode_hclr },
164 };
165 
166 const static size_t box_count = FF_ARRAY_ELEMS(box_types);
167 
169 {
170  MovTextContext *s = avctx->priv_data;
171 
174  av_freep(&s->fonts);
176  return 0;
177 }
178 
180 {
181  ASS *ass;
182  ASSStyle *style;
183  int i, j;
184  uint32_t back_color = 0;
185  int font_names_total_len = 0;
186  MovTextContext *s = avctx->priv_data;
187  uint8_t buf[30], *p = buf;
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
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 avaiable 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) {
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  return AVERROR(ENOMEM);
312  }
313 
314  avctx->extradata_size = s->buffer.len;
316  if (!avctx->extradata) {
317  return AVERROR(ENOMEM);
318  }
319 
320  memcpy(avctx->extradata, s->buffer.str, avctx->extradata_size);
321  av_bprint_clear(&s->buffer);
322 
323  return 0;
324 }
325 
327 {
328  int ret;
329  MovTextContext *s = avctx->priv_data;
330  s->avctx = avctx;
331 
333 
334  s->ass_ctx = ff_ass_split(avctx->subtitle_header);
335  if (!s->ass_ctx)
336  return AVERROR_INVALIDDATA;
337  ret = encode_sample_description(avctx);
338  if (ret < 0)
339  return ret;
340 
341  return 0;
342 }
343 
344 // Start a new style box if needed
346 {
347  // there's an existing style entry
349  // Still at same text pos, use same entry
350  return 1;
351  if (s->style_attributes_temp.style_flag != s->d.style_flag ||
352  s->style_attributes_temp.style_color != s->d.style_color ||
353  s->style_attributes_temp.style_fontID != s->d.style_fontID ||
354  s->style_attributes_temp.style_fontsize != s->d.style_fontsize) {
355  StyleBox *tmp;
356 
357  // last style != defaults, end the style entry and start a new one
358  if (s->count + 1 > SIZE_MAX / sizeof(*s->style_attributes) ||
361  (s->count + 1) * sizeof(*s->style_attributes)))) {
362  mov_text_cleanup(s);
363  av_bprint_clear(&s->buffer);
364  s->box_flags &= ~STYL_BOX;
365  return 0;
366  }
367  s->style_attributes = tmp;
370  s->box_flags |= STYL_BOX;
371  s->style_attributes_temp = s->d;
373  } else { // style entry matches defaults, drop entry
374  s->style_attributes_temp = s->d;
376  }
377  return 1;
378 }
379 
380 static uint8_t mov_text_style_to_flag(const char style)
381 {
382  uint8_t style_flag = 0;
383 
384  switch (style){
385  case 'b':
386  style_flag = STYLE_FLAG_BOLD;
387  break;
388  case 'i':
389  style_flag = STYLE_FLAG_ITALIC;
390  break;
391  case 'u':
392  style_flag = STYLE_FLAG_UNDERLINE;
393  break;
394  }
395  return style_flag;
396 }
397 
398 static void mov_text_style_set(MovTextContext *s, uint8_t style_flags)
399 {
400  if (!((s->style_attributes_temp.style_flag & style_flags) ^ style_flags)) {
401  // setting flags that that are already set
402  return;
403  }
404  if (mov_text_style_start(s))
405  s->style_attributes_temp.style_flag |= style_flags;
406 }
407 
408 static void mov_text_style_cb(void *priv, const char style, int close)
409 {
410  MovTextContext *s = priv;
411  uint8_t style_flag = mov_text_style_to_flag(style);
412 
413  if (!!(s->style_attributes_temp.style_flag & style_flag) != close) {
414  // setting flag that is already set
415  return;
416  }
417  if (mov_text_style_start(s)) {
418  if (!close)
419  s->style_attributes_temp.style_flag |= style_flag;
420  else
421  s->style_attributes_temp.style_flag &= ~style_flag;
422  }
423 }
424 
425 static void mov_text_color_set(MovTextContext *s, uint32_t color)
426 {
427  if ((s->style_attributes_temp.style_color & 0xffffff00) == color) {
428  // color hasn't changed
429  return;
430  }
431  if (mov_text_style_start(s))
432  s->style_attributes_temp.style_color = (color & 0xffffff00) |
434 }
435 
436 static void mov_text_color_cb(void *priv, unsigned int color, unsigned int color_id)
437 {
438  MovTextContext *s = priv;
439 
440  color = BGR_TO_RGB(color) << 8;
441  if (color_id == 1) { //primary color changes
442  mov_text_color_set(s, color);
443  } else if (color_id == 2) { //secondary color changes
444  if (!(s->box_flags & HCLR_BOX))
445  // Highlight alpha not set yet, use current primary alpha
447  if (!(s->box_flags & HLIT_BOX) || s->hlit.start == s->text_pos) {
448  s->box_flags |= HCLR_BOX;
449  s->box_flags |= HLIT_BOX;
450  s->hlit.start = s->text_pos;
451  s->hclr.color = color | (s->hclr.color & 0xFF);
452  }
453  else //close tag
454  s->hlit.end = s->text_pos;
455  /* If there are more than one secondary color changes in ASS,
456  take start of first section and end of last section. Movtext
457  allows only one highlight box per sample.
458  */
459  }
460  // Movtext does not support changes to other color_id (outline, background)
461 }
462 
464 {
465  if ((s->style_attributes_temp.style_color & 0xff) == alpha) {
466  // color hasn't changed
467  return;
468  }
469  if (mov_text_style_start(s))
471  (s->style_attributes_temp.style_color & 0xffffff00) | alpha;
472 }
473 
474 static void mov_text_alpha_cb(void *priv, int alpha, int alpha_id)
475 {
476  MovTextContext *s = priv;
477 
478  alpha = 255 - alpha;
479  if (alpha_id == 1) // primary alpha changes
480  mov_text_alpha_set(s, alpha);
481  else if (alpha_id == 2) { //secondary alpha changes
482  if (!(s->box_flags & HCLR_BOX))
483  // Highlight color not set yet, use current primary color
485  if (!(s->box_flags & HLIT_BOX) || s->hlit.start == s->text_pos) {
486  s->box_flags |= HCLR_BOX;
487  s->box_flags |= HLIT_BOX;
488  s->hlit.start = s->text_pos;
489  s->hclr.color = (s->hclr.color & 0xffffff00) | alpha;
490  }
491  else //close tag
492  s->hlit.end = s->text_pos;
493  }
494  // Movtext does not support changes to other alpha_id (outline, background)
495 }
496 
497 static uint16_t find_font_id(MovTextContext *s, const char *name)
498 {
499  int i;
500  for (i = 0; i < s->font_count; i++) {
501  if (!strcmp(name, s->fonts[i]))
502  return i + 1;
503  }
504  return 1;
505 }
506 
507 static void mov_text_font_name_set(MovTextContext *s, const char *name)
508 {
509  int fontID = find_font_id(s, name);
510  if (s->style_attributes_temp.style_fontID == fontID) {
511  // color hasn't changed
512  return;
513  }
514  if (mov_text_style_start(s))
516 }
517 
518 static void mov_text_font_name_cb(void *priv, const char *name)
519 {
521 }
522 
524 {
525  size = FONTSIZE_SCALE(s, size);
526  if (s->style_attributes_temp.style_fontsize == size) {
527  // color hasn't changed
528  return;
529  }
530  if (mov_text_style_start(s))
532 }
533 
534 static void mov_text_font_size_cb(void *priv, int size)
535 {
537 }
538 
539 static void mov_text_end_cb(void *priv)
540 {
541  // End of text, close any open style record
543 }
544 
546 {
547  uint8_t style_flags, alpha;
548  uint32_t color;
549 
550  if (style) {
551  style_flags = (!!style->bold * STYLE_FLAG_BOLD) |
552  (!!style->italic * STYLE_FLAG_ITALIC) |
553  (!!style->underline * STYLE_FLAG_UNDERLINE);
554  mov_text_style_set(s, style_flags);
555  color = BGR_TO_RGB(style->primary_color & 0xffffff) << 8;
556  mov_text_color_set(s, color);
557  alpha = 255 - ((uint32_t)style->primary_color >> 24);
558  mov_text_alpha_set(s, alpha);
561  } else {
562  // End current style record, go back to defaults
564  }
565 }
566 
568 {
569  ASSStyle *style = ff_ass_style_get(s->ass_ctx, dialog->style);
570 
571  s->ass_dialog_style = style;
572  mov_text_ass_style_set(s, style);
573 }
574 
575 static void mov_text_cancel_overrides_cb(void *priv, const char *style_name)
576 {
577  MovTextContext *s = priv;
578  ASSStyle *style;
579 
580  if (!style_name || !*style_name)
581  style = s->ass_dialog_style;
582  else
583  style= ff_ass_style_get(s->ass_ctx, style_name);
584 
585  mov_text_ass_style_set(s, style);
586 }
587 
588 static uint16_t utf8_strlen(const char *text, int len)
589 {
590  uint16_t i = 0, ret = 0;
591  while (i < len) {
592  char c = text[i];
593  if ((c & 0x80) == 0)
594  i += 1;
595  else if ((c & 0xE0) == 0xC0)
596  i += 2;
597  else if ((c & 0xF0) == 0xE0)
598  i += 3;
599  else if ((c & 0xF8) == 0xF0)
600  i += 4;
601  else
602  return 0;
603  ret++;
604  }
605  return ret;
606 }
607 
608 static void mov_text_text_cb(void *priv, const char *text, int len)
609 {
610  uint16_t utf8_len = utf8_strlen(text, len);
611  MovTextContext *s = priv;
612  av_bprint_append_data(&s->buffer, text, len);
613  // If it's not utf-8, just use the byte length
614  s->text_pos += utf8_len ? utf8_len : len;
615  s->byte_count += len;
616 }
617 
618 static void mov_text_new_line_cb(void *priv, int forced)
619 {
620  MovTextContext *s = priv;
621  av_bprint_append_data(&s->buffer, "\n", 1);
622  s->text_pos += 1;
623  s->byte_count += 1;
624 }
625 
628  .new_line = mov_text_new_line_cb,
629  .style = mov_text_style_cb,
630  .color = mov_text_color_cb,
631  .alpha = mov_text_alpha_cb,
632  .font_name = mov_text_font_name_cb,
633  .font_size = mov_text_font_size_cb,
634  .cancel_overrides = mov_text_cancel_overrides_cb,
635  .end = mov_text_end_cb,
636 };
637 
638 static int mov_text_encode_frame(AVCodecContext *avctx, unsigned char *buf,
639  int bufsize, const AVSubtitle *sub)
640 {
641  MovTextContext *s = avctx->priv_data;
642  ASSDialog *dialog;
643  int i, length;
644  size_t j;
645 
646  s->byte_count = 0;
647  s->text_pos = 0;
648  s->count = 0;
649  s->box_flags = 0;
650  for (i = 0; i < sub->num_rects; i++) {
651  const char *ass = sub->rects[i]->ass;
652 
653  if (sub->rects[i]->type != SUBTITLE_ASS) {
654  av_log(avctx, AV_LOG_ERROR, "Only SUBTITLE_ASS type supported.\n");
655  return AVERROR(EINVAL);
656  }
657 
658 #if FF_API_ASS_TIMING
659  if (!strncmp(ass, "Dialogue: ", 10)) {
660  int num;
661  dialog = ff_ass_split_dialog(s->ass_ctx, ass, 0, &num);
662  for (; dialog && num--; dialog++) {
663  mov_text_dialog(s, dialog);
664  ff_ass_split_override_codes(&mov_text_callbacks, s, dialog->text);
665  }
666  } else {
667 #endif
668  dialog = ff_ass_split_dialog2(s->ass_ctx, ass);
669  if (!dialog)
670  return AVERROR(ENOMEM);
671  mov_text_dialog(s, dialog);
672  ff_ass_split_override_codes(&mov_text_callbacks, s, dialog->text);
673  ff_ass_free_dialog(&dialog);
674 #if FF_API_ASS_TIMING
675  }
676 #endif
677 
678  for (j = 0; j < box_count; j++) {
679  box_types[j].encode(s);
680  }
681  }
682 
683  AV_WB16(buf, s->byte_count);
684  buf += 2;
685 
686  if (!av_bprint_is_complete(&s->buffer)) {
687  length = AVERROR(ENOMEM);
688  goto exit;
689  }
690 
691  if (!s->buffer.len) {
692  length = 0;
693  goto exit;
694  }
695 
696  if (s->buffer.len > bufsize - 3) {
697  av_log(avctx, AV_LOG_ERROR, "Buffer too small for ASS event.\n");
698  length = AVERROR_BUFFER_TOO_SMALL;
699  goto exit;
700  }
701 
702  memcpy(buf, s->buffer.str, s->buffer.len);
703  length = s->buffer.len + 2;
704 
705 exit:
706  av_bprint_clear(&s->buffer);
707  return length;
708 }
709 
710 #define OFFSET(x) offsetof(MovTextContext, x)
711 #define FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_SUBTITLE_PARAM
712 static const AVOption options[] = {
713  { "height", "Frame height, usually video height", OFFSET(frame_height), AV_OPT_TYPE_INT, {.i64=0}, 0, INT_MAX, FLAGS },
714  { NULL },
715 };
716 
718  .class_name = "MOV text enoder",
719  .item_name = av_default_item_name,
720  .option = options,
721  .version = LIBAVUTIL_VERSION_INT,
722 };
723 
725  .name = "mov_text",
726  .long_name = NULL_IF_CONFIG_SMALL("3GPP Timed Text subtitle"),
727  .type = AVMEDIA_TYPE_SUBTITLE,
728  .id = AV_CODEC_ID_MOV_TEXT,
729  .priv_data_size = sizeof(MovTextContext),
730  .priv_class = &mov_text_encoder_class,
732  .encode_sub = mov_text_encode_frame,
733  .close = mov_text_encode_close,
734  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
735 };
#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:48
char * style
name of the ASSStyle to use with this dialog
Definition: ass_split.h:76
#define NULL
Definition: coverity.c:32
static const AVOption options[]
Definition: movtextenc.c:712
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
static void mov_text_dialog(MovTextContext *s, ASSDialog *dialog)
Definition: movtextenc.c:567
AVOption.
Definition: opt.h:248
fields extracted from the [Events] section
Definition: ass_split.h:71
#define OFFSET(x)
Definition: movtextenc.c:710
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
Memory handling functions.
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
ASSDialog * ff_ass_split_dialog2(ASSSplitContext *ctx, const char *buf)
Split one ASS Dialogue line from a string buffer.
Definition: ass_split.c:444
static const size_t box_count
Definition: movtextenc.c:166
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:374
uint16_t style_fontID
Definition: movtextdec.c:84
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
static void mov_text_font_size_set(MovTextContext *s, int size)
Definition: movtextenc.c:523
structure containing the whole split ASS data
Definition: ass_split.h:90
static av_cold int mov_text_encode_init(AVCodecContext *avctx)
Definition: movtextenc.c:326
unsigned num_rects
Definition: avcodec.h:2698
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
#define DEFAULT_STYLE_FONT_ID
Definition: movtextenc.c:45
AVCodec.
Definition: codec.h:190
int back_color
color of the subtitle outline or shadow
Definition: ass_split.h:46
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:235
static void mov_text_cancel_overrides_cb(void *priv, const char *style_name)
Definition: movtextenc.c:575
AVSubtitleRect ** rects
Definition: avcodec.h:2699
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
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
This struct can be casted to ASS to access to the split data.
Definition: ass_split.c:197
uint8_t
#define av_cold
Definition: attributes.h:88
void ff_ass_free_dialog(ASSDialog **dialogp)
Free a dialogue obtained from ff_ass_split_dialog2().
Definition: ass_split.c:432
AVOptions.
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
Definition: log.c:92
static void mov_text_font_name_set(MovTextContext *s, const char *name)
Definition: movtextenc.c:507
ASSSplitContext * ass_ctx
Definition: movtextenc.c:76
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 bold
whether text is bold (1) or not (0)
Definition: ass_split.h:47
AVBPrint buffer
Definition: movtextenc.c:82
#define STYL_BOX
Definition: movtextenc.c:41
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:627
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:494
static void mov_text_color_cb(void *priv, unsigned int color, unsigned int color_id)
Definition: movtextenc.c:436
void av_bprint_append_data(AVBPrint *buf, const char *data, unsigned size)
Append data to a print buffer.
Definition: bprint.c:158
#define FONTSIZE_SCALE(s, fs)
Definition: movtextenc.c:51
static void mov_text_text_cb(void *priv, const char *text, int len)
Definition: movtextenc.c:608
static void mov_text_color_set(MovTextContext *s, uint32_t color)
Definition: movtextenc.c:425
static const AVClass mov_text_encoder_class
Definition: movtextenc.c:717
static int mov_text_style_start(MovTextContext *s)
Definition: movtextenc.c:345
ptrdiff_t size
Definition: opengl_enc.c:100
#define AV_WB16(p, v)
Definition: intreadwrite.h:405
HighlightBox hlit
Definition: movtextenc.c:83
unsigned style_attributes_bytes_allocated
Definition: movtextenc.c:80
ASSDialog * ff_ass_split_dialog(ASSSplitContext *ctx, const char *buf, int cache, int *number)
Split one or several ASS "Dialogue" lines from a string buffer and store them in an already initializ...
Definition: ass_split.c:413
#define av_log(a,...)
uint16_t end
Definition: movtextenc.c:65
MovTextDefault d
Definition: movtextdec.c:107
static void mov_text_alpha_set(MovTextContext *s, uint8_t alpha)
Definition: movtextenc.c:463
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
#define STYLE_FLAG_UNDERLINE
Definition: movtextenc.c:37
#define AV_BPRINT_SIZE_UNLIMITED
uint8_t style_flag
Definition: movtextdec.c:77
void(* encode)(MovTextContext *s)
Definition: movtextenc.c:96
#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
simple assert() macros that are a bit more flexible than ISO C assert().
GLsizei GLsizei * length
Definition: opengl_enc.c:114
int font_size
font height
Definition: ass_split.h:42
const char * name
Name of the codec implementation.
Definition: codec.h:197
uint32_t color
Definition: movtextenc.c:69
#define DEFAULT_STYLE_COLOR
Definition: movtextenc.c:47
#define STYLE_FLAG_ITALIC
Definition: movtextenc.c:36
static const Box box_types[]
Definition: movtextenc.c:160
int play_res_y
video height that ASS coords are referring to
Definition: ass_split.h:32
static void mov_text_cleanup(MovTextContext *s)
Definition: movtextenc.c:99
uint8_t box_flags
Definition: movtextdec.c:108
#define FLAGS
Definition: movtextenc.c:711
#define DEFAULT_STYLE_FONTSIZE
Definition: movtextenc.c:46
#define AVERROR_BUFFER_TOO_SMALL
Buffer too small.
Definition: error.h:51
typedef void(APIENTRY *FF_PFNGLACTIVETEXTUREPROC)(GLenum texture)
static uint16_t utf8_strlen(const char *text, int len)
Definition: movtextenc.c:588
static uint16_t find_font_id(MovTextContext *s, const char *name)
Definition: movtextenc.c:497
static void mov_text_font_name_cb(void *priv, const char *name)
Definition: movtextenc.c:518
#define SIZE_ADD
Definition: movtextenc.c:39
static uint8_t mov_text_style_to_flag(const char style)
Definition: movtextenc.c:380
AVCodecContext * avctx
Definition: movtextenc.c:74
int italic
whether text is italic (1) or not (0)
Definition: ass_split.h:48
#define HLIT_BOX
Definition: movtextenc.c:42
#define s(width, name)
Definition: cbs_vp9.c:257
static int encode_sample_description(AVCodecContext *avctx)
Definition: movtextenc.c:179
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:478
static int av_bprint_is_complete(const AVBPrint *buf)
Test if the print buffer is complete (not truncated).
Definition: bprint.h:185
Set of callback functions corresponding to each override codes that can be encountered in a "Dialogue...
Definition: ass_split.h:154
static void encode_styl(MovTextContext *s)
Definition: movtextenc.c:105
AVCodec ff_movtext_encoder
Definition: movtextenc.c:724
static void mov_text_style_set(MovTextContext *s, uint8_t style_flags)
Definition: movtextenc.c:398
uint16_t style_start
Definition: movtextdec.c:75
#define FF_ARRAY_ELEMS(a)
static int mov_text_encode_frame(AVCodecContext *avctx, unsigned char *buf, int bufsize, const AVSubtitle *sub)
Definition: movtextenc.c:638
if(ret)
int primary_color
color that a subtitle will normally appear in
Definition: ass_split.h:43
Libavcodec external API header.
static const ASSCodesCallbacks mov_text_callbacks
Definition: movtextenc.c:626
uint8_t style_fontsize
Definition: movtextenc.c:59
uint16_t style_end
Definition: movtextdec.c:76
static const int16_t alpha[]
Definition: ilbcdata.h:55
#define STYLE_RECORD_SIZE
Definition: movtextenc.c:38
main external API structure.
Definition: avcodec.h:526
static int mov_text_encode_close(AVCodecContext *avctx)
Definition: movtextenc.c:168
static void encode(AVCodecContext *ctx, AVFrame *frame, AVPacket *pkt, FILE *output)
Definition: encode_audio.c:95
#define STYLE_FLAG_BOLD
Definition: movtextenc.c:35
int extradata_size
Definition: avcodec.h:628
Describe the class of an AVClass context structure.
Definition: log.h:67
uint16_t text_pos
Definition: movtextenc.c:87
uint32_t style_color
Definition: movtextenc.c:60
static void mov_text_end_cb(void *priv)
Definition: movtextenc.c:539
static void encode_hclr(MovTextContext *s)
Definition: movtextenc.c:147
char ** fonts
Definition: movtextenc.c:89
char * font_name
font face (case sensitive)
Definition: ass_split.h:41
#define BGR_TO_RGB(c)
Definition: movtextenc.c:50
static void encode_hlit(MovTextContext *s)
Definition: movtextenc.c:133
ASSScriptInfo script_info
general information about the SSA script
Definition: ass_split.h:91
HilightcolorBox hclr
Definition: movtextenc.c:84
fields extracted from the [V4(+) Styles] section
Definition: ass_split.h:39
ASSStyle * ff_ass_style_get(ASSSplitContext *ctx, const char *style)
Find an ASSStyle structure by its name.
Definition: ass_split.c:589
static void mov_text_ass_style_set(MovTextContext *s, ASSStyle *style)
Definition: movtextenc.c:545
void av_bprint_clear(AVBPrint *buf)
Reset the string to "" but keep internal allocated data.
Definition: bprint.c:227
common internal api header.
common internal and external API header
static void mov_text_font_size_cb(void *priv, int size)
Definition: movtextenc.c:534
void(* text)(void *priv, const char *text, int len)
Definition: ass_split.h:159
uint16_t start
Definition: movtextenc.c:64
StyleBox * style_attributes
Definition: movtextenc.c:78
static void mov_text_new_line_cb(void *priv, int forced)
Definition: movtextenc.c:618
#define MKBETAG(a, b, c, d)
Definition: common.h:406
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
Definition: avcodec.h:215
uint16_t byte_count
Definition: movtextenc.c:88
static void mov_text_style_cb(void *priv, const char style, int close)
Definition: movtextenc.c:408
static void mov_text_alpha_cb(void *priv, int alpha, int alpha_id)
Definition: movtextenc.c:474
void * priv_data
Definition: avcodec.h:553
Formatted text, the ass field must be set by the decoder and is authoritative.
Definition: avcodec.h:2654
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
int len
#define HCLR_BOX
Definition: movtextenc.c:43
double font_scale_factor
Definition: movtextenc.c:91
#define av_bprint_append_any(buf, data, size)
Definition: movtextenc.c:52
int styles_count
number of ASSStyle in the styles array
Definition: ass_split.h:93
char * ass
0 terminated ASS/SSA compatible event line.
Definition: avcodec.h:2689
#define DEFAULT_STYLE_FLAG
Definition: movtextenc.c:48
StyleBox style_attributes_temp
Definition: movtextenc.c:81
void ff_ass_split_free(ASSSplitContext *ctx)
Free all the memory allocated for an ASSSplitContext.
Definition: ass_split.c:481
#define av_freep(p)
StyleBox d
Definition: movtextenc.c:86
static float sub(float src0, float src1)
unsigned count
Definition: movtextenc.c:79
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
enum AVSubtitleType type
Definition: avcodec.h:2680
ASSStyle * ass_dialog_style
Definition: movtextenc.c:77
int underline
whether text is underlined (1) or not (0)
Definition: ass_split.h:49
int i
Definition: input.c:407
ASSStyle * styles
array of split out styles
Definition: ass_split.h:92
const char * name
Definition: opengl_enc.c:102
uint8_t * subtitle_header
Header containing style information for text subtitles.
Definition: avcodec.h:2014
static uint8_t tmp[11]
Definition: aes_ctr.c:26