Home | History | Annotate | Download | only in avcenc
      1 /*
      2  * Copyright 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 //#define LOG_NDEBUG 0
     18 #define LOG_TAG "SoftAVCEnc"
     19 #include <utils/Log.h>
     20 #include <utils/misc.h>
     21 
     22 #include "OMX_Video.h"
     23 
     24 #include <HardwareAPI.h>
     25 #include <MetadataBufferType.h>
     26 #include <media/stagefright/foundation/ADebug.h>
     27 #include <media/stagefright/MediaDefs.h>
     28 #include <media/stagefright/MediaErrors.h>
     29 #include <media/stagefright/MetaData.h>
     30 #include <OMX_IndexExt.h>
     31 #include <OMX_VideoExt.h>
     32 
     33 #include "ih264_typedefs.h"
     34 #include "iv2.h"
     35 #include "ive2.h"
     36 #include "ih264e.h"
     37 #include "SoftAVCEnc.h"
     38 
     39 namespace android {
     40 
     41     #define ive_api_function ih264e_api_function
     42 
     43 template<class T>
     44 static void InitOMXParams(T *params) {
     45     params->nSize = sizeof(T);
     46     params->nVersion.s.nVersionMajor = 1;
     47     params->nVersion.s.nVersionMinor = 0;
     48     params->nVersion.s.nRevision = 0;
     49     params->nVersion.s.nStep = 0;
     50 }
     51 
     52 struct LevelConversion {
     53     OMX_VIDEO_AVCLEVELTYPE omxLevel;
     54     WORD32 avcLevel;
     55 };
     56 
     57 static LevelConversion ConversionTable[] = {
     58     { OMX_VIDEO_AVCLevel1,  10 },
     59     { OMX_VIDEO_AVCLevel1b, 9  },
     60     { OMX_VIDEO_AVCLevel11, 11 },
     61     { OMX_VIDEO_AVCLevel12, 12 },
     62     { OMX_VIDEO_AVCLevel13, 13 },
     63     { OMX_VIDEO_AVCLevel2,  20 },
     64     { OMX_VIDEO_AVCLevel21, 21 },
     65     { OMX_VIDEO_AVCLevel22, 22 },
     66     { OMX_VIDEO_AVCLevel3,  30 },
     67     { OMX_VIDEO_AVCLevel31, 31 },
     68     { OMX_VIDEO_AVCLevel32, 32 },
     69     { OMX_VIDEO_AVCLevel4,  40 },
     70     { OMX_VIDEO_AVCLevel41, 41 },
     71     { OMX_VIDEO_AVCLevel42, 42 },
     72     { OMX_VIDEO_AVCLevel5,  50 },
     73     { OMX_VIDEO_AVCLevel51, 51 },
     74 };
     75 
     76 static const CodecProfileLevel kProfileLevels[] = {
     77     { OMX_VIDEO_AVCProfileConstrainedBaseline, OMX_VIDEO_AVCLevel41 },
     78 
     79     { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel41 },
     80 
     81     { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel41 },
     82 };
     83 
     84 static size_t GetCPUCoreCount() {
     85     long cpuCoreCount = 1;
     86 #if defined(_SC_NPROCESSORS_ONLN)
     87     cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN);
     88 #else
     89     // _SC_NPROC_ONLN must be defined...
     90     cpuCoreCount = sysconf(_SC_NPROC_ONLN);
     91 #endif
     92     CHECK(cpuCoreCount >= 1);
     93     ALOGV("Number of CPU cores: %ld", cpuCoreCount);
     94     return (size_t)cpuCoreCount;
     95 }
     96 
     97 static status_t ConvertOmxAvcLevelToAvcSpecLevel(
     98         OMX_VIDEO_AVCLEVELTYPE omxLevel, WORD32 *avcLevel) {
     99     for (size_t i = 0; i < NELEM(ConversionTable); ++i) {
    100         if (omxLevel == ConversionTable[i].omxLevel) {
    101             *avcLevel = ConversionTable[i].avcLevel;
    102             return OK;
    103         }
    104     }
    105 
    106     ALOGE("ConvertOmxAvcLevelToAvcSpecLevel: %d level not supported",
    107             (int32_t)omxLevel);
    108 
    109     return BAD_VALUE;
    110 }
    111 
    112 static status_t ConvertAvcSpecLevelToOmxAvcLevel(
    113         WORD32 avcLevel, OMX_VIDEO_AVCLEVELTYPE *omxLevel) {
    114     for (size_t i = 0; i < NELEM(ConversionTable); ++i) {
    115         if (avcLevel == ConversionTable[i].avcLevel) {
    116             *omxLevel = ConversionTable[i].omxLevel;
    117             return OK;
    118         }
    119     }
    120 
    121     ALOGE("ConvertAvcSpecLevelToOmxAvcLevel: %d level not supported",
    122             (int32_t)avcLevel);
    123 
    124     return BAD_VALUE;
    125 }
    126 
    127 
    128 SoftAVC::SoftAVC(
    129         const char *name,
    130         const OMX_CALLBACKTYPE *callbacks,
    131         OMX_PTR appData,
    132         OMX_COMPONENTTYPE **component)
    133     : SoftVideoEncoderOMXComponent(
    134             name, "video_encoder.avc", OMX_VIDEO_CodingAVC,
    135             kProfileLevels, NELEM(kProfileLevels),
    136             176 /* width */, 144 /* height */,
    137             callbacks, appData, component),
    138       mUpdateFlag(0),
    139       mIvVideoColorFormat(IV_YUV_420P),
    140       mAVCEncProfile(IV_PROFILE_BASE),
    141       mAVCEncLevel(41),
    142       mStarted(false),
    143       mSawInputEOS(false),
    144       mSawOutputEOS(false),
    145       mSignalledError(false),
    146       mCodecCtx(NULL) {
    147 
    148     initPorts(kNumBuffers, kNumBuffers, ((mWidth * mHeight * 3) >> 1),
    149             MEDIA_MIMETYPE_VIDEO_AVC, 2);
    150 
    151     // If dump is enabled, then open create an empty file
    152     GENERATE_FILE_NAMES();
    153     CREATE_DUMP_FILE(mInFile);
    154     CREATE_DUMP_FILE(mOutFile);
    155     memset(mConversionBuffers, 0, sizeof(mConversionBuffers));
    156     memset(mInputBufferInfo, 0, sizeof(mInputBufferInfo));
    157 
    158     initEncParams();
    159 
    160 }
    161 
    162 SoftAVC::~SoftAVC() {
    163     releaseEncoder();
    164     List<BufferInfo *> &outQueue = getPortQueue(1);
    165     List<BufferInfo *> &inQueue = getPortQueue(0);
    166     CHECK(outQueue.empty());
    167     CHECK(inQueue.empty());
    168 }
    169 
    170 void  SoftAVC::initEncParams() {
    171     mCodecCtx = NULL;
    172     mMemRecords = NULL;
    173     mNumMemRecords = DEFAULT_MEM_REC_CNT;
    174     mHeaderGenerated = 0;
    175     mNumCores = GetCPUCoreCount();
    176     mArch = DEFAULT_ARCH;
    177     mSliceMode = DEFAULT_SLICE_MODE;
    178     mSliceParam = DEFAULT_SLICE_PARAM;
    179     mHalfPelEnable = DEFAULT_HPEL;
    180     mIInterval = DEFAULT_I_INTERVAL;
    181     mIDRInterval = DEFAULT_IDR_INTERVAL;
    182     mDisableDeblkLevel = DEFAULT_DISABLE_DEBLK_LEVEL;
    183     mEnableFastSad = DEFAULT_ENABLE_FAST_SAD;
    184     mEnableAltRef = DEFAULT_ENABLE_ALT_REF;
    185     mEncSpeed = DEFAULT_ENC_SPEED;
    186     mIntra4x4 = DEFAULT_INTRA4x4;
    187     mConstrainedIntraFlag = DEFAULT_CONSTRAINED_INTRA;
    188     mAIRMode = DEFAULT_AIR;
    189     mAIRRefreshPeriod = DEFAULT_AIR_REFRESH_PERIOD;
    190     mPSNREnable = DEFAULT_PSNR_ENABLE;
    191     mReconEnable = DEFAULT_RECON_ENABLE;
    192     mEntropyMode = DEFAULT_ENTROPY_MODE;
    193     mBframes = DEFAULT_B_FRAMES;
    194 
    195     gettimeofday(&mTimeStart, NULL);
    196     gettimeofday(&mTimeEnd, NULL);
    197 
    198 }
    199 
    200 
    201 OMX_ERRORTYPE SoftAVC::setDimensions() {
    202     ive_ctl_set_dimensions_ip_t s_dimensions_ip;
    203     ive_ctl_set_dimensions_op_t s_dimensions_op;
    204     IV_STATUS_T status;
    205 
    206     s_dimensions_ip.e_cmd = IVE_CMD_VIDEO_CTL;
    207     s_dimensions_ip.e_sub_cmd = IVE_CMD_CTL_SET_DIMENSIONS;
    208     s_dimensions_ip.u4_ht = mHeight;
    209     s_dimensions_ip.u4_wd = mWidth;
    210 
    211     s_dimensions_ip.u4_timestamp_high = -1;
    212     s_dimensions_ip.u4_timestamp_low = -1;
    213 
    214     s_dimensions_ip.u4_size = sizeof(ive_ctl_set_dimensions_ip_t);
    215     s_dimensions_op.u4_size = sizeof(ive_ctl_set_dimensions_op_t);
    216 
    217     status = ive_api_function(mCodecCtx, &s_dimensions_ip, &s_dimensions_op);
    218     if (status != IV_SUCCESS) {
    219         ALOGE("Unable to set frame dimensions = 0x%x\n",
    220                 s_dimensions_op.u4_error_code);
    221         return OMX_ErrorUndefined;
    222     }
    223     return OMX_ErrorNone;
    224 }
    225 
    226 OMX_ERRORTYPE SoftAVC::setNumCores() {
    227     IV_STATUS_T status;
    228     ive_ctl_set_num_cores_ip_t s_num_cores_ip;
    229     ive_ctl_set_num_cores_op_t s_num_cores_op;
    230     s_num_cores_ip.e_cmd = IVE_CMD_VIDEO_CTL;
    231     s_num_cores_ip.e_sub_cmd = IVE_CMD_CTL_SET_NUM_CORES;
    232     s_num_cores_ip.u4_num_cores = MIN(mNumCores, CODEC_MAX_CORES);
    233     s_num_cores_ip.u4_timestamp_high = -1;
    234     s_num_cores_ip.u4_timestamp_low = -1;
    235     s_num_cores_ip.u4_size = sizeof(ive_ctl_set_num_cores_ip_t);
    236 
    237     s_num_cores_op.u4_size = sizeof(ive_ctl_set_num_cores_op_t);
    238 
    239     status = ive_api_function(
    240             mCodecCtx, (void *) &s_num_cores_ip, (void *) &s_num_cores_op);
    241     if (status != IV_SUCCESS) {
    242         ALOGE("Unable to set processor params = 0x%x\n",
    243                 s_num_cores_op.u4_error_code);
    244         return OMX_ErrorUndefined;
    245     }
    246     return OMX_ErrorNone;
    247 }
    248 
    249 OMX_ERRORTYPE SoftAVC::setFrameRate() {
    250     ive_ctl_set_frame_rate_ip_t s_frame_rate_ip;
    251     ive_ctl_set_frame_rate_op_t s_frame_rate_op;
    252     IV_STATUS_T status;
    253 
    254     s_frame_rate_ip.e_cmd = IVE_CMD_VIDEO_CTL;
    255     s_frame_rate_ip.e_sub_cmd = IVE_CMD_CTL_SET_FRAMERATE;
    256 
    257     s_frame_rate_ip.u4_src_frame_rate = mFramerate >> 16;
    258     s_frame_rate_ip.u4_tgt_frame_rate = mFramerate >> 16;
    259 
    260     s_frame_rate_ip.u4_timestamp_high = -1;
    261     s_frame_rate_ip.u4_timestamp_low = -1;
    262 
    263     s_frame_rate_ip.u4_size = sizeof(ive_ctl_set_frame_rate_ip_t);
    264     s_frame_rate_op.u4_size = sizeof(ive_ctl_set_frame_rate_op_t);
    265 
    266     status = ive_api_function(mCodecCtx, &s_frame_rate_ip, &s_frame_rate_op);
    267     if (status != IV_SUCCESS) {
    268         ALOGE("Unable to set frame rate = 0x%x\n",
    269                 s_frame_rate_op.u4_error_code);
    270         return OMX_ErrorUndefined;
    271     }
    272     return OMX_ErrorNone;
    273 }
    274 
    275 OMX_ERRORTYPE SoftAVC::setIpeParams() {
    276     ive_ctl_set_ipe_params_ip_t s_ipe_params_ip;
    277     ive_ctl_set_ipe_params_op_t s_ipe_params_op;
    278     IV_STATUS_T status;
    279 
    280     s_ipe_params_ip.e_cmd = IVE_CMD_VIDEO_CTL;
    281     s_ipe_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_IPE_PARAMS;
    282 
    283     s_ipe_params_ip.u4_enable_intra_4x4 = mIntra4x4;
    284     s_ipe_params_ip.u4_enc_speed_preset = mEncSpeed;
    285     s_ipe_params_ip.u4_constrained_intra_pred = mConstrainedIntraFlag;
    286 
    287     s_ipe_params_ip.u4_timestamp_high = -1;
    288     s_ipe_params_ip.u4_timestamp_low = -1;
    289 
    290     s_ipe_params_ip.u4_size = sizeof(ive_ctl_set_ipe_params_ip_t);
    291     s_ipe_params_op.u4_size = sizeof(ive_ctl_set_ipe_params_op_t);
    292 
    293     status = ive_api_function(mCodecCtx, &s_ipe_params_ip, &s_ipe_params_op);
    294     if (status != IV_SUCCESS) {
    295         ALOGE("Unable to set ipe params = 0x%x\n",
    296                 s_ipe_params_op.u4_error_code);
    297         return OMX_ErrorUndefined;
    298     }
    299     return OMX_ErrorNone;
    300 }
    301 
    302 OMX_ERRORTYPE SoftAVC::setBitRate() {
    303     ive_ctl_set_bitrate_ip_t s_bitrate_ip;
    304     ive_ctl_set_bitrate_op_t s_bitrate_op;
    305     IV_STATUS_T status;
    306 
    307     s_bitrate_ip.e_cmd = IVE_CMD_VIDEO_CTL;
    308     s_bitrate_ip.e_sub_cmd = IVE_CMD_CTL_SET_BITRATE;
    309 
    310     s_bitrate_ip.u4_target_bitrate = mBitrate;
    311 
    312     s_bitrate_ip.u4_timestamp_high = -1;
    313     s_bitrate_ip.u4_timestamp_low = -1;
    314 
    315     s_bitrate_ip.u4_size = sizeof(ive_ctl_set_bitrate_ip_t);
    316     s_bitrate_op.u4_size = sizeof(ive_ctl_set_bitrate_op_t);
    317 
    318     status = ive_api_function(mCodecCtx, &s_bitrate_ip, &s_bitrate_op);
    319     if (status != IV_SUCCESS) {
    320         ALOGE("Unable to set bit rate = 0x%x\n", s_bitrate_op.u4_error_code);
    321         return OMX_ErrorUndefined;
    322     }
    323     return OMX_ErrorNone;
    324 }
    325 
    326 OMX_ERRORTYPE SoftAVC::setFrameType(IV_PICTURE_CODING_TYPE_T e_frame_type) {
    327     ive_ctl_set_frame_type_ip_t s_frame_type_ip;
    328     ive_ctl_set_frame_type_op_t s_frame_type_op;
    329     IV_STATUS_T status;
    330     s_frame_type_ip.e_cmd = IVE_CMD_VIDEO_CTL;
    331     s_frame_type_ip.e_sub_cmd = IVE_CMD_CTL_SET_FRAMETYPE;
    332 
    333     s_frame_type_ip.e_frame_type = e_frame_type;
    334 
    335     s_frame_type_ip.u4_timestamp_high = -1;
    336     s_frame_type_ip.u4_timestamp_low = -1;
    337 
    338     s_frame_type_ip.u4_size = sizeof(ive_ctl_set_frame_type_ip_t);
    339     s_frame_type_op.u4_size = sizeof(ive_ctl_set_frame_type_op_t);
    340 
    341     status = ive_api_function(mCodecCtx, &s_frame_type_ip, &s_frame_type_op);
    342     if (status != IV_SUCCESS) {
    343         ALOGE("Unable to set frame type = 0x%x\n",
    344                 s_frame_type_op.u4_error_code);
    345         return OMX_ErrorUndefined;
    346     }
    347     return OMX_ErrorNone;
    348 }
    349 
    350 OMX_ERRORTYPE SoftAVC::setQp() {
    351     ive_ctl_set_qp_ip_t s_qp_ip;
    352     ive_ctl_set_qp_op_t s_qp_op;
    353     IV_STATUS_T status;
    354 
    355     s_qp_ip.e_cmd = IVE_CMD_VIDEO_CTL;
    356     s_qp_ip.e_sub_cmd = IVE_CMD_CTL_SET_QP;
    357 
    358     s_qp_ip.u4_i_qp = DEFAULT_I_QP;
    359     s_qp_ip.u4_i_qp_max = DEFAULT_QP_MAX;
    360     s_qp_ip.u4_i_qp_min = DEFAULT_QP_MIN;
    361 
    362     s_qp_ip.u4_p_qp = DEFAULT_P_QP;
    363     s_qp_ip.u4_p_qp_max = DEFAULT_QP_MAX;
    364     s_qp_ip.u4_p_qp_min = DEFAULT_QP_MIN;
    365 
    366     s_qp_ip.u4_b_qp = DEFAULT_P_QP;
    367     s_qp_ip.u4_b_qp_max = DEFAULT_QP_MAX;
    368     s_qp_ip.u4_b_qp_min = DEFAULT_QP_MIN;
    369 
    370     s_qp_ip.u4_timestamp_high = -1;
    371     s_qp_ip.u4_timestamp_low = -1;
    372 
    373     s_qp_ip.u4_size = sizeof(ive_ctl_set_qp_ip_t);
    374     s_qp_op.u4_size = sizeof(ive_ctl_set_qp_op_t);
    375 
    376     status = ive_api_function(mCodecCtx, &s_qp_ip, &s_qp_op);
    377     if (status != IV_SUCCESS) {
    378         ALOGE("Unable to set qp 0x%x\n", s_qp_op.u4_error_code);
    379         return OMX_ErrorUndefined;
    380     }
    381     return OMX_ErrorNone;
    382 }
    383 
    384 OMX_ERRORTYPE SoftAVC::setEncMode(IVE_ENC_MODE_T e_enc_mode) {
    385     IV_STATUS_T status;
    386     ive_ctl_set_enc_mode_ip_t s_enc_mode_ip;
    387     ive_ctl_set_enc_mode_op_t s_enc_mode_op;
    388 
    389     s_enc_mode_ip.e_cmd = IVE_CMD_VIDEO_CTL;
    390     s_enc_mode_ip.e_sub_cmd = IVE_CMD_CTL_SET_ENC_MODE;
    391 
    392     s_enc_mode_ip.e_enc_mode = e_enc_mode;
    393 
    394     s_enc_mode_ip.u4_timestamp_high = -1;
    395     s_enc_mode_ip.u4_timestamp_low = -1;
    396 
    397     s_enc_mode_ip.u4_size = sizeof(ive_ctl_set_enc_mode_ip_t);
    398     s_enc_mode_op.u4_size = sizeof(ive_ctl_set_enc_mode_op_t);
    399 
    400     status = ive_api_function(mCodecCtx, &s_enc_mode_ip, &s_enc_mode_op);
    401     if (status != IV_SUCCESS) {
    402         ALOGE("Unable to set in header encode mode = 0x%x\n",
    403                 s_enc_mode_op.u4_error_code);
    404         return OMX_ErrorUndefined;
    405     }
    406     return OMX_ErrorNone;
    407 }
    408 
    409 OMX_ERRORTYPE SoftAVC::setVbvParams() {
    410     ive_ctl_set_vbv_params_ip_t s_vbv_ip;
    411     ive_ctl_set_vbv_params_op_t s_vbv_op;
    412     IV_STATUS_T status;
    413 
    414     s_vbv_ip.e_cmd = IVE_CMD_VIDEO_CTL;
    415     s_vbv_ip.e_sub_cmd = IVE_CMD_CTL_SET_VBV_PARAMS;
    416 
    417     s_vbv_ip.u4_vbv_buf_size = 0;
    418     s_vbv_ip.u4_vbv_buffer_delay = 1000;
    419 
    420     s_vbv_ip.u4_timestamp_high = -1;
    421     s_vbv_ip.u4_timestamp_low = -1;
    422 
    423     s_vbv_ip.u4_size = sizeof(ive_ctl_set_vbv_params_ip_t);
    424     s_vbv_op.u4_size = sizeof(ive_ctl_set_vbv_params_op_t);
    425 
    426     status = ive_api_function(mCodecCtx, &s_vbv_ip, &s_vbv_op);
    427     if (status != IV_SUCCESS) {
    428         ALOGE("Unable to set VBC params = 0x%x\n", s_vbv_op.u4_error_code);
    429         return OMX_ErrorUndefined;
    430     }
    431     return OMX_ErrorNone;
    432 }
    433 
    434 OMX_ERRORTYPE SoftAVC::setAirParams() {
    435     ive_ctl_set_air_params_ip_t s_air_ip;
    436     ive_ctl_set_air_params_op_t s_air_op;
    437     IV_STATUS_T status;
    438 
    439     s_air_ip.e_cmd = IVE_CMD_VIDEO_CTL;
    440     s_air_ip.e_sub_cmd = IVE_CMD_CTL_SET_AIR_PARAMS;
    441 
    442     s_air_ip.e_air_mode = mAIRMode;
    443     s_air_ip.u4_air_refresh_period = mAIRRefreshPeriod;
    444 
    445     s_air_ip.u4_timestamp_high = -1;
    446     s_air_ip.u4_timestamp_low = -1;
    447 
    448     s_air_ip.u4_size = sizeof(ive_ctl_set_air_params_ip_t);
    449     s_air_op.u4_size = sizeof(ive_ctl_set_air_params_op_t);
    450 
    451     status = ive_api_function(mCodecCtx, &s_air_ip, &s_air_op);
    452     if (status != IV_SUCCESS) {
    453         ALOGE("Unable to set air params = 0x%x\n", s_air_op.u4_error_code);
    454         return OMX_ErrorUndefined;
    455     }
    456     return OMX_ErrorNone;
    457 }
    458 
    459 OMX_ERRORTYPE SoftAVC::setMeParams() {
    460     IV_STATUS_T status;
    461     ive_ctl_set_me_params_ip_t s_me_params_ip;
    462     ive_ctl_set_me_params_op_t s_me_params_op;
    463 
    464     s_me_params_ip.e_cmd = IVE_CMD_VIDEO_CTL;
    465     s_me_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_ME_PARAMS;
    466 
    467     s_me_params_ip.u4_enable_fast_sad = mEnableFastSad;
    468     s_me_params_ip.u4_enable_alt_ref = mEnableAltRef;
    469 
    470     s_me_params_ip.u4_enable_hpel = mHalfPelEnable;
    471     s_me_params_ip.u4_enable_qpel = DEFAULT_QPEL;
    472     s_me_params_ip.u4_me_speed_preset = DEFAULT_ME_SPEED;
    473     s_me_params_ip.u4_srch_rng_x = DEFAULT_SRCH_RNG_X;
    474     s_me_params_ip.u4_srch_rng_y = DEFAULT_SRCH_RNG_Y;
    475 
    476     s_me_params_ip.u4_timestamp_high = -1;
    477     s_me_params_ip.u4_timestamp_low = -1;
    478 
    479     s_me_params_ip.u4_size = sizeof(ive_ctl_set_me_params_ip_t);
    480     s_me_params_op.u4_size = sizeof(ive_ctl_set_me_params_op_t);
    481 
    482     status = ive_api_function(mCodecCtx, &s_me_params_ip, &s_me_params_op);
    483     if (status != IV_SUCCESS) {
    484         ALOGE("Unable to set me params = 0x%x\n", s_me_params_op.u4_error_code);
    485         return OMX_ErrorUndefined;
    486     }
    487     return OMX_ErrorNone;
    488 }
    489 
    490 OMX_ERRORTYPE SoftAVC::setGopParams() {
    491     IV_STATUS_T status;
    492     ive_ctl_set_gop_params_ip_t s_gop_params_ip;
    493     ive_ctl_set_gop_params_op_t s_gop_params_op;
    494 
    495     s_gop_params_ip.e_cmd = IVE_CMD_VIDEO_CTL;
    496     s_gop_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_GOP_PARAMS;
    497 
    498     s_gop_params_ip.u4_i_frm_interval = mIInterval;
    499     s_gop_params_ip.u4_idr_frm_interval = mIDRInterval;
    500 
    501     s_gop_params_ip.u4_timestamp_high = -1;
    502     s_gop_params_ip.u4_timestamp_low = -1;
    503 
    504     s_gop_params_ip.u4_size = sizeof(ive_ctl_set_gop_params_ip_t);
    505     s_gop_params_op.u4_size = sizeof(ive_ctl_set_gop_params_op_t);
    506 
    507     status = ive_api_function(mCodecCtx, &s_gop_params_ip, &s_gop_params_op);
    508     if (status != IV_SUCCESS) {
    509         ALOGE("Unable to set ME params = 0x%x\n",
    510                 s_gop_params_op.u4_error_code);
    511         return OMX_ErrorUndefined;
    512     }
    513     return OMX_ErrorNone;
    514 }
    515 
    516 OMX_ERRORTYPE SoftAVC::setProfileParams() {
    517     IV_STATUS_T status;
    518     ive_ctl_set_profile_params_ip_t s_profile_params_ip;
    519     ive_ctl_set_profile_params_op_t s_profile_params_op;
    520 
    521     s_profile_params_ip.e_cmd = IVE_CMD_VIDEO_CTL;
    522     s_profile_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_PROFILE_PARAMS;
    523 
    524     s_profile_params_ip.e_profile = DEFAULT_EPROFILE;
    525     s_profile_params_ip.u4_entropy_coding_mode = mEntropyMode;
    526     s_profile_params_ip.u4_timestamp_high = -1;
    527     s_profile_params_ip.u4_timestamp_low = -1;
    528 
    529     s_profile_params_ip.u4_size = sizeof(ive_ctl_set_profile_params_ip_t);
    530     s_profile_params_op.u4_size = sizeof(ive_ctl_set_profile_params_op_t);
    531 
    532     status = ive_api_function(mCodecCtx, &s_profile_params_ip, &s_profile_params_op);
    533     if (status != IV_SUCCESS) {
    534         ALOGE("Unable to set profile params = 0x%x\n",
    535                 s_profile_params_op.u4_error_code);
    536         return OMX_ErrorUndefined;
    537     }
    538     return OMX_ErrorNone;
    539 }
    540 
    541 OMX_ERRORTYPE SoftAVC::setDeblockParams() {
    542     IV_STATUS_T status;
    543     ive_ctl_set_deblock_params_ip_t s_deblock_params_ip;
    544     ive_ctl_set_deblock_params_op_t s_deblock_params_op;
    545 
    546     s_deblock_params_ip.e_cmd = IVE_CMD_VIDEO_CTL;
    547     s_deblock_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_DEBLOCK_PARAMS;
    548 
    549     s_deblock_params_ip.u4_disable_deblock_level = mDisableDeblkLevel;
    550 
    551     s_deblock_params_ip.u4_timestamp_high = -1;
    552     s_deblock_params_ip.u4_timestamp_low = -1;
    553 
    554     s_deblock_params_ip.u4_size = sizeof(ive_ctl_set_deblock_params_ip_t);
    555     s_deblock_params_op.u4_size = sizeof(ive_ctl_set_deblock_params_op_t);
    556 
    557     status = ive_api_function(mCodecCtx, &s_deblock_params_ip, &s_deblock_params_op);
    558     if (status != IV_SUCCESS) {
    559         ALOGE("Unable to enable/disable deblock params = 0x%x\n",
    560                 s_deblock_params_op.u4_error_code);
    561         return OMX_ErrorUndefined;
    562     }
    563     return OMX_ErrorNone;
    564 }
    565 
    566 void SoftAVC::logVersion() {
    567     ive_ctl_getversioninfo_ip_t s_ctl_ip;
    568     ive_ctl_getversioninfo_op_t s_ctl_op;
    569     UWORD8 au1_buf[512];
    570     IV_STATUS_T status;
    571 
    572     s_ctl_ip.e_cmd = IVE_CMD_VIDEO_CTL;
    573     s_ctl_ip.e_sub_cmd = IVE_CMD_CTL_GETVERSION;
    574     s_ctl_ip.u4_size = sizeof(ive_ctl_getversioninfo_ip_t);
    575     s_ctl_op.u4_size = sizeof(ive_ctl_getversioninfo_op_t);
    576     s_ctl_ip.pu1_version = au1_buf;
    577     s_ctl_ip.u4_version_bufsize = sizeof(au1_buf);
    578 
    579     status = ive_api_function(mCodecCtx, (void *) &s_ctl_ip, (void *) &s_ctl_op);
    580 
    581     if (status != IV_SUCCESS) {
    582         ALOGE("Error in getting version: 0x%x", s_ctl_op.u4_error_code);
    583     } else {
    584         ALOGV("Ittiam encoder version: %s", (char *)s_ctl_ip.pu1_version);
    585     }
    586     return;
    587 }
    588 
    589 OMX_ERRORTYPE SoftAVC::initEncoder() {
    590     IV_STATUS_T status;
    591     WORD32 level;
    592     uint32_t displaySizeY;
    593 
    594     CHECK(!mStarted);
    595 
    596     OMX_ERRORTYPE errType = OMX_ErrorNone;
    597 
    598     displaySizeY = mWidth * mHeight;
    599     if (displaySizeY > (1920 * 1088)) {
    600         level = 50;
    601     } else if (displaySizeY > (1280 * 720)) {
    602         level = 40;
    603     } else if (displaySizeY > (720 * 576)) {
    604         level = 31;
    605     } else if (displaySizeY > (624 * 320)) {
    606         level = 30;
    607     } else if (displaySizeY > (352 * 288)) {
    608         level = 21;
    609     } else if (displaySizeY > (176 * 144)) {
    610         level = 20;
    611     } else {
    612         level = 10;
    613     }
    614     mAVCEncLevel = MAX(level, mAVCEncLevel);
    615 
    616     mStride = mWidth;
    617 
    618     if (mInputDataIsMeta) {
    619         for (size_t i = 0; i < MAX_CONVERSION_BUFFERS; i++) {
    620             if (mConversionBuffers[i] != NULL) {
    621                 free(mConversionBuffers[i]);
    622                 mConversionBuffers[i] = 0;
    623             }
    624 
    625             if (((uint64_t)mStride * mHeight) > ((uint64_t)INT32_MAX / 3)) {
    626                 ALOGE("Buffer size is too big.");
    627                 return OMX_ErrorUndefined;
    628             }
    629             mConversionBuffers[i] = (uint8_t *)malloc(mStride * mHeight * 3 / 2);
    630 
    631             if (mConversionBuffers[i] == NULL) {
    632                 ALOGE("Allocating conversion buffer failed.");
    633                 return OMX_ErrorUndefined;
    634             }
    635 
    636             mConversionBuffersFree[i] = 1;
    637         }
    638     }
    639 
    640     switch (mColorFormat) {
    641         case OMX_COLOR_FormatYUV420SemiPlanar:
    642             mIvVideoColorFormat = IV_YUV_420SP_UV;
    643             ALOGV("colorFormat YUV_420SP");
    644             break;
    645         default:
    646         case OMX_COLOR_FormatYUV420Planar:
    647             mIvVideoColorFormat = IV_YUV_420P;
    648             ALOGV("colorFormat YUV_420P");
    649             break;
    650     }
    651 
    652     ALOGD("Params width %d height %d level %d colorFormat %d", mWidth,
    653             mHeight, mAVCEncLevel, mIvVideoColorFormat);
    654 
    655     /* Getting Number of MemRecords */
    656     {
    657         iv_num_mem_rec_ip_t s_num_mem_rec_ip;
    658         iv_num_mem_rec_op_t s_num_mem_rec_op;
    659 
    660         s_num_mem_rec_ip.u4_size = sizeof(iv_num_mem_rec_ip_t);
    661         s_num_mem_rec_op.u4_size = sizeof(iv_num_mem_rec_op_t);
    662 
    663         s_num_mem_rec_ip.e_cmd = IV_CMD_GET_NUM_MEM_REC;
    664 
    665         status = ive_api_function(0, &s_num_mem_rec_ip, &s_num_mem_rec_op);
    666 
    667         if (status != IV_SUCCESS) {
    668             ALOGE("Get number of memory records failed = 0x%x\n",
    669                     s_num_mem_rec_op.u4_error_code);
    670             return OMX_ErrorUndefined;
    671         }
    672 
    673         mNumMemRecords = s_num_mem_rec_op.u4_num_mem_rec;
    674     }
    675 
    676     /* Allocate array to hold memory records */
    677     if (mNumMemRecords > SIZE_MAX / sizeof(iv_mem_rec_t)) {
    678         ALOGE("requested memory size is too big.");
    679         return OMX_ErrorUndefined;
    680     }
    681     mMemRecords = (iv_mem_rec_t *)malloc(mNumMemRecords * sizeof(iv_mem_rec_t));
    682     if (NULL == mMemRecords) {
    683         ALOGE("Unable to allocate memory for hold memory records: Size %zu",
    684                 mNumMemRecords * sizeof(iv_mem_rec_t));
    685         mSignalledError = true;
    686         notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
    687         return OMX_ErrorUndefined;
    688     }
    689 
    690     {
    691         iv_mem_rec_t *ps_mem_rec;
    692         ps_mem_rec = mMemRecords;
    693         for (size_t i = 0; i < mNumMemRecords; i++) {
    694             ps_mem_rec->u4_size = sizeof(iv_mem_rec_t);
    695             ps_mem_rec->pv_base = NULL;
    696             ps_mem_rec->u4_mem_size = 0;
    697             ps_mem_rec->u4_mem_alignment = 0;
    698             ps_mem_rec->e_mem_type = IV_NA_MEM_TYPE;
    699 
    700             ps_mem_rec++;
    701         }
    702     }
    703 
    704     /* Getting MemRecords Attributes */
    705     {
    706         iv_fill_mem_rec_ip_t s_fill_mem_rec_ip;
    707         iv_fill_mem_rec_op_t s_fill_mem_rec_op;
    708 
    709         s_fill_mem_rec_ip.u4_size = sizeof(iv_fill_mem_rec_ip_t);
    710         s_fill_mem_rec_op.u4_size = sizeof(iv_fill_mem_rec_op_t);
    711 
    712         s_fill_mem_rec_ip.e_cmd = IV_CMD_FILL_NUM_MEM_REC;
    713         s_fill_mem_rec_ip.ps_mem_rec = mMemRecords;
    714         s_fill_mem_rec_ip.u4_num_mem_rec = mNumMemRecords;
    715         s_fill_mem_rec_ip.u4_max_wd = mWidth;
    716         s_fill_mem_rec_ip.u4_max_ht = mHeight;
    717         s_fill_mem_rec_ip.u4_max_level = mAVCEncLevel;
    718         s_fill_mem_rec_ip.e_color_format = DEFAULT_INP_COLOR_FORMAT;
    719         s_fill_mem_rec_ip.u4_max_ref_cnt = DEFAULT_MAX_REF_FRM;
    720         s_fill_mem_rec_ip.u4_max_reorder_cnt = DEFAULT_MAX_REORDER_FRM;
    721         s_fill_mem_rec_ip.u4_max_srch_rng_x = DEFAULT_MAX_SRCH_RANGE_X;
    722         s_fill_mem_rec_ip.u4_max_srch_rng_y = DEFAULT_MAX_SRCH_RANGE_Y;
    723 
    724         status = ive_api_function(0, &s_fill_mem_rec_ip, &s_fill_mem_rec_op);
    725 
    726         if (status != IV_SUCCESS) {
    727             ALOGE("Fill memory records failed = 0x%x\n",
    728                     s_fill_mem_rec_op.u4_error_code);
    729             mSignalledError = true;
    730             notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
    731             return OMX_ErrorUndefined;
    732         }
    733     }
    734 
    735     /* Allocating Memory for Mem Records */
    736     {
    737         WORD32 total_size;
    738         iv_mem_rec_t *ps_mem_rec;
    739         total_size = 0;
    740         ps_mem_rec = mMemRecords;
    741 
    742         for (size_t i = 0; i < mNumMemRecords; i++) {
    743             ps_mem_rec->pv_base = ive_aligned_malloc(
    744                     ps_mem_rec->u4_mem_alignment, ps_mem_rec->u4_mem_size);
    745             if (ps_mem_rec->pv_base == NULL) {
    746                 ALOGE("Allocation failure for mem record id %zu size %u\n", i,
    747                         ps_mem_rec->u4_mem_size);
    748                 mSignalledError = true;
    749                 notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
    750                 return OMX_ErrorUndefined;
    751 
    752             }
    753             total_size += ps_mem_rec->u4_mem_size;
    754 
    755             ps_mem_rec++;
    756         }
    757     }
    758 
    759     /* Codec Instance Creation */
    760     {
    761         ive_init_ip_t s_init_ip;
    762         ive_init_op_t s_init_op;
    763 
    764         mCodecCtx = (iv_obj_t *)mMemRecords[0].pv_base;
    765         mCodecCtx->u4_size = sizeof(iv_obj_t);
    766         mCodecCtx->pv_fxns = (void *)ive_api_function;
    767 
    768         s_init_ip.u4_size = sizeof(ive_init_ip_t);
    769         s_init_op.u4_size = sizeof(ive_init_op_t);
    770 
    771         s_init_ip.e_cmd = IV_CMD_INIT;
    772         s_init_ip.u4_num_mem_rec = mNumMemRecords;
    773         s_init_ip.ps_mem_rec = mMemRecords;
    774         s_init_ip.u4_max_wd = mWidth;
    775         s_init_ip.u4_max_ht = mHeight;
    776         s_init_ip.u4_max_ref_cnt = DEFAULT_MAX_REF_FRM;
    777         s_init_ip.u4_max_reorder_cnt = DEFAULT_MAX_REORDER_FRM;
    778         s_init_ip.u4_max_level = mAVCEncLevel;
    779         s_init_ip.e_inp_color_fmt = mIvVideoColorFormat;
    780 
    781         if (mReconEnable || mPSNREnable) {
    782             s_init_ip.u4_enable_recon = 1;
    783         } else {
    784             s_init_ip.u4_enable_recon = 0;
    785         }
    786         s_init_ip.e_recon_color_fmt = DEFAULT_RECON_COLOR_FORMAT;
    787         s_init_ip.e_rc_mode = DEFAULT_RC_MODE;
    788         s_init_ip.u4_max_framerate = DEFAULT_MAX_FRAMERATE;
    789         s_init_ip.u4_max_bitrate = DEFAULT_MAX_BITRATE;
    790         s_init_ip.u4_num_bframes = mBframes;
    791         s_init_ip.e_content_type = IV_PROGRESSIVE;
    792         s_init_ip.u4_max_srch_rng_x = DEFAULT_MAX_SRCH_RANGE_X;
    793         s_init_ip.u4_max_srch_rng_y = DEFAULT_MAX_SRCH_RANGE_Y;
    794         s_init_ip.e_slice_mode = mSliceMode;
    795         s_init_ip.u4_slice_param = mSliceParam;
    796         s_init_ip.e_arch = mArch;
    797         s_init_ip.e_soc = DEFAULT_SOC;
    798 
    799         status = ive_api_function(mCodecCtx, &s_init_ip, &s_init_op);
    800 
    801         if (status != IV_SUCCESS) {
    802             ALOGE("Init memory records failed = 0x%x\n",
    803                     s_init_op.u4_error_code);
    804             mSignalledError = true;
    805             notify(OMX_EventError, OMX_ErrorUndefined, 0 /* arg2 */, NULL /* data */);
    806             return OMX_ErrorUndefined;
    807         }
    808     }
    809 
    810     /* Get Codec Version */
    811     logVersion();
    812 
    813     /* set processor details */
    814     setNumCores();
    815 
    816     /* Video control Set Frame dimensions */
    817     setDimensions();
    818 
    819     /* Video control Set Frame rates */
    820     setFrameRate();
    821 
    822     /* Video control Set IPE Params */
    823     setIpeParams();
    824 
    825     /* Video control Set Bitrate */
    826     setBitRate();
    827 
    828     /* Video control Set QP */
    829     setQp();
    830 
    831     /* Video control Set AIR params */
    832     setAirParams();
    833 
    834     /* Video control Set VBV params */
    835     setVbvParams();
    836 
    837     /* Video control Set Motion estimation params */
    838     setMeParams();
    839 
    840     /* Video control Set GOP params */
    841     setGopParams();
    842 
    843     /* Video control Set Deblock params */
    844     setDeblockParams();
    845 
    846     /* Video control Set Profile params */
    847     setProfileParams();
    848 
    849     /* Video control Set in Encode header mode */
    850     setEncMode(IVE_ENC_MODE_HEADER);
    851 
    852     ALOGV("init_codec successfull");
    853 
    854     mSpsPpsHeaderReceived = false;
    855     mStarted = true;
    856 
    857     return OMX_ErrorNone;
    858 }
    859 
    860 OMX_ERRORTYPE SoftAVC::releaseEncoder() {
    861     IV_STATUS_T status = IV_SUCCESS;
    862     iv_retrieve_mem_rec_ip_t s_retrieve_mem_ip;
    863     iv_retrieve_mem_rec_op_t s_retrieve_mem_op;
    864     iv_mem_rec_t *ps_mem_rec;
    865 
    866     if (!mStarted) {
    867         return OMX_ErrorNone;
    868     }
    869 
    870     s_retrieve_mem_ip.u4_size = sizeof(iv_retrieve_mem_rec_ip_t);
    871     s_retrieve_mem_op.u4_size = sizeof(iv_retrieve_mem_rec_op_t);
    872     s_retrieve_mem_ip.e_cmd = IV_CMD_RETRIEVE_MEMREC;
    873     s_retrieve_mem_ip.ps_mem_rec = mMemRecords;
    874 
    875     status = ive_api_function(mCodecCtx, &s_retrieve_mem_ip, &s_retrieve_mem_op);
    876 
    877     if (status != IV_SUCCESS) {
    878         ALOGE("Unable to retrieve memory records = 0x%x\n",
    879                 s_retrieve_mem_op.u4_error_code);
    880         return OMX_ErrorUndefined;
    881     }
    882 
    883     /* Free memory records */
    884     ps_mem_rec = mMemRecords;
    885     for (size_t i = 0; i < s_retrieve_mem_op.u4_num_mem_rec_filled; i++) {
    886         ive_aligned_free(ps_mem_rec->pv_base);
    887         ps_mem_rec++;
    888     }
    889 
    890     free(mMemRecords);
    891 
    892     for (size_t i = 0; i < MAX_CONVERSION_BUFFERS; i++) {
    893         if (mConversionBuffers[i]) {
    894             free(mConversionBuffers[i]);
    895             mConversionBuffers[i] = NULL;
    896         }
    897     }
    898 
    899     // clear other pointers into the space being free()d
    900     mCodecCtx = NULL;
    901 
    902     mStarted = false;
    903 
    904     return OMX_ErrorNone;
    905 }
    906 
    907 OMX_ERRORTYPE SoftAVC::internalGetParameter(OMX_INDEXTYPE index, OMX_PTR params) {
    908     switch (index) {
    909         case OMX_IndexParamVideoBitrate:
    910         {
    911             OMX_VIDEO_PARAM_BITRATETYPE *bitRate =
    912                 (OMX_VIDEO_PARAM_BITRATETYPE *)params;
    913 
    914             if (!isValidOMXParam(bitRate)) {
    915                 return OMX_ErrorBadParameter;
    916             }
    917 
    918             if (bitRate->nPortIndex != 1) {
    919                 return OMX_ErrorUndefined;
    920             }
    921 
    922             bitRate->eControlRate = OMX_Video_ControlRateVariable;
    923             bitRate->nTargetBitrate = mBitrate;
    924             return OMX_ErrorNone;
    925         }
    926 
    927         case OMX_IndexParamVideoAvc:
    928         {
    929             OMX_VIDEO_PARAM_AVCTYPE *avcParams = (OMX_VIDEO_PARAM_AVCTYPE *)params;
    930 
    931             if (!isValidOMXParam(avcParams)) {
    932                 return OMX_ErrorBadParameter;
    933             }
    934 
    935             if (avcParams->nPortIndex != 1) {
    936                 return OMX_ErrorUndefined;
    937             }
    938 
    939             OMX_VIDEO_AVCLEVELTYPE omxLevel = OMX_VIDEO_AVCLevel41;
    940             if (OMX_ErrorNone
    941                     != ConvertAvcSpecLevelToOmxAvcLevel(mAVCEncLevel, &omxLevel)) {
    942                 return OMX_ErrorUndefined;
    943             }
    944 
    945             // TODO: maintain profile
    946             avcParams->eProfile = (OMX_VIDEO_AVCPROFILETYPE)OMX_VIDEO_AVCProfileConstrainedBaseline;
    947             avcParams->eLevel = omxLevel;
    948             avcParams->nRefFrames = 1;
    949             avcParams->bUseHadamard = OMX_TRUE;
    950             avcParams->nAllowedPictureTypes = (OMX_VIDEO_PictureTypeI
    951                     | OMX_VIDEO_PictureTypeP | OMX_VIDEO_PictureTypeB);
    952             avcParams->nRefIdx10ActiveMinus1 = 0;
    953             avcParams->nRefIdx11ActiveMinus1 = 0;
    954             avcParams->bWeightedPPrediction = OMX_FALSE;
    955             avcParams->bconstIpred = OMX_FALSE;
    956             avcParams->bDirect8x8Inference = OMX_FALSE;
    957             avcParams->bDirectSpatialTemporal = OMX_FALSE;
    958             avcParams->nCabacInitIdc = 0;
    959             return OMX_ErrorNone;
    960         }
    961 
    962         default:
    963             return SoftVideoEncoderOMXComponent::internalGetParameter(index, params);
    964     }
    965 }
    966 
    967 OMX_ERRORTYPE SoftAVC::internalSetParameter(OMX_INDEXTYPE index, const OMX_PTR params) {
    968     int32_t indexFull = index;
    969 
    970     switch (indexFull) {
    971         case OMX_IndexParamVideoBitrate:
    972         {
    973             OMX_VIDEO_PARAM_BITRATETYPE *bitRate =
    974                 (OMX_VIDEO_PARAM_BITRATETYPE *)params;
    975 
    976             if (!isValidOMXParam(bitRate)) {
    977                 return OMX_ErrorBadParameter;
    978             }
    979 
    980             return internalSetBitrateParams(bitRate);
    981         }
    982 
    983         case OMX_IndexParamVideoAvc:
    984         {
    985             OMX_VIDEO_PARAM_AVCTYPE *avcType = (OMX_VIDEO_PARAM_AVCTYPE *)params;
    986 
    987             if (!isValidOMXParam(avcType)) {
    988                 return OMX_ErrorBadParameter;
    989             }
    990 
    991             if (avcType->nPortIndex != 1) {
    992                 return OMX_ErrorUndefined;
    993             }
    994 
    995             mEntropyMode = 0;
    996 
    997             if (OMX_TRUE == avcType->bEntropyCodingCABAC)
    998                 mEntropyMode = 1;
    999 
   1000             if ((avcType->nAllowedPictureTypes & OMX_VIDEO_PictureTypeB) &&
   1001                     avcType->nPFrames) {
   1002                 mBframes = avcType->nBFrames;
   1003             }
   1004 
   1005             mIInterval = (avcType->nPFrames + 1) * (avcType->nBFrames + 1);
   1006             mConstrainedIntraFlag = avcType->bconstIpred;
   1007 
   1008             if (OMX_VIDEO_AVCLoopFilterDisable == avcType->eLoopFilterMode)
   1009                 mDisableDeblkLevel = 4;
   1010 
   1011             if (avcType->nRefFrames != 1
   1012                     || avcType->bUseHadamard != OMX_TRUE
   1013                     || avcType->nRefIdx10ActiveMinus1 != 0
   1014                     || avcType->nRefIdx11ActiveMinus1 != 0
   1015                     || avcType->bWeightedPPrediction != OMX_FALSE
   1016                     || avcType->bDirect8x8Inference != OMX_FALSE
   1017                     || avcType->bDirectSpatialTemporal != OMX_FALSE
   1018                     || avcType->nCabacInitIdc != 0) {
   1019                 // OMX does not allow a way to signal what values are wrong, so it's
   1020                 // best for components to just do best effort in supporting these values
   1021                 ALOGV("ignoring unsupported settings");
   1022             }
   1023 
   1024             if (OK != ConvertOmxAvcLevelToAvcSpecLevel(avcType->eLevel, &mAVCEncLevel)) {
   1025                 return OMX_ErrorUndefined;
   1026             }
   1027 
   1028             return OMX_ErrorNone;
   1029         }
   1030 
   1031         default:
   1032             return SoftVideoEncoderOMXComponent::internalSetParameter(index, params);
   1033     }
   1034 }
   1035 
   1036 OMX_ERRORTYPE SoftAVC::getConfig(
   1037         OMX_INDEXTYPE index, OMX_PTR _params) {
   1038     switch ((int)index) {
   1039         case OMX_IndexConfigAndroidIntraRefresh:
   1040         {
   1041             OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *intraRefreshParams =
   1042                 (OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *)_params;
   1043 
   1044             if (!isValidOMXParam(intraRefreshParams)) {
   1045                 return OMX_ErrorBadParameter;
   1046             }
   1047 
   1048             if (intraRefreshParams->nPortIndex != kOutputPortIndex) {
   1049                 return OMX_ErrorUndefined;
   1050             }
   1051 
   1052             intraRefreshParams->nRefreshPeriod =
   1053                     (mAIRMode == IVE_AIR_MODE_NONE) ? 0 : mAIRRefreshPeriod;
   1054             return OMX_ErrorNone;
   1055         }
   1056 
   1057         default:
   1058             return SoftVideoEncoderOMXComponent::getConfig(index, _params);
   1059     }
   1060 }
   1061 
   1062 OMX_ERRORTYPE SoftAVC::setConfig(
   1063         OMX_INDEXTYPE index, const OMX_PTR _params) {
   1064     switch ((int)index) {
   1065         case OMX_IndexConfigVideoIntraVOPRefresh:
   1066         {
   1067             OMX_CONFIG_INTRAREFRESHVOPTYPE *params =
   1068                 (OMX_CONFIG_INTRAREFRESHVOPTYPE *)_params;
   1069 
   1070             if (!isValidOMXParam(params)) {
   1071                 return OMX_ErrorBadParameter;
   1072             }
   1073 
   1074             if (params->nPortIndex != kOutputPortIndex) {
   1075                 return OMX_ErrorBadPortIndex;
   1076             }
   1077 
   1078             if (params->IntraRefreshVOP) {
   1079                 mUpdateFlag |= kRequestKeyFrame;
   1080             }
   1081             return OMX_ErrorNone;
   1082         }
   1083 
   1084         case OMX_IndexConfigVideoBitrate:
   1085         {
   1086             OMX_VIDEO_CONFIG_BITRATETYPE *params =
   1087                 (OMX_VIDEO_CONFIG_BITRATETYPE *)_params;
   1088 
   1089             if (!isValidOMXParam(params)) {
   1090                 return OMX_ErrorBadParameter;
   1091             }
   1092 
   1093             if (params->nPortIndex != kOutputPortIndex) {
   1094                 return OMX_ErrorBadPortIndex;
   1095             }
   1096 
   1097             if (mBitrate != params->nEncodeBitrate) {
   1098                 mBitrate = params->nEncodeBitrate;
   1099                 mUpdateFlag |= kUpdateBitrate;
   1100             }
   1101             return OMX_ErrorNone;
   1102         }
   1103 
   1104         case OMX_IndexConfigAndroidIntraRefresh:
   1105         {
   1106             const OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *intraRefreshParams =
   1107                 (const OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *)_params;
   1108 
   1109             if (!isValidOMXParam(intraRefreshParams)) {
   1110                 return OMX_ErrorBadParameter;
   1111             }
   1112 
   1113             if (intraRefreshParams->nPortIndex != kOutputPortIndex) {
   1114                 return OMX_ErrorUndefined;
   1115             }
   1116 
   1117             if (intraRefreshParams->nRefreshPeriod == 0) {
   1118                 mAIRMode = IVE_AIR_MODE_NONE;
   1119                 mAIRRefreshPeriod = 0;
   1120             } else if (intraRefreshParams->nRefreshPeriod > 0) {
   1121                 mAIRMode = IVE_AIR_MODE_CYCLIC;
   1122                 mAIRRefreshPeriod = intraRefreshParams->nRefreshPeriod;
   1123             }
   1124             mUpdateFlag |= kUpdateAIRMode;
   1125             return OMX_ErrorNone;
   1126         }
   1127 
   1128         default:
   1129             return SimpleSoftOMXComponent::setConfig(index, _params);
   1130     }
   1131 }
   1132 
   1133 OMX_ERRORTYPE SoftAVC::internalSetBitrateParams(
   1134         const OMX_VIDEO_PARAM_BITRATETYPE *bitrate) {
   1135     if (bitrate->nPortIndex != kOutputPortIndex) {
   1136         return OMX_ErrorUnsupportedIndex;
   1137     }
   1138 
   1139     mBitrate = bitrate->nTargetBitrate;
   1140     mUpdateFlag |= kUpdateBitrate;
   1141 
   1142     return OMX_ErrorNone;
   1143 }
   1144 
   1145 OMX_ERRORTYPE SoftAVC::setEncodeArgs(
   1146         ive_video_encode_ip_t *ps_encode_ip,
   1147         ive_video_encode_op_t *ps_encode_op,
   1148         OMX_BUFFERHEADERTYPE *inputBufferHeader,
   1149         OMX_BUFFERHEADERTYPE *outputBufferHeader) {
   1150     iv_raw_buf_t *ps_inp_raw_buf;
   1151     const uint8_t *source;
   1152     UWORD8 *pu1_buf;
   1153 
   1154     ps_inp_raw_buf = &ps_encode_ip->s_inp_buf;
   1155     ps_encode_ip->s_out_buf.pv_buf = outputBufferHeader->pBuffer;
   1156     ps_encode_ip->s_out_buf.u4_bytes = 0;
   1157     ps_encode_ip->s_out_buf.u4_bufsize = outputBufferHeader->nAllocLen;
   1158     ps_encode_ip->u4_size = sizeof(ive_video_encode_ip_t);
   1159     ps_encode_op->u4_size = sizeof(ive_video_encode_op_t);
   1160 
   1161     ps_encode_ip->e_cmd = IVE_CMD_VIDEO_ENCODE;
   1162     ps_encode_ip->pv_bufs = NULL;
   1163     ps_encode_ip->pv_mb_info = NULL;
   1164     ps_encode_ip->pv_pic_info = NULL;
   1165     ps_encode_ip->u4_mb_info_type = 0;
   1166     ps_encode_ip->u4_pic_info_type = 0;
   1167     ps_encode_op->s_out_buf.pv_buf = NULL;
   1168 
   1169     /* Initialize color formats */
   1170     ps_inp_raw_buf->e_color_fmt = mIvVideoColorFormat;
   1171     source = NULL;
   1172     if ((inputBufferHeader != NULL) && inputBufferHeader->nFilledLen) {
   1173         source = inputBufferHeader->pBuffer + inputBufferHeader->nOffset;
   1174 
   1175         if (mInputDataIsMeta) {
   1176             uint8_t *conversionBuffer = NULL;
   1177             for (size_t i = 0; i < MAX_CONVERSION_BUFFERS; i++) {
   1178                 if (mConversionBuffersFree[i]) {
   1179                     mConversionBuffersFree[i] = 0;
   1180                     conversionBuffer = mConversionBuffers[i];
   1181                     break;
   1182                 }
   1183             }
   1184 
   1185             if (NULL == conversionBuffer) {
   1186                 ALOGE("No free buffers to hold conversion data");
   1187                 return OMX_ErrorUndefined;
   1188             }
   1189 
   1190             source = extractGraphicBuffer(
   1191                     conversionBuffer, (mWidth * mHeight * 3 / 2), source,
   1192                     inputBufferHeader->nFilledLen, mWidth, mHeight);
   1193 
   1194             if (source == NULL) {
   1195                 ALOGE("Error in extractGraphicBuffer");
   1196                 notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
   1197                 return OMX_ErrorUndefined;
   1198             }
   1199         }
   1200         ps_encode_ip->u4_is_last = 0;
   1201         ps_encode_ip->u4_timestamp_high = (inputBufferHeader->nTimeStamp) >> 32;
   1202         ps_encode_ip->u4_timestamp_low = (inputBufferHeader->nTimeStamp) & 0xFFFFFFFF;
   1203     }
   1204     else {
   1205         if (mSawInputEOS){
   1206             ps_encode_ip->u4_is_last = 1;
   1207         }
   1208         memset(ps_inp_raw_buf, 0, sizeof(iv_raw_buf_t));
   1209         ps_inp_raw_buf->e_color_fmt = mIvVideoColorFormat;
   1210         ps_inp_raw_buf->u4_size = sizeof(iv_raw_buf_t);
   1211         return OMX_ErrorNone;
   1212     }
   1213 
   1214     pu1_buf = (UWORD8 *)source;
   1215     switch (mIvVideoColorFormat) {
   1216         case IV_YUV_420P:
   1217         {
   1218             ps_inp_raw_buf->apv_bufs[0] = pu1_buf;
   1219             pu1_buf += (mStride) * mHeight;
   1220             ps_inp_raw_buf->apv_bufs[1] = pu1_buf;
   1221             pu1_buf += (mStride / 2) * mHeight / 2;
   1222             ps_inp_raw_buf->apv_bufs[2] = pu1_buf;
   1223 
   1224             ps_inp_raw_buf->au4_wd[0] = mWidth;
   1225             ps_inp_raw_buf->au4_wd[1] = mWidth / 2;
   1226             ps_inp_raw_buf->au4_wd[2] = mWidth / 2;
   1227 
   1228             ps_inp_raw_buf->au4_ht[0] = mHeight;
   1229             ps_inp_raw_buf->au4_ht[1] = mHeight / 2;
   1230             ps_inp_raw_buf->au4_ht[2] = mHeight / 2;
   1231 
   1232             ps_inp_raw_buf->au4_strd[0] = mStride;
   1233             ps_inp_raw_buf->au4_strd[1] = (mStride / 2);
   1234             ps_inp_raw_buf->au4_strd[2] = (mStride / 2);
   1235             break;
   1236         }
   1237 
   1238         case IV_YUV_422ILE:
   1239         {
   1240             ps_inp_raw_buf->apv_bufs[0] = pu1_buf;
   1241             ps_inp_raw_buf->au4_wd[0] = mWidth * 2;
   1242             ps_inp_raw_buf->au4_ht[0] = mHeight;
   1243             ps_inp_raw_buf->au4_strd[0] = mStride * 2;
   1244             break;
   1245         }
   1246 
   1247         case IV_YUV_420SP_UV:
   1248         case IV_YUV_420SP_VU:
   1249         default:
   1250         {
   1251             ps_inp_raw_buf->apv_bufs[0] = pu1_buf;
   1252             pu1_buf += (mStride) * mHeight;
   1253             ps_inp_raw_buf->apv_bufs[1] = pu1_buf;
   1254 
   1255             ps_inp_raw_buf->au4_wd[0] = mWidth;
   1256             ps_inp_raw_buf->au4_wd[1] = mWidth;
   1257 
   1258             ps_inp_raw_buf->au4_ht[0] = mHeight;
   1259             ps_inp_raw_buf->au4_ht[1] = mHeight / 2;
   1260 
   1261             ps_inp_raw_buf->au4_strd[0] = mStride;
   1262             ps_inp_raw_buf->au4_strd[1] = mStride;
   1263             break;
   1264         }
   1265     }
   1266     return OMX_ErrorNone;
   1267 }
   1268 
   1269 void SoftAVC::onQueueFilled(OMX_U32 portIndex) {
   1270     IV_STATUS_T status;
   1271     WORD32 timeDelay, timeTaken;
   1272 
   1273     UNUSED(portIndex);
   1274 
   1275     // Initialize encoder if not already initialized
   1276     if (mCodecCtx == NULL) {
   1277         if (OMX_ErrorNone != initEncoder()) {
   1278             ALOGE("Failed to initialize encoder");
   1279             notify(OMX_EventError, OMX_ErrorUndefined, 0 /* arg2 */, NULL /* data */);
   1280             return;
   1281         }
   1282     }
   1283     if (mSignalledError) {
   1284         return;
   1285     }
   1286 
   1287     List<BufferInfo *> &inQueue = getPortQueue(0);
   1288     List<BufferInfo *> &outQueue = getPortQueue(1);
   1289 
   1290     while (!mSawOutputEOS && !outQueue.empty()) {
   1291 
   1292         OMX_ERRORTYPE error;
   1293         ive_video_encode_ip_t s_encode_ip;
   1294         ive_video_encode_op_t s_encode_op;
   1295         BufferInfo *outputBufferInfo = *outQueue.begin();
   1296         OMX_BUFFERHEADERTYPE *outputBufferHeader = outputBufferInfo->mHeader;
   1297 
   1298         BufferInfo *inputBufferInfo;
   1299         OMX_BUFFERHEADERTYPE *inputBufferHeader;
   1300 
   1301         if (mSawInputEOS) {
   1302             inputBufferHeader = NULL;
   1303             inputBufferInfo = NULL;
   1304         } else if (!inQueue.empty()) {
   1305             inputBufferInfo = *inQueue.begin();
   1306             inputBufferHeader = inputBufferInfo->mHeader;
   1307         } else {
   1308             return;
   1309         }
   1310 
   1311         outputBufferHeader->nTimeStamp = 0;
   1312         outputBufferHeader->nFlags = 0;
   1313         outputBufferHeader->nOffset = 0;
   1314         outputBufferHeader->nFilledLen = 0;
   1315         outputBufferHeader->nOffset = 0;
   1316 
   1317         if (inputBufferHeader != NULL) {
   1318             outputBufferHeader->nFlags = inputBufferHeader->nFlags;
   1319         }
   1320 
   1321         uint8_t *outPtr = (uint8_t *)outputBufferHeader->pBuffer;
   1322 
   1323         if (!mSpsPpsHeaderReceived) {
   1324             error = setEncodeArgs(&s_encode_ip, &s_encode_op, NULL, outputBufferHeader);
   1325             if (error != OMX_ErrorNone) {
   1326                 mSignalledError = true;
   1327                 notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
   1328                 return;
   1329             }
   1330             status = ive_api_function(mCodecCtx, &s_encode_ip, &s_encode_op);
   1331 
   1332             if (IV_SUCCESS != status) {
   1333                 ALOGE("Encode Frame failed = 0x%x\n",
   1334                         s_encode_op.u4_error_code);
   1335             } else {
   1336                 ALOGV("Bytes Generated in header %d\n",
   1337                         s_encode_op.s_out_buf.u4_bytes);
   1338             }
   1339 
   1340             mSpsPpsHeaderReceived = true;
   1341 
   1342             outputBufferHeader->nFlags = OMX_BUFFERFLAG_CODECCONFIG;
   1343             outputBufferHeader->nFilledLen = s_encode_op.s_out_buf.u4_bytes;
   1344             if (inputBufferHeader != NULL) {
   1345                 outputBufferHeader->nTimeStamp = inputBufferHeader->nTimeStamp;
   1346             }
   1347 
   1348             outQueue.erase(outQueue.begin());
   1349             outputBufferInfo->mOwnedByUs = false;
   1350 
   1351             DUMP_TO_FILE(
   1352                     mOutFile, outputBufferHeader->pBuffer,
   1353                     outputBufferHeader->nFilledLen);
   1354             notifyFillBufferDone(outputBufferHeader);
   1355 
   1356             setEncMode(IVE_ENC_MODE_PICTURE);
   1357             return;
   1358         }
   1359 
   1360         if (mUpdateFlag) {
   1361             if (mUpdateFlag & kUpdateBitrate) {
   1362                 setBitRate();
   1363             }
   1364             if (mUpdateFlag & kRequestKeyFrame) {
   1365                 setFrameType(IV_IDR_FRAME);
   1366             }
   1367             if (mUpdateFlag & kUpdateAIRMode) {
   1368                 setAirParams();
   1369                 notify(OMX_EventPortSettingsChanged, kOutputPortIndex,
   1370                         OMX_IndexConfigAndroidIntraRefresh, NULL);
   1371             }
   1372             mUpdateFlag = 0;
   1373         }
   1374 
   1375         if ((inputBufferHeader != NULL)
   1376                 && (inputBufferHeader->nFlags & OMX_BUFFERFLAG_EOS)) {
   1377             mSawInputEOS = true;
   1378         }
   1379 
   1380         /* In normal mode, store inputBufferInfo and this will be returned
   1381            when encoder consumes this input */
   1382         if (!mInputDataIsMeta && (inputBufferInfo != NULL)) {
   1383             for (size_t i = 0; i < MAX_INPUT_BUFFER_HEADERS; i++) {
   1384                 if (NULL == mInputBufferInfo[i]) {
   1385                     mInputBufferInfo[i] = inputBufferInfo;
   1386                     break;
   1387                 }
   1388             }
   1389         }
   1390         error = setEncodeArgs(
   1391                 &s_encode_ip, &s_encode_op, inputBufferHeader, outputBufferHeader);
   1392 
   1393         if (error != OMX_ErrorNone) {
   1394             mSignalledError = true;
   1395             notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
   1396             return;
   1397         }
   1398 
   1399         DUMP_TO_FILE(
   1400                 mInFile, s_encode_ip.s_inp_buf.apv_bufs[0],
   1401                 (mHeight * mStride * 3 / 2));
   1402 
   1403         GETTIME(&mTimeStart, NULL);
   1404         /* Compute time elapsed between end of previous decode()
   1405          * to start of current decode() */
   1406         TIME_DIFF(mTimeEnd, mTimeStart, timeDelay);
   1407         status = ive_api_function(mCodecCtx, &s_encode_ip, &s_encode_op);
   1408 
   1409         if (IV_SUCCESS != status) {
   1410             ALOGE("Encode Frame failed = 0x%x\n",
   1411                     s_encode_op.u4_error_code);
   1412             mSignalledError = true;
   1413             notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
   1414             return;
   1415         }
   1416 
   1417         GETTIME(&mTimeEnd, NULL);
   1418         /* Compute time taken for decode() */
   1419         TIME_DIFF(mTimeStart, mTimeEnd, timeTaken);
   1420 
   1421         ALOGV("timeTaken=%6d delay=%6d numBytes=%6d", timeTaken, timeDelay,
   1422                 s_encode_op.s_out_buf.u4_bytes);
   1423 
   1424         /* In encoder frees up an input buffer, mark it as free */
   1425         if (s_encode_op.s_inp_buf.apv_bufs[0] != NULL) {
   1426             if (mInputDataIsMeta) {
   1427                 for (size_t i = 0; i < MAX_CONVERSION_BUFFERS; i++) {
   1428                     if (mConversionBuffers[i] == s_encode_op.s_inp_buf.apv_bufs[0]) {
   1429                         mConversionBuffersFree[i] = 1;
   1430                         break;
   1431                     }
   1432                 }
   1433             } else {
   1434                 /* In normal mode, call EBD on inBuffeHeader that is freed by the codec */
   1435                 for (size_t i = 0; i < MAX_INPUT_BUFFER_HEADERS; i++) {
   1436                     uint8_t *buf = NULL;
   1437                     OMX_BUFFERHEADERTYPE *bufHdr = NULL;
   1438                     if (mInputBufferInfo[i] != NULL) {
   1439                         bufHdr = mInputBufferInfo[i]->mHeader;
   1440                         buf = bufHdr->pBuffer + bufHdr->nOffset;
   1441                     }
   1442                     if (s_encode_op.s_inp_buf.apv_bufs[0] == buf) {
   1443                         mInputBufferInfo[i]->mOwnedByUs = false;
   1444                         notifyEmptyBufferDone(bufHdr);
   1445                         mInputBufferInfo[i] = NULL;
   1446                         break;
   1447                     }
   1448                 }
   1449             }
   1450         }
   1451 
   1452         outputBufferHeader->nFilledLen = s_encode_op.s_out_buf.u4_bytes;
   1453 
   1454         if (IV_IDR_FRAME == s_encode_op.u4_encoded_frame_type) {
   1455             outputBufferHeader->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
   1456         }
   1457 
   1458         if (inputBufferHeader != NULL) {
   1459             inQueue.erase(inQueue.begin());
   1460 
   1461             /* If in meta data, call EBD on input */
   1462             /* In case of normal mode, EBD will be done once encoder
   1463             releases the input buffer */
   1464             if (mInputDataIsMeta) {
   1465                 inputBufferInfo->mOwnedByUs = false;
   1466                 notifyEmptyBufferDone(inputBufferHeader);
   1467             }
   1468         }
   1469 
   1470         if (s_encode_op.u4_is_last) {
   1471             outputBufferHeader->nFlags |= OMX_BUFFERFLAG_EOS;
   1472             mSawOutputEOS = true;
   1473         } else {
   1474             outputBufferHeader->nFlags &= ~OMX_BUFFERFLAG_EOS;
   1475         }
   1476 
   1477         if (outputBufferHeader->nFilledLen || s_encode_op.u4_is_last) {
   1478             outputBufferHeader->nTimeStamp = s_encode_op.u4_timestamp_high;
   1479             outputBufferHeader->nTimeStamp <<= 32;
   1480             outputBufferHeader->nTimeStamp |= s_encode_op.u4_timestamp_low;
   1481             outputBufferInfo->mOwnedByUs = false;
   1482             outQueue.erase(outQueue.begin());
   1483             DUMP_TO_FILE(mOutFile, outputBufferHeader->pBuffer,
   1484                     outputBufferHeader->nFilledLen);
   1485             notifyFillBufferDone(outputBufferHeader);
   1486         }
   1487 
   1488         if (s_encode_op.u4_is_last == 1) {
   1489             return;
   1490         }
   1491     }
   1492     return;
   1493 }
   1494 
   1495 void SoftAVC::onReset() {
   1496     SoftVideoEncoderOMXComponent::onReset();
   1497 
   1498     if (releaseEncoder() != OMX_ErrorNone) {
   1499         ALOGW("releaseEncoder failed");
   1500     }
   1501 }
   1502 
   1503 }  // namespace android
   1504 
   1505 android::SoftOMXComponent *createSoftOMXComponent(
   1506         const char *name, const OMX_CALLBACKTYPE *callbacks,
   1507         OMX_PTR appData, OMX_COMPONENTTYPE **component) {
   1508     return new android::SoftAVC(name, callbacks, appData, component);
   1509 }
   1510