Parsed: 112284

  private function HandleEMBLClusterBlock($element, $block_type, &$info) {
    // http://www.matroska.org/technical/specs/index.html#block_structure
    // http://www.matroska.org/technical/specs/index.html#simpleblock_structure

    $block_data = array();
    $block_data['tracknumber'] = $this->getid3_matroska::readEBMLint();
    $block_data['timecode']    = getid3_lib::BigEndian2Int($this->getid3_matroska::readEBMLelementData(2), false, true);
    $block_data['flags_raw']   = getid3_lib::BigEndian2Int($this->getid3_matroska::readEBMLelementData(1));

    if ($block_type == EBML_ID_CLUSTERSIMPLEBLOCK) {
      $block_data['flags']['keyframe']  = (($block_data['flags_raw'] & 0x80) >> 7);
      //$block_data['flags']['reserved1'] = (($block_data['flags_raw'] & 0x70) >> 4);
    }
    else {
      //$block_data['flags']['reserved1'] = (($block_data['flags_raw'] & 0xF0) >> 4);
    }
    $block_data['flags']['invisible'] = (bool)(($block_data['flags_raw'] & 0x08) >> 3);
    $block_data['flags']['lacing']    =       (($block_data['flags_raw'] & 0x06) >> 1);  // 00=no lacing; 01=Xiph lacing; 11=EBML lacing; 10=fixed-size lacing
    if ($block_type == EBML_ID_CLUSTERSIMPLEBLOCK) {
      $block_data['flags']['discardable'] = (($block_data['flags_raw'] & 0x01));
    }
    else {
      //$block_data['flags']['reserved2'] = (($block_data['flags_raw'] & 0x01) >> 0);
    }
    $block_data['flags']['lacing_type'] = self::BlockLacingType($block_data['flags']['lacing']);

    // Lace (when lacing bit is set)
    if ($block_data['flags']['lacing'] > 0) {
      $block_data['lace_frames'] = getid3_lib::BigEndian2Int($this->getid3_matroska::readEBMLelementData(1)) + 1; // Number of frames in the lace-1 (uint8)
      if ($block_data['flags']['lacing'] != 0x02) {
        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).
          if ($block_data['flags']['lacing'] == 0x03) { // EBML lacing
            $block_data['lace_frames_size'][$i] = $this->getid3_matroska::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.
          }
          else { // Xiph lacing
            $block_data['lace_frames_size'][$i] = 0;
            do {
              $size = getid3_lib::BigEndian2Int($this->getid3_matroska::readEBMLelementData(1));
              $block_data['lace_frames_size'][$i] += $size;
            }
            while ($size == 255);
          }
        }
        if ($block_data['flags']['lacing'] == 0x01) { // calc size of the last frame only for Xiph lacing, till EBML sizes are now anyway determined incorrectly
          $block_data['lace_frames_size'][] = $element['end'] - $this->current_offset - array_sum($block_data['lace_frames_size']);
        }
      }
    }

    if (!isset($info['matroska']['track_data_offsets'][$block_data['tracknumber']])) {
      $info['matroska']['track_data_offsets'][$block_data['tracknumber']]['offset'] = $this->current_offset;
      $info['matroska']['track_data_offsets'][$block_data['tracknumber']]['length'] = $element['end'] - $this->current_offset;
      //$info['matroska']['track_data_offsets'][$block_data['tracknumber']]['total_length'] = 0;
    }
    //$info['matroska']['track_data_offsets'][$block_data['tracknumber']]['total_length'] += $info['matroska']['track_data_offsets'][$block_data['tracknumber']]['length'];
    //$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);

    // set offset manually
    $this->current_offset = $element['end'];

    return $block_data;
  }