Dmitry Kovalev | 50fa585 | 2014-01-07 15:15:25 -0800 | [diff] [blame] | 1 | /* |
Yaowu Xu | 9c01aa1 | 2016-09-01 14:32:49 -0700 | [diff] [blame] | 2 | * Copyright (c) 2016, Alliance for Open Media. All rights reserved |
Dmitry Kovalev | 50fa585 | 2014-01-07 15:15:25 -0800 | [diff] [blame] | 3 | * |
Yaowu Xu | 9c01aa1 | 2016-09-01 14:32:49 -0700 | [diff] [blame] | 4 | * This source code is subject to the terms of the BSD 2 Clause License and |
| 5 | * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License |
| 6 | * was not distributed with this source code in the LICENSE file, you can |
| 7 | * obtain it at www.aomedia.org/license/software. If the Alliance for Open |
| 8 | * Media Patent License 1.0 was not distributed with this source code in the |
| 9 | * PATENTS file, you can obtain it at www.aomedia.org/license/patent. |
Dmitry Kovalev | 50fa585 | 2014-01-07 15:15:25 -0800 | [diff] [blame] | 10 | */ |
| 11 | |
| 12 | // Frame-by-frame MD5 Checksum |
| 13 | // =========================== |
| 14 | // |
| 15 | // This example builds upon the simple decoder loop to show how checksums |
| 16 | // of the decoded output can be generated. These are used for validating |
| 17 | // decoder implementations against the reference implementation, for example. |
| 18 | // |
| 19 | // MD5 algorithm |
| 20 | // ------------- |
| 21 | // The Message-Digest 5 (MD5) is a well known hash function. We have provided |
| 22 | // an implementation derived from the RSA Data Security, Inc. MD5 Message-Digest |
| 23 | // Algorithm for your use. Our implmentation only changes the interface of this |
| 24 | // reference code. You must include the `md5_utils.h` header for access to these |
| 25 | // functions. |
| 26 | // |
| 27 | // Processing The Decoded Data |
| 28 | // --------------------------- |
| 29 | // Each row of the image is passed to the MD5 accumulator. First the Y plane |
| 30 | // is processed, then U, then V. It is important to honor the image's `stride` |
| 31 | // values. |
| 32 | |
Dmitry Kovalev | 50fa585 | 2014-01-07 15:15:25 -0800 | [diff] [blame] | 33 | #include <stdio.h> |
| 34 | #include <stdlib.h> |
| 35 | #include <string.h> |
Dmitry Kovalev | c2b3368 | 2014-01-24 11:20:09 -0800 | [diff] [blame] | 36 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 37 | #include "aom/aomdx.h" |
| 38 | #include "aom/aom_decoder.h" |
Dmitry Kovalev | c2b3368 | 2014-01-24 11:20:09 -0800 | [diff] [blame] | 39 | |
Tom Finegan | 9e96bdc | 2015-02-04 16:11:57 -0800 | [diff] [blame] | 40 | #include "../md5_utils.h" |
| 41 | #include "../tools_common.h" |
| 42 | #include "../video_reader.h" |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 43 | #include "./aom_config.h" |
Dmitry Kovalev | 50fa585 | 2014-01-07 15:15:25 -0800 | [diff] [blame] | 44 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 45 | static void get_image_md5(const aom_image_t *img, unsigned char digest[16]) { |
Dmitry Kovalev | a31dd32 | 2014-01-10 14:50:58 -0800 | [diff] [blame] | 46 | int plane, y; |
| 47 | MD5Context md5; |
| 48 | |
| 49 | MD5Init(&md5); |
| 50 | |
| 51 | for (plane = 0; plane < 3; ++plane) { |
| 52 | const unsigned char *buf = img->planes[plane]; |
| 53 | const int stride = img->stride[plane]; |
| 54 | const int w = plane ? (img->d_w + 1) >> 1 : img->d_w; |
| 55 | const int h = plane ? (img->d_h + 1) >> 1 : img->d_h; |
| 56 | |
| 57 | for (y = 0; y < h; ++y) { |
| 58 | MD5Update(&md5, buf, w); |
| 59 | buf += stride; |
| 60 | } |
| 61 | } |
| 62 | |
Dmitry Kovalev | 0f8787d | 2014-01-15 14:38:27 -0800 | [diff] [blame] | 63 | MD5Final(digest, &md5); |
| 64 | } |
| 65 | |
| 66 | static void print_md5(FILE *stream, unsigned char digest[16]) { |
| 67 | int i; |
| 68 | |
clang-format | 397d964 | 2016-08-08 18:51:16 -0700 | [diff] [blame] | 69 | for (i = 0; i < 16; ++i) fprintf(stream, "%02x", digest[i]); |
Dmitry Kovalev | a31dd32 | 2014-01-10 14:50:58 -0800 | [diff] [blame] | 70 | } |
Dmitry Kovalev | 50fa585 | 2014-01-07 15:15:25 -0800 | [diff] [blame] | 71 | |
Dmitry Kovalev | c2b3368 | 2014-01-24 11:20:09 -0800 | [diff] [blame] | 72 | static const char *exec_name; |
| 73 | |
James Zern | 59e7a47 | 2015-05-09 10:33:26 -0700 | [diff] [blame] | 74 | void usage_exit(void) { |
Dmitry Kovalev | c2b3368 | 2014-01-24 11:20:09 -0800 | [diff] [blame] | 75 | fprintf(stderr, "Usage: %s <infile> <outfile>\n", exec_name); |
| 76 | exit(EXIT_FAILURE); |
| 77 | } |
| 78 | |
Dmitry Kovalev | 50fa585 | 2014-01-07 15:15:25 -0800 | [diff] [blame] | 79 | int main(int argc, char **argv) { |
Dmitry Kovalev | 37e6fd3 | 2014-02-05 18:34:46 -0800 | [diff] [blame] | 80 | int frame_cnt = 0; |
| 81 | FILE *outfile = NULL; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 82 | aom_codec_ctx_t codec; |
| 83 | AvxVideoReader *reader = NULL; |
| 84 | const AvxVideoInfo *info = NULL; |
| 85 | const AvxInterface *decoder = NULL; |
Dmitry Kovalev | c2b3368 | 2014-01-24 11:20:09 -0800 | [diff] [blame] | 86 | |
| 87 | exec_name = argv[0]; |
Dmitry Kovalev | 50fa585 | 2014-01-07 15:15:25 -0800 | [diff] [blame] | 88 | |
clang-format | 397d964 | 2016-08-08 18:51:16 -0700 | [diff] [blame] | 89 | if (argc != 3) die("Invalid number of arguments."); |
Dmitry Kovalev | a31dd32 | 2014-01-10 14:50:58 -0800 | [diff] [blame] | 90 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 91 | reader = aom_video_reader_open(argv[1]); |
clang-format | 397d964 | 2016-08-08 18:51:16 -0700 | [diff] [blame] | 92 | if (!reader) die("Failed to open %s for reading.", argv[1]); |
Dmitry Kovalev | a31dd32 | 2014-01-10 14:50:58 -0800 | [diff] [blame] | 93 | |
| 94 | if (!(outfile = fopen(argv[2], "wb"))) |
Dmitry Kovalev | 37e6fd3 | 2014-02-05 18:34:46 -0800 | [diff] [blame] | 95 | die("Failed to open %s for writing.", argv[2]); |
Dmitry Kovalev | 50fa585 | 2014-01-07 15:15:25 -0800 | [diff] [blame] | 96 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 97 | info = aom_video_reader_get_info(reader); |
Dmitry Kovalev | 50fa585 | 2014-01-07 15:15:25 -0800 | [diff] [blame] | 98 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 99 | decoder = get_aom_decoder_by_fourcc(info->codec_fourcc); |
clang-format | 397d964 | 2016-08-08 18:51:16 -0700 | [diff] [blame] | 100 | if (!decoder) die("Unknown input codec."); |
Dmitry Kovalev | a31dd32 | 2014-01-10 14:50:58 -0800 | [diff] [blame] | 101 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 102 | printf("Using %s\n", aom_codec_iface_name(decoder->codec_interface())); |
Dmitry Kovalev | 0f8787d | 2014-01-15 14:38:27 -0800 | [diff] [blame] | 103 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 104 | if (aom_codec_dec_init(&codec, decoder->codec_interface(), NULL, 0)) |
Dmitry Kovalev | 50fa585 | 2014-01-07 15:15:25 -0800 | [diff] [blame] | 105 | die_codec(&codec, "Failed to initialize decoder"); |
| 106 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 107 | while (aom_video_reader_read_frame(reader)) { |
| 108 | aom_codec_iter_t iter = NULL; |
| 109 | aom_image_t *img = NULL; |
Dmitry Kovalev | c2b3368 | 2014-01-24 11:20:09 -0800 | [diff] [blame] | 110 | size_t frame_size = 0; |
clang-format | 397d964 | 2016-08-08 18:51:16 -0700 | [diff] [blame] | 111 | const unsigned char *frame = |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 112 | aom_video_reader_get_frame(reader, &frame_size); |
Sean DuBois | 47cc255 | 2018-01-23 07:44:16 +0000 | [diff] [blame] | 113 | if (aom_codec_decode(&codec, frame, (unsigned int)frame_size, NULL)) |
Dmitry Kovalev | 50fa585 | 2014-01-07 15:15:25 -0800 | [diff] [blame] | 114 | die_codec(&codec, "Failed to decode frame"); |
| 115 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 116 | while ((img = aom_codec_get_frame(&codec, &iter)) != NULL) { |
Dmitry Kovalev | 0f8787d | 2014-01-15 14:38:27 -0800 | [diff] [blame] | 117 | unsigned char digest[16]; |
Dmitry Kovalev | 50fa585 | 2014-01-07 15:15:25 -0800 | [diff] [blame] | 118 | |
Dmitry Kovalev | 0f8787d | 2014-01-15 14:38:27 -0800 | [diff] [blame] | 119 | get_image_md5(img, digest); |
| 120 | print_md5(outfile, digest); |
clang-format | 397d964 | 2016-08-08 18:51:16 -0700 | [diff] [blame] | 121 | fprintf(outfile, " img-%dx%d-%04d.i420\n", img->d_w, img->d_h, |
| 122 | ++frame_cnt); |
Dmitry Kovalev | 50fa585 | 2014-01-07 15:15:25 -0800 | [diff] [blame] | 123 | } |
| 124 | } |
| 125 | |
Dmitry Kovalev | a31dd32 | 2014-01-10 14:50:58 -0800 | [diff] [blame] | 126 | printf("Processed %d frames.\n", frame_cnt); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 127 | if (aom_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec."); |
Dmitry Kovalev | 50fa585 | 2014-01-07 15:15:25 -0800 | [diff] [blame] | 128 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 129 | aom_video_reader_close(reader); |
Dmitry Kovalev | c2b3368 | 2014-01-24 11:20:09 -0800 | [diff] [blame] | 130 | |
Dmitry Kovalev | 50fa585 | 2014-01-07 15:15:25 -0800 | [diff] [blame] | 131 | fclose(outfile); |
Dmitry Kovalev | 50fa585 | 2014-01-07 15:15:25 -0800 | [diff] [blame] | 132 | return EXIT_SUCCESS; |
| 133 | } |