xref: /aosp_15_r20/external/libhevc/test/encoder/main.c (revision c83a76b084498d55f252f48b2e3786804cdf24b7)
1 /******************************************************************************
2  *
3  * Copyright (C) 2018 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 
21 /*!
22 ******************************************************************************
23 * \file main.c
24 *
25 * \brief
26 *    This file contains sample application for HEVC Encoder
27 *
28 * \date
29 *    18/09/2012
30 *
31 * \author
32 *    Ittiam
33 *
34 ******************************************************************************
35 */
36 
37 /*****************************************************************************/
38 /* File Includes                                                             */
39 /*****************************************************************************/
40 
41 /* System include files */
42 #include <assert.h>
43 #include <stddef.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <stdarg.h>
48 #include <stdint.h>
49 #include <limits.h>
50 
51 /* User include files */
52 #include "ihevc_typedefs.h"
53 #include "itt_video_api.h"
54 #include "ihevce_api.h"
55 #include "ihevce_plugin.h"
56 #include "ihevce_profile.h"
57 #include "app.h"
58 
59 /*****************************************************************************/
60 /* Constant Macros                                                           */
61 /*****************************************************************************/
62 #define DYN_BITRATE_TEST 0
63 #define FORCE_IDR_TEST 0
64 
65 /*****************************************************************************/
66 /* Global definitions                                                        */
67 /*****************************************************************************/
68 
69 /*!
70 *******************************************************************************
71 * \brief
72 *    list of supported arguments
73 *
74 *****************************************************************************
75 */
76 // clang-format off
77 static const argument_t argument_mapping[] =
78 {
79     {"-h",                  "--help",                       HELP,                     "Print help \n"},
80     {"-c",                  "--config",                     CONFIG,                   "Input Config file \n" },
81     {"-v",                  "--version",                    VERSION,                  "Encoder version \n"},
82     {"",                    "",                             GRPINFO, "\n " " File I/O Parameters  \n" " ---------------------\n"},
83     {"-i",                  "--input",                      INPUT_YUV,                "Input yuv file {mandatory} \n"},
84     {"-o",                  "--output",                     OUTPUT,                   "Output bitstream file {mandatory}\n"},
85     {"-frames",             "--num_frames_to_encode",       NUM_FRAMES_TO_ENCODE,     "Number of frames to encode \n"},
86     {"-log",                "--log_dump_level",             LOG_DUMP_LEVEL,           "0- [No log/prints] 1- [BitsGenerated, POC, Qp, Pic-type]\n"
87     "                                                 2- [1 + PSNR + Seq Summary] 3- [2 + SSIM + Frame Summary] {0}\n"},
88     {"",                    "",                             GRPINFO,                  "\n " " Source Parameters    \n" " ---------------------\n"},
89     {"-sw",                 "--src_width",                  SRC_WIDTH,                "Input Source Width {mandatory}[240:4096]\n"},
90     {"-sh",                 "--src_height",                 SRC_HEIGHT,               "Input Source Height {mandatory}[128:2176] [ \n"},
91     {"-fNum",               "--src_frame_rate_num",         SRC_FRAME_RATE_NUM,       "Frame rate numerator {30000}[7500:120000]\n"},
92     {"-fDen",               "--src_frame_rate_denom",       SRC_FRAME_RATE_DENOM,     "Frame rate denominator {1000}[1000,1001]\n"},
93     {"-pixfmt",             "--input_chroma_format",        INPUT_CHROMA_FORMAT,      "11- YUV_420P; 13- YUV_422P {11}\n"},
94     {"",                    "",                             GRPINFO,                  "\n " " Target Parameters  (for all the layers of multi-resolution encoding)    \n" " ------------------------------------------------------------------------\n"},
95     {"-level",              "--codec_level",                CODEC_LEVEL,              "Coded Level multiplied by 30 {153}[0:153]\n"},
96     {"-b",                  "--tgt_bitrate",                TGT_BITRATE,              "Target bitrates in bps{5000000}."
97     "                                                 For MRESxMBR comma seperated BR1,BR2,BR3...\n"},
98     {"-qp",                 "--frame_qp",                   FRAME_QP,                 "Initial QP values.Dependes on bit depth {38},"
99     "                                                 For MRESxMBR comma seperated QP1,QP2,QP3...\n"},
100     {"-obd",                "--output_bit_depth",           OUTPUT_BIT_DEPTH,         "Output bit depth common for all Res.{-ibd}[8,10,12] \n"},
101     {"",                    "",                             GRPINFO,                  "\n " " GOP structure Parameters    \n" " ----------------------------\n"},
102     {"-maxCgop",            "--max_closed_gop_period",      MAX_CLOSED_GOP_PERIOD,    "Max IDR Pic distance- Closed GOP {0}[0:300] \n"},
103     {"-minCgop",            "--min_closed_gop_period",      MIN_CLOSED_GOP_PERIOD,    "Min IDR Pic distance- Closed GOP {0}[0:300]\n"},
104     {"-craOgop",            "--max_cra_open_gop_period",    MAX_CRA_OPEN_GOP_PERIOD,  "Max CRA Pic distance- Open GOP {60}[0:300]\n"},
105     {"-maxIgop",            "--max_i_open_gop_period",      MAX_I_OPEN_GOP_PERIOD,    "Max I (non CRA, non IDR) Pic distance {0}[0:300]\n"},
106     {"-bpicTL",             "--max_temporal_layers",        MAX_TEMPORAL_LAYERS,      "B pyramid layers {3}[0:3] \n"},
107     {"",                    "",                             GRPINFO,                  "\n " " Coding tools Parameters    \n" " ---------------------------\n"},
108     {"-preset",             "--quality_preset",             QUALITY_PRESET,           "0- PQ, 2- HQ, 3- MS, 4- HS, 5- ES {3}\n"},
109     {"-lfd",                "--deblocking_type",            DEBLOCKING_TYPE,          "Debocking 0- enabled, 1- disabled {0}\n"},
110     {"-scm",                "--use_default_sc_mtx",         USE_DEFAULT_SC_MTX,       "0- disabled, 1- enabled {0}\n"},
111     {"-wpp",                "--enable_entropy_sync",        ENABLE_ENTROPY_SYNC,      "Entropy sync 1- enabled, 0- disabled {0}\n"},
112     {"-intraTD",            "--max_tr_tree_depth_I",        MAX_TR_TREE_DEPTH_I,      "Max transform tree depth for intra {3}[1,2,3]\n"},
113     {"-interTD",            "--max_tr_tree_depth_nI",       MAX_TR_TREE_DEPTH_NI,     "Max transform tree depth for inter {3}[2,3,4]\n"},
114     {"-hrange",             "--max_search_range_horz",      MAX_SEARCH_RANGE_HORZ,    "Horizontal search range {512}[64:512]\n"},
115     {"-vrange",             "--max_search_range_vert",      MAX_SEARCH_RANGE_VERT,    "Vertical search range {256}[32:256]\n"},
116     {"-arch",                 "--archType",                 ARCH_TYPE,                 "0 => Automatic, 4 => ARM(No neon)\n"},
117 
118     {"",                    "",                             GRPINFO,                  "\n " " Multi Core parameters    \n" " -------------------------\n"},
119     {"-core",               "--num_cores",                  NUM_CORES,                "#Logical cores (Include hyperthreads){auto}[1:80] \n"},
120     {"",                    "",                             GRPINFO,                  "\n " " Rate Control parameters  \n" " -------------------------\n"},
121     {"-rc",                 "--rate_control_mode",          RATE_CONTROL_MODE,        "1 -Capped VBR,2- VBR ,3- CQP, 5- CBR {5} \n"},
122     {"-aq",                 "--cu_level_rc",                CU_LEVEL_RC,              "CU Qp Modulation 0- Disable 1-Spatial QP modulation \n"},
123     {"-maxqp",              "--max_frame_qp",               MAX_FRAME_QP,             "Max frame Qp for I frame {51}[51] \n"},
124     {"-minqp",              "--min_frame_qp",               MIN_FRAME_QP,             "Min frame Qp for I frame. Depends on Bit depth {1}[1/-12/-24] \n"},
125     {"",                    "",                             GRPINFO,                  "\n " " Look Ahead Processing Parameters  \n" " ----------------------------------\n"},
126 
127     {"-lapwindow",          "--rc_look_ahead_pics",         RC_LOOK_AHEAD_PICS,       "RC look ahead window {60}[0:120] \n"},
128     {"",                    "",                             GRPINFO,                  "\n " " Output stream Parameters          \n" " ----------------------------------\n"},
129     {"-codec",              "--codec_type",                 CODEC_TYPE,               "0- HEVC {0}\n"},
130     {"-profile",            "--codec_profile",              CODEC_PROFILE,            "1- Main 2- Main10 4- RExt {1} \n"},
131     {"-tier",               "--codec_tier",                 CODEC_TIER,               "0- Main 1- High {1} \n"},
132     {"-sps",                "--sps_at_cdr_enable",          SPS_AT_CDR_ENABLE,        "1- enable, 0- disable {1}\n"},
133     {"",                    "",                             GRPINFO,                  "\n " " Tile  Parameters          \n" " --------------------------\n"},
134     {"-tiles",              "--tiles_enabled_flag",         TILES_ENABLED_FLAG,       "Tile encoding 0- disable 1-enable {0} \n"},
135     {"",                    "",                             GRPINFO,                  "\n " " Slice  Parameters         \n" " --------------------------\n"},
136     {"-slicemode",          "--slice_segment_mode",         SLICE_SEGMENT_MODE,       "Flag to control dependent slice generation {0}[0,1,2]\n"
137     "                                                  0- Disable slices\n"
138     "                                                  1- CTB/Slice\n"
139     "                                                  2- Bytes/Slice  \n"},
140     {"",                    "",                            GRPINFO, "\n " " SEI  parameters            \n" " ---------------------------\n"},
141     {"-sei",                "--sei_enable_flags",           SEI_ENABLE_FLAGS,         "1- enable, 0- disable {0}\n"},
142     {"-seipayload",         "--sei_payload_enable_flags",   SEI_PAYLOAD_ENABLE_FLAGS, "1- enable, 0- disable {0}\n"},
143     {"-seipayloadpath",     "--sei_payload_path",            SEI_PAYLOAD_PATH,          "Input SEI Payload Path (optional)" },
144     {"-seibuf",             "--sei_buffer_period_flags",    SEI_BUFFER_PERIOD_FLAGS,  "1- enable, 0- disable {0}\n"},
145     {"-seipictime",         "--sei_pic_timing_flags",       SEI_PIC_TIMING_FLAGS,     "1- enable, 0- disable {0}\n"},
146     {"-seirecpt",           "--sei_recovery_point_flags",   SEI_RECOVERY_POINT_FLAGS, "1- enable, 0- disable {0}\n"},
147     {"-seihash",            "--sei_hash_flags",             SEI_HASH_FLAGS,           "3- Checksum, 2- CRC, 1- MD5, 0- disable {0}\n"},
148     {"-seidispcol",         "--sei_mastering_disp_colour_vol_flags",    SEI_MASTERING_DISP_COLOUR_VOL_FLAGS,           "1: enable, 0: disable {0}\n"},
149     {"-seiprimx",           "--display_primaries_x",        DISPLAY_PRIMARIES_X,      "X-Primaries: comma separated R,G,B values {}[0:50000] \n"},
150     {"-seiprimy",           "--display_primaries_y",        DISPLAY_PRIMARIES_Y,      "Y-Primaries: comma separated R,G,B values {}[0:50000]  \n"},
151     {"-seiwhiteptx",        "--white_point_x",              WHITE_POINT_X,            "X White point value {}[0:50000] \n"},
152     {"-seiwhitepty",        "--white_point_y",              WHITE_POINT_Y,            "Y White point value {}[0:50000] \n"},
153     {"-seidisplummax",      "--max_display_mastering_luminance",  MAX_DISPLAY_MASTERING_LUMINANCE, "Max mastering Luminance. In units  of  0.0001  Candelas/sqmtr {} \n"},
154     {"-seidisplummin",      "--min_display_mastering_luminance",  MIN_DISPLAY_MASTERING_LUMINANCE, "Min mastering Luminance. In units  of  0.0001  Candelas/sqmtr {}\n"},
155     {"-seicllinfo",         "--sei_content_light_level_info",      SEI_CLL_INFO_ENABLE, "1- enable, 0- disable {0}\n"},
156     {"-seimaxcll",          "--max_content_light_level",          SEI_MAX_CLL,        "16bit unsigned number indicating max pixel intensity\n"},
157     {"-seiavgcll",          "--max_frame_average_light_level",      SEI_AVG_CLL,      "16bit unsigned number indicating max avg pixel intensity\n"},
158     {"",                    "",                             GRPINFO,                  "\n " " VUI  Parameters         \n" " ------------------------\n"},
159     {"-vui",                "--vui_enable",                 VUI_ENABLE,               "1- enable, 0- disable {0}\n"},
160     {"-arFlag",             "--aspect_ratio_info_present_flag",   ASPECT_RATIO_INFO_PRESENT_FLAG,  "Aspect Ratio 1-enable 0-diable {0} \n"},
161     {"-arIdc",              "--aspect_ratio_idc",           ASPECT_RATIO_IDC,        "Aspect Ration IDC {255}[0:255]\n"},
162     {"-sarw",               "--sar_width",                  SAR_WIDTH,               "SAR Width {4}[0:65535]\n"},
163     {"-sarh",               "--sar_height",                 SAR_HEIGHT,              "SAR Height {3}[0:65535] \n"},
164     {"-overscan",           "--overscan_info_present_flag", OVERSCAN_INFO_PRESENT_FLAG,  "Overscan Info. 1-enable 0-disable {0}\n"},
165     {"-overscanValid",      "--overscan_appropriate_flag",  OVERSCAN_APPROPRIATE_FLAG,   "Overscan Appropriate 1-enable 0-disable {0}\n"},
166     {"-vidsigp",            "--video_signal_type_present_flag",      VIDEO_SIGNAL_TYPE_PRESENT_FLAG,    "Video Signal Type Present. 1-enable 0-diable {1} \n"},
167     {"-vidfmt",             "--video_format",               VIDEO_FORMAT,            "Video Format {5}[0:5]\n"},
168     {"-fullrange",          "--video_full_range_flag",      VIDEO_FULL_RANGE_FLAG,   "Video Full Range. 1-enable 0-diable {1}\n"},
169     {"-colorDesc",          "--colour_description_present_flag",     COLOUR_DESCRIPTION_PRESENT_FLAG,  "Colour description.1-enable 0-diable {0}\n"},
170     {"-colorPrim",          "--colour_primaries",           COLOUR_PRIMARIES,        "Colour Primaries {2}[0:255] \n"},
171     {"-xferCh",             "--transfer_characteristics",   TRANSFER_CHARACTERISTICS,                  "Transfer Characteristic {2}[0:255]\n"},
172     {"-mxcoeff",            "--matrix_coefficients",        MATRIX_COEFFICIENTS,                       "Matrix Coefficients {2}[0:255]\n"},
173     {"-chloc",              "--chroma_loc_info_present_flag",        CHROMA_LOC_INFO_PRESENT_FLAG,     "Presence of chroma_sample_loc_type_top_field and "
174     "chroma_sample_loc_type_bottom_field.1-enable 0-diable {0}\n"},
175     {"-chtf",               "--chroma_sample_loc_type_top_field",    CHROMA_SAMPLE_LOC_TYPE_TOP_FIELD, "Location of Chroma samples for Top field.{0}[0,1] \n"},
176     {"-chbf",               "--chroma_sample_loc_type_bottom_field", CHROMA_SAMPLE_LOC_TYPE_BOTTOM_FIELD,    "Location of Chroma samples for Bottom field..{0}[0,1] \n"},
177     {"-timinginfo",         "--timing_info_present_flag",            TIMING_INFO_PRESENT_FLAG,        "Timing info.1-enable 0-diable {0}\n"},
178     {"-vuihrdparam",        "--vui_hrd_parameters_present_flag",     VUI_HRD_PARAMETERS_PRESENT_FLAG,  "HRD parameters.1-enable 0-diable {0} \n"},
179     {"-nalhrdparam",        "--nal_hrd_parameters_present_flag",     NAL_HRD_PARAMETERS_PRESENT_FLAG,  "NAL HRD parameters.1-enable 0-diable {0}\n"}
180 };
181 // clang-format on
182 
183 /*!
184 ******************************************************************************
185 * \if Function name : print_usage \endif
186 *
187 * \brief
188 *    prints application usage
189 *
190 *****************************************************************************
191 */
print_usage(void)192 void print_usage(void)
193 {
194     WORD32 i = 0;
195     WORD32 num_entries = sizeof(argument_mapping) / sizeof(argument_t);
196 
197     printf("\nUsage:\n");
198     while(i < num_entries)
199     {
200         printf("%-32s\t %s", argument_mapping[i].argument_name, argument_mapping[i].description);
201         i++;
202     }
203 }
204 
205 /*!
206 ******************************************************************************
207 * \if Function name : get_argument \endif
208 *
209 * \brief
210 *    Maps input string to a argument. If the input string is not recognized,
211 *    returns INVALID
212 *
213 *****************************************************************************
214 */
get_argument(CHAR * name)215 ARGUMENT_T get_argument(CHAR *name)
216 {
217     WORD32 i;
218     WORD32 num_entries = sizeof(argument_mapping) / sizeof(argument_t);
219 
220     for(i = 0; i < num_entries; i++)
221     {
222         if((0 == strcmp(argument_mapping[i].argument_name, name)) ||
223            ((0 == strcmp(argument_mapping[i].argument_shortname, name)) &&
224             (0 != strcmp(argument_mapping[i].argument_shortname, "--"))))
225         {
226             return argument_mapping[i].argument;
227         }
228     }
229     return INVALID;
230 }
231 
232 /*!
233 ******************************************************************************
234 * \if Function name : codec_exit \endif
235 *
236 * \brief
237 *    handles unrecoverable errors. Prints error message to console and exits
238 *
239 *****************************************************************************
240 */
codec_exit(CHAR * pc_err_message)241 void codec_exit(CHAR *pc_err_message)
242 {
243     printf("%s\n", pc_err_message);
244     exit(-1);
245 }
246 
247 /*!
248 ******************************************************************************
249 * \if Function name : parse_argument \endif
250 *
251 * \brief
252 *    Parse input argument
253 *
254 *****************************************************************************
255 */
parse_argument(appl_ctxt_t * ps_ctxt,CHAR * argument,CHAR * value)256 IHEVCE_PLUGIN_STATUS_T parse_argument(appl_ctxt_t *ps_ctxt, CHAR *argument, CHAR *value)
257 {
258     ihevce_static_cfg_params_t *ps_static_prms = &ps_ctxt->s_static_cfg_prms;
259     ARGUMENT_T arg = get_argument(argument);
260     WORD32 i4_value = 0;
261     UWORD8 au1_keywd_str[STR_LEN];
262     UWORD8 *pu1_keywd_str = au1_keywd_str;
263 
264     switch(arg)
265     {
266     case HELP:
267         print_usage();
268         return IHEVCE_EFAIL;
269 
270     case VERSION:
271         break;
272 
273     case INPUT_YUV:
274         sscanf(value, "%s", ps_ctxt->au1_in_file);
275         assert(strlen((char *)ps_ctxt->au1_in_file) < STR_LEN);
276         break;
277 
278     case OUTPUT:
279         sscanf(value, "%s", ps_ctxt->au1_out_file[0][0]);
280         assert(strlen((char *)ps_ctxt->au1_out_file[0][0]) < STR_LEN);
281         break;
282     case NUM_FRAMES_TO_ENCODE:
283         sscanf(value, "%d", &i4_value);
284         if(i4_value < 0)
285             ps_static_prms->s_config_prms.i4_num_frms_to_encode = INT32_MAX - 1;
286         else
287             ps_static_prms->s_config_prms.i4_num_frms_to_encode = i4_value;
288         break;
289 
290     case LOG_DUMP_LEVEL:
291         sscanf(value, "%d", &i4_value);
292         ps_static_prms->i4_log_dump_level = i4_value;
293         break;
294     case SRC_WIDTH:
295         sscanf(value, "%d", &i4_value);
296         ps_static_prms->s_src_prms.i4_width = i4_value;
297         break;
298 
299     case SRC_HEIGHT:
300         sscanf(value, "%d", &i4_value);
301         ps_static_prms->s_src_prms.i4_height = i4_value;
302         break;
303 
304     case SRC_FRAME_RATE_NUM:
305         sscanf(value, "%d", &i4_value);
306         ps_static_prms->s_src_prms.i4_frm_rate_num = i4_value;
307         break;
308 
309     case SRC_FRAME_RATE_DENOM:
310         sscanf(value, "%d", &i4_value);
311         ps_static_prms->s_src_prms.i4_frm_rate_denom = i4_value;
312         break;
313     case INPUT_CHROMA_FORMAT:
314         sscanf(value, "%d", &i4_value);
315         ps_static_prms->s_src_prms.inp_chr_format = (IV_COLOR_FORMAT_T)i4_value;
316         break;
317     case CODEC_LEVEL:
318         sscanf(value, "%d", &i4_value);
319         ps_static_prms->s_tgt_lyr_prms.as_tgt_params[0].i4_codec_level = i4_value;
320         break;
321     case TGT_BITRATE:
322         sscanf(value, "%d", &i4_value);
323         ps_static_prms->s_tgt_lyr_prms.as_tgt_params[0].ai4_tgt_bitrate[0] = i4_value;
324         break;
325 
326     case FRAME_QP:
327         sscanf(value, "%d", &i4_value);
328         ps_static_prms->s_tgt_lyr_prms.as_tgt_params[0].ai4_frame_qp[0] = i4_value;
329         break;
330     case MAX_CLOSED_GOP_PERIOD:
331         sscanf(value, "%d", &i4_value);
332         ps_static_prms->s_coding_tools_prms.i4_max_closed_gop_period = i4_value;
333         break;
334 
335     case MIN_CLOSED_GOP_PERIOD:
336         sscanf(value, "%d", &i4_value);
337         ps_static_prms->s_coding_tools_prms.i4_min_closed_gop_period = i4_value;
338         break;
339 
340     case MAX_CRA_OPEN_GOP_PERIOD:
341         sscanf(value, "%d", &i4_value);
342         ps_static_prms->s_coding_tools_prms.i4_max_cra_open_gop_period = i4_value;
343         break;
344 
345     case MAX_I_OPEN_GOP_PERIOD:
346         sscanf(value, "%d", &i4_value);
347         ps_static_prms->s_coding_tools_prms.i4_max_i_open_gop_period = i4_value;
348         break;
349 
350     case MAX_TEMPORAL_LAYERS:
351         sscanf(value, "%d", &i4_value);
352         ps_static_prms->s_coding_tools_prms.i4_max_temporal_layers = i4_value;
353         break;
354 
355     case QUALITY_PRESET:
356         sscanf(value, "%d", &i4_value);
357         ps_static_prms->s_tgt_lyr_prms.as_tgt_params[0].i4_quality_preset =
358             (IHEVCE_QUALITY_CONFIG_T)i4_value;
359         break;
360 
361     case DEBLOCKING_TYPE:
362         sscanf(value, "%d", &i4_value);
363         ps_static_prms->s_coding_tools_prms.i4_deblocking_type = i4_value;
364         break;
365 
366     case USE_DEFAULT_SC_MTX:
367         sscanf(value, "%d", &i4_value);
368         ps_static_prms->s_coding_tools_prms.i4_use_default_sc_mtx = i4_value;
369         break;
370 
371     case ENABLE_ENTROPY_SYNC:
372         sscanf(value, "%d", &i4_value);
373         ps_static_prms->s_coding_tools_prms.i4_enable_entropy_sync = i4_value;
374         break;
375 
376     case MAX_TR_TREE_DEPTH_I:
377         sscanf(value, "%d", &i4_value);
378         ps_static_prms->s_config_prms.i4_max_tr_tree_depth_I = i4_value;
379         break;
380 
381     case MAX_TR_TREE_DEPTH_NI:
382         sscanf(value, "%d", &i4_value);
383         ps_static_prms->s_config_prms.i4_max_tr_tree_depth_nI = i4_value;
384         break;
385 
386     case MAX_SEARCH_RANGE_HORZ:
387         sscanf(value, "%d", &i4_value);
388         ps_static_prms->s_config_prms.i4_max_search_range_horz = i4_value;
389         break;
390 
391     case MAX_SEARCH_RANGE_VERT:
392         sscanf(value, "%d", &i4_value);
393         ps_static_prms->s_config_prms.i4_max_search_range_vert = i4_value;
394         break;
395     case ARCH_TYPE:
396         sscanf(value, "%d", &i4_value);
397         switch(i4_value)
398         {
399         case 0:
400             ps_static_prms->e_arch_type = ARCH_NA;
401             break;
402         case 4:
403             ps_static_prms->e_arch_type = ARCH_ARM_NONEON;
404             break;
405         default:
406             ps_static_prms->e_arch_type = ARCH_ARM_NONEON;
407             break;
408         }
409         break;
410 
411     case NUM_CORES:
412         sscanf(value, "%d", &i4_value);
413         ps_static_prms->s_multi_thrd_prms.i4_max_num_cores = i4_value;
414         if((i4_value > MAX_NUM_CORES) || (i4_value < 1))
415         {
416             printf("APLN ERROR >> Number of cores per CPU configured is "
417                    "unsupported \n");
418             return IHEVCE_EFAIL;
419         }
420         break;
421     case RATE_CONTROL_MODE:
422         sscanf(value, "%d", &i4_value);
423         ps_static_prms->s_config_prms.i4_rate_control_mode = i4_value;
424         break;
425     case CU_LEVEL_RC:
426         sscanf(value, "%d", &i4_value);
427         ps_static_prms->s_config_prms.i4_cu_level_rc = i4_value;
428         break;
429     case MAX_FRAME_QP:
430         sscanf(value, "%d", &i4_value);
431         ps_static_prms->s_config_prms.i4_max_frame_qp = i4_value;
432         break;
433 
434     case MIN_FRAME_QP:
435         sscanf(value, "%d", &i4_value);
436         ps_static_prms->s_config_prms.i4_min_frame_qp = i4_value;
437         break;
438 
439     case RC_LOOK_AHEAD_PICS:
440         sscanf(value, "%d", &i4_value);
441         ps_static_prms->s_lap_prms.i4_rc_look_ahead_pics = i4_value;
442         break;
443 
444     case CODEC_TYPE:
445         sscanf(value, "%d", &i4_value);
446         ps_static_prms->s_out_strm_prms.i4_codec_type = i4_value;
447         break;
448 
449     case CODEC_PROFILE:
450         sscanf(value, "%d", &i4_value);
451         ps_static_prms->s_out_strm_prms.i4_codec_profile = i4_value;
452         break;
453 
454     case CODEC_TIER:
455         sscanf(value, "%d", &i4_value);
456         ps_static_prms->s_out_strm_prms.i4_codec_tier = i4_value;
457         break;
458 
459     case SPS_AT_CDR_ENABLE:
460         sscanf(value, "%d", &i4_value);
461         ps_static_prms->s_out_strm_prms.i4_sps_at_cdr_enable = i4_value;
462         break;
463 
464     case VUI_ENABLE:
465         sscanf(value, "%d", &i4_value);
466         ps_static_prms->s_out_strm_prms.i4_vui_enable = i4_value;
467         break;
468 
469     case SEI_ENABLE_FLAGS:
470         sscanf(value, "%d", &i4_value);
471         ps_static_prms->s_out_strm_prms.i4_sei_enable_flag = i4_value;
472         break;
473 
474     case SEI_PAYLOAD_ENABLE_FLAGS:
475         sscanf(value, "%d", &i4_value);
476         ps_static_prms->s_out_strm_prms.i4_sei_payload_enable_flag = i4_value;
477         break;
478 
479     case SEI_PAYLOAD_PATH:
480         sscanf(value, "%s", ps_ctxt->ai1_sei_payload_path);
481         assert(strlen((char *)ps_ctxt->ai1_sei_payload_path) < STR_LEN);
482         break;
483 
484     case SEI_BUFFER_PERIOD_FLAGS:
485         sscanf(value, "%d", &i4_value);
486         ps_static_prms->s_out_strm_prms.i4_sei_buffer_period_flags = i4_value;
487         break;
488 
489     case SEI_PIC_TIMING_FLAGS:
490         sscanf(value, "%d", &i4_value);
491         ps_static_prms->s_out_strm_prms.i4_sei_pic_timing_flags = i4_value;
492         break;
493 
494     case SEI_RECOVERY_POINT_FLAGS:
495         sscanf(value, "%d", &i4_value);
496         ps_static_prms->s_out_strm_prms.i4_sei_recovery_point_flags = i4_value;
497         break;
498 
499     case SEI_HASH_FLAGS:
500         sscanf(value, "%d", &i4_value);
501         ps_static_prms->s_out_strm_prms.i4_decoded_pic_hash_sei_flag = i4_value;
502         break;
503 
504     case SEI_MASTERING_DISP_COLOUR_VOL_FLAGS:
505         sscanf(value, "%d", &i4_value);
506         ps_static_prms->s_out_strm_prms.i4_sei_mastering_disp_colour_vol_flags = i4_value;
507         break;
508 
509     case DISPLAY_PRIMARIES_X:
510     {
511         char *token;
512         char *str;
513         const char s[2] = ",";
514         WORD32 i;
515 
516         if(0 == ps_static_prms->s_out_strm_prms.i4_sei_mastering_disp_colour_vol_flags)
517         {
518             break;
519         }
520         sscanf(value, "%s", pu1_keywd_str);
521 
522         str = (char *)pu1_keywd_str;
523         token = strtok(str, s);
524 
525         for(i = 0; i < 3; i++)
526         {
527             if(token != NULL)
528             {
529                 sscanf(token, "%d", &i4_value);
530                 ps_static_prms->s_out_strm_prms.au2_display_primaries_x[i] = i4_value;
531                 token = strtok(NULL, s);
532             }
533             else if((token == NULL) && (i != 2))
534             {
535                 printf("APLN ERROR >> Insufficient number of display_primary_x "
536                        "values entered \n");
537                 return IHEVCE_EFAIL;
538             }
539         }
540     }
541     break;
542 
543     case DISPLAY_PRIMARIES_Y:
544     {
545         char *token;
546         char *str;
547         const char s[2] = ",";
548         WORD32 i;
549 
550         if(0 == ps_static_prms->s_out_strm_prms.i4_sei_mastering_disp_colour_vol_flags)
551         {
552             break;
553         }
554         sscanf(value, "%s", pu1_keywd_str);
555 
556         str = (char *)pu1_keywd_str;
557         token = strtok(str, s);
558 
559         for(i = 0; i < 3; i++)
560         {
561             if(token != NULL)
562             {
563                 sscanf(token, "%d", &i4_value);
564                 ps_static_prms->s_out_strm_prms.au2_display_primaries_y[i] = i4_value;
565                 token = strtok(NULL, s);
566             }
567             else if((token == NULL) && (i != 2))
568             {
569                 printf("APLN ERROR >> Insufficient number of display_primary_x "
570                        "values entered \n");
571                 return IHEVCE_EFAIL;
572             }
573         }
574     }
575     break;
576 
577     case WHITE_POINT_X:
578         sscanf(value, "%d", &i4_value);
579         ps_static_prms->s_out_strm_prms.u2_white_point_x = i4_value;
580         break;
581 
582     case WHITE_POINT_Y:
583         sscanf(value, "%d", &i4_value);
584         ps_static_prms->s_out_strm_prms.u2_white_point_y = i4_value;
585         break;
586 
587     case MAX_DISPLAY_MASTERING_LUMINANCE:
588         sscanf(value, "%d", &i4_value);
589         ps_static_prms->s_out_strm_prms.u4_max_display_mastering_luminance = i4_value;
590         break;
591 
592     case MIN_DISPLAY_MASTERING_LUMINANCE:
593         sscanf(value, "%d", &i4_value);
594         ps_static_prms->s_out_strm_prms.u4_min_display_mastering_luminance = i4_value;
595         break;
596 
597     case SEI_CLL_INFO_ENABLE:
598         sscanf(value, "%d", &i4_value);
599         ps_static_prms->s_out_strm_prms.i4_sei_cll_enable = i4_value;
600         break;
601 
602     case SEI_MAX_CLL:
603         sscanf(value, "%d", &i4_value);
604         ps_static_prms->s_out_strm_prms.u2_sei_max_cll = i4_value;
605         break;
606 
607     case SEI_AVG_CLL:
608         sscanf(value, "%d", &i4_value);
609         ps_static_prms->s_out_strm_prms.u2_sei_avg_cll = i4_value;
610         break;
611 
612     case TILES_ENABLED_FLAG:
613         sscanf(value, "%d", &i4_value);
614         ps_static_prms->s_app_tile_params.i4_tiles_enabled_flag = i4_value;
615         break;
616     case SLICE_SEGMENT_MODE:
617         sscanf(value, "%d", &i4_value);
618         ps_static_prms->s_slice_params.i4_slice_segment_mode = i4_value;
619         break;
620     case ASPECT_RATIO_INFO_PRESENT_FLAG:
621         sscanf(value, "%d", &i4_value);
622         ps_static_prms->s_vui_sei_prms.u1_aspect_ratio_info_present_flag = i4_value;
623         break;
624 
625     case ASPECT_RATIO_IDC:
626         sscanf(value, "%d", &i4_value);
627         ps_static_prms->s_vui_sei_prms.au1_aspect_ratio_idc[0] = i4_value;
628         break;
629 
630     case SAR_WIDTH:
631         sscanf(value, "%d", &i4_value);
632         ps_static_prms->s_vui_sei_prms.au2_sar_width[0] = i4_value;
633         break;
634 
635     case SAR_HEIGHT:
636         sscanf(value, "%d", &i4_value);
637         ps_static_prms->s_vui_sei_prms.au2_sar_height[0] = i4_value;
638         break;
639 
640     case OVERSCAN_INFO_PRESENT_FLAG:
641         sscanf(value, "%d", &i4_value);
642         ps_static_prms->s_vui_sei_prms.u1_overscan_info_present_flag = i4_value;
643         break;
644 
645     case OVERSCAN_APPROPRIATE_FLAG:
646         sscanf(value, "%d", &i4_value);
647         ps_static_prms->s_vui_sei_prms.u1_overscan_appropriate_flag = i4_value;
648         break;
649 
650     case VIDEO_SIGNAL_TYPE_PRESENT_FLAG:
651         sscanf(value, "%d", &i4_value);
652         ps_static_prms->s_vui_sei_prms.u1_video_signal_type_present_flag = i4_value;
653         break;
654 
655     case VIDEO_FORMAT:
656         sscanf(value, "%d", &i4_value);
657         ps_static_prms->s_vui_sei_prms.u1_video_format = i4_value;
658         break;
659 
660     case VIDEO_FULL_RANGE_FLAG:
661         sscanf(value, "%d", &i4_value);
662         ps_static_prms->s_vui_sei_prms.u1_video_full_range_flag = i4_value;
663         break;
664 
665     case COLOUR_DESCRIPTION_PRESENT_FLAG:
666         sscanf(value, "%d", &i4_value);
667         ps_static_prms->s_vui_sei_prms.u1_colour_description_present_flag = i4_value;
668         break;
669 
670     case COLOUR_PRIMARIES:
671         sscanf(value, "%d", &i4_value);
672         ps_static_prms->s_vui_sei_prms.u1_colour_primaries = i4_value;
673         break;
674 
675     case TRANSFER_CHARACTERISTICS:
676         sscanf(value, "%d", &i4_value);
677         ps_static_prms->s_vui_sei_prms.u1_transfer_characteristics = i4_value;
678         break;
679 
680     case MATRIX_COEFFICIENTS:
681         sscanf(value, "%d", &i4_value);
682         ps_static_prms->s_vui_sei_prms.u1_matrix_coefficients = i4_value;
683         break;
684 
685     case CHROMA_LOC_INFO_PRESENT_FLAG:
686         sscanf(value, "%d", &i4_value);
687         ps_static_prms->s_vui_sei_prms.u1_chroma_loc_info_present_flag = i4_value;
688         break;
689 
690     case CHROMA_SAMPLE_LOC_TYPE_TOP_FIELD:
691         sscanf(value, "%d", &i4_value);
692         ps_static_prms->s_vui_sei_prms.u1_chroma_sample_loc_type_top_field = i4_value;
693         break;
694 
695     case CHROMA_SAMPLE_LOC_TYPE_BOTTOM_FIELD:
696         sscanf(value, "%d", &i4_value);
697         ps_static_prms->s_vui_sei_prms.u1_chroma_sample_loc_type_bottom_field = i4_value;
698         break;
699 
700     case TIMING_INFO_PRESENT_FLAG:
701         sscanf(value, "%d", &i4_value);
702         ps_static_prms->s_vui_sei_prms.u1_timing_info_present_flag = i4_value;
703         break;
704 
705     case VUI_HRD_PARAMETERS_PRESENT_FLAG:
706         sscanf(value, "%d", &i4_value);
707         ps_static_prms->s_vui_sei_prms.u1_vui_hrd_parameters_present_flag = i4_value;
708         break;
709 
710     case NAL_HRD_PARAMETERS_PRESENT_FLAG:
711         sscanf(value, "%d", &i4_value);
712         ps_static_prms->s_vui_sei_prms.u1_nal_hrd_parameters_present_flag = i4_value;
713         break;
714 
715     case INVALID:
716     default:
717         printf("APLN ERROR >> Argument %s is invalid, ignoring \n", argument);
718         break;
719     }
720 
721     return IHEVCE_EOK;
722 }
723 
724 /*!
725 ******************************************************************************
726 * \if Function name : read_cfg_file \endif
727 *
728 * \brief
729 *    Parse config file
730 *
731 *****************************************************************************
732 */
read_cfg_file(appl_ctxt_t * ps_ctxt,FILE * fp_cfg)733 IHEVCE_PLUGIN_STATUS_T read_cfg_file(appl_ctxt_t *ps_ctxt, FILE *fp_cfg)
734 {
735     while(1)
736     {
737         CHAR line[STR_LEN] = { '\0' };
738         CHAR argument[STR_LEN] = { '\0' };
739         CHAR value[STR_LEN];
740         CHAR description[STR_LEN];
741         IHEVCE_PLUGIN_STATUS_T status;
742 
743         if(NULL == fgets(line, STR_LEN, fp_cfg))
744             return IHEVCE_EOK;
745 
746         /* split string on whitespace */
747         sscanf(line, "%s %s %s", argument, value, description);
748         if(argument[0] == '\0' || argument[0] == '#')
749             continue;
750 
751         status = parse_argument(ps_ctxt, argument, value);
752         if(status != IHEVCE_EOK)
753         {
754             return status;
755         }
756     }
757 }
758 
759 /*!
760 ******************************************************************************
761 * \if Function name : libihevce_encode_init \endif
762 *
763 * \brief
764 *    Allocates the memory and calls encoder init
765 *
766 *****************************************************************************
767 */
libihevce_encode_init(appl_ctxt_t * ps_ctxt)768 IHEVCE_PLUGIN_STATUS_T libihevce_encode_init(appl_ctxt_t *ps_ctxt)
769 {
770     ihevce_static_cfg_params_t *params = &ps_ctxt->s_static_cfg_prms;
771     CHAR ac_error[STR_LEN];
772 
773     /* call the function to initialise encoder*/
774     if(IHEVCE_EFAIL == ihevce_init(params, (void *)&ps_ctxt->ihevceHdl))
775     {
776         sprintf(ac_error, "Unable to initialise libihevce encoder\n");
777         return IHEVCE_EFAIL;
778     }
779 
780     return IHEVCE_EOK;
781 }
782 
783 /*!
784 ******************************************************************************
785 * \if Function name : allocate_input \endif
786 *
787 * \brief
788 *    allocate input buffers
789 *
790 *****************************************************************************
791 */
allocate_input(appl_ctxt_t * ps_ctxt,ihevce_inp_buf_t * inp_pic)792 IHEVCE_PLUGIN_STATUS_T allocate_input(appl_ctxt_t *ps_ctxt, ihevce_inp_buf_t *inp_pic)
793 {
794     ihevce_static_cfg_params_t *params = &ps_ctxt->s_static_cfg_prms;
795     WORD32 y_sz = params->s_src_prms.i4_width * params->s_src_prms.i4_height;
796     WORD32 uv_sz = y_sz >> 1;
797     WORD32 pic_size = y_sz + uv_sz;
798     UWORD8 *pu1_buf;
799 
800 #ifdef X86_MINGW
801     pu1_buf = (UWORD8 *)_aligned_malloc(pic_size, 64);
802 #else
803     if (0 != posix_memalign((void **)&pu1_buf, 64, pic_size))
804     {
805         return (IHEVCE_EFAIL);
806     }
807 #endif
808     if(NULL == pu1_buf)
809     {
810         return (IHEVCE_EFAIL);
811     }
812     if(IV_YUV_420P == params->s_src_prms.inp_chr_format)
813     {
814         inp_pic->apv_inp_planes[0] = pu1_buf;
815         inp_pic->apv_inp_planes[1] = pu1_buf + y_sz;
816         inp_pic->apv_inp_planes[2] = pu1_buf + y_sz + (uv_sz >> 1);
817 
818         inp_pic->ai4_inp_strd[0] = params->s_src_prms.i4_width;
819         inp_pic->ai4_inp_strd[1] = params->s_src_prms.i4_width >> 1;
820         inp_pic->ai4_inp_strd[2] = params->s_src_prms.i4_width >> 1;
821 
822         inp_pic->ai4_inp_size[0] = y_sz;
823         inp_pic->ai4_inp_size[1] = (uv_sz >> 1);
824         inp_pic->ai4_inp_size[2] = (uv_sz >> 1);
825     }
826     else if(IV_YUV_420SP_UV == params->s_src_prms.inp_chr_format)
827     {
828         inp_pic->apv_inp_planes[0] = pu1_buf;
829         inp_pic->apv_inp_planes[1] = pu1_buf + y_sz;
830         inp_pic->apv_inp_planes[2] = NULL;
831 
832         inp_pic->ai4_inp_strd[0] = params->s_src_prms.i4_width;
833         inp_pic->ai4_inp_strd[1] = params->s_src_prms.i4_width;
834         inp_pic->ai4_inp_strd[2] = 0;
835 
836         inp_pic->ai4_inp_size[0] = y_sz;
837         inp_pic->ai4_inp_size[1] = uv_sz;
838         inp_pic->ai4_inp_size[2] = 0;
839     }
840 
841     inp_pic->i4_curr_bitrate = params->s_tgt_lyr_prms.as_tgt_params[0].ai4_tgt_bitrate[0];
842     inp_pic->i4_curr_peak_bitrate = params->s_tgt_lyr_prms.as_tgt_params[0].ai4_peak_bitrate[0];
843     inp_pic->u8_pts = 0;
844     inp_pic->i4_force_idr_flag = 0;
845 
846     return IHEVCE_EOK;
847 }
848 
849 /*!
850 ******************************************************************************
851 * \if Function name : read_input \endif
852 *
853 * \brief
854 *    read input from a file
855 *
856 *****************************************************************************
857 */
read_input(appl_ctxt_t * ps_ctxt,FILE * fp,ihevce_inp_buf_t * inp_pic)858 IHEVCE_PLUGIN_STATUS_T read_input(appl_ctxt_t *ps_ctxt, FILE *fp, ihevce_inp_buf_t *inp_pic)
859 {
860     ihevce_static_cfg_params_t *params = &ps_ctxt->s_static_cfg_prms;
861     WORD32 au4_wd[3] = { 0 };
862     WORD32 au4_ht[3] = { 0 };
863     WORD32 num_comp = 3;
864     WORD32 comp_idx;
865     WORD32 i;
866 
867     if(IV_YUV_420P == params->s_src_prms.inp_chr_format)
868     {
869         au4_wd[0] = params->s_src_prms.i4_width;
870         au4_wd[1] = au4_wd[2] = params->s_src_prms.i4_width >> 1;
871         au4_ht[0] = params->s_src_prms.i4_height;
872         au4_ht[1] = au4_ht[2] = params->s_src_prms.i4_height >> 1;
873 
874         num_comp = 3;
875     }
876     else if(IV_YUV_420SP_UV == params->s_src_prms.inp_chr_format)
877     {
878         au4_wd[0] = params->s_src_prms.i4_width;
879         au4_wd[1] = params->s_src_prms.i4_width;
880         au4_ht[0] = params->s_src_prms.i4_height;
881         au4_ht[1] = params->s_src_prms.i4_height >> 1;
882 
883         num_comp = 2;
884     }
885 
886     for(comp_idx = 0; comp_idx < num_comp; comp_idx++)
887     {
888         WORD32 wd = au4_wd[comp_idx];
889         WORD32 ht = au4_ht[comp_idx];
890         WORD32 strd = inp_pic->ai4_inp_strd[comp_idx];
891         UWORD8 *pu1_buf = inp_pic->apv_inp_planes[comp_idx];
892 
893         for(i = 0; i < ht; i++)
894         {
895             WORD32 bytes = fread(pu1_buf, sizeof(UWORD8), wd, fp);
896             if(bytes != wd)
897             {
898                 return (IHEVCE_EFAIL);
899             }
900             pu1_buf += strd;
901         }
902     }
903 
904     return IHEVCE_EOK;
905 }
906 
907 /*!
908 ******************************************************************************
909 * \if Function name : write_output \endif
910 *
911 * \brief
912 *    Write bitstream buffers to a file
913 *
914 *****************************************************************************
915 */
write_output(FILE * fp,ihevce_out_buf_t * out_pic)916 IHEVCE_PLUGIN_STATUS_T write_output(FILE *fp, ihevce_out_buf_t *out_pic)
917 {
918     WORD32 bytes;
919 
920     bytes = fwrite(out_pic->pu1_output_buf, sizeof(UWORD8), out_pic->i4_bytes_generated, fp);
921     if(bytes != out_pic->i4_bytes_generated)
922         return IHEVCE_EFAIL;
923 
924     return IHEVCE_EOK;
925 }
926 
927 /*!
928 ******************************************************************************
929 * \if Function name : free_input \endif
930 *
931 * \brief
932 *    free input buffers
933 *
934 *****************************************************************************
935 */
free_input(ihevce_inp_buf_t * inp_pic)936 void free_input(ihevce_inp_buf_t *inp_pic)
937 {
938     if(inp_pic->apv_inp_planes[0])
939     {
940 #ifdef X86_MINGW
941         _aligned_free(inp_pic->apv_inp_planes[0]);
942 #else
943         free(inp_pic->apv_inp_planes[0]);
944 #endif
945     }
946 }
947 
948 /*!
949 ******************************************************************************
950 * \if Function name : libihevce_encode_close \endif
951 *
952 * \brief
953 *    Frees all the allocated resources and call encoder free
954 *
955 *****************************************************************************
956 */
libihevce_encode_close(appl_ctxt_t * ps_ctxt)957 IHEVCE_PLUGIN_STATUS_T libihevce_encode_close(appl_ctxt_t *ps_ctxt)
958 {
959     /* encoder close */
960     if(ps_ctxt->ihevceHdl)
961         ihevce_close(ps_ctxt->ihevceHdl);
962 
963     return IHEVCE_EOK;
964 }
965 
966 /*!
967 ******************************************************************************
968 * \if Function name : libihevce_encode_frame \endif
969 *
970 * \brief
971 *    Calls encoder process and copied the output to pckt buffer
972 *
973 *****************************************************************************
974 */
libihevce_encode_frame(appl_ctxt_t * ps_ctxt,FILE * pf_inp_yuv,FILE * pf_out)975 IHEVCE_PLUGIN_STATUS_T libihevce_encode_frame(appl_ctxt_t *ps_ctxt, FILE *pf_inp_yuv, FILE *pf_out)
976 {
977     ihevce_static_cfg_params_t *params = &ps_ctxt->s_static_cfg_prms;
978     IHEVCE_PLUGIN_STATUS_T status = IHEVCE_EOK;
979     WORD32 i4_num_frames = 0;
980     ihevce_inp_buf_t inp_pic;
981     ihevce_out_buf_t out_pic;
982     CHAR ac_error[STR_LEN];
983     profile_database_t s_profile_data;
984 #if HEADER_MODE
985     ihevce_out_buf_t out_pic_hdr;
986 #endif
987 
988     (void)s_profile_data;
989     memset(&inp_pic, 0, sizeof(inp_pic));
990     memset(&out_pic, 0, sizeof(out_pic));
991 #if HEADER_MODE
992     memset(&out_pic_hdr, 0, sizeof(out_pic_hdr));
993 #endif
994 
995     status = allocate_input(ps_ctxt, &inp_pic);
996     if(status != IHEVCE_EOK)
997     {
998         sprintf(ac_error, "Unable to allocate input");
999         return IHEVCE_EFAIL;
1000     }
1001 
1002 #if HEADER_MODE
1003     status = ihevce_encode_header(ps_ctxt->ihevceHdl, &out_pic_hdr);
1004     if(status != IHEVCE_EOK)
1005     {
1006         sprintf(ac_error, "encode header call failed");
1007         return IHEVCE_EFAIL;
1008     }
1009     if(out_pic_hdr.i4_bytes_generated)
1010     {
1011         status = write_output(pf_out, &out_pic_hdr);
1012         if(status != IHEVCE_EOK)
1013         {
1014             sprintf(ac_error, "Unable to write output");
1015             return IHEVCE_EFAIL;
1016         }
1017     }
1018 #endif
1019 
1020     PROFILE_INIT(&s_profile_data);
1021 
1022     while(1)
1023     {
1024         ihevce_inp_buf_t *ps_inp_pic = &inp_pic;
1025 
1026         ps_inp_pic->i4_force_idr_flag = 0;
1027 
1028         if(i4_num_frames < params->s_config_prms.i4_num_frms_to_encode)
1029         {
1030             status = read_input(ps_ctxt, pf_inp_yuv, &inp_pic);
1031             if(status != IHEVCE_EOK)
1032             {
1033                 ps_inp_pic = NULL;
1034             }
1035         }
1036         else
1037         {
1038             ps_inp_pic = NULL;
1039         }
1040 #if DYN_BITRATE_TEST
1041         if((i4_num_frames == 200) && (ps_inp_pic != NULL))
1042         {
1043             ps_inp_pic->i4_curr_bitrate = ps_inp_pic->i4_curr_bitrate << 1;
1044         }
1045 #endif
1046 #if FORCE_IDR_TEST
1047         if((i4_num_frames == 70) && (ps_inp_pic != NULL))
1048         {
1049             ps_inp_pic->i4_force_idr_flag = 1;
1050         }
1051 #endif
1052         /* call encoder process frame */
1053         PROFILE_START(&s_profile_data);
1054         status = ihevce_encode(ps_ctxt->ihevceHdl, ps_inp_pic, &out_pic);
1055         PROFILE_STOP(&s_profile_data, NULL);
1056         if(status != IHEVCE_EOK)
1057         {
1058             sprintf(ac_error, "Unable to process encode");
1059             return IHEVCE_EFAIL;
1060         }
1061 
1062         if(out_pic.i4_bytes_generated)
1063         {
1064             status = write_output(pf_out, &out_pic);
1065             if(status != IHEVCE_EOK)
1066             {
1067                 sprintf(ac_error, "Unable to write output");
1068                 return IHEVCE_EFAIL;
1069             }
1070         }
1071 
1072         if(out_pic.i4_end_flag)
1073             break;
1074 
1075         i4_num_frames++;
1076         inp_pic.u8_pts +=
1077             (1000000 * params->s_src_prms.i4_frm_rate_denom) / params->s_src_prms.i4_frm_rate_num;
1078     }
1079 
1080     PROFILE_END(&s_profile_data, "encode API call");
1081 
1082     free_input(&inp_pic);
1083 
1084     return IHEVCE_EOK;
1085 }
1086 
1087 /*!
1088 ******************************************************************************
1089 * \if Function name : main \endif
1090 *
1091 * \brief
1092 *    Application to demonstrate codec API. Shows how to use create,
1093 *    process, control and delete
1094 *
1095 *****************************************************************************
1096 */
main(int argc,char * argv[])1097 int main(int argc, char *argv[])
1098 {
1099     /* Main context */
1100     main_ctxt_t s_main_ctxt;
1101 
1102     /* app ctxt */
1103     appl_ctxt_t *ps_ctxt = &s_main_ctxt.s_app_ctxt;
1104 
1105     /* cfg params */
1106     ihevce_static_cfg_params_t *params = &ps_ctxt->s_static_cfg_prms;
1107 
1108     /* error string */
1109     CHAR ac_error[STR_LEN];
1110 
1111     /* config file name */
1112     CHAR ac_cfg_fname[STR_LEN];
1113 
1114     WORD32 i;
1115     FILE *fp_cfg = NULL;
1116     FILE *pf_inp_yuv = NULL;
1117     FILE *pf_out = NULL;
1118 
1119     /* error status */
1120     IHEVCE_PLUGIN_STATUS_T status = IHEVCE_EOK;
1121 
1122     /* call the function to set default params */
1123     if(IHEVCE_EFAIL == ihevce_set_def_params(params))
1124     {
1125         sprintf(ac_error, "Unable to set default parameters\n");
1126         codec_exit(ac_error);
1127     }
1128 
1129     /* Usage */
1130     if(argc < 2)
1131     {
1132         printf("Using enc.cfg as configuration file \n");
1133         strcpy(ac_cfg_fname, "enc.cfg");
1134     }
1135     else if(argc == 2)
1136     {
1137         if(!strcmp(argv[1], "--help"))
1138         {
1139             print_usage();
1140             exit(-1);
1141         }
1142         strcpy(ac_cfg_fname, argv[1]);
1143     }
1144 
1145     /*************************************************************************/
1146     /* Parse arguments                                                       */
1147     /*************************************************************************/
1148     /* Read command line arguments */
1149     if(argc > 2)
1150     {
1151         for(i = 1; i + 1 < argc; i += 2)
1152         {
1153             if(CONFIG == get_argument(argv[i]))
1154             {
1155                 strcpy(ac_cfg_fname, argv[i + 1]);
1156                 if((fp_cfg = fopen(ac_cfg_fname, "r")) == NULL)
1157                 {
1158                     sprintf(ac_error, "Could not open Configuration file %s", ac_cfg_fname);
1159                     codec_exit(ac_error);
1160                 }
1161                 status = read_cfg_file(ps_ctxt, fp_cfg);
1162                 if(status != IHEVCE_EOK)
1163                 {
1164                     sprintf(ac_error, "Encountered error in cfg file");
1165                     codec_exit(ac_error);
1166                 }
1167                 fclose(fp_cfg);
1168             }
1169             else
1170             {
1171                 status = parse_argument(ps_ctxt, argv[i], argv[i + 1]);
1172                 if(status != IHEVCE_EOK)
1173                 {
1174                     sprintf(ac_error, "Encountered error in cfg file");
1175                     codec_exit(ac_error);
1176                 }
1177             }
1178         }
1179     }
1180     else
1181     {
1182         if((fp_cfg = fopen(ac_cfg_fname, "r")) == NULL)
1183         {
1184             sprintf(ac_error, "Could not open Configuration file %s", ac_cfg_fname);
1185             codec_exit(ac_error);
1186         }
1187         status = read_cfg_file(ps_ctxt, fp_cfg);
1188         if(status != IHEVCE_EOK)
1189         {
1190             sprintf(ac_error, "Unable to set Configuration parameter");
1191             codec_exit(ac_error);
1192         }
1193         fclose(fp_cfg);
1194     }
1195 
1196     pf_inp_yuv = fopen(ps_ctxt->au1_in_file, "rb");
1197     printf("Input file %s \n", ps_ctxt->au1_in_file);
1198     if(NULL == pf_inp_yuv)
1199     {
1200         sprintf(ac_error, "Could not open input file");
1201         codec_exit(ac_error);
1202     }
1203 
1204     pf_out = fopen(ps_ctxt->au1_out_file[0][0], "wb");
1205     printf("Output file %s \n", ps_ctxt->au1_out_file[0][0]);
1206     if(NULL == pf_out)
1207     {
1208         sprintf(ac_error, "Could not open output file");
1209         codec_exit(ac_error);
1210     }
1211 
1212     status = libihevce_encode_init(ps_ctxt);
1213     if(status != IHEVCE_EOK)
1214     {
1215         sprintf(ac_error, "Unable to init encoder");
1216         codec_exit(ac_error);
1217     }
1218 
1219     status = libihevce_encode_frame(ps_ctxt, pf_inp_yuv, pf_out);
1220     if(status != IHEVCE_EOK)
1221     {
1222         sprintf(ac_error, "Unable to encode frame");
1223         codec_exit(ac_error);
1224     }
1225 
1226     status = libihevce_encode_close(ps_ctxt);
1227     if(status != IHEVCE_EOK)
1228     {
1229         sprintf(ac_error, "Unable to close encoder");
1230         return IHEVCE_EFAIL;
1231     }
1232 
1233     if(NULL != pf_inp_yuv)
1234         fclose(pf_inp_yuv);
1235 
1236     if(NULL != pf_out)
1237         fclose(pf_out);
1238 
1239     return 0;
1240 }
1241