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