ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
getid3_matroska Class Reference

http://www.matroska.org/technical/specs/index.html More...

+ Inheritance diagram for getid3_matroska:
+ Collaboration diagram for getid3_matroska:

Public Member Functions

 Analyze ()
 
- Public Member Functions inherited from getid3_handler
 __construct (getID3 $getid3, $call_module=null)
 
 Analyze ()
 
 AnalyzeString ($string)
 
 setStringMode ($string)
 
 saveAttachment ($name, $offset, $length, $image_mime=null)
 

Static Public Member Functions

static TargetTypeValue ($target_type)
 
static BlockLacingType ($lacingtype)
 
static CodecIDtoCommonName ($codecid)
 
static displayUnit ($value)
 

Static Public Attributes

static $hide_clusters = true
 
static $parse_whole_file = false
 

Private Member Functions

 parseEBML (&$info)
 
 EnsureBufferHasEnoughData ($min_data=1024)
 
 readEBMLint ()
 
 readEBMLelementData ($length, $check_buffer=false)
 
 getEBMLelement (&$element, $parent_end, $get_data=false)
 
 unhandledElement ($type, $line, $element)
 
 ExtractCommentsSimpleTag ($SimpleTagArray)
 
 HandleEMBLSimpleTag ($parent_end)
 
 HandleEMBLClusterBlock ($element, $block_type, &$info)
 

Static Private Member Functions

static EBML2Int ($EBMLstring)
 
static EBMLdate2unix ($EBMLdatestamp)
 
static EBMLidName ($value)
 
static getDefaultStreamInfo ($streams)
 

Private Attributes

 $EBMLbuffer = ''
 
 $EBMLbuffer_offset = 0
 
 $EBMLbuffer_length = 0
 
 $current_offset = 0
 
 $unuseful_elements = array(EBML_ID_CRC32, EBML_ID_VOID)
 

Additional Inherited Members

- Protected Member Functions inherited from getid3_handler
 ftell ()
 
 fread ($bytes)
 
 fseek ($bytes, $whence=SEEK_SET)
 
 feof ()
 
 isDependencyFor ($module)
 
 error ($text)
 
 warning ($text)
 
 notice ($text)
 
- Protected Attributes inherited from getid3_handler
 $getid3
 
 $data_string_flag = false
 
 $data_string = ''
 
 $data_string_position = 0
 
 $data_string_length = 0
 

Detailed Description

http://www.matroska.org/technical/specs/index.html

Todo:

Rewrite EBML parser to reduce it's size and honor default element values

After rewrite implement stream size calculation, that will provide additional useful info and enable AAC/FLAC audio bitrate detection

Definition at line 216 of file module.audio-video.matroska.php.

Member Function Documentation

◆ Analyze()

getid3_matroska::Analyze ( )

Definition at line 229 of file module.audio-video.matroska.php.

References $i, $info, $key, getID3\ATTACHMENTS_NONE, getid3_handler\error(), ExtractCommentsSimpleTag(), getid3_riff\fourccLookup(), getid3_lib\IncludeDependency(), getid3_riff\ParseBITMAPINFOHEADER(), parseEBML(), getid3_riff\parseWAVEFORMATex(), and getid3_handler\warning().

230  {
231  $info = &$this->getid3->info;
232 
233  // parse container
234  try {
235  $this->parseEBML($info);
236  } catch (Exception $e) {
237  $this->error('EBML parser: '.$e->getMessage());
238  }
239 
240  // calculate playtime
241  if (isset($info['matroska']['info']) && is_array($info['matroska']['info'])) {
242  foreach ($info['matroska']['info'] as $key => $infoarray) {
243  if (isset($infoarray['Duration'])) {
244  // TimecodeScale is how many nanoseconds each Duration unit is
245  $info['playtime_seconds'] = $infoarray['Duration'] * ((isset($infoarray['TimecodeScale']) ? $infoarray['TimecodeScale'] : 1000000) / 1000000000);
246  break;
247  }
248  }
249  }
250 
251  // extract tags
252  if (isset($info['matroska']['tags']) && is_array($info['matroska']['tags'])) {
253  foreach ($info['matroska']['tags'] as $key => $infoarray) {
254  $this->ExtractCommentsSimpleTag($infoarray);
255  }
256  }
257 
258  // process tracks
259  if (isset($info['matroska']['tracks']['tracks']) && is_array($info['matroska']['tracks']['tracks'])) {
260  foreach ($info['matroska']['tracks']['tracks'] as $key => $trackarray) {
261 
262  $track_info = array();
263  $track_info['dataformat'] = self::CodecIDtoCommonName($trackarray['CodecID']);
264  $track_info['default'] = (isset($trackarray['FlagDefault']) ? $trackarray['FlagDefault'] : true);
265  if (isset($trackarray['Name'])) { $track_info['name'] = $trackarray['Name']; }
266 
267  switch ($trackarray['TrackType']) {
268 
269  case 1: // Video
270  $track_info['resolution_x'] = $trackarray['PixelWidth'];
271  $track_info['resolution_y'] = $trackarray['PixelHeight'];
272  $track_info['display_unit'] = self::displayUnit(isset($trackarray['DisplayUnit']) ? $trackarray['DisplayUnit'] : 0);
273  $track_info['display_x'] = (isset($trackarray['DisplayWidth']) ? $trackarray['DisplayWidth'] : $trackarray['PixelWidth']);
274  $track_info['display_y'] = (isset($trackarray['DisplayHeight']) ? $trackarray['DisplayHeight'] : $trackarray['PixelHeight']);
275 
276  if (isset($trackarray['PixelCropBottom'])) { $track_info['crop_bottom'] = $trackarray['PixelCropBottom']; }
277  if (isset($trackarray['PixelCropTop'])) { $track_info['crop_top'] = $trackarray['PixelCropTop']; }
278  if (isset($trackarray['PixelCropLeft'])) { $track_info['crop_left'] = $trackarray['PixelCropLeft']; }
279  if (isset($trackarray['PixelCropRight'])) { $track_info['crop_right'] = $trackarray['PixelCropRight']; }
280  if (isset($trackarray['DefaultDuration'])) { $track_info['frame_rate'] = round(1000000000 / $trackarray['DefaultDuration'], 3); }
281  if (isset($trackarray['CodecName'])) { $track_info['codec'] = $trackarray['CodecName']; }
282 
283  switch ($trackarray['CodecID']) {
284  case 'V_MS/VFW/FOURCC':
285  getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.riff.php', __FILE__, true);
286 
287  $parsed = getid3_riff::ParseBITMAPINFOHEADER($trackarray['CodecPrivate']);
288  $track_info['codec'] = getid3_riff::fourccLookup($parsed['fourcc']);
289  $info['matroska']['track_codec_parsed'][$trackarray['TrackNumber']] = $parsed;
290  break;
291 
292  /*case 'V_MPEG4/ISO/AVC':
293  $h264['profile'] = getid3_lib::BigEndian2Int(substr($trackarray['CodecPrivate'], 1, 1));
294  $h264['level'] = getid3_lib::BigEndian2Int(substr($trackarray['CodecPrivate'], 3, 1));
295  $rn = getid3_lib::BigEndian2Int(substr($trackarray['CodecPrivate'], 4, 1));
296  $h264['NALUlength'] = ($rn & 3) + 1;
297  $rn = getid3_lib::BigEndian2Int(substr($trackarray['CodecPrivate'], 5, 1));
298  $nsps = ($rn & 31);
299  $offset = 6;
300  for ($i = 0; $i < $nsps; $i ++) {
301  $length = getid3_lib::BigEndian2Int(substr($trackarray['CodecPrivate'], $offset, 2));
302  $h264['SPS'][] = substr($trackarray['CodecPrivate'], $offset + 2, $length);
303  $offset += 2 + $length;
304  }
305  $npps = getid3_lib::BigEndian2Int(substr($trackarray['CodecPrivate'], $offset, 1));
306  $offset += 1;
307  for ($i = 0; $i < $npps; $i ++) {
308  $length = getid3_lib::BigEndian2Int(substr($trackarray['CodecPrivate'], $offset, 2));
309  $h264['PPS'][] = substr($trackarray['CodecPrivate'], $offset + 2, $length);
310  $offset += 2 + $length;
311  }
312  $info['matroska']['track_codec_parsed'][$trackarray['TrackNumber']] = $h264;
313  break;*/
314  }
315 
316  $info['video']['streams'][] = $track_info;
317  break;
318 
319  case 2: // Audio
320  $track_info['sample_rate'] = (isset($trackarray['SamplingFrequency']) ? $trackarray['SamplingFrequency'] : 8000.0);
321  $track_info['channels'] = (isset($trackarray['Channels']) ? $trackarray['Channels'] : 1);
322  $track_info['language'] = (isset($trackarray['Language']) ? $trackarray['Language'] : 'eng');
323  if (isset($trackarray['BitDepth'])) { $track_info['bits_per_sample'] = $trackarray['BitDepth']; }
324  if (isset($trackarray['CodecName'])) { $track_info['codec'] = $trackarray['CodecName']; }
325 
326  switch ($trackarray['CodecID']) {
327  case 'A_PCM/INT/LIT':
328  case 'A_PCM/INT/BIG':
329  $track_info['bitrate'] = $trackarray['SamplingFrequency'] * $trackarray['Channels'] * $trackarray['BitDepth'];
330  break;
331 
332  case 'A_AC3':
333  case 'A_EAC3':
334  case 'A_DTS':
335  case 'A_MPEG/L3':
336  case 'A_MPEG/L2':
337  case 'A_FLAC':
338  $module_dataformat = ($track_info['dataformat'] == 'mp2' ? 'mp3' : ($track_info['dataformat'] == 'eac3' ? 'ac3' : $track_info['dataformat']));
339  getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.'.$module_dataformat.'.php', __FILE__, true);
340 
341  if (!isset($info['matroska']['track_data_offsets'][$trackarray['TrackNumber']])) {
342  $this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because $info[matroska][track_data_offsets]['.$trackarray['TrackNumber'].'] not set');
343  break;
344  }
345 
346  // create temp instance
347  $getid3_temp = new getID3();
348  if ($track_info['dataformat'] != 'flac') {
349  $getid3_temp->openfile($this->getid3->filename);
350  }
351  $getid3_temp->info['avdataoffset'] = $info['matroska']['track_data_offsets'][$trackarray['TrackNumber']]['offset'];
352  if ($track_info['dataformat'][0] == 'm' || $track_info['dataformat'] == 'flac') {
353  $getid3_temp->info['avdataend'] = $info['matroska']['track_data_offsets'][$trackarray['TrackNumber']]['offset'] + $info['matroska']['track_data_offsets'][$trackarray['TrackNumber']]['length'];
354  }
355 
356  // analyze
357  $class = 'getid3_'.$module_dataformat;
358  $header_data_key = $track_info['dataformat'][0] == 'm' ? 'mpeg' : $track_info['dataformat'];
359  $getid3_audio = new $class($getid3_temp, __CLASS__);
360  if ($track_info['dataformat'] == 'flac') {
361  $getid3_audio->AnalyzeString($trackarray['CodecPrivate']);
362  }
363  else {
364  $getid3_audio->Analyze();
365  }
366  if (!empty($getid3_temp->info[$header_data_key])) {
367  $info['matroska']['track_codec_parsed'][$trackarray['TrackNumber']] = $getid3_temp->info[$header_data_key];
368  if (isset($getid3_temp->info['audio']) && is_array($getid3_temp->info['audio'])) {
369  foreach ($getid3_temp->info['audio'] as $key => $value) {
370  $track_info[$key] = $value;
371  }
372  }
373  }
374  else {
375  $this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because '.$class.'::Analyze() failed at offset '.$getid3_temp->info['avdataoffset']);
376  }
377 
378  // copy errors and warnings
379  if (!empty($getid3_temp->info['error'])) {
380  foreach ($getid3_temp->info['error'] as $newerror) {
381  $this->warning($class.'() says: ['.$newerror.']');
382  }
383  }
384  if (!empty($getid3_temp->info['warning'])) {
385  foreach ($getid3_temp->info['warning'] as $newerror) {
386  $this->warning($class.'() says: ['.$newerror.']');
387  }
388  }
389  unset($getid3_temp, $getid3_audio);
390  break;
391 
392  case 'A_AAC':
393  case 'A_AAC/MPEG2/LC':
394  case 'A_AAC/MPEG2/LC/SBR':
395  case 'A_AAC/MPEG4/LC':
396  case 'A_AAC/MPEG4/LC/SBR':
397  $this->warning($trackarray['CodecID'].' audio data contains no header, audio/video bitrates can\'t be calculated');
398  break;
399 
400  case 'A_VORBIS':
401  if (!isset($trackarray['CodecPrivate'])) {
402  $this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because CodecPrivate data not set');
403  break;
404  }
405  $vorbis_offset = strpos($trackarray['CodecPrivate'], 'vorbis', 1);
406  if ($vorbis_offset === false) {
407  $this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because CodecPrivate data does not contain "vorbis" keyword');
408  break;
409  }
410  $vorbis_offset -= 1;
411 
412  getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ogg.php', __FILE__, true);
413 
414  // create temp instance
415  $getid3_temp = new getID3();
416 
417  // analyze
418  $getid3_ogg = new getid3_ogg($getid3_temp);
419  $oggpageinfo['page_seqno'] = 0;
420  $getid3_ogg->ParseVorbisPageHeader($trackarray['CodecPrivate'], $vorbis_offset, $oggpageinfo);
421  if (!empty($getid3_temp->info['ogg'])) {
422  $info['matroska']['track_codec_parsed'][$trackarray['TrackNumber']] = $getid3_temp->info['ogg'];
423  if (isset($getid3_temp->info['audio']) && is_array($getid3_temp->info['audio'])) {
424  foreach ($getid3_temp->info['audio'] as $key => $value) {
425  $track_info[$key] = $value;
426  }
427  }
428  }
429 
430  // copy errors and warnings
431  if (!empty($getid3_temp->info['error'])) {
432  foreach ($getid3_temp->info['error'] as $newerror) {
433  $this->warning('getid3_ogg() says: ['.$newerror.']');
434  }
435  }
436  if (!empty($getid3_temp->info['warning'])) {
437  foreach ($getid3_temp->info['warning'] as $newerror) {
438  $this->warning('getid3_ogg() says: ['.$newerror.']');
439  }
440  }
441 
442  if (!empty($getid3_temp->info['ogg']['bitrate_nominal'])) {
443  $track_info['bitrate'] = $getid3_temp->info['ogg']['bitrate_nominal'];
444  }
445  unset($getid3_temp, $getid3_ogg, $oggpageinfo, $vorbis_offset);
446  break;
447 
448  case 'A_MS/ACM':
449  getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.riff.php', __FILE__, true);
450 
451  $parsed = getid3_riff::parseWAVEFORMATex($trackarray['CodecPrivate']);
452  foreach ($parsed as $key => $value) {
453  if ($key != 'raw') {
454  $track_info[$key] = $value;
455  }
456  }
457  $info['matroska']['track_codec_parsed'][$trackarray['TrackNumber']] = $parsed;
458  break;
459 
460  default:
461  $this->warning('Unhandled audio type "'.(isset($trackarray['CodecID']) ? $trackarray['CodecID'] : '').'"');
462  break;
463  }
464 
465  $info['audio']['streams'][] = $track_info;
466  break;
467  }
468  }
469 
470  if (!empty($info['video']['streams'])) {
471  $info['video'] = self::getDefaultStreamInfo($info['video']['streams']);
472  }
473  if (!empty($info['audio']['streams'])) {
474  $info['audio'] = self::getDefaultStreamInfo($info['audio']['streams']);
475  }
476  }
477 
478  // process attachments
479  if (isset($info['matroska']['attachments']) && $this->getid3->option_save_attachments !== getID3::ATTACHMENTS_NONE) {
480  foreach ($info['matroska']['attachments'] as $i => $entry) {
481  if (strpos($entry['FileMimeType'], 'image/') === 0 && !empty($entry['FileData'])) {
482  $info['matroska']['comments']['picture'][] = array('data' => $entry['FileData'], 'image_mime' => $entry['FileMimeType'], 'filename' => $entry['FileName']);
483  }
484  }
485  }
486 
487  // determine mime type
488  if (!empty($info['video']['streams'])) {
489  $info['mime_type'] = ($info['matroska']['doctype'] == 'webm' ? 'video/webm' : 'video/x-matroska');
490  } elseif (!empty($info['audio']['streams'])) {
491  $info['mime_type'] = ($info['matroska']['doctype'] == 'webm' ? 'audio/webm' : 'audio/x-matroska');
492  } elseif (isset($info['mime_type'])) {
493  unset($info['mime_type']);
494  }
495 
496  return true;
497  }
static ParseBITMAPINFOHEADER($BITMAPINFOHEADER, $littleEndian=true)
const ATTACHMENTS_NONE
Definition: getid3.php:118
error($text)
Definition: getid3.php:1752
warning($text)
Definition: getid3.php:1758
static parseWAVEFORMATex($WaveFormatExData)
static IncludeDependency($filename, $sourcefile, $DieOnFailure=false)
static fourccLookup($fourcc)
$i
Definition: disco.tpl.php:19
ExtractCommentsSimpleTag($SimpleTagArray)
$info
Definition: index.php:5
$key
Definition: croninfo.php:18
+ Here is the call graph for this function:

