omx_videodec_component.c

Go to the documentation of this file.
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   //common parameters related to input port
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   //common parameters related to output port
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     // IL client specified an invalid component name 
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   /* frees port/s */   
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     //omx_videodec_component_Private->avCodecContext->extradata = NULL;
00273     //omx_videodec_component_Private->avCodecContext->extradata_size = 0;
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, // The command was completed 
00475            nLen,  //to adjust the file pointer to resume the correct decode process
00476            0, // This is the input port index 
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       //Buffer is fully consumed. Request for new Input Buffer
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   /* Check which structure we are being fed and make control its header */
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         /*Check Structure Header and verify component state*/
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: /*Call the base component function*/
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   /* Check which structure we are being fed and fill its header */
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: /*Call the base component function*/
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   // Execute the base message handling
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   /* Check which structure we are being fed and fill its header */
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: // delegate to superclass
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 

Generated for OpenMAX Bellagio rel. 0.9.0 by  doxygen 1.5.1
SourceForge.net Logo