ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
getid3_matroska Class Reference

getID3() by James Heinrich info@.nosp@m.geti.nosp@m.d3.or.nosp@m.g // More...

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

Public Member Functions

 getid3_matroska (&$fd, &$ThisFileInfo)
 
 EBML2Int ($EBMLstring)
 
 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

getID3() by James Heinrich info@.nosp@m.geti.nosp@m.d3.or.nosp@m.g //

@tutorial 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 17 of file module.audio-video.matroska.php.

Member Function Documentation

◆ Analyze()

getid3_matroska::Analyze ( )

Reimplemented from getid3_handler.

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

230 {
231 $info = &$this->getid3->info;
232
233 // parse container
234 try {
235 $this->parseEBML($info);
236 } catch (Exception $e) {
237 $info['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_DTS':
334 case 'A_MPEG/L3':
335 case 'A_MPEG/L2':
336 case 'A_FLAC':
337 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.'.($track_info['dataformat'] == 'mp2' ? 'mp3' : $track_info['dataformat']).'.php', __FILE__, true);
338
339 if (!isset($info['matroska']['track_data_offsets'][$trackarray['TrackNumber']])) {
340 $this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because $info[matroska][track_data_offsets]['.$trackarray['TrackNumber'].'] not set');
341 break;
342 }
343
344 // create temp instance
345 $getid3_temp = new getID3();
346 if ($track_info['dataformat'] != 'flac') {
347 $getid3_temp->openfile($this->getid3->filename);
348 }
349 $getid3_temp->info['avdataoffset'] = $info['matroska']['track_data_offsets'][$trackarray['TrackNumber']]['offset'];
350 if ($track_info['dataformat'][0] == 'm' || $track_info['dataformat'] == 'flac') {
351 $getid3_temp->info['avdataend'] = $info['matroska']['track_data_offsets'][$trackarray['TrackNumber']]['offset'] + $info['matroska']['track_data_offsets'][$trackarray['TrackNumber']]['length'];
352 }
353
354 // analyze
355 $class = 'getid3_'.($track_info['dataformat'] == 'mp2' ? 'mp3' : $track_info['dataformat']);
356 $header_data_key = $track_info['dataformat'][0] == 'm' ? 'mpeg' : $track_info['dataformat'];
357 $getid3_audio = new $class($getid3_temp, __CLASS__);
358 if ($track_info['dataformat'] == 'flac') {
359 $getid3_audio->AnalyzeString($trackarray['CodecPrivate']);
360 }
361 else {
362 $getid3_audio->Analyze();
363 }
364 if (!empty($getid3_temp->info[$header_data_key])) {
365 $info['matroska']['track_codec_parsed'][$trackarray['TrackNumber']] = $getid3_temp->info[$header_data_key];
366 if (isset($getid3_temp->info['audio']) && is_array($getid3_temp->info['audio'])) {
367 foreach ($getid3_temp->info['audio'] as $key => $value) {
368 $track_info[$key] = $value;
369 }
370 }
371 }
372 else {
373 $this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because '.$class.'::Analyze() failed at offset '.$getid3_temp->info['avdataoffset']);
374 }
375
376 // copy errors and warnings
377 if (!empty($getid3_temp->info['error'])) {
378 foreach ($getid3_temp->info['error'] as $newerror) {
379 $this->warning($class.'() says: ['.$newerror.']');
380 }
381 }
382 if (!empty($getid3_temp->info['warning'])) {
383 foreach ($getid3_temp->info['warning'] as $newerror) {
384 $this->warning($class.'() says: ['.$newerror.']');
385 }
386 }
387 unset($getid3_temp, $getid3_audio);
388 break;
389
390 case 'A_AAC':
391 case 'A_AAC/MPEG2/LC':
392 case 'A_AAC/MPEG2/LC/SBR':
393 case 'A_AAC/MPEG4/LC':
394 case 'A_AAC/MPEG4/LC/SBR':
395 $this->warning($trackarray['CodecID'].' audio data contains no header, audio/video bitrates can\'t be calculated');
396 break;
397
398 case 'A_VORBIS':
399 if (!isset($trackarray['CodecPrivate'])) {
400 $this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because CodecPrivate data not set');
401 break;
402 }
403 $vorbis_offset = strpos($trackarray['CodecPrivate'], 'vorbis', 1);
404 if ($vorbis_offset === false) {
405 $this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because CodecPrivate data does not contain "vorbis" keyword');
406 break;
407 }
408 $vorbis_offset -= 1;
409
410 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ogg.php', __FILE__, true);
411
412 // create temp instance
413 $getid3_temp = new getID3();
414
415 // analyze
416 $getid3_ogg = new getid3_ogg($getid3_temp);
417 $oggpageinfo['page_seqno'] = 0;
418 $getid3_ogg->ParseVorbisPageHeader($trackarray['CodecPrivate'], $vorbis_offset, $oggpageinfo);
419 if (!empty($getid3_temp->info['ogg'])) {
420 $info['matroska']['track_codec_parsed'][$trackarray['TrackNumber']] = $getid3_temp->info['ogg'];
421 if (isset($getid3_temp->info['audio']) && is_array($getid3_temp->info['audio'])) {
422 foreach ($getid3_temp->info['audio'] as $key => $value) {
423 $track_info[$key] = $value;
424 }
425 }
426 }
427
428 // copy errors and warnings
429 if (!empty($getid3_temp->info['error'])) {
430 foreach ($getid3_temp->info['error'] as $newerror) {
431 $this->warning('getid3_ogg() says: ['.$newerror.']');
432 }
433 }
434 if (!empty($getid3_temp->info['warning'])) {
435 foreach ($getid3_temp->info['warning'] as $newerror) {
436 $this->warning('getid3_ogg() says: ['.$newerror.']');
437 }
438 }
439
440 if (!empty($getid3_temp->info['ogg']['bitrate_nominal'])) {
441 $track_info['bitrate'] = $getid3_temp->info['ogg']['bitrate_nominal'];
442 }
443 unset($getid3_temp, $getid3_ogg, $oggpageinfo, $vorbis_offset);
444 break;
445
446 case 'A_MS/ACM':
447 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.riff.php', __FILE__, true);
448
449 $parsed = getid3_riff::parseWAVEFORMATex($trackarray['CodecPrivate']);
450 foreach ($parsed as $key => $value) {
451 if ($key != 'raw') {
452 $track_info[$key] = $value;
453 }
454 }
455 $info['matroska']['track_codec_parsed'][$trackarray['TrackNumber']] = $parsed;
456 break;
457
458 default:
459 $this->warning('Unhandled audio type "'.(isset($trackarray['CodecID']) ? $trackarray['CodecID'] : '').'"');
460 break;
461 }
462
463 $info['audio']['streams'][] = $track_info;
464 break;
465 }
466 }
467
468 if (!empty($info['video']['streams'])) {
469 $info['video'] = self::getDefaultStreamInfo($info['video']['streams']);
470 }
471 if (!empty($info['audio']['streams'])) {
472 $info['audio'] = self::getDefaultStreamInfo($info['audio']['streams']);
473 }
474 }
475
476 // process attachments
477 if (isset($info['matroska']['attachments']) && $this->getid3->option_save_attachments !== getID3::ATTACHMENTS_NONE) {
478 foreach ($info['matroska']['attachments'] as $i => $entry) {
479 if (strpos($entry['FileMimeType'], 'image/') === 0 && !empty($entry['FileData'])) {
480 $info['matroska']['comments']['picture'][] = array('data' => $entry['FileData'], 'image_mime' => $entry['FileMimeType'], 'filename' => $entry['FileName']);
481 }
482 }
483 }
484
485 // determine mime type
486 if (!empty($info['video']['streams'])) {
487 $info['mime_type'] = ($info['matroska']['doctype'] == 'webm' ? 'video/webm' : 'video/x-matroska');
488 } elseif (!empty($info['audio']['streams'])) {
489 $info['mime_type'] = ($info['matroska']['doctype'] == 'webm' ? 'audio/webm' : 'audio/x-matroska');
490 } elseif (isset($info['mime_type'])) {
491 unset($info['mime_type']);
492 }
493
494 return true;
495 }
const ATTACHMENTS_NONE
Definition: getid3.php:115
warning($text)
Definition: getid3.php:1744
IncludeDependency($filename, $sourcefile, $DieOnFailure=false)
static CodecIDtoCommonName($codecid)
static getDefaultStreamInfo($streams)
ExtractCommentsSimpleTag($SimpleTagArray)
static parseWAVEFORMATex($WaveFormatExData)
static ParseBITMAPINFOHEADER($BITMAPINFOHEADER, $littleEndian=true)
static fourccLookup($fourcc)
$info
Definition: example_052.php:80