◆ BlockLacingType()

static getid3_matroska::BlockLacingType (   $lacingtype)
static

Definition at line 1512 of file module.audio-video.matroska.php.

1512  {
1513  // http://matroska.org/technical/specs/index.html#block_structure
1514  static $BlockLacingType = array();
1515  if (empty($BlockLacingType)) {
1516  $BlockLacingType[0x00] = 'no lacing';
1517  $BlockLacingType[0x01] = 'Xiph lacing';
1518  $BlockLacingType[0x02] = 'fixed-size lacing';
1519  $BlockLacingType[0x03] = 'EBML lacing';
1520  }
1521  return (isset($BlockLacingType[$lacingtype]) ? $BlockLacingType[$lacingtype] : $lacingtype);
1522  }

◆ CodecIDtoCommonName()

static getid3_matroska::CodecIDtoCommonName (   $codecid)
static

Definition at line 1524 of file module.audio-video.matroska.php.

1524  {
1525  // http://www.matroska.org/technical/specs/codecid/index.html
1526  static $CodecIDlist = array();
1527  if (empty($CodecIDlist)) {
1528  $CodecIDlist['A_AAC'] = 'aac';
1529  $CodecIDlist['A_AAC/MPEG2/LC'] = 'aac';
1530  $CodecIDlist['A_AC3'] = 'ac3';
1531  $CodecIDlist['A_EAC3'] = 'eac3';
1532  $CodecIDlist['A_DTS'] = 'dts';
1533  $CodecIDlist['A_FLAC'] = 'flac';
1534  $CodecIDlist['A_MPEG/L1'] = 'mp1';
1535  $CodecIDlist['A_MPEG/L2'] = 'mp2';
1536  $CodecIDlist['A_MPEG/L3'] = 'mp3';
1537  $CodecIDlist['A_PCM/INT/LIT'] = 'pcm'; // PCM Integer Little Endian
1538  $CodecIDlist['A_PCM/INT/BIG'] = 'pcm'; // PCM Integer Big Endian
1539  $CodecIDlist['A_QUICKTIME/QDMC'] = 'quicktime'; // Quicktime: QDesign Music
1540  $CodecIDlist['A_QUICKTIME/QDM2'] = 'quicktime'; // Quicktime: QDesign Music v2
1541  $CodecIDlist['A_VORBIS'] = 'vorbis';
1542  $CodecIDlist['V_MPEG1'] = 'mpeg';
1543  $CodecIDlist['V_THEORA'] = 'theora';
1544  $CodecIDlist['V_REAL/RV40'] = 'real';
1545  $CodecIDlist['V_REAL/RV10'] = 'real';
1546  $CodecIDlist['V_REAL/RV20'] = 'real';
1547  $CodecIDlist['V_REAL/RV30'] = 'real';
1548  $CodecIDlist['V_QUICKTIME'] = 'quicktime'; // Quicktime
1549  $CodecIDlist['V_MPEG4/ISO/AP'] = 'mpeg4';
1550  $CodecIDlist['V_MPEG4/ISO/ASP'] = 'mpeg4';
1551  $CodecIDlist['V_MPEG4/ISO/AVC'] = 'h264';
1552  $CodecIDlist['V_MPEG4/ISO/SP'] = 'mpeg4';
1553  $CodecIDlist['V_VP8'] = 'vp8';
1554  $CodecIDlist['V_MS/VFW/FOURCC'] = 'vcm'; // Microsoft (TM) Video Codec Manager (VCM)
1555  $CodecIDlist['A_MS/ACM'] = 'acm'; // Microsoft (TM) Audio Codec Manager (ACM)
1556  }
1557  return (isset($CodecIDlist[$codecid]) ? $CodecIDlist[$codecid] : $codecid);
1558  }

◆ displayUnit()

static getid3_matroska::displayUnit (   $value)
static

Definition at line 1758 of file module.audio-video.matroska.php.

1758  {
1759  // http://www.matroska.org/technical/specs/index.html#DisplayUnit
1760  static $units = array(
1761  0 => 'pixels',
1762  1 => 'centimeters',
1763  2 => 'inches',
1764  3 => 'Display Aspect Ratio');
1765 
1766  return (isset($units[$value]) ? $units[$value] : 'unknown');
1767  }

◆ EBML2Int()

static getid3_matroska::EBML2Int (   $EBMLstring)
staticprivate

Definition at line 1449 of file module.audio-video.matroska.php.

References getid3_lib\BigEndian2Int().

1449  {
1450  // http://matroska.org/specs/
1451 
1452  // Element ID coded with an UTF-8 like system:
1453  // 1xxx xxxx - Class A IDs (2^7 -2 possible values) (base 0x8X)
1454  // 01xx xxxx xxxx xxxx - Class B IDs (2^14-2 possible values) (base 0x4X 0xXX)
1455  // 001x xxxx xxxx xxxx xxxx xxxx - Class C IDs (2^21-2 possible values) (base 0x2X 0xXX 0xXX)
1456  // 0001 xxxx xxxx xxxx xxxx xxxx xxxx xxxx - Class D IDs (2^28-2 possible values) (base 0x1X 0xXX 0xXX 0xXX)
1457  // Values with all x at 0 and 1 are reserved (hence the -2).
1458 
1459  // Data size, in octets, is also coded with an UTF-8 like system :
1460  // 1xxx xxxx - value 0 to 2^7-2
1461  // 01xx xxxx xxxx xxxx - value 0 to 2^14-2
1462  // 001x xxxx xxxx xxxx xxxx xxxx - value 0 to 2^21-2
1463  // 0001 xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^28-2
1464  // 0000 1xxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^35-2
1465  // 0000 01xx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^42-2
1466  // 0000 001x xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^49-2
1467  // 0000 0001 xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^56-2
1468 
1469  $first_byte_int = ord($EBMLstring[0]);
1470  if (0x80 & $first_byte_int) {
1471  $EBMLstring[0] = chr($first_byte_int & 0x7F);
1472  } elseif (0x40 & $first_byte_int) {
1473  $EBMLstring[0] = chr($first_byte_int & 0x3F);
1474  } elseif (0x20 & $first_byte_int) {
1475  $EBMLstring[0] = chr($first_byte_int & 0x1F);
1476  } elseif (0x10 & $first_byte_int) {
1477  $EBMLstring[0] = chr($first_byte_int & 0x0F);
1478  } elseif (0x08 & $first_byte_int) {
1479  $EBMLstring[0] = chr($first_byte_int & 0x07);
1480  } elseif (0x04 & $first_byte_int) {
1481  $EBMLstring[0] = chr($first_byte_int & 0x03);
1482  } elseif (0x02 & $first_byte_int) {
1483  $EBMLstring[0] = chr($first_byte_int & 0x01);
1484  } elseif (0x01 & $first_byte_int) {
1485  $EBMLstring[0] = chr($first_byte_int & 0x00);
1486  }
1487 
1488  return getid3_lib::BigEndian2Int($EBMLstring);
1489  }
static BigEndian2Int($byteword, $synchsafe=false, $signed=false)
Definition: getid3.lib.php:263
+ Here is the call graph for this function:

◆ EBMLdate2unix()

static getid3_matroska::EBMLdate2unix (   $EBMLdatestamp)
staticprivate

Definition at line 1491 of file module.audio-video.matroska.php.

1491  {
1492  // Date - signed 8 octets integer in nanoseconds with 0 indicating the precise beginning of the millennium (at 2001-01-01T00:00:00,000000000 UTC)
1493  // 978307200 == mktime(0, 0, 0, 1, 1, 2001) == January 1, 2001 12:00:00am UTC
1494  return round(($EBMLdatestamp / 1000000000) + 978307200);
1495  }

◆ EBMLidName()

static getid3_matroska::EBMLidName (   $value)
staticprivate

Definition at line 1560 of file module.audio-video.matroska.php.

References EBML_ID_ASPECTRATIOTYPE, EBML_ID_ATTACHEDFILE, EBML_ID_ATTACHMENTLINK, EBML_ID_ATTACHMENTS, EBML_ID_AUDIO, EBML_ID_BITDEPTH, EBML_ID_CHANNELPOSITIONS, EBML_ID_CHANNELS, EBML_ID_CHAPCOUNTRY, EBML_ID_CHAPLANGUAGE, EBML_ID_CHAPPROCESS, EBML_ID_CHAPPROCESSCODECID, EBML_ID_CHAPPROCESSCOMMAND, EBML_ID_CHAPPROCESSDATA, EBML_ID_CHAPPROCESSPRIVATE, EBML_ID_CHAPPROCESSTIME, EBML_ID_CHAPSTRING, EBML_ID_CHAPTERATOM, EBML_ID_CHAPTERDISPLAY, EBML_ID_CHAPTERFLAGENABLED, EBML_ID_CHAPTERFLAGHIDDEN, EBML_ID_CHAPTERPHYSICALEQUIV, EBML_ID_CHAPTERS, EBML_ID_CHAPTERSEGMENTEDITIONUID, EBML_ID_CHAPTERSEGMENTUID, EBML_ID_CHAPTERTIMEEND, EBML_ID_CHAPTERTIMESTART, EBML_ID_CHAPTERTRACK, EBML_ID_CHAPTERTRACKNUMBER, EBML_ID_CHAPTERTRANSLATE, EBML_ID_CHAPTERTRANSLATECODEC, EBML_ID_CHAPTERTRANSLATEEDITIONUID, EBML_ID_CHAPTERTRANSLATEID, EBML_ID_CHAPTERUID, EBML_ID_CLUSTER, EBML_ID_CLUSTERBLOCK, EBML_ID_CLUSTERBLOCKADDID, EBML_ID_CLUSTERBLOCKADDITIONAL, EBML_ID_CLUSTERBLOCKADDITIONID, EBML_ID_CLUSTERBLOCKADDITIONS, EBML_ID_CLUSTERBLOCKDURATION, EBML_ID_CLUSTERBLOCKGROUP, EBML_ID_CLUSTERBLOCKMORE, EBML_ID_CLUSTERBLOCKVIRTUAL, EBML_ID_CLUSTERCODECSTATE, EBML_ID_CLUSTERDELAY, EBML_ID_CLUSTERDURATION, EBML_ID_CLUSTERENCRYPTEDBLOCK, EBML_ID_CLUSTERFRAMENUMBER, EBML_ID_CLUSTERLACENUMBER, EBML_ID_CLUSTERPOSITION, EBML_ID_CLUSTERPREVSIZE, EBML_ID_CLUSTERREFERENCEBLOCK, EBML_ID_CLUSTERREFERENCEPRIORITY, EBML_ID_CLUSTERREFERENCEVIRTUAL, EBML_ID_CLUSTERSILENTTRACKNUMBER, EBML_ID_CLUSTERSILENTTRACKS, EBML_ID_CLUSTERSIMPLEBLOCK, EBML_ID_CLUSTERSLICES, EBML_ID_CLUSTERTIMECODE, EBML_ID_CLUSTERTIMESLICE, EBML_ID_CODECDECODEALL, EBML_ID_CODECDOWNLOADURL, EBML_ID_CODECID, EBML_ID_CODECINFOURL, EBML_ID_CODECNAME, EBML_ID_CODECPRIVATE, EBML_ID_CODECSETTINGS, EBML_ID_COLOURSPACE, EBML_ID_CONTENTCOMPALGO, EBML_ID_CONTENTCOMPRESSION, EBML_ID_CONTENTCOMPSETTINGS, EBML_ID_CONTENTENCALGO, EBML_ID_CONTENTENCKEYID, EBML_ID_CONTENTENCODING, EBML_ID_CONTENTENCODINGORDER, EBML_ID_CONTENTENCODINGS, EBML_ID_CONTENTENCODINGSCOPE, EBML_ID_CONTENTENCODINGTYPE, EBML_ID_CONTENTENCRYPTION, EBML_ID_CONTENTSIGALGO, EBML_ID_CONTENTSIGHASHALGO, EBML_ID_CONTENTSIGKEYID, EBML_ID_CONTENTSIGNATURE, EBML_ID_CRC32, EBML_ID_CUEBLOCKNUMBER, EBML_ID_CUECLUSTERPOSITION, EBML_ID_CUECODECSTATE, EBML_ID_CUEPOINT, EBML_ID_CUEREFCLUSTER, EBML_ID_CUEREFCODECSTATE, EBML_ID_CUEREFERENCE, EBML_ID_CUEREFNUMBER, EBML_ID_CUEREFTIME, EBML_ID_CUES, EBML_ID_CUETIME, EBML_ID_CUETRACK, EBML_ID_CUETRACKPOSITIONS, EBML_ID_DATEUTC, EBML_ID_DEFAULTDURATION, EBML_ID_DISPLAYHEIGHT, EBML_ID_DISPLAYUNIT, EBML_ID_DISPLAYWIDTH, EBML_ID_DOCTYPE, EBML_ID_DOCTYPEREADVERSION, EBML_ID_DOCTYPEVERSION, EBML_ID_DURATION, EBML_ID_EBML, EBML_ID_EBMLMAXIDLENGTH, EBML_ID_EBMLMAXSIZELENGTH, EBML_ID_EBMLREADVERSION, EBML_ID_EBMLVERSION, EBML_ID_EDITIONENTRY, EBML_ID_EDITIONFLAGDEFAULT, EBML_ID_EDITIONFLAGHIDDEN, EBML_ID_EDITIONFLAGORDERED, EBML_ID_EDITIONUID, EBML_ID_FILEDATA, EBML_ID_FILEDESCRIPTION, EBML_ID_FILEMIMETYPE, EBML_ID_FILENAME, EBML_ID_FILEREFERRAL, EBML_ID_FILEUID, EBML_ID_FLAGDEFAULT, EBML_ID_FLAGENABLED, EBML_ID_FLAGFORCED, EBML_ID_FLAGINTERLACED, EBML_ID_FLAGLACING, EBML_ID_GAMMAVALUE, EBML_ID_INFO, EBML_ID_LANGUAGE, EBML_ID_MAXBLOCKADDITIONID, EBML_ID_MAXCACHE, EBML_ID_MINCACHE, EBML_ID_MUXINGAPP, EBML_ID_NAME, EBML_ID_NEXTFILENAME, EBML_ID_NEXTUID, EBML_ID_OLDSTEREOMODE, EBML_ID_OUTPUTSAMPLINGFREQUENCY, EBML_ID_PIXELCROPBOTTOM, EBML_ID_PIXELCROPLEFT, EBML_ID_PIXELCROPRIGHT, EBML_ID_PIXELCROPTOP, EBML_ID_PIXELHEIGHT, EBML_ID_PIXELWIDTH, EBML_ID_PREVFILENAME, EBML_ID_PREVUID, EBML_ID_SAMPLINGFREQUENCY, EBML_ID_SEEK, EBML_ID_SEEKHEAD, EBML_ID_SEEKID, EBML_ID_SEEKPOSITION, EBML_ID_SEGMENT, EBML_ID_SEGMENTFAMILY, EBML_ID_SEGMENTFILENAME, EBML_ID_SEGMENTUID, EBML_ID_SIMPLETAG, EBML_ID_STEREOMODE, EBML_ID_TAG, EBML_ID_TAGATTACHMENTUID, EBML_ID_TAGBINARY, EBML_ID_TAGCHAPTERUID, EBML_ID_TAGDEFAULT, EBML_ID_TAGEDITIONUID, EBML_ID_TAGLANGUAGE, EBML_ID_TAGNAME, EBML_ID_TAGS, EBML_ID_TAGSTRING, EBML_ID_TAGTRACKUID, EBML_ID_TARGETS, EBML_ID_TARGETTYPE, EBML_ID_TARGETTYPEVALUE, EBML_ID_TIMECODESCALE, EBML_ID_TITLE, EBML_ID_TRACKENTRY, EBML_ID_TRACKNUMBER, EBML_ID_TRACKOFFSET, EBML_ID_TRACKOVERLAY, EBML_ID_TRACKS, EBML_ID_TRACKTIMECODESCALE, EBML_ID_TRACKTRANSLATE, EBML_ID_TRACKTRANSLATECODEC, EBML_ID_TRACKTRANSLATEEDITIONUID, EBML_ID_TRACKTRANSLATETRACKID, EBML_ID_TRACKTYPE, EBML_ID_TRACKUID, EBML_ID_VIDEO, EBML_ID_VOID, and EBML_ID_WRITINGAPP.

