source: main/trunk/greenstone2/perllib/cpan/Image/ExifTool/DV.pm@ 34921

Last change on this file since 34921 was 34921, checked in by anupama, 3 years ago

Committing the improvements to EmbeddedMetaPlugin's processing of Keywords vs other metadata fields. Keywords were literally stored as arrays of words rather than phrases in PDFs (at least in Diego's sample PDF), whereas other meta fields like Subjects and Creators stored them as arrays of phrases. To get both to work, Kathy updated EXIF to a newer version, to retrieve the actual EXIF values stored in the PDF. And Kathy and Dr Bainbridge came up with a new option that I added called apply_join_before_split_to_metafields that's a regex which can list the metadata fields to apply the join_before_split to and whcih previously always got applied to all metadata fields. Now it's applied to any *Keywords metafields by default, as that's the metafield we have experience of that behaves differently to the others, as it stores by word instead of phrases. Tested on Diego's sample PDF. Diego has double-checked it to works on his sample PDF too, setting the split char to ; and turning on the join_before_split and leaving apply_join_before_split_to_metafields at its default of .*Keywords. File changes are strings.properties for the tooltip, the plugin introducing the option and working with it and Kathy's EXIF updates affecting cpan/File and cpan/Image.

  • Property svn:executable set to *
File size: 9.8 KB
Line 
1#------------------------------------------------------------------------------
2# File: DV.pm
3#
4# Description: Read DV meta information
5#
6# Revisions: 2010/12/24 - P. Harvey Created
7#
8# References: 1) http://www.ffmpeg.org/
9# 2) http://dvswitch.alioth.debian.org/wiki/DV_format/
10#------------------------------------------------------------------------------
11
12package Image::ExifTool::DV;
13
14use strict;
15use vars qw($VERSION);
16use Image::ExifTool qw(:DataAccess :Utils);
17
18$VERSION = '1.02';
19
20# DV profiles (ref 1)
21my @dvProfiles = (
22 {
23 DSF => 0,
24 VideoSType => 0x0,
25 FrameSize => 120000,
26 VideoFormat => 'IEC 61834, SMPTE-314M - 525/60 (NTSC)',
27 Colorimetry => '4:1:1',
28 FrameRate => 30000/1001,
29 ImageHeight => 480,
30 ImageWidth => 720,
31 },{
32 DSF => 1,
33 VideoSType => 0x0,
34 FrameSize => 144000,
35 VideoFormat => 'IEC 61834 - 625/50 (PAL)',
36 Colorimetry => '4:2:0',
37 FrameRate => 25/1,
38 ImageHeight => 576,
39 ImageWidth => 720,
40 },{
41 DSF => 1,
42 VideoSType => 0x0,
43 FrameSize => 144000,
44 VideoFormat => 'SMPTE-314M - 625/50 (PAL)',
45 Colorimetry => '4:1:1',
46 FrameRate => 25/1,
47 ImageHeight => 576,
48 ImageWidth => 720,
49 },{
50 DSF => 0,
51 VideoSType => 0x4,
52 FrameSize => 240000,
53 VideoFormat => 'DVCPRO50: SMPTE-314M - 525/60 (NTSC) 50 Mbps',
54 Colorimetry => '4:2:2',
55 FrameRate => 30000/1001,
56 ImageHeight => 480,
57 ImageWidth => 720,
58 },{
59 DSF => 1,
60 VideoSType => 0x4,
61 FrameSize => 288000,
62 VideoFormat => 'DVCPRO50: SMPTE-314M - 625/50 (PAL) 50 Mbps',
63 Colorimetry => '4:2:2',
64 FrameRate => 25/1,
65 ImageHeight => 576,
66 ImageWidth => 720,
67 },{
68 DSF => 0,
69 VideoSType => 0x14,
70 FrameSize => 480000,
71 VideoFormat => 'DVCPRO HD: SMPTE-370M - 1080i60 100 Mbps',
72 Colorimetry => '4:2:2',
73 FrameRate => 30000/1001,
74 ImageHeight => 1080,
75 ImageWidth => 1280,
76 },{
77 DSF => 1,
78 VideoSType => 0x14,
79 FrameSize => 576000,
80 VideoFormat => 'DVCPRO HD: SMPTE-370M - 1080i50 100 Mbps',
81 Colorimetry => '4:2:2',
82 FrameRate => 25/1,
83 ImageHeight => 1080,
84 ImageWidth => 1440,
85 },{
86 DSF => 0,
87 VideoSType => 0x18,
88 FrameSize => 240000,
89 VideoFormat => 'DVCPRO HD: SMPTE-370M - 720p60 100 Mbps',
90 Colorimetry => '4:2:2',
91 FrameRate => 60000/1001,
92 ImageHeight => 720,
93 ImageWidth => 960,
94 },{
95 DSF => 1,
96 VideoSType => 0x18,
97 FrameSize => 288000,
98 VideoFormat => 'DVCPRO HD: SMPTE-370M - 720p50 100 Mbps',
99 Colorimetry => '4:2:2',
100 FrameRate => 50/1,
101 ImageHeight => 720,
102 ImageWidth => 960,
103 },{
104 DSF => 1,
105 VideoSType => 0x1,
106 FrameSize => 144000,
107 VideoFormat => 'IEC 61883-5 - 625/50 (PAL)',
108 Colorimetry => '4:2:0',
109 FrameRate => 25/1,
110 ImageHeight => 576,
111 ImageWidth => 720,
112 },
113);
114
115# tags to extract, in the order we want to extract them
116my @dvTags = (
117 'DateTimeOriginal', 'ImageWidth', 'ImageHeight', 'Duration',
118 'TotalBitrate', 'VideoFormat', 'VideoScanType', 'FrameRate',
119 'AspectRatio', 'Colorimetry', 'AudioChannels', 'AudioSampleRate',
120 'AudioBitsPerSample',
121);
122
123# DV tags
124%Image::ExifTool::DV::Main = (
125 GROUPS => { 2 => 'Video' },
126 VARS => { NO_ID => 1 },
127 NOTES => 'The following tags are extracted from DV videos.',
128 DateTimeOriginal => {
129 Description => 'Date/Time Original',
130 Groups => { 2 => 'Time' },
131 PrintConv => '$self->ConvertDateTime($val)',
132 },
133 ImageWidth => { },
134 ImageHeight => { },
135 Duration => { PrintConv => 'ConvertDuration($val)' },
136 TotalBitrate => { PrintConv => 'ConvertBitrate($val)' },
137 VideoFormat => { },
138 VideoScanType => { },
139 FrameRate => { PrintConv => 'int($val * 1000 + 0.5) / 1000' },
140 AspectRatio => { },
141 Colorimetry => { },
142 AudioChannels => { Groups => { 2 => 'Audio' } },
143 AudioSampleRate => { Groups => { 2 => 'Audio' } },
144 AudioBitsPerSample => { Groups => { 2 => 'Audio' } },
145);
146
147#------------------------------------------------------------------------------
148# Read information in a DV file (ref 1)
149# Inputs: 0) ExifTool ref, 1) dirInfo ref
150# Returns: 1 on success, 0 if this wasn't a valid DV file
151sub ProcessDV($$)
152{
153 my ($et, $dirInfo) = @_;
154 local $_;
155 my $raf = $$dirInfo{RAF};
156 my ($buff, $start, $profile, $tag, $i, $j);
157
158 $raf->Read($buff, 12000) or return 0;
159 if ($buff =~ /\x1f\x07\0[\x3f\xbf]/sg) {
160 $start = pos($buff) - 4;
161 } else {
162 while ($buff =~ /[\0\xff]\x3f\x07\0.{76}\xff\x3f\x07\x01/sg) {
163 next if pos($buff) - 163 < 0;
164 $start = pos($buff) - 163;
165 last;
166 }
167 return 0 unless defined $start;
168 }
169 my $len = length $buff;
170 # must at least have a full DIF header
171 return 0 if $start + 80 * 6 > $len;
172
173 $et->SetFileType();
174
175 my $pos = $start;
176 my $dsf = (Get8u(\$buff, $pos + 3) & 0x80) >> 7;
177 my $stype = Get8u(\$buff, $pos + 80*5 + 48 + 3) & 0x1f;
178
179 # 576i50 25Mbps 4:1:1 is a special case
180 if ($dsf == 1 && $stype == 0 && Get8u(\$buff, 4) & 0x07) {
181 $profile = $dvProfiles[2];
182 } else {
183 foreach (@dvProfiles) {
184 next unless $dsf == $$_{DSF} and $stype == $$_{VideoSType};
185 $profile = $_;
186 last;
187 }
188 $profile or $et->Warn("Unrecognized DV profile"), return 1;
189 }
190 my $tagTablePtr = GetTagTable('Image::ExifTool::DV::Main');
191
192 # calculate total bit rate and duration
193 my $byteRate = $$profile{FrameSize} * $$profile{FrameRate};
194 my $fileSize = $$et{VALUE}{FileSize};
195 $$profile{TotalBitrate} = 8 * $byteRate;
196 $$profile{Duration} = $fileSize / $byteRate if defined $fileSize;
197
198 # read DVPack metadata from the VAUX DIF's to extract video tags
199 delete $$profile{DateTimeOriginal};
200 delete $$profile{AspectRatio};
201 delete $$profile{VideoScanType};
202 my ($date, $time, $is16_9, $interlace);
203 for ($i=1; $i<6; ++$i) {
204 $pos += 80;
205 my $type = Get8u(\$buff, $pos);
206 next unless ($type & 0xf0) == 0x50; # look for VAUX types
207 for ($j=0; $j<15; ++$j) {
208 my $p = $pos + $j * 5 + 3;
209 $type = Get8u(\$buff, $p);
210 if ($type == 0x61) { # video control
211 my $apt = Get8u(\$buff, $start + 4) & 0x07;
212 my $t = Get8u(\$buff, $p + 2);
213 $is16_9 = (($t & 0x07) == 0x02 or (not $apt and ($t & 0x07) == 0x07));
214 $interlace = Get8u(\$buff, $p + 3) & 0x10; # (ref 2)
215 } elsif ($type == 0x62) { # date
216 # mask off unused bits
217 my @d = unpack('C*', substr($buff, $p + 1, 4));
218 # (ignore timezone in byte 0 until we can test this properly - see ref 2)
219 $date = sprintf('%.2x:%.2x:%.2x', $d[3], $d[2] & 0x1f, $d[1] & 0x3f);
220 if ($date =~ /[a-f]/) {
221 undef $date; # invalid date
222 } else {
223 # add century (this will work until 2089)
224 $date = ($date lt '9' ? '20' : '19') . $date;
225 }
226 undef $time;
227 } elsif ($type == 0x63 and $date) { # time
228 # (ignore frames past second in byte 0 for now - see ref 2)
229 my $val = Get32u(\$buff, $p + 1) & 0x007f7f3f;
230 my @t = unpack('C*', substr($buff, $p + 1, 4));
231 $time = sprintf('%.2x:%.2x:%.2x', $t[3] & 0x3f, $t[2] & 0x7f, $t[1] & 0x7f);
232 last;
233 } else {
234 undef $time; # must be consecutive
235 }
236 }
237 }
238 if ($date and $time) {
239 $$profile{DateTimeOriginal} = "$date $time";
240 if (defined $is16_9) {
241 $$profile{AspectRatio} = $is16_9 ? '16:9' : '4:3';
242 $$profile{VideoScanType} = $interlace ? 'Interlaced' : 'Progressive';
243 }
244 }
245
246 # read audio tags if available
247 delete $$profile{AudioSampleRate};
248 delete $$profile{AudioBitsPerSample};
249 delete $$profile{AudioChannels};
250 $pos = $start + 80*6 + 80*16*3 + 3;
251 if ($pos + 4 < $len and Get8u(\$buff, $pos) == 0x50) {
252 my $smpls = Get8u(\$buff, $pos + 1);
253 my $freq = (Get8u(\$buff, $pos + 4) >> 3) & 0x07;
254 my $stype = Get8u(\$buff, $pos + 3) & 0x1f;
255 my $quant = Get8u(\$buff, $pos + 4) & 0x07;
256 if ($freq < 3) {
257 $$profile{AudioSampleRate} = {0=>48000, 1=>44100, 2=>32000}->{$freq};
258 }
259 if ($stype < 3) {
260 $stype = 2 if $stype == 0 and $quant and $freq == 2;
261 $$profile{AudioChannels} = {0=>2, 1=>0, 2=>4, 3=>8}->{$stype};
262 }
263 $$profile{AudioBitsPerSample} = $quant ? 12 : 16;
264 }
265
266 # save our metadata
267 foreach $tag (@dvTags) {
268 next unless defined $$profile{$tag};
269 $et->HandleTag($tagTablePtr, $tag, $$profile{$tag});
270 }
271
272 return 1;
273}
274
2751; # end
276
277__END__
278
279=head1 NAME
280
281Image::ExifTool::DV - Read DV meta information
282
283=head1 SYNOPSIS
284
285This module is used by Image::ExifTool
286
287=head1 DESCRIPTION
288
289This module contains definitions required by Image::ExifTool to read meta
290information from DV (raw Digital Video) files.
291
292=head1 AUTHOR
293
294Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
295
296This library is free software; you can redistribute it and/or modify it
297under the same terms as Perl itself.
298
299=head1 REFERENCES
300
301=over 4
302
303=item L<http://ffmpeg.org/>
304
305=item L<http://dvswitch.alioth.debian.org/wiki/DV_format/>
306
307=back
308
309=head1 SEE ALSO
310
311L<Image::ExifTool::TagNames/DV Tags>,
312L<Image::ExifTool(3pm)|Image::ExifTool>
313
314=cut
315
Note: See TracBrowser for help on using the repository browser.