/* * libzvbi - Events * * Copyright (C) 2000, 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: event.h,v 1.11 2006/05/07 20:53:33 mschimek Exp $ */ #ifndef EVENT_H #define EVENT_H #include "bcd.h" #ifndef VBI_DECODER #define VBI_DECODER typedef struct vbi_decoder vbi_decoder; #endif /* Public */ #include /** * @addtogroup Event Events * @ingroup HiDec * * Typically the transmission of VBI data like a Teletext or Closed * Caption page spans several VBI lines or even video frames. So internally * the data service decoder maintains caches accumulating data. When a page * or other object is complete it calls the respective event handler to * notify the application. * * Clients can register any number of handlers needed, also different * handlers for the same event. They will be called in the order registered * from the vbi_decode() function. Since they block decoding, they should * return as soon as possible. The event structure and all data * pointed to from there must be read only. The data is only valid until * the handler returns. */ /** * @ingroup Event * @brief Unique network id (a libzvbi thing). * * 0 = unknown network, bit 31 reserved for preliminary nuids. * Other network codes are arbitrary. */ typedef unsigned int vbi_nuid; /** * @ingroup Event * @brief Network description. * * All strings are ISO 8859-1 encoded (yes that's stupid, sorry) * and @c NUL terminated. Prepare for empty strings. Read only. */ typedef struct { vbi_nuid nuid; /** * Name of the network from XDS or from a table lookup of * CNIs in Teletext packet 8/30 or VPS. */ signed char name[64]; /** * Network call letters, from XDS. Empty if unknown or * not applicable. */ signed char call[40]; /** * Tape delay in minutes, from XDS. Zero if unknown or * not applicable. **/ int tape_delay; /** * The European Broadcasting Union (EBU) maintains several tables * of Country and Network Identification (CNI) codes. CNIs of type * VPS, 8/30-1 and 8/30-2 can be used to identify networks during * a channel scan. * * This field contains the CNI of the network found in a VPS * packet. It can be zero if unknown or CNI's are not applicable. * Note VPS has room for only 4 lsb of the country code (0xCNN). * * For example ZDF: 0xDC2. */ int cni_vps; /** * CNI of the network from Teletext packet 8/30 format 1, * zero if unknown or not applicable. The country code is * stored in the MSB, the network code in the LSB (0xCCNN). * Note these CNIs may use different country and network codes * than the PDC (VPS, 8/30-2) CNIs. * * For example BBC1: 0x447F, ZDF: 0x4902. */ int cni_8301; /** * CNI of the network from Teletext packet 8/30 format 2, * zero if unknown or not applicable. The country code is * stored in the MSB, the network code in the LSB (0xCCNN). * * For example BBC1: 0x2C7F, ZDF: 0x1DC2. */ int cni_8302; int reserved; /** Private. */ int cycle; } vbi_network; /* * Link */ /** * @ingroup Event * @brief Link type. */ typedef enum { /** * vbi_resolve_link() may return a link of this type on failure. */ VBI_LINK_NONE = 0, /** * Not really a link, only vbi_link->name will be set. (Probably * something like "Help! Help! The station is on fire!") */ VBI_LINK_MESSAGE, /** * Points to a Teletext page, vbi_link->pgno and vbi_link->subno, * eventually vbi_link->nuid and a descriptive text in vbi_link->name. */ VBI_LINK_PAGE, /** * Also a Teletext page link, but this one is used exclusively * to link subpages of the page containing the link. */ VBI_LINK_SUBPAGE, /** * vbi_link->url is a HTTP URL (like "http://zapping.sf.net"), * eventually accompanied by a descriptive text vbi_link->name. */ VBI_LINK_HTTP, /** * vbi_link->url is a FTP URL (like "ftp://foo.bar.com/baz"), * eventually accompanied by a descriptive text vbi_link->name. */ VBI_LINK_FTP, /** * vbi_link->url is an e-mail address (like "mailto:foo@bar"), * eventually accompanied by a descriptive text vbi_link->name. */ VBI_LINK_EMAIL, /** Is a trigger link id. Not useful, just ignore. */ VBI_LINK_LID, /** Is a SuperTeletext link, ignore. */ VBI_LINK_TELEWEB } vbi_link_type; /** * @ingroup Event * @brief ITV link type. * * Some ITV (WebTV, ATVEF) triggers include a type id intended * to filter relevant information. The names should speak for * themselves. EACEM triggers always have type @c VBI_WEBLINK_UNKNOWN. **/ typedef enum { VBI_WEBLINK_UNKNOWN = 0, VBI_WEBLINK_PROGRAM_RELATED, VBI_WEBLINK_NETWORK_RELATED, VBI_WEBLINK_STATION_RELATED, VBI_WEBLINK_SPONSOR_MESSAGE, VBI_WEBLINK_OPERATOR } vbi_itv_type; /** * @ingroup Event * * General purpose link description for ATVEF (ITV, WebTV in the * United States) and EACEM (SuperTeletext et al in Europe) triggers, * Teletext TOP and FLOF navigation, and for links "guessed" by * libzvbi from the text (e. g. page numbers and URLs). Usually * not all fields will be used. */ typedef struct vbi_link { /** * See vbi_link_type. */ vbi_link_type type; /** * Links can be obtained two ways, via @ref VBI_EVENT_TRIGGER, * then it arrived either through the EACEM or ATVEF transport * method as flagged by this field. Or it is a navigational link * returned by vbi_resolve_link(), then this field does not apply. */ vbi_bool eacem; /** * Some descriptive text, Latin-1, possibly blank. */ signed char name[80]; signed char url[256]; /** * A piece of ECMA script (Javascript), this may be * used on WebTV or SuperTeletext pages to trigger some action. * Usually blank. */ signed char script[256]; /** * Teletext page links (no Closed Caption counterpart) can * can actually reach across networks. That happens for example * when vbi_resolve_link() picked up a link on a page after we * switch away from that channel, or with EACEM triggers * deliberately pointing to a page on another network (sic!). * So the network id (if known, otherwise 0) is part of the * page number. See vbi_nuid. */ vbi_nuid nuid; /** * @a pgno and @a subno Teletext page number, see vbi_pgno, vbi_subno. */ vbi_pgno pgno; vbi_subno subno; /** * The time in seconds and fractions since * 1970-01-01 00:00 when the link should no longer be offered * to the user, similar to a HTTP cache expiration date. */ double expires; /** * See vbi_itv_type. This field applies only to * ATVEF triggers, is otherwise @c VBI_WEBLINK_UNKNOWN. */ vbi_itv_type itv_type; /** * Trigger priority. 0 = emergency, should never be * blocked. 1 or 2 = "high", 3 ... 5 = "medium", 6 ... 9 = * "low". The default is 9. Apart of filtering triggers, this * is also used to determine at which priority multiple links * should be presented to the user. This field applies only to * EACEM triggers, is otherwise 9. */ int priority; /** * Open the target without user confirmation. (Supposedly * this flag will be used to trigger scripts, not to open pages, * but I have yet to see such a trigger.) */ vbi_bool autoload; } vbi_link; /* * Aspect ratio information. */ /** * @ingroup Event * @brief Open subtitle information. * * Open because they have been inserted into the picture, as * opposed to closed subtitles (closed caption) encoded in the vbi. */ typedef enum { VBI_SUBT_NONE, /**< No open subtitles. */ VBI_SUBT_ACTIVE, /**< Inserted in active picture. */ VBI_SUBT_MATTE, /**< Inserted in upper or lower letterbox bar. */ VBI_SUBT_UNKNOWN /**< Presence of open subtitles unknown. */ } vbi_subt; /** * @ingroup Event * @brief Information about the picture aspect ratio and open subtitles. * * This is available via @ref VBI_EVENT_ASPECT. */ typedef struct { /** * @a first_line and @a last_line, inclusive, describe the bounds of active * video, i. e. without the black bars in letterbox mode. These are * first field line numbers according to the ITU-R line * numbering scheme, see vbi_sliced. For example PAL 23 ... 310 (288 lines), * NTSC 22 ... 262 (240 lines). */ int first_line; int last_line; /** * The picture aspect ratio in anamorphic mode, * 16/9 for example. Normal or letterboxed video has aspect ratio 1/1. */ double ratio; /** * @c TRUE when the source is known to be film transferred to * video, as opposed to interlaced video from a video camera. (This is * actually a helper flag for PALPlus decoders, but it may assist * deinterlacers too.) */ vbi_bool film_mode; /** * Describes how subtitles are inserted into the picture, * see vbi_subt for details. */ vbi_subt open_subtitles; } vbi_aspect_ratio; /* * Program Info * * ATTN this is new stuff and subject to change */ /** * @ingroup Event * @brief Program rating source. * * If program rating information is available (also known in the * U. S. as V-Chip data), this describes which rating scheme is * being used: U. S. film, U. S. TV, Canadian English or French TV. * You can convert the rating code to a string with * vbi_rating_string(). * * When the scheme is @c VBI_RATING_TV_US, additionally the * DLSV rating flags will be set. */ typedef enum { VBI_RATING_AUTH_NONE = 0, VBI_RATING_AUTH_MPAA, VBI_RATING_AUTH_TV_US, VBI_RATING_AUTH_TV_CA_EN, VBI_RATING_AUTH_TV_CA_FR } vbi_rating_auth; /** * @ingroup Event * @name US TV rating flags * @{ */ #define VBI_RATING_D 0x08 /**< "sexually suggestive dialog" */ #define VBI_RATING_L 0x04 /**< "indecent language" */ #define VBI_RATING_S 0x02 /**< "sexual situations" */ #define VBI_RATING_V 0x01 /**< "violence" */ /** @} */ extern const char * vbi_rating_string(vbi_rating_auth auth, int id); /** * @ingroup Event * @brief Program classification schemes. * * libzvbi understands two different program classification schemes, * the EIA-608 based in the United States and the ETS 300 231 based * one in Europe. You can convert the program type code into a * string with vbi_prog_type_string(). **/ typedef enum { VBI_PROG_CLASSF_NONE = 0, VBI_PROG_CLASSF_EIA_608, VBI_PROG_CLASSF_ETS_300231 } vbi_prog_classf; /** * @addtogroup Event * @{ */ extern const char * vbi_prog_type_string(vbi_prog_classf classf, int id); /** @} */ /** * @ingroup Event * @brief Type of audio transmitted on one (mono or stereo) * audio track. */ /* code depends on order, don't change */ typedef enum { VBI_AUDIO_MODE_NONE = 0, /**< No sound. */ VBI_AUDIO_MODE_MONO, /**< Mono audio. */ VBI_AUDIO_MODE_STEREO, /**< Stereo audio. */ VBI_AUDIO_MODE_STEREO_SURROUND, /**< Surround. */ VBI_AUDIO_MODE_SIMULATED_STEREO, /**< ? */ /** * Spoken descriptions of the program for the blind, on a secondary audio track. */ VBI_AUDIO_MODE_VIDEO_DESCRIPTIONS, /** * Unrelated to the current program. */ VBI_AUDIO_MODE_NON_PROGRAM_AUDIO, VBI_AUDIO_MODE_SPECIAL_EFFECTS, /**< ? */ VBI_AUDIO_MODE_DATA_SERVICE, /**< ? */ /** * We have no information what is transmitted. */ VBI_AUDIO_MODE_UNKNOWN } vbi_audio_mode; /** * @ingroup Event * * Information about the current program, preliminary. */ typedef struct vbi_program_info { /* * Refers to the current or next program. * (No [2] to allow clients filtering current data more easily.) */ unsigned int future : 1; /* 01 Program Identification Number */ /* If unknown all these fields are -1 */ signed char month; /* 0 ... 11 */ signed char day; /* 0 ... 30 */ signed char hour; /* 0 ... 23 */ signed char min; /* 0 ... 59 */ /* * VD: "T indicates if a program is routinely tape delayed for the * Mountain and Pacific time zones." */ signed char tape_delayed; /* 02 Program Length */ /* If unknown all these fields are -1 */ signed char length_hour; /* 0 ... 63 */ signed char length_min; /* 0 ... 59 */ signed char elapsed_hour; /* 0 ... 63 */ signed char elapsed_min; /* 0 ... 59 */ signed char elapsed_sec; /* 0 ... 59 */ /* 03 Program name */ /* If unknown title[0] == 0 */ signed char title[64]; /* ASCII + '\0' */ /* 04 Program type */ /* * If unknown type_classf == VBI_PROG_CLASSF_NONE. * VBI_PROG_CLASSF_EIA_608 can have up to 32 tags * identifying 96 keywords. Their numerical value * is given here instead of composing a string for * easier filtering. Use vbi_prog_type_str_by_id to * get the keywords. A zero marks the end. */ vbi_prog_classf type_classf; int type_id[33]; /* 05 Program rating */ /* * For details STFW for "v-chip" * If unknown rating_auth == VBI_RATING_NONE */ vbi_rating_auth rating_auth; int rating_id; /* Only valid when auth == VBI_RATING_TV_US */ int rating_dlsv; /* 06 Program Audio Services */ /* * BTSC audio (two independent tracks) is flagged according to XDS, * Zweiton/NICAM/EIA-J audio is flagged mono/none, stereo/none or * mono/mono for bilingual transmissions. */ struct { /* If unknown mode == VBI_AUDIO_MODE_UNKNOWN */ vbi_audio_mode mode; /* If unknown language == NULL */ unsigned char * language; /* Latin-1 */ } audio[2]; /* primary and secondary */ /* 07 Program Caption Services */ /* * Bits 0...7 corresponding to Caption page 1...8. * Note for the current program this information is also * available via vbi_classify_page(). * * If unknown caption_services == -1, _language[] = NULL */ int caption_services; unsigned char * caption_language[8]; /* Latin-1 */ /* 08 Copy Generation Management System */ /* If unknown cgms_a == -1 */ int cgms_a; /* XXX */ /* 09 Aspect Ratio */ /* * Note for the current program this information is also * available via VBI_EVENT_ASPECT. * * If unknown first_line == last_line == -1, ratio == 0.0 */ vbi_aspect_ratio aspect; /* 10 - 17 Program Description */ /* * 8 rows of 0...32 ASCII chars + '\0', * if unknown description[0...7][0] == 0 */ signed char description[8][33]; } vbi_program_info; /** * @addtogroup Event * @{ */ extern void vbi_reset_prog_info(vbi_program_info *pi); /** @} */ /** * @ingroup Event * @name Event types. * @{ */ /** * @anchor VBI_EVENT_ * No event. */ #define VBI_EVENT_NONE 0x0000 /** * The vbi decoding context is about to be closed. This event is * sent by vbi_decoder_delete() and can be used to clean up * event handlers. */ #define VBI_EVENT_CLOSE 0x0001 /** * The vbi decoder received and cached another Teletext page * designated by ev.ttx_page.pgno and ev.ttx_page.subno. * * ev.ttx_page.roll_header flags the page header as suitable for * rolling page numbers, e. g. excluding pages transmitted out * of order. * * The ev.ttx_page.header_update flag is set when the header, * excluding the page number and real time clock, changed since the * last @c VBI_EVENT_TTX_PAGE. Note this may happen at midnight when the * date string changes. The ev.ttx_page.clock_update flag is set when * the real time clock changed since the last @c VBI_EVENT_TTX_PAGE (that is * at most once per second). They are both set at the first * @c VBI_EVENT_TTX_PAGE sent and unset while the received header * or clock field is corrupted. * * If any of the roll_header, header_update or clock_update flags * are set ev.ttx_page.raw_header is a pointer to the raw header data * (40 bytes), which remains valid until the event handler returns. * ev.ttx_page.pn_offset will be the offset (0 ... 37) of the three * digit page number in the raw or formatted header. Allways call * vbi_fetch_vt_page() for proper translation of national characters * and character attributes, the raw header is only provided here * as a means to quickly detect changes. */ #define VBI_EVENT_TTX_PAGE 0x0002 /** * A Closed Caption page has changed and needs visual update. * The page or "CC channel" is designated by ev.caption.pgno, * see vbi_pgno for details. * * When the client is monitoring this page, the expected action is * to call vbi_fetch_cc_page(). To speed up rendering more detailed * update information is provided in vbi_page.dirty, see #vbi_page. * The vbi_page will be a snapshot of the status at fetch time * and not event time, vbi_page.dirty accumulates all changes since * the last fetch. */ #define VBI_EVENT_CAPTION 0x0004 /** * Some station/network identifier has been received or is no longer * transmitted (vbi_network all zero, eg. after a channel switch). * ev.network is a vbi_network object, read only. The event will not * repeat*) unless a different identifier has been received and confirmed. * * Minimum time to identify network, when data service is transmitted: * * * * *
VPS (DE/AT/CH only):0.08 s
Teletext PDC, 8/30:2 s
XDS (US only):unknown, between 0.1x to 10x seconds
* * *) VPS/TTX and XDS will not combine in real life, feeding the decoder * with artificial data can confuse the logic. */ #define VBI_EVENT_NETWORK 0x0008 /** * @anchor VBI_EVENT_TRIGGER * * Triggers are sent by broadcasters to start some action on the * user interface of modern TVs. Until libzvbi implements all ;-) of * WebTV and SuperTeletext the information available are program * related (or unrelated) URLs, short messages and Teletext * page links. * * This event is sent when a trigger has fired, ev.trigger * points to a vbi_link structure describing the link in detail. * The structure must be read only. */ #define VBI_EVENT_TRIGGER 0x0010 /** * @anchor VBI_EVENT_ASPECT * * The vbi decoder received new information (potentially from * PAL WSS, NTSC XDS or EIA-J CPR-1204) about the program * aspect ratio. ev.ratio is a pointer to a vbi_ratio structure. * The structure must be read only. */ #define VBI_EVENT_ASPECT 0x0040 /** * We have new information about the current or next program. * ev.prog_info is a vbi_program_info pointer (due to size), read only. * * Preliminary. * * XXX Info from Teletext not implemented yet. * XXX Change to get_prog_info. network ditto? */ #define VBI_EVENT_PROG_INFO 0x0080 /** * Like @a VBI_EVENT_NETWORK, but this event will also be sent * when the decoder cannot determine a network name. * * @since 0.2.20 */ #define VBI_EVENT_NETWORK_ID 0x0100 /** @} */ /** * @example examples/network.c * Network identification example. */ #include /** * @ingroup Event * @brief Event union. */ /* XXX network, aspect, prog_info: should only notify about * changes and provide functions to query current value. */ typedef struct vbi_event { int type; union { struct { int pgno; int subno; uint8_t * raw_header; int pn_offset; unsigned int roll_header : 1; unsigned int header_update : 1; unsigned int clock_update : 1; } ttx_page; struct { int pgno; } caption; vbi_network network; vbi_link * trigger; vbi_aspect_ratio aspect; vbi_program_info * prog_info; } ev; } vbi_event; /** * @addtogroup Event * @{ */ typedef void (* vbi_event_handler)(vbi_event *event, void *user_data); extern vbi_bool vbi_event_handler_add(vbi_decoder *vbi, int event_mask, vbi_event_handler handler, void *user_data); extern void vbi_event_handler_remove(vbi_decoder *vbi, vbi_event_handler handler); extern vbi_bool vbi_event_handler_register(vbi_decoder *vbi, int event_mask, vbi_event_handler handler, void *user_data); extern void vbi_event_handler_unregister(vbi_decoder *vbi, vbi_event_handler handler, void *user_data); /** @} */ /* Private */ extern void vbi_send_event(vbi_decoder *vbi, vbi_event *ev); #endif /* EVENT_H */