1560  {
1561  static $EBMLidList = array();
1562  if (empty($EBMLidList)) {
1563  $EBMLidList[EBML_ID_ASPECTRATIOTYPE] = 'AspectRatioType';
1564  $EBMLidList[EBML_ID_ATTACHEDFILE] = 'AttachedFile';
1565  $EBMLidList[EBML_ID_ATTACHMENTLINK] = 'AttachmentLink';
1566  $EBMLidList[EBML_ID_ATTACHMENTS] = 'Attachments';
1567  $EBMLidList[EBML_ID_AUDIO] = 'Audio';
1568  $EBMLidList[EBML_ID_BITDEPTH] = 'BitDepth';
1569  $EBMLidList[EBML_ID_CHANNELPOSITIONS] = 'ChannelPositions';
1570  $EBMLidList[EBML_ID_CHANNELS] = 'Channels';
1571  $EBMLidList[EBML_ID_CHAPCOUNTRY] = 'ChapCountry';
1572  $EBMLidList[EBML_ID_CHAPLANGUAGE] = 'ChapLanguage';
1573  $EBMLidList[EBML_ID_CHAPPROCESS] = 'ChapProcess';
1574  $EBMLidList[EBML_ID_CHAPPROCESSCODECID] = 'ChapProcessCodecID';
1575  $EBMLidList[EBML_ID_CHAPPROCESSCOMMAND] = 'ChapProcessCommand';
1576  $EBMLidList[EBML_ID_CHAPPROCESSDATA] = 'ChapProcessData';
1577  $EBMLidList[EBML_ID_CHAPPROCESSPRIVATE] = 'ChapProcessPrivate';
1578  $EBMLidList[EBML_ID_CHAPPROCESSTIME] = 'ChapProcessTime';
1579  $EBMLidList[EBML_ID_CHAPSTRING] = 'ChapString';
1580  $EBMLidList[EBML_ID_CHAPTERATOM] = 'ChapterAtom';
1581  $EBMLidList[EBML_ID_CHAPTERDISPLAY] = 'ChapterDisplay';
1582  $EBMLidList[EBML_ID_CHAPTERFLAGENABLED] = 'ChapterFlagEnabled';
1583  $EBMLidList[EBML_ID_CHAPTERFLAGHIDDEN] = 'ChapterFlagHidden';
1584  $EBMLidList[EBML_ID_CHAPTERPHYSICALEQUIV] = 'ChapterPhysicalEquiv';
1585  $EBMLidList[EBML_ID_CHAPTERS] = 'Chapters';
1586  $EBMLidList[EBML_ID_CHAPTERSEGMENTEDITIONUID] = 'ChapterSegmentEditionUID';
1587  $EBMLidList[EBML_ID_CHAPTERSEGMENTUID] = 'ChapterSegmentUID';
1588  $EBMLidList[EBML_ID_CHAPTERTIMEEND] = 'ChapterTimeEnd';
1589  $EBMLidList[EBML_ID_CHAPTERTIMESTART] = 'ChapterTimeStart';
1590  $EBMLidList[EBML_ID_CHAPTERTRACK] = 'ChapterTrack';
1591  $EBMLidList[EBML_ID_CHAPTERTRACKNUMBER] = 'ChapterTrackNumber';
1592  $EBMLidList[EBML_ID_CHAPTERTRANSLATE] = 'ChapterTranslate';
1593  $EBMLidList[EBML_ID_CHAPTERTRANSLATECODEC] = 'ChapterTranslateCodec';
1594  $EBMLidList[EBML_ID_CHAPTERTRANSLATEEDITIONUID] = 'ChapterTranslateEditionUID';
1595  $EBMLidList[EBML_ID_CHAPTERTRANSLATEID] = 'ChapterTranslateID';
1596  $EBMLidList[EBML_ID_CHAPTERUID] = 'ChapterUID';
1597  $EBMLidList[EBML_ID_CLUSTER] = 'Cluster';
1598  $EBMLidList[EBML_ID_CLUSTERBLOCK] = 'ClusterBlock';
1599  $EBMLidList[EBML_ID_CLUSTERBLOCKADDID] = 'ClusterBlockAddID';
1600  $EBMLidList[EBML_ID_CLUSTERBLOCKADDITIONAL] = 'ClusterBlockAdditional';
1601  $EBMLidList[EBML_ID_CLUSTERBLOCKADDITIONID] = 'ClusterBlockAdditionID';
1602  $EBMLidList[EBML_ID_CLUSTERBLOCKADDITIONS] = 'ClusterBlockAdditions';
1603  $EBMLidList[EBML_ID_CLUSTERBLOCKDURATION] = 'ClusterBlockDuration';
1604  $EBMLidList[EBML_ID_CLUSTERBLOCKGROUP] = 'ClusterBlockGroup';
1605  $EBMLidList[EBML_ID_CLUSTERBLOCKMORE] = 'ClusterBlockMore';
1606  $EBMLidList[EBML_ID_CLUSTERBLOCKVIRTUAL] = 'ClusterBlockVirtual';
1607  $EBMLidList[EBML_ID_CLUSTERCODECSTATE] = 'ClusterCodecState';
1608  $EBMLidList[EBML_ID_CLUSTERDELAY] = 'ClusterDelay';
1609  $EBMLidList[EBML_ID_CLUSTERDURATION] = 'ClusterDuration';
1610  $EBMLidList[EBML_ID_CLUSTERENCRYPTEDBLOCK] = 'ClusterEncryptedBlock';
1611  $EBMLidList[EBML_ID_CLUSTERFRAMENUMBER] = 'ClusterFrameNumber';
1612  $EBMLidList[EBML_ID_CLUSTERLACENUMBER] = 'ClusterLaceNumber';
1613  $EBMLidList[EBML_ID_CLUSTERPOSITION] = 'ClusterPosition';
1614  $EBMLidList[EBML_ID_CLUSTERPREVSIZE] = 'ClusterPrevSize';
1615  $EBMLidList[EBML_ID_CLUSTERREFERENCEBLOCK] = 'ClusterReferenceBlock';
1616  $EBMLidList[EBML_ID_CLUSTERREFERENCEPRIORITY] = 'ClusterReferencePriority';
1617  $EBMLidList[EBML_ID_CLUSTERREFERENCEVIRTUAL] = 'ClusterReferenceVirtual';
1618  $EBMLidList[EBML_ID_CLUSTERSILENTTRACKNUMBER] = 'ClusterSilentTrackNumber';
1619  $EBMLidList[EBML_ID_CLUSTERSILENTTRACKS] = 'ClusterSilentTracks';
1620  $EBMLidList[EBML_ID_CLUSTERSIMPLEBLOCK] = 'ClusterSimpleBlock';
1621  $EBMLidList[EBML_ID_CLUSTERTIMECODE] = 'ClusterTimecode';
1622  $EBMLidList[EBML_ID_CLUSTERTIMESLICE] = 'ClusterTimeSlice';
1623  $EBMLidList[EBML_ID_CODECDECODEALL] = 'CodecDecodeAll';
1624  $EBMLidList[EBML_ID_CODECDOWNLOADURL] = 'CodecDownloadURL';
1625  $EBMLidList[EBML_ID_CODECID] = 'CodecID';
1626  $EBMLidList[EBML_ID_CODECINFOURL] = 'CodecInfoURL';
1627  $EBMLidList[EBML_ID_CODECNAME] = 'CodecName';
1628  $EBMLidList[EBML_ID_CODECPRIVATE] = 'CodecPrivate';
1629  $EBMLidList[EBML_ID_CODECSETTINGS] = 'CodecSettings';
1630  $EBMLidList[EBML_ID_COLOURSPACE] = 'ColourSpace';
1631  $EBMLidList[EBML_ID_CONTENTCOMPALGO] = 'ContentCompAlgo';
1632  $EBMLidList[EBML_ID_CONTENTCOMPRESSION] = 'ContentCompression';
1633  $EBMLidList[EBML_ID_CONTENTCOMPSETTINGS] = 'ContentCompSettings';
1634  $EBMLidList[EBML_ID_CONTENTENCALGO] = 'ContentEncAlgo';
1635  $EBMLidList[EBML_ID_CONTENTENCKEYID] = 'ContentEncKeyID';
1636  $EBMLidList[EBML_ID_CONTENTENCODING] = 'ContentEncoding';
1637  $EBMLidList[EBML_ID_CONTENTENCODINGORDER] = 'ContentEncodingOrder';
1638  $EBMLidList[EBML_ID_CONTENTENCODINGS] = 'ContentEncodings';
1639  $EBMLidList[EBML_ID_CONTENTENCODINGSCOPE] = 'ContentEncodingScope';
1640  $EBMLidList[EBML_ID_CONTENTENCODINGTYPE] = 'ContentEncodingType';
1641  $EBMLidList[EBML_ID_CONTENTENCRYPTION] = 'ContentEncryption';
1642  $EBMLidList[EBML_ID_CONTENTSIGALGO] = 'ContentSigAlgo';
1643  $EBMLidList[EBML_ID_CONTENTSIGHASHALGO] = 'ContentSigHashAlgo';
1644  $EBMLidList[EBML_ID_CONTENTSIGKEYID] = 'ContentSigKeyID';
1645  $EBMLidList[EBML_ID_CONTENTSIGNATURE] = 'ContentSignature';
1646  $EBMLidList[EBML_ID_CRC32] = 'CRC32';
1647  $EBMLidList[EBML_ID_CUEBLOCKNUMBER] = 'CueBlockNumber';
1648  $EBMLidList[EBML_ID_CUECLUSTERPOSITION] = 'CueClusterPosition';
1649  $EBMLidList[EBML_ID_CUECODECSTATE] = 'CueCodecState';
1650  $EBMLidList[EBML_ID_CUEPOINT] = 'CuePoint';
1651  $EBMLidList[EBML_ID_CUEREFCLUSTER] = 'CueRefCluster';
1652  $EBMLidList[EBML_ID_CUEREFCODECSTATE] = 'CueRefCodecState';
1653  $EBMLidList[EBML_ID_CUEREFERENCE] = 'CueReference';
1654  $EBMLidList[EBML_ID_CUEREFNUMBER] = 'CueRefNumber';
1655  $EBMLidList[EBML_ID_CUEREFTIME] = 'CueRefTime';
1656  $EBMLidList[EBML_ID_CUES] = 'Cues';
1657  $EBMLidList[EBML_ID_CUETIME] = 'CueTime';
1658  $EBMLidList[EBML_ID_CUETRACK] = 'CueTrack';
1659  $EBMLidList[EBML_ID_CUETRACKPOSITIONS] = 'CueTrackPositions';
1660  $EBMLidList[EBML_ID_DATEUTC] = 'DateUTC';
1661  $EBMLidList[EBML_ID_DEFAULTDURATION] = 'DefaultDuration';
1662  $EBMLidList[EBML_ID_DISPLAYHEIGHT] = 'DisplayHeight';
1663  $EBMLidList[EBML_ID_DISPLAYUNIT] = 'DisplayUnit';
1664  $EBMLidList[EBML_ID_DISPLAYWIDTH] = 'DisplayWidth';
1665  $EBMLidList[EBML_ID_DOCTYPE] = 'DocType';
1666  $EBMLidList[EBML_ID_DOCTYPEREADVERSION] = 'DocTypeReadVersion';
1667  $EBMLidList[EBML_ID_DOCTYPEVERSION] = 'DocTypeVersion';
1668  $EBMLidList[EBML_ID_DURATION] = 'Duration';
1669  $EBMLidList[EBML_ID_EBML] = 'EBML';
1670  $EBMLidList[EBML_ID_EBMLMAXIDLENGTH] = 'EBMLMaxIDLength';
1671  $EBMLidList[EBML_ID_EBMLMAXSIZELENGTH] = 'EBMLMaxSizeLength';
1672  $EBMLidList[EBML_ID_EBMLREADVERSION] = 'EBMLReadVersion';
1673  $EBMLidList[EBML_ID_EBMLVERSION] = 'EBMLVersion';
1674  $EBMLidList[EBML_ID_EDITIONENTRY] = 'EditionEntry';
1675  $EBMLidList[EBML_ID_EDITIONFLAGDEFAULT] = 'EditionFlagDefault';
1676  $EBMLidList[EBML_ID_EDITIONFLAGHIDDEN] = 'EditionFlagHidden';
1677  $EBMLidList[EBML_ID_EDITIONFLAGORDERED] = 'EditionFlagOrdered';
1678  $EBMLidList[EBML_ID_EDITIONUID] = 'EditionUID';
1679  $EBMLidList[EBML_ID_FILEDATA] = 'FileData';
1680  $EBMLidList[EBML_ID_FILEDESCRIPTION] = 'FileDescription';
1681  $EBMLidList[EBML_ID_FILEMIMETYPE] = 'FileMimeType';
1682  $EBMLidList[EBML_ID_FILENAME] = 'FileName';
1683  $EBMLidList[EBML_ID_FILEREFERRAL] = 'FileReferral';
1684  $EBMLidList[EBML_ID_FILEUID] = 'FileUID';
1685  $EBMLidList[EBML_ID_FLAGDEFAULT] = 'FlagDefault';
1686  $EBMLidList[EBML_ID_FLAGENABLED] = 'FlagEnabled';
1687  $EBMLidList[EBML_ID_FLAGFORCED] = 'FlagForced';
1688  $EBMLidList[EBML_ID_FLAGINTERLACED] = 'FlagInterlaced';
1689  $EBMLidList[EBML_ID_FLAGLACING] = 'FlagLacing';
1690  $EBMLidList[EBML_ID_GAMMAVALUE] = 'GammaValue';
1691  $EBMLidList[EBML_ID_INFO] = 'Info';
1692  $EBMLidList[EBML_ID_LANGUAGE] = 'Language';
1693  $EBMLidList[EBML_ID_MAXBLOCKADDITIONID] = 'MaxBlockAdditionID';
1694  $EBMLidList[EBML_ID_MAXCACHE] = 'MaxCache';
1695  $EBMLidList[EBML_ID_MINCACHE] = 'MinCache';
1696  $EBMLidList[EBML_ID_MUXINGAPP] = 'MuxingApp';
1697  $EBMLidList[EBML_ID_NAME] = 'Name';
1698  $EBMLidList[EBML_ID_NEXTFILENAME] = 'NextFilename';
1699  $EBMLidList[EBML_ID_NEXTUID] = 'NextUID';
1700  $EBMLidList[EBML_ID_OUTPUTSAMPLINGFREQUENCY] = 'OutputSamplingFrequency';
1701  $EBMLidList[EBML_ID_PIXELCROPBOTTOM] = 'PixelCropBottom';
1702  $EBMLidList[EBML_ID_PIXELCROPLEFT] = 'PixelCropLeft';
1703  $EBMLidList[EBML_ID_PIXELCROPRIGHT] = 'PixelCropRight';
1704  $EBMLidList[EBML_ID_PIXELCROPTOP] = 'PixelCropTop';
1705  $EBMLidList[EBML_ID_PIXELHEIGHT] = 'PixelHeight';
1706  $EBMLidList[EBML_ID_PIXELWIDTH] = 'PixelWidth';
1707  $EBMLidList[EBML_ID_PREVFILENAME] = 'PrevFilename';
1708  $EBMLidList[EBML_ID_PREVUID] = 'PrevUID';
1709  $EBMLidList[EBML_ID_SAMPLINGFREQUENCY] = 'SamplingFrequency';
1710  $EBMLidList[EBML_ID_SEEK] = 'Seek';
1711  $EBMLidList[EBML_ID_SEEKHEAD] = 'SeekHead';
1712  $EBMLidList[EBML_ID_SEEKID] = 'SeekID';
1713  $EBMLidList[EBML_ID_SEEKPOSITION] = 'SeekPosition';
1714  $EBMLidList[EBML_ID_SEGMENT] = 'Segment';
1715  $EBMLidList[EBML_ID_SEGMENTFAMILY] = 'SegmentFamily';
1716  $EBMLidList[EBML_ID_SEGMENTFILENAME] = 'SegmentFilename';
1717  $EBMLidList[EBML_ID_SEGMENTUID] = 'SegmentUID';
1718  $EBMLidList[EBML_ID_SIMPLETAG] = 'SimpleTag';
1719  $EBMLidList[EBML_ID_CLUSTERSLICES] = 'ClusterSlices';
1720  $EBMLidList[EBML_ID_STEREOMODE] = 'StereoMode';
1721  $EBMLidList[EBML_ID_OLDSTEREOMODE] = 'OldStereoMode';
1722  $EBMLidList[EBML_ID_TAG] = 'Tag';
1723  $EBMLidList[EBML_ID_TAGATTACHMENTUID] = 'TagAttachmentUID';
1724  $EBMLidList[EBML_ID_TAGBINARY] = 'TagBinary';
1725  $EBMLidList[EBML_ID_TAGCHAPTERUID] = 'TagChapterUID';
1726  $EBMLidList[EBML_ID_TAGDEFAULT] = 'TagDefault';
1727  $EBMLidList[EBML_ID_TAGEDITIONUID] = 'TagEditionUID';
1728  $EBMLidList[EBML_ID_TAGLANGUAGE] = 'TagLanguage';
1729  $EBMLidList[EBML_ID_TAGNAME] = 'TagName';
1730  $EBMLidList[EBML_ID_TAGTRACKUID] = 'TagTrackUID';
1731  $EBMLidList[EBML_ID_TAGS] = 'Tags';
1732  $EBMLidList[EBML_ID_TAGSTRING] = 'TagString';
1733  $EBMLidList[EBML_ID_TARGETS] = 'Targets';
1734  $EBMLidList[EBML_ID_TARGETTYPE] = 'TargetType';
1735  $EBMLidList[EBML_ID_TARGETTYPEVALUE] = 'TargetTypeValue';
1736  $EBMLidList[EBML_ID_TIMECODESCALE] = 'TimecodeScale';
1737  $EBMLidList[EBML_ID_TITLE] = 'Title';
1738  $EBMLidList[EBML_ID_TRACKENTRY] = 'TrackEntry';
1739  $EBMLidList[EBML_ID_TRACKNUMBER] = 'TrackNumber';
1740  $EBMLidList[EBML_ID_TRACKOFFSET] = 'TrackOffset';
1741  $EBMLidList[EBML_ID_TRACKOVERLAY] = 'TrackOverlay';
1742  $EBMLidList[EBML_ID_TRACKS] = 'Tracks';
1743  $EBMLidList[EBML_ID_TRACKTIMECODESCALE] = 'TrackTimecodeScale';
1744  $EBMLidList[EBML_ID_TRACKTRANSLATE] = 'TrackTranslate';
1745  $EBMLidList[EBML_ID_TRACKTRANSLATECODEC] = 'TrackTranslateCodec';
1746  $EBMLidList[EBML_ID_TRACKTRANSLATEEDITIONUID] = 'TrackTranslateEditionUID';
1747  $EBMLidList[EBML_ID_TRACKTRANSLATETRACKID] = 'TrackTranslateTrackID';
1748  $EBMLidList[EBML_ID_TRACKTYPE] = 'TrackType';
1749  $EBMLidList[EBML_ID_TRACKUID] = 'TrackUID';
1750  $EBMLidList[EBML_ID_VIDEO] = 'Video';
1751  $EBMLidList[EBML_ID_VOID] = 'Void';
1752  $EBMLidList[EBML_ID_WRITINGAPP] = 'WritingApp';
1753  }
1754 
1755  return (isset($EBMLidList[$value]) ? $EBMLidList[$value] : dechex($value));
1756  }
const EBML_ID_CONTENTSIGALGO
const EBML_ID_CUECLUSTERPOSITION
const EBML_ID_CLUSTERCODECSTATE
const EBML_ID_TRACKNUMBER
const EBML_ID_CLUSTERPREVSIZE
const EBML_ID_CHAPPROCESSCODECID
const EBML_ID_CONTENTSIGNATURE
const EBML_ID_DISPLAYUNIT
const EBML_ID_TARGETTYPEVALUE
const EBML_ID_CLUSTERDURATION
const EBML_ID_TAGBINARY
const EBML_ID_FLAGFORCED
const EBML_ID_PREVUID
const EBML_ID_CHAPTERDISPLAY
const EBML_ID_SAMPLINGFREQUENCY
const EBML_ID_ATTACHMENTLINK
const EBML_ID_CONTENTENCODING
const EBML_ID_ASPECTRATIOTYPE
const EBML_ID_GAMMAVALUE
const EBML_ID_CHAPTERTRANSLATEID
const EBML_ID_CLUSTERBLOCKADDITIONAL
const EBML_ID_CHAPTERFLAGENABLED
const EBML_ID_TAGSTRING
const EBML_ID_COLOURSPACE
const EBML_ID_CONTENTENCODINGSCOPE
const EBML_ID_CUEREFTIME
const EBML_ID_CLUSTERSILENTTRACKS
const EBML_ID_SEEKHEAD
const EBML_ID_CHAPPROCESSPRIVATE
const EBML_ID_ATTACHEDFILE
const EBML_ID_TRACKOVERLAY
const EBML_ID_CONTENTENCKEYID
const EBML_ID_FILEDATA
const EBML_ID_EDITIONENTRY
const EBML_ID_CODECPRIVATE
const EBML_ID_CLUSTERSIMPLEBLOCK
const EBML_ID_CONTENTENCODINGORDER
const EBML_ID_SEEKPOSITION
const EBML_ID_CUEREFERENCE
const EBML_ID_CONTENTCOMPALGO
const EBML_ID_TRACKTRANSLATECODEC
const EBML_ID_CHAPLANGUAGE
const EBML_ID_CONTENTENCODINGTYPE
const EBML_ID_FILEREFERRAL
const EBML_ID_TRACKUID
const EBML_ID_CLUSTERREFERENCEVIRTUAL
const EBML_ID_CODECNAME
const EBML_ID_CHAPPROCESSCOMMAND
const EBML_ID_CODECDOWNLOADURL
const EBML_ID_CHAPTERUID
const EBML_ID_PIXELHEIGHT
const EBML_ID_NEXTUID
const EBML_ID_FLAGENABLED
const EBML_ID_CLUSTERENCRYPTEDBLOCK
const EBML_ID_TRACKS
const EBML_ID_CLUSTERBLOCKADDID
const EBML_ID_CONTENTSIGHASHALGO
const EBML_ID_PIXELCROPRIGHT
const EBML_ID_CLUSTERBLOCK
const EBML_ID_NEXTFILENAME
const EBML_ID_TAGEDITIONUID
const EBML_ID_CHAPTERTRACKNUMBER
const EBML_ID_CHAPTERPHYSICALEQUIV
const EBML_ID_SIMPLETAG
const EBML_ID_EDITIONFLAGHIDDEN
const EBML_ID_SEGMENTUID
const EBML_ID_CUETRACKPOSITIONS
const EBML_ID_CUEREFNUMBER
const EBML_ID_TAGNAME
const EBML_ID_DEFAULTDURATION
const EBML_ID_MINCACHE
const EBML_ID_CHAPTERSEGMENTUID
const EBML_ID_CUEPOINT
const EBML_ID_LANGUAGE
const EBML_ID_CHAPTERFLAGHIDDEN
const EBML_ID_CHAPTERTIMESTART
const EBML_ID_SEGMENT
const EBML_ID_DISPLAYWIDTH
const EBML_ID_TAGCHAPTERUID
const EBML_ID_CODECSETTINGS
const EBML_ID_CHAPCOUNTRY
const EBML_ID_CHAPTERTIMEEND
const EBML_ID_EDITIONFLAGDEFAULT
const EBML_ID_CLUSTERSLICES
const EBML_ID_CHANNELPOSITIONS
const EBML_ID_EBMLVERSION
const EBML_ID_OUTPUTSAMPLINGFREQUENCY
const EBML_ID_DOCTYPE
const EBML_ID_DURATION
const EBML_ID_CLUSTER
const EBML_ID_CLUSTERTIMESLICE
const EBML_ID_CODECINFOURL
const EBML_ID_EDITIONFLAGORDERED
const EBML_ID_CLUSTERFRAMENUMBER
const EBML_ID_CONTENTENCODINGS
const EBML_ID_CLUSTERSILENTTRACKNUMBER
const EBML_ID_CUETRACK
const EBML_ID_ATTACHMENTS
const EBML_ID_CLUSTERREFERENCEPRIORITY
const EBML_ID_BITDEPTH
const EBML_ID_CONTENTCOMPSETTINGS
const EBML_ID_CHAPPROCESS
const EBML_ID_CHANNELS
const EBML_ID_CLUSTERBLOCKGROUP
const EBML_ID_PIXELCROPTOP
const EBML_ID_SEGMENTFILENAME
const EBML_ID_TAGTRACKUID
const EBML_ID_MUXINGAPP
const EBML_ID_CUEREFCLUSTER
const EBML_ID_TRACKTRANSLATEEDITIONUID
const EBML_ID_CHAPTERTRANSLATE
const EBML_ID_TRACKTIMECODESCALE
const EBML_ID_CONTENTCOMPRESSION
const EBML_ID_CHAPTERSEGMENTEDITIONUID
const EBML_ID_CHAPPROCESSTIME
const EBML_ID_PIXELCROPBOTTOM
const EBML_ID_TARGETTYPE
const EBML_ID_CLUSTERLACENUMBER
const EBML_ID_CLUSTERPOSITION
const EBML_ID_EBMLMAXIDLENGTH
const EBML_ID_FLAGLACING
const EBML_ID_CHAPTERTRANSLATECODEC
const EBML_ID_TRACKTRANSLATETRACKID
const EBML_ID_MAXCACHE
const EBML_ID_TRACKTRANSLATE
const EBML_ID_STEREOMODE
const EBML_ID_TAGLANGUAGE
const EBML_ID_CHAPTERTRANSLATEEDITIONUID
const EBML_ID_CONTENTSIGKEYID
const EBML_ID_CODECDECODEALL
const EBML_ID_EBMLMAXSIZELENGTH
const EBML_ID_FLAGINTERLACED
const EBML_ID_DISPLAYHEIGHT
const EBML_ID_CHAPTERATOM
const EBML_ID_FILEDESCRIPTION
const EBML_ID_TAGATTACHMENTUID
const EBML_ID_CHAPPROCESSDATA
const EBML_ID_FLAGDEFAULT
const EBML_ID_CLUSTERBLOCKVIRTUAL
const EBML_ID_CUEBLOCKNUMBER
const EBML_ID_CLUSTERBLOCKADDITIONID
const EBML_ID_FILEUID
const EBML_ID_FILENAME
const EBML_ID_EBMLREADVERSION
const EBML_ID_CLUSTERREFERENCEBLOCK
const EBML_ID_DOCTYPEVERSION
const EBML_ID_PIXELWIDTH
const EBML_ID_PREVFILENAME
const EBML_ID_TRACKTYPE
const EBML_ID_TIMECODESCALE
const EBML_ID_WRITINGAPP
const EBML_ID_SEGMENTFAMILY
const EBML_ID_TRACKOFFSET
const EBML_ID_CLUSTERBLOCKADDITIONS
const EBML_ID_DOCTYPEREADVERSION
const EBML_ID_CUECODECSTATE
const EBML_ID_CUEREFCODECSTATE
const EBML_ID_CHAPTERTRACK
const EBML_ID_PIXELCROPLEFT
const EBML_ID_CONTENTENCRYPTION
const EBML_ID_SEEKID
const EBML_ID_FILEMIMETYPE
const EBML_ID_CONTENTENCALGO
const EBML_ID_MAXBLOCKADDITIONID
const EBML_ID_CLUSTERBLOCKDURATION
const EBML_ID_TAGDEFAULT
const EBML_ID_DATEUTC
const EBML_ID_EDITIONUID
const EBML_ID_CHAPTERS
getID3() by James Heinrich info@getid3.org //
const EBML_ID_CLUSTERTIMECODE
const EBML_ID_OLDSTEREOMODE
const EBML_ID_CLUSTERDELAY
const EBML_ID_CHAPSTRING
const EBML_ID_TRACKENTRY
const EBML_ID_CLUSTERBLOCKMORE

