diff options
Diffstat (limited to 'examples/avcenc/main.c')
-rw-r--r-- | examples/avcenc/main.c | 3075 |
1 files changed, 3075 insertions, 0 deletions
diff --git a/examples/avcenc/main.c b/examples/avcenc/main.c new file mode 100644 index 0000000..79629b7 --- /dev/null +++ b/examples/avcenc/main.c @@ -0,0 +1,3075 @@ +/****************************************************************************** + * + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore +*/ + +/** +******************************************************************************* +* @file +* main.c +* +* @brief +* sample test application +* +* @author +* ittiam +* +* @remarks +* none +* +******************************************************************************* +*/ + +/*****************************************************************************/ +/* File Includes */ +/*****************************************************************************/ + +/* System include files */ +#include <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#include <assert.h> +#include <string.h> +#include <stdbool.h> + +#ifdef WINDOWS_TIMER +#include "windows.h" +#else +#include <sys/time.h> +#endif + +/* User include files */ +#include "ih264_typedefs.h" +#include "iv2.h" +#include "ive2.h" +#include "ih264e.h" +#include "app.h" +#include "psnr.h" + +/*****************************************************************************/ +/* Enums */ +/*****************************************************************************/ +typedef enum +{ + INVALID, + HELP, + INPUT_FILE, + OUTPUT_FILE, + RECON_FILE, + RECON_ENABLE, + CHKSUM_ENABLE, + CHKSUM_FILE, + INPUT_CHROMA_FORMAT, + RECON_CHROMA_FORMAT, + MAX_WD, + MAX_HT, + WD, + HT, + MAX_LEVEL, + ENC_SPEED, + ME_SPEED, + START_FRM, + NUM_FRMS, + MAX_FRAMERATE, + SRC_FRAMERATE, + TGT_FRAMERATE, + RC, + MAX_BITRATE, + BITRATE, + I_QP, + P_QP, + B_QP, + I_QP_MAX, + P_QP_MAX, + B_QP_MAX, + I_QP_MIN, + P_QP_MIN, + B_QP_MIN, + ENTROPY, + AIR, + AIR_REFRESH_PERIOD, + ARCH, + SOC, + NUMCORES, + PRE_ENC_ME, + PRE_ENC_IPE, + HPEL, + QPEL, + SRCH_RNG_X, + SRCH_RNG_Y, + I_INTERVAL, + IDR_INTERVAL, + CONSTRAINED_INTRA_PRED, + B_FRMS, + NUM_B_FRMS, + DISABLE_DBLK, + PROFILE, + FAST_SAD, + ALT_REF, + DISABLE_DEBLOCK_LEVEL, + PSNR, + SLICE_MODE, + SLICE_PARAM, + CONFIG, + LOOPBACK, + VBV_DELAY, + VBV_SIZE, + INTRA_4x4_ENABLE, + MB_INFO_FILE, + MB_INFO_TYPE, + PIC_INFO_FILE, + PIC_INFO_TYPE, +} ARGUMENT_T; + +/*****************************************************************************/ +/* Structure definitions */ +/*****************************************************************************/ + +/** +************************************************************************** +* @brief argument mapping construct +************************************************************************** +*/ +typedef struct +{ + CHAR argument_shortname[8]; + CHAR argument_name[128]; + ARGUMENT_T argument; + CHAR description[512]; +} argument_t; + +/*****************************************************************************/ +/* Global definitions */ +/*****************************************************************************/ + +/** +************************************************************************** +* @brief list of supported arguments +************************************************************************** +*/ +static const argument_t argument_mapping[] = +{ + { "--", "--help", HELP, "Print this help\n" }, + { "-i", "--input", INPUT_FILE, "Input file\n" }, + { "-o", "--output", OUTPUT_FILE, "Output file\n" }, + { "--", "--recon_enable", RECON_ENABLE, "Recon enable flag\n" }, + { "-r", "--recon", RECON_FILE, "Recon file \n" }, + { "--", "--input_chroma_format", INPUT_CHROMA_FORMAT, + "Input Chroma format Supported values YUV_420P, YUV_420SP_UV, YUV_420SP_VU\n" }, + { "--", "--recon_chroma_format", RECON_CHROMA_FORMAT, + "Recon Chroma format Supported values YUV_420P, YUV_420SP_UV, YUV_420SP_VU\n" }, + { "-w", "--width", WD, "Width of input file\n" }, + { "-h", "--height", HT, "Height of input file\n" }, + { "--", "--start_frame", START_FRM, "Starting frame number\n" }, + { "-f", "--num_frames", NUM_FRMS, "Number of frames to be encoded\n" }, + { "--", "--rc", RC, "Rate control mode 0: Constant Qp, 1: Storage, 2: CBR non low delay \n" }, + { "--", "--max_framerate", MAX_FRAMERATE, "Maximum frame rate \n" }, + { "--", "--tgt_framerate", TGT_FRAMERATE, "Target frame rate \n" }, + { "--", "--src_framerate", SRC_FRAMERATE, "Source frame rate \n" }, + { "--", "--i_interval", I_INTERVAL, "Intra frame interval \n" }, + { "--", "--idr_interval", IDR_INTERVAL, "IDR frame interval \n" }, + { "--", "--constrained_intrapred", CONSTRAINED_INTRA_PRED, "Constrained IntraPrediction Flag \n" }, + { "--", "--bframes", NUM_B_FRMS, "Maximum number of consecutive B frames \n" }, + { "--", "--speed", ENC_SPEED, "Encoder speed preset 0 (slowest) and 100 (fastest)\n" }, + { "--", "--me_speed", ME_SPEED, "Encoder speed preset 0 (slowest) and 100 (fastest)\n" }, + { "--", "--fast_sad", FAST_SAD, "Flag for faster sad execution\n" }, + { "--", "--alt_ref", ALT_REF , "Flag to enable alternate reference frames\n"}, + { "--", "--hpel", HPEL, "Flag to enable/disable Quarter pel estimation \n" }, + { "--", "--qpel", QPEL, "Flag to enable/disable Quarter pel estimation \n" }, + { "--", "--disable_deblock_level", DISABLE_DEBLOCK_LEVEL, + "Disable deblock level - 0 : Enables deblock completely, " + "1: enables for I and 8th frame , 2: Enables for I only, " + "3 : disables completely\n" }, + { "--", "--search_range_x", SRCH_RNG_X, "Search range for X \n" }, + { "--", "--search_range_y", SRCH_RNG_Y, "Search range for Y \n" }, + { "--", "--psnr", PSNR, "Enable PSNR computation (Disable while benchmarking performance) \n" }, + { "--", "--pre_enc_me", PRE_ENC_ME, "Flag to enable/disable Pre Enc Motion Estimation\n" }, + { "--", "--pre_enc_ipe", PRE_ENC_IPE, "Flag to enable/disable Pre Enc Intra prediction Estimation\n" }, + { "-n", "--num_cores", NUMCORES, "Number of cores to be used\n" }, + { "--", "--adaptive_intra_refresh", AIR, "Adaptive Intra Refresh enable/disable\n"}, + { "--", "--air_refresh_period", AIR_REFRESH_PERIOD,"adaptive intra refresh period\n"}, + { "--", "--slice", SLICE_MODE, "Slice mode - 0 :No slice, 1: Bytes per slice, 2: MB/CTB per slice\n" }, + { "--", "--slice_param", SLICE_PARAM, "Slice param value based on slice mode. Slice mode of 1 implies number of bytes per slice, 2 implies number of MBs/CTBs, for 0 value is neglected \n" }, + { "--", "--max_wd", MAX_WD, "Maximum width (Default: 1920) \n" }, + { "--", "--max_ht", MAX_HT, "Maximum height (Default: 1088)\n" }, + { "--", "--max_level", MAX_LEVEL, "Maximum Level (Default: 50)\n" }, + { "--", "--arch", ARCH, "Set Architecture. Supported values ARM_NONEON, ARM_A9Q, ARM_A7, ARM_A5, ARM_NEONINTR, X86_GENERIC, X86_SSSE3, X86_SSE4 \n" }, + { "--", "--soc", SOC, "Set SOC. Supported values GENERIC\n" }, + { "--", "--chksum", CHKSUM_FILE, "Save Check sum file for recon data\n" }, + { "--", "--chksum_enable", CHKSUM_ENABLE, "Recon MD5 Checksum file\n"}, + { "-c", "--config", CONFIG, "config file (Default: enc.cfg)\n" }, + { "--", "--loopback", LOOPBACK, "Enable encoding in a loop\n" }, + { "--", "--profile", PROFILE, "Profile mode: Supported values BASE, MAIN, HIGH\n" }, + { "--", "--max_bitrate", MAX_BITRATE, "Max bitrate\n"}, + { "--", "--bitrate", BITRATE, "Target bitrate\n"}, + { "--", "--qp_i", I_QP, "QP for I frames\n"}, + { "--", "--qp_p", P_QP, "QP for P frames\n"}, + { "--", "--qp_b", B_QP, "QP for B frames\n"}, + { "--", "--qp_i_max",I_QP_MAX, "Max QP for I frames\n"}, + { "--", "--qp_p_max", P_QP_MAX, "Max QP for P frames\n"}, + { "--", "--qp_b_max", B_QP_MAX, "Max QP for B frames\n"}, + { "--", "--qp_i_min", I_QP_MIN, "Min QP for I frames\n"}, + { "--", "--qp_p_min", P_QP_MIN, "Min QP for P frames\n"}, + { "--", "--qp_b_min", B_QP_MIN, "Min QP for B frames\n"}, + { "--", "--entropy", ENTROPY, "Entropy coding mode(0: CAVLC or 1: CABAC)\n"}, + { "--", "--vbv_delay", VBV_DELAY, "VBV buffer delay\n"}, + { "--", "--vbv_size", VBV_SIZE, "VBV buffer size\n"}, + { "--", "--intra_4x4_enable", INTRA_4x4_ENABLE, "Intra 4x4 enable \n" }, + { "--", "--mb_info_file", MB_INFO_FILE, "MB info file\n"}, + { "--", "--mb_info_type", MB_INFO_TYPE, "MB info type\n"}, + { "--", "--pic_info_file", PIC_INFO_FILE, "Pic info file\n"}, + { "--", "--pic_info_type", PIC_INFO_TYPE, "Pic info type\n"}, +}; + + +/*****************************************************************************/ +/* Function Definitions */ +/*****************************************************************************/ + +/** +******************************************************************************* +* +* @brief Returns malloc data. Ideally should return aligned memory +* +* @param[in] alignment +* Alignment +* +* @param[in] size +* size +* +* @returns pointer to allocated memory +* +* @remarks none +* +******************************************************************************* +*/ +#if(defined X86) && (defined X86_MINGW) + +void * ih264a_aligned_malloc(WORD32 alignment, WORD32 size) +{ + return _aligned_malloc(size, alignment); +} + +void ih264a_aligned_free(void *pv_buf) +{ + _aligned_free(pv_buf); + return; +} + +#elif IOS + +void * ih264a_aligned_malloc(WORD32 alignment, WORD32 size) +{ + return malloc(size); +} + +void ih264a_aligned_free(void *pv_buf) +{ + free(pv_buf); + return; +} + +#else + +void * ih264a_aligned_malloc(WORD32 alignment, WORD32 size) +{ + void *buf = NULL; + if (0 != posix_memalign(&buf, alignment, size)) + { + return NULL; + } + return buf; +} + +void ih264a_aligned_free(void *pv_buf) +{ + free(pv_buf); + return; +} + +#endif + +/** +******************************************************************************* +* +* @brief handles unrecoverable errors. Prints error message to console and exits. +* +* @param[in] pc_err_message +* error message +* +* @returns none +* +******************************************************************************* +*/ +void codec_exit(CHAR *pc_err_message) +{ + printf("%s\n", pc_err_message); + exit(-1); +} + +/** +******************************************************************************* +* +* @brief Maps input string to color format +* +* @param[in] value +* string +* +* @returns color format ID +* +* @remarks If the input string is not recognized, display a message and choose +* YUV420P as color format +* +******************************************************************************* +*/ +IV_COLOR_FORMAT_T get_chroma_fmt(CHAR *value) +{ + IV_COLOR_FORMAT_T e_chroma_format = IV_YUV_420P; + + if((strcmp(value, "YUV_420P")) == 0) + e_chroma_format = IV_YUV_420P; + else if((strcmp(value, "YUV_422ILE")) == 0) + e_chroma_format = IV_YUV_422ILE; + else if((strcmp(value, "RGB_565")) == 0) + e_chroma_format = IV_RGB_565; + else if((strcmp(value, "RGBA_8888")) == 0) + e_chroma_format = IV_RGBA_8888; + else if((strcmp(value, "YUV_420SP_UV")) == 0) + e_chroma_format = IV_YUV_420SP_UV; + else if((strcmp(value, "YUV_420SP_VU")) == 0) + e_chroma_format = IV_YUV_420SP_VU; + else + printf("\nInvalid colour format setting it to IV_YUV_420P\n"); + + return e_chroma_format; +} + +/** +******************************************************************************* +* +* @brief Maps input string to a speed preset +* +* @param[in] value +* string +* +* @returns speed preset ID +* +* @remarks If the input string is not recognized, display a message and choose +* IVE_FASTEST as speed preset +* +******************************************************************************* +*/ +IVE_SPEED_CONFIG get_speed_preset(CHAR *value) +{ + IVE_SPEED_CONFIG e_enc_speed_preset = IVE_FASTEST; + + if((strcmp(value, "CONFIG")) == 0) + e_enc_speed_preset = IVE_CONFIG; + else if((strcmp(value, "SLOWEST")) == 0) + e_enc_speed_preset = IVE_SLOWEST; + else if((strcmp(value, "NORMAL")) == 0) + e_enc_speed_preset = IVE_NORMAL; + else if((strcmp(value, "FAST")) == 0) + e_enc_speed_preset = IVE_FAST; + else if((strcmp(value, "HIGH_SPEED")) == 0) + e_enc_speed_preset = IVE_HIGH_SPEED; + else if((strcmp(value, "FASTEST")) == 0) + e_enc_speed_preset = IVE_FASTEST; + else + printf("\nInvalid speed preset, setting it to IVE_FASTEST\n"); + + return e_enc_speed_preset; +} + +/** +******************************************************************************* +* @brief prints application usage +******************************************************************************* +*/ +void print_usage(void) +{ + WORD32 i = 0; + WORD32 num_entries = sizeof(argument_mapping) / sizeof(argument_t); + + printf("\nUsage:\n"); + while(i < num_entries) + { + printf("%-32s\t %s", argument_mapping[i].argument_name, + argument_mapping[i].description); + i++; + } +} + +/** +******************************************************************************* +* +* @brief Maps input string to a argument +* +* @param[in] value +* string +* +* @returns argument ID +* +* @remarks If the input string is not recognized, returns INVALID +* +******************************************************************************* +*/ +ARGUMENT_T get_argument(CHAR *name) +{ + WORD32 i; + WORD32 num_entries = sizeof(argument_mapping) / sizeof(argument_t); + + for(i = 0;i < num_entries;i++) + { + if((0 == strcmp(argument_mapping[i].argument_name, name)) || + ((0 == strcmp(argument_mapping[i].argument_shortname, name)) && + (0 != strcmp(argument_mapping[i].argument_shortname, "--")))) + { + return argument_mapping[i].argument; + } + } + return INVALID; +} + +/** +******************************************************************************* +* +* @brief Parse input argument +* +* @param[in] ps_app_ctxt +* pointer to application context +* +* @param[in] argument +* argument string +* +* @param[in] value +* value corresponding to the argument +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ +void parse_argument(app_ctxt_t *ps_app_ctxt, CHAR *argument, CHAR *value) +{ + ARGUMENT_T arg = get_argument(argument); + + switch(arg) + { + case HELP: + print_usage(); + exit(-1); + break; + + case SLICE_MODE: + sscanf(value, "%d", &ps_app_ctxt->u4_slice_mode); + break; + + case SLICE_PARAM: + sscanf(value, "%d", &ps_app_ctxt->u4_slice_param); + break; + + case INPUT_FILE: + sscanf(value, "%s", ps_app_ctxt->ac_ip_fname); + break; + + case OUTPUT_FILE: + sscanf(value, "%s", ps_app_ctxt->ac_op_fname); + break; + + case RECON_FILE: + sscanf(value, "%s", ps_app_ctxt->ac_recon_fname); + break; + + case RECON_ENABLE: + sscanf(value, "%d", &ps_app_ctxt->u4_recon_enable); + break; + + case CHKSUM_FILE: + sscanf(value, "%s", ps_app_ctxt->ac_chksum_fname); + break; + + case CHKSUM_ENABLE: + sscanf(value, "%d", &ps_app_ctxt->u4_chksum_enable); + break; + + case MB_INFO_FILE: + sscanf(value, "%s", ps_app_ctxt->ac_mb_info_fname); + break; + + case MB_INFO_TYPE: + sscanf(value, "%d", &ps_app_ctxt->u4_mb_info_type); + break; + + case PIC_INFO_FILE: + sscanf(value, "%s", ps_app_ctxt->ac_pic_info_fname); + break; + + case PIC_INFO_TYPE: + sscanf(value, "%d", &ps_app_ctxt->u4_pic_info_type); + break; + + case INPUT_CHROMA_FORMAT: + ps_app_ctxt->e_inp_color_fmt = get_chroma_fmt(value); + break; + + case RECON_CHROMA_FORMAT: + ps_app_ctxt->e_recon_color_fmt = get_chroma_fmt(value); + break; + + case MAX_WD: + sscanf(value, "%d", &ps_app_ctxt->u4_max_wd); + break; + + case MAX_HT: + sscanf(value, "%d", &ps_app_ctxt->u4_max_ht); + break; + + case WD: + sscanf(value, "%d", &ps_app_ctxt->u4_wd); + break; + + case HT: + sscanf(value, "%d", &ps_app_ctxt->u4_ht); + break; + + case MAX_LEVEL: + sscanf(value, "%d", &ps_app_ctxt->u4_max_level); + break; + + case ENC_SPEED: + ps_app_ctxt->u4_enc_speed = get_speed_preset(value); + break; + + case ME_SPEED: + sscanf(value, "%d", &ps_app_ctxt->u4_me_speed); + break; + + case START_FRM: + sscanf(value, "%d", &ps_app_ctxt->u4_start_frm); + break; + + case NUM_FRMS: + sscanf(value, "%d", &ps_app_ctxt->u4_max_num_frms); + break; + + case MAX_FRAMERATE: + sscanf(value, "%d", &ps_app_ctxt->u4_max_frame_rate); + if(ps_app_ctxt->u4_max_frame_rate <= 0) + ps_app_ctxt->u4_max_frame_rate = DEFAULT_MAX_FRAMERATE; + break; + + case SRC_FRAMERATE: + sscanf(value, "%d", &ps_app_ctxt->u4_src_frame_rate); + if(ps_app_ctxt->u4_src_frame_rate <= 0) + ps_app_ctxt->u4_src_frame_rate = DEFAULT_SRC_FRAME_RATE; + break; + + case TGT_FRAMERATE: + sscanf(value, "%d", &ps_app_ctxt->u4_tgt_frame_rate); + if(ps_app_ctxt->u4_tgt_frame_rate <= 0) + ps_app_ctxt->u4_tgt_frame_rate = DEFAULT_TGT_FRAME_RATE; + break; + + case RC: + sscanf(value, "%d", &ps_app_ctxt->u4_rc); + break; + + case MAX_BITRATE: + sscanf(value, "%d", &ps_app_ctxt->u4_max_bitrate); + break; + + case BITRATE: + sscanf(value, "%d", &ps_app_ctxt->u4_bitrate); + break; + + case I_QP: + sscanf(value, "%d", &ps_app_ctxt->u4_i_qp); + break; + + case I_QP_MAX: + sscanf(value, "%d", &ps_app_ctxt->u4_i_qp_max); + break; + + case I_QP_MIN: + sscanf(value, "%d", &ps_app_ctxt->u4_i_qp_min); + break; + + case P_QP: + sscanf(value, "%d", &ps_app_ctxt->u4_p_qp); + break; + + case P_QP_MAX: + sscanf(value, "%d", &ps_app_ctxt->u4_p_qp_max); + break; + + case P_QP_MIN: + sscanf(value, "%d", &ps_app_ctxt->u4_p_qp_min); + break; + + case B_QP: + sscanf(value, "%d", &ps_app_ctxt->u4_b_qp); + break; + + case B_QP_MAX: + sscanf(value, "%d", &ps_app_ctxt->u4_b_qp_max); + break; + + case B_QP_MIN: + sscanf(value, "%d", &ps_app_ctxt->u4_b_qp_min); + break; + + case ENTROPY: + sscanf(value, "%d", &ps_app_ctxt->u4_entropy_coding_mode); + break; + + case AIR: + sscanf(value, "%d", &ps_app_ctxt->u4_air); + break; + + case ARCH: + if((strcmp(value, "ARM_NONEON")) == 0) + ps_app_ctxt->e_arch = ARCH_ARM_NONEON; + else if((strcmp(value, "ARM_A9Q")) == 0) + ps_app_ctxt->e_arch = ARCH_ARM_A9Q; + else if((strcmp(value, "ARM_A7")) == 0) + ps_app_ctxt->e_arch = ARCH_ARM_A7; + else if((strcmp(value, "ARM_A5")) == 0) + ps_app_ctxt->e_arch = ARCH_ARM_A5; + else if((strcmp(value, "ARM_NEONINTR")) == 0) + ps_app_ctxt->e_arch = ARCH_ARM_NEONINTR; + else if((strcmp(value, "X86_GENERIC")) == 0) + ps_app_ctxt->e_arch = ARCH_X86_GENERIC; + else if((strcmp(value, "X86_SSSE3")) == 0) + ps_app_ctxt->e_arch = ARCH_X86_SSSE3; + else if((strcmp(value, "X86_SSE42")) == 0) + ps_app_ctxt->e_arch = ARCH_X86_SSE42; + else if((strcmp(value, "ARM_A53")) == 0) + ps_app_ctxt->e_arch = ARCH_ARM_A53; + else if((strcmp(value, "ARM_A57")) == 0) + ps_app_ctxt->e_arch = ARCH_ARM_A57; + else if((strcmp(value, "ARM_V8_NEON")) == 0) + ps_app_ctxt->e_arch = ARCH_ARM_V8_NEON; + else + { + printf("\nInvalid Arch. Setting it to ARM_A9Q\n"); + ps_app_ctxt->e_arch = ARCH_ARM_A9Q; + } + break; + + case SOC: + if((strcmp(value, "GENERIC")) == 0) + ps_app_ctxt->e_soc = SOC_GENERIC; + else + { + printf("\nInvalid SOC. Setting it to SOC_GENERIC\n"); + ps_app_ctxt->e_soc = SOC_GENERIC; + } + break; + + case NUMCORES: + sscanf(value, "%d", &ps_app_ctxt->u4_num_cores); + break; + + case LOOPBACK: + sscanf(value, "%d", &ps_app_ctxt->u4_loopback); + break; + + case PRE_ENC_ME: + sscanf(value, "%d", &ps_app_ctxt->u4_pre_enc_me); + break; + + case PRE_ENC_IPE: + sscanf(value, "%d", &ps_app_ctxt->u4_pre_enc_ipe); + break; + + case HPEL: + sscanf(value, "%d", &ps_app_ctxt->u4_hpel); + break; + + case QPEL: + sscanf(value, "%d", &ps_app_ctxt->u4_qpel); + break; + + case SRCH_RNG_X: + sscanf(value, "%d", &ps_app_ctxt->u4_srch_rng_x); + break; + + case SRCH_RNG_Y: + sscanf(value, "%d", &ps_app_ctxt->u4_srch_rng_y); + break; + + case I_INTERVAL: + sscanf(value, "%d", &ps_app_ctxt->u4_i_interval); + break; + + case IDR_INTERVAL: + sscanf(value, "%d", &ps_app_ctxt->u4_idr_interval); + break; + + case CONSTRAINED_INTRA_PRED: + sscanf(value, "%d", &ps_app_ctxt->u4_constrained_intra_pred); + break; + + case NUM_B_FRMS: + sscanf(value, "%d", &ps_app_ctxt->u4_num_bframes); + break; + + case DISABLE_DEBLOCK_LEVEL: + sscanf(value, "%d", &ps_app_ctxt->u4_disable_deblk_level); + break; + + case VBV_DELAY: + sscanf(value, "%d", &ps_app_ctxt->u4_vbv_buffer_delay); + break; + + case VBV_SIZE: + sscanf(value, "%d", &ps_app_ctxt->u4_vbv_buf_size); + break; + + case FAST_SAD: + sscanf(value, "%d", &ps_app_ctxt->u4_enable_fast_sad); + break; + + case ALT_REF: + sscanf(value, "%d", &ps_app_ctxt->u4_enable_alt_ref); + break; + + case AIR_REFRESH_PERIOD: + sscanf(value, "%d", &ps_app_ctxt->u4_air_refresh_period); + break; + + case PROFILE: + if((strcmp(value, "BASE")) == 0) + ps_app_ctxt->e_profile = IV_PROFILE_BASE; + else if((strcmp(value, "MAIN")) == 0) + ps_app_ctxt->e_profile = IV_PROFILE_MAIN; + else if((strcmp(value, "HIGH")) == 0) + ps_app_ctxt->e_profile = IV_PROFILE_HIGH; + else + { + printf("\nInvalid profile. Setting it to BASE\n"); + ps_app_ctxt->e_profile = IV_PROFILE_BASE; + } + break; + + case PSNR: + sscanf(value, "%d", &ps_app_ctxt->u4_psnr_enable); + break; + + case INTRA_4x4_ENABLE: + sscanf(value, "%d", &ps_app_ctxt->u4_enable_intra_4x4); + break; + + case INVALID: + default: + printf("Ignoring argument : %s\n", argument); + break; + } +} + +/** +******************************************************************************* +* +* @brief Parse config file +* +* @param[in] ps_app_ctxt +* pointer to application context +* +* @param[in] fp_cfg +* config file pointer +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ +void read_cfg_file(app_ctxt_t *ps_app_ctxt, FILE *fp_cfg) +{ + while(1) + { + CHAR line[STRLENGTH] = {'\0'}; + CHAR argument[STRLENGTH] = {'\0'}; + CHAR value[STRLENGTH]; + CHAR description[STRLENGTH]; + + if(NULL == fgets(line, STRLENGTH, fp_cfg)) return; + + /* split string on whitespace */ + sscanf(line, "%s %s %s", argument, value, description); + if(argument[0] == '\0') + continue; + + parse_argument(ps_app_ctxt, argument, value); + } +} + +/** +******************************************************************************* +* +* @brief handles unrecoverable errors. Prints error message to console and exits. +* +* @param[in] pc_err_message +* error message +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ +void invalid_argument_exit(CHAR *pc_err_message) +{ + print_usage(); + codec_exit(pc_err_message); +} + +/** +******************************************************************************* +* +* @brief validate configured params +* +* @param[in] ps_app_ctxt +* pointer to application context +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ +void validate_params(app_ctxt_t *ps_app_ctxt) +{ + CHAR ac_error[STRLENGTH]; + + if(ps_app_ctxt->ac_ip_fname[0] == '\0') + { + invalid_argument_exit("Specify input file"); + } + if(ps_app_ctxt->ac_op_fname[0] == '\0') + { + invalid_argument_exit("Specify output file"); + } + if((1 == ps_app_ctxt->u4_recon_enable) && (ps_app_ctxt->ac_recon_fname[0] == '\0')) + { + invalid_argument_exit("Specify recon file"); + } + if((1 == ps_app_ctxt->u4_chksum_enable) && (ps_app_ctxt->ac_chksum_fname[0] == '\0')) + { + invalid_argument_exit("Specify checksum file"); + } + if(0 >= (WORD32)ps_app_ctxt->u4_wd) + { + sprintf(ac_error, "Invalid width: %d", ps_app_ctxt->u4_wd); + invalid_argument_exit(ac_error); + } + if(0 >= (WORD32)ps_app_ctxt->u4_ht) + { + sprintf(ac_error, "Invalid height: %d", ps_app_ctxt->u4_ht); + invalid_argument_exit(ac_error); + } + if(0 == (WORD32)ps_app_ctxt->u4_max_num_frms) + { + sprintf(ac_error, "Invalid number of frames to be encoded: %d", ps_app_ctxt->u4_max_num_frms); + invalid_argument_exit(ac_error); + } +} + +/** +******************************************************************************* +* +* @brief initialize default params +* +* @param[in] ps_app_ctxt +* pointer to application context +* +* @returns none +* +* @remarks none +* +******************************************************************************* +*/ +void init_default_params(app_ctxt_t *ps_app_ctxt) +{ + ps_app_ctxt->ps_enc = NULL; + ps_app_ctxt->ps_mem_rec = NULL; + ps_app_ctxt->u4_num_mem_rec = DEFAULT_MEM_REC_CNT; + ps_app_ctxt->u4_recon_enable = DEFAULT_RECON_ENABLE; + ps_app_ctxt->u4_chksum_enable = DEFAULT_CHKSUM_ENABLE; + ps_app_ctxt->u4_mb_info_type = 0; + ps_app_ctxt->u4_pic_info_type = 0; + ps_app_ctxt->u4_mb_info_size = 0; + ps_app_ctxt->u4_pic_info_size = 0; + ps_app_ctxt->u4_start_frm = DEFAULT_START_FRM; + ps_app_ctxt->u4_max_num_frms = DEFAULT_NUM_FRMS; + ps_app_ctxt->u4_total_bytes = 0; + ps_app_ctxt->u4_pics_cnt = 0; + ps_app_ctxt->e_inp_color_fmt = DEFAULT_INP_COLOR_FMT; + ps_app_ctxt->e_recon_color_fmt = DEFAULT_RECON_COLOR_FMT; + ps_app_ctxt->e_arch = ARCH_ARM_A9Q; + ps_app_ctxt->e_soc = SOC_GENERIC; + ps_app_ctxt->header_generated = 0; + ps_app_ctxt->pv_codec_obj = NULL; + ps_app_ctxt->u4_num_cores = DEFAULT_NUM_CORES; + ps_app_ctxt->u4_pre_enc_me = 0; + ps_app_ctxt->u4_pre_enc_ipe = 0; + ps_app_ctxt->ac_ip_fname[0] = '\0'; + ps_app_ctxt->ac_op_fname[0] = '\0'; + ps_app_ctxt->ac_recon_fname[0] = '\0'; + ps_app_ctxt->ac_chksum_fname[0] = '\0'; + ps_app_ctxt->ac_mb_info_fname[0] = '\0'; + ps_app_ctxt->fp_ip = NULL; + ps_app_ctxt->fp_op = NULL; + ps_app_ctxt->fp_recon = NULL; + ps_app_ctxt->fp_chksum = NULL; + ps_app_ctxt->fp_psnr_ip = NULL; + ps_app_ctxt->fp_mb_info = NULL; + ps_app_ctxt->fp_pic_info = NULL; + ps_app_ctxt->u4_loopback = DEFAULT_LOOPBACK; + ps_app_ctxt->u4_max_frame_rate = DEFAULT_MAX_FRAMERATE; + ps_app_ctxt->u4_src_frame_rate = DEFAULT_SRC_FRAME_RATE; + ps_app_ctxt->u4_tgt_frame_rate = DEFAULT_TGT_FRAME_RATE; + ps_app_ctxt->u4_max_wd = DEFAULT_MAX_WD; + ps_app_ctxt->u4_max_ht = DEFAULT_MAX_HT; + ps_app_ctxt->u4_max_level = DEFAULT_MAX_LEVEL; + ps_app_ctxt->u4_strd = DEFAULT_STRIDE; + ps_app_ctxt->u4_wd = DEFAULT_WD; + ps_app_ctxt->u4_ht = DEFAULT_HT; + ps_app_ctxt->u4_psnr_enable = DEFAULT_PSNR_ENABLE; + ps_app_ctxt->u4_enc_speed = IVE_FASTEST; + ps_app_ctxt->u4_me_speed = DEFAULT_ME_SPEED; + ps_app_ctxt->u4_enable_fast_sad = DEFAULT_ENABLE_FAST_SAD; + ps_app_ctxt->u4_enable_alt_ref = DEFAULT_ENABLE_ALT_REF; + ps_app_ctxt->u4_rc = DEFAULT_RC; + ps_app_ctxt->u4_max_bitrate = DEFAULT_MAX_BITRATE; + ps_app_ctxt->u4_bitrate = DEFAULT_BITRATE; + ps_app_ctxt->u4_i_qp = DEFAULT_I_QP; + ps_app_ctxt->u4_i_qp_max = DEFAULT_QP_MAX; + ps_app_ctxt->u4_i_qp_min = DEFAULT_QP_MIN; + ps_app_ctxt->u4_p_qp = DEFAULT_P_QP; + ps_app_ctxt->u4_p_qp_max = DEFAULT_QP_MAX; + ps_app_ctxt->u4_p_qp_min = DEFAULT_QP_MIN; + ps_app_ctxt->u4_b_qp = DEFAULT_B_QP; + ps_app_ctxt->u4_b_qp_max = DEFAULT_QP_MAX; + ps_app_ctxt->u4_b_qp_min = DEFAULT_QP_MIN; + ps_app_ctxt->u4_air = DEFAULT_AIR; + ps_app_ctxt->u4_air_refresh_period = DEFAULT_AIR_REFRESH_PERIOD; + ps_app_ctxt->u4_srch_rng_x = DEFAULT_SRCH_RNG_X; + ps_app_ctxt->u4_srch_rng_y = DEFAULT_SRCH_RNG_Y; + ps_app_ctxt->u4_i_interval = DEFAULT_I_INTERVAL; + ps_app_ctxt->u4_idr_interval = DEFAULT_IDR_INTERVAL; + ps_app_ctxt->u4_constrained_intra_pred = DEFAULT_CONSTRAINED_INTRAPRED; + ps_app_ctxt->u4_num_bframes = DEFAULT_NUM_BFRAMES; + ps_app_ctxt->u4_disable_deblk_level = DEFAULT_DISABLE_DEBLK_LEVEL; + ps_app_ctxt->u4_hpel = DEFAULT_HPEL; + ps_app_ctxt->u4_qpel = DEFAULT_QPEL; + ps_app_ctxt->u4_enable_intra_4x4 = DEFAULT_I4; + ps_app_ctxt->e_profile = DEFAULT_EPROFILE; + ps_app_ctxt->u4_slice_mode = DEFAULT_SLICE_MODE; + ps_app_ctxt->u4_slice_param = DEFAULT_SLICE_PARAM; + ps_app_ctxt->u4_entropy_coding_mode = DEFAULT_ENTROPY_CODING_MODE; + ps_app_ctxt->pv_input_thread_handle = NULL; + ps_app_ctxt->pv_output_thread_handle = NULL; + ps_app_ctxt->pv_recon_thread_handle = NULL; + ps_app_ctxt->adbl_psnr[0] = 0.0; + ps_app_ctxt->adbl_psnr[1] = 0.0; + ps_app_ctxt->adbl_psnr[2] = 0.0; + ps_app_ctxt->u4_psnr_cnt = 0; + ps_app_ctxt->pu1_psnr_buf = NULL; + ps_app_ctxt->u4_psnr_buf_size = 0; + ps_app_ctxt->u4_vbv_buffer_delay = 1000; + ps_app_ctxt->u4_vbv_buf_size = 0; + ps_app_ctxt->avg_time = 0; +} + +/** +******************************************************************************* +* @brief configure input dimensions +******************************************************************************* +*/ +void set_dimensions(app_ctxt_t *ps_app_ctxt, + UWORD32 u4_timestamp_low, + UWORD32 u4_timestamp_high) +{ + ih264e_ctl_set_dimensions_ip_t s_frame_dimensions_ip; + ih264e_ctl_set_dimensions_op_t s_frame_dimensions_op; + IV_STATUS_T status; + + s_frame_dimensions_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_dimensions_ip_t); + s_frame_dimensions_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; + s_frame_dimensions_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_DIMENSIONS; + s_frame_dimensions_ip.s_ive_ip.u4_wd = ps_app_ctxt->u4_wd; + s_frame_dimensions_ip.s_ive_ip.u4_ht = ps_app_ctxt->u4_ht; + s_frame_dimensions_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; + s_frame_dimensions_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; + + s_frame_dimensions_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_dimensions_op_t); + + status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_frame_dimensions_ip, + &s_frame_dimensions_op); + if(status != IV_SUCCESS) + { + CHAR ac_error[STRLENGTH]; + sprintf(ac_error, "Unable to set frame dimensions = 0x%x\n", + s_frame_dimensions_op.s_ive_op.u4_error_code); + codec_exit(ac_error); + } +} + +/** +******************************************************************************* +* @brief configure source & target framerates +******************************************************************************* +*/ +void set_frame_rate(app_ctxt_t *ps_app_ctxt, + UWORD32 u4_timestamp_low, + UWORD32 u4_timestamp_high) +{ + ih264e_ctl_set_frame_rate_ip_t s_frame_rate_ip; + ih264e_ctl_set_frame_rate_op_t s_frame_rate_op; + IV_STATUS_T status; + + s_frame_rate_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_frame_rate_ip_t); + s_frame_rate_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; + s_frame_rate_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_FRAMERATE; + s_frame_rate_ip.s_ive_ip.u4_src_frame_rate = ps_app_ctxt->u4_src_frame_rate; + s_frame_rate_ip.s_ive_ip.u4_tgt_frame_rate = ps_app_ctxt->u4_tgt_frame_rate; + s_frame_rate_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; + s_frame_rate_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; + + s_frame_rate_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_frame_rate_op_t); + + status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_frame_rate_ip, + &s_frame_rate_op); + if(status != IV_SUCCESS) + { + CHAR ac_error[STRLENGTH]; + sprintf(ac_error, "Unable to set frame rate = 0x%x\n", + s_frame_rate_op.s_ive_op.u4_error_code); + codec_exit(ac_error); + } +} + +/** +******************************************************************************* +* @brief configure IPE params +******************************************************************************* +*/ +void set_ipe_params(app_ctxt_t *ps_app_ctxt, + UWORD32 u4_timestamp_low, + UWORD32 u4_timestamp_high) +{ + ih264e_ctl_set_ipe_params_ip_t s_ipe_params_ip; + ih264e_ctl_set_ipe_params_op_t s_ipe_params_op; + IV_STATUS_T status; + + s_ipe_params_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_ipe_params_ip_t); + s_ipe_params_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; + s_ipe_params_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_IPE_PARAMS; + s_ipe_params_ip.s_ive_ip.u4_enable_intra_4x4 = ps_app_ctxt->u4_enable_intra_4x4; + s_ipe_params_ip.s_ive_ip.u4_enc_speed_preset = ps_app_ctxt->u4_enc_speed; + s_ipe_params_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; + s_ipe_params_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; + s_ipe_params_ip.s_ive_ip.u4_constrained_intra_pred = ps_app_ctxt->u4_constrained_intra_pred; + + s_ipe_params_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_ipe_params_op_t); + + status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_ipe_params_ip, + &s_ipe_params_op); + if(status != IV_SUCCESS) + { + CHAR ac_error[STRLENGTH]; + sprintf(ac_error, "Unable to set ipe params = 0x%x\n", + s_ipe_params_op.s_ive_op.u4_error_code); + codec_exit(ac_error); + } +} + +/** +******************************************************************************* +* @brief configure bitrate +******************************************************************************* +*/ +void set_bit_rate(app_ctxt_t *ps_app_ctxt, + UWORD32 u4_timestamp_low, + UWORD32 u4_timestamp_high) +{ + ih264e_ctl_set_bitrate_ip_t s_bitrate_ip; + ih264e_ctl_set_bitrate_op_t s_bitrate_op; + IV_STATUS_T status; + + s_bitrate_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_bitrate_ip_t); + s_bitrate_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; + s_bitrate_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_BITRATE; + s_bitrate_ip.s_ive_ip.u4_target_bitrate = ps_app_ctxt->u4_bitrate; + s_bitrate_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; + s_bitrate_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; + + s_bitrate_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_bitrate_op_t); + + status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_bitrate_ip, + &s_bitrate_op); + if(status != IV_SUCCESS) + { + CHAR ac_error[STRLENGTH]; + sprintf(ac_error, "Unable to set bit rate = 0x%x\n", + s_bitrate_op.s_ive_op.u4_error_code); + codec_exit(ac_error); + } +} + +/** +******************************************************************************* +* @brief configure frame type +******************************************************************************* +*/ +void set_frame_type(app_ctxt_t *ps_app_ctxt, + UWORD32 u4_timestamp_low, + UWORD32 u4_timestamp_high, + IV_PICTURE_CODING_TYPE_T e_frame_type) +{ + ih264e_ctl_set_frame_type_ip_t s_frame_type_ip; + ih264e_ctl_set_frame_type_op_t s_frame_type_op; + IV_STATUS_T status; + + s_frame_type_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_frame_type_ip_t); + s_frame_type_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; + s_frame_type_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_FRAMETYPE; + s_frame_type_ip.s_ive_ip.e_frame_type = e_frame_type; + s_frame_type_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; + s_frame_type_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; + + s_frame_type_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_frame_type_op_t); + + status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_frame_type_ip, + &s_frame_type_op); + if(status != IV_SUCCESS) + { + CHAR ac_error[STRLENGTH]; + sprintf(ac_error, "Unable to set frame type = 0x%x\n", + s_frame_type_op.s_ive_op.u4_error_code); + codec_exit(ac_error); + } +} + +/** +******************************************************************************* +* @brief configure qp +******************************************************************************* +*/ +void set_qp(app_ctxt_t *ps_app_ctxt, + UWORD32 u4_timestamp_low, + UWORD32 u4_timestamp_high) +{ + ih264e_ctl_set_qp_ip_t s_qp_ip; + ih264e_ctl_set_qp_op_t s_qp_op; + IV_STATUS_T status; + + s_qp_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_qp_ip_t); + s_qp_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; + s_qp_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_QP; + s_qp_ip.s_ive_ip.u4_i_qp = ps_app_ctxt->u4_i_qp; + s_qp_ip.s_ive_ip.u4_i_qp_max = ps_app_ctxt->u4_i_qp_max; + s_qp_ip.s_ive_ip.u4_i_qp_min = ps_app_ctxt->u4_i_qp_min; + s_qp_ip.s_ive_ip.u4_p_qp = ps_app_ctxt->u4_p_qp; + s_qp_ip.s_ive_ip.u4_p_qp_max = ps_app_ctxt->u4_p_qp_max; + s_qp_ip.s_ive_ip.u4_p_qp_min = ps_app_ctxt->u4_p_qp_min; + s_qp_ip.s_ive_ip.u4_b_qp = ps_app_ctxt->u4_b_qp; + s_qp_ip.s_ive_ip.u4_b_qp_max = ps_app_ctxt->u4_b_qp_max; + s_qp_ip.s_ive_ip.u4_b_qp_min = ps_app_ctxt->u4_b_qp_min; + s_qp_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; + s_qp_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; + + s_qp_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_qp_op_t); + + status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_qp_ip, &s_qp_op); + if(status != IV_SUCCESS) + { + CHAR ac_error[STRLENGTH]; + sprintf(ac_error, "Unable to set qp 0x%x\n", + s_qp_op.s_ive_op.u4_error_code); + codec_exit(ac_error); + } +} + +/** +******************************************************************************* +* @brief configure encoder mode +******************************************************************************* +*/ +void set_enc_mode(app_ctxt_t *ps_app_ctxt, + UWORD32 u4_timestamp_low, + UWORD32 u4_timestamp_high, + IVE_ENC_MODE_T e_enc_mode) +{ + ih264e_ctl_set_enc_mode_ip_t s_enc_mode_ip; + ih264e_ctl_set_enc_mode_op_t s_enc_mode_op; + IV_STATUS_T status; + + s_enc_mode_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_enc_mode_ip_t); + s_enc_mode_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; + s_enc_mode_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_ENC_MODE; + s_enc_mode_ip.s_ive_ip.e_enc_mode = e_enc_mode; + s_enc_mode_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; + s_enc_mode_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; + + s_enc_mode_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_enc_mode_op_t); + + status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_enc_mode_ip, + &s_enc_mode_op); + if(status != IV_SUCCESS) + { + CHAR ac_error[STRLENGTH]; + sprintf(ac_error, "Unable to set in header encode mode = 0x%x\n", + s_enc_mode_op.s_ive_op.u4_error_code); + codec_exit(ac_error); + } +} + +/** +******************************************************************************* +* @brief configure vbv params +******************************************************************************* +*/ +void set_vbv_params(app_ctxt_t *ps_app_ctxt, + UWORD32 u4_timestamp_low, + UWORD32 u4_timestamp_high) +{ + ih264e_ctl_set_vbv_params_ip_t s_vbv_ip; + ih264e_ctl_set_vbv_params_op_t s_vbv_op; + IV_STATUS_T status; + + s_vbv_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_vbv_params_ip_t); + s_vbv_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; + s_vbv_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_VBV_PARAMS; + s_vbv_ip.s_ive_ip.u4_vbv_buffer_delay = ps_app_ctxt->u4_vbv_buffer_delay; + s_vbv_ip.s_ive_ip.u4_vbv_buf_size = ps_app_ctxt->u4_vbv_buf_size; + s_vbv_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; + s_vbv_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; + + s_vbv_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_vbv_params_op_t); + + status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_vbv_ip, &s_vbv_op); + if(status != IV_SUCCESS) + { + CHAR ac_error[STRLENGTH]; + sprintf(ac_error, "Unable to set VBC params = 0x%x\n", + s_vbv_op.s_ive_op.u4_error_code); + codec_exit(ac_error); + } +} + +/** +******************************************************************************* +* @brief configure air params +******************************************************************************* +*/ +void set_air_params(app_ctxt_t *ps_app_ctxt, + UWORD32 u4_timestamp_low, + UWORD32 u4_timestamp_high) +{ + ih264e_ctl_set_air_params_ip_t s_air_ip; + ih264e_ctl_set_air_params_op_t s_air_op; + IV_STATUS_T status; + + s_air_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_air_params_ip_t); + s_air_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; + s_air_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_AIR_PARAMS; + s_air_ip.s_ive_ip.e_air_mode = ps_app_ctxt->u4_air; + s_air_ip.s_ive_ip.u4_air_refresh_period = ps_app_ctxt->u4_air_refresh_period; + s_air_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; + s_air_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; + + s_air_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_air_params_op_t); + + status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_air_ip, &s_air_op); + if(status != IV_SUCCESS) + { + CHAR ac_error[STRLENGTH]; + sprintf(ac_error, "Unable to set air params = 0x%x\n", + s_air_op.s_ive_op.u4_error_code); + codec_exit(ac_error); + } +} + +/** +******************************************************************************* +* @brief configure me params +******************************************************************************* +*/ +void set_me_params(app_ctxt_t *ps_app_ctxt, + UWORD32 u4_timestamp_low, + UWORD32 u4_timestamp_high) +{ + ih264e_ctl_set_me_params_ip_t s_me_params_ip; + ih264e_ctl_set_me_params_op_t s_me_params_op; + IV_STATUS_T status; + + s_me_params_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_me_params_ip_t); + s_me_params_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; + s_me_params_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_ME_PARAMS; + s_me_params_ip.s_ive_ip.u4_me_speed_preset = ps_app_ctxt->u4_me_speed; + s_me_params_ip.s_ive_ip.u4_enable_hpel = ps_app_ctxt->u4_hpel; + s_me_params_ip.s_ive_ip.u4_enable_qpel = ps_app_ctxt->u4_qpel; + s_me_params_ip.s_ive_ip.u4_enable_fast_sad = ps_app_ctxt->u4_enable_fast_sad; + s_me_params_ip.s_ive_ip.u4_enable_alt_ref = ps_app_ctxt->u4_enable_alt_ref; + s_me_params_ip.s_ive_ip.u4_srch_rng_x = ps_app_ctxt->u4_srch_rng_x; + s_me_params_ip.s_ive_ip.u4_srch_rng_y = ps_app_ctxt->u4_srch_rng_y; + s_me_params_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; + s_me_params_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; + + s_me_params_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_me_params_op_t); + + status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_me_params_ip, + &s_me_params_op); + if(status != IV_SUCCESS) + { + CHAR ac_error[STRLENGTH]; + sprintf(ac_error, "Unable to set me params = 0x%x\n", + s_me_params_op.s_ive_op.u4_error_code); + codec_exit(ac_error); + } +} + +/** +******************************************************************************* +* @brief configure gop params +******************************************************************************* +*/ +void set_gop_params(app_ctxt_t *ps_app_ctxt, + UWORD32 u4_timestamp_low, + UWORD32 u4_timestamp_high) +{ + ih264e_ctl_set_gop_params_ip_t s_gop_params_ip; + ih264e_ctl_set_gop_params_op_t s_gop_params_op; + IV_STATUS_T status; + + s_gop_params_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_gop_params_ip_t); + s_gop_params_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; + s_gop_params_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_GOP_PARAMS; + s_gop_params_ip.s_ive_ip.u4_i_frm_interval = ps_app_ctxt->u4_i_interval; + s_gop_params_ip.s_ive_ip.u4_idr_frm_interval = ps_app_ctxt->u4_idr_interval; + s_gop_params_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; + s_gop_params_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; + + s_gop_params_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_gop_params_op_t); + + status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_gop_params_ip, + &s_gop_params_op); + if(status != IV_SUCCESS) + { + CHAR ac_error[STRLENGTH]; + sprintf(ac_error, "Unable to set GOP params = 0x%x\n", + s_gop_params_op.s_ive_op.u4_error_code); + codec_exit(ac_error); + } +} + +/** +******************************************************************************* +* @brief configure profile params +******************************************************************************* +*/ +void set_profile_params(app_ctxt_t *ps_app_ctxt, + UWORD32 u4_timestamp_low, + UWORD32 u4_timestamp_high) +{ + ih264e_ctl_set_profile_params_ip_t s_profile_params_ip; + ih264e_ctl_set_profile_params_op_t s_profile_params_op; + IV_STATUS_T status; + + s_profile_params_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_profile_params_ip_t); + s_profile_params_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; + s_profile_params_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_PROFILE_PARAMS; + s_profile_params_ip.s_ive_ip.e_profile = ps_app_ctxt->e_profile; + s_profile_params_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; + s_profile_params_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; + s_profile_params_ip.s_ive_ip.u4_entropy_coding_mode = ps_app_ctxt->u4_entropy_coding_mode; + + s_profile_params_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_profile_params_op_t); + + status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_profile_params_ip, + &s_profile_params_op); + if(status != IV_SUCCESS) + { + CHAR ac_error[STRLENGTH]; + sprintf(ac_error, "Unable to set profile params = 0x%x\n", + s_profile_params_op.s_ive_op.u4_error_code); + codec_exit(ac_error); + } +} + +/** +******************************************************************************* +* @brief configure deblock params +******************************************************************************* +*/ +void set_deblock_params(app_ctxt_t *ps_app_ctxt, + UWORD32 u4_timestamp_low, + UWORD32 u4_timestamp_high) +{ + ih264e_ctl_set_deblock_params_ip_t s_deblock_params_ip; + ih264e_ctl_set_deblock_params_op_t s_deblock_params_op; + IV_STATUS_T status; + + s_deblock_params_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_deblock_params_ip_t); + s_deblock_params_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; + s_deblock_params_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_DEBLOCK_PARAMS; + s_deblock_params_ip.s_ive_ip.u4_disable_deblock_level = ps_app_ctxt->u4_disable_deblk_level; + s_deblock_params_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; + s_deblock_params_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; + + s_deblock_params_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_deblock_params_op_t); + + status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_deblock_params_ip, + &s_deblock_params_op); + if(status != IV_SUCCESS) + { + CHAR ac_error[STRLENGTH]; + sprintf(ac_error, "Unable to enable/disable deblock params = 0x%x\n", + s_deblock_params_op.s_ive_op.u4_error_code); + codec_exit(ac_error); + } +} + +/** +******************************************************************************* +* @brief configure VUI params +******************************************************************************* +*/ +void set_vui_params(app_ctxt_t *ps_app_ctxt) +{ + ih264e_vui_ip_t s_vui_params_ip; + ih264e_vui_op_t s_vui_params_op; + IV_STATUS_T status; + + s_vui_params_ip.u4_size = sizeof(ih264e_vui_ip_t); + s_vui_params_ip.e_cmd = IVE_CMD_VIDEO_CTL; + s_vui_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_VUI_PARAMS; + s_vui_params_ip.u1_aspect_ratio_info_present_flag = 0; + s_vui_params_ip.u1_aspect_ratio_idc = 0; + s_vui_params_ip.u2_sar_width = 0; + s_vui_params_ip.u2_sar_height = 0; + s_vui_params_ip.u1_overscan_info_present_flag = 0; + s_vui_params_ip.u1_overscan_appropriate_flag = 0; + s_vui_params_ip.u1_video_signal_type_present_flag = 1; + s_vui_params_ip.u1_video_format = 0; + s_vui_params_ip.u1_video_full_range_flag = 0; + s_vui_params_ip.u1_colour_description_present_flag = 1; + s_vui_params_ip.u1_colour_primaries = 2; + s_vui_params_ip.u1_transfer_characteristics = 2; + s_vui_params_ip.u1_matrix_coefficients = 2; + s_vui_params_ip.u1_chroma_loc_info_present_flag = 0; + s_vui_params_ip.u1_chroma_sample_loc_type_top_field = 0; + s_vui_params_ip.u1_chroma_sample_loc_type_bottom_field = 0; + s_vui_params_ip.u1_vui_timing_info_present_flag = 0; + s_vui_params_ip.u4_vui_num_units_in_tick = 0; + s_vui_params_ip.u4_vui_time_scale = ps_app_ctxt->u4_tgt_frame_rate * 2000; + s_vui_params_ip.u1_fixed_frame_rate_flag = 0; + s_vui_params_ip.u1_nal_hrd_parameters_present_flag = 0; + s_vui_params_ip.u1_vcl_hrd_parameters_present_flag = 0; + s_vui_params_ip.u1_low_delay_hrd_flag = 0; + s_vui_params_ip.u1_pic_struct_present_flag = 0; + s_vui_params_ip.u1_bitstream_restriction_flag = 0; + s_vui_params_ip.u1_motion_vectors_over_pic_boundaries_flag = 0; + s_vui_params_ip.u1_max_bytes_per_pic_denom = 0; + s_vui_params_ip.u1_max_bits_per_mb_denom = 0; + s_vui_params_ip.u1_log2_max_mv_length_horizontal = 0; + s_vui_params_ip.u1_log2_max_mv_length_vertical = 0; + s_vui_params_ip.u1_num_reorder_frames = 0; + s_vui_params_ip.u1_max_dec_frame_buffering = 0; + + s_vui_params_op.u4_size = sizeof(ih264e_vui_op_t); + + status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_vui_params_ip, + &s_vui_params_op); + if(status != IV_SUCCESS) + { + CHAR ac_error[STRLENGTH]; + sprintf(ac_error, "Unable to set vui params = 0x%x\n", + s_vui_params_op.u4_error_code); + codec_exit(ac_error); + } + return; +} + +void set_sei_mdcv_params(app_ctxt_t *ps_app_ctxt, + UWORD32 u4_timestamp_low, + UWORD32 u4_timestamp_high) +{ + WORD32 i4_count; + IV_STATUS_T status; + + ih264e_ctl_set_sei_mdcv_params_ip_t s_sei_mdcv_params_ip; + ih264e_ctl_set_sei_mdcv_params_op_t s_sei_mdcv_params_op; + + s_sei_mdcv_params_ip.e_cmd = IVE_CMD_VIDEO_CTL; + s_sei_mdcv_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_SEI_MDCV_PARAMS; + + s_sei_mdcv_params_ip.u1_sei_mdcv_params_present_flag = + (UWORD8)ps_app_ctxt->u4_sei_mdcv_params_present_flag; + + for(i4_count = 0; i4_count < NUM_SEI_MDCV_PRIMARIES; i4_count++) + { + s_sei_mdcv_params_ip.au2_display_primaries_x[i4_count] = + (UWORD16)ps_app_ctxt->au4_display_primaries_x[i4_count]; + s_sei_mdcv_params_ip.au2_display_primaries_y[i4_count] = + (UWORD16)ps_app_ctxt->au4_display_primaries_y[i4_count]; + } + + s_sei_mdcv_params_ip.u2_white_point_x = (UWORD16)ps_app_ctxt->u4_white_point_x; + s_sei_mdcv_params_ip.u2_white_point_y = (UWORD16)ps_app_ctxt->u4_white_point_y; + s_sei_mdcv_params_ip.u4_max_display_mastering_luminance = + ps_app_ctxt->u4_max_display_mastering_luminance; + s_sei_mdcv_params_ip.u4_min_display_mastering_luminance = + ps_app_ctxt->u4_min_display_mastering_luminance; + + s_sei_mdcv_params_ip.u4_timestamp_high = u4_timestamp_high; + s_sei_mdcv_params_ip.u4_timestamp_low = u4_timestamp_low; + + s_sei_mdcv_params_ip.u4_size = sizeof(ih264e_ctl_set_sei_mdcv_params_ip_t); + s_sei_mdcv_params_op.u4_size = sizeof(ih264e_ctl_set_sei_mdcv_params_op_t); + + if((ps_app_ctxt->s_sei_mdcv_params.au2_display_primaries_x[0] != + s_sei_mdcv_params_ip.au2_display_primaries_x[0]) || + (ps_app_ctxt->s_sei_mdcv_params.au2_display_primaries_x[1] != + s_sei_mdcv_params_ip.au2_display_primaries_x[1]) || + (ps_app_ctxt->s_sei_mdcv_params.au2_display_primaries_x[2] != + s_sei_mdcv_params_ip.au2_display_primaries_x[2]) || + (ps_app_ctxt->s_sei_mdcv_params.au2_display_primaries_y[0] != + s_sei_mdcv_params_ip.au2_display_primaries_y[0]) || + (ps_app_ctxt->s_sei_mdcv_params.au2_display_primaries_y[1] != + s_sei_mdcv_params_ip.au2_display_primaries_y[1]) || + (ps_app_ctxt->s_sei_mdcv_params.au2_display_primaries_y[2] != + s_sei_mdcv_params_ip.au2_display_primaries_y[2]) || + (ps_app_ctxt->s_sei_mdcv_params.u2_white_point_x != + s_sei_mdcv_params_ip.u2_white_point_x) || + (ps_app_ctxt->s_sei_mdcv_params.u2_white_point_y != + s_sei_mdcv_params_ip.u2_white_point_x) || + (ps_app_ctxt->s_sei_mdcv_params.u4_max_display_mastering_luminance != + s_sei_mdcv_params_ip.u4_max_display_mastering_luminance) || + (ps_app_ctxt->s_sei_mdcv_params.u4_min_display_mastering_luminance != + s_sei_mdcv_params_ip.u4_min_display_mastering_luminance)) + { + status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_sei_mdcv_params_ip, + &s_sei_mdcv_params_op); + if(status != IV_SUCCESS) + { + printf("Unable to set sei mdcv params = 0x%x\n", + s_sei_mdcv_params_op.u4_error_code); + } + ps_app_ctxt->s_sei_mdcv_params = s_sei_mdcv_params_ip; + } + return; +} + +void set_sei_cll_params(app_ctxt_t *ps_app_ctxt, + UWORD32 u4_timestamp_low, + UWORD32 u4_timestamp_high) +{ + IV_STATUS_T status; + + ih264e_ctl_set_sei_cll_params_ip_t s_sei_cll_params_ip; + ih264e_ctl_set_sei_cll_params_op_t s_sei_cll_params_op; + + s_sei_cll_params_ip.e_cmd = IVE_CMD_VIDEO_CTL; + s_sei_cll_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_SEI_CLL_PARAMS; + + s_sei_cll_params_ip.u1_sei_cll_params_present_flag = + (UWORD8)ps_app_ctxt->u4_sei_cll_params_present_flag; + + s_sei_cll_params_ip.u2_max_content_light_level = + (UWORD16)ps_app_ctxt->u4_max_content_light_level; + s_sei_cll_params_ip.u2_max_pic_average_light_level = + (UWORD16)ps_app_ctxt->u4_max_pic_average_light_level; + + s_sei_cll_params_ip.u4_timestamp_high = u4_timestamp_high; + s_sei_cll_params_ip.u4_timestamp_low = u4_timestamp_low; + + s_sei_cll_params_ip.u4_size = sizeof(ih264e_ctl_set_sei_cll_params_ip_t); + s_sei_cll_params_op.u4_size = sizeof(ih264e_ctl_set_sei_cll_params_op_t); + + if((ps_app_ctxt->s_sei_cll_params.u2_max_content_light_level != + s_sei_cll_params_ip.u2_max_content_light_level) || + (ps_app_ctxt->s_sei_cll_params.u2_max_pic_average_light_level != + s_sei_cll_params_ip.u2_max_pic_average_light_level)) + { + status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_sei_cll_params_ip, + &s_sei_cll_params_op); + if(status != IV_SUCCESS) + { + printf("Unable to set sei cll params = 0x%x\n", + s_sei_cll_params_op.u4_error_code); + } + ps_app_ctxt->s_sei_cll_params = s_sei_cll_params_ip; + } + return; +} + +void set_sei_ave_params(app_ctxt_t *ps_app_ctxt, + UWORD32 u4_timestamp_low, + UWORD32 u4_timestamp_high) +{ + IV_STATUS_T status; + + ih264e_ctl_set_sei_ave_params_ip_t s_sei_ave_params_ip; + ih264e_ctl_set_sei_ave_params_op_t s_sei_ave_params_op; + + s_sei_ave_params_ip.e_cmd = IVE_CMD_VIDEO_CTL; + s_sei_ave_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_SEI_AVE_PARAMS; + + s_sei_ave_params_ip.u1_sei_ave_params_present_flag = + (UWORD8)ps_app_ctxt->u4_sei_ave_params_present_flag; + + s_sei_ave_params_ip.u4_ambient_illuminance = ps_app_ctxt->u4_ambient_illuminance; + s_sei_ave_params_ip.u2_ambient_light_x = (UWORD16)ps_app_ctxt->u4_ambient_light_x; + s_sei_ave_params_ip.u2_ambient_light_y = (UWORD16)ps_app_ctxt->u4_ambient_light_y; + + s_sei_ave_params_ip.u4_timestamp_high = u4_timestamp_high; + s_sei_ave_params_ip.u4_timestamp_low = u4_timestamp_low; + + s_sei_ave_params_ip.u4_size = sizeof(ih264e_ctl_set_sei_ave_params_ip_t); + s_sei_ave_params_op.u4_size = sizeof(ih264e_ctl_set_sei_ave_params_op_t); + + if((ps_app_ctxt->s_sei_ave_params.u4_ambient_illuminance != + s_sei_ave_params_ip.u4_ambient_illuminance) || + (ps_app_ctxt->s_sei_ave_params.u2_ambient_light_x != + s_sei_ave_params_ip.u2_ambient_light_x) || + (ps_app_ctxt->s_sei_ave_params.u2_ambient_light_y != + s_sei_ave_params_ip.u2_ambient_light_y)) + { + status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_sei_ave_params_ip, + &s_sei_ave_params_op); + if(status != IV_SUCCESS) + { + printf("Unable to set sei ave params = 0x%x\n", + s_sei_ave_params_op.u4_error_code); + } + ps_app_ctxt->s_sei_ave_params = s_sei_ave_params_ip; + } + return; +} + +void set_sei_ccv_params(app_ctxt_t *ps_app_ctxt, + UWORD32 u4_timestamp_low, + UWORD32 u4_timestamp_high) +{ + WORD32 i4_count; + IV_STATUS_T status; + + ih264e_ctl_set_sei_ccv_params_ip_t s_sei_ccv_params_ip; + ih264e_ctl_set_sei_ccv_params_op_t s_sei_ccv_params_op; + + s_sei_ccv_params_ip.e_cmd = IVE_CMD_VIDEO_CTL; + s_sei_ccv_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_SEI_CCV_PARAMS; + + s_sei_ccv_params_ip.u1_sei_ccv_params_present_flag = + (UWORD8)ps_app_ctxt->u4_sei_ccv_params_present_flag; + + s_sei_ccv_params_ip.u1_ccv_cancel_flag = (UWORD8)ps_app_ctxt->u4_ccv_cancel_flag; + s_sei_ccv_params_ip.u1_ccv_persistence_flag = + (UWORD8)ps_app_ctxt->u4_ccv_persistence_flag; + s_sei_ccv_params_ip.u1_ccv_primaries_present_flag = + (UWORD8)ps_app_ctxt->u4_ccv_primaries_present_flag; + s_sei_ccv_params_ip.u1_ccv_min_luminance_value_present_flag = + (UWORD8)ps_app_ctxt->u4_ccv_min_luminance_value_present_flag; + s_sei_ccv_params_ip.u1_ccv_max_luminance_value_present_flag = + (UWORD8)ps_app_ctxt->u4_ccv_max_luminance_value_present_flag; + s_sei_ccv_params_ip.u1_ccv_avg_luminance_value_present_flag = + (UWORD8)ps_app_ctxt->u4_ccv_avg_luminance_value_present_flag; + s_sei_ccv_params_ip.u1_ccv_reserved_zero_2bits = + (UWORD8)ps_app_ctxt->u4_ccv_reserved_zero_2bits; + + for(i4_count = 0; i4_count < NUM_SEI_CCV_PRIMARIES; i4_count++) + { + s_sei_ccv_params_ip.ai4_ccv_primaries_x[i4_count] = + ps_app_ctxt->ai4_ccv_primaries_x[i4_count]; + s_sei_ccv_params_ip.ai4_ccv_primaries_y[i4_count] = + ps_app_ctxt->ai4_ccv_primaries_y[i4_count]; + } + + s_sei_ccv_params_ip.u4_ccv_min_luminance_value = ps_app_ctxt->u4_ccv_min_luminance_value; + s_sei_ccv_params_ip.u4_ccv_max_luminance_value = ps_app_ctxt->u4_ccv_max_luminance_value; + s_sei_ccv_params_ip.u4_ccv_avg_luminance_value = ps_app_ctxt->u4_ccv_avg_luminance_value; + + s_sei_ccv_params_ip.u4_timestamp_high = u4_timestamp_high; + s_sei_ccv_params_ip.u4_timestamp_low = u4_timestamp_low; + + s_sei_ccv_params_ip.u4_size = sizeof(ih264e_ctl_set_sei_ccv_params_ip_t); + s_sei_ccv_params_op.u4_size = sizeof(ih264e_ctl_set_sei_ccv_params_op_t); + + status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_sei_ccv_params_ip, + &s_sei_ccv_params_op); + if(status != IV_SUCCESS) + { + printf("Unable to set sei ccv params = 0x%x\n", + s_sei_ccv_params_op.u4_error_code); + } + return; +} + +void set_sei_sii_params(app_ctxt_t *ps_app_ctxt, UWORD32 u4_timestamp_low, + UWORD32 u4_timestamp_high) +{ + IV_STATUS_T status; + int i; + bool au4_sub_layer_num_units_in_shutter_interval_flag = 0; + + ih264e_ctl_set_sei_sii_params_ip_t s_sei_sii_params_ip = {0}; + ih264e_ctl_set_sei_sii_params_op_t s_sei_sii_params_op = {0}; + + s_sei_sii_params_ip.e_cmd = IVE_CMD_VIDEO_CTL; + s_sei_sii_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_SEI_SII_PARAMS; + + s_sei_sii_params_ip.u4_sii_sub_layer_idx = ps_app_ctxt->u4_sii_sub_layer_idx; + + if(0 == s_sei_sii_params_ip.u4_sii_sub_layer_idx) + { + s_sei_sii_params_ip.u1_shutter_interval_info_present_flag = + (UWORD8) ps_app_ctxt->u4_shutter_interval_info_present_flag; + + if(1 == s_sei_sii_params_ip.u1_shutter_interval_info_present_flag) + { + s_sei_sii_params_ip.u4_sii_time_scale = ps_app_ctxt->u4_sii_time_scale; + s_sei_sii_params_ip.u1_fixed_shutter_interval_within_cvs_flag = + (UWORD8) ps_app_ctxt->u4_fixed_shutter_interval_within_cvs_flag; + + if(1 == s_sei_sii_params_ip.u1_fixed_shutter_interval_within_cvs_flag) + { + s_sei_sii_params_ip.u4_sii_num_units_in_shutter_interval = + ps_app_ctxt->u4_sii_num_units_in_shutter_interval; + } + else + { + s_sei_sii_params_ip.u1_sii_max_sub_layers_minus1 = + (UWORD8) ps_app_ctxt->u4_sii_max_sub_layers_minus1; + + for(i = 0; i <= s_sei_sii_params_ip.u1_sii_max_sub_layers_minus1; i++) + { + s_sei_sii_params_ip.au4_sub_layer_num_units_in_shutter_interval[i] = + ps_app_ctxt->au4_sub_layer_num_units_in_shutter_interval[i]; + } + } + } + } + + s_sei_sii_params_ip.u4_timestamp_high = u4_timestamp_high; + s_sei_sii_params_ip.u4_timestamp_low = u4_timestamp_low; + + s_sei_sii_params_ip.u4_size = sizeof(ih264e_ctl_set_sei_sii_params_ip_t); + s_sei_sii_params_op.u4_size = sizeof(ih264e_ctl_set_sei_sii_params_op_t); + + for(i = 0; i <= s_sei_sii_params_ip.u1_sii_max_sub_layers_minus1; i++) + { + au4_sub_layer_num_units_in_shutter_interval_flag = + (au4_sub_layer_num_units_in_shutter_interval_flag || + (ps_app_ctxt->s_sei_sii_params.au4_sub_layer_num_units_in_shutter_interval[i] != + s_sei_sii_params_ip.au4_sub_layer_num_units_in_shutter_interval[i])); + } + + if((ps_app_ctxt->s_sei_sii_params.u4_sii_sub_layer_idx != + s_sei_sii_params_ip.u4_sii_sub_layer_idx) || + (ps_app_ctxt->s_sei_sii_params.u1_shutter_interval_info_present_flag != + s_sei_sii_params_ip.u1_shutter_interval_info_present_flag) || + (ps_app_ctxt->s_sei_sii_params.u4_sii_time_scale != s_sei_sii_params_ip.u4_sii_time_scale) || + (ps_app_ctxt->s_sei_sii_params.u1_fixed_shutter_interval_within_cvs_flag != + s_sei_sii_params_ip.u1_fixed_shutter_interval_within_cvs_flag) || + (ps_app_ctxt->s_sei_sii_params.u4_sii_num_units_in_shutter_interval != + s_sei_sii_params_ip.u4_sii_num_units_in_shutter_interval) || + (ps_app_ctxt->s_sei_sii_params.u1_sii_max_sub_layers_minus1 != + s_sei_sii_params_ip.u1_sii_max_sub_layers_minus1) || + au4_sub_layer_num_units_in_shutter_interval_flag) + { + status = + ih264e_api_function(ps_app_ctxt->ps_enc, &s_sei_sii_params_ip, &s_sei_sii_params_op); + if(status != IV_SUCCESS) + { + printf("Unable to set sei sii params = 0x%x\n", s_sei_sii_params_op.u4_error_code); + } + ps_app_ctxt->s_sei_sii_params = s_sei_sii_params_ip; + } + return; +} + +/** +******************************************************************************* +* @brief encode input +******************************************************************************* +*/ +void synchronous_encode(iv_obj_t *ps_enc, app_ctxt_t *ps_app_ctxt) +{ +#define PEAK_WINDOW_SIZE 8 + ih264e_video_encode_ip_t ih264e_video_encode_ip = {0}; + ih264e_video_encode_op_t ih264e_video_encode_op = {0}; + + ive_video_encode_ip_t *ps_video_encode_ip = &ih264e_video_encode_ip.s_ive_ip; + ive_video_encode_op_t *ps_video_encode_op = &ih264e_video_encode_op.s_ive_op; + + iv_raw_buf_t *ps_inp_raw_buf = &ps_video_encode_ip->s_inp_buf; + + IV_STATUS_T status = IV_SUCCESS; + + WORD32 i, is_last = 0, buff_size = 0, num_bytes = 0; + UWORD32 u4_total_time = 0; + UWORD8 *pu1_buf = NULL; + UWORD32 u4_timestamp_low = 0, u4_timestamp_high = 0; + void *pv_mb_info = NULL, *pv_pic_info = NULL; + + TIMER curtime; +#ifdef WINDOWS_TIMER + TIMER frequency; +#endif + WORD32 peak_window[PEAK_WINDOW_SIZE] = {0}; + WORD32 peak_window_idx = 0; + WORD32 peak_avg_max = 0, timetaken = 0; + iv_raw_buf_t s_inp_buf, s_recon_buf; + CHAR ac_error[STRLENGTH]; + WORD32 end_of_frames = 0; + WORD32 i4_inp_done = 0; + + /* Allocate I/O Buffers */ + allocate_input(ps_app_ctxt); + allocate_output(ps_app_ctxt); + allocate_recon(ps_app_ctxt); + + /* init psnr ctxt */ + init_psnr(ps_app_ctxt); + + /* open file pointers */ + ps_app_ctxt->fp_ip = fopen(ps_app_ctxt->ac_ip_fname, "rb"); + if(NULL == ps_app_ctxt->fp_ip) + { + sprintf(ac_error, "Unable to open input file for reading: %s", + ps_app_ctxt->ac_ip_fname); + invalid_argument_exit(ac_error); + } + + ps_app_ctxt->fp_op = fopen(ps_app_ctxt->ac_op_fname, "wb"); + if(NULL == ps_app_ctxt->fp_op) + { + sprintf(ac_error, "Unable to open output file for writing: %s", + ps_app_ctxt->ac_op_fname); + invalid_argument_exit(ac_error); + } + + if(1 == ps_app_ctxt->u4_recon_enable) + { + ps_app_ctxt->fp_recon = fopen(ps_app_ctxt->ac_recon_fname, "wb"); + if(NULL == ps_app_ctxt->fp_recon) + { + sprintf(ac_error, "Unable to open recon file for writing: %s", + ps_app_ctxt->ac_recon_fname); + invalid_argument_exit(ac_error); + } + } + + if(1 == ps_app_ctxt->u4_chksum_enable) + { + ps_app_ctxt->fp_chksum = fopen(ps_app_ctxt->ac_chksum_fname, "wb"); + if(NULL == ps_app_ctxt->fp_chksum) + { + sprintf(ac_error, "Unable to open checksum file for writing: %s", + ps_app_ctxt->ac_chksum_fname); + invalid_argument_exit(ac_error); + } + } + + /* + * If PSNR is enabled, open input file again and hold a different file pointer + * This makes it easy to compute PSNR without adding dependency between + * input and recon threads + */ + if(1 == ps_app_ctxt->u4_psnr_enable) + { + ps_app_ctxt->fp_psnr_ip = fopen(ps_app_ctxt->ac_ip_fname, "rb"); + if(NULL == ps_app_ctxt->fp_psnr_ip) + { + sprintf(ac_error, "Unable to open input file for reading: %s", + ps_app_ctxt->ac_ip_fname); + invalid_argument_exit(ac_error); + } + } + + if(0 != ps_app_ctxt->u4_mb_info_type) + { + ps_app_ctxt->fp_mb_info = fopen(ps_app_ctxt->ac_mb_info_fname, "rb"); + if(NULL == ps_app_ctxt->fp_mb_info) + { + sprintf(ac_error, "Unable to open MB info file for reading: %s", + ps_app_ctxt->ac_mb_info_fname); + invalid_argument_exit(ac_error); + } + } + + if(ps_app_ctxt->u4_pic_info_type) + { + ps_app_ctxt->fp_pic_info = fopen(ps_app_ctxt->ac_pic_info_fname, "rb"); + if(NULL == ps_app_ctxt->fp_pic_info) + { + sprintf(ac_error, "Unable to open Pic info file for reading: %s", + ps_app_ctxt->ac_pic_info_fname); + invalid_argument_exit(ac_error); + } + } + + /*****************************************************************************/ + /* Video control Set in Encode header mode */ + /*****************************************************************************/ + set_enc_mode(ps_app_ctxt, -1, -1, IVE_ENC_MODE_HEADER); + + // Encode header + memset(&ih264e_video_encode_ip, 0, sizeof(ih264e_video_encode_ip)); + memset(&ih264e_video_encode_op, 0, sizeof(ih264e_video_encode_op)); + + ps_video_encode_ip->u4_size = sizeof(ih264e_video_encode_ip_t); + ps_video_encode_op->u4_size = sizeof(ih264e_video_encode_op_t); + + ps_inp_raw_buf->apv_bufs[0] = NULL; + ps_inp_raw_buf->apv_bufs[1] = NULL; + ps_inp_raw_buf->apv_bufs[2] = NULL; + + ps_video_encode_ip->e_cmd = IVE_CMD_VIDEO_ENCODE; + ps_video_encode_ip->pv_bufs = NULL; + ps_video_encode_ip->pv_mb_info = NULL; + ps_video_encode_ip->pv_pic_info = NULL; + ps_video_encode_ip->u4_pic_info_type = ps_app_ctxt->u4_pic_info_type; + ps_video_encode_ip->u4_is_last = 0; + ps_video_encode_ip->u4_mb_info_type = ps_app_ctxt->u4_mb_info_type; + ps_video_encode_ip->u4_pic_info_type = ps_app_ctxt->u4_pic_info_type; + ps_video_encode_ip->s_out_buf.pv_buf = ps_app_ctxt->as_output_buf[0].pu1_buf; + ps_video_encode_ip->s_out_buf.u4_bytes = 0; + ps_video_encode_ip->s_out_buf.u4_bufsize = ps_app_ctxt->as_output_buf[0].u4_buf_size; + ps_video_encode_ip->u4_timestamp_high = 0; + ps_video_encode_ip->u4_timestamp_low = 0; + + status = ih264e_api_function(ps_enc, &ih264e_video_encode_ip, &ih264e_video_encode_op); + if(IV_SUCCESS != status) + { + printf("Encode Header failed = 0x%x\n", ih264e_video_encode_op.s_ive_op.u4_error_code); + return; + } + + if(1 == ps_video_encode_op->output_present) + { + status = write_output(ps_app_ctxt->fp_op, (UWORD8 *) ps_video_encode_op->s_out_buf.pv_buf, + ps_video_encode_op->s_out_buf.u4_bytes); + if(IV_SUCCESS != status) + { + printf("Error: Unable to write to output file\n"); + return; + } + } + + /*****************************************************************************/ + /* Video control Set in Encode picture mode */ + /*****************************************************************************/ + set_enc_mode(ps_app_ctxt, -1, -1, IVE_ENC_MODE_PICTURE); + + GETTIME(&ps_app_ctxt->enc_start_time); + ps_app_ctxt->enc_last_time = ps_app_ctxt->enc_start_time; + + while(1) + { + IV_PICTURE_CODING_TYPE_T e_frame_type; + WORD32 i4_count; + + /* Default sei params values*/ + ps_app_ctxt->u4_sei_mdcv_params_present_flag = 1; + if(1 == ps_app_ctxt->u4_sei_mdcv_params_present_flag) + { + for(i4_count = 0; i4_count < NUM_SEI_MDCV_PRIMARIES; i4_count++) + { + ps_app_ctxt->au4_display_primaries_x[i4_count] = 0; + ps_app_ctxt->au4_display_primaries_y[i4_count] = 0; + } + ps_app_ctxt->u4_white_point_x = 0; + ps_app_ctxt->u4_white_point_y = 0; + ps_app_ctxt->u4_max_display_mastering_luminance = DEFAULT_MAX_DISPLAY_MASTERING_LUMINANCE; + ps_app_ctxt->u4_min_display_mastering_luminance = DEFAULT_MIN_DISPLAY_MASTERING_LUMINANCE; + set_sei_mdcv_params(ps_app_ctxt, u4_timestamp_low, u4_timestamp_high); + } + + ps_app_ctxt->u4_sei_cll_params_present_flag = 1; + if(1 == ps_app_ctxt->u4_sei_cll_params_present_flag) + { + ps_app_ctxt->u4_max_content_light_level = 0; + ps_app_ctxt->u4_max_pic_average_light_level = 0; + set_sei_cll_params(ps_app_ctxt, u4_timestamp_low, u4_timestamp_high); + } + + ps_app_ctxt->u4_sei_ave_params_present_flag = 1; + if(1 == ps_app_ctxt->u4_sei_ave_params_present_flag) + { + ps_app_ctxt->u4_ambient_illuminance = 1; + ps_app_ctxt->u4_ambient_light_x = 0; + ps_app_ctxt->u4_ambient_light_y = 0; + set_sei_ave_params(ps_app_ctxt, u4_timestamp_low, u4_timestamp_high); + } + + ps_app_ctxt->u4_sei_ccv_params_present_flag = 1; + if(1 == ps_app_ctxt->u4_sei_ccv_params_present_flag) + { + ps_app_ctxt->u4_ccv_cancel_flag = 0; + ps_app_ctxt->u4_ccv_persistence_flag = 1; + ps_app_ctxt->u4_ccv_primaries_present_flag = 1; + ps_app_ctxt->u4_ccv_min_luminance_value_present_flag = 1; + ps_app_ctxt->u4_ccv_max_luminance_value_present_flag = 1; + ps_app_ctxt->u4_ccv_avg_luminance_value_present_flag = 1; + ps_app_ctxt->u4_ccv_reserved_zero_2bits = 0; + for(i4_count = 0; i4_count < NUM_SEI_CCV_PRIMARIES; i4_count++) + { + ps_app_ctxt->ai4_ccv_primaries_x[i4_count] = 1; + ps_app_ctxt->ai4_ccv_primaries_y[i4_count] = 1; + } + ps_app_ctxt->u4_ccv_min_luminance_value = 1; + ps_app_ctxt->u4_ccv_max_luminance_value = 1; + ps_app_ctxt->u4_ccv_avg_luminance_value = 1; + set_sei_ccv_params(ps_app_ctxt, u4_timestamp_low, u4_timestamp_high); + } + + ps_app_ctxt->u4_sii_sub_layer_idx = SII_SUB_LAYER_IDX; + + if(0 == ps_app_ctxt->u4_sii_sub_layer_idx) + { + ps_app_ctxt->u4_shutter_interval_info_present_flag = SHUTTER_INTERVAL_INFO_PRESENT_FLAG; + + if(1 == ps_app_ctxt->u4_shutter_interval_info_present_flag) + { + ps_app_ctxt->u4_sii_time_scale = SII_TIME_SCALE; + ps_app_ctxt->u4_fixed_shutter_interval_within_cvs_flag = + FIXED_SHUTTER_INTERVAL_WITHIN_CVS_FLAG; + + if(1 == ps_app_ctxt->u4_fixed_shutter_interval_within_cvs_flag) + { + ps_app_ctxt->u4_sii_num_units_in_shutter_interval = + SII_NUM_UNITS_IN_SHUTTER_INTERVAL; + } + else + { + int i; + ps_app_ctxt->u4_sii_max_sub_layers_minus1 = SII_MAX_SUB_LAYERS_MINUS1; + + for(i = 0; i <= (int) ps_app_ctxt->u4_sii_max_sub_layers_minus1; i++) + { + ps_app_ctxt->au4_sub_layer_num_units_in_shutter_interval[i] = + SUB_LAYER_NUM_UNITS_IN_SHUTTER_INTERVAL_HFR; + } + ps_app_ctxt->au4_sub_layer_num_units_in_shutter_interval + [ps_app_ctxt->u4_sii_max_sub_layers_minus1] = + SUB_LAYER_NUM_UNITS_IN_SHUTTER_INTERVAL_SFR; + } + } + } + set_sei_sii_params(ps_app_ctxt, u4_timestamp_low, u4_timestamp_high); + + /* Input Initialization */ + for(i = 0; i < DEFAULT_MAX_INPUT_BUFS; i++) + { + if(ps_app_ctxt->as_input_buf[i].u4_is_free) + { + pu1_buf = ps_app_ctxt->as_input_buf[i].pu1_buf; + pv_mb_info = ps_app_ctxt->as_input_buf[i].pv_mb_info; + pv_pic_info = ps_app_ctxt->as_input_buf[i].pv_pic_info; + ps_app_ctxt->as_input_buf[i].u4_is_free = 0; + break; + } + } + if (i == DEFAULT_MAX_INPUT_BUFS) + { + printf("\n Unable to find a free input buffer!!"); + exit(0); + } + + ps_video_encode_ip->u4_size = sizeof(ih264e_video_encode_ip_t); + ps_video_encode_ip->e_cmd = IVE_CMD_VIDEO_ENCODE; + ps_video_encode_ip->pv_bufs = pu1_buf; + ps_video_encode_ip->pv_mb_info = pv_mb_info; + ps_video_encode_ip->pv_pic_info = pv_pic_info; + ps_video_encode_ip->u4_pic_info_type = ps_app_ctxt->u4_pic_info_type; + + ps_video_encode_op->u4_size = sizeof(ih264e_video_encode_op_t); + + /* + * Since the buffers are used for reading, + * And after each row we have a stride we need to calculate + * the luma size according to the stride + */ + ps_inp_raw_buf->e_color_fmt = ps_app_ctxt->e_inp_color_fmt; + if(IV_YUV_420SP_UV == ps_app_ctxt->e_inp_color_fmt + || IV_YUV_420SP_VU == ps_app_ctxt->e_inp_color_fmt) + { + /* init luma buffer */ + ps_inp_raw_buf->apv_bufs[0] = pu1_buf; + + /* init chroma buffer */ + pu1_buf += ps_app_ctxt->u4_strd * ps_app_ctxt->u4_ht; + ps_inp_raw_buf->apv_bufs[1] = pu1_buf; + + ps_inp_raw_buf->au4_wd[0] = ps_app_ctxt->u4_wd; + ps_inp_raw_buf->au4_wd[1] = ps_app_ctxt->u4_wd; + + ps_inp_raw_buf->au4_ht[0] = ps_app_ctxt->u4_ht; + ps_inp_raw_buf->au4_ht[1] = ps_app_ctxt->u4_ht / 2; + + ps_inp_raw_buf->au4_strd[0] = ps_app_ctxt->u4_strd; + ps_inp_raw_buf->au4_strd[1] = ps_app_ctxt->u4_strd; + } + else if(IV_YUV_420P == ps_app_ctxt->e_inp_color_fmt) + { + /* init luma buffer */ + ps_inp_raw_buf->apv_bufs[0] = pu1_buf; + pu1_buf += (ps_app_ctxt->u4_wd) * ps_app_ctxt->u4_ht; + + /* init chroma buffer U */ + ps_inp_raw_buf->apv_bufs[1] = pu1_buf; + pu1_buf += (ps_app_ctxt->u4_wd >> 1) * (ps_app_ctxt->u4_ht >> 1); + + /* init chroma buffer V */ + ps_inp_raw_buf->apv_bufs[2] = pu1_buf; + + ps_inp_raw_buf->au4_wd[0] = ps_app_ctxt->u4_wd; + ps_inp_raw_buf->au4_wd[1] = ps_app_ctxt->u4_wd / 2; + ps_inp_raw_buf->au4_wd[2] = ps_app_ctxt->u4_wd / 2; + + ps_inp_raw_buf->au4_ht[0] = ps_app_ctxt->u4_ht; + ps_inp_raw_buf->au4_ht[1] = ps_app_ctxt->u4_ht / 2; + ps_inp_raw_buf->au4_ht[2] = ps_app_ctxt->u4_ht / 2; + + ps_inp_raw_buf->au4_strd[0] = ps_app_ctxt->u4_strd; + ps_inp_raw_buf->au4_strd[1] = ps_app_ctxt->u4_strd / 2; + ps_inp_raw_buf->au4_strd[2] = ps_app_ctxt->u4_strd / 2; + + } + else if(IV_YUV_422ILE == ps_app_ctxt->e_inp_color_fmt) + { + /* init luma buffer */ + ps_inp_raw_buf->apv_bufs[0] = pu1_buf; + + ps_inp_raw_buf->au4_wd[0] = ps_app_ctxt->u4_wd * 2; + + ps_inp_raw_buf->au4_ht[0] = ps_app_ctxt->u4_ht; + + ps_inp_raw_buf->au4_strd[0] = ps_app_ctxt->u4_strd * 2; + } + + /* Read input and other associated buffers */ + while(1) + { + IV_STATUS_T mb_info_status = IV_SUCCESS; + IV_STATUS_T pic_info_status = IV_SUCCESS; + + status = read_input(ps_app_ctxt->fp_ip, ps_inp_raw_buf); + + if(ps_app_ctxt->u4_mb_info_type != 0) + { + mb_info_status = read_mb_info(ps_app_ctxt, pv_mb_info); + } + if(ps_app_ctxt->u4_pic_info_type != 0) + { + pic_info_status = read_pic_info(ps_app_ctxt, pv_pic_info); + } + if((IV_SUCCESS != status) || (IV_SUCCESS != mb_info_status) + || (IV_SUCCESS != pic_info_status)) + { + if(0 == ps_app_ctxt->u4_loopback) + { + is_last = 1; + break; + } + else + { + fseek(ps_app_ctxt->fp_ip, 0, SEEK_SET); + } + } + break; + } + + /* Output Initialization */ + for(i = 0; i < DEFAULT_MAX_OUTPUT_BUFS; i++) + { + if(ps_app_ctxt->as_output_buf[i].u4_is_free) + { + pu1_buf = ps_app_ctxt->as_output_buf[i].pu1_buf; + buff_size = ps_app_ctxt->as_output_buf[i].u4_buf_size; + ps_app_ctxt->as_output_buf[i].u4_is_free = 0; + break; + } + } + if (i == DEFAULT_MAX_OUTPUT_BUFS) + { + printf("\n Unable to find a free output buffer!!"); + exit(0); + } + ps_video_encode_ip->s_out_buf.pv_buf = pu1_buf; + ps_video_encode_ip->s_out_buf.u4_bytes = 0; + ps_video_encode_ip->s_out_buf.u4_bufsize = buff_size; + + /* Recon Initialization */ + init_raw_buf_descr(ps_app_ctxt, &s_recon_buf, + ps_app_ctxt->as_recon_buf[0].pu1_buf, + ps_app_ctxt->e_recon_color_fmt); + ps_video_encode_ip->s_recon_buf = s_recon_buf; + + if(ps_app_ctxt->u4_psnr_enable) + { + init_raw_buf_descr(ps_app_ctxt, &s_inp_buf, + ps_app_ctxt->pu1_psnr_buf, + ps_app_ctxt->e_inp_color_fmt); + } + + if(0 == ps_app_ctxt->u4_loopback) + { + /* If input file is read completely and loopback is not enabled, + * then exit the loop */ + if(feof(ps_app_ctxt->fp_ip)) + { + is_last = 1; + } + } + + /* If last frame, send input null to get back encoded frames */ + if(is_last == 1 || ((ps_app_ctxt->u4_max_num_frms) <= u4_timestamp_low)) + { + is_last = 1; + ps_inp_raw_buf->apv_bufs[0] = NULL; + ps_inp_raw_buf->apv_bufs[1] = NULL; + ps_inp_raw_buf->apv_bufs[2] = NULL; + } + + ps_video_encode_ip->u4_is_last = is_last; + ps_video_encode_ip->u4_mb_info_type = ps_app_ctxt->u4_mb_info_type; + ps_video_encode_ip->u4_pic_info_type = ps_app_ctxt->u4_pic_info_type; + ps_video_encode_op->s_out_buf.pv_buf = NULL; + ps_video_encode_ip->u4_timestamp_high = u4_timestamp_high; + ps_video_encode_ip->u4_timestamp_low = u4_timestamp_low; + + GETTIME(&ps_app_ctxt->enc_last_time); + + /* encoder api call */ + status = ih264e_api_function(ps_enc, &ih264e_video_encode_ip, + &ih264e_video_encode_op); + if(IV_SUCCESS != status) + { + printf("Encode Frame failed = 0x%x\n", + ih264e_video_encode_op.s_ive_op.u4_error_code); + break; + } + +#ifdef WINDOWS_TIMER + QueryPerformanceFrequency ( &frequency); +#endif + GETTIME(&curtime); + ELAPSEDTIME(ps_app_ctxt->enc_last_time, curtime, timetaken, frequency); + ps_app_ctxt->enc_last_time = curtime; + +#ifdef PROFILE_ENABLE + { + WORD32 peak_avg, id; + + u4_total_time += timetaken; + peak_window[peak_window_idx++] = timetaken; + if(peak_window_idx == PEAK_WINDOW_SIZE) + peak_window_idx = 0; + peak_avg = 0; + for(id = 0; id < PEAK_WINDOW_SIZE; id++) + { + peak_avg += peak_window[id]; + } + peak_avg /= PEAK_WINDOW_SIZE; + if (peak_avg > peak_avg_max) + peak_avg_max = peak_avg; + } +#endif + + /* Write Output */ + num_bytes = 0; + if(1 == ps_video_encode_op->output_present) + { + num_bytes = ps_video_encode_op->s_out_buf.u4_bytes; + buff_size = ps_video_encode_op->s_out_buf.u4_bufsize; + pu1_buf = (UWORD8*)ps_video_encode_op->s_out_buf.pv_buf; + status = write_output(ps_app_ctxt->fp_op, pu1_buf, num_bytes); + if(IV_SUCCESS != status) + { + printf("Error: Unable to write to output file\n"); + break; + } + } + + /* free input bufer if codec returns a valid input buffer */ + if(ps_video_encode_op->s_inp_buf.apv_bufs[0]) + { + /* Reuse of freed input buffer */ + for(i = 0; i < DEFAULT_MAX_INPUT_BUFS; i++) + { + if(ps_app_ctxt->as_input_buf[i].pu1_buf + == ps_video_encode_op->s_inp_buf.apv_bufs[0]) + { + ps_app_ctxt->as_input_buf[i].u4_is_free = 1; + break; + } + } + } + + /* free output buffer if codec returns a valid output buffer */ + if(ps_video_encode_op->s_out_buf.pv_buf) + { + for(i = 0; i < DEFAULT_MAX_OUTPUT_BUFS; i++) + { + if(ps_app_ctxt->as_output_buf[i].pu1_buf + == ps_video_encode_op->s_out_buf.pv_buf) + { + ps_app_ctxt->as_output_buf[i].u4_is_free = 1; + break; + } + } + } + + /* Print stats */ + { + UWORD8 u1_pic_type[][5] = { "IDR", "I", "P", "B", "NA" }; + WORD32 lookup_idx = 0; + + switch(ih264e_video_encode_op.s_ive_op.u4_encoded_frame_type) + { + case IV_IDR_FRAME: + lookup_idx = 0; + break; + case IV_I_FRAME: + lookup_idx = 1; + break; + case IV_P_FRAME: + lookup_idx = 2; + break; + case IV_B_FRAME: + lookup_idx = 3; + break; + case IV_NA_FRAME: + lookup_idx = 4; + break; + default: + break; + } + + if(ih264e_video_encode_op.s_ive_op.u4_encoded_frame_type + != IV_NA_FRAME) + { + ps_app_ctxt->u4_pics_cnt++; + ps_app_ctxt->avg_time = u4_total_time / ps_app_ctxt->u4_pics_cnt; + ps_app_ctxt->u4_total_bytes += num_bytes; + } + + if(ps_app_ctxt->u4_psnr_enable == 0) + { + printf("[%s] PicNum %4d Bytes Generated %6d TimeTaken(microsec): %6d AvgTime: %6d PeakAvgTimeMax: %6d\n", + u1_pic_type[lookup_idx], ps_app_ctxt->u4_pics_cnt, + num_bytes, timetaken, ps_app_ctxt->avg_time, + peak_avg_max); + } + } + + + /* For psnr computation, we need to read the correct input frame and + * compare with recon. The difficulty with doing it is that we only know + * that the frame number of recon is monotonically increasing. There + * may be gaps in the recon if any pre or post enc skip happens. There are + * 3 senarios + * 1) A frame is encoded -> returns the pic type + * 2) A frame is not encoded -> Encoder is waiting, the frame may get + * encoded later + * 3) A frame is not encoded -> A post enc or pre enc skip happend. The + * frame is not going to be encoded + * + * The 1st and 2nd scenarios are easy, since we just needs to increment + * recon cnt whenever we get a valid recon. This cnt can we used to + * sync the recon and input + * 3rd scenario in conjuction with 2nd will pose problems. Even if + * the returning frame is NA, we donot know we should increment the + * recon cnt or not becasue it can be case 2 or case 3. + * + * Solutions: + * ------------------------- + * One way to over come this will be to return more information as of + * the frame type. We can send if a frame was skipped as a part of the + * return frame type. + * This will not work. Since the output and recon are not in sync, we + * cannot use the current output frame type to determine if a recon + * is present currently or not. We need some other way to acheive this. + * + * Other way to do this which is cleaner and maintains the seperation + * between recon and the ouptut is to set the width [& height] of output recon + * buffer to be zero. Hence we will in effect be saying :"look there + * is a recon, but due to frame not being encoded it is having a width 0". + * To be more clear we need to make height also to be zero. + * + * But are we using these variables for allocating and deallocating + * the buffers some where ? No we are not. The buffer gets re-init + * at every encode call + * + * Fixes + * ------------------------ + * Currently the recon buff width and height are set in the encoder. + * This will not work now because since recon and input are not + * in sync. Hence a recon buff sent at time stamp x will get used to + * fill recon of input at time stamp y (x > y). If we reduced the + * frame dimensions in between, the recon buffer will not have enough + * space. Hence we need to set the with and height appropriatley inside + * lib itself. + */ + + if (ps_app_ctxt->u4_recon_enable || ps_app_ctxt->u4_chksum_enable + || ps_app_ctxt->u4_psnr_enable) + { + if (ps_video_encode_op->dump_recon) + { + s_recon_buf = ps_video_encode_op->s_recon_buf; + + /* Read input for psnr computuation */ + if (ps_app_ctxt->u4_psnr_enable) + read_input(ps_app_ctxt->fp_psnr_ip, &s_inp_buf); + + /* if we have a valid recon buffer do the assocated tasks */ + if (s_recon_buf.au4_wd[0]) + { + /* Dump recon when enabled, and output bytes != 0 */ + if (ps_app_ctxt->u4_recon_enable) + { + status = write_recon(ps_app_ctxt->fp_recon, &s_recon_buf); + if (IV_SUCCESS != status) + { + printf("Error: Unable to write to recon file\n"); + break; + } + } + + if (ps_app_ctxt->u4_psnr_enable) + { + compute_psnr(ps_app_ctxt, &s_recon_buf, &s_inp_buf); + } + + + if (ps_app_ctxt->u4_chksum_enable) + { + WORD32 comp, num_comp = 2; + + if (IV_YUV_420P == s_recon_buf.e_color_fmt) + num_comp = 3; + + for (comp = 0; comp < num_comp; comp++) + { + UWORD8 au1_chksum[16]; + calc_md5_cksum((UWORD8 *)s_recon_buf.apv_bufs[comp], + s_recon_buf.au4_strd[comp], + s_recon_buf.au4_wd[comp], + s_recon_buf.au4_ht[comp], + au1_chksum); + fwrite(au1_chksum, sizeof(UWORD8), 16, ps_app_ctxt->fp_chksum); + } + } + } + } + } + + u4_timestamp_low++; + + /* Break if all the encoded frames are taken from encoder */ + if (1 == ps_video_encode_op->u4_is_last) + { + break; + } + } + + /* Pic count is 1 more than actual num frames encoded, because last call is + * to just get the output */ + ps_app_ctxt->u4_pics_cnt--; + + if(ps_app_ctxt->u4_psnr_enable) + { + print_average_psnr(ps_app_ctxt); + } + + /* house keeping operations */ + fclose(ps_app_ctxt->fp_ip); + fclose(ps_app_ctxt->fp_op); + if(1 == ps_app_ctxt->u4_recon_enable) + { + fclose(ps_app_ctxt->fp_recon); + } + if(1 == ps_app_ctxt->u4_chksum_enable) + { + fclose(ps_app_ctxt->fp_chksum); + } + if(1 == ps_app_ctxt->u4_psnr_enable) + { + fclose(ps_app_ctxt->fp_psnr_ip); + } + + if(0 != ps_app_ctxt->u4_mb_info_type) + { + fclose(ps_app_ctxt->fp_mb_info); + } + if (ps_app_ctxt->u4_pic_info_type) + { + fclose(ps_app_ctxt->fp_pic_info); + } + + free_input(ps_app_ctxt); + free_output(ps_app_ctxt); + free_recon(ps_app_ctxt); +} + +/** +******************************************************************************* +* @brief Application to demonstrate codec API. Shows how to use create, +* process, control and delete +******************************************************************************* +*/ +#ifdef IOS +int h264enc_main(char * homedir,char *documentdir, int screen_wd, int screen_ht) +#else +int main(int argc, char *argv[]) +#endif +{ + /* Config Parameters for Encoding */ + app_ctxt_t s_app_ctxt; + + /* error string */ + CHAR ac_error[STRLENGTH]; + + /* config file name */ + CHAR ac_cfg_fname[STRLENGTH]; + + /* error status */ + IV_STATUS_T status = IV_SUCCESS; +#ifdef IOS + /* temp var */ + CHAR filename_with_path[STRLENGTH]; +#endif + WORD32 num_mem_recs; + iv_obj_t *ps_enc; + WORD32 i; + FILE *fp_cfg = NULL; + +#ifdef X86_MINGW + + /* For getting printfs without any delay in eclipse */ + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + +#endif + + init_default_params(&s_app_ctxt); + +#ifndef IOS + + /* Usage */ + if(argc < 2) + { + printf("Using enc.cfg as configuration file \n"); + strcpy(ac_cfg_fname, "enc.cfg"); + } + else if(argc == 2) + { + if (!strcmp(argv[1], "--help")) + { + print_usage(); + exit(-1); + } + strcpy(ac_cfg_fname, argv[1]); + } + +#else + strcpy(ac_cfg_fname, "test.cfg"); + +#endif + + /*************************************************************************/ + /* Parse arguments */ + /*************************************************************************/ + +#ifndef IOS + + /* Read command line arguments */ + if(argc > 2) + { + for(i = 1; i + 1 < argc; i += 2) + { + if(CONFIG == get_argument(argv[i])) + { + strcpy(ac_cfg_fname, argv[i + 1]); + if((fp_cfg = fopen(ac_cfg_fname, "r")) == NULL) + { + sprintf(ac_error, + "Could not open Configuration file %s", + ac_cfg_fname); + codec_exit(ac_error); + } + read_cfg_file(&s_app_ctxt, fp_cfg); + fclose(fp_cfg); + } + else + { + parse_argument(&s_app_ctxt, argv[i], argv[i + 1]); + } + } + } + else + { + if((fp_cfg = fopen(ac_cfg_fname, "r")) == NULL) + { + sprintf(ac_error, "Could not open Configuration file %s", + ac_cfg_fname); + codec_exit(ac_error); + } + read_cfg_file(&s_app_ctxt, fp_cfg); + fclose(fp_cfg); + } + +#else + + sprintf(filename_with_path, "%s/%s", homedir, "enc.cfg"); + if((fp_cfg = fopen(filename_with_path, "r")) == NULL) + { + sprintf(ac_error, "Could not open Configuration file %s", + ac_cfg_fname); + codec_exit(ac_error); + + } + read_cfg_file(&s_app_ctxt, fp_cfg); + fclose(fp_cfg); + +#endif + + validate_params(&s_app_ctxt); + + + /*************************************************************************/ + /* Getting Number of MemRecords */ + /*************************************************************************/ + { + ih264e_num_mem_rec_ip_t s_num_mem_rec_ip; + ih264e_num_mem_rec_op_t s_num_mem_rec_op; + + s_num_mem_rec_ip.s_ive_ip.u4_size = sizeof(ih264e_num_mem_rec_ip_t); + s_num_mem_rec_ip.s_ive_ip.e_cmd = IV_CMD_GET_NUM_MEM_REC; + + s_num_mem_rec_op.s_ive_op.u4_size = sizeof(ih264e_num_mem_rec_op_t); + + status = ih264e_api_function(NULL, &s_num_mem_rec_ip, &s_num_mem_rec_op); + if(status != IV_SUCCESS) + { + sprintf(ac_error, "Get number of memory records failed = 0x%x\n", + s_num_mem_rec_op.s_ive_op.u4_error_code); + codec_exit(ac_error); + } + + s_app_ctxt.u4_num_mem_rec = s_num_mem_rec_op.s_ive_op.u4_num_mem_rec; + num_mem_recs = s_num_mem_rec_op.s_ive_op.u4_num_mem_rec; + } + + /*************************************************************************/ + /* Allocate and Default initialize MemRecords */ + /*************************************************************************/ + s_app_ctxt.ps_mem_rec = malloc(num_mem_recs * sizeof(iv_mem_rec_t)); + if(NULL == s_app_ctxt.ps_mem_rec) + { + sprintf(ac_error, + "Unable to allocate memory for hold memory records: Size %d", + (WORD32)(num_mem_recs * sizeof(iv_mem_rec_t))); + codec_exit(ac_error); + } + /* Default init memory records */ + { + iv_mem_rec_t *ps_mem_rec = s_app_ctxt.ps_mem_rec; + + for(i = 0; i < num_mem_recs; i++, ps_mem_rec++) + { + ps_mem_rec->u4_size = sizeof(iv_mem_rec_t); + ps_mem_rec->pv_base = NULL; + ps_mem_rec->u4_mem_size = 0; + ps_mem_rec->u4_mem_alignment = 0; + ps_mem_rec->e_mem_type = IV_NA_MEM_TYPE; + } + } + + /*************************************************************************/ + /* Getting MemRecords Attributes */ + /*************************************************************************/ + { + ih264e_fill_mem_rec_ip_t s_fill_mem_rec_ip; + ih264e_fill_mem_rec_op_t s_fill_mem_rec_op; + + s_fill_mem_rec_ip.s_ive_ip.u4_size = sizeof(ih264e_fill_mem_rec_ip_t); + s_fill_mem_rec_ip.s_ive_ip.e_cmd = IV_CMD_FILL_NUM_MEM_REC; + s_fill_mem_rec_ip.s_ive_ip.ps_mem_rec = s_app_ctxt.ps_mem_rec; + s_fill_mem_rec_ip.s_ive_ip.u4_num_mem_rec = s_app_ctxt.u4_num_mem_rec; + s_fill_mem_rec_ip.s_ive_ip.u4_max_wd = s_app_ctxt.u4_max_wd; + s_fill_mem_rec_ip.s_ive_ip.u4_max_ht = s_app_ctxt.u4_max_ht; + s_fill_mem_rec_ip.s_ive_ip.u4_max_ref_cnt = DEFAULT_MAX_REF_FRM; + s_fill_mem_rec_ip.s_ive_ip.u4_max_reorder_cnt = DEFAULT_MAX_REORDER_FRM; + s_fill_mem_rec_ip.s_ive_ip.u4_max_level = s_app_ctxt.u4_max_level; + s_fill_mem_rec_ip.s_ive_ip.e_color_format = DEFAULT_INP_COLOR_FMT; + s_fill_mem_rec_ip.s_ive_ip.u4_max_srch_rng_x = DEFAULT_MAX_SRCH_RANGE_X; + s_fill_mem_rec_ip.s_ive_ip.u4_max_srch_rng_y = DEFAULT_MAX_SRCH_RANGE_Y; + + s_fill_mem_rec_op.s_ive_op.u4_size = sizeof(ih264e_fill_mem_rec_op_t); + + status = ih264e_api_function(NULL, &s_fill_mem_rec_ip, &s_fill_mem_rec_op); + if(status != IV_SUCCESS) + { + sprintf(ac_error, "Fill memory records failed = 0x%x\n", + s_fill_mem_rec_op.s_ive_op.u4_error_code); + codec_exit(ac_error); + } + } + + /*************************************************************************/ + /* Allocating Memory for Mem Records */ + /*************************************************************************/ + { + iv_mem_rec_t *ps_mem_rec = s_app_ctxt.ps_mem_rec; + WORD32 total_size = 0; + + for(i = 0; i < num_mem_recs; i++) + { + ps_mem_rec->pv_base = ih264a_aligned_malloc( + ps_mem_rec->u4_mem_alignment, + ps_mem_rec->u4_mem_size); + if(ps_mem_rec->pv_base == NULL) + { + sprintf(ac_error, + "Allocation failure for mem record id %d size %d\n", i, + ps_mem_rec->u4_mem_size); + codec_exit(ac_error); + } + total_size += ps_mem_rec->u4_mem_size; + + ps_mem_rec++; + } + printf("\nTotal memory for codec %d\n", total_size); + } + + + /*************************************************************************/ + /* Codec Instance Creation */ + /*************************************************************************/ + { + ih264e_init_ip_t s_init_ip; + ih264e_init_op_t s_init_op; + + ps_enc = s_app_ctxt.ps_mem_rec[0].pv_base; + ps_enc->u4_size = sizeof(iv_obj_t); + ps_enc->pv_fxns = ih264e_api_function; + s_app_ctxt.ps_enc = ps_enc; + + s_init_ip.s_ive_ip.u4_size = sizeof(ih264e_init_ip_t); + s_init_ip.s_ive_ip.e_cmd = IV_CMD_INIT; + s_init_ip.s_ive_ip.u4_num_mem_rec = s_app_ctxt.u4_num_mem_rec; + s_init_ip.s_ive_ip.ps_mem_rec = s_app_ctxt.ps_mem_rec; + s_init_ip.s_ive_ip.u4_max_wd = s_app_ctxt.u4_max_wd; + s_init_ip.s_ive_ip.u4_max_ht = s_app_ctxt.u4_max_ht; + s_init_ip.s_ive_ip.u4_max_ref_cnt = DEFAULT_MAX_REF_FRM; + s_init_ip.s_ive_ip.u4_max_reorder_cnt = DEFAULT_MAX_REORDER_FRM; + s_init_ip.s_ive_ip.u4_max_level = s_app_ctxt.u4_max_level; + s_init_ip.s_ive_ip.e_inp_color_fmt = s_app_ctxt.e_inp_color_fmt; + if(s_app_ctxt.u4_recon_enable || s_app_ctxt.u4_psnr_enable + || s_app_ctxt.u4_chksum_enable) + { + s_init_ip.s_ive_ip.u4_enable_recon = 1; + } + else + { + s_init_ip.s_ive_ip.u4_enable_recon = 0; + } + s_init_ip.s_ive_ip.e_recon_color_fmt = s_app_ctxt.e_recon_color_fmt; + s_init_ip.s_ive_ip.e_rc_mode = s_app_ctxt.u4_rc; + s_init_ip.s_ive_ip.u4_max_framerate = s_app_ctxt.u4_max_frame_rate; + s_init_ip.s_ive_ip.u4_max_bitrate = s_app_ctxt.u4_max_bitrate; + s_init_ip.s_ive_ip.u4_num_bframes = s_app_ctxt.u4_num_bframes; + s_init_ip.s_ive_ip.e_content_type = IV_PROGRESSIVE; + s_init_ip.s_ive_ip.u4_max_srch_rng_x = DEFAULT_MAX_SRCH_RANGE_X; + s_init_ip.s_ive_ip.u4_max_srch_rng_y = DEFAULT_MAX_SRCH_RANGE_Y; + s_init_ip.s_ive_ip.e_slice_mode = s_app_ctxt.u4_slice_mode; + s_init_ip.s_ive_ip.u4_slice_param = s_app_ctxt.u4_slice_param; + s_init_ip.s_ive_ip.e_arch = s_app_ctxt.e_arch; + s_init_ip.s_ive_ip.e_soc = s_app_ctxt.e_soc; + + s_init_op.s_ive_op.u4_size = sizeof(ih264e_init_op_t); + + status = ih264e_api_function(ps_enc, &s_init_ip, &s_init_op); + if(status != IV_SUCCESS) + { + sprintf(ac_error, "Init memory records failed = 0x%x\n", + s_init_op.s_ive_op.u4_error_code); + codec_exit(ac_error); + } + } + + /*************************************************************************/ + /* set processor details */ + /*************************************************************************/ + { + ih264e_ctl_set_num_cores_ip_t s_ctl_set_num_cores_ip; + ih264e_ctl_set_num_cores_op_t s_ctl_set_num_cores_op; + + s_ctl_set_num_cores_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_num_cores_ip_t); + s_ctl_set_num_cores_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; + s_ctl_set_num_cores_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_NUM_CORES; + s_ctl_set_num_cores_ip.s_ive_ip.u4_num_cores = s_app_ctxt.u4_num_cores; + s_ctl_set_num_cores_ip.s_ive_ip.u4_timestamp_high = 0; + s_ctl_set_num_cores_ip.s_ive_ip.u4_timestamp_low = 0; + + s_ctl_set_num_cores_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_num_cores_op_t); + + status = ih264e_api_function(ps_enc, (void *)&s_ctl_set_num_cores_ip, + (void *)&s_ctl_set_num_cores_op); + if(status != IV_SUCCESS) + { + sprintf(ac_error, "Unable to set processor params = 0x%x\n", + s_ctl_set_num_cores_op.s_ive_op.u4_error_code); + codec_exit(ac_error); + } + } + + /*************************************************************************/ + /* Get Codec Version */ + /*************************************************************************/ + { + ih264e_ctl_getversioninfo_ip_t s_ctl_set_getversioninfo_ip; + ih264e_ctl_getversioninfo_op_t s_ctl_set_getversioninfo_op; + CHAR ac_version_string[STRLENGTH]; + + s_ctl_set_getversioninfo_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_getversioninfo_ip_t); + s_ctl_set_getversioninfo_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; + s_ctl_set_getversioninfo_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_GETVERSION; + s_ctl_set_getversioninfo_ip.s_ive_ip.pu1_version = (UWORD8 *)ac_version_string; + s_ctl_set_getversioninfo_ip.s_ive_ip.u4_version_bufsize = sizeof(ac_version_string); + + s_ctl_set_getversioninfo_op.s_ive_op.u4_size = sizeof(ih264e_ctl_getversioninfo_op_t); + + status = ih264e_api_function(ps_enc, + (void *)&s_ctl_set_getversioninfo_ip, + (void *)&s_ctl_set_getversioninfo_op); + if(status != IV_SUCCESS) + { + sprintf(ac_error, "Unable to get codec version = 0x%x\n", + s_ctl_set_getversioninfo_op.s_ive_op.u4_error_code); + codec_exit(ac_error); + } + printf("CODEC VERSION %s\n", ac_version_string); + } + + /*************************************************************************/ + /* Get I/O Buffer Requirement */ + /*************************************************************************/ + { + ih264e_ctl_getbufinfo_ip_t s_get_buf_info_ip; + ih264e_ctl_getbufinfo_op_t s_get_buf_info_op; + + s_get_buf_info_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_getbufinfo_ip_t); + s_get_buf_info_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; + s_get_buf_info_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_GETBUFINFO; + s_get_buf_info_ip.s_ive_ip.u4_max_ht = s_app_ctxt.u4_max_ht; + s_get_buf_info_ip.s_ive_ip.u4_max_wd = s_app_ctxt.u4_max_wd; + s_get_buf_info_ip.s_ive_ip.e_inp_color_fmt = s_app_ctxt.e_inp_color_fmt; + + s_get_buf_info_op.s_ive_op.u4_size = sizeof(ih264e_ctl_getbufinfo_op_t); + + status = ih264e_api_function(ps_enc, &s_get_buf_info_ip, + &s_get_buf_info_op); + if(status != IV_SUCCESS) + { + sprintf(ac_error, "Unable to get I/O buffer requirements = 0x%x\n", + s_get_buf_info_op.s_ive_op.u4_error_code); + codec_exit(ac_error); + } + s_app_ctxt.s_get_buf_info_op = s_get_buf_info_op; + } + + /**************************************************************************/ + /* Add the following initializations based on the parameters in context */ + /**************************************************************************/ + + /**************************************************************************/ + /* Video control Set Frame dimensions */ + /**************************************************************************/ + s_app_ctxt.u4_strd = s_app_ctxt.u4_wd; + set_dimensions(&s_app_ctxt, 0, 0); + + /**************************************************************************/ + /* Video control Set Frame rates */ + /**************************************************************************/ + set_frame_rate(&s_app_ctxt, 0, 0); + + /**************************************************************************/ + /* Video control Set IPE Params */ + /**************************************************************************/ + set_ipe_params(&s_app_ctxt, 0, 0); + + /**************************************************************************/ + /* Video control Set Bitrate */ + /**************************************************************************/ + set_bit_rate(&s_app_ctxt, 0, 0); + + /**************************************************************************/ + /* Video control Set QP */ + /**************************************************************************/ + set_qp(&s_app_ctxt, 0, 0); + + /**************************************************************************/ + /* Video control Set AIR params */ + /**************************************************************************/ + set_air_params(&s_app_ctxt, 0, 0); + + /**************************************************************************/ + /* Video control Set VBV params */ + /**************************************************************************/ + set_vbv_params(&s_app_ctxt, 0, 0); + + /**************************************************************************/ + /* Video control Set Motion estimation params */ + /**************************************************************************/ + set_me_params(&s_app_ctxt, 0, 0); + + /**************************************************************************/ + /* Video control Set GOP params */ + /**************************************************************************/ + set_gop_params(&s_app_ctxt, 0, 0); + + /**************************************************************************/ + /* Video control Set Deblock params */ + /**************************************************************************/ + set_deblock_params(&s_app_ctxt, 0, 0); + + /**************************************************************************/ + /* Video control Set Profile params */ + /**************************************************************************/ + set_profile_params(&s_app_ctxt, 0, 0); + + /**************************************************************************/ + /* Video usability information */ + /**************************************************************************/ + set_vui_params(&s_app_ctxt); + +#ifdef IOS + /* Correct file paths */ + sprintf(filename_with_path, "%s/%s", documentdir, s_app_ctxt.ac_ip_fname); + strcpy (s_app_ctxt.ac_ip_fname, filename_with_path); + + sprintf(filename_with_path, "%s/%s", documentdir, s_app_ctxt.ac_op_fname); + strcpy (s_app_ctxt.ac_op_fname, filename_with_path); + + sprintf(filename_with_path, "%s/%s", documentdir, s_app_ctxt.ac_recon_fname); + strcpy (s_app_ctxt.ac_recon_fname, filename_with_path); + + sprintf(filename_with_path, "%s/%s", documentdir, s_app_ctxt.ac_chksum_fname); + strcpy (s_app_ctxt.ac_chksum_fname, filename_with_path); + + sprintf(filename_with_path, "%s/%s", documentdir, s_app_ctxt.ac_mb_info_fname); + strcpy (s_app_ctxt.ac_mb_info_fname, filename_with_path); + + sprintf(filename_with_path, "%s/%s", documentdir, s_app_ctxt.ac_pic_info_fname); + strcpy (s_app_ctxt.ac_pic_info_fname, filename_with_path); +#endif + + /*************************************************************************/ + /* Encoding */ + /*************************************************************************/ + synchronous_encode(ps_enc, &s_app_ctxt); + + /*************************************************************************/ + /* Print summary */ + /*************************************************************************/ + { + DOUBLE bytes_per_frame; + DOUBLE bytes_per_second; + WORD32 achieved_bitrate; + + if(s_app_ctxt.u4_pics_cnt != 0) + { + bytes_per_frame = (s_app_ctxt.u4_total_bytes) / (s_app_ctxt.u4_pics_cnt); + } + else + { + bytes_per_frame = 0; + } + bytes_per_second = (bytes_per_frame * s_app_ctxt.u4_tgt_frame_rate); + + achieved_bitrate = bytes_per_second * 8; + + printf("\nEncoding Completed\n"); + printf("Summary\n"); + printf("Input filename : %s\n", s_app_ctxt.ac_ip_fname); + printf("Output filename : %s\n", s_app_ctxt.ac_op_fname); + printf("Output Width : %-4d\n", s_app_ctxt.u4_wd); + printf("Output Height : %-4d\n", s_app_ctxt.u4_ht); + printf("Target Bitrate (bps) : %-4d\n", s_app_ctxt.u4_bitrate); + printf("Achieved Bitrate (bps) : %-4d\n", achieved_bitrate); + printf("Average Time per Frame : %-4d\n", s_app_ctxt.avg_time); + printf("Achieved FPS : %-4.2f\n", 1000000.0 / s_app_ctxt.avg_time); + } + + + /*************************************************************************/ + /* Close Codec Instance */ + /*************************************************************************/ + { + ih264e_retrieve_mem_rec_ip_t s_retrieve_mem_ip; + ih264e_retrieve_mem_rec_op_t s_retrieve_mem_op; + iv_mem_rec_t *ps_mem_rec = s_app_ctxt.ps_mem_rec; + + s_retrieve_mem_ip.s_ive_ip.u4_size = sizeof(ih264e_retrieve_mem_rec_ip_t); + s_retrieve_mem_ip.s_ive_ip.e_cmd = IV_CMD_RETRIEVE_MEMREC; + s_retrieve_mem_ip.s_ive_ip.ps_mem_rec = s_app_ctxt.ps_mem_rec; + + s_retrieve_mem_op.s_ive_op.u4_size = sizeof(ih264e_retrieve_mem_rec_op_t); + + status = ih264e_api_function(ps_enc, &s_retrieve_mem_ip, &s_retrieve_mem_op); + if(status != IV_SUCCESS) + { + sprintf(ac_error, "Unable to retrieve memory records = 0x%x\n", + s_retrieve_mem_op.s_ive_op.u4_error_code); + codec_exit(ac_error); + } + + /* Free memory records */ + for(i = 0; i < num_mem_recs; i++) + { + ih264a_aligned_free(ps_mem_rec->pv_base); + ps_mem_rec++; + } + free(s_app_ctxt.ps_mem_rec); + } + + return 0; +} + + +#ifdef ANDROID_NDK +int raise(int a) +{ + printf("Divide by zero\n"); + return 0; +} +void __aeabi_assert(const char *assertion, const char *file, unsigned int line) +{ + return; +} +#endif |