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