예제 #1
0
extern "C" int main_webminfo(int argc, const char* argv[])
{
  string input;
  Options options;

  const int argc_check = argc - 1;
  for (int i = 0; i < argc; ++i) {
    if (!strcmp("-h", argv[i]) || !strcmp("-?", argv[i])) {
      Usage();
      return EXIT_SUCCESS;
    } else if (!strcmp("-v", argv[i])) {
      printf("version: %s\n", VERSION_STRING);
    } else if (!strcmp("-i", argv[i]) && i < argc_check) {
      input = argv[++i];
    } else if (!strcmp("-all", argv[i])) {
      options.SetAll(true);
    } else if (Options::MatchesBooleanOption("video", argv[i])) {
      options.output_video = !strcmp("-video", argv[i]);
    } else if (Options::MatchesBooleanOption("audio", argv[i])) {
      options.output_audio = !strcmp("-audio", argv[i]);
    } else if (Options::MatchesBooleanOption("size", argv[i])) {
      options.output_size = !strcmp("-size", argv[i]);
    } else if (Options::MatchesBooleanOption("offset", argv[i])) {
      options.output_offset = !strcmp("-offset", argv[i]);
    } else if (Options::MatchesBooleanOption("times_seconds", argv[i])) {
      options.output_seconds = !strcmp("-times_seconds", argv[i]);
    } else if (Options::MatchesBooleanOption("ebml_header", argv[i])) {
      options.output_ebml_header = !strcmp("-ebml_header", argv[i]);
    } else if (Options::MatchesBooleanOption("segment", argv[i])) {
      options.output_segment = !strcmp("-segment", argv[i]);
    } else if (Options::MatchesBooleanOption("segment_info", argv[i])) {
      options.output_segment_info = !strcmp("-segment_info", argv[i]);
    } else if (Options::MatchesBooleanOption("tracks", argv[i])) {
      options.output_tracks = !strcmp("-tracks", argv[i]);
    } else if (Options::MatchesBooleanOption("clusters", argv[i])) {
      options.output_clusters = !strcmp("-clusters", argv[i]);
    } else if (Options::MatchesBooleanOption("blocks", argv[i])) {
      options.output_blocks = !strcmp("-blocks", argv[i]);
    } else if (Options::MatchesBooleanOption("codec_info", argv[i])) {
      options.output_codec_info = !strcmp("-codec_info", argv[i]);
    } else if (Options::MatchesBooleanOption("clusters_size", argv[i])) {
      options.output_clusters_size = !strcmp("-clusters_size", argv[i]);
    } else if (Options::MatchesBooleanOption("encrypted_info", argv[i])) {
      options.output_encrypted_info = !strcmp("-encrypted_info", argv[i]);
    } else if (Options::MatchesBooleanOption("cues", argv[i])) {
      options.output_cues = !strcmp("-cues", argv[i]);
    }
  }

  if (argc < 2 || input.empty()) {
    Usage();
    return EXIT_FAILURE;
  }

  // TODO(fgalligan): Replace auto_ptr with scoped_ptr.
  std::auto_ptr<mkvparser::MkvReader>
      reader(new (std::nothrow) mkvparser::MkvReader());  // NOLINT
  if (reader->Open(input.c_str())) {
    fprintf(stderr, "Error opening file:%s\n", input.c_str());
    return EXIT_FAILURE;
  }

  int64 pos = 0;
  std::auto_ptr<mkvparser::EBMLHeader>
      ebml_header(new (std::nothrow) mkvparser::EBMLHeader());  // NOLINT
  if (ebml_header->Parse(reader.get(), pos) < 0) {
    fprintf(stderr, "Error parsing EBML header.\n");
    return EXIT_FAILURE;
  }

  Indent indent(0);
  FILE* out = stdout;

  if (options.output_ebml_header)
    OutputEBMLHeader(*ebml_header.get(), out, &indent);

  mkvparser::Segment* temp_segment;
  if (mkvparser::Segment::CreateInstance(reader.get(), pos, temp_segment)) {
    fprintf(stderr, "Segment::CreateInstance() failed.\n");
    return EXIT_FAILURE;
  }
  std::auto_ptr<mkvparser::Segment> segment(temp_segment);

  if (segment->Load() < 0) {
      fprintf(stderr, "Segment::Load() failed.\n");
      return EXIT_FAILURE;
  }

  if (options.output_segment) {
    OutputSegment(*(segment.get()), options, out);
    indent.Adjust(webm_tools::kIncreaseIndent);
  }

  if (options.output_segment_info)
    if (!OutputSegmentInfo(*(segment.get()), options, out, &indent))
      return EXIT_FAILURE;

  if (options.output_tracks)
    if (!OutputTracks(*(segment.get()), options, out, &indent))
      return EXIT_FAILURE;

  const mkvparser::Tracks* const tracks = segment->GetTracks();
  if (!tracks) {
    fprintf(stderr, "Could not get Tracks.\n");
    return EXIT_FAILURE;
  }

  // If Cues are before the clusters output them first.
  if (options.output_cues) {
    const mkvparser::Cluster* cluster = segment->GetFirst();
    const mkvparser::Cues* const cues = segment->GetCues();
    if (cluster != NULL && cues != NULL) {
      if (cues->m_element_start < cluster->m_element_start) {
        if (!OutputCues(*segment, *tracks, options, out, &indent)) {
          return EXIT_FAILURE;
        }
        options.output_cues = false;
      }
    }
  }

  if (options.output_clusters)
    fprintf(out, "%sClusters (count):%ld\n",
            indent.indent_str().c_str(), segment->GetCount());

  int64 clusters_size = 0;
  const mkvparser::Cluster* cluster = segment->GetFirst();
  while (cluster != NULL && !cluster->EOS()) {
    if (!OutputCluster(*cluster,
                       *tracks,
                       options,
                       out,
                       reader.get(),
                       &indent,
                       &clusters_size))
      return EXIT_FAILURE;
    cluster = segment->GetNext(cluster);
  }

  if (options.output_clusters_size)
    fprintf(out, "%sClusters (size):%lld\n",
            indent.indent_str().c_str(), clusters_size);

  if (options.output_cues)
    if (!OutputCues(*segment, *tracks, options, out, &indent))
      return EXIT_FAILURE;

  return EXIT_SUCCESS;
}