References $info, getID3\ATTACHMENTS_NONE, CodecIDtoCommonName(), displayUnit(), ExtractCommentsSimpleTag(), getid3_riff\fourccLookup(), getDefaultStreamInfo(), getid3_lib\IncludeDependency(), getid3_riff\ParseBITMAPINFOHEADER(), parseEBML(), getid3_riff\parseWAVEFORMATex(), and getid3_handler\warning().

+ Here is the call graph for this function:

◆ BlockLacingType()

static getid3_matroska::BlockLacingType (   $lacingtype)
static

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

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

Referenced by HandleEMBLClusterBlock().

+ Here is the caller graph for this function:

◆ CodecIDtoCommonName()

static getid3_matroska::CodecIDtoCommonName (   $codecid)
static

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

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

Referenced by Analyze().

+ Here is the caller graph for this function:

◆ displayUnit()

static getid3_matroska::displayUnit (   $value)
static

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

1752 {
1753 // http://www.matroska.org/technical/specs/index.html#DisplayUnit
1754 static $units = array(
1755 0 => 'pixels',
1756 1 => 'centimeters',
1757 2 => 'inches',
1758 3 => 'Display Aspect Ratio');
1759
1760 return (isset($units[$value]) ? $units[$value] : 'unknown');
1761 }

Referenced by Analyze().

+ Here is the caller graph for this function:

◆ EBML2Int() [1/2]

getid3_matroska::EBML2Int (   $EBMLstring)

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

34 {
35 // http://matroska.org/specs/
36
37 // Element ID coded with an UTF-8 like system:
38 // 1xxx xxxx - Class A IDs (2^7 -2 possible values) (base 0x8X)
39 // 01xx xxxx xxxx xxxx - Class B IDs (2^14-2 possible values) (base 0x4X 0xXX)
40 // 001x xxxx xxxx xxxx xxxx xxxx - Class C IDs (2^21-2 possible values) (base 0x2X 0xXX 0xXX)
41 // 0001 xxxx xxxx xxxx xxxx xxxx xxxx xxxx - Class D IDs (2^28-2 possible values) (base 0x1X 0xXX 0xXX 0xXX)
42 // Values with all x at 0 and 1 are reserved (hence the -2).
43
44 // Data size, in octets, is also coded with an UTF-8 like system :
45 // 1xxx xxxx - value 0 to 2^7-2
46 // 01xx xxxx xxxx xxxx - value 0 to 2^14-2
47 // 001x xxxx xxxx xxxx xxxx xxxx - value 0 to 2^21-2
48 // 0001 xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^28-2
49 // 0000 1xxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^35-2
50 // 0000 01xx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^42-2
51 // 0000 001x xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^49-2
52 // 0000 0001 xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^56-2
53
54 if (0x80 & ord($EBMLstring{0})) {
55 $EBMLstring{0} = chr(ord($EBMLstring{0}) & 0x7F);
56 } elseif (0x40 & ord($EBMLstring{0})) {
57 $EBMLstring{0} = chr(ord($EBMLstring{0}) & 0x3F);
58 } elseif (0x20 & ord($EBMLstring{0})) {
59 $EBMLstring{0} = chr(ord($EBMLstring{0}) & 0x1F);
60 } elseif (0x10 & ord($EBMLstring{0})) {
61 $EBMLstring{0} = chr(ord($EBMLstring{0}) & 0x0F);
62 } elseif (0x08 & ord($EBMLstring{0})) {
63 $EBMLstring{0} = chr(ord($EBMLstring{0}) & 0x07);
64 } elseif (0x04 & ord($EBMLstring{0})) {
65 $EBMLstring{0} = chr(ord($EBMLstring{0}) & 0x03);
66 } elseif (0x02 & ord($EBMLstring{0})) {
67 $EBMLstring{0} = chr(ord($EBMLstring{0}) & 0x01);
68 } elseif (0x01 & ord($EBMLstring{0})) {
69 $EBMLstring{0} = chr(ord($EBMLstring{0}) & 0x00);
70 } else {
71 return false;
72 }
73 return getid3_lib::BigEndian2Int($EBMLstring);
74 }
BigEndian2Int($byteword, $synchsafe=false, $signed=false)
Definition: getid3.lib.php:234