◆ EnsureBufferHasEnoughData()

getid3_matroska::EnsureBufferHasEnoughData (   $min_data = 1024)
private

Definition at line 1231 of file module.audio-video.matroska.php.

References $current_offset, getid3_handler\error(), getid3_handler\feof(), getid3_handler\fread(), getid3_handler\fseek(), and getid3_handler\warning().

Referenced by getEBMLelement(), and readEBMLelementData().

1231  {
1232  if (($this->current_offset - $this->EBMLbuffer_offset) >= ($this->EBMLbuffer_length - $min_data)) {
1233  $read_bytes = max($min_data, $this->getid3->fread_buffer_size());
1234 
1235  try {
1236  $this->fseek($this->current_offset);
1237  $this->EBMLbuffer_offset = $this->current_offset;
1238  $this->EBMLbuffer = $this->fread($read_bytes);
1239  $this->EBMLbuffer_length = strlen($this->EBMLbuffer);
1240  } catch (getid3_exception $e) {
1241  $this->warning('EBML parser: '.$e->getMessage());
1242  return false;
1243  }
1244 
1245  if ($this->EBMLbuffer_length == 0 && $this->feof()) {
1246  return $this->error('EBML parser: ran out of file at offset '.$this->current_offset);
1247  }
1248  }
1249  return true;
1250  }
error($text)
Definition: getid3.php:1752
warning($text)
Definition: getid3.php:1758
fread($bytes)
Definition: getid3.php:1683
fseek($bytes, $whence=SEEK_SET)
Definition: getid3.php:1711
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ExtractCommentsSimpleTag()

