line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Linux::DVB::DVBT::Advert ;
|
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
=head1 NAME
|
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
Linux::DVB::DVBT::Advert - Advert (commercials) detection and removal
|
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
=head1 SYNOPSIS
|
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
use Linux::DVB::DVBT::Advert ;
|
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
# Read advert config info
|
12
|
|
|
|
|
|
|
my $ad_config_href = ad_config() ;
|
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
# skip advert detection
|
15
|
|
|
|
|
|
|
if (!ok_to_detect($results_settings_href))
|
16
|
|
|
|
|
|
|
{
|
17
|
|
|
|
|
|
|
print "Skipping advert detection...\n" ;
|
18
|
|
|
|
|
|
|
exit 0 ;
|
19
|
|
|
|
|
|
|
}
|
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
# detect
|
22
|
|
|
|
|
|
|
my $settings_href = {
|
23
|
|
|
|
|
|
|
'debug' => $DEBUG,
|
24
|
|
|
|
|
|
|
'progress_callback' => \&progress,
|
25
|
|
|
|
|
|
|
} ;
|
26
|
|
|
|
|
|
|
$results_href = detect($file, $settings_href, $channel, $ad_config_href, $det) ;
|
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
# .. or re-use saved deetction
|
29
|
|
|
|
|
|
|
$results_href = detect_from_file($detect_file) ;
|
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
# analyse
|
32
|
|
|
|
|
|
|
my @cut_list = analyse($file, $results_href, $ad_config_href, $channel, $csv, $expected_aref, $settings_href) ;
|
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
# remove adverts
|
35
|
|
|
|
|
|
|
ad_cut($file, $cutfile, \@cut_list) ;
|
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
# ..or split file at advert boundaries
|
38
|
|
|
|
|
|
|
ad_split($file, $cutfile, \@cut_list) ;
|
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
=head1 DESCRIPTION
|
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
Module provides the interface into the advert (commercials) detection and removal utilities.
|
45
|
|
|
|
|
|
|
As well as an underlying transport stream parsing framework, this module also incorporates
|
46
|
|
|
|
|
|
|
MPEG2 video decoding and AAC audio decoding (see L module for full details).
|
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
=head2 Basic Operation
|
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
Advert removal is split into 2 phases: detection and analysis. The detection phase processes the
|
51
|
|
|
|
|
|
|
video and audio data, producing raw statistics for each video frame (I effectively sunchronise the
|
52
|
|
|
|
|
|
|
audio frames and group their results into video frames). These raw statistics are then post-processed
|
53
|
|
|
|
|
|
|
in the analysis phase to determine the (hopefully!) actual location of the commercial breaks.
|
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
The detection phase is completely run in C code under XS; the analysis phase is completely run in Perl.
|
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
=head2 Settings
|
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
Settings are passed into the routines via a HASH ref. Settings also come from the default set, and
|
61
|
|
|
|
|
|
|
from any config file parameters. Please see L for full details.
|
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
In general, you will probably only be interested in changing the analysis settings to tweak the results for
|
64
|
|
|
|
|
|
|
a particular channel (or to completely disable advert detection for a channel). The detection parameters
|
65
|
|
|
|
|
|
|
seem to be pretty good for all channels.
|
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
=head2 Results Files
|
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
The output from each phase can be stored into files for later re-use or analysis. The detection phase
|
70
|
|
|
|
|
|
|
output file can be reloaded and passed to the analyse phase multiple times to try out different analysis
|
71
|
|
|
|
|
|
|
settings. The analyse phase output can be plotted to show the effectiveness of the algorithms used.
|
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
=cut
|
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
#============================================================================================
|
77
|
|
|
|
|
|
|
# USES
|
78
|
|
|
|
|
|
|
#============================================================================================
|
79
|
12
|
|
|
12
|
|
491630
|
use strict ;
|
|
12
|
|
|
|
|
27
|
|
|
12
|
|
|
|
|
491
|
|
80
|
12
|
|
|
12
|
|
23194
|
use Env ;
|
|
12
|
|
|
|
|
39901
|
|
|
12
|
|
|
|
|
68
|
|
81
|
12
|
|
|
12
|
|
7322
|
use Carp ;
|
|
12
|
|
|
|
|
26
|
|
|
12
|
|
|
|
|
680
|
|
82
|
12
|
|
|
12
|
|
68
|
use File::Basename ;
|
|
12
|
|
|
|
|
23
|
|
|
12
|
|
|
|
|
1334
|
|
83
|
12
|
|
|
12
|
|
75
|
use File::Path ;
|
|
12
|
|
|
|
|
31
|
|
|
12
|
|
|
|
|
817
|
|
84
|
|
|
|
|
|
|
|
85
|
12
|
|
|
12
|
|
13361
|
use Linux::DVB::DVBT::Advert::Config ;
|
|
12
|
|
|
|
|
41
|
|
|
12
|
|
|
|
|
587
|
|
86
|
12
|
|
|
12
|
|
131
|
use Linux::DVB::DVBT::Advert::Constants ;
|
|
12
|
|
|
|
|
21
|
|
|
12
|
|
|
|
|
273
|
|
87
|
|
|
|
|
|
|
|
88
|
12
|
|
|
12
|
|
9183
|
use Linux::DVB::DVBT::Advert::Mem ;
|
|
12
|
|
|
|
|
35
|
|
|
12
|
|
|
|
|
405
|
|
89
|
|
|
|
|
|
|
|
90
|
12
|
|
|
12
|
|
87
|
use Data::Dumper ;
|
|
12
|
|
|
|
|
21
|
|
|
12
|
|
|
|
|
4135
|
|
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
#============================================================================================
|
93
|
|
|
|
|
|
|
# EXPORTER
|
94
|
|
|
|
|
|
|
#============================================================================================
|
95
|
|
|
|
|
|
|
require Exporter;
|
96
|
|
|
|
|
|
|
our @ISA = qw(Exporter);
|
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
our @EXPORT = qw/
|
99
|
|
|
|
|
|
|
ad_config
|
100
|
|
|
|
|
|
|
ad_debug
|
101
|
|
|
|
|
|
|
detect
|
102
|
|
|
|
|
|
|
detect_from_file
|
103
|
|
|
|
|
|
|
analyse
|
104
|
|
|
|
|
|
|
ad_cut
|
105
|
|
|
|
|
|
|
ad_split
|
106
|
|
|
|
|
|
|
ok_to_detect
|
107
|
|
|
|
|
|
|
/ ;
|
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
our @CHECK_OK = qw/
|
110
|
|
|
|
|
|
|
read_adv
|
111
|
|
|
|
|
|
|
adv_to_cutlist
|
112
|
|
|
|
|
|
|
/ ;
|
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
our @OK = qw/
|
115
|
|
|
|
|
|
|
ad_config_search
|
116
|
|
|
|
|
|
|
channel_settings
|
117
|
|
|
|
|
|
|
read_expected
|
118
|
|
|
|
|
|
|
write_default_config
|
119
|
|
|
|
|
|
|
/ ;
|
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
our @EXPORT_OK = (@OK, @CHECK_OK) ;
|
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
our %EXPORT_TAGS = (
|
124
|
|
|
|
|
|
|
'all' => [ @EXPORT, @EXPORT_OK ],
|
125
|
|
|
|
|
|
|
'check' => [ @EXPORT, @CHECK_OK ],
|
126
|
|
|
|
|
|
|
) ;
|
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
#============================================================================================
|
129
|
|
|
|
|
|
|
# GLOBALS
|
130
|
|
|
|
|
|
|
#============================================================================================
|
131
|
|
|
|
|
|
|
our $VERSION = '0.04' ;
|
132
|
|
|
|
|
|
|
our $DEBUG = 0 ;
|
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
our $USE_XS_MEM = 3 ;
|
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
#our $CONFIG_DIR = $Linux::DVB::DVBT::Advert::Config::DEFAULT_CONFIG_PATH ;
|
138
|
|
|
|
|
|
|
our $CONFIG_DIR ;
|
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
#============================================================================================
|
141
|
|
|
|
|
|
|
# XS
|
142
|
|
|
|
|
|
|
#============================================================================================
|
143
|
|
|
|
|
|
|
require XSLoader;
|
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
if (!$ENV{'ADVERT_NO_XS'})
|
146
|
|
|
|
|
|
|
{
|
147
|
|
|
|
|
|
|
XSLoader::load('Linux::DVB::DVBT::Advert', $VERSION);
|
148
|
|
|
|
|
|
|
}
|
149
|
|
|
|
|
|
|
else
|
150
|
|
|
|
|
|
|
{
|
151
|
|
|
|
|
|
|
print STDERR "WARNING: Running Linux::DVB::DVBT::Advert without XS\n" ;
|
152
|
|
|
|
|
|
|
}
|
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
#============================================================================================
|
155
|
|
|
|
|
|
|
BEGIN {
|
156
|
|
|
|
|
|
|
|
157
|
12
|
|
|
12
|
|
206768
|
$CONFIG_DIR = $Linux::DVB::DVBT::Advert::Config::DEFAULT_CONFIG_PATH ;
|
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
}
|
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
#============================================================================================
|
162
|
|
|
|
|
|
|
my $FPS = $Linux::DVB::DVBT::Advert::Constants::CONSTANTS{'FRAMES_PER_SEC'} ;
|
163
|
|
|
|
|
|
|
my $FRAME_FIELD = 'frame' ;
|
164
|
|
|
|
|
|
|
my $FRAME_END_FIELD = 'frame_end' ;
|
165
|
|
|
|
|
|
|
my $PROG_FIELD = 'program' ;
|
166
|
|
|
|
|
|
|
my $PACKET_FIELD = 'start_pkt' ;
|
167
|
|
|
|
|
|
|
my $PACKET_END_FIELD = 'end_pkt' ;
|
168
|
|
|
|
|
|
|
my $PACKET_GOP_FIELD = 'gop_pkt' ;
|
169
|
|
|
|
|
|
|
my $EXPECTED_FIELD = 'expected' ;
|
170
|
|
|
|
|
|
|
my $LOGO_PROCESSED_FIELD = 'logo_proc' ;
|
171
|
|
|
|
|
|
|
my $LOGO_COALESCED_FIELD = 'logo_coal' ;
|
172
|
|
|
|
|
|
|
my $REDUCED_LOGO_COALESCED_FIELD = 'reduced_logo_coal' ;
|
173
|
|
|
|
|
|
|
my $BLACK_COALESCED_FIELD = 'black_coal' ;
|
174
|
|
|
|
|
|
|
my $SILENT_COALESCED_FIELD = 'silent_coal' ;
|
175
|
|
|
|
|
|
|
my $SILENT_BLACK_FIELD = 'silent_black' ;
|
176
|
|
|
|
|
|
|
my $REDUCED_SILENT_BLACK_FIELD = 'reduced_silent_black' ;
|
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
my $_FRAMENUMS_KEY = '_framenums' ;
|
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
#============================================================================================
|
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
=head2 Functions
|
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
=over 4
|
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
=cut
|
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
#----------------------------------------------------------------------
|
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
=item B
|
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
Get advert configuration information from a config file. Optionally sets the
|
194
|
|
|
|
|
|
|
search path - which is an ARRAY ref containing the list of directories to search.
|
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
Returns the HASH ref of advert settings.
|
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
=cut
|
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
sub ad_config
|
201
|
|
|
|
|
|
|
{
|
202
|
5
|
|
|
5
|
1
|
9708
|
my ($search) = @_ ;
|
203
|
|
|
|
|
|
|
|
204
|
5
|
|
66
|
|
|
29
|
$search ||= $CONFIG_DIR ;
|
205
|
5
|
|
|
|
|
19
|
$CONFIG_DIR = $search ;
|
206
|
|
|
|
|
|
|
|
207
|
5
|
|
|
|
|
25
|
my $ad_config_href = Linux::DVB::DVBT::Advert::Config::read_dvb_adv($CONFIG_DIR) ;
|
208
|
5
|
|
|
|
|
15
|
return $ad_config_href ;
|
209
|
|
|
|
|
|
|
}
|
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
#----------------------------------------------------------------------
|
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
=item B
|
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
Set debug level.
|
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
=cut
|
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
sub ad_debug
|
221
|
|
|
|
|
|
|
{
|
222
|
0
|
|
|
0
|
1
|
0
|
my ($level) = @_ ;
|
223
|
0
|
0
|
|
|
|
0
|
$DEBUG = $level if defined($level) ;
|
224
|
|
|
|
|
|
|
}
|
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
#----------------------------------------------------------------------
|
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
=item B
|
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
Get/set search path for advert config file.
|
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
Returns the current setting.
|
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
=cut
|
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
sub ad_config_search
|
238
|
|
|
|
|
|
|
{
|
239
|
2
|
|
|
2
|
1
|
4181
|
my ($new_path) = @_ ;
|
240
|
|
|
|
|
|
|
|
241
|
2
|
50
|
|
|
|
11
|
if ($new_path)
|
242
|
|
|
|
|
|
|
{
|
243
|
2
|
|
|
|
|
5
|
$CONFIG_DIR = $new_path ;
|
244
|
|
|
|
|
|
|
}
|
245
|
2
|
|
|
|
|
7
|
return $CONFIG_DIR ;
|
246
|
|
|
|
|
|
|
}
|
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
#----------------------------------------------------------------------
|
250
|
|
|
|
|
|
|
#
|
251
|
|
|
|
|
|
|
#=item B<_advert_settings($ad_config_href [, $channel])>
|
252
|
|
|
|
|
|
|
#
|
253
|
|
|
|
|
|
|
#Using the reference to the tuning info HASH (normally read in by B),
|
254
|
|
|
|
|
|
|
#returns a HASH containing just the advert settings information.
|
255
|
|
|
|
|
|
|
#
|
256
|
|
|
|
|
|
|
#If no channel name is specified then this just returns the global settings.
|
257
|
|
|
|
|
|
|
#If a channel name is specified (and that channel can be found in the settings HASH),
|
258
|
|
|
|
|
|
|
#then merges any global settings with the channel-sepcific settings.
|
259
|
|
|
|
|
|
|
#
|
260
|
|
|
|
|
|
|
#If I<$ad_config_href> is undef, then this function first reads the config files (NOTE: this will
|
261
|
|
|
|
|
|
|
#only use the default search path).
|
262
|
|
|
|
|
|
|
#
|
263
|
|
|
|
|
|
|
#Returns the HASH ref of settings.
|
264
|
|
|
|
|
|
|
#
|
265
|
|
|
|
|
|
|
#=cut
|
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
sub _advert_settings
|
268
|
|
|
|
|
|
|
{
|
269
|
1
|
|
|
1
|
|
2
|
my ($ad_config_href, $channel) = @_ ;
|
270
|
|
|
|
|
|
|
|
271
|
1
|
50
|
|
|
|
4
|
print "_advert_settings($ad_config_href, $channel)\n" if $DEBUG>=10 ;
|
272
|
|
|
|
|
|
|
|
273
|
1
|
50
|
|
|
|
5
|
if (!$ad_config_href)
|
274
|
|
|
|
|
|
|
{
|
275
|
0
|
|
|
|
|
0
|
$ad_config_href = ad_config() ;
|
276
|
|
|
|
|
|
|
}
|
277
|
|
|
|
|
|
|
|
278
|
1
|
50
|
|
|
|
4
|
print Data::Dumper->Dump(["_advert_settings($channel) advert settings:", $ad_config_href]) if $DEBUG>=10 ;
|
279
|
|
|
|
|
|
|
|
280
|
1
|
|
|
|
|
6
|
my $settings_href = Linux::DVB::DVBT::Advert::Config::channel_settings($ad_config_href, $channel) ;
|
281
|
|
|
|
|
|
|
|
282
|
1
|
50
|
|
|
|
4
|
print Data::Dumper->Dump(["_advert_settings($channel) OUT:", $settings_href]) if $DEBUG>=10 ;
|
283
|
|
|
|
|
|
|
|
284
|
1
|
|
|
|
|
3
|
return $settings_href ;
|
285
|
|
|
|
|
|
|
}
|
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
=item B
|
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
Returns a HASH ref containing advert settings from the config file
|
293
|
|
|
|
|
|
|
(if available).
|
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
The B<$settings_href> settings HASH ref contains any new settings that the user wishes to
|
296
|
|
|
|
|
|
|
use, overriding global values or config file values.
|
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
The B<$ad_config_href> parameter is expected to be the tuning info HASH ref read in using
|
299
|
|
|
|
|
|
|
L. It is used to set any settings read in
|
300
|
|
|
|
|
|
|
from the default config file.
|
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
=cut
|
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
sub channel_settings
|
305
|
|
|
|
|
|
|
{
|
306
|
1
|
|
|
1
|
1
|
3136
|
my ($settings_href, $channel, $ad_config_href) = @_ ;
|
307
|
|
|
|
|
|
|
|
308
|
1
|
|
50
|
|
|
6
|
$channel ||= "" ;
|
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
## if channel specified, get channel-specific config
|
311
|
1
|
|
|
|
|
6
|
my $config_settings_href = _advert_settings($ad_config_href, $channel) ;
|
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
## Get defaults
|
314
|
1
|
|
|
|
|
112
|
my $default_settings_href = Linux::DVB::DVBT::Advert::dvb_advert_def_settings() ;
|
315
|
|
|
|
|
|
|
|
316
|
1
|
50
|
|
|
|
5
|
if ($DEBUG)
|
317
|
|
|
|
|
|
|
{
|
318
|
0
|
|
|
|
|
0
|
print Data::Dumper->Dump(["config settings:", $config_settings_href]) ;
|
319
|
0
|
|
|
|
|
0
|
print Data::Dumper->Dump(["default settings:", $default_settings_href]) ;
|
320
|
|
|
|
|
|
|
}
|
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
## Merge them all together
|
323
|
1
|
|
|
|
|
6
|
my $chan_settings_href = Linux::DVB::DVBT::Advert::Config::merge_settings(
|
324
|
|
|
|
|
|
|
$default_settings_href,
|
325
|
|
|
|
|
|
|
$config_settings_href,
|
326
|
|
|
|
|
|
|
$settings_href,
|
327
|
|
|
|
|
|
|
) ;
|
328
|
|
|
|
|
|
|
|
329
|
1
|
|
|
|
|
15
|
return $chan_settings_href ;
|
330
|
|
|
|
|
|
|
}
|
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
=item B
|
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
Read the source TS file I<$src> and return a HASH containing the detection statistics
|
338
|
|
|
|
|
|
|
for each frame.
|
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
The B<$ad_config_href> parameter is expected to be the tuning info HASH ref read in using
|
341
|
|
|
|
|
|
|
L. It is used to set any settings read in
|
342
|
|
|
|
|
|
|
from the default config file. If it is undef then a default search path is used.
|
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
The B<$settings_href> settings HASH ref contains any new settings that the user wishes to
|
345
|
|
|
|
|
|
|
use, overriding global values or config file values.
|
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
The optional I<$channel> parameter is used to specify the TV channel that the video was recorded
|
348
|
|
|
|
|
|
|
from. This then allows the config fiel to contain channel-specific settings which are used in the
|
349
|
|
|
|
|
|
|
detection. If no channel is specified (or the channel name is not found in the config file) then just
|
350
|
|
|
|
|
|
|
default settings are used.
|
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
If the optional I<$detect> parameter is specified then the results are saved into the text file
|
353
|
|
|
|
|
|
|
named by the parameter
|
354
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
=cut
|
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
sub detect
|
358
|
|
|
|
|
|
|
{
|
359
|
0
|
|
|
0
|
1
|
0
|
my ($src, $settings_href, $channel, $ad_config_href, $detect) = @_ ;
|
360
|
|
|
|
|
|
|
|
361
|
0
|
0
|
|
|
|
0
|
if ($DEBUG)
|
362
|
|
|
|
|
|
|
{
|
363
|
0
|
|
|
|
|
0
|
print Data::Dumper->Dump(["===detect====", "settings:", $settings_href, "AD ($channel) config", $ad_config_href]) ;
|
364
|
|
|
|
|
|
|
}
|
365
|
|
|
|
|
|
|
|
366
|
0
|
|
0
|
|
|
0
|
$channel ||= "" ;
|
367
|
0
|
|
|
|
|
0
|
my $results_href = {} ;
|
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
## Get combined settings for this channel
|
370
|
0
|
|
|
|
|
0
|
$settings_href = channel_settings($settings_href, $channel, $ad_config_href) ;
|
371
|
|
|
|
|
|
|
|
372
|
0
|
0
|
|
|
|
0
|
if ($DEBUG)
|
373
|
|
|
|
|
|
|
{
|
374
|
0
|
|
|
|
|
0
|
print Data::Dumper->Dump(["channel settings:", $settings_href]) ;
|
375
|
|
|
|
|
|
|
}
|
376
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
## Skip if disabled
|
378
|
0
|
0
|
|
|
|
0
|
if (ok_to_detect($settings_href))
|
379
|
|
|
|
|
|
|
{
|
380
|
0
|
|
|
|
|
0
|
my $adata_ref ;
|
381
|
|
|
|
|
|
|
|
382
|
0
|
|
|
|
|
0
|
$settings_href->{'debug'} =0;
|
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
## Do detection
|
385
|
0
|
|
|
|
|
0
|
my $det_aref = Linux::DVB::DVBT::Advert::dvb_advert_detect($src, $settings_href) ;
|
386
|
|
|
|
|
|
|
|
387
|
0
|
|
|
|
|
0
|
($results_href, $adata_ref) = @$det_aref ;
|
388
|
|
|
|
|
|
|
|
389
|
0
|
0
|
|
|
|
0
|
if ($DEBUG)
|
390
|
|
|
|
|
|
|
{
|
391
|
0
|
|
|
|
|
0
|
print Data::Dumper->Dump(["after detect - results settings:", $results_href->{'settings'}]) ;
|
392
|
|
|
|
|
|
|
}
|
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
# tie an array to the internal data - this is *much* more effecient than letting Perl gobble up
|
395
|
|
|
|
|
|
|
# 10x the memory
|
396
|
0
|
|
|
|
|
0
|
my @frames ;
|
397
|
0
|
|
|
|
|
0
|
tie @frames, 'Linux::DVB::DVBT::Advert', 'ADATA', [$$adata_ref] ;
|
398
|
0
|
|
|
|
|
0
|
$results_href->{'frames'} = \@frames ;
|
399
|
|
|
|
|
|
|
|
400
|
0
|
0
|
|
|
|
0
|
if ($DEBUG)
|
401
|
|
|
|
|
|
|
{
|
402
|
0
|
|
|
|
|
0
|
print "Read $results_href->{settings}{num_frames} frames\n" ;
|
403
|
0
|
|
|
|
|
0
|
print Data::Dumper->Dump(["Results", $results_href]) ;
|
404
|
|
|
|
|
|
|
}
|
405
|
|
|
|
|
|
|
}
|
406
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
## Optionally save results
|
408
|
0
|
0
|
|
|
|
0
|
if ($detect)
|
409
|
|
|
|
|
|
|
{
|
410
|
0
|
0
|
|
|
|
0
|
open my $fh, ">$detect" or die "Error: unable to write to detect file $detect : $!" ;
|
411
|
|
|
|
|
|
|
|
412
|
|
|
|
|
|
|
## Save settings
|
413
|
0
|
|
|
|
|
0
|
my $save_settings_href = $results_href->{'settings'} ;
|
414
|
0
|
|
|
|
|
0
|
foreach my $var (sort keys %$save_settings_href)
|
415
|
|
|
|
|
|
|
{
|
416
|
0
|
0
|
|
|
|
0
|
if (ref($save_settings_href->{$var}) eq 'HASH')
|
417
|
|
|
|
|
|
|
{
|
418
|
0
|
|
|
|
|
0
|
foreach my $subvar (sort keys %{$save_settings_href->{$var}})
|
|
0
|
|
|
|
|
0
|
|
419
|
|
|
|
|
|
|
{
|
420
|
0
|
|
|
|
|
0
|
print $fh "# $var.$subvar = $save_settings_href->{$var}{$subvar}\n" ;
|
421
|
|
|
|
|
|
|
}
|
422
|
|
|
|
|
|
|
}
|
423
|
|
|
|
|
|
|
else
|
424
|
|
|
|
|
|
|
{
|
425
|
0
|
|
|
|
|
0
|
print $fh "# $var = $save_settings_href->{$var}\n" ;
|
426
|
|
|
|
|
|
|
}
|
427
|
|
|
|
|
|
|
}
|
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
## Save frames
|
430
|
0
|
|
|
|
|
0
|
my $frame_href = $results_href->{'frames'}[0] ;
|
431
|
0
|
|
|
|
|
0
|
my $line = $FRAME_FIELD ;
|
432
|
0
|
|
|
|
|
0
|
foreach my $field (sort keys %$frame_href)
|
433
|
|
|
|
|
|
|
{
|
434
|
0
|
0
|
|
|
|
0
|
next unless !ref($frame_href->{$field}) ;
|
435
|
0
|
0
|
|
|
|
0
|
next if $field eq $FRAME_FIELD ;
|
436
|
0
|
|
|
|
|
0
|
$line .= ",$field" ;
|
437
|
|
|
|
|
|
|
}
|
438
|
0
|
|
|
|
|
0
|
print $fh "$line\n" ;
|
439
|
0
|
|
|
|
|
0
|
for (my $idx=0; $idx < $results_href->{'settings'}{'num_frames'}; ++$idx)
|
440
|
|
|
|
|
|
|
{
|
441
|
0
|
|
|
|
|
0
|
$frame_href = $results_href->{'frames'}[$idx] ;
|
442
|
0
|
0
|
|
|
|
0
|
next unless scalar(keys %$frame_href) ;
|
443
|
0
|
|
|
|
|
0
|
my $frame = $frame_href->{$FRAME_FIELD} ;
|
444
|
0
|
|
|
|
|
0
|
$line = "$frame" ;
|
445
|
0
|
|
|
|
|
0
|
foreach my $field (sort keys %$frame_href)
|
446
|
|
|
|
|
|
|
{
|
447
|
0
|
0
|
|
|
|
0
|
next unless !ref($frame_href->{$field}) ;
|
448
|
0
|
0
|
|
|
|
0
|
next if $field eq $FRAME_FIELD ;
|
449
|
0
|
|
|
|
|
0
|
$line .= ",$frame_href->{$field}" ;
|
450
|
|
|
|
|
|
|
}
|
451
|
0
|
|
|
|
|
0
|
print $fh "$line\n" ;
|
452
|
|
|
|
|
|
|
}
|
453
|
|
|
|
|
|
|
|
454
|
0
|
|
|
|
|
0
|
close $fh ;
|
455
|
|
|
|
|
|
|
}
|
456
|
|
|
|
|
|
|
|
457
|
0
|
|
|
|
|
0
|
return $results_href ;
|
458
|
|
|
|
|
|
|
}
|
459
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
462
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
=item B
|
464
|
|
|
|
|
|
|
|
465
|
|
|
|
|
|
|
Read the text file named by the I<$detect> parameter and return a HASH containing the detection statistics
|
466
|
|
|
|
|
|
|
for each frame. All settings are read in from the detection file (but any settings may be overridden in the
|
467
|
|
|
|
|
|
|
L function).
|
468
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
=cut
|
470
|
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
sub detect_from_file
|
472
|
|
|
|
|
|
|
{
|
473
|
5
|
|
|
5
|
1
|
204
|
my ($detect, $settings_href) = @_ ;
|
474
|
|
|
|
|
|
|
|
475
|
5
|
|
50
|
|
|
20
|
$settings_href ||= {} ;
|
476
|
|
|
|
|
|
|
|
477
|
|
|
|
|
|
|
# check file
|
478
|
5
|
50
|
|
|
|
276
|
open my $fh, "<$detect" or die "Error: unable to read to detect file $detect : $!" ;
|
479
|
5
|
|
|
|
|
50
|
close $fh ;
|
480
|
|
|
|
|
|
|
|
481
|
|
|
|
|
|
|
## Do detection
|
482
|
5
|
|
|
|
|
64542
|
my $det_aref = Linux::DVB::DVBT::Advert::dvb_advert_detect_from_file($detect, $settings_href) ;
|
483
|
|
|
|
|
|
|
|
484
|
5
|
|
|
|
|
35
|
my ($results_href, $adata_ref) = @$det_aref ;
|
485
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
# tie an array to the internal data - this is *much* more effecient than letting Perl gobble up
|
487
|
|
|
|
|
|
|
# 10x the memory
|
488
|
5
|
|
|
|
|
16
|
my @frames ;
|
489
|
5
|
|
|
|
|
157
|
tie @frames, 'Linux::DVB::DVBT::Advert', 'ADATA', [$$adata_ref] ;
|
490
|
5
|
|
|
|
|
28
|
$results_href->{'frames'} = \@frames ;
|
491
|
|
|
|
|
|
|
# $results_href->{'__adata'} = $adata_ref ;
|
492
|
|
|
|
|
|
|
|
493
|
5
|
100
|
|
|
|
38
|
if ($DEBUG >= 10)
|
494
|
|
|
|
|
|
|
{
|
495
|
1
|
|
|
|
|
56
|
print "Read $results_href->{settings}{num_frames} frames\n" ;
|
496
|
1
|
|
|
|
|
27
|
print Data::Dumper->Dump(["Results", $results_href]) ;
|
497
|
|
|
|
|
|
|
}
|
498
|
|
|
|
|
|
|
|
499
|
5
|
|
|
|
|
101635
|
return $results_href ;
|
500
|
|
|
|
|
|
|
}
|
501
|
|
|
|
|
|
|
|
502
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
505
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
=item B
|
507
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
Read in expected results file. Used more for debug / display purposes.
|
509
|
|
|
|
|
|
|
|
510
|
|
|
|
|
|
|
=cut
|
511
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
sub read_expected
|
513
|
|
|
|
|
|
|
{
|
514
|
0
|
|
|
0
|
1
|
0
|
my ($expected_file) = @_ ;
|
515
|
|
|
|
|
|
|
|
516
|
|
|
|
|
|
|
## check for expected results
|
517
|
0
|
|
|
|
|
0
|
my @expected ;
|
518
|
|
|
|
|
|
|
#print "expected results: $expected_file\n" ;
|
519
|
0
|
0
|
|
|
|
0
|
if (open my $fh, "<$expected_file")
|
520
|
|
|
|
|
|
|
{
|
521
|
0
|
|
|
|
|
0
|
my $line ;
|
522
|
0
|
|
|
|
|
0
|
while (defined($line=<$fh>))
|
523
|
|
|
|
|
|
|
{
|
524
|
0
|
|
|
|
|
0
|
chomp $line ;
|
525
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
# expected:
|
527
|
|
|
|
|
|
|
# 0) 1 1387 0:00:55.43
|
528
|
|
|
|
|
|
|
# 1) 22208 25186 0:01:59.12
|
529
|
|
|
|
|
|
|
# 2) 40451 42151 0:01:08.00
|
530
|
|
|
|
|
|
|
# 3) 46763 48741 0:01:19.12
|
531
|
|
|
|
|
|
|
#
|
532
|
0
|
0
|
|
|
|
0
|
if ($line =~ /^\s*(\d+)\)\s+(\d+)\s+(\d+)\s+(\d+):(\d+):(\d+)\.(\d+)/)
|
533
|
|
|
|
|
|
|
{
|
534
|
0
|
|
|
|
|
0
|
my ($idx, $start, $end, $hh, $mm, $ss, $ms) = ($1, $2, $3, $4, $5, $6, $7) ;
|
535
|
0
|
|
|
|
|
0
|
push @expected, {
|
536
|
|
|
|
|
|
|
'start' => $start,
|
537
|
|
|
|
|
|
|
'end' => $end,
|
538
|
|
|
|
|
|
|
} ;
|
539
|
|
|
|
|
|
|
#print "$idx) $start .. $end\n" ;
|
540
|
|
|
|
|
|
|
}
|
541
|
|
|
|
|
|
|
}
|
542
|
0
|
|
|
|
|
0
|
close $fh ;
|
543
|
|
|
|
|
|
|
}
|
544
|
|
|
|
|
|
|
|
545
|
0
|
|
|
|
|
0
|
return @expected ;
|
546
|
|
|
|
|
|
|
}
|
547
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
|
549
|
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
550
|
|
|
|
|
|
|
|
551
|
|
|
|
|
|
|
=item B
|
552
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
Process the results to create a cut list for the video using the results gathered by
|
554
|
|
|
|
|
|
|
L or L.
|
555
|
|
|
|
|
|
|
Results from detection are stored in the B<$results_href> HASH ref.
|
556
|
|
|
|
|
|
|
|
557
|
|
|
|
|
|
|
The B<$ad_config_href> parameter is expected to be the tuning info HASH ref read in using
|
558
|
|
|
|
|
|
|
L. It is used to set any settings read in
|
559
|
|
|
|
|
|
|
from the default config file. If it is undef then a default search path is used.
|
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
The optional I<$channel> parameter is used to specify the TV channel that the video was recorded
|
562
|
|
|
|
|
|
|
from. This then allows the config fiel to contain channel-specific settings which are used in the
|
563
|
|
|
|
|
|
|
detection. If no channel is specified (or the channel name is not found in the config file) then just
|
564
|
|
|
|
|
|
|
default settings are used.
|
565
|
|
|
|
|
|
|
|
566
|
|
|
|
|
|
|
Optionally specify a filename using B<$csv> to save the analysis results in a comma-separated
|
567
|
|
|
|
|
|
|
output file (from use in GUI viewing tool).
|
568
|
|
|
|
|
|
|
|
569
|
|
|
|
|
|
|
Optionally specify an ARRAY ref of expected results (read in using L) to
|
570
|
|
|
|
|
|
|
allow the GUI viewing tool to mark the positions of the expected program breaks.
|
571
|
|
|
|
|
|
|
|
572
|
|
|
|
|
|
|
Optionally specify extra settings in order to override the defaults and those used during detection.
|
573
|
|
|
|
|
|
|
|
574
|
|
|
|
|
|
|
|
575
|
|
|
|
|
|
|
=cut
|
576
|
|
|
|
|
|
|
|
577
|
|
|
|
|
|
|
|
578
|
|
|
|
|
|
|
sub analyse
|
579
|
|
|
|
|
|
|
{
|
580
|
0
|
|
|
0
|
1
|
0
|
my ($src, $results_href, $ad_config_href, $channel, $csv, $expected_aref, $extra_settings_href) = @_ ;
|
581
|
|
|
|
|
|
|
|
582
|
0
|
|
|
|
|
0
|
my @cut_list = () ;
|
583
|
|
|
|
|
|
|
|
584
|
0
|
|
|
|
|
0
|
Linux::DVB::DVBT::Advert::Mem::print_used("Start of analyse") ;
|
585
|
|
|
|
|
|
|
|
586
|
|
|
|
|
|
|
## Frame results
|
587
|
0
|
|
|
|
|
0
|
my $frames_adata_aref = $results_href->{'frames'} ;
|
588
|
|
|
|
|
|
|
|
589
|
|
|
|
|
|
|
## Should contain all the settings used during detection
|
590
|
0
|
|
0
|
|
|
0
|
my $results_settings_href = $results_href->{'settings'} || {} ;
|
591
|
|
|
|
|
|
|
|
592
|
|
|
|
|
|
|
# if no channel specified try using value stored in results
|
593
|
0
|
|
0
|
|
|
0
|
$channel ||= $results_settings_href->{'channel'} ;
|
594
|
|
|
|
|
|
|
|
595
|
0
|
0
|
|
|
|
0
|
if ($DEBUG)
|
596
|
|
|
|
|
|
|
{
|
597
|
0
|
|
|
|
|
0
|
print Data::Dumper->Dump(["===analyse====", "det file settings:", $results_settings_href]) ;
|
598
|
|
|
|
|
|
|
}
|
599
|
|
|
|
|
|
|
|
600
|
|
|
|
|
|
|
# get defaults used by C routines
|
601
|
0
|
|
|
|
|
0
|
my $default_settings_href = Linux::DVB::DVBT::Advert::dvb_advert_def_settings() ;
|
602
|
0
|
0
|
|
|
|
0
|
if ($DEBUG)
|
603
|
|
|
|
|
|
|
{
|
604
|
0
|
|
|
|
|
0
|
print Data::Dumper->Dump(["defaults:", $default_settings_href]) ;
|
605
|
|
|
|
|
|
|
}
|
606
|
|
|
|
|
|
|
|
607
|
|
|
|
|
|
|
# merge together all defaults with the settings used during detection to create a complete set of settings
|
608
|
0
|
|
|
|
|
0
|
$results_settings_href = Linux::DVB::DVBT::Advert::Config::merge_settings(
|
609
|
|
|
|
|
|
|
$default_settings_href,
|
610
|
|
|
|
|
|
|
$results_settings_href,
|
611
|
|
|
|
|
|
|
) ;
|
612
|
|
|
|
|
|
|
|
613
|
|
|
|
|
|
|
## if channel specified, get channel-specific config
|
614
|
0
|
|
|
|
|
0
|
my $config_settings_href = _advert_settings($ad_config_href, $channel) ;
|
615
|
|
|
|
|
|
|
|
616
|
0
|
0
|
|
|
|
0
|
if ($DEBUG)
|
617
|
|
|
|
|
|
|
{
|
618
|
0
|
|
|
|
|
0
|
print Data::Dumper->Dump(["config file settings [chan=$channel]:", $config_settings_href]) ;
|
619
|
|
|
|
|
|
|
}
|
620
|
|
|
|
|
|
|
|
621
|
|
|
|
|
|
|
## Merge together the default
|
622
|
0
|
|
|
|
|
0
|
$extra_settings_href = Linux::DVB::DVBT::Advert::Config::merge_settings(
|
623
|
|
|
|
|
|
|
$config_settings_href,
|
624
|
|
|
|
|
|
|
$extra_settings_href,
|
625
|
|
|
|
|
|
|
) ;
|
626
|
|
|
|
|
|
|
|
627
|
|
|
|
|
|
|
## Add expected results
|
628
|
|
|
|
|
|
|
# actually a list of adverts (i.e. and advert is between start & end)
|
629
|
0
|
0
|
0
|
|
|
0
|
if ($expected_aref && (ref($expected_aref) eq 'ARRAY') )
|
630
|
|
|
|
|
|
|
{
|
631
|
0
|
|
|
|
|
0
|
my $expect_href = shift @$expected_aref ;
|
632
|
0
|
|
|
|
|
0
|
foreach my $frame_href (@$frames_adata_aref)
|
633
|
|
|
|
|
|
|
{
|
634
|
0
|
|
|
|
|
0
|
my $framenum = $frame_href->{'frame'} ;
|
635
|
0
|
|
|
|
|
0
|
$frame_href->{$EXPECTED_FIELD} = 1 ;
|
636
|
0
|
0
|
|
|
|
0
|
if ($expect_href)
|
637
|
|
|
|
|
|
|
{
|
638
|
0
|
0
|
0
|
|
|
0
|
if ( ($framenum >= $expect_href->{'start'}) && ($framenum <= $expect_href->{'end'}) )
|
|
|
0
|
|
|
|
|
|
639
|
|
|
|
|
|
|
{
|
640
|
0
|
|
|
|
|
0
|
$frame_href->{$EXPECTED_FIELD} = 0 ;
|
641
|
|
|
|
|
|
|
}
|
642
|
|
|
|
|
|
|
elsif ($framenum > $expect_href->{'end'})
|
643
|
|
|
|
|
|
|
{
|
644
|
0
|
|
|
|
|
0
|
$expect_href = shift @$expected_aref ;
|
645
|
|
|
|
|
|
|
}
|
646
|
|
|
|
|
|
|
}
|
647
|
|
|
|
|
|
|
}
|
648
|
|
|
|
|
|
|
}
|
649
|
|
|
|
|
|
|
|
650
|
0
|
0
|
|
|
|
0
|
prt_frames($frames_adata_aref) if $DEBUG >= 3 ;
|
651
|
|
|
|
|
|
|
|
652
|
|
|
|
|
|
|
# total number of frames
|
653
|
0
|
|
|
|
|
0
|
my $last_frame = -1 ;
|
654
|
0
|
0
|
|
|
|
0
|
if (scalar(@$frames_adata_aref))
|
655
|
|
|
|
|
|
|
{
|
656
|
0
|
|
|
|
|
0
|
$last_frame = $frames_adata_aref->[-1]{'frame'} ;
|
657
|
|
|
|
|
|
|
}
|
658
|
0
|
|
|
|
|
0
|
my $total_frames = $last_frame + 1 ;
|
659
|
0
|
|
|
|
|
0
|
$results_settings_href->{'num_frames'} = $total_frames ;
|
660
|
|
|
|
|
|
|
|
661
|
0
|
0
|
|
|
|
0
|
return @cut_list unless $total_frames ;
|
662
|
|
|
|
|
|
|
|
663
|
|
|
|
|
|
|
|
664
|
|
|
|
|
|
|
# total packets
|
665
|
0
|
|
|
|
|
0
|
my $total_pkts = $frames_adata_aref->[$last_frame]{'end_pkt'} ;
|
666
|
|
|
|
|
|
|
|
667
|
0
|
0
|
|
|
|
0
|
print "== analyse() == : total frames:$total_frames, pkts:$total_pkts\n" if $DEBUG ;
|
668
|
|
|
|
|
|
|
|
669
|
|
|
|
|
|
|
## Split frame results out into arrays (containing the HASH refs stored in results) where the specified
|
670
|
|
|
|
|
|
|
## field flag is true
|
671
|
0
|
|
|
|
|
0
|
my $black_frames_ada_ref = frames_list($results_href, 'black_frame') ;
|
672
|
|
|
|
|
|
|
# my $scene_frames_ada_aref = frames_list($results_href, 'scene_frame') ;
|
673
|
|
|
|
|
|
|
# my $size_frames_ada_aref = frames_list($results_href, 'size_change') ;
|
674
|
0
|
|
|
|
|
0
|
my $logo_frames_ada_aref = frames_list($results_href, 'logo_frame') ;
|
675
|
0
|
|
|
|
|
0
|
my $silent_frames_ada_aref = frames_list($results_href, 'silent_frame') ;
|
676
|
|
|
|
|
|
|
# my $all_frames_ada_aref = frames_list($results_href, '') ;
|
677
|
|
|
|
|
|
|
|
678
|
0
|
|
|
|
|
0
|
my $csv_frames_aref = new_csv_frames($results_href) ;
|
679
|
|
|
|
|
|
|
|
680
|
0
|
|
|
|
|
0
|
Linux::DVB::DVBT::Advert::Mem::print_used(" + created ADA arrays") ;
|
681
|
|
|
|
|
|
|
|
682
|
|
|
|
|
|
|
|
683
|
|
|
|
|
|
|
# if ($DEBUG)
|
684
|
|
|
|
|
|
|
# {
|
685
|
|
|
|
|
|
|
## dump_frames(\@size_frames, "All SIZE frames") if (@size_frames) ;
|
686
|
|
|
|
|
|
|
# dump_frames(\@scene_frames, "All SCENE frames") if (@scene_frames) ;
|
687
|
|
|
|
|
|
|
# dump_frames(\@black_frames, "All BLACK frames") if (@black_frames) ;
|
688
|
|
|
|
|
|
|
# dump_frames(\@logo_frames, "All LOGO frames") if (@logo_frames) ;
|
689
|
|
|
|
|
|
|
# dump_frames(\@silent_frames, "All SILENT frames") if (@silent_frames) ;
|
690
|
|
|
|
|
|
|
# #dump_frames(\@banner_frames, "All BANNER frames") if (@banner_frames) ;
|
691
|
|
|
|
|
|
|
# #dump_frames(\@audio_frames, "All AUDIO frames") if (@audio_frames) ;
|
692
|
|
|
|
|
|
|
# }
|
693
|
|
|
|
|
|
|
|
694
|
|
|
|
|
|
|
## Analysis results
|
695
|
0
|
|
|
|
|
0
|
my @black_cut_list ;
|
696
|
|
|
|
|
|
|
my @silent_cut_list ;
|
697
|
0
|
|
|
|
|
0
|
my @logo_cut_list ;
|
698
|
|
|
|
|
|
|
|
699
|
|
|
|
|
|
|
## Settings
|
700
|
0
|
|
|
|
|
0
|
my $global_settings_href = Linux::DVB::DVBT::Advert::Config::cascade_settings($extra_settings_href, '', $results_settings_href) ;
|
701
|
0
|
|
|
|
|
0
|
my $black_settings_href = Linux::DVB::DVBT::Advert::Config::cascade_settings($extra_settings_href, 'frame', $results_settings_href) ;
|
702
|
0
|
|
|
|
|
0
|
my $logo_settings_href = Linux::DVB::DVBT::Advert::Config::cascade_settings($extra_settings_href, 'logo', $results_settings_href) ;
|
703
|
0
|
|
|
|
|
0
|
my $silent_settings_href = Linux::DVB::DVBT::Advert::Config::cascade_settings($extra_settings_href, 'audio', $results_settings_href) ;
|
704
|
|
|
|
|
|
|
|
705
|
|
|
|
|
|
|
# return cascaded settings
|
706
|
0
|
|
|
|
|
0
|
$results_href->{'settings'} = {
|
707
|
|
|
|
|
|
|
$global_settings_href,
|
708
|
|
|
|
|
|
|
'frame' => $black_settings_href,
|
709
|
|
|
|
|
|
|
'logo' => $logo_settings_href,
|
710
|
|
|
|
|
|
|
'audio' => $silent_settings_href,
|
711
|
|
|
|
|
|
|
} ;
|
712
|
|
|
|
|
|
|
|
713
|
0
|
|
0
|
|
|
0
|
my $rise_thresh = $logo_settings_href->{'logo_rise_threshold'} || 1 ;
|
714
|
0
|
|
0
|
|
|
0
|
my $fall_thresh = $logo_settings_href->{'logo_fall_threshold'} || 1 ;
|
715
|
|
|
|
|
|
|
|
716
|
0
|
|
|
|
|
0
|
Linux::DVB::DVBT::Advert::Mem::print_used(" + got settings") ;
|
717
|
|
|
|
|
|
|
|
718
|
|
|
|
|
|
|
|
719
|
|
|
|
|
|
|
## Skip if disabled
|
720
|
0
|
0
|
|
|
|
0
|
if (!ok_to_detect($global_settings_href))
|
721
|
|
|
|
|
|
|
{
|
722
|
0
|
|
|
|
|
0
|
return @cut_list ;
|
723
|
|
|
|
|
|
|
}
|
724
|
|
|
|
|
|
|
|
725
|
|
|
|
|
|
|
|
726
|
|
|
|
|
|
|
## Saved CSV file for post-detection analysis
|
727
|
0
|
|
|
|
|
0
|
my @csv_settings ;
|
728
|
0
|
|
|
|
|
0
|
csv_add_setting(\@csv_settings, "frame", "0::") ;
|
729
|
0
|
|
|
|
|
0
|
csv_add_setting(\@csv_settings, $PACKET_FIELD, "0::") ;
|
730
|
0
|
|
|
|
|
0
|
csv_add_setting(\@csv_settings, $PACKET_END_FIELD, "0::") ;
|
731
|
0
|
|
|
|
|
0
|
csv_add_setting(\@csv_settings, $PACKET_GOP_FIELD, "0::") ;
|
732
|
0
|
|
|
|
|
0
|
csv_add_setting(\@csv_settings, "black_frame", "0:1:1") ;
|
733
|
0
|
|
|
|
|
0
|
csv_add_setting(\@csv_settings, "scene_frame", "0:1:1") ;
|
734
|
0
|
|
|
|
|
0
|
csv_add_setting(\@csv_settings, "size_change", "0:1:1") ;
|
735
|
0
|
|
|
|
|
0
|
csv_add_setting(\@csv_settings, "match_percent", "0:$rise_thresh:100") ;
|
736
|
0
|
|
|
|
|
0
|
csv_add_setting(\@csv_settings, "ave_percent", "0:$rise_thresh/$fall_thresh:100") ;
|
737
|
0
|
|
|
|
|
0
|
csv_add_setting(\@csv_settings, "volume_dB", "-96:-60:0") ;
|
738
|
0
|
|
|
|
|
0
|
csv_add_setting(\@csv_settings, "silent_frame", "0:1:1") ;
|
739
|
0
|
|
|
|
|
0
|
csv_add_setting(\@csv_settings, $PROG_FIELD, "0:1:100") ;
|
740
|
|
|
|
|
|
|
|
741
|
0
|
0
|
|
|
|
0
|
if ($expected_aref)
|
742
|
|
|
|
|
|
|
{
|
743
|
0
|
|
|
|
|
0
|
csv_add_setting(\@csv_settings, $EXPECTED_FIELD, "0:1:1") ;
|
744
|
|
|
|
|
|
|
}
|
745
|
|
|
|
|
|
|
|
746
|
|
|
|
|
|
|
## Check that this channel doesn't splat logos across the adverts too!
|
747
|
0
|
|
|
|
|
0
|
my $logo_frames_percent = (100.0 * $results_settings_href->{'total_logo_frames'}) / (1.0 * $results_settings_href->{'num_frames'}) ;
|
748
|
0
|
0
|
|
|
|
0
|
print "CUTS: Logo % = $logo_frames_percent\n" if $DEBUG ;
|
749
|
|
|
|
|
|
|
|
750
|
0
|
0
|
|
|
|
0
|
if ($logo_frames_percent > 90.0)
|
751
|
|
|
|
|
|
|
{
|
752
|
0
|
0
|
|
|
|
0
|
print "CUTS: Skipping ALL-LOGOS frames...\n" if $DEBUG ;
|
753
|
|
|
|
|
|
|
##TODO: fix....
|
754
|
0
|
|
|
|
|
0
|
@$logo_frames_ada_aref = () ;
|
755
|
|
|
|
|
|
|
}
|
756
|
|
|
|
|
|
|
|
757
|
|
|
|
|
|
|
##--[ Black detect ]----------------------------------------------------
|
758
|
0
|
|
|
|
|
0
|
Linux::DVB::DVBT::Advert::Mem::print_used("Black detect") ;
|
759
|
0
|
|
|
|
|
0
|
my $new_black_frames_aref = [] ;
|
760
|
0
|
0
|
|
|
|
0
|
if (@$black_frames_ada_ref)
|
761
|
|
|
|
|
|
|
{
|
762
|
|
|
|
|
|
|
#print STDERR "black detect\n" ;
|
763
|
|
|
|
|
|
|
## process
|
764
|
0
|
|
|
|
|
0
|
@black_cut_list = process_black_frames($black_frames_ada_ref, $new_black_frames_aref,
|
765
|
|
|
|
|
|
|
$total_pkts, $total_frames, $black_settings_href,
|
766
|
|
|
|
|
|
|
$frames_adata_aref, $csv_frames_aref, \@csv_settings) ;
|
767
|
|
|
|
|
|
|
|
768
|
0
|
|
|
|
|
0
|
$black_frames_ada_ref = undef ;
|
769
|
|
|
|
|
|
|
|
770
|
|
|
|
|
|
|
## validate cuts
|
771
|
0
|
|
|
|
|
0
|
validate_cutlist(\@black_cut_list, $black_settings_href) ;
|
772
|
|
|
|
|
|
|
|
773
|
|
|
|
|
|
|
# default to using the black cut list
|
774
|
0
|
|
|
|
|
0
|
@cut_list = @black_cut_list ;
|
775
|
|
|
|
|
|
|
|
776
|
0
|
0
|
|
|
|
0
|
print "BLACK CUTS: " . scalar(@black_cut_list) . "\n" if $DEBUG ;
|
777
|
|
|
|
|
|
|
|
778
|
|
|
|
|
|
|
#print STDERR "black detect - done\n" ;
|
779
|
|
|
|
|
|
|
}
|
780
|
|
|
|
|
|
|
|
781
|
|
|
|
|
|
|
##--[ Logo detect ]----------------------------------------------------
|
782
|
0
|
0
|
|
|
|
0
|
if (@$logo_frames_ada_aref)
|
783
|
|
|
|
|
|
|
{
|
784
|
|
|
|
|
|
|
#print STDERR "logo detect\n" ;
|
785
|
0
|
|
|
|
|
0
|
Linux::DVB::DVBT::Advert::Mem::print_used("Logo detect") ;
|
786
|
|
|
|
|
|
|
|
787
|
0
|
|
|
|
|
0
|
my $scene_frames_ada_aref = frames_list($results_href, 'scene_frame') ;
|
788
|
0
|
|
|
|
|
0
|
my $all_frames_ada_aref = frames_list($results_href, '') ;
|
789
|
|
|
|
|
|
|
|
790
|
|
|
|
|
|
|
## process
|
791
|
0
|
|
|
|
|
0
|
@logo_cut_list = process_logo_frames($all_frames_ada_aref, $new_black_frames_aref, $scene_frames_ada_aref,
|
792
|
|
|
|
|
|
|
$total_pkts, $total_frames, $logo_settings_href,
|
793
|
|
|
|
|
|
|
$frames_adata_aref, $csv_frames_aref, \@csv_settings) ;
|
794
|
|
|
|
|
|
|
|
795
|
0
|
|
|
|
|
0
|
$scene_frames_ada_aref = undef ;
|
796
|
0
|
|
|
|
|
0
|
$all_frames_ada_aref = undef ;
|
797
|
0
|
|
|
|
|
0
|
$logo_frames_ada_aref = undef ;
|
798
|
|
|
|
|
|
|
|
799
|
|
|
|
|
|
|
## validate cuts
|
800
|
0
|
|
|
|
|
0
|
validate_cutlist(\@logo_cut_list, $logo_settings_href) ;
|
801
|
|
|
|
|
|
|
|
802
|
0
|
0
|
|
|
|
0
|
print "LOGO CUTS: " . scalar(@logo_cut_list) . "\n" if $DEBUG ;
|
803
|
|
|
|
|
|
|
|
804
|
|
|
|
|
|
|
# use this logo list
|
805
|
0
|
0
|
|
|
|
0
|
if (@logo_cut_list >= @cut_list)
|
806
|
|
|
|
|
|
|
{
|
807
|
0
|
|
|
|
|
0
|
@cut_list = @logo_cut_list ;
|
808
|
|
|
|
|
|
|
}
|
809
|
|
|
|
|
|
|
else
|
810
|
|
|
|
|
|
|
{
|
811
|
0
|
|
|
|
|
0
|
@logo_cut_list = () ;
|
812
|
0
|
0
|
|
|
|
0
|
print " + Cleared LOGO CUTS\n" if $DEBUG ;
|
813
|
|
|
|
|
|
|
}
|
814
|
|
|
|
|
|
|
#print STDERR "logo detect - done\n" ;
|
815
|
|
|
|
|
|
|
}
|
816
|
|
|
|
|
|
|
|
817
|
|
|
|
|
|
|
|
818
|
|
|
|
|
|
|
##--[ Silence detect ]----------------------------------------------------
|
819
|
0
|
0
|
0
|
|
|
0
|
if (!@logo_cut_list && @$new_black_frames_aref && $silent_frames_ada_aref)
|
|
|
|
0
|
|
|
|
|
820
|
|
|
|
|
|
|
{
|
821
|
|
|
|
|
|
|
#print STDERR "silence detect\n" ;
|
822
|
0
|
|
|
|
|
0
|
Linux::DVB::DVBT::Advert::Mem::print_used("Silence detect") ;
|
823
|
|
|
|
|
|
|
|
824
|
|
|
|
|
|
|
## process
|
825
|
0
|
|
|
|
|
0
|
@silent_cut_list = process_silent_frames($new_black_frames_aref, $silent_frames_ada_aref,
|
826
|
|
|
|
|
|
|
$total_pkts, $total_frames, $silent_settings_href,
|
827
|
|
|
|
|
|
|
$frames_adata_aref, $csv_frames_aref, \@csv_settings) ;
|
828
|
|
|
|
|
|
|
|
829
|
0
|
|
|
|
|
0
|
$silent_frames_ada_aref = undef ;
|
830
|
|
|
|
|
|
|
|
831
|
|
|
|
|
|
|
## validate cuts
|
832
|
0
|
|
|
|
|
0
|
validate_cutlist(\@silent_cut_list, $silent_settings_href) ;
|
833
|
|
|
|
|
|
|
|
834
|
0
|
0
|
|
|
|
0
|
print "SILENT CUTS: " . scalar(@silent_cut_list) . "\n" if $DEBUG ;
|
835
|
|
|
|
|
|
|
|
836
|
|
|
|
|
|
|
# default to using the black cut list
|
837
|
0
|
0
|
|
|
|
0
|
if (@silent_cut_list)
|
838
|
|
|
|
|
|
|
{
|
839
|
0
|
|
|
|
|
0
|
@cut_list = @silent_cut_list ;
|
840
|
|
|
|
|
|
|
}
|
841
|
|
|
|
|
|
|
#print STDERR "silence detect - done\n" ;
|
842
|
|
|
|
|
|
|
}
|
843
|
|
|
|
|
|
|
|
844
|
|
|
|
|
|
|
#print STDERR "Detect - end\n" ;
|
845
|
|
|
|
|
|
|
|
846
|
|
|
|
|
|
|
##--[ Final ]----------------------------------------------------
|
847
|
0
|
|
|
|
|
0
|
Linux::DVB::DVBT::Advert::Mem::print_used("Detect end") ;
|
848
|
|
|
|
|
|
|
|
849
|
0
|
0
|
|
|
|
0
|
if ($DEBUG)
|
850
|
|
|
|
|
|
|
{
|
851
|
|
|
|
|
|
|
#print STDERR "printing cut lists...\n" ;
|
852
|
0
|
0
|
|
|
|
0
|
if (@black_cut_list)
|
853
|
|
|
|
|
|
|
{
|
854
|
0
|
|
|
|
|
0
|
dump_cutlist("BLACK CUT LIST", \@black_cut_list, "#") ;
|
855
|
|
|
|
|
|
|
}
|
856
|
0
|
0
|
|
|
|
0
|
if (@logo_cut_list)
|
857
|
|
|
|
|
|
|
{
|
858
|
0
|
|
|
|
|
0
|
dump_cutlist("LOGO CUT LIST", \@logo_cut_list, "#") ;
|
859
|
|
|
|
|
|
|
}
|
860
|
0
|
0
|
|
|
|
0
|
if (@silent_cut_list)
|
861
|
|
|
|
|
|
|
{
|
862
|
0
|
|
|
|
|
0
|
dump_cutlist("SILENT CUT LIST", \@silent_cut_list, "#") ;
|
863
|
|
|
|
|
|
|
}
|
864
|
|
|
|
|
|
|
|
865
|
0
|
|
|
|
|
0
|
dump_cutlist("FINAL CUT LIST", \@cut_list, "") ;
|
866
|
|
|
|
|
|
|
#print STDERR "done printing cut lists...\n" ;
|
867
|
|
|
|
|
|
|
}
|
868
|
|
|
|
|
|
|
|
869
|
|
|
|
|
|
|
## Save CSV info
|
870
|
0
|
0
|
|
|
|
0
|
if ($csv)
|
871
|
|
|
|
|
|
|
{
|
872
|
|
|
|
|
|
|
#print STDERR "write csv\n" ;
|
873
|
0
|
|
|
|
|
0
|
Linux::DVB::DVBT::Advert::Mem::print_used("Writing CSV") ;
|
874
|
|
|
|
|
|
|
|
875
|
|
|
|
|
|
|
## Add cut list as program boundaries
|
876
|
0
|
|
|
|
|
0
|
csv_add_prog($results_href, $csv_frames_aref, $PROG_FIELD, \@cut_list) ;
|
877
|
|
|
|
|
|
|
|
878
|
|
|
|
|
|
|
## write out csv
|
879
|
0
|
|
|
|
|
0
|
write_csv($csv, $results_href, $csv_frames_aref, @csv_settings) ;
|
880
|
|
|
|
|
|
|
|
881
|
|
|
|
|
|
|
#print STDERR "write csv - done\n" ;
|
882
|
|
|
|
|
|
|
}
|
883
|
|
|
|
|
|
|
|
884
|
|
|
|
|
|
|
## Tidy up
|
885
|
0
|
|
|
|
|
0
|
$results_href = undef ;
|
886
|
|
|
|
|
|
|
|
887
|
0
|
|
|
|
|
0
|
Linux::DVB::DVBT::Advert::Mem::print_used("End of analyse") ;
|
888
|
|
|
|
|
|
|
|
889
|
|
|
|
|
|
|
#print STDERR "Analyse - done\n" ;
|
890
|
|
|
|
|
|
|
|
891
|
|
|
|
|
|
|
## return results
|
892
|
0
|
|
|
|
|
0
|
return @cut_list ;
|
893
|
|
|
|
|
|
|
}
|
894
|
|
|
|
|
|
|
|
895
|
|
|
|
|
|
|
|
896
|
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
897
|
|
|
|
|
|
|
|
898
|
|
|
|
|
|
|
=item B
|
899
|
|
|
|
|
|
|
|
900
|
|
|
|
|
|
|
Cut the $src_file at the points specified in the ARRAY ref $cut_list_aref, writing the output
|
901
|
|
|
|
|
|
|
to $cut_file
|
902
|
|
|
|
|
|
|
|
903
|
|
|
|
|
|
|
=cut
|
904
|
|
|
|
|
|
|
|
905
|
|
|
|
|
|
|
sub ad_cut
|
906
|
|
|
|
|
|
|
{
|
907
|
0
|
|
|
0
|
1
|
0
|
my ($src_file, $cut_file, $cut_list_aref) = @_ ;
|
908
|
|
|
|
|
|
|
|
909
|
0
|
0
|
|
|
|
0
|
croak "Unable to read \"$src_file\"" unless -f $src_file ;
|
910
|
0
|
0
|
|
|
|
0
|
croak "Zero-length file \"$src_file\"" unless -s $src_file ;
|
911
|
0
|
0
|
|
|
|
0
|
croak "Must specify a destination filename" unless $cut_file ;
|
912
|
|
|
|
|
|
|
|
913
|
|
|
|
|
|
|
# ensure dest directory exists
|
914
|
0
|
|
|
|
|
0
|
my $dir = dirname($cut_file) ;
|
915
|
0
|
0
|
|
|
|
0
|
if (! -d $dir)
|
916
|
|
|
|
|
|
|
{
|
917
|
|
|
|
|
|
|
# create dir
|
918
|
0
|
0
|
|
|
|
0
|
mkpath([$dir], $DEBUG, 0755) or return "Unable to create directory $dir : $!" ;
|
919
|
|
|
|
|
|
|
}
|
920
|
|
|
|
|
|
|
|
921
|
|
|
|
|
|
|
# run cut
|
922
|
0
|
|
|
|
|
0
|
my $rc = dvb_ad_cut($src_file, $cut_file, $cut_list_aref) ;
|
923
|
|
|
|
|
|
|
|
924
|
0
|
|
|
|
|
0
|
return $rc ;
|
925
|
|
|
|
|
|
|
}
|
926
|
|
|
|
|
|
|
|
927
|
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
928
|
|
|
|
|
|
|
|
929
|
|
|
|
|
|
|
=item B
|
930
|
|
|
|
|
|
|
|
931
|
|
|
|
|
|
|
Split the $src_file at the points specified in the ARRAY ref $cut_list_aref, writing the output files
|
932
|
|
|
|
|
|
|
to $cut_file with suffix XXXX where XXXX is in incrementing count starting at 0001
|
933
|
|
|
|
|
|
|
|
934
|
|
|
|
|
|
|
=cut
|
935
|
|
|
|
|
|
|
|
936
|
|
|
|
|
|
|
sub ad_split
|
937
|
|
|
|
|
|
|
{
|
938
|
0
|
|
|
0
|
1
|
0
|
my ($src_file, $cut_file, $cut_list_aref) = @_ ;
|
939
|
|
|
|
|
|
|
|
940
|
0
|
0
|
|
|
|
0
|
croak "Unable to read \"$src_file\"" unless -f $src_file ;
|
941
|
0
|
0
|
|
|
|
0
|
croak "Zero-length file \"$src_file\"" unless -s $src_file ;
|
942
|
0
|
0
|
|
|
|
0
|
croak "Must specify a destination filename" unless $cut_file ;
|
943
|
|
|
|
|
|
|
|
944
|
|
|
|
|
|
|
# ensure dest directory exists
|
945
|
0
|
|
|
|
|
0
|
my $dir = dirname($cut_file) ;
|
946
|
0
|
0
|
|
|
|
0
|
if (! -d $dir)
|
947
|
|
|
|
|
|
|
{
|
948
|
|
|
|
|
|
|
# create dir
|
949
|
0
|
0
|
|
|
|
0
|
mkpath([$dir], $DEBUG, 0755) or return "Unable to create directory $dir : $!" ;
|
950
|
|
|
|
|
|
|
}
|
951
|
|
|
|
|
|
|
|
952
|
|
|
|
|
|
|
# run cut
|
953
|
0
|
|
|
|
|
0
|
my $rc = dvb_ad_split($src_file, $cut_file, $cut_list_aref) ;
|
954
|
|
|
|
|
|
|
|
955
|
0
|
|
|
|
|
0
|
return $rc ;
|
956
|
|
|
|
|
|
|
}
|
957
|
|
|
|
|
|
|
|
958
|
|
|
|
|
|
|
|
959
|
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
960
|
|
|
|
|
|
|
|
961
|
|
|
|
|
|
|
=item B
|
962
|
|
|
|
|
|
|
|
963
|
|
|
|
|
|
|
Looks at the settings and returns TRUE if the settings are such that advert detection
|
964
|
|
|
|
|
|
|
will be preformed (i.e. detection_method is not 'disabled' or 0)
|
965
|
|
|
|
|
|
|
|
966
|
|
|
|
|
|
|
=cut
|
967
|
|
|
|
|
|
|
|
968
|
|
|
|
|
|
|
sub ok_to_detect
|
969
|
|
|
|
|
|
|
{
|
970
|
0
|
|
|
0
|
1
|
0
|
my ($settings_href) = @_ ;
|
971
|
|
|
|
|
|
|
|
972
|
0
|
|
|
|
|
0
|
my $ok = 0 ;
|
973
|
0
|
0
|
0
|
|
|
0
|
if (exists($settings_href->{'detection_method'}) && $settings_href->{'detection_method'})
|
974
|
|
|
|
|
|
|
{
|
975
|
0
|
|
|
|
|
0
|
$ok = 1 ;
|
976
|
|
|
|
|
|
|
}
|
977
|
|
|
|
|
|
|
|
978
|
0
|
|
|
|
|
0
|
return $ok ;
|
979
|
|
|
|
|
|
|
}
|
980
|
|
|
|
|
|
|
|
981
|
|
|
|
|
|
|
|
982
|
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
983
|
|
|
|
|
|
|
|
984
|
|
|
|
|
|
|
=item B
|
985
|
|
|
|
|
|
|
|
986
|
|
|
|
|
|
|
Writes a default Advert config file. If the optional B<$force> parameter is set, then
|
987
|
|
|
|
|
|
|
writes a new file even if one already exists. Uses the optional search path to find
|
988
|
|
|
|
|
|
|
a writeable directory (other than the default search path).
|
989
|
|
|
|
|
|
|
|
990
|
|
|
|
|
|
|
=cut
|
991
|
|
|
|
|
|
|
|
992
|
|
|
|
|
|
|
sub write_default_config
|
993
|
|
|
|
|
|
|
{
|
994
|
0
|
|
|
0
|
1
|
0
|
my ($force, $search_path) = @_ ;
|
995
|
|
|
|
|
|
|
|
996
|
0
|
|
0
|
|
|
0
|
$search_path ||= $CONFIG_DIR ;
|
997
|
0
|
|
|
|
|
0
|
$CONFIG_DIR = $search_path ;
|
998
|
|
|
|
|
|
|
|
999
|
0
|
|
|
|
|
0
|
my $fname = Linux::DVB::DVBT::Advert::Config::write_filename($search_path) ;
|
1000
|
0
|
0
|
|
|
|
0
|
if ($fname)
|
1001
|
|
|
|
|
|
|
{
|
1002
|
|
|
|
|
|
|
## only write if it doesn't exist OR we're forced to overwrite
|
1003
|
0
|
0
|
0
|
|
|
0
|
if ($force || (!$force && ! -f $fname))
|
|
|
|
0
|
|
|
|
|
1004
|
|
|
|
|
|
|
{
|
1005
|
|
|
|
|
|
|
# get defaults used by C routines
|
1006
|
0
|
|
|
|
|
0
|
my $default_settings_href = Linux::DVB::DVBT::Advert::dvb_advert_def_settings() ;
|
1007
|
0
|
|
|
|
|
0
|
my %settings = (
|
1008
|
|
|
|
|
|
|
$Linux::DVB::DVBT::Advert::Config::ADVERT_GLOBAL_SECTION => $default_settings_href,
|
1009
|
|
|
|
|
|
|
) ;
|
1010
|
|
|
|
|
|
|
|
1011
|
|
|
|
|
|
|
# write config
|
1012
|
0
|
|
|
|
|
0
|
Linux::DVB::DVBT::Advert::Config::write_default_dvb_adv(\%settings, $search_path) ;
|
1013
|
|
|
|
|
|
|
}
|
1014
|
|
|
|
|
|
|
}
|
1015
|
|
|
|
|
|
|
}
|
1016
|
|
|
|
|
|
|
|
1017
|
|
|
|
|
|
|
|
1018
|
|
|
|
|
|
|
#============================================================================================
|
1019
|
|
|
|
|
|
|
# PRIVATE
|
1020
|
|
|
|
|
|
|
#============================================================================================
|
1021
|
|
|
|
|
|
|
|
1022
|
|
|
|
|
|
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
1023
|
|
|
|
|
|
|
# FRAMES LISTS
|
1024
|
|
|
|
|
|
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
1025
|
|
|
|
|
|
|
|
1026
|
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
1027
|
|
|
|
|
|
|
# Split frame results out into arrays (containing the HASH refs stored in results) where the specified
|
1028
|
|
|
|
|
|
|
# field flag is true. If flag_field is empty then return the list of all frames
|
1029
|
|
|
|
|
|
|
#
|
1030
|
|
|
|
|
|
|
# XS
|
1031
|
|
|
|
|
|
|
#
|
1032
|
|
|
|
|
|
|
sub frames_list
|
1033
|
|
|
|
|
|
|
{
|
1034
|
2
|
|
|
2
|
0
|
23
|
my ($results_href, $flag_field) = @_ ;
|
1035
|
|
|
|
|
|
|
|
1036
|
2
|
|
|
|
|
5
|
my @list_ada ;
|
1037
|
|
|
|
|
|
|
|
1038
|
2
|
|
|
|
|
4
|
my $thing = tied @{$results_href->{'frames'}} ;
|
|
2
|
|
|
|
|
7
|
|
1039
|
|
|
|
|
|
|
|
1040
|
2
|
|
|
|
|
37
|
tie @list_ada, 'Linux::DVB::DVBT::Advert', 'FILTER',
|
1041
|
|
|
|
|
|
|
[$thing, $flag_field, 1] ;
|
1042
|
|
|
|
|
|
|
|
1043
|
2
|
|
|
|
|
6
|
my $ada = tied @list_ada ;
|
1044
|
2
|
|
|
|
|
32
|
$ada->update_gaps() ;
|
1045
|
|
|
|
|
|
|
|
1046
|
2
|
|
|
|
|
24
|
return \@list_ada ;
|
1047
|
|
|
|
|
|
|
}
|
1048
|
|
|
|
|
|
|
|
1049
|
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
1050
|
|
|
|
|
|
|
# Pull out any entries where the specified field >= threshold
|
1051
|
|
|
|
|
|
|
#
|
1052
|
|
|
|
|
|
|
sub frames_matching
|
1053
|
|
|
|
|
|
|
{
|
1054
|
0
|
|
|
0
|
0
|
0
|
my ($frames_adata_aref, $flag_field, $threshold) = @_ ;
|
1055
|
|
|
|
|
|
|
|
1056
|
0
|
|
|
|
|
0
|
my @list ;
|
1057
|
|
|
|
|
|
|
|
1058
|
0
|
|
|
|
|
0
|
my $thing = tied @$frames_adata_aref ;
|
1059
|
|
|
|
|
|
|
|
1060
|
0
|
|
|
|
|
0
|
my @list_ada ;
|
1061
|
0
|
|
|
|
|
0
|
tie @list_ada, 'Linux::DVB::DVBT::Advert', 'FILTER',
|
1062
|
|
|
|
|
|
|
[$thing, $flag_field, $threshold] ;
|
1063
|
|
|
|
|
|
|
|
1064
|
|
|
|
|
|
|
#dump_frames(\@list_ada, "frames_matching() - raw") ;
|
1065
|
|
|
|
|
|
|
|
1066
|
0
|
|
|
|
|
0
|
my $ada = tied @list_ada ;
|
1067
|
0
|
|
|
|
|
0
|
$ada->update_gaps() ;
|
1068
|
|
|
|
|
|
|
|
1069
|
|
|
|
|
|
|
#dump_frames(\@list_ada, "frames_matching() - updated gap") ;
|
1070
|
|
|
|
|
|
|
|
1071
|
|
|
|
|
|
|
# turn into a list of frame HASH entries
|
1072
|
0
|
|
|
|
|
0
|
@list = frames_array_to_hashlist(\@list_ada) ;
|
1073
|
|
|
|
|
|
|
|
1074
|
|
|
|
|
|
|
#dump_frames(\@list, "frames_matching() - frames_array_to_hashlist") ;
|
1075
|
|
|
|
|
|
|
|
1076
|
0
|
|
|
|
|
0
|
return \@list ;
|
1077
|
|
|
|
|
|
|
}
|
1078
|
|
|
|
|
|
|
|
1079
|
|
|
|
|
|
|
|
1080
|
|
|
|
|
|
|
|
1081
|
|
|
|
|
|
|
|
1082
|
|
|
|
|
|
|
#---------------------------------------------------------------------------------
|
1083
|
|
|
|
|
|
|
# Convert a list of all frames into a list of frame HASH entries
|
1084
|
|
|
|
|
|
|
sub frames_array_to_hashlist
|
1085
|
|
|
|
|
|
|
{
|
1086
|
0
|
|
|
0
|
0
|
0
|
my ($frames_aref) = @_ ;
|
1087
|
|
|
|
|
|
|
|
1088
|
|
|
|
|
|
|
## coalesce (also updates the gap settings)
|
1089
|
0
|
|
|
|
|
0
|
my @frames = coalesce_frames($frames_aref,
|
1090
|
|
|
|
|
|
|
{
|
1091
|
|
|
|
|
|
|
'frame_window' => 1,
|
1092
|
|
|
|
|
|
|
'min_frames' => 1,
|
1093
|
|
|
|
|
|
|
}
|
1094
|
|
|
|
|
|
|
) ;
|
1095
|
|
|
|
|
|
|
|
1096
|
0
|
|
|
|
|
0
|
return @frames ;
|
1097
|
|
|
|
|
|
|
}
|
1098
|
|
|
|
|
|
|
|
1099
|
|
|
|
|
|
|
|
1100
|
|
|
|
|
|
|
|
1101
|
|
|
|
|
|
|
#---------------------------------------------------------------------------------
|
1102
|
|
|
|
|
|
|
sub frames_subtract
|
1103
|
|
|
|
|
|
|
{
|
1104
|
0
|
|
|
0
|
0
|
0
|
my ($src_frames_aref, $sub_frames_aref, $fuzziness) = @_ ;
|
1105
|
|
|
|
|
|
|
|
1106
|
|
|
|
|
|
|
## add
|
1107
|
0
|
|
|
|
|
0
|
my @frames = frames_subtract_array($src_frames_aref, $sub_frames_aref, $fuzziness) ;
|
1108
|
|
|
|
|
|
|
|
1109
|
|
|
|
|
|
|
## convert to list of frame hashs
|
1110
|
0
|
|
|
|
|
0
|
@frames = frames_array_to_hashlist(\@frames) ;
|
1111
|
|
|
|
|
|
|
|
1112
|
|
|
|
|
|
|
return @frames
|
1113
|
0
|
|
|
|
|
0
|
}
|
1114
|
|
|
|
|
|
|
|
1115
|
|
|
|
|
|
|
#---------------------------------------------------------------------------------
|
1116
|
|
|
|
|
|
|
# Add frames list - return the array of all frames
|
1117
|
|
|
|
|
|
|
sub frames_add_array
|
1118
|
|
|
|
|
|
|
{
|
1119
|
0
|
|
|
0
|
0
|
0
|
my ($src_frames_aref, $add_frames_aref, $fuzziness) = @_ ;
|
1120
|
|
|
|
|
|
|
|
1121
|
|
|
|
|
|
|
## get first entry from source to use to replicate into newly added entries
|
1122
|
0
|
|
|
|
|
0
|
my $new_href = $add_frames_aref->[0] ;
|
1123
|
|
|
|
|
|
|
|
1124
|
|
|
|
|
|
|
## pre-process subtracting array
|
1125
|
0
|
|
|
|
|
0
|
my $first_frame = $add_frames_aref->[0]{'frame'} - $fuzziness ;
|
1126
|
0
|
|
|
|
|
0
|
my $last_frame = $add_frames_aref->[-1]{'frame_end'} + $fuzziness ;
|
1127
|
0
|
|
|
|
|
0
|
foreach my $href (@$add_frames_aref)
|
1128
|
|
|
|
|
|
|
{
|
1129
|
0
|
|
|
|
|
0
|
my $frame_start = $href->{'frame'} - $fuzziness ;
|
1130
|
0
|
|
|
|
|
0
|
my $frame_end = $href->{'frame_end'} + $fuzziness ;
|
1131
|
|
|
|
|
|
|
}
|
1132
|
|
|
|
|
|
|
|
1133
|
|
|
|
|
|
|
## pre-process source array
|
1134
|
0
|
|
|
|
|
0
|
my @frames ;
|
1135
|
0
|
0
|
|
|
|
0
|
$first_frame = $add_frames_aref->[0]{'frame'} if $first_frame > $add_frames_aref->[0]{'frame'} ;
|
1136
|
0
|
0
|
|
|
|
0
|
$last_frame = $add_frames_aref->[-1]{'frame_end'} if $last_frame < $add_frames_aref->[-1]{'frame_end'} ;
|
1137
|
0
|
|
|
|
|
0
|
my %add_frames ;
|
1138
|
0
|
|
|
|
|
0
|
foreach my $href (@$add_frames_aref)
|
1139
|
|
|
|
|
|
|
{
|
1140
|
0
|
|
|
|
|
0
|
my $frame_start = $href->{'frame'} ;
|
1141
|
0
|
|
|
|
|
0
|
my $frame_end = $href->{'frame_end'} ;
|
1142
|
0
|
|
|
|
|
0
|
foreach my $fnum ($frame_start..$frame_end)
|
1143
|
|
|
|
|
|
|
{
|
1144
|
0
|
|
|
|
|
0
|
$add_frames{$fnum} = $href ;
|
1145
|
|
|
|
|
|
|
}
|
1146
|
|
|
|
|
|
|
}
|
1147
|
|
|
|
|
|
|
|
1148
|
|
|
|
|
|
|
## Merge the two arrays
|
1149
|
0
|
|
|
|
|
0
|
foreach my $fnum ($first_frame..$last_frame)
|
1150
|
|
|
|
|
|
|
{
|
1151
|
0
|
0
|
|
|
|
0
|
if (exists($add_frames{$fnum}))
|
|
|
0
|
|
|
|
|
|
1152
|
|
|
|
|
|
|
{
|
1153
|
0
|
|
|
|
|
0
|
push @frames, $add_frames{$fnum} ;
|
1154
|
|
|
|
|
|
|
}
|
1155
|
|
|
|
|
|
|
elsif (exists($add_frames{$fnum}))
|
1156
|
|
|
|
|
|
|
{
|
1157
|
0
|
|
|
|
|
0
|
push @frames, {
|
1158
|
|
|
|
|
|
|
%$new_href,
|
1159
|
0
|
|
|
|
|
0
|
%{$add_frames{$fnum}},
|
1160
|
|
|
|
|
|
|
} ;
|
1161
|
|
|
|
|
|
|
}
|
1162
|
|
|
|
|
|
|
}
|
1163
|
0
|
|
|
|
|
0
|
update_gap(\@frames) ;
|
1164
|
|
|
|
|
|
|
|
1165
|
|
|
|
|
|
|
return @frames
|
1166
|
0
|
|
|
|
|
0
|
}
|
1167
|
|
|
|
|
|
|
|
1168
|
|
|
|
|
|
|
|
1169
|
|
|
|
|
|
|
|
1170
|
|
|
|
|
|
|
#---------------------------------------------------------------------------------
|
1171
|
|
|
|
|
|
|
# Subtract frames list - return the array of all frames
|
1172
|
|
|
|
|
|
|
sub frames_subtract_array
|
1173
|
|
|
|
|
|
|
{
|
1174
|
0
|
|
|
0
|
0
|
0
|
my ($src_frames_aref, $sub_frames_aref, $fuzziness) = @_ ;
|
1175
|
|
|
|
|
|
|
|
1176
|
|
|
|
|
|
|
## Make subtracting frames "fuzzy"
|
1177
|
0
|
|
|
|
|
0
|
my %fuzzy_frames ;
|
1178
|
0
|
|
|
|
|
0
|
foreach my $href (@$sub_frames_aref)
|
1179
|
|
|
|
|
|
|
{
|
1180
|
0
|
|
|
|
|
0
|
my $frame_start = $href->{'frame'} - $fuzziness ;
|
1181
|
0
|
|
|
|
|
0
|
my $frame_end = $href->{'frame_end'} + $fuzziness ;
|
1182
|
0
|
0
|
|
|
|
0
|
$frame_start=0 if ($frame_start<0) ;
|
1183
|
0
|
|
|
|
|
0
|
foreach my $fnum ($frame_start..$frame_end)
|
1184
|
|
|
|
|
|
|
{
|
1185
|
0
|
|
|
|
|
0
|
$fuzzy_frames{$fnum} = $href ;
|
1186
|
|
|
|
|
|
|
}
|
1187
|
|
|
|
|
|
|
}
|
1188
|
|
|
|
|
|
|
|
1189
|
|
|
|
|
|
|
## Remove source frames that do not coincide with subtracted
|
1190
|
0
|
|
|
|
|
0
|
my @frames ;
|
1191
|
0
|
|
|
|
|
0
|
foreach my $href (@$src_frames_aref)
|
1192
|
|
|
|
|
|
|
{
|
1193
|
0
|
|
|
|
|
0
|
my $framenum = $href->{'frame'} ;
|
1194
|
0
|
|
|
|
|
0
|
my $framenum_end = $href->{'frame_end'} ;
|
1195
|
|
|
|
|
|
|
|
1196
|
0
|
|
|
|
|
0
|
my $ok = 0 ;
|
1197
|
0
|
|
|
|
|
0
|
foreach my $fnum ($href->{'frame'}..$href->{'frame_end'})
|
1198
|
|
|
|
|
|
|
{
|
1199
|
0
|
0
|
|
|
|
0
|
if (exists($fuzzy_frames{$fnum}))
|
1200
|
|
|
|
|
|
|
{
|
1201
|
0
|
|
|
|
|
0
|
$ok=1 ;
|
1202
|
|
|
|
|
|
|
}
|
1203
|
|
|
|
|
|
|
}
|
1204
|
0
|
0
|
|
|
|
0
|
if ($ok)
|
1205
|
|
|
|
|
|
|
{
|
1206
|
0
|
|
|
|
|
0
|
push @frames, $href ;
|
1207
|
|
|
|
|
|
|
}
|
1208
|
|
|
|
|
|
|
}
|
1209
|
|
|
|
|
|
|
|
1210
|
0
|
|
|
|
|
0
|
update_gap(\@frames) ;
|
1211
|
|
|
|
|
|
|
|
1212
|
|
|
|
|
|
|
return @frames
|
1213
|
0
|
|
|
|
|
0
|
}
|
1214
|
|
|
|
|
|
|
|
1215
|
|
|
|
|
|
|
#---------------------------------------------------------------------------------
|
1216
|
|
|
|
|
|
|
# Add frames list - return a list of frame HASH refs
|
1217
|
|
|
|
|
|
|
sub frames_add
|
1218
|
|
|
|
|
|
|
{
|
1219
|
0
|
|
|
0
|
0
|
0
|
my ($src_frames_aref, $add_frames_aref, $fuzziness) = @_ ;
|
1220
|
|
|
|
|
|
|
|
1221
|
|
|
|
|
|
|
## add
|
1222
|
0
|
|
|
|
|
0
|
my @frames = frames_add_array($src_frames_aref, $add_frames_aref, $fuzziness) ;
|
1223
|
|
|
|
|
|
|
|
1224
|
|
|
|
|
|
|
## convert to list of frame hashs
|
1225
|
0
|
|
|
|
|
0
|
@frames = frames_array_to_hashlist(\@frames) ;
|
1226
|
|
|
|
|
|
|
|
1227
|
|
|
|
|
|
|
return @frames
|
1228
|
0
|
|
|
|
|
0
|
}
|
1229
|
|
|
|
|
|
|
|
1230
|
|
|
|
|
|
|
#---------------------------------------------------------------------------------
|
1231
|
|
|
|
|
|
|
# Reduce the program length of the specified frame HASH entry to the nearest gap start
|
1232
|
|
|
|
|
|
|
# in the given list
|
1233
|
|
|
|
|
|
|
#
|
1234
|
|
|
|
|
|
|
# HASH entry:
|
1235
|
|
|
|
|
|
|
#
|
1236
|
|
|
|
|
|
|
# numframes=n
|
1237
|
|
|
|
|
|
|
# |----------------------------------------------->|
|
1238
|
|
|
|
|
|
|
# |
|
1239
|
|
|
|
|
|
|
# _...............................................
|
1240
|
|
|
|
|
|
|
# | | :
|
1241
|
|
|
|
|
|
|
# ___________| |______________________________________________:____
|
1242
|
|
|
|
|
|
|
# ^ ^
|
1243
|
|
|
|
|
|
|
# frame=f frame_end
|
1244
|
|
|
|
|
|
|
# |<----------window--------------------:
|
1245
|
|
|
|
|
|
|
#
|
1246
|
|
|
|
|
|
|
# Closest entry in list:
|
1247
|
|
|
|
|
|
|
#
|
1248
|
|
|
|
|
|
|
# |<---min_gap--------->|
|
1249
|
|
|
|
|
|
|
#
|
1250
|
|
|
|
|
|
|
# | |
|
1251
|
|
|
|
|
|
|
# |<--------------------|
|
1252
|
|
|
|
|
|
|
# gap _...........
|
1253
|
|
|
|
|
|
|
# : | | :
|
1254
|
|
|
|
|
|
|
# _________________________:_____________________| |__________:____
|
1255
|
|
|
|
|
|
|
# ^ ^
|
1256
|
|
|
|
|
|
|
# frame=f frame_end
|
1257
|
|
|
|
|
|
|
#
|
1258
|
|
|
|
|
|
|
#
|
1259
|
|
|
|
|
|
|
# HASH entry after reduction:
|
1260
|
|
|
|
|
|
|
#
|
1261
|
|
|
|
|
|
|
# numframes
|
1262
|
|
|
|
|
|
|
# |------------>|
|
1263
|
|
|
|
|
|
|
# |
|
1264
|
|
|
|
|
|
|
# _............
|
1265
|
|
|
|
|
|
|
# | | :
|
1266
|
|
|
|
|
|
|
# ___________| |___________:_______________________________________
|
1267
|
|
|
|
|
|
|
# ^ ^
|
1268
|
|
|
|
|
|
|
# frame=f frame_end
|
1269
|
|
|
|
|
|
|
#
|
1270
|
|
|
|
|
|
|
#
|
1271
|
|
|
|
|
|
|
sub frames_reduce_end
|
1272
|
|
|
|
|
|
|
{
|
1273
|
0
|
|
|
0
|
0
|
0
|
my ($frame_href, $frames_aref, $window, $min_gap) = @_ ;
|
1274
|
|
|
|
|
|
|
|
1275
|
0
|
|
|
|
|
0
|
my $gap_href ;
|
1276
|
|
|
|
|
|
|
|
1277
|
0
|
0
|
|
|
|
0
|
if ($DEBUG) {print "frames_reduce_end(win=$window, gap=$min_gap) -START : "; dump_frame($frame_href) ;}
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
1278
|
|
|
|
|
|
|
|
1279
|
|
|
|
|
|
|
## Find any gaps that are within the specified window AND gap >= min_gap
|
1280
|
|
|
|
|
|
|
## (If window=0, allow any gaps)
|
1281
|
|
|
|
|
|
|
## $gap_href will be set to the PREVIOUS entry so that the 'frame_end' and 'end_pkt'
|
1282
|
|
|
|
|
|
|
## values can be used
|
1283
|
|
|
|
|
|
|
##
|
1284
|
0
|
|
|
|
|
0
|
my $min_framenum = $frame_href->{'frame_end'} - $window ;
|
1285
|
0
|
|
|
|
|
0
|
my $max_framenum = $frame_href->{'frame_end'} ;
|
1286
|
0
|
0
|
|
|
|
0
|
$min_framenum = 0 if !$window ;
|
1287
|
0
|
|
|
|
|
0
|
my $prev_href = {'frame_end'=>0, 'end_pkt'=>0} ;
|
1288
|
0
|
|
|
|
|
0
|
foreach my $this_href (@$frames_aref)
|
1289
|
|
|
|
|
|
|
{
|
1290
|
0
|
0
|
|
|
|
0
|
if ($DEBUG) {print " + evaluating gap : "; dump_frame($this_href) ;}
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
1291
|
|
|
|
|
|
|
|
1292
|
|
|
|
|
|
|
## Stop at first valid match
|
1293
|
0
|
0
|
0
|
|
|
0
|
if (($this_href->{'frame'} >= $min_framenum) && ($this_href->{'frame'} >= $min_framenum) && ($this_href->{'gap'} >= $min_gap))
|
|
|
|
0
|
|
|
|
|
1294
|
|
|
|
|
|
|
{
|
1295
|
0
|
|
|
|
|
0
|
$gap_href = $prev_href ;
|
1296
|
0
|
0
|
|
|
|
0
|
if ($DEBUG) {print " + + found gap : using "; dump_frame($gap_href) ;}
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
1297
|
0
|
|
|
|
|
0
|
last ;
|
1298
|
|
|
|
|
|
|
}
|
1299
|
0
|
|
|
|
|
0
|
$prev_href = $this_href ;
|
1300
|
|
|
|
|
|
|
}
|
1301
|
|
|
|
|
|
|
|
1302
|
|
|
|
|
|
|
|
1303
|
|
|
|
|
|
|
## Reduce end point to beginning of gap
|
1304
|
0
|
0
|
|
|
|
0
|
if ($gap_href)
|
1305
|
|
|
|
|
|
|
{
|
1306
|
0
|
|
|
|
|
0
|
$frame_href->{'frame_end'} = $gap_href->{'frame_end'} ;
|
1307
|
0
|
|
|
|
|
0
|
$frame_href->{'end_pkt'} = $gap_href->{'end_pkt'} ;
|
1308
|
|
|
|
|
|
|
|
1309
|
0
|
0
|
|
|
|
0
|
if ($DEBUG) {print " ++ Reduced "; dump_frame($frame_href) ;}
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
1310
|
|
|
|
|
|
|
}
|
1311
|
|
|
|
|
|
|
|
1312
|
0
|
0
|
|
|
|
0
|
if ($DEBUG) {print "frames_reduce_end(win=$window, gap=$min_gap) -END : "; dump_frame($frame_href) ;}
|
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
1313
|
|
|
|
|
|
|
|
1314
|
0
|
|
|
|
|
0
|
return $frame_href
|
1315
|
|
|
|
|
|
|
}
|
1316
|
|
|
|
|
|
|
|
1317
|
|
|
|
|
|
|
#---------------------------------------------------------------------------------
|
1318
|
|
|
|
|
|
|
# !!!TBD!!!
|
1319
|
|
|
|
|
|
|
#
|
1320
|
|
|
|
|
|
|
# TODO: Work out what to do here!
|
1321
|
|
|
|
|
|
|
#
|
1322
|
|
|
|
|
|
|
# Reduce the program length of the specified frame HASH entry to the nearest gap start
|
1323
|
|
|
|
|
|
|
# in the given list
|
1324
|
|
|
|
|
|
|
#
|
1325
|
|
|
|
|
|
|
# HASH entry:
|
1326
|
|
|
|
|
|
|
#
|
1327
|
|
|
|
|
|
|
# numframes=n
|
1328
|
|
|
|
|
|
|
# |----------------------------------------------->|
|
1329
|
|
|
|
|
|
|
# |
|
1330
|
|
|
|
|
|
|
# _...............................................
|
1331
|
|
|
|
|
|
|
# | | :
|
1332
|
|
|
|
|
|
|
# ___________| |______________________________________________:____
|
1333
|
|
|
|
|
|
|
# ^ ^
|
1334
|
|
|
|
|
|
|
# frame=f frame_end
|
1335
|
|
|
|
|
|
|
# |<----------window--------------------:
|
1336
|
|
|
|
|
|
|
#
|
1337
|
|
|
|
|
|
|
# Closest entry in list:
|
1338
|
|
|
|
|
|
|
#
|
1339
|
|
|
|
|
|
|
# |<---min_gap--------->|
|
1340
|
|
|
|
|
|
|
#
|
1341
|
|
|
|
|
|
|
# | |
|
1342
|
|
|
|
|
|
|
# |<--------------------|
|
1343
|
|
|
|
|
|
|
# gap _...........
|
1344
|
|
|
|
|
|
|
# : | | :
|
1345
|
|
|
|
|
|
|
# _________________________:_____________________| |__________:____
|
1346
|
|
|
|
|
|
|
# ^ ^
|
1347
|
|
|
|
|
|
|
# frame=f frame_end
|
1348
|
|
|
|
|
|
|
#
|
1349
|
|
|
|
|
|
|
#
|
1350
|
|
|
|
|
|
|
# HASH entry after reduction:
|
1351
|
|
|
|
|
|
|
#
|
1352
|
|
|
|
|
|
|
# numframes
|
1353
|
|
|
|
|
|
|
# |------------>|
|
1354
|
|
|
|
|
|
|
# |
|
1355
|
|
|
|
|
|
|
# _............
|
1356
|
|
|
|
|
|
|
# | | :
|
1357
|
|
|
|
|
|
|
# ___________| |___________:_______________________________________
|
1358
|
|
|
|
|
|
|
# ^ ^
|
1359
|
|
|
|
|
|
|
# frame=f frame_end
|
1360
|
|
|
|
|
|
|
#
|
1361
|
|
|
|
|
|
|
#
|
1362
|
|
|
|
|
|
|
sub frames_increase_start
|
1363
|
|
|
|
|
|
|
{
|
1364
|
0
|
|
|
0
|
0
|
0
|
my ($frame_href, $frames_aref, $window, $min_gap) = @_ ;
|
1365
|
|
|
|
|
|
|
|
1366
|
|
|
|
|
|
|
# my $gap_href ;
|
1367
|
|
|
|
|
|
|
#
|
1368
|
|
|
|
|
|
|
#if ($DEBUG) {print "frames_reduce_end(win=$window, gap=$min_gap) -START : "; dump_frame($frame_href) ;}
|
1369
|
|
|
|
|
|
|
#
|
1370
|
|
|
|
|
|
|
# ## Find any gaps that are within the specified window AND gap >= min_gap
|
1371
|
|
|
|
|
|
|
# ## (If window=0, allow any gaps)
|
1372
|
|
|
|
|
|
|
# ## $gap_href will be set to the PREVIOUS entry so that the 'frame_end' and 'end_pkt'
|
1373
|
|
|
|
|
|
|
# ## values can be used
|
1374
|
|
|
|
|
|
|
# ##
|
1375
|
|
|
|
|
|
|
# my $min_framenum = $frame_href->{'frame_end'} - $window ;
|
1376
|
|
|
|
|
|
|
# my $max_framenum = $frame_href->{'frame_end'} ;
|
1377
|
|
|
|
|
|
|
# $min_framenum = 0 if !$window ;
|
1378
|
|
|
|
|
|
|
# my $prev_href = {'frame_end'=>0, 'end_pkt'=>0} ;
|
1379
|
|
|
|
|
|
|
# foreach my $this_href (@$frames_aref)
|
1380
|
|
|
|
|
|
|
# {
|
1381
|
|
|
|
|
|
|
#if ($DEBUG) {print " + evaluating gap : "; dump_frame($this_href) ;}
|
1382
|
|
|
|
|
|
|
#
|
1383
|
|
|
|
|
|
|
# ## Stop at first valid match
|
1384
|
|
|
|
|
|
|
# if (($this_href->{'frame'} >= $min_framenum) && ($this_href->{'frame'} >= $min_framenum) && ($this_href->{'gap'} >= $min_gap))
|
1385
|
|
|
|
|
|
|
# {
|
1386
|
|
|
|
|
|
|
# $gap_href = $prev_href ;
|
1387
|
|
|
|
|
|
|
#if ($DEBUG) {print " + + found gap : using "; dump_frame($gap_href) ;}
|
1388
|
|
|
|
|
|
|
# last ;
|
1389
|
|
|
|
|
|
|
# }
|
1390
|
|
|
|
|
|
|
# $prev_href = $this_href ;
|
1391
|
|
|
|
|
|
|
# }
|
1392
|
|
|
|
|
|
|
#
|
1393
|
|
|
|
|
|
|
#
|
1394
|
|
|
|
|
|
|
# ## Reduce end point to beginning of gap
|
1395
|
|
|
|
|
|
|
# if ($gap_href)
|
1396
|
|
|
|
|
|
|
# {
|
1397
|
|
|
|
|
|
|
# $frame_href->{'frame_end'} = $gap_href->{'frame_end'} ;
|
1398
|
|
|
|
|
|
|
# $frame_href->{'end_pkt'} = $gap_href->{'end_pkt'} ;
|
1399
|
|
|
|
|
|
|
#
|
1400
|
|
|
|
|
|
|
#if ($DEBUG) {print " ++ Reduced "; dump_frame($frame_href) ;}
|
1401
|
|
|
|
|
|
|
# }
|
1402
|
|
|
|
|
|
|
#
|
1403
|
|
|
|
|
|
|
#if ($DEBUG) {print "frames_reduce_end(win=$window, gap=$min_gap) -END : "; dump_frame($frame_href) ;}
|
1404
|
|
|
|
|
|
|
|
1405
|
0
|
|
|
|
|
0
|
return $frame_href
|
1406
|
|
|
|
|
|
|
}
|
1407
|
|
|
|
|
|
|
|
1408
|
|
|
|
|
|
|
|
1409
|
|
|
|
|
|
|
|
1410
|
|
|
|
|
|
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
1411
|
|
|
|
|
|
|
# CSV
|
1412
|
|
|
|
|
|
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
1413
|
|
|
|
|
|
|
|
1414
|
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
1415
|
|
|
|
|
|
|
#
|
1416
|
|
|
|
|
|
|
sub new_csv_frames
|
1417
|
|
|
|
|
|
|
{
|
1418
|
3
|
|
|
3
|
0
|
24
|
my ($results_href) = @_ ;
|
1419
|
|
|
|
|
|
|
|
1420
|
|
|
|
|
|
|
#print STDERR "new_csv_frames()\n";
|
1421
|
|
|
|
|
|
|
|
1422
|
|
|
|
|
|
|
# Create
|
1423
|
3
|
|
|
|
|
6
|
my @list ;
|
1424
|
|
|
|
|
|
|
|
1425
|
3
|
|
|
|
|
7
|
my $thing = tied @{$results_href->{'frames'}} ;
|
|
3
|
|
|
|
|
9
|
|
1426
|
|
|
|
|
|
|
|
1427
|
3
|
|
|
|
|
95
|
tie @list, 'Linux::DVB::DVBT::Advert', 'ADV', [$thing] ;
|
1428
|
|
|
|
|
|
|
|
1429
|
3
|
|
|
|
|
12
|
return \@list ;
|
1430
|
|
|
|
|
|
|
}
|
1431
|
|
|
|
|
|
|
|
1432
|
|
|
|
|
|
|
|
1433
|
|
|
|
|
|
|
#---------------------------------------------------------------------------------
|
1434
|
|
|
|
|
|
|
sub csv_add_setting
|
1435
|
|
|
|
|
|
|
{
|
1436
|
0
|
|
|
0
|
0
|
|
my ($settings_aref, $key, $threshold) = @_ ;
|
1437
|
|
|
|
|
|
|
|
1438
|
0
|
|
|
|
|
|
push @{$settings_aref->[0]}, $key ;
|
|
0
|
|
|
|
|
|
|
1439
|
0
|
|
|
|
|
|
push @{$settings_aref->[1]}, $threshold ;
|
|
0
|
|
|
|
|
|
|
1440
|
|
|
|
|
|
|
}
|
1441
|
|
|
|
|
|
|
|
1442
|
|
|
|
|
|
|
#---------------------------------------------------------------------------------
|
1443
|
|
|
|
|
|
|
sub csv_add_prog
|
1444
|
|
|
|
|
|
|
{
|
1445
|
0
|
|
|
0
|
0
|
|
my ($results_href, $csv_frames_aref, $prog_field, $cutlist_aref) = @_ ;
|
1446
|
|
|
|
|
|
|
|
1447
|
0
|
0
|
|
|
|
|
print "csv_add_prog()\n" if $DEBUG;
|
1448
|
|
|
|
|
|
|
|
1449
|
0
|
|
|
|
|
|
my @cuts = @$cutlist_aref ;
|
1450
|
0
|
|
|
|
|
|
my $cut_href = shift @cuts ;
|
1451
|
|
|
|
|
|
|
|
1452
|
0
|
|
|
|
|
|
my $adv = tied @$csv_frames_aref ;
|
1453
|
0
|
|
|
|
|
|
$adv->add_key($prog_field) ;
|
1454
|
|
|
|
|
|
|
|
1455
|
0
|
|
|
|
|
|
for(my $i=0; $i < scalar(@$csv_frames_aref); ++$i)
|
1456
|
|
|
|
|
|
|
{
|
1457
|
|
|
|
|
|
|
#my $href = $csv_frames_aref->[$i] ;
|
1458
|
0
|
|
|
|
|
|
my $href = {} ;
|
1459
|
0
|
|
|
|
|
|
my $framenum = $csv_frames_aref->[$i]->{'frame'} ;
|
1460
|
|
|
|
|
|
|
|
1461
|
0
|
0
|
|
|
|
|
print " + frame $framenum : cut_href s=$cut_href->{'frame'} .. e=$cut_href->{'frame_end'}\n" if $DEBUG;
|
1462
|
|
|
|
|
|
|
|
1463
|
0
|
|
|
|
|
|
$href->{$prog_field} = 100 ;
|
1464
|
0
|
|
|
|
|
|
my $done = 0 ;
|
1465
|
0
|
|
0
|
|
|
|
while ($cut_href && !$done)
|
1466
|
|
|
|
|
|
|
{
|
1467
|
0
|
0
|
0
|
|
|
|
if ($framenum < $cut_href->{'frame'})
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
1468
|
|
|
|
|
|
|
{
|
1469
|
0
|
|
|
|
|
|
$href->{$prog_field} = 100 ;
|
1470
|
0
|
|
|
|
|
|
++$done ;
|
1471
|
|
|
|
|
|
|
}
|
1472
|
|
|
|
|
|
|
elsif ( ($framenum >= $cut_href->{'frame'}) && ($framenum <= $cut_href->{'frame_end'}))
|
1473
|
|
|
|
|
|
|
{
|
1474
|
0
|
|
|
|
|
|
$href->{$prog_field} = 0 ;
|
1475
|
0
|
|
|
|
|
|
++$done ;
|
1476
|
|
|
|
|
|
|
}
|
1477
|
|
|
|
|
|
|
elsif ( ($framenum > $cut_href->{'frame_end'}))
|
1478
|
|
|
|
|
|
|
{
|
1479
|
|
|
|
|
|
|
# get next in the list
|
1480
|
0
|
0
|
|
|
|
|
if (@cuts)
|
1481
|
|
|
|
|
|
|
{
|
1482
|
0
|
|
|
|
|
|
$cut_href = shift @cuts ;
|
1483
|
|
|
|
|
|
|
}
|
1484
|
|
|
|
|
|
|
else
|
1485
|
|
|
|
|
|
|
{
|
1486
|
0
|
|
|
|
|
|
$href->{$prog_field} = 100 ;
|
1487
|
0
|
|
|
|
|
|
++$done ;
|
1488
|
|
|
|
|
|
|
}
|
1489
|
|
|
|
|
|
|
}
|
1490
|
|
|
|
|
|
|
}
|
1491
|
|
|
|
|
|
|
|
1492
|
0
|
|
|
|
|
|
$csv_frames_aref->[$i] = $href ;
|
1493
|
|
|
|
|
|
|
}
|
1494
|
|
|
|
|
|
|
|
1495
|
0
|
0
|
|
|
|
|
print "csv_add_prog() - END\n" if $DEBUG;
|
1496
|
|
|
|
|
|
|
|
1497
|
|
|
|
|
|
|
}
|
1498
|
|
|
|
|
|
|
|
1499
|
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
1500
|
|
|
|
|
|
|
sub csv_add_frames
|
1501
|
|
|
|
|
|
|
{
|
1502
|
0
|
|
|
0
|
0
|
|
my ($csv_settings_aref, $frames_adata_aref, $csv_frames_aref, $new_frames_aref, $field, $threshold, $new_field) = @_ ;
|
1503
|
|
|
|
|
|
|
|
1504
|
|
|
|
|
|
|
#print STDERR "csv_add_frames()\n";
|
1505
|
|
|
|
|
|
|
|
1506
|
0
|
|
|
|
|
|
push @{$csv_settings_aref->[0]}, $field ;
|
|
0
|
|
|
|
|
|
|
1507
|
0
|
|
|
|
|
|
push @{$csv_settings_aref->[1]}, $threshold ;
|
|
0
|
|
|
|
|
|
|
1508
|
|
|
|
|
|
|
|
1509
|
|
|
|
|
|
|
# start by clearing
|
1510
|
0
|
|
|
|
|
|
my $adv = tied @$csv_frames_aref ;
|
1511
|
0
|
|
|
|
|
|
$adv->add_key($field) ;
|
1512
|
|
|
|
|
|
|
|
1513
|
|
|
|
|
|
|
# next add frames
|
1514
|
0
|
|
|
|
|
|
foreach my $buff_href (@$new_frames_aref)
|
1515
|
|
|
|
|
|
|
{
|
1516
|
0
|
|
|
|
|
|
my $fnum_start = $buff_href->{'frame'} ;
|
1517
|
0
|
|
0
|
|
|
|
my $fnum_end = $buff_href->{'frame_end'} || $fnum_start ;
|
1518
|
|
|
|
|
|
|
|
1519
|
0
|
0
|
0
|
|
|
|
if ( defined($fnum_end) && ($fnum_end > $fnum_start))
|
1520
|
|
|
|
|
|
|
{
|
1521
|
0
|
|
|
|
|
|
foreach my $fnum ($fnum_start..$fnum_end)
|
1522
|
|
|
|
|
|
|
{
|
1523
|
0
|
|
|
|
|
|
$csv_frames_aref->[$fnum] = { $field => $buff_href->{$new_field} };
|
1524
|
|
|
|
|
|
|
}
|
1525
|
|
|
|
|
|
|
}
|
1526
|
|
|
|
|
|
|
else
|
1527
|
|
|
|
|
|
|
{
|
1528
|
0
|
|
|
|
|
|
$csv_frames_aref->[$fnum_start] = { $field => $buff_href->{$new_field} };
|
1529
|
|
|
|
|
|
|
}
|
1530
|
|
|
|
|
|
|
}
|
1531
|
|
|
|
|
|
|
|
1532
|
|
|
|
|
|
|
#print STDERR "csv_add_frames() - END\n";
|
1533
|
|
|
|
|
|
|
|
1534
|
|
|
|
|
|
|
}
|
1535
|
|
|
|
|
|
|
|
1536
|
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
1537
|
|
|
|
|
|
|
# Write CSV
|
1538
|
|
|
|
|
|
|
sub write_csv
|
1539
|
|
|
|
|
|
|
{
|
1540
|
0
|
|
|
0
|
0
|
|
my ($fname, $results_href, $csv_frames_aref, $headings_aref, $levels_aref) = @_;
|
1541
|
|
|
|
|
|
|
|
1542
|
0
|
0
|
|
|
|
|
print "Writing CSV $fname ... \n" if $DEBUG ;
|
1543
|
|
|
|
|
|
|
|
1544
|
0
|
0
|
|
|
|
|
open my $fh, ">$fname" or die "Unable to write CSV $fname : $!" ;
|
1545
|
0
|
|
|
|
|
|
print $fh "$headings_aref->[0]" ;
|
1546
|
0
|
|
|
|
|
|
for (my $i=1; $i < scalar(@$headings_aref); ++$i)
|
1547
|
|
|
|
|
|
|
{
|
1548
|
0
|
|
|
|
|
|
print $fh ",$headings_aref->[$i] [$levels_aref->[$i]]" ;
|
1549
|
|
|
|
|
|
|
}
|
1550
|
0
|
|
|
|
|
|
print $fh "\n" ;
|
1551
|
|
|
|
|
|
|
|
1552
|
0
|
|
|
|
|
|
my $frames_adata_aref = $results_href->{'frames'} ;
|
1553
|
0
|
|
|
|
|
|
foreach my $frame_href (@$frames_adata_aref)
|
1554
|
|
|
|
|
|
|
{
|
1555
|
0
|
|
|
|
|
|
my $frame = $frame_href->{'frame'} ;
|
1556
|
0
|
|
|
|
|
|
my $href = $csv_frames_aref->[$frame] ;
|
1557
|
|
|
|
|
|
|
|
1558
|
0
|
|
|
|
|
|
my $head = $headings_aref->[0] ;
|
1559
|
0
|
|
|
|
|
|
print $fh "$href->{$head}" ;
|
1560
|
0
|
|
|
|
|
|
for (my $i=1; $i < scalar(@$headings_aref); ++$i)
|
1561
|
|
|
|
|
|
|
{
|
1562
|
0
|
|
|
|
|
|
$head = $headings_aref->[$i] ;
|
1563
|
0
|
0
|
|
|
|
|
my $val = exists($href->{$head}) ? $href->{$head} : $frame_href->{$head} ;
|
1564
|
0
|
|
|
|
|
|
print $fh ",$val" ;
|
1565
|
|
|
|
|
|
|
}
|
1566
|
0
|
|
|
|
|
|
print $fh "\n" ;
|
1567
|
|
|
|
|
|
|
}
|
1568
|
|
|
|
|
|
|
|
1569
|
0
|
|
|
|
|
|
close $fh ;
|
1570
|
|
|
|
|
|
|
}
|
1571
|
|
|
|
|
|
|
|
1572
|
|
|
|
|
|
|
|
1573
|
|
|
|
|
|
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
1574
|
|
|
|
|
|
|
# FRAME HASH
|
1575
|
|
|
|
|
|
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
1576
|
|
|
|
|
|
|
|
1577
|
|
|
|
|
|
|
# Each frame HASH entry, along with specific information, stores the relationship with it's
|
1578
|
|
|
|
|
|
|
# previous entry
|
1579
|
|
|
|
|
|
|
#
|
1580
|
|
|
|
|
|
|
# numframes=n
|
1581
|
|
|
|
|
|
|
# | |----------->|
|
1582
|
|
|
|
|
|
|
# |<--------------------|
|
1583
|
|
|
|
|
|
|
# _............ gap _...........
|
1584
|
|
|
|
|
|
|
# | | : | | :
|
1585
|
|
|
|
|
|
|
# ___________| |___________:_____________________| |__________:____
|
1586
|
|
|
|
|
|
|
# ^ ^
|
1587
|
|
|
|
|
|
|
# frame=f frame_end
|
1588
|
|
|
|
|
|
|
#
|
1589
|
|
|
|
|
|
|
#
|
1590
|
|
|
|
|
|
|
|
1591
|
|
|
|
|
|
|
|
1592
|
|
|
|
|
|
|
|
1593
|
|
|
|
|
|
|
|
1594
|
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
1595
|
|
|
|
|
|
|
# Set the gap counts - the distance each frame is from it's previous frame
|
1596
|
|
|
|
|
|
|
#
|
1597
|
|
|
|
|
|
|
# numframes=n' numframes=n
|
1598
|
|
|
|
|
|
|
# |------------>| |----------->|
|
1599
|
|
|
|
|
|
|
# |<--------------------|
|
1600
|
|
|
|
|
|
|
# _............ gap _...........
|
1601
|
|
|
|
|
|
|
# | | : | | :
|
1602
|
|
|
|
|
|
|
# ___________| |___________:_____________________| |__________:____
|
1603
|
|
|
|
|
|
|
# ^ ^ ^
|
1604
|
|
|
|
|
|
|
# frame=f' frame_end=e' frame=f
|
1605
|
|
|
|
|
|
|
#
|
1606
|
|
|
|
|
|
|
#
|
1607
|
|
|
|
|
|
|
# | f' ..... e' | e'+1 ......... f-1 |
|
1608
|
|
|
|
|
|
|
# |------------>|
|
1609
|
|
|
|
|
|
|
# n'=e'-f'+1 |
|
1610
|
|
|
|
|
|
|
# |<--------------------|
|
1611
|
|
|
|
|
|
|
# gap = (f-1) - (e'+1) + 1
|
1612
|
|
|
|
|
|
|
#
|
1613
|
|
|
|
|
|
|
#
|
1614
|
|
|
|
|
|
|
#
|
1615
|
|
|
|
|
|
|
# For frame f:
|
1616
|
|
|
|
|
|
|
#
|
1617
|
|
|
|
|
|
|
# gap = f - e' - 1
|
1618
|
|
|
|
|
|
|
#
|
1619
|
|
|
|
|
|
|
sub calc_gap
|
1620
|
|
|
|
|
|
|
{
|
1621
|
0
|
|
|
0
|
0
|
|
my ($frame, $prev_frame_end) = @_ ;
|
1622
|
|
|
|
|
|
|
|
1623
|
0
|
|
|
|
|
|
return $frame - $prev_frame_end - 1 ;
|
1624
|
|
|
|
|
|
|
}
|
1625
|
|
|
|
|
|
|
|
1626
|
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
1627
|
|
|
|
|
|
|
#
|
1628
|
|
|
|
|
|
|
sub update_gap
|
1629
|
|
|
|
|
|
|
{
|
1630
|
0
|
|
|
0
|
0
|
|
my ($frames_aref) = @_ ;
|
1631
|
|
|
|
|
|
|
|
1632
|
0
|
|
|
|
|
|
my $prev_frame_end = -1 ;
|
1633
|
0
|
|
|
|
|
|
foreach my $href (@$frames_aref)
|
1634
|
|
|
|
|
|
|
{
|
1635
|
0
|
|
|
|
|
|
my $frame = $href->{'frame'} ;
|
1636
|
0
|
|
|
|
|
|
$href->{'gap'} = calc_gap($frame, $prev_frame_end) ;
|
1637
|
|
|
|
|
|
|
|
1638
|
0
|
|
|
|
|
|
$prev_frame_end = $href->{'frame_end'} ;
|
1639
|
|
|
|
|
|
|
}
|
1640
|
|
|
|
|
|
|
}
|
1641
|
|
|
|
|
|
|
|
1642
|
|
|
|
|
|
|
|
1643
|
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
1644
|
|
|
|
|
|
|
# Return the number of frames for this frame entry
|
1645
|
|
|
|
|
|
|
#
|
1646
|
|
|
|
|
|
|
# numframes=n' numframes=n
|
1647
|
|
|
|
|
|
|
# |------------>| |----------->|
|
1648
|
|
|
|
|
|
|
# _............ _...........
|
1649
|
|
|
|
|
|
|
# | | : | | :
|
1650
|
|
|
|
|
|
|
# ___________| |___________:_____________________| |__________:____
|
1651
|
|
|
|
|
|
|
# frame=f' frame_end=e' frame=f frame_end=e
|
1652
|
|
|
|
|
|
|
#
|
1653
|
|
|
|
|
|
|
# For frame f:
|
1654
|
|
|
|
|
|
|
#
|
1655
|
|
|
|
|
|
|
# numframes: n = e - f + 1
|
1656
|
|
|
|
|
|
|
#
|
1657
|
|
|
|
|
|
|
|
1658
|
|
|
|
|
|
|
sub numframes
|
1659
|
|
|
|
|
|
|
{
|
1660
|
0
|
|
|
0
|
0
|
|
my ($frame_href) = @_ ;
|
1661
|
|
|
|
|
|
|
|
1662
|
0
|
|
|
|
|
|
return $frame_href->{frame_end} - $frame_href->{frame} + 1 ;
|
1663
|
|
|
|
|
|
|
}
|
1664
|
|
|
|
|
|
|
|
1665
|
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
1666
|
|
|
|
|
|
|
# Set the type based on section length
|
1667
|
|
|
|
|
|
|
sub _prog_type
|
1668
|
|
|
|
|
|
|
{
|
1669
|
0
|
|
|
0
|
|
|
my ($duration, $settings_href) = @_;
|
1670
|
|
|
|
|
|
|
|
1671
|
|
|
|
|
|
|
# could be either
|
1672
|
0
|
|
|
|
|
|
my $type = "advert/prog" ;
|
1673
|
0
|
0
|
|
|
|
|
if ($duration <= $settings_href->{'max_advert'})
|
|
|
0
|
|
|
|
|
|
1674
|
|
|
|
|
|
|
{
|
1675
|
0
|
|
|
|
|
|
$type = "advert" ;
|
1676
|
0
|
0
|
|
|
|
|
print "_prog_type=$type : $duration <= $settings_href->{'max_advert'}\n" if $DEBUG >= 2 ;
|
1677
|
|
|
|
|
|
|
}
|
1678
|
|
|
|
|
|
|
elsif ($duration >= $settings_href->{'min_program'})
|
1679
|
|
|
|
|
|
|
{
|
1680
|
0
|
|
|
|
|
|
$type = "program" ;
|
1681
|
0
|
0
|
|
|
|
|
print "_prog_type=$type : $duration >= $settings_href->{'min_program'}\n" if $DEBUG >= 2 ;
|
1682
|
|
|
|
|
|
|
}
|
1683
|
0
|
|
|
|
|
|
return $type ;
|
1684
|
|
|
|
|
|
|
}
|
1685
|
|
|
|
|
|
|
|
1686
|
|
|
|
|
|
|
#---------------------------------------------------------------------------------
|
1687
|
|
|
|
|
|
|
# Ensure each cut is of a valid length
|
1688
|
|
|
|
|
|
|
sub validate_cutlist
|
1689
|
|
|
|
|
|
|
{
|
1690
|
0
|
|
|
0
|
0
|
|
my ($cutlist_aref, $settings_href) = @_ ;
|
1691
|
|
|
|
|
|
|
|
1692
|
0
|
0
|
|
|
|
|
print "validate_cutlist:\n" if $DEBUG ;
|
1693
|
|
|
|
|
|
|
|
1694
|
|
|
|
|
|
|
## Throw away rubbish (e.g. at start of video when there is actually nothing to cut)
|
1695
|
0
|
|
|
|
|
|
my $prev_end = 0 ;
|
1696
|
0
|
|
|
|
|
|
my @list ;
|
1697
|
0
|
|
|
|
|
|
my $num_entries = scalar(@$cutlist_aref) ;
|
1698
|
0
|
|
|
|
|
|
for (my $i=0; $i < $num_entries; ++$i)
|
1699
|
|
|
|
|
|
|
{
|
1700
|
0
|
|
|
|
|
|
my $cut_href = shift @$cutlist_aref ;
|
1701
|
0
|
|
|
|
|
|
my $period = ($cut_href->{'frame_end'}-$cut_href->{'frame'}+1) ;
|
1702
|
0
|
0
|
|
|
|
|
if ($period > 0)
|
1703
|
|
|
|
|
|
|
{
|
1704
|
|
|
|
|
|
|
|
1705
|
|
|
|
|
|
|
# see if gap (i.e. program) long enough
|
1706
|
0
|
|
|
|
|
|
my $ok=1 ;
|
1707
|
0
|
|
|
|
|
|
my $prog_period =($cut_href->{'frame'}-$prev_end+1) ;
|
1708
|
0
|
0
|
|
|
|
|
if ($DEBUG) { print " + checking (prog=$prog_period min=$settings_href->{'min_program'}) : "; dump_frame($cut_href) ; }
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
1709
|
0
|
0
|
|
|
|
|
if ($prog_period < $settings_href->{'min_program'})
|
1710
|
|
|
|
|
|
|
{
|
1711
|
0
|
0
|
|
|
|
|
print " !! Program period too small (prog=$prog_period min=$settings_href->{'min_program'})" if $DEBUG ;
|
1712
|
0
|
0
|
|
|
|
|
if (scalar(@list))
|
1713
|
|
|
|
|
|
|
{
|
1714
|
0
|
0
|
|
|
|
|
if ($DEBUG) { print " , appending new to end of previous" ; dump_frame($list[-1]) ; }
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
1715
|
0
|
|
|
|
|
|
$ok=0 ;
|
1716
|
0
|
|
|
|
|
|
$list[-1]{'frame_end'} = $cut_href->{'frame_end'} ;
|
1717
|
0
|
|
|
|
|
|
$list[-1]{'end_pkt'} = $cut_href->{'end_pkt'} ;
|
1718
|
|
|
|
|
|
|
}
|
1719
|
|
|
|
|
|
|
else
|
1720
|
|
|
|
|
|
|
{
|
1721
|
0
|
0
|
|
|
|
|
print ", setting start to 0\n" if $DEBUG ;
|
1722
|
|
|
|
|
|
|
# start of list, amend first frame
|
1723
|
0
|
|
|
|
|
|
$cut_href = { %$cut_href } ;
|
1724
|
0
|
|
|
|
|
|
$cut_href->{'frame'} = 0 ;
|
1725
|
0
|
|
|
|
|
|
$cut_href->{'start_pkt'} = 0 ;
|
1726
|
0
|
|
|
|
|
|
$cut_href->{'gap'} = 0 ;
|
1727
|
|
|
|
|
|
|
}
|
1728
|
|
|
|
|
|
|
}
|
1729
|
|
|
|
|
|
|
|
1730
|
0
|
0
|
|
|
|
|
if ($ok)
|
1731
|
|
|
|
|
|
|
{
|
1732
|
0
|
0
|
|
|
|
|
if ($DEBUG) { print " + + saved : " ; dump_frame($cut_href) ; }
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
1733
|
0
|
|
|
|
|
|
push @list, $cut_href ;
|
1734
|
0
|
|
|
|
|
|
$prev_end = $cut_href->{'frame_end'} ;
|
1735
|
|
|
|
|
|
|
}
|
1736
|
|
|
|
|
|
|
}
|
1737
|
|
|
|
|
|
|
}
|
1738
|
|
|
|
|
|
|
|
1739
|
|
|
|
|
|
|
## Build new list
|
1740
|
0
|
|
|
|
|
|
$prev_end = 0 ;
|
1741
|
0
|
|
|
|
|
|
$num_entries = scalar(@list) ;
|
1742
|
0
|
|
|
|
|
|
for (my $i=0; $i < $num_entries; ++$i)
|
1743
|
|
|
|
|
|
|
{
|
1744
|
0
|
|
|
|
|
|
my $cut_href = $list[$i] ;
|
1745
|
|
|
|
|
|
|
|
1746
|
0
|
0
|
|
|
|
|
if (defined($prev_end))
|
1747
|
|
|
|
|
|
|
{
|
1748
|
0
|
|
|
|
|
|
my $prog_period = ($cut_href->{'frame'}-$prev_end+1) ;
|
1749
|
0
|
0
|
|
|
|
|
printf("(PROG $prev_end .. $cut_href->{'frame'} period=$prog_period (min=$settings_href->{'min_program'})") if $DEBUG ;
|
1750
|
0
|
0
|
|
|
|
|
if ($prog_period >= $settings_href->{'min_program'})
|
1751
|
|
|
|
|
|
|
{
|
1752
|
0
|
0
|
|
|
|
|
print " - OK" if $DEBUG ;
|
1753
|
|
|
|
|
|
|
}
|
1754
|
0
|
0
|
|
|
|
|
print " )\n" if $DEBUG ;
|
1755
|
|
|
|
|
|
|
|
1756
|
|
|
|
|
|
|
}
|
1757
|
|
|
|
|
|
|
|
1758
|
|
|
|
|
|
|
# don't check start/end
|
1759
|
0
|
|
|
|
|
|
my $period = ($cut_href->{'frame_end'}-$cut_href->{'frame'}+1) ;
|
1760
|
|
|
|
|
|
|
|
1761
|
0
|
0
|
|
|
|
|
printf("%2d: $cut_href->{'frame'}..$cut_href->{'frame_end'} period=$period (min=$settings_href->{'min_advert'})", $i) if $DEBUG ;
|
1762
|
0
|
0
|
0
|
|
|
|
if ( ($i==0) || ($period >= $settings_href->{'min_advert'}) || ($i==$num_entries-1) )
|
|
|
|
0
|
|
|
|
|
1763
|
|
|
|
|
|
|
{
|
1764
|
0
|
|
|
|
|
|
push @$cutlist_aref, $cut_href ;
|
1765
|
0
|
0
|
|
|
|
|
print " - OK" if $DEBUG ;
|
1766
|
|
|
|
|
|
|
}
|
1767
|
0
|
0
|
|
|
|
|
print "\n" if $DEBUG ;
|
1768
|
|
|
|
|
|
|
|
1769
|
0
|
|
|
|
|
|
$prev_end = $cut_href->{'frame_end'} ;
|
1770
|
|
|
|
|
|
|
}
|
1771
|
|
|
|
|
|
|
}
|
1772
|
|
|
|
|
|
|
|
1773
|
|
|
|
|
|
|
|
1774
|
|
|
|
|
|
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
1775
|
|
|
|
|
|
|
# ANALYSIS UTILS
|
1776
|
|
|
|
|
|
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
1777
|
|
|
|
|
|
|
|
1778
|
|
|
|
|
|
|
#---------------------------------------------------------------------------------
|
1779
|
|
|
|
|
|
|
#
|
1780
|
|
|
|
|
|
|
sub coalesce_frames
|
1781
|
|
|
|
|
|
|
{
|
1782
|
0
|
|
|
0
|
0
|
|
my ($frames_aref, $settings_href, $start_framenum, $title) = @_ ;
|
1783
|
|
|
|
|
|
|
|
1784
|
0
|
|
0
|
|
|
|
$title ||= "" ;
|
1785
|
0
|
0
|
|
|
|
|
print "coalesce_frames($title)\n" if $DEBUG ;
|
1786
|
|
|
|
|
|
|
|
1787
|
0
|
|
0
|
|
|
|
$start_framenum ||= 0 ;
|
1788
|
|
|
|
|
|
|
|
1789
|
0
|
|
|
|
|
|
my @frames ;
|
1790
|
|
|
|
|
|
|
my $curr_href ;
|
1791
|
0
|
|
|
|
|
|
for (my $idx=0; $idx < scalar(@$frames_aref); $idx++)
|
1792
|
|
|
|
|
|
|
{
|
1793
|
0
|
0
|
|
|
|
|
if ($DEBUG >= 2) { print " -> frame "; dump_frame($frames_aref->[$idx]) ; }
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
1794
|
|
|
|
|
|
|
|
1795
|
|
|
|
|
|
|
# start of new "block"
|
1796
|
0
|
0
|
|
|
|
|
if ($frames_aref->[$idx]{'gap'} > $settings_href->{'frame_window'})
|
1797
|
|
|
|
|
|
|
{
|
1798
|
0
|
0
|
|
|
|
|
if ($DEBUG) { print "new block : "; dump_frame($curr_href) ; }
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
1799
|
|
|
|
|
|
|
|
1800
|
|
|
|
|
|
|
## check existing
|
1801
|
|
|
|
|
|
|
|
1802
|
|
|
|
|
|
|
# curr idx
|
1803
|
|
|
|
|
|
|
# |||| ||| |
|
1804
|
|
|
|
|
|
|
# curr
|
1805
|
|
|
|
|
|
|
# <----gap idx
|
1806
|
|
|
|
|
|
|
# <---gap
|
1807
|
|
|
|
|
|
|
#
|
1808
|
|
|
|
|
|
|
# Can now check to see if previous block (the "current" HASH) is a spurious block
|
1809
|
|
|
|
|
|
|
#
|
1810
|
0
|
0
|
0
|
|
|
|
if ($curr_href &&
|
1811
|
|
|
|
|
|
|
(numframes($curr_href) < $settings_href->{'min_frames'})
|
1812
|
|
|
|
|
|
|
)
|
1813
|
|
|
|
|
|
|
{
|
1814
|
0
|
0
|
|
|
|
|
if ($DEBUG) { print " - (curr gap = $frames_aref->[$idx]{'gap'}, curr numframes = $curr_href->{'numframes'}) removed spurious : "; dump_frame($curr_href) ; }
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
1815
|
|
|
|
|
|
|
|
1816
|
|
|
|
|
|
|
# remove spurious
|
1817
|
0
|
|
|
|
|
|
pop @frames ;
|
1818
|
|
|
|
|
|
|
}
|
1819
|
|
|
|
|
|
|
|
1820
|
|
|
|
|
|
|
# start new
|
1821
|
|
|
|
|
|
|
$curr_href = {
|
1822
|
0
|
|
|
|
|
|
'frame_start' => $frames_aref->[$idx]{'frame'},
|
1823
|
|
|
|
|
|
|
'frame_end' => $frames_aref->[$idx]{'frame'},
|
1824
|
0
|
|
|
|
|
|
%{$frames_aref->[$idx]},
|
1825
|
|
|
|
|
|
|
} ;
|
1826
|
0
|
|
|
|
|
|
push @frames, $curr_href ;
|
1827
|
|
|
|
|
|
|
|
1828
|
0
|
|
|
|
|
|
my $prev_frame_end = $start_framenum ;
|
1829
|
0
|
0
|
|
|
|
|
if (scalar(@frames) >= 2)
|
1830
|
|
|
|
|
|
|
{
|
1831
|
0
|
|
|
|
|
|
$prev_frame_end = $frames[-2]{'frame_end'} ;
|
1832
|
0
|
0
|
|
|
|
|
if ($DEBUG) { print " - calc prev : "; dump_frame($frames[-2]) ; }
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
1833
|
|
|
|
|
|
|
}
|
1834
|
0
|
|
|
|
|
|
$curr_href->{'gap'} = calc_gap($curr_href->{'frame_start'}, $prev_frame_end ) ;
|
1835
|
|
|
|
|
|
|
}
|
1836
|
|
|
|
|
|
|
else
|
1837
|
|
|
|
|
|
|
{
|
1838
|
0
|
0
|
|
|
|
|
if (!$curr_href)
|
1839
|
|
|
|
|
|
|
{
|
1840
|
|
|
|
|
|
|
# start new
|
1841
|
0
|
|
|
|
|
|
$curr_href = {
|
1842
|
|
|
|
|
|
|
'frame_start' => $frames_aref->[$idx]{'frame'},
|
1843
|
|
|
|
|
|
|
'frame_end' => $frames_aref->[$idx]{'frame_end'},
|
1844
|
0
|
|
|
|
|
|
%{$frames_aref->[$idx]},
|
1845
|
|
|
|
|
|
|
} ;
|
1846
|
0
|
|
|
|
|
|
push @frames, $curr_href ;
|
1847
|
|
|
|
|
|
|
}
|
1848
|
|
|
|
|
|
|
else
|
1849
|
|
|
|
|
|
|
{
|
1850
|
|
|
|
|
|
|
# expand end time
|
1851
|
0
|
|
|
|
|
|
$curr_href->{'end_pkt'} = $frames_aref->[$idx]{'end_pkt'} ;
|
1852
|
0
|
|
|
|
|
|
$curr_href->{'frame_end'} = $frames_aref->[$idx]{'frame_end'} ;
|
1853
|
|
|
|
|
|
|
}
|
1854
|
|
|
|
|
|
|
}
|
1855
|
|
|
|
|
|
|
}
|
1856
|
|
|
|
|
|
|
|
1857
|
0
|
0
|
0
|
|
|
|
if ($curr_href && (numframes($curr_href) < $settings_href->{'min_frames'}))
|
1858
|
|
|
|
|
|
|
{
|
1859
|
0
|
0
|
|
|
|
|
if ($DEBUG) { print " - removed spurious : "; dump_frame($curr_href) ; }
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
1860
|
|
|
|
|
|
|
# remove spurious
|
1861
|
0
|
|
|
|
|
|
pop @frames ;
|
1862
|
|
|
|
|
|
|
}
|
1863
|
|
|
|
|
|
|
|
1864
|
0
|
0
|
|
|
|
|
print "coalesce_frames($title) - DONE\n" if $DEBUG ;
|
1865
|
|
|
|
|
|
|
|
1866
|
0
|
|
|
|
|
|
update_gap(\@frames) ;
|
1867
|
|
|
|
|
|
|
|
1868
|
0
|
|
|
|
|
|
return @frames ;
|
1869
|
|
|
|
|
|
|
}
|
1870
|
|
|
|
|
|
|
|
1871
|
|
|
|
|
|
|
#============================================================================================
|
1872
|
|
|
|
|
|
|
# DEBUG
|
1873
|
|
|
|
|
|
|
#============================================================================================
|
1874
|
|
|
|
|
|
|
|
1875
|
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
1876
|
|
|
|
|
|
|
# format fps into time
|
1877
|
|
|
|
|
|
|
sub fps_time
|
1878
|
|
|
|
|
|
|
{
|
1879
|
0
|
|
|
0
|
0
|
|
my ($fps_duration) = @_;
|
1880
|
0
|
|
|
|
|
|
my $str ;
|
1881
|
|
|
|
|
|
|
|
1882
|
0
|
|
|
|
|
|
my $fsecs = $fps_duration * 1.0 / $FPS ;
|
1883
|
0
|
|
|
|
|
|
my $secs = int($fps_duration / $FPS) ;
|
1884
|
0
|
|
|
|
|
|
my ($mins, $hours) ;
|
1885
|
|
|
|
|
|
|
|
1886
|
0
|
0
|
|
|
|
|
if ($secs > 60)
|
1887
|
|
|
|
|
|
|
{
|
1888
|
0
|
0
|
|
|
|
|
if ($secs > 60*60)
|
1889
|
|
|
|
|
|
|
{
|
1890
|
0
|
|
|
|
|
|
$hours = int($secs / (60*60)) ;
|
1891
|
0
|
|
|
|
|
|
$secs -= $hours * 60*60 ;
|
1892
|
|
|
|
|
|
|
}
|
1893
|
|
|
|
|
|
|
|
1894
|
0
|
|
|
|
|
|
$mins = int($secs / (60)) ;
|
1895
|
0
|
|
|
|
|
|
$secs -= $mins * 60 ;
|
1896
|
|
|
|
|
|
|
}
|
1897
|
|
|
|
|
|
|
|
1898
|
0
|
0
|
|
|
|
|
if ($hours)
|
1899
|
|
|
|
|
|
|
{
|
1900
|
0
|
|
|
|
|
|
$str .= sprintf "%d hours ", $hours ;
|
1901
|
|
|
|
|
|
|
}
|
1902
|
0
|
0
|
|
|
|
|
if ($mins)
|
1903
|
|
|
|
|
|
|
{
|
1904
|
0
|
|
|
|
|
|
$str .= sprintf "%d mins ", $mins ;
|
1905
|
|
|
|
|
|
|
}
|
1906
|
0
|
|
|
|
|
|
$str .= sprintf "%d secs", $secs ;
|
1907
|
|
|
|
|
|
|
|
1908
|
0
|
|
|
|
|
|
return $str ;
|
1909
|
|
|
|
|
|
|
}
|
1910
|
|
|
|
|
|
|
|
1911
|
|
|
|
|
|
|
|
1912
|
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
1913
|
|
|
|
|
|
|
# format fps into time
|
1914
|
|
|
|
|
|
|
sub fps_timestamp
|
1915
|
|
|
|
|
|
|
{
|
1916
|
0
|
|
|
0
|
0
|
|
my ($fps_duration) = @_;
|
1917
|
0
|
|
|
|
|
|
my $str ;
|
1918
|
|
|
|
|
|
|
|
1919
|
0
|
|
|
|
|
|
my $fsecs = $fps_duration * 1.0 / $FPS ;
|
1920
|
0
|
|
|
|
|
|
my $secs = int($fps_duration / $FPS) ;
|
1921
|
0
|
|
|
|
|
|
my ($mins, $hours, $msec) = (0, 0, 0);
|
1922
|
|
|
|
|
|
|
|
1923
|
0
|
|
|
|
|
|
$msec = int($fsecs*1000 - $secs*1000) ;
|
1924
|
|
|
|
|
|
|
|
1925
|
0
|
0
|
|
|
|
|
if ($secs > 60)
|
1926
|
|
|
|
|
|
|
{
|
1927
|
0
|
0
|
|
|
|
|
if ($secs > 60*60)
|
1928
|
|
|
|
|
|
|
{
|
1929
|
0
|
|
|
|
|
|
$hours = int($secs / (60*60)) ;
|
1930
|
0
|
|
|
|
|
|
$secs -= $hours * 60*60 ;
|
1931
|
|
|
|
|
|
|
}
|
1932
|
|
|
|
|
|
|
|
1933
|
0
|
|
|
|
|
|
$mins = int($secs / (60)) ;
|
1934
|
0
|
|
|
|
|
|
$secs -= $mins * 60 ;
|
1935
|
|
|
|
|
|
|
}
|
1936
|
|
|
|
|
|
|
|
1937
|
0
|
|
|
|
|
|
$str = sprintf "%0d:%02d:%02d.%03d", $hours, $mins, $secs, $msec ;
|
1938
|
|
|
|
|
|
|
|
1939
|
0
|
|
|
|
|
|
return $str ;
|
1940
|
|
|
|
|
|
|
}
|
1941
|
|
|
|
|
|
|
|
1942
|
|
|
|
|
|
|
#---------------------------------------------------------------------------------
|
1943
|
|
|
|
|
|
|
#
|
1944
|
|
|
|
|
|
|
sub dump_cutlist
|
1945
|
|
|
|
|
|
|
{
|
1946
|
0
|
|
|
0
|
0
|
|
my ($title, $cutlist_aref, $prefix) = @_ ;
|
1947
|
|
|
|
|
|
|
|
1948
|
0
|
|
|
|
|
|
print "\n\n# $title\n" ;
|
1949
|
0
|
|
|
|
|
|
foreach my $cut_href (@$cutlist_aref)
|
1950
|
|
|
|
|
|
|
{
|
1951
|
0
|
|
|
|
|
|
printf "${prefix}# frame=%d:%d %s\n", $cut_href->{'frame'}, $cut_href->{'frame_end'}, fps_time($cut_href->{'frame_end'}-$cut_href->{'frame'}+1) ;
|
1952
|
|
|
|
|
|
|
}
|
1953
|
0
|
|
|
|
|
|
foreach my $cut_href (@$cutlist_aref)
|
1954
|
|
|
|
|
|
|
{
|
1955
|
0
|
|
|
|
|
|
printf "${prefix}p=%d:%d\n", $cut_href->{'start_pkt'}, $cut_href->{'end_pkt'} ;
|
1956
|
|
|
|
|
|
|
}
|
1957
|
|
|
|
|
|
|
}
|
1958
|
|
|
|
|
|
|
|
1959
|
|
|
|
|
|
|
|
1960
|
|
|
|
|
|
|
|
1961
|
|
|
|
|
|
|
|
1962
|
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
1963
|
|
|
|
|
|
|
# Display this black frame entry
|
1964
|
|
|
|
|
|
|
sub dump_frame
|
1965
|
|
|
|
|
|
|
{
|
1966
|
0
|
|
|
0
|
0
|
|
my ($frame_href) = @_;
|
1967
|
|
|
|
|
|
|
|
1968
|
0
|
|
|
|
|
|
printf("frame=%d [%s] gap=%d (%s) numframes=%d : ",
|
1969
|
|
|
|
|
|
|
$frame_href->{'frame'},
|
1970
|
|
|
|
|
|
|
fps_timestamp($frame_href->{'frame'}),
|
1971
|
|
|
|
|
|
|
$frame_href->{'gap'},
|
1972
|
|
|
|
|
|
|
fps_time($frame_href->{'gap'}),
|
1973
|
|
|
|
|
|
|
numframes($frame_href),
|
1974
|
|
|
|
|
|
|
) ;
|
1975
|
0
|
0
|
|
|
|
|
if (exists($frame_href->{'match_percent'}))
|
1976
|
|
|
|
|
|
|
{
|
1977
|
0
|
|
|
|
|
|
printf "Qual=%d%% : ", $frame_href->{'match_percent'} ;
|
1978
|
|
|
|
|
|
|
}
|
1979
|
0
|
0
|
|
|
|
|
if (exists($frame_href->{'weight'}))
|
1980
|
|
|
|
|
|
|
{
|
1981
|
0
|
|
|
|
|
|
printf "Weight=%d%% : ", $frame_href->{'weight'} ;
|
1982
|
|
|
|
|
|
|
}
|
1983
|
0
|
0
|
|
|
|
|
if (exists($frame_href->{'ave_percent'}))
|
1984
|
|
|
|
|
|
|
{
|
1985
|
0
|
|
|
|
|
|
printf "Ave. Qual=%d%% : ", $frame_href->{'ave_percent'} ;
|
1986
|
|
|
|
|
|
|
}
|
1987
|
0
|
|
|
|
|
|
printf("%d .. %d",
|
1988
|
|
|
|
|
|
|
$frame_href->{'start_pkt'}, $frame_href->{'end_pkt'},
|
1989
|
|
|
|
|
|
|
) ;
|
1990
|
|
|
|
|
|
|
|
1991
|
0
|
0
|
|
|
|
|
if (exists($frame_href->{'type'}))
|
1992
|
|
|
|
|
|
|
{
|
1993
|
0
|
|
|
|
|
|
print " : Type=$frame_href->{'type'}" ;
|
1994
|
|
|
|
|
|
|
}
|
1995
|
|
|
|
|
|
|
|
1996
|
0
|
0
|
|
|
|
|
if (exists($frame_href->{'adverts'}))
|
1997
|
|
|
|
|
|
|
{
|
1998
|
0
|
|
|
|
|
|
print " : Ads=$frame_href->{'adverts'}" ;
|
1999
|
|
|
|
|
|
|
}
|
2000
|
0
|
0
|
|
|
|
|
if (exists($frame_href->{'frame_start'}))
|
2001
|
|
|
|
|
|
|
{
|
2002
|
0
|
|
|
|
|
|
print " : Frames $frame_href->{'frame_start'} .. $frame_href->{'frame_end'} duration (" .
|
2003
|
|
|
|
|
|
|
fps_time(numframes($frame_href))
|
2004
|
|
|
|
|
|
|
. ")" ;
|
2005
|
|
|
|
|
|
|
}
|
2006
|
0
|
|
|
|
|
|
print "\n" ;
|
2007
|
|
|
|
|
|
|
}
|
2008
|
|
|
|
|
|
|
|
2009
|
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
2010
|
|
|
|
|
|
|
# Show the current black frames list
|
2011
|
|
|
|
|
|
|
sub dump_frames
|
2012
|
|
|
|
|
|
|
{
|
2013
|
0
|
|
|
0
|
0
|
|
my ($frames_aref, $msg) = @_;
|
2014
|
|
|
|
|
|
|
|
2015
|
0
|
|
|
|
|
|
my @edges ;
|
2016
|
|
|
|
|
|
|
my $edge_href ;
|
2017
|
|
|
|
|
|
|
|
2018
|
0
|
|
|
|
|
|
print "\n----[ $msg (", scalar(@$frames_aref)," frames) ]------------------------------\n" ;
|
2019
|
0
|
|
|
|
|
|
foreach my $href (@$frames_aref)
|
2020
|
|
|
|
|
|
|
{
|
2021
|
0
|
|
0
|
|
|
|
while ( $edge_href && ($href->{'frame'} > $edge_href->{'frame'}) )
|
2022
|
|
|
|
|
|
|
{
|
2023
|
0
|
0
|
|
|
|
|
print "*** $edge_href->{'frame'} ** " . ($edge_href->{'type'} eq 'start_pkt' ? "vvvvvvvvvv" : "^^^^^^^^^^") . "******\n" ;
|
2024
|
0
|
|
|
|
|
|
$edge_href = shift @edges ;
|
2025
|
|
|
|
|
|
|
}
|
2026
|
|
|
|
|
|
|
|
2027
|
0
|
0
|
|
|
|
|
print "---------\n" if ($href->{'gap'}>1);
|
2028
|
|
|
|
|
|
|
|
2029
|
0
|
0
|
0
|
|
|
|
if ( $edge_href && ($href->{'frame'} == $edge_href->{'frame'}) && ($edge_href->{'type'} eq 'start_pkt'))
|
|
|
|
0
|
|
|
|
|
2030
|
|
|
|
|
|
|
{
|
2031
|
0
|
0
|
|
|
|
|
print "*** $edge_href->{'frame'} ** " . ($edge_href->{'type'} eq 'start_pkt' ? "vvvvvvvvvv" : "^^^^^^^^^^") . "******\n" ;
|
2032
|
0
|
|
|
|
|
|
$edge_href = shift @edges ;
|
2033
|
|
|
|
|
|
|
}
|
2034
|
0
|
0
|
|
|
|
|
print "???BAD??? " if ($href->{'gap'}<0);
|
2035
|
|
|
|
|
|
|
|
2036
|
0
|
|
|
|
|
|
dump_frame($href) ;
|
2037
|
|
|
|
|
|
|
|
2038
|
0
|
0
|
0
|
|
|
|
if ( $edge_href && ($href->{'frame'} == $edge_href->{'frame'}) && ($edge_href->{'type'} eq 'end_pkt'))
|
|
|
|
0
|
|
|
|
|
2039
|
|
|
|
|
|
|
{
|
2040
|
0
|
0
|
|
|
|
|
print "*** $edge_href->{'frame'} ** " . ($edge_href->{'type'} eq 'start_pkt' ? "vvvvvvvvvv" : "^^^^^^^^^^") . "******\n" ;
|
2041
|
0
|
|
|
|
|
|
$edge_href = shift @edges ;
|
2042
|
|
|
|
|
|
|
}
|
2043
|
|
|
|
|
|
|
}
|
2044
|
0
|
|
|
|
|
|
print "\n----------------------------------\n" ;
|
2045
|
|
|
|
|
|
|
}
|
2046
|
|
|
|
|
|
|
|
2047
|
|
|
|
|
|
|
sub prt_frame
|
2048
|
|
|
|
|
|
|
{
|
2049
|
0
|
|
|
0
|
0
|
|
my ($frames_aref, $framenum) = @_;
|
2050
|
|
|
|
|
|
|
|
2051
|
0
|
|
|
|
|
|
print "$framenum : " ;
|
2052
|
0
|
|
|
|
|
|
foreach my $key (sort keys %{$frames_aref->[$framenum]})
|
|
0
|
|
|
|
|
|
|
2053
|
|
|
|
|
|
|
{
|
2054
|
0
|
|
|
|
|
|
print " $key=$frames_aref->[$framenum]{$key}" ;
|
2055
|
|
|
|
|
|
|
}
|
2056
|
0
|
|
|
|
|
|
print "\n" ;
|
2057
|
|
|
|
|
|
|
}
|
2058
|
|
|
|
|
|
|
sub prt_frames
|
2059
|
|
|
|
|
|
|
{
|
2060
|
0
|
|
|
0
|
0
|
|
my ($frames_aref) = @_;
|
2061
|
|
|
|
|
|
|
|
2062
|
0
|
|
|
|
|
|
foreach my $frame_href (@$frames_aref)
|
2063
|
|
|
|
|
|
|
{
|
2064
|
0
|
|
|
|
|
|
prt_frame($frames_aref, $frame_href->{'frame'}) ;
|
2065
|
|
|
|
|
|
|
}
|
2066
|
|
|
|
|
|
|
}
|
2067
|
|
|
|
|
|
|
|
2068
|
|
|
|
|
|
|
#=================================================================================
|
2069
|
|
|
|
|
|
|
# BLACK FRAMES
|
2070
|
|
|
|
|
|
|
#=================================================================================
|
2071
|
|
|
|
|
|
|
|
2072
|
|
|
|
|
|
|
#---------------------------------------------------------------------------------
|
2073
|
|
|
|
|
|
|
#
|
2074
|
|
|
|
|
|
|
sub black_frame_cutlist
|
2075
|
|
|
|
|
|
|
{
|
2076
|
0
|
|
|
0
|
0
|
|
my ($frames_aref, $total_pkts, $total_frames, $settings_href) = @_ ;
|
2077
|
0
|
|
|
|
|
|
my @cut_list ;
|
2078
|
|
|
|
|
|
|
|
2079
|
0
|
0
|
|
|
|
|
print "--- black_frame_cutlist() ---\n" if $DEBUG ;
|
2080
|
|
|
|
|
|
|
|
2081
|
|
|
|
|
|
|
# : start : : end :
|
2082
|
|
|
|
|
|
|
# : pad : : pad :
|
2083
|
|
|
|
|
|
|
# _________|||____________|||___________|||______
|
2084
|
|
|
|
|
|
|
# : :
|
2085
|
|
|
|
|
|
|
#
|
2086
|
|
|
|
|
|
|
|
2087
|
|
|
|
|
|
|
#
|
2088
|
|
|
|
|
|
|
# _____|||____________|||___________|||__________
|
2089
|
|
|
|
|
|
|
# : :
|
2090
|
|
|
|
|
|
|
#
|
2091
|
|
|
|
|
|
|
|
2092
|
|
|
|
|
|
|
#
|
2093
|
|
|
|
|
|
|
# __|||____________|||___________|||_____________
|
2094
|
|
|
|
|
|
|
# : :
|
2095
|
|
|
|
|
|
|
#
|
2096
|
|
|
|
|
|
|
|
2097
|
0
|
|
|
|
|
|
my $curr_href=undef ;
|
2098
|
0
|
|
|
|
|
|
foreach my $href (@$frames_aref)
|
2099
|
|
|
|
|
|
|
{
|
2100
|
0
|
|
|
|
|
|
my $type = _prog_type($href->{'gap'}, $settings_href) ;
|
2101
|
|
|
|
|
|
|
|
2102
|
0
|
0
|
|
|
|
|
if ($DEBUG)
|
2103
|
|
|
|
|
|
|
{
|
2104
|
0
|
|
|
|
|
|
print "Cutlist len = " . scalar(@cut_list)."\n" ;
|
2105
|
0
|
|
|
|
|
|
print "[$type] " ; dump_frame($href) ;
|
|
0
|
|
|
|
|
|
|
2106
|
|
|
|
|
|
|
}
|
2107
|
|
|
|
|
|
|
|
2108
|
|
|
|
|
|
|
# start of new "block"
|
2109
|
0
|
0
|
|
|
|
|
if ($type eq 'program')
|
2110
|
|
|
|
|
|
|
{
|
2111
|
0
|
0
|
|
|
|
|
print " + New prog\n" if $DEBUG ;
|
2112
|
|
|
|
|
|
|
|
2113
|
|
|
|
|
|
|
# start new
|
2114
|
0
|
|
|
|
|
|
$curr_href = {
|
2115
|
|
|
|
|
|
|
'adverts' => 0,
|
2116
|
|
|
|
|
|
|
'type' => $type,
|
2117
|
|
|
|
|
|
|
%$href,
|
2118
|
|
|
|
|
|
|
} ;
|
2119
|
0
|
|
|
|
|
|
push @cut_list, $curr_href ;
|
2120
|
|
|
|
|
|
|
|
2121
|
0
|
0
|
|
|
|
|
print " + new prog added\n" if $DEBUG ;
|
2122
|
|
|
|
|
|
|
}
|
2123
|
|
|
|
|
|
|
else
|
2124
|
|
|
|
|
|
|
{
|
2125
|
0
|
0
|
|
|
|
|
if (!$curr_href)
|
2126
|
|
|
|
|
|
|
{
|
2127
|
|
|
|
|
|
|
# start new
|
2128
|
0
|
|
|
|
|
|
$curr_href = {
|
2129
|
|
|
|
|
|
|
'adverts' => 0,
|
2130
|
|
|
|
|
|
|
'type' => $type,
|
2131
|
|
|
|
|
|
|
%$href,
|
2132
|
|
|
|
|
|
|
} ;
|
2133
|
0
|
|
|
|
|
|
push @cut_list, $curr_href ;
|
2134
|
0
|
0
|
|
|
|
|
print " + new advert\n" if $DEBUG ;
|
2135
|
|
|
|
|
|
|
}
|
2136
|
|
|
|
|
|
|
else
|
2137
|
|
|
|
|
|
|
{
|
2138
|
|
|
|
|
|
|
# inc advert count
|
2139
|
0
|
|
|
|
|
|
$curr_href->{'adverts'}++ ;
|
2140
|
|
|
|
|
|
|
|
2141
|
|
|
|
|
|
|
# expand end time
|
2142
|
0
|
|
|
|
|
|
$curr_href->{'end_pkt'} = $href->{'end_pkt'} ;
|
2143
|
0
|
|
|
|
|
|
$curr_href->{'frame_end'} = $href->{'frame_end'} ;
|
2144
|
0
|
0
|
|
|
|
|
print " + extend\n" if $DEBUG ;
|
2145
|
|
|
|
|
|
|
}
|
2146
|
|
|
|
|
|
|
}
|
2147
|
|
|
|
|
|
|
}
|
2148
|
|
|
|
|
|
|
|
2149
|
|
|
|
|
|
|
## process start and end
|
2150
|
0
|
0
|
|
|
|
|
if (@cut_list)
|
2151
|
|
|
|
|
|
|
{
|
2152
|
|
|
|
|
|
|
## start
|
2153
|
0
|
|
|
|
|
|
my $start_href = $cut_list[0] ;
|
2154
|
0
|
0
|
|
|
|
|
if ($start_href->{'type'} ne 'program')
|
2155
|
|
|
|
|
|
|
{
|
2156
|
0
|
|
|
|
|
|
$start_href->{'start_pkt'} = 0 ;
|
2157
|
0
|
|
|
|
|
|
$start_href->{'frame_start'} = 0 ; # for debug
|
2158
|
|
|
|
|
|
|
}
|
2159
|
|
|
|
|
|
|
|
2160
|
|
|
|
|
|
|
## end
|
2161
|
0
|
|
|
|
|
|
my $end_href = $cut_list[-1] ;
|
2162
|
0
|
|
|
|
|
|
my $end_gap = $total_frames - $end_href->{'frame_end'} - 1 ;
|
2163
|
0
|
|
|
|
|
|
my $end_type = _prog_type($end_gap, $settings_href) ;
|
2164
|
0
|
0
|
|
|
|
|
if ($end_type ne 'program')
|
2165
|
|
|
|
|
|
|
{
|
2166
|
0
|
|
|
|
|
|
$end_href->{'end_pkt'} = $total_pkts-1 ;
|
2167
|
0
|
|
|
|
|
|
$end_href->{'frame_end'} = $total_frames-1 ; # for debug
|
2168
|
|
|
|
|
|
|
}
|
2169
|
|
|
|
|
|
|
}
|
2170
|
|
|
|
|
|
|
|
2171
|
|
|
|
|
|
|
|
2172
|
0
|
|
|
|
|
|
return @cut_list ;
|
2173
|
|
|
|
|
|
|
}
|
2174
|
|
|
|
|
|
|
|
2175
|
|
|
|
|
|
|
#---------------------------------------------------------------------------------
|
2176
|
|
|
|
|
|
|
#
|
2177
|
|
|
|
|
|
|
sub process_black_frames
|
2178
|
|
|
|
|
|
|
{
|
2179
|
0
|
|
|
0
|
0
|
|
my ($black_frames_ada_ref, $new_black_frames_aref, $total_pkts, $total_frames, $settings_href, $frames_adata_aref, $csv_frames_aref, $csv_settings_aref) = @_ ;
|
2180
|
|
|
|
|
|
|
|
2181
|
0
|
0
|
|
|
|
|
if ($DEBUG)
|
2182
|
|
|
|
|
|
|
{
|
2183
|
0
|
|
|
|
|
|
print "\n=================================================\n" ;
|
2184
|
0
|
|
|
|
|
|
print "process_black_frames()\n" ;
|
2185
|
0
|
|
|
|
|
|
print Data::Dumper->Dump(["Settings:", $settings_href]) ;
|
2186
|
|
|
|
|
|
|
}
|
2187
|
|
|
|
|
|
|
|
2188
|
|
|
|
|
|
|
## strip out any spurious frames
|
2189
|
|
|
|
|
|
|
|
2190
|
|
|
|
|
|
|
# start by coalescing the contiguous black frames
|
2191
|
0
|
|
|
|
|
|
my @frames = coalesce_frames($black_frames_ada_ref, $settings_href, 0) ;
|
2192
|
|
|
|
|
|
|
|
2193
|
0
|
0
|
|
|
|
|
dump_frames(\@frames, "BLACK coalesced") if $DEBUG >= 2 ;
|
2194
|
|
|
|
|
|
|
|
2195
|
0
|
|
|
|
|
|
csv_add_frames($csv_settings_aref, $frames_adata_aref, $csv_frames_aref, \@frames,
|
2196
|
|
|
|
|
|
|
$BLACK_COALESCED_FIELD, "0:1:1", 'black_frame') ;
|
2197
|
|
|
|
|
|
|
|
2198
|
|
|
|
|
|
|
## update input array with coalesced version
|
2199
|
0
|
|
|
|
|
|
my $num_black = scalar(@$black_frames_ada_ref) ;
|
2200
|
0
|
|
|
|
|
|
foreach my $href (@frames)
|
2201
|
|
|
|
|
|
|
{
|
2202
|
0
|
|
|
|
|
|
push @$new_black_frames_aref, $href ;
|
2203
|
|
|
|
|
|
|
}
|
2204
|
|
|
|
|
|
|
|
2205
|
|
|
|
|
|
|
## Create black frame cutlist
|
2206
|
0
|
|
|
|
|
|
my @cut_list = black_frame_cutlist(\@frames, $total_pkts, $total_frames, $settings_href) ;
|
2207
|
|
|
|
|
|
|
|
2208
|
0
|
0
|
|
|
|
|
dump_frames(\@cut_list, "Final BLACK Cut List") if $DEBUG >= 2 ;
|
2209
|
|
|
|
|
|
|
|
2210
|
0
|
|
|
|
|
|
return @cut_list ;
|
2211
|
|
|
|
|
|
|
}
|
2212
|
|
|
|
|
|
|
|
2213
|
|
|
|
|
|
|
#---------------------------------------------------------------------------------
|
2214
|
|
|
|
|
|
|
#
|
2215
|
|
|
|
|
|
|
sub process_silent_frames
|
2216
|
|
|
|
|
|
|
{
|
2217
|
0
|
|
|
0
|
0
|
|
my ($black_frames_aref, $silent_frames_ada_aref, $total_pkts, $total_frames, $settings_href, $frames_adata_aref, $csv_frames_aref, $csv_settings_aref) = @_ ;
|
2218
|
|
|
|
|
|
|
|
2219
|
0
|
0
|
|
|
|
|
if ($DEBUG)
|
2220
|
|
|
|
|
|
|
{
|
2221
|
0
|
|
|
|
|
|
print "\n=================================================\n" ;
|
2222
|
0
|
|
|
|
|
|
print "process_silent_frames()\n" ;
|
2223
|
0
|
|
|
|
|
|
print Data::Dumper->Dump(["Settings:", $settings_href]) ;
|
2224
|
|
|
|
|
|
|
}
|
2225
|
|
|
|
|
|
|
|
2226
|
|
|
|
|
|
|
## strip out any spurious frames
|
2227
|
|
|
|
|
|
|
|
2228
|
|
|
|
|
|
|
# start by coalescing the contiguous black frames
|
2229
|
0
|
|
|
|
|
|
my @silent_frames = coalesce_frames($silent_frames_ada_aref, $settings_href, 0) ;
|
2230
|
|
|
|
|
|
|
|
2231
|
0
|
|
|
|
|
|
csv_add_frames($csv_settings_aref, $frames_adata_aref, $csv_frames_aref, \@silent_frames,
|
2232
|
|
|
|
|
|
|
$SILENT_COALESCED_FIELD, "0:1:1", 'silent_frame') ;
|
2233
|
|
|
|
|
|
|
|
2234
|
|
|
|
|
|
|
#my $SILENCE_WINDOW = 100 ;
|
2235
|
|
|
|
|
|
|
|
2236
|
|
|
|
|
|
|
## Remove black frames that do not coincide with silence (with silence "fuzzy")
|
2237
|
0
|
|
|
|
|
|
my @frames = frames_subtract($black_frames_aref, \@silent_frames, $settings_href->{'silence_window'}) ;
|
2238
|
|
|
|
|
|
|
|
2239
|
0
|
0
|
|
|
|
|
if ($DEBUG >= 2)
|
2240
|
|
|
|
|
|
|
{
|
2241
|
0
|
|
|
|
|
|
dump_frames(\@silent_frames, "SILENT") ;
|
2242
|
0
|
|
|
|
|
|
dump_frames(\@frames, "SILENT BLACK") ;
|
2243
|
|
|
|
|
|
|
}
|
2244
|
|
|
|
|
|
|
|
2245
|
|
|
|
|
|
|
# Now have blocks of silence (in @silence_frames) along with spikes of black frames that are "silent".
|
2246
|
|
|
|
|
|
|
# Overlay the silent blocks with the black blocks, coalesce (again!) and we should have the answer
|
2247
|
0
|
|
|
|
|
|
my @combined_frames ;
|
2248
|
0
|
|
|
|
|
|
my %silent_frames = map { $_->{'frame'} => $_ } @silent_frames ;
|
|
0
|
|
|
|
|
|
|
2249
|
0
|
|
|
|
|
|
my %silent_black_frames = map { $_->{'frame'} => $_ } @frames ;
|
|
0
|
|
|
|
|
|
|
2250
|
0
|
|
|
|
|
|
my $last_framenum = $silent_frames[-1]{'frame'} ;
|
2251
|
0
|
0
|
|
|
|
|
$last_framenum = $frames[-1]{'frame'} if $last_framenum < $frames[-1]{'frame'} ;
|
2252
|
0
|
0
|
|
|
|
|
print "Process frames 0..$last_framenum\n" if $DEBUG ;
|
2253
|
0
|
|
|
|
|
|
for (my $framenum=0; $framenum <= $last_framenum; ++$framenum)
|
2254
|
|
|
|
|
|
|
{
|
2255
|
0
|
|
|
|
|
|
my $href ;
|
2256
|
0
|
0
|
|
|
|
|
if (exists($silent_frames{$framenum}))
|
|
|
0
|
|
|
|
|
|
2257
|
|
|
|
|
|
|
{
|
2258
|
0
|
|
|
|
|
|
$href = $silent_frames{$framenum} ;
|
2259
|
0
|
0
|
|
|
|
|
if ($DEBUG) {print " + silent @ $framenum : " ; dump_frame($href) ;}
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
2260
|
|
|
|
|
|
|
}
|
2261
|
|
|
|
|
|
|
elsif (exists($silent_black_frames{$framenum}))
|
2262
|
|
|
|
|
|
|
{
|
2263
|
0
|
|
|
|
|
|
$href = $silent_black_frames{$framenum} ;
|
2264
|
0
|
0
|
|
|
|
|
if ($DEBUG) {print " + silent_black @ $framenum : " ; dump_frame($href) ;}
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
2265
|
|
|
|
|
|
|
}
|
2266
|
|
|
|
|
|
|
|
2267
|
0
|
0
|
|
|
|
|
if ($href)
|
2268
|
|
|
|
|
|
|
{
|
2269
|
0
|
|
|
|
|
|
push @combined_frames, { %$href, 'black_frame'=>1 } ;
|
2270
|
0
|
|
|
|
|
|
$framenum = $href->{'frame_end'} ;
|
2271
|
|
|
|
|
|
|
}
|
2272
|
|
|
|
|
|
|
}
|
2273
|
0
|
|
|
|
|
|
update_gap(\@combined_frames) ;
|
2274
|
|
|
|
|
|
|
|
2275
|
0
|
|
|
|
|
|
@combined_frames = coalesce_frames(\@combined_frames, $settings_href, 0) ;
|
2276
|
0
|
0
|
|
|
|
|
dump_frames(\@combined_frames, "COMBINED COAL") if $DEBUG >= 2 ;
|
2277
|
|
|
|
|
|
|
|
2278
|
0
|
|
|
|
|
|
csv_add_frames($csv_settings_aref, $frames_adata_aref, $csv_frames_aref, \@combined_frames,
|
2279
|
|
|
|
|
|
|
$SILENT_BLACK_FIELD, "0:1:1", 'black_frame') ;
|
2280
|
|
|
|
|
|
|
|
2281
|
|
|
|
|
|
|
##NEW###################################################
|
2282
|
|
|
|
|
|
|
#my $reduce_end = 15 * $FPS ; # 15 sec window
|
2283
|
|
|
|
|
|
|
#my $reduce_min_gap = 2 * $FPS ; # need at least 2 sec gap
|
2284
|
|
|
|
|
|
|
|
2285
|
0
|
0
|
|
|
|
|
if ($settings_href->{'reduce_end'})
|
2286
|
|
|
|
|
|
|
{
|
2287
|
|
|
|
|
|
|
## reduce the program end to the nearest silent region within
|
2288
|
|
|
|
|
|
|
## the window of the end
|
2289
|
0
|
|
|
|
|
|
foreach my $frame_href (@combined_frames)
|
2290
|
|
|
|
|
|
|
{
|
2291
|
0
|
|
|
|
|
|
frames_reduce_end($frame_href, \@silent_frames, $settings_href->{'reduce_end'}, $settings_href->{'reduce_min_gap'}) ;
|
2292
|
|
|
|
|
|
|
}
|
2293
|
|
|
|
|
|
|
|
2294
|
0
|
|
|
|
|
|
csv_add_frames($csv_settings_aref, $frames_adata_aref, $csv_frames_aref, \@combined_frames,
|
2295
|
|
|
|
|
|
|
$REDUCED_SILENT_BLACK_FIELD, "0:1:1", 'black_frame') ;
|
2296
|
|
|
|
|
|
|
|
2297
|
|
|
|
|
|
|
}
|
2298
|
|
|
|
|
|
|
|
2299
|
|
|
|
|
|
|
|
2300
|
|
|
|
|
|
|
##NEW###################################################
|
2301
|
|
|
|
|
|
|
|
2302
|
|
|
|
|
|
|
|
2303
|
|
|
|
|
|
|
|
2304
|
|
|
|
|
|
|
|
2305
|
|
|
|
|
|
|
|
2306
|
|
|
|
|
|
|
## Create black frame cutlist
|
2307
|
0
|
|
|
|
|
|
my @cut_list = black_frame_cutlist(\@combined_frames, $total_pkts, $total_frames, $settings_href) ;
|
2308
|
|
|
|
|
|
|
|
2309
|
0
|
0
|
|
|
|
|
dump_frames(\@cut_list, "Final SILENT Cut List") if $DEBUG >= 2 ;
|
2310
|
|
|
|
|
|
|
|
2311
|
0
|
|
|
|
|
|
return @cut_list ;
|
2312
|
|
|
|
|
|
|
}
|
2313
|
|
|
|
|
|
|
|
2314
|
|
|
|
|
|
|
|
2315
|
|
|
|
|
|
|
#=================================================================================
|
2316
|
|
|
|
|
|
|
# LOGO FRAMES
|
2317
|
|
|
|
|
|
|
#=================================================================================
|
2318
|
|
|
|
|
|
|
|
2319
|
|
|
|
|
|
|
# TODO: Handle all start cases - record after start of prog (i.e. logo = 100%), record during adverts, record during end of previous
|
2320
|
|
|
|
|
|
|
# TODO: Handle all end cases - record end before end of prog, record end during adverts, record end at start of next prog
|
2321
|
|
|
|
|
|
|
|
2322
|
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
2323
|
|
|
|
|
|
|
# Given a frame number and a list of frames, find the frames from the list that
|
2324
|
|
|
|
|
|
|
# are immediately adjacent to this one.
|
2325
|
|
|
|
|
|
|
#
|
2326
|
|
|
|
|
|
|
sub bounding_frames
|
2327
|
|
|
|
|
|
|
{
|
2328
|
0
|
|
|
0
|
0
|
|
my ($framenum, $frames_aref) = @_ ;
|
2329
|
|
|
|
|
|
|
|
2330
|
0
|
|
|
|
|
|
my ($before, $after) ;
|
2331
|
0
|
|
|
|
|
|
foreach my $href (@$frames_aref)
|
2332
|
|
|
|
|
|
|
{
|
2333
|
0
|
|
|
|
|
|
my $frame_end = $href->{'frame_end'} ;
|
2334
|
0
|
0
|
|
|
|
|
if ($frame_end <= $framenum)
|
|
|
0
|
|
|
|
|
|
2335
|
|
|
|
|
|
|
{
|
2336
|
0
|
|
|
|
|
|
$before = $href->{'frame_end'} ;
|
2337
|
|
|
|
|
|
|
}
|
2338
|
|
|
|
|
|
|
elsif ($href->{'frame'} > $framenum)
|
2339
|
|
|
|
|
|
|
{
|
2340
|
0
|
|
|
|
|
|
$after = $href->{'frame'} ;
|
2341
|
0
|
|
|
|
|
|
last ;
|
2342
|
|
|
|
|
|
|
}
|
2343
|
|
|
|
|
|
|
}
|
2344
|
0
|
|
|
|
|
|
return ($before, $after) ;
|
2345
|
|
|
|
|
|
|
}
|
2346
|
|
|
|
|
|
|
|
2347
|
|
|
|
|
|
|
|
2348
|
|
|
|
|
|
|
#---------------------------------------------------------------------------------
|
2349
|
|
|
|
|
|
|
sub logo_add_frames
|
2350
|
|
|
|
|
|
|
{
|
2351
|
0
|
|
|
0
|
0
|
|
my ($msg_str, $frames_adata_aref, $logo_frames_aref, $start_frame, $end_frame, $settings_href, $edge_ref) = @_ ;
|
2352
|
|
|
|
|
|
|
|
2353
|
|
|
|
|
|
|
# my @add_frames ;
|
2354
|
0
|
|
|
|
|
|
foreach my $fnum ($start_frame..$end_frame)
|
2355
|
|
|
|
|
|
|
{
|
2356
|
|
|
|
|
|
|
# save first edge
|
2357
|
0
|
0
|
|
|
|
|
if ($edge_ref)
|
2358
|
|
|
|
|
|
|
{
|
2359
|
0
|
0
|
|
|
|
|
$$edge_ref = $fnum unless defined($$edge_ref) ;
|
2360
|
|
|
|
|
|
|
}
|
2361
|
|
|
|
|
|
|
|
2362
|
|
|
|
|
|
|
# spoof an entry that looks like a valid logo detection
|
2363
|
0
|
|
|
|
|
|
my $buff_href = { %{$frames_adata_aref->[$fnum]} } ;
|
|
0
|
|
|
|
|
|
|
2364
|
0
|
|
|
|
|
|
$buff_href->{'match_percent'} = $settings_href->{'logo_rise_threshold'} ;
|
2365
|
0
|
|
|
|
|
|
$buff_href->{'ave_percent'} = $settings_href->{'logo_rise_threshold'} ;
|
2366
|
|
|
|
|
|
|
|
2367
|
0
|
0
|
|
|
|
|
if ($DEBUG) {print " + + $msg_str extended by : " ; dump_frame($buff_href) ;}
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
2368
|
|
|
|
|
|
|
|
2369
|
|
|
|
|
|
|
# push @add_frames, $buff_href ;
|
2370
|
0
|
|
|
|
|
|
push @$logo_frames_aref, $buff_href ;
|
2371
|
|
|
|
|
|
|
}
|
2372
|
|
|
|
|
|
|
# push @$logo_frames_aref, @add_frames ;
|
2373
|
|
|
|
|
|
|
|
2374
|
|
|
|
|
|
|
}
|
2375
|
|
|
|
|
|
|
|
2376
|
|
|
|
|
|
|
#---------------------------------------------------------------------------------
|
2377
|
|
|
|
|
|
|
#
|
2378
|
|
|
|
|
|
|
sub process_logo_frames
|
2379
|
|
|
|
|
|
|
{
|
2380
|
0
|
|
|
0
|
0
|
|
my ($logo_all_frames_ada_aref, $black_frames_aref, $scene_frames_ada_aref, $total_pkts, $total_frames, $settings_href,
|
2381
|
|
|
|
|
|
|
$frames_adata_aref, $csv_frames_aref, $csv_settings_aref) = @_ ;
|
2382
|
|
|
|
|
|
|
|
2383
|
0
|
|
|
|
|
|
my @cut_list ;
|
2384
|
|
|
|
|
|
|
|
2385
|
0
|
0
|
|
|
|
|
if ($DEBUG)
|
2386
|
|
|
|
|
|
|
{
|
2387
|
0
|
|
|
|
|
|
print "\n=================================================\n" ;
|
2388
|
0
|
|
|
|
|
|
print "process_logo_frames()\n" ;
|
2389
|
0
|
|
|
|
|
|
print Data::Dumper->Dump(["Settings:", $settings_href]) ;
|
2390
|
|
|
|
|
|
|
}
|
2391
|
|
|
|
|
|
|
|
2392
|
0
|
|
|
|
|
|
my $logo_frames_adl_aref ;
|
2393
|
0
|
|
|
|
|
|
$logo_frames_adl_aref = [] ;
|
2394
|
|
|
|
|
|
|
|
2395
|
0
|
|
|
|
|
|
my @lf ;
|
2396
|
0
|
|
|
|
|
|
my $thing = tied @$frames_adata_aref ;
|
2397
|
|
|
|
|
|
|
|
2398
|
0
|
|
|
|
|
|
tie @lf, 'Linux::DVB::DVBT::Advert', 'LOGO',
|
2399
|
|
|
|
|
|
|
[$thing] ;
|
2400
|
|
|
|
|
|
|
|
2401
|
0
|
|
|
|
|
|
$logo_frames_adl_aref = \@lf ;
|
2402
|
|
|
|
|
|
|
|
2403
|
0
|
|
|
|
|
|
my $adl = tied @$logo_frames_adl_aref ;
|
2404
|
|
|
|
|
|
|
|
2405
|
|
|
|
|
|
|
|
2406
|
|
|
|
|
|
|
## Threshold the frames based on average quality
|
2407
|
0
|
|
|
|
|
|
my $prev = 0 ;
|
2408
|
0
|
|
|
|
|
|
my $detect_mode = 'rise' ;
|
2409
|
0
|
|
|
|
|
|
foreach my $href (@$logo_all_frames_ada_aref)
|
2410
|
|
|
|
|
|
|
{
|
2411
|
0
|
|
|
|
|
|
my $framenum = $href->{'frame'} ;
|
2412
|
|
|
|
|
|
|
|
2413
|
0
|
0
|
|
|
|
|
if ($DEBUG)
|
2414
|
|
|
|
|
|
|
{
|
2415
|
0
|
|
|
|
|
|
$adl->logo_frames_sanity($framenum) ;
|
2416
|
|
|
|
|
|
|
}
|
2417
|
|
|
|
|
|
|
|
2418
|
|
|
|
|
|
|
## threshold detection with hysteresis
|
2419
|
0
|
|
|
|
|
|
my $above = 0 ;
|
2420
|
0
|
0
|
|
|
|
|
if ($detect_mode eq 'rise')
|
2421
|
|
|
|
|
|
|
{
|
2422
|
|
|
|
|
|
|
# rising detect
|
2423
|
0
|
0
|
|
|
|
|
if ($href->{'ave_percent'} >= $settings_href->{'logo_rise_threshold'})
|
2424
|
|
|
|
|
|
|
{
|
2425
|
0
|
|
|
|
|
|
$above = 1 ;
|
2426
|
0
|
|
|
|
|
|
$detect_mode = 'fall' ;
|
2427
|
|
|
|
|
|
|
}
|
2428
|
|
|
|
|
|
|
}
|
2429
|
|
|
|
|
|
|
else
|
2430
|
|
|
|
|
|
|
{
|
2431
|
|
|
|
|
|
|
# falling detect
|
2432
|
0
|
|
|
|
|
|
$above = 1 ;
|
2433
|
0
|
0
|
|
|
|
|
if ($href->{'ave_percent'} < $settings_href->{'logo_fall_threshold'})
|
2434
|
|
|
|
|
|
|
{
|
2435
|
0
|
|
|
|
|
|
$above = 0 ;
|
2436
|
0
|
|
|
|
|
|
$detect_mode = 'rise' ;
|
2437
|
|
|
|
|
|
|
}
|
2438
|
|
|
|
|
|
|
}
|
2439
|
|
|
|
|
|
|
|
2440
|
|
|
|
|
|
|
## use detected threshold
|
2441
|
0
|
0
|
|
|
|
|
if ($above)
|
2442
|
|
|
|
|
|
|
{
|
2443
|
0
|
0
|
|
|
|
|
if (!$prev)
|
2444
|
|
|
|
|
|
|
{
|
2445
|
0
|
0
|
|
|
|
|
if ($DEBUG) {print " + rising edge : " ; dump_frame($href) ;}
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
2446
|
|
|
|
|
|
|
|
2447
|
|
|
|
|
|
|
## rising edge - prefix by previous points to previous scene change
|
2448
|
|
|
|
|
|
|
|
2449
|
|
|
|
|
|
|
|
2450
|
|
|
|
|
|
|
# See if any scene changes are within (yet another) window of the new start edge
|
2451
|
|
|
|
|
|
|
#
|
2452
|
|
|
|
|
|
|
# Scene Change: | | | |
|
2453
|
|
|
|
|
|
|
# Logo ave quality: ||||||||||||||||||||||||||||||
|
2454
|
|
|
|
|
|
|
# Extended (scene): ::::::::::::||||||||||||||||||||||||||||||...
|
2455
|
|
|
|
|
|
|
#
|
2456
|
0
|
|
|
|
|
|
my $start_framenum = $framenum ;
|
2457
|
|
|
|
|
|
|
|
2458
|
|
|
|
|
|
|
## extend back while "raw" quality > threshold
|
2459
|
0
|
|
|
|
|
|
my $extend_start = $start_framenum - $settings_href->{'logo_ave_points'} ;
|
2460
|
0
|
0
|
|
|
|
|
$extend_start = 0 if ($extend_start < 0) ;
|
2461
|
0
|
|
|
|
|
|
for (my $fnum = $start_framenum-1; $fnum >= $extend_start; --$fnum)
|
2462
|
|
|
|
|
|
|
{
|
2463
|
0
|
0
|
|
|
|
|
if (($frames_adata_aref->[$fnum]{'match_percent'} >= $settings_href->{'logo_rise_threshold'}))
|
2464
|
|
|
|
|
|
|
{
|
2465
|
0
|
|
|
|
|
|
$start_framenum = $fnum ;
|
2466
|
0
|
0
|
|
|
|
|
if ($DEBUG) {print " + + match extended by : " ; dump_frame($frames_adata_aref->[$fnum]) ;}
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
2467
|
|
|
|
|
|
|
}
|
2468
|
|
|
|
|
|
|
else
|
2469
|
|
|
|
|
|
|
{
|
2470
|
|
|
|
|
|
|
# stop
|
2471
|
0
|
|
|
|
|
|
last ;
|
2472
|
|
|
|
|
|
|
}
|
2473
|
|
|
|
|
|
|
}
|
2474
|
|
|
|
|
|
|
|
2475
|
0
|
|
|
|
|
|
my $found_edge = 0 ;
|
2476
|
0
|
|
|
|
|
|
my $edge = undef ;
|
2477
|
|
|
|
|
|
|
|
2478
|
|
|
|
|
|
|
# find any black frames around new start frame
|
2479
|
0
|
0
|
|
|
|
|
print "rising black bounding..\n" if $DEBUG ;
|
2480
|
0
|
|
|
|
|
|
my ($black_before, $black_after) = bounding_frames($start_framenum, $black_frames_aref) ;
|
2481
|
|
|
|
|
|
|
|
2482
|
0
|
0
|
|
|
|
|
print " - black : rising frame $start_framenum, black before $black_before, black after $black_after\n" if $DEBUG ;
|
2483
|
|
|
|
|
|
|
|
2484
|
|
|
|
|
|
|
# find any scene changes around new start frame
|
2485
|
0
|
0
|
|
|
|
|
print "rising scene bounding..\n" if $DEBUG ;
|
2486
|
0
|
|
|
|
|
|
my ($scene_before, $scene_after) = bounding_frames($start_framenum, $scene_frames_ada_aref) ;
|
2487
|
|
|
|
|
|
|
|
2488
|
0
|
0
|
|
|
|
|
print " - scene : rising frame $start_framenum, scene before $scene_before, scene after $scene_after\n" if $DEBUG ;
|
2489
|
|
|
|
|
|
|
|
2490
|
|
|
|
|
|
|
# if change occurs before the start frame AND it's not too far away, then extend to this point
|
2491
|
0
|
0
|
0
|
|
|
|
if (($black_before < $start_framenum) && ( ($start_framenum-$black_before) < $settings_href->{'logo_ave_points'}))
|
2492
|
|
|
|
|
|
|
{
|
2493
|
0
|
|
|
|
|
|
++$found_edge ;
|
2494
|
0
|
|
|
|
|
|
logo_add_frames("black", $frames_adata_aref, $logo_frames_adl_aref, $black_before, $framenum-1, $settings_href, \$edge) ;
|
2495
|
|
|
|
|
|
|
}
|
2496
|
|
|
|
|
|
|
|
2497
|
|
|
|
|
|
|
|
2498
|
|
|
|
|
|
|
# if scene change occurs before the start frame AND it's not too far away, then extend to this point
|
2499
|
0
|
0
|
0
|
|
|
|
if (!$found_edge && ($scene_before < $start_framenum) && ( ($start_framenum-$scene_before) < $settings_href->{'logo_ave_points'}))
|
|
|
|
0
|
|
|
|
|
2500
|
|
|
|
|
|
|
{
|
2501
|
0
|
|
|
|
|
|
++$found_edge ;
|
2502
|
0
|
|
|
|
|
|
logo_add_frames("scene", $frames_adata_aref, $logo_frames_adl_aref, $scene_before, $framenum-1, $settings_href, \$edge) ;
|
2503
|
|
|
|
|
|
|
}
|
2504
|
|
|
|
|
|
|
|
2505
|
0
|
0
|
|
|
|
|
print " - found? $found_edge : edge=$edge\n" if $DEBUG ;
|
2506
|
|
|
|
|
|
|
|
2507
|
|
|
|
|
|
|
## if this is the start of the video, see if we can extend to the start (use the lower threshold)
|
2508
|
0
|
0
|
0
|
|
|
|
if ($found_edge && ($edge) && ($edge <= $settings_href->{'logo_ave_points'}) )
|
|
|
|
0
|
|
|
|
|
2509
|
|
|
|
|
|
|
{
|
2510
|
0
|
0
|
|
|
|
|
print " + + start extending...\n" if $DEBUG ;
|
2511
|
0
|
|
|
|
|
|
my $fnum = $edge-1 ;
|
2512
|
0
|
|
|
|
|
|
my $window_count = 0 ;
|
2513
|
0
|
|
0
|
|
|
|
while ( ($fnum >= 0) && ($window_count < $settings_href->{'frame_window'}) )
|
2514
|
|
|
|
|
|
|
{
|
2515
|
0
|
0
|
|
|
|
|
if ($frames_adata_aref->[$fnum]{'match_percent'} >= $settings_href->{'logo_fall_threshold'})
|
2516
|
|
|
|
|
|
|
{
|
2517
|
0
|
|
|
|
|
|
$window_count = 0 ;
|
2518
|
|
|
|
|
|
|
}
|
2519
|
|
|
|
|
|
|
else
|
2520
|
|
|
|
|
|
|
{
|
2521
|
0
|
|
|
|
|
|
++$window_count ;
|
2522
|
|
|
|
|
|
|
}
|
2523
|
0
|
|
|
|
|
|
--$fnum ;
|
2524
|
|
|
|
|
|
|
}
|
2525
|
|
|
|
|
|
|
|
2526
|
|
|
|
|
|
|
# if we're nearly at the start, then just start at 0
|
2527
|
0
|
|
|
|
|
|
++$fnum ;
|
2528
|
0
|
0
|
|
|
|
|
$fnum = 0 if ($fnum <= $settings_href->{frame_window}) ;
|
2529
|
|
|
|
|
|
|
|
2530
|
|
|
|
|
|
|
# add frames (skip any < threshold)
|
2531
|
0
|
|
|
|
|
|
my @start_frames ;
|
2532
|
0
|
|
|
|
|
|
while ($fnum < $edge)
|
2533
|
|
|
|
|
|
|
{
|
2534
|
0
|
0
|
|
|
|
|
if ($frames_adata_aref->[$fnum]{'match_percent'} >= $settings_href->{'logo_rise_threshold'})
|
2535
|
|
|
|
|
|
|
{
|
2536
|
0
|
0
|
|
|
|
|
if ($DEBUG) {print " + + start-extended by : " ; dump_frame($frames_adata_aref->[$fnum]) ;}
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
2537
|
|
|
|
|
|
|
# push @start_frames, $frames_adata_aref->[$fnum] ;
|
2538
|
0
|
|
|
|
|
|
unshift @$logo_frames_adl_aref, $frames_adata_aref->[$fnum] ;
|
2539
|
|
|
|
|
|
|
}
|
2540
|
0
|
|
|
|
|
|
++$fnum ;
|
2541
|
|
|
|
|
|
|
}
|
2542
|
|
|
|
|
|
|
|
2543
|
|
|
|
|
|
|
# insert these at the start
|
2544
|
|
|
|
|
|
|
# unshift @$logo_frames_adl_aref, @start_frames ;
|
2545
|
|
|
|
|
|
|
}
|
2546
|
|
|
|
|
|
|
|
2547
|
|
|
|
|
|
|
## fall back on extending as much as possible
|
2548
|
0
|
0
|
|
|
|
|
if (!$found_edge)
|
2549
|
|
|
|
|
|
|
{
|
2550
|
|
|
|
|
|
|
# failed to use scene change - fall back on using raw quality
|
2551
|
|
|
|
|
|
|
|
2552
|
|
|
|
|
|
|
## rising edge - prefix by previous points > threshold
|
2553
|
|
|
|
|
|
|
|
2554
|
|
|
|
|
|
|
# calc where to start from (allow a window where quality can be < threshold)
|
2555
|
|
|
|
|
|
|
# (need to use frame buffer)
|
2556
|
0
|
|
|
|
|
|
my $end_index = $framenum-1 ;
|
2557
|
0
|
|
|
|
|
|
my $start_index = $end_index ;
|
2558
|
0
|
|
|
|
|
|
my $window_count = 0 ;
|
2559
|
0
|
|
0
|
|
|
|
while ( ($start_index > 0) && ($end_index-$start_index < $settings_href->{'logo_ave_points'}) && ($window_count < $settings_href->{'frame_window'}) )
|
|
|
|
0
|
|
|
|
|
2560
|
|
|
|
|
|
|
{
|
2561
|
0
|
0
|
|
|
|
|
if ($frames_adata_aref->[$start_index]{'match_percent'} >= $settings_href->{'logo_rise_threshold'})
|
2562
|
|
|
|
|
|
|
{
|
2563
|
0
|
|
|
|
|
|
$window_count = 0 ;
|
2564
|
|
|
|
|
|
|
}
|
2565
|
|
|
|
|
|
|
else
|
2566
|
|
|
|
|
|
|
{
|
2567
|
0
|
|
|
|
|
|
++$window_count ;
|
2568
|
|
|
|
|
|
|
}
|
2569
|
0
|
|
|
|
|
|
--$start_index ;
|
2570
|
|
|
|
|
|
|
}
|
2571
|
|
|
|
|
|
|
|
2572
|
0
|
0
|
|
|
|
|
if ($DEBUG) {print " + start..end : $start_index .. $end_index\n" ; }
|
|
0
|
|
|
|
|
|
|
2573
|
|
|
|
|
|
|
|
2574
|
|
|
|
|
|
|
# add frames (skip any < threshold)
|
2575
|
0
|
|
|
|
|
|
++$start_index ;
|
2576
|
0
|
|
|
|
|
|
foreach my $buff_href (@$frames_adata_aref[$start_index..$end_index])
|
2577
|
|
|
|
|
|
|
{
|
2578
|
0
|
0
|
|
|
|
|
if ($buff_href->{'match_percent'} > $settings_href->{'logo_rise_threshold'})
|
2579
|
|
|
|
|
|
|
{
|
2580
|
0
|
0
|
|
|
|
|
if ($DEBUG) {print " + + extended by : " ; dump_frame($buff_href) ;}
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
2581
|
0
|
|
|
|
|
|
push @$logo_frames_adl_aref, $buff_href ;
|
2582
|
|
|
|
|
|
|
}
|
2583
|
|
|
|
|
|
|
}
|
2584
|
|
|
|
|
|
|
}
|
2585
|
|
|
|
|
|
|
|
2586
|
0
|
|
|
|
|
|
$adl->update_gaps() ;
|
2587
|
|
|
|
|
|
|
|
2588
|
0
|
0
|
|
|
|
|
dump_frames($logo_frames_adl_aref, "LOGO after extending due to rising edge") if $DEBUG >= 2;
|
2589
|
|
|
|
|
|
|
|
2590
|
|
|
|
|
|
|
}
|
2591
|
|
|
|
|
|
|
|
2592
|
|
|
|
|
|
|
## add this frame
|
2593
|
0
|
|
|
|
|
|
push @$logo_frames_adl_aref, $href ;
|
2594
|
|
|
|
|
|
|
|
2595
|
0
|
|
|
|
|
|
$prev = 1 ;
|
2596
|
|
|
|
|
|
|
}
|
2597
|
|
|
|
|
|
|
else
|
2598
|
|
|
|
|
|
|
{
|
2599
|
0
|
0
|
|
|
|
|
if ($prev)
|
2600
|
|
|
|
|
|
|
{
|
2601
|
0
|
0
|
|
|
|
|
if ($DEBUG) {print " + falling edge : " ; dump_frame($href) ;}
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
2602
|
|
|
|
|
|
|
|
2603
|
0
|
|
|
|
|
|
$adl->update_gaps() ;
|
2604
|
|
|
|
|
|
|
|
2605
|
0
|
0
|
|
|
|
|
dump_frames($logo_frames_adl_aref, "LOGO before reducing due to falling edge") if $DEBUG >= 2;
|
2606
|
|
|
|
|
|
|
|
2607
|
|
|
|
|
|
|
## trailing edge - remove any raw points < threshold
|
2608
|
|
|
|
|
|
|
# use logo array we're building
|
2609
|
|
|
|
|
|
|
|
2610
|
|
|
|
|
|
|
# remove ALL frames for the length of the buffer, then start adding them back iff > threshold AND not too far away
|
2611
|
0
|
|
|
|
|
|
my $end_index = scalar(@$logo_frames_adl_aref)-1 ;
|
2612
|
0
|
|
|
|
|
|
my $start_index = $end_index-$settings_href->{'logo_ave_points'} ;
|
2613
|
0
|
0
|
|
|
|
|
$start_index = 0 if $start_index < 0 ;
|
2614
|
0
|
|
|
|
|
|
my $num_end_frames = $end_index - $start_index + 1 ;
|
2615
|
0
|
0
|
|
|
|
|
if ($DEBUG) {print " + + reduced by $num_end_frames frames (start idx=$start_index, end idx=$end_index) to : " ; dump_frame($logo_frames_adl_aref->[$start_index]) ;}
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
2616
|
|
|
|
|
|
|
|
2617
|
0
|
|
|
|
|
|
splice @$logo_frames_adl_aref, $start_index ;
|
2618
|
|
|
|
|
|
|
|
2619
|
|
|
|
|
|
|
## check we have some points left?
|
2620
|
0
|
0
|
|
|
|
|
if (scalar(@$logo_frames_adl_aref))
|
2621
|
|
|
|
|
|
|
{
|
2622
|
|
|
|
|
|
|
|
2623
|
|
|
|
|
|
|
# create a list of these removed frames that are > threshold
|
2624
|
0
|
|
|
|
|
|
my @end_frames = () ;
|
2625
|
0
|
0
|
|
|
|
|
print STDERR "logo_frames_adl_aref size = ",scalar(@$logo_frames_adl_aref),"\n" if $DEBUG >= 2;
|
2626
|
0
|
0
|
|
|
|
|
print STDERR "About to read from logo_frames_adl_aref[-1] ...\n" if $DEBUG >= 2;
|
2627
|
0
|
|
|
|
|
|
my $new_framenum = $logo_frames_adl_aref->[-1]{'frame'}+1 ;
|
2628
|
0
|
|
|
|
|
|
foreach (1..$num_end_frames)
|
2629
|
|
|
|
|
|
|
{
|
2630
|
0
|
0
|
|
|
|
|
if ($frames_adata_aref->[$new_framenum]{'match_percent'} >= $settings_href->{'logo_rise_threshold'})
|
2631
|
|
|
|
|
|
|
{
|
2632
|
0
|
0
|
|
|
|
|
if ($DEBUG) {print " >> end_frames + $new_framenum " ; dump_frame($frames_adata_aref->[$new_framenum]) ;}
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
2633
|
0
|
|
|
|
|
|
push @end_frames, $frames_adata_aref->[$new_framenum] ;
|
2634
|
|
|
|
|
|
|
}
|
2635
|
0
|
|
|
|
|
|
++$new_framenum ;
|
2636
|
|
|
|
|
|
|
}
|
2637
|
|
|
|
|
|
|
|
2638
|
|
|
|
|
|
|
# coalesce valid frames together
|
2639
|
0
|
|
|
|
|
|
update_gap(\@end_frames) ;
|
2640
|
0
|
|
|
|
|
|
@end_frames = coalesce_frames(\@end_frames, $settings_href, $logo_frames_adl_aref->[-1]{'frame'}, "logo end frames") ;
|
2641
|
|
|
|
|
|
|
|
2642
|
0
|
0
|
|
|
|
|
dump_frames(\@end_frames, "coalesced end logo frames") if $DEBUG >= 2;
|
2643
|
|
|
|
|
|
|
|
2644
|
|
|
|
|
|
|
# Just use the first block - the end *should* be the real end of the program
|
2645
|
0
|
0
|
|
|
|
|
if (@end_frames)
|
2646
|
|
|
|
|
|
|
{
|
2647
|
0
|
|
|
|
|
|
my $f_href = $end_frames[0] ;
|
2648
|
0
|
|
|
|
|
|
foreach my $new_framenum ($f_href->{'frame'}..$f_href->{'frame_end'})
|
2649
|
|
|
|
|
|
|
{
|
2650
|
0
|
|
|
|
|
|
push @$logo_frames_adl_aref, $frames_adata_aref->[$new_framenum] ;
|
2651
|
0
|
0
|
|
|
|
|
if ($DEBUG) {print " + + re-extend by : " ; dump_frame($frames_adata_aref->[$new_framenum]) ;}
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
2652
|
|
|
|
|
|
|
}
|
2653
|
|
|
|
|
|
|
}
|
2654
|
|
|
|
|
|
|
|
2655
|
0
|
|
|
|
|
|
@end_frames = () ;
|
2656
|
|
|
|
|
|
|
|
2657
|
0
|
|
|
|
|
|
$adl->update_gaps() ;
|
2658
|
|
|
|
|
|
|
|
2659
|
0
|
0
|
|
|
|
|
dump_frames($logo_frames_adl_aref, "LOGO after reducing") if $DEBUG >= 2 ;
|
2660
|
|
|
|
|
|
|
|
2661
|
|
|
|
|
|
|
|
2662
|
|
|
|
|
|
|
## see if we can expand out to a scene change
|
2663
|
0
|
|
|
|
|
|
my $end_framenum = $logo_frames_adl_aref->[-1]{'frame'} ;
|
2664
|
0
|
0
|
|
|
|
|
print " end frame=$end_framenum\n" if $DEBUG ;
|
2665
|
|
|
|
|
|
|
|
2666
|
|
|
|
|
|
|
# find any black frames around new end frame
|
2667
|
0
|
0
|
|
|
|
|
print "falling black bounding..\n" if $DEBUG ;
|
2668
|
0
|
|
|
|
|
|
my ($black_before, $black_after) = bounding_frames($end_framenum, $black_frames_aref) ;
|
2669
|
|
|
|
|
|
|
|
2670
|
0
|
0
|
|
|
|
|
print " - black : falling frame $end_framenum, black before $black_before, black after $black_after\n" if $DEBUG ;
|
2671
|
|
|
|
|
|
|
|
2672
|
|
|
|
|
|
|
# find any scene changes around new end frame
|
2673
|
0
|
0
|
|
|
|
|
print "falling scene bounding..\n" if $DEBUG ;
|
2674
|
0
|
|
|
|
|
|
my ($scene_before, $scene_after) = bounding_frames($end_framenum, $scene_frames_ada_aref) ;
|
2675
|
|
|
|
|
|
|
|
2676
|
0
|
0
|
|
|
|
|
print " - scene : falling frame $end_framenum, scene before $scene_before, scene after $scene_after\n" if $DEBUG ;
|
2677
|
|
|
|
|
|
|
|
2678
|
0
|
|
|
|
|
|
my $found_edge = 0 ;
|
2679
|
|
|
|
|
|
|
|
2680
|
|
|
|
|
|
|
# if black frame occurs after the end frame AND it's not too far away, then extend to this point
|
2681
|
0
|
0
|
0
|
|
|
|
if (($black_after > $end_framenum) && ( ($black_after-$end_framenum) < $settings_href->{'logo_ave_points'}))
|
2682
|
|
|
|
|
|
|
{
|
2683
|
0
|
|
|
|
|
|
++$found_edge ;
|
2684
|
0
|
|
|
|
|
|
logo_add_frames("black", $frames_adata_aref, $logo_frames_adl_aref, $end_framenum+1, $black_after, $settings_href) ;
|
2685
|
|
|
|
|
|
|
}
|
2686
|
|
|
|
|
|
|
|
2687
|
|
|
|
|
|
|
# if scene change occurs after the end frame AND it's not too far away, then extend to this point
|
2688
|
0
|
0
|
0
|
|
|
|
if (!$found_edge && ($scene_after > $end_framenum) && ( ($scene_after-$end_framenum) < $settings_href->{'logo_ave_points'}))
|
|
|
|
0
|
|
|
|
|
2689
|
|
|
|
|
|
|
{
|
2690
|
0
|
|
|
|
|
|
++$found_edge ;
|
2691
|
0
|
|
|
|
|
|
logo_add_frames("scene", $frames_adata_aref, $logo_frames_adl_aref, $end_framenum+1, $scene_after, $settings_href) ;
|
2692
|
|
|
|
|
|
|
}
|
2693
|
|
|
|
|
|
|
|
2694
|
0
|
0
|
0
|
|
|
|
if (!$found_edge && $DEBUG)
|
2695
|
|
|
|
|
|
|
{
|
2696
|
0
|
|
|
|
|
|
print "Bugger - failed to find edge!\n" ;
|
2697
|
|
|
|
|
|
|
}
|
2698
|
|
|
|
|
|
|
|
2699
|
0
|
|
|
|
|
|
$adl->update_gaps() ;
|
2700
|
|
|
|
|
|
|
|
2701
|
0
|
0
|
|
|
|
|
dump_frames($logo_frames_adl_aref, "LOGO after re-extending") if $DEBUG >= 2 ;
|
2702
|
|
|
|
|
|
|
|
2703
|
|
|
|
|
|
|
} # if got some logo frames left after splice?
|
2704
|
|
|
|
|
|
|
}
|
2705
|
|
|
|
|
|
|
|
2706
|
0
|
|
|
|
|
|
$prev = 0 ;
|
2707
|
|
|
|
|
|
|
}
|
2708
|
|
|
|
|
|
|
}
|
2709
|
|
|
|
|
|
|
|
2710
|
|
|
|
|
|
|
|
2711
|
|
|
|
|
|
|
## update gap's
|
2712
|
0
|
|
|
|
|
|
$adl->update_gaps() ;
|
2713
|
|
|
|
|
|
|
|
2714
|
|
|
|
|
|
|
|
2715
|
|
|
|
|
|
|
## Add processed information
|
2716
|
0
|
|
0
|
|
|
|
my $rise_thresh = $settings_href->{'logo_rise_threshold'} || 1 ;
|
2717
|
0
|
|
0
|
|
|
|
my $fall_thresh = $settings_href->{'logo_fall_threshold'} || 1 ;
|
2718
|
|
|
|
|
|
|
|
2719
|
0
|
0
|
|
|
|
|
dump_frames($logo_frames_adl_aref, "LOGO processed") if $DEBUG >= 2 ;
|
2720
|
|
|
|
|
|
|
|
2721
|
0
|
|
|
|
|
|
csv_add_frames($csv_settings_aref, $frames_adata_aref, $csv_frames_aref, $logo_frames_adl_aref,
|
2722
|
|
|
|
|
|
|
$LOGO_PROCESSED_FIELD, "0:$rise_thresh/$fall_thresh:100", 'match_percent') ;
|
2723
|
|
|
|
|
|
|
|
2724
|
|
|
|
|
|
|
## start by coalescing the contiguous frames
|
2725
|
0
|
|
|
|
|
|
my @frames = coalesce_frames($logo_frames_adl_aref, $settings_href, 0, "logo frames") ;
|
2726
|
|
|
|
|
|
|
|
2727
|
0
|
0
|
|
|
|
|
dump_frames(\@frames, "LOGO coalesced") if $DEBUG >= 2 ;
|
2728
|
|
|
|
|
|
|
|
2729
|
0
|
|
|
|
|
|
csv_add_frames($csv_settings_aref, $frames_adata_aref, $csv_frames_aref, \@frames,
|
2730
|
|
|
|
|
|
|
$LOGO_COALESCED_FIELD, "0:$rise_thresh/$fall_thresh:100", 'match_percent') ;
|
2731
|
|
|
|
|
|
|
|
2732
|
|
|
|
|
|
|
|
2733
|
|
|
|
|
|
|
##NEW###################################################
|
2734
|
|
|
|
|
|
|
#my $reduce_end = 15 * $FPS ; # 15 sec window
|
2735
|
|
|
|
|
|
|
#my $reduce_min_gap = 2 * $FPS ; # need at least 2 sec gap
|
2736
|
|
|
|
|
|
|
|
2737
|
|
|
|
|
|
|
## calc logo match frames - used for frame end reduction
|
2738
|
0
|
|
|
|
|
|
my $logo_match_frames_aref = frames_matching($logo_all_frames_ada_aref, 'match_percent', $settings_href->{'logo_rise_threshold'});
|
2739
|
0
|
|
|
|
|
|
csv_add_frames($csv_settings_aref, $frames_adata_aref, $csv_frames_aref, $logo_match_frames_aref,
|
2740
|
|
|
|
|
|
|
'logo_match', "0:$rise_thresh/$rise_thresh:100", 'match_percent') ;
|
2741
|
|
|
|
|
|
|
|
2742
|
|
|
|
|
|
|
|
2743
|
|
|
|
|
|
|
#dump_frames($logo_match_frames_aref, "LOGO match frames") ;
|
2744
|
|
|
|
|
|
|
|
2745
|
|
|
|
|
|
|
## process end reduction
|
2746
|
0
|
0
|
|
|
|
|
if ($settings_href->{'reduce_end'})
|
2747
|
|
|
|
|
|
|
{
|
2748
|
|
|
|
|
|
|
## reduce the program end to the nearest silent region within
|
2749
|
|
|
|
|
|
|
## the window of the end
|
2750
|
0
|
|
|
|
|
|
foreach my $frame_href (@frames)
|
2751
|
|
|
|
|
|
|
{
|
2752
|
0
|
|
|
|
|
|
frames_reduce_end($frame_href, $logo_match_frames_aref, $settings_href->{'reduce_end'}, $settings_href->{'reduce_min_gap'}) ;
|
2753
|
|
|
|
|
|
|
}
|
2754
|
|
|
|
|
|
|
|
2755
|
0
|
|
|
|
|
|
csv_add_frames($csv_settings_aref, $frames_adata_aref, $csv_frames_aref, \@frames,
|
2756
|
|
|
|
|
|
|
$REDUCED_LOGO_COALESCED_FIELD, "0:$rise_thresh/$fall_thresh:100", 'match_percent') ;
|
2757
|
|
|
|
|
|
|
|
2758
|
|
|
|
|
|
|
}
|
2759
|
|
|
|
|
|
|
|
2760
|
|
|
|
|
|
|
|
2761
|
|
|
|
|
|
|
##NEW###################################################
|
2762
|
|
|
|
|
|
|
|
2763
|
|
|
|
|
|
|
|
2764
|
|
|
|
|
|
|
|
2765
|
|
|
|
|
|
|
## Now glue together blocks
|
2766
|
0
|
|
|
|
|
|
my @blocks ;
|
2767
|
0
|
|
|
|
|
|
my $curr_href=undef ;
|
2768
|
0
|
|
|
|
|
|
foreach my $href (@frames)
|
2769
|
|
|
|
|
|
|
{
|
2770
|
0
|
0
|
|
|
|
|
printf("frame=%d gap=%d (%8.3f) numframes=%d : %d .. %d\n",
|
2771
|
|
|
|
|
|
|
$href->{'frame'},
|
2772
|
|
|
|
|
|
|
$href->{'gap'},
|
2773
|
|
|
|
|
|
|
$href->{'gap'}*1.0 / $FPS,
|
2774
|
|
|
|
|
|
|
numframes($href),
|
2775
|
|
|
|
|
|
|
$href->{'start_pkt'}, $href->{'end_pkt'},
|
2776
|
|
|
|
|
|
|
) if $DEBUG ;
|
2777
|
|
|
|
|
|
|
|
2778
|
|
|
|
|
|
|
# start of new "block"
|
2779
|
0
|
0
|
|
|
|
|
if ($href->{'gap'} >= $settings_href->{'max_gap'})
|
2780
|
|
|
|
|
|
|
{
|
2781
|
0
|
0
|
|
|
|
|
print " + New\n" if $DEBUG ;
|
2782
|
|
|
|
|
|
|
# start new
|
2783
|
0
|
|
|
|
|
|
$curr_href = {
|
2784
|
|
|
|
|
|
|
%$href,
|
2785
|
|
|
|
|
|
|
} ;
|
2786
|
0
|
|
|
|
|
|
push @blocks, $curr_href ;
|
2787
|
|
|
|
|
|
|
}
|
2788
|
|
|
|
|
|
|
else
|
2789
|
|
|
|
|
|
|
{
|
2790
|
0
|
0
|
|
|
|
|
print " - extend : new numframes=",numframes($href),", new gap=$href->{'gap'}\n" if $DEBUG ;
|
2791
|
0
|
0
|
|
|
|
|
if (!$curr_href)
|
2792
|
|
|
|
|
|
|
{
|
2793
|
0
|
0
|
|
|
|
|
print " - + extend NEW\n" if $DEBUG ;
|
2794
|
|
|
|
|
|
|
# start new
|
2795
|
0
|
|
|
|
|
|
$curr_href = {
|
2796
|
|
|
|
|
|
|
%$href,
|
2797
|
|
|
|
|
|
|
} ;
|
2798
|
0
|
|
|
|
|
|
push @blocks, $curr_href ;
|
2799
|
|
|
|
|
|
|
}
|
2800
|
|
|
|
|
|
|
else
|
2801
|
|
|
|
|
|
|
{
|
2802
|
0
|
0
|
|
|
|
|
print " - + extend curr numframes=",numframes($href),"\n" if $DEBUG ;
|
2803
|
|
|
|
|
|
|
# expand end time
|
2804
|
|
|
|
|
|
|
###$curr_href->{'numframes'} += $href->{'numframes'} ;
|
2805
|
0
|
|
|
|
|
|
$curr_href->{'end_pkt'} = $href->{'end_pkt'} ;
|
2806
|
0
|
|
|
|
|
|
$curr_href->{'frame_end'} = $href->{'frame_end'} ;
|
2807
|
|
|
|
|
|
|
}
|
2808
|
|
|
|
|
|
|
}
|
2809
|
|
|
|
|
|
|
}
|
2810
|
0
|
0
|
|
|
|
|
dump_frames(\@blocks, "Logo Blocks") if $DEBUG ;
|
2811
|
|
|
|
|
|
|
|
2812
|
|
|
|
|
|
|
|
2813
|
|
|
|
|
|
|
## Create cut list
|
2814
|
0
|
0
|
|
|
|
|
if (@blocks)
|
2815
|
|
|
|
|
|
|
{
|
2816
|
0
|
|
|
|
|
|
my $cut_href = {'start_pkt'=>0, 'frame'=>0} ;
|
2817
|
0
|
|
|
|
|
|
push @cut_list, $cut_href ;
|
2818
|
0
|
|
|
|
|
|
foreach my $href (@blocks)
|
2819
|
|
|
|
|
|
|
{
|
2820
|
0
|
|
|
|
|
|
$cut_href->{'end_pkt'} = $href->{'start_pkt'}-1 ;
|
2821
|
0
|
|
|
|
|
|
$cut_href->{'frame_end'} = $href->{'frame'}-1 ;
|
2822
|
|
|
|
|
|
|
|
2823
|
0
|
|
|
|
|
|
$cut_href = {
|
2824
|
|
|
|
|
|
|
'start_pkt' => $href->{'end_pkt'}+1,
|
2825
|
|
|
|
|
|
|
'frame' => $href->{'frame_end'}+1,
|
2826
|
|
|
|
|
|
|
} ;
|
2827
|
0
|
|
|
|
|
|
push @cut_list, $cut_href ;
|
2828
|
|
|
|
|
|
|
}
|
2829
|
0
|
|
|
|
|
|
$cut_href->{'end_pkt'} = $total_pkts-1 ;
|
2830
|
0
|
|
|
|
|
|
$cut_href->{'frame_end'} = $total_frames-1 ;
|
2831
|
|
|
|
|
|
|
|
2832
|
|
|
|
|
|
|
# check last (first?) entry has a valid length
|
2833
|
0
|
0
|
|
|
|
|
if ($cut_href->{'frame'} >= $cut_href->{'frame_end'})
|
2834
|
|
|
|
|
|
|
{
|
2835
|
0
|
|
|
|
|
|
pop @cut_list ;
|
2836
|
|
|
|
|
|
|
}
|
2837
|
|
|
|
|
|
|
|
2838
|
|
|
|
|
|
|
}
|
2839
|
|
|
|
|
|
|
|
2840
|
0
|
|
|
|
|
|
return @cut_list ;
|
2841
|
|
|
|
|
|
|
}
|
2842
|
|
|
|
|
|
|
|
2843
|
|
|
|
|
|
|
|
2844
|
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
2845
|
|
|
|
|
|
|
sub _no_once_warning
|
2846
|
|
|
|
|
|
|
{
|
2847
|
0
|
|
|
0
|
|
|
return \%Linux::DVB::DVBT::Advert::Constants::CONSTANTS ;
|
2848
|
|
|
|
|
|
|
}
|
2849
|
|
|
|
|
|
|
|
2850
|
|
|
|
|
|
|
|
2851
|
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
2852
|
|
|
|
|
|
|
sub read_adv
|
2853
|
|
|
|
|
|
|
{
|
2854
|
0
|
|
|
0
|
0
|
|
my ($advfile) = @_ ;
|
2855
|
|
|
|
|
|
|
|
2856
|
0
|
|
|
|
|
|
my %adv ;
|
2857
|
0
|
0
|
|
|
|
|
open my $fh, "<$advfile" or die "Error: unable to read to adv file $advfile : $!" ;
|
2858
|
0
|
|
|
|
|
|
my $line = "" ;
|
2859
|
0
|
|
|
|
|
|
my @head ;
|
2860
|
0
|
|
|
|
|
|
my $file_settings_href = {} ;
|
2861
|
|
|
|
|
|
|
|
2862
|
0
|
|
|
|
|
|
while (defined($line=<$fh>))
|
2863
|
|
|
|
|
|
|
{
|
2864
|
0
|
|
|
|
|
|
chomp $line ;
|
2865
|
0
|
|
|
|
|
|
$line =~ s/#.*$// ;
|
2866
|
0
|
|
|
|
|
|
$line =~ s/\s+$// ;
|
2867
|
0
|
|
|
|
|
|
$line =~ s/^\s+// ;
|
2868
|
0
|
0
|
|
|
|
|
next unless $line ;
|
2869
|
|
|
|
|
|
|
|
2870
|
0
|
|
|
|
|
|
my @fields = split(/,/, $line) ;
|
2871
|
|
|
|
|
|
|
|
2872
|
|
|
|
|
|
|
## Save frames
|
2873
|
|
|
|
|
|
|
# first line is fields definition
|
2874
|
0
|
0
|
|
|
|
|
if (@head)
|
2875
|
|
|
|
|
|
|
{
|
2876
|
|
|
|
|
|
|
# got head, so save data
|
2877
|
0
|
|
|
|
|
|
my $href = {} ;
|
2878
|
0
|
|
|
|
|
|
my $framenum ;
|
2879
|
0
|
|
|
|
|
|
for(my $i=0; $i < scalar(@head); ++$i)
|
2880
|
|
|
|
|
|
|
{
|
2881
|
0
|
|
|
|
|
|
$href->{$head[$i]} = $fields[$i] ;
|
2882
|
|
|
|
|
|
|
|
2883
|
0
|
0
|
|
|
|
|
$framenum = $fields[$i] if $head[$i] eq $FRAME_FIELD ;
|
2884
|
|
|
|
|
|
|
|
2885
|
|
|
|
|
|
|
}
|
2886
|
0
|
0
|
|
|
|
|
$adv{$framenum} = $href if defined($framenum) ;
|
2887
|
|
|
|
|
|
|
}
|
2888
|
|
|
|
|
|
|
else
|
2889
|
|
|
|
|
|
|
{
|
2890
|
|
|
|
|
|
|
# get head
|
2891
|
0
|
|
|
|
|
|
@head = @fields ;
|
2892
|
|
|
|
|
|
|
|
2893
|
0
|
|
|
|
|
|
foreach my $head (@head)
|
2894
|
|
|
|
|
|
|
{
|
2895
|
0
|
|
|
|
|
|
$head =~ s/\s*\[.*$// ;
|
2896
|
|
|
|
|
|
|
}
|
2897
|
|
|
|
|
|
|
}
|
2898
|
|
|
|
|
|
|
}
|
2899
|
0
|
|
|
|
|
|
close $fh ;
|
2900
|
|
|
|
|
|
|
|
2901
|
0
|
|
|
|
|
|
return \%adv ;
|
2902
|
|
|
|
|
|
|
}
|
2903
|
|
|
|
|
|
|
|
2904
|
|
|
|
|
|
|
|
2905
|
|
|
|
|
|
|
#-----------------------------------------------------------------------------
|
2906
|
|
|
|
|
|
|
sub adv_to_cutlist
|
2907
|
|
|
|
|
|
|
{
|
2908
|
0
|
|
|
0
|
0
|
|
my ($adv_href) = @_ ;
|
2909
|
|
|
|
|
|
|
|
2910
|
0
|
|
|
|
|
|
my @cutlist ;
|
2911
|
|
|
|
|
|
|
my $prog ;
|
2912
|
0
|
|
|
|
|
|
my $cut_href ;
|
2913
|
0
|
|
|
|
|
|
foreach my $framenum (sort {$a <=> $b} keys %$adv_href)
|
|
0
|
|
|
|
|
|
|
2914
|
|
|
|
|
|
|
{
|
2915
|
|
|
|
|
|
|
# ____________
|
2916
|
|
|
|
|
|
|
# prog _________| |_______________
|
2917
|
|
|
|
|
|
|
#
|
2918
|
|
|
|
|
|
|
# cut s--------e s---------------e
|
2919
|
|
|
|
|
|
|
#
|
2920
|
|
|
|
|
|
|
# ____________
|
2921
|
|
|
|
|
|
|
# prog |_______________
|
2922
|
|
|
|
|
|
|
#
|
2923
|
|
|
|
|
|
|
# cut s---------------e
|
2924
|
|
|
|
|
|
|
#
|
2925
|
0
|
|
0
|
|
|
|
my $prog_change = !defined($prog) || ($prog != $adv_href->{$framenum}{$PROG_FIELD}) ;
|
2926
|
0
|
|
|
|
|
|
$prog = $adv_href->{$framenum}{$PROG_FIELD} ;
|
2927
|
|
|
|
|
|
|
|
2928
|
|
|
|
|
|
|
# look for start of advert
|
2929
|
0
|
0
|
0
|
|
|
|
if (!$prog && $prog_change )
|
2930
|
|
|
|
|
|
|
{
|
2931
|
0
|
|
|
|
|
|
$cut_href = {
|
2932
|
|
|
|
|
|
|
$FRAME_FIELD => $adv_href->{$framenum}{$FRAME_FIELD},
|
2933
|
|
|
|
|
|
|
$FRAME_END_FIELD => $adv_href->{$framenum}{$FRAME_FIELD},
|
2934
|
|
|
|
|
|
|
$PACKET_FIELD => $adv_href->{$framenum}{$PACKET_FIELD},
|
2935
|
|
|
|
|
|
|
$PACKET_END_FIELD => $adv_href->{$framenum}{$PACKET_END_FIELD},
|
2936
|
|
|
|
|
|
|
} ;
|
2937
|
|
|
|
|
|
|
}
|
2938
|
|
|
|
|
|
|
|
2939
|
|
|
|
|
|
|
# keep track of end of advert
|
2940
|
0
|
0
|
|
|
|
|
if (!$prog)
|
2941
|
|
|
|
|
|
|
{
|
2942
|
0
|
|
|
|
|
|
$cut_href->{$FRAME_END_FIELD} = $adv_href->{$framenum}{$FRAME_FIELD} ;
|
2943
|
0
|
|
|
|
|
|
$cut_href->{$PACKET_END_FIELD} = $adv_href->{$framenum}{$PACKET_END_FIELD} ;
|
2944
|
|
|
|
|
|
|
}
|
2945
|
|
|
|
|
|
|
|
2946
|
|
|
|
|
|
|
# look for end
|
2947
|
0
|
0
|
0
|
|
|
|
if ($prog && $prog_change )
|
2948
|
|
|
|
|
|
|
{
|
2949
|
0
|
0
|
|
|
|
|
if ($cut_href)
|
2950
|
|
|
|
|
|
|
{
|
2951
|
0
|
|
|
|
|
|
push @cutlist, $cut_href ;
|
2952
|
0
|
|
|
|
|
|
$cut_href = undef ;
|
2953
|
|
|
|
|
|
|
}
|
2954
|
|
|
|
|
|
|
}
|
2955
|
|
|
|
|
|
|
}
|
2956
|
|
|
|
|
|
|
|
2957
|
|
|
|
|
|
|
# catch end of video
|
2958
|
0
|
0
|
|
|
|
|
if ($cut_href)
|
2959
|
|
|
|
|
|
|
{
|
2960
|
0
|
|
|
|
|
|
push @cutlist, $cut_href ;
|
2961
|
|
|
|
|
|
|
}
|
2962
|
|
|
|
|
|
|
|
2963
|
0
|
|
|
|
|
|
return @cutlist ;
|
2964
|
|
|
|
|
|
|
}
|
2965
|
|
|
|
|
|
|
|
2966
|
|
|
|
|
|
|
# ============================================================================================
|
2967
|
|
|
|
|
|
|
# END OF PACKAGE
|
2968
|
|
|
|
|
|
|
|
2969
|
|
|
|
|
|
|
1;
|
2970
|
|
|
|
|
|
|
|
2971
|
|
|
|
|
|
|
#Start of analyse: Memory used 50.6484375 MB (since last call 50.6484375 MB)
|
2972
|
|
|
|
|
|
|
# + created ADA arrays: Memory used 179.1953125 MB (since last call 128.546875 MB)
|
2973
|
|
|
|
|
|
|
# + got settings: Memory used 179.19921875 MB (since last call 0.00390625 MB)
|
2974
|
|
|
|
|
|
|
#Black detect: Memory used 179.19921875 MB (since last call 0 MB)
|
2975
|
|
|
|
|
|
|
#Logo detect: Memory used 189.3984375 MB (since last call 10.19921875 MB)
|
2976
|
|
|
|
|
|
|
#Detect end: Memory used 940.23046875 MB (since last call 750.83203125 MB)
|
2977
|
|
|
|
|
|
|
#End of analyse: Memory used 1313.71484375 MB (since last call 373.484375 MB)
|
2978
|
|
|
|
|
|
|
|
2979
|
|
|
|
|
|
|
__END__
|