Esempio n. 1
0
/*
 * Read the file, and calculate the md5 sum for
 * each block.
 */
int read_file(int fd) {
	int				rnumber, bnumber, i;
	unsigned char	md5val[MD5_STRING_LEN];
	
	lseek(fd, 0, SEEK_SET);
	bnumber = 0;
	while ((rnumber = read(fd, block_buf, BLOCK_SIZE)) > 0) {
		/*
		// TODO : If the file size is not 8K * n.
		if (rnumber != BLOCK_SIZE) {
		}
		else {
		}
		*/
		MD5(block_buf, rnumber, md5val);
		printf("block[%4d] : ", bnumber);
		print_md5(md5val);
		bnumber++;
	}

	if (rnumber == -1) {
		perror("Read file");
		exit(-1);
	}

	return 0;
}
Esempio n. 2
0
int main(int argc, char **argv) {
  int frame_cnt = 0;
  FILE *outfile = NULL;
  vpx_codec_ctx_t codec;
  VpxVideoReader *reader = NULL;
  const VpxVideoInfo *info = NULL;
  const VpxInterface *decoder = NULL;

  exec_name = argv[0];

  if (argc != 3)
    die("Invalid number of arguments.");

  reader = vpx_video_reader_open(argv[1]);
  if (!reader)
    die("Failed to open %s for reading.", argv[1]);

  if (!(outfile = fopen(argv[2], "wb")))
    die("Failed to open %s for writing.", argv[2]);

  info = vpx_video_reader_get_info(reader);

  decoder = get_vpx_decoder_by_fourcc(info->codec_fourcc);
  if (!decoder)
    die("Unknown input codec.");

  printf("Using %s\n", vpx_codec_iface_name(decoder->codec_interface()));

  if (vpx_codec_dec_init(&codec, decoder->codec_interface(), NULL, 0))
    die_codec(&codec, "Failed to initialize decoder");

  while (vpx_video_reader_read_frame(reader)) {
    vpx_codec_iter_t iter = NULL;
    vpx_image_t *img = NULL;
    size_t frame_size = 0;
    const unsigned char *frame = vpx_video_reader_get_frame(reader,
                                                            &frame_size);
    if (vpx_codec_decode(&codec, frame, (unsigned int)frame_size, NULL, 0))
      die_codec(&codec, "Failed to decode frame");

    while ((img = vpx_codec_get_frame(&codec, &iter)) != NULL) {
      unsigned char digest[16];

      get_image_md5(img, digest);
      print_md5(outfile, digest);
      fprintf(outfile, "  img-%dx%d-%04d.i420\n",
              img->d_w, img->d_h, ++frame_cnt);
    }
  }

  printf("Processed %d frames.\n", frame_cnt);
  if (vpx_codec_destroy(&codec))
    die_codec(&codec, "Failed to destroy codec.");

  vpx_video_reader_close(reader);

  fclose(outfile);
  return EXIT_SUCCESS;
}
Esempio n. 3
0
int main(void){
    uint8_t md5val[16];
    int i;
    uint8_t in[1000];

    for (i = 0; i < 1000; i++)
        in[i] = i * i;
    av_md5_sum(md5val, in, 1000); print_md5(md5val);
    av_md5_sum(md5val, in,   63); print_md5(md5val);
    av_md5_sum(md5val, in,   64); print_md5(md5val);
    av_md5_sum(md5val, in,   65); print_md5(md5val);
    for (i = 0; i < 1000; i++)
        in[i] = i % 127;
    av_md5_sum(md5val, in,  999); print_md5(md5val);

    return 0;
}
Esempio n. 4
0
//
// Compare and print the MD5 hashes hashes1 and hashes2 of plaintext vector
// ptext. Complain if they don't match.
//
void compare_hashes(std::vector<md5hash> &hashes1, std::vector<md5hash> &hashes2, const std::vector<std::string> &ptext)
{
	FILE *o;
	o = fopen ("dataOut", "w");
	if (NULL == o)
	{
		printf ("FAIL!\n");
		exit (1);
	}

	// Compare & print
	for(uint i=0; i != hashes1.size(); i++)
	{
		if(memcmp(hashes1[i].ui, hashes2[i].ui, 16) == 0)
		{
		//	printf("OK   ");
		//	print_md5(hashes1[i].ui);
			uint8_t *p;
			p = (uint8_t *)&hashes1[i].ui[0];
			fprintf (o, "%2.2x%2.2x%2.2x%2.2x", p[0], p[1], p[2], p[3]);
			fprintf (o, " ");
			p = (uint8_t *)&hashes1[i].ui[1];
			fprintf (o, "%2.2x%2.2x%2.2x%2.2x", p[0], p[1], p[2], p[3]);
			fprintf (o, " ");
			p = (uint8_t *)&hashes1[i].ui[2];
			fprintf (o, "%2.2x%2.2x%2.2x%2.2x", p[0], p[1], p[2], p[3]);
			fprintf (o, " ");
			p = (uint8_t *)&hashes1[i].ui[3];
			fprintf (o, "%2.2x%2.2x%2.2x%2.2x", p[0], p[1], p[2], p[3]);
			fprintf (o, "\n");
		}
		else
		{
			printf("%-56s ", ptext[i].c_str());
			printf("ERROR   ");
			print_md5(hashes1[i].ui, false);
			printf(" != ");
			print_md5(hashes2[i].ui);
			std::cerr << "Hash " << i << " didn't match. Test failed. Aborting.\n";
			return;
		} 
	}
	std::cerr << "All hashes match.\n";

	fclose (o);
}
Esempio n. 5
0
int main(void){
    uint8_t md5val[16];
    int i;
    volatile uint8_t in[1000]; // volatile to workaround http://llvm.org/bugs/show_bug.cgi?id=20849
    // FIXME remove volatile once it has been fixed and all fate clients are updated

    for (i = 0; i < 1000; i++)
        in[i] = i * i;
    av_md5_sum(md5val, in, 1000); print_md5(md5val);
    av_md5_sum(md5val, in,   63); print_md5(md5val);
    av_md5_sum(md5val, in,   64); print_md5(md5val);
    av_md5_sum(md5val, in,   65); print_md5(md5val);
    for (i = 0; i < 1000; i++)
        in[i] = i % 127;
    av_md5_sum(md5val, in,  999); print_md5(md5val);

    return 0;
}
Esempio n. 6
0
int print_block(Block_Content *blk, char *comment) {
	unsigned int	i;
	unsigned char   md5val[MD5_STRING_LEN];
	
	if (comment != NULL) printf("%s :\n", comment);
	for (i = 0; i < blk->block_size; i++) printf("%02x", blk->block_cont[i]);
	printf("\n");

	calculate_md5(blk, md5val);
	printf("md5sum : ");
	print_md5(md5val);
	
	return 0;
}
Esempio n. 7
0
int main_loop(int argc, const char **argv_) {
  vpx_codec_ctx_t       decoder;
  char                  *fn = NULL;
  int                    i;
  uint8_t               *buf = NULL;
  size_t                 bytes_in_buffer = 0, buffer_size = 0;
  FILE                  *infile;
  int                    frame_in = 0, frame_out = 0, flipuv = 0, noblit = 0;
  int                    do_md5 = 0, progress = 0;
  int                    stop_after = 0, postproc = 0, summary = 0, quiet = 1;
  int                    arg_skip = 0;
  int                    ec_enabled = 0;
  const VpxInterface *interface = NULL;
  const VpxInterface *fourcc_interface = NULL;
  uint64_t dx_time = 0;
  struct arg               arg;
  char                   **argv, **argi, **argj;

  int                     single_file;
  int                     use_y4m = 1;
  vpx_codec_dec_cfg_t     cfg = {0};
#if CONFIG_VP8_DECODER
  vp8_postproc_cfg_t      vp8_pp_cfg = {0};
  int                     vp8_dbg_color_ref_frame = 0;
  int                     vp8_dbg_color_mb_modes = 0;
  int                     vp8_dbg_color_b_modes = 0;
  int                     vp8_dbg_display_mv = 0;
#endif
  int                     frames_corrupted = 0;
  int                     dec_flags = 0;
  int                     do_scale = 0;
  vpx_image_t             *scaled_img = NULL;
  int                     frame_avail, got_data;
  int                     num_external_frame_buffers = 0;
  struct ExternalFrameBufferList ext_fb_list = {0};

  const char *outfile_pattern = NULL;
  char outfile_name[PATH_MAX] = {0};
  FILE *outfile = NULL;

  MD5Context md5_ctx;
  unsigned char md5_digest[16];

  struct VpxDecInputContext input = {0};
  struct VpxInputContext vpx_input_ctx = {0};
  struct WebmInputContext webm_ctx = {0};
  input.vpx_input_ctx = &vpx_input_ctx;
  input.webm_ctx = &webm_ctx;

  /* Parse command line */
  exec_name = argv_[0];
  argv = argv_dup(argc - 1, argv_ + 1);

  for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) {
    memset(&arg, 0, sizeof(arg));
    arg.argv_step = 1;

    if (arg_match(&arg, &codecarg, argi)) {
      interface = get_vpx_decoder_by_name(arg.val);
      if (!interface)
        die("Error: Unrecognized argument (%s) to --codec\n", arg.val);
    } else if (arg_match(&arg, &looparg, argi)) {
      // no-op
    } else if (arg_match(&arg, &outputfile, argi))
      outfile_pattern = arg.val;
    else if (arg_match(&arg, &use_yv12, argi)) {
      use_y4m = 0;
      flipuv = 1;
    } else if (arg_match(&arg, &use_i420, argi)) {
      use_y4m = 0;
      flipuv = 0;
    } else if (arg_match(&arg, &flipuvarg, argi))
      flipuv = 1;
    else if (arg_match(&arg, &noblitarg, argi))
      noblit = 1;
    else if (arg_match(&arg, &progressarg, argi))
      progress = 1;
    else if (arg_match(&arg, &limitarg, argi))
      stop_after = arg_parse_uint(&arg);
    else if (arg_match(&arg, &skiparg, argi))
      arg_skip = arg_parse_uint(&arg);
    else if (arg_match(&arg, &postprocarg, argi))
      postproc = 1;
    else if (arg_match(&arg, &md5arg, argi))
      do_md5 = 1;
    else if (arg_match(&arg, &summaryarg, argi))
      summary = 1;
    else if (arg_match(&arg, &threadsarg, argi))
      cfg.threads = arg_parse_uint(&arg);
    else if (arg_match(&arg, &verbosearg, argi))
      quiet = 0;
    else if (arg_match(&arg, &scalearg, argi))
      do_scale = 1;
    else if (arg_match(&arg, &fb_arg, argi))
      num_external_frame_buffers = arg_parse_uint(&arg);

#if CONFIG_VP8_DECODER
    else if (arg_match(&arg, &addnoise_level, argi)) {
      postproc = 1;
      vp8_pp_cfg.post_proc_flag |= VP8_ADDNOISE;
      vp8_pp_cfg.noise_level = arg_parse_uint(&arg);
    } else if (arg_match(&arg, &demacroblock_level, argi)) {
      postproc = 1;
      vp8_pp_cfg.post_proc_flag |= VP8_DEMACROBLOCK;
      vp8_pp_cfg.deblocking_level = arg_parse_uint(&arg);
    } else if (arg_match(&arg, &deblock, argi)) {
      postproc = 1;
      vp8_pp_cfg.post_proc_flag |= VP8_DEBLOCK;
    } else if (arg_match(&arg, &mfqe, argi)) {
      postproc = 1;
      vp8_pp_cfg.post_proc_flag |= VP8_MFQE;
    } else if (arg_match(&arg, &pp_debug_info, argi)) {
      unsigned int level = arg_parse_uint(&arg);

      postproc = 1;
      vp8_pp_cfg.post_proc_flag &= ~0x7;

      if (level)
        vp8_pp_cfg.post_proc_flag |= level;
    } else if (arg_match(&arg, &pp_disp_ref_frame, argi)) {
      unsigned int flags = arg_parse_int(&arg);
      if (flags) {
        postproc = 1;
        vp8_dbg_color_ref_frame = flags;
      }
    } else if (arg_match(&arg, &pp_disp_mb_modes, argi)) {
      unsigned int flags = arg_parse_int(&arg);
      if (flags) {
        postproc = 1;
        vp8_dbg_color_mb_modes = flags;
      }
    } else if (arg_match(&arg, &pp_disp_b_modes, argi)) {
      unsigned int flags = arg_parse_int(&arg);
      if (flags) {
        postproc = 1;
        vp8_dbg_color_b_modes = flags;
      }
    } else if (arg_match(&arg, &pp_disp_mvs, argi)) {
      unsigned int flags = arg_parse_int(&arg);
      if (flags) {
        postproc = 1;
        vp8_dbg_display_mv = flags;
      }
    } else if (arg_match(&arg, &error_concealment, argi)) {
      ec_enabled = 1;
    }

#endif
    else
      argj++;
  }

  /* Check for unrecognized options */
  for (argi = argv; *argi; argi++)
    if (argi[0][0] == '-' && strlen(argi[0]) > 1)
      die("Error: Unrecognized option %s\n", *argi);

  /* Handle non-option arguments */
  fn = argv[0];

  if (!fn)
    usage_exit();

  /* Open file */
  infile = strcmp(fn, "-") ? fopen(fn, "rb") : set_binary_mode(stdin);

  if (!infile) {
    fprintf(stderr, "Failed to open file '%s'", strcmp(fn, "-") ? fn : "stdin");
    return EXIT_FAILURE;
  }
