MPEG.pm 22 KB

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