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