getid3_matroska::ExtractCommentsSimpleTag (   $SimpleTagArray)
private

Definition at line 1341 of file module.audio-video.matroska.php.

Referenced by Analyze().

1341  {
1342  if (!empty($SimpleTagArray['SimpleTag'])) {
1343  foreach ($SimpleTagArray['SimpleTag'] as $SimpleTagKey => $SimpleTagData) {
1344  if (!empty($SimpleTagData['TagName']) && !empty($SimpleTagData['TagString'])) {
1345  $this->getid3->info['matroska']['comments'][strtolower($SimpleTagData['TagName'])][] = $SimpleTagData['TagString'];
1346  }
1347  if (!empty($SimpleTagData['SimpleTag'])) {
1348  $this->ExtractCommentsSimpleTag($SimpleTagData);
1349  }
1350  }
1351  }
1352 
1353  return true;
1354  }
ExtractCommentsSimpleTag($SimpleTagArray)
+ Here is the caller graph for this function:

◆ getDefaultStreamInfo()

static getid3_matroska::getDefaultStreamInfo (   $streams)
staticprivate

Definition at line 1769 of file module.audio-video.matroska.php.

References $info, and GuzzleHttp\Psr7\$stream.

1770  {
1771  foreach (array_reverse($streams) as $stream) {
1772  if ($stream['default']) {
1773  break;
1774  }
1775  }
1776 
1777  $unset = array('default', 'name');
1778  foreach ($unset as $u) {
1779  if (isset($stream[$u])) {
1780  unset($stream[$u]);
1781  }
1782  }
1783 
1784  $info = $stream;
1785  $info['streams'] = $streams;
1786 
1787  return $info;
1788  }
$stream
PHP stream implementation.
$info
Definition: index.php:5

◆ getEBMLelement()

getid3_matroska::getEBMLelement ( $element,
  $parent_end,
  $get_data = false 
)
private

Definition at line 1293 of file module.audio-video.matroska.php.

References $current_offset, EnsureBufferHasEnoughData(), readEBMLelementData(), and readEBMLint().

Referenced by HandleEMBLSimpleTag(), and parseEBML().

1293  {
1294  if ($this->current_offset >= $parent_end) {
1295  return false;
1296  }
1297 
1298  if (!$this->EnsureBufferHasEnoughData()) {
1299  $this->current_offset = PHP_INT_MAX; // do not exit parser right now, allow to finish current loop to gather maximum information
1300  return false;
1301  }
1302 
1303  $element = array();
1304 
1305  // set offset
1306  $element['offset'] = $this->current_offset;
1307 
1308  // get ID
1309  $element['id'] = $this->readEBMLint();
1310 
1311  // get name
1312  $element['id_name'] = self::EBMLidName($element['id']);
1313 
1314  // get length
1315  $element['length'] = $this->readEBMLint();
1316 
1317  // get end offset
1318  $element['end'] = $this->current_offset + $element['length'];
1319 
1320  // get raw data
1321  $dont_parse = (in_array($element['id'], $this->unuseful_elements) || $element['id_name'] == dechex($element['id']));
1322  if (($get_data === true || (is_array($get_data) && !in_array($element['id'], $get_data))) && !$dont_parse) {
1323  $element['data'] = $this->readEBMLelementData($element['length'], $element);
1324  }
1325 
1326  return true;
1327  }
EnsureBufferHasEnoughData($min_data=1024)
readEBMLelementData($length, $check_buffer=false)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ HandleEMBLClusterBlock()

getid3_matroska::HandleEMBLClusterBlock (   $element,
  $block_type,
$info 
)
private

Definition at line 1386 of file module.audio-video.matroska.php.

References $current_offset, $i, $info, $size, getid3_lib\BigEndian2Int(), EBML_ID_CLUSTERSIMPLEBLOCK, readEBMLelementData(), and readEBMLint().

Referenced by parseEBML().

1386  {
1387  // http://www.matroska.org/technical/specs/index.html#block_structure
1388  // http://www.matroska.org/technical/specs/index.html#simpleblock_structure
1389 
1390  $block_data = array();
1391  $block_data['tracknumber'] = $this->readEBMLint();
1392  $block_data['timecode'] = getid3_lib::BigEndian2Int($this->readEBMLelementData(2), false, true);
1393  $block_data['flags_raw'] = getid3_lib::BigEndian2Int($this->readEBMLelementData(1));
1394 
1395  if ($block_type == EBML_ID_CLUSTERSIMPLEBLOCK) {
1396  $block_data['flags']['keyframe'] = (($block_data['flags_raw'] & 0x80) >> 7);
1397  //$block_data['flags']['reserved1'] = (($block_data['flags_raw'] & 0x70) >> 4);
1398  }
1399  else {
1400  //$block_data['flags']['reserved1'] = (($block_data['flags_raw'] & 0xF0) >> 4);
1401  }
1402  $block_data['flags']['invisible'] = (bool)(($block_data['flags_raw'] & 0x08) >> 3);
1403  $block_data['flags']['lacing'] = (($block_data['flags_raw'] & 0x06) >> 1); // 00=no lacing; 01=Xiph lacing; 11=EBML lacing; 10=fixed-size lacing
1404  if ($block_type == EBML_ID_CLUSTERSIMPLEBLOCK) {
1405  $block_data['flags']['discardable'] = (($block_data['flags_raw'] & 0x01));
1406  }
1407  else {
1408  //$block_data['flags']['reserved2'] = (($block_data['flags_raw'] & 0x01) >> 0);
1409  }
1410  $block_data['flags']['lacing_type'] = self::BlockLacingType($block_data['flags']['lacing']);
1411 
1412  // Lace (when lacing bit is set)
1413  if ($block_data['flags']['lacing'] > 0) {
1414  $block_data['lace_frames'] = getid3_lib::BigEndian2Int($this->readEBMLelementData(1)) + 1; // Number of frames in the lace-1 (uint8)
1415  if ($block_data['flags']['lacing'] != 0x02) {
1416  for ($i = 1; $i < $block_data['lace_frames']; $i ++) { // Lace-coded size of each frame of the lace, except for the last one (multiple uint8). *This is not used with Fixed-size lacing as it is calculated automatically from (total size of lace) / (number of frames in lace).
1417  if ($block_data['flags']['lacing'] == 0x03) { // EBML lacing
1418  $block_data['lace_frames_size'][$i] = $this->readEBMLint(); // TODO: read size correctly, calc size for the last frame. For now offsets are deteminded OK with readEBMLint() and that's the most important thing.
1419  }
1420  else { // Xiph lacing
1421  $block_data['lace_frames_size'][$i] = 0;
1422  do {
1424  $block_data['lace_frames_size'][$i] += $size;
1425  }
1426  while ($size == 255);
1427  }
1428  }
1429  if ($block_data['flags']['lacing'] == 0x01) { // calc size of the last frame only for Xiph lacing, till EBML sizes are now anyway determined incorrectly
1430  $block_data['lace_frames_size'][] = $element['end'] - $this->current_offset - array_sum($block_data['lace_frames_size']);
1431  }
1432  }
1433  }
1434 
1435  if (!isset($info['matroska']['track_data_offsets'][$block_data['tracknumber']])) {
1436  $info['matroska']['track_data_offsets'][$block_data['tracknumber']]['offset'] = $this->current_offset;
1437  $info['matroska']['track_data_offsets'][$block_data['tracknumber']]['length'] = $element['end'] - $this->current_offset;
1438  //$info['matroska']['track_data_offsets'][$block_data['tracknumber']]['total_length'] = 0;
1439  }
1440  //$info['matroska']['track_data_offsets'][$block_data['tracknumber']]['total_length'] += $info['matroska']['track_data_offsets'][$block_data['tracknumber']]['length'];
1441  //$info['matroska']['track_data_offsets'][$block_data['tracknumber']]['duration'] = $block_data['timecode'] * ((isset($info['matroska']['info'][0]['TimecodeScale']) ? $info['matroska']['info'][0]['TimecodeScale'] : 1000000) / 1000000000);
1442 
1443  // set offset manually
1444  $this->current_offset = $element['end'];
1445 
1446  return $block_data;
1447  }
$size
Definition: RandomTest.php:84
const EBML_ID_CLUSTERSIMPLEBLOCK
readEBMLelementData($length, $check_buffer=false)
$i
Definition: disco.tpl.php:19
$info
Definition: index.php:5
static BigEndian2Int($byteword, $synchsafe=false, $signed=false)
Definition: getid3.lib.php:263
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ HandleEMBLSimpleTag()

getid3_matroska::HandleEMBLSimpleTag (   $parent_end)
private

Definition at line 1356 of file module.audio-video.matroska.php.

References getid3_lib\BigEndian2Int(), EBML_ID_SIMPLETAG, EBML_ID_TAGBINARY, EBML_ID_TAGDEFAULT, EBML_ID_TAGLANGUAGE, EBML_ID_TAGNAME, EBML_ID_TAGSTRING, getEBMLelement(), and unhandledElement().

Referenced by parseEBML().

1356  {
1357  $simpletag_entry = array();
1358 
1359  while ($this->getEBMLelement($element, $parent_end, array(EBML_ID_SIMPLETAG))) {
1360  switch ($element['id']) {
1361 
1362  case EBML_ID_TAGNAME:
1363  case EBML_ID_TAGLANGUAGE:
1364  case EBML_ID_TAGSTRING:
1365  case EBML_ID_TAGBINARY:
1366  $simpletag_entry[$element['id_name']] = $element['data'];
1367  break;
1368 
1369  case EBML_ID_SIMPLETAG:
1370  $simpletag_entry[$element['id_name']][] = $this->HandleEMBLSimpleTag($element['end']);
1371  break;
1372 
1373  case EBML_ID_TAGDEFAULT:
1374  $simpletag_entry[$element['id_name']] = (bool)getid3_lib::BigEndian2Int($element['data']);
1375  break;
1376 
1377  default:
1378  $this->unhandledElement('tag.simpletag', __LINE__, $element);
1379  break;
1380  }
1381  }
1382 
1383  return $simpletag_entry;
1384  }
const EBML_ID_TAGBINARY
const EBML_ID_TAGSTRING
const EBML_ID_SIMPLETAG
const EBML_ID_TAGNAME
getEBMLelement(&$element, $parent_end, $get_data=false)
const EBML_ID_TAGLANGUAGE
unhandledElement($type, $line, $element)
static BigEndian2Int($byteword, $synchsafe=false, $signed=false)
Definition: getid3.lib.php:263
const EBML_ID_TAGDEFAULT
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parseEBML()

getid3_matroska::parseEBML ( $info)
private

Definition at line 499 of file module.audio-video.matroska.php.

