Add dr prediction test
[aom.git] / examples / lightfield_decoder.c
blobed61923b9d285d158ab6bef4eb59303ea2a4d0bd
1 /*
2 * Copyright (c) 2017, Alliance for Open Media. All rights reserved
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.
12 // Lightfield Decoder
13 // ==================
15 // This is an example of a simple lightfield decoder. It builds upon the
16 // simple_decoder.c example. It takes an input file containing the compressed
17 // data (in ivf format), treating it as a lightfield instead of a video and
18 // will decode a single lightfield tile. The lf_width and lf_height arguments
19 // are the number of lightfield images in each dimension. The tile to decode
20 // is specified by the tile_u, tile_v, tile_s, tile_t arguments. The tile_u,
21 // tile_v specify the image and tile_s, tile_t specify the tile in the image.
22 // After running the lightfield encoder, run lightfield decoder to decode a
23 // single tile:
24 // examples/lightfield_decoder vase10x10.ivf vase_tile.yuv 10 10 3 4 5 10 5
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
30 #include "aom/aom_decoder.h"
31 #include "aom/aomdx.h"
32 #include "common/tools_common.h"
33 #include "common/video_reader.h"
35 #define MAX_EXTERNAL_REFERENCES 128
36 #define AOM_BORDER_IN_PIXELS 288
38 static const char *exec_name;
40 void usage_exit(void) {
41 fprintf(stderr,
42 "Usage: %s <infile> <outfile> <lf_width> <lf_height> <tlie_u>"
43 " <tile_v> <tile_s> <tile_t> <lf_blocksize>\n",
44 exec_name);
45 exit(EXIT_FAILURE);
48 int main(int argc, char **argv) {
49 FILE *outfile = NULL;
50 aom_codec_ctx_t codec;
51 AvxVideoReader *reader = NULL;
52 const AvxInterface *decoder = NULL;
53 const AvxVideoInfo *info = NULL;
54 const char *lf_width_arg;
55 const char *lf_height_arg;
56 const char *tile_u_arg;
57 const char *tile_v_arg;
58 const char *tile_s_arg;
59 const char *tile_t_arg;
60 const char *lf_blocksize_arg;
61 int width, height;
62 int lf_width, lf_height;
63 int tile_u, tile_v, tile_s, tile_t;
64 int lf_blocksize;
65 int u_blocks;
66 int v_blocks;
67 aom_image_t reference_images[MAX_EXTERNAL_REFERENCES];
68 size_t frame_size = 0;
69 const unsigned char *frame = NULL;
70 int i;
72 exec_name = argv[0];
74 if (argc != 10) die("Invalid number of arguments.");
76 reader = aom_video_reader_open(argv[1]);
77 if (!reader) die("Failed to open %s for reading.", argv[1]);
79 if (!(outfile = fopen(argv[2], "wb")))
80 die("Failed to open %s for writing.", argv[2]);
82 lf_width_arg = argv[3];
83 lf_height_arg = argv[4];
84 tile_u_arg = argv[5];
85 tile_v_arg = argv[6];
86 tile_s_arg = argv[7];
87 tile_t_arg = argv[8];
88 lf_blocksize_arg = argv[9];
89 lf_width = (int)strtol(lf_width_arg, NULL, 0);
90 lf_height = (int)strtol(lf_height_arg, NULL, 0);
91 tile_u = (int)strtol(tile_u_arg, NULL, 0);
92 tile_v = (int)strtol(tile_v_arg, NULL, 0);
93 tile_s = (int)strtol(tile_s_arg, NULL, 0);
94 tile_t = (int)strtol(tile_t_arg, NULL, 0);
95 lf_blocksize = (int)strtol(lf_blocksize_arg, NULL, 0);
97 info = aom_video_reader_get_info(reader);
98 width = info->frame_width;
99 height = info->frame_height;
101 decoder = get_aom_decoder_by_fourcc(info->codec_fourcc);
102 if (!decoder) die("Unknown input codec.");
103 printf("Using %s\n", aom_codec_iface_name(decoder->codec_interface()));
105 if (aom_codec_dec_init(&codec, decoder->codec_interface(), NULL, 0))
106 die_codec(&codec, "Failed to initialize decoder.");
108 // How many anchor frames we have.
109 u_blocks = (lf_width + lf_blocksize - 1) / lf_blocksize;
110 v_blocks = (lf_height + lf_blocksize - 1) / lf_blocksize;
112 int num_references = v_blocks * u_blocks;
113 int frame_count = 0;
115 // Allocate memory to store decoded references.
116 aom_img_fmt_t ref_fmt = AOM_IMG_FMT_I420;
117 if (!CONFIG_LOWBITDEPTH) ref_fmt |= AOM_IMG_FMT_HIGHBITDEPTH;
118 // Allocate memory with the border so that it can be used as a reference.
119 for (i = 0; i < num_references; i++) {
120 unsigned int border = AOM_BORDER_IN_PIXELS;
121 if (!aom_img_alloc_with_border(&reference_images[i], ref_fmt, width, height,
122 32, 8, border)) {
123 die("Failed to allocate references.");
127 // Decode anchor frames.
128 aom_codec_control_(&codec, AV1_SET_TILE_MODE, 0);
130 for (i = 0; i < num_references; ++i) {
131 aom_video_reader_read_frame(reader);
132 frame = aom_video_reader_get_frame(reader, &frame_size);
133 if (aom_codec_decode(&codec, frame, frame_size, NULL))
134 die_codec(&codec, "Failed to decode frame.");
136 if (aom_codec_control(&codec, AV1_COPY_NEW_FRAME_IMAGE,
137 &reference_images[i]))
138 die_codec(&codec, "Failed to copy decoded reference frame");
140 aom_codec_iter_t iter = NULL;
141 aom_image_t *img = NULL;
142 while ((img = aom_codec_get_frame(&codec, &iter)) != NULL) {
143 char name[1024];
144 snprintf(name, sizeof(name), "ref_%d.yuv", i);
145 printf("writing ref image to %s, %d, %d\n", name, img->d_w, img->d_h);
146 FILE *ref_file = fopen(name, "wb");
147 aom_img_write(img, ref_file);
148 fclose(ref_file);
152 frame_count = 0;
153 int decode_frame_index = tile_v * lf_width + tile_u;
154 do {
155 aom_video_reader_read_frame(reader);
156 } while (frame_count++ != decode_frame_index);
158 frame = aom_video_reader_get_frame(reader, &frame_size);
159 int ref_bu = tile_u / lf_blocksize;
160 int ref_bv = tile_v / lf_blocksize;
161 int ref_bi = ref_bu + ref_bv * u_blocks;
162 av1_ref_frame_t ref;
163 ref.idx = 0;
164 ref.use_external_ref = 1;
165 ref.img = reference_images[ref_bi];
167 if (aom_codec_control(&codec, AV1_SET_REFERENCE, &ref)) {
168 die_codec(&codec, "Failed to set reference frame.");
170 aom_codec_control_(&codec, AV1_SET_TILE_MODE, 1);
171 aom_codec_control_(&codec, AV1_SET_DECODE_TILE_ROW, tile_t);
172 aom_codec_control_(&codec, AV1_SET_DECODE_TILE_COL, tile_s);
173 aom_codec_control_(&codec, AV1D_EXT_TILE_DEBUG, 1);
174 aom_codec_err_t aom_status =
175 aom_codec_decode(&codec, frame, frame_size, NULL);
176 if (aom_status) die_codec(&codec, "Failed to decode tile.");
177 aom_codec_iter_t iter = NULL;
178 aom_image_t *img = aom_codec_get_frame(&codec, &iter);
179 aom_img_write(img, outfile);
181 for (i = 0; i < num_references; i++) aom_img_free(&reference_images[i]);
182 if (aom_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
183 aom_video_reader_close(reader);
184 fclose(outfile);
186 return EXIT_SUCCESS;