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)
38*abb65b4bSAndroid Build Coastguard Worker #define MAX_NUM_FRMS (1) // supports only 1-frame in an access unit
39*abb65b4bSAndroid Build Coastguard Worker #define FRM_IDX (0) // supports only 1-frame in an access unit
40*abb65b4bSAndroid Build Coastguard Worker #define MAX_NUM_CC (OAPV_MAX_CC) // Max number of color componets (upto 4:4:4:4)
41*abb65b4bSAndroid Build Coastguard Worker
42*abb65b4bSAndroid Build Coastguard Worker typedef enum _STATES {
43*abb65b4bSAndroid Build Coastguard Worker STATE_ENCODING,
44*abb65b4bSAndroid Build Coastguard Worker STATE_SKIPPING,
45*abb65b4bSAndroid Build Coastguard Worker STATE_STOP
46*abb65b4bSAndroid Build Coastguard Worker } STATES;
47*abb65b4bSAndroid Build Coastguard Worker
48*abb65b4bSAndroid Build Coastguard Worker // clang-format off
49*abb65b4bSAndroid Build Coastguard Worker
50*abb65b4bSAndroid Build Coastguard Worker /* define various command line options as a table */
51*abb65b4bSAndroid Build Coastguard Worker static const args_opt_t enc_args_opts[] = {
52*abb65b4bSAndroid Build Coastguard Worker {
53*abb65b4bSAndroid Build Coastguard Worker 'v', "verbose", ARGS_VAL_TYPE_INTEGER, 0, NULL,
54*abb65b4bSAndroid Build Coastguard Worker "verbose (log) level\n"
55*abb65b4bSAndroid Build Coastguard Worker " - 0: no message\n"
56*abb65b4bSAndroid Build Coastguard Worker " - 1: only error message\n"
57*abb65b4bSAndroid Build Coastguard Worker " - 2: simple messages\n"
58*abb65b4bSAndroid Build Coastguard Worker " - 3: frame-level messages"
59*abb65b4bSAndroid Build Coastguard Worker },
60*abb65b4bSAndroid Build Coastguard Worker {
61*abb65b4bSAndroid Build Coastguard Worker 'i', "input", ARGS_VAL_TYPE_STRING | ARGS_VAL_TYPE_MANDATORY, 0, NULL,
62*abb65b4bSAndroid Build Coastguard Worker "file name of input video"
63*abb65b4bSAndroid Build Coastguard Worker },
64*abb65b4bSAndroid Build Coastguard Worker {
65*abb65b4bSAndroid Build Coastguard Worker 'o', "output", ARGS_VAL_TYPE_STRING, 0, NULL,
66*abb65b4bSAndroid Build Coastguard Worker "file name of output bitstream"
67*abb65b4bSAndroid Build Coastguard Worker },
68*abb65b4bSAndroid Build Coastguard Worker {
69*abb65b4bSAndroid Build Coastguard Worker 'r', "recon", ARGS_VAL_TYPE_STRING, 0, NULL,
70*abb65b4bSAndroid Build Coastguard Worker "file name of reconstructed video"
71*abb65b4bSAndroid Build Coastguard Worker },
72*abb65b4bSAndroid Build Coastguard Worker {
73*abb65b4bSAndroid Build Coastguard Worker 'w', "width", ARGS_VAL_TYPE_INTEGER | ARGS_VAL_TYPE_MANDATORY, 0, NULL,
74*abb65b4bSAndroid Build Coastguard Worker "pixel width of input video"
75*abb65b4bSAndroid Build Coastguard Worker },
76*abb65b4bSAndroid Build Coastguard Worker {
77*abb65b4bSAndroid Build Coastguard Worker 'h', "height", ARGS_VAL_TYPE_INTEGER | ARGS_VAL_TYPE_MANDATORY, 0, NULL,
78*abb65b4bSAndroid Build Coastguard Worker "pixel height of input video"
79*abb65b4bSAndroid Build Coastguard Worker },
80*abb65b4bSAndroid Build Coastguard Worker {
81*abb65b4bSAndroid Build Coastguard Worker 'q', "qp", ARGS_VAL_TYPE_INTEGER, 0, NULL,
82*abb65b4bSAndroid Build Coastguard Worker "QP value (0~51)"
83*abb65b4bSAndroid Build Coastguard Worker },
84*abb65b4bSAndroid Build Coastguard Worker {
85*abb65b4bSAndroid Build Coastguard Worker 'z', "fps", ARGS_VAL_TYPE_STRING | ARGS_VAL_TYPE_MANDATORY, 0, NULL,
86*abb65b4bSAndroid Build Coastguard Worker "frame rate (frame per second))"
87*abb65b4bSAndroid Build Coastguard Worker },
88*abb65b4bSAndroid Build Coastguard Worker {
89*abb65b4bSAndroid Build Coastguard Worker 'm', "threads", ARGS_VAL_TYPE_INTEGER, 0, NULL,
90*abb65b4bSAndroid Build Coastguard Worker "force to use a specific number of threads"
91*abb65b4bSAndroid Build Coastguard Worker },
92*abb65b4bSAndroid Build Coastguard Worker {
93*abb65b4bSAndroid Build Coastguard Worker ARGS_NO_KEY, "preset", ARGS_VAL_TYPE_STRING, 0, NULL,
94*abb65b4bSAndroid Build Coastguard Worker "encoder preset [fastest, fast, medium, slow, placebo]"
95*abb65b4bSAndroid Build Coastguard Worker },
96*abb65b4bSAndroid Build Coastguard Worker {
97*abb65b4bSAndroid Build Coastguard Worker 'd', "input-depth", ARGS_VAL_TYPE_INTEGER, 0, NULL,
98*abb65b4bSAndroid Build Coastguard Worker "input bit depth (8, 10) "
99*abb65b4bSAndroid Build Coastguard Worker },
100*abb65b4bSAndroid Build Coastguard Worker {
101*abb65b4bSAndroid Build Coastguard Worker ARGS_NO_KEY, "input-csp", ARGS_VAL_TYPE_INTEGER, 0, NULL,
102*abb65b4bSAndroid Build Coastguard Worker "input color space (chroma format)\n"
103*abb65b4bSAndroid Build Coastguard Worker " - 0: YUV400\n"
104*abb65b4bSAndroid Build Coastguard Worker " - 1: YUV420\n"
105*abb65b4bSAndroid Build Coastguard Worker " - 2: YUV422\n"
106*abb65b4bSAndroid Build Coastguard Worker " - 3: YUV444\n"
107*abb65b4bSAndroid Build Coastguard Worker " - 4: YUV4444\n"
108*abb65b4bSAndroid Build Coastguard Worker " - 5: P2(Planar Y, Combined UV, 422)"
109*abb65b4bSAndroid Build Coastguard Worker },
110*abb65b4bSAndroid Build Coastguard Worker {
111*abb65b4bSAndroid Build Coastguard Worker ARGS_NO_KEY, "profile", ARGS_VAL_TYPE_STRING, 0, NULL,
112*abb65b4bSAndroid Build Coastguard Worker "profile setting flag (422-10)"
113*abb65b4bSAndroid Build Coastguard Worker },
114*abb65b4bSAndroid Build Coastguard Worker {
115*abb65b4bSAndroid Build Coastguard Worker ARGS_NO_KEY, "level", ARGS_VAL_TYPE_STRING, 0, NULL,
116*abb65b4bSAndroid Build Coastguard Worker "level setting (1, 1.1, 2, 2.1, 3, 3.1, 4, 4.1, 5, 5.1, 6, 6.1, 7, 7.1)"
117*abb65b4bSAndroid Build Coastguard Worker },
118*abb65b4bSAndroid Build Coastguard Worker {
119*abb65b4bSAndroid Build Coastguard Worker ARGS_NO_KEY, "band", ARGS_VAL_TYPE_INTEGER, 0, NULL,
120*abb65b4bSAndroid Build Coastguard Worker "band setting (0, 1, 2, 3)"
121*abb65b4bSAndroid Build Coastguard Worker },
122*abb65b4bSAndroid Build Coastguard Worker {
123*abb65b4bSAndroid Build Coastguard Worker ARGS_NO_KEY, "max-au", ARGS_VAL_TYPE_INTEGER, 0, NULL,
124*abb65b4bSAndroid Build Coastguard Worker "maximum number of access units to be encoded"
125*abb65b4bSAndroid Build Coastguard Worker },
126*abb65b4bSAndroid Build Coastguard Worker {
127*abb65b4bSAndroid Build Coastguard Worker ARGS_NO_KEY, "seek", ARGS_VAL_TYPE_INTEGER, 0, NULL,
128*abb65b4bSAndroid Build Coastguard Worker "number of skipped access units before encoding"
129*abb65b4bSAndroid Build Coastguard Worker },
130*abb65b4bSAndroid Build Coastguard Worker {
131*abb65b4bSAndroid Build Coastguard Worker ARGS_NO_KEY, "qp-cb-offset", ARGS_VAL_TYPE_INTEGER, 0, NULL,
132*abb65b4bSAndroid Build Coastguard Worker "QP offset value for Cb"
133*abb65b4bSAndroid Build Coastguard Worker },
134*abb65b4bSAndroid Build Coastguard Worker {
135*abb65b4bSAndroid Build Coastguard Worker ARGS_NO_KEY, "qp-cr-offset", ARGS_VAL_TYPE_INTEGER, 0, NULL,
136*abb65b4bSAndroid Build Coastguard Worker "QP offset value for Cr"
137*abb65b4bSAndroid Build Coastguard Worker },
138*abb65b4bSAndroid Build Coastguard Worker {
139*abb65b4bSAndroid Build Coastguard Worker ARGS_NO_KEY, "tile-w-mb", ARGS_VAL_TYPE_INTEGER, 0, NULL,
140*abb65b4bSAndroid Build Coastguard Worker "width of tile in units of MBs"
141*abb65b4bSAndroid Build Coastguard Worker },
142*abb65b4bSAndroid Build Coastguard Worker {
143*abb65b4bSAndroid Build Coastguard Worker ARGS_NO_KEY, "tile-h-mb", ARGS_VAL_TYPE_INTEGER, 0, NULL,
144*abb65b4bSAndroid Build Coastguard Worker "height of tile in units of MBs"
145*abb65b4bSAndroid Build Coastguard Worker },
146*abb65b4bSAndroid Build Coastguard Worker {
147*abb65b4bSAndroid Build Coastguard Worker ARGS_NO_KEY, "bitrate", ARGS_VAL_TYPE_STRING, 0, NULL,
148*abb65b4bSAndroid Build Coastguard Worker "enable ABR rate control\n"
149*abb65b4bSAndroid Build Coastguard Worker " bitrate in terms of kilo-bits per second: Kbps(none,K,k), Mbps(M,m)\n"
150*abb65b4bSAndroid Build Coastguard Worker " ex) 100 = 100K = 0.1M"
151*abb65b4bSAndroid Build Coastguard Worker },
152*abb65b4bSAndroid Build Coastguard Worker {
153*abb65b4bSAndroid Build Coastguard Worker ARGS_NO_KEY, "use-filler", ARGS_VAL_TYPE_INTEGER, 0, NULL,
154*abb65b4bSAndroid Build Coastguard Worker "user filler flag"
155*abb65b4bSAndroid Build Coastguard Worker },
156*abb65b4bSAndroid Build Coastguard Worker {
157*abb65b4bSAndroid Build Coastguard Worker ARGS_NO_KEY, "q-matrix-y", ARGS_VAL_TYPE_STRING, 0, NULL,
158*abb65b4bSAndroid Build Coastguard Worker "custom quantization matrix for Y \"q1 q2 ... q63 q64\""
159*abb65b4bSAndroid Build Coastguard Worker },
160*abb65b4bSAndroid Build Coastguard Worker {
161*abb65b4bSAndroid Build Coastguard Worker ARGS_NO_KEY, "q-matrix-u", ARGS_VAL_TYPE_STRING, 0, NULL,
162*abb65b4bSAndroid Build Coastguard Worker "custom quantization matrix for U \"q1 q2 ... q63 q64\""
163*abb65b4bSAndroid Build Coastguard Worker },
164*abb65b4bSAndroid Build Coastguard Worker {
165*abb65b4bSAndroid Build Coastguard Worker ARGS_NO_KEY, "q-matrix-v", ARGS_VAL_TYPE_STRING, 0, NULL,
166*abb65b4bSAndroid Build Coastguard Worker "custom quantization matrix for V \"q1 q2 ... q63 q64\""
167*abb65b4bSAndroid Build Coastguard Worker },
168*abb65b4bSAndroid Build Coastguard Worker {
169*abb65b4bSAndroid Build Coastguard Worker ARGS_NO_KEY, "q-matrix-x", ARGS_VAL_TYPE_STRING, 0, NULL,
170*abb65b4bSAndroid Build Coastguard Worker "custom quantization matrix for X \"q1 q2 ... q63 q64\""
171*abb65b4bSAndroid Build Coastguard Worker },
172*abb65b4bSAndroid Build Coastguard Worker {
173*abb65b4bSAndroid Build Coastguard Worker ARGS_NO_KEY, "hash", ARGS_VAL_TYPE_NONE, 0, NULL,
174*abb65b4bSAndroid Build Coastguard Worker "embed frame hash value for conformance checking in decoding"
175*abb65b4bSAndroid Build Coastguard Worker },
176*abb65b4bSAndroid Build Coastguard Worker {ARGS_END_KEY, "", ARGS_VAL_TYPE_NONE, 0, NULL, ""} /* termination */
177*abb65b4bSAndroid Build Coastguard Worker };
178*abb65b4bSAndroid Build Coastguard Worker
179*abb65b4bSAndroid Build Coastguard Worker // clang-format on
180*abb65b4bSAndroid Build Coastguard Worker
181*abb65b4bSAndroid Build Coastguard Worker #define NUM_ARGS_OPT ((int)(sizeof(enc_args_opts) / sizeof(enc_args_opts[0])))
182*abb65b4bSAndroid Build Coastguard Worker
183*abb65b4bSAndroid Build Coastguard Worker typedef struct args_var {
184*abb65b4bSAndroid Build Coastguard Worker /* variables for options */
185*abb65b4bSAndroid Build Coastguard Worker char fname_inp[256];
186*abb65b4bSAndroid Build Coastguard Worker char fname_out[256];
187*abb65b4bSAndroid Build Coastguard Worker char fname_rec[256];
188*abb65b4bSAndroid Build Coastguard Worker int max_au;
189*abb65b4bSAndroid Build Coastguard Worker int hash;
190*abb65b4bSAndroid Build Coastguard Worker int input_depth;
191*abb65b4bSAndroid Build Coastguard Worker int input_csp;
192*abb65b4bSAndroid Build Coastguard Worker int seek;
193*abb65b4bSAndroid Build Coastguard Worker int threads;
194*abb65b4bSAndroid Build Coastguard Worker char profile[32];
195*abb65b4bSAndroid Build Coastguard Worker char level[32];
196*abb65b4bSAndroid Build Coastguard Worker int band;
197*abb65b4bSAndroid Build Coastguard Worker char bitrate[64];
198*abb65b4bSAndroid Build Coastguard Worker char fps[256];
199*abb65b4bSAndroid Build Coastguard Worker char q_matrix_y[512];
200*abb65b4bSAndroid Build Coastguard Worker char q_matrix_u[512];
201*abb65b4bSAndroid Build Coastguard Worker char q_matrix_v[512];
202*abb65b4bSAndroid Build Coastguard Worker char q_matrix_x[512];
203*abb65b4bSAndroid Build Coastguard Worker char preset[32];
204*abb65b4bSAndroid Build Coastguard Worker oapve_param_t *param;
205*abb65b4bSAndroid Build Coastguard Worker } args_var_t;
206*abb65b4bSAndroid Build Coastguard Worker
args_init_vars(args_parser_t * args,oapve_param_t * param)207*abb65b4bSAndroid Build Coastguard Worker static args_var_t *args_init_vars(args_parser_t *args, oapve_param_t *param)
208*abb65b4bSAndroid Build Coastguard Worker {
209*abb65b4bSAndroid Build Coastguard Worker args_opt_t *opts;
210*abb65b4bSAndroid Build Coastguard Worker args_var_t *vars;
211*abb65b4bSAndroid Build Coastguard Worker
212*abb65b4bSAndroid Build Coastguard Worker opts = args->opts;
213*abb65b4bSAndroid Build Coastguard Worker vars = malloc(sizeof(args_var_t));
214*abb65b4bSAndroid Build Coastguard Worker assert_rv(vars != NULL, NULL);
215*abb65b4bSAndroid Build Coastguard Worker memset(vars, 0, sizeof(args_var_t));
216*abb65b4bSAndroid Build Coastguard Worker
217*abb65b4bSAndroid Build Coastguard Worker vars->param = param;
218*abb65b4bSAndroid Build Coastguard Worker
219*abb65b4bSAndroid Build Coastguard Worker /*args_set_variable_by_key_long(opts, "config", args->fname_cfg);*/
220*abb65b4bSAndroid Build Coastguard Worker args_set_variable_by_key_long(opts, "input", vars->fname_inp);
221*abb65b4bSAndroid Build Coastguard Worker args_set_variable_by_key_long(opts, "output", vars->fname_out);
222*abb65b4bSAndroid Build Coastguard Worker args_set_variable_by_key_long(opts, "recon", vars->fname_rec);
223*abb65b4bSAndroid Build Coastguard Worker args_set_variable_by_key_long(opts, "max-au", &vars->max_au);
224*abb65b4bSAndroid Build Coastguard Worker args_set_variable_by_key_long(opts, "hash", &vars->hash);
225*abb65b4bSAndroid Build Coastguard Worker args_set_variable_by_key_long(opts, "verbose", &op_verbose);
226*abb65b4bSAndroid Build Coastguard Worker op_verbose = VERBOSE_SIMPLE; /* default */
227*abb65b4bSAndroid Build Coastguard Worker args_set_variable_by_key_long(opts, "input-depth", &vars->input_depth);
228*abb65b4bSAndroid Build Coastguard Worker vars->input_depth = 10; /* default */
229*abb65b4bSAndroid Build Coastguard Worker args_set_variable_by_key_long(opts, "input-csp", &vars->input_csp);
230*abb65b4bSAndroid Build Coastguard Worker vars->input_csp = -1;
231*abb65b4bSAndroid Build Coastguard Worker args_set_variable_by_key_long(opts, "seek", &vars->seek);
232*abb65b4bSAndroid Build Coastguard Worker args_set_variable_by_key_long(opts, "profile", vars->profile);
233*abb65b4bSAndroid Build Coastguard Worker strncpy(vars->profile, "422-10", sizeof(vars->profile) - 1);
234*abb65b4bSAndroid Build Coastguard Worker args_set_variable_by_key_long(opts, "level", vars->level);
235*abb65b4bSAndroid Build Coastguard Worker strncpy(vars->level, "4.1", sizeof(vars->level) - 1);
236*abb65b4bSAndroid Build Coastguard Worker args_set_variable_by_key_long(opts, "band", &vars->band);
237*abb65b4bSAndroid Build Coastguard Worker vars->band = 2; /* default */
238*abb65b4bSAndroid Build Coastguard Worker args_set_variable_by_key_long(opts, "bitrate", vars->bitrate);
239*abb65b4bSAndroid Build Coastguard Worker args_set_variable_by_key_long(opts, "fps", vars->fps);
240*abb65b4bSAndroid Build Coastguard Worker strncpy(vars->fps, "60", sizeof(vars->fps) - 1);
241*abb65b4bSAndroid Build Coastguard Worker args_set_variable_by_key_long(opts, "q-matrix-y", vars->q_matrix_y);
242*abb65b4bSAndroid Build Coastguard Worker strncpy(vars->q_matrix_y, "", sizeof(vars->q_matrix_y) - 1);
243*abb65b4bSAndroid Build Coastguard Worker args_set_variable_by_key_long(opts, "q-matrix-u", vars->q_matrix_u);
244*abb65b4bSAndroid Build Coastguard Worker strncpy(vars->q_matrix_u, "", sizeof(vars->q_matrix_y) - 1);
245*abb65b4bSAndroid Build Coastguard Worker args_set_variable_by_key_long(opts, "q-matrix-v", vars->q_matrix_v);
246*abb65b4bSAndroid Build Coastguard Worker strncpy(vars->q_matrix_v, "", sizeof(vars->q_matrix_y) - 1);
247*abb65b4bSAndroid Build Coastguard Worker args_set_variable_by_key_long(opts, "q-matrix-x", vars->q_matrix_x);
248*abb65b4bSAndroid Build Coastguard Worker strncpy(vars->q_matrix_x, "", sizeof(vars->q_matrix_x) - 1);
249*abb65b4bSAndroid Build Coastguard Worker args_set_variable_by_key_long(opts, "threads", &vars->threads);
250*abb65b4bSAndroid Build Coastguard Worker vars->threads = 1; /* default */
251*abb65b4bSAndroid Build Coastguard Worker args_set_variable_by_key_long(opts, "preset", vars->preset);
252*abb65b4bSAndroid Build Coastguard Worker strncpy(vars->preset, "", sizeof(vars->preset) - 1);
253*abb65b4bSAndroid Build Coastguard Worker
254*abb65b4bSAndroid Build Coastguard Worker ARGS_SET_PARAM_VAR_KEY(opts, param, w);
255*abb65b4bSAndroid Build Coastguard Worker ARGS_SET_PARAM_VAR_KEY(opts, param, h);
256*abb65b4bSAndroid Build Coastguard Worker ARGS_SET_PARAM_VAR_KEY_LONG(opts, param, qp);
257*abb65b4bSAndroid Build Coastguard Worker ARGS_SET_PARAM_VAR_KEY_LONG(opts, param, use_filler);
258*abb65b4bSAndroid Build Coastguard Worker ARGS_SET_PARAM_VAR_KEY_LONG(opts, param, tile_w_mb);
259*abb65b4bSAndroid Build Coastguard Worker ARGS_SET_PARAM_VAR_KEY_LONG(opts, param, tile_h_mb);
260*abb65b4bSAndroid Build Coastguard Worker ARGS_SET_PARAM_VAR_KEY_LONG(opts, param, qp_cb_offset);
261*abb65b4bSAndroid Build Coastguard Worker ARGS_SET_PARAM_VAR_KEY_LONG(opts, param, qp_cr_offset);
262*abb65b4bSAndroid Build Coastguard Worker
263*abb65b4bSAndroid Build Coastguard Worker return vars;
264*abb65b4bSAndroid Build Coastguard Worker }
265*abb65b4bSAndroid Build Coastguard Worker
print_usage(const char ** argv)266*abb65b4bSAndroid Build Coastguard Worker static void print_usage(const char **argv)
267*abb65b4bSAndroid Build Coastguard Worker {
268*abb65b4bSAndroid Build Coastguard Worker int i;
269*abb65b4bSAndroid Build Coastguard Worker char str[1024];
270*abb65b4bSAndroid Build Coastguard Worker args_parser_t *args;
271*abb65b4bSAndroid Build Coastguard Worker args_var_t *args_var = NULL;
272*abb65b4bSAndroid Build Coastguard Worker oapve_param_t default_param;
273*abb65b4bSAndroid Build Coastguard Worker
274*abb65b4bSAndroid Build Coastguard Worker oapve_param_default(&default_param);
275*abb65b4bSAndroid Build Coastguard Worker args = args_create(enc_args_opts, NUM_ARGS_OPT);
276*abb65b4bSAndroid Build Coastguard Worker if(args == NULL)
277*abb65b4bSAndroid Build Coastguard Worker goto ERR;
278*abb65b4bSAndroid Build Coastguard Worker args_var = args_init_vars(args, &default_param);
279*abb65b4bSAndroid Build Coastguard Worker if(args_var == NULL)
280*abb65b4bSAndroid Build Coastguard Worker goto ERR;
281*abb65b4bSAndroid Build Coastguard Worker
282*abb65b4bSAndroid Build Coastguard Worker logv2("Syntax: \n");
283*abb65b4bSAndroid Build Coastguard Worker logv2(" %s -i 'input-file' [ options ] \n\n", argv[0]);
284*abb65b4bSAndroid Build Coastguard Worker
285*abb65b4bSAndroid Build Coastguard Worker logv2("Options:\n");
286*abb65b4bSAndroid Build Coastguard Worker logv2(" --help\n : list options\n");
287*abb65b4bSAndroid Build Coastguard Worker for(i = 0; i < args->num_option; i++) {
288*abb65b4bSAndroid Build Coastguard Worker if(args->get_help(args, i, str) < 0)
289*abb65b4bSAndroid Build Coastguard Worker return;
290*abb65b4bSAndroid Build Coastguard Worker logv2("%s\n", str);
291*abb65b4bSAndroid Build Coastguard Worker }
292*abb65b4bSAndroid Build Coastguard Worker
293*abb65b4bSAndroid Build Coastguard Worker ERR:
294*abb65b4bSAndroid Build Coastguard Worker if(args)
295*abb65b4bSAndroid Build Coastguard Worker args->release(args);
296*abb65b4bSAndroid Build Coastguard Worker if(args_var)
297*abb65b4bSAndroid Build Coastguard Worker free(args_var);
298*abb65b4bSAndroid Build Coastguard Worker }
299*abb65b4bSAndroid Build Coastguard Worker
check_conf(oapve_cdesc_t * cdesc,args_var_t * vars)300*abb65b4bSAndroid Build Coastguard Worker static int check_conf(oapve_cdesc_t *cdesc, args_var_t *vars)
301*abb65b4bSAndroid Build Coastguard Worker {
302*abb65b4bSAndroid Build Coastguard Worker int i;
303*abb65b4bSAndroid Build Coastguard Worker for(i = 0; i < cdesc->max_num_frms; i++) {
304*abb65b4bSAndroid Build Coastguard Worker if(vars->hash && strlen(vars->fname_rec) == 0) {
305*abb65b4bSAndroid Build Coastguard Worker logerr("cannot use frame hash without reconstructed picture option!\n");
306*abb65b4bSAndroid Build Coastguard Worker return -1;
307*abb65b4bSAndroid Build Coastguard Worker }
308*abb65b4bSAndroid Build Coastguard Worker }
309*abb65b4bSAndroid Build Coastguard Worker return 0;
310*abb65b4bSAndroid Build Coastguard Worker }
311*abb65b4bSAndroid Build Coastguard Worker
set_extra_config(oapve_t id,args_var_t * vars,oapve_param_t * param)312*abb65b4bSAndroid Build Coastguard Worker static int set_extra_config(oapve_t id, args_var_t *vars, oapve_param_t *param)
313*abb65b4bSAndroid Build Coastguard Worker {
314*abb65b4bSAndroid Build Coastguard Worker int ret = 0, size, value;
315*abb65b4bSAndroid Build Coastguard Worker
316*abb65b4bSAndroid Build Coastguard Worker if(vars->hash) {
317*abb65b4bSAndroid Build Coastguard Worker value = 1;
318*abb65b4bSAndroid Build Coastguard Worker size = 4;
319*abb65b4bSAndroid Build Coastguard Worker ret = oapve_config(id, OAPV_CFG_SET_USE_FRM_HASH, &value, &size);
320*abb65b4bSAndroid Build Coastguard Worker if(OAPV_FAILED(ret)) {
321*abb65b4bSAndroid Build Coastguard Worker logerr("failed to set config for using frame hash\n");
322*abb65b4bSAndroid Build Coastguard Worker return -1;
323*abb65b4bSAndroid Build Coastguard Worker }
324*abb65b4bSAndroid Build Coastguard Worker }
325*abb65b4bSAndroid Build Coastguard Worker return ret;
326*abb65b4bSAndroid Build Coastguard Worker }
327*abb65b4bSAndroid Build Coastguard Worker
print_commandline(int argc,const char ** argv)328*abb65b4bSAndroid Build Coastguard Worker static void print_commandline(int argc, const char **argv)
329*abb65b4bSAndroid Build Coastguard Worker {
330*abb65b4bSAndroid Build Coastguard Worker int i;
331*abb65b4bSAndroid Build Coastguard Worker if(op_verbose < VERBOSE_FRAME)
332*abb65b4bSAndroid Build Coastguard Worker return;
333*abb65b4bSAndroid Build Coastguard Worker
334*abb65b4bSAndroid Build Coastguard Worker logv3("Command line: ");
335*abb65b4bSAndroid Build Coastguard Worker for(i = 0; i < argc; i++) {
336*abb65b4bSAndroid Build Coastguard Worker logv3("%s ", argv[i]);
337*abb65b4bSAndroid Build Coastguard Worker }
338*abb65b4bSAndroid Build Coastguard Worker logv3("\n\n");
339*abb65b4bSAndroid Build Coastguard Worker }
340*abb65b4bSAndroid Build Coastguard Worker
print_config(args_var_t * vars,oapve_param_t * param)341*abb65b4bSAndroid Build Coastguard Worker static void print_config(args_var_t *vars, oapve_param_t *param)
342*abb65b4bSAndroid Build Coastguard Worker {
343*abb65b4bSAndroid Build Coastguard Worker if(op_verbose < VERBOSE_FRAME)
344*abb65b4bSAndroid Build Coastguard Worker return;
345*abb65b4bSAndroid Build Coastguard Worker
346*abb65b4bSAndroid Build Coastguard Worker logv3_line("Configurations");
347*abb65b4bSAndroid Build Coastguard Worker logv3("Input sequence : %s \n", vars->fname_inp);
348*abb65b4bSAndroid Build Coastguard Worker if(strlen(vars->fname_out) > 0) {
349*abb65b4bSAndroid Build Coastguard Worker logv3("Output bitstream : %s \n", vars->fname_out);
350*abb65b4bSAndroid Build Coastguard Worker }
351*abb65b4bSAndroid Build Coastguard Worker if(strlen(vars->fname_rec) > 0) {
352*abb65b4bSAndroid Build Coastguard Worker logv3("Reconstructed sequence : %s \n", vars->fname_rec);
353*abb65b4bSAndroid Build Coastguard Worker }
354*abb65b4bSAndroid Build Coastguard Worker logv3(" profile = %s\n", vars->profile);
355*abb65b4bSAndroid Build Coastguard Worker logv3(" width = %d\n", param->w);
356*abb65b4bSAndroid Build Coastguard Worker logv3(" height = %d\n", param->h);
357*abb65b4bSAndroid Build Coastguard Worker logv3(" FPS = %.2f\n", (float)param->fps_num / param->fps_den);
358*abb65b4bSAndroid Build Coastguard Worker logv3(" QP = %d\n", param->qp);
359*abb65b4bSAndroid Build Coastguard Worker logv3(" max number of AUs = %d\n", vars->max_au);
360*abb65b4bSAndroid Build Coastguard Worker logv3(" rate control type = %s\n", (param->rc_type == OAPV_RC_ABR) ? "average Bitrate" : "constant QP");
361*abb65b4bSAndroid Build Coastguard Worker if(param->rc_type == OAPV_RC_ABR) {
362*abb65b4bSAndroid Build Coastguard Worker logv3(" target bitrate = %dkbps\n", param->bitrate);
363*abb65b4bSAndroid Build Coastguard Worker }
364*abb65b4bSAndroid Build Coastguard Worker logv3(" tile size = %d x %d\n", param->tile_w_mb * OAPV_MB_W, param->tile_h_mb * OAPV_MB_H);
365*abb65b4bSAndroid Build Coastguard Worker }
366*abb65b4bSAndroid Build Coastguard Worker
print_stat_au(oapve_stat_t * stat,int au_cnt,oapve_param_t * param,int max_au,double bitrate_tot,oapv_clk_t clk_au,oapv_clk_t clk_tot)367*abb65b4bSAndroid Build Coastguard Worker static void print_stat_au(oapve_stat_t *stat, int au_cnt, oapve_param_t *param, int max_au, double bitrate_tot, oapv_clk_t clk_au, oapv_clk_t clk_tot)
368*abb65b4bSAndroid Build Coastguard Worker {
369*abb65b4bSAndroid Build Coastguard Worker if(op_verbose >= VERBOSE_FRAME) {
370*abb65b4bSAndroid Build Coastguard Worker logv3_line("");
371*abb65b4bSAndroid Build Coastguard Worker logv3("AU %-5d %10d-bytes %3d-frame(s) %10d msec\n", au_cnt, stat->write, stat->aui.num_frms, oapv_clk_msec(clk_au));
372*abb65b4bSAndroid Build Coastguard Worker }
373*abb65b4bSAndroid Build Coastguard Worker else {
374*abb65b4bSAndroid Build Coastguard Worker int total_time = ((int)oapv_clk_msec(clk_tot) / 1000);
375*abb65b4bSAndroid Build Coastguard Worker int h = total_time / 3600;
376*abb65b4bSAndroid Build Coastguard Worker total_time = total_time % 3600;
377*abb65b4bSAndroid Build Coastguard Worker int m = total_time / 60;
378*abb65b4bSAndroid Build Coastguard Worker total_time = total_time % 60;
379*abb65b4bSAndroid Build Coastguard Worker int s = total_time;
380*abb65b4bSAndroid Build Coastguard Worker double curr_bitrate = bitrate_tot;
381*abb65b4bSAndroid Build Coastguard Worker curr_bitrate *= (((float)param->fps_num / param->fps_den) * 8);
382*abb65b4bSAndroid Build Coastguard Worker curr_bitrate /= (au_cnt + 1);
383*abb65b4bSAndroid Build Coastguard Worker curr_bitrate /= 1000;
384*abb65b4bSAndroid Build Coastguard Worker logv2("[ %d / %d AU(s) ] [ %.2f AU/sec ] [ %.4f kbps ] [ %2dh %2dm %2ds ] \r",
385*abb65b4bSAndroid Build Coastguard Worker au_cnt, max_au, ((float)(au_cnt + 1) * 1000) / ((float)oapv_clk_msec(clk_tot)), curr_bitrate, h, m, s);
386*abb65b4bSAndroid Build Coastguard Worker fflush(stdout);
387*abb65b4bSAndroid Build Coastguard Worker }
388*abb65b4bSAndroid Build Coastguard Worker }
389*abb65b4bSAndroid Build Coastguard Worker
print_stat_frms(oapve_stat_t * stat,oapv_frms_t * ifrms,oapv_frms_t * rfrms,double psnr_avg[MAX_NUM_FRMS][MAX_NUM_CC])390*abb65b4bSAndroid Build Coastguard Worker static void print_stat_frms(oapve_stat_t *stat, oapv_frms_t *ifrms, oapv_frms_t *rfrms, double psnr_avg[MAX_NUM_FRMS][MAX_NUM_CC])
391*abb65b4bSAndroid Build Coastguard Worker {
392*abb65b4bSAndroid Build Coastguard Worker int i, j;
393*abb65b4bSAndroid Build Coastguard Worker oapv_frm_info_t *finfo;
394*abb65b4bSAndroid Build Coastguard Worker double psnr[MAX_NUM_FRMS][MAX_NUM_CC] = { 0 };
395*abb65b4bSAndroid Build Coastguard Worker
396*abb65b4bSAndroid Build Coastguard Worker assert(stat->aui.num_frms == ifrms->num_frms);
397*abb65b4bSAndroid Build Coastguard Worker assert(stat->aui.num_frms <= MAX_NUM_FRMS);
398*abb65b4bSAndroid Build Coastguard Worker
399*abb65b4bSAndroid Build Coastguard Worker // calculate PSNRs
400*abb65b4bSAndroid Build Coastguard Worker if(rfrms != NULL) {
401*abb65b4bSAndroid Build Coastguard Worker for(i = 0; i < stat->aui.num_frms; i++) {
402*abb65b4bSAndroid Build Coastguard Worker if(rfrms->frm[i].imgb) {
403*abb65b4bSAndroid Build Coastguard Worker measure_psnr(ifrms->frm[i].imgb, rfrms->frm[i].imgb, psnr[i], OAPV_CS_GET_BIT_DEPTH(ifrms->frm[i].imgb->cs));
404*abb65b4bSAndroid Build Coastguard Worker for(j = 0; j < MAX_NUM_CC; j++) {
405*abb65b4bSAndroid Build Coastguard Worker psnr_avg[i][j] += psnr[i][j];
406*abb65b4bSAndroid Build Coastguard Worker }
407*abb65b4bSAndroid Build Coastguard Worker }
408*abb65b4bSAndroid Build Coastguard Worker }
409*abb65b4bSAndroid Build Coastguard Worker }
410*abb65b4bSAndroid Build Coastguard Worker // print verbose messages
411*abb65b4bSAndroid Build Coastguard Worker if(op_verbose < VERBOSE_FRAME)
412*abb65b4bSAndroid Build Coastguard Worker return;
413*abb65b4bSAndroid Build Coastguard Worker
414*abb65b4bSAndroid Build Coastguard Worker finfo = stat->aui.frm_info;
415*abb65b4bSAndroid Build Coastguard Worker
416*abb65b4bSAndroid Build Coastguard Worker for(i = 0; i < stat->aui.num_frms; i++) {
417*abb65b4bSAndroid Build Coastguard Worker // clang-format off
418*abb65b4bSAndroid Build Coastguard Worker const char* str_frm_type = finfo[i].pbu_type == OAPV_PBU_TYPE_PRIMARY_FRAME ? "PRIMARY"
419*abb65b4bSAndroid Build Coastguard Worker : finfo[i].pbu_type == OAPV_PBU_TYPE_NON_PRIMARY_FRAME ? "NON-PRIMARY"
420*abb65b4bSAndroid Build Coastguard Worker : finfo[i].pbu_type == OAPV_PBU_TYPE_PREVIEW_FRAME ? "PREVIEW"
421*abb65b4bSAndroid Build Coastguard Worker : finfo[i].pbu_type == OAPV_PBU_TYPE_DEPTH_FRAME ? "DEPTH"
422*abb65b4bSAndroid Build Coastguard Worker : finfo[i].pbu_type == OAPV_PBU_TYPE_ALPHA_FRAME ? "ALPHA"
423*abb65b4bSAndroid Build Coastguard Worker : "UNKNOWN";
424*abb65b4bSAndroid Build Coastguard Worker // clang-format on
425*abb65b4bSAndroid Build Coastguard Worker
426*abb65b4bSAndroid Build Coastguard Worker logv3("- FRM %-2d GID %-5d %-11s %9d-bytes %8.4fdB %8.4fdB %8.4fdB\n",
427*abb65b4bSAndroid Build Coastguard Worker i, finfo[i].group_id, str_frm_type, stat->frm_size[i], psnr[i][0], psnr[i][1], psnr[i][2]);
428*abb65b4bSAndroid Build Coastguard Worker }
429*abb65b4bSAndroid Build Coastguard Worker fflush(stdout);
430*abb65b4bSAndroid Build Coastguard Worker fflush(stderr);
431*abb65b4bSAndroid Build Coastguard Worker }
432*abb65b4bSAndroid Build Coastguard Worker
kbps_str_to_int(char * str)433*abb65b4bSAndroid Build Coastguard Worker static int kbps_str_to_int(char *str)
434*abb65b4bSAndroid Build Coastguard Worker {
435*abb65b4bSAndroid Build Coastguard Worker int kbps;
436*abb65b4bSAndroid Build Coastguard Worker if(strchr(str, 'K') || strchr(str, 'k')) {
437*abb65b4bSAndroid Build Coastguard Worker char *tmp = strtok(str, "Kk ");
438*abb65b4bSAndroid Build Coastguard Worker kbps = (int)(atof(tmp));
439*abb65b4bSAndroid Build Coastguard Worker }
440*abb65b4bSAndroid Build Coastguard Worker else if(strchr(str, 'M') || strchr(str, 'm')) {
441*abb65b4bSAndroid Build Coastguard Worker char *tmp = strtok(str, "Mm ");
442*abb65b4bSAndroid Build Coastguard Worker kbps = (int)(atof(tmp) * 1000);
443*abb65b4bSAndroid Build Coastguard Worker }
444*abb65b4bSAndroid Build Coastguard Worker else {
445*abb65b4bSAndroid Build Coastguard Worker kbps = atoi(str);
446*abb65b4bSAndroid Build Coastguard Worker }
447*abb65b4bSAndroid Build Coastguard Worker return kbps;
448*abb65b4bSAndroid Build Coastguard Worker }
449*abb65b4bSAndroid Build Coastguard Worker
update_param(args_var_t * vars,oapve_param_t * param)450*abb65b4bSAndroid Build Coastguard Worker static int update_param(args_var_t *vars, oapve_param_t *param)
451*abb65b4bSAndroid Build Coastguard Worker {
452*abb65b4bSAndroid Build Coastguard Worker /* update reate controller parameters */
453*abb65b4bSAndroid Build Coastguard Worker if(strlen(vars->bitrate) > 0) {
454*abb65b4bSAndroid Build Coastguard Worker param->bitrate = kbps_str_to_int(vars->bitrate);
455*abb65b4bSAndroid Build Coastguard Worker param->rc_type = OAPV_RC_ABR;
456*abb65b4bSAndroid Build Coastguard Worker }
457*abb65b4bSAndroid Build Coastguard Worker
458*abb65b4bSAndroid Build Coastguard Worker /* update q_matrix */
459*abb65b4bSAndroid Build Coastguard Worker int len_y = (int)strlen(vars->q_matrix_y);
460*abb65b4bSAndroid Build Coastguard Worker if(len_y > 0) {
461*abb65b4bSAndroid Build Coastguard Worker param->use_q_matrix = 1;
462*abb65b4bSAndroid Build Coastguard Worker char *tmp = vars->q_matrix_y;
463*abb65b4bSAndroid Build Coastguard Worker int cnt = 0;
464*abb65b4bSAndroid Build Coastguard Worker int len_cnt = 0;
465*abb65b4bSAndroid Build Coastguard Worker while(len_cnt < len_y && cnt < OAPV_BLK_D) {
466*abb65b4bSAndroid Build Coastguard Worker sscanf(tmp, "%d", ¶m->q_matrix_y[cnt]);
467*abb65b4bSAndroid Build Coastguard Worker if(param->q_matrix_y[cnt] < 1 || param->q_matrix_y[cnt] > 255) {
468*abb65b4bSAndroid Build Coastguard Worker logerr("input value of q_matrix_y is invalid\n");
469*abb65b4bSAndroid Build Coastguard Worker return -1;
470*abb65b4bSAndroid Build Coastguard Worker }
471*abb65b4bSAndroid Build Coastguard Worker len_cnt += (int)log10(param->q_matrix_y[cnt]) + 2;
472*abb65b4bSAndroid Build Coastguard Worker tmp = vars->q_matrix_y + len_cnt;
473*abb65b4bSAndroid Build Coastguard Worker cnt++;
474*abb65b4bSAndroid Build Coastguard Worker }
475*abb65b4bSAndroid Build Coastguard Worker if(cnt < OAPV_BLK_D) {
476*abb65b4bSAndroid Build Coastguard Worker logerr("input number of q_matrix_y is not enough\n");
477*abb65b4bSAndroid Build Coastguard Worker return -1;
478*abb65b4bSAndroid Build Coastguard Worker }
479*abb65b4bSAndroid Build Coastguard Worker }
480*abb65b4bSAndroid Build Coastguard Worker
481*abb65b4bSAndroid Build Coastguard Worker int len_u = (int)strlen(vars->q_matrix_u);
482*abb65b4bSAndroid Build Coastguard Worker if(len_u > 0) {
483*abb65b4bSAndroid Build Coastguard Worker param->use_q_matrix = 1;
484*abb65b4bSAndroid Build Coastguard Worker char *tmp = vars->q_matrix_u;
485*abb65b4bSAndroid Build Coastguard Worker int cnt = 0;
486*abb65b4bSAndroid Build Coastguard Worker int len_cnt = 0;
487*abb65b4bSAndroid Build Coastguard Worker while(len_cnt < len_u && cnt < OAPV_BLK_D) {
488*abb65b4bSAndroid Build Coastguard Worker sscanf(tmp, "%d", ¶m->q_matrix_u[cnt]);
489*abb65b4bSAndroid Build Coastguard Worker if(param->q_matrix_u[cnt] < 1 || param->q_matrix_u[cnt] > 255) {
490*abb65b4bSAndroid Build Coastguard Worker logerr("input value of q_matrix_u is invalid\n");
491*abb65b4bSAndroid Build Coastguard Worker return -1;
492*abb65b4bSAndroid Build Coastguard Worker }
493*abb65b4bSAndroid Build Coastguard Worker len_cnt += (int)log10(param->q_matrix_u[cnt]) + 2;
494*abb65b4bSAndroid Build Coastguard Worker tmp = vars->q_matrix_u + len_cnt;
495*abb65b4bSAndroid Build Coastguard Worker cnt++;
496*abb65b4bSAndroid Build Coastguard Worker }
497*abb65b4bSAndroid Build Coastguard Worker if(cnt < OAPV_BLK_D) {
498*abb65b4bSAndroid Build Coastguard Worker logerr("input number of q_matrix_u is not enough\n");
499*abb65b4bSAndroid Build Coastguard Worker return -1;
500*abb65b4bSAndroid Build Coastguard Worker }
501*abb65b4bSAndroid Build Coastguard Worker }
502*abb65b4bSAndroid Build Coastguard Worker
503*abb65b4bSAndroid Build Coastguard Worker int len_v = (int)strlen(vars->q_matrix_v);
504*abb65b4bSAndroid Build Coastguard Worker if(len_v > 0) {
505*abb65b4bSAndroid Build Coastguard Worker param->use_q_matrix = 1;
506*abb65b4bSAndroid Build Coastguard Worker char *tmp = vars->q_matrix_v;
507*abb65b4bSAndroid Build Coastguard Worker int cnt = 0;
508*abb65b4bSAndroid Build Coastguard Worker int len_cnt = 0;
509*abb65b4bSAndroid Build Coastguard Worker while(len_cnt < len_v && cnt < OAPV_BLK_D) {
510*abb65b4bSAndroid Build Coastguard Worker sscanf(tmp, "%d", ¶m->q_matrix_v[cnt]);
511*abb65b4bSAndroid Build Coastguard Worker if(param->q_matrix_v[cnt] < 1 || param->q_matrix_v[cnt] > 255) {
512*abb65b4bSAndroid Build Coastguard Worker logerr("input value of q_matrix_v is invalid\n");
513*abb65b4bSAndroid Build Coastguard Worker return -1;
514*abb65b4bSAndroid Build Coastguard Worker }
515*abb65b4bSAndroid Build Coastguard Worker len_cnt += (int)log10(param->q_matrix_v[cnt]) + 2;
516*abb65b4bSAndroid Build Coastguard Worker tmp = vars->q_matrix_v + len_cnt;
517*abb65b4bSAndroid Build Coastguard Worker cnt++;
518*abb65b4bSAndroid Build Coastguard Worker }
519*abb65b4bSAndroid Build Coastguard Worker if(cnt < OAPV_BLK_D) {
520*abb65b4bSAndroid Build Coastguard Worker logerr("input number of q_matrix_v is not enough\n");
521*abb65b4bSAndroid Build Coastguard Worker return -1;
522*abb65b4bSAndroid Build Coastguard Worker }
523*abb65b4bSAndroid Build Coastguard Worker }
524*abb65b4bSAndroid Build Coastguard Worker
525*abb65b4bSAndroid Build Coastguard Worker int len_x = (int)strlen(vars->q_matrix_x);
526*abb65b4bSAndroid Build Coastguard Worker if (len_x > 0) {
527*abb65b4bSAndroid Build Coastguard Worker param->use_q_matrix = 1;
528*abb65b4bSAndroid Build Coastguard Worker char* tmp = vars->q_matrix_x;
529*abb65b4bSAndroid Build Coastguard Worker int cnt = 0;
530*abb65b4bSAndroid Build Coastguard Worker int len_cnt = 0;
531*abb65b4bSAndroid Build Coastguard Worker while (len_cnt < len_x && cnt < OAPV_BLK_D) {
532*abb65b4bSAndroid Build Coastguard Worker sscanf(tmp, "%d", ¶m->q_matrix_x[cnt]);
533*abb65b4bSAndroid Build Coastguard Worker if (param->q_matrix_x[cnt] < 1 || param->q_matrix_x[cnt] > 255) {
534*abb65b4bSAndroid Build Coastguard Worker logerr("input value of q_matrix_x is invalid\n");
535*abb65b4bSAndroid Build Coastguard Worker return -1;
536*abb65b4bSAndroid Build Coastguard Worker }
537*abb65b4bSAndroid Build Coastguard Worker len_cnt += (int)log10(param->q_matrix_x[cnt]) + 2;
538*abb65b4bSAndroid Build Coastguard Worker tmp = vars->q_matrix_x + len_cnt;
539*abb65b4bSAndroid Build Coastguard Worker cnt++;
540*abb65b4bSAndroid Build Coastguard Worker }
541*abb65b4bSAndroid Build Coastguard Worker if (cnt < OAPV_BLK_D) {
542*abb65b4bSAndroid Build Coastguard Worker logerr("input number of q_matrix_x is not enough\n");
543*abb65b4bSAndroid Build Coastguard Worker return -1;
544*abb65b4bSAndroid Build Coastguard Worker }
545*abb65b4bSAndroid Build Coastguard Worker }
546*abb65b4bSAndroid Build Coastguard Worker
547*abb65b4bSAndroid Build Coastguard Worker if(param->use_q_matrix) {
548*abb65b4bSAndroid Build Coastguard Worker if(len_y == 0) {
549*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < OAPV_BLK_D; i++) {
550*abb65b4bSAndroid Build Coastguard Worker param->q_matrix_y[i] = 16;
551*abb65b4bSAndroid Build Coastguard Worker }
552*abb65b4bSAndroid Build Coastguard Worker }
553*abb65b4bSAndroid Build Coastguard Worker
554*abb65b4bSAndroid Build Coastguard Worker if(len_u == 0) {
555*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < OAPV_BLK_D; i++) {
556*abb65b4bSAndroid Build Coastguard Worker param->q_matrix_u[i] = 16;
557*abb65b4bSAndroid Build Coastguard Worker }
558*abb65b4bSAndroid Build Coastguard Worker }
559*abb65b4bSAndroid Build Coastguard Worker
560*abb65b4bSAndroid Build Coastguard Worker if(len_v == 0) {
561*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < OAPV_BLK_D; i++) {
562*abb65b4bSAndroid Build Coastguard Worker param->q_matrix_v[i] = 16;
563*abb65b4bSAndroid Build Coastguard Worker }
564*abb65b4bSAndroid Build Coastguard Worker }
565*abb65b4bSAndroid Build Coastguard Worker
566*abb65b4bSAndroid Build Coastguard Worker if (len_x == 0) {
567*abb65b4bSAndroid Build Coastguard Worker for (int i = 0; i < OAPV_BLK_D; i++) {
568*abb65b4bSAndroid Build Coastguard Worker param->q_matrix_x[i] = 16;
569*abb65b4bSAndroid Build Coastguard Worker }
570*abb65b4bSAndroid Build Coastguard Worker }
571*abb65b4bSAndroid Build Coastguard Worker }
572*abb65b4bSAndroid Build Coastguard Worker
573*abb65b4bSAndroid Build Coastguard Worker param->csp = vars->input_csp;
574*abb65b4bSAndroid Build Coastguard Worker
575*abb65b4bSAndroid Build Coastguard Worker /* update level idc */
576*abb65b4bSAndroid Build Coastguard Worker double tmp_level = 0;
577*abb65b4bSAndroid Build Coastguard Worker sscanf(vars->level, "%lf", &tmp_level);
578*abb65b4bSAndroid Build Coastguard Worker param->level_idc = tmp_level * 30;
579*abb65b4bSAndroid Build Coastguard Worker /* update band idc */
580*abb65b4bSAndroid Build Coastguard Worker param->band_idc = vars->band;
581*abb65b4bSAndroid Build Coastguard Worker
582*abb65b4bSAndroid Build Coastguard Worker /* update fps */
583*abb65b4bSAndroid Build Coastguard Worker if(strpbrk(vars->fps, "/") != NULL) {
584*abb65b4bSAndroid Build Coastguard Worker sscanf(vars->fps, "%d/%d", ¶m->fps_num, ¶m->fps_den);
585*abb65b4bSAndroid Build Coastguard Worker }
586*abb65b4bSAndroid Build Coastguard Worker else if(strpbrk(vars->fps, ".") != NULL) {
587*abb65b4bSAndroid Build Coastguard Worker float tmp_fps = 0;
588*abb65b4bSAndroid Build Coastguard Worker sscanf(vars->fps, "%f", &tmp_fps);
589*abb65b4bSAndroid Build Coastguard Worker param->fps_num = tmp_fps * 10000;
590*abb65b4bSAndroid Build Coastguard Worker param->fps_den = 10000;
591*abb65b4bSAndroid Build Coastguard Worker }
592*abb65b4bSAndroid Build Coastguard Worker else {
593*abb65b4bSAndroid Build Coastguard Worker sscanf(vars->fps, "%d", ¶m->fps_num);
594*abb65b4bSAndroid Build Coastguard Worker param->fps_den = 1;
595*abb65b4bSAndroid Build Coastguard Worker }
596*abb65b4bSAndroid Build Coastguard Worker
597*abb65b4bSAndroid Build Coastguard Worker if(strlen(vars->preset) > 0) {
598*abb65b4bSAndroid Build Coastguard Worker if(strcmp(vars->preset, "fastest") == 0) {
599*abb65b4bSAndroid Build Coastguard Worker param->preset = OAPV_PRESET_FASTEST;
600*abb65b4bSAndroid Build Coastguard Worker }
601*abb65b4bSAndroid Build Coastguard Worker else if(strcmp(vars->preset, "fast") == 0) {
602*abb65b4bSAndroid Build Coastguard Worker param->preset = OAPV_PRESET_FAST;
603*abb65b4bSAndroid Build Coastguard Worker }
604*abb65b4bSAndroid Build Coastguard Worker else if(strcmp(vars->preset, "medium") == 0) {
605*abb65b4bSAndroid Build Coastguard Worker param->preset = OAPV_PRESET_MEDIUM;
606*abb65b4bSAndroid Build Coastguard Worker }
607*abb65b4bSAndroid Build Coastguard Worker else if(strcmp(vars->preset, "slow") == 0) {
608*abb65b4bSAndroid Build Coastguard Worker param->preset = OAPV_PRESET_SLOW;
609*abb65b4bSAndroid Build Coastguard Worker }
610*abb65b4bSAndroid Build Coastguard Worker else if(strcmp(vars->preset, "placebo") == 0) {
611*abb65b4bSAndroid Build Coastguard Worker param->preset = OAPV_PRESET_PLACEBO;
612*abb65b4bSAndroid Build Coastguard Worker }
613*abb65b4bSAndroid Build Coastguard Worker else {
614*abb65b4bSAndroid Build Coastguard Worker logerr("input value of preset is invalid\n");
615*abb65b4bSAndroid Build Coastguard Worker return -1;
616*abb65b4bSAndroid Build Coastguard Worker }
617*abb65b4bSAndroid Build Coastguard Worker }
618*abb65b4bSAndroid Build Coastguard Worker else {
619*abb65b4bSAndroid Build Coastguard Worker param->preset = OAPV_PRESET_DEFAULT;
620*abb65b4bSAndroid Build Coastguard Worker }
621*abb65b4bSAndroid Build Coastguard Worker
622*abb65b4bSAndroid Build Coastguard Worker return 0;
623*abb65b4bSAndroid Build Coastguard Worker }
624*abb65b4bSAndroid Build Coastguard Worker
main(int argc,const char ** argv)625*abb65b4bSAndroid Build Coastguard Worker int main(int argc, const char **argv)
626*abb65b4bSAndroid Build Coastguard Worker {
627*abb65b4bSAndroid Build Coastguard Worker args_parser_t *args = NULL;
628*abb65b4bSAndroid Build Coastguard Worker args_var_t *args_var = NULL;
629*abb65b4bSAndroid Build Coastguard Worker STATES state = STATE_ENCODING;
630*abb65b4bSAndroid Build Coastguard Worker unsigned char *bs_buf = NULL;
631*abb65b4bSAndroid Build Coastguard Worker FILE *fp_inp = NULL;
632*abb65b4bSAndroid Build Coastguard Worker oapve_t id = NULL;
633*abb65b4bSAndroid Build Coastguard Worker oapvm_t mid = NULL;
634*abb65b4bSAndroid Build Coastguard Worker oapve_cdesc_t cdesc;
635*abb65b4bSAndroid Build Coastguard Worker oapve_param_t *param = NULL;
636*abb65b4bSAndroid Build Coastguard Worker oapv_bitb_t bitb;
637*abb65b4bSAndroid Build Coastguard Worker oapve_stat_t stat;
638*abb65b4bSAndroid Build Coastguard Worker oapv_imgb_t *imgb_r = NULL; // image buffer for read
639*abb65b4bSAndroid Build Coastguard Worker oapv_imgb_t *imgb_w = NULL; // image buffer for write
640*abb65b4bSAndroid Build Coastguard Worker oapv_imgb_t *imgb_i = NULL; // image buffer for input
641*abb65b4bSAndroid Build Coastguard Worker oapv_imgb_t *imgb_o = NULL; // image buffer for output
642*abb65b4bSAndroid Build Coastguard Worker oapv_frms_t ifrms = { 0 }; // frames for input
643*abb65b4bSAndroid Build Coastguard Worker oapv_frms_t rfrms = { 0 }; // frames for reconstruction
644*abb65b4bSAndroid Build Coastguard Worker int ret;
645*abb65b4bSAndroid Build Coastguard Worker oapv_clk_t clk_beg, clk_end, clk_tot;
646*abb65b4bSAndroid Build Coastguard Worker oapv_mtime_t au_cnt, au_skip;
647*abb65b4bSAndroid Build Coastguard Worker double bitrate_tot; // total bitrate (byte)
648*abb65b4bSAndroid Build Coastguard Worker double psnr_avg[MAX_NUM_FRMS][MAX_NUM_CC] = { 0 };
649*abb65b4bSAndroid Build Coastguard Worker int is_y4m;
650*abb65b4bSAndroid Build Coastguard Worker y4m_params_t y4m;
651*abb65b4bSAndroid Build Coastguard Worker int is_out = 0, is_rec = 0;
652*abb65b4bSAndroid Build Coastguard Worker char *errstr = NULL;
653*abb65b4bSAndroid Build Coastguard Worker int cfmt; // color format
654*abb65b4bSAndroid Build Coastguard Worker const int num_frames = MAX_NUM_FRMS; // number of frames in an access unit
655*abb65b4bSAndroid Build Coastguard Worker
656*abb65b4bSAndroid Build Coastguard Worker /* help message */
657*abb65b4bSAndroid Build Coastguard Worker if(argc < 2 || !strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")) {
658*abb65b4bSAndroid Build Coastguard Worker print_usage(argv);
659*abb65b4bSAndroid Build Coastguard Worker return 0;
660*abb65b4bSAndroid Build Coastguard Worker }
661*abb65b4bSAndroid Build Coastguard Worker
662*abb65b4bSAndroid Build Coastguard Worker /* set default parameters */
663*abb65b4bSAndroid Build Coastguard Worker memset(&cdesc, 0, sizeof(oapve_cdesc_t));
664*abb65b4bSAndroid Build Coastguard Worker param = &cdesc.param[FRM_IDX];
665*abb65b4bSAndroid Build Coastguard Worker ret = oapve_param_default(param);
666*abb65b4bSAndroid Build Coastguard Worker if(OAPV_FAILED(ret)) {
667*abb65b4bSAndroid Build Coastguard Worker logerr("cannot set default parameter\n");
668*abb65b4bSAndroid Build Coastguard Worker ret = -1;
669*abb65b4bSAndroid Build Coastguard Worker goto ERR;
670*abb65b4bSAndroid Build Coastguard Worker }
671*abb65b4bSAndroid Build Coastguard Worker /* parse command line */
672*abb65b4bSAndroid Build Coastguard Worker args = args_create(enc_args_opts, NUM_ARGS_OPT);
673*abb65b4bSAndroid Build Coastguard Worker if(args == NULL) {
674*abb65b4bSAndroid Build Coastguard Worker logerr("cannot create argument parser\n");
675*abb65b4bSAndroid Build Coastguard Worker ret = -1;
676*abb65b4bSAndroid Build Coastguard Worker goto ERR;
677*abb65b4bSAndroid Build Coastguard Worker }
678*abb65b4bSAndroid Build Coastguard Worker args_var = args_init_vars(args, param);
679*abb65b4bSAndroid Build Coastguard Worker if(args_var == NULL) {
680*abb65b4bSAndroid Build Coastguard Worker logerr("cannot initialize argument parser\n");
681*abb65b4bSAndroid Build Coastguard Worker ret = -1;
682*abb65b4bSAndroid Build Coastguard Worker goto ERR;
683*abb65b4bSAndroid Build Coastguard Worker }
684*abb65b4bSAndroid Build Coastguard Worker if(args->parse(args, argc, argv, &errstr)) {
685*abb65b4bSAndroid Build Coastguard Worker logerr("command parsing error (%s)\n", errstr);
686*abb65b4bSAndroid Build Coastguard Worker ret = -1;
687*abb65b4bSAndroid Build Coastguard Worker goto ERR;
688*abb65b4bSAndroid Build Coastguard Worker }
689*abb65b4bSAndroid Build Coastguard Worker // print logo
690*abb65b4bSAndroid Build Coastguard Worker logv2(" ____ ___ ___ _ __\n");
691*abb65b4bSAndroid Build Coastguard Worker logv2(" / __ \\___ ___ ___ / _ | / _ \\ | / / Encoder\n");
692*abb65b4bSAndroid Build Coastguard Worker logv2("/ /_/ / _ \\/ -_) _ \\/ __ |/ ___/ |/ / \n");
693*abb65b4bSAndroid Build Coastguard Worker logv2("\\____/ .__/\\__/_//_/_/ |_/_/ |___/ \n");
694*abb65b4bSAndroid Build Coastguard Worker logv2(" /_/ \n");
695*abb65b4bSAndroid Build Coastguard Worker logv2("\n");
696*abb65b4bSAndroid Build Coastguard Worker
697*abb65b4bSAndroid Build Coastguard Worker // print command line string for information
698*abb65b4bSAndroid Build Coastguard Worker print_commandline(argc, argv);
699*abb65b4bSAndroid Build Coastguard Worker
700*abb65b4bSAndroid Build Coastguard Worker // check mandatory arguments
701*abb65b4bSAndroid Build Coastguard Worker if(args->check_mandatory(args, &errstr)) {
702*abb65b4bSAndroid Build Coastguard Worker logerr("'--%s' argument is mandatory\n", errstr);
703*abb65b4bSAndroid Build Coastguard Worker ret = -1;
704*abb65b4bSAndroid Build Coastguard Worker goto ERR;
705*abb65b4bSAndroid Build Coastguard Worker }
706*abb65b4bSAndroid Build Coastguard Worker
707*abb65b4bSAndroid Build Coastguard Worker /* try to open input file */
708*abb65b4bSAndroid Build Coastguard Worker fp_inp = fopen(args_var->fname_inp, "rb");
709*abb65b4bSAndroid Build Coastguard Worker if(fp_inp == NULL) {
710*abb65b4bSAndroid Build Coastguard Worker logerr("ERROR: cannot open input file = (%s)\n", args_var->fname_inp);
711*abb65b4bSAndroid Build Coastguard Worker ret = -1;
712*abb65b4bSAndroid Build Coastguard Worker goto ERR;
713*abb65b4bSAndroid Build Coastguard Worker }
714*abb65b4bSAndroid Build Coastguard Worker
715*abb65b4bSAndroid Build Coastguard Worker /* y4m header parsing */
716*abb65b4bSAndroid Build Coastguard Worker is_y4m = y4m_test(fp_inp);
717*abb65b4bSAndroid Build Coastguard Worker if(is_y4m) {
718*abb65b4bSAndroid Build Coastguard Worker if(y4m_header_parser(fp_inp, &y4m)) {
719*abb65b4bSAndroid Build Coastguard Worker logerr("This y4m is not supported (%s)\n", args_var->fname_inp);
720*abb65b4bSAndroid Build Coastguard Worker ret = -1;
721*abb65b4bSAndroid Build Coastguard Worker goto ERR;
722*abb65b4bSAndroid Build Coastguard Worker }
723*abb65b4bSAndroid Build Coastguard Worker y4m_update_param(args, &y4m);
724*abb65b4bSAndroid Build Coastguard Worker cfmt = y4m.color_format;
725*abb65b4bSAndroid Build Coastguard Worker // clang-format off
726*abb65b4bSAndroid Build Coastguard Worker args_var->input_csp = (cfmt == OAPV_CF_YCBCR400 ? 0 : \
727*abb65b4bSAndroid Build Coastguard Worker (cfmt == OAPV_CF_YCBCR420 ? 1 : \
728*abb65b4bSAndroid Build Coastguard Worker (cfmt == OAPV_CF_YCBCR422 ? 2 : \
729*abb65b4bSAndroid Build Coastguard Worker (cfmt == OAPV_CF_YCBCR444 ? 3 : \
730*abb65b4bSAndroid Build Coastguard Worker (cfmt == OAPV_CF_YCBCR4444 ? 4 : \
731*abb65b4bSAndroid Build Coastguard Worker (cfmt == OAPV_CF_PLANAR2 ? 5 : -1))))));
732*abb65b4bSAndroid Build Coastguard Worker // clang-format on
733*abb65b4bSAndroid Build Coastguard Worker
734*abb65b4bSAndroid Build Coastguard Worker if(args_var->input_csp != -1) {
735*abb65b4bSAndroid Build Coastguard Worker // force "input-csp" argument has set
736*abb65b4bSAndroid Build Coastguard Worker args->set_flag(args, "input-csp", 1);
737*abb65b4bSAndroid Build Coastguard Worker }
738*abb65b4bSAndroid Build Coastguard Worker }
739*abb65b4bSAndroid Build Coastguard Worker else {
740*abb65b4bSAndroid Build Coastguard Worker // clang-format off
741*abb65b4bSAndroid Build Coastguard Worker cfmt = (args_var->input_csp == 0 ? OAPV_CF_YCBCR400 : \
742*abb65b4bSAndroid Build Coastguard Worker (args_var->input_csp == 1 ? OAPV_CF_YCBCR420 : \
743*abb65b4bSAndroid Build Coastguard Worker (args_var->input_csp == 2 ? OAPV_CF_YCBCR422 : \
744*abb65b4bSAndroid Build Coastguard Worker (args_var->input_csp == 3 ? OAPV_CF_YCBCR444 : \
745*abb65b4bSAndroid Build Coastguard Worker (args_var->input_csp == 4 ? OAPV_CF_YCBCR4444 : \
746*abb65b4bSAndroid Build Coastguard Worker (args_var->input_csp == 5 ? OAPV_CF_PLANAR2 : OAPV_CF_UNKNOWN))))));
747*abb65b4bSAndroid Build Coastguard Worker // clang-format on
748*abb65b4bSAndroid Build Coastguard Worker }
749*abb65b4bSAndroid Build Coastguard Worker if(args_var->input_csp == -1) {
750*abb65b4bSAndroid Build Coastguard Worker logerr("Unknown input color space. set '--input-csp' argument\n");
751*abb65b4bSAndroid Build Coastguard Worker ret = -1;
752*abb65b4bSAndroid Build Coastguard Worker goto ERR;
753*abb65b4bSAndroid Build Coastguard Worker }
754*abb65b4bSAndroid Build Coastguard Worker
755*abb65b4bSAndroid Build Coastguard Worker /* update parameters */
756*abb65b4bSAndroid Build Coastguard Worker if(update_param(args_var, param)) {
757*abb65b4bSAndroid Build Coastguard Worker logerr("parameters is not proper\n");
758*abb65b4bSAndroid Build Coastguard Worker ret = -1;
759*abb65b4bSAndroid Build Coastguard Worker goto ERR;
760*abb65b4bSAndroid Build Coastguard Worker }
761*abb65b4bSAndroid Build Coastguard Worker
762*abb65b4bSAndroid Build Coastguard Worker cdesc.max_bs_buf_size = MAX_BS_BUF; /* maximum bitstream buffer size */
763*abb65b4bSAndroid Build Coastguard Worker cdesc.max_num_frms = MAX_NUM_FRMS;
764*abb65b4bSAndroid Build Coastguard Worker cdesc.threads = args_var->threads;
765*abb65b4bSAndroid Build Coastguard Worker
766*abb65b4bSAndroid Build Coastguard Worker if(check_conf(&cdesc, args_var)) {
767*abb65b4bSAndroid Build Coastguard Worker logerr("invalid configuration\n");
768*abb65b4bSAndroid Build Coastguard Worker ret = -1;
769*abb65b4bSAndroid Build Coastguard Worker goto ERR;
770*abb65b4bSAndroid Build Coastguard Worker }
771*abb65b4bSAndroid Build Coastguard Worker
772*abb65b4bSAndroid Build Coastguard Worker if(strlen(args_var->fname_out) > 0) {
773*abb65b4bSAndroid Build Coastguard Worker clear_data(args_var->fname_out);
774*abb65b4bSAndroid Build Coastguard Worker is_out = 1;
775*abb65b4bSAndroid Build Coastguard Worker }
776*abb65b4bSAndroid Build Coastguard Worker
777*abb65b4bSAndroid Build Coastguard Worker if(strlen(args_var->fname_rec) > 0) {
778*abb65b4bSAndroid Build Coastguard Worker clear_data(args_var->fname_rec);
779*abb65b4bSAndroid Build Coastguard Worker is_rec = 1;
780*abb65b4bSAndroid Build Coastguard Worker }
781*abb65b4bSAndroid Build Coastguard Worker
782*abb65b4bSAndroid Build Coastguard Worker /* allocate bitstream buffer */
783*abb65b4bSAndroid Build Coastguard Worker bs_buf = (unsigned char *)malloc(MAX_BS_BUF);
784*abb65b4bSAndroid Build Coastguard Worker if(bs_buf == NULL) {
785*abb65b4bSAndroid Build Coastguard Worker logerr("cannot allocate bitstream buffer, size=%d", MAX_BS_BUF);
786*abb65b4bSAndroid Build Coastguard Worker ret = -1;
787*abb65b4bSAndroid Build Coastguard Worker goto ERR;
788*abb65b4bSAndroid Build Coastguard Worker }
789*abb65b4bSAndroid Build Coastguard Worker
790*abb65b4bSAndroid Build Coastguard Worker /* create encoder */
791*abb65b4bSAndroid Build Coastguard Worker id = oapve_create(&cdesc, NULL);
792*abb65b4bSAndroid Build Coastguard Worker if(id == NULL) {
793*abb65b4bSAndroid Build Coastguard Worker logerr("cannot create OAPV encoder\n");
794*abb65b4bSAndroid Build Coastguard Worker ret = -1;
795*abb65b4bSAndroid Build Coastguard Worker goto ERR;
796*abb65b4bSAndroid Build Coastguard Worker }
797*abb65b4bSAndroid Build Coastguard Worker
798*abb65b4bSAndroid Build Coastguard Worker /* create metadata handler */
799*abb65b4bSAndroid Build Coastguard Worker mid = oapvm_create(&ret);
800*abb65b4bSAndroid Build Coastguard Worker if(mid == NULL || OAPV_FAILED(ret)) {
801*abb65b4bSAndroid Build Coastguard Worker logerr("cannot create OAPV metadata handler\n");
802*abb65b4bSAndroid Build Coastguard Worker ret = -1;
803*abb65b4bSAndroid Build Coastguard Worker goto ERR;
804*abb65b4bSAndroid Build Coastguard Worker }
805*abb65b4bSAndroid Build Coastguard Worker
806*abb65b4bSAndroid Build Coastguard Worker if(set_extra_config(id, args_var, param)) {
807*abb65b4bSAndroid Build Coastguard Worker logerr("cannot set extra configurations\n");
808*abb65b4bSAndroid Build Coastguard Worker ret = -1;
809*abb65b4bSAndroid Build Coastguard Worker goto ERR;
810*abb65b4bSAndroid Build Coastguard Worker }
811*abb65b4bSAndroid Build Coastguard Worker
812*abb65b4bSAndroid Build Coastguard Worker print_config(args_var, param);
813*abb65b4bSAndroid Build Coastguard Worker
814*abb65b4bSAndroid Build Coastguard Worker bitrate_tot = 0;
815*abb65b4bSAndroid Build Coastguard Worker bitb.addr = bs_buf;
816*abb65b4bSAndroid Build Coastguard Worker bitb.bsize = MAX_BS_BUF;
817*abb65b4bSAndroid Build Coastguard Worker
818*abb65b4bSAndroid Build Coastguard Worker if(args_var->seek > 0) {
819*abb65b4bSAndroid Build Coastguard Worker state = STATE_SKIPPING;
820*abb65b4bSAndroid Build Coastguard Worker }
821*abb65b4bSAndroid Build Coastguard Worker
822*abb65b4bSAndroid Build Coastguard Worker clk_tot = 0;
823*abb65b4bSAndroid Build Coastguard Worker au_cnt = 0;
824*abb65b4bSAndroid Build Coastguard Worker au_skip = 0;
825*abb65b4bSAndroid Build Coastguard Worker
826*abb65b4bSAndroid Build Coastguard Worker // create input and reconstruction image buffers
827*abb65b4bSAndroid Build Coastguard Worker memset(&ifrms, 0, sizeof(oapv_frm_t));
828*abb65b4bSAndroid Build Coastguard Worker memset(&rfrms, 0, sizeof(oapv_frm_t));
829*abb65b4bSAndroid Build Coastguard Worker
830*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < num_frames; i++) {
831*abb65b4bSAndroid Build Coastguard Worker if(args_var->input_depth == 10) {
832*abb65b4bSAndroid Build Coastguard Worker ifrms.frm[i].imgb = imgb_create(param->w, param->h, OAPV_CS_SET(cfmt, args_var->input_depth, 0));
833*abb65b4bSAndroid Build Coastguard Worker }
834*abb65b4bSAndroid Build Coastguard Worker else {
835*abb65b4bSAndroid Build Coastguard Worker imgb_r = imgb_create(param->w, param->h, OAPV_CS_SET(cfmt, args_var->input_depth, 0));
836*abb65b4bSAndroid Build Coastguard Worker ifrms.frm[i].imgb = imgb_create(param->w, param->h, OAPV_CS_SET(cfmt, 10, 0));
837*abb65b4bSAndroid Build Coastguard Worker }
838*abb65b4bSAndroid Build Coastguard Worker
839*abb65b4bSAndroid Build Coastguard Worker if(is_rec) {
840*abb65b4bSAndroid Build Coastguard Worker if(args_var->input_depth == 10) {
841*abb65b4bSAndroid Build Coastguard Worker rfrms.frm[i].imgb = imgb_create(param->w, param->h, OAPV_CS_SET(cfmt, args_var->input_depth, 0));
842*abb65b4bSAndroid Build Coastguard Worker }
843*abb65b4bSAndroid Build Coastguard Worker else {
844*abb65b4bSAndroid Build Coastguard Worker imgb_w = imgb_create(param->w, param->h, OAPV_CS_SET(cfmt, args_var->input_depth, 0));
845*abb65b4bSAndroid Build Coastguard Worker rfrms.frm[i].imgb = imgb_create(param->w, param->h, OAPV_CS_SET(cfmt, 10, 0));
846*abb65b4bSAndroid Build Coastguard Worker }
847*abb65b4bSAndroid Build Coastguard Worker rfrms.num_frms++;
848*abb65b4bSAndroid Build Coastguard Worker }
849*abb65b4bSAndroid Build Coastguard Worker ifrms.num_frms++;
850*abb65b4bSAndroid Build Coastguard Worker }
851*abb65b4bSAndroid Build Coastguard Worker
852*abb65b4bSAndroid Build Coastguard Worker /* encode pictures *******************************************************/
853*abb65b4bSAndroid Build Coastguard Worker while(args_var->max_au == 0 || (au_cnt < args_var->max_au)) {
854*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < num_frames; i++) {
855*abb65b4bSAndroid Build Coastguard Worker if(args_var->input_depth == 10) {
856*abb65b4bSAndroid Build Coastguard Worker imgb_i = ifrms.frm[i].imgb;
857*abb65b4bSAndroid Build Coastguard Worker }
858*abb65b4bSAndroid Build Coastguard Worker else {
859*abb65b4bSAndroid Build Coastguard Worker imgb_i = imgb_r;
860*abb65b4bSAndroid Build Coastguard Worker }
861*abb65b4bSAndroid Build Coastguard Worker ret = imgb_read(fp_inp, imgb_i, param->w, param->h, is_y4m);
862*abb65b4bSAndroid Build Coastguard Worker if(ret < 0) {
863*abb65b4bSAndroid Build Coastguard Worker logv3("reached out the end of input file\n");
864*abb65b4bSAndroid Build Coastguard Worker ret = OAPV_OK;
865*abb65b4bSAndroid Build Coastguard Worker state = STATE_STOP;
866*abb65b4bSAndroid Build Coastguard Worker break;
867*abb65b4bSAndroid Build Coastguard Worker }
868*abb65b4bSAndroid Build Coastguard Worker if(args_var->input_depth != 10) {
869*abb65b4bSAndroid Build Coastguard Worker imgb_cpy(ifrms.frm[i].imgb, imgb_i);
870*abb65b4bSAndroid Build Coastguard Worker }
871*abb65b4bSAndroid Build Coastguard Worker ifrms.frm[i].group_id = 1; // FIX-ME : need to set properly in case of multi-frame
872*abb65b4bSAndroid Build Coastguard Worker ifrms.frm[i].pbu_type = OAPV_PBU_TYPE_PRIMARY_FRAME;
873*abb65b4bSAndroid Build Coastguard Worker }
874*abb65b4bSAndroid Build Coastguard Worker
875*abb65b4bSAndroid Build Coastguard Worker if(state == STATE_ENCODING) {
876*abb65b4bSAndroid Build Coastguard Worker /* encoding */
877*abb65b4bSAndroid Build Coastguard Worker clk_beg = oapv_clk_get();
878*abb65b4bSAndroid Build Coastguard Worker
879*abb65b4bSAndroid Build Coastguard Worker ret = oapve_encode(id, &ifrms, mid, &bitb, &stat, &rfrms);
880*abb65b4bSAndroid Build Coastguard Worker
881*abb65b4bSAndroid Build Coastguard Worker clk_end = oapv_clk_from(clk_beg);
882*abb65b4bSAndroid Build Coastguard Worker clk_tot += clk_end;
883*abb65b4bSAndroid Build Coastguard Worker
884*abb65b4bSAndroid Build Coastguard Worker bitrate_tot += stat.frm_size[FRM_IDX];
885*abb65b4bSAndroid Build Coastguard Worker
886*abb65b4bSAndroid Build Coastguard Worker print_stat_au(&stat, au_cnt, param, args_var->max_au, bitrate_tot, clk_end, clk_tot);
887*abb65b4bSAndroid Build Coastguard Worker
888*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < num_frames; i++) {
889*abb65b4bSAndroid Build Coastguard Worker if(is_rec) {
890*abb65b4bSAndroid Build Coastguard Worker if(args_var->input_depth != 10) {
891*abb65b4bSAndroid Build Coastguard Worker imgb_cpy(imgb_w, rfrms.frm[i].imgb);
892*abb65b4bSAndroid Build Coastguard Worker imgb_o = imgb_w;
893*abb65b4bSAndroid Build Coastguard Worker }
894*abb65b4bSAndroid Build Coastguard Worker else {
895*abb65b4bSAndroid Build Coastguard Worker imgb_o = rfrms.frm[i].imgb;
896*abb65b4bSAndroid Build Coastguard Worker }
897*abb65b4bSAndroid Build Coastguard Worker }
898*abb65b4bSAndroid Build Coastguard Worker
899*abb65b4bSAndroid Build Coastguard Worker /* store bitstream */
900*abb65b4bSAndroid Build Coastguard Worker if(OAPV_SUCCEEDED(ret)) {
901*abb65b4bSAndroid Build Coastguard Worker if(is_out && stat.write > 0) {
902*abb65b4bSAndroid Build Coastguard Worker if(write_data(args_var->fname_out, bs_buf, stat.write)) {
903*abb65b4bSAndroid Build Coastguard Worker logerr("cannot write bitstream\n");
904*abb65b4bSAndroid Build Coastguard Worker ret = -1;
905*abb65b4bSAndroid Build Coastguard Worker goto ERR;
906*abb65b4bSAndroid Build Coastguard Worker }
907*abb65b4bSAndroid Build Coastguard Worker }
908*abb65b4bSAndroid Build Coastguard Worker }
909*abb65b4bSAndroid Build Coastguard Worker else {
910*abb65b4bSAndroid Build Coastguard Worker logerr("failed to encode\n");
911*abb65b4bSAndroid Build Coastguard Worker ret = -1;
912*abb65b4bSAndroid Build Coastguard Worker goto ERR;
913*abb65b4bSAndroid Build Coastguard Worker }
914*abb65b4bSAndroid Build Coastguard Worker
915*abb65b4bSAndroid Build Coastguard Worker // store recon image
916*abb65b4bSAndroid Build Coastguard Worker if(is_rec) {
917*abb65b4bSAndroid Build Coastguard Worker if(imgb_write(args_var->fname_rec, imgb_o)) {
918*abb65b4bSAndroid Build Coastguard Worker logerr("cannot write reconstruction image\n");
919*abb65b4bSAndroid Build Coastguard Worker ret = -1;
920*abb65b4bSAndroid Build Coastguard Worker goto ERR;
921*abb65b4bSAndroid Build Coastguard Worker }
922*abb65b4bSAndroid Build Coastguard Worker }
923*abb65b4bSAndroid Build Coastguard Worker
924*abb65b4bSAndroid Build Coastguard Worker print_stat_frms(&stat, &ifrms, &rfrms, psnr_avg);
925*abb65b4bSAndroid Build Coastguard Worker au_cnt++;
926*abb65b4bSAndroid Build Coastguard Worker }
927*abb65b4bSAndroid Build Coastguard Worker }
928*abb65b4bSAndroid Build Coastguard Worker else if(state == STATE_SKIPPING) {
929*abb65b4bSAndroid Build Coastguard Worker if(au_skip < args_var->seek) {
930*abb65b4bSAndroid Build Coastguard Worker au_skip++;
931*abb65b4bSAndroid Build Coastguard Worker continue;
932*abb65b4bSAndroid Build Coastguard Worker }
933*abb65b4bSAndroid Build Coastguard Worker else {
934*abb65b4bSAndroid Build Coastguard Worker state = STATE_ENCODING;
935*abb65b4bSAndroid Build Coastguard Worker }
936*abb65b4bSAndroid Build Coastguard Worker }
937*abb65b4bSAndroid Build Coastguard Worker else if(state == STATE_STOP) {
938*abb65b4bSAndroid Build Coastguard Worker break;
939*abb65b4bSAndroid Build Coastguard Worker }
940*abb65b4bSAndroid Build Coastguard Worker oapvm_rem_all(mid);
941*abb65b4bSAndroid Build Coastguard Worker }
942*abb65b4bSAndroid Build Coastguard Worker
943*abb65b4bSAndroid Build Coastguard Worker logv2_line("Summary");
944*abb65b4bSAndroid Build Coastguard Worker psnr_avg[FRM_IDX][0] /= au_cnt;
945*abb65b4bSAndroid Build Coastguard Worker psnr_avg[FRM_IDX][1] /= au_cnt;
946*abb65b4bSAndroid Build Coastguard Worker psnr_avg[FRM_IDX][2] /= au_cnt;
947*abb65b4bSAndroid Build Coastguard Worker if(cfmt == OAPV_CF_YCBCR4444) {
948*abb65b4bSAndroid Build Coastguard Worker psnr_avg[FRM_IDX][3] /= au_cnt;
949*abb65b4bSAndroid Build Coastguard Worker }
950*abb65b4bSAndroid Build Coastguard Worker
951*abb65b4bSAndroid Build Coastguard Worker logv3(" PSNR Y(dB) : %-5.4f\n", psnr_avg[FRM_IDX][0]);
952*abb65b4bSAndroid Build Coastguard Worker logv3(" PSNR U(dB) : %-5.4f\n", psnr_avg[FRM_IDX][1]);
953*abb65b4bSAndroid Build Coastguard Worker logv3(" PSNR V(dB) : %-5.4f\n", psnr_avg[FRM_IDX][2]);
954*abb65b4bSAndroid Build Coastguard Worker if(cfmt == OAPV_CF_YCBCR4444) {
955*abb65b4bSAndroid Build Coastguard Worker logv3(" PSNR T(dB) : %-5.4f\n", psnr_avg[FRM_IDX][3]);
956*abb65b4bSAndroid Build Coastguard Worker }
957*abb65b4bSAndroid Build Coastguard Worker logv3(" Total bits(bits) : %.0f\n", bitrate_tot * 8);
958*abb65b4bSAndroid Build Coastguard Worker bitrate_tot *= (((float)param->fps_num / param->fps_den) * 8);
959*abb65b4bSAndroid Build Coastguard Worker bitrate_tot /= au_cnt;
960*abb65b4bSAndroid Build Coastguard Worker bitrate_tot /= 1000;
961*abb65b4bSAndroid Build Coastguard Worker
962*abb65b4bSAndroid Build Coastguard Worker logv3(" -----------------: bitrate(kbps)\tPSNR-Y\tPSNR-U\tPSNR-V\n");
963*abb65b4bSAndroid Build Coastguard Worker if(cfmt == OAPV_CF_YCBCR4444) {
964*abb65b4bSAndroid Build Coastguard Worker logv3(" Summary : %-4.4f\t%-5.4f\t%-5.4f\t%-5.4f\t%-5.4f\n",
965*abb65b4bSAndroid Build Coastguard Worker bitrate_tot, psnr_avg[FRM_IDX][0], psnr_avg[FRM_IDX][1], psnr_avg[FRM_IDX][2], psnr_avg[FRM_IDX][3]);
966*abb65b4bSAndroid Build Coastguard Worker }
967*abb65b4bSAndroid Build Coastguard Worker else {
968*abb65b4bSAndroid Build Coastguard Worker logv3(" Summary : %-5.4f\t%-5.4f\t%-5.4f\t%-5.4f\n",
969*abb65b4bSAndroid Build Coastguard Worker bitrate_tot, psnr_avg[FRM_IDX][0], psnr_avg[FRM_IDX][1], psnr_avg[FRM_IDX][2]);
970*abb65b4bSAndroid Build Coastguard Worker }
971*abb65b4bSAndroid Build Coastguard Worker
972*abb65b4bSAndroid Build Coastguard Worker logv2("Bitrate = %.4f kbps\n", bitrate_tot);
973*abb65b4bSAndroid Build Coastguard Worker logv2("Encoded frame count = %d\n", (int)au_cnt);
974*abb65b4bSAndroid Build Coastguard Worker logv2("Total encoding time = %.3f msec,",
975*abb65b4bSAndroid Build Coastguard Worker (float)oapv_clk_msec(clk_tot));
976*abb65b4bSAndroid Build Coastguard Worker logv2(" %.3f sec\n", (float)(oapv_clk_msec(clk_tot) / 1000.0));
977*abb65b4bSAndroid Build Coastguard Worker
978*abb65b4bSAndroid Build Coastguard Worker logv2("Average encoding time for a frame = %.3f msec\n",
979*abb65b4bSAndroid Build Coastguard Worker (float)oapv_clk_msec(clk_tot) / au_cnt);
980*abb65b4bSAndroid Build Coastguard Worker logv2("Average encoding speed = %.3f frames/sec\n",
981*abb65b4bSAndroid Build Coastguard Worker ((float)au_cnt * 1000) / ((float)oapv_clk_msec(clk_tot)));
982*abb65b4bSAndroid Build Coastguard Worker logv2_line(NULL);
983*abb65b4bSAndroid Build Coastguard Worker
984*abb65b4bSAndroid Build Coastguard Worker if(args_var->max_au > 0 && au_cnt != args_var->max_au) {
985*abb65b4bSAndroid Build Coastguard Worker logv3("Wrong frames count: should be %d was %d\n", args_var->max_au, (int)au_cnt);
986*abb65b4bSAndroid Build Coastguard Worker }
987*abb65b4bSAndroid Build Coastguard Worker ERR:
988*abb65b4bSAndroid Build Coastguard Worker
989*abb65b4bSAndroid Build Coastguard Worker if(imgb_r != NULL)
990*abb65b4bSAndroid Build Coastguard Worker imgb_r->release(imgb_r);
991*abb65b4bSAndroid Build Coastguard Worker if(imgb_w != NULL)
992*abb65b4bSAndroid Build Coastguard Worker imgb_w->release(imgb_w);
993*abb65b4bSAndroid Build Coastguard Worker
994*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < num_frames; i++) {
995*abb65b4bSAndroid Build Coastguard Worker if(ifrms.frm[i].imgb != NULL) {
996*abb65b4bSAndroid Build Coastguard Worker ifrms.frm[i].imgb->release(ifrms.frm[i].imgb);
997*abb65b4bSAndroid Build Coastguard Worker }
998*abb65b4bSAndroid Build Coastguard Worker }
999*abb65b4bSAndroid Build Coastguard Worker for(int i = 0; i < num_frames; i++) {
1000*abb65b4bSAndroid Build Coastguard Worker if(rfrms.frm[i].imgb != NULL) {
1001*abb65b4bSAndroid Build Coastguard Worker rfrms.frm[i].imgb->release(rfrms.frm[i].imgb);
1002*abb65b4bSAndroid Build Coastguard Worker }
1003*abb65b4bSAndroid Build Coastguard Worker }
1004*abb65b4bSAndroid Build Coastguard Worker
1005*abb65b4bSAndroid Build Coastguard Worker if(id)
1006*abb65b4bSAndroid Build Coastguard Worker oapve_delete(id);
1007*abb65b4bSAndroid Build Coastguard Worker if(mid)
1008*abb65b4bSAndroid Build Coastguard Worker oapvm_delete(mid);
1009*abb65b4bSAndroid Build Coastguard Worker if(fp_inp)
1010*abb65b4bSAndroid Build Coastguard Worker fclose(fp_inp);
1011*abb65b4bSAndroid Build Coastguard Worker if(bs_buf)
1012*abb65b4bSAndroid Build Coastguard Worker free(bs_buf); /* release bitstream buffer */
1013*abb65b4bSAndroid Build Coastguard Worker if(args)
1014*abb65b4bSAndroid Build Coastguard Worker args->release(args);
1015*abb65b4bSAndroid Build Coastguard Worker if(args_var)
1016*abb65b4bSAndroid Build Coastguard Worker free(args_var);
1017*abb65b4bSAndroid Build Coastguard Worker
1018*abb65b4bSAndroid Build Coastguard Worker return ret;
1019*abb65b4bSAndroid Build Coastguard Worker }
1020