References $current_offset, $info, getid3_lib\BigEndian2Float(), getid3_lib\BigEndian2Int(), EBML_ID_ASPECTRATIOTYPE, EBML_ID_ATTACHEDFILE, EBML_ID_ATTACHMENTS, EBML_ID_AUDIO, EBML_ID_BITDEPTH, EBML_ID_CHANNELPOSITIONS, EBML_ID_CHANNELS, EBML_ID_CHAPCOUNTRY, EBML_ID_CHAPLANGUAGE, EBML_ID_CHAPSTRING, EBML_ID_CHAPTERATOM, EBML_ID_CHAPTERDISPLAY, EBML_ID_CHAPTERFLAGENABLED, EBML_ID_CHAPTERFLAGHIDDEN, EBML_ID_CHAPTERS, EBML_ID_CHAPTERSEGMENTEDITIONUID, EBML_ID_CHAPTERSEGMENTUID, EBML_ID_CHAPTERTIMEEND, EBML_ID_CHAPTERTIMESTART, EBML_ID_CHAPTERTRACK, EBML_ID_CHAPTERTRACKNUMBER, EBML_ID_CHAPTERTRANSLATE, EBML_ID_CHAPTERTRANSLATECODEC, EBML_ID_CHAPTERTRANSLATEEDITIONUID, EBML_ID_CHAPTERTRANSLATEID, EBML_ID_CHAPTERUID, EBML_ID_CLUSTER, EBML_ID_CLUSTERBLOCK, EBML_ID_CLUSTERBLOCKDURATION, EBML_ID_CLUSTERBLOCKGROUP, EBML_ID_CLUSTERCODECSTATE, EBML_ID_CLUSTERPOSITION, EBML_ID_CLUSTERPREVSIZE, EBML_ID_CLUSTERREFERENCEBLOCK, EBML_ID_CLUSTERREFERENCEPRIORITY, EBML_ID_CLUSTERSILENTTRACKNUMBER, EBML_ID_CLUSTERSILENTTRACKS, EBML_ID_CLUSTERSIMPLEBLOCK, EBML_ID_CLUSTERTIMECODE, EBML_ID_CODECDECODEALL, EBML_ID_CODECID, EBML_ID_CODECNAME, EBML_ID_CODECPRIVATE, EBML_ID_COLOURSPACE, EBML_ID_CONTENTCOMPALGO, EBML_ID_CONTENTCOMPRESSION, EBML_ID_CONTENTCOMPSETTINGS, EBML_ID_CONTENTENCALGO, EBML_ID_CONTENTENCKEYID, EBML_ID_CONTENTENCODING, EBML_ID_CONTENTENCODINGORDER, EBML_ID_CONTENTENCODINGS, EBML_ID_CONTENTENCODINGSCOPE, EBML_ID_CONTENTENCODINGTYPE, EBML_ID_CONTENTENCRYPTION, EBML_ID_CONTENTSIGALGO, EBML_ID_CONTENTSIGHASHALGO, EBML_ID_CONTENTSIGKEYID, EBML_ID_CONTENTSIGNATURE, EBML_ID_CUEBLOCKNUMBER, EBML_ID_CUECLUSTERPOSITION, EBML_ID_CUECODECSTATE, EBML_ID_CUEPOINT, EBML_ID_CUES, EBML_ID_CUETIME, EBML_ID_CUETRACK, EBML_ID_CUETRACKPOSITIONS, EBML_ID_DATEUTC, EBML_ID_DEFAULTDURATION, EBML_ID_DISPLAYHEIGHT, EBML_ID_DISPLAYUNIT, EBML_ID_DISPLAYWIDTH, EBML_ID_DOCTYPE, EBML_ID_DOCTYPEREADVERSION, EBML_ID_DOCTYPEVERSION, EBML_ID_DURATION, EBML_ID_EBML, EBML_ID_EBMLMAXIDLENGTH, EBML_ID_EBMLMAXSIZELENGTH, EBML_ID_EBMLREADVERSION, EBML_ID_EBMLVERSION, EBML_ID_EDITIONENTRY, EBML_ID_EDITIONFLAGDEFAULT, EBML_ID_EDITIONFLAGHIDDEN, EBML_ID_EDITIONFLAGORDERED, EBML_ID_EDITIONUID, EBML_ID_FILEDATA, EBML_ID_FILEDESCRIPTION, EBML_ID_FILEMIMETYPE, EBML_ID_FILENAME, EBML_ID_FILEUID, EBML_ID_FLAGDEFAULT, EBML_ID_FLAGENABLED, EBML_ID_FLAGFORCED, EBML_ID_FLAGINTERLACED, EBML_ID_FLAGLACING, EBML_ID_GAMMAVALUE, EBML_ID_INFO, EBML_ID_LANGUAGE, EBML_ID_MAXBLOCKADDITIONID, EBML_ID_MAXCACHE, EBML_ID_MINCACHE, EBML_ID_MUXINGAPP, EBML_ID_NAME, EBML_ID_NEXTFILENAME, EBML_ID_NEXTUID, EBML_ID_OLDSTEREOMODE, EBML_ID_OUTPUTSAMPLINGFREQUENCY, EBML_ID_PIXELCROPBOTTOM, EBML_ID_PIXELCROPLEFT, EBML_ID_PIXELCROPRIGHT, EBML_ID_PIXELCROPTOP, EBML_ID_PIXELHEIGHT, EBML_ID_PIXELWIDTH, EBML_ID_PREVFILENAME, EBML_ID_PREVUID, EBML_ID_SAMPLINGFREQUENCY, EBML_ID_SEEK, EBML_ID_SEEKHEAD, EBML_ID_SEEKID, EBML_ID_SEEKPOSITION, EBML_ID_SEGMENT, EBML_ID_SEGMENTFAMILY, EBML_ID_SEGMENTFILENAME, EBML_ID_SEGMENTUID, EBML_ID_SIMPLETAG, EBML_ID_STEREOMODE, EBML_ID_TAG, EBML_ID_TAGATTACHMENTUID, EBML_ID_TAGCHAPTERUID, EBML_ID_TAGEDITIONUID, EBML_ID_TAGS, EBML_ID_TAGTRACKUID, EBML_ID_TARGETS, EBML_ID_TARGETTYPE, EBML_ID_TARGETTYPEVALUE, EBML_ID_TIMECODESCALE, EBML_ID_TITLE, EBML_ID_TRACKENTRY, EBML_ID_TRACKNUMBER, EBML_ID_TRACKS, EBML_ID_TRACKTIMECODESCALE, EBML_ID_TRACKTYPE, EBML_ID_TRACKUID, EBML_ID_VIDEO, EBML_ID_WRITINGAPP, getEBMLelement(), HandleEMBLClusterBlock(), HandleEMBLSimpleTag(), readEBMLelementData(), getid3_handler\saveAttachment(), getid3_lib\trimNullByte(), unhandledElement(), and getid3_handler\warning().

Referenced by Analyze().

