/* * 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; }
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; }
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; }
// // 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); }
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; }
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; }
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; }
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; }
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; }
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; }
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); }
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; }
/** * 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; }
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; }