summaryrefslogtreecommitdiffstats
path: root/stream/tvi_vbi.c
diff options
context:
space:
mode:
Diffstat (limited to 'stream/tvi_vbi.c')
-rw-r--r--stream/tvi_vbi.c1197
1 files changed, 0 insertions, 1197 deletions
diff --git a/stream/tvi_vbi.c b/stream/tvi_vbi.c
deleted file mode 100644
index 226cf9b342..0000000000
--- a/stream/tvi_vbi.c
+++ /dev/null
@@ -1,1197 +0,0 @@
-#include "config.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-
-#include "tv.h"
-#include "tvi_vbi.h"
-#include "mp_msg.h"
-#include "libmpcodecs/img_format.h"
-
-#ifdef USE_ICONV
-#include <iconv.h>
-#endif
-
-#define VBI_TEXT_CHARSET "UTF-8"
-
-char* tv_param_tdevice=NULL; ///< teletext vbi device
-char* tv_param_tformat="gray"; ///< format: text,bw,gray,color
-int tv_param_tpage=100; ///< page number
-
-
-#ifdef USE_ICONV
-/*
-------------------------------------------------------------------
- zvbi-0.2.25/src/exp-txt.c skip debug "if(1) fprintf(stderr,) " message
-------------------------------------------------------------------
-*/
-
-/**
- * libzvbi - Text export functions
- *
- * Copyright (C) 2001, 2002 Michael H. Schimek
- *
- * Based on code from AleVT 1.5.1
- * Copyright (C) 1998, 1999 Edgar Toernig <froese@gmx.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- **/
-
-/** $Id$ **/
-
-static vbi_bool
-print_unicode(iconv_t cd, int endian, int unicode, char **p, int n)
-{
- char in[2], *ip, *op;
- size_t li, lo, r;
-
- in[0 + endian] = unicode;
- in[1 - endian] = unicode >> 8;
- ip = in; op = *p;
- li = sizeof(in); lo = n;
-
- r = iconv(cd, &ip, &li, &op, &lo);
-
- if ((size_t) -1 == r
- || (**p == 0x40 && unicode != 0x0040)) {
- in[0 + endian] = 0x20;
- in[1 - endian] = 0;
- ip = in; op = *p;
- li = sizeof(in); lo = n;
-
- r = iconv(cd, &ip, &li, &op, &lo);
-
- if ((size_t) -1 == r
- || (r == 1 && **p == 0x40))
- goto error;
- }
-
- *p = op;
-
- return TRUE;
-
- error:
- return FALSE;
-}
-
-static int
-vbi_print_page_region_nodebug(vbi_page * pg, char *buf, int size,
- const char *format, vbi_bool table,
- vbi_bool rtl, int column, int row, int width,
- int height)
-{
- int endian = vbi_ucs2be();
- int column0, column1, row0, row1;
- int x, y, spaces, doubleh, doubleh0;
- iconv_t cd;
- char *p;
-
- rtl = rtl;
-
-#if 0
- if (1)
- fprintf (stderr, "vbi_print_page_region '%s' "
- "table=%d col=%d row=%d width=%d height=%d\n",
- format, table, column, row, width, height);
-#endif
-
- column0 = column;
- row0 = row;
- column1 = column + width - 1;
- row1 = row + height - 1;
-
- if (!pg || !buf || size < 0 || !format
- || column0 < 0 || column1 >= pg->columns
- || row0 < 0 || row1 >= pg->rows
- || endian < 0)
- return 0;
-
- if ((cd = iconv_open(format, "UCS-2")) == (iconv_t) -1)
- return 0;
-
- p = buf;
-
- doubleh = 0;
-
- for (y = row0; y <= row1; y++) {
- int x0, x1, xl;
-
- x0 = (table || y == row0) ? column0 : 0;
- x1 = (table || y == row1) ? column1 : (pg->columns - 1);
-
- xl = (table || y != row0 || (y + 1) != row1) ? -1 : column1;
-
- doubleh0 = doubleh;
-
- spaces = 0;
- doubleh = 0;
-
- for (x = x0; x <= x1; x++) {
- vbi_char ac = pg->text[y * pg->columns + x];
-
- if (table) {
- if (ac.size > VBI_DOUBLE_SIZE)
- ac.unicode = 0x0020;
- } else {
- switch (ac.size) {
- case VBI_NORMAL_SIZE:
- case VBI_DOUBLE_WIDTH:
- break;
-
- case VBI_DOUBLE_HEIGHT:
- case VBI_DOUBLE_SIZE:
- doubleh++;
- break;
-
- case VBI_OVER_TOP:
- case VBI_OVER_BOTTOM:
- continue;
-
- case VBI_DOUBLE_HEIGHT2:
- case VBI_DOUBLE_SIZE2:
- if (y > row0)
- ac.unicode = 0x0020;
- break;
- }
-
- /*
- * Special case two lines row0 ... row1, and all chars
- * in row0, column0 ... column1 are double height: Skip
- * row1, don't wrap around.
- */
- if (x == xl && doubleh >= (x - x0)) {
- x1 = xl;
- y = row1;
- }
-
- if (ac.unicode == 0x20 || !vbi_is_print(ac.unicode)) {
- spaces++;
- continue;
- } else {
- if (spaces < (x - x0) || y == row0) {
- for (; spaces > 0; spaces--)
- if (!print_unicode(cd, endian, 0x0020,
- &p, buf + size - p))
- goto failure;
- } else /* discard leading spaces */
- spaces = 0;
- }
- }
-
- if (!print_unicode(cd, endian, ac.unicode, &p, buf + size - p))
- goto failure;
- }
-
- /* if !table discard trailing spaces and blank lines */
-
- if (y < row1) {
- int left = buf + size - p;
-
- if (left < 1)
- goto failure;
-
- if (table) {
- *p++ = '\n'; /* XXX convert this (eg utf16) */
- } else if (spaces >= (x1 - x0)) {
- ; /* suppress blank line */
- } else {
- /* exactly one space between adjacent rows */
- if (!print_unicode(cd, endian, 0x0020, &p, left))
- goto failure;
- }
- } else {
- if (doubleh0 > 0) {
- ; /* prentend this is a blank double height lower row */
- } else {
- for (; spaces > 0; spaces--)
- if (!print_unicode(cd, endian, 0x0020, &p, buf + size - p))
- goto failure;
- }
- }
- }
-
- iconv_close(cd);
- return p - buf;
-
- failure:
- iconv_close(cd);
- return 0;
-}
-#endif
-/*
- end of zvbi-0.2.25/src/exp-txt.c part
-*/
-
-
-/*
-------------------------------------------------------------------
- Private routines
-------------------------------------------------------------------
-*/
-
-/**
- * \brief Decode event handler
- * \param ev VBI event
- * \param data pointer to user defined data
- *
- */
-static void event_handler(vbi_event * ev, void *data)
-{
- priv_vbi_t *user_vbi = (priv_vbi_t *) data;
- vbi_page pg;
- char *s;
- int i;
-
- switch (ev->type) {
- case VBI_EVENT_CAPTION:
- mp_msg(MSGT_TV,MSGL_DBG3,"caption\n");
- break;
- case VBI_EVENT_NETWORK:
- s = ev->ev.network.name;
- if (s) {
- pthread_mutex_lock(&(user_vbi->buffer_mutex));
- if (user_vbi->network_name)
- free(user_vbi->network_name);
- user_vbi->network_name = strdup(s);
- pthread_mutex_unlock(&(user_vbi->buffer_mutex));
- }
- break;
- case VBI_EVENT_NETWORK_ID:
- s = ev->ev.network.name;
- if (s) {
- pthread_mutex_lock(&(user_vbi->buffer_mutex));
- if (user_vbi->network_id)
- free(user_vbi->network_id);
- user_vbi->network_id = strdup(s);
- pthread_mutex_unlock(&(user_vbi->buffer_mutex));
- }
- break;
- case VBI_EVENT_TTX_PAGE:
- pthread_mutex_lock(&(user_vbi->buffer_mutex));
- user_vbi->curr_pgno = ev->ev.ttx_page.pgno; // page number
- user_vbi->curr_subno = ev->ev.ttx_page.subno; // subpage
- i = vbi_bcd2dec(ev->ev.ttx_page.pgno);
- if (i > 0 && i < 1000) {
- if (!user_vbi->cache[i])
- user_vbi->cache[i] = (vbi_page *) malloc(sizeof(vbi_page));
- vbi_fetch_vt_page(user_vbi->decoder, // fetch page
- user_vbi->cache[i],
- ev->ev.ttx_page.pgno,
- ev->ev.ttx_page.subno,
- VBI_WST_LEVEL_3p5, 25, TRUE);
- memcpy(user_vbi->theader, user_vbi->cache[i]->text,
- sizeof(user_vbi->theader));
- }
- pthread_mutex_unlock(&(user_vbi->buffer_mutex));
- break;
- }
-}
-
-/**
- * \brief Prepares page to be shown on screen
- * \param priv_vbi private data structure
- *
- * This routine adds page number, current time, etc to page header
- *
- */
-static void process_page(priv_vbi_t * priv_vbi)
-{
- char *pagesptr;
- int csize, i, j, subtitle = 0, sflg, send;
- void *canvas;
- char cpage[5];
- vbi_page page;
-
- memcpy(&(page), priv_vbi->page, sizeof(vbi_page));
- if (priv_vbi->pgno != priv_vbi->page->pgno) {
- //don't clear first line
- for (i = page.columns; i < 1056; i++) {
- page.text[i].unicode = ' ';
- page.text[i].background = VBI_TRANSPARENT_COLOR;
- }
- snprintf(cpage, sizeof(cpage), "%03X", priv_vbi->pgno);
- page.text[1].unicode = cpage[0];
- page.text[2].unicode = cpage[1];
- page.text[3].unicode = cpage[2];
- page.text[4].unicode = ' ';
- page.text[5].unicode = ' ';
- page.text[6].unicode = ' ';
- }
-
- //background page number & title
- j=vbi_bcd2dec(priv_vbi->curr_pgno);
- if (j>0 && j<1000 && priv_vbi->cache[j]){
- for(i=8;i<priv_vbi->cache[j]->columns;i++){
- page.text[i].unicode = priv_vbi->cache[j]->text[i].unicode;
- }
- }
-
- if (page.text[1].unicode == ' ' && page.text[2].unicode == ' ' &&
- page.text[3].unicode == ' ' && page.text[4].unicode == ' ' &&
- page.text[5].unicode == ' ' && page.text[5].unicode == ' '
- && !priv_vbi->half)
- subtitle = 1; // subtitle page
- if (priv_vbi->pagenumdec) {
- i = (priv_vbi->pagenumdec >> 12) & 0xf;
- switch (i) {
- case 1:
- page.text[1].unicode = '0' + ((priv_vbi->pagenumdec >> 0) & 0xf);
- page.text[2].unicode = '-';
- page.text[3].unicode = '-';
- break;
- case 2:
- page.text[1].unicode = '0' + ((priv_vbi->pagenumdec >> 4) & 0xf);
- page.text[2].unicode = '0' + ((priv_vbi->pagenumdec >> 0) & 0xf);
- page.text[3].unicode = '-';
- break;
- }
- page.text[4].unicode = ' ';
- page.text[5].unicode = ' ';
- page.text[6].unicode = ' ';
- page.text[1].foreground = VBI_WHITE;
- page.text[2].foreground = VBI_WHITE;
- page.text[3].foreground = VBI_WHITE;
- }
- priv_vbi->columns = page.columns;
- priv_vbi->rows = page.rows;
- if (!subtitle) { // update time in header
- memcpy(&(page.text[VBI_TIME_LINEPOS]),
- &(priv_vbi->theader[VBI_TIME_LINEPOS]),
- sizeof(vbi_char) * (priv_vbi->columns - VBI_TIME_LINEPOS));
- }
- switch (priv_vbi->tformat) {
- case VBI_TFORMAT_TEXT: // mode: text
- if (priv_vbi->txtpage) {
-#ifdef USE_ICONV
- vbi_print_page_region_nodebug(&(page), priv_vbi->txtpage,
- VBI_TXT_PAGE_SIZE, VBI_TEXT_CHARSET, TRUE,
- 0, 0, 0, page.columns, page.rows); // vbi_page to text without message
-#else
- vbi_print_page(&(page), priv_vbi->txtpage,
- VBI_TXT_PAGE_SIZE, VBI_TEXT_CHARSET, TRUE, 0);
-#endif
- }
- priv_vbi->valid_page = 1;
- break;
- case VBI_TFORMAT_BW: // mode: black & white
- for (i=0; i < (priv_vbi->pgno!=page.pgno?page.columns:1056); i++) {
- if (priv_vbi->foreground){
- page.text[i].foreground = VBI_BLACK;
- page.text[i].background = VBI_WHITE;
- }else{
- page.text[i].foreground = VBI_WHITE;
- page.text[i].background = VBI_BLACK;
- }
- }
- case VBI_TFORMAT_GRAY: // mode: grayscale
- case VBI_TFORMAT_COLOR: // mode: color (request color spu patch!)
-
-
-
- page.color_map[VBI_TRANSPARENT_COLOR] = 0;
- if (priv_vbi->alpha) {
- if (subtitle) {
- for (i = 0; i < page.rows; i++) {
- sflg = 0;
- send = 0;
- for (j = 0; j < page.columns; j++) {
- if (page.text[i * page.columns + j].unicode != ' ') {
- sflg = 1;
- send = j;
- }
- if (sflg == 0)
- page.text[i * page.columns + j].background =
- VBI_TRANSPARENT_COLOR;
- }
- for (j = send + 1; j < page.columns; j++)
- page.text[i * page.columns + j].background =
- VBI_TRANSPARENT_COLOR;
- }
- } else {
- for (i = 0; i < 1056; i++)
- page.text[i].background = VBI_TRANSPARENT_COLOR;
- }
- }
- csize = page.columns * page.rows * 12 * 10 * sizeof(vbi_rgba);
- if (csize == 0)
- break;
- if (csize > priv_vbi->canvas_size) { // test canvas size
- if (priv_vbi->canvas)
- free(priv_vbi->canvas);
- priv_vbi->canvas = malloc(csize);
- priv_vbi->canvas_size = 0;
- if (priv_vbi->canvas)
- priv_vbi->canvas_size = csize;
- }
- if (priv_vbi->canvas) {
- vbi_draw_vt_page(&(page),
- priv_vbi->fmt,
- priv_vbi->canvas,
- priv_vbi->reveal, priv_vbi->flash_on);
- priv_vbi->csize = csize;
- }
- priv_vbi->spudec_proc = 1;
- priv_vbi->valid_page = 1;
- break;
- }
-}
-
-/**
- * \brief Update page in cache
- * \param priv_vbi private data structure
- *
- * Routine also calls process_page to refresh currently visible page (if so)
- * every time it was received from VBI by background thread.
- *
- */
-static void update_page(priv_vbi_t * priv_vbi)
-{
- int i;
- int index;
- pthread_mutex_lock(&(priv_vbi->buffer_mutex));
- /*
- priv_vbi->redraw=1 - page redraw requested
- pgno!=page->pgno - page was switched
- curr_pgno==pgno - backgound process just fetched current page, refresh it
- */
- if (priv_vbi->redraw ||
- priv_vbi->pgno != priv_vbi->page->pgno ||
- priv_vbi->curr_pgno == priv_vbi->pgno) {
- index = vbi_bcd2dec(priv_vbi->pgno);
- if ( index <= 0 || index > 999 || !priv_vbi->cache[index]) {
- // curr_pgno is last decoded page
- index = vbi_bcd2dec(priv_vbi->curr_pgno);
- }
-
- if (index <=0 || index >999 || !priv_vbi->cache[index]){
- priv_vbi->valid_page = 0;
- memset(priv_vbi->page, 0, sizeof(vbi_page));
- }else
- {
- memcpy(priv_vbi->page, priv_vbi->cache[index], sizeof(vbi_page));
- process_page(priv_vbi);//prepare page to be shown on screen
- }
- }
- pthread_mutex_unlock(&(priv_vbi->buffer_mutex));
-}
-
-/**
- * \brief background grabber routine
- * \param data user-defined data
- *
- */
-static void *grabber(void *data)
-{
- priv_vbi_t *user_vbi = (priv_vbi_t *) data;
- vbi_capture_buffer *sliced_buffer;
- struct timeval timeout;
- unsigned int n_lines;
- int r, err_count = 0;
-
- while (!user_vbi->eof) {
- timeout.tv_sec = 0;
- timeout.tv_usec = 500;
- r = vbi_capture_pull(user_vbi->capture, NULL, &sliced_buffer, &timeout); // grab slices
- if (user_vbi->eof)
- return NULL;
- switch (r) {
- case -1: // read error
- if (err_count++ > 4)
- user_vbi->eof = 1;
- break;
- case 0: // time out
- break;
- default:
- err_count = 0;
- }
- if (r != 1)
- continue;
- n_lines = sliced_buffer->size / sizeof(vbi_sliced);
- vbi_decode(user_vbi->decoder, (vbi_sliced *) sliced_buffer->data,
- n_lines, sliced_buffer->timestamp); // decode slice
- update_page(user_vbi);
- }
- switch (r) {
- case -1:
- mp_msg(MSGT_TV, MSGL_ERR, "VBI read error %d (%s)\n",
- errno, strerror(errno));
- return NULL;
- case 0:
- mp_msg(MSGT_TV, MSGL_ERR, "VBI read timeout\n");
- return NULL;
- }
- return NULL;
-}
-
-/**
- * \brief calculate increased/decreased by given value page number
- * \param curr current page number in hexadecimal for
- * \param direction decimal value (can be negative) to add to value or curr parameter
- * \return new page number in hexadecimal form
- *
- * VBI page numbers are represented in special hexadecimal form, e.g.
- * page with number 123 (as seen by user) internally has number 0x123.
- * and equation 0x123+8 should be equal to 0x131 instead of regular 0x12b.
- * Page numbers 0xYYY (where Y is not belongs to (0..9) and pages below 0x100 and
- * higher 0x999 are reserved for internal use.
- *
- */
-static int steppage(int curr, int direction)
-{
- int newpage = vbi_dec2bcd(vbi_bcd2dec(curr) + direction);
- if (newpage < 0x100)
- newpage = 0x100;
- if (newpage > 0x999)
- newpage = 0x999;
- return newpage;
-}
-
-/**
- * \brief toggles teletext page displaying mode
- * \param priv_vbi private data structure
- * \param flag new mode
- * \return
- * TVI_CONTROL_TRUE is success,
- * TVI_CONTROL_FALSE otherwise
- *
- * flag:
- * 0 - off
- * 1 - on & opaque
- * 2 - on & transparent
- * 3 - on & transparent with black foreground color (only in bw mode)
- *
- */
-static int teletext_set_mode(priv_vbi_t * priv_vbi, int flag)
-{
- if (flag<0 || flag>3)
- return TVI_CONTROL_FALSE;
-
- pthread_mutex_lock(&(priv_vbi->buffer_mutex));
-
- priv_vbi->on = flag;
-
- if (priv_vbi->on > 2 && priv_vbi->tformat != VBI_TFORMAT_BW)
- priv_vbi->on = 0;
-
- priv_vbi->foreground = 0;
- priv_vbi->pagenumdec = 0;
- priv_vbi->spudec_proc = 1;
- priv_vbi->redraw = 1;
- switch (priv_vbi->on) {
- case 0:
- priv_vbi->csize = 0;
- break;
- case 1:
- priv_vbi->alpha = 0;
- break;
- case 2:
- priv_vbi->alpha = 1;
- break;
- case 3:
- priv_vbi->alpha = 1;
- priv_vbi->foreground = 1;
- break;
- }
- pthread_mutex_unlock(&(priv_vbi->buffer_mutex));
- return TVI_CONTROL_TRUE;
-}
-
-/**
- * \brief get half page mode (only in SPU mode)
- * \param priv_vbi private data structure
- * \return current mode
- * 0 : half mode off
- * 1 : top half page
- * 2 : bottom half page
- */
-static int vbi_get_half(priv_vbi_t * priv_vbi)
-{
- int flag = 0;
- pthread_mutex_lock(&(priv_vbi->buffer_mutex));
- if (priv_vbi->valid_page)
- flag = priv_vbi->half;
- priv_vbi->pagenumdec = 0;
- pthread_mutex_unlock(&(priv_vbi->buffer_mutex));
- return flag;
-}
-
-/**
- * \brief set half page mode (only in SPU mode)
- * \param priv_vbi private data structure
- * \param flag new half page mode
- * \return
- * TVI_CONTROL_TRUE is success,
- * TVI_CONTROL_FALSE otherwise
- *
- *
- * flag:
- * 0 : half mode off
- * 1 : top half page
- * 2 : bottom half page
- */
-static int teletext_set_half_page(priv_vbi_t * priv_vbi, int flag)
-{
- if (flag<0 || flag>2)
- return TVI_CONTROL_FALSE;
-
- pthread_mutex_lock(&(priv_vbi->buffer_mutex));
- priv_vbi->half = flag;
- if (priv_vbi->tformat == VBI_TFORMAT_TEXT && priv_vbi->half > 1)
- priv_vbi->half = 0;
- priv_vbi->redraw = 1;
- priv_vbi->pagenumdec = 0;
- pthread_mutex_unlock(&(priv_vbi->buffer_mutex));
- return TVI_CONTROL_TRUE;
-}
-
-/**
- * \brief displays specified page
- * \param priv_vbi private data structure
- * \param pgno page number to display
- * \param subno subpage number
- *
- */
-static void vbi_setpage(priv_vbi_t * priv_vbi, int pgno, int subno)
-{
- pthread_mutex_lock(&(priv_vbi->buffer_mutex));
- priv_vbi->pgno = steppage(0, pgno);
- priv_vbi->subno = subno;
- priv_vbi->redraw = 1;
- priv_vbi->pagenumdec = 0;
- pthread_mutex_unlock(&(priv_vbi->buffer_mutex));
-}
-
-/**
- * \brief steps over pages by a given value
- * \param priv_vbi private data structure
- * \param direction decimal step value (can be negative)
- *
- */
-static void vbi_steppage(priv_vbi_t * priv_vbi, int direction)
-{
- pthread_mutex_lock(&(priv_vbi->buffer_mutex));
- priv_vbi->pgno = steppage(priv_vbi->pgno, direction);
- priv_vbi->redraw = 1;
- priv_vbi->pagenumdec = 0;
- pthread_mutex_unlock(&(priv_vbi->buffer_mutex));
-}
-
-/**
- * \brief append just entered digit to editing page number
- * \param priv_vbi private data structure
- * \param dec decimal digit to append
- *
- * dec:
- * '0'..'9' append digit
- * '-' remove last digit (backspace emulation)
- *
- * This routine allows user to jump to arbitrary page.
- * It implements simple page number editing algorithm.
- *
- * Subsystem can be on one of two modes: normal and page number edit mode.
- * Zero value of priv_vbi->pagenumdec means normal mode
- * Non-zero value means page number edit mode and equals to packed
- * decimal number of already entered part of page number.
- *
- * How this works.
- * Let's assume that current mode is normal (pagenumdec is zero), teletext page
- * 100 are displayed as usual. topmost left corner of page contains page number.
- * Then vbi_add_dec is sequentally called (through slave
- * command of course) with 1,4,-,2,3 * values of dec parameter.
- *
- * +-----+------------+------------------+
- * | dec | pagenumxec | displayed number |
- * +-----+------------+------------------+
- * | | 0x000 | 100 |
- * +-----+------------+------------------+
- * | 1 | 0x001 | __1 |
- * +-----+------------+------------------+
- * | 4 | 0x014 | _14 |
- * +-----+------------+------------------+
- * | - | 0x001 | __1 |
- * +-----+------------+------------------+
- * | 2 | 0x012 | _12 |
- * +-----+------------+------------------+
- * | 3 | 0x123 | 123 |
- * +-----+------------+------------------+
- * | | 0x000 | 123 |
- * +-----+------------+------------------+
- *
- * pagenumdec will automatically receive zero value after third digit of page number
- * is entered and current page will be switched to another one with entered page number.
- *
- */
-static void vbi_add_dec(priv_vbi_t * priv_vbi, char *dec)
-{
- int count, shift;
- if (!dec)
- return;
- if (!priv_vbi->on)
- return;
- if ((*dec < '0' || *dec > '9') && *dec != '-')
- return;
- pthread_mutex_lock(&(priv_vbi->buffer_mutex));
- count = (priv_vbi->pagenumdec >> 12) & 0xf;
- if (*dec == '-') {
- count--;
- if (count)
- priv_vbi->pagenumdec = ((priv_vbi->pagenumdec >> 4) & 0xfff) | (count << 12);
- else
- priv_vbi->pagenumdec = 0;
- } else {
- shift = count * 4;
- count++;
- priv_vbi->pagenumdec =
- (((priv_vbi->pagenumdec) << 4 | (*dec -'0')) & 0xfff) | (count << 12);
- if (count == 3) {
- priv_vbi->pgno = priv_vbi->pagenumdec & 0xfff;
- priv_vbi->subno = 0;
- priv_vbi->redraw = 1;
- priv_vbi->pagenumdec = 0;
- }
- }
- pthread_mutex_unlock(&(priv_vbi->buffer_mutex));
-}
-
-/**
- * \brief follows link specified on current page
- * \param priv_vbi private data structure
- * \param linkno link number (0..6)
- * \return
- * TVI_CONTROL_FALSE if linkno is outside 0..6 range or if
- * teletext is switched off
- * TVI_CONTROL_TRUE otherwise
- *
- * linkno:
- * 0: tpage in tv parameters (starting page, usually 100)
- * 1..6: follows link on current page with given number
- *
- * FIXME: quick test shows that this is working strange
- * FIXME: routine does not checks whether links exists on page or not
- * TODO: more precise look
- *
- */
-static int vbi_golink(priv_vbi_t * priv_vbi, int linkno)
-{
- if (linkno < 0 || linkno > 6)
- return TVI_CONTROL_FALSE;
- if (!priv_vbi->on)
- return TVI_CONTROL_FALSE;
- pthread_mutex_lock(&(priv_vbi->buffer_mutex));
- if (linkno == 0) {
- priv_vbi->pgno = priv_vbi->tpage;
- priv_vbi->subno = priv_vbi->page->nav_link[linkno].subno;
- priv_vbi->redraw = 1;
- priv_vbi->pagenumdec = 0;
- } else {
- linkno--;
- if (priv_vbi->pgno == priv_vbi->page->pgno) {
- priv_vbi->pgno = priv_vbi->page->nav_link[linkno].pgno;
- priv_vbi->subno = priv_vbi->page->nav_link[linkno].subno;
- priv_vbi->redraw = 1;
- priv_vbi->pagenumdec = 0;
- }
- }
- priv_vbi->pagenumdec = 0;
- pthread_mutex_unlock(&(priv_vbi->buffer_mutex));
- return TVI_CONTROL_TRUE;
-}
-
-/**
- * \brief get pointer to current teletext page
- * \param priv_vbi private data structure
- * \return pointer to vbi_page structure if teletext is
- * switched on and current page is valid, NULL - otherwise
- *
- */
-static vbi_page *vbi_getpage(priv_vbi_t * priv_vbi)
-{
- vbi_page *page = NULL;
-
- if (!priv_vbi->on)
- return NULL;
- pthread_mutex_lock(&(priv_vbi->buffer_mutex));
- if (priv_vbi->valid_page)
- if (page = malloc(sizeof(vbi_page)))
- memcpy(page, priv_vbi->page, sizeof(vbi_page));
- pthread_mutex_unlock(&(priv_vbi->buffer_mutex));
- return page;
-}
-
-/**
- * \brief get pointer to current teletext page
- * \param priv_vbi private data structure
- * \return pointer to character string, containing text-only data of
- * teletext page. If teletext is switched off, current page is invalid
- * or page format if not equal to "text" then returning value is NULL.
- *
- */
-static char *vbi_getpagetext(priv_vbi_t * priv_vbi)
-{
- char *page = NULL;
-
- if (!priv_vbi->on)
- return NULL;
- if (priv_vbi->tformat != VBI_TFORMAT_TEXT && priv_vbi->canvas)
- return NULL;
- pthread_mutex_lock(&(priv_vbi->buffer_mutex));
- if (priv_vbi->valid_page)
- page = priv_vbi->txtpage;
- if (!page)
- page = priv_vbi->header;
- pthread_mutex_unlock(&(priv_vbi->buffer_mutex));
- return page;
-}
-
-/**
- * \brief get current page RGBA32 image (only in SPU mode)
- * \param priv_vbi private data structure
- * \return pointer to tv_teletext_img_t structure, containing among
- * other things rendered RGBA32 image of current teletext page.
- * return NULL is image is not available for some reason.
- *
- */
-static tv_teletext_img_t *vbi_getpageimg(priv_vbi_t * priv_vbi)
-{
- tv_teletext_img_t *img = NULL;
-
- if (priv_vbi->tformat == VBI_TFORMAT_TEXT)
- return NULL;
- if (priv_vbi->spudec_proc == 0)
- return NULL;
- pthread_mutex_lock(&(priv_vbi->buffer_mutex));
- if (NULL != (img = malloc(sizeof(tv_teletext_img_t)))) {
- img->tformat = priv_vbi->tformat; // format: bw|gray|color
- img->tformat = VBI_TFORMAT_GRAY; // format: bw|gray|color
- img->half = priv_vbi->half; // half mode
- img->columns = priv_vbi->columns; // page size
- img->rows = priv_vbi->rows;
- img->width = priv_vbi->columns * 12;
- img->width = priv_vbi->rows * 10;
- img->canvas = NULL;
- // is page ok?
- if (priv_vbi->canvas && priv_vbi->on && priv_vbi->csize && priv_vbi->valid_page) {
-
- if (NULL != (img->canvas = malloc(priv_vbi->csize)))
- memcpy(img->canvas, priv_vbi->canvas, priv_vbi->csize);
- }
- }
- priv_vbi->spudec_proc = 0;
- pthread_mutex_unlock(&(priv_vbi->buffer_mutex));
- return img;
-}
-
-/**
- * \brief start teletext sybsystem
- * \param priv_vbi private data structure
- *
- * initializes cache, vbi decoder and starts background thread
- *
- */
-static void vbi_start(priv_vbi_t * priv_vbi)
-{
- if (!priv_vbi)
- return;
- if (NULL != (priv_vbi->txtpage = malloc(VBI_TXT_PAGE_SIZE))) // alloc vbi_page
- memset(priv_vbi->txtpage, 0, VBI_TXT_PAGE_SIZE);
- priv_vbi->page = malloc(sizeof(vbi_page));
- priv_vbi->cache = (vbi_page **) malloc(1000 * sizeof(vbi_page *));
- memset(priv_vbi->cache, 0, 1000 * sizeof(vbi_page *));
- priv_vbi->decoder = vbi_decoder_new();
- priv_vbi->subno = 0;
- priv_vbi->fmt = VBI_PIXFMT_RGBA32_LE;
- memset(priv_vbi->theader, 0, sizeof(priv_vbi->theader));
- snprintf(priv_vbi->header, sizeof(priv_vbi->header), "%s", VBI_NO_TELETEXT);
- vbi_event_handler_add(priv_vbi->decoder, ~0, event_handler, (void *) priv_vbi); // add event handler
- pthread_create(&priv_vbi->grabber_thread, NULL, grabber, priv_vbi); // add grab function
- pthread_mutex_init(&priv_vbi->buffer_mutex, NULL);
- priv_vbi->valid_page = 0;
- priv_vbi->pagenumdec = 0;
- mp_msg(MSGT_TV, MSGL_INFO, "Teletext device: %s\n", priv_vbi->device);
-}
-
-/**
- * \brief Teletext reset
- * \param priv_vbi private data structure
- *
- * should be called during frequency, norm change, etc
- *
- */
-static void vbi_reset(priv_vbi_t * priv_vbi)
-{
- int i;
- pthread_mutex_lock(&(priv_vbi->buffer_mutex));
- if (priv_vbi->canvas)
- free(priv_vbi->canvas);
- priv_vbi->canvas = NULL;
- priv_vbi->canvas_size = 0;
- priv_vbi->redraw = 1;
- priv_vbi->csize = 0;
- priv_vbi->valid_page = 0;
- priv_vbi->spudec_proc = 1;
- priv_vbi->pagenumdec = 0;
- if (priv_vbi->page)
- memset(priv_vbi->page, 0, sizeof(vbi_page));
- if (priv_vbi->txtpage)
- memset(priv_vbi->txtpage, 0, VBI_TXT_PAGE_SIZE);
- memset(priv_vbi->theader, 0, sizeof(priv_vbi->theader));
- if (priv_vbi->cache) {
- for (i = 0; i < 1000; i++) {
- if (priv_vbi->cache[i])
- free(priv_vbi->cache[i]);
- priv_vbi->cache[i] = NULL;
- }
- }
- snprintf(priv_vbi->header, sizeof(priv_vbi->header), "%s",
- VBI_NO_TELETEXT);
- pthread_mutex_unlock(&(priv_vbi->buffer_mutex));
-}
-
-/*
----------------------------------------------------------------------------------
- Public routines
----------------------------------------------------------------------------------
-*/
-
-/**
- * \brief teletext subsystem init
- * \note Routine uses global variables tv_param_tdevice, tv_param_tpage
- * and tv_param_tformat for initialization.
- *
- */
-priv_vbi_t *teletext_init(void)
-{
- priv_vbi_t *priv_vbi;
- int formatid, startpage;
- unsigned int services = VBI_SLICED_TELETEXT_B |
- VBI_SLICED_CAPTION_525 |
- VBI_SLICED_CAPTION_625 |
- VBI_SLICED_VBI_525 |
- VBI_SLICED_VBI_625 |
- VBI_SLICED_WSS_625 |
- VBI_SLICED_WSS_CPR1204 |
- VBI_SLICED_VPS;
-
- if (!tv_param_tdevice)
- return NULL;
-
- if (NULL == (priv_vbi = malloc(sizeof(priv_vbi_t))))
- return NULL;
- memset(priv_vbi, 0, sizeof(priv_vbi_t));
- formatid = VBI_TFORMAT_TEXT; // default
- if (tv_param_tformat != NULL) {
- if (strcmp(tv_param_tformat, "text") == 0)
- formatid = VBI_TFORMAT_TEXT;
- if (strcmp(tv_param_tformat, "bw") == 0)
- formatid = VBI_TFORMAT_BW;
- if (strcmp(tv_param_tformat, "gray") == 0)
- formatid = VBI_TFORMAT_GRAY;
- if (strcmp(tv_param_tformat, "color") == 0)
- formatid = VBI_TFORMAT_COLOR;
- }
- startpage = steppage(0, tv_param_tpage); // page number is HEX
- if (startpage < 0x100 || startpage > 0x999)
- startpage = 0x100;
- priv_vbi->device = strdup(tv_param_tdevice);
- priv_vbi->tformat = formatid;
- priv_vbi->tpage = startpage; // page number
- priv_vbi->pgno = startpage; // page number
-
-
- if (!priv_vbi->capture) {
- priv_vbi->services = services; // probe v4l2
- priv_vbi->capture = vbi_capture_v4l2_new(priv_vbi->device, // device
- 20, // buffer numbers
- &(priv_vbi->services), // services
- 0, // strict
- &(priv_vbi->errstr), // error string
- 0); // trace
- }
- services = priv_vbi->services;
- if (priv_vbi->capture == NULL) {
- priv_vbi->services = services; // probe v4l
- priv_vbi->capture = vbi_capture_v4l_new(priv_vbi->device,
- 20,
- &(priv_vbi->services),
- 0, &(priv_vbi->errstr), 0);
- }
-
- if (!priv_vbi->capture) {
- free(priv_vbi->device);
- free(priv_vbi);
- mp_msg(MSGT_TV, MSGL_INFO, "No teletext\n");
-