499  {
500  // http://www.matroska.org/technical/specs/index.html#EBMLBasics
501  $this->current_offset = $info['avdataoffset'];
502 
503  while ($this->getEBMLelement($top_element, $info['avdataend'])) {
504  switch ($top_element['id']) {
505 
506  case EBML_ID_EBML:
507  $info['matroska']['header']['offset'] = $top_element['offset'];
508  $info['matroska']['header']['length'] = $top_element['length'];
509 
510  while ($this->getEBMLelement($element_data, $top_element['end'], true)) {
511  switch ($element_data['id']) {
512 
513  case EBML_ID_EBMLVERSION:
519  $element_data['data'] = getid3_lib::BigEndian2Int($element_data['data']);
520  break;
521 
522  case EBML_ID_DOCTYPE:
523  $element_data['data'] = getid3_lib::trimNullByte($element_data['data']);
524  $info['matroska']['doctype'] = $element_data['data'];
525  $info['fileformat'] = $element_data['data'];
526  break;
527 
528  default:
529  $this->unhandledElement('header', __LINE__, $element_data);
530  break;
531  }
532 
533  unset($element_data['offset'], $element_data['end']);
534  $info['matroska']['header']['elements'][] = $element_data;
535  }
536  break;
537 
538  case EBML_ID_SEGMENT:
539  $info['matroska']['segment'][0]['offset'] = $top_element['offset'];
540  $info['matroska']['segment'][0]['length'] = $top_element['length'];
541 
542  while ($this->getEBMLelement($element_data, $top_element['end'])) {
543  if ($element_data['id'] != EBML_ID_CLUSTER || !self::$hide_clusters) { // collect clusters only if required
544  $info['matroska']['segments'][] = $element_data;
545  }
546  switch ($element_data['id']) {
547 
548  case EBML_ID_SEEKHEAD: // Contains the position of other level 1 elements.
549 
550  while ($this->getEBMLelement($seek_entry, $element_data['end'])) {
551  switch ($seek_entry['id']) {
552 
553  case EBML_ID_SEEK: // Contains a single seek entry to an EBML element
554  while ($this->getEBMLelement($sub_seek_entry, $seek_entry['end'], true)) {
555 
556  switch ($sub_seek_entry['id']) {
557 
558  case EBML_ID_SEEKID:
559  $seek_entry['target_id'] = self::EBML2Int($sub_seek_entry['data']);
560  $seek_entry['target_name'] = self::EBMLidName($seek_entry['target_id']);
561  break;
562 
564  $seek_entry['target_offset'] = $element_data['offset'] + getid3_lib::BigEndian2Int($sub_seek_entry['data']);
565  break;
566 
567  default:
568  $this->unhandledElement('seekhead.seek', __LINE__, $sub_seek_entry); }
569  break;
570  }
571  if (!isset($seek_entry['target_id'])) {
572  $this->warning('seek_entry[target_id] unexpectedly not set at '.$seek_entry['offset']);
573  break;
574  }
575  if (($seek_entry['target_id'] != EBML_ID_CLUSTER) || !self::$hide_clusters) { // collect clusters only if required
576  $info['matroska']['seek'][] = $seek_entry;
577  }
578  break;
579 
580  default:
581  $this->unhandledElement('seekhead', __LINE__, $seek_entry);
582  break;
583  }
584  }
585  break;
586 
587  case EBML_ID_TRACKS: // A top-level block of information with many tracks described.
588  $info['matroska']['tracks'] = $element_data;
589 
590  while ($this->getEBMLelement($track_entry, $element_data['end'])) {
591  switch ($track_entry['id']) {
592 
593  case EBML_ID_TRACKENTRY: //subelements: Describes a track with all elements.
594 
595  while ($this->getEBMLelement($subelement, $track_entry['end'], array(EBML_ID_VIDEO, EBML_ID_AUDIO, EBML_ID_CONTENTENCODINGS, EBML_ID_CODECPRIVATE))) {
596  switch ($subelement['id']) {
597 
598  case EBML_ID_TRACKNUMBER:
599  case EBML_ID_TRACKUID:
600  case EBML_ID_TRACKTYPE:
601  case EBML_ID_MINCACHE:
602  case EBML_ID_MAXCACHE:
604  case EBML_ID_DEFAULTDURATION: // nanoseconds per frame
605  $track_entry[$subelement['id_name']] = getid3_lib::BigEndian2Int($subelement['data']);
606  break;
607 
609  $track_entry[$subelement['id_name']] = getid3_lib::BigEndian2Float($subelement['data']);
610  break;
611 
612  case EBML_ID_CODECID:
613  case EBML_ID_LANGUAGE:
614  case EBML_ID_NAME:
615  case EBML_ID_CODECNAME:
616  $track_entry[$subelement['id_name']] = getid3_lib::trimNullByte($subelement['data']);
617  break;
618 
620  $track_entry[$subelement['id_name']] = $this->readEBMLelementData($subelement['length'], true);
621  break;
622 
623  case EBML_ID_FLAGENABLED:
624  case EBML_ID_FLAGDEFAULT:
625  case EBML_ID_FLAGFORCED:
626  case EBML_ID_FLAGLACING:
628  $track_entry[$subelement['id_name']] = (bool) getid3_lib::BigEndian2Int($subelement['data']);
629  break;
630 
631  case EBML_ID_VIDEO:
632 
633  while ($this->getEBMLelement($sub_subelement, $subelement['end'], true)) {
634  switch ($sub_subelement['id']) {
635 
636  case EBML_ID_PIXELWIDTH:
637  case EBML_ID_PIXELHEIGHT:
644  case EBML_ID_DISPLAYUNIT:
646  case EBML_ID_STEREOMODE:
648  $track_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']);
649  break;
650 
652  $track_entry[$sub_subelement['id_name']] = (bool)getid3_lib::BigEndian2Int($sub_subelement['data']);
653  break;
654 
655  case EBML_ID_GAMMAVALUE:
656  $track_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Float($sub_subelement['data']);
657  break;
658 
659  case EBML_ID_COLOURSPACE:
660  $track_entry[$sub_subelement['id_name']] = getid3_lib::trimNullByte($sub_subelement['data']);
661  break;
662 
663  default:
664  $this->unhandledElement('track.video', __LINE__, $sub_subelement);
665  break;
666  }
667  }
668  break;
669 
670  case EBML_ID_AUDIO:
671 
672  while ($this->getEBMLelement($sub_subelement, $subelement['end'], true)) {
673  switch ($sub_subelement['id']) {
674 
675  case EBML_ID_CHANNELS:
676  case EBML_ID_BITDEPTH:
677  $track_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']);
678  break;
679 
682  $track_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Float($sub_subelement['data']);
683  break;
684 
686  $track_entry[$sub_subelement['id_name']] = getid3_lib::trimNullByte($sub_subelement['data']);
687  break;
688 
689  default:
690  $this->unhandledElement('track.audio', __LINE__, $sub_subelement);
691  break;
692  }
693  }
694  break;
695 
697 
698  while ($this->getEBMLelement($sub_subelement, $subelement['end'])) {
699  switch ($sub_subelement['id']) {
700 
702 
703  while ($this->getEBMLelement($sub_sub_subelement, $sub_subelement['end'], array(EBML_ID_CONTENTCOMPRESSION, EBML_ID_CONTENTENCRYPTION))) {
704  switch ($sub_sub_subelement['id']) {
705 
709  $track_entry[$sub_subelement['id_name']][$sub_sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_sub_subelement['data']);
710  break;
711 
713 
714  while ($this->getEBMLelement($sub_sub_sub_subelement, $sub_sub_subelement['end'], true)) {
715  switch ($sub_sub_sub_subelement['id']) {
716 
718  $track_entry[$sub_subelement['id_name']][$sub_sub_subelement['id_name']][$sub_sub_sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_sub_sub_subelement['data']);
719  break;
720 
722  $track_entry[$sub_subelement['id_name']][$sub_sub_subelement['id_name']][$sub_sub_sub_subelement['id_name']] = $sub_sub_sub_subelement['data'];
723  break;
724 
725  default:
726  $this->unhandledElement('track.contentencodings.contentencoding.contentcompression', __LINE__, $sub_sub_sub_subelement);
727  break;
728  }
729  }
730  break;
731 
733 
734  while ($this->getEBMLelement($sub_sub_sub_subelement, $sub_sub_subelement['end'], true)) {
735  switch ($sub_sub_sub_subelement['id']) {
736 
740  $track_entry[$sub_subelement['id_name']][$sub_sub_subelement['id_name']][$sub_sub_sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_sub_sub_subelement['data']);
741  break;
742 
746  $track_entry[$sub_subelement['id_name']][$sub_sub_subelement['id_name']][$sub_sub_sub_subelement['id_name']] = $sub_sub_sub_subelement['data'];
747  break;
748 
749  default:
750  $this->unhandledElement('track.contentencodings.contentencoding.contentcompression', __LINE__, $sub_sub_sub_subelement);
751  break;
752  }
753  }
754  break;
755 
756  default:
757  $this->unhandledElement('track.contentencodings.contentencoding', __LINE__, $sub_sub_subelement);
758  break;
759  }
760  }
761  break;
762 
763  default:
764  $this->unhandledElement('track.contentencodings', __LINE__, $sub_subelement);
765  break;
766  }
767  }
768  break;
769 
770  default:
771  $this->unhandledElement('track', __LINE__, $subelement);
772  break;
773  }
774  }
775 
776  $info['matroska']['tracks']['tracks'][] = $track_entry;
777  break;
778 
779  default:
780  $this->unhandledElement('tracks', __LINE__, $track_entry);
781  break;
782  }
783  }
784  break;
785 
786  case EBML_ID_INFO: // Contains miscellaneous general information and statistics on the file.
787  $info_entry = array();
788 
789  while ($this->getEBMLelement($subelement, $element_data['end'], true)) {
790  switch ($subelement['id']) {
791 
793  $info_entry[$subelement['id_name']] = getid3_lib::BigEndian2Int($subelement['data']);
794  break;
795 
796  case EBML_ID_DURATION:
797  $info_entry[$subelement['id_name']] = getid3_lib::BigEndian2Float($subelement['data']);
798  break;
799 
800  case EBML_ID_DATEUTC:
801  $info_entry[$subelement['id_name']] = getid3_lib::BigEndian2Int($subelement['data']);
802  $info_entry[$subelement['id_name'].'_unix'] = self::EBMLdate2unix($info_entry[$subelement['id_name']]);
803  break;
804 
805  case EBML_ID_SEGMENTUID:
806  case EBML_ID_PREVUID:
807  case EBML_ID_NEXTUID:
808  $info_entry[$subelement['id_name']] = getid3_lib::trimNullByte($subelement['data']);
809  break;
810 
812  $info_entry[$subelement['id_name']][] = getid3_lib::trimNullByte($subelement['data']);
813  break;
814 
818  case EBML_ID_TITLE:
819  case EBML_ID_MUXINGAPP:
820  case EBML_ID_WRITINGAPP:
821  $info_entry[$subelement['id_name']] = getid3_lib::trimNullByte($subelement['data']);
822  $info['matroska']['comments'][strtolower($subelement['id_name'])][] = $info_entry[$subelement['id_name']];
823  break;
824 
826  $chaptertranslate_entry = array();
827 
828  while ($this->getEBMLelement($sub_subelement, $subelement['end'], true)) {
829  switch ($sub_subelement['id']) {
830 
832  $chaptertranslate_entry[$sub_subelement['id_name']][] = getid3_lib::BigEndian2Int($sub_subelement['data']);
833  break;
834 
836  $chaptertranslate_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']);
837  break;
838 
840  $chaptertranslate_entry[$sub_subelement['id_name']] = getid3_lib::trimNullByte($sub_subelement['data']);
841  break;
842 
843  default:
844  $this->unhandledElement('info.chaptertranslate', __LINE__, $sub_subelement);
845  break;
846  }
847  }
848  $info_entry[$subelement['id_name']] = $chaptertranslate_entry;
849  break;
850 
851  default:
852  $this->unhandledElement('info', __LINE__, $subelement);
853  break;
854  }
855  }
856  $info['matroska']['info'][] = $info_entry;
857  break;
858 
859  case EBML_ID_CUES: // A top-level element to speed seeking access. All entries are local to the segment. Should be mandatory for non "live" streams.
860  if (self::$hide_clusters) { // do not parse cues if hide clusters is "ON" till they point to clusters anyway
861  $this->current_offset = $element_data['end'];
862  break;
863  }
864  $cues_entry = array();
865 
866  while ($this->getEBMLelement($subelement, $element_data['end'])) {
867  switch ($subelement['id']) {
868 
869  case EBML_ID_CUEPOINT:
870  $cuepoint_entry = array();
871 
872  while ($this->getEBMLelement($sub_subelement, $subelement['end'], array(EBML_ID_CUETRACKPOSITIONS))) {
873  switch ($sub_subelement['id']) {
874 
876  $cuetrackpositions_entry = array();
877 
878  while ($this->getEBMLelement($sub_sub_subelement, $sub_subelement['end'], true)) {
879  switch ($sub_sub_subelement['id']) {
880 
881  case EBML_ID_CUETRACK:
885  $cuetrackpositions_entry[$sub_sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_sub_subelement['data']);
886  break;
887 
888  default:
889  $this->unhandledElement('cues.cuepoint.cuetrackpositions', __LINE__, $sub_sub_subelement);
890  break;
891  }
892  }
893  $cuepoint_entry[$sub_subelement['id_name']][] = $cuetrackpositions_entry;
894  break;
895 
896  case EBML_ID_CUETIME:
897  $cuepoint_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']);
898  break;
899 
900  default:
901  $this->unhandledElement('cues.cuepoint', __LINE__, $sub_subelement);
902  break;
903  }
904  }
905  $cues_entry[] = $cuepoint_entry;
906  break;
907 
908  default:
909  $this->unhandledElement('cues', __LINE__, $subelement);
910  break;
911  }
912  }
913  $info['matroska']['cues'] = $cues_entry;
914  break;
915 
916  case EBML_ID_TAGS: // Element containing elements specific to Tracks/Chapters.
917  $tags_entry = array();
918 
919  while ($this->getEBMLelement($subelement, $element_data['end'], false)) {
920  switch ($subelement['id']) {
921 
922  case EBML_ID_TAG:
923  $tag_entry = array();
924 
925  while ($this->getEBMLelement($sub_subelement, $subelement['end'], false)) {
926  switch ($sub_subelement['id']) {
927 
928  case EBML_ID_TARGETS:
929  $targets_entry = array();
930 
931  while ($this->getEBMLelement($sub_sub_subelement, $sub_subelement['end'], true)) {
932  switch ($sub_sub_subelement['id']) {
933 
935  $targets_entry[$sub_sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_sub_subelement['data']);
936  $targets_entry[strtolower($sub_sub_subelement['id_name']).'_long'] = self::TargetTypeValue($targets_entry[$sub_sub_subelement['id_name']]);
937  break;
938 
939  case EBML_ID_TARGETTYPE:
940  $targets_entry[$sub_sub_subelement['id_name']] = $sub_sub_subelement['data'];
941  break;
942 
943  case EBML_ID_TAGTRACKUID:
947  $targets_entry[$sub_sub_subelement['id_name']][] = getid3_lib::BigEndian2Int($sub_sub_subelement['data']);
948  break;
949 
950  default:
951  $this->unhandledElement('tags.tag.targets', __LINE__, $sub_sub_subelement);
952  break;
953  }
954  }
955  $tag_entry[$sub_subelement['id_name']] = $targets_entry;
956  break;
957 
958  case EBML_ID_SIMPLETAG:
959  $tag_entry[$sub_subelement['id_name']][] = $this->HandleEMBLSimpleTag($sub_subelement['end']);
960  break;
961 
962  default:
963  $this->unhandledElement('tags.tag', __LINE__, $sub_subelement);
964  break;
965  }
966  }
967  $tags_entry[] = $tag_entry;
968  break;
969 
970  default:
971  $this->unhandledElement('tags', __LINE__, $subelement);
972  break;
973  }
974  }
975  $info['matroska']['tags'] = $tags_entry;
976  break;
977 
978  case EBML_ID_ATTACHMENTS: // Contain attached files.
979 
980  while ($this->getEBMLelement($subelement, $element_data['end'])) {
981  switch ($subelement['id']) {
982 
984  $attachedfile_entry = array();
985 
986  while ($this->getEBMLelement($sub_subelement, $subelement['end'], array(EBML_ID_FILEDATA))) {
987  switch ($sub_subelement['id']) {
988 
990  case EBML_ID_FILENAME:
992  $attachedfile_entry[$sub_subelement['id_name']] = $sub_subelement['data'];
993  break;
994 
995  case EBML_ID_FILEDATA:
996  $attachedfile_entry['data_offset'] = $this->current_offset;
997  $attachedfile_entry['data_length'] = $sub_subelement['length'];
998 
999  $attachedfile_entry[$sub_subelement['id_name']] = $this->saveAttachment(
1000  $attachedfile_entry['FileName'],
1001  $attachedfile_entry['data_offset'],
1002  $attachedfile_entry['data_length']);
1003 
1004  $this->current_offset = $sub_subelement['end'];
1005  break;
1006 
1007  case EBML_ID_FILEUID:
1008  $attachedfile_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']);
1009  break;
1010 
1011  default:
1012  $this->unhandledElement('attachments.attachedfile', __LINE__, $sub_subelement);
1013  break;
1014  }
1015  }
1016  $info['matroska']['attachments'][] = $attachedfile_entry;
1017  break;
1018 
1019  default:
1020  $this->unhandledElement('attachments', __LINE__, $subelement);
1021  break;
1022  }
1023  }
1024  break;
1025 
1026  case EBML_ID_CHAPTERS:
1027 
1028  while ($this->getEBMLelement($subelement, $element_data['end'])) {
1029  switch ($subelement['id']) {
1030 
1031  case EBML_ID_EDITIONENTRY:
1032  $editionentry_entry = array();
1033 
1034  while ($this->getEBMLelement($sub_subelement, $subelement['end'], array(EBML_ID_CHAPTERATOM))) {
1035  switch ($sub_subelement['id']) {
1036 
1037  case EBML_ID_EDITIONUID:
1038  $editionentry_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']);
1039  break;
1040 
1044  $editionentry_entry[$sub_subelement['id_name']] = (bool)getid3_lib::BigEndian2Int($sub_subelement['data']);
1045  break;
1046 
1047  case EBML_ID_CHAPTERATOM:
1048  $chapteratom_entry = array();
1049 
1050  while ($this->getEBMLelement($sub_sub_subelement, $sub_subelement['end'], array(EBML_ID_CHAPTERTRACK, EBML_ID_CHAPTERDISPLAY))) {
1051  switch ($sub_sub_subelement['id']) {
1052 
1055  $chapteratom_entry[$sub_sub_subelement['id_name']] = $sub_sub_subelement['data'];
1056  break;
1057 
1060  $chapteratom_entry[$sub_sub_subelement['id_name']] = (bool)getid3_lib::BigEndian2Int($sub_sub_subelement['data']);
1061  break;
1062 
1063  case EBML_ID_CHAPTERUID:
1066  $chapteratom_entry[$sub_sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_sub_subelement['data']);
1067  break;
1068 
1069  case EBML_ID_CHAPTERTRACK:
1070  $chaptertrack_entry = array();
1071 
1072  while ($this->getEBMLelement($sub_sub_sub_subelement, $sub_sub_subelement['end'], true)) {
1073  switch ($sub_sub_sub_subelement['id']) {
1074 
1076  $chaptertrack_entry[$sub_sub_sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_sub_sub_subelement['data']);
1077  break;
1078 
1079  default:
1080  $this->unhandledElement('chapters.editionentry.chapteratom.chaptertrack', __LINE__, $sub_sub_sub_subelement);
1081  break;
1082  }
1083  }
1084  $chapteratom_entry[$sub_sub_subelement['id_name']][] = $chaptertrack_entry;
1085  break;
1086 
1088  $chapterdisplay_entry = array();
1089 
1090  while ($this->getEBMLelement($sub_sub_sub_subelement, $sub_sub_subelement['end'], true)) {
1091  switch ($sub_sub_sub_subelement['id']) {
1092 
1093  case EBML_ID_CHAPSTRING:
1094  case EBML_ID_CHAPLANGUAGE:
1095  case EBML_ID_CHAPCOUNTRY:
1096  $chapterdisplay_entry[$sub_sub_sub_subelement['id_name']] = $sub_sub_sub_subelement['data'];
1097  break;
1098 
1099  default:
1100  $this->unhandledElement('chapters.editionentry.chapteratom.chapterdisplay', __LINE__, $sub_sub_sub_subelement);
1101  break;
1102  }
1103  }
1104  $chapteratom_entry[$sub_sub_subelement['id_name']][] = $chapterdisplay_entry;
1105  break;
1106 
1107  default:
1108  $this->unhandledElement('chapters.editionentry.chapteratom', __LINE__, $sub_sub_subelement);
1109  break;
1110  }
1111  }
1112  $editionentry_entry[$sub_subelement['id_name']][] = $chapteratom_entry;
1113  break;
1114 
1115  default:
1116  $this->unhandledElement('chapters.editionentry', __LINE__, $sub_subelement);
1117  break;
1118  }
1119  }
1120  $info['matroska']['chapters'][] = $editionentry_entry;
1121  break;
1122 
1123  default:
1124  $this->unhandledElement('chapters', __LINE__, $subelement);
1125  break;
1126  }
1127  }
1128  break;
1129 
1130  case EBML_ID_CLUSTER: // The lower level element containing the (monolithic) Block structure.
1131  $cluster_entry = array();
1132 
1133  while ($this->getEBMLelement($subelement, $element_data['end'], array(EBML_ID_CLUSTERSILENTTRACKS, EBML_ID_CLUSTERBLOCKGROUP, EBML_ID_CLUSTERSIMPLEBLOCK))) {
1134  switch ($subelement['id']) {
1135 
1139  $cluster_entry[$subelement['id_name']] = getid3_lib::BigEndian2Int($subelement['data']);
1140  break;
1141 
1143  $cluster_silent_tracks = array();
1144 
1145  while ($this->getEBMLelement($sub_subelement, $subelement['end'], true)) {
1146  switch ($sub_subelement['id']) {
1147 
1149  $cluster_silent_tracks[] = getid3_lib::BigEndian2Int($sub_subelement['data']);
1150  break;
1151 
1152  default:
1153  $this->unhandledElement('cluster.silenttracks', __LINE__, $sub_subelement);
1154  break;
1155  }
1156  }
1157  $cluster_entry[$subelement['id_name']][] = $cluster_silent_tracks;
1158  break;
1159 
1161  $cluster_block_group = array('offset' => $this->current_offset);
1162 
1163  while ($this->getEBMLelement($sub_subelement, $subelement['end'], array(EBML_ID_CLUSTERBLOCK))) {
1164  switch ($sub_subelement['id']) {
1165 
1166  case EBML_ID_CLUSTERBLOCK:
1167  $cluster_block_group[$sub_subelement['id_name']] = $this->HandleEMBLClusterBlock($sub_subelement, EBML_ID_CLUSTERBLOCK, $info);
1168  break;
1169 
1170  case EBML_ID_CLUSTERREFERENCEPRIORITY: // unsigned-int
1171  case EBML_ID_CLUSTERBLOCKDURATION: // unsigned-int
1172  $cluster_block_group[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']);
1173  break;
1174 
1175  case EBML_ID_CLUSTERREFERENCEBLOCK: // signed-int
1176  $cluster_block_group[$sub_subelement['id_name']][] = getid3_lib::BigEndian2Int($sub_subelement['data'], false, true);
1177  break;
1178 
1180  $cluster_block_group[$sub_subelement['id_name']] = getid3_lib::trimNullByte($sub_subelement['data']);
1181  break;
1182 
1183  default:
1184  $this->unhandledElement('clusters.blockgroup', __LINE__, $sub_subelement);
1185  break;
1186  }
1187  }
1188  $cluster_entry[$subelement['id_name']][] = $cluster_block_group;
1189  break;
1190 
1192  $cluster_entry[$subelement['id_name']][] = $this->HandleEMBLClusterBlock($subelement, EBML_ID_CLUSTERSIMPLEBLOCK, $info);
1193  break;
1194 
1195  default:
1196  $this->unhandledElement('cluster', __LINE__, $subelement);
1197  break;
1198  }
1199  $this->current_offset = $subelement['end'];
1200  }
1201  if (!self::$hide_clusters) {
1202  $info['matroska']['cluster'][] = $cluster_entry;
1203  }
1204 
1205  // check to see if all the data we need exists already, if so, break out of the loop
1206  if (!self::$parse_whole_file) {
1207  if (isset($info['matroska']['info']) && is_array($info['matroska']['info'])) {
1208  if (isset($info['matroska']['tracks']['tracks']) && is_array($info['matroska']['tracks']['tracks'])) {
1209  if (count($info['matroska']['track_data_offsets']) == count($info['matroska']['tracks']['tracks'])) {
1210  return;
1211  }
1212  }
1213  }
1214  }
1215  break;
1216 
1217  default:
1218  $this->unhandledElement('segment', __LINE__, $element_data);
1219  break;
1220  }
1221  }
1222  break;
1223 
1224  default:
1225  $this->unhandledElement('root', __LINE__, $top_element);
1226  break;
1227  }
1228  }
1229  }
const EBML_ID_CONTENTSIGALGO
const EBML_ID_CUECLUSTERPOSITION
const EBML_ID_CLUSTERCODECSTATE
const EBML_ID_TRACKNUMBER
const EBML_ID_CLUSTERPREVSIZE
const EBML_ID_CONTENTSIGNATURE
const EBML_ID_DISPLAYUNIT
const EBML_ID_TARGETTYPEVALUE
const EBML_ID_FLAGFORCED
const EBML_ID_PREVUID
const EBML_ID_CHAPTERDISPLAY
const EBML_ID_SAMPLINGFREQUENCY
const EBML_ID_CONTENTENCODING
const EBML_ID_ASPECTRATIOTYPE
const EBML_ID_GAMMAVALUE
const EBML_ID_CHAPTERTRANSLATEID
const EBML_ID_CHAPTERFLAGENABLED
const EBML_ID_COLOURSPACE
const EBML_ID_CONTENTENCODINGSCOPE
const EBML_ID_CLUSTERSILENTTRACKS
const EBML_ID_SEEKHEAD
const EBML_ID_ATTACHEDFILE
const EBML_ID_CONTENTENCKEYID
const EBML_ID_FILEDATA
const EBML_ID_EDITIONENTRY
const EBML_ID_CODECPRIVATE
const EBML_ID_CLUSTERSIMPLEBLOCK
const EBML_ID_CONTENTENCODINGORDER
const EBML_ID_SEEKPOSITION
const EBML_ID_CONTENTCOMPALGO
const EBML_ID_CHAPLANGUAGE
HandleEMBLClusterBlock($element, $block_type, &$info)
const EBML_ID_CONTENTENCODINGTYPE
const EBML_ID_TRACKUID
const EBML_ID_CODECNAME
const EBML_ID_CHAPTERUID
const EBML_ID_PIXELHEIGHT
const EBML_ID_NEXTUID
const EBML_ID_FLAGENABLED
const EBML_ID_TRACKS
warning($text)
Definition: getid3.php:1758
saveAttachment($name, $offset, $length, $image_mime=null)
Definition: getid3.php:1766
const EBML_ID_CONTENTSIGHASHALGO
const EBML_ID_PIXELCROPRIGHT
const EBML_ID_CLUSTERBLOCK
const EBML_ID_NEXTFILENAME
const EBML_ID_TAGEDITIONUID
const EBML_ID_CHAPTERTRACKNUMBER
const EBML_ID_SIMPLETAG
const EBML_ID_EDITIONFLAGHIDDEN
const EBML_ID_SEGMENTUID
const EBML_ID_CUETRACKPOSITIONS
const EBML_ID_DEFAULTDURATION
const EBML_ID_MINCACHE
const EBML_ID_CHAPTERSEGMENTUID
const EBML_ID_CUEPOINT
getEBMLelement(&$element, $parent_end, $get_data=false)
const EBML_ID_LANGUAGE
const EBML_ID_CHAPTERFLAGHIDDEN
const EBML_ID_CHAPTERTIMESTART
const EBML_ID_SEGMENT
const EBML_ID_DISPLAYWIDTH
const EBML_ID_TAGCHAPTERUID
const EBML_ID_CHAPCOUNTRY
static BigEndian2Float($byteword)
Definition: getid3.lib.php:185
const EBML_ID_CHAPTERTIMEEND
const EBML_ID_EDITIONFLAGDEFAULT
const EBML_ID_CHANNELPOSITIONS
const EBML_ID_EBMLVERSION
const EBML_ID_OUTPUTSAMPLINGFREQUENCY
const EBML_ID_DOCTYPE
const EBML_ID_DURATION
const EBML_ID_CLUSTER
const EBML_ID_EDITIONFLAGORDERED
const EBML_ID_CONTENTENCODINGS
const EBML_ID_CLUSTERSILENTTRACKNUMBER
const EBML_ID_CUETRACK
const EBML_ID_ATTACHMENTS
static trimNullByte($string)
const EBML_ID_CLUSTERREFERENCEPRIORITY
const EBML_ID_BITDEPTH
const EBML_ID_CONTENTCOMPSETTINGS
const EBML_ID_CHANNELS
const EBML_ID_CLUSTERBLOCKGROUP
const EBML_ID_PIXELCROPTOP
const EBML_ID_SEGMENTFILENAME
const EBML_ID_TAGTRACKUID
const EBML_ID_MUXINGAPP
readEBMLelementData($length, $check_buffer=false)
const EBML_ID_CHAPTERTRANSLATE
const EBML_ID_TRACKTIMECODESCALE
const EBML_ID_CONTENTCOMPRESSION
const EBML_ID_CHAPTERSEGMENTEDITIONUID
const EBML_ID_PIXELCROPBOTTOM
const EBML_ID_TARGETTYPE
const EBML_ID_CLUSTERPOSITION
const EBML_ID_EBMLMAXIDLENGTH
const EBML_ID_FLAGLACING
const EBML_ID_CHAPTERTRANSLATECODEC
const EBML_ID_MAXCACHE
const EBML_ID_STEREOMODE
const EBML_ID_CHAPTERTRANSLATEEDITIONUID
const EBML_ID_CONTENTSIGKEYID
const EBML_ID_CODECDECODEALL
const EBML_ID_EBMLMAXSIZELENGTH
const EBML_ID_FLAGINTERLACED
const EBML_ID_DISPLAYHEIGHT
const EBML_ID_CHAPTERATOM
const EBML_ID_FILEDESCRIPTION
const EBML_ID_TAGATTACHMENTUID
const EBML_ID_FLAGDEFAULT
const EBML_ID_CUEBLOCKNUMBER
const EBML_ID_FILEUID
const EBML_ID_FILENAME
const EBML_ID_EBMLREADVERSION
unhandledElement($type, $line, $element)
const EBML_ID_CLUSTERREFERENCEBLOCK
const EBML_ID_DOCTYPEVERSION
const EBML_ID_PIXELWIDTH
const EBML_ID_PREVFILENAME
const EBML_ID_TRACKTYPE
const EBML_ID_TIMECODESCALE
const EBML_ID_WRITINGAPP
const EBML_ID_SEGMENTFAMILY
const EBML_ID_DOCTYPEREADVERSION
const EBML_ID_CUECODECSTATE
const EBML_ID_CHAPTERTRACK
const EBML_ID_PIXELCROPLEFT
const EBML_ID_CONTENTENCRYPTION
$info
Definition: index.php:5
const EBML_ID_SEEKID
const EBML_ID_FILEMIMETYPE
static BigEndian2Int($byteword, $synchsafe=false, $signed=false)
Definition: getid3.lib.php:263
const EBML_ID_CONTENTENCALGO
const EBML_ID_MAXBLOCKADDITIONID
const EBML_ID_CLUSTERBLOCKDURATION
const EBML_ID_DATEUTC
const EBML_ID_EDITIONUID
const EBML_ID_CHAPTERS
getID3() by James Heinrich info@getid3.org //
const EBML_ID_CLUSTERTIMECODE
const EBML_ID_OLDSTEREOMODE
const EBML_ID_CHAPSTRING
const EBML_ID_TRACKENTRY
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ readEBMLelementData()

getid3_matroska::readEBMLelementData (   $length,
  $check_buffer = false 
)
private

Definition at line 1284 of file module.audio-video.matroska.php.

References $data, and EnsureBufferHasEnoughData().

Referenced by getEBMLelement(), HandleEMBLClusterBlock(), and parseEBML().

1284  {
1285  if ($check_buffer && !$this->EnsureBufferHasEnoughData($length)) {
1286  return false;
1287  }
1288  $data = substr($this->EBMLbuffer, $this->current_offset - $this->EBMLbuffer_offset, $length);
1289  $this->current_offset += $length;
1290  return $data;
1291  }
EnsureBufferHasEnoughData($min_data=1024)
$data
Definition: bench.php:6
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ readEBMLint()

getid3_matroska::readEBMLint ( )
private

Definition at line 1252 of file module.audio-video.matroska.php.

References $EBMLbuffer_offset.

Referenced by getEBMLelement(), and HandleEMBLClusterBlock().

1252  {
1253  $actual_offset = $this->current_offset - $this->EBMLbuffer_offset;
1254 
1255  // get length of integer
1256  $first_byte_int = ord($this->EBMLbuffer[$actual_offset]);
1257  if (0x80 & $first_byte_int) {
1258  $length = 1;
1259  } elseif (0x40 & $first_byte_int) {
1260  $length = 2;
1261  } elseif (0x20 & $first_byte_int) {
1262  $length = 3;
1263  } elseif (0x10 & $first_byte_int) {
1264  $length = 4;
1265  } elseif (0x08 & $first_byte_int) {
1266  $length = 5;
1267  } elseif (0x04 & $first_byte_int) {
1268  $length = 6;
1269  } elseif (0x02 & $first_byte_int) {
1270  $length = 7;
1271  } elseif (0x01 & $first_byte_int) {
1272  $length = 8;
1273  } else {
1274  throw new Exception('invalid EBML integer (leading 0x00) at '.$this->current_offset);
1275  }
1276 
1277  // read
1278  $int_value = self::EBML2Int(substr($this->EBMLbuffer, $actual_offset, $length));
1279  $this->current_offset += $length;
1280 
1281  return $int_value;
1282  }
+ Here is the caller graph for this function:

◆ TargetTypeValue()

static getid3_matroska::TargetTypeValue (   $target_type)
static

Definition at line 1497 of file module.audio-video.matroska.php.

References $target_type.

1497  {
1498  // http://www.matroska.org/technical/specs/tagging/index.html
1499  static $TargetTypeValue = array();
1500  if (empty($TargetTypeValue)) {
1501  $TargetTypeValue[10] = 'A: ~ V:shot'; // the lowest hierarchy found in music or movies
1502  $TargetTypeValue[20] = 'A:subtrack/part/movement ~ V:scene'; // corresponds to parts of a track for audio (like a movement)
1503  $TargetTypeValue[30] = 'A:track/song ~ V:chapter'; // the common parts of an album or a movie
1504  $TargetTypeValue[40] = 'A:part/session ~ V:part/session'; // when an album or episode has different logical parts
1505  $TargetTypeValue[50] = 'A:album/opera/concert ~ V:movie/episode/concert'; // the most common grouping level of music and video (equals to an episode for TV series)
1506  $TargetTypeValue[60] = 'A:edition/issue/volume/opus ~ V:season/sequel/volume'; // a list of lower levels grouped together
1507  $TargetTypeValue[70] = 'A:collection ~ V:collection'; // the high hierarchy consisting of many different lower items
1508  }
1509  return (isset($TargetTypeValue[$target_type]) ? $TargetTypeValue[$target_type] : $target_type);
1510  }
$target_type
Definition: goto.php:48

◆ unhandledElement()

getid3_matroska::unhandledElement (   $type,
  $line,
  $element 
)
private

Definition at line 1329 of file module.audio-video.matroska.php.

References $type, and getid3_handler\warning().

Referenced by HandleEMBLSimpleTag(), and parseEBML().

1329  {
1330  // warn only about unknown and missed elements, not about unuseful
1331  if (!in_array($element['id'], $this->unuseful_elements)) {
1332  $this->warning('Unhandled '.$type.' element ['.basename(__FILE__).':'.$line.'] ('.$element['id'].'::'.$element['id_name'].' ['.$element['length'].' bytes]) at '.$element['offset']);
1333  }
1334 
1335  // increase offset for unparsed elements
1336  if (!isset($element['data'])) {
1337  $this->current_offset = $element['end'];
1338  }
1339  }
$type
warning($text)
Definition: getid3.php:1758
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Field Documentation

◆ $current_offset

getid3_matroska::$current_offset = 0
private

◆ $EBMLbuffer

getid3_matroska::$EBMLbuffer = ''
private

Definition at line 223 of file module.audio-video.matroska.php.

◆ $EBMLbuffer_length

getid3_matroska::$EBMLbuffer_length = 0
private

Definition at line 225 of file module.audio-video.matroska.php.

◆ $EBMLbuffer_offset

getid3_matroska::$EBMLbuffer_offset = 0
private

Definition at line 224 of file module.audio-video.matroska.php.

Referenced by readEBMLint().

◆ $hide_clusters

getid3_matroska::$hide_clusters = true
static

Definition at line 219 of file module.audio-video.matroska.php.

◆ $parse_whole_file

getid3_matroska::$parse_whole_file = false
static

Definition at line 220 of file module.audio-video.matroska.php.

◆ $unuseful_elements

getid3_matroska::$unuseful_elements = array(EBML_ID_CRC32, EBML_ID_VOID)
private

Definition at line 227 of file module.audio-video.matroska.php.


The documentation for this class was generated from the following file: