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