1*abb65b4bSAndroid Build Coastguard Worker /*
2*abb65b4bSAndroid Build Coastguard Worker * Copyright (c) 2022 Samsung Electronics Co., Ltd.
3*abb65b4bSAndroid Build Coastguard Worker * All Rights Reserved.
4*abb65b4bSAndroid Build Coastguard Worker *
5*abb65b4bSAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
6*abb65b4bSAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions are met:
7*abb65b4bSAndroid Build Coastguard Worker *
8*abb65b4bSAndroid Build Coastguard Worker * - Redistributions of source code must retain the above copyright notice,
9*abb65b4bSAndroid Build Coastguard Worker * this list of conditions and the following disclaimer.
10*abb65b4bSAndroid Build Coastguard Worker *
11*abb65b4bSAndroid Build Coastguard Worker * - Redistributions in binary form must reproduce the above copyright notice,
12*abb65b4bSAndroid Build Coastguard Worker * this list of conditions and the following disclaimer in the documentation
13*abb65b4bSAndroid Build Coastguard Worker * and/or other materials provided with the distribution.
14*abb65b4bSAndroid Build Coastguard Worker *
15*abb65b4bSAndroid Build Coastguard Worker * - Neither the name of the copyright owner, nor the names of its contributors
16*abb65b4bSAndroid Build Coastguard Worker * may be used to endorse or promote products derived from this software
17*abb65b4bSAndroid Build Coastguard Worker * without specific prior written permission.
18*abb65b4bSAndroid Build Coastguard Worker *
19*abb65b4bSAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20*abb65b4bSAndroid Build Coastguard Worker * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21*abb65b4bSAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*abb65b4bSAndroid Build Coastguard Worker * ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23*abb65b4bSAndroid Build Coastguard Worker * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24*abb65b4bSAndroid Build Coastguard Worker * CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*abb65b4bSAndroid Build Coastguard Worker * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*abb65b4bSAndroid Build Coastguard Worker * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*abb65b4bSAndroid Build Coastguard Worker * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*abb65b4bSAndroid Build Coastguard Worker * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*abb65b4bSAndroid Build Coastguard Worker * POSSIBILITY OF SUCH DAMAGE.
30*abb65b4bSAndroid Build Coastguard Worker */
31*abb65b4bSAndroid Build Coastguard Worker
32*abb65b4bSAndroid Build Coastguard Worker #include "oapv.h"
33*abb65b4bSAndroid Build Coastguard Worker #include "oapv_app_util.h"
34*abb65b4bSAndroid Build Coastguard Worker #include "oapv_app_args.h"
35*abb65b4bSAndroid Build Coastguard Worker #include "oapv_app_y4m.h"
36*abb65b4bSAndroid Build Coastguard Worker
37*abb65b4bSAndroid Build Coastguard Worker #define MAX_BS_BUF 128 * 1024 * 1024 /* byte */
38*abb65b4bSAndroid Build Coastguard Worker
39*abb65b4bSAndroid Build Coastguard Worker // check generic frame or not
40*abb65b4bSAndroid Build Coastguard Worker #define IS_NON_AUX_FRM(frm) (((frm)->pbu_type == OAPV_PBU_TYPE_PRIMARY_FRAME) || ((frm)->pbu_type == OAPV_PBU_TYPE_NON_PRIMARY_FRAME))
41*abb65b4bSAndroid Build Coastguard Worker // check auxiliary frame or not
42*abb65b4bSAndroid Build Coastguard Worker #define IS_AUX_FRM(frm) (!(IS_NON_AUX_FRM(frm)))
43*abb65b4bSAndroid Build Coastguard Worker
44*abb65b4bSAndroid Build Coastguard Worker #define OUTPUT_CSP_NATIVE (0)
45*abb65b4bSAndroid Build Coastguard Worker #define OUTPUT_CSP_P210 (1)
46*abb65b4bSAndroid Build Coastguard Worker
47*abb65b4bSAndroid Build Coastguard Worker // clang-format off
48*abb65b4bSAndroid Build Coastguard Worker
49*abb65b4bSAndroid Build Coastguard Worker /* define various command line options as a table */
50*abb65b4bSAndroid Build Coastguard Worker static const args_opt_t dec_args_opts[] = {
51*abb65b4bSAndroid Build Coastguard Worker {
52*abb65b4bSAndroid Build Coastguard Worker 'v', "verbose", ARGS_VAL_TYPE_INTEGER, 0, NULL,
53*abb65b4bSAndroid Build Coastguard Worker "verbose (log) level\n"
54*abb65b4bSAndroid Build Coastguard Worker " - 0: no message\n"
55*abb65b4bSAndroid Build Coastguard Worker " - 1: only error message\n"
56*abb65b4bSAndroid Build Coastguard Worker " - 2: simple messages\n"
57*abb65b4bSAndroid Build Coastguard Worker " - 3: frame-level messages"
58*abb65b4bSAndroid Build Coastguard Worker },
59*abb65b4bSAndroid Build Coastguard Worker {
60*abb65b4bSAndroid Build Coastguard Worker 'i', "input", ARGS_VAL_TYPE_STRING | ARGS_VAL_TYPE_MANDATORY, 0, NULL,
61*abb65b4bSAndroid Build Coastguard Worker "file name of input bitstream"
62*abb65b4bSAndroid Build Coastguard Worker },
63*abb65b4bSAndroid Build Coastguard Worker {
64*abb65b4bSAndroid Build Coastguard Worker 'o', "output", ARGS_VAL_TYPE_STRING, 0, NULL,
65*abb65b4bSAndroid Build Coastguard Worker "file name of decoded output"
66*abb65b4bSAndroid Build Coastguard Worker },
67*abb65b4bSAndroid Build Coastguard Worker {
68*abb65b4bSAndroid Build Coastguard Worker ARGS_NO_KEY, "max-au", ARGS_VAL_TYPE_INTEGER, 0, NULL,
69*abb65b4bSAndroid Build Coastguard Worker "maximum number of access units to be decoded"
70*abb65b4bSAndroid Build Coastguard Worker },
71*abb65b4bSAndroid Build Coastguard Worker {
72*abb65b4bSAndroid Build Coastguard Worker 'm', "threads", ARGS_VAL_TYPE_INTEGER, 0, NULL,
73*abb65b4bSAndroid Build Coastguard Worker "force to use a specific number of threads"
74*abb65b4bSAndroid Build Coastguard Worker },
75*abb65b4bSAndroid Build Coastguard Worker {
76*abb65b4bSAndroid Build Coastguard Worker 'd', "output-depth", ARGS_VAL_TYPE_INTEGER, 0, NULL,
77*abb65b4bSAndroid Build Coastguard Worker "output bit depth (8, 10) "
78*abb65b4bSAndroid Build Coastguard Worker },
79*abb65b4bSAndroid Build Coastguard Worker {
80*abb65b4bSAndroid Build Coastguard Worker ARGS_NO_KEY, "hash", ARGS_VAL_TYPE_NONE, 0, NULL,
81*abb65b4bSAndroid Build Coastguard Worker "parse frame hash value for conformance checking in decoding"
82*abb65b4bSAndroid Build Coastguard Worker },
83*abb65b4bSAndroid Build Coastguard Worker {
84*abb65b4bSAndroid Build Coastguard Worker ARGS_NO_KEY, "output-csp", ARGS_VAL_TYPE_INTEGER, 0, NULL,
85*abb65b4bSAndroid Build Coastguard Worker "output color space (chroma format)\n"
86*abb65b4bSAndroid Build Coastguard Worker " - 0: coded CSP\n"
87*abb65b4bSAndroid Build Coastguard Worker " - 1: convert to P210 in case of YCbCr422\n"
88*abb65b4bSAndroid Build Coastguard Worker },
89*abb65b4bSAndroid Build Coastguard Worker {ARGS_END_KEY, "", ARGS_VAL_TYPE_NONE, 0, NULL, ""} /* termination */
90*abb65b4bSAndroid Build Coastguard Worker };
91*abb65b4bSAndroid Build Coastguard Worker
92*abb65b4bSAndroid Build Coastguard Worker // clang-format on
93*abb65b4bSAndroid Build Coastguard Worker
94*abb65b4bSAndroid Build Coastguard Worker #define NUM_ARGS_OPT ((int)(sizeof(dec_args_opts) / sizeof(dec_args_opts[0])))
95*abb65b4bSAndroid Build Coastguard Worker
96*abb65b4bSAndroid Build Coastguard Worker typedef struct args_var {
97*abb65b4bSAndroid Build Coastguard Worker char fname_inp[256];
98*abb65b4bSAndroid Build Coastguard Worker char fname_out[256];
99*abb65b4bSAndroid Build Coastguard Worker int max_au;
100*abb65b4bSAndroid Build Coastguard Worker int hash;
101*abb65b4bSAndroid Build Coastguard Worker int threads;
102*abb65b4bSAndroid Build Coastguard Worker int output_depth;
103*abb65b4bSAndroid Build Coastguard Worker int output_csp;
104*abb65b4bSAndroid Build Coastguard Worker } args_var_t;
105*abb65b4bSAndroid Build Coastguard Worker
args_init_vars(args_parser_t * args)106*abb65b4bSAndroid Build Coastguard Worker static args_var_t *args_init_vars(args_parser_t *args)
107*abb65b4bSAndroid Build Coastguard Worker {
108*abb65b4bSAndroid Build Coastguard Worker args_opt_t *opts;
109*abb65b4bSAndroid Build Coastguard Worker args_var_t *vars;
110*abb65b4bSAndroid Build Coastguard Worker opts = args->opts;
111*abb65b4bSAndroid Build Coastguard Worker vars = malloc(sizeof(args_var_t));
112*abb65b4bSAndroid Build Coastguard Worker assert_rv(vars != NULL, NULL);
113*abb65b4bSAndroid Build Coastguard Worker memset(vars, 0, sizeof(args_var_t));
114*abb65b4bSAndroid Build Coastguard Worker
115*abb65b4bSAndroid Build Coastguard Worker /*args_set_variable_by_key_long(opts, "config", args->fname_cfg);*/
116*abb65b4bSAndroid Build Coastguard Worker args_set_variable_by_key_long(opts, "input", vars->fname_inp);
117*abb65b4bSAndroid Build Coastguard Worker args_set_variable_by_key_long(opts, "output", vars->fname_out);
118*abb65b4bSAndroid Build Coastguard Worker args_set_variable_by_key_long(opts, "max-au", &vars->max_au);
119*abb65b4bSAndroid Build Coastguard Worker args_set_variable_by_key_long(opts, "hash", &vars->hash);
120*abb65b4bSAndroid Build Coastguard Worker args_set_variable_by_key_long(opts, "verbose", &op_verbose);
121*abb65b4bSAndroid Build Coastguard Worker op_verbose = VERBOSE_SIMPLE; /* default */
122*abb65b4bSAndroid Build Coastguard Worker args_set_variable_by_key_long(opts, "threads", &vars->threads);
123*abb65b4bSAndroid Build Coastguard Worker vars->threads = 1; /* default */
124*abb65b4bSAndroid Build Coastguard Worker args_set_variable_by_key_long(opts, "output-depth", &vars->output_depth);
125*abb65b4bSAndroid Build Coastguard Worker args_set_variable_by_key_long(opts, "output-csp", &vars->output_csp);
126*abb65b4bSAndroid Build Coastguard Worker vars->output_csp = 0; /* default: coded CSP */
127*abb65b4bSAndroid Build Coastguard Worker
128*abb65b4bSAndroid Build Coastguard Worker return vars;
129*abb65b4bSAndroid Build Coastguard Worker }
130*abb65b4bSAndroid Build Coastguard Worker
print_usage(const char ** argv)131*abb65b4bSAndroid Build Coastguard Worker static void print_usage(const char **argv)
132*abb65b4bSAndroid Build Coastguard Worker {
133*abb65b4bSAndroid Build Coastguard Worker int i;
134*abb65b4bSAndroid Build Coastguard Worker char str[1024];
135*abb65b4bSAndroid Build Coastguard Worker args_var_t *args_var = NULL;
136*abb65b4bSAndroid Build Coastguard Worker args_parser_t *args;
137*abb65b4bSAndroid Build Coastguard Worker
138*abb65b4bSAndroid Build Coastguard Worker args = args_create(dec_args_opts, NUM_ARGS_OPT);
139*abb65b4bSAndroid Build Coastguard Worker if(args == NULL)
140*abb65b4bSAndroid Build Coastguard Worker goto ERR;
141*abb65b4bSAndroid Build Coastguard Worker args_var = args_init_vars(args);
142*abb65b4bSAndroid Build Coastguard Worker if(args_var == NULL)
143*abb65b4bSAndroid Build Coastguard Worker goto ERR;
144*abb65b4bSAndroid Build Coastguard Worker
145*abb65b4bSAndroid Build Coastguard Worker logv2("Syntax: \n");
146*abb65b4bSAndroid Build Coastguard Worker logv2(" %s -i 'input-file' [ options ] \n\n", argv[0]);
147*abb65b4bSAndroid Build Coastguard Worker
148*abb65b4bSAndroid Build Coastguard Worker logv2("Options:\n");
149*abb65b4bSAndroid Build Coastguard Worker logv2(" --help\n : list options\n");
150*abb65b4bSAndroid Build Coastguard Worker for(i = 0; i < args->num_option; i++) {
151*abb65b4bSAndroid Build Coastguard Worker if(args->get_help(args, i, str) < 0)
152*abb65b4bSAndroid Build Coastguard Worker return;
153*abb65b4bSAndroid Build Coastguard Worker logv2("%s\n", str);
154*abb65b4bSAndroid Build Coastguard Worker }
155*abb65b4bSAndroid Build Coastguard Worker
156*abb65b4bSAndroid Build Coastguard Worker ERR:
157*abb65b4bSAndroid Build Coastguard Worker if(args)
158*abb65b4bSAndroid Build Coastguard Worker args->release(args);
159*abb65b4bSAndroid Build Coastguard Worker if(args_var)
160*abb65b4bSAndroid Build Coastguard Worker free(args_var);
161*abb65b4bSAndroid Build Coastguard Worker }
162*abb65b4bSAndroid Build Coastguard Worker
read_au_size(FILE * fp)163*abb65b4bSAndroid Build Coastguard Worker static int read_au_size(FILE *fp)
164*abb65b4bSAndroid Build Coastguard Worker {
165*abb65b4bSAndroid Build Coastguard Worker unsigned char buf[4];
166*abb65b4bSAndroid Build Coastguard Worker
167*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < 4; i++) {
168*abb65b4bSAndroid Build Coastguard Worker if(1 != fread(&buf[i], 1, 1, fp))
169*abb65b4bSAndroid Build Coastguard Worker return -1;
170*abb65b4bSAndroid Build Coastguard Worker }
171*abb65b4bSAndroid Build Coastguard Worker return ((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3]));
172*abb65b4bSAndroid Build Coastguard Worker }
173*abb65b4bSAndroid Build Coastguard Worker
read_bitstream(FILE * fp,unsigned char * bs_buf,int * bs_buf_size)174*abb65b4bSAndroid Build Coastguard Worker static int read_bitstream(FILE *fp, unsigned char *bs_buf, int *bs_buf_size)
175*abb65b4bSAndroid Build Coastguard Worker {
176*abb65b4bSAndroid Build Coastguard Worker int au_size, read_size = 0;
177*abb65b4bSAndroid Build Coastguard Worker unsigned char b = 0;
178*abb65b4bSAndroid Build Coastguard Worker if(!fseek(fp, 0, SEEK_CUR)) {
179*abb65b4bSAndroid Build Coastguard Worker /* read size first */
180*abb65b4bSAndroid Build Coastguard Worker au_size = read_au_size(fp);
181*abb65b4bSAndroid Build Coastguard Worker if(au_size > 0) {
182*abb65b4bSAndroid Build Coastguard Worker while(au_size > 0) {
183*abb65b4bSAndroid Build Coastguard Worker /* read byte */
184*abb65b4bSAndroid Build Coastguard Worker if(1 != fread(&b, 1, 1, fp)) {
185*abb65b4bSAndroid Build Coastguard Worker logerr("Cannot read bitstream!\n");
186*abb65b4bSAndroid Build Coastguard Worker return -1;
187*abb65b4bSAndroid Build Coastguard Worker }
188*abb65b4bSAndroid Build Coastguard Worker bs_buf[read_size] = b;
189*abb65b4bSAndroid Build Coastguard Worker read_size++;
190*abb65b4bSAndroid Build Coastguard Worker au_size--;
191*abb65b4bSAndroid Build Coastguard Worker }
192*abb65b4bSAndroid Build Coastguard Worker *bs_buf_size = read_size;
193*abb65b4bSAndroid Build Coastguard Worker }
194*abb65b4bSAndroid Build Coastguard Worker else {
195*abb65b4bSAndroid Build Coastguard Worker if(feof(fp)) {
196*abb65b4bSAndroid Build Coastguard Worker logv2_line("");
197*abb65b4bSAndroid Build Coastguard Worker logv2("End of file\n");
198*abb65b4bSAndroid Build Coastguard Worker return 0;
199*abb65b4bSAndroid Build Coastguard Worker }
200*abb65b4bSAndroid Build Coastguard Worker else {
201*abb65b4bSAndroid Build Coastguard Worker logerr("Cannot read bitstream size!\n")
202*abb65b4bSAndroid Build Coastguard Worker return -1;
203*abb65b4bSAndroid Build Coastguard Worker };
204*abb65b4bSAndroid Build Coastguard Worker }
205*abb65b4bSAndroid Build Coastguard Worker }
206*abb65b4bSAndroid Build Coastguard Worker else {
207*abb65b4bSAndroid Build Coastguard Worker logerr("Cannot seek bitstream!\n");
208*abb65b4bSAndroid Build Coastguard Worker return -1;
209*abb65b4bSAndroid Build Coastguard Worker }
210*abb65b4bSAndroid Build Coastguard Worker return read_size + 4;
211*abb65b4bSAndroid Build Coastguard Worker }
212*abb65b4bSAndroid Build Coastguard Worker
set_extra_config(oapvd_t id,args_var_t * args_vars)213*abb65b4bSAndroid Build Coastguard Worker static int set_extra_config(oapvd_t id, args_var_t *args_vars)
214*abb65b4bSAndroid Build Coastguard Worker {
215*abb65b4bSAndroid Build Coastguard Worker int ret, size, value;
216*abb65b4bSAndroid Build Coastguard Worker
217*abb65b4bSAndroid Build Coastguard Worker if(args_vars->hash) { // enable frame hash calculation
218*abb65b4bSAndroid Build Coastguard Worker value = 1;
219*abb65b4bSAndroid Build Coastguard Worker size = 4;
220*abb65b4bSAndroid Build Coastguard Worker ret = oapvd_config(id, OAPV_CFG_SET_USE_FRM_HASH, &value, &size);
221*abb65b4bSAndroid Build Coastguard Worker if(OAPV_FAILED(ret)) {
222*abb65b4bSAndroid Build Coastguard Worker logerr("failed to set config for using frame hash\n");
223*abb65b4bSAndroid Build Coastguard Worker return -1;
224*abb65b4bSAndroid Build Coastguard Worker }
225*abb65b4bSAndroid Build Coastguard Worker }
226*abb65b4bSAndroid Build Coastguard Worker return 0;
227*abb65b4bSAndroid Build Coastguard Worker }
228*abb65b4bSAndroid Build Coastguard Worker
write_dec_img(char * fname,oapv_imgb_t * img,int flag_y4m)229*abb65b4bSAndroid Build Coastguard Worker static int write_dec_img(char *fname, oapv_imgb_t *img, int flag_y4m)
230*abb65b4bSAndroid Build Coastguard Worker {
231*abb65b4bSAndroid Build Coastguard Worker if(flag_y4m) {
232*abb65b4bSAndroid Build Coastguard Worker if(write_y4m_frame_header(fname))
233*abb65b4bSAndroid Build Coastguard Worker return -1;
234*abb65b4bSAndroid Build Coastguard Worker }
235*abb65b4bSAndroid Build Coastguard Worker if(imgb_write(fname, img))
236*abb65b4bSAndroid Build Coastguard Worker return -1;
237*abb65b4bSAndroid Build Coastguard Worker return 0;
238*abb65b4bSAndroid Build Coastguard Worker }
239*abb65b4bSAndroid Build Coastguard Worker
check_frm_hash(oapvm_t mid,oapv_imgb_t * imgb,int group_id)240*abb65b4bSAndroid Build Coastguard Worker static int check_frm_hash(oapvm_t mid, oapv_imgb_t *imgb, int group_id)
241*abb65b4bSAndroid Build Coastguard Worker {
242*abb65b4bSAndroid Build Coastguard Worker unsigned char uuid_frm_hash[16] = { 0xf8, 0x72, 0x1b, 0x3e, 0xcd, 0xee, 0x47, 0x21, 0x98, 0x0d, 0x9b, 0x9e, 0x39, 0x20, 0x28, 0x49 };
243*abb65b4bSAndroid Build Coastguard Worker void *buf;
244*abb65b4bSAndroid Build Coastguard Worker int size;
245*abb65b4bSAndroid Build Coastguard Worker if(OAPV_SUCCEEDED(oapvm_get(mid, group_id, OAPV_METADATA_USER_DEFINED, &buf, &size, uuid_frm_hash))) {
246*abb65b4bSAndroid Build Coastguard Worker if(size != (imgb->np * 16) /* hash */ + 16 /* uuid */) {
247*abb65b4bSAndroid Build Coastguard Worker return 1; // unexpected error
248*abb65b4bSAndroid Build Coastguard Worker }
249*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < imgb->np; i++) {
250*abb65b4bSAndroid Build Coastguard Worker if(memcmp((unsigned char *)buf + ((i + 1) * 16), imgb->hash[i], 16) != 0) {
251*abb65b4bSAndroid Build Coastguard Worker return -1; // frame hash is mismatched
252*abb65b4bSAndroid Build Coastguard Worker }
253*abb65b4bSAndroid Build Coastguard Worker }
254*abb65b4bSAndroid Build Coastguard Worker return 0; // frame hash is correct
255*abb65b4bSAndroid Build Coastguard Worker }
256*abb65b4bSAndroid Build Coastguard Worker return 1; // frame hash data is not available
257*abb65b4bSAndroid Build Coastguard Worker }
258*abb65b4bSAndroid Build Coastguard Worker
print_commandline(int argc,const char ** argv)259*abb65b4bSAndroid Build Coastguard Worker static void print_commandline(int argc, const char **argv)
260*abb65b4bSAndroid Build Coastguard Worker {
261*abb65b4bSAndroid Build Coastguard Worker int i;
262*abb65b4bSAndroid Build Coastguard Worker if(op_verbose < VERBOSE_FRAME)
263*abb65b4bSAndroid Build Coastguard Worker return;
264*abb65b4bSAndroid Build Coastguard Worker
265*abb65b4bSAndroid Build Coastguard Worker logv3("Command line: ");
266*abb65b4bSAndroid Build Coastguard Worker for(i = 0; i < argc; i++) {
267*abb65b4bSAndroid Build Coastguard Worker logv3("%s ", argv[i]);
268*abb65b4bSAndroid Build Coastguard Worker }
269*abb65b4bSAndroid Build Coastguard Worker logv3("\n\n");
270*abb65b4bSAndroid Build Coastguard Worker }
271*abb65b4bSAndroid Build Coastguard Worker
print_stat_au(oapvd_stat_t * stat,int au_cnt,args_var_t * args_var,oapv_clk_t clk_au,oapv_clk_t clk_tot)272*abb65b4bSAndroid Build Coastguard Worker static void print_stat_au(oapvd_stat_t *stat, int au_cnt, args_var_t *args_var, oapv_clk_t clk_au, oapv_clk_t clk_tot)
273*abb65b4bSAndroid Build Coastguard Worker {
274*abb65b4bSAndroid Build Coastguard Worker if(op_verbose >= VERBOSE_FRAME) {
275*abb65b4bSAndroid Build Coastguard Worker if(au_cnt == 0) {
276*abb65b4bSAndroid Build Coastguard Worker if(args_var->output_csp != OUTPUT_CSP_NATIVE && args_var->hash != 0) {
277*abb65b4bSAndroid Build Coastguard Worker logv2("[Warning] cannot check frame hash value if special output CSP is defined\n")
278*abb65b4bSAndroid Build Coastguard Worker }
279*abb65b4bSAndroid Build Coastguard Worker }
280*abb65b4bSAndroid Build Coastguard Worker logv3_line("");
281*abb65b4bSAndroid Build Coastguard Worker logv3("AU %-5d %10d-bytes %3d-frame(s) %10d msec\n", au_cnt, stat->read, stat->aui.num_frms, oapv_clk_msec(clk_au));
282*abb65b4bSAndroid Build Coastguard Worker }
283*abb65b4bSAndroid Build Coastguard Worker else {
284*abb65b4bSAndroid Build Coastguard Worker int total_time = ((int)oapv_clk_msec(clk_tot) / 1000);
285*abb65b4bSAndroid Build Coastguard Worker int h = total_time / 3600;
286*abb65b4bSAndroid Build Coastguard Worker total_time = total_time % 3600;
287*abb65b4bSAndroid Build Coastguard Worker int m = total_time / 60;
288*abb65b4bSAndroid Build Coastguard Worker total_time = total_time % 60;
289*abb65b4bSAndroid Build Coastguard Worker int s = total_time;
290*abb65b4bSAndroid Build Coastguard Worker logv2("[ %d AU(s) ] [ %.2f AU/sec ] [ %2dh %2dm %2ds ] \r",
291*abb65b4bSAndroid Build Coastguard Worker au_cnt, ((float)(au_cnt + 1) * 1000) / ((float)oapv_clk_msec(clk_tot)), h, m, s);
292*abb65b4bSAndroid Build Coastguard Worker fflush(stdout);
293*abb65b4bSAndroid Build Coastguard Worker }
294*abb65b4bSAndroid Build Coastguard Worker }
295*abb65b4bSAndroid Build Coastguard Worker
print_stat_frm(oapvd_stat_t * stat,oapv_frms_t * frms,oapvm_t mid,args_var_t * args_var)296*abb65b4bSAndroid Build Coastguard Worker static void print_stat_frm(oapvd_stat_t *stat, oapv_frms_t *frms, oapvm_t mid, args_var_t *args_var)
297*abb65b4bSAndroid Build Coastguard Worker {
298*abb65b4bSAndroid Build Coastguard Worker oapv_frm_info_t *finfo;
299*abb65b4bSAndroid Build Coastguard Worker int i, ret, hash_idx;
300*abb65b4bSAndroid Build Coastguard Worker
301*abb65b4bSAndroid Build Coastguard Worker if(op_verbose < VERBOSE_FRAME)
302*abb65b4bSAndroid Build Coastguard Worker return;
303*abb65b4bSAndroid Build Coastguard Worker
304*abb65b4bSAndroid Build Coastguard Worker assert(stat->aui.num_frms == frms->num_frms);
305*abb65b4bSAndroid Build Coastguard Worker
306*abb65b4bSAndroid Build Coastguard Worker finfo = stat->aui.frm_info;
307*abb65b4bSAndroid Build Coastguard Worker
308*abb65b4bSAndroid Build Coastguard Worker for(i = 0; i < stat->aui.num_frms; i++) {
309*abb65b4bSAndroid Build Coastguard Worker // clang-format off
310*abb65b4bSAndroid Build Coastguard Worker const char* str_frm_type = finfo[i].pbu_type == OAPV_PBU_TYPE_PRIMARY_FRAME ? "PRIMARY"
311*abb65b4bSAndroid Build Coastguard Worker : finfo[i].pbu_type == OAPV_PBU_TYPE_NON_PRIMARY_FRAME ? "NON-PRIMARY"
312*abb65b4bSAndroid Build Coastguard Worker : finfo[i].pbu_type == OAPV_PBU_TYPE_PREVIEW_FRAME ? "PREVIEW"
313*abb65b4bSAndroid Build Coastguard Worker : finfo[i].pbu_type == OAPV_PBU_TYPE_DEPTH_FRAME ? "DEPTH"
314*abb65b4bSAndroid Build Coastguard Worker : finfo[i].pbu_type == OAPV_PBU_TYPE_ALPHA_FRAME ? "ALPHA"
315*abb65b4bSAndroid Build Coastguard Worker : "UNKNOWN";
316*abb65b4bSAndroid Build Coastguard Worker
317*abb65b4bSAndroid Build Coastguard Worker const char * str_csp = finfo[i].cs == OAPV_CS_YCBCR400_10LE ? "4:0:0-10"
318*abb65b4bSAndroid Build Coastguard Worker : finfo[i].cs == OAPV_CS_YCBCR422_10LE ? "4:2:2-10"
319*abb65b4bSAndroid Build Coastguard Worker : finfo[i].cs == OAPV_CS_YCBCR444_10LE ? "4:4:4-10"
320*abb65b4bSAndroid Build Coastguard Worker : finfo[i].cs == OAPV_CS_YCBCR4444_10LE ? "4:4:4:4-10"
321*abb65b4bSAndroid Build Coastguard Worker : "unknown-cs";
322*abb65b4bSAndroid Build Coastguard Worker
323*abb65b4bSAndroid Build Coastguard Worker // clang-format on
324*abb65b4bSAndroid Build Coastguard Worker
325*abb65b4bSAndroid Build Coastguard Worker logv2("- FRM %-2d GID %-5d %-11s %9d-bytes %5dx%4d %-10s",
326*abb65b4bSAndroid Build Coastguard Worker i, finfo[i].group_id, str_frm_type, stat->frm_size[i], finfo[i].w, finfo[i].h, str_csp);
327*abb65b4bSAndroid Build Coastguard Worker
328*abb65b4bSAndroid Build Coastguard Worker if(args_var->hash) {
329*abb65b4bSAndroid Build Coastguard Worker char *str_hash[4] = { "unsupport", "mismatch", "unavail", "match" };
330*abb65b4bSAndroid Build Coastguard Worker
331*abb65b4bSAndroid Build Coastguard Worker if(args_var->output_csp != OUTPUT_CSP_NATIVE) {
332*abb65b4bSAndroid Build Coastguard Worker hash_idx = 0;
333*abb65b4bSAndroid Build Coastguard Worker }
334*abb65b4bSAndroid Build Coastguard Worker else {
335*abb65b4bSAndroid Build Coastguard Worker ret = check_frm_hash(mid, frms->frm[i].imgb, frms->frm[i].group_id);
336*abb65b4bSAndroid Build Coastguard Worker if(ret < 0)
337*abb65b4bSAndroid Build Coastguard Worker hash_idx = 1; // mismatch
338*abb65b4bSAndroid Build Coastguard Worker else if(ret > 0)
339*abb65b4bSAndroid Build Coastguard Worker hash_idx = 2; // unavailable
340*abb65b4bSAndroid Build Coastguard Worker else
341*abb65b4bSAndroid Build Coastguard Worker hash_idx = 3; // matched
342*abb65b4bSAndroid Build Coastguard Worker }
343*abb65b4bSAndroid Build Coastguard Worker logv2("hash:%s", str_hash[hash_idx]);
344*abb65b4bSAndroid Build Coastguard Worker }
345*abb65b4bSAndroid Build Coastguard Worker logv2("\n");
346*abb65b4bSAndroid Build Coastguard Worker }
347*abb65b4bSAndroid Build Coastguard Worker }
348*abb65b4bSAndroid Build Coastguard Worker
main(int argc,const char ** argv)349*abb65b4bSAndroid Build Coastguard Worker int main(int argc, const char **argv)
350*abb65b4bSAndroid Build Coastguard Worker {
351*abb65b4bSAndroid Build Coastguard Worker args_parser_t *args;
352*abb65b4bSAndroid Build Coastguard Worker args_var_t *args_var = NULL;
353*abb65b4bSAndroid Build Coastguard Worker unsigned char *bs_buf = NULL;
354*abb65b4bSAndroid Build Coastguard Worker oapvd_t did = NULL;
355*abb65b4bSAndroid Build Coastguard Worker oapvm_t mid = NULL;
356*abb65b4bSAndroid Build Coastguard Worker oapvd_cdesc_t cdesc;
357*abb65b4bSAndroid Build Coastguard Worker oapv_bitb_t bitb;
358*abb65b4bSAndroid Build Coastguard Worker oapv_frms_t ofrms;
359*abb65b4bSAndroid Build Coastguard Worker oapv_imgb_t *imgb_w = NULL;
360*abb65b4bSAndroid Build Coastguard Worker oapv_imgb_t *imgb_o = NULL;
361*abb65b4bSAndroid Build Coastguard Worker oapv_frm_t *frm = NULL;
362*abb65b4bSAndroid Build Coastguard Worker oapv_au_info_t aui;
363*abb65b4bSAndroid Build Coastguard Worker oapvd_stat_t stat;
364*abb65b4bSAndroid Build Coastguard Worker int i, ret = 0;
365*abb65b4bSAndroid Build Coastguard Worker oapv_clk_t clk_beg, clk_end, clk_tot;
366*abb65b4bSAndroid Build Coastguard Worker int au_cnt, frm_cnt[OAPV_MAX_NUM_FRAMES];
367*abb65b4bSAndroid Build Coastguard Worker int read_size, bs_buf_size = 0;
368*abb65b4bSAndroid Build Coastguard Worker FILE *fp_bs = NULL;
369*abb65b4bSAndroid Build Coastguard Worker int is_y4m = 0;
370*abb65b4bSAndroid Build Coastguard Worker char *errstr = NULL;
371*abb65b4bSAndroid Build Coastguard Worker oapv_frm_info_t *finfo = NULL;
372*abb65b4bSAndroid Build Coastguard Worker
373*abb65b4bSAndroid Build Coastguard Worker memset(frm_cnt, 0, sizeof(int) * OAPV_MAX_NUM_FRAMES);
374*abb65b4bSAndroid Build Coastguard Worker memset(&aui, 0, sizeof(oapv_au_info_t));
375*abb65b4bSAndroid Build Coastguard Worker memset(&ofrms, 0, sizeof(oapv_frms_t));
376*abb65b4bSAndroid Build Coastguard Worker
377*abb65b4bSAndroid Build Coastguard Worker /* help message */
378*abb65b4bSAndroid Build Coastguard Worker if(argc < 2 || !strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")) {
379*abb65b4bSAndroid Build Coastguard Worker print_usage(argv);
380*abb65b4bSAndroid Build Coastguard Worker return 0;
381*abb65b4bSAndroid Build Coastguard Worker }
382*abb65b4bSAndroid Build Coastguard Worker /* parse command line */
383*abb65b4bSAndroid Build Coastguard Worker args = args_create(dec_args_opts, NUM_ARGS_OPT);
384*abb65b4bSAndroid Build Coastguard Worker if(args == NULL) {
385*abb65b4bSAndroid Build Coastguard Worker logerr("cannot create argument parser\n");
386*abb65b4bSAndroid Build Coastguard Worker ret = -1;
387*abb65b4bSAndroid Build Coastguard Worker goto ERR;
388*abb65b4bSAndroid Build Coastguard Worker }
389*abb65b4bSAndroid Build Coastguard Worker args_var = args_init_vars(args);
390*abb65b4bSAndroid Build Coastguard Worker if(args_var == NULL) {
391*abb65b4bSAndroid Build Coastguard Worker logerr("cannot initialize argument parser\n");
392*abb65b4bSAndroid Build Coastguard Worker ret = -1;
393*abb65b4bSAndroid Build Coastguard Worker goto ERR;
394*abb65b4bSAndroid Build Coastguard Worker }
395*abb65b4bSAndroid Build Coastguard Worker if(args->parse(args, argc, argv, &errstr)) {
396*abb65b4bSAndroid Build Coastguard Worker logerr("command parsing error (%s)\n", errstr);
397*abb65b4bSAndroid Build Coastguard Worker ret = -1;
398*abb65b4bSAndroid Build Coastguard Worker goto ERR;
399*abb65b4bSAndroid Build Coastguard Worker }
400*abb65b4bSAndroid Build Coastguard Worker // print logo
401*abb65b4bSAndroid Build Coastguard Worker logv2(" ____ ___ ___ _ __\n");
402*abb65b4bSAndroid Build Coastguard Worker logv2(" / __ \\___ ___ ___ / _ | / _ \\ | / / Decoder\n");
403*abb65b4bSAndroid Build Coastguard Worker logv2("/ /_/ / _ \\/ -_) _ \\/ __ |/ ___/ |/ / \n");
404*abb65b4bSAndroid Build Coastguard Worker logv2("\\____/ .__/\\__/_//_/_/ |_/_/ |___/ \n");
405*abb65b4bSAndroid Build Coastguard Worker logv2(" /_/ \n");
406*abb65b4bSAndroid Build Coastguard Worker logv2("\n");
407*abb65b4bSAndroid Build Coastguard Worker
408*abb65b4bSAndroid Build Coastguard Worker // print command line string for information
409*abb65b4bSAndroid Build Coastguard Worker print_commandline(argc, argv);
410*abb65b4bSAndroid Build Coastguard Worker
411*abb65b4bSAndroid Build Coastguard Worker if(args->check_mandatory(args, &errstr)) {
412*abb65b4bSAndroid Build Coastguard Worker logerr("'--%s' argument is mandatory\n", errstr);
413*abb65b4bSAndroid Build Coastguard Worker ret = -1;
414*abb65b4bSAndroid Build Coastguard Worker goto ERR;
415*abb65b4bSAndroid Build Coastguard Worker }
416*abb65b4bSAndroid Build Coastguard Worker
417*abb65b4bSAndroid Build Coastguard Worker /* open input file */
418*abb65b4bSAndroid Build Coastguard Worker fp_bs = fopen(args_var->fname_inp, "rb");
419*abb65b4bSAndroid Build Coastguard Worker if(fp_bs == NULL) {
420*abb65b4bSAndroid Build Coastguard Worker logerr("ERROR: cannot open bitstream file = %s\n", args_var->fname_inp);
421*abb65b4bSAndroid Build Coastguard Worker print_usage(argv);
422*abb65b4bSAndroid Build Coastguard Worker return -1;
423*abb65b4bSAndroid Build Coastguard Worker }
424*abb65b4bSAndroid Build Coastguard Worker /* open output file */
425*abb65b4bSAndroid Build Coastguard Worker if(strlen(args_var->fname_out) > 0) {
426*abb65b4bSAndroid Build Coastguard Worker char fext[16];
427*abb65b4bSAndroid Build Coastguard Worker char *fname = (char *)args_var->fname_out;
428*abb65b4bSAndroid Build Coastguard Worker
429*abb65b4bSAndroid Build Coastguard Worker if(strlen(fname) < 5) { /* at least x.yuv or x.y4m */
430*abb65b4bSAndroid Build Coastguard Worker logerr("ERROR: invalide output file name\n");
431*abb65b4bSAndroid Build Coastguard Worker return -1;
432*abb65b4bSAndroid Build Coastguard Worker }
433*abb65b4bSAndroid Build Coastguard Worker strncpy(fext, fname + strlen(fname) - 3, sizeof(fext) - 1);
434*abb65b4bSAndroid Build Coastguard Worker fext[0] = toupper(fext[0]);
435*abb65b4bSAndroid Build Coastguard Worker fext[1] = toupper(fext[1]);
436*abb65b4bSAndroid Build Coastguard Worker fext[2] = toupper(fext[2]);
437*abb65b4bSAndroid Build Coastguard Worker
438*abb65b4bSAndroid Build Coastguard Worker if(strcmp(fext, "YUV") == 0) {
439*abb65b4bSAndroid Build Coastguard Worker is_y4m = 0;
440*abb65b4bSAndroid Build Coastguard Worker }
441*abb65b4bSAndroid Build Coastguard Worker else if(strcmp(fext, "Y4M") == 0) {
442*abb65b4bSAndroid Build Coastguard Worker is_y4m = 1;
443*abb65b4bSAndroid Build Coastguard Worker }
444*abb65b4bSAndroid Build Coastguard Worker else {
445*abb65b4bSAndroid Build Coastguard Worker logerr("ERROR: unknown output format\n");
446*abb65b4bSAndroid Build Coastguard Worker ret = -1;
447*abb65b4bSAndroid Build Coastguard Worker goto ERR;
448*abb65b4bSAndroid Build Coastguard Worker }
449*abb65b4bSAndroid Build Coastguard Worker clear_data(fname); /* remove decoded file contents if exists */
450*abb65b4bSAndroid Build Coastguard Worker }
451*abb65b4bSAndroid Build Coastguard Worker
452*abb65b4bSAndroid Build Coastguard Worker // create bitstream buffer
453*abb65b4bSAndroid Build Coastguard Worker bs_buf = malloc(MAX_BS_BUF);
454*abb65b4bSAndroid Build Coastguard Worker if(bs_buf == NULL) {
455*abb65b4bSAndroid Build Coastguard Worker logerr("ERROR: cannot allocate bitstream buffer, size=%d\n", MAX_BS_BUF);
456*abb65b4bSAndroid Build Coastguard Worker ret = -1;
457*abb65b4bSAndroid Build Coastguard Worker goto ERR;
458*abb65b4bSAndroid Build Coastguard Worker }
459*abb65b4bSAndroid Build Coastguard Worker // create decoder
460*abb65b4bSAndroid Build Coastguard Worker cdesc.threads = args_var->threads;
461*abb65b4bSAndroid Build Coastguard Worker did = oapvd_create(&cdesc, &ret);
462*abb65b4bSAndroid Build Coastguard Worker if(did == NULL) {
463*abb65b4bSAndroid Build Coastguard Worker logerr("ERROR: cannot create OAPV decoder (err=%d)\n", ret);
464*abb65b4bSAndroid Build Coastguard Worker ret = -1;
465*abb65b4bSAndroid Build Coastguard Worker goto ERR;
466*abb65b4bSAndroid Build Coastguard Worker }
467*abb65b4bSAndroid Build Coastguard Worker if(set_extra_config(did, args_var)) {
468*abb65b4bSAndroid Build Coastguard Worker logerr("ERROR: cannot set extra configurations\n");
469*abb65b4bSAndroid Build Coastguard Worker ret = -1;
470*abb65b4bSAndroid Build Coastguard Worker goto ERR;
471*abb65b4bSAndroid Build Coastguard Worker }
472*abb65b4bSAndroid Build Coastguard Worker
473*abb65b4bSAndroid Build Coastguard Worker clk_tot = 0;
474*abb65b4bSAndroid Build Coastguard Worker au_cnt = 0;
475*abb65b4bSAndroid Build Coastguard Worker
476*abb65b4bSAndroid Build Coastguard Worker /* create metadata container */
477*abb65b4bSAndroid Build Coastguard Worker mid = oapvm_create(&ret);
478*abb65b4bSAndroid Build Coastguard Worker if(OAPV_FAILED(ret)) {
479*abb65b4bSAndroid Build Coastguard Worker logerr("ERROR: cannot create OAPV metadata container (err=%d)\n", ret);
480*abb65b4bSAndroid Build Coastguard Worker ret = -1;
481*abb65b4bSAndroid Build Coastguard Worker goto ERR;
482*abb65b4bSAndroid Build Coastguard Worker }
483*abb65b4bSAndroid Build Coastguard Worker
484*abb65b4bSAndroid Build Coastguard Worker /* decoding loop */
485*abb65b4bSAndroid Build Coastguard Worker while(args_var->max_au == 0 || (au_cnt < args_var->max_au)) {
486*abb65b4bSAndroid Build Coastguard Worker read_size = read_bitstream(fp_bs, bs_buf, &bs_buf_size);
487*abb65b4bSAndroid Build Coastguard Worker if (read_size == 0) {
488*abb65b4bSAndroid Build Coastguard Worker logv3("--> end of bitstream\n")
489*abb65b4bSAndroid Build Coastguard Worker break;
490*abb65b4bSAndroid Build Coastguard Worker }
491*abb65b4bSAndroid Build Coastguard Worker if (read_size < 0) {
492*abb65b4bSAndroid Build Coastguard Worker logv3("--> bitstream reading error\n")
493*abb65b4bSAndroid Build Coastguard Worker ret = -1;
494*abb65b4bSAndroid Build Coastguard Worker goto ERR;
495*abb65b4bSAndroid Build Coastguard Worker }
496*abb65b4bSAndroid Build Coastguard Worker
497*abb65b4bSAndroid Build Coastguard Worker if(OAPV_FAILED(oapvd_info(bs_buf, bs_buf_size, &aui))) {
498*abb65b4bSAndroid Build Coastguard Worker logerr("cannot get information from bitstream\n");
499*abb65b4bSAndroid Build Coastguard Worker ret = -1;
500*abb65b4bSAndroid Build Coastguard Worker goto ERR;
501*abb65b4bSAndroid Build Coastguard Worker }
502*abb65b4bSAndroid Build Coastguard Worker
503*abb65b4bSAndroid Build Coastguard Worker /* create decoding frame buffers */
504*abb65b4bSAndroid Build Coastguard Worker ofrms.num_frms = aui.num_frms;
505*abb65b4bSAndroid Build Coastguard Worker for(i = 0; i < ofrms.num_frms; i++) {
506*abb65b4bSAndroid Build Coastguard Worker finfo = &aui.frm_info[i];
507*abb65b4bSAndroid Build Coastguard Worker frm = &ofrms.frm[i];
508*abb65b4bSAndroid Build Coastguard Worker
509*abb65b4bSAndroid Build Coastguard Worker if(frm->imgb != NULL && (frm->imgb->w[0] != finfo->w || frm->imgb->h[0] != finfo->h)) {
510*abb65b4bSAndroid Build Coastguard Worker frm->imgb->release(frm->imgb);
511*abb65b4bSAndroid Build Coastguard Worker frm->imgb = NULL;
512*abb65b4bSAndroid Build Coastguard Worker }
513*abb65b4bSAndroid Build Coastguard Worker
514*abb65b4bSAndroid Build Coastguard Worker if(frm->imgb == NULL) {
515*abb65b4bSAndroid Build Coastguard Worker if(args_var->output_csp == 1) {
516*abb65b4bSAndroid Build Coastguard Worker frm->imgb = imgb_create(finfo->w, finfo->h, OAPV_CS_SET(OAPV_CF_PLANAR2, 10, 0));
517*abb65b4bSAndroid Build Coastguard Worker }
518*abb65b4bSAndroid Build Coastguard Worker else {
519*abb65b4bSAndroid Build Coastguard Worker frm->imgb = imgb_create(finfo->w, finfo->h, finfo->cs);
520*abb65b4bSAndroid Build Coastguard Worker }
521*abb65b4bSAndroid Build Coastguard Worker if(frm->imgb == NULL) {
522*abb65b4bSAndroid Build Coastguard Worker logerr("cannot allocate image buffer (w:%d, h:%d, cs:%d)\n",
523*abb65b4bSAndroid Build Coastguard Worker finfo->w, finfo->h, finfo->cs);
524*abb65b4bSAndroid Build Coastguard Worker ret = -1;
525*abb65b4bSAndroid Build Coastguard Worker goto ERR;
526*abb65b4bSAndroid Build Coastguard Worker }
527*abb65b4bSAndroid Build Coastguard Worker }
528*abb65b4bSAndroid Build Coastguard Worker }
529*abb65b4bSAndroid Build Coastguard Worker
530*abb65b4bSAndroid Build Coastguard Worker if(args_var->output_depth == 0) {
531*abb65b4bSAndroid Build Coastguard Worker args_var->output_depth = OAPV_CS_GET_BIT_DEPTH(finfo->cs);
532*abb65b4bSAndroid Build Coastguard Worker }
533*abb65b4bSAndroid Build Coastguard Worker
534*abb65b4bSAndroid Build Coastguard Worker /* main decoding block */
535*abb65b4bSAndroid Build Coastguard Worker bitb.addr = bs_buf;
536*abb65b4bSAndroid Build Coastguard Worker bitb.ssize = bs_buf_size;
537*abb65b4bSAndroid Build Coastguard Worker memset(&stat, 0, sizeof(oapvd_stat_t));
538*abb65b4bSAndroid Build Coastguard Worker
539*abb65b4bSAndroid Build Coastguard Worker clk_beg = oapv_clk_get();
540*abb65b4bSAndroid Build Coastguard Worker
541*abb65b4bSAndroid Build Coastguard Worker ret = oapvd_decode(did, &bitb, &ofrms, mid, &stat);
542*abb65b4bSAndroid Build Coastguard Worker
543*abb65b4bSAndroid Build Coastguard Worker clk_end = oapv_clk_from(clk_beg);
544*abb65b4bSAndroid Build Coastguard Worker clk_tot += clk_end;
545*abb65b4bSAndroid Build Coastguard Worker
546*abb65b4bSAndroid Build Coastguard Worker if(OAPV_FAILED(ret)) {
547*abb65b4bSAndroid Build Coastguard Worker logerr("failed to decode bitstream\n");
548*abb65b4bSAndroid Build Coastguard Worker ret = -1;
549*abb65b4bSAndroid Build Coastguard Worker goto END;
550*abb65b4bSAndroid Build Coastguard Worker }
551*abb65b4bSAndroid Build Coastguard Worker if(stat.read != bs_buf_size) {
552*abb65b4bSAndroid Build Coastguard Worker logerr("\t=> different reading of bitstream (in:%d, read:%d)\n",
553*abb65b4bSAndroid Build Coastguard Worker bs_buf_size, stat.read);
554*abb65b4bSAndroid Build Coastguard Worker continue;
555*abb65b4bSAndroid Build Coastguard Worker }
556*abb65b4bSAndroid Build Coastguard Worker
557*abb65b4bSAndroid Build Coastguard Worker /* testing of metadata reading */
558*abb65b4bSAndroid Build Coastguard Worker if(mid) {
559*abb65b4bSAndroid Build Coastguard Worker oapvm_payload_t *pld = NULL; // metadata payload
560*abb65b4bSAndroid Build Coastguard Worker int num_plds = 0; // number of metadata payload
561*abb65b4bSAndroid Build Coastguard Worker
562*abb65b4bSAndroid Build Coastguard Worker ret = oapvm_get_all(mid, NULL, &num_plds);
563*abb65b4bSAndroid Build Coastguard Worker
564*abb65b4bSAndroid Build Coastguard Worker if(OAPV_FAILED(ret)) {
565*abb65b4bSAndroid Build Coastguard Worker logerr("failed to read metadata\n");
566*abb65b4bSAndroid Build Coastguard Worker goto END;
567*abb65b4bSAndroid Build Coastguard Worker }
568*abb65b4bSAndroid Build Coastguard Worker if(num_plds > 0) {
569*abb65b4bSAndroid Build Coastguard Worker pld = malloc(sizeof(oapvm_payload_t) * num_plds);
570*abb65b4bSAndroid Build Coastguard Worker ret = oapvm_get_all(mid, pld, &num_plds);
571*abb65b4bSAndroid Build Coastguard Worker if(OAPV_FAILED(ret)) {
572*abb65b4bSAndroid Build Coastguard Worker logerr("failed to read metadata\n");
573*abb65b4bSAndroid Build Coastguard Worker free(pld);
574*abb65b4bSAndroid Build Coastguard Worker goto END;
575*abb65b4bSAndroid Build Coastguard Worker }
576*abb65b4bSAndroid Build Coastguard Worker }
577*abb65b4bSAndroid Build Coastguard Worker if(pld != NULL)
578*abb65b4bSAndroid Build Coastguard Worker free(pld);
579*abb65b4bSAndroid Build Coastguard Worker }
580*abb65b4bSAndroid Build Coastguard Worker
581*abb65b4bSAndroid Build Coastguard Worker /* print decoding results */
582*abb65b4bSAndroid Build Coastguard Worker print_stat_au(&stat, au_cnt, args_var, clk_end, clk_tot);
583*abb65b4bSAndroid Build Coastguard Worker print_stat_frm(&stat, &ofrms, mid, args_var);
584*abb65b4bSAndroid Build Coastguard Worker
585*abb65b4bSAndroid Build Coastguard Worker /* write decoded frames into files */
586*abb65b4bSAndroid Build Coastguard Worker for(i = 0; i < ofrms.num_frms; i++) {
587*abb65b4bSAndroid Build Coastguard Worker frm = &ofrms.frm[i];
588*abb65b4bSAndroid Build Coastguard Worker if(ofrms.num_frms > 0) {
589*abb65b4bSAndroid Build Coastguard Worker if(OAPV_CS_GET_BIT_DEPTH(frm->imgb->cs) != args_var->output_depth) {
590*abb65b4bSAndroid Build Coastguard Worker if(imgb_w == NULL) {
591*abb65b4bSAndroid Build Coastguard Worker imgb_w = imgb_create(frm->imgb->w[0], frm->imgb->h[0],
592*abb65b4bSAndroid Build Coastguard Worker OAPV_CS_SET(OAPV_CS_GET_FORMAT(frm->imgb->cs), args_var->output_depth, 0));
593*abb65b4bSAndroid Build Coastguard Worker if(imgb_w == NULL) {
594*abb65b4bSAndroid Build Coastguard Worker logerr("cannot allocate image buffer (w:%d, h:%d, cs:%d)\n",
595*abb65b4bSAndroid Build Coastguard Worker frm->imgb->w[0], frm->imgb->h[0], frm->imgb->cs);
596*abb65b4bSAndroid Build Coastguard Worker ret = -1;
597*abb65b4bSAndroid Build Coastguard Worker goto ERR;
598*abb65b4bSAndroid Build Coastguard Worker }
599*abb65b4bSAndroid Build Coastguard Worker }
600*abb65b4bSAndroid Build Coastguard Worker imgb_cpy(imgb_w, frm->imgb);
601*abb65b4bSAndroid Build Coastguard Worker imgb_o = imgb_w;
602*abb65b4bSAndroid Build Coastguard Worker }
603*abb65b4bSAndroid Build Coastguard Worker else {
604*abb65b4bSAndroid Build Coastguard Worker imgb_o = frm->imgb;
605*abb65b4bSAndroid Build Coastguard Worker }
606*abb65b4bSAndroid Build Coastguard Worker
607*abb65b4bSAndroid Build Coastguard Worker if(strlen(args_var->fname_out)) {
608*abb65b4bSAndroid Build Coastguard Worker if(frm_cnt[i] == 0 && is_y4m) {
609*abb65b4bSAndroid Build Coastguard Worker if(write_y4m_header(args_var->fname_out, imgb_o)) {
610*abb65b4bSAndroid Build Coastguard Worker logerr("cannot write Y4M header\n");
611*abb65b4bSAndroid Build Coastguard Worker ret = -1;
612*abb65b4bSAndroid Build Coastguard Worker goto END;
613*abb65b4bSAndroid Build Coastguard Worker }
614*abb65b4bSAndroid Build Coastguard Worker }
615*abb65b4bSAndroid Build Coastguard Worker write_dec_img(args_var->fname_out, imgb_o, is_y4m);
616*abb65b4bSAndroid Build Coastguard Worker }
617*abb65b4bSAndroid Build Coastguard Worker frm_cnt[i]++;
618*abb65b4bSAndroid Build Coastguard Worker }
619*abb65b4bSAndroid Build Coastguard Worker }
620*abb65b4bSAndroid Build Coastguard Worker au_cnt++;
621*abb65b4bSAndroid Build Coastguard Worker oapvm_rem_all(mid); // remove all metadata for next au decoding
622*abb65b4bSAndroid Build Coastguard Worker fflush(stdout);
623*abb65b4bSAndroid Build Coastguard Worker fflush(stderr);
624*abb65b4bSAndroid Build Coastguard Worker }
625*abb65b4bSAndroid Build Coastguard Worker
626*abb65b4bSAndroid Build Coastguard Worker END:
627*abb65b4bSAndroid Build Coastguard Worker logv2_line("Summary");
628*abb65b4bSAndroid Build Coastguard Worker logv2("Processed access units = %d\n", au_cnt);
629*abb65b4bSAndroid Build Coastguard Worker int total_frame_count = 0;
630*abb65b4bSAndroid Build Coastguard Worker for(i = 0; i < OAPV_MAX_NUM_FRAMES; i++)
631*abb65b4bSAndroid Build Coastguard Worker total_frame_count += frm_cnt[i];
632*abb65b4bSAndroid Build Coastguard Worker logv2("Decoded frame count = %d\n", total_frame_count);
633*abb65b4bSAndroid Build Coastguard Worker if(total_frame_count > 0) {
634*abb65b4bSAndroid Build Coastguard Worker logv2("Total decoding time = %d msec,", (int)oapv_clk_msec(clk_tot));
635*abb65b4bSAndroid Build Coastguard Worker logv2(" %.3f sec\n", (float)(oapv_clk_msec(clk_tot) / 1000.0));
636*abb65b4bSAndroid Build Coastguard Worker logv2("Average decoding time for a frame = %d msec\n", (int)oapv_clk_msec(clk_tot) / total_frame_count);
637*abb65b4bSAndroid Build Coastguard Worker logv2("Average decoding speed = %.3f frames/sec\n", ((float)total_frame_count * 1000) / ((float)oapv_clk_msec(clk_tot)));
638*abb65b4bSAndroid Build Coastguard Worker }
639*abb65b4bSAndroid Build Coastguard Worker logv2_line(NULL);
640*abb65b4bSAndroid Build Coastguard Worker
641*abb65b4bSAndroid Build Coastguard Worker ERR:
642*abb65b4bSAndroid Build Coastguard Worker if(did)
643*abb65b4bSAndroid Build Coastguard Worker oapvd_delete(did);
644*abb65b4bSAndroid Build Coastguard Worker
645*abb65b4bSAndroid Build Coastguard Worker if(mid)
646*abb65b4bSAndroid Build Coastguard Worker oapvm_delete(mid);
647*abb65b4bSAndroid Build Coastguard Worker
648*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < ofrms.num_frms; i++) {
649*abb65b4bSAndroid Build Coastguard Worker if(ofrms.frm[i].imgb != NULL) {
650*abb65b4bSAndroid Build Coastguard Worker ofrms.frm[i].imgb->release(ofrms.frm[i].imgb);
651*abb65b4bSAndroid Build Coastguard Worker }
652*abb65b4bSAndroid Build Coastguard Worker }
653*abb65b4bSAndroid Build Coastguard Worker if(imgb_w != NULL)
654*abb65b4bSAndroid Build Coastguard Worker imgb_w->release(imgb_w);
655*abb65b4bSAndroid Build Coastguard Worker if(fp_bs)
656*abb65b4bSAndroid Build Coastguard Worker fclose(fp_bs);
657*abb65b4bSAndroid Build Coastguard Worker if(bs_buf)
658*abb65b4bSAndroid Build Coastguard Worker free(bs_buf);
659*abb65b4bSAndroid Build Coastguard Worker if(args)
660*abb65b4bSAndroid Build Coastguard Worker args->release(args);
661*abb65b4bSAndroid Build Coastguard Worker if(args_var)
662*abb65b4bSAndroid Build Coastguard Worker free(args_var);
663*abb65b4bSAndroid Build Coastguard Worker return ret;
664*abb65b4bSAndroid Build Coastguard Worker }
665