#if CONFIG_OS_SUPPORT
  /* Make sure we don't dump to the terminal, unless forced to with -o - */
  if (!outfile_pattern && isatty(fileno(stdout)) && !do_md5 && !noblit) {
    fprintf(stderr,
            "Not dumping raw video to your terminal. Use '-o -' to "
            "override.\n");
    return EXIT_FAILURE;
  }
#endif
  input.vpx_input_ctx->file = infile;
  if (file_is_ivf(input.vpx_input_ctx))
    input.vpx_input_ctx->file_type = FILE_TYPE_IVF;
#if CONFIG_WEBM_IO
  else if (file_is_webm(input.webm_ctx, input.vpx_input_ctx))
    input.vpx_input_ctx->file_type = FILE_TYPE_WEBM;
#endif
  else if (file_is_raw(input.vpx_input_ctx))
    input.vpx_input_ctx->file_type = FILE_TYPE_RAW;
  else {
    fprintf(stderr, "Unrecognized input file type.\n");
#if !CONFIG_WEBM_IO
    fprintf(stderr, "vpxdec was built without WebM container support.\n");
#endif
    return EXIT_FAILURE;
  }

  outfile_pattern = outfile_pattern ? outfile_pattern : "-";
  single_file = is_single_file(outfile_pattern);

  if (!noblit && single_file) {
    generate_filename(outfile_pattern, outfile_name, PATH_MAX,
                      vpx_input_ctx.width, vpx_input_ctx.height, 0);
    if (do_md5)
      MD5Init(&md5_ctx);
    else
      outfile = open_outfile(outfile_name);
  }

  if (use_y4m && !noblit) {
    if (!single_file) {
      fprintf(stderr, "YUV4MPEG2 not supported with output patterns,"
              " try --i420 or --yv12.\n");
      return EXIT_FAILURE;
    }

#if CONFIG_WEBM_IO
    if (vpx_input_ctx.file_type == FILE_TYPE_WEBM) {
      if (webm_guess_framerate(input.webm_ctx, input.vpx_input_ctx)) {
        fprintf(stderr, "Failed to guess framerate -- error parsing "
                "webm file?\n");
        return EXIT_FAILURE;
      }
    }
#endif
  }

  fourcc_interface = get_vpx_decoder_by_fourcc(vpx_input_ctx.fourcc);
  if (interface && fourcc_interface && interface != fourcc_interface)
    warn("Header indicates codec: %s\n", fourcc_interface->name);
  else
    interface = fourcc_interface;

  if (!interface)
    interface = get_vpx_decoder_by_index(0);

  dec_flags = (postproc ? VPX_CODEC_USE_POSTPROC : 0) |
              (ec_enabled ? VPX_CODEC_USE_ERROR_CONCEALMENT : 0);
  if (vpx_codec_dec_init(&decoder, interface->interface(), &cfg, dec_flags)) {
    fprintf(stderr, "Failed to initialize decoder: %s\n",
            vpx_codec_error(&decoder));
    return EXIT_FAILURE;
  }

  if (!quiet)
    fprintf(stderr, "%s\n", decoder.name);

#if CONFIG_VP8_DECODER

  if (vp8_pp_cfg.post_proc_flag
      && vpx_codec_control(&decoder, VP8_SET_POSTPROC, &vp8_pp_cfg)) {
    fprintf(stderr, "Failed to configure postproc: %s\n", vpx_codec_error(&decoder));
    return EXIT_FAILURE;
  }

  if (vp8_dbg_color_ref_frame
      && vpx_codec_control(&decoder, VP8_SET_DBG_COLOR_REF_FRAME, vp8_dbg_color_ref_frame)) {
    fprintf(stderr, "Failed to configure reference block visualizer: %s\n", vpx_codec_error(&decoder));
    return EXIT_FAILURE;
  }

  if (vp8_dbg_color_mb_modes
      && vpx_codec_control(&decoder, VP8_SET_DBG_COLOR_MB_MODES, vp8_dbg_color_mb_modes)) {
    fprintf(stderr, "Failed to configure macro block visualizer: %s\n", vpx_codec_error(&decoder));
    return EXIT_FAILURE;
  }

  if (vp8_dbg_color_b_modes
      && vpx_codec_control(&decoder, VP8_SET_DBG_COLOR_B_MODES, vp8_dbg_color_b_modes)) {
    fprintf(stderr, "Failed to configure block visualizer: %s\n", vpx_codec_error(&decoder));
    return EXIT_FAILURE;
  }

  if (vp8_dbg_display_mv
      && vpx_codec_control(&decoder, VP8_SET_DBG_DISPLAY_MV, vp8_dbg_display_mv)) {
    fprintf(stderr, "Failed to configure motion vector visualizer: %s\n", vpx_codec_error(&decoder));
    return EXIT_FAILURE;
  }
#endif


  if (arg_skip)
    fprintf(stderr, "Skipping first %d frames.\n", arg_skip);
  while (arg_skip) {
    if (read_frame(&input, &buf, &bytes_in_buffer, &buffer_size))
      break;
    arg_skip--;
  }

  if (num_external_frame_buffers > 0) {
    ext_fb_list.num_external_frame_buffers = num_external_frame_buffers;
    ext_fb_list.ext_fb = (struct ExternalFrameBuffer *)calloc(
        num_external_frame_buffers, sizeof(*ext_fb_list.ext_fb));
    if (vpx_codec_set_frame_buffer_functions(
            &decoder, get_vp9_frame_buffer, release_vp9_frame_buffer,
            &ext_fb_list)) {
      fprintf(stderr, "Failed to configure external frame buffers: %s\n",
              vpx_codec_error(&decoder));
      return EXIT_FAILURE;
    }
  }

  frame_avail = 1;
  got_data = 0;

  /* Decode file */
  while (frame_avail || got_data) {
    vpx_codec_iter_t  iter = NULL;
    vpx_image_t    *img;
    struct vpx_usec_timer timer;
    int                   corrupted;

    frame_avail = 0;
    if (!stop_after || frame_in < stop_after) {
      if (!read_frame(&input, &buf, &bytes_in_buffer, &buffer_size)) {
        frame_avail = 1;
        frame_in++;

        vpx_usec_timer_start(&timer);

        if (vpx_codec_decode(&decoder, buf, (unsigned int)bytes_in_buffer,
                             NULL, 0)) {
          const char *detail = vpx_codec_error_detail(&decoder);
          warn("Failed to decode frame %d: %s",
               frame_in, vpx_codec_error(&decoder));

          if (detail)
            warn("Additional information: %s", detail);
          goto fail;
        }

        vpx_usec_timer_mark(&timer);
        dx_time += vpx_usec_timer_elapsed(&timer);
      }
    }

    vpx_usec_timer_start(&timer);

    got_data = 0;
    if ((img = vpx_codec_get_frame(&decoder, &iter))) {
      ++frame_out;
      got_data = 1;
    }

    vpx_usec_timer_mark(&timer);
    dx_time += (unsigned int)vpx_usec_timer_elapsed(&timer);

    if (vpx_codec_control(&decoder, VP8D_GET_FRAME_CORRUPTED, &corrupted)) {
      warn("Failed VP8_GET_FRAME_CORRUPTED: %s", vpx_codec_error(&decoder));
      goto fail;
    }
    frames_corrupted += corrupted;

    if (progress)
      show_progress(frame_in, frame_out, dx_time);

    if (!noblit && img) {
      const int PLANES_YUV[] = {VPX_PLANE_Y, VPX_PLANE_U, VPX_PLANE_V};
      const int PLANES_YVU[] = {VPX_PLANE_Y, VPX_PLANE_V, VPX_PLANE_U};
      const int *planes = flipuv ? PLANES_YVU : PLANES_YUV;

      if (do_scale) {
        if (frame_out == 1) {
          // If the output frames are to be scaled to a fixed display size then
          // use the width and height specified in the container. If either of
          // these is set to 0, use the display size set in the first frame
          // header. If that is unavailable, use the raw decoded size of the
          // first decoded frame.
          int display_width = vpx_input_ctx.width;
          int display_height = vpx_input_ctx.height;
          if (!display_width || !display_height) {
            int display_size[2];
            if (vpx_codec_control(&decoder, VP9D_GET_DISPLAY_SIZE,
                                  display_size)) {
              // As last resort use size of first frame as display size.
              display_width = img->d_w;
              display_height = img->d_h;
            } else {
              display_width = display_size[0];
              display_height = display_size[1];
            }
          }
          scaled_img = vpx_img_alloc(NULL, VPX_IMG_FMT_I420, display_width,
                                     display_height, 16);
        }

        if (img->d_w != scaled_img->d_w || img->d_h != scaled_img->d_h) {
          vpx_image_scale(img, scaled_img, kFilterBox);
          img = scaled_img;
        }
      }

      if (single_file) {
        if (use_y4m) {
          char buf[Y4M_BUFFER_SIZE] = {0};
          size_t len = 0;
          if (frame_out == 1) {
            // Y4M file header
            len = y4m_write_file_header(buf, sizeof(buf),
                                        vpx_input_ctx.width,
                                        vpx_input_ctx.height,
                                        &vpx_input_ctx.framerate, img->fmt);
            if (do_md5) {
              MD5Update(&md5_ctx, (md5byte *)buf, (unsigned int)len);
            } else {
              fputs(buf, outfile);
            }
          }

          // Y4M frame header
          len = y4m_write_frame_header(buf, sizeof(buf));
          if (do_md5) {
            MD5Update(&md5_ctx, (md5byte *)buf, (unsigned int)len);
          } else {
            fputs(buf, outfile);
          }
        }

        if (do_md5) {
          update_image_md5(img, planes, &md5_ctx);
        } else {
          write_image_file(img, planes, outfile);
        }
      } else {
        generate_filename(outfile_pattern, outfile_name, PATH_MAX,
                          img->d_w, img->d_h, frame_in);
        if (do_md5) {
          MD5Init(&md5_ctx);
          update_image_md5(img, planes, &md5_ctx);
          MD5Final(md5_digest, &md5_ctx);
          print_md5(md5_digest, outfile_name);
        } else {
          outfile = open_outfile(outfile_name);
          write_image_file(img, planes, outfile);
          fclose(outfile);
        }
      }
    }

    if (stop_after && frame_in >= stop_after)
      break;
  }

  if (summary || progress) {
    show_progress(frame_in, frame_out, dx_time);
    fprintf(stderr, "\n");
  }

  if (frames_corrupted)
    fprintf(stderr, "WARNING: %d frames corrupted.\n", frames_corrupted);

