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