static void gst_teletextdec_zvbi_init (GstTeletextDec * teletext) { g_return_if_fail (teletext != NULL); GST_LOG_OBJECT (teletext, "Initializing structures"); teletext->decoder = vbi_decoder_new (); vbi_event_handler_register (teletext->decoder, VBI_EVENT_TTX_PAGE | VBI_EVENT_CAPTION, gst_teletextdec_event_handler, teletext); g_mutex_lock (teletext->queue_lock); teletext->queue = g_queue_new (); g_mutex_unlock (teletext->queue_lock); }
/***************************************************************************** * Open: probe the decoder and return score ***************************************************************************** * Tries to launch a decoder and return score so that the interface is able * to chose. *****************************************************************************/ static int Open( vlc_object_t *p_this ) { decoder_t *p_dec = (decoder_t *) p_this; decoder_sys_t *p_sys = NULL; if( p_dec->fmt_in.i_codec != VLC_CODEC_TELETEXT ) return VLC_EGENERIC; p_dec->pf_decode_sub = Decode; p_sys = p_dec->p_sys = calloc( 1, sizeof(decoder_sys_t) ); if( p_sys == NULL ) return VLC_ENOMEM; p_sys->i_key[0] = p_sys->i_key[1] = p_sys->i_key[2] = '*' - '0'; p_sys->b_update = false; p_sys->p_vbi_dec = vbi_decoder_new(); p_sys->p_dvb_demux = vbi_dvb_pes_demux_new( NULL, NULL ); vlc_mutex_init( &p_sys->lock ); if( (p_sys->p_vbi_dec == NULL) || (p_sys->p_dvb_demux == NULL) ) { msg_Err( p_dec, "VBI decoder/demux could not be created." ); Close( p_this ); return VLC_ENOMEM; } /* Some broadcasters in countries with level 1 and level 1.5 still not send a G0 to do * matches against table 32 of ETSI 300 706. We try to do some best effort guessing * This is not perfect, but might handle some cases where we know the vbi language * is known. It would be better if people started sending G0 */ for( int i = 0; ppsz_default_triplet[i] != NULL; i++ ) { if( p_dec->fmt_in.psz_language && !strcasecmp( p_dec->fmt_in.psz_language, ppsz_default_triplet[i] ) ) { vbi_teletext_set_default_region( p_sys->p_vbi_dec, pi_default_triplet[i]); msg_Dbg( p_dec, "overwriting default zvbi region: %d", pi_default_triplet[i] ); } } vbi_event_handler_register( p_sys->p_vbi_dec, VBI_EVENT_TTX_PAGE | VBI_EVENT_NETWORK | #ifdef ZVBI_DEBUG VBI_EVENT_CAPTION | VBI_EVENT_TRIGGER | VBI_EVENT_ASPECT | VBI_EVENT_PROG_INFO | VBI_EVENT_NETWORK_ID | #endif 0 , EventHandler, p_dec ); /* Create the var on vlc_global. */ p_sys->i_wanted_page = var_CreateGetInteger( p_dec, "vbi-page" ); var_AddCallback( p_dec, "vbi-page", RequestPage, p_sys ); /* Check if the Teletext track has a known "initial page". */ if( p_sys->i_wanted_page == 100 && p_dec->fmt_in.subs.teletext.i_magazine != -1 ) { p_sys->i_wanted_page = 100 * p_dec->fmt_in.subs.teletext.i_magazine + vbi_bcd2dec( p_dec->fmt_in.subs.teletext.i_page ); var_SetInteger( p_dec, "vbi-page", p_sys->i_wanted_page ); } p_sys->i_wanted_subpage = VBI_ANY_SUBNO; p_sys->b_opaque = var_CreateGetBool( p_dec, "vbi-opaque" ); var_AddCallback( p_dec, "vbi-opaque", Opaque, p_sys ); p_sys->i_align = var_CreateGetInteger( p_dec, "vbi-position" ); var_AddCallback( p_dec, "vbi-position", Position, p_sys ); p_sys->b_text = var_CreateGetBool( p_dec, "vbi-text" ); // var_AddCallback( p_dec, "vbi-text", Text, p_sys ); /* Listen for keys */ var_AddCallback( p_dec->p_libvlc, "key-pressed", EventKey, p_dec ); es_format_Init( &p_dec->fmt_out, SPU_ES, VLC_CODEC_SPU ); if( p_sys->b_text ) p_dec->fmt_out.video.i_chroma = VLC_CODEC_TEXT; else p_dec->fmt_out.video.i_chroma = VLC_CODEC_RGBA; return VLC_SUCCESS; }
int main(int argc, char **argv) { int region = -1; const char *device = default_device; int opt; enum { OPT_DUMMY = CHAR_MAX, OPT_VERSION }; static struct option long_options[] = { {"help", no_argument, NULL, 'h'}, {"version", no_argument, NULL, OPT_VERSION}, {NULL, 0, NULL, 0} }; while ((opt = getopt_long(argc, argv, "d:l:h", long_options, NULL)) != -1) switch (opt) { case 'd': device = optarg; break; case 'l': region = dochttx_region_for_lang(optarg); if (region < 0) { errno = EINVAL; perror("dochttx: -l"); exit(EXIT_FAILURE); } break; case 'h': long_usage(stdout); exit(EXIT_SUCCESS); case OPT_VERSION: print_version(); exit(EXIT_SUCCESS); default: /* '?' */ usage(stderr); exit(EXIT_FAILURE); } if (optind != argc) { usage(stderr); exit(EXIT_FAILURE); } int rc = dochttx_locale_init(); if (rc < 0) { perror("dochttx: locale initialization failed"); return EXIT_FAILURE; } if (region < 0) region = dochttx_region_for_locale(); if (region < 0) region = dochttx_region_for_lang("en"); assert(region >= 0); struct dochttx_vbi_state* vbi = dochttx_vbi_open(device, region); if (vbi == NULL) return EXIT_FAILURE; dochttx_ncurses_init(); mvvline(0, 41, ACS_VLINE, 25); for (int y = 0; y < 25; y++) mvhline(y, 0, ACS_BOARD, 41); mvhline(25, 0, ACS_HLINE, COLS); mvaddch(25, 41, ACS_BTEE); vbi_event_handler_register(vbi->dec, VBI_EVENT_TTX_PAGE, on_event_ttx_page, NULL); vbi_pgno req_pgno = 0x100; vbi_subno req_subno = VBI_ANY_SUBNO; draw_looking_for(req_pgno, req_subno); bool req_drawn = false; struct input input = { .text = {0}, .position = 0, .status = INPUT_NORMAL, }; draw_input(&input); refresh(); while (true) { struct pollfd fds[2] = { { .fd = STDIN_FILENO, .events = POLLIN }, { .fd = vbi->fd, .events = POLLIN, .revents = POLLIN }, };
/** * @param vbi Initialized vbi decoding context. * @param handler Event handler function. * @param user_data Pointer passed to the handler. * * Unregisters an event handler. * * Apart of removing a handler this function also disables decoding * of data services when no handler is registered to consume the * respective data. Removing the last @c VBI_EVENT_TTX_PAGE handler for * example disables Teletext decoding. * * This function can be safely called at any time, even from a handler * removing itself or another handler, and regardless if the @a handler * has been successfully registered. **/ void vbi_event_handler_unregister(vbi_decoder *vbi, vbi_event_handler handler, void *user_data) { vbi_event_handler_register(vbi, 0, handler, user_data); }