SoftAVCEnc.cpp revision c884adf00fce70170003d6f18ad65c8912535ac8
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 } 641 642 mConversionBuffers[i] = (uint8_t *)malloc(mStride * mHeight * 3 / 2); 643 644 if (mConversionBuffers[i] == NULL) { 645 ALOGE("Allocating conversion buffer failed."); 646 return OMX_ErrorUndefined; 647 } 648 649 mConversionBuffersFree[i] = 1; 650 } 651 } 652 653 switch (mColorFormat) { 654 case OMX_COLOR_FormatYUV420SemiPlanar: 655 mIvVideoColorFormat = IV_YUV_420SP_UV; 656 ALOGV("colorFormat YUV_420SP"); 657 break; 658 default: 659 case OMX_COLOR_FormatYUV420Planar: 660 mIvVideoColorFormat = IV_YUV_420P; 661 ALOGV("colorFormat YUV_420P"); 662 break; 663 } 664 665 ALOGD("Params width %d height %d level %d colorFormat %d", mWidth, 666 mHeight, mAVCEncLevel, mIvVideoColorFormat); 667 668 /* Getting Number of MemRecords */ 669 { 670 iv_num_mem_rec_ip_t s_num_mem_rec_ip; 671 iv_num_mem_rec_op_t s_num_mem_rec_op; 672 673 s_num_mem_rec_ip.u4_size = sizeof(iv_num_mem_rec_ip_t); 674 s_num_mem_rec_op.u4_size = sizeof(iv_num_mem_rec_op_t); 675 676 s_num_mem_rec_ip.e_cmd = IV_CMD_GET_NUM_MEM_REC; 677 678 status = ive_api_function(0, &s_num_mem_rec_ip, &s_num_mem_rec_op); 679 680 if (status != IV_SUCCESS) { 681 ALOGE("Get number of memory records failed = 0x%x\n", 682 s_num_mem_rec_op.u4_error_code); 683 return OMX_ErrorUndefined; 684 } 685 686 mNumMemRecords = s_num_mem_rec_op.u4_num_mem_rec; 687 } 688 689 /* Allocate array to hold memory records */ 690 mMemRecords = (iv_mem_rec_t *)malloc(mNumMemRecords * sizeof(iv_mem_rec_t)); 691 if (NULL == mMemRecords) { 692 ALOGE("Unable to allocate memory for hold memory records: Size %d", 693 mNumMemRecords * sizeof(iv_mem_rec_t)); 694 mSignalledError = true; 695 notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 696 return OMX_ErrorUndefined; 697 } 698 699 { 700 iv_mem_rec_t *ps_mem_rec; 701 ps_mem_rec = mMemRecords; 702 for (size_t i = 0; i < mNumMemRecords; i++) { 703 ps_mem_rec->u4_size = sizeof(iv_mem_rec_t); 704 ps_mem_rec->pv_base = NULL; 705 ps_mem_rec->u4_mem_size = 0; 706 ps_mem_rec->u4_mem_alignment = 0; 707 ps_mem_rec->e_mem_type = IV_NA_MEM_TYPE; 708 709 ps_mem_rec++; 710 } 711 } 712 713 /* Getting MemRecords Attributes */ 714 { 715 iv_fill_mem_rec_ip_t s_fill_mem_rec_ip; 716 iv_fill_mem_rec_op_t s_fill_mem_rec_op; 717 718 s_fill_mem_rec_ip.u4_size = sizeof(iv_fill_mem_rec_ip_t); 719 s_fill_mem_rec_op.u4_size = sizeof(iv_fill_mem_rec_op_t); 720 721 s_fill_mem_rec_ip.e_cmd = IV_CMD_FILL_NUM_MEM_REC; 722 s_fill_mem_rec_ip.ps_mem_rec = mMemRecords; 723 s_fill_mem_rec_ip.u4_num_mem_rec = mNumMemRecords; 724 s_fill_mem_rec_ip.u4_max_wd = mWidth; 725 s_fill_mem_rec_ip.u4_max_ht = mHeight; 726 s_fill_mem_rec_ip.u4_max_level = mAVCEncLevel; 727 s_fill_mem_rec_ip.e_color_format = DEFAULT_INP_COLOR_FORMAT; 728 s_fill_mem_rec_ip.u4_max_ref_cnt = DEFAULT_MAX_REF_FRM; 729 s_fill_mem_rec_ip.u4_max_reorder_cnt = DEFAULT_MAX_REORDER_FRM; 730 s_fill_mem_rec_ip.u4_max_srch_rng_x = DEFAULT_MAX_SRCH_RANGE_X; 731 s_fill_mem_rec_ip.u4_max_srch_rng_y = DEFAULT_MAX_SRCH_RANGE_Y; 732 733 status = ive_api_function(0, &s_fill_mem_rec_ip, &s_fill_mem_rec_op); 734 735 if (status != IV_SUCCESS) { 736 ALOGE("Fill memory records failed = 0x%x\n", 737 s_fill_mem_rec_op.u4_error_code); 738 mSignalledError = true; 739 notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 740 return OMX_ErrorUndefined; 741 } 742 } 743 744 /* Allocating Memory for Mem Records */ 745 { 746 WORD32 total_size; 747 iv_mem_rec_t *ps_mem_rec; 748 total_size = 0; 749 ps_mem_rec = mMemRecords; 750 751 for (size_t i = 0; i < mNumMemRecords; i++) { 752 ps_mem_rec->pv_base = ive_aligned_malloc( 753 ps_mem_rec->u4_mem_alignment, ps_mem_rec->u4_mem_size); 754 if (ps_mem_rec->pv_base == NULL) { 755 ALOGE("Allocation failure for mem record id %d size %d\n", i, 756 ps_mem_rec->u4_mem_size); 757 mSignalledError = true; 758 notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 759 return OMX_ErrorUndefined; 760 761 } 762 total_size += ps_mem_rec->u4_mem_size; 763 764 ps_mem_rec++; 765 } 766 } 767 768 /* Codec Instance Creation */ 769 { 770 ive_init_ip_t s_init_ip; 771 ive_init_op_t s_init_op; 772 773 mCodecCtx = (iv_obj_t *)mMemRecords[0].pv_base; 774 mCodecCtx->u4_size = sizeof(iv_obj_t); 775 mCodecCtx->pv_fxns = (void *)ive_api_function; 776 777 s_init_ip.u4_size = sizeof(ive_init_ip_t); 778 s_init_op.u4_size = sizeof(ive_init_op_t); 779 780 s_init_ip.e_cmd = IV_CMD_INIT; 781 s_init_ip.u4_num_mem_rec = mNumMemRecords; 782 s_init_ip.ps_mem_rec = mMemRecords; 783 s_init_ip.u4_max_wd = mWidth; 784 s_init_ip.u4_max_ht = mHeight; 785 s_init_ip.u4_max_ref_cnt = DEFAULT_MAX_REF_FRM; 786 s_init_ip.u4_max_reorder_cnt = DEFAULT_MAX_REORDER_FRM; 787 s_init_ip.u4_max_level = mAVCEncLevel; 788 s_init_ip.e_inp_color_fmt = mIvVideoColorFormat; 789 790 if (mReconEnable || mPSNREnable) { 791 s_init_ip.u4_enable_recon = 1; 792 } else { 793 s_init_ip.u4_enable_recon = 0; 794 } 795 s_init_ip.e_recon_color_fmt = DEFAULT_RECON_COLOR_FORMAT; 796 s_init_ip.e_rc_mode = DEFAULT_RC_MODE; 797 s_init_ip.u4_max_framerate = DEFAULT_MAX_FRAMERATE; 798 s_init_ip.u4_max_bitrate = DEFAULT_MAX_BITRATE; 799 s_init_ip.u4_num_bframes = mBframes; 800 s_init_ip.e_content_type = IV_PROGRESSIVE; 801 s_init_ip.u4_max_srch_rng_x = DEFAULT_MAX_SRCH_RANGE_X; 802 s_init_ip.u4_max_srch_rng_y = DEFAULT_MAX_SRCH_RANGE_Y; 803 s_init_ip.e_slice_mode = mSliceMode; 804 s_init_ip.u4_slice_param = mSliceParam; 805 s_init_ip.e_arch = mArch; 806 s_init_ip.e_soc = DEFAULT_SOC; 807 808 status = ive_api_function(mCodecCtx, &s_init_ip, &s_init_op); 809 810 if (status != IV_SUCCESS) { 811 ALOGE("Init memory records failed = 0x%x\n", 812 s_init_op.u4_error_code); 813 mSignalledError = true; 814 notify(OMX_EventError, OMX_ErrorUndefined, 0 /* arg2 */, NULL /* data */); 815 return OMX_ErrorUndefined; 816 } 817 } 818 819 /* Get Codec Version */ 820 logVersion(); 821 822 /* set processor details */ 823 setNumCores(); 824 825 /* Video control Set Frame dimensions */ 826 setDimensions(); 827 828 /* Video control Set Frame rates */ 829 setFrameRate(); 830 831 /* Video control Set IPE Params */ 832 setIpeParams(); 833 834 /* Video control Set Bitrate */ 835 setBitRate(); 836 837 /* Video control Set QP */ 838 setQp(); 839 840 /* Video control Set AIR params */ 841 setAirParams(); 842 843 /* Video control Set VBV params */ 844 setVbvParams(); 845 846 /* Video control Set Motion estimation params */ 847 setMeParams(); 848 849 /* Video control Set GOP params */ 850 setGopParams(); 851 852 /* Video control Set Deblock params */ 853 setDeblockParams(); 854 855 /* Video control Set Profile params */ 856 setProfileParams(); 857 858 /* Video control Set in Encode header mode */ 859 setEncMode(IVE_ENC_MODE_HEADER); 860 861 ALOGV("init_codec successfull"); 862 863 mSpsPpsHeaderReceived = false; 864 mStarted = true; 865 866 return OMX_ErrorNone; 867} 868 869OMX_ERRORTYPE SoftAVC::releaseEncoder() { 870 IV_STATUS_T status = IV_SUCCESS; 871 iv_retrieve_mem_rec_ip_t s_retrieve_mem_ip; 872 iv_retrieve_mem_rec_op_t s_retrieve_mem_op; 873 iv_mem_rec_t *ps_mem_rec; 874 875 if (!mStarted) { 876 return OMX_ErrorNone; 877 } 878 879 s_retrieve_mem_ip.u4_size = sizeof(iv_retrieve_mem_rec_ip_t); 880 s_retrieve_mem_op.u4_size = sizeof(iv_retrieve_mem_rec_op_t); 881 s_retrieve_mem_ip.e_cmd = IV_CMD_RETRIEVE_MEMREC; 882 s_retrieve_mem_ip.ps_mem_rec = mMemRecords; 883 884 status = ive_api_function(mCodecCtx, &s_retrieve_mem_ip, &s_retrieve_mem_op); 885 886 if (status != IV_SUCCESS) { 887 ALOGE("Unable to retrieve memory records = 0x%x\n", 888 s_retrieve_mem_op.u4_error_code); 889 return OMX_ErrorUndefined; 890 } 891 892 /* Free memory records */ 893 ps_mem_rec = mMemRecords; 894 for (size_t i = 0; i < s_retrieve_mem_op.u4_num_mem_rec_filled; i++) { 895 ive_aligned_free(ps_mem_rec->pv_base); 896 ps_mem_rec++; 897 } 898 899 free(mMemRecords); 900 901 for (size_t i = 0; i < MAX_CONVERSION_BUFFERS; i++) { 902 if (mConversionBuffers[i]) { 903 free(mConversionBuffers[i]); 904 mConversionBuffers[i] = NULL; 905 } 906 } 907 908 mStarted = false; 909 910 return OMX_ErrorNone; 911} 912 913OMX_ERRORTYPE SoftAVC::internalGetParameter(OMX_INDEXTYPE index, OMX_PTR params) { 914 switch (index) { 915 case OMX_IndexParamVideoBitrate: 916 { 917 OMX_VIDEO_PARAM_BITRATETYPE *bitRate = 918 (OMX_VIDEO_PARAM_BITRATETYPE *)params; 919 920 if (bitRate->nPortIndex != 1) { 921 return OMX_ErrorUndefined; 922 } 923 924 bitRate->eControlRate = OMX_Video_ControlRateVariable; 925 bitRate->nTargetBitrate = mBitrate; 926 return OMX_ErrorNone; 927 } 928 929 case OMX_IndexParamVideoAvc: 930 { 931 OMX_VIDEO_PARAM_AVCTYPE *avcParams = (OMX_VIDEO_PARAM_AVCTYPE *)params; 932 933 if (avcParams->nPortIndex != 1) { 934 return OMX_ErrorUndefined; 935 } 936 937 OMX_VIDEO_AVCLEVELTYPE omxLevel = OMX_VIDEO_AVCLevel41; 938 if (OMX_ErrorNone 939 != ConvertAvcSpecLevelToOmxAvcLevel(mAVCEncLevel, &omxLevel)) { 940 return OMX_ErrorUndefined; 941 } 942 943 avcParams->eProfile = OMX_VIDEO_AVCProfileBaseline; 944 avcParams->eLevel = omxLevel; 945 avcParams->nRefFrames = 1; 946 avcParams->bUseHadamard = OMX_TRUE; 947 avcParams->nAllowedPictureTypes = (OMX_VIDEO_PictureTypeI 948 | OMX_VIDEO_PictureTypeP | OMX_VIDEO_PictureTypeB); 949 avcParams->nRefIdx10ActiveMinus1 = 0; 950 avcParams->nRefIdx11ActiveMinus1 = 0; 951 avcParams->bWeightedPPrediction = OMX_FALSE; 952 avcParams->bconstIpred = OMX_FALSE; 953 avcParams->bDirect8x8Inference = OMX_FALSE; 954 avcParams->bDirectSpatialTemporal = OMX_FALSE; 955 avcParams->nCabacInitIdc = 0; 956 return OMX_ErrorNone; 957 } 958 959 default: 960 return SoftVideoEncoderOMXComponent::internalGetParameter(index, params); 961 } 962} 963 964OMX_ERRORTYPE SoftAVC::internalSetParameter(OMX_INDEXTYPE index, const OMX_PTR params) { 965 int32_t indexFull = index; 966 967 switch (indexFull) { 968 case OMX_IndexParamVideoBitrate: 969 { 970 return internalSetBitrateParams( 971 (const OMX_VIDEO_PARAM_BITRATETYPE *)params); 972 } 973 974 case OMX_IndexParamVideoAvc: 975 { 976 OMX_VIDEO_PARAM_AVCTYPE *avcType = (OMX_VIDEO_PARAM_AVCTYPE *)params; 977 978 if (avcType->nPortIndex != 1) { 979 return OMX_ErrorUndefined; 980 } 981 982 mEntropyMode = 0; 983 984 if (OMX_TRUE == avcType->bEntropyCodingCABAC) 985 mEntropyMode = 1; 986 987 if ((avcType->nAllowedPictureTypes & OMX_VIDEO_PictureTypeB) && 988 avcType->nPFrames) { 989 mBframes = avcType->nBFrames / avcType->nPFrames; 990 } 991 992 mIInterval = avcType->nPFrames + avcType->nBFrames; 993 994 if (OMX_VIDEO_AVCLoopFilterDisable == avcType->eLoopFilterMode) 995 mDisableDeblkLevel = 4; 996 997 if (avcType->nRefFrames != 1 998 || avcType->bUseHadamard != OMX_TRUE 999 || avcType->nRefIdx10ActiveMinus1 != 0 1000 || avcType->nRefIdx11ActiveMinus1 != 0 1001 || avcType->bWeightedPPrediction != OMX_FALSE 1002 || avcType->bconstIpred != OMX_FALSE 1003 || avcType->bDirect8x8Inference != OMX_FALSE 1004 || avcType->bDirectSpatialTemporal != OMX_FALSE 1005 || avcType->nCabacInitIdc != 0) { 1006 return OMX_ErrorUndefined; 1007 } 1008 1009 if (OK != ConvertOmxAvcLevelToAvcSpecLevel(avcType->eLevel, &mAVCEncLevel)) { 1010 return OMX_ErrorUndefined; 1011 } 1012 1013 return OMX_ErrorNone; 1014 } 1015 1016 default: 1017 return SoftVideoEncoderOMXComponent::internalSetParameter(index, params); 1018 } 1019} 1020 1021OMX_ERRORTYPE SoftAVC::setConfig( 1022 OMX_INDEXTYPE index, const OMX_PTR _params) { 1023 switch (index) { 1024 case OMX_IndexConfigVideoIntraVOPRefresh: 1025 { 1026 OMX_CONFIG_INTRAREFRESHVOPTYPE *params = 1027 (OMX_CONFIG_INTRAREFRESHVOPTYPE *)_params; 1028 1029 if (params->nPortIndex != kOutputPortIndex) { 1030 return OMX_ErrorBadPortIndex; 1031 } 1032 1033 mKeyFrameRequested = params->IntraRefreshVOP; 1034 return OMX_ErrorNone; 1035 } 1036 1037 case OMX_IndexConfigVideoBitrate: 1038 { 1039 OMX_VIDEO_CONFIG_BITRATETYPE *params = 1040 (OMX_VIDEO_CONFIG_BITRATETYPE *)_params; 1041 1042 if (params->nPortIndex != kOutputPortIndex) { 1043 return OMX_ErrorBadPortIndex; 1044 } 1045 1046 if (mBitrate != params->nEncodeBitrate) { 1047 mBitrate = params->nEncodeBitrate; 1048 mBitrateUpdated = true; 1049 } 1050 return OMX_ErrorNone; 1051 } 1052 1053 default: 1054 return SimpleSoftOMXComponent::setConfig(index, _params); 1055 } 1056} 1057 1058OMX_ERRORTYPE SoftAVC::internalSetBitrateParams( 1059 const OMX_VIDEO_PARAM_BITRATETYPE *bitrate) { 1060 if (bitrate->nPortIndex != kOutputPortIndex) { 1061 return OMX_ErrorUnsupportedIndex; 1062 } 1063 1064 mBitrate = bitrate->nTargetBitrate; 1065 mBitrateUpdated = true; 1066 1067 return OMX_ErrorNone; 1068} 1069 1070OMX_ERRORTYPE SoftAVC::setEncodeArgs( 1071 ive_video_encode_ip_t *ps_encode_ip, 1072 ive_video_encode_op_t *ps_encode_op, 1073 OMX_BUFFERHEADERTYPE *inputBufferHeader, 1074 OMX_BUFFERHEADERTYPE *outputBufferHeader) { 1075 iv_raw_buf_t *ps_inp_raw_buf; 1076 const uint8_t *source; 1077 UWORD8 *pu1_buf; 1078 1079 ps_inp_raw_buf = &ps_encode_ip->s_inp_buf; 1080 ps_encode_ip->s_out_buf.pv_buf = outputBufferHeader->pBuffer; 1081 ps_encode_ip->s_out_buf.u4_bytes = 0; 1082 ps_encode_ip->s_out_buf.u4_bufsize = outputBufferHeader->nAllocLen; 1083 ps_encode_ip->u4_size = sizeof(ive_video_encode_ip_t); 1084 ps_encode_op->u4_size = sizeof(ive_video_encode_op_t); 1085 1086 ps_encode_ip->e_cmd = IVE_CMD_VIDEO_ENCODE; 1087 ps_encode_ip->pv_bufs = NULL; 1088 ps_encode_ip->pv_mb_info = NULL; 1089 ps_encode_ip->pv_pic_info = NULL; 1090 ps_encode_ip->u4_mb_info_type = 0; 1091 ps_encode_ip->u4_pic_info_type = 0; 1092 ps_encode_op->s_out_buf.pv_buf = NULL; 1093 1094 /* Initialize color formats */ 1095 ps_inp_raw_buf->e_color_fmt = mIvVideoColorFormat; 1096 source = NULL; 1097 if ((inputBufferHeader != NULL) && inputBufferHeader->nFilledLen) { 1098 source = inputBufferHeader->pBuffer + inputBufferHeader->nOffset; 1099 1100 if (mInputDataIsMeta) { 1101 uint8_t *conversionBuffer = NULL; 1102 for (size_t i = 0; i < MAX_CONVERSION_BUFFERS; i++) { 1103 if (mConversionBuffersFree[i]) { 1104 mConversionBuffersFree[i] = 0; 1105 conversionBuffer = mConversionBuffers[i]; 1106 break; 1107 } 1108 } 1109 1110 if (NULL == conversionBuffer) { 1111 ALOGE("No free buffers to hold conversion data"); 1112 return OMX_ErrorUndefined; 1113 } 1114 1115 source = extractGraphicBuffer( 1116 conversionBuffer, (mWidth * mHeight * 3 / 2), source, 1117 inputBufferHeader->nFilledLen, mWidth, mHeight); 1118 1119 if (source == NULL) { 1120 ALOGE("Error in extractGraphicBuffer"); 1121 notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 1122 return OMX_ErrorUndefined; 1123 } 1124 } 1125 ps_encode_ip->u4_is_last = 0; 1126 ps_encode_ip->u4_timestamp_high = (inputBufferHeader->nTimeStamp) >> 32; 1127 ps_encode_ip->u4_timestamp_low = (inputBufferHeader->nTimeStamp) & 0xFFFFFFFF; 1128 } 1129 else { 1130 if (mSawInputEOS){ 1131 ps_encode_ip->u4_is_last = 1; 1132 } 1133 memset(ps_inp_raw_buf, 0, sizeof(iv_raw_buf_t)); 1134 ps_inp_raw_buf->e_color_fmt = mIvVideoColorFormat; 1135 ps_inp_raw_buf->u4_size = sizeof(iv_raw_buf_t); 1136 return OMX_ErrorNone; 1137 } 1138 1139 pu1_buf = (UWORD8 *)source; 1140 switch (mIvVideoColorFormat) { 1141 case IV_YUV_420P: 1142 { 1143 ps_inp_raw_buf->apv_bufs[0] = pu1_buf; 1144 pu1_buf += (mStride) * mHeight; 1145 ps_inp_raw_buf->apv_bufs[1] = pu1_buf; 1146 pu1_buf += (mStride / 2) * mHeight / 2; 1147 ps_inp_raw_buf->apv_bufs[2] = pu1_buf; 1148 1149 ps_inp_raw_buf->au4_wd[0] = mWidth; 1150 ps_inp_raw_buf->au4_wd[1] = mWidth / 2; 1151 ps_inp_raw_buf->au4_wd[2] = mWidth / 2; 1152 1153 ps_inp_raw_buf->au4_ht[0] = mHeight; 1154 ps_inp_raw_buf->au4_ht[1] = mHeight / 2; 1155 ps_inp_raw_buf->au4_ht[2] = mHeight / 2; 1156 1157 ps_inp_raw_buf->au4_strd[0] = mStride; 1158 ps_inp_raw_buf->au4_strd[1] = (mStride / 2); 1159 ps_inp_raw_buf->au4_strd[2] = (mStride / 2); 1160 break; 1161 } 1162 1163 case IV_YUV_422ILE: 1164 { 1165 ps_inp_raw_buf->apv_bufs[0] = pu1_buf; 1166 ps_inp_raw_buf->au4_wd[0] = mWidth * 2; 1167 ps_inp_raw_buf->au4_ht[0] = mHeight; 1168 ps_inp_raw_buf->au4_strd[0] = mStride * 2; 1169 break; 1170 } 1171 1172 case IV_YUV_420SP_UV: 1173 case IV_YUV_420SP_VU: 1174 default: 1175 { 1176 ps_inp_raw_buf->apv_bufs[0] = pu1_buf; 1177 pu1_buf += (mStride) * mHeight; 1178 ps_inp_raw_buf->apv_bufs[1] = pu1_buf; 1179 1180 ps_inp_raw_buf->au4_wd[0] = mWidth; 1181 ps_inp_raw_buf->au4_wd[1] = mWidth; 1182 1183 ps_inp_raw_buf->au4_ht[0] = mHeight; 1184 ps_inp_raw_buf->au4_ht[1] = mHeight / 2; 1185 1186 ps_inp_raw_buf->au4_strd[0] = mStride; 1187 ps_inp_raw_buf->au4_strd[1] = mStride; 1188 break; 1189 } 1190 } 1191 return OMX_ErrorNone; 1192} 1193 1194void SoftAVC::onQueueFilled(OMX_U32 portIndex) { 1195 IV_STATUS_T status; 1196 WORD32 timeDelay, timeTaken; 1197 1198 UNUSED(portIndex); 1199 1200 // Initialize encoder if not already initialized 1201 if (mCodecCtx == NULL) { 1202 if (OMX_ErrorNone != initEncoder()) { 1203 ALOGE("Failed to initialize encoder"); 1204 notify(OMX_EventError, OMX_ErrorUndefined, 0 /* arg2 */, NULL /* data */); 1205 return; 1206 } 1207 } 1208 if (mSignalledError) { 1209 return; 1210 } 1211 1212 List<BufferInfo *> &inQueue = getPortQueue(0); 1213 List<BufferInfo *> &outQueue = getPortQueue(1); 1214 1215 while (!mSawOutputEOS && !outQueue.empty()) { 1216 1217 OMX_ERRORTYPE error; 1218 ive_video_encode_ip_t s_encode_ip; 1219 ive_video_encode_op_t s_encode_op; 1220 BufferInfo *outputBufferInfo = *outQueue.begin(); 1221 OMX_BUFFERHEADERTYPE *outputBufferHeader = outputBufferInfo->mHeader; 1222 1223 BufferInfo *inputBufferInfo; 1224 OMX_BUFFERHEADERTYPE *inputBufferHeader; 1225 1226 if (mSawInputEOS) { 1227 inputBufferHeader = NULL; 1228 inputBufferInfo = NULL; 1229 } else if (!inQueue.empty()) { 1230 inputBufferInfo = *inQueue.begin(); 1231 inputBufferHeader = inputBufferInfo->mHeader; 1232 } else { 1233 return; 1234 } 1235 1236 outputBufferHeader->nTimeStamp = 0; 1237 outputBufferHeader->nFlags = 0; 1238 outputBufferHeader->nOffset = 0; 1239 outputBufferHeader->nFilledLen = 0; 1240 outputBufferHeader->nOffset = 0; 1241 1242 if (inputBufferHeader != NULL) { 1243 outputBufferHeader->nFlags = inputBufferHeader->nFlags; 1244 } 1245 1246 uint8_t *outPtr = (uint8_t *)outputBufferHeader->pBuffer; 1247 1248 if (!mSpsPpsHeaderReceived) { 1249 error = setEncodeArgs(&s_encode_ip, &s_encode_op, NULL, outputBufferHeader); 1250 if (error != OMX_ErrorNone) { 1251 mSignalledError = true; 1252 notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 1253 return; 1254 } 1255 status = ive_api_function(mCodecCtx, &s_encode_ip, &s_encode_op); 1256 1257 if (IV_SUCCESS != status) { 1258 ALOGE("Encode Frame failed = 0x%x\n", 1259 s_encode_op.u4_error_code); 1260 } else { 1261 ALOGV("Bytes Generated in header %d\n", 1262 s_encode_op.s_out_buf.u4_bytes); 1263 } 1264 1265 mSpsPpsHeaderReceived = true; 1266 1267 outputBufferHeader->nFlags = OMX_BUFFERFLAG_CODECCONFIG; 1268 outputBufferHeader->nFilledLen = s_encode_op.s_out_buf.u4_bytes; 1269 if (inputBufferHeader != NULL) { 1270 outputBufferHeader->nTimeStamp = inputBufferHeader->nTimeStamp; 1271 } 1272 1273 outQueue.erase(outQueue.begin()); 1274 outputBufferInfo->mOwnedByUs = false; 1275 1276 DUMP_TO_FILE( 1277 mOutFile, outputBufferHeader->pBuffer, 1278 outputBufferHeader->nFilledLen); 1279 notifyFillBufferDone(outputBufferHeader); 1280 1281 setEncMode(IVE_ENC_MODE_PICTURE); 1282 return; 1283 } 1284 1285 if (mBitrateUpdated) { 1286 setBitRate(); 1287 } 1288 1289 if (mKeyFrameRequested) { 1290 setFrameType(IV_IDR_FRAME); 1291 } 1292 1293 if ((inputBufferHeader != NULL) 1294 && (inputBufferHeader->nFlags & OMX_BUFFERFLAG_EOS)) { 1295 mSawInputEOS = true; 1296 } 1297 1298 /* In normal mode, store inputBufferInfo and this will be returned 1299 when encoder consumes this input */ 1300 if (!mInputDataIsMeta && (inputBufferInfo != NULL)) { 1301 for (size_t i = 0; i < MAX_INPUT_BUFFER_HEADERS; i++) { 1302 if (NULL == mInputBufferInfo[i]) { 1303 mInputBufferInfo[i] = inputBufferInfo; 1304 break; 1305 } 1306 } 1307 } 1308 error = setEncodeArgs( 1309 &s_encode_ip, &s_encode_op, inputBufferHeader, outputBufferHeader); 1310 1311 if (error != OMX_ErrorNone) { 1312 mSignalledError = true; 1313 notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 1314 return; 1315 } 1316 1317 DUMP_TO_FILE( 1318 mInFile, s_encode_ip.s_inp_buf.apv_bufs[0], 1319 (mHeight * mStride * 3 / 2)); 1320 1321 GETTIME(&mTimeStart, NULL); 1322 /* Compute time elapsed between end of previous decode() 1323 * to start of current decode() */ 1324 TIME_DIFF(mTimeEnd, mTimeStart, timeDelay); 1325 status = ive_api_function(mCodecCtx, &s_encode_ip, &s_encode_op); 1326 1327 if (IV_SUCCESS != status) { 1328 ALOGE("Encode Frame failed = 0x%x\n", 1329 s_encode_op.u4_error_code); 1330 mSignalledError = true; 1331 notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); 1332 return; 1333 } 1334 1335 GETTIME(&mTimeEnd, NULL); 1336 /* Compute time taken for decode() */ 1337 TIME_DIFF(mTimeStart, mTimeEnd, timeTaken); 1338 1339 ALOGV("timeTaken=%6d delay=%6d numBytes=%6d", timeTaken, timeDelay, 1340 s_encode_op.s_out_buf.u4_bytes); 1341 1342 /* In encoder frees up an input buffer, mark it as free */ 1343 if (s_encode_op.s_inp_buf.apv_bufs[0] != NULL) { 1344 if (mInputDataIsMeta) { 1345 for (size_t i = 0; i < MAX_CONVERSION_BUFFERS; i++) { 1346 if (mConversionBuffers[i] == s_encode_op.s_inp_buf.apv_bufs[0]) { 1347 mConversionBuffersFree[i] = 1; 1348 break; 1349 } 1350 } 1351 } else { 1352 /* In normal mode, call EBD on inBuffeHeader that is freed by the codec */ 1353 for (size_t i = 0; i < MAX_INPUT_BUFFER_HEADERS; i++) { 1354 uint8_t *buf = NULL; 1355 OMX_BUFFERHEADERTYPE *bufHdr = NULL; 1356 if (mInputBufferInfo[i] != NULL) { 1357 bufHdr = mInputBufferInfo[i]->mHeader; 1358 buf = bufHdr->pBuffer + bufHdr->nOffset; 1359 } 1360 if (s_encode_op.s_inp_buf.apv_bufs[0] == buf) { 1361 mInputBufferInfo[i]->mOwnedByUs = false; 1362 notifyEmptyBufferDone(bufHdr); 1363 mInputBufferInfo[i] = NULL; 1364 break; 1365 } 1366 } 1367 } 1368 } 1369 1370 outputBufferHeader->nFilledLen = s_encode_op.s_out_buf.u4_bytes; 1371 1372 if (IV_IDR_FRAME == s_encode_op.u4_encoded_frame_type) { 1373 outputBufferHeader->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; 1374 } 1375 1376 if (inputBufferHeader != NULL) { 1377 inQueue.erase(inQueue.begin()); 1378 1379 /* If in meta data, call EBD on input */ 1380 /* In case of normal mode, EBD will be done once encoder 1381 releases the input buffer */ 1382 if (mInputDataIsMeta) { 1383 inputBufferInfo->mOwnedByUs = false; 1384 notifyEmptyBufferDone(inputBufferHeader); 1385 } 1386 } 1387 1388 if (s_encode_op.u4_is_last) { 1389 outputBufferHeader->nFlags |= OMX_BUFFERFLAG_EOS; 1390 mSawOutputEOS = true; 1391 } else { 1392 outputBufferHeader->nFlags &= ~OMX_BUFFERFLAG_EOS; 1393 } 1394 1395 if (outputBufferHeader->nFilledLen || s_encode_op.u4_is_last) { 1396 outputBufferHeader->nTimeStamp = s_encode_op.u4_timestamp_high; 1397 outputBufferHeader->nTimeStamp <<= 32; 1398 outputBufferHeader->nTimeStamp |= s_encode_op.u4_timestamp_low; 1399 outputBufferInfo->mOwnedByUs = false; 1400 outQueue.erase(outQueue.begin()); 1401 DUMP_TO_FILE(mOutFile, outputBufferHeader->pBuffer, 1402 outputBufferHeader->nFilledLen); 1403 notifyFillBufferDone(outputBufferHeader); 1404 } 1405 1406 if (s_encode_op.u4_is_last == 1) { 1407 return; 1408 } 1409 } 1410 return; 1411} 1412 1413} // namespace android 1414 1415android::SoftOMXComponent *createSoftOMXComponent( 1416 const char *name, const OMX_CALLBACKTYPE *callbacks, 1417 OMX_PTR appData, OMX_COMPONENTTYPE **component) { 1418 return new android::SoftAVC(name, callbacks, appData, component); 1419} 1420