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