source: main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MPEG.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.

File size: 22.3 KB
Line 
1#------------------------------------------------------------------------------
2# File: MPEG.pm
3#
4# Description: Read MPEG-1 and MPEG-2 meta information
5#
6# Revisions: 05/11/2006 - P. Harvey Created
7#
8# References: 1) http://www.mp3-tech.org/
9# 2) http://www.getid3.org/
10# 3) http://dvd.sourceforge.net/dvdinfo/dvdmpeg.html
11# 4) http://ffmpeg.org/
12# 5) http://sourceforge.net/projects/mediainfo/
13#------------------------------------------------------------------------------
14
15package Image::ExifTool::MPEG;
16
17use strict;
18use vars qw($VERSION);
19use Image::ExifTool qw(:DataAccess :Utils);
20
21$VERSION = '1.16';
22
23%Image::ExifTool::MPEG::Audio = (
24 GROUPS => { 2 => 'Audio' },
25 'Bit11-12' => {
26 Name => 'MPEGAudioVersion',
27 RawConv => '$self->{MPEG_Vers} = $val',
28 PrintConv => {
29 0 => 2.5,
30 2 => 2,
31 3 => 1,
32 },
33 },
34 'Bit13-14' => {
35 Name => 'AudioLayer',
36 RawConv => '$self->{MPEG_Layer} = $val',
37 PrintConv => {
38 1 => 3,
39 2 => 2,
40 3 => 1,
41 },
42 },
43 # Bit 15 indicates CRC protection
44 'Bit16-19' => [
45 {
46 Name => 'AudioBitrate',
47 Condition => '$self->{MPEG_Vers} == 3 and $self->{MPEG_Layer} == 3',
48 Notes => 'version 1, layer 1',
49 PrintConvColumns => 3,
50 ValueConv => {
51 0 => 'free',
52 1 => 32000,
53 2 => 64000,
54 3 => 96000,
55 4 => 128000,
56 5 => 160000,
57 6 => 192000,
58 7 => 224000,
59 8 => 256000,
60 9 => 288000,
61 10 => 320000,
62 11 => 352000,
63 12 => 384000,
64 13 => 416000,
65 14 => 448000,
66 },
67 PrintConv => 'ConvertBitrate($val)',
68 },
69 {
70 Name => 'AudioBitrate',
71 Condition => '$self->{MPEG_Vers} == 3 and $self->{MPEG_Layer} == 2',
72 Notes => 'version 1, layer 2',
73 PrintConvColumns => 3,
74 ValueConv => {
75 0 => 'free',
76 1 => 32000,
77 2 => 48000,
78 3 => 56000,
79 4 => 64000,
80 5 => 80000,
81 6 => 96000,
82 7 => 112000,
83 8 => 128000,
84 9 => 160000,
85 10 => 192000,
86 11 => 224000,
87 12 => 256000,
88 13 => 320000,
89 14 => 384000,
90 },
91 PrintConv => 'ConvertBitrate($val)',
92 },
93 {
94 Name => 'AudioBitrate',
95 Condition => '$self->{MPEG_Vers} == 3 and $self->{MPEG_Layer} == 1',
96 Notes => 'version 1, layer 3',
97 PrintConvColumns => 3,
98 ValueConv => {
99 0 => 'free',
100 1 => 32000,
101 2 => 40000,
102 3 => 48000,
103 4 => 56000,
104 5 => 64000,
105 6 => 80000,
106 7 => 96000,
107 8 => 112000,
108 9 => 128000,
109 10 => 160000,
110 11 => 192000,
111 12 => 224000,
112 13 => 256000,
113 14 => 320000,
114 },
115 PrintConv => 'ConvertBitrate($val)',
116 },
117 {
118 Name => 'AudioBitrate',
119 Condition => '$self->{MPEG_Vers} != 3 and $self->{MPEG_Layer} == 3',
120 Notes => 'version 2 or 2.5, layer 1',
121 PrintConvColumns => 3,
122 ValueConv => {
123 0 => 'free',
124 1 => 32000,
125 2 => 48000,
126 3 => 56000,
127 4 => 64000,
128 5 => 80000,
129 6 => 96000,
130 7 => 112000,
131 8 => 128000,
132 9 => 144000,
133 10 => 160000,
134 11 => 176000,
135 12 => 192000,
136 13 => 224000,
137 14 => 256000,
138 },
139 PrintConv => 'ConvertBitrate($val)',
140 },
141 {
142 Name => 'AudioBitrate',
143 Condition => '$self->{MPEG_Vers} != 3 and $self->{MPEG_Layer}',
144 Notes => 'version 2 or 2.5, layer 2 or 3',
145 PrintConvColumns => 3,
146 ValueConv => {
147 0 => 'free',
148 1 => 8000,
149 2 => 16000,
150 3 => 24000,
151 4 => 32000,
152 5 => 40000,
153 6 => 48000,
154 7 => 56000,
155 8 => 64000,
156 9 => 80000,
157 10 => 96000,
158 11 => 112000,
159 12 => 128000,
160 13 => 144000,
161 14 => 160000,
162 },
163 PrintConv => 'ConvertBitrate($val)',
164 },
165 ],
166 'Bit20-21' => [
167 {
168 Name => 'SampleRate',
169 Condition => '$self->{MPEG_Vers} == 3',
170 Notes => 'version 1',
171 PrintConv => {
172 0 => 44100,
173 1 => 48000,
174 2 => 32000,
175 },
176 },
177 {
178 Name => 'SampleRate',
179 Condition => '$self->{MPEG_Vers} == 2',
180 Notes => 'version 2',
181 PrintConv => {
182 0 => 22050,
183 1 => 24000,
184 2 => 16000,
185 },
186 },
187 {
188 Name => 'SampleRate',
189 Condition => '$self->{MPEG_Vers} == 0',
190 Notes => 'version 2.5',
191 PrintConv => {
192 0 => 11025,
193 1 => 12000,
194 2 => 8000,
195 },
196 },
197 ],
198 # Bit 22 - padding flag
199 # Bit 23 - private bit
200 'Bit24-25' => {
201 Name => 'ChannelMode',
202 RawConv => '$self->{MPEG_Mode} = $val',
203 PrintConv => {
204 0 => 'Stereo',
205 1 => 'Joint Stereo',
206 2 => 'Dual Channel',
207 3 => 'Single Channel',
208 },
209 },
210 'Bit26' => {
211 Name => 'MSStereo',
212 Condition => '$self->{MPEG_Layer} == 1',
213 Notes => 'layer 3',
214 PrintConv => { 0 => 'Off', 1 => 'On' },
215 },
216 'Bit27' => {
217 Name => 'IntensityStereo',
218 Condition => '$self->{MPEG_Layer} == 1',
219 Notes => 'layer 3',
220 PrintConv => { 0 => 'Off', 1 => 'On' },
221 },
222 'Bit26-27' => {
223 Name => 'ModeExtension',
224 Condition => '$self->{MPEG_Layer} > 1',
225 Notes => 'layer 1 or 2',
226 PrintConv => {
227 0 => 'Bands 4-31',
228 1 => 'Bands 8-31',
229 2 => 'Bands 12-31',
230 3 => 'Bands 16-31',
231 },
232 },
233 'Bit28' => {
234 Name => 'CopyrightFlag',
235 PrintConv => {
236 0 => 'False',
237 1 => 'True',
238 },
239 },
240 'Bit29' => {
241 Name => 'OriginalMedia',
242 PrintConv => {
243 0 => 'False',
244 1 => 'True',
245 },
246 },
247 'Bit30-31' => {
248 Name => 'Emphasis',
249 PrintConv => {
250 0 => 'None',
251 1 => '50/15 ms',
252 2 => 'reserved',
253 3 => 'CCIT J.17',
254 },
255 },
256);
257
258%Image::ExifTool::MPEG::Video = (
259 GROUPS => { 2 => 'Video' },
260 'Bit00-11' => 'ImageWidth',
261 'Bit12-23' => 'ImageHeight',
262 'Bit24-27' => {
263 Name => 'AspectRatio',
264 ValueConv => {
265 1 => 1,
266 2 => 0.6735,
267 3 => 0.7031,
268 4 => 0.7615,
269 5 => 0.8055,
270 6 => 0.8437,
271 7 => 0.8935,
272 8 => 0.9157,
273 9 => 0.9815,
274 10 => 1.0255,
275 11 => 1.0695,
276 12 => 1.0950,
277 13 => 1.1575,
278 14 => 1.2015,
279 },
280 PrintConv => {
281 1 => '1:1',
282 0.6735 => '0.6735',
283 0.7031 => '16:9, 625 line, PAL',
284 0.7615 => '0.7615',
285 0.8055 => '0.8055',
286 0.8437 => '16:9, 525 line, NTSC',
287 0.8935 => '0.8935',
288 0.9157 => '4:3, 625 line, PAL, CCIR601',
289 0.9815 => '0.9815',
290 1.0255 => '1.0255',
291 1.0695 => '1.0695',
292 1.0950 => '4:3, 525 line, NTSC, CCIR601',
293 1.1575 => '1.1575',
294 1.2015 => '1.2015',
295 },
296 },
297 'Bit28-31' => {
298 Name => 'FrameRate',
299 ValueConv => {
300 1 => 23.976,
301 2 => 24,
302 3 => 25,
303 4 => 29.97,
304 5 => 30,
305 6 => 50,
306 7 => 59.94,
307 8 => 60,
308 },
309 PrintConv => '"$val fps"',
310 },
311 'Bit32-49' => {
312 Name => 'VideoBitrate',
313 ValueConv => '$val eq 0x3ffff ? "Variable" : $val * 400',
314 PrintConv => 'ConvertBitrate($val)',
315 },
316 # these tags not very interesting
317 #'Bit50' => 'MarkerBit',
318 #'Bit51-60' => 'VBVBufferSize',
319 #'Bit61' => 'ConstrainedParamFlag',
320 #'Bit62' => 'IntraQuantMatrixFlag',
321);
322
323%Image::ExifTool::MPEG::Xing = (
324 GROUPS => { 2 => 'Audio' },
325 VARS => { NO_ID => 1 },
326 NOTES => 'These tags are extracted from the Xing/Info frame.',
327 1 => { Name => 'VBRFrames' },
328 2 => { Name => 'VBRBytes' },
329 3 => { Name => 'VBRScale' },
330 4 => { Name => 'Encoder' },
331 5 => { Name => 'LameVBRQuality' },
332 6 => { Name => 'LameQuality' },
333 7 => { # (for documentation only)
334 Name => 'LameHeader',
335 SubDirectory => { TagTable => 'Image::ExifTool::MPEG::Lame' },
336 },
337);
338
339# Lame header tags (ref 5)
340%Image::ExifTool::MPEG::Lame = (
341 PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
342 GROUPS => { 2 => 'Audio' },
343 NOTES => 'Tags extracted from Lame 3.90 or later header.',
344 9 => {
345 Name => 'LameMethod',
346 Mask => 0x0f,
347 PrintConv => {
348 1 => 'CBR',
349 2 => 'ABR',
350 3 => 'VBR (old/rh)',
351 4 => 'VBR (new/mtrh)',
352 5 => 'VBR (old/rh)',
353 6 => 'VBR',
354 8 => 'CBR (2-pass)',
355 9 => 'ABR (2-pass)',
356 },
357 },
358 10 => {
359 Name => 'LameLowPassFilter',
360 ValueConv => '$val * 100',
361 PrintConv => '($val / 1000) . " kHz"',
362 },
363 # 19 - EncodingFlags
364 20 => {
365 Name => 'LameBitrate',
366 ValueConv => '$val * 1000',
367 PrintConv => 'ConvertBitrate($val)',
368 },
369 24 => {
370 Name => 'LameStereoMode',
371 Mask => 0x1c,
372 PrintConv => {
373 0 => 'Mono',
374 1 => 'Stereo',
375 2 => 'Dual Channels',
376 3 => 'Joint Stereo',
377 4 => 'Forced Joint Stereo',
378 6 => 'Auto',
379 7 => 'Intensity Stereo',
380 },
381 },
382);
383
384# composite tags
385%Image::ExifTool::MPEG::Composite = (
386 Duration => {
387 Groups => { 2 => 'Video' },
388 Require => {
389 0 => 'FileSize',
390 },
391 Desire => {
392 1 => 'ID3Size',
393 2 => 'MPEG:AudioBitrate',
394 3 => 'MPEG:VideoBitrate',
395 4 => 'MPEG:VBRFrames',
396 5 => 'MPEG:SampleRate',
397 6 => 'MPEG:MPEGAudioVersion',
398 },
399 Priority => -1, # (don't want to replace any other Duration tag)
400 ValueConv => q{
401 if ($val[4] and defined $val[5] and defined $val[6]) {
402 # calculate from number of VBR audio frames
403 my $mfs = $prt[5] / ($val[6] == 3 ? 144 : 72);
404 # calculate using VBR length
405 return 8 * $val[4] / $mfs;
406 }
407 # calculate duration as file size divided by total bitrate
408 # (note: this is only approximate!)
409 return undef unless $val[2] or $val[3];
410 return undef if $val[2] and not $val[2] =~ /^\d+$/;
411 return undef if $val[3] and not $val[3] =~ /^\d+$/;
412 return (8 * ($val[0] - ($val[1]||0))) / (($val[2]||0) + ($val[3]||0));
413 },
414 PrintConv => 'ConvertDuration($val) . " (approx)"',
415 },
416 AudioBitrate => {
417 Groups => { 2 => 'Audio' },
418 Notes => 'calculated for variable-bitrate MPEG audio',
419 Require => {
420 0 => 'MPEG:MPEGAudioVersion',
421 1 => 'MPEG:SampleRate',
422 2 => 'MPEG:VBRBytes',
423 3 => 'MPEG:VBRFrames',
424 },
425 ValueConv => q{
426 return undef unless $val[3];
427 my $mfs = $prt[1] / ($val[0] == 3 ? 144 : 72);
428 return $mfs * $val[2] / $val[3];
429 },
430 PrintConv => 'ConvertBitrate($val)',
431 },
432);
433
434# add our composite tags
435Image::ExifTool::AddCompositeTags('Image::ExifTool::MPEG');
436
437
438#------------------------------------------------------------------------------
439# Process information in an MPEG audio or video frame header
440# Inputs: 0) ExifTool object ref, 1) tag table ref, 2-N) list of 32-bit data words
441sub ProcessFrameHeader($$@)
442{
443 my ($et, $tagTablePtr, @data) = @_;
444 my $tag;
445 foreach $tag (sort keys %$tagTablePtr) {
446 next unless $tag =~ /^Bit(\d{2})-?(\d{2})?/;
447 my ($b1, $b2) = ($1, $2 || $1);
448 my $index = int($b1 / 32);
449 my $word = $data[$index];
450 my $mask = 0;
451 foreach (0 .. ($b2 - $b1)) {
452 $mask += (1 << $_);
453 }
454 my $val = ($word >> (31 + 32*$index - $b2)) & $mask;
455 $et->HandleTag($tagTablePtr, $tag, $val);
456 }
457}
458
459#------------------------------------------------------------------------------
460# Read MPEG audio frame header
461# Inputs: 0) ExifTool object reference, 1) Reference to audio data
462# 2) flag set if we are trying to recognized MP3 file only
463# Returns: 1 on success, 0 if no audio header was found
464sub ParseMPEGAudio($$;$)
465{
466 my ($et, $buffPt, $mp3) = @_;
467 my ($word, $pos);
468 my $ext = $$et{FILE_EXT} || '';
469
470 for (;;) {
471 # find frame sync
472 return 0 unless $$buffPt =~ m{(\xff.{3})}sg;
473 $word = unpack('N', $1); # get audio frame header word
474 unless (($word & 0xffe00000) == 0xffe00000) {
475 pos($$buffPt) = pos($$buffPt) - 2; # next possible location for frame sync
476 next;
477 }
478 # validate header as much as possible
479 if (($word & 0x180000) == 0x080000 or # 01 is a reserved version ID
480 ($word & 0x060000) == 0x000000 or # 00 is a reserved layer description
481 ($word & 0x00f000) == 0x000000 or # 0000 is the "free" bitrate index
482 ($word & 0x00f000) == 0x00f000 or # 1111 is a bad bitrate index
483 ($word & 0x000c00) == 0x000c00 or # 11 is a reserved sampling frequency
484 ($word & 0x000003) == 0x000002 or # 10 is a reserved emphasis
485 (($mp3 and ($word & 0x060000) != 0x020000))) # must be layer 3 for MP3
486 {
487 # give up easily unless this really should be an MP3 file
488 return 0 unless $ext eq 'MP3';
489 pos($$buffPt) = pos($$buffPt) - 1;
490 next;
491 }
492 $pos = pos($$buffPt);
493 last;
494 }
495 # set file type if not done already
496 $et->SetFileType();
497
498 my $tagTablePtr = GetTagTable('Image::ExifTool::MPEG::Audio');
499 ProcessFrameHeader($et, $tagTablePtr, $word);
500
501 # extract the VBR information (ref MP3::Info)
502 my ($v, $m) = ($$et{MPEG_Vers}, $$et{MPEG_Mode});
503 while (defined $v and defined $m) {
504 my $len = length $$buffPt;
505 $pos += $v == 3 ? ($m == 3 ? 17 : 32) : ($m == 3 ? 9 : 17);
506 last if $pos + 8 > $len;
507 my $buff = substr($$buffPt, $pos, 8);
508 last unless $buff =~ /^(Xing|Info)/;
509 my $xingTable = GetTagTable('Image::ExifTool::MPEG::Xing');
510 my $vbrScale;
511 my $flags = unpack('x4N', $buff);
512 my $isVBR = ($buff !~ /^Info/); # Info frame is not VBR (ref 5)
513 $pos += 8;
514 if ($flags & 0x01) { # VBRFrames
515 last if $pos + 4 > $len;
516 $et->HandleTag($xingTable, 1, unpack("x${pos}N", $$buffPt)) if $isVBR;
517 $pos += 4;
518 }
519 if ($flags & 0x02) { # VBRBytes
520 last if $pos + 4 > $len;
521 $et->HandleTag($xingTable, 2, unpack("x${pos}N", $$buffPt)) if $isVBR;
522 $pos += 4;
523 }
524 if ($flags & 0x04) { # VBR_TOC
525 last if $pos + 100 > $len;
526 # (ignore toc for now)
527 $pos += 100;
528 }
529 if ($flags & 0x08) { # VBRScale
530 last if $pos + 4 > $len;
531 $vbrScale = unpack("x${pos}N", $$buffPt);
532 $et->HandleTag($xingTable, 3, $vbrScale) if $isVBR;
533 $pos += 4;
534 }
535 # process Lame header (ref 5)
536 if ($flags & 0x10) { # Lame
537 last if $pos + 348 > $len;
538 } elsif ($pos + 4 <= $len) {
539 my $lib = substr($$buffPt, $pos, 4);
540 unless ($lib eq 'LAME' or $lib eq 'GOGO') {
541 # attempt to identify other encoders
542 my $n;
543 if (index($$buffPt, 'RCA mp3PRO Encoder') >= 0) {
544 $lib = 'RCA mp3PRO';
545 } elsif (($n = index($$buffPt, 'THOMSON mp3PRO Encoder')) >= 0) {
546 $lib = 'Thomson mp3PRO';
547 $n += 22;
548 $lib .= ' ' . substr($$buffPt, $n, 6) if length($$buffPt) - $n >= 6;
549 } elsif (index($$buffPt, 'MPGE') >= 0) {
550 $lib = 'Gogo (<3.0)';
551 } else {
552 last;
553 }
554 $et->HandleTag($xingTable, 4, $lib);
555 last;
556 }
557 }
558 my $lameLen = $len - $pos;
559 last if $lameLen < 9;
560 my $enc = substr($$buffPt, $pos, 9);
561 if ($enc ge 'LAME3.90') {
562 $et->HandleTag($xingTable, 4, $enc);
563 if ($vbrScale <= 100) {
564 $et->HandleTag($xingTable, 5, int((100 - $vbrScale) / 10));
565 $et->HandleTag($xingTable, 6, (100 - $vbrScale) % 10);
566 }
567 my %dirInfo = (
568 DataPt => $buffPt,
569 DirStart => $pos,
570 DirLen => length($$buffPt) - $pos,
571 );
572 my $subTablePtr = GetTagTable('Image::ExifTool::MPEG::Lame');
573 $et->ProcessDirectory(\%dirInfo, $subTablePtr);
574 } else {
575 $et->HandleTag($xingTable, 4, substr($$buffPt, $pos, 20));
576 }
577 last; # (didn't want to loop anyway)
578 }
579
580 return 1;
581}
582
583#------------------------------------------------------------------------------
584# Read MPEG video frame header
585# Inputs: 0) ExifTool object reference, 1) Reference to video data
586# Returns: 1 on success, 0 if no video header was found
587sub ProcessMPEGVideo($$)
588{
589 my ($et, $buffPt) = @_;
590
591 return 0 unless length $$buffPt >= 4;
592 my ($w1, $w2) = unpack('N2', $$buffPt);
593 # validate as much as possible
594 if (($w1 & 0x000000f0) == 0x00000000 or # 0000 is a forbidden aspect ratio
595 ($w1 & 0x000000f0) == 0x000000f0 or # 1111 is a reserved aspect ratio
596 ($w1 & 0x0000000f) == 0 or # frame rate must be 1-8
597 ($w1 & 0x0000000f) > 8)
598 {
599 return 0;
600 }
601 # set file type if not done already
602 $et->SetFileType('MPEG') unless $$et{VALUE}{FileType};
603
604 my $tagTablePtr = GetTagTable('Image::ExifTool::MPEG::Video');
605 ProcessFrameHeader($et, $tagTablePtr, $w1, $w2);
606 return 1;
607}
608
609#------------------------------------------------------------------------------
610# Read MPEG audio and video frame headers
611# Inputs: 0) ExifTool object reference, 1) Reference to audio/video data
612# Returns: 1 on success, 0 if no video header was found
613# To Do: Properly parse MPEG streams:
614# 0xb7 - sequence end
615# 0xb9 - end code
616# 0xba - pack start code
617# 0xbb - system header
618# 0xbc - program map <-- should parse this
619# 0xbd - private stream 1 --> for VOB, this contains sub-streams:
620# 0x20-0x3f - pictures
621# 0x80-0x87 - audio (AC3,DTS,SDDS)
622# 0xa0-0xa7 - audio (LPCM)
623# 0xbe - padding
624# 0xbf - private stream 2
625# 0xc0-0xdf - audio stream
626# 0xe0-0xef - video stream
627sub ParseMPEGAudioVideo($$)
628{
629 my ($et, $buffPt) = @_;
630 my (%found, $didHdr);
631 my $rtnVal = 0;
632 my %proc = ( audio => \&ParseMPEGAudio, video => \&ProcessMPEGVideo );
633
634 delete $$et{AudioBitrate};
635 delete $$et{VideoBitrate};
636
637 while ($$buffPt =~ /\0\0\x01(\xb3|\xc0)/g) {
638 my $type = $1 eq "\xb3" ? 'video' : 'audio';
639 unless ($didHdr) {
640 # make sure we didn't miss an audio frame sync before this (eg. MP3 file)
641 # (the last byte of the 4-byte MP3 audio frame header word may be zero,
642 # but the 2nd last must be non-zero, so we need only check to pos-3)
643 my $buff = substr($$buffPt, 0, pos($$buffPt) - 3);
644 $found{audio} = 1 if ParseMPEGAudio($et, \$buff);
645 $didHdr = 1;
646 }
647 next if $found{$type};
648 my $len = length($$buffPt) - pos($$buffPt);
649 last if $len < 4;
650 $len > 256 and $len = 256;
651 my $dat = substr($$buffPt, pos($$buffPt), $len);
652 # process MPEG audio or video
653 if (&{$proc{$type}}($et, \$dat)) {
654 $rtnVal = 1;
655 $found{$type} = 1;
656 # done if we found audio and video
657 last if scalar(keys %found) == 2;
658 }
659 }
660 return $rtnVal;
661}
662
663#------------------------------------------------------------------------------
664# Read information from an MPEG file
665# Inputs: 0) ExifTool object reference, 1) Directory information reference
666# Returns: 1 on success, 0 if this wasn't a valid MPEG file
667sub ProcessMPEG($$)
668{
669 my ($et, $dirInfo) = @_;
670 my $raf = $$dirInfo{RAF};
671 my $buff;
672
673 $raf->Read($buff, 4) == 4 or return 0;
674 return 0 unless $buff =~ /^\0\0\x01[\xb0-\xbf]/;
675 $et->SetFileType();
676
677 $raf->Seek(0,0);
678 $raf->Read($buff, 65536*4) or return 0;
679
680 return ParseMPEGAudioVideo($et, \$buff);
681}
682
6831; # end
684
685__END__
686
687=head1 NAME
688
689Image::ExifTool::MPEG - Read MPEG-1 and MPEG-2 meta information
690
691=head1 SYNOPSIS
692
693This module is used by Image::ExifTool
694
695=head1 DESCRIPTION
696
697This module contains definitions required by Image::ExifTool to read MPEG-1
698and MPEG-2 audio/video files.
699
700=head1 NOTES
701
702Since ISO charges money for the official MPEG specification, this module is
703based on unofficial sources which may be incomplete, inaccurate or outdated.
704
705=head1 AUTHOR
706
707Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
708
709This library is free software; you can redistribute it and/or modify it
710under the same terms as Perl itself.
711
712=head1 REFERENCES
713
714=over 4
715
716=item L<http://www.mp3-tech.org/>
717
718=item L<http://www.getid3.org/>
719
720=item L<http://dvd.sourceforge.net/dvdinfo/dvdmpeg.html>
721
722=item L<http://ffmpeg.org/>
723
724=item L<http://sourceforge.net/projects/mediainfo/>
725
726=back
727
728=head1 SEE ALSO
729
730L<Image::ExifTool::TagNames/MPEG Tags>,
731L<MP3::Info(3pm)|MP3::Info>,
732L<Image::ExifTool(3pm)|Image::ExifTool>
733
734=cut
735
Note: See TracBrowser for help on using the repository browser.