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

Generated for OpenMAX Bellagio rel. 0.3.5-svn by  doxygen 1.5.1
SourceForge.net Logo