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