fail:

  if (vpx_codec_destroy(&decoder)) {
    fprintf(stderr, "Failed to destroy decoder: %s\n",
            vpx_codec_error(&decoder));
    return EXIT_FAILURE;
  }

  if (!noblit && single_file) {
    if (do_md5) {
      MD5Final(md5_digest, &md5_ctx);
      print_md5(md5_digest, outfile_name);
    } else {
      fclose(outfile);
    }
  }

#if CONFIG_WEBM_IO
  if (input.vpx_input_ctx->file_type == FILE_TYPE_WEBM)
    webm_free(input.webm_ctx);
#endif

  if (input.vpx_input_ctx->file_type != FILE_TYPE_WEBM)
    free(buf);

  if (scaled_img) vpx_img_free(scaled_img);

  for (i = 0; i < ext_fb_list.num_external_frame_buffers; ++i) {
    free(ext_fb_list.ext_fb[i].data);
  }
  free(ext_fb_list.ext_fb);

  fclose(infile);
  free(argv);

  return frames_corrupted ? EXIT_FAILURE : EXIT_SUCCESS;
}
Esempio n. 8
0
int main(int argc, char **argv) {
  FILE *infile, *outfile;
  vpx_codec_ctx_t codec;
  vpx_codec_iface_t *iface;
  int flags = 0, frame_cnt = 0;
  unsigned char file_hdr[IVF_FILE_HDR_SZ];
  unsigned char frame_hdr[IVF_FRAME_HDR_SZ];
  unsigned char frame[256 * 1024];

  if (argc != 3)
    die("Usage: %s <infile> <outfile>\n", argv[0]);

  if (!(infile = fopen(argv[1], "rb")))
    die("Failed to open %s for reading", argv[1]);

  if (!(outfile = fopen(argv[2], "wb")))
    die("Failed to open %s for writing", argv[2]);

  if (!(fread(file_hdr, 1, IVF_FILE_HDR_SZ, infile) == IVF_FILE_HDR_SZ &&
     file_hdr[0] == 'D' && file_hdr[1] == 'K' &&
     file_hdr[2] == 'I' && file_hdr[3] == 'F'))
    die("%s is not an IVF file.", argv[1]);

  iface = get_codec_interface(mem_get_le32(file_hdr + 8));
  if (!iface)
    die("Unknown FOURCC code.");


  printf("Using %s\n", vpx_codec_iface_name(iface));

  if (vpx_codec_dec_init(&codec, iface, NULL, flags))
    die_codec(&codec, "Failed to initialize decoder");

  while (fread(frame_hdr, 1, IVF_FRAME_HDR_SZ, infile) == IVF_FRAME_HDR_SZ) {
    const int frame_size = mem_get_le32(frame_hdr);
    vpx_codec_iter_t iter = NULL;
    vpx_image_t *img;

    if (frame_size > sizeof(frame))
      die("Frame %d data too big for example code buffer", frame_size);

    if (fread(frame, 1, frame_size, infile) != frame_size)
      die("Failed to read complete frame");

    if (vpx_codec_decode(&codec, frame, frame_size, NULL, 0))
      die_codec(&codec, "Failed to decode frame");

    while ((img = vpx_codec_get_frame(&codec, &iter)) != NULL) {
      unsigned char digest[16];

      get_image_md5(img, digest);
      print_md5(outfile, digest);
      fprintf(outfile, "  img-%dx%d-%04d.i420\n",
              img->d_w, img->d_h, ++frame_cnt);
    }
  }

  printf("Processed %d frames.\n", frame_cnt);
  if (vpx_codec_destroy(&codec))
    die_codec(&codec, "Failed to destroy codec");

  fclose(outfile);
  fclose(infile);
  return EXIT_SUCCESS;
}
Esempio n. 9
0
static int main_loop(int argc, const char **argv_) {
  aom_codec_ctx_t decoder;
  char *fn = NULL;
  int i;
  int ret = EXIT_FAILURE;
  uint8_t *buf = NULL;
  size_t bytes_in_buffer = 0, buffer_size = 0;
  FILE *infile;
  int frame_in = 0, frame_out = 0, flipuv = 0, noblit = 0;
  int do_md5 = 0, progress = 0, frame_parallel = 0;
  int stop_after = 0, postproc = 0, summary = 0, quiet = 1;
  int arg_skip = 0;
  int ec_enabled = 0;
  int keep_going = 0;
  const AvxInterface *interface = NULL;
  const AvxInterface *fourcc_interface = NULL;
  uint64_t dx_time = 0;
  struct arg arg;
  char **argv, **argi, **argj;

  int single_file;
  int use_y4m = 1;
  int opt_yv12 = 0;
  int opt_i420 = 0;
  aom_codec_dec_cfg_t cfg = { 0, 0, 0 };
#if CONFIG_AOM_HIGHBITDEPTH
  unsigned int output_bit_depth = 0;
#endif
#if CONFIG_EXT_TILE
  int tile_row = -1;
  int tile_col = -1;
#endif  // CONFIG_EXT_TILE
  int frames_corrupted = 0;
  int dec_flags = 0;
  int do_scale = 0;
  aom_image_t *scaled_img = NULL;
#if CONFIG_AOM_HIGHBITDEPTH
  aom_image_t *img_shifted = NULL;
#endif
  int frame_avail, got_data, flush_decoder = 0;
  int num_external_frame_buffers = 0;
  struct ExternalFrameBufferList ext_fb_list = { 0, NULL };

  const char *outfile_pattern = NULL;
  char outfile_name[PATH_MAX] = { 0 };
  FILE *outfile = NULL;

  FILE *framestats_file = NULL;

  MD5Context md5_ctx;
  unsigned char md5_digest[16];

  struct AvxDecInputContext input = { NULL, NULL };
  struct AvxInputContext aom_input_ctx;
#if CONFIG_WEBM_IO
  struct WebmInputContext webm_ctx;
  memset(&(webm_ctx), 0, sizeof(webm_ctx));
  input.webm_ctx = &webm_ctx;
#endif
  input.aom_input_ctx = &aom_input_ctx;

  /* Parse command line */
  exec_name = argv_[0];
  argv = argv_dup(argc - 1, argv_ + 1);

  for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) {
    memset(&arg, 0, sizeof(arg));
    arg.argv_step = 1;

    if (arg_match(&arg, &codecarg, argi)) {
      interface = get_aom_decoder_by_name(arg.val);
      if (!interface)
        die("Error: Unrecognized argument (%s) to --codec\n", arg.val);
    } else if (arg_match(&arg, &looparg, argi)) {
      // no-op
    } else if (arg_match(&arg, &outputfile, argi)) {
      outfile_pattern = arg.val;
    } else if (arg_match(&arg, &use_yv12, argi)) {
      use_y4m = 0;
      flipuv = 1;
      opt_yv12 = 1;
    } else if (arg_match(&arg, &use_i420, argi)) {
      use_y4m = 0;
      flipuv = 0;
      opt_i420 = 1;
    } else if (arg_match(&arg, &rawvideo, argi)) {
      use_y4m = 0;
    } else if (arg_match(&arg, &flipuvarg, argi)) {
      flipuv = 1;
    } else if (arg_match(&arg, &noblitarg, argi)) {
      noblit = 1;
    } else if (arg_match(&arg, &progressarg, argi)) {
      progress = 1;
    } else if (arg_match(&arg, &limitarg, argi)) {
      stop_after = arg_parse_uint(&arg);
    } else if (arg_match(&arg, &skiparg, argi)) {
      arg_skip = arg_parse_uint(&arg);
    } else if (arg_match(&arg, &postprocarg, argi)) {
      postproc = 1;
    } else if (arg_match(&arg, &md5arg, argi)) {
      do_md5 = 1;
    } else if (arg_match(&arg, &framestatsarg, argi)) {
      framestats_file = fopen(arg.val, "w");
      if (!framestats_file) {
        die("Error: Could not open --framestats file (%s) for writing.\n",
            arg.val);
      }
    } else if (arg_match(&arg, &summaryarg, argi)) {
      summary = 1;
    } else if (arg_match(&arg, &threadsarg, argi)) {
      cfg.threads = arg_parse_uint(&arg);
    }
#if CONFIG_AV1_DECODER
    else if (arg_match(&arg, &frameparallelarg, argi))
      frame_parallel = 1;
#endif
    else if (arg_match(&arg, &verbosearg, argi))
      quiet = 0;
    else if (arg_match(&arg, &scalearg, argi))
      do_scale = 1;
    else if (arg_match(&arg, &fb_arg, argi))
      num_external_frame_buffers = arg_parse_uint(&arg);
    else if (arg_match(&arg, &continuearg, argi))
      keep_going = 1;
#if CONFIG_AOM_HIGHBITDEPTH
    else if (arg_match(&arg, &outbitdeptharg, argi)) {
      output_bit_depth = arg_parse_uint(&arg);
    }
#endif
#if CONFIG_EXT_TILE
    else if (arg_match(&arg, &tiler, argi))
      tile_row = arg_parse_int(&arg);
    else if (arg_match(&arg, &tilec, argi))
      tile_col = arg_parse_int(&arg);
#endif  // CONFIG_EXT_TILE
    else
      argj++;
  }

  /* Check for unrecognized options */
  for (argi = argv; *argi; argi++)
    if (argi[0][0] == '-' && strlen(argi[0]) > 1)
      die("Error: Unrecognized option %s\n", *argi);

  /* Handle non-option arguments */
  fn = argv[0];

  if (!fn) {
    free(argv);
    usage_exit();
  }
  /* Open file */
  infile = strcmp(fn, "-") ? fopen(fn, "rb") : set_binary_mode(stdin);

  if (!infile) {
    fatal("Failed to open input file '%s'", strcmp(fn, "-") ? fn : "stdin");
  }
