Esempio n. 1
0
int main(int argc, char ** argv)
{
    try {
        const std::string description =
                "Parallel Empirical Variogram: A massively parallel solution "
                "for computing empirical variograms of large-scale data.";

        const std::string input_desc = "Path to input file";
        const std::string output_desc = "Path to output file. Defaults to stdout.";
        const std::string timing_desc = "Path to timing file. "
                                        "Defaults to not writing timing information.";
        const std::string repl_desc = "Desired replication factor. Defaults to 1.";
        const std::string bins_desc = "Number of distance bins to use for empirical variogram. "
                                      "Defaults to 15.";
        const std::string format_desc = "Prints information about output formats instead of performing computations.";

        // TODO: Improve input file descriptions to describe output formats
        TCLAP::CmdLine cmd(description, ' ', "0.1");
        TCLAP::ValueArg<std::string> input_file_arg("i", "input", input_desc, true, "", "path");
        TCLAP::ValueArg<std::string> output_file_arg("o", "output", output_desc, false, "", "path");
        TCLAP::ValueArg<std::string> timing_file_arg("t", "timing", timing_desc, false, "", "path");
//        TCLAP::ValueArg<int> repl_factor_arg("c", "replication", repl_desc,
//                                             false, 1, &positive_constraint);
        TCLAP::ValueArg<int> num_bins_arg("b", "bins", bins_desc, false, 15, &positive_constraint);
        TCLAP::SwitchArg format_arg("p", "print-formats", format_desc, false);

        // We only want EITHER input file or format
        cmd.xorAdd(input_file_arg, format_arg);
        cmd.add(output_file_arg);
        cmd.add(timing_file_arg);
//        cmd.add(repl_factor_arg);
        cmd.add(num_bins_arg);
        cmd.parse(argc, argv);

        const int num_bins = num_bins_arg.getValue();
//        const int replication_factor = repl_factor_arg.getValue();
        const std::string input_path = input_file_arg.getValue();
        const std::string output_path = output_file_arg.getValue();
        const std::string timing_path = timing_file_arg.getValue();

        MPI_Init(&argc, &argv);
        int rank, ranks;
        MPI_Comm_rank(MPI_COMM_WORLD, &rank);
        MPI_Comm_size(MPI_COMM_WORLD, &ranks);

        if (format_arg.isSet())
        {
            if (rank == 0)
                print_formats();
            MPI_Finalize();
            return 0;
        }

        pev::parallel_options options(ranks, 1);
        if (rank == 0)
        {
            std::cout << "Using " << options.active_processor_count() << " of "
                      << ranks << " processors with replication factor " << options.replication_factor()
                      << std::endl;
        }

        pev::variogram_data variogram = pev::empirical_variogram_parallel(input_path, num_bins);

        if (rank == 0)
        {
            std::ofstream outfile;
            if (output_file_arg.isSet())
                outfile.open(output_path);

            // Print to stdout if output file not supplied
            std::ostream & out = output_file_arg.isSet()
                    ? outfile
                    : std::cout;

            pev::print_variogram(out, variogram);

            if (timing_file_arg.isSet())
            {
                std::ofstream outfile;

                // Append to timing file if path is given
                if (timing_path != "-")
                    outfile.open(timing_path, std::ios_base::out | std::ios_base::app);

                std::ostream & out = timing_path == "-"
                        ? std::cout
                        : outfile;

                pev::print_timing_info(out, variogram);
            }
        }

        MPI_Finalize();

        return 0;

    } catch (const TCLAP::ArgException & e)
    {
        std::cerr << "ERROR: " << e.what() << " for argument " << e.argId() << std::endl;
        return -1;
    }
}
Esempio n. 2
0
int main (int argc, char *argv[]) {
  /* Program Option parsing */

  int num_frames = 1;
  int threads = 1;
  bool disable_output = false;
  bool colourise_quantiser = false;
  bool colourise_padding = false;
  bool colourise_unpadded = false;
  bool quartersize = false;
  bool verbose = false;

  std::string input_filename;
  std::string output_filename;

  try {
    TCLAP::CmdLine cmd("VC2 HQ profile Decoder Example\n"
                       "All input files must be vc2 streams\n"
                       "All output files will be yuv422p10le\n", '=', "0.1", true);

    TCLAP::SwitchArg     verbose_arg             ("v", "verbose",        "verbose mode",                                    cmd, false);
    TCLAP::ValueArg<int> num_frames_arg          ("n", "num-frames",     "Number of frames to decode", false, 1, "integer", cmd);
    TCLAP::ValueArg<int> num_threads_arg         ("t", "threads",        "Number of threads",          false, 1, "integer", cmd);
    TCLAP::SwitchArg     disable_output_args     ("d", "disable-output",      "disable output",                                  cmd, false);
    TCLAP::SwitchArg     colourise_quantiser_args("q", "colourise-quantiser", "colourise based on quantiser levels",             cmd, false);
    TCLAP::SwitchArg     colourise_padding_args  ("p", "colourise-padding", "colourise based on padding levels",               cmd, false);
    TCLAP::SwitchArg     colourise_unpadded_args ("u", "colourise-unpadded", "colourise based on lack of padding",              cmd, false);
    
    TCLAP::UnlabeledValueArg<std::string> input_file_arg("input_file",   "encoded input file",         true, "", "string",  cmd);
    TCLAP::UnlabeledValueArg<std::string> output_file_arg("output_file", "output file (defaults to input file + .yuv)", false, "", "string", cmd);

    cmd.parse( argc, argv );

    num_frames          = num_frames_arg.getValue();
    threads             = num_threads_arg.getValue();
    disable_output      = disable_output_args.getValue();
    colourise_quantiser = colourise_quantiser_args.getValue();
    colourise_padding   = colourise_padding_args.getValue();
    colourise_unpadded  = colourise_unpadded_args.getValue();
    verbose             = verbose_arg.getValue();

    input_filename = input_file_arg.getValue();
    output_filename = output_file_arg.getValue();
  } catch (TCLAP::ArgException &e) {
    std::cerr << "error: " << e.error() << " for arg " << e.argId() << std::endl; return 1;
  }

  if (output_filename == "")
    output_filename = input_filename + ".yuv";

  /* Variables for storing input and output buffers */
  char *idata;
  size_t input_length = 0;
  uint16_t **odata = new uint16_t*[num_frames];   // Output frame pointers
  uint16_t ***opics = new uint16_t**[num_frames*2]; // Output picture pointers (which may be different for interlaced sequences)
  for (int i = 0; i < num_frames * 2; i++) {
    opics[i] = new uint16_t*[3];
  }
  int ostride[3];
  int num_frames_decoded_from_sequence = 0;
  int total_frames_decoded = 0;




  
  /* Initialise decoder */
  vc2decode_init();
  VC2DecoderHandle decoder = vc2decode_create();

  /* Configure decoder */
  {
    VC2DecoderParamsUser params;
    memset((void *)&params, 0, sizeof(params));

    params.threads = threads;
    params.colourise_quantiser = colourise_quantiser;
    params.colourise_padding   = colourise_padding;
    params.colourise_unpadded  = colourise_unpadded;


    /* QuarterSize is only really sensible for HD */
    if (quartersize) {
      params.partial_decode = true;
      params.partial_decode_width  = 1920/2;
      params.partial_decode_height = 1080/2;

      params.partial_decode_offset_x  = 0;
      params.partial_decode_offset_y  = 540;
    }


    {
      VC2DecoderResult r = vc2decode_set_parameters(decoder, params);
      if (r != VC2DECODER_OK) {
        printf("Parameter Error: %d\n", r);
        return 1;
      }
    }
  }


  /* Read input data */
  {
    FILE *f = FOPEN(input_filename.c_str(), "rb");
    if (!f) {
      fprintf(stderr, "Could not open: %s\n", input_filename.c_str());
      perror("Invalid input file: ");
      return 1;
    }
    int r = fseek(f, 0L, SEEK_END);
    if (r < 0) {
      perror("Error seeking in input file");
      return 1;
    }
    input_length = ftell(f);
    rewind(f);

    idata = (char *)malloc(input_length);
    size_t s = fread(idata, 1, input_length, f);
    if (s != input_length) {
      if (ferror(f))
        fprintf(stderr, "Error reading file\n");
      else
        fprintf(stderr, "Improper Length on Input File\n");
      return 1;
    }

    fclose(f);

    printf("Read %lubytes of input data\n", input_length);
  }


  /* Set the output fmt to something invalid to start with */
  VC2DecoderOutputFormat fmt;
  fmt.width            = 0;
  fmt.height           = 0;
  fmt.signal_range     = 0;
  fmt.source_sampling  = 0;
  fmt.frame_rate_numer = 0;
  fmt.frame_rate_denom = 0;
  fmt.interlaced       = 0;

  ostride[0] = 0;
  ostride[1] = 0;
  ostride[2] = 0;

  for (int i = 0; i < num_frames; i++) {
    odata[i] = NULL;
  }




  /* Begin the main program loop */
  int err = 0;
  uint64_t time_taken = 0;
  while (total_frames_decoded < num_frames) {
    VC2DecoderResult r;

    /* Reset to the start of the input data */
    char *id = idata;
    char *iend = idata + input_length;

    /* We are at the start of a sequence, so synchronise */
    r = vc2decode_synchronise(decoder, &id, iend - id, true);
    if (r != VC2DECODER_OK_RECONFIGURED) {
      fprintf(stderr, "Error synchronising to sequence");
      err = 1;
      break;
    }

    /* We have synchronised, so get the output format */
    VC2DecoderOutputFormat new_fmt;
    r = vc2decode_get_output_format(decoder, &new_fmt);
    if (r != VC2DECODER_OK) {
      fprintf(stderr, "Output format error: %d\n", r);
      err = 1;
      break;
    }

    /* Reconfigure output buffers if this format doesn't
       match the current one */
    if (fmt.width != new_fmt.width ||
        fmt.height != new_fmt.height ||
        fmt.interlaced != new_fmt.interlaced) {
      fmt = new_fmt;

      for (int i = 0; i < num_frames; i++) {
        if (odata[i])
          free(odata[i]);
        odata[i] = (uint16_t *)malloc(fmt.width*fmt.height*2*sizeof(uint16_t));
      }

      if (fmt.interlaced) {
        ostride[0] = fmt.width*2;
        ostride[1] = fmt.width;
        ostride[2] = fmt.width;
        for (int i = 0; i < num_frames; i++) {
          opics[2*i + 0][0] = odata[i];
          opics[2*i + 0][1] = odata[i] + fmt.width*fmt.height;
          opics[2*i + 0][2] = odata[i] + fmt.width*fmt.height + fmt.width*fmt.height/2;

          opics[2*i + 1][0] = odata[i] + fmt.width;
          opics[2*i + 1][1] = odata[i] + fmt.width*fmt.height + fmt.width/2;
          opics[2*i + 1][2] = odata[i] + fmt.width*fmt.height + fmt.width*fmt.height/2 + fmt.width/2;
        }
      } else {
        ostride[0] = fmt.width;
        ostride[1] = fmt.width/2;
        ostride[2] = fmt.width/2;
        for (int i = 0; i < num_frames; i++) {
          opics[i][0] = odata[i];
          opics[i][1] = odata[i] + fmt.width*fmt.height;
          opics[i][2] = odata[i] + fmt.width*fmt.height + fmt.width*fmt.height/2;
        }
      }
    }

    /* Decode Pictures from stream */
    int picture = 0;
    struct timespec start, end;
    clock_gettime(CLOCK_MONOTONIC, &start);
    while (total_frames_decoded < num_frames) {
      r = vc2decode_decode_one_picture(decoder, &id, iend - id, opics[picture], ostride, true);

      /* If End of Sequence break from loop */
      if (r == VC2DECODER_OK_EOS) {
        break;
      }

      /* If a picture has been sucessfully decoded continue */
      if (r == VC2DECODER_OK_PICTURE) {
        if (!fmt.interlaced || (picture%2))
          total_frames_decoded++;
        picture++;
        if (id == NULL) {
          fprintf(stderr, "Premature end of stream\n");
          break;
        }
        continue;
      }

      /* If a reconfiguration has been triggered this is an invalid sequence, flag that */
      if (r == VC2DECODER_OK_RECONFIGURED) {
        fprintf(stderr, "Warning: this sequence changes parameters part way through\n");
        break;
      }

      /* Otherwise we have an error */
      if (r < 0) {
        fprintf(stderr, "Error decoding:\n");
        fprintf(stderr, "  %s\n", VC2DecoderErrorString[-r]);
        err=1;
        break;
      }

      fprintf(stderr, "Unknown Return value: %d\n", r);
      break;
    }
    clock_gettime(CLOCK_MONOTONIC, &end);
    /* We have reached the end of a sequence, or have decoded enough frames */

    /*If an error has occurred bail */
    if (err)
      break;

    /*If no pictures were decoded bail */
    if (picture == 0) {
      fprintf(stderr, "No pictures in sequence!\n");
      err = 1;
      break;
    }

    /* Otherwise update the record of how many decoded frames have been recorded */
    int num_frames_decoded_from_this_sequence = (fmt.interlaced)?(picture/2):(picture);
    if (num_frames_decoded_from_this_sequence > num_frames_decoded_from_sequence)
      num_frames_decoded_from_sequence = num_frames_decoded_from_this_sequence;

    /* And update the record of time taken to decode */
    time_taken += (end.tv_sec*1000000000 + end.tv_nsec) - (start.tv_sec*1000000000 + start.tv_nsec);
  }

  /* If there has been no error print the speed */
  if (!err) {
    printf("--------------------------------------------------\n");
    printf("  %d frames decoded in %5.3fs\n", total_frames_decoded, time_taken/1000000000.0);
    printf("  %5.3ffps\n", total_frames_decoded*1000000000.0/time_taken);
    printf("--------------------------------------------------\n");
  }

  /* If there has been no error get decoder statistics  */
  if (!err) {
    VC2DecoderSequenceInfo info;
    vc2decode_sequence_info(decoder, &info);

    print_sequence_info(info, verbose);
  }

  /*
     If there is no error and output is enabled write the output to a file

     This code actually performs an endianess swap and some bit shifting on the output
     data to put it into the desired format (10-bit data in the high order bits of 16-bit
     words in network byte order).
   */
  if (!err && !disable_output) {
    try {
      FILE *of = FOPEN(output_filename.c_str(), "wb");

      for (int i = 0; i < num_frames_decoded_from_sequence; i++) {

        for (int y = 0; y < fmt.height; y++) {
          size_t s = fwrite(&odata[i][(y*fmt.width)], 1, fmt.width*sizeof(uint16_t), of);
          if (s != fmt.width*sizeof(uint16_t))
            throw std::runtime_error("Writing Error");
        }
        for (int y = 0; y < fmt.height*2; y++) {
          size_t s = fwrite(&odata[i][(fmt.height*fmt.width + y*fmt.width/2)], 1, fmt.width/2*sizeof(uint16_t), of);
          if (s != fmt.width/2*sizeof(uint16_t))
            throw std::runtime_error("Writing Error");
        }
      }
      printf("Wrote out %d frames\n", num_frames_decoded_from_sequence);
      fclose(of);
    } catch(...) {
      fprintf(stderr, "Error writing output\n");
      err = 1;
    }
  }

  /* Destroy the decoder */
  vc2decode_destroy(decoder);


  /* Deallocate buffers */
  free(idata);

  for (int i = 0; i < num_frames; i++)
    if (odata[i])
      free(odata[i]);

  delete[] odata;
  for (int i = 0; i < num_frames * 2; i++)
    delete[] opics[i];
  delete[] opics;

  return err;
}