OMXVideoEncoderAVC.cpp revision 80114224b110cdd1707292e6283e970e08b513f0
1/* 2* Copyright (c) 2009-2011 Intel Corporation. All rights reserved. 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 18//#define LOG_NDEBUG 0 19#define LOG_TAG "OMXVideoEncoderAVC" 20#include <utils/Log.h> 21#include "OMXVideoEncoderAVC.h" 22 23static const char *AVC_MIME_TYPE = "video/h264"; 24 25OMXVideoEncoderAVC::OMXVideoEncoderAVC() { 26 BuildHandlerList(); 27 mVideoEncoder = createVideoEncoder(AVC_MIME_TYPE); 28 if (!mVideoEncoder) LOGE("OMX_ErrorInsufficientResources"); 29 30 mAVCParams = new VideoParamsAVC(); 31 if (!mAVCParams) LOGE("OMX_ErrorInsufficientResources"); 32} 33 34OMXVideoEncoderAVC::~OMXVideoEncoderAVC() { 35 if(mAVCParams) { 36 delete mAVCParams; 37 mAVCParams = NULL; 38 } 39} 40 41OMX_ERRORTYPE OMXVideoEncoderAVC::InitOutputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionOutput) { 42 // OMX_VIDEO_PARAM_AVCTYPE 43 memset(&mParamAvc, 0, sizeof(mParamAvc)); 44 SetTypeHeader(&mParamAvc, sizeof(mParamAvc)); 45 mParamAvc.nPortIndex = OUTPORT_INDEX; 46 mParamAvc.eProfile = OMX_VIDEO_AVCProfileBaseline; 47 mParamAvc.eLevel = OMX_VIDEO_AVCLevel1; 48 49 // OMX_NALSTREAMFORMATTYPE 50 memset(&mNalStreamFormat, 0, sizeof(mNalStreamFormat)); 51 SetTypeHeader(&mNalStreamFormat, sizeof(mNalStreamFormat)); 52 mNalStreamFormat.nPortIndex = OUTPORT_INDEX; 53 // TODO: check if this is desired Nalu Format 54 // mNalStreamFormat.eNaluFormat = OMX_NaluFormatStartCodesSeparateFirstHeader; 55 mNalStreamFormat.eNaluFormat = OMX_NaluFormatLengthPrefixedSeparateFirstHeader; 56 // OMX_VIDEO_CONFIG_AVCINTRAPERIOD 57 memset(&mConfigAvcIntraPeriod, 0, sizeof(mConfigAvcIntraPeriod)); 58 SetTypeHeader(&mConfigAvcIntraPeriod, sizeof(mConfigAvcIntraPeriod)); 59 mConfigAvcIntraPeriod.nPortIndex = OUTPORT_INDEX; 60 // TODO: need to be populated from Video Encoder 61 mConfigAvcIntraPeriod.nIDRPeriod = 1; 62 mConfigAvcIntraPeriod.nPFrames = 0; 63 64 // OMX_VIDEO_CONFIG_NALSIZE 65 memset(&mConfigNalSize, 0, sizeof(mConfigNalSize)); 66 SetTypeHeader(&mConfigNalSize, sizeof(mConfigNalSize)); 67 mConfigNalSize.nPortIndex = OUTPORT_INDEX; 68 mConfigNalSize.nNaluBytes = 0; 69 70 // OMX_VIDEO_PARAM_INTEL_AVCVUI 71 memset(&mParamIntelAvcVui, 0, sizeof(mParamIntelAvcVui)); 72 SetTypeHeader(&mParamIntelAvcVui, sizeof(mParamIntelAvcVui)); 73 mParamIntelAvcVui.nPortIndex = OUTPORT_INDEX; 74 mParamIntelAvcVui.bVuiGeneration = OMX_FALSE; 75 76 // OMX_VIDEO_CONFIG_INTEL_SLICE_NUMBERS 77 memset(&mConfigIntelSliceNumbers, 0, sizeof(mConfigIntelSliceNumbers)); 78 SetTypeHeader(&mConfigIntelSliceNumbers, sizeof(mConfigIntelSliceNumbers)); 79 mConfigIntelSliceNumbers.nPortIndex = OUTPORT_INDEX; 80 mConfigIntelSliceNumbers.nISliceNumber = 2; 81 mConfigIntelSliceNumbers.nPSliceNumber = 2; 82 83 // Override OMX_PARAM_PORTDEFINITIONTYPE 84 paramPortDefinitionOutput->nBufferCountActual = OUTPORT_ACTUAL_BUFFER_COUNT; 85 paramPortDefinitionOutput->nBufferCountMin = OUTPORT_MIN_BUFFER_COUNT; 86 paramPortDefinitionOutput->nBufferSize = OUTPORT_BUFFER_SIZE; 87 paramPortDefinitionOutput->format.video.cMIMEType = (OMX_STRING)AVC_MIME_TYPE; 88 paramPortDefinitionOutput->format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; 89 90 // Override OMX_VIDEO_PARAM_PROFILELEVELTYPE 91 // TODO: check if profile/level supported is correct 92 mParamProfileLevel.eProfile = mParamAvc.eProfile; 93 mParamProfileLevel.eLevel = mParamAvc.eLevel; 94 95 // Override OMX_VIDEO_PARAM_BITRATETYPE 96 mParamBitrate.nTargetBitrate = 192000; 97 98 // Override OMX_VIDEO_CONFIG_INTEL_BITRATETYPE 99 mConfigIntelBitrate.nInitialQP = 24; // Initial QP for I frames 100 101 return OMX_ErrorNone; 102} 103 104OMX_ERRORTYPE OMXVideoEncoderAVC::SetVideoEncoderParam(void) { 105 106 Encode_Status ret = ENCODE_SUCCESS; 107 LOGV("OMXVideoEncoderAVC::SetVideoEncoderParam"); 108 109 if (!mEncoderParams) { 110 LOGE("NULL pointer: mEncoderParams"); 111 return OMX_ErrorBadParameter; 112 } 113 114 mVideoEncoder->getParameters(mEncoderParams); 115 mEncoderParams->profile = (VAProfile)VAProfileH264Baseline; 116 OMXVideoEncoderBase::SetVideoEncoderParam(); 117 118 mVideoEncoder->getParameters(mAVCParams); 119 if(mParamIntelAvcVui.bVuiGeneration == OMX_TRUE) { 120 mAVCParams->VUIFlag = 1; 121 } 122 mAVCParams->sliceNum.iSliceNum = mConfigIntelSliceNumbers.nISliceNumber; 123 mAVCParams->sliceNum.pSliceNum = mConfigIntelSliceNumbers.nPSliceNumber; 124 mAVCParams->idrInterval = mConfigAvcIntraPeriod.nIDRPeriod; 125 mAVCParams->maxSliceSize = mConfigNalSize.nNaluBytes * 8; 126 ret = mVideoEncoder ->setParameters(mAVCParams); 127 CHECK_ENCODE_STATUS("setParameters"); 128 129 LOGV("VUIFlag = %d\n", mAVCParams->VUIFlag); 130 LOGV("sliceNum.iSliceNum = %d\n", mAVCParams->sliceNum.iSliceNum); 131 LOGV("sliceNum.pSliceNum = %d\n", mAVCParams->sliceNum.pSliceNum); 132 LOGV("idrInterval = %d\n ", mAVCParams->idrInterval); 133 LOGV("maxSliceSize = %d\n ", mAVCParams->maxSliceSize); 134 return OMX_ErrorNone; 135} 136 137OMX_ERRORTYPE OMXVideoEncoderAVC::ProcessorInit(void) { 138 mFirstFrame = OMX_TRUE; 139 return OMXVideoEncoderBase::ProcessorInit(); 140} 141 142OMX_ERRORTYPE OMXVideoEncoderAVC::ProcessorDeinit(void) { 143 return OMXVideoEncoderBase::ProcessorDeinit(); 144} 145 146OMX_ERRORTYPE OMXVideoEncoderAVC::ProcessorProcess( 147 OMX_BUFFERHEADERTYPE **buffers, 148 buffer_retain_t *retains, 149 OMX_U32 numberBuffers) { 150 151 OMX_U32 outfilledlen = 0; 152 OMX_S64 outtimestamp = 0; 153 OMX_U32 outflags = 0; 154 155 OMX_ERRORTYPE oret = OMX_ErrorNone; 156 Encode_Status ret = ENCODE_SUCCESS; 157 158 VideoEncOutputBuffer outBuf; 159 VideoEncRawBuffer inBuf; 160 161 LOGV_IF(buffers[INPORT_INDEX]->nFlags & OMX_BUFFERFLAG_EOS, 162 "%s(),%d: got OMX_BUFFERFLAG_EOS\n", __func__, __LINE__); 163 164 if (!buffers[INPORT_INDEX]->nFilledLen) { 165 LOGE("%s(),%d: input buffer's nFilledLen is zero\n", __func__, __LINE__); 166 goto out; 167 } 168 169 if (mBsState != BS_STATE_INVALID) { 170 LOGV(" Share buffer mode\n"); 171 inBuf.size = mSharedBufArray[0].dataSize; 172 inBuf.data = 173 *(reinterpret_cast<uint8_t **>(buffers[INPORT_INDEX]->pBuffer + buffers[INPORT_INDEX]->nOffset)); 174 } else { 175 inBuf.data = buffers[INPORT_INDEX]->pBuffer + buffers[INPORT_INDEX]->nOffset; 176 inBuf.size = buffers[INPORT_INDEX]->nFilledLen; 177 } 178 179 LOGV("inBuf.data=%x, size=%d",(unsigned)inBuf.data, inBuf.size); 180 181 outBuf.data = buffers[OUTPORT_INDEX]->pBuffer + buffers[OUTPORT_INDEX]->nOffset; 182 outBuf.dataSize = 0; 183 outBuf.bufferSize = buffers[OUTPORT_INDEX]->nAllocLen - buffers[OUTPORT_INDEX]->nOffset; 184 185 if(inBuf.size<=0) { 186 LOGE("The Input buf size is 0\n"); 187 return OMX_ErrorBadParameter; 188 } 189 190 LOGV("in buffer = 0x%x ts = %lld", 191 buffers[INPORT_INDEX]->pBuffer + buffers[INPORT_INDEX]->nOffset, 192 buffers[INPORT_INDEX]->nTimeStamp); 193 194 if(mFrameRetrieved) { 195 // encode and setConfig need to be thread safe 196 pthread_mutex_lock(&mSerializationLock); 197 ret = mVideoEncoder->encode(&inBuf); 198 pthread_mutex_unlock(&mSerializationLock); 199 CHECK_ENCODE_STATUS("encode"); 200 mFrameRetrieved = OMX_FALSE; 201 202 // This is for buffer contention, we won't release current buffer 203 // but the last input buffer 204 ports[INPORT_INDEX]->ReturnAllRetainedBuffers(); 205 } 206 207 switch (mNalStreamFormat.eNaluFormat) { 208 case OMX_NaluFormatStartCodes: 209 210 outBuf.format = OUTPUT_EVERYTHING; 211 ret = mVideoEncoder->getOutput(&outBuf); 212 CHECK_ENCODE_STATUS("encode"); 213 214 LOGV("output data size = %d", outBuf.dataSize); 215 outfilledlen = outBuf.dataSize; 216 outtimestamp = buffers[INPORT_INDEX]->nTimeStamp; 217 218 219 if (outBuf.flag & ENCODE_BUFFERFLAG_SYNCFRAME) { 220 outflags |= OMX_BUFFERFLAG_SYNCFRAME; 221 } 222 223 if(outBuf.flag & ENCODE_BUFFERFLAG_ENDOFFRAME) { 224 outflags |= OMX_BUFFERFLAG_ENDOFFRAME; 225 mFrameRetrieved = OMX_TRUE; 226 retains[INPORT_INDEX] = BUFFER_RETAIN_ACCUMULATE; 227 228 } else { 229 retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; //get again 230 231 } 232 233 if (outfilledlen > 0) { 234 retains[OUTPORT_INDEX] = BUFFER_RETAIN_NOT_RETAIN; 235 } else { 236 retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; 237 } 238 239 break; 240 case OMX_NaluFormatOneNaluPerBuffer: 241 242 outBuf.format = OUTPUT_ONE_NAL; 243 ret = mVideoEncoder->getOutput(&outBuf); 244 CHECK_ENCODE_STATUS("getOutput"); 245 // Return code could not be ENCODE_BUFFER_TOO_SMALL 246 // If we don't return error, we will have dead lock issue 247 if (ret == ENCODE_BUFFER_TOO_SMALL) { 248 return OMX_ErrorUndefined; 249 } 250 251 LOGV("output codec data size = %d", outBuf.dataSize); 252 253 outfilledlen = outBuf.dataSize; 254 outtimestamp = buffers[INPORT_INDEX]->nTimeStamp; 255 256 if (outBuf.flag & ENCODE_BUFFERFLAG_SYNCFRAME) { 257 outflags |= OMX_BUFFERFLAG_SYNCFRAME; 258 } 259 260 if(outBuf.flag & ENCODE_BUFFERFLAG_ENDOFFRAME) { 261 outflags |= OMX_BUFFERFLAG_ENDOFFRAME; 262 mFrameRetrieved = OMX_TRUE; 263 retains[INPORT_INDEX] = BUFFER_RETAIN_ACCUMULATE; 264 265 } else { 266 retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; //get again 267 } 268 269 if (outfilledlen > 0) { 270 retains[OUTPORT_INDEX] = BUFFER_RETAIN_NOT_RETAIN; 271 } else { 272 retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; 273 } 274 275 break; 276 case OMX_NaluFormatStartCodesSeparateFirstHeader: 277 278 if(mFirstFrame) { 279 LOGV("mFirstFrame\n"); 280 outBuf.format = OUTPUT_CODEC_DATA; 281 ret = mVideoEncoder->getOutput(&outBuf); 282 CHECK_ENCODE_STATUS("getOutput"); 283 // Return code could not be ENCODE_BUFFER_TOO_SMALL 284 // If we don't return error, we will have dead lock issue 285 if (ret == ENCODE_BUFFER_TOO_SMALL) { 286 return OMX_ErrorUndefined; 287 } 288 289 LOGV("output codec data size = %d", outBuf.dataSize); 290 291 outflags |= OMX_BUFFERFLAG_CODECCONFIG; 292 outflags |= OMX_BUFFERFLAG_ENDOFFRAME; 293 outflags |= OMX_BUFFERFLAG_SYNCFRAME; 294 295 // This input buffer need to be gotten again 296 retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; 297 outfilledlen = outBuf.dataSize; 298 mFirstFrame = OMX_FALSE; 299 } else { 300 outBuf.format = OUTPUT_EVERYTHING; 301 mVideoEncoder->getOutput(&outBuf); 302 CHECK_ENCODE_STATUS("getOutput"); 303 304 LOGV("output data size = %d", outBuf.dataSize); 305 306 outfilledlen = outBuf.dataSize; 307 outtimestamp = buffers[INPORT_INDEX]->nTimeStamp; 308 309 if (outBuf.flag & ENCODE_BUFFERFLAG_SYNCFRAME) { 310 outflags |= OMX_BUFFERFLAG_SYNCFRAME; 311 } 312 if(outBuf.flag & ENCODE_BUFFERFLAG_ENDOFFRAME) { 313 LOGV("Get buffer done\n"); 314 outflags |= OMX_BUFFERFLAG_ENDOFFRAME; 315 mFrameRetrieved = OMX_TRUE; 316 retains[INPORT_INDEX] = BUFFER_RETAIN_ACCUMULATE; 317 318 } else { 319 retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; //get again 320 321 } 322 } 323 324 if (outfilledlen > 0) { 325 retains[OUTPORT_INDEX] = BUFFER_RETAIN_NOT_RETAIN; 326 } else { 327 retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; 328 } 329 break; 330 case OMX_NaluFormatLengthPrefixedSeparateFirstHeader: 331 332 if(mFirstFrame) { 333 LOGV("mFirstFrame\n"); 334 outBuf.format = OUTPUT_CODEC_DATA; 335 ret = mVideoEncoder->getOutput(&outBuf); 336 CHECK_ENCODE_STATUS("getOutput"); 337 // Return code could not be ENCODE_BUFFER_TOO_SMALL 338 // If we don't return error, we will have dead lock issue 339 if (ret == ENCODE_BUFFER_TOO_SMALL) { 340 return OMX_ErrorUndefined; 341 } 342 343 LOGV("output codec data size = %d", outBuf.dataSize); 344 345 outflags |= OMX_BUFFERFLAG_CODECCONFIG; 346 outflags |= OMX_BUFFERFLAG_ENDOFFRAME; 347 outflags |= OMX_BUFFERFLAG_SYNCFRAME; 348 349 // This input buffer need to be gotten again 350 retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; 351 outfilledlen = outBuf.dataSize; 352 mFirstFrame = OMX_FALSE; 353 } else { 354 outBuf.format = OUTPUT_LENGTH_PREFIXED; 355 mVideoEncoder->getOutput(&outBuf); 356 CHECK_ENCODE_STATUS("getOutput"); 357 358 LOGV("output data size = %d", outBuf.dataSize); 359 360 outfilledlen = outBuf.dataSize; 361 outtimestamp = buffers[INPORT_INDEX]->nTimeStamp; 362 363 if (outBuf.flag & ENCODE_BUFFERFLAG_SYNCFRAME) { 364 outflags |= OMX_BUFFERFLAG_SYNCFRAME; 365 } 366 if(outBuf.flag & ENCODE_BUFFERFLAG_ENDOFFRAME) { 367 LOGV("Get buffer done\n"); 368 outflags |= OMX_BUFFERFLAG_ENDOFFRAME; 369 mFrameRetrieved = OMX_TRUE; 370 retains[INPORT_INDEX] = BUFFER_RETAIN_ACCUMULATE; 371 372 } else { 373 retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; //get again 374 } 375 } 376 377 if (outfilledlen > 0) { 378 retains[OUTPORT_INDEX] = BUFFER_RETAIN_NOT_RETAIN; 379 } else { 380 retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; 381 } 382 break; 383 } 384 385out: 386 LOGV("output buffers = %p:%d, flag = %x", buffers[OUTPORT_INDEX]->pBuffer, outfilledlen, outflags); 387 388 if(retains[OUTPORT_INDEX] != BUFFER_RETAIN_GETAGAIN) { 389 buffers[OUTPORT_INDEX]->nFilledLen = outfilledlen; 390 buffers[OUTPORT_INDEX]->nTimeStamp = outtimestamp; 391 buffers[OUTPORT_INDEX]->nFlags = outflags; 392 } 393 394 if (retains[INPORT_INDEX] == BUFFER_RETAIN_NOT_RETAIN || 395 retains[INPORT_INDEX] == BUFFER_RETAIN_ACCUMULATE ) { 396 mFrameInputCount ++; 397 } 398 399 if (retains[OUTPORT_INDEX] == BUFFER_RETAIN_NOT_RETAIN) mFrameOutputCount ++; 400 401#if 0 402 if (avcEncParamIntelBitrateType.eControlRate != OMX_Video_Intel_ControlRateVideoConferencingMode) { 403 if (oret == (OMX_ERRORTYPE) OMX_ErrorIntelExtSliceSizeOverflow) { 404 oret = OMX_ErrorNone; 405 } 406 } 407#endif 408 LOGV_IF(oret == OMX_ErrorNone, "%s(),%d: exit, encode is done\n", __func__, __LINE__); 409 410 return oret; 411 412} 413 414OMX_ERRORTYPE OMXVideoEncoderAVC::BuildHandlerList(void) { 415 OMXVideoEncoderBase::BuildHandlerList(); 416 AddHandler(OMX_IndexParamVideoAvc, GetParamVideoAvc, SetParamVideoAvc); 417 AddHandler((OMX_INDEXTYPE)OMX_IndexParamNalStreamFormat, GetParamNalStreamFormat, SetParamNalStreamFormat); 418 AddHandler((OMX_INDEXTYPE)OMX_IndexParamNalStreamFormatSupported, GetParamNalStreamFormatSupported, SetParamNalStreamFormatSupported); 419 AddHandler((OMX_INDEXTYPE)OMX_IndexParamNalStreamFormatSelect, GetParamNalStreamFormatSelect, SetParamNalStreamFormatSelect); 420 AddHandler(OMX_IndexConfigVideoAVCIntraPeriod, GetConfigVideoAVCIntraPeriod, SetConfigVideoAVCIntraPeriod); 421 AddHandler(OMX_IndexConfigVideoNalSize, GetConfigVideoNalSize, SetConfigVideoNalSize); 422 AddHandler((OMX_INDEXTYPE)OMX_IndexConfigIntelSliceNumbers, GetConfigIntelSliceNumbers, SetConfigIntelSliceNumbers); 423 AddHandler((OMX_INDEXTYPE)OMX_IndexParamIntelAVCVUI, GetParamIntelAVCVUI, SetParamIntelAVCVUI); 424 AddHandler((OMX_INDEXTYPE)OMX_IndexParamVideoBytestream, GetParamVideoBytestream, SetParamVideoBytestream); 425 return OMX_ErrorNone; 426} 427 428OMX_ERRORTYPE OMXVideoEncoderAVC::GetParamVideoAvc(OMX_PTR pStructure) { 429 OMX_ERRORTYPE ret; 430 OMX_VIDEO_PARAM_AVCTYPE *p = (OMX_VIDEO_PARAM_AVCTYPE *)pStructure; 431 CHECK_TYPE_HEADER(p); 432 CHECK_PORT_INDEX(p, OUTPORT_INDEX); 433 434 memcpy(p, &mParamAvc, sizeof(*p)); 435 return OMX_ErrorNone; 436} 437 438OMX_ERRORTYPE OMXVideoEncoderAVC::SetParamVideoAvc(OMX_PTR pStructure) { 439 OMX_ERRORTYPE ret; 440 OMX_VIDEO_PARAM_AVCTYPE *p = (OMX_VIDEO_PARAM_AVCTYPE *)pStructure; 441 CHECK_TYPE_HEADER(p); 442 CHECK_PORT_INDEX(p, OUTPORT_INDEX); 443 CHECK_SET_PARAM_STATE(); 444 445 // TODO: do we need to check if port is enabled? 446 // TODO: see SetPortAvcParam implementation - Can we make simple copy???? 447 memcpy(&mParamAvc, p, sizeof(mParamAvc)); 448 return OMX_ErrorNone; 449} 450 451OMX_ERRORTYPE OMXVideoEncoderAVC::GetParamNalStreamFormat(OMX_PTR pStructure) { 452 OMX_ERRORTYPE ret; 453 OMX_NALSTREAMFORMATTYPE *p = (OMX_NALSTREAMFORMATTYPE *)pStructure; 454 455 CHECK_TYPE_HEADER(p); 456 CHECK_PORT_INDEX(p, OUTPORT_INDEX); 457 // TODO: check if this is desired format 458 p->eNaluFormat = mNalStreamFormat.eNaluFormat; //OMX_NaluFormatStartCodes; 459 return OMX_ErrorNone; 460} 461 462OMX_ERRORTYPE OMXVideoEncoderAVC::SetParamNalStreamFormat(OMX_PTR pStructure) { 463 OMX_ERRORTYPE ret; 464 OMX_NALSTREAMFORMATTYPE *p = (OMX_NALSTREAMFORMATTYPE *)pStructure; 465 466 CHECK_TYPE_HEADER(p); 467 CHECK_PORT_INDEX(p, OUTPORT_INDEX); 468 469 LOGV("p->eNaluFormat =%d\n",p->eNaluFormat); 470 if(p->eNaluFormat != OMX_NaluFormatStartCodes && 471 p->eNaluFormat != OMX_NaluFormatStartCodesSeparateFirstHeader && 472 p->eNaluFormat != OMX_NaluFormatOneNaluPerBuffer && 473 p->eNaluFormat != OMX_NaluFormatLengthPrefixedSeparateFirstHeader) { 474 LOGE("Format not support\n"); 475 return OMX_ErrorUnsupportedSetting; 476 } 477 mNalStreamFormat.eNaluFormat = p->eNaluFormat; 478 return OMX_ErrorNone; 479} 480 481OMX_ERRORTYPE OMXVideoEncoderAVC::GetParamNalStreamFormatSupported(OMX_PTR pStructure) { 482 OMX_ERRORTYPE ret; 483 OMX_NALSTREAMFORMATTYPE *p = (OMX_NALSTREAMFORMATTYPE *)pStructure; 484 485 CHECK_TYPE_HEADER(p); 486 CHECK_PORT_INDEX(p, OUTPORT_INDEX); 487 p->eNaluFormat = (OMX_NALUFORMATSTYPE) 488 (OMX_NaluFormatStartCodes | 489 OMX_NaluFormatStartCodesSeparateFirstHeader | 490 OMX_NaluFormatOneNaluPerBuffer| 491 OMX_NaluFormatLengthPrefixedSeparateFirstHeader); 492 493 // TODO: check if this is desired format 494 // OMX_NaluFormatFourByteInterleaveLength | 495 // OMX_NaluFormatZeroByteInterleaveLength); 496 return OMX_ErrorNone; 497} 498 499OMX_ERRORTYPE OMXVideoEncoderAVC::SetParamNalStreamFormatSupported(OMX_PTR pStructure) { 500 LOGW("SetParamNalStreamFormatSupported is not supported."); 501 return OMX_ErrorUnsupportedSetting; 502} 503 504OMX_ERRORTYPE OMXVideoEncoderAVC::GetParamNalStreamFormatSelect(OMX_PTR pStructure) { 505 LOGW("GetParamNalStreamFormatSelect is not supported."); 506 return OMX_ErrorUnsupportedSetting; 507} 508 509OMX_ERRORTYPE OMXVideoEncoderAVC::SetParamNalStreamFormatSelect(OMX_PTR pStructure) { 510 OMX_ERRORTYPE ret; 511 OMX_NALSTREAMFORMATTYPE *p = (OMX_NALSTREAMFORMATTYPE *)pStructure; 512 CHECK_TYPE_HEADER(p); 513 CHECK_PORT_INDEX(p, OUTPORT_INDEX); 514 515 // return OMX_ErrorIncorrectStateOperation if not in Loaded state 516 CHECK_SET_PARAM_STATE(); 517 518 if (p->eNaluFormat != OMX_NaluFormatStartCodes && 519 p->eNaluFormat != OMX_NaluFormatStartCodesSeparateFirstHeader && 520 p->eNaluFormat != OMX_NaluFormatOneNaluPerBuffer&& 521 p->eNaluFormat != OMX_NaluFormatLengthPrefixedSeparateFirstHeader) { 522 //p->eNaluFormat != OMX_NaluFormatFourByteInterleaveLength && 523 //p->eNaluFormat != OMX_NaluFormatZeroByteInterleaveLength) { 524 // TODO: check if this is desried 525 return OMX_ErrorBadParameter; 526 } 527 528 mNalStreamFormat = *p; 529 return OMX_ErrorNone; 530} 531 532OMX_ERRORTYPE OMXVideoEncoderAVC::GetConfigVideoAVCIntraPeriod(OMX_PTR pStructure) { 533 OMX_ERRORTYPE ret; 534 OMX_VIDEO_CONFIG_AVCINTRAPERIOD *p = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD *)pStructure; 535 536 CHECK_TYPE_HEADER(p); 537 CHECK_PORT_INDEX(p, OUTPORT_INDEX); 538 // TODO: populate mConfigAvcIntraPeriod from VideoEncoder 539 // return OMX_ErrorNotReady if VideoEncoder is not created. 540 memcpy(p, &mConfigAvcIntraPeriod, sizeof(*p)); 541 return OMX_ErrorNone; 542} 543 544OMX_ERRORTYPE OMXVideoEncoderAVC::SetConfigVideoAVCIntraPeriod(OMX_PTR pStructure) { 545 OMX_ERRORTYPE ret; 546 Encode_Status retStatus = ENCODE_SUCCESS; 547 OMX_VIDEO_CONFIG_AVCINTRAPERIOD *p = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD *)pStructure; 548 CHECK_TYPE_HEADER(p); 549 CHECK_PORT_INDEX(p, OUTPORT_INDEX); 550 551 // set in either Loaded state (ComponentSetParam) or Executing state (ComponentSetConfig) 552 mConfigAvcIntraPeriod = *p; 553 554 // return OMX_ErrorNone if not in Executing state 555 // TODO: return OMX_ErrorIncorrectStateOperation? 556 CHECK_SET_CONFIG_STATE(); 557 558 // TODO: apply AVC Intra Period configuration in Executing state 559 VideoConfigAVCIntraPeriod avcIntraPreriod; 560 avcIntraPreriod.idrInterval = mConfigAvcIntraPeriod.nIDRPeriod; 561 avcIntraPreriod.intraPeriod = mConfigAvcIntraPeriod.nPFrames; 562 retStatus = mVideoEncoder->setConfig(&avcIntraPreriod); 563 if(retStatus != ENCODE_SUCCESS) { 564 LOGW("set avc intra prerod config failed"); 565 } 566 return OMX_ErrorNone; 567} 568 569OMX_ERRORTYPE OMXVideoEncoderAVC::GetConfigVideoNalSize(OMX_PTR pStructure) { 570 OMX_ERRORTYPE ret; 571 OMX_VIDEO_CONFIG_NALSIZE *p = (OMX_VIDEO_CONFIG_NALSIZE *)pStructure; 572 573 CHECK_TYPE_HEADER(p); 574 CHECK_PORT_INDEX(p, OUTPORT_INDEX); 575 memcpy(p, &mConfigNalSize, sizeof(*p)); 576 return OMX_ErrorNone; 577} 578 579OMX_ERRORTYPE OMXVideoEncoderAVC::SetConfigVideoNalSize(OMX_PTR pStructure) { 580 OMX_ERRORTYPE ret; 581 Encode_Status retStatus = ENCODE_SUCCESS; 582 if (mParamIntelBitrate.eControlRate == OMX_Video_Intel_ControlRateMax) { 583 LOGE("SetConfigVideoNalSize failed. Feature is disabled."); 584 return OMX_ErrorUnsupportedIndex; 585 } 586 OMX_VIDEO_CONFIG_NALSIZE *p = (OMX_VIDEO_CONFIG_NALSIZE *)pStructure; 587 CHECK_TYPE_HEADER(p); 588 CHECK_PORT_INDEX(p, OUTPORT_INDEX); 589 590 // set in either Loaded state (ComponentSetParam) or Executing state (ComponentSetConfig) 591 mConfigNalSize = *p; 592 593 // return OMX_ErrorNone if not in Executing state 594 // TODO: return OMX_ErrorIncorrectStateOperation? 595 CHECK_SET_CONFIG_STATE(); 596 597 if (mParamIntelBitrate.eControlRate != OMX_Video_Intel_ControlRateVideoConferencingMode) { 598 LOGE("SetConfigVideoNalSize failed. Feature is supported only in VCM."); 599 return OMX_ErrorUnsupportedSetting; 600 } 601 VideoConfigNALSize configNalSize; 602 configNalSize.maxSliceSize = mConfigNalSize.nNaluBytes * 8; 603 retStatus = mVideoEncoder->setConfig(&configNalSize); 604 if(retStatus != ENCODE_SUCCESS) { 605 LOGW("set NAL size config failed"); 606 } 607 return OMX_ErrorNone; 608} 609 610OMX_ERRORTYPE OMXVideoEncoderAVC::GetConfigIntelSliceNumbers(OMX_PTR pStructure) { 611 OMX_ERRORTYPE ret; 612 OMX_VIDEO_CONFIG_INTEL_SLICE_NUMBERS *p = (OMX_VIDEO_CONFIG_INTEL_SLICE_NUMBERS *)pStructure; 613 614 CHECK_TYPE_HEADER(p); 615 CHECK_PORT_INDEX(p, OUTPORT_INDEX); 616 memcpy(p, &mConfigIntelSliceNumbers, sizeof(*p)); 617 return OMX_ErrorNone; 618} 619 620OMX_ERRORTYPE OMXVideoEncoderAVC::SetConfigIntelSliceNumbers(OMX_PTR pStructure) { 621 OMX_ERRORTYPE ret; 622 Encode_Status retStatus = ENCODE_SUCCESS; 623 if (mParamIntelBitrate.eControlRate == OMX_Video_Intel_ControlRateMax) { 624 LOGE("SetConfigIntelSliceNumbers failed. Feature is disabled."); 625 return OMX_ErrorUnsupportedIndex; 626 } 627 OMX_VIDEO_CONFIG_INTEL_SLICE_NUMBERS *p = (OMX_VIDEO_CONFIG_INTEL_SLICE_NUMBERS *)pStructure; 628 CHECK_TYPE_HEADER(p); 629 CHECK_PORT_INDEX(p, OUTPORT_INDEX); 630 631 // set in either Loaded state (ComponentSetParam) or Executing state (ComponentSetConfig) 632 mConfigIntelSliceNumbers = *p; 633 634 // return OMX_ErrorNone if not in Executing state 635 // TODO: return OMX_ErrorIncorrectStateOperation? 636 CHECK_SET_CONFIG_STATE(); 637 638 if (mParamIntelBitrate.eControlRate != OMX_Video_Intel_ControlRateVideoConferencingMode) { 639 LOGE("SetConfigIntelSliceNumbers failed. Feature is supported only in VCM."); 640 return OMX_ErrorUnsupportedSetting; 641 } 642 VideoConfigSliceNum sliceNum; 643 sliceNum.sliceNum.iSliceNum = mConfigIntelSliceNumbers.nISliceNumber; 644 sliceNum.sliceNum.pSliceNum = mConfigIntelSliceNumbers.nPSliceNumber; 645 retStatus = mVideoEncoder->setConfig(&sliceNum); 646 if(retStatus != ENCODE_SUCCESS) { 647 LOGW("set silce num config failed!\n"); 648 } 649 return OMX_ErrorNone; 650} 651 652OMX_ERRORTYPE OMXVideoEncoderAVC::GetParamIntelAVCVUI(OMX_PTR pStructure) { 653 654 OMX_ERRORTYPE ret; 655 OMX_VIDEO_PARAM_INTEL_AVCVUI *p = (OMX_VIDEO_PARAM_INTEL_AVCVUI *)pStructure; 656 657 CHECK_TYPE_HEADER(p); 658 CHECK_PORT_INDEX(p, OUTPORT_INDEX); 659 memcpy(p, &mParamIntelAvcVui, sizeof(*p)); 660 661 return OMX_ErrorNone; 662} 663 664OMX_ERRORTYPE OMXVideoEncoderAVC::SetParamIntelAVCVUI(OMX_PTR pStructure) { 665 666 OMX_ERRORTYPE ret; 667 OMX_VIDEO_PARAM_INTEL_AVCVUI *p = (OMX_VIDEO_PARAM_INTEL_AVCVUI *)pStructure; 668 CHECK_TYPE_HEADER(p); 669 CHECK_PORT_INDEX(p, OUTPORT_INDEX); 670 671 // set only in Loaded state (ComponentSetParam) 672 CHECK_SET_PARAM_STATE(); 673 674 mParamIntelAvcVui = *p; 675 return OMX_ErrorNone; 676} 677 678OMX_ERRORTYPE OMXVideoEncoderAVC::GetParamVideoBytestream(OMX_PTR pStructure) { 679 return OMX_ErrorUnsupportedSetting; 680} 681 682OMX_ERRORTYPE OMXVideoEncoderAVC::SetParamVideoBytestream(OMX_PTR pStructure) { 683 OMX_ERRORTYPE ret; 684 OMX_VIDEO_PARAM_BYTESTREAMTYPE *p = (OMX_VIDEO_PARAM_BYTESTREAMTYPE *)pStructure; 685 CHECK_TYPE_HEADER(p); 686 CHECK_PORT_INDEX(p, OUTPORT_INDEX); 687 688 // set only in Loaded state (ComponentSetParam) 689 CHECK_SET_PARAM_STATE(); 690 691 if (p->bBytestream == OMX_TRUE) { 692 mNalStreamFormat.eNaluFormat = OMX_NaluFormatStartCodes; 693 } else { 694 // TODO: do we need to override the Nalu format? 695 mNalStreamFormat.eNaluFormat = OMX_NaluFormatZeroByteInterleaveLength; 696 } 697 698 return OMX_ErrorNone; 699} 700 701 702DECLARE_OMX_COMPONENT("OMX.Intel.VideoEncoder.AVC", "video_encoder.avc", OMXVideoEncoderAVC); 703