blob: 75bb97d4e4814bb4850d2f2bc1ffc6965d98c826 [file] [log] [blame]
Dmitry Kovalev50fa5852014-01-07 15:15:25 -08001/*
Yaowu Xu9c01aa12016-09-01 14:32:49 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Dmitry Kovalev50fa5852014-01-07 15:15:25 -08003 *
Yaowu Xu9c01aa12016-09-01 14:32:49 -07004 * 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 Kovalev50fa5852014-01-07 15:15:25 -080010 */
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 Kovalev50fa5852014-01-07 15:15:25 -080033#include <stdio.h>
34#include <stdlib.h>
35#include <string.h>
Dmitry Kovalevc2b33682014-01-24 11:20:09 -080036
Yaowu Xuf883b422016-08-30 14:01:10 -070037#include "aom/aomdx.h"
38#include "aom/aom_decoder.h"
Dmitry Kovalevc2b33682014-01-24 11:20:09 -080039
Tom Finegan9e96bdc2015-02-04 16:11:57 -080040#include "../md5_utils.h"
41#include "../tools_common.h"
42#include "../video_reader.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070043#include "./aom_config.h"
Dmitry Kovalev50fa5852014-01-07 15:15:25 -080044
Yaowu Xuf883b422016-08-30 14:01:10 -070045static void get_image_md5(const aom_image_t *img, unsigned char digest[16]) {
Dmitry Kovaleva31dd322014-01-10 14:50:58 -080046 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 Kovalev0f8787d2014-01-15 14:38:27 -080063 MD5Final(digest, &md5);
64}
65
66static void print_md5(FILE *stream, unsigned char digest[16]) {
67 int i;
68
clang-format397d9642016-08-08 18:51:16 -070069 for (i = 0; i < 16; ++i) fprintf(stream, "%02x", digest[i]);
Dmitry Kovaleva31dd322014-01-10 14:50:58 -080070}
Dmitry Kovalev50fa5852014-01-07 15:15:25 -080071
Dmitry Kovalevc2b33682014-01-24 11:20:09 -080072static const char *exec_name;
73
James Zern59e7a472015-05-09 10:33:26 -070074void usage_exit(void) {
Dmitry Kovalevc2b33682014-01-24 11:20:09 -080075 fprintf(stderr, "Usage: %s <infile> <outfile>\n", exec_name);
76 exit(EXIT_FAILURE);
77}
78
Dmitry Kovalev50fa5852014-01-07 15:15:25 -080079int main(int argc, char **argv) {
Dmitry Kovalev37e6fd32014-02-05 18:34:46 -080080 int frame_cnt = 0;
81 FILE *outfile = NULL;
Yaowu Xuf883b422016-08-30 14:01:10 -070082 aom_codec_ctx_t codec;
83 AvxVideoReader *reader = NULL;
84 const AvxVideoInfo *info = NULL;
85 const AvxInterface *decoder = NULL;
Dmitry Kovalevc2b33682014-01-24 11:20:09 -080086
87 exec_name = argv[0];
Dmitry Kovalev50fa5852014-01-07 15:15:25 -080088
clang-format397d9642016-08-08 18:51:16 -070089 if (argc != 3) die("Invalid number of arguments.");
Dmitry Kovaleva31dd322014-01-10 14:50:58 -080090
Yaowu Xuf883b422016-08-30 14:01:10 -070091 reader = aom_video_reader_open(argv[1]);
clang-format397d9642016-08-08 18:51:16 -070092 if (!reader) die("Failed to open %s for reading.", argv[1]);
Dmitry Kovaleva31dd322014-01-10 14:50:58 -080093
94 if (!(outfile = fopen(argv[2], "wb")))
Dmitry Kovalev37e6fd32014-02-05 18:34:46 -080095 die("Failed to open %s for writing.", argv[2]);
Dmitry Kovalev50fa5852014-01-07 15:15:25 -080096
Yaowu Xuf883b422016-08-30 14:01:10 -070097 info = aom_video_reader_get_info(reader);
Dmitry Kovalev50fa5852014-01-07 15:15:25 -080098
Yaowu Xuf883b422016-08-30 14:01:10 -070099 decoder = get_aom_decoder_by_fourcc(info->codec_fourcc);
clang-format397d9642016-08-08 18:51:16 -0700100 if (!decoder) die("Unknown input codec.");
Dmitry Kovaleva31dd322014-01-10 14:50:58 -0800101
Yaowu Xuf883b422016-08-30 14:01:10 -0700102 printf("Using %s\n", aom_codec_iface_name(decoder->codec_interface()));
Dmitry Kovalev0f8787d2014-01-15 14:38:27 -0800103
Yaowu Xuf883b422016-08-30 14:01:10 -0700104 if (aom_codec_dec_init(&codec, decoder->codec_interface(), NULL, 0))
Dmitry Kovalev50fa5852014-01-07 15:15:25 -0800105 die_codec(&codec, "Failed to initialize decoder");
106
Yaowu Xuf883b422016-08-30 14:01:10 -0700107 while (aom_video_reader_read_frame(reader)) {
108 aom_codec_iter_t iter = NULL;
109 aom_image_t *img = NULL;
Dmitry Kovalevc2b33682014-01-24 11:20:09 -0800110 size_t frame_size = 0;
clang-format397d9642016-08-08 18:51:16 -0700111 const unsigned char *frame =
Yaowu Xuf883b422016-08-30 14:01:10 -0700112 aom_video_reader_get_frame(reader, &frame_size);
Sean DuBois47cc2552018-01-23 07:44:16 +0000113 if (aom_codec_decode(&codec, frame, (unsigned int)frame_size, NULL))
Dmitry Kovalev50fa5852014-01-07 15:15:25 -0800114 die_codec(&codec, "Failed to decode frame");
115
Yaowu Xuf883b422016-08-30 14:01:10 -0700116 while ((img = aom_codec_get_frame(&codec, &iter)) != NULL) {
Dmitry Kovalev0f8787d2014-01-15 14:38:27 -0800117 unsigned char digest[16];
Dmitry Kovalev50fa5852014-01-07 15:15:25 -0800118
Dmitry Kovalev0f8787d2014-01-15 14:38:27 -0800119 get_image_md5(img, digest);
120 print_md5(outfile, digest);
clang-format397d9642016-08-08 18:51:16 -0700121 fprintf(outfile, " img-%dx%d-%04d.i420\n", img->d_w, img->d_h,
122 ++frame_cnt);
Dmitry Kovalev50fa5852014-01-07 15:15:25 -0800123 }
124 }
125
Dmitry Kovaleva31dd322014-01-10 14:50:58 -0800126 printf("Processed %d frames.\n", frame_cnt);
Yaowu Xuf883b422016-08-30 14:01:10 -0700127 if (aom_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");
Dmitry Kovalev50fa5852014-01-07 15:15:25 -0800128
Yaowu Xuf883b422016-08-30 14:01:10 -0700129 aom_video_reader_close(reader);
Dmitry Kovalevc2b33682014-01-24 11:20:09 -0800130
Dmitry Kovalev50fa5852014-01-07 15:15:25 -0800131 fclose(outfile);
Dmitry Kovalev50fa5852014-01-07 15:15:25 -0800132 return EXIT_SUCCESS;
133}