#if CONFIG_OS_SUPPORT
  /* Make sure we don't dump to the terminal, unless forced to with -o - */
  if (!outfile_pattern && isatty(STDOUT_FILENO) && !do_md5 && !noblit) {
    fprintf(stderr,
            "Not dumping raw video to your terminal. Use '-o -' to "
            "override.\n");
    return EXIT_FAILURE;
  }
#endif
  input.aom_input_ctx->file = infile;
  if (file_is_ivf(input.aom_input_ctx))
    input.aom_input_ctx->file_type = FILE_TYPE_IVF;
#if CONFIG_WEBM_IO
  else if (file_is_webm(input.webm_ctx, input.aom_input_ctx))
    input.aom_input_ctx->file_type = FILE_TYPE_WEBM;
#endif
  else if (file_is_raw(input.aom_input_ctx))
    input.aom_input_ctx->file_type = FILE_TYPE_RAW;
  else {
    fprintf(stderr, "Unrecognized input file type.\n");
#if !CONFIG_WEBM_IO
    fprintf(stderr, "aomdec was built without WebM container support.\n");
#endif
    return EXIT_FAILURE;
  }

  outfile_pattern = outfile_pattern ? outfile_pattern : "-";
  single_file = is_single_file(outfile_pattern);

  if (!noblit && single_file) {
    generate_filename(outfile_pattern, outfile_name, PATH_MAX,
                      aom_input_ctx.width, aom_input_ctx.height, 0);
    if (do_md5)
      MD5Init(&md5_ctx);
    else
      outfile = open_outfile(outfile_name);
  }

  if (use_y4m && !noblit) {
    if (!single_file) {
      fprintf(stderr,
              "YUV4MPEG2 not supported with output patterns,"
              " try --i420 or --yv12 or --rawvideo.\n");
      return EXIT_FAILURE;
    }

#if CONFIG_WEBM_IO
    if (aom_input_ctx.file_type == FILE_TYPE_WEBM) {
      if (webm_guess_framerate(input.webm_ctx, input.aom_input_ctx)) {
        fprintf(stderr,
                "Failed to guess framerate -- error parsing "
                "webm file?\n");
        return EXIT_FAILURE;
      }
    }
#endif
  }

  fourcc_interface = get_aom_decoder_by_fourcc(aom_input_ctx.fourcc);
  if (interface && fourcc_interface && interface != fourcc_interface)
    warn("Header indicates codec: %s\n", fourcc_interface->name);
  else
    interface = fourcc_interface;

  if (!interface) interface = get_aom_decoder_by_index(0);

  dec_flags = (postproc ? AOM_CODEC_USE_POSTPROC : 0) |
              (ec_enabled ? AOM_CODEC_USE_ERROR_CONCEALMENT : 0) |
              (frame_parallel ? AOM_CODEC_USE_FRAME_THREADING : 0);
  if (aom_codec_dec_init(&decoder, interface->codec_interface(), &cfg,
                         dec_flags)) {
    fprintf(stderr, "Failed to initialize decoder: %s\n",
            aom_codec_error(&decoder));
    goto fail2;
  }

  if (!quiet) fprintf(stderr, "%s\n", decoder.name);

#if CONFIG_AV1_DECODER && CONFIG_EXT_TILE
  if (aom_codec_control(&decoder, AV1_SET_DECODE_TILE_ROW, tile_row)) {
    fprintf(stderr, "Failed to set decode_tile_row: %s\n",
            aom_codec_error(&decoder));
    goto fail;
  }

  if (aom_codec_control(&decoder, AV1_SET_DECODE_TILE_COL, tile_col)) {
    fprintf(stderr, "Failed to set decode_tile_col: %s\n",
            aom_codec_error(&decoder));
    goto fail;
  }
#endif

  if (arg_skip) fprintf(stderr, "Skipping first %d frames.\n", arg_skip);
  while (arg_skip) {
    if (read_frame(&input, &buf, &bytes_in_buffer, &buffer_size)) break;
    arg_skip--;
  }

  if (num_external_frame_buffers > 0) {
    ext_fb_list.num_external_frame_buffers = num_external_frame_buffers;
    ext_fb_list.ext_fb = (struct ExternalFrameBuffer *)calloc(
        num_external_frame_buffers, sizeof(*ext_fb_list.ext_fb));
    if (aom_codec_set_frame_buffer_functions(&decoder, get_av1_frame_buffer,
                                             release_av1_frame_buffer,
                                             &ext_fb_list)) {
      fprintf(stderr, "Failed to configure external frame buffers: %s\n",
              aom_codec_error(&decoder));
      goto fail;
    }
  }

  frame_avail = 1;
  got_data = 0;

  if (framestats_file) fprintf(framestats_file, "bytes,qp\r\n");

  /* Decode file */
  while (frame_avail || got_data) {
    aom_codec_iter_t iter = NULL;
    aom_image_t *img;
    struct aom_usec_timer timer;
    int corrupted = 0;

    frame_avail = 0;
    if (!stop_after || frame_in < stop_after) {
      if (!read_frame(&input, &buf, &bytes_in_buffer, &buffer_size)) {
        frame_avail = 1;
        frame_in++;

        aom_usec_timer_start(&timer);

        if (aom_codec_decode(&decoder, buf, (unsigned int)bytes_in_buffer, NULL,
                             0)) {
          const char *detail = aom_codec_error_detail(&decoder);
          warn("Failed to decode frame %d: %s", frame_in,
               aom_codec_error(&decoder));

          if (detail) warn("Additional information: %s", detail);
          if (!keep_going) goto fail;
        }

        if (framestats_file) {
          int qp;
          if (aom_codec_control(&decoder, AOMD_GET_LAST_QUANTIZER, &qp)) {
            warn("Failed AOMD_GET_LAST_QUANTIZER: %s",
                 aom_codec_error(&decoder));
            if (!keep_going) goto fail;
          }
          fprintf(framestats_file, "%d,%d\r\n", (int)bytes_in_buffer, qp);
        }

        aom_usec_timer_mark(&timer);
        dx_time += aom_usec_timer_elapsed(&timer);
      } else {
        flush_decoder = 1;
      }
    } else {
      flush_decoder = 1;
    }

    aom_usec_timer_start(&timer);

    if (flush_decoder) {
      // Flush the decoder in frame parallel decode.
      if (aom_codec_decode(&decoder, NULL, 0, NULL, 0)) {
        warn("Failed to flush decoder: %s", aom_codec_error(&decoder));
      }
    }

    got_data = 0;
    if ((img = aom_codec_get_frame(&decoder, &iter))) {
      ++frame_out;
      got_data = 1;
    }

    aom_usec_timer_mark(&timer);
    dx_time += (unsigned int)aom_usec_timer_elapsed(&timer);

    if (!frame_parallel &&
        aom_codec_control(&decoder, AOMD_GET_FRAME_CORRUPTED, &corrupted)) {
      warn("Failed AOM_GET_FRAME_CORRUPTED: %s", aom_codec_error(&decoder));
      if (!keep_going) goto fail;
    }
    frames_corrupted += corrupted;

    if (progress) show_progress(frame_in, frame_out, dx_time);

    if (!noblit && img) {
      const int PLANES_YUV[] = { AOM_PLANE_Y, AOM_PLANE_U, AOM_PLANE_V };
      const int PLANES_YVU[] = { AOM_PLANE_Y, AOM_PLANE_V, AOM_PLANE_U };
      const int *planes = flipuv ? PLANES_YVU : PLANES_YUV;

      if (do_scale) {
        if (frame_out == 1) {
          // If the output frames are to be scaled to a fixed display size then
          // use the width and height specified in the container. If either of
          // these is set to 0, use the display size set in the first frame
          // header. If that is unavailable, use the raw decoded size of the
          // first decoded frame.
          int render_width = aom_input_ctx.width;
          int render_height = aom_input_ctx.height;
          if (!render_width || !render_height) {
            int render_size[2];
            if (aom_codec_control(&decoder, AV1D_GET_DISPLAY_SIZE,
                                  render_size)) {
              // As last resort use size of first frame as display size.
              render_width = img->d_w;
              render_height = img->d_h;
            } else {
              render_width = render_size[0];
              render_height = render_size[1];
            }
          }
          scaled_img =
              aom_img_alloc(NULL, img->fmt, render_width, render_height, 16);
          scaled_img->bit_depth = img->bit_depth;
        }

        if (img->d_w != scaled_img->d_w || img->d_h != scaled_img->d_h) {
#if CONFIG_LIBYUV
          libyuv_scale(img, scaled_img, kFilterBox);
          img = scaled_img;
#else
          fprintf(stderr,
                  "Failed  to scale output frame: %s.\n"
                  "Scaling is disabled in this configuration. "
                  "To enable scaling, configure with --enable-libyuv\n",
                  aom_codec_error(&decoder));
          goto fail;
#endif
        }
      }
#if CONFIG_AOM_HIGHBITDEPTH
      // Default to codec bit depth if output bit depth not set
      if (!output_bit_depth && single_file && !do_md5) {
        output_bit_depth = img->bit_depth;
      }
      // Shift up or down if necessary
      if (output_bit_depth != 0 && output_bit_depth != img->bit_depth) {
        const aom_img_fmt_t shifted_fmt =
            output_bit_depth == 8
                ? img->fmt ^ (img->fmt & AOM_IMG_FMT_HIGHBITDEPTH)
                : img->fmt | AOM_IMG_FMT_HIGHBITDEPTH;
        if (img_shifted &&
            img_shifted_realloc_required(img, img_shifted, shifted_fmt)) {
          aom_img_free(img_shifted);
          img_shifted = NULL;
        }
        if (!img_shifted) {
          img_shifted =
              aom_img_alloc(NULL, shifted_fmt, img->d_w, img->d_h, 16);
          img_shifted->bit_depth = output_bit_depth;
        }
        if (output_bit_depth > img->bit_depth) {
          aom_img_upshift(img_shifted, img, output_bit_depth - img->bit_depth);
        } else {
          aom_img_downshift(img_shifted, img,
                            img->bit_depth - output_bit_depth);
        }
        img = img_shifted;
      }
#endif

#if CONFIG_EXT_TILE
      aom_input_ctx.width = img->d_w;
      aom_input_ctx.height = img->d_h;
#endif  // CONFIG_EXT_TILE

      if (single_file) {
        if (use_y4m) {
          char y4m_buf[Y4M_BUFFER_SIZE] = { 0 };
          size_t len = 0;
          if (img->fmt == AOM_IMG_FMT_I440 || img->fmt == AOM_IMG_FMT_I44016) {
            fprintf(stderr, "Cannot produce y4m output for 440 sampling.\n");
            goto fail;
          }
          if (frame_out == 1) {
            // Y4M file header
            len = y4m_write_file_header(
                y4m_buf, sizeof(y4m_buf), aom_input_ctx.width,
                aom_input_ctx.height, &aom_input_ctx.framerate, img->fmt,
                img->bit_depth);
            if (do_md5) {
              MD5Update(&md5_ctx, (md5byte *)y4m_buf, (unsigned int)len);
            } else {
              fputs(y4m_buf, outfile);
            }
          }

          // Y4M frame header
          len = y4m_write_frame_header(y4m_buf, sizeof(y4m_buf));
          if (do_md5) {
            MD5Update(&md5_ctx, (md5byte *)y4m_buf, (unsigned int)len);
          } else {
            fputs(y4m_buf, outfile);
          }
        } else {
          if (frame_out == 1) {
            // Check if --yv12 or --i420 options are consistent with the
            // bit-stream decoded
            if (opt_i420) {
              if (img->fmt != AOM_IMG_FMT_I420 &&
                  img->fmt != AOM_IMG_FMT_I42016) {
                fprintf(stderr, "Cannot produce i420 output for bit-stream.\n");
                goto fail;
              }
            }
            if (opt_yv12) {
              if ((img->fmt != AOM_IMG_FMT_I420 &&
                   img->fmt != AOM_IMG_FMT_YV12) ||
                  img->bit_depth != 8) {
                fprintf(stderr, "Cannot produce yv12 output for bit-stream.\n");
                goto fail;
              }
            }
          }
        }

        if (do_md5) {
          update_image_md5(img, planes, &md5_ctx);
        } else {
          write_image_file(img, planes, outfile);
        }
      } else {
        generate_filename(outfile_pattern, outfile_name, PATH_MAX, img->d_w,
                          img->d_h, frame_in);
        if (do_md5) {
          MD5Init(&md5_ctx);
          update_image_md5(img, planes, &md5_ctx);
          MD5Final(md5_digest, &md5_ctx);
          print_md5(md5_digest, outfile_name);
        } else {
          outfile = open_outfile(outfile_name);
          write_image_file(img, planes, outfile);
          fclose(outfile);
        }
      }
    }
  }

  if (summary || progress) {
    show_progress(frame_in, frame_out, dx_time);
    fprintf(stderr, "\n");
  }

  if (frames_corrupted) {
    fprintf(stderr, "WARNING: %d frames corrupted.\n", frames_corrupted);
  } else {
    ret = EXIT_SUCCESS;
  }

