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