예제 #1
0
static std::string
parse_args(std::vector<std::string> &args) {
  std::string file_name;

  for (auto & arg: args) {
    if ((arg == "-h") || (arg == "--help"))
      show_help();

    else if ((arg == "-V") || (arg == "--version"))
      show_version();

    else if ((arg == "-c") || (arg == "--checksum"))
      g_opt_checksum = true;

    else if ((arg == "-f") || (arg == "--frame-headers"))
      g_opt_frame_headers = true;

    else if (!file_name.empty())
      mxerror(Y("More than one input file given\n"));

    else
      file_name = arg;
  }

  if (file_name.empty())
    mxerror(Y("No file name given\n"));

  return file_name;
}
예제 #2
0
void
xtr_avc_c::create_file(xtr_base_c *master,
                       KaxTrackEntry &track) {
  xtr_base_c::create_file(master, track);

  KaxCodecPrivate *priv = FindChild<KaxCodecPrivate>(&track);
  if (!priv)
    mxerror(boost::format(Y("Track %1% with the CodecID '%2%' is missing the \"codec private\" element and cannot be extracted.\n")) % m_tid % m_codec_id);

  memory_cptr mpriv = decode_codec_private(priv);

  if (mpriv->get_size() < 6)
    mxerror(boost::format(Y("Track %1% CodecPrivate is too small.\n")) % m_tid);

  binary *buf     = mpriv->get_buffer();
  m_nal_size_size = 1 + (buf[4] & 3);

  size_t pos          = 6;
  unsigned int numsps = buf[5] & 0x1f;
  size_t i;
  for (i = 0; (i < numsps) && (mpriv->get_size() > pos); ++i)
    if (!write_nal(buf, pos, mpriv->get_size(), 2))
      break;

  if (mpriv->get_size() <= pos)
    return;

  unsigned int numpps = buf[pos++];

  for (i = 0; (i < numpps) && (mpriv->get_size() > pos); ++i)
    write_nal(buf, pos, mpriv->get_size(), 2);
}
static file_type_e
detect_text_file_formats(filelist_t const &file) {
  auto text_io = mm_text_io_cptr{};
  try {
    text_io        = std::make_shared<mm_text_io_c>(new mm_file_io_c(file.name));
    auto text_size = text_io->get_size();

    if (webvtt_reader_c::probe_file(text_io.get(), text_size))
      return FILE_TYPE_WEBVTT;
    else if (srt_reader_c::probe_file(text_io.get(), text_size))
      return FILE_TYPE_SRT;
    else if (ssa_reader_c::probe_file(text_io.get(), text_size))
      return FILE_TYPE_SSA;
    else if (vobsub_reader_c::probe_file(text_io.get(), text_size))
      return FILE_TYPE_VOBSUB;
    else if (usf_reader_c::probe_file(text_io.get(), text_size))
      return FILE_TYPE_USF;

    // Unsupported text subtitle formats
    else if (microdvd_reader_c::probe_file(text_io.get(), text_size))
      return FILE_TYPE_MICRODVD;

  } catch (mtx::mm_io::exception &ex) {
    mxerror(boost::format(Y("The file '%1%' could not be opened for reading: %2%.\n")) % file.name % ex);

  } catch (...) {
    mxerror(boost::format(Y("The source file '%1%' could not be opened successfully, or retrieving its size by seeking to the end did not work.\n")) % file.name);
  }

  return FILE_TYPE_IS_UNKNOWN;
}
예제 #4
0
kax_chapters_cptr
ebml_chapters_converter_c::parse_file(std::string const &file_name,
                                      bool throw_on_error) {
  auto parse = [&]() -> std::shared_ptr<KaxChapters> {
    auto master = ebml_chapters_converter_c{}.to_ebml(file_name, "Chapters");
    sort_ebml_master(master.get());
    fix_mandatory_chapter_elements(static_cast<KaxChapters *>(master.get()));
    return std::dynamic_pointer_cast<KaxChapters>(master);
  };

  if (!throw_on_error)
    return parse();

  try {
    return parse();

  } catch (mtx::mm_io::exception &ex) {
    mxerror(boost::format(Y("The XML chapter file '%1%' could not be read.\n")) % file_name);

  } catch (mtx::xml::xml_parser_x &ex) {
    mxerror(boost::format(Y("The XML chapter file '%1%' contains an error at position %3%: %2%\n")) % file_name % ex.result().description() % ex.result().offset);

  } catch (mtx::xml::exception &ex) {
    mxerror(boost::format(Y("The XML chapter file '%1%' contains an error: %2%\n")) % file_name % ex.what());
  }

  return kax_chapters_cptr{};
}
예제 #5
0
void
flac_reader_c::read_headers() {
  if (g_identifying)
    return;

  show_demuxer_info();

  if (!parse_file())
    throw mtx::input::header_parsing_x();

  try {
    uint32_t block_size = 0;

    for (current_block = blocks.begin(); (current_block != blocks.end()) && (FLAC_BLOCK_TYPE_HEADERS == current_block->type); current_block++)
      block_size += current_block->len;

    m_header = memory_c::alloc(block_size);

    block_size         = 0;
    for (current_block = blocks.begin(); (current_block != blocks.end()) && (FLAC_BLOCK_TYPE_HEADERS == current_block->type); current_block++) {
      m_in->setFilePointer(current_block->filepos);
      if (m_in->read(m_header->get_buffer() + block_size, current_block->len) != current_block->len)
        mxerror(Y("flac_reader: Could not read a header packet.\n"));
      block_size += current_block->len;
    }

  } catch (mtx::exception &) {
    mxerror(Y("flac_reader: could not initialize the FLAC packetizer.\n"));
  }
}
예제 #6
0
void
xtr_wavpack4_c::create_file(xtr_base_c *master,
                            KaxTrackEntry &track) {
  memory_cptr mpriv;

  init_content_decoder(track);

  KaxCodecPrivate *priv = FindChild<KaxCodecPrivate>(&track);
  if (priv)
    mpriv = decode_codec_private(priv);

  if (!priv || (2 > mpriv->get_size()))
    mxerror(boost::format(Y("Track %1% with the CodecID '%2%' is missing the \"codec private\" element and cannot be extracted.\n")) % m_tid % m_codec_id);
  memcpy(m_version, mpriv->get_buffer(), 2);

  xtr_base_c::create_file(master, track);

  m_channels = kt_get_a_channels(track);

  if ((0 != kt_get_max_blockadd_id(track)) && (0 != m_extract_blockadd_level)) {
    std::string corr_name = m_file_name;
    size_t pos            = corr_name.rfind('.');

    if ((std::string::npos != pos) && (0 != pos))
      corr_name.erase(pos + 1);
    corr_name += "wvc";

    try {
      m_corr_out = mm_write_buffer_io_c::open(corr_name, 5 * 1024 * 1024);
    } catch (mtx::mm_io::exception &ex) {
      mxerror(boost::format(Y("The file '%1%' could not be opened for writing: %2%.\n")) % corr_name % ex);
    }
  }
}
예제 #7
0
void
timecode_factory_v2_c::parse(mm_io_c &in) {
  std::string line;
  std::map<int64_t, int64_t> dur_map;

  int64_t dur_sum          = 0;
  int line_no              = 0;
  double previous_timecode = 0;

  while (in.getline2(line)) {
    line_no++;
    strip(line);
    if ((line.length() == 0) || (line[0] == '#'))
      continue;

    double timecode;
    if (!parse_double(line.c_str(), timecode))
      mxerror(boost::format(Y("The line %1% of the timecode file '%2%' does not contain a valid floating point number.\n")) % line_no % m_file_name);

    if ((2 == m_version) && (timecode < previous_timecode))
      mxerror(boost::format(Y("The timecode v2 file '%1%' contains timecodes that are not ordered. "
                              "Due to a bug in mkvmerge versions up to and including v1.5.0 this was necessary "
                              "if the track to which the timecode file was applied contained B frames. "
                              "Starting with v1.5.1 mkvmerge now handles this correctly, and the timecodes in the timecode file must be ordered normally. "
                              "For example, the frame sequence 'IPBBP...' at 25 FPS requires a timecode file with "
                              "the first timecodes being '0', '40', '80', '120' etc and not '0', '120', '40', '80' etc.\n\n"
                              "If you really have to specify non-sorted timecodes then use the timecode format v4. "
                              "It is identical to format v2 but allows non-sorted timecodes.\n"))
              % in.get_file_name());

    previous_timecode = timecode;
    m_timecodes.push_back((int64_t)(timecode * 1000000));
    if (m_timecodes.size() > 1) {
      int64_t duration = m_timecodes[m_timecodes.size() - 1] - m_timecodes[m_timecodes.size() - 2];
      if (dur_map.find(duration) == dur_map.end())
        dur_map[duration] = 1;
      else
        dur_map[duration] = dur_map[duration] + 1;
      dur_sum += duration;
      m_durations.push_back(duration);
    }
  }

  if (m_timecodes.empty())
    mxerror(boost::format(Y("The timecode file '%1%' does not contain any valid entry.\n")) % m_file_name);

  dur_sum = -1;
  std::pair<int64_t, int64_t> entry;
  for (auto entry : dur_map) {
    if ((0 > dur_sum) || (dur_map[dur_sum] < entry.second))
      dur_sum = entry.first;
    mxverb(4, boost::format("ext_m_timecodes v2 dur_map %1% = %2%\n") % entry.first % entry.second);
  }
  mxverb(4, boost::format("ext_m_timecodes v2 max is %1% = %2%\n") % dur_sum % dur_map[dur_sum]);

  if (0 < dur_sum)
    m_default_fps = (double)1000000000.0 / dur_sum;

  m_durations.push_back(dur_sum);
}
예제 #8
0
void
xtr_hevc_c::create_file(xtr_base_c *master,
                        KaxTrackEntry &track) {
  xtr_base_c::create_file(master, track);

  auto priv = FindChild<KaxCodecPrivate>(&track);
  if (!priv)
    mxerror(boost::format(Y("Track %1% with the CodecID '%2%' is missing the \"codec private\" element and cannot be extracted.\n")) % m_tid % m_codec_id);

  auto mpriv = decode_codec_private(priv);
  if (mpriv->get_size() < 23)
    mxerror(boost::format(Y("Track %1% CodecPrivate is too small.\n")) % m_tid);

  auto buf        = mpriv->get_buffer();
  m_nal_size_size = 1 + (buf[21] & 3);

  // Parameter sets in this order: vps, sps, pps, sei
  auto num_parameter_sets = static_cast<unsigned int>(buf[22]);
  auto pos                = static_cast<size_t>(23);

  while (num_parameter_sets && (mpriv->get_size() > (pos + 3))) {
    auto nal_unit_count  = get_uint16_be(&buf[pos + 1]);
    pos                 += 3;

    while (nal_unit_count && (mpriv->get_size() > pos)) {
      if (!write_nal(buf, pos, mpriv->get_size(), 2))
        return;

      --nal_unit_count;
      --num_parameter_sets;
    }
  }
}
예제 #9
0
static void
display_update_element_result(const EbmlCallbacks &callbacks,
                              kax_analyzer_c::update_element_result_e result) {
  mxinfo(boost::format(Y("Updating the '%1%' element failed. Reason:\n")) % callbacks.DebugName);

  switch (result) {
    case kax_analyzer_c::uer_error_segment_size_for_element:
      mxerror(Y("The element was written at the end of the file, but the segment size could not be updated. Therefore the element will not be visible. "
                "The process will be aborted. The file has been changed!"));
      break;

    case kax_analyzer_c::uer_error_segment_size_for_meta_seek:
      mxerror(Y("The meta seek element was written at the end of the file, but the segment size could not be updated. Therefore the element will not be visible. "
                "The process will be aborted. The file has been changed!"));
      break;

    case kax_analyzer_c::uer_error_meta_seek:
      mxerror(Y("The Matroska file was modified, but the meta seek entry could not be updated. This means that players might have a hard time finding this element. "
                "Please use your favorite player to check this file.\n"));
      break;

    default:
      mxerror(Y("An unknown error occured. The file has been modified."));
  }
}
예제 #10
0
void
extract_cli_parser_c::assert_mode(options_c::extraction_mode_e mode) {
  if      ((options_c::em_tracks   == mode) && (m_options.m_extraction_mode != mode))
    mxerror(boost::format(Y("'%1%' is only allowed when extracting tracks.\n"))   % m_current_arg);

  else if ((options_c::em_chapters == mode) && (m_options.m_extraction_mode != mode))
    mxerror(boost::format(Y("'%1%' is only allowed when extracting chapters.\n")) % m_current_arg);
}
예제 #11
0
void
xtr_tta_c::finish_file() {
  m_out.reset();

  mm_io_cptr in;
  try {
    in = mm_file_io_c::open(m_temp_file_name);
  } catch (mtx::mm_io::exception &ex) {
    mxerror(boost::format(Y("The temporary file '%1%' could not be opened for reading: %2%.\n")) % m_temp_file_name % ex);
  }

  try {
    m_out = mm_write_buffer_io_c::open(m_file_name, 5 * 1024 * 1024);
  } catch (mtx::mm_io::exception &ex) {
    mxerror(boost::format(Y("The file '%1%' could not be opened for writing: %2%.\n")) % m_file_name % ex);
  }

  tta_file_header_t tta_header;
  memcpy(tta_header.signature, "TTA1", 4);
  if (3 != m_bps)
    put_uint16_le(&tta_header.audio_format, 1);
  else
    put_uint16_le(&tta_header.audio_format, 3);
  put_uint16_le(&tta_header.channels, m_channels);
  put_uint16_le(&tta_header.bits_per_sample, m_bps);
  put_uint32_le(&tta_header.sample_rate, m_sfreq);

  if (0 >= m_previous_duration)
    m_previous_duration = (int64_t)(TTA_FRAME_TIME * m_sfreq) * 1000000000ll;
  put_uint32_le(&tta_header.data_length, (uint32_t)(m_sfreq * (TTA_FRAME_TIME * (m_frame_sizes.size() - 1) + (double)m_previous_duration / 1000000000.0l)));
  put_uint32_le(&tta_header.crc, 0xffffffff ^ mtx::checksum::calculate_as_uint(mtx::checksum::algorithm_e::crc32_ieee_le, &tta_header, sizeof(tta_file_header_t) - 4, 0xffffffff));

  m_out->write(&tta_header, sizeof(tta_file_header_t));

  unsigned char *buffer = (unsigned char *)safemalloc(m_frame_sizes.size() * 4);
  size_t k;
  for (k = 0; m_frame_sizes.size() > k; ++k)
    put_uint32_le(buffer + 4 * k, m_frame_sizes[k]);

  m_out->write(buffer, m_frame_sizes.size() * 4);

  m_out->write_uint32_le(0xffffffff ^ mtx::checksum::calculate_as_uint(mtx::checksum::algorithm_e::crc32_ieee_le, buffer, m_frame_sizes.size() * 4, 0xffffffff));

  safefree(buffer);

  mxinfo(boost::format(Y("\nThe temporary TTA file for track ID %1% is being copied into the final TTA file. This may take some time.\n")) % m_tid);

  buffer = (unsigned char *)safemalloc(128000);
  int nread;
  do {
    nread = in->read(buffer, 128000);
    m_out->write(buffer, nread);
  } while (nread == 128000);

  m_out.reset();
  unlink(m_temp_file_name.c_str());
}
예제 #12
0
void
options_c::validate() {
  if (m_file_name.empty())
    mxerror(Y("No file name given.\n"));

  if (!has_changes())
    mxerror(Y("Nothing to do.\n"));

  for (auto &target : m_targets)
    target->validate();
}
예제 #13
0
static void
run(options_cptr &options) {
  console_kax_analyzer_cptr analyzer;

  try {
    if (!kax_analyzer_c::probe(options->m_file_name))
      mxerror(boost::format("The file '%1%' is not a Matroska file or it could not be found.\n") % options->m_file_name);

    analyzer = console_kax_analyzer_cptr(new console_kax_analyzer_c(options->m_file_name));
  } catch (mtx::mm_io::exception &ex) {
    mxerror(boost::format("The file '%1%' could not be opened for reading and writing: %1.\n") % options->m_file_name % ex);
  }

  mxinfo(boost::format("%1%\n") % Y("The file is being analyzed."));

  analyzer->set_show_progress(options->m_show_progress);

  bool ok = false;
  try {
    ok = analyzer
      ->set_parse_mode(options->m_parse_mode)
      .set_open_mode(MODE_WRITE)
      .set_throw_on_error(true)
      .process();
  } catch (mtx::mm_io::exception &ex) {
    mxerror(boost::format(Y("The file '%1%' could not be opened for reading and writing, or a read/write operation on it failed: %2%.\n")) % options->m_file_name % ex);
  } catch (...) {
  }

  if (!ok)
    mxerror(Y("This file could not be opened or parsed.\n"));

  options->find_elements(analyzer.get());
  options->validate();

  if (debugging_c::requested("dump_options")) {
    mxinfo("\nDumping options after file and element analysis\n\n");
    options->dump_info();
  }

  options->execute(*analyzer);

  if (has_content_been_modified(options)) {
    mxinfo(Y("The changes are written to the file.\n"));

    write_changes(options, analyzer.get());

    mxinfo(Y("Done.\n"));

  } else
    mxinfo(Y("No changes were made.\n"));

  mxexit();
}
예제 #14
0
void
xtr_oggbase_c::create_standard_file(xtr_base_c *master,
                                    KaxTrackEntry &track,
                                    LacingType lacing) {
  KaxCodecPrivate *priv = FindChild<KaxCodecPrivate>(&track);
  if (!priv)
    mxerror(boost::format(Y("Track %1% with the CodecID '%2%' is missing the \"codec private\" element and cannot be extracted.\n")) % m_tid % m_codec_id);

  init_content_decoder(track);
  memory_cptr mpriv = decode_codec_private(priv);

  std::vector<memory_cptr> header_packets;

  try {
    if (lacing == LACING_NONE)
      header_packets.push_back(mpriv);

    else {
      header_packets = unlace_memory_xiph(mpriv);

      if (header_packets.empty())
        throw false;
    }

    header_packets_unlaced(header_packets);

  } catch (...) {
    mxerror(boost::format(Y("Track %1% with the CodecID '%2%' does not contain valid headers.\n")) % m_tid % m_codec_id);
  }

  xtr_oggbase_c::create_file(master, track);

  ogg_packet op;
  for (m_packetno = 0; header_packets.size() > m_packetno; ++m_packetno) {
    // Handle all the header packets: ID header, comments, etc
    op.b_o_s      = (0 == m_packetno ? 1 : 0);
    op.e_o_s      = 0;
    op.packetno   = m_packetno;
    op.packet     = header_packets[m_packetno]->get_buffer();
    op.bytes      = header_packets[m_packetno]->get_size();
    op.granulepos = 0;
    ogg_stream_packetin(&m_os, &op);

    if (0 == m_packetno) /* ID header must be alone on a separate page */
      flush_pages();
  }

  /* flush at last header, data must start on a new page */
  flush_pages();
}
예제 #15
0
std::vector<property_element_c> &
property_element_c::get_table_for(const EbmlCallbacks &master_callbacks,
                                  const EbmlCallbacks *sub_master_callbacks,
                                  bool full_table) {
  if (s_properties.empty())
    init_tables();

  std::map<uint32_t, std::vector<property_element_c> >::iterator src_map_it = s_properties.find(master_callbacks.GlobalId.Value);
  if (s_properties.end() == src_map_it)
    mxerror(boost::format("property_element_c::get_table_for(): programming error: no table found for EBML ID %|1$08x|\n") % master_callbacks.GlobalId.Value);

  if (full_table)
    return src_map_it->second;

  uint32_t element_id = !sub_master_callbacks ? master_callbacks.GlobalId.Value : sub_master_callbacks->GlobalId.Value;
  std::map<uint32_t, std::vector<property_element_c> >::iterator composed_map_it = s_composed_properties.find(element_id);
  if (s_composed_properties.end() != composed_map_it)
    return composed_map_it->second;

  s_composed_properties[element_id]      = std::vector<property_element_c>();
  std::vector<property_element_c> &table = s_composed_properties[element_id];

  for (auto &property : src_map_it->second)
    if (!property.m_sub_master_callbacks || (sub_master_callbacks && (sub_master_callbacks->GlobalId == property.m_sub_master_callbacks->GlobalId)))
      table.push_back(property);

  return table;
}
예제 #16
0
void
xtr_wav_c::create_file(xtr_base_c *master,
                       KaxTrackEntry &track) {
  init_content_decoder(track);

  int channels = kt_get_a_channels(track);
  int sfreq    = (int)kt_get_a_sfreq(track);
  int bps      = kt_get_a_bps(track);

  if (-1 == bps)
    mxerror(boost::format(Y("Track %1% with the CodecID '%2%' is missing the \"bits per second (bps)\" element and cannot be extracted.\n")) % m_tid % m_codec_id);

  xtr_base_c::create_file(master, track);

  memcpy(&m_wh.riff.id,      "RIFF", 4);
  memcpy(&m_wh.riff.wave_id, "WAVE", 4);
  memcpy(&m_wh.format.id,    "fmt ", 4);
  memcpy(&m_wh.data.id,      "data", 4);

  put_uint32_le(&m_wh.format.len,              16);
  put_uint16_le(&m_wh.common.wFormatTag,        1);
  put_uint16_le(&m_wh.common.wChannels,        channels);
  put_uint32_le(&m_wh.common.dwSamplesPerSec,  sfreq);
  put_uint32_le(&m_wh.common.dwAvgBytesPerSec, channels * sfreq * bps / 8);
  put_uint16_le(&m_wh.common.wBlockAlign,       4);
  put_uint16_le(&m_wh.common.wBitsPerSample,   bps);

  m_out->write(&m_wh, sizeof(wave_header));
}
예제 #17
0
static void
parse_file(const std::string &file_name) {
  mm_file_io_c in(file_name);

  const int buf_size = 100000;
  int64_t size       = in.get_size();

  if (4 > size)
    mxerror(Y("File too small\n"));

  memory_cptr mem    = memory_c::alloc(buf_size);
  unsigned char *ptr = mem->get_buffer();

  vc1_info_c parser;

  while (1) {
    int num_read = in.read(ptr, buf_size);

    parser.add_bytes(ptr, num_read);
    if (num_read < buf_size) {
      parser.flush();
      break;
    }
  }
}
예제 #18
0
void
options_c::set_file_name(const std::string &file_name) {
  if (!m_file_name.empty())
    mxerror(boost::format(Y("More than one file name has been given ('%1%' and '%2%').\n")) % m_file_name % file_name);

  m_file_name = file_name;
}
예제 #19
0
static FLAC__StreamDecoderReadStatus
fhe_read_cb(const FLAC__StreamDecoder *,
            FLAC__byte buffer[],
            size_t *bytes,
            void *client_data) {
  ogg_packet op;

  flac_header_extractor_c *fhe = (flac_header_extractor_c *)client_data;
  if (fhe->done)
    return FLAC__STREAM_DECODER_READ_STATUS_ABORT;

  if (ogg_stream_packetout(&fhe->os, &op) != 1)
    if (!fhe->read_page() || (ogg_stream_packetout(&fhe->os, &op) != 1))
      return FLAC__STREAM_DECODER_READ_STATUS_ABORT;

  if (*bytes < static_cast<size_t>(op.bytes))
    mxerror(boost::format(Y("flac_header_extraction: bytes (%1%) < op.bytes (%2%). Could not read the FLAC headers.\n")) % *bytes % op.bytes);

  int offset = 0;

  if ((0 == fhe->num_packets) && (ofm_post_1_1_1 == fhe->mode) && (13 < op.bytes))
    offset = 9;

  memcpy(buffer, &op.packet[offset], op.bytes - offset);
  *bytes = op.bytes - offset;

  fhe->num_packets++;
  mxverb(2, boost::format("flac_header_extraction: read packet number %1% with %2% bytes and offset %3%\n") % fhe->num_packets % op.bytes % offset);

  return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
}
예제 #20
0
base_uptr
for_algorithm(algorithm_e algorithm,
              uint64_t initial_value) {
  if (algorithm_e::adler32 == algorithm)
    return std::make_unique<adler32_c>();

  else if (algorithm_e::crc8_atm == algorithm)
    return std::make_unique<crc8_atm_c>(initial_value);

  else if (algorithm_e::crc16_ansi == algorithm)
    return std::make_unique<crc16_ansi_c>(initial_value);

  else if (algorithm_e::crc16_ccitt == algorithm)
    return std::make_unique<crc16_ccitt_c>(initial_value);

  else if (algorithm_e::crc32_ieee == algorithm)
    return std::make_unique<crc32_ieee_c>(initial_value);

  else if (algorithm_e::crc32_ieee_le == algorithm)
    return std::make_unique<crc32_ieee_le_c>(initial_value);

  else if (algorithm_e::md5 == algorithm)
    return std::make_unique<md5_c>();

  else
    mxerror(boost::format("Programming error: unknown checksum algorithm %1%\n") % static_cast<int>(algorithm));

  return {};
}
예제 #21
0
void
change_c::parse_binary() {
  try {
    m_x_value = bitvalue_c(m_value, 128);
  } catch (...) {
    mxerror(boost::format(Y("The property value is not a valid binary spec or it is not exactly 128 bits long in '%1%'. %2%\n")) % get_spec() % FILE_NOT_MODIFIED);
  }
}
예제 #22
0
void
change_c::parse_boolean() {
  try {
    m_b_value = parse_bool(m_value);
  } catch (...) {
    mxerror(boost::format(Y("The property value is not a valid boolean in '%1%'. %2%\n")) % get_spec() % FILE_NOT_MODIFIED);
  }
}
예제 #23
0
void
change_c::parse_ascii_string() {
  size_t i;
  for (i = 0; m_value.length() > i; ++i)
    if (127 < static_cast<unsigned char>(m_value[i]))
      mxerror(boost::format(Y("The property value contains non-ASCII characters, but the property is not a Unicode string in '%1%'. %2%\n")) % get_spec() % FILE_NOT_MODIFIED);

  m_s_value = m_value;
}
예제 #24
0
static void
parse_file(const std::string &file_name) {
  auto in     = mm_file_io_c{file_name};
  auto parser = mtx::mpls::parser_c{};

  if (!parser.parse(&in))
    mxerror("MPLS file could not be parsed.\n");

  parser.dump();
}
예제 #25
0
unsigned char *
_safemalloc(size_t size,
            const char *file,
            int line) {
  unsigned char *mem = reinterpret_cast<unsigned char *>(malloc(size));
  if (!mem)
    mxerror(boost::format(Y("memory.cpp/safemalloc() called from file %1%, line %2%: malloc() returned nullptr for a size of %3% bytes.\n")) % file % line % size);

  return mem;
}
예제 #26
0
int32_t M2VParser::OrderFrame(MPEGFrame* frame){
  MPEGFrame *p = frame;
  bool flushQueue = false;

  if (waitSecondField && (p->pictureStructure == MPEG2_PICTURE_TYPE_FRAME)){
    mxerror(Y("Unexpected picture frame after single field frame. Fix the MPEG2 video stream before attempting to multiplex it.\n"));
  }

  if((p->timecode == queueTime) && waitQueue.empty()){
    if((p->pictureStructure == MPEG2_PICTURE_TYPE_FRAME) || waitSecondField)
      queueTime++;
    StampFrame(p);
    buffers.push(p);
  }else if((p->timecode > queueTime) && waitQueue.empty()){
    waitExpectedTime = p->timecode - 1;
    p->stamped = false;
    waitQueue.push(p);
  }else if(p->timecode > waitExpectedTime){
    p->stamped = false;
    waitQueue.push(p);
  }else if(p->timecode == waitExpectedTime){
    StampFrame(p);
    waitQueue.push(p);
    if((p->pictureStructure == MPEG2_PICTURE_TYPE_FRAME) || waitSecondField)
      flushQueue = true;
  }else{
    StampFrame(p);
    waitQueue.push(p);
  }

  if(flushQueue){
    int i,l;
    waitSecondField = false;

    l = waitQueue.size();
    for(i=0;i<l;i++){
      p = waitQueue.front();
      waitQueue.pop();
      if(!p->stamped) {
        StampFrame(p);
      }
      buffers.push(p);
      if((p->pictureStructure == MPEG2_PICTURE_TYPE_FRAME) || waitSecondField){
        queueTime++;
      }
      if(p->pictureStructure != MPEG2_PICTURE_TYPE_FRAME)
        waitSecondField = !waitSecondField;
    }
    waitSecondField = false;
  }else if (p->pictureStructure != MPEG2_PICTURE_TYPE_FRAME){
    waitSecondField = !waitSecondField;
  }

  return 0;
}
static mm_io_cptr
open_input_file(filelist_t &file) {
  try {
    if (file.all_names.size() == 1)
      return mm_io_cptr(new mm_read_buffer_io_c(new mm_file_io_c(file.name), 1 << 17));

    else {
      std::vector<bfs::path> paths = file_names_to_paths(file.all_names);
      return mm_io_cptr(new mm_read_buffer_io_c(new mm_multi_file_io_c(paths, file.name), 1 << 17));
    }

  } catch (mtx::mm_io::exception &ex) {
    mxerror(boost::format(Y("The file '%1%' could not be opened for reading: %2%.\n")) % file.name % ex);
    return mm_io_cptr{};

  } catch (...) {
    mxerror(boost::format(Y("The source file '%1%' could not be opened successfully, or retrieving its size by seeking to the end did not work.\n")) % file.name);
    return mm_io_cptr{};
  }
}
예제 #28
0
void
extract_cli_parser_c::add_extraction_spec() {
  if (   (options_c::em_tracks       != m_options.m_extraction_mode)
      && (options_c::em_timecodes_v2 != m_options.m_extraction_mode)
      && (options_c::em_attachments  != m_options.m_extraction_mode))
    mxerror(boost::format(Y("Unrecognized command line option '%1%'.\n")) % m_current_arg);

  boost::regex s_track_id_re("^(\\d+)(:(.+))?$", boost::regex::perl);

  boost::smatch matches;
  if (!boost::regex_search(m_current_arg, matches, s_track_id_re)) {
    if (options_c::em_attachments == m_options.m_extraction_mode)
      mxerror(boost::format(Y("Invalid attachment ID/file name specification in argument '%1%'.\n")) % m_current_arg);
    else
      mxerror(boost::format(Y("Invalid track ID/file name specification in argument '%1%'.\n")) % m_current_arg);
  }

  track_spec_t track;

  parse_number(matches[1].str(), track.tid);

  std::string output_file_name;
  if (matches[3].matched)
    output_file_name = matches[3].str();

  if (output_file_name.empty()) {
    if (options_c::em_attachments == m_options.m_extraction_mode)
      mxinfo(Y("No output file name specified, will use attachment name.\n"));
    else
      mxerror(boost::format(Y("Missing output file name in argument '%1%'.\n")) % m_current_arg);
  }

  track.out_name               = output_file_name;
  track.sub_charset            = m_charset;
  track.extract_cuesheet       = m_extract_cuesheet;
  track.extract_blockadd_level = m_extract_blockadd_level;
  track.target_mode            = m_target_mode;
  m_options.m_tracks.push_back(track);

  set_default_values();
}
예제 #29
0
int
generic_reader_c::add_packetizer(generic_packetizer_c *ptzr) {
  if (outputting_webm() && !ptzr->is_compatible_with(OC_WEBM))
    mxerror(boost::format(Y("The codec type '%1%' cannot be used in a WebM compliant file.\n")) % ptzr->get_format_name());

  m_reader_packetizers.push_back(ptzr);
  m_used_track_ids.push_back(ptzr->m_ti.m_id);
  if (!m_appending)
    add_packetizer_globally(ptzr);

  return m_reader_packetizers.size() - 1;
}
예제 #30
0
void
xtr_flac_c::create_file(xtr_base_c *_master,
                        KaxTrackEntry &track) {
  KaxCodecPrivate *priv = FindChild<KaxCodecPrivate>(&track);
  if (!priv)
    mxerror(boost::format(Y("Track %1% with the CodecID '%2%' is missing the \"codec private\" element and cannot be extracted.\n")) % m_tid % m_codec_id);

  xtr_base_c::create_file(_master, track);

  memory_cptr mpriv = decode_codec_private(priv);
  m_out->write(mpriv);
}