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