#!/usr/bin/perl -w # # libzvbi network identification example. # # Copyright (C) 2006 Michael H. Schimek # Perl Port: Copyright (C) 2007 Tom Zoerner # # 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. # # Perl $Id: network.pl,v 1.1 2007/11/18 18:48:35 tom Exp tom $ # ZVBI #Id: network.c,v 1.2 2006/10/27 04:52:08 mschimek Exp # # This example shows how to identify a network from data transmitted # in XDS packets, Teletext packet 8/30 format 1 and 2, and VPS packets. use blib; use strict; use Getopt::Long; use Encode; use Video::ZVBI qw(/^VBI_/); my $cap; my $dec; my $quit; my $option_vps = 0; my $option_8301 = 0; my $option_8302 = 0; my $option_help = 0; my $services; sub handler { my($ev_type, $ev, $user_data) = @_; my $event_name; my $call_sign; my $network_name; # VBI_EVENT_NETWORK_ID is always sent when the decoder # receives a CNI. VBI_EVENT_NETWORK only if it can # determine a network name. if ($ev_type == VBI_EVENT_NETWORK) { $event_name = "VBI_EVENT_NETWORK"; } elsif ($ev_type == VBI_EVENT_NETWORK_ID) { $event_name = "VBI_EVENT_NETWORK_ID"; } else { die "Unexpected event type: $ev_type\n"; } if (defined $ev->{name}) { # The network name is an ISO-8859-1 string (the API is # quite old...) so we convert it to locale encoding, # nowadays usually UTF-8. $network_name = decode("ISO-8859-1", $ev->{name}); } else { $network_name = "unknown"; } # ASCII. if (defined $ev->{call}) { $call_sign = $ev->{call}; } else { $call_sign = "unknown"; } printf "%s: receiving: \"%s\" call sign: \"%s\" " . "CNI VPS: 0x%x 8/30-1: 0x%x 8/30-2: 0x%x\n", $event_name, $network_name, $call_sign, $ev->{cni_vps}, $ev->{cni_8301}, $ev->{cni_8302}; $quit = 1 if $ev->{cni_vps} != 0 && $option_vps; $quit = 1 if $ev->{cni_8301} != 0 && $option_8301; $quit = 1 if $ev->{cni_8302} != 0 && $option_8302; } sub mainloop { my $timeout; my $sliced_buffer; my $n_frames; # Don't wait more than two seconds for the driver to return data. $timeout = 2000; # Should receive a CNI within two seconds, call sign within ten seconds(?). if ($services & VBI_SLICED_CAPTION_525) { $n_frames = 11 * 30; } else { $n_frames = 3 * 25; } for (; $n_frames > 0; --$n_frames) { my $n_lines; my $timestamp; my $r; $r = $cap->pull_sliced ( $sliced_buffer, $n_lines, $timestamp, $timeout); if ($r == -1) { # Could be ignored, esp. EIO with some drivers. die "VBI read error: $!\n"; } elsif ($r == 0) { die "VBI read timeout\n"; } elsif ($r == 1) { # continue } else { die "Unexpected result code from pull_sliced: $r\n"; } $dec->decode ( $sliced_buffer, $n_lines, $timestamp ); return if defined $quit; } print "No network ID received or network unknown.\n"; } sub usage { print STDERR "$0 - network identification test\n". "Options:\n". "\t--vps\tStop after receiving VPS\n". "\t--8301\tStop after receiving packet 8/30/1\n". "\t--8302\tStop after receiving packet 8/30/2\n". "\t--help\tPrint this usage info\n"; exit(1); } my %CmdOpts = ( "vps" => \$option_vps, "8301" => \$option_8301, "8302" => \$option_8302, ); sub main_func { my $errstr; my $success; GetOptions(%CmdOpts) || usage(); if (!$option_vps && !$option_8301 && !$option_8302) { $option_vps = $option_8301 = $option_8302 = 1; } $services = (VBI_SLICED_TELETEXT_B | VBI_SLICED_VPS | VBI_SLICED_CAPTION_525); # open VBI device (buffers:=5, strict:=0, verbose:=FALSE $cap = Video::ZVBI::capture::v4l2_new ("/dev/vbi0", 5, $services, 0, $errstr, 0); die "Cannot capture VBI data with V4L2 interface: $errstr\n" unless $cap; $dec = Video::ZVBI::vt::decoder_new (); die "Failed to create VT decoder\n" unless $dec; $success = $dec->event_handler_add ( (VBI_EVENT_NETWORK | VBI_EVENT_NETWORK_ID), \&handler ); die "Failed to install event handler\n" unless $success; mainloop (); } main_func();