References getid3_lib\BigEndian2Int().

Referenced by parseEBML(), and readEBMLint().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ EBML2Int() [2/2]

static getid3_matroska::EBML2Int (   $EBMLstring)
staticprivate

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

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

References getid3_lib\BigEndian2Int().

+ Here is the call graph for this function:

◆ EBMLdate2unix()

static getid3_matroska::EBMLdate2unix (   $EBMLdatestamp)
staticprivate

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

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

Referenced by parseEBML().

+ Here is the caller graph for this function:

◆ EBMLidName()

static getid3_matroska::EBMLidName (   $value)
staticprivate

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

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

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.

Referenced by getEBMLelement(), and parseEBML().

+ Here is the caller graph for this function:

◆ EnsureBufferHasEnoughData()

getid3_matroska::EnsureBufferHasEnoughData (   $min_data = 1024)
private

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

1226 {
1227 if (($this->current_offset - $this->EBMLbuffer_offset) >= ($this->EBMLbuffer_length - $min_data)) {
1228 $read_bytes = max($min_data, $this->getid3->fread_buffer_size());
1229
1230 try {
1231 $this->fseek($this->current_offset);
1232 $this->EBMLbuffer_offset = $this->current_offset;
1233 $this->EBMLbuffer = $this->fread($read_bytes);
1234 $this->EBMLbuffer_length = strlen($this->EBMLbuffer);
1235 } catch (getid3_exception $e) {
1236 $this->warning('EBML parser: '.$e->getMessage());
1237 return false;
1238 }
1239
1240 if ($this->EBMLbuffer_length == 0 && $this->feof()) {
1241 return $this->error('EBML parser: ran out of file at offset '.$this->current_offset);
1242 }
1243 }
1244 return true;
1245 }
fseek($bytes, $whence=SEEK_SET)
Definition: getid3.php:1697
fread($bytes)
Definition: getid3.php:1685
error($text)
Definition: getid3.php:1738

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

Referenced by getEBMLelement(), and readEBMLelementData().

+ 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 1336 of file module.audio-video.matroska.php.

1336 {
1337 if (!empty($SimpleTagArray['SimpleTag'])) {
1338 foreach ($SimpleTagArray['SimpleTag'] as $SimpleTagKey => $SimpleTagData) {
1339 if (!empty($SimpleTagData['TagName']) && !empty($SimpleTagData['TagString'])) {
1340 $this->getid3->info['matroska']['comments'][strtolower($SimpleTagData['TagName'])][] = $SimpleTagData['TagString'];
1341 }
1342 if (!empty($SimpleTagData['SimpleTag'])) {
1343 $this->ExtractCommentsSimpleTag($SimpleTagData);
1344 }
1345 }
1346 }
1347
1348 return true;
1349 }

References ExtractCommentsSimpleTag().

Referenced by Analyze(), and ExtractCommentsSimpleTag().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getDefaultStreamInfo()

static getid3_matroska::getDefaultStreamInfo (   $streams)
staticprivate

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

1764 {
1765 foreach (array_reverse($streams) as $stream) {
1766 if ($stream['default']) {
1767 break;
1768 }
1769 }
1770
1771 $unset = array('default', 'name');
1772 foreach ($unset as $u) {
1773 if (isset($stream[$u])) {
1774 unset($stream[$u]);
1775 }
1776 }
1777
1778 $info = $stream;
1779 $info['streams'] = $streams;
1780
1781 return $info;
1782 }

References $info.

Referenced by Analyze().

+ Here is the caller graph for this function:

◆ getEBMLelement()

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

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

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

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

Referenced by HandleEMBLSimpleTag(), and parseEBML().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getid3_matroska()

getid3_matroska::getid3_matroska ( $fd,
$ThisFileInfo 
)

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

20 {
21
22 $ThisFileInfo['fileformat'] = 'matroska';
23
24 fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET);
25
26 //$ThisFileInfo['matroska']['raw']['a'] = $this->EBML2Int(fread($fd, 4));
27
28 $ThisFileInfo['error'][] = 'Mastroka parsing not enabled in this version of getID3()';
29 return false;
30
31 }

References getid3_handler\fseek().

+ Here is the call graph for this function:

◆ HandleEMBLClusterBlock()

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

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

