Example #1
0
bool
kax_file_c::is_level1_element_id(vint_c id) const {
  const EbmlSemanticContext &context = EBML_CLASS_CONTEXT(KaxSegment);
  for (size_t segment_idx = 0; EBML_CTX_SIZE(context) > segment_idx; ++segment_idx)
    if (EBML_ID_VALUE(EBML_CTX_IDX_ID(context,segment_idx)) == id.m_value)
      return true;

  return false;
}
Example #2
0
bool
kax_file_c::is_level1_element_id(vint_c id) const {
  auto &context = EBML_CLASS_CONTEXT(KaxSegment);
  for (int segment_idx = 0, end = EBML_CTX_SIZE(context); end > segment_idx; ++segment_idx)
    if (EBML_ID_VALUE(EBML_CTX_IDX_ID(context,segment_idx)) == id.m_value)
      return true;

  return false;
}
Example #3
0
KaxCluster *
kax_file_c::read_next_cluster() {
  return static_cast<KaxCluster *>(read_next_level1_element(EBML_ID_VALUE(EBML_ID(KaxCluster))));
}
Example #4
0
EbmlElement *
kax_file_c::resync_to_level1_element_internal(uint32_t wanted_id) {
  if (m_segment_end && (m_in->getFilePointer() >= m_segment_end))
    return nullptr;

  m_resynced         = true;
  m_resync_start_pos = m_in->getFilePointer();

  uint32_t actual_id = m_in->read_uint32_be();
  int64_t start_time = mtx::sys::get_current_time_millis();
  bool is_cluster_id = !wanted_id || (EBML_ID_VALUE(EBML_ID(KaxCluster)) == wanted_id); // 0 means: any level 1 element will do

  mxinfo(boost::format(Y("%1%: Error in the Matroska file structure at position %2%. Resyncing to the next level 1 element.\n"))
         % m_in->get_file_name() % m_resync_start_pos);

  if (is_cluster_id && (-1 != m_last_timecode)) {
    mxinfo(boost::format(Y("The last timecode processed before the error was encountered was %1%.\n")) % format_timecode(m_last_timecode));
    m_last_timecode = -1;
  }

  if (m_debug_resync)
    mxinfo(boost::format("kax_file::resync_to_level1_element(): starting at %1% potential ID %|2$08x|\n") % m_resync_start_pos % actual_id);

  while (m_in->getFilePointer() < m_file_size) {
    int64_t now = mtx::sys::get_current_time_millis();
    if ((now - start_time) >= 10000) {
      mxinfo(boost::format("Still resyncing at position %1%.\n") % m_in->getFilePointer());
      start_time = now;
    }

    actual_id = (actual_id << 8) | m_in->read_uint8();

    if (   ((0 != wanted_id) && (wanted_id != actual_id))
        || ((0 == wanted_id) && !is_level1_element_id(vint_c(actual_id, 4))))
      continue;

    uint64_t current_start_pos = m_in->getFilePointer() - 4;
    uint64_t element_pos       = current_start_pos;
    unsigned int num_headers   = 1;
    bool valid_unknown_size    = false;

    if (m_debug_resync)
      mxinfo(boost::format("kax_file::resync_to_level1_element(): byte-for-byte search, found level 1 ID %|2$x| at %1%\n") % current_start_pos % actual_id);

    try {
      unsigned int idx;
      for (idx = 0; 3 > idx; ++idx) {
        vint_c length = vint_c::read(m_in);

        if (m_debug_resync)
          mxinfo(boost::format("kax_file::resync_to_level1_element():   read ebml length %1%/%2% valid? %3% unknown? %4%\n")
                 % length.m_value % length.m_coded_size % length.is_valid() % length.is_unknown());

        if (length.is_unknown()) {
          valid_unknown_size = true;
          break;
        }

        if (   !length.is_valid()
            || ((element_pos + length.m_value + length.m_coded_size + 2 * 4) >= m_file_size)
            || !m_in->setFilePointer2(element_pos + 4 + length.m_value + length.m_coded_size, seek_beginning))
          break;

        element_pos      = m_in->getFilePointer();
        uint32_t next_id = m_in->read_uint32_be();

        if (m_debug_resync)
          mxinfo(boost::format("kax_file::resync_to_level1_element():   next ID is %|1$x| at %2%\n") % next_id % element_pos);

        if (   ((0 != wanted_id) && (wanted_id != next_id))
            || ((0 == wanted_id) && !is_level1_element_id(vint_c(next_id, 4))))
          break;

        ++num_headers;
      }
    } catch (...) {
    }

    if ((4 == num_headers) || valid_unknown_size) {
      mxinfo(boost::format(Y("Resyncing successful at position %1%.\n")) % current_start_pos);
      m_in->setFilePointer(current_start_pos, seek_beginning);
      return read_next_level1_element(wanted_id, is_cluster_id);
    }

    m_in->setFilePointer(current_start_pos + 4, seek_beginning);
  }

  mxinfo(Y("Resync failed: no valid Matroska level 1 element found.\n"));

  return nullptr;
}
Example #5
0
bool
kax_file_c::is_global_element_id(vint_c id) const {
  return (EBML_ID_VALUE(EBML_ID(EbmlVoid))  == id.m_value)
    ||   (EBML_ID_VALUE(EBML_ID(EbmlCrc32)) == id.m_value);
}