FFmpeg
libzvbi-teletextdec.c
Go to the documentation of this file.
1 /*
2  * Teletext decoding for ffmpeg
3  * Copyright (c) 2005-2010, 2012 Wolfram Gloger
4  * Copyright (c) 2013 Marton Balint
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "avcodec.h"
22 #include "libavcodec/ass.h"
23 #include "libavcodec/dvbtxt.h"
24 #include "libavutil/opt.h"
25 #include "libavutil/bprint.h"
26 #include "libavutil/internal.h"
27 #include "libavutil/intreadwrite.h"
28 #include "libavutil/log.h"
29 #include "libavutil/common.h"
30 
31 #include <libzvbi.h>
32 
33 #define TEXT_MAXSZ (25 * (56 + 1) * 4 + 2)
34 #define VBI_NB_COLORS 40
35 #define VBI_TRANSPARENT_BLACK 8
36 #define RGBA(r,g,b,a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
37 #define VBI_R(rgba) (((rgba) >> 0) & 0xFF)
38 #define VBI_G(rgba) (((rgba) >> 8) & 0xFF)
39 #define VBI_B(rgba) (((rgba) >> 16) & 0xFF)
40 #define VBI_A(rgba) (((rgba) >> 24) & 0xFF)
41 #define MAX_BUFFERED_PAGES 25
42 #define BITMAP_CHAR_WIDTH 12
43 #define BITMAP_CHAR_HEIGHT 10
44 #define MAX_SLICES 64
45 
46 typedef struct TeletextPage
47 {
49  int pgno;
50  int subno;
51  int64_t pts;
52 } TeletextPage;
53 
54 typedef struct TeletextContext
55 {
56  AVClass *class;
57  char *pgno;
58  int x_offset;
59  int y_offset;
60  int format_id; /* 0 = bitmap, 1 = text/ass, 2 = ass */
61  int chop_top;
62  int sub_duration; /* in msec */
64  int opacity;
66 
69  int nb_pages;
70  int64_t pts;
72 
73  vbi_decoder * vbi;
74  vbi_sliced sliced[MAX_SLICES];
75 
76  int readorder;
77  uint8_t subtitle_map[2048];
78  int last_pgno;
79  int last_p5;
82 
84 {
86  char *new_header;
87  uint8_t *event_pos;
88 
89  if (ret < 0)
90  return ret;
91 
92  event_pos = strstr(avctx->subtitle_header, "\r\n[Events]\r\n");
93  if (!event_pos)
94  return AVERROR_BUG;
95 
96  new_header = av_asprintf("%.*s%s%s",
97  (int)(event_pos - avctx->subtitle_header), avctx->subtitle_header,
98  "Style: "
99  "Teletext," /* Name */
100  "Monospace,11," /* Font{name,size} */
101  "&Hffffff,&Hffffff,&H0,&H0," /* {Primary,Secondary,Outline,Back}Colour */
102  "0,0,0,0," /* Bold, Italic, Underline, StrikeOut */
103  "160,100," /* Scale{X,Y} */
104  "0,0," /* Spacing, Angle */
105  "3,0.1,0," /* BorderStyle, Outline, Shadow */
106  "5,1,1,1," /* Alignment, Margin[LRV] */
107  "0\r\n" /* Encoding */
108  "Style: "
109  "Subtitle," /* Name */
110  "Monospace,16," /* Font{name,size} */
111  "&Hffffff,&Hffffff,&H0,&H0," /* {Primary,Secondary,Outline,Back}Colour */
112  "0,0,0,0," /* Bold, Italic, Underline, StrikeOut */
113  "100,100," /* Scale{X,Y} */
114  "0,0," /* Spacing, Angle */
115  "1,1,1," /* BorderStyle, Outline, Shadow */
116  "8,48,48,20," /* Alignment, Margin[LRV] */
117  "0\r\n" /* Encoding */
118  , event_pos);
119 
120  if (!new_header)
121  return AVERROR(ENOMEM);
122 
123  av_free(avctx->subtitle_header);
124  avctx->subtitle_header = new_header;
125  avctx->subtitle_header_size = strlen(new_header);
126  return 0;
127 }
128 
129 static int chop_spaces_utf8(const unsigned char* t, int len)
130 {
131  t += len;
132  while (len > 0) {
133  if (*--t != ' ' || (len-1 > 0 && *(t-1) & 0x80))
134  break;
135  --len;
136  }
137  return len;
138 }
139 
141 {
142  av_freep(&(*sub_rect)->data[0]);
143  av_freep(&(*sub_rect)->data[1]);
144  av_freep(&(*sub_rect)->ass);
145  av_freep(sub_rect);
146 }
147 
148 static char *create_ass_text(TeletextContext *ctx, const char *text)
149 {
150  char *dialog;
151  AVBPrint buf;
152 
154  ff_ass_bprint_text_event(&buf, text, strlen(text), "", 0);
155  if (!av_bprint_is_complete(&buf)) {
156  av_bprint_finalize(&buf, NULL);
157  return NULL;
158  }
159  dialog = ff_ass_get_dialog(ctx->readorder++, 0, NULL, NULL, buf.str);
160  av_bprint_finalize(&buf, NULL);
161  return dialog;
162 }
163 
164 /* Draw a page as text */
165 static int gen_sub_text(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_page *page, int chop_top)
166 {
167  const char *in;
168  AVBPrint buf;
169  char *vbi_text = av_malloc(TEXT_MAXSZ);
170  int sz;
171 
172  if (!vbi_text)
173  return AVERROR(ENOMEM);
174 
175  sz = vbi_print_page_region(page, vbi_text, TEXT_MAXSZ-1, "UTF-8",
176  /*table mode*/ TRUE, FALSE,
177  0, chop_top,
178  page->columns, page->rows-chop_top);
179  if (sz <= 0) {
180  av_log(ctx, AV_LOG_ERROR, "vbi_print error\n");
181  av_free(vbi_text);
182  return AVERROR_EXTERNAL;
183  }
184  vbi_text[sz] = '\0';
185  in = vbi_text;
186  av_bprint_init(&buf, 0, TEXT_MAXSZ);
187 
188  if (ctx->chop_spaces) {
189  for (;;) {
190  int nl, sz;
191 
192  // skip leading spaces and newlines
193  in += strspn(in, " \n");
194  // compute end of row
195  for (nl = 0; in[nl]; ++nl)
196  if (in[nl] == '\n' && (nl==0 || !(in[nl-1] & 0x80)))
197  break;
198  if (!in[nl])
199  break;
200  // skip trailing spaces
201  sz = chop_spaces_utf8(in, nl);
202  av_bprint_append_data(&buf, in, sz);
203  av_bprintf(&buf, "\n");
204  in += nl;
205  }
206  } else {
207  av_bprintf(&buf, "%s\n", vbi_text);
208  }
209  av_free(vbi_text);
210 
211  if (!av_bprint_is_complete(&buf)) {
212  av_bprint_finalize(&buf, NULL);
213  return AVERROR(ENOMEM);
214  }
215 
216  if (buf.len) {
217  sub_rect->type = SUBTITLE_ASS;
218  sub_rect->ass = create_ass_text(ctx, buf.str);
219 
220  if (!sub_rect->ass) {
221  av_bprint_finalize(&buf, NULL);
222  return AVERROR(ENOMEM);
223  }
224  av_log(ctx, AV_LOG_DEBUG, "subtext:%s:txetbus\n", sub_rect->ass);
225  } else {
226  sub_rect->type = SUBTITLE_NONE;
227  }
228  av_bprint_finalize(&buf, NULL);
229  return 0;
230 }
231 
232 static void bprint_color(const char *type, AVBPrint *buf, vbi_page *page, unsigned ci)
233 {
234  int r = VBI_R(page->color_map[ci]);
235  int g = VBI_G(page->color_map[ci]);
236  int b = VBI_B(page->color_map[ci]);
237  av_bprintf(buf, "{\\%s&H%02X%02X%02X&}", type, b, g, r);
238 }
239 
240 #define IS_TXT_SPACE(ch) ((ch).unicode < 0x0020 || (ch).unicode >= 0xe000 || (ch).unicode == 0x00a0 ||\
241  (ch).size > VBI_DOUBLE_SIZE || (ch).opacity == VBI_TRANSPARENT_SPACE)
242 
243 static void get_trim_info(vbi_page *page, vbi_char *row, int *leading, int *trailing, int *olen)
244 {
245  int i, len = 0;
246  int char_seen = 0;
247 
248  *leading = 0;
249 
250  for (i = 0; i < page->columns; i++) {
251  uint16_t out = IS_TXT_SPACE(row[i]) ? 32 : row[i].unicode;
252 
253  if (out == 32 && !char_seen)
254  (*leading)++;
255  else if (out != 32)
256  char_seen = 1, len = i - (*leading) + 1;
257  }
258 
259  *olen = len;
260  *trailing = len > 0 ? page->columns - *leading - len : page->columns;
261 }
262 
263 static void decode_string(vbi_page *page, vbi_char *row, AVBPrint *buf,
264  int start, int end, vbi_color *cur_color, vbi_color *cur_back_color)
265 {
266  int i;
267 
268  for (i = start; i < end; i++) {
269  uint16_t out = IS_TXT_SPACE(row[i]) ? 32 : row[i].unicode;
270 
271  if (*cur_color != row[i].foreground) {
272  bprint_color("c", buf, page, row[i].foreground);
273  *cur_color = row[i].foreground;
274  }
275  if (*cur_back_color != row[i].background) {
276  bprint_color("3c", buf, page, row[i].background);
277  *cur_back_color = row[i].background;
278  }
279 
280  if (out == 32) {
281  av_bprintf(buf, "\\h");
282  } else if (out == '\\' || out == '{' || out == '}') {
283  av_bprintf(buf, "\\%c", (char)out);
284  } else {
285  char tmp;
286  /* convert to utf-8 */
287  PUT_UTF8(out, tmp, av_bprint_chars(buf, tmp, 1););
288  }
289  }
290 }
291 
292 /* Draw a page as ass formatted text */
293 static int gen_sub_ass(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_page *page, int chop_top)
294 {
295  int i;
296  int leading, trailing, len;
297  int last_trailing = -1, last_leading = -1;
298  int min_trailing = page->columns, min_leading = page->columns;
299  int alignment = 2;
300  int vertical_align = -1;
301  int can_align_left = 1, can_align_right = 1, can_align_center = 1;
302  int is_subtitle_page = ctx->subtitle_map[page->pgno & 0x7ff];
303  int empty_lines = 0;
304  vbi_color cur_color = VBI_WHITE;
305  vbi_color cur_back_color = VBI_BLACK;
306  AVBPrint buf;
307 
309 
310  for (i = chop_top; i < page->rows; i++) {
311  vbi_char *row = page->text + i * page->columns;
312 
313  get_trim_info(page, row, &leading, &trailing, &len);
314 
315  if (len) {
316  if (last_leading != -1 && last_leading != leading || leading > 5)
317  can_align_left = 0;
318  if (last_trailing != -1 && last_trailing != trailing || trailing > 2)
319  can_align_right = 0;
320  if (last_trailing != -1 && (FFABS((trailing - leading) - (last_trailing - last_leading)) > 1) || trailing - leading > 4)
321  can_align_center = 0;
322  last_leading = leading;
323  last_trailing = trailing;
324  min_leading = FFMIN(leading, min_leading);
325  min_trailing = FFMIN(trailing, min_trailing);
326  }
327  }
328 
329  if (!can_align_right && can_align_left && !can_align_center) {
330  ctx->last_ass_alignment = alignment = 1;
331  } else if (!can_align_right && !can_align_left && can_align_center) {
332  ctx->last_ass_alignment = alignment = 2;
333  } else if (can_align_right && !can_align_left && !can_align_center) {
334  ctx->last_ass_alignment = alignment = 3;
335  } else {
336  if (ctx->last_ass_alignment == 1 && can_align_left ||
337  ctx->last_ass_alignment == 2 && can_align_center ||
338  ctx->last_ass_alignment == 3 && can_align_right)
339  alignment = ctx->last_ass_alignment;
340  }
341 
342  for (i = chop_top; i < page->rows; i++) {
343  int j;
344  vbi_char *row = page->text + i * page->columns;
345  int is_transparent_line;
346 
347  for (j = 0; j < page->columns; j++)
348  if (row[j].opacity != VBI_TRANSPARENT_SPACE)
349  break;
350  is_transparent_line = (j == page->columns);
351 
352  len = is_transparent_line ? 0 : page->columns;
353  leading = trailing = is_transparent_line ? page->columns : 0;
354 
355  if (is_subtitle_page) {
356  if (!is_transparent_line)
357  get_trim_info(page, row, &leading, &trailing, &len);
358 
359  if (vertical_align == -1 && len) {
360  vertical_align = (2 - (av_clip(i + 1, 0, 23) / 8));
361  av_bprintf(&buf, "{\\an%d}", alignment + vertical_align * 3);
362  if (vertical_align != 2)
363  empty_lines = 0;
364  }
365 
366  if (len && empty_lines > 1)
367  for (empty_lines /= 2; empty_lines > 0; empty_lines--)
368  av_bprintf(&buf, " \\N");
369 
370  if (alignment == 1 || alignment == 2 && !can_align_center)
371  leading = min_leading;
372  if (alignment == 3 || alignment == 2 && !can_align_center)
373  trailing = min_trailing;
374  }
375 
376  if (len || !is_subtitle_page) {
377  decode_string(page, row, &buf, leading, page->columns - trailing, &cur_color, &cur_back_color);
378  av_bprintf(&buf, " \\N");
379  empty_lines = 0;
380  } else {
381  empty_lines++;
382  }
383  }
384 
385  if (vertical_align == 0)
386  for (empty_lines = (empty_lines - 1) / 2; empty_lines > 0; empty_lines--)
387  av_bprintf(&buf, " \\N");
388 
389  if (!av_bprint_is_complete(&buf)) {
390  av_bprint_finalize(&buf, NULL);
391  return AVERROR(ENOMEM);
392  }
393 
394  if (buf.len) {
395  sub_rect->type = SUBTITLE_ASS;
396  sub_rect->ass = ff_ass_get_dialog(ctx->readorder++, 0, is_subtitle_page ? "Subtitle" : "Teletext", NULL, buf.str);
397 
398  if (!sub_rect->ass) {
399  av_bprint_finalize(&buf, NULL);
400  return AVERROR(ENOMEM);
401  }
402  av_log(ctx, AV_LOG_DEBUG, "subtext:%s:txetbus\n", sub_rect->ass);
403  } else {
404  sub_rect->type = SUBTITLE_NONE;
405  }
406  av_bprint_finalize(&buf, NULL);
407  return 0;
408 }
409 
411  int chop_top, int resx, int resy)
412 {
413  int iy;
414 
415  // Hack for transparency, inspired by VLC code...
416  for (iy = 0; iy < resy; iy++) {
417  uint8_t *pixel = sub_rect->data[0] + iy * sub_rect->linesize[0];
418  vbi_char *vc = page->text + (iy / BITMAP_CHAR_HEIGHT + chop_top) * page->columns;
419  vbi_char *vcnext = vc + page->columns;
420  for (; vc < vcnext; vc++) {
421  uint8_t *pixelnext = pixel + BITMAP_CHAR_WIDTH;
422  switch (vc->opacity) {
423  case VBI_TRANSPARENT_SPACE:
424  memset(pixel, VBI_TRANSPARENT_BLACK, BITMAP_CHAR_WIDTH);
425  break;
426  case VBI_OPAQUE:
427  if (!ctx->transparent_bg)
428  break;
429  case VBI_SEMI_TRANSPARENT:
430  if (ctx->opacity > 0) {
431  if (ctx->opacity < 255)
432  for(; pixel < pixelnext; pixel++)
433  if (*pixel == vc->background)
434  *pixel += VBI_NB_COLORS;
435  break;
436  }
437  case VBI_TRANSPARENT_FULL:
438  for(; pixel < pixelnext; pixel++)
439  if (*pixel == vc->background)
440  *pixel = VBI_TRANSPARENT_BLACK;
441  break;
442  }
443  pixel = pixelnext;
444  }
445  }
446 }
447 
448 /* Draw a page as bitmap */
449 static int gen_sub_bitmap(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_page *page, int chop_top)
450 {
451  int resx = page->columns * BITMAP_CHAR_WIDTH;
452  int resy = (page->rows - chop_top) * BITMAP_CHAR_HEIGHT;
453  uint8_t ci;
454  vbi_char *vc = page->text + (chop_top * page->columns);
455  vbi_char *vcend = page->text + (page->rows * page->columns);
456 
457  for (; vc < vcend; vc++) {
458  if (vc->opacity != VBI_TRANSPARENT_SPACE)
459  break;
460  }
461 
462  if (vc >= vcend) {
463  av_log(ctx, AV_LOG_DEBUG, "dropping empty page %3x\n", page->pgno);
464  sub_rect->type = SUBTITLE_NONE;
465  return 0;
466  }
467 
468  sub_rect->data[0] = av_mallocz(resx * resy);
469  sub_rect->linesize[0] = resx;
470  if (!sub_rect->data[0])
471  return AVERROR(ENOMEM);
472 
473  vbi_draw_vt_page_region(page, VBI_PIXFMT_PAL8,
474  sub_rect->data[0], sub_rect->linesize[0],
475  0, chop_top, page->columns, page->rows - chop_top,
476  /*reveal*/ 1, /*flash*/ 1);
477 
478  fix_transparency(ctx, sub_rect, page, chop_top, resx, resy);
479  sub_rect->x = ctx->x_offset;
480  sub_rect->y = ctx->y_offset + chop_top * BITMAP_CHAR_HEIGHT;
481  sub_rect->w = resx;
482  sub_rect->h = resy;
483  sub_rect->nb_colors = ctx->opacity > 0 && ctx->opacity < 255 ? 2 * VBI_NB_COLORS : VBI_NB_COLORS;
484  sub_rect->data[1] = av_mallocz(AVPALETTE_SIZE);
485  if (!sub_rect->data[1]) {
486  av_freep(&sub_rect->data[0]);
487  return AVERROR(ENOMEM);
488  }
489  for (ci = 0; ci < VBI_NB_COLORS; ci++) {
490  int r, g, b, a;
491 
492  r = VBI_R(page->color_map[ci]);
493  g = VBI_G(page->color_map[ci]);
494  b = VBI_B(page->color_map[ci]);
495  a = VBI_A(page->color_map[ci]);
496  ((uint32_t *)sub_rect->data[1])[ci] = RGBA(r, g, b, a);
497  ((uint32_t *)sub_rect->data[1])[ci + VBI_NB_COLORS] = RGBA(r, g, b, ctx->opacity);
498  ff_dlog(ctx, "palette %0x\n", ((uint32_t *)sub_rect->data[1])[ci]);
499  }
500  ((uint32_t *)sub_rect->data[1])[VBI_TRANSPARENT_BLACK] = RGBA(0, 0, 0, 0);
501  ((uint32_t *)sub_rect->data[1])[VBI_TRANSPARENT_BLACK + VBI_NB_COLORS] = RGBA(0, 0, 0, 0);
502  sub_rect->type = SUBTITLE_BITMAP;
503  return 0;
504 }
505 
506 static void handler(vbi_event *ev, void *user_data)
507 {
509  TeletextPage *new_pages;
510  vbi_page page;
511  int res;
512  char pgno_str[12];
513  int chop_top;
514  int is_subtitle_page = ctx->subtitle_map[ev->ev.ttx_page.pgno & 0x7ff];
515 
516  snprintf(pgno_str, sizeof pgno_str, "%03x", ev->ev.ttx_page.pgno);
517  av_log(ctx, AV_LOG_DEBUG, "decoded page %s.%02x\n",
518  pgno_str, ev->ev.ttx_page.subno & 0xFF);
519 
520  if (strcmp(ctx->pgno, "*") && (strcmp(ctx->pgno, "subtitle") || !is_subtitle_page) && !strstr(ctx->pgno, pgno_str))
521  return;
522  if (ctx->handler_ret < 0)
523  return;
524 
525  res = vbi_fetch_vt_page(ctx->vbi, &page,
526  ev->ev.ttx_page.pgno,
527  ev->ev.ttx_page.subno,
528  VBI_WST_LEVEL_3p5, 25, TRUE);
529 
530  if (!res)
531  return;
532 
533  chop_top = ctx->chop_top || ((page.rows > 1) && is_subtitle_page);
534 
535  av_log(ctx, AV_LOG_DEBUG, "%d x %d page chop:%d\n",
536  page.columns, page.rows, chop_top);
537 
538  if (ctx->nb_pages < MAX_BUFFERED_PAGES) {
539  if ((new_pages = av_realloc_array(ctx->pages, ctx->nb_pages + 1, sizeof(TeletextPage)))) {
540  TeletextPage *cur_page = new_pages + ctx->nb_pages;
541  ctx->pages = new_pages;
542  cur_page->sub_rect = av_mallocz(sizeof(*cur_page->sub_rect));
543  cur_page->pts = ctx->pts;
544  cur_page->pgno = ev->ev.ttx_page.pgno;
545  cur_page->subno = ev->ev.ttx_page.subno;
546  if (cur_page->sub_rect) {
547  switch (ctx->format_id) {
548  case 0:
549  res = gen_sub_bitmap(ctx, cur_page->sub_rect, &page, chop_top);
550  break;
551  case 1:
552  res = gen_sub_text(ctx, cur_page->sub_rect, &page, chop_top);
553  break;
554  case 2:
555  res = gen_sub_ass(ctx, cur_page->sub_rect, &page, chop_top);
556  break;
557  default:
558  res = AVERROR_BUG;
559  break;
560  }
561  if (res < 0) {
562  av_freep(&cur_page->sub_rect);
563  ctx->handler_ret = res;
564  } else {
565  ctx->pages[ctx->nb_pages++] = *cur_page;
566  }
567  } else {
568  ctx->handler_ret = AVERROR(ENOMEM);
569  }
570  } else {
571  ctx->handler_ret = AVERROR(ENOMEM);
572  }
573  } else {
574  //TODO: If multiple packets contain more than one page, pages may got queued up, and this may happen...
575  av_log(ctx, AV_LOG_ERROR, "Buffered too many pages, dropping page %s.\n", pgno_str);
576  ctx->handler_ret = AVERROR(ENOSYS);
577  }
578 
579  vbi_unref_page(&page);
580 }
581 
583 {
584  int lines = 0;
585  while (size >= 2 && lines < MAX_SLICES) {
586  int data_unit_id = buf[0];
587  int data_unit_length = buf[1];
588  if (data_unit_length + 2 > size)
589  return AVERROR_INVALIDDATA;
590  if (ff_data_unit_id_is_teletext(data_unit_id)) {
591  if (data_unit_length != 0x2c)
592  return AVERROR_INVALIDDATA;
593  else {
594  int line_offset = buf[2] & 0x1f;
595  int field_parity = buf[2] & 0x20;
596  uint8_t *p = ctx->sliced[lines].data;
597  int i, pmag;
598  ctx->sliced[lines].id = VBI_SLICED_TELETEXT_B;
599  ctx->sliced[lines].line = (line_offset > 0 ? (line_offset + (field_parity ? 0 : 313)) : 0);
600  for (i = 0; i < 42; i++)
601  p[i] = vbi_rev8(buf[4 + i]);
602  /* Unfortunately libzvbi does not expose page flags, and
603  * vbi_classify_page only checks MIP, so we have to manually
604  * decode the page flags and store the results. */
605  pmag = vbi_unham16p(p);
606  if (pmag >= 0 && pmag >> 3 == 0) { // We found a row 0 header
607  int page = vbi_unham16p(p + 2);
608  int flags1 = vbi_unham16p(p + 6);
609  int flags2 = vbi_unham16p(p + 8);
610  if (page >= 0 && flags1 >= 0 && flags2 >= 0) {
611  int pgno = ((pmag & 7) << 8) + page;
612  // Check for disabled NEWSFLASH flag and enabled SUBTITLE and SUPRESS_HEADER flags
613  ctx->subtitle_map[pgno] = (!(flags1 & 0x40) && flags1 & 0x80 && flags2 & 0x01);
614  // Propagate ERASE_PAGE flag for repeated page headers to work around a libzvbi bug
615  if (ctx->subtitle_map[pgno] && pgno == ctx->last_pgno) {
616  int last_byte9 = vbi_unham8(ctx->last_p5);
617  if (last_byte9 >= 0 && last_byte9 & 0x8) {
618  int byte9 = vbi_unham8(p[5]);
619  if (byte9 >= 0)
620  p[5] = vbi_ham8(byte9 | 0x8);
621  }
622  }
623  ctx->last_pgno = pgno;
624  ctx->last_p5 = p[5];
625  }
626  }
627  lines++;
628  }
629  }
630  size -= data_unit_length + 2;
631  buf += data_unit_length + 2;
632  }
633  if (size)
634  av_log(ctx, AV_LOG_WARNING, "%d bytes remained after slicing data\n", size);
635  return lines;
636 }
637 
638 static int teletext_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *pkt)
639 {
640  TeletextContext *ctx = avctx->priv_data;
641  AVSubtitle *sub = data;
642  int ret = 0;
643  int j;
644 
645  if (!ctx->vbi) {
646  if (!(ctx->vbi = vbi_decoder_new()))
647  return AVERROR(ENOMEM);
648  if (!vbi_event_handler_register(ctx->vbi, VBI_EVENT_TTX_PAGE, handler, ctx)) {
649  vbi_decoder_delete(ctx->vbi);
650  ctx->vbi = NULL;
651  return AVERROR(ENOMEM);
652  }
653  }
654 
655  if (avctx->pkt_timebase.num && pkt->pts != AV_NOPTS_VALUE)
656  ctx->pts = av_rescale_q(pkt->pts, avctx->pkt_timebase, AV_TIME_BASE_Q);
657 
658  if (pkt->size) {
659  int lines;
660  const int full_pes_size = pkt->size + 45; /* PES header is 45 bytes */
661 
662  // We allow unreasonably big packets, even if the standard only allows a max size of 1472
663  if (full_pes_size < 184 || full_pes_size > 65504 || full_pes_size % 184 != 0)
664  return AVERROR_INVALIDDATA;
665 
666  ctx->handler_ret = pkt->size;
667 
669  if ((lines = slice_to_vbi_lines(ctx, pkt->data + 1, pkt->size - 1)) < 0)
670  return lines;
671  ff_dlog(avctx, "ctx=%p buf_size=%d lines=%u pkt_pts=%7.3f\n",
672  ctx, pkt->size, lines, (double)pkt->pts/90000.0);
673  if (lines > 0) {
674  vbi_decode(ctx->vbi, ctx->sliced, lines, 0.0);
675  ctx->lines_processed += lines;
676  }
677  }
678  ctx->pts = AV_NOPTS_VALUE;
679  ret = ctx->handler_ret;
680  }
681 
682  if (ret < 0)
683  return ret;
684 
685  // is there a subtitle to pass?
686  if (ctx->nb_pages) {
687  int i;
688  sub->format = !!ctx->format_id;
689  sub->start_display_time = 0;
690  sub->end_display_time = ctx->sub_duration;
691  sub->num_rects = 0;
692  sub->pts = ctx->pages->pts;
693 
694  if (ctx->pages->sub_rect->type != SUBTITLE_NONE) {
695  sub->rects = av_malloc(sizeof(*sub->rects));
696  if (sub->rects) {
697  sub->num_rects = 1;
698  sub->rects[0] = ctx->pages->sub_rect;
699 #if FF_API_AVPICTURE
701  for (j = 0; j < 4; j++) {
702  sub->rects[0]->pict.data[j] = sub->rects[0]->data[j];
703  sub->rects[0]->pict.linesize[j] = sub->rects[0]->linesize[j];
704  }
706 #endif
707  } else {
708  ret = AVERROR(ENOMEM);
709  }
710  } else {
711  av_log(avctx, AV_LOG_DEBUG, "sending empty sub\n");
712  sub->rects = NULL;
713  }
714  if (!sub->rects) // no rect was passed
716 
717  for (i = 0; i < ctx->nb_pages - 1; i++)
718  ctx->pages[i] = ctx->pages[i + 1];
719  ctx->nb_pages--;
720 
721  if (ret >= 0)
722  *data_size = 1;
723  } else
724  *data_size = 0;
725 
726  return ret;
727 }
728 
730 {
731  TeletextContext *ctx = avctx->priv_data;
732  unsigned int maj, min, rev;
733 
734  vbi_version(&maj, &min, &rev);
735  if (!(maj > 0 || min > 2 || min == 2 && rev >= 26)) {
736  av_log(avctx, AV_LOG_ERROR, "decoder needs zvbi version >= 0.2.26.\n");
737  return AVERROR_EXTERNAL;
738  }
739 
740  if (ctx->format_id == 0) {
741  avctx->width = 41 * BITMAP_CHAR_WIDTH;
742  avctx->height = 25 * BITMAP_CHAR_HEIGHT;
743  }
744 
745  ctx->vbi = NULL;
746  ctx->pts = AV_NOPTS_VALUE;
747  ctx->last_pgno = -1;
748  ctx->last_ass_alignment = 2;
749 
750  if (ctx->opacity == -1)
751  ctx->opacity = ctx->transparent_bg ? 0 : 255;
752 
753  av_log(avctx, AV_LOG_VERBOSE, "page filter: %s\n", ctx->pgno);
754 
755  switch (ctx->format_id) {
756  case 0:
757  return 0;
758  case 1:
759  return ff_ass_subtitle_header_default(avctx);
760  case 2:
761  return my_ass_subtitle_header(avctx);
762  }
763  return AVERROR_BUG;
764 }
765 
767 {
768  TeletextContext *ctx = avctx->priv_data;
769 
770  ff_dlog(avctx, "lines_total=%u\n", ctx->lines_processed);
771  while (ctx->nb_pages)
772  subtitle_rect_free(&ctx->pages[--ctx->nb_pages].sub_rect);
773  av_freep(&ctx->pages);
774 
775  vbi_decoder_delete(ctx->vbi);
776  ctx->vbi = NULL;
777  ctx->pts = AV_NOPTS_VALUE;
778  ctx->last_pgno = -1;
779  ctx->last_ass_alignment = 2;
780  memset(ctx->subtitle_map, 0, sizeof(ctx->subtitle_map));
781  if (!(avctx->flags2 & AV_CODEC_FLAG2_RO_FLUSH_NOOP))
782  ctx->readorder = 0;
783  return 0;
784 }
785 
786 static void teletext_flush(AVCodecContext *avctx)
787 {
788  teletext_close_decoder(avctx);
789 }
790 
791 #define OFFSET(x) offsetof(TeletextContext, x)
792 #define SD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM
793 static const AVOption options[] = {
794  {"txt_page", "page numbers to decode, subtitle for subtitles, * for all", OFFSET(pgno), AV_OPT_TYPE_STRING, {.str = "*"}, 0, 0, SD},
795  {"txt_chop_top", "discards the top teletext line", OFFSET(chop_top), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, SD},
796  {"txt_format", "format of the subtitles (bitmap or text or ass)", OFFSET(format_id), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 2, SD, "txt_format"},
797  {"bitmap", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, SD, "txt_format"},
798  {"text", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 0, SD, "txt_format"},
799  {"ass", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 0, SD, "txt_format"},
800  {"txt_left", "x offset of generated bitmaps", OFFSET(x_offset), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 65535, SD},
801  {"txt_top", "y offset of generated bitmaps", OFFSET(y_offset), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 65535, SD},
802  {"txt_chop_spaces", "chops leading and trailing spaces from text", OFFSET(chop_spaces), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, SD},
803  {"txt_duration", "display duration of teletext pages in msecs", OFFSET(sub_duration), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 86400000, SD},
804  {"txt_transparent", "force transparent background of the teletext", OFFSET(transparent_bg), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, SD},
805  {"txt_opacity", "set opacity of the transparent background", OFFSET(opacity), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 255, SD},
806  { NULL },
807 };
808 
809 static const AVClass teletext_class = {
810  .class_name = "libzvbi_teletextdec",
811  .item_name = av_default_item_name,
812  .option = options,
813  .version = LIBAVUTIL_VERSION_INT,
814 };
815 
817  .name = "libzvbi_teletextdec",
818  .long_name = NULL_IF_CONFIG_SMALL("Libzvbi DVB teletext decoder"),
819  .type = AVMEDIA_TYPE_SUBTITLE,
821  .priv_data_size = sizeof(TeletextContext),
823  .close = teletext_close_decoder,
825  .capabilities = AV_CODEC_CAP_DELAY,
827  .priv_class= &teletext_class,
828  .wrapper_name = "libzvbi",
829 };
static av_always_inline int ff_data_identifier_is_teletext(int data_identifier)
Definition: dvbtxt.h:28
static void fix_transparency(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_page *page, int chop_top, int resx, int resy)
#define NULL
Definition: coverity.c:32
static int gen_sub_text(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_page *page, int chop_top)
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:94
static int my_ass_subtitle_header(AVCodecContext *avctx)
int x
top left corner of pict, undefined when pict is not set
Definition: avcodec.h:3899
AVOption.
Definition: opt.h:246
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
static void flush(AVCodecContext *avctx)
static av_always_inline int ff_data_unit_id_is_teletext(int data_unit_id)
Definition: dvbtxt.h:36
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
#define VBI_NB_COLORS
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
const char * g
Definition: vf_curves.c:115
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
#define VBI_A(rgba)
#define TEXT_MAXSZ
int num
Numerator.
Definition: rational.h:59
int nb_colors
number of colors in pict, undefined when pict is not set
Definition: avcodec.h:3903
int size
Definition: avcodec.h:1478
static char * create_ass_text(TeletextContext *ctx, const char *text)
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
vbi_sliced sliced[MAX_SLICES]
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:36
static int chop_spaces_utf8(const unsigned char *t, int len)
GLint GLenum type
Definition: opengl_enc.c:104
unsigned num_rects
Definition: avcodec.h:3937
static void decode_string(vbi_page *page, vbi_char *row, AVBPrint *buf, int start, int end, vbi_color *cur_color, vbi_color *cur_back_color)
#define OFFSET(x)
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:236
#define PUT_UTF8(val, tmp, PUT_BYTE)
Convert a 32-bit Unicode character to its UTF-8 encoded form (up to 4 bytes long).
Definition: common.h:438
static AVPacket pkt
AVCodec.
Definition: avcodec.h:3481
#define MAX_SLICES
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:42
attribute_deprecated AVPicture pict
Definition: avcodec.h:3910
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:235
AVSubtitleRect ** rects
Definition: avcodec.h:3938
static int gen_sub_ass(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_page *page, int chop_top)
static int slice_to_vbi_lines(TeletextContext *ctx, uint8_t *buf, int size)
int w
width of pict, undefined when pict is not set
Definition: avcodec.h:3901
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
#define AV_CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
Definition: avcodec.h:1006
uint8_t
#define av_malloc(s)
AVOptions.
int subtitle_header_size
Definition: avcodec.h:3051
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
attribute_deprecated int linesize[AV_NUM_DATA_POINTERS]
number of bytes per line
Definition: avcodec.h:3870
int ff_ass_subtitle_header_default(AVCodecContext *avctx)
Generate a suitable AVCodecContext.subtitle_header for SUBTITLE_ASS with default style.
Definition: ass.c:80
static void handler(vbi_event *ev, void *user_data)
void av_bprint_append_data(AVBPrint *buf, const char *data, unsigned size)
Append data to a print buffer.
Definition: bprint.c:158
uint8_t * data
Definition: avcodec.h:1477
#define ff_dlog(a,...)
#define BITMAP_CHAR_HEIGHT
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
ptrdiff_t size
Definition: opengl_enc.c:100
#define MAX_BUFFERED_PAGES
int h
height of pict, undefined when pict is not set
Definition: avcodec.h:3902
#define AV_CODEC_FLAG2_RO_FLUSH_NOOP
Do not reset ASS ReadOrder field on flush (subtitles decoding)
Definition: avcodec.h:963
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:198
static void get_trim_info(vbi_page *page, vbi_char *row, int *leading, int *trailing, int *olen)
#define av_log(a,...)
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
AVRational pkt_timebase
Timebase in which pkt_dts/pts and AVPacket.dts/pts are.
Definition: avcodec.h:3119
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
#define AV_BPRINT_SIZE_UNLIMITED
char * ff_ass_get_dialog(int readorder, int layer, const char *style, const char *speaker, const char *text)
Craft an ASS dialog string.
Definition: ass.c:93
#define SD
int y
top left corner of pict, undefined when pict is not set
Definition: avcodec.h:3900
#define FALSE
Definition: windows2linux.h:37
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
AVS_Value void * user_data
Definition: avisynth_c.h:775
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
const char * r
Definition: vf_curves.c:114
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
const char * name
Name of the codec implementation.
Definition: avcodec.h:3488
#define VBI_G(rgba)
uint8_t subtitle_map[2048]
#define BITMAP_CHAR_WIDTH
uint32_t end_display_time
Definition: avcodec.h:3936
int64_t pts
Same as packet pts, in AV_TIME_BASE.
Definition: avcodec.h:3939
char * av_asprintf(const char *fmt,...)
Definition: avstring.c:113
AVCodec ff_libzvbi_teletext_decoder
common internal API header
A bitmap, pict will be set.
Definition: avcodec.h:3881
int linesize[4]
Definition: avcodec.h:3917
#define b
Definition: input.c:41
#define VBI_B(rgba)
#define FFMIN(a, b)
Definition: common.h:96
int width
picture width / height.
Definition: avcodec.h:1738
AVFormatContext * ctx
Definition: movenc.c:48
attribute_deprecated uint8_t * data[AV_NUM_DATA_POINTERS]
pointers to the image data planes
Definition: avcodec.h:3868
#define TRUE
Definition: windows2linux.h:33
uint16_t format
Definition: avcodec.h:3934
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:72
static void teletext_flush(AVCodecContext *avctx)
static int av_bprint_is_complete(const AVBPrint *buf)
Test if the print buffer is complete (not truncated).
Definition: bprint.h:185
#define RGBA(r, g, b, a)
uint8_t * data[4]
data+linesize for the bitmap of this subtitle.
Definition: avcodec.h:3916
#define VBI_R(rgba)
if(ret)
static int teletext_close_decoder(AVCodecContext *avctx)
static void bprint_color(const char *type, AVBPrint *buf, vbi_page *page, unsigned ci)
Libavcodec external API header.
#define VBI_TRANSPARENT_BLACK
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:260
static const AVOption options[]
main external API structure.
Definition: avcodec.h:1565
void * buf
Definition: avisynth_c.h:766
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:50
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31))))#define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac){}void ff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map){AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);return NULL;}return ac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;}int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){int use_generic=1;int len=in->nb_samples;int p;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
Describe the class of an AVClass context structure.
Definition: log.h:67
static int teletext_init_decoder(AVCodecContext *avctx)
#define snprintf
Definition: snprintf.h:34
static int teletext_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *pkt)
uint8_t pixel
Definition: tiny_ssim.c:42
static const AVClass teletext_class
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:84
common internal and external API header
uint32_t start_display_time
Definition: avcodec.h:3935
TeletextPage * pages
static int gen_sub_bitmap(TeletextContext *ctx, AVSubtitleRect *sub_rect, vbi_page *page, int chop_top)
void * priv_data
Definition: avcodec.h:1592
Formatted text, the ass field must be set by the decoder and is authoritative.
Definition: avcodec.h:3893
#define av_free(p)
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:85
int len
void ff_ass_bprint_text_event(AVBPrint *buf, const char *p, int size, const char *linebreaks, int keep_ass_markup)
Escape a text subtitle using ASS syntax into an AVBPrint buffer.
Definition: ass.c:131
char * ass
0 terminated ASS/SSA compatible event line.
Definition: avcodec.h:3928
int flags2
AV_CODEC_FLAG2_*.
Definition: avcodec.h:1652
FILE * out
Definition: movenc.c:54
#define av_freep(p)
void INT64 start
Definition: avisynth_c.h:766
static void subtitle_rect_free(AVSubtitleRect **sub_rect)
#define IS_TXT_SPACE(ch)
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:3919
float min
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:57
This structure stores compressed data.
Definition: avcodec.h:1454
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1470
AVSubtitleRect * sub_rect
for(j=16;j >0;--j)
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
uint8_t * subtitle_header
Header containing style information for text subtitles.
Definition: avcodec.h:3050
void av_bprint_chars(AVBPrint *buf, char c, unsigned n)
Append char c n times to a print buffer.
Definition: bprint.c:140
static uint8_t tmp[11]
Definition: aes_ctr.c:26