1381 {
1382 // http://www.matroska.org/technical/specs/index.html#block_structure
1383 // http://www.matroska.org/technical/specs/index.html#simpleblock_structure
1384
1385 $block_data = array();
1386 $block_data['tracknumber'] = $this->readEBMLint();
1387 $block_data['timecode'] = getid3_lib::BigEndian2Int($this->readEBMLelementData(2), false, true);
1388 $block_data['flags_raw'] = getid3_lib::BigEndian2Int($this->readEBMLelementData(1));
1389
1390 if ($block_type == EBML_ID_CLUSTERSIMPLEBLOCK) {
1391 $block_data['flags']['keyframe'] = (($block_data['flags_raw'] & 0x80) >> 7);
1392 //$block_data['flags']['reserved1'] = (($block_data['flags_raw'] & 0x70) >> 4);
1393 }
1394 else {
1395 //$block_data['flags']['reserved1'] = (($block_data['flags_raw'] & 0xF0) >> 4);
1396 }
1397 $block_data['flags']['invisible'] = (bool)(($block_data['flags_raw'] & 0x08) >> 3);
1398 $block_data['flags']['lacing'] = (($block_data['flags_raw'] & 0x06) >> 1); // 00=no lacing; 01=Xiph lacing; 11=EBML lacing; 10=fixed-size lacing
1399 if ($block_type == EBML_ID_CLUSTERSIMPLEBLOCK) {
1400 $block_data['flags']['discardable'] = (($block_data['flags_raw'] & 0x01));
1401 }
1402 else {
1403 //$block_data['flags']['reserved2'] = (($block_data['flags_raw'] & 0x01) >> 0);
1404 }
1405 $block_data['flags']['lacing_type'] = self::BlockLacingType($block_data['flags']['lacing']);
1406
1407 // Lace (when lacing bit is set)
1408 if ($block_data['flags']['lacing'] > 0) {
1409 $block_data['lace_frames'] = getid3_lib::BigEndian2Int($this->readEBMLelementData(1)) + 1; // Number of frames in the lace-1 (uint8)
1410 if ($block_data['flags']['lacing'] != 0x02) {
1411 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).
1412 if ($block_data['flags']['lacing'] == 0x03) { // EBML lacing
1413 $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.
1414 }
1415 else { // Xiph lacing
1416 $block_data['lace_frames_size'][$i] = 0;
1417 do {
1419 $block_data['lace_frames_size'][$i] += $size;
1420 }
1421 while ($size == 255);
1422 }
1423 }
1424 if ($block_data['flags']['lacing'] == 0x01) { // calc size of the last frame only for Xiph lacing, till EBML sizes are now anyway determined incorrectly
1425 $block_data['lace_frames_size'][] = $element['end'] - $this->current_offset - array_sum($block_data['lace_frames_size']);
1426 }
1427 }
1428 }
1429
1430 if (!isset($info['matroska']['track_data_offsets'][$block_data['tracknumber']])) {
1431 $info['matroska']['track_data_offsets'][$block_data['tracknumber']]['offset'] = $this->current_offset;
1432 $info['matroska']['track_data_offsets'][$block_data['tracknumber']]['length'] = $element['end'] - $this->current_offset;
1433 //$info['matroska']['track_data_offsets'][$block_data['tracknumber']]['total_length'] = 0;
1434 }
1435 //$info['matroska']['track_data_offsets'][$block_data['tracknumber']]['total_length'] += $info['matroska']['track_data_offsets'][$block_data['tracknumber']]['length'];
1436 //$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);
1437
1438 // set offset manually
1439 $this->current_offset = $element['end'];
1440
1441 return $block_data;
1442 }
$size
Definition: RandomTest.php:79
static BlockLacingType($lacingtype)

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

Referenced by parseEBML().

+ 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 1351 of file module.audio-video.matroska.php.

1351 {
1352 $simpletag_entry = array();
1353
1354 while ($this->getEBMLelement($element, $parent_end, array(EBML_ID_SIMPLETAG))) {
1355 switch ($element['id']) {
1356
1357 case EBML_ID_TAGNAME:
1359 case EBML_ID_TAGSTRING:
1360 case EBML_ID_TAGBINARY:
1361 $simpletag_entry[$element['id_name']] = $element['data'];
1362 break;
1363
1364 case EBML_ID_SIMPLETAG:
1365 $simpletag_entry[$element['id_name']][] = $this->HandleEMBLSimpleTag($element['end']);
1366 break;
1367
1368 case EBML_ID_TAGDEFAULT:
1369 $simpletag_entry[$element['id_name']] = (bool)getid3_lib::BigEndian2Int($element['data']);
1370 break;
1371
1372 default:
1373 $this->unhandledElement('tag.simpletag', __LINE__, $element);
1374 break;
1375 }
1376 }
1377
1378 return $simpletag_entry;
1379 }
getEBMLelement(&$element, $parent_end, $get_data=false)
unhandledElement($type, $line, $element)

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

Referenced by HandleEMBLSimpleTag(), and parseEBML().

+ 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 497 of file module.audio-video.matroska.php.

