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