00001
00030 #include <omxcore.h>
00031 #include <omx_base_video_port.h>
00032 #include <omx_videodec_component.h>
00033 #include<OMX_Video.h>
00034
00036 #define MAX_COMPONENT_VIDEODEC 4
00037
00039 static OMX_U32 noVideoDecInstance = 0;
00040
00042 #define OUTPUT_DECODED_COLOR_FMT OMX_COLOR_FormatYUV420Planar
00043
00044 #define DEFAULT_WIDTH 352
00045 #define DEFAULT_HEIGHT 288
00046
00047 #define DEFAULT_VIDEO_OUTPUT_BUF_SIZE DEFAULT_WIDTH*DEFAULT_HEIGHT*3/2 // YUV 420P
00048
00053 OMX_ERRORTYPE omx_videodec_component_Constructor(OMX_COMPONENTTYPE *openmaxStandComp,OMX_STRING cComponentName) {
00054
00055 OMX_ERRORTYPE eError = OMX_ErrorNone;
00056 omx_videodec_component_PrivateType* omx_videodec_component_Private;
00057 omx_base_video_PortType *inPort,*outPort;
00058 OMX_U32 i;
00059
00060 if (!openmaxStandComp->pComponentPrivate) {
00061 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s, allocating component\n", __func__);
00062 openmaxStandComp->pComponentPrivate = calloc(1, sizeof(omx_videodec_component_PrivateType));
00063 if(openmaxStandComp->pComponentPrivate == NULL) {
00064 return OMX_ErrorInsufficientResources;
00065 }
00066 } else {
00067 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s, Error Component %x Already Allocated\n", __func__, (int)openmaxStandComp->pComponentPrivate);
00068 }
00069
00070 omx_videodec_component_Private = openmaxStandComp->pComponentPrivate;
00071 omx_videodec_component_Private->ports = NULL;
00072
00073 eError = omx_base_filter_Constructor(openmaxStandComp, cComponentName);
00074
00075 omx_videodec_component_Private->sPortTypesParam[OMX_PortDomainVideo].nStartPortNumber = 0;
00076 omx_videodec_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts = 2;
00077
00079 if (omx_videodec_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts && !omx_videodec_component_Private->ports) {
00080 omx_videodec_component_Private->ports = calloc(omx_videodec_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts, sizeof(omx_base_PortType *));
00081 if (!omx_videodec_component_Private->ports) {
00082 return OMX_ErrorInsufficientResources;
00083 }
00084 for (i=0; i < omx_videodec_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts; i++) {
00085 omx_videodec_component_Private->ports[i] = calloc(1, sizeof(omx_base_video_PortType));
00086 if (!omx_videodec_component_Private->ports[i]) {
00087 return OMX_ErrorInsufficientResources;
00088 }
00089 }
00090 }
00091
00092 base_video_port_Constructor(openmaxStandComp, &omx_videodec_component_Private->ports[0], 0, OMX_TRUE);
00093 base_video_port_Constructor(openmaxStandComp, &omx_videodec_component_Private->ports[1], 1, OMX_FALSE);
00094
00102
00103 inPort = (omx_base_video_PortType *)omx_videodec_component_Private->ports[OMX_BASE_FILTER_INPUTPORT_INDEX];
00104 inPort->sPortParam.nBufferSize = DEFAULT_OUT_BUFFER_SIZE;
00105 inPort->sPortParam.format.video.xFramerate = 25;
00106
00107
00108 outPort = (omx_base_video_PortType *)omx_videodec_component_Private->ports[OMX_BASE_FILTER_OUTPUTPORT_INDEX];
00109 outPort->sPortParam.format.video.eColorFormat = OUTPUT_DECODED_COLOR_FMT;
00110 outPort->sPortParam.nBufferSize = DEFAULT_VIDEO_OUTPUT_BUF_SIZE;
00111 outPort->sPortParam.format.video.xFramerate = 25;
00112
00114 outPort->sVideoParam.eColorFormat = OUTPUT_DECODED_COLOR_FMT;
00115 outPort->sVideoParam.xFramerate = 25;
00116
00118 if(!strcmp(cComponentName, VIDEO_DEC_MPEG4_NAME)) {
00119 omx_videodec_component_Private->video_coding_type = OMX_VIDEO_CodingMPEG4;
00120 } else if(!strcmp(cComponentName, VIDEO_DEC_H264_NAME)) {
00121 omx_videodec_component_Private->video_coding_type = OMX_VIDEO_CodingAVC;
00122 } else if (!strcmp(cComponentName, VIDEO_DEC_BASE_NAME)) {
00123 omx_videodec_component_Private->video_coding_type = OMX_VIDEO_CodingUnused;
00124 } else {
00125
00126 return OMX_ErrorInvalidComponentName;
00127 }
00128
00129 if(!omx_videodec_component_Private->avCodecSyncSem) {
00130 omx_videodec_component_Private->avCodecSyncSem = malloc(sizeof(tsem_t));
00131 if(omx_videodec_component_Private->avCodecSyncSem == NULL) {
00132 return OMX_ErrorInsufficientResources;
00133 }
00134 tsem_init(omx_videodec_component_Private->avCodecSyncSem, 0);
00135 }
00136
00137 SetInternalVideoParameters(openmaxStandComp);
00138
00139 omx_videodec_component_Private->eOutFramePixFmt = PIX_FMT_YUV420P;
00140
00141 if(omx_videodec_component_Private->video_coding_type == OMX_VIDEO_CodingMPEG4) {
00142 omx_videodec_component_Private->ports[OMX_BASE_FILTER_INPUTPORT_INDEX]->sPortParam.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
00143 } else {
00144 omx_videodec_component_Private->ports[OMX_BASE_FILTER_INPUTPORT_INDEX]->sPortParam.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
00145 }
00146
00150 omx_videodec_component_Private->avCodec = NULL;
00151 omx_videodec_component_Private->avCodecContext= NULL;
00152 omx_videodec_component_Private->avcodecReady = OMX_FALSE;
00153 omx_videodec_component_Private->extradata = NULL;
00154 omx_videodec_component_Private->extradata_size = 0;
00155 omx_videodec_component_Private->BufferMgmtCallback = omx_videodec_component_BufferMgmtCallback;
00156
00158 omx_videodec_component_Private->messageHandler = omx_videodec_component_MessageHandler;
00159 omx_videodec_component_Private->destructor = omx_videodec_component_Destructor;
00160 openmaxStandComp->SetParameter = omx_videodec_component_SetParameter;
00161 openmaxStandComp->GetParameter = omx_videodec_component_GetParameter;
00162 openmaxStandComp->SetConfig = omx_videodec_component_SetConfig;
00163 openmaxStandComp->ComponentRoleEnum = omx_videodec_component_ComponentRoleEnum;
00164 openmaxStandComp->GetExtensionIndex = omx_videodec_component_GetExtensionIndex;
00165
00166 noVideoDecInstance++;
00167
00168 if(noVideoDecInstance > MAX_COMPONENT_VIDEODEC) {
00169 return OMX_ErrorInsufficientResources;
00170 }
00171 return eError;
00172 }
00173
00174
00177 OMX_ERRORTYPE omx_videodec_component_Destructor(OMX_COMPONENTTYPE *openmaxStandComp) {
00178 omx_videodec_component_PrivateType* omx_videodec_component_Private = openmaxStandComp->pComponentPrivate;
00179 OMX_U32 i;
00180
00181 if(omx_videodec_component_Private->extradata) {
00182 free(omx_videodec_component_Private->extradata);
00183 omx_videodec_component_Private->extradata=NULL;
00184 }
00185
00186 if(omx_videodec_component_Private->avCodecSyncSem) {
00187 tsem_deinit(omx_videodec_component_Private->avCodecSyncSem);
00188 free(omx_videodec_component_Private->avCodecSyncSem);
00189 omx_videodec_component_Private->avCodecSyncSem = NULL;
00190 }
00191
00192
00193 if (omx_videodec_component_Private->ports) {
00194 for (i=0; i < omx_videodec_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts; i++) {
00195 if(omx_videodec_component_Private->ports[i])
00196 omx_videodec_component_Private->ports[i]->PortDestructor(omx_videodec_component_Private->ports[i]);
00197 }
00198 free(omx_videodec_component_Private->ports);
00199 omx_videodec_component_Private->ports=NULL;
00200 }
00201
00202
00203 DEBUG(DEB_LEV_FUNCTION_NAME, "Destructor of video decoder component is called\n");
00204
00205 omx_base_filter_Destructor(openmaxStandComp);
00206 noVideoDecInstance--;
00207
00208 return OMX_ErrorNone;
00209 }
00210
00211
00214 OMX_ERRORTYPE omx_videodec_component_ffmpegLibInit(omx_videodec_component_PrivateType* omx_videodec_component_Private) {
00215
00216 OMX_U32 target_codecID;
00217 avcodec_init();
00218 av_register_all();
00219
00220 DEBUG(DEB_LEV_SIMPLE_SEQ, "FFmpeg library/codec initialized\n");
00221
00222 switch(omx_videodec_component_Private->video_coding_type) {
00223 case OMX_VIDEO_CodingMPEG4 :
00224 target_codecID = CODEC_ID_MPEG4;
00225 break;
00226 case OMX_VIDEO_CodingAVC :
00227 target_codecID = CODEC_ID_H264;
00228 break;
00229 default :
00230 DEBUG(DEB_LEV_ERR, "\n codecs other than H.264 / MPEG-4 AVC are not supported -- codec not found\n");
00231 return OMX_ErrorComponentNotFound;
00232 }
00233
00235 omx_videodec_component_Private->avCodec = avcodec_find_decoder(target_codecID);
00236 if (omx_videodec_component_Private->avCodec == NULL) {
00237 DEBUG(DEB_LEV_ERR, "Codec not found\n");
00238 return OMX_ErrorInsufficientResources;
00239 }
00240
00241 omx_videodec_component_Private->avCodecContext = avcodec_alloc_context();
00242
00244 omx_videodec_component_Private->avFrame = avcodec_alloc_frame();
00245 if(omx_videodec_component_Private->extradata_size >0) {
00246 omx_videodec_component_Private->avCodecContext->extradata = omx_videodec_component_Private->extradata;
00247 omx_videodec_component_Private->avCodecContext->extradata_size = (int)omx_videodec_component_Private->extradata_size;
00248 } else {
00249 omx_videodec_component_Private->avCodecContext->flags |= CODEC_FLAG_TRUNCATED;
00250 }
00251
00252 if (avcodec_open(omx_videodec_component_Private->avCodecContext, omx_videodec_component_Private->avCodec) < 0) {
00253 DEBUG(DEB_LEV_ERR, "Could not open codec\n");
00254 return OMX_ErrorInsufficientResources;
00255 }
00256 tsem_up(omx_videodec_component_Private->avCodecSyncSem);
00257 DEBUG(DEB_LEV_SIMPLE_SEQ, "done\n");
00258
00259 return OMX_ErrorNone;
00260 }
00261
00264 void omx_videodec_component_ffmpegLibDeInit(omx_videodec_component_PrivateType* omx_videodec_component_Private) {
00265
00266 avcodec_close(omx_videodec_component_Private->avCodecContext);
00267 if (omx_videodec_component_Private->avCodecContext->priv_data) {
00268 avcodec_close (omx_videodec_component_Private->avCodecContext);
00269 }
00270 if (omx_videodec_component_Private->extradata_size == 0 && omx_videodec_component_Private->avCodecContext->extradata) {
00271 av_free (omx_videodec_component_Private->avCodecContext->extradata);
00272
00273
00274 }
00275 av_free (omx_videodec_component_Private->avCodecContext);
00276
00277 av_free(omx_videodec_component_Private->avFrame);
00278
00279 }
00280
00283 void SetInternalVideoParameters(OMX_COMPONENTTYPE *openmaxStandComp) {
00284
00285 omx_videodec_component_PrivateType* omx_videodec_component_Private;
00286 omx_base_video_PortType *inPort ;
00287
00288 omx_videodec_component_Private = openmaxStandComp->pComponentPrivate;;
00289
00290 if (omx_videodec_component_Private->video_coding_type == OMX_VIDEO_CodingMPEG4) {
00291 strcpy(omx_videodec_component_Private->ports[OMX_BASE_FILTER_INPUTPORT_INDEX]->sPortParam.format.video.cMIMEType,"video/mpeg4");
00292 omx_videodec_component_Private->ports[OMX_BASE_FILTER_INPUTPORT_INDEX]->sPortParam.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
00293
00294 setHeader(&omx_videodec_component_Private->pVideoMpeg4, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE));
00295 omx_videodec_component_Private->pVideoMpeg4.nPortIndex = 0;
00296 omx_videodec_component_Private->pVideoMpeg4.nSliceHeaderSpacing = 0;
00297 omx_videodec_component_Private->pVideoMpeg4.bSVH = OMX_FALSE;
00298 omx_videodec_component_Private->pVideoMpeg4.bGov = OMX_FALSE;
00299 omx_videodec_component_Private->pVideoMpeg4.nPFrames = 0;
00300 omx_videodec_component_Private->pVideoMpeg4.nBFrames = 0;
00301 omx_videodec_component_Private->pVideoMpeg4.nIDCVLCThreshold = 0;
00302 omx_videodec_component_Private->pVideoMpeg4.bACPred = OMX_FALSE;
00303 omx_videodec_component_Private->pVideoMpeg4.nMaxPacketSize = 0;
00304 omx_videodec_component_Private->pVideoMpeg4.nTimeIncRes = 0;
00305 omx_videodec_component_Private->pVideoMpeg4.eProfile = OMX_VIDEO_MPEG4ProfileSimple;
00306 omx_videodec_component_Private->pVideoMpeg4.eLevel = OMX_VIDEO_MPEG4Level0;
00307 omx_videodec_component_Private->pVideoMpeg4.nAllowedPictureTypes = 0;
00308 omx_videodec_component_Private->pVideoMpeg4.nHeaderExtension = 0;
00309 omx_videodec_component_Private->pVideoMpeg4.bReversibleVLC = OMX_FALSE;
00310
00311 inPort = (omx_base_video_PortType *)omx_videodec_component_Private->ports[OMX_BASE_FILTER_INPUTPORT_INDEX];
00312 inPort->sVideoParam.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
00313
00314 } else if (omx_videodec_component_Private->video_coding_type == OMX_VIDEO_CodingAVC) {
00315 strcpy(omx_videodec_component_Private->ports[OMX_BASE_FILTER_INPUTPORT_INDEX]->sPortParam.format.video.cMIMEType,"video/avc(h264)");
00316 omx_videodec_component_Private->ports[OMX_BASE_FILTER_INPUTPORT_INDEX]->sPortParam.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
00317
00318 setHeader(&omx_videodec_component_Private->pVideoAvc, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
00319 omx_videodec_component_Private->pVideoAvc.nPortIndex = 0;
00320 omx_videodec_component_Private->pVideoAvc.nSliceHeaderSpacing = 0;
00321 omx_videodec_component_Private->pVideoAvc.bUseHadamard = OMX_FALSE;
00322 omx_videodec_component_Private->pVideoAvc.nRefFrames = 2;
00323 omx_videodec_component_Private->pVideoAvc.nPFrames = 0;
00324 omx_videodec_component_Private->pVideoAvc.nBFrames = 0;
00325 omx_videodec_component_Private->pVideoAvc.bUseHadamard = OMX_FALSE;
00326 omx_videodec_component_Private->pVideoAvc.nRefFrames = 2;
00327 omx_videodec_component_Private->pVideoAvc.eProfile = OMX_VIDEO_AVCProfileBaseline;
00328 omx_videodec_component_Private->pVideoAvc.eLevel = OMX_VIDEO_AVCLevel1;
00329 omx_videodec_component_Private->pVideoAvc.nAllowedPictureTypes = 0;
00330 omx_videodec_component_Private->pVideoAvc.bFrameMBsOnly = OMX_FALSE;
00331 omx_videodec_component_Private->pVideoAvc.nRefIdx10ActiveMinus1 = 0;
00332 omx_videodec_component_Private->pVideoAvc.nRefIdx11ActiveMinus1 = 0;
00333 omx_videodec_component_Private->pVideoAvc.bEnableUEP = OMX_FALSE;
00334 omx_videodec_component_Private->pVideoAvc.bEnableFMO = OMX_FALSE;
00335 omx_videodec_component_Private->pVideoAvc.bEnableASO = OMX_FALSE;
00336 omx_videodec_component_Private->pVideoAvc.bEnableRS = OMX_FALSE;
00337
00338 omx_videodec_component_Private->pVideoAvc.bMBAFF = OMX_FALSE;
00339 omx_videodec_component_Private->pVideoAvc.bEntropyCodingCABAC = OMX_FALSE;
00340 omx_videodec_component_Private->pVideoAvc.bWeightedPPrediction = OMX_FALSE;
00341 omx_videodec_component_Private->pVideoAvc.nWeightedBipredicitonMode = 0;
00342 omx_videodec_component_Private->pVideoAvc.bconstIpred = OMX_FALSE;
00343 omx_videodec_component_Private->pVideoAvc.bDirect8x8Inference = OMX_FALSE;
00344 omx_videodec_component_Private->pVideoAvc.bDirectSpatialTemporal = OMX_FALSE;
00345 omx_videodec_component_Private->pVideoAvc.nCabacInitIdc = 0;
00346 omx_videodec_component_Private->pVideoAvc.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterDisable;
00347
00348 inPort = (omx_base_video_PortType *)omx_videodec_component_Private->ports[OMX_BASE_FILTER_INPUTPORT_INDEX];
00349 inPort->sVideoParam.eCompressionFormat = OMX_VIDEO_CodingAVC;
00350 }
00351 }
00352
00353
00356 OMX_ERRORTYPE omx_videodec_component_Init(OMX_COMPONENTTYPE *openmaxStandComp) {
00357
00358 omx_videodec_component_PrivateType* omx_videodec_component_Private = openmaxStandComp->pComponentPrivate;
00359 OMX_ERRORTYPE eError = OMX_ErrorNone;
00360
00362 omx_videodec_component_Private->inputCurrBuffer = NULL;
00363 omx_videodec_component_Private->inputCurrLength = 0;
00364 omx_videodec_component_Private->isFirstBuffer = 1;
00365 omx_videodec_component_Private->isNewBuffer = 1;
00366
00367 return eError;
00368 }
00369
00372 OMX_ERRORTYPE omx_videodec_component_Deinit(OMX_COMPONENTTYPE *openmaxStandComp) {
00373
00374 omx_videodec_component_PrivateType* omx_videodec_component_Private = openmaxStandComp->pComponentPrivate;
00375 OMX_ERRORTYPE eError = OMX_ErrorNone;
00376
00377 if (omx_videodec_component_Private->avcodecReady) {
00378 omx_videodec_component_ffmpegLibDeInit(omx_videodec_component_Private);
00379 omx_videodec_component_Private->avcodecReady = OMX_FALSE;
00380 }
00381
00382 return eError;
00383 }
00384
00387 static inline void UpdateFrameSize(OMX_COMPONENTTYPE *openmaxStandComp) {
00388 omx_videodec_component_PrivateType* omx_videodec_component_Private = openmaxStandComp->pComponentPrivate;
00389 omx_base_video_PortType *outPort = (omx_base_video_PortType *)omx_videodec_component_Private->ports[OMX_BASE_FILTER_OUTPUTPORT_INDEX];
00390 omx_base_video_PortType *inPort = (omx_base_video_PortType *)omx_videodec_component_Private->ports[OMX_BASE_FILTER_INPUTPORT_INDEX];
00391 outPort->sPortParam.format.video.nFrameWidth = inPort->sPortParam.format.video.nFrameWidth;
00392 outPort->sPortParam.format.video.nFrameHeight = inPort->sPortParam.format.video.nFrameHeight;
00393 switch(outPort->sVideoParam.eColorFormat) {
00394 case OMX_COLOR_FormatYUV420Planar:
00395 if(outPort->sPortParam.format.video.nFrameWidth && outPort->sPortParam.format.video.nFrameHeight) {
00396 outPort->sPortParam.nBufferSize = outPort->sPortParam.format.video.nFrameWidth * outPort->sPortParam.format.video.nFrameHeight * 3/2;
00397 }
00398 break;
00399 default:
00400 if(outPort->sPortParam.format.video.nFrameWidth && outPort->sPortParam.format.video.nFrameHeight) {
00401 outPort->sPortParam.nBufferSize = outPort->sPortParam.format.video.nFrameWidth * outPort->sPortParam.format.video.nFrameHeight * 3;
00402 }
00403 break;
00404 }
00405 }
00406
00409 void omx_videodec_component_BufferMgmtCallback(OMX_COMPONENTTYPE *openmaxStandComp, OMX_BUFFERHEADERTYPE* pInputBuffer, OMX_BUFFERHEADERTYPE* pOutputBuffer) {
00410
00411 omx_videodec_component_PrivateType* omx_videodec_component_Private = openmaxStandComp->pComponentPrivate;
00412 AVPicture pic;
00413
00414 OMX_S32 nOutputFilled = 0;
00415 OMX_U8* outputCurrBuffer;
00416 int nLen = 0;
00417 int internalOutputFilled=0;
00418 int nSize;
00419 struct SwsContext *imgConvertYuvCtx = NULL;
00420
00421 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00423 if(omx_videodec_component_Private->isNewBuffer) {
00424 omx_videodec_component_Private->inputCurrBuffer = pInputBuffer->pBuffer;
00425 omx_videodec_component_Private->inputCurrLength = pInputBuffer->nFilledLen;
00426 omx_videodec_component_Private->isNewBuffer = 0;
00427 DEBUG(DEB_LEV_FULL_SEQ, "New Buffer FilledLen = %d\n", (int)pInputBuffer->nFilledLen);
00428 }
00429
00430 outputCurrBuffer = pOutputBuffer->pBuffer;
00431 pOutputBuffer->nFilledLen = 0;
00432 pOutputBuffer->nOffset = 0;
00433
00434 while (!nOutputFilled) {
00435 if (omx_videodec_component_Private->isFirstBuffer) {
00436 tsem_down(omx_videodec_component_Private->avCodecSyncSem);
00437 omx_videodec_component_Private->isFirstBuffer = 0;
00438 }
00439 omx_videodec_component_Private->avCodecContext->frame_number++;
00440
00441 nLen = avcodec_decode_video(omx_videodec_component_Private->avCodecContext,
00442 omx_videodec_component_Private->avFrame,
00443 (int*)&internalOutputFilled,
00444 omx_videodec_component_Private->inputCurrBuffer,
00445 omx_videodec_component_Private->inputCurrLength);
00446
00447 if (nLen < 0) {
00448 DEBUG(DEB_LEV_ERR, "----> A general error or simply frame not decoded?\n");
00449 }
00450
00451 {
00452 omx_base_video_PortType *inPort = (omx_base_video_PortType *)omx_videodec_component_Private->ports[OMX_BASE_FILTER_INPUTPORT_INDEX];
00453 if((inPort->sPortParam.format.video.nFrameWidth != omx_videodec_component_Private->avCodecContext->width) ||
00454 (inPort->sPortParam.format.video.nFrameHeight != omx_videodec_component_Private->avCodecContext->height)) {
00455 DEBUG(DEB_LEV_SIMPLE_SEQ, "---->Sending Port Settings Change Event in video decoder\n");
00456
00457 switch(omx_videodec_component_Private->video_coding_type) {
00458 case OMX_VIDEO_CodingMPEG4 :
00459 case OMX_VIDEO_CodingAVC :
00460 inPort->sPortParam.format.video.nFrameWidth = omx_videodec_component_Private->avCodecContext->width;
00461 inPort->sPortParam.format.video.nFrameHeight = omx_videodec_component_Private->avCodecContext->height;
00462 break;
00463 default :
00464 DEBUG(DEB_LEV_ERR, "Video formats other than MPEG-4 AVC not supported\nCodec not found\n");
00465 break;
00466 }
00467
00468 UpdateFrameSize (openmaxStandComp);
00469
00471 (*(omx_videodec_component_Private->callbacks->EventHandler))
00472 (openmaxStandComp,
00473 omx_videodec_component_Private->callbackData,
00474 OMX_EventPortSettingsChanged,
00475 nLen,
00476 0,
00477 NULL);
00478 }
00479 }
00480
00481 if ( nLen >= 0 && internalOutputFilled) {
00482 omx_videodec_component_Private->inputCurrBuffer += nLen;
00483 omx_videodec_component_Private->inputCurrLength -= nLen;
00484 pInputBuffer->nFilledLen -= nLen;
00485
00486
00487 if(pInputBuffer->nFilledLen == 0) {
00488 omx_videodec_component_Private->isNewBuffer = 1;
00489 }
00490
00491 nSize = avpicture_get_size (omx_videodec_component_Private->eOutFramePixFmt,
00492 omx_videodec_component_Private->avCodecContext->width,
00493 omx_videodec_component_Private->avCodecContext->height);
00494
00495 if(pOutputBuffer->nAllocLen < nSize) {
00496 DEBUG(DEB_LEV_ERR, "Ouch!!!! Output buffer Alloc Len %d less than Frame Size %d\n",(int)pOutputBuffer->nAllocLen,nSize);
00497 return;
00498 }
00499
00500 avpicture_fill (&pic, (unsigned char*)(outputCurrBuffer),
00501 omx_videodec_component_Private->eOutFramePixFmt,
00502 omx_videodec_component_Private->avCodecContext->width,
00503 omx_videodec_component_Private->avCodecContext->height);
00504
00505 if ( !imgConvertYuvCtx ) {
00506 imgConvertYuvCtx = sws_getContext( omx_videodec_component_Private->avCodecContext->width,
00507 omx_videodec_component_Private->avCodecContext->height,
00508 omx_videodec_component_Private->avCodecContext->pix_fmt,
00509 omx_videodec_component_Private->avCodecContext->width,
00510 omx_videodec_component_Private->avCodecContext->height,
00511 omx_videodec_component_Private->eOutFramePixFmt, SWS_FAST_BILINEAR, NULL, NULL, NULL );
00512 }
00513
00514 sws_scale(imgConvertYuvCtx, omx_videodec_component_Private->avFrame->data,
00515 omx_videodec_component_Private->avFrame->linesize, 0,
00516 omx_videodec_component_Private->avCodecContext->height, pic.data, pic.linesize );
00517
00518 if (imgConvertYuvCtx ) {
00519 sws_freeContext(imgConvertYuvCtx);
00520 }
00521
00522 DEBUG(DEB_LEV_FULL_SEQ, "nSize=%d,frame linesize=%d,height=%d,pic linesize=%d PixFmt=%d\n",nSize,
00523 omx_videodec_component_Private->avFrame->linesize[0],
00524 omx_videodec_component_Private->avCodecContext->height,
00525 pic.linesize[0],omx_videodec_component_Private->eOutFramePixFmt);
00526
00527 pOutputBuffer->nFilledLen += nSize;
00528
00529 } else {
00533 pInputBuffer->nFilledLen = 0;
00537 omx_videodec_component_Private->isNewBuffer = 1;
00538 pOutputBuffer->nFilledLen = 0;
00539 }
00540
00541 nOutputFilled = 1;
00542 }
00543 DEBUG(DEB_LEV_FULL_SEQ, "One output buffer %x nLen=%d is full returning in video decoder\n",
00544 (int)pOutputBuffer->pBuffer, (int)pOutputBuffer->nFilledLen);
00545 }
00546
00547 OMX_ERRORTYPE omx_videodec_component_SetParameter(
00548 OMX_IN OMX_HANDLETYPE hComponent,
00549 OMX_IN OMX_INDEXTYPE nParamIndex,
00550 OMX_IN OMX_PTR ComponentParameterStructure) {
00551
00552 OMX_ERRORTYPE eError = OMX_ErrorNone;
00553 OMX_U32 portIndex;
00554
00555
00556 OMX_COMPONENTTYPE *openmaxStandComp = hComponent;
00557 omx_videodec_component_PrivateType* omx_videodec_component_Private = openmaxStandComp->pComponentPrivate;
00558 omx_base_video_PortType *port;
00559 if (ComponentParameterStructure == NULL) {
00560 return OMX_ErrorBadParameter;
00561 }
00562
00563 DEBUG(DEB_LEV_SIMPLE_SEQ, " Setting parameter %i\n", nParamIndex);
00564 switch(nParamIndex) {
00565 case OMX_IndexParamPortDefinition:
00566 {
00567 eError = omx_base_component_SetParameter(hComponent, nParamIndex, ComponentParameterStructure);
00568 if(eError == OMX_ErrorNone) {
00569 OMX_PARAM_PORTDEFINITIONTYPE *pPortDef = (OMX_PARAM_PORTDEFINITIONTYPE*)ComponentParameterStructure;
00570 UpdateFrameSize (openmaxStandComp);
00571 portIndex = pPortDef->nPortIndex;
00572 port = (omx_base_video_PortType *)omx_videodec_component_Private->ports[portIndex];
00573 port->sVideoParam.eColorFormat = port->sPortParam.format.video.eColorFormat;
00574 }
00575 break;
00576 }
00577 case OMX_IndexParamVideoPortFormat:
00578 {
00579 OMX_VIDEO_PARAM_PORTFORMATTYPE *pVideoPortFormat;
00580 pVideoPortFormat = ComponentParameterStructure;
00581 portIndex = pVideoPortFormat->nPortIndex;
00582
00583 eError = omx_base_component_ParameterSanityCheck(hComponent, portIndex, pVideoPortFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
00584 if(eError!=OMX_ErrorNone) {
00585 DEBUG(DEB_LEV_ERR, "In %s Parameter Check Error=%x\n",__func__,eError);
00586 break;
00587 }
00588 if (portIndex <= 1) {
00589 port = (omx_base_video_PortType *)omx_videodec_component_Private->ports[portIndex];
00590 memcpy(&port->sVideoParam, pVideoPortFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
00591 omx_videodec_component_Private->ports[portIndex]->sPortParam.format.video.eColorFormat = port->sVideoParam.eColorFormat;
00592
00593 if (portIndex == 1) {
00594 switch(port->sVideoParam.eColorFormat) {
00595 case OMX_COLOR_Format24bitRGB888 :
00596 omx_videodec_component_Private->eOutFramePixFmt = PIX_FMT_RGB24;
00597 break;
00598 case OMX_COLOR_Format24bitBGR888 :
00599 omx_videodec_component_Private->eOutFramePixFmt = PIX_FMT_BGR24;
00600 break;
00601 case OMX_COLOR_Format32bitBGRA8888 :
00602 omx_videodec_component_Private->eOutFramePixFmt = PIX_FMT_BGR32;
00603 break;
00604 case OMX_COLOR_Format32bitARGB8888 :
00605 omx_videodec_component_Private->eOutFramePixFmt = PIX_FMT_RGB32;
00606 break;
00607 case OMX_COLOR_Format16bitARGB1555 :
00608 omx_videodec_component_Private->eOutFramePixFmt = PIX_FMT_RGB555;
00609 break;
00610 case OMX_COLOR_Format16bitRGB565 :
00611 omx_videodec_component_Private->eOutFramePixFmt = PIX_FMT_RGB565;
00612 break;
00613 case OMX_COLOR_Format16bitBGR565 :
00614 omx_videodec_component_Private->eOutFramePixFmt = PIX_FMT_BGR565;
00615 break;
00616 default:
00617 omx_videodec_component_Private->eOutFramePixFmt = PIX_FMT_YUV420P;
00618 break;
00619 }
00620 UpdateFrameSize (openmaxStandComp);
00621 }
00622 } else {
00623 return OMX_ErrorBadPortIndex;
00624 }
00625 break;
00626 }
00627 case OMX_IndexParamVideoAvc:
00628 {
00629 OMX_VIDEO_PARAM_AVCTYPE *pVideoAvc;
00630 pVideoAvc = ComponentParameterStructure;
00631 portIndex = pVideoAvc->nPortIndex;
00632 eError = omx_base_component_ParameterSanityCheck(hComponent, portIndex, pVideoAvc, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
00633 if(eError!=OMX_ErrorNone) {
00634 DEBUG(DEB_LEV_ERR, "In %s Parameter Check Error=%x\n",__func__,eError);
00635 break;
00636 }
00637 memcpy(&omx_videodec_component_Private->pVideoAvc, pVideoAvc, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
00638 break;
00639 }
00640 case OMX_IndexParamStandardComponentRole:
00641 {
00642 OMX_PARAM_COMPONENTROLETYPE *pComponentRole;
00643 pComponentRole = ComponentParameterStructure;
00644 if (!strcmp((char *)pComponentRole->cRole, VIDEO_DEC_MPEG4_ROLE)) {
00645 omx_videodec_component_Private->video_coding_type = OMX_VIDEO_CodingMPEG4;
00646 } else if (!strcmp((char *)pComponentRole->cRole, VIDEO_DEC_H264_ROLE)) {
00647 omx_videodec_component_Private->video_coding_type = OMX_VIDEO_CodingAVC;
00648 } else {
00649 return OMX_ErrorBadParameter;
00650 }
00651 SetInternalVideoParameters(openmaxStandComp);
00652 break;
00653 }
00654 case OMX_IndexParamVideoMpeg4:
00655 {
00656 OMX_VIDEO_PARAM_MPEG4TYPE *pVideoMpeg4;
00657 pVideoMpeg4 = ComponentParameterStructure;
00658 portIndex = pVideoMpeg4->nPortIndex;
00659 eError = omx_base_component_ParameterSanityCheck(hComponent, portIndex, pVideoMpeg4, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE));
00660 if(eError!=OMX_ErrorNone) {
00661 DEBUG(DEB_LEV_ERR, "In %s Parameter Check Error=%x\n",__func__,eError);
00662 break;
00663 }
00664 if (pVideoMpeg4->nPortIndex == 0) {
00665 memcpy(&omx_videodec_component_Private->pVideoMpeg4, pVideoMpeg4, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE));
00666 } else {
00667 return OMX_ErrorBadPortIndex;
00668 }
00669 break;
00670 }
00671 default:
00672 return omx_base_component_SetParameter(hComponent, nParamIndex, ComponentParameterStructure);
00673 }
00674 return eError;
00675 }
00676
00677 OMX_ERRORTYPE omx_videodec_component_GetParameter(
00678 OMX_IN OMX_HANDLETYPE hComponent,
00679 OMX_IN OMX_INDEXTYPE nParamIndex,
00680 OMX_INOUT OMX_PTR ComponentParameterStructure) {
00681
00682 omx_base_video_PortType *port;
00683 OMX_ERRORTYPE eError = OMX_ErrorNone;
00684
00685 OMX_COMPONENTTYPE *openmaxStandComp = hComponent;
00686 omx_videodec_component_PrivateType* omx_videodec_component_Private = openmaxStandComp->pComponentPrivate;
00687 if (ComponentParameterStructure == NULL) {
00688 return OMX_ErrorBadParameter;
00689 }
00690 DEBUG(DEB_LEV_SIMPLE_SEQ, " Getting parameter %i\n", nParamIndex);
00691
00692 switch(nParamIndex) {
00693 case OMX_IndexParamVideoInit:
00694 if ((eError = checkHeader(ComponentParameterStructure, sizeof(OMX_PORT_PARAM_TYPE))) != OMX_ErrorNone) {
00695 break;
00696 }
00697 memcpy(ComponentParameterStructure, &omx_videodec_component_Private->sPortTypesParam[OMX_PortDomainVideo], sizeof(OMX_PORT_PARAM_TYPE));
00698 break;
00699 case OMX_IndexParamVideoPortFormat:
00700 {
00701 OMX_VIDEO_PARAM_PORTFORMATTYPE *pVideoPortFormat;
00702 pVideoPortFormat = ComponentParameterStructure;
00703 if ((eError = checkHeader(ComponentParameterStructure, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE))) != OMX_ErrorNone) {
00704 break;
00705 }
00706 if (pVideoPortFormat->nPortIndex <= 1) {
00707 port = (omx_base_video_PortType *)omx_videodec_component_Private->ports[pVideoPortFormat->nPortIndex];
00708 memcpy(pVideoPortFormat, &port->sVideoParam, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
00709 } else {
00710 return OMX_ErrorBadPortIndex;
00711 }
00712 break;
00713 }
00714 case OMX_IndexParamVideoMpeg4:
00715 {
00716 OMX_VIDEO_PARAM_MPEG4TYPE *pVideoMpeg4;
00717 pVideoMpeg4 = ComponentParameterStructure;
00718 if (pVideoMpeg4->nPortIndex != 0) {
00719 return OMX_ErrorBadPortIndex;
00720 }
00721 if ((eError = checkHeader(ComponentParameterStructure, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE))) != OMX_ErrorNone) {
00722 break;
00723 }
00724 memcpy(pVideoMpeg4, &omx_videodec_component_Private->pVideoMpeg4, sizeof(OMX_VIDEO_PARAM_MPEG4TYPE));
00725 break;
00726 }
00727 case OMX_IndexParamVideoAvc:
00728 {
00729 OMX_VIDEO_PARAM_AVCTYPE * pVideoAvc;
00730 pVideoAvc = ComponentParameterStructure;
00731 if (pVideoAvc->nPortIndex != 0) {
00732 return OMX_ErrorBadPortIndex;
00733 }
00734 if ((eError = checkHeader(ComponentParameterStructure, sizeof(OMX_VIDEO_PARAM_AVCTYPE))) != OMX_ErrorNone) {
00735 break;
00736 }
00737 memcpy(pVideoAvc, &omx_videodec_component_Private->pVideoAvc, sizeof(OMX_VIDEO_PARAM_AVCTYPE));
00738 break;
00739 }
00740 case OMX_IndexParamStandardComponentRole:
00741 {
00742 OMX_PARAM_COMPONENTROLETYPE * pComponentRole;
00743 pComponentRole = ComponentParameterStructure;
00744 if ((eError = checkHeader(ComponentParameterStructure, sizeof(OMX_PARAM_COMPONENTROLETYPE))) != OMX_ErrorNone) {
00745 break;
00746 }
00747 if (omx_videodec_component_Private->video_coding_type == OMX_VIDEO_CodingMPEG4) {
00748 strcpy((char *)pComponentRole->cRole, VIDEO_DEC_MPEG4_ROLE);
00749 } else if (omx_videodec_component_Private->video_coding_type == OMX_VIDEO_CodingAVC) {
00750 strcpy((char *)pComponentRole->cRole, VIDEO_DEC_H264_ROLE);
00751 } else {
00752 strcpy((char *)pComponentRole->cRole,"\0");
00753 }
00754 break;
00755 }
00756 default:
00757 return omx_base_component_GetParameter(hComponent, nParamIndex, ComponentParameterStructure);
00758 }
00759 return OMX_ErrorNone;
00760 }
00761
00762 OMX_ERRORTYPE omx_videodec_component_MessageHandler(OMX_COMPONENTTYPE* openmaxStandComp,internalRequestMessageType *message) {
00763 omx_videodec_component_PrivateType* omx_videodec_component_Private = (omx_videodec_component_PrivateType*)openmaxStandComp->pComponentPrivate;
00764 OMX_ERRORTYPE err;
00765 OMX_STATETYPE eCurrentState = omx_videodec_component_Private->state;
00766
00767 DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00768
00769 if (message->messageType == OMX_CommandStateSet){
00770 if ((message->messageParam == OMX_StateExecuting ) && (omx_videodec_component_Private->state == OMX_StateIdle)) {
00771 if (!omx_videodec_component_Private->avcodecReady) {
00772 err = omx_videodec_component_ffmpegLibInit(omx_videodec_component_Private);
00773 if (err != OMX_ErrorNone) {
00774 return OMX_ErrorNotReady;
00775 }
00776 omx_videodec_component_Private->avcodecReady = OMX_TRUE;
00777 }
00778 }
00779 else if ((message->messageParam == OMX_StateIdle ) && (omx_videodec_component_Private->state == OMX_StateLoaded)) {
00780 err = omx_videodec_component_Init(openmaxStandComp);
00781 if(err!=OMX_ErrorNone) {
00782 DEBUG(DEB_LEV_ERR, "In %s Video Decoder Init Failed Error=%x\n",__func__,err);
00783 return err;
00784 }
00785 } else if ((message->messageParam == OMX_StateLoaded) && (omx_videodec_component_Private->state == OMX_StateIdle)) {
00786 err = omx_videodec_component_Deinit(openmaxStandComp);
00787 if(err!=OMX_ErrorNone) {
00788 DEBUG(DEB_LEV_ERR, "In %s Video Decoder Deinit Failed Error=%x\n",__func__,err);
00789 return err;
00790 }
00791 }
00792 }
00793
00794 err = omx_base_component_MessageHandler(openmaxStandComp,message);
00795
00796 if (message->messageType == OMX_CommandStateSet){
00797 if ((message->messageParam == OMX_StateIdle ) && (eCurrentState == OMX_StateExecuting)) {
00798 if (omx_videodec_component_Private->avcodecReady) {
00799 omx_videodec_component_ffmpegLibDeInit(omx_videodec_component_Private);
00800 omx_videodec_component_Private->avcodecReady = OMX_FALSE;
00801 }
00802 }
00803 }
00804 return err;
00805 }
00806 OMX_ERRORTYPE omx_videodec_component_ComponentRoleEnum(
00807 OMX_IN OMX_HANDLETYPE hComponent,
00808 OMX_OUT OMX_U8 *cRole,
00809 OMX_IN OMX_U32 nIndex) {
00810
00811 if (nIndex == 0) {
00812 strcpy((char *)cRole, VIDEO_DEC_MPEG4_ROLE);
00813 } else if (nIndex == 1) {
00814 strcpy((char *)cRole, VIDEO_DEC_H264_ROLE);
00815 } else {
00816 return OMX_ErrorUnsupportedIndex;
00817 }
00818 return OMX_ErrorNone;
00819 }
00820
00821 OMX_ERRORTYPE omx_videodec_component_SetConfig(
00822 OMX_HANDLETYPE hComponent,
00823 OMX_INDEXTYPE nIndex,
00824 OMX_PTR pComponentConfigStructure) {
00825
00826 OMX_ERRORTYPE err = OMX_ErrorNone;
00827 OMX_VENDOR_EXTRADATATYPE* pExtradata;
00828
00829 OMX_COMPONENTTYPE *openmaxStandComp = (OMX_COMPONENTTYPE *)hComponent;
00830 omx_videodec_component_PrivateType* omx_videodec_component_Private = (omx_videodec_component_PrivateType*)openmaxStandComp->pComponentPrivate;
00831 if (pComponentConfigStructure == NULL) {
00832 return OMX_ErrorBadParameter;
00833 }
00834 DEBUG(DEB_LEV_SIMPLE_SEQ, " Getting configuration %i\n", nIndex);
00835
00836 switch (nIndex) {
00837 case OMX_IndexVendorVideoExtraData :
00838 pExtradata = (OMX_VENDOR_EXTRADATATYPE*)pComponentConfigStructure;
00839 if (pExtradata->nPortIndex <= 1) {
00841 omx_videodec_component_Private->extradata_size = (OMX_U32)pExtradata->nDataSize;
00842 if(omx_videodec_component_Private->extradata_size > 0) {
00843 if(omx_videodec_component_Private->extradata) {
00844 free(omx_videodec_component_Private->extradata);
00845 }
00846 omx_videodec_component_Private->extradata = (unsigned char *)malloc((int)pExtradata->nDataSize*sizeof(char));
00847 memcpy(omx_videodec_component_Private->extradata,(unsigned char*)(pExtradata->pData),pExtradata->nDataSize);
00848 } else {
00849 DEBUG(DEB_LEV_SIMPLE_SEQ,"extradata size is 0 !!!\n");
00850 }
00851 } else {
00852 return OMX_ErrorBadPortIndex;
00853 }
00854 break;
00855
00856 default:
00857 return omx_base_component_SetConfig(hComponent, nIndex, pComponentConfigStructure);
00858 }
00859 return err;
00860 }
00861
00862 OMX_ERRORTYPE omx_videodec_component_GetExtensionIndex(
00863 OMX_IN OMX_HANDLETYPE hComponent,
00864 OMX_IN OMX_STRING cParameterName,
00865 OMX_OUT OMX_INDEXTYPE* pIndexType) {
00866
00867 DEBUG(DEB_LEV_FUNCTION_NAME,"In %s \n",__func__);
00868
00869 if(strcmp(cParameterName,"OMX.ST.index.config.videoextradata") == 0) {
00870 *pIndexType = OMX_IndexVendorVideoExtraData;
00871 } else {
00872 return OMX_ErrorBadParameter;
00873 }
00874 return OMX_ErrorNone;
00875 }
00876