fail:

  if (aom_codec_destroy(&decoder)) {
    fprintf(stderr, "Failed to destroy decoder: %s\n",
            aom_codec_error(&decoder));
  }

fail2:

  if (!noblit && single_file) {
    if (do_md5) {
      MD5Final(md5_digest, &md5_ctx);
      print_md5(md5_digest, outfile_name);
    } else {
      fclose(outfile);
    }
  }

#if CONFIG_WEBM_IO
  if (input.aom_input_ctx->file_type == FILE_TYPE_WEBM)
    webm_free(input.webm_ctx);
#endif

  if (input.aom_input_ctx->file_type != FILE_TYPE_WEBM) free(buf);

  if (scaled_img) aom_img_free(scaled_img);
#if CONFIG_AOM_HIGHBITDEPTH
  if (img_shifted) aom_img_free(img_shifted);
#endif

  for (i = 0; i < ext_fb_list.num_external_frame_buffers; ++i) {
    free(ext_fb_list.ext_fb[i].data);
  }
  free(ext_fb_list.ext_fb);

  fclose(infile);
  if (framestats_file) fclose(framestats_file);

  free(argv);

  return ret;
}
Esempio n. 10
0
File: aaa.c Progetto: aunoor/xl2tpd
int decrypt_avp (char *buf, struct tunnel *t)
{
    /* Decrypts a hidden AVP pointed to by buf.  The
       new header will be expected to be two characters
       offset from the old */
    int cnt = 0;
    int len, olen, flags;
    unsigned char digest[MD_SIG_SIZE];
    char *ptr, *end;
    _u16 attr;
    struct avp_hdr *old_hdr = (struct avp_hdr *) buf;
    struct avp_hdr *new_hdr = (struct avp_hdr *) (buf + 2);
    int saved_segment_len;      /* maybe less 16; may be used if the cipher is longer than 16 octets */
    unsigned char saved_segment[MD_SIG_SIZE];
    ptr = ((char *) old_hdr) + sizeof (struct avp_hdr);
    olen = old_hdr->length & 0x0FFF;
    end = buf + olen;
    if (!t->chal_us.vector)
    {
        l2tp_log (LOG_DEBUG,
             "%s: Hidden bit set, but no random vector specified!\n", __FUNCTION__);
        return -EINVAL;
    }
    /* First, let's decrypt all the data.  We're not guaranteed
       that it will be padded to a 16 byte boundary, so we
       have to be more careful than when encrypting */
    attr = ntohs (old_hdr->attr);
    MD5Init (&t->chal_us.md5);
    MD5Update (&t->chal_us.md5, (void *) &attr, 2);
    MD5Update (&t->chal_us.md5, t->chal_us.secret,
               strlen ((char *)t->chal_us.secret));
    MD5Update (&t->chal_us.md5, t->chal_us.vector, t->chal_us.vector_len);
    MD5Final (digest, &t->chal_us.md5);
#ifdef DEBUG_HIDDEN
    l2tp_log (LOG_DEBUG, "attribute is %d and challenge is: ", attr);
    print_challenge (&t->chal_us);
    l2tp_log (LOG_DEBUG, "md5 is: ");
    print_md5 (digest);
#endif
    while (ptr < end)
    {
        if (cnt >= MD_SIG_SIZE)
        {
            MD5Init (&t->chal_us.md5);
            MD5Update (&t->chal_us.md5, t->chal_us.secret,
                       strlen ((char *)t->chal_us.secret));
            MD5Update (&t->chal_us.md5, saved_segment, MD_SIG_SIZE);
            MD5Final (digest, &t->chal_us.md5);
            cnt = 0;
        }
        /* at the beginning of each segment, we save the current segment (16 octets or less) of cipher 
         * so that the next round of MD5 (if there is a next round) hash could use it 
         */
        if (cnt == 0)
        {
            saved_segment_len =
                (end - ptr < MD_SIG_SIZE) ? (end - ptr) : MD_SIG_SIZE;
            memcpy (saved_segment, ptr, saved_segment_len);
        }
        *ptr = *ptr ^ digest[cnt++];
        ptr++;
    }
    /* Hopefully we're all nice and decrypted now.  Let's rewrite the header. 
       First save the old flags, and get the new stuff */
    flags = old_hdr->length & 0xF000 & ~HBIT;
    len = ntohs (new_hdr->attr) + sizeof (struct avp_hdr);
    if (len > olen - 2)
    {
        l2tp_log (LOG_DEBUG,
             "%s: Decrypted length is too long (%d > %d)\n", __FUNCTION__, len,
             olen - 2);
        return -EINVAL;
    }
    new_hdr->attr = old_hdr->attr;
    new_hdr->vendorid = old_hdr->vendorid;
    new_hdr->length = len | flags;
    return 0;
}
Esempio n. 11
0
File: aaa.c Progetto: aunoor/xl2tpd
static inline void print_challenge (struct challenge *chal)
{
    l2tp_log (LOG_DEBUG, "vector: ");
    print_md5 (chal->vector);
    l2tp_log (LOG_DEBUG, "secret: %s\n", chal->secret);
}
Esempio n. 12
0
int main(int argc, char const *argv[])
{
    struct addrinfo hints, *servinfo, *p;
    struct sockaddr_in address;
    int sock = 0, valread, rv;
    struct sockaddr_in serv_addr;
    char buffer[BUFFSIZE] = {0};
	const char *filename;
    int PORT = 8088;
    const char* server_ip;
    char received_md5[MD5_DIGEST_LENGTH];
	char calculated_md5[MD5_DIGEST_LENGTH];
    char ack[]="ACK!";
	char nack[] = "NACK";
    
    if(argc < 4){
      printf("Error need exactly 3 arguments. Arg1: Server-IP Arg2: Port# Arg3: File Name\n");
        exit(0);
    }else{
        server_ip = argv[1];
        PORT = atoi(argv[2]);
        filename =  argv[3];
    }

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE; 

    //argv[2] is the port# arg
    if ((rv = getaddrinfo(server_ip, argv[2], &hints, &servinfo)) != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
        return 1;
    }

    //connect to the first result from our getaddrinfo lookup on the specified ip
    for(p = servinfo; p != NULL; p = p->ai_next) {
        if ((sock = socket(p->ai_family, p->ai_socktype,
                p->ai_protocol)) == -1) {
            perror("client: socket");
            continue;
        }

        break;
    }

    memset(&serv_addr, '0', sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(PORT);
      
    // Convert IPv4 and IPv6 addresses from text to binary form
    if(inet_pton(AF_INET, server_ip, &serv_addr.sin_addr)<=0) 
    {
        printf("\nInvalid address/Address not supported \n");
        return -1;
    }

    if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
    {
        printf("\nConnection Failed \n");
        return -1;
    }
    printf("Connection request sent\n");
	
  	// receive connection message
  	valread = recv( sock , buffer, BUFFSIZE,0);
    printf("%s\n",buffer);
  	memset(&buffer,'\0',BUFFSIZE);
  
  	//send the filename to the server
	send(sock , filename , strlen(filename) , 0 );
	printf("Filename request sent\n");
    
  	// Receive ACK or NACK message
	valread = recv(sock,buffer,5,0);
	printf("%s\n",buffer);
  	if(buffer[0] == 'N')
	{
		printf("Error file does not exist in server.\n");
		exit(1);
	}
  
	//Receive the checksum
    memset(&buffer,'\0',BUFFSIZE);
    valread = recv(sock,buffer,BUFFSIZE,0);
    memcpy(received_md5,buffer,MD5_DIGEST_LENGTH);

  
  	//RECEIVE SIZE INFO
    //next message should be file size
    int read_code = recv(sock, buffer, MSGSIZE,0);
    printf("%s\n",buffer);
    int size = atoi(buffer);
    printf("Received size of file: %d bytes\n", size);
  	int bytes_received = 0;
  	FILE *jpeg;
  	char* out_file;
    int fail_count = 0;
    int write_fail_count = 0;
    int packets_received = 0;
    
  	jpeg = fopen("out_file.jpg","wb");
  	
  	while(bytes_received < size){
        
        memset(&buffer,'\0',BUFFSIZE);
        // valread = recv(sock,work_buffer+wb_offset,BUFFSIZE,0);
        valread = recv(sock,buffer,BUFFSIZE,0);
      	if(valread < 0){ //an error has occured
            printf("Error recieving packet\n");
            fail_count++;
            break;
        }else if(valread == 0){ //the connection has been closed
            printf("Server has closed the connection\n");
            break;

        }else{
            packets_received++;
            int write_error = fwrite(buffer,sizeof(char),valread, jpeg);
            if(write_error <= 0){
                write_fail_count++;
            }
            bytes_received += valread;	
            printf("bytes received: %d / %d (%d received %d dropped)\n",bytes_received,size,packets_received, fail_count);
            // printf("%s\n",buffer);
        }
    }
    fclose(jpeg);
  
    //check the received md5 with the calculated one
    jpeg = fopen("out_file.jpg","rb");
    generate_md5(jpeg, calculated_md5);
    printf("Calculated MD5:\n");
    print_md5(calculated_md5);
    printf("Received MD5:\n");
    print_md5(received_md5);

    if(strncmp(calculated_md5, received_md5, MD5_DIGEST_LENGTH) == 0){
        //send match
        send(sock,ack,strlen(ack),0);
        printf("Checksums match\n");
    }else{
        //send mismatch
        send(sock,nack,strlen(nack),0);
        printf("Checksum mismatch\n");
    }
    printf("Write fails: %d\n", write_fail_count);
    printf("File received\n");
  	fclose(jpeg);
    shutdown(sock,2);
    return 0;
}
Esempio n. 13
0
/**
 * Starts the harness.
 *
 * \param argc Num of args
 * \param argv The args
 * \returns 0 on success, -1 on error
 */
int main(int argc, char *argv[])
{
  SHORT_PROCESS_NAME = basename_safe(argv[0]);
  PROCESS_NAME = argv[0];

  // We accept only one argument, namely the transport address of the
  // global configuration server
  if (argc != 2)
  {
    print_usage();
    return -1;
  }

  if (config_init(argv[1]) != 0)
  {
    error_log("Unable to setup test harness. Is there a problem with the endpoint syntax? %s", argv[1]);
    return -1;
  }

  int ret = 0;

  ret = logger_config_init();

  if (ret != 0)
  {
    error_log("Failed to create log transport");
    cleanup(NULL);
    return -1;
  }

  char *test_harness_listen_endpoint = g_strdup_printf("%s-%d", TEST_SOCKET, getpid());

  debug_log("Test harness is listening on %s", test_harness_listen_endpoint);
  transport_t transport = transport_init(TRANSPORT_TYPE_PUSHPULL, test_harness_listen_endpoint);

  if (transport == NULL)
  {
    error_log("Unable to create transport");
    g_free(test_harness_listen_endpoint);
    cleanup(NULL);
    return -1;
  }

  if (spawn_subcontractor(argv[1], test_harness_listen_endpoint) != 0)
  {
    error_log("Unable to spawn subcontractor");
    g_free(test_harness_listen_endpoint);
    cleanup(transport);
    return -1;
  }
  g_free(test_harness_listen_endpoint);
  test_harness_listen_endpoint = NULL;

  char *input_file;

  if ((config_get(NULL, CONFIG_INPUT_FILE_OPTION_NAME, &input_file) != 0) || (input_file == NULL))
  {
    error_log("Could not get input file name");
    cleanup(transport);
    return -1;
  }

  char *subcontractor;

  if ((config_get(NULL, CONFIG_TEST_HARNESS_SUBCONTRACTOR_TO_TEST_OPTION_NAME, &subcontractor) != 0) || (subcontractor == NULL))
  {
    error_log("Unable to get the name of the subcontractor which means I couldn't calculate the timeout!");
    return -1;
  }

  const char *sub_name = basename_safe(subcontractor);

  long timeout = CONFIG_CONTRACTOR_SUBCONTRACTOR_TRANSPORT_TIMEOUT_DEFAULT;

  if (config_get_long_group_or_general_with_default_macro(sub_name, CONFIG_CONTRACTOR_SUBCONTRACTOR_TRANSPORT_TIMEOUT, &timeout) != 0)
  {
    info_log("Couldn't find out what timeout option to use, using default");
  }

  transport_set_recv_timeout(transport, timeout);
  debug_log("Using %li for timeout to subcontractor", timeout);

  unsigned int contract_string_size;
  contract_t c = contract_init(NULL, 0);

  contract_set_path(c, input_file);
  contract_set_contiguous(c, 1);
  contract_set_absolute_offset(c, 0);
  char *contract_string = contract_serialise(c, &contract_string_size);

  contract_close(c);
  g_free(input_file);
  if (contract_string == NULL)
  {
    perror("Failed to create contract_string");
    g_free(contract_string);
    g_free(subcontractor);
    cleanup(transport);
    return -1;
  }

  info_log("Sending message");

  unsigned int subcontractor_result_msg_size;
  const char *subcontractor_result_msg = transport_sendrecv(transport, contract_string, contract_string_size, &child_pid, &subcontractor_result_msg_size);

  if (subcontractor_result_msg == NULL)
  {

    if (errno == EAGAIN)
    {
      // Timeout.
      error_log
        ("Timeout in receiving message from subcontractor! Either your subcontractor hung (it will be killed when running in pronghorn) or it didn't compelete in time. You need to make sure that the timeout is long enough, by setting subcontractor_timeout (specifcally for your sub contractor or the general case). In pronghorn, this would be via the config file. Using the test harness, you can specificy this using \"-o %s.subcontractor_timeout=<timeout in milliseconds>\" or \"-o general.subcontractor_timeout=<timeout in milliseconds>\" at the end of the command line",
         sub_name);

    } else if (errno == EINTR)
    {
      // Interupted.
      error_log("Something when wrong waiting for your subcontractor to return. Did it crash?! You might like to try adding \"-o %s.valgrind_opts=<path to valgrind>\" when testing.", sub_name);
    }

    cleanup(transport);
    g_free(contract_string);
    g_free(subcontractor);
    return -1;
  }

  g_free(subcontractor);

  contract_completion_report_t report = contract_completion_report_init(subcontractor_result_msg, subcontractor_result_msg_size);

  if (report == NULL)
  {
    perror("Recreating contract_completion_report");
    g_free(contract_string);
    cleanup(transport);
    return -1;
  } else
  {
    info_log("Reconstructed message");
  }

  info_log("=====================");
  info_log("Results: ");
  unsigned int results_count;
  const result_t *results = contract_completion_report_get_results(report, &results_count);

  c = contract_completion_report_get_original_contract(report);;

  for (int i = 0; i < results_count; i++)
  {
    const result_t r = results[i];

    info_log("Path=%s. Type=(%s) %s. Confidence=%d", contract_get_path(c), result_get_brief_data_description(r), result_get_data_description(r), result_get_confidence(r));

#if PRINT_BLOCK_ARRAY
    unsigned int block_range_size;
    const block_range_t *ranges = result_get_block_ranges(r, &block_range_size);

    if (block_range_size > 0)
    {
      int j;

      info_log("Blocks:");

      // This is inefficient. But it works and this function is rarely used
      char *big_s = g_strdup("");

      for (j = 0; j < block_range_size; j++)
      {
        unsigned long long pos;
        unsigned long long len;

        block_range_get_range(ranges[j], &pos, &len);
        char *new_s = g_strdup_printf("%s %llu-%llu", big_s, pos, pos + len - 1);

        g_free(big_s);
        big_s = new_s;
      }
      info_log("%s", big_s);
      g_free(big_s);
    }
#endif // PRINT_BLOCK_ARRAY

    unsigned int new_contracts_count;

#if SIMPLE_CONTRACT_ENUMERATION
    result_get_new_contracts(r, &new_contracts_count);

    info_log("\t- With %d new contracts!", new_contracts_count);
#else // SIMPLE_CONTRACT_ENUMERATION
    // Yes, this looks dodgy, but it's fine until r gets destroyed (which is after we destroy our copy)
    const contract_t *new_contracts_const = result_get_new_contracts(r, &new_contracts_count);
    contract_t *new_contracts = (contract_t *) g_malloc(sizeof(contract_t) * new_contracts_count);

    memcpy(new_contracts, new_contracts_const, sizeof(contract_t) * new_contracts_count);

    if (new_contracts_count > 0)
    {
      // Sorting the array
#if SORT_CONTRACT_ARRAY
      {
        int j;

        for (j = 0; j < new_contracts_count - 1; j++)
        {
          int k;

          for (k = 0; k < new_contracts_count - j - 1; k++)
          {
            int a = atoi(contract_get_path(new_contracts[k]));
            int b = atoi(contract_get_path(new_contracts[k + 1]));

            if (a > b)
            {
              contract_t temp = new_contracts[k];

              new_contracts[k] = new_contracts[k + 1];
              new_contracts[k + 1] = temp;
            } else if (a == b)
            {
              warning_log("Duplicate entry found! %s", contract_get_path(new_contracts[k]));
            }
          }
        }
      }
#endif // SORT_CONTRACT_ARRAY
#if PRINT_CONTRACT_ARRAY
      {
        info_log("New contracts: ");
        int j;

        for (j = new_contracts_count - 1; j >= 0; j--)
        {
          const char *path = contract_get_path(new_contracts[j]);

          if (access(path, R_OK) == 0)
          {
            info_log("OK %s", path);
            print_md5(path);
          } else
          {
            info_log("Couldn't access advertised new path %s", path);
          }
        }
      }
#endif // PRINT_CONTRACT_ARRAY
    }
    g_free(new_contracts);
#endif // SIMPLE_CONTRACT_ENUMERATION
  }
  contract_completion_report_close(report);


  if (NUM_EXERCISE_LOOPS != 0)
  {
    info_log("=====================");
    info_log("Exercising the plugin");
    for (int i = 0; i < NUM_EXERCISE_LOOPS; i++)
    {
      subcontractor_result_msg = transport_sendrecv(transport, (char *) contract_string, contract_string_size, &child_pid, &subcontractor_result_msg_size);
    }

    info_log("Finished exercising the plugin");
  }

  info_log("=====================");

  info_log("Telling subcontractor to close nicely");

  g_free(contract_string);

  // Send empty contract to tell child to close
  c = contract_init(NULL, 0);
  contract_set_path(c, "");
  contract_string = contract_serialise(c, &contract_string_size);
  contract_close(c);
  subcontractor_result_msg = transport_sendrecv(transport, (char *) contract_string, contract_string_size, &child_pid, &subcontractor_result_msg_size);
  g_free(contract_string);

  if (child_pid != -1)
  {
    sleep(100);
  }

  volatile int local_child_pid = child_pid;

  if (local_child_pid != -1)
  {
    warning_log("Process hasn't died automatically. Sending SIGTERM");
    kill(local_child_pid, SIGTERM);
    sleep(10);
    local_child_pid = child_pid;
    if (local_child_pid != -1)
    {
      warning_log("Process STILL hasn't died... Killing it");
      kill(local_child_pid, SIGKILL);
    }
  }

  cleanup(transport);

  return 0;
}
Esempio n. 14
0
static int main_loop(int argc, const char **argv_) {
  aom_codec_ctx_t decoder;
  char *fn = NULL;
  int i;
  int ret = EXIT_FAILURE;
  uint8_t *buf = NULL;
  size_t bytes_in_buffer = 0, buffer_size = 0;
  FILE *infile;
  int frame_in = 0, frame_out = 0, flipuv = 0, noblit = 0;
  int do_md5 = 0, progress = 0;
  int stop_after = 0, postproc = 0, summary = 0, quiet = 1;
  int arg_skip = 0;
  int keep_going = 0;
  const AvxInterface *interface = NULL;
  const AvxInterface *fourcc_interface = NULL;
  uint64_t dx_time = 0;
  struct arg arg;
  char **argv, **argi, **argj;

  int single_file;
  int use_y4m = 1;
  int opt_yv12 = 0;
  int opt_i420 = 0;
  int opt_raw = 0;
  aom_codec_dec_cfg_t cfg = { 0, 0, 0, CONFIG_LOWBITDEPTH, { 1 } };
  unsigned int fixed_output_bit_depth = 0;
  unsigned int is_annexb = 0;
  int frames_corrupted = 0;
  int dec_flags = 0;
  int do_scale = 0;
  int operating_point = 0;
  int output_all_layers = 0;
  int skip_film_grain = 0;
  aom_image_t *scaled_img = NULL;
  aom_image_t *img_shifted = NULL;
  int frame_avail, got_data, flush_decoder = 0;
  int num_external_frame_buffers = 0;
  struct ExternalFrameBufferList ext_fb_list = { 0, NULL };

  const char *outfile_pattern = NULL;
  char outfile_name[PATH_MAX] = { 0 };
  FILE *outfile = NULL;

  FILE *framestats_file = NULL;

  MD5Context md5_ctx;
  unsigned char md5_digest[16];

  struct AvxDecInputContext input = { NULL, NULL, NULL };
  struct AvxInputContext aom_input_ctx;
  memset(&aom_input_ctx, 0, sizeof(aom_input_ctx));
#if CONFIG_WEBM_IO
  struct WebmInputContext webm_ctx;
  memset(&webm_ctx, 0, sizeof(webm_ctx));
  input.webm_ctx = &webm_ctx;
#endif
  struct ObuDecInputContext obu_ctx = { NULL, NULL, 0, 0, 0 };

  obu_ctx.avx_ctx = &aom_input_ctx;
  input.obu_ctx = &obu_ctx;
  input.aom_input_ctx = &aom_input_ctx;

  /* Parse command line */
  exec_name = argv_[0];
  argv = argv_dup(argc - 1, argv_ + 1);

  for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) {
    memset(&arg, 0, sizeof(arg));
    arg.argv_step = 1;

    if (arg_match(&arg, &help, argi)) {
      show_help(stdout, 0);
      exit(EXIT_SUCCESS);
    } else if (arg_match(&arg, &codecarg, argi)) {
      interface = get_aom_decoder_by_name(arg.val);
      if (!interface)
        die("Error: Unrecognized argument (%s) to --codec\n", arg.val);
    } else if (arg_match(&arg, &looparg, argi)) {
      // no-op
    } else if (arg_match(&arg, &outputfile, argi)) {
      outfile_pattern = arg.val;
    } else if (arg_match(&arg, &use_yv12, argi)) {
      use_y4m = 0;
      flipuv = 1;
      opt_yv12 = 1;
      opt_i420 = 0;
      opt_raw = 0;
    } else if (arg_match(&arg, &use_i420, argi)) {
      use_y4m = 0;
      flipuv = 0;
      opt_yv12 = 0;
      opt_i420 = 1;
      opt_raw = 0;
    } else if (arg_match(&arg, &rawvideo, argi)) {
      use_y4m = 0;
      opt_yv12 = 0;
      opt_i420 = 0;
      opt_raw = 1;
    } else if (arg_match(&arg, &flipuvarg, argi)) {
      flipuv = 1;
    } else if (arg_match(&arg, &noblitarg, argi)) {
      noblit = 1;
    } else if (arg_match(&arg, &progressarg, argi)) {
      progress = 1;
    } else if (arg_match(&arg, &limitarg, argi)) {
      stop_after = arg_parse_uint(&arg);
    } else if (arg_match(&arg, &skiparg, argi)) {
      arg_skip = arg_parse_uint(&arg);
    } else if (arg_match(&arg, &postprocarg, argi)) {
      postproc = 1;
    } else if (arg_match(&arg, &md5arg, argi)) {
      do_md5 = 1;
    } else if (arg_match(&arg, &framestatsarg, argi)) {
      framestats_file = fopen(arg.val, "w");
      if (!framestats_file) {
        die("Error: Could not open --framestats file (%s) for writing.\n",
            arg.val);
      }
    } else if (arg_match(&arg, &summaryarg, argi)) {
      summary = 1;
    } else if (arg_match(&arg, &threadsarg, argi)) {
      cfg.threads = arg_parse_uint(&arg);
#if !CONFIG_MULTITHREAD
      if (cfg.threads > 1) {
        die("Error: --threads=%d is not supported when CONFIG_MULTITHREAD = "
            "0.\n",
            cfg.threads);
      }
#endif
    } else if (arg_match(&arg, &verbosearg, argi)) {
      quiet = 0;
    } else if (arg_match(&arg, &scalearg, argi)) {
      do_scale = 1;
    } else if (arg_match(&arg, &fb_arg, argi)) {
      num_external_frame_buffers = arg_parse_uint(&arg);
    } else if (arg_match(&arg, &continuearg, argi)) {
      keep_going = 1;
    } else if (arg_match(&arg, &outbitdeptharg, argi)) {
      fixed_output_bit_depth = arg_parse_uint(&arg);
    } else if (arg_match(&arg, &isannexb, argi)) {
      is_annexb = 1;
      input.obu_ctx->is_annexb = 1;
    } else if (arg_match(&arg, &oppointarg, argi)) {
      operating_point = arg_parse_int(&arg);
    } else if (arg_match(&arg, &outallarg, argi)) {
      output_all_layers = 1;
    } else if (arg_match(&arg, &skipfilmgrain, argi)) {
      skip_film_grain = 1;
    } else {
      argj++;
    }
  }

  /* Check for unrecognized options */
  for (argi = argv; *argi; argi++)
    if (argi[0][0] == '-' && strlen(argi[0]) > 1)
      die("Error: Unrecognized option %s\n", *argi);

  /* Handle non-option arguments */
  fn = argv[0];

  if (!fn) {
    free(argv);
    fprintf(stderr, "No input file specified!\n");
    usage_exit();
  }
  /* Open file */
  infile = strcmp(fn, "-") ? fopen(fn, "rb") : set_binary_mode(stdin);

  if (!infile) {
    fatal("Failed to open input file '%s'", strcmp(fn, "-") ? fn : "stdin");
  }
#if CONFIG_OS_SUPPORT
  /* Make sure we don't dump to the terminal, unless forced to with -o - */
  if (!outfile_pattern && isatty(STDOUT_FILENO) && !do_md5 && !noblit) {
    fprintf(stderr,
            "Not dumping raw video to your terminal. Use '-o -' to "
            "override.\n");
    return EXIT_FAILURE;
  }
#endif
  input.aom_input_ctx->filename = fn;
  input.aom_input_ctx->file = infile;
  if (file_is_ivf(input.aom_input_ctx))
    input.aom_input_ctx->file_type = FILE_TYPE_IVF;
#if CONFIG_WEBM_IO
  else if (file_is_webm(input.webm_ctx, input.aom_input_ctx))
    input.aom_input_ctx->file_type = FILE_TYPE_WEBM;
#endif
  else if (file_is_obu(&obu_ctx))
    input.aom_input_ctx->file_type = FILE_TYPE_OBU;
  else if (file_is_raw(input.aom_input_ctx))
    input.aom_input_ctx->file_type = FILE_TYPE_RAW;
  else {
    fprintf(stderr, "Unrecognized input file type.\n");
#if !CONFIG_WEBM_IO
    fprintf(stderr, "aomdec was built without WebM container support.\n");
#endif
    return EXIT_FAILURE;
  }

  outfile_pattern = outfile_pattern ? outfile_pattern : "-";
  single_file = is_single_file(outfile_pattern);

  if (!noblit && single_file) {
    generate_filename(outfile_pattern, outfile_name, PATH_MAX,
                      aom_input_ctx.width, aom_input_ctx.height, 0);
    if (do_md5)
      MD5Init(&md5_ctx);
    else
      outfile = open_outfile(outfile_name);
  }

  if (use_y4m && !noblit) {
    if (!single_file) {
      fprintf(stderr,
              "YUV4MPEG2 not supported with output patterns,"
              " try --i420 or --yv12 or --rawvideo.\n");
      return EXIT_FAILURE;
    }

#if CONFIG_WEBM_IO
    if (aom_input_ctx.file_type == FILE_TYPE_WEBM) {
      if (webm_guess_framerate(input.webm_ctx, input.aom_input_ctx)) {
        fprintf(stderr,
                "Failed to guess framerate -- error parsing "
                "webm file?\n");
        return EXIT_FAILURE;
      }
    }
#endif
  }

  fourcc_interface = get_aom_decoder_by_fourcc(aom_input_ctx.fourcc);
  if (interface && fourcc_interface && interface != fourcc_interface)
    warn("Header indicates codec: %s\n", fourcc_interface->name);
  else
    interface = fourcc_interface;

  if (!interface) interface = get_aom_decoder_by_index(0);

  dec_flags = (postproc ? AOM_CODEC_USE_POSTPROC : 0);
  if (aom_codec_dec_init(&decoder, interface->codec_interface(), &cfg,
                         dec_flags)) {
    fprintf(stderr, "Failed to initialize decoder: %s\n",
            aom_codec_error(&decoder));
    goto fail2;
  }

  if (!quiet) fprintf(stderr, "%s\n", decoder.name);

  if (aom_codec_control(&decoder, AV1D_SET_IS_ANNEXB, is_annexb)) {
    fprintf(stderr, "Failed to set is_annexb: %s\n", aom_codec_error(&decoder));
    goto fail;
  }

  if (aom_codec_control(&decoder, AV1D_SET_OPERATING_POINT, operating_point)) {
    fprintf(stderr, "Failed to set operating_point: %s\n",
            aom_codec_error(&decoder));
    goto fail;
  }

  if (aom_codec_control(&decoder, AV1D_SET_OUTPUT_ALL_LAYERS,
                        output_all_layers)) {
    fprintf(stderr, "Failed to set output_all_layers: %s\n",
            aom_codec_error(&decoder));
    goto fail;
  }

  if (aom_codec_control(&decoder, AV1D_SET_SKIP_FILM_GRAIN, skip_film_grain)) {
    fprintf(stderr, "Failed to set skip_film_grain: %s\n",
            aom_codec_error(&decoder));
    goto fail;
  }

  if (arg_skip) fprintf(stderr, "Skipping first %d frames.\n", arg_skip);
  while (arg_skip) {
    if (read_frame(&input, &buf, &bytes_in_buffer, &buffer_size)) break;
    arg_skip--;
  }

  if (num_external_frame_buffers > 0) {
    ext_fb_list.num_external_frame_buffers = num_external_frame_buffers;
    ext_fb_list.ext_fb = (struct ExternalFrameBuffer *)calloc(
        num_external_frame_buffers, sizeof(*ext_fb_list.ext_fb));
    if (aom_codec_set_frame_buffer_functions(&decoder, get_av1_frame_buffer,
                                             release_av1_frame_buffer,
                                             &ext_fb_list)) {
      fprintf(stderr, "Failed to configure external frame buffers: %s\n",
              aom_codec_error(&decoder));
      goto fail;
    }
  }

  frame_avail = 1;
  got_data = 0;

  if (framestats_file) fprintf(framestats_file, "bytes,qp\r\n");

  /* Decode file */
  while (frame_avail || got_data) {
    aom_codec_iter_t iter = NULL;
    aom_image_t *img;
    struct aom_usec_timer timer;
    int corrupted = 0;

    frame_avail = 0;
    if (!stop_after || frame_in < stop_after) {
      if (!read_frame(&input, &buf, &bytes_in_buffer, &buffer_size)) {
        frame_avail = 1;
        frame_in++;

        aom_usec_timer_start(&timer);

        if (aom_codec_decode(&decoder, buf, bytes_in_buffer, NULL)) {
          const char *detail = aom_codec_error_detail(&decoder);
          warn("Failed to decode frame %d: %s", frame_in,
               aom_codec_error(&decoder));

          if (detail) warn("Additional information: %s", detail);
          if (!keep_going) goto fail;
        }

        if (framestats_file) {
          int qp;
          if (aom_codec_control(&decoder, AOMD_GET_LAST_QUANTIZER, &qp)) {
            warn("Failed AOMD_GET_LAST_QUANTIZER: %s",
                 aom_codec_error(&decoder));
            if (!keep_going) goto fail;
          }
          fprintf(framestats_file, "%d,%d\r\n", (int)bytes_in_buffer, qp);
        }

        aom_usec_timer_mark(&timer);
        dx_time += aom_usec_timer_elapsed(&timer);
      } else {
        flush_decoder = 1;
      }
    } else {
      flush_decoder = 1;
    }

    aom_usec_timer_start(&timer);

    if (flush_decoder) {
      // Flush the decoder.
      if (aom_codec_decode(&decoder, NULL, 0, NULL)) {
        warn("Failed to flush decoder: %s", aom_codec_error(&decoder));
      }
    }

    aom_usec_timer_mark(&timer);
    dx_time += aom_usec_timer_elapsed(&timer);

    got_data = 0;
    while ((img = aom_codec_get_frame(&decoder, &iter))) {
      ++frame_out;
      got_data = 1;

      if (aom_codec_control(&decoder, AOMD_GET_FRAME_CORRUPTED, &corrupted)) {
        warn("Failed AOM_GET_FRAME_CORRUPTED: %s", aom_codec_error(&decoder));
        if (!keep_going) goto fail;
      }
      frames_corrupted += corrupted;

      if (progress) show_progress(frame_in, frame_out, dx_time);

      if (!noblit) {
        const int PLANES_YUV[] = { AOM_PLANE_Y, AOM_PLANE_U, AOM_PLANE_V };
        const int PLANES_YVU[] = { AOM_PLANE_Y, AOM_PLANE_V, AOM_PLANE_U };
        const int *planes = flipuv ? PLANES_YVU : PLANES_YUV;

        if (do_scale) {
          if (frame_out == 1) {
            // If the output frames are to be scaled to a fixed display size
            // then use the width and height specified in the container. If
            // either of these is set to 0, use the display size set in the
            // first frame header. If that is unavailable, use the raw decoded
            // size of the first decoded frame.
            int render_width = aom_input_ctx.width;
            int render_height = aom_input_ctx.height;
            if (!render_width || !render_height) {
              int render_size[2];
              if (aom_codec_control(&decoder, AV1D_GET_DISPLAY_SIZE,
                                    render_size)) {
                // As last resort use size of first frame as display size.
                render_width = img->d_w;
                render_height = img->d_h;
              } else {
                render_width = render_size[0];
                render_height = render_size[1];
              }
            }
            scaled_img =
                aom_img_alloc(NULL, img->fmt, render_width, render_height, 16);
            scaled_img->bit_depth = img->bit_depth;
            scaled_img->monochrome = img->monochrome;
            scaled_img->csp = img->csp;
          }

          if (img->d_w != scaled_img->d_w || img->d_h != scaled_img->d_h) {
#if CONFIG_LIBYUV
            libyuv_scale(img, scaled_img, kFilterBox);
            img = scaled_img;
#else
            fprintf(
                stderr,
                "Failed to scale output frame: %s.\n"
                "libyuv is required for scaling but is currently disabled.\n"
                "Be sure to specify -DCONFIG_LIBYUV=1 when running cmake.\n",
                aom_codec_error(&decoder));
            goto fail;
#endif
          }
        }
        // Default to codec bit depth if output bit depth not set
        unsigned int output_bit_depth;
        if (!fixed_output_bit_depth && single_file && !do_md5) {
          output_bit_depth = img->bit_depth;
        } else {
          output_bit_depth = fixed_output_bit_depth;
        }
        // Shift up or down if necessary
        if (output_bit_depth != 0)
          aom_shift_img(output_bit_depth, &img, &img_shifted);

        aom_input_ctx.width = img->d_w;
        aom_input_ctx.height = img->d_h;

        int num_planes = (opt_raw && img->monochrome) ? 1 : 3;
        if (single_file) {
          if (use_y4m) {
            char y4m_buf[Y4M_BUFFER_SIZE] = { 0 };
            size_t len = 0;
            if (frame_out == 1) {
              // Y4M file header
              len = y4m_write_file_header(
                  y4m_buf, sizeof(y4m_buf), aom_input_ctx.width,
                  aom_input_ctx.height, &aom_input_ctx.framerate,
                  img->monochrome, img->csp, img->fmt, img->bit_depth);
              if (img->csp == AOM_CSP_COLOCATED) {
                fprintf(stderr,
                        "Warning: Y4M lacks a colorspace for colocated "
                        "chroma. Using a placeholder.\n");
              }
              if (do_md5) {
                MD5Update(&md5_ctx, (md5byte *)y4m_buf, (unsigned int)len);
              } else {
                fputs(y4m_buf, outfile);
              }
            }

            // Y4M frame header
            len = y4m_write_frame_header(y4m_buf, sizeof(y4m_buf));
            if (do_md5) {
              MD5Update(&md5_ctx, (md5byte *)y4m_buf, (unsigned int)len);
              y4m_update_image_md5(img, planes, &md5_ctx);
            } else {
              fputs(y4m_buf, outfile);
              y4m_write_image_file(img, planes, outfile);
            }
          } else {
            if (frame_out == 1) {
              // Check if --yv12 or --i420 options are consistent with the
              // bit-stream decoded
              if (opt_i420) {
                if (img->fmt != AOM_IMG_FMT_I420 &&
                    img->fmt != AOM_IMG_FMT_I42016) {
                  fprintf(stderr,
                          "Cannot produce i420 output for bit-stream.\n");
                  goto fail;
                }
              }
              if (opt_yv12) {
                if ((img->fmt != AOM_IMG_FMT_I420 &&
                     img->fmt != AOM_IMG_FMT_YV12) ||
                    img->bit_depth != 8) {
                  fprintf(stderr,
                          "Cannot produce yv12 output for bit-stream.\n");
                  goto fail;
                }
              }
            }
            if (do_md5) {
              raw_update_image_md5(img, planes, num_planes, &md5_ctx);
            } else {
              raw_write_image_file(img, planes, num_planes, outfile);
            }
          }
        } else {
          generate_filename(outfile_pattern, outfile_name, PATH_MAX, img->d_w,
                            img->d_h, frame_in);
          if (do_md5) {
            MD5Init(&md5_ctx);
            if (use_y4m) {
              y4m_update_image_md5(img, planes, &md5_ctx);
            } else {
              raw_update_image_md5(img, planes, num_planes, &md5_ctx);
            }
            MD5Final(md5_digest, &md5_ctx);
            print_md5(md5_digest, outfile_name);
          } else {
            outfile = open_outfile(outfile_name);
            if (use_y4m) {
              y4m_write_image_file(img, planes, outfile);
            } else {
              raw_write_image_file(img, planes, num_planes, outfile);
            }
            fclose(outfile);
          }
        }
      }
    }
  }

  if (summary || progress) {
    show_progress(frame_in, frame_out, dx_time);
    fprintf(stderr, "\n");
  }

  if (frames_corrupted) {
    fprintf(stderr, "WARNING: %d frames corrupted.\n", frames_corrupted);
  } else {
    ret = EXIT_SUCCESS;
  }

fail:

  if (aom_codec_destroy(&decoder)) {
    fprintf(stderr, "Failed to destroy decoder: %s\n",
            aom_codec_error(&decoder));
  }

fail2:

  if (!noblit && single_file) {
    if (do_md5) {
      MD5Final(md5_digest, &md5_ctx);
      print_md5(md5_digest, outfile_name);
    } else {
      fclose(outfile);
    }
  }

#if CONFIG_WEBM_IO
  if (input.aom_input_ctx->file_type == FILE_TYPE_WEBM)
    webm_free(input.webm_ctx);
#endif
  if (input.aom_input_ctx->file_type == FILE_TYPE_OBU)
    obudec_free(input.obu_ctx);

  if (input.aom_input_ctx->file_type != FILE_TYPE_WEBM) free(buf);

  if (scaled_img) aom_img_free(scaled_img);
  if (img_shifted) aom_img_free(img_shifted);

  for (i = 0; i < ext_fb_list.num_external_frame_buffers; ++i) {
    free(ext_fb_list.ext_fb[i].data);
  }
  free(ext_fb_list.ext_fb);

  fclose(infile);
  if (framestats_file) fclose(framestats_file);

  free(argv);

  return ret;
}