497 {
498 // http://www.matroska.org/technical/specs/index.html#EBMLBasics
499 $this->current_offset = $info['avdataoffset'];
500
501 while ($this->getEBMLelement($top_element, $info['avdataend'])) {
502 switch ($top_element['id']) {
503
504 case EBML_ID_EBML:
505 $info['matroska']['header']['offset'] = $top_element['offset'];
506 $info['matroska']['header']['length'] = $top_element['length'];
507
508 while ($this->getEBMLelement($element_data, $top_element['end'], true)) {
509 switch ($element_data['id']) {
510
517 $element_data['data'] = getid3_lib::BigEndian2Int($element_data['data']);
518 break;
519
520 case EBML_ID_DOCTYPE:
521 $element_data['data'] = getid3_lib::trimNullByte($element_data['data']);
522 $info['matroska']['doctype'] = $element_data['data'];
523 $info['fileformat'] = $element_data['data'];
524 break;
525
526 default:
527 $this->unhandledElement('header', __LINE__, $element_data);
528 break;
529 }
530
531 unset($element_data['offset'], $element_data['end']);
532 $info['matroska']['header']['elements'][] = $element_data;
533 }
534 break;
535
536 case EBML_ID_SEGMENT:
537 $info['matroska']['segment'][0]['offset'] = $top_element['offset'];
538 $info['matroska']['segment'][0]['length'] = $top_element['length'];
539
540 while ($this->getEBMLelement($element_data, $top_element['end'])) {
541 if ($element_data['id'] != EBML_ID_CLUSTER || !self::$hide_clusters) { // collect clusters only if required
542 $info['matroska']['segments'][] = $element_data;
543 }
544 switch ($element_data['id']) {
545
546 case EBML_ID_SEEKHEAD: // Contains the position of other level 1 elements.
547
548 while ($this->getEBMLelement($seek_entry, $element_data['end'])) {
549 switch ($seek_entry['id']) {
550
551 case EBML_ID_SEEK: // Contains a single seek entry to an EBML element
552 while ($this->getEBMLelement($sub_seek_entry, $seek_entry['end'], true)) {
553
554 switch ($sub_seek_entry['id']) {
555
556 case EBML_ID_SEEKID:
557 $seek_entry['target_id'] = self::EBML2Int($sub_seek_entry['data']);
558 $seek_entry['target_name'] = self::EBMLidName($seek_entry['target_id']);
559 break;
560
562 $seek_entry['target_offset'] = $element_data['offset'] + getid3_lib::BigEndian2Int($sub_seek_entry['data']);
563 break;
564
565 default:
566 $this->unhandledElement('seekhead.seek', __LINE__, $sub_seek_entry); }
567 break;
568 }
569
570 if ($seek_entry['target_id'] != EBML_ID_CLUSTER || !self::$hide_clusters) { // collect clusters only if required
571 $info['matroska']['seek'][] = $seek_entry;
572 }
573 break;
574
575 default:
576 $this->unhandledElement('seekhead', __LINE__, $seek_entry);
577 break;
578 }
579 }
580 break;
581
582 case EBML_ID_TRACKS: // A top-level block of information with many tracks described.
583 $info['matroska']['tracks'] = $element_data;
584
585 while ($this->getEBMLelement($track_entry, $element_data['end'])) {
586 switch ($track_entry['id']) {
587
588 case EBML_ID_TRACKENTRY: //subelements: Describes a track with all elements.
589
590 while ($this->getEBMLelement($subelement, $track_entry['end'], array(EBML_ID_VIDEO, EBML_ID_AUDIO, EBML_ID_CONTENTENCODINGS, EBML_ID_CODECPRIVATE))) {
591 switch ($subelement['id']) {
592
594 case EBML_ID_TRACKUID:
596 case EBML_ID_MINCACHE:
597 case EBML_ID_MAXCACHE:
599 case EBML_ID_DEFAULTDURATION: // nanoseconds per frame
600 $track_entry[$subelement['id_name']] = getid3_lib::BigEndian2Int($subelement['data']);
601 break;
602
604 $track_entry[$subelement['id_name']] = getid3_lib::BigEndian2Float($subelement['data']);
605 break;
606
607 case EBML_ID_CODECID:
608 case EBML_ID_LANGUAGE:
609 case EBML_ID_NAME:
611 $track_entry[$subelement['id_name']] = getid3_lib::trimNullByte($subelement['data']);
612 break;
613
615 $track_entry[$subelement['id_name']] = $this->readEBMLelementData($subelement['length'], true);
616 break;
617
623 $track_entry[$subelement['id_name']] = (bool) getid3_lib::BigEndian2Int($subelement['data']);
624 break;
625
626 case EBML_ID_VIDEO:
627
628 while ($this->getEBMLelement($sub_subelement, $subelement['end'], true)) {
629 switch ($sub_subelement['id']) {
630
643 $track_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']);
644 break;
645
647 $track_entry[$sub_subelement['id_name']] = (bool)getid3_lib::BigEndian2Int($sub_subelement['data']);
648 break;
649
651 $track_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Float($sub_subelement['data']);
652 break;
653
655 $track_entry[$sub_subelement['id_name']] = getid3_lib::trimNullByte($sub_subelement['data']);
656 break;
657
658 default:
659 $this->unhandledElement('track.video', __LINE__, $sub_subelement);
660 break;
661 }
662 }
663 break;
664
665 case EBML_ID_AUDIO:
666
667 while ($this->getEBMLelement($sub_subelement, $subelement['end'], true)) {
668 switch ($sub_subelement['id']) {
669
670 case EBML_ID_CHANNELS:
671 case EBML_ID_BITDEPTH:
672 $track_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']);
673 break;
674
677 $track_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Float($sub_subelement['data']);
678 break;
679
681 $track_entry[$sub_subelement['id_name']] = getid3_lib::trimNullByte($sub_subelement['data']);
682 break;
683
684 default:
685 $this->unhandledElement('track.audio', __LINE__, $sub_subelement);
686 break;
687 }
688 }
689 break;
690
692
693 while ($this->getEBMLelement($sub_subelement, $subelement['end'])) {
694 switch ($sub_subelement['id']) {
695
697
698 while ($this->getEBMLelement($sub_sub_subelement, $sub_subelement['end'], array(EBML_ID_CONTENTCOMPRESSION, EBML_ID_CONTENTENCRYPTION))) {
699 switch ($sub_sub_subelement['id']) {
700
704 $track_entry[$sub_subelement['id_name']][$sub_sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_sub_subelement['data']);
705 break;
706
708
709 while ($this->getEBMLelement($sub_sub_sub_subelement, $sub_sub_subelement['end'], true)) {
710 switch ($sub_sub_sub_subelement['id']) {
711
713 $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']);
714 break;
715
717 $track_entry[$sub_subelement['id_name']][$sub_sub_subelement['id_name']][$sub_sub_sub_subelement['id_name']] = $sub_sub_sub_subelement['data'];
718 break;
719
720 default:
721 $this->unhandledElement('track.contentencodings.contentencoding.contentcompression', __LINE__, $sub_sub_sub_subelement);
722 break;
723 }
724 }
725 break;
726
728
729 while ($this->getEBMLelement($sub_sub_sub_subelement, $sub_sub_subelement['end'], true)) {
730 switch ($sub_sub_sub_subelement['id']) {
731
735 $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']);
736 break;
737
741 $track_entry[$sub_subelement['id_name']][$sub_sub_subelement['id_name']][$sub_sub_sub_subelement['id_name']] = $sub_sub_sub_subelement['data'];
742 break;
743
744 default:
745 $this->unhandledElement('track.contentencodings.contentencoding.contentcompression', __LINE__, $sub_sub_sub_subelement);
746 break;
747 }
748 }
749 break;
750
751 default:
752 $this->unhandledElement('track.contentencodings.contentencoding', __LINE__, $sub_sub_subelement);
753 break;
754 }
755 }
756 break;
757
758 default:
759 $this->unhandledElement('track.contentencodings', __LINE__, $sub_subelement);
760 break;
761 }
762 }
763 break;
764
765 default:
766 $this->unhandledElement('track', __LINE__, $subelement);
767 break;
768 }
769 }
770
771 $info['matroska']['tracks']['tracks'][] = $track_entry;
772 break;
773
774 default:
775 $this->unhandledElement('tracks', __LINE__, $track_entry);
776 break;
777 }
778 }
779 break;
780
781 case EBML_ID_INFO: // Contains miscellaneous general information and statistics on the file.
782 $info_entry = array();
783
784 while ($this->getEBMLelement($subelement, $element_data['end'], true)) {
785 switch ($subelement['id']) {
786
788 $info_entry[$subelement['id_name']] = getid3_lib::BigEndian2Int($subelement['data']);
789 break;
790
791 case EBML_ID_DURATION:
792 $info_entry[$subelement['id_name']] = getid3_lib::BigEndian2Float($subelement['data']);
793 break;
794
795 case EBML_ID_DATEUTC:
796 $info_entry[$subelement['id_name']] = getid3_lib::BigEndian2Int($subelement['data']);
797 $info_entry[$subelement['id_name'].'_unix'] = self::EBMLdate2unix($info_entry[$subelement['id_name']]);
798 break;
799
801 case EBML_ID_PREVUID:
802 case EBML_ID_NEXTUID:
803 $info_entry[$subelement['id_name']] = getid3_lib::trimNullByte($subelement['data']);
804 break;
805
807 $info_entry[$subelement['id_name']][] = getid3_lib::trimNullByte($subelement['data']);
808 break;
809
813 case EBML_ID_TITLE:
816 $info_entry[$subelement['id_name']] = getid3_lib::trimNullByte($subelement['data']);
817 $info['matroska']['comments'][strtolower($subelement['id_name'])][] = $info_entry[$subelement['id_name']];
818 break;
819
821 $chaptertranslate_entry = array();
822
823 while ($this->getEBMLelement($sub_subelement, $subelement['end'], true)) {
824 switch ($sub_subelement['id']) {
825
827 $chaptertranslate_entry[$sub_subelement['id_name']][] = getid3_lib::BigEndian2Int($sub_subelement['data']);
828 break;
829
831 $chaptertranslate_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']);
832 break;
833
835 $chaptertranslate_entry[$sub_subelement['id_name']] = getid3_lib::trimNullByte($sub_subelement['data']);
836 break;
837
838 default:
839 $this->unhandledElement('info.chaptertranslate', __LINE__, $sub_subelement);
840 break;
841 }
842 }
843 $info_entry[$subelement['id_name']] = $chaptertranslate_entry;
844 break;
845
846 default:
847 $this->unhandledElement('info', __LINE__, $subelement);
848 break;
849 }
850 }
851 $info['matroska']['info'][] = $info_entry;
852 break;
853
854 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.
855 if (self::$hide_clusters) { // do not parse cues if hide clusters is "ON" till they point to clusters anyway
856 $this->current_offset = $element_data['end'];
857 break;
858 }
859 $cues_entry = array();
860
861 while ($this->getEBMLelement($subelement, $element_data['end'])) {
862 switch ($subelement['id']) {
863
864 case EBML_ID_CUEPOINT:
865 $cuepoint_entry = array();
866
867 while ($this->getEBMLelement($sub_subelement, $subelement['end'], array(EBML_ID_CUETRACKPOSITIONS))) {
868 switch ($sub_subelement['id']) {
869
871 $cuetrackpositions_entry = array();
872
873 while ($this->getEBMLelement($sub_sub_subelement, $sub_subelement['end'], true)) {
874 switch ($sub_sub_subelement['id']) {
875
876 case EBML_ID_CUETRACK:
880 $cuetrackpositions_entry[$sub_sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_sub_subelement['data']);
881 break;
882
883 default:
884 $this->unhandledElement('cues.cuepoint.cuetrackpositions', __LINE__, $sub_sub_subelement);
885 break;
886 }
887 }
888 $cuepoint_entry[$sub_subelement['id_name']][] = $cuetrackpositions_entry;
889 break;
890
891 case EBML_ID_CUETIME:
892 $cuepoint_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']);
893 break;
894
895 default:
896 $this->unhandledElement('cues.cuepoint', __LINE__, $sub_subelement);
897 break;
898 }
899 }
900 $cues_entry[] = $cuepoint_entry;
901 break;
902
903 default:
904 $this->unhandledElement('cues', __LINE__, $subelement);
905 break;
906 }
907 }
908 $info['matroska']['cues'] = $cues_entry;
909 break;
910
911 case EBML_ID_TAGS: // Element containing elements specific to Tracks/Chapters.
912 $tags_entry = array();
913
914 while ($this->getEBMLelement($subelement, $element_data['end'], false)) {
915 switch ($subelement['id']) {
916
917 case EBML_ID_TAG:
918 $tag_entry = array();
919
920 while ($this->getEBMLelement($sub_subelement, $subelement['end'], false)) {
921 switch ($sub_subelement['id']) {
922
923 case EBML_ID_TARGETS:
924 $targets_entry = array();
925
926 while ($this->getEBMLelement($sub_sub_subelement, $sub_subelement['end'], true)) {
927 switch ($sub_sub_subelement['id']) {
928
930 $targets_entry[$sub_sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_sub_subelement['data']);
931 $targets_entry[strtolower($sub_sub_subelement['id_name']).'_long'] = self::TargetTypeValue($targets_entry[$sub_sub_subelement['id_name']]);
932 break;
933
935 $targets_entry[$sub_sub_subelement['id_name']] = $sub_sub_subelement['data'];
936 break;
937
942 $targets_entry[$sub_sub_subelement['id_name']][] = getid3_lib::BigEndian2Int($sub_sub_subelement['data']);
943 break;
944
945 default:
946 $this->unhandledElement('tags.tag.targets', __LINE__, $sub_sub_subelement);
947 break;
948 }
949 }
950 $tag_entry[$sub_subelement['id_name']] = $targets_entry;
951 break;
952
954 $tag_entry[$sub_subelement['id_name']][] = $this->HandleEMBLSimpleTag($sub_subelement['end']);
955 break;
956
957 default:
958 $this->unhandledElement('tags.tag', __LINE__, $sub_subelement);
959 break;
960 }
961 }
962 $tags_entry[] = $tag_entry;
963 break;
964
965 default:
966 $this->unhandledElement('tags', __LINE__, $subelement);
967 break;
968 }
969 }
970 $info['matroska']['tags'] = $tags_entry;
971 break;
972
973 case EBML_ID_ATTACHMENTS: // Contain attached files.
974
975 while ($this->getEBMLelement($subelement, $element_data['end'])) {
976 switch ($subelement['id']) {
977
979 $attachedfile_entry = array();
980
981 while ($this->getEBMLelement($sub_subelement, $subelement['end'], array(EBML_ID_FILEDATA))) {
982 switch ($sub_subelement['id']) {
983
985 case EBML_ID_FILENAME:
987 $attachedfile_entry[$sub_subelement['id_name']] = $sub_subelement['data'];
988 break;
989
990 case EBML_ID_FILEDATA:
991 $attachedfile_entry['data_offset'] = $this->current_offset;
992 $attachedfile_entry['data_length'] = $sub_subelement['length'];
993
994 $attachedfile_entry[$sub_subelement['id_name']] = $this->saveAttachment(
995 $attachedfile_entry['FileName'],
996 $attachedfile_entry['data_offset'],
997 $attachedfile_entry['data_length']);
998
999 $this->current_offset = $sub_subelement['end'];
1000 break;
1001
1002 case EBML_ID_FILEUID:
1003 $attachedfile_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']);
1004 break;
1005
1006 default:
1007 $this->unhandledElement('attachments.attachedfile', __LINE__, $sub_subelement);
1008 break;
1009 }
1010 }
1011 $info['matroska']['attachments'][] = $attachedfile_entry;
1012 break;
1013
1014 default:
1015 $this->unhandledElement('attachments', __LINE__, $subelement);
1016 break;
1017 }
1018 }
1019 break;
1020
1021 case EBML_ID_CHAPTERS:
1022
1023 while ($this->getEBMLelement($subelement, $element_data['end'])) {
1024 switch ($subelement['id']) {
1025
1027 $editionentry_entry = array();
1028
1029 while ($this->getEBMLelement($sub_subelement, $subelement['end'], array(EBML_ID_CHAPTERATOM))) {
1030 switch ($sub_subelement['id']) {
1031
1032 case EBML_ID_EDITIONUID:
1033 $editionentry_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']);
1034 break;
1035
1039 $editionentry_entry[$sub_subelement['id_name']] = (bool)getid3_lib::BigEndian2Int($sub_subelement['data']);
1040 break;
1041
1043 $chapteratom_entry = array();
1044
1045 while ($this->getEBMLelement($sub_sub_subelement, $sub_subelement['end'], array(EBML_ID_CHAPTERTRACK, EBML_ID_CHAPTERDISPLAY))) {
1046 switch ($sub_sub_subelement['id']) {
1047
1050 $chapteratom_entry[$sub_sub_subelement['id_name']] = $sub_sub_subelement['data'];
1051 break;
1052
1055 $chapteratom_entry[$sub_sub_subelement['id_name']] = (bool)getid3_lib::BigEndian2Int($sub_sub_subelement['data']);
1056 break;
1057
1058 case EBML_ID_CHAPTERUID:
1061 $chapteratom_entry[$sub_sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_sub_subelement['data']);
1062 break;
1063
1065 $chaptertrack_entry = array();
1066
1067 while ($this->getEBMLelement($sub_sub_sub_subelement, $sub_sub_subelement['end'], true)) {
1068 switch ($sub_sub_sub_subelement['id']) {
1069
1071 $chaptertrack_entry[$sub_sub_sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_sub_sub_subelement['data']);
1072 break;
1073
1074 default:
1075 $this->unhandledElement('chapters.editionentry.chapteratom.chaptertrack', __LINE__, $sub_sub_sub_subelement);
1076 break;
1077 }
1078 }
1079 $chapteratom_entry[$sub_sub_subelement['id_name']][] = $chaptertrack_entry;
1080 break;
1081
1083 $chapterdisplay_entry = array();
1084
1085 while ($this->getEBMLelement($sub_sub_sub_subelement, $sub_sub_subelement['end'], true)) {
1086 switch ($sub_sub_sub_subelement['id']) {
1087
1088 case EBML_ID_CHAPSTRING:
1091 $chapterdisplay_entry[$sub_sub_sub_subelement['id_name']] = $sub_sub_sub_subelement['data'];
1092 break;
1093
1094 default:
1095 $this->unhandledElement('chapters.editionentry.chapteratom.chapterdisplay', __LINE__, $sub_sub_sub_subelement);
1096 break;
1097 }
1098 }
1099 $chapteratom_entry[$sub_sub_subelement['id_name']][] = $chapterdisplay_entry;
1100 break;
1101
1102 default:
1103 $this->unhandledElement('chapters.editionentry.chapteratom', __LINE__, $sub_sub_subelement);
1104 break;
1105 }
1106 }
1107 $editionentry_entry[$sub_subelement['id_name']][] = $chapteratom_entry;
1108 break;
1109
1110 default:
1111 $this->unhandledElement('chapters.editionentry', __LINE__, $sub_subelement);
1112 break;
1113 }
1114 }
1115 $info['matroska']['chapters'][] = $editionentry_entry;
1116 break;
1117
1118 default:
1119 $this->unhandledElement('chapters', __LINE__, $subelement);
1120 break;
1121 }
1122 }
1123 break;
1124
1125 case EBML_ID_CLUSTER: // The lower level element containing the (monolithic) Block structure.
1126 $cluster_entry = array();
1127
1128 while ($this->getEBMLelement($subelement, $element_data['end'], array(EBML_ID_CLUSTERSILENTTRACKS, EBML_ID_CLUSTERBLOCKGROUP, EBML_ID_CLUSTERSIMPLEBLOCK))) {
1129 switch ($subelement['id']) {
1130
1134 $cluster_entry[$subelement['id_name']] = getid3_lib::BigEndian2Int($subelement['data']);
1135 break;
1136
1138 $cluster_silent_tracks = array();
1139
1140 while ($this->getEBMLelement($sub_subelement, $subelement['end'], true)) {
1141 switch ($sub_subelement['id']) {
1142
1144 $cluster_silent_tracks[] = getid3_lib::BigEndian2Int($sub_subelement['data']);
1145 break;
1146
1147 default:
1148 $this->unhandledElement('cluster.silenttracks', __LINE__, $sub_subelement);
1149 break;
1150 }
1151 }
1152 $cluster_entry[$subelement['id_name']][] = $cluster_silent_tracks;
1153 break;
1154
1156 $cluster_block_group = array('offset' => $this->current_offset);
1157
1158 while ($this->getEBMLelement($sub_subelement, $subelement['end'], array(EBML_ID_CLUSTERBLOCK))) {
1159 switch ($sub_subelement['id']) {
1160
1162 $cluster_block_group[$sub_subelement['id_name']] = $this->HandleEMBLClusterBlock($sub_subelement, EBML_ID_CLUSTERBLOCK, $info);
1163 break;
1164
1165 case EBML_ID_CLUSTERREFERENCEPRIORITY: // unsigned-int
1166 case EBML_ID_CLUSTERBLOCKDURATION: // unsigned-int
1167 $cluster_block_group[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']);
1168 break;
1169
1170 case EBML_ID_CLUSTERREFERENCEBLOCK: // signed-int
1171 $cluster_block_group[$sub_subelement['id_name']][] = getid3_lib::BigEndian2Int($sub_subelement['data'], false, true);
1172 break;
1173
1175 $cluster_block_group[$sub_subelement['id_name']] = getid3_lib::trimNullByte($sub_subelement['data']);
1176 break;
1177
1178 default:
1179 $this->unhandledElement('clusters.blockgroup', __LINE__, $sub_subelement);
1180 break;
1181 }
1182 }
1183 $cluster_entry[$subelement['id_name']][] = $cluster_block_group;
1184 break;
1185
1187 $cluster_entry[$subelement['id_name']][] = $this->HandleEMBLClusterBlock($subelement, EBML_ID_CLUSTERSIMPLEBLOCK, $info);
1188 break;
1189
1190 default:
1191 $this->unhandledElement('cluster', __LINE__, $subelement);
1192 break;
1193 }
1194 $this->current_offset = $subelement['end'];
1195 }
1196 if (!self::$hide_clusters) {
1197 $info['matroska']['cluster'][] = $cluster_entry;
1198 }
1199
1200 // check to see if all the data we need exists already, if so, break out of the loop
1201 if (!self::$parse_whole_file) {
1202 if (isset($info['matroska']['info']) && is_array($info['matroska']['info'])) {
1203 if (isset($info['matroska']['tracks']['tracks']) && is_array($info['matroska']['tracks']['tracks'])) {
1204 if (count($info['matroska']['track_data_offsets']) == count($info['matroska']['tracks']['tracks'])) {
1205 return;
1206 }
1207 }
1208 }
1209 }
1210 break;
1211
1212 default:
1213 $this->unhandledElement('segment', __LINE__, $element_data);
1214 break;
1215 }
1216 }
1217 break;
1218
1219 default:
1220 $this->unhandledElement('root', __LINE__, $top_element);
1221 break;
1222 }
1223 }
1224 }
saveAttachment($name, $offset, $length, $image_mime=null)
Definition: getid3.php:1752
BigEndian2Float($byteword)
Definition: getid3.lib.php:159
static trimNullByte($string)
static TargetTypeValue($target_type)
static EBMLdate2unix($EBMLdatestamp)
HandleEMBLClusterBlock($element, $block_type, &$info)

References $current_offset, $info, getid3_lib\BigEndian2Float(), getid3_lib\BigEndian2Int(), EBML2Int(), 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, EBMLdate2unix(), EBMLidName(), getEBMLelement(), HandleEMBLClusterBlock(), HandleEMBLSimpleTag(), readEBMLelementData(), getid3_handler\saveAttachment(), TargetTypeValue(), getid3_lib\trimNullByte(), and unhandledElement().

Referenced by Analyze().

+ 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 1279 of file module.audio-video.matroska.php.

1279 {
1280 if ($check_buffer && !$this->EnsureBufferHasEnoughData($length)) {
1281 return false;
1282 }
1283 $data = substr($this->EBMLbuffer, $this->current_offset - $this->EBMLbuffer_offset, $length);
1284 $this->current_offset += $length;
1285 return $data;
1286 }
$data

References $data, and EnsureBufferHasEnoughData().

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

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ readEBMLint()

getid3_matroska::readEBMLint ( )
private

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

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

References $EBMLbuffer_offset, and EBML2Int().

Referenced by getEBMLelement(), and HandleEMBLClusterBlock().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ TargetTypeValue()

static getid3_matroska::TargetTypeValue (   $target_type)
static

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

1492 {
1493 // http://www.matroska.org/technical/specs/tagging/index.html
1494 static $TargetTypeValue = array();
1495 if (empty($TargetTypeValue)) {
1496 $TargetTypeValue[10] = 'A: ~ V:shot'; // the lowest hierarchy found in music or movies
1497 $TargetTypeValue[20] = 'A:subtrack/part/movement ~ V:scene'; // corresponds to parts of a track for audio (like a movement)
1498 $TargetTypeValue[30] = 'A:track/song ~ V:chapter'; // the common parts of an album or a movie
1499 $TargetTypeValue[40] = 'A:part/session ~ V:part/session'; // when an album or episode has different logical parts
1500 $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)
1501 $TargetTypeValue[60] = 'A:edition/issue/volume/opus ~ V:season/sequel/volume'; // a list of lower levels grouped together
1502 $TargetTypeValue[70] = 'A:collection ~ V:collection'; // the high hierarchy consisting of many different lower items
1503 }
1504 return (isset($TargetTypeValue[$target_type]) ? $TargetTypeValue[$target_type] : $target_type);
1505 }
$target_type
Definition: goto.php:87

References $target_type.

Referenced by parseEBML().

+ Here is the caller graph for this function:

◆ unhandledElement()

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

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

1324 {
1325 // warn only about unknown and missed elements, not about unuseful
1326 if (!in_array($element['id'], $this->unuseful_elements)) {
1327 $this->warning('Unhandled '.$type.' element ['.basename(__FILE__).':'.$line.'] ('.$element['id'].'::'.$element['id_name'].' ['.$element['length'].' bytes]) at '.$element['offset']);
1328 }
1329
1330 // increase offset for unparsed elements
1331 if (!isset($element['data'])) {
1332 $this->current_offset = $element['end'];
1333 }
1334 }

References getid3_handler\warning().

Referenced by HandleEMBLSimpleTag(), and parseEBML().

+ 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 files: