ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Video-Capture-V4l/examples/getepg
Revision: 1.2
Committed: Sat May 13 02:08:48 2000 UTC (26 years, 4 months ago) by pcg
Branch: MAIN
CVS Tags: rel-0_9, rel-0_902, HEAD
Changes since 1.1: +1 -1 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 pcg 1.1 #!/usr/bin/perl
2    
3     # EPG (Electronic Program Guide Decoder)
4     # Commercial Name: nexTView
5    
6     use Video::Capture::V4l;
7     use Video::Capture::VBI;
8    
9     package Video::Capture::VBI::EPG;
10    
11 pcg 1.2 use Video::Capture::VBI qw(:DEFAULT %VPS_CNI %VT_NI);
12 pcg 1.1 use Storable;
13    
14     use base 'Video::Capture::VBI::VT';
15    
16     sub new {
17     my $class = shift;
18     my $self = $class->SUPER::new(@_);
19     $self;
20     }
21    
22     my $lastcni = -1;
23     sub feed {
24     my $self = shift;
25     my @r;
26     for ($self->SUPER::feed(@_)) {
27     if ($_->[0] == VBI_VPS) {
28     if ($_->[3] != $lastcni) {
29     $lastcni = $_->[3];
30     printf "CNI %04x (%s)\n", $_->[3], $VPS_CNI{$_->[3] & 0xfff};
31     }
32     } else {
33     push @r, $_;
34     }
35     }
36     @r;
37     }
38    
39     sub mydump {
40     local $_ = shift;
41     if (ref $_ eq "HASH") {
42     print "{ ";
43     while(my($k,$v)=each %$_) {
44     print ", $k => ";
45     mydump($v);
46     }
47     print " }";
48     } elsif (ref $_ eq "ARRAY") {
49     print "[ ";
50     for (@$_) {
51     print ", ";
52     mydump($_);
53     }
54     print " ]";
55     } else {
56     y/\x20-\x7e//cd;
57     print $_;
58     }
59     }
60    
61     sub set_epg {
62     my $self = shift;
63     my $name = shift;
64     my $new_db = main::gen_db_name ($name);
65     print "SET_EPG $new_db <= ", $self->{db_name}, "\n";
66     if ($self->{db_name} and $new_db eq $self->{db_name}) {
67     print "saving ",$new_db,"...";
68     Storable::nstore($self->db, "$new_db~");
69     rename "$new_db~", $new_db;
70     print "ok\n";
71     } else {
72     $self->{db_name} = $new_db;
73     print "trying to load $new_db...";
74     $self->db(eval { $self->db(Storable::retrieve($new_db)) });
75     print "ok\n";
76     }
77     }
78    
79     # just display the page
80     sub enter_page {
81     my($self,$page)=@_;
82    
83     $pages++;
84    
85     return unless $page->{page} == 0x1df;
86    
87     my $sub = $page->{ctrl};
88     my $stream = VTX_S3($sub);
89     my $height = VTX_S4($sub)<<3 | VTX_S2($sub);
90     my $seq = VTX_S1($sub);
91    
92     my $s = \%{$self->{stream}{$stream}};
93    
94     delete $s->{raw} unless (($seq-1)&15) == $s->{seq};
95     $s->{seq}=$seq;
96     push @{$s->{raw}}, @{$page->{packet}}[1..$height];
97    
98     $packets[$stream]++;
99     #print "stream $stream, height $height, seq $seq, ",scalar @{$s->{raw}},"<\n";
100    
101     for(decode_stream $s->{raw}) {
102     if (my ($dt, $bi) = decode_block $_, \@{$self->{bundle}}) {
103     if ($dt == 1) {
104     my $ai = $self->{db}{ai};
105     $self->set_epg($bi->{service_name});
106     if ($ai) {
107     print "$ai->{epg_version}, $ai->{epg_version_swo}, $ai->{this_network_op}, $ai->{service_name}\n";
108     if ($bi->{epg_version} != $ai->{epg_version}
109     || $bi->{epg_version_swo} != $ai->{epg_version_swo}
110     || $bi->{this_network_op} != $ai->{this_network_op}) {
111     print "CHANNEL SWITCH, WIPING DATABASE\n";
112     delete $self->{db};
113     }
114     }
115     $self->{db}{ai} = $bi;
116     } elsif ($dt == 2) {
117     $self->{db}{pi}{$bi->{netwop_no}}{$bi->{block_no}} = $bi;
118     } elsif ($dt == 3) {
119     $self->{db}{ni}{$bi->{block_no}} = $bi;
120     } elsif ($dt == 4) {
121     $self->{db}{oi}{$bi->{block_no}} = $bi;
122     } elsif ($dt == 5) {
123     $self->{db}{mi}{$bi->{block_no}} = $bi;
124     } else {
125     print "UNKNOWN BLOCK TYPE $dt found\n";
126     }
127     }
128     }
129     $|=1;
130     printf "%7d %6d %6d %5d %5d %5d %5d\r", $pages, $packets[0], $packets[1],
131     1*%{$self->{db}{pi}},
132     1*%{$self->{db}{ni}},
133     1*%{$self->{db}{oi}},
134     1*%{$self->{db}{mi}};
135    
136     #printf "received epg page %04x\n", $sub;
137     }
138    
139     sub enter_packet {
140     my $self = shift;
141     my $p = shift;
142     return unless $p->[3] <= 1 && $p->[2] == 30;
143     #printf "packet(@$p %04x)", $p->[6];
144     print "\n";
145     }
146    
147     sub db {
148     my $self = shift;
149     $self->{db} = shift if @_;
150     $self->{db};
151     }
152    
153     package main;
154    
155     $vbi = new Video::Capture::V4l::VBI or die;
156    
157     # the next line is optional (it enables buffering)
158     $vbi->backlog(150); # max. 5 seconds backlog (~4.6Mb)
159    
160     $inp_fd = fileno STDIN;
161     $vbi_fd = $vbi->fileno;
162    
163     $vt = new Video::Capture::VBI::EPG;
164    
165     sub gen_db_name {
166     shift() . ".epg";
167     }
168    
169     print "Capturing VBI block. Make sure you have tuned in to a channel with EPG!\n";
170     print "Aquisition may take up to twenty minutes (and more)!\n";
171    
172     for(;;) {
173     my $r="";
174     vec($r,$inp_fd,1)=1;
175     vec($r,$vbi_fd,1)=1;
176     select $r,undef,undef,0.04;
177     $vt->feed(decode_field $vbi->field, VBI_VT|VBI_VPS) while $vbi->queued;
178     if (vec($r,$inp_fd,1)) {
179     $_ = <STDIN>;
180     if (/^q/i) {
181     last;
182     }
183     }
184     }
185