omx_ffmpeg_colorconv_component.c

Go to the documentation of this file.
00001 
00030 #include <omxcore.h>
00031 #include <omx_ffmpeg_colorconv_component.h>
00032 
00034 #define MAX_COMPONENT_VIDEOCOLORCONV 2
00035 
00037 static OMX_U32 noVideoColorConvInstance = 0;
00038 
00039 #define DEFAULT_WIDTH 352
00040 #define DEFAULT_HEIGHT 288
00041 
00042 #define DEFAULT_VIDEO_INPUT_BUF_SIZE DEFAULT_WIDTH*DEFAULT_HEIGHT*3/2
00043 
00044 
00050 enum PixelFormat find_ffmpeg_pxlfmt(OMX_COLOR_FORMATTYPE omx_pxlfmt) {
00051   enum PixelFormat ffmpeg_pxlfmt;
00052 
00053   switch (omx_pxlfmt) {
00054     case OMX_COLOR_FormatL8:
00055       ffmpeg_pxlfmt = PIX_FMT_GRAY8;
00056       break;
00057     case OMX_COLOR_Format16bitARGB1555:
00058       ffmpeg_pxlfmt = PIX_FMT_RGB555;
00059       break;
00060     case OMX_COLOR_Format16bitRGB565:
00061     case OMX_COLOR_Format16bitBGR565:
00062       ffmpeg_pxlfmt = PIX_FMT_RGB565;
00063       break;
00064     case OMX_COLOR_Format24bitRGB888:
00065       ffmpeg_pxlfmt = PIX_FMT_RGB24;
00066       break;
00067     case OMX_COLOR_Format24bitBGR888:
00068       ffmpeg_pxlfmt = PIX_FMT_BGR24;
00069       break;
00070     case OMX_COLOR_Format32bitBGRA8888:
00071     case OMX_COLOR_Format32bitARGB8888:
00072       ffmpeg_pxlfmt = PIX_FMT_RGBA32;
00073       break;
00074     case OMX_COLOR_FormatYUV411Planar:
00075     case OMX_COLOR_FormatYUV411PackedPlanar:
00076       ffmpeg_pxlfmt = PIX_FMT_YUV411P;
00077       break;
00078     case OMX_COLOR_FormatYUV420Planar:
00079     case OMX_COLOR_FormatYUV420PackedPlanar:
00080       ffmpeg_pxlfmt = PIX_FMT_YUV420P;
00081       break;
00082     case OMX_COLOR_FormatYUV422Planar:
00083     case OMX_COLOR_FormatYUV422PackedPlanar:
00084       ffmpeg_pxlfmt = PIX_FMT_YUV422P;
00085       break;
00086     case OMX_COLOR_FormatCbYCrY:
00087       ffmpeg_pxlfmt = PIX_FMT_UYVY422;
00088       break;
00089     case OMX_COLOR_FormatMonochrome:  //  Better hope resolutions are multiples of 8
00090       ffmpeg_pxlfmt = PIX_FMT_MONOBLACK;
00091       break;
00092     case OMX_COLOR_FormatL2:
00093     case OMX_COLOR_FormatL4:
00094     case OMX_COLOR_FormatL16:
00095     case OMX_COLOR_FormatL24:
00096     case OMX_COLOR_FormatL32:
00097     case OMX_COLOR_Format8bitRGB332:
00098     case OMX_COLOR_Format12bitRGB444:
00099     case OMX_COLOR_Format16bitARGB4444:
00100     case OMX_COLOR_Format18bitRGB666:
00101     case OMX_COLOR_Format18bitARGB1665:
00102     case OMX_COLOR_Format19bitARGB1666:
00103     case OMX_COLOR_Format24bitARGB1887:
00104     case OMX_COLOR_Format25bitARGB1888:
00105     case OMX_COLOR_FormatYUV420SemiPlanar:
00106     case OMX_COLOR_FormatYUV422SemiPlanar:
00107     case OMX_COLOR_FormatYCbYCr:
00108     case OMX_COLOR_FormatYCrYCb:
00109     case OMX_COLOR_FormatCrYCbY:
00110     case OMX_COLOR_FormatYUV444Interleaved:
00111     case OMX_COLOR_FormatRawBayer8bit:
00112     case OMX_COLOR_FormatRawBayer10bit:
00113     case OMX_COLOR_FormatRawBayer8bitcompressed:
00114     case OMX_COLOR_FormatUnused:
00115     default:
00116       ffmpeg_pxlfmt = PIX_FMT_NONE;
00117       break;
00118   }
00119   return ffmpeg_pxlfmt;
00120 }
00121 
00128 OMX_S32 calcStride(OMX_U32 width, OMX_COLOR_FORMATTYPE omx_pxlfmt) {
00129   OMX_U32 stride;
00130   OMX_U32 bpp; // bit per pixel
00131 
00132   switch(omx_pxlfmt) {
00133     case OMX_COLOR_FormatMonochrome:
00134       bpp = 1;
00135       break;
00136     case OMX_COLOR_FormatL2:
00137       bpp = 2;
00138     case OMX_COLOR_FormatL4:
00139       bpp = 4;
00140       break;
00141     case OMX_COLOR_FormatL8:
00142     case OMX_COLOR_Format8bitRGB332:
00143     case OMX_COLOR_FormatRawBayer8bit:
00144     case OMX_COLOR_FormatRawBayer8bitcompressed:
00145       bpp = 8;
00146       break;
00147     case OMX_COLOR_FormatRawBayer10bit:
00148       bpp = 10;
00149       break;
00150     case OMX_COLOR_FormatYUV411Planar:
00151     case OMX_COLOR_FormatYUV411PackedPlanar:
00152     case OMX_COLOR_Format12bitRGB444:
00153     case OMX_COLOR_FormatYUV420Planar:
00154     case OMX_COLOR_FormatYUV420PackedPlanar:
00155     case OMX_COLOR_FormatYUV420SemiPlanar:
00156     case OMX_COLOR_FormatYUV444Interleaved:
00157       bpp = 12;
00158       break;
00159     case OMX_COLOR_FormatL16:
00160     case OMX_COLOR_Format16bitARGB4444:
00161     case OMX_COLOR_Format16bitARGB1555:
00162     case OMX_COLOR_Format16bitRGB565:
00163     case OMX_COLOR_Format16bitBGR565:
00164     case OMX_COLOR_FormatYUV422Planar:
00165     case OMX_COLOR_FormatYUV422PackedPlanar:
00166     case OMX_COLOR_FormatYUV422SemiPlanar:
00167     case OMX_COLOR_FormatYCbYCr:
00168     case OMX_COLOR_FormatYCrYCb:
00169     case OMX_COLOR_FormatCbYCrY:
00170     case OMX_COLOR_FormatCrYCbY:
00171       bpp = 16;
00172       break;
00173     case OMX_COLOR_Format18bitRGB666:
00174     case OMX_COLOR_Format18bitARGB1665:
00175       bpp = 18;
00176       break;
00177     case OMX_COLOR_Format19bitARGB1666:
00178       bpp = 19;
00179       break;
00180     case OMX_COLOR_FormatL24:
00181     case OMX_COLOR_Format24bitRGB888:
00182     case OMX_COLOR_Format24bitBGR888:
00183     case OMX_COLOR_Format24bitARGB1887:
00184       bpp = 24;
00185       break;
00186     case OMX_COLOR_Format25bitARGB1888:
00187       bpp = 25;
00188       break;
00189     case OMX_COLOR_FormatL32:
00190     case OMX_COLOR_Format32bitBGRA8888:
00191     case OMX_COLOR_Format32bitARGB8888:
00192       bpp = 32;
00193       break;
00194     default:
00195       bpp = 0;
00196       break;
00197   }
00198   stride = (width * bpp) >> 3;
00199   return (OMX_S32) stride;
00200 }
00201 
00206 OMX_ERRORTYPE omx_ffmpeg_colorconv_component_Constructor(OMX_COMPONENTTYPE *openmaxStandComp, OMX_STRING cComponentName) {
00207   OMX_ERRORTYPE err = OMX_ErrorNone;
00208   omx_ffmpeg_colorconv_component_PrivateType* omx_ffmpeg_colorconv_component_Private;
00209   omx_ffmpeg_colorconv_component_PortType *inPort,*outPort;
00210   OMX_U32 i;
00211 
00212   if (!openmaxStandComp->pComponentPrivate) {
00213     DEBUG(DEB_LEV_FUNCTION_NAME, "In %s, allocating component\n", __func__);
00214     openmaxStandComp->pComponentPrivate = calloc(1, sizeof(omx_ffmpeg_colorconv_component_PrivateType));
00215     if(openmaxStandComp->pComponentPrivate == NULL) {
00216       return OMX_ErrorInsufficientResources;
00217     }
00218   } else {
00219     DEBUG(DEB_LEV_FUNCTION_NAME, "In %s, Error Component %x Already Allocated\n", __func__, (int)openmaxStandComp->pComponentPrivate);
00220   }
00221 
00222   omx_ffmpeg_colorconv_component_Private = openmaxStandComp->pComponentPrivate;
00223   omx_ffmpeg_colorconv_component_Private->ports = NULL;
00224   
00228   err = omx_base_filter_Constructor(openmaxStandComp, cComponentName);
00229 
00230   omx_ffmpeg_colorconv_component_Private->sPortTypesParam[OMX_PortDomainVideo].nStartPortNumber = 0;
00231   omx_ffmpeg_colorconv_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts = 2;
00232 
00234   if (omx_ffmpeg_colorconv_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts && !omx_ffmpeg_colorconv_component_Private->ports) {
00235     omx_ffmpeg_colorconv_component_Private->ports = calloc(omx_ffmpeg_colorconv_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts, sizeof(omx_base_PortType *));
00236     if (!omx_ffmpeg_colorconv_component_Private->ports) {
00237       return OMX_ErrorInsufficientResources;
00238     }
00239     for (i=0; i < omx_ffmpeg_colorconv_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts; i++) {
00240       omx_ffmpeg_colorconv_component_Private->ports[i] = calloc(1, sizeof(omx_ffmpeg_colorconv_component_PortType));
00241       if (!omx_ffmpeg_colorconv_component_Private->ports[i]) {
00242         return OMX_ErrorInsufficientResources;
00243       }
00244     }
00245   }
00246 
00247   base_video_port_Constructor(openmaxStandComp, &omx_ffmpeg_colorconv_component_Private->ports[0], 0, OMX_TRUE);
00248   base_video_port_Constructor(openmaxStandComp, &omx_ffmpeg_colorconv_component_Private->ports[1], 1, OMX_FALSE);
00249   
00250   inPort = (omx_ffmpeg_colorconv_component_PortType *) omx_ffmpeg_colorconv_component_Private->ports[OMX_BASE_FILTER_INPUTPORT_INDEX];
00251   outPort = (omx_ffmpeg_colorconv_component_PortType *) omx_ffmpeg_colorconv_component_Private->ports[OMX_BASE_FILTER_OUTPUTPORT_INDEX];
00252 
00255   inPort->sVideoParam.eColorFormat = OMX_COLOR_FormatYUV420Planar;
00256   outPort->sVideoParam.eColorFormat = OMX_COLOR_Format24bitRGB888;
00257 
00258   //input port parameter settings
00259   inPort->sPortParam.format.video.nFrameWidth = DEFAULT_WIDTH;
00260   inPort->sPortParam.format.video.nFrameHeight = DEFAULT_HEIGHT;
00261   inPort->sPortParam.format.video.nStride = calcStride(inPort->sPortParam.format.video.nFrameWidth, inPort->sVideoParam.eColorFormat);
00262   inPort->sPortParam.format.video.nSliceHeight = inPort->sPortParam.format.video.nFrameHeight;  //  No support for slices yet
00263 
00264   inPort->sPortParam.format.video.xFramerate = 25; 
00265   inPort->ffmpeg_pxlfmt = PIX_FMT_YUV420P;
00266   inPort->sPortParam.nBufferSize = DEFAULT_VIDEO_INPUT_BUF_SIZE;
00267   inPort->sPortParam.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar;
00268   inPort->sPortParam.format.video.pNativeWindow = NULL;
00269 
00270   //output port parameter settings
00271   outPort->sPortParam.format.video.nFrameWidth = DEFAULT_WIDTH;
00272   outPort->sPortParam.format.video.nFrameHeight = DEFAULT_HEIGHT;
00273   outPort->sPortParam.format.video.nStride = calcStride(outPort->sPortParam.format.video.nFrameWidth, outPort->sVideoParam.eColorFormat);
00274   outPort->sPortParam.format.video.nSliceHeight = outPort->sPortParam.format.video.nFrameHeight;  //  No support for slices yet
00275   outPort->sPortParam.format.video.xFramerate = 25; 
00276   outPort->ffmpeg_pxlfmt = PIX_FMT_RGB24;
00277   outPort->sPortParam.nBufferSize = DEFAULT_VIDEO_INPUT_BUF_SIZE * 2;
00278   outPort->sPortParam.format.video.eColorFormat = OMX_COLOR_Format24bitRGB888;
00279 
00280   setHeader(&inPort->omxConfigCrop, sizeof(OMX_CONFIG_RECTTYPE));
00281   inPort->omxConfigCrop.nPortIndex = OMX_BASE_FILTER_INPUTPORT_INDEX;
00282   inPort->omxConfigCrop.nLeft = inPort->omxConfigCrop.nTop = 0;
00283   inPort->omxConfigCrop.nWidth = DEFAULT_WIDTH;
00284   inPort->omxConfigCrop.nHeight = DEFAULT_HEIGHT;
00285 
00286   setHeader(&inPort->omxConfigRotate, sizeof(OMX_CONFIG_ROTATIONTYPE));
00287   inPort->omxConfigRotate.nPortIndex = OMX_BASE_FILTER_INPUTPORT_INDEX;
00288   inPort->omxConfigRotate.nRotation = 0;
00289 
00290   setHeader(&inPort->omxConfigMirror, sizeof(OMX_CONFIG_MIRRORTYPE));
00291   inPort->omxConfigMirror.nPortIndex = OMX_BASE_FILTER_INPUTPORT_INDEX;
00292   inPort->omxConfigMirror.eMirror = OMX_MirrorNone;
00293 
00294   setHeader(&inPort->omxConfigScale, sizeof(OMX_CONFIG_SCALEFACTORTYPE));
00295   inPort->omxConfigScale.nPortIndex = OMX_BASE_FILTER_INPUTPORT_INDEX;
00296   inPort->omxConfigScale.xWidth = inPort->omxConfigScale.xHeight = 0x10000;
00297 
00298   setHeader(&inPort->omxConfigOutputPosition, sizeof(OMX_CONFIG_POINTTYPE));
00299   inPort->omxConfigOutputPosition.nPortIndex = OMX_BASE_FILTER_INPUTPORT_INDEX;
00300   inPort->omxConfigOutputPosition.nX = inPort->omxConfigOutputPosition.nY = 0;
00301 
00302   setHeader(&outPort->omxConfigCrop, sizeof(OMX_CONFIG_RECTTYPE));
00303   outPort->omxConfigCrop.nPortIndex = OMX_BASE_FILTER_OUTPUTPORT_INDEX;
00304   outPort->omxConfigCrop.nLeft = outPort->omxConfigCrop.nTop = 0;
00305   outPort->omxConfigCrop.nWidth = DEFAULT_WIDTH;
00306   outPort->omxConfigCrop.nHeight = DEFAULT_HEIGHT;
00307 
00308   setHeader(&outPort->omxConfigRotate, sizeof(OMX_CONFIG_ROTATIONTYPE));
00309   outPort->omxConfigRotate.nPortIndex = OMX_BASE_FILTER_OUTPUTPORT_INDEX;
00310   outPort->omxConfigRotate.nRotation = 0;
00311 
00312   setHeader(&outPort->omxConfigMirror, sizeof(OMX_CONFIG_MIRRORTYPE));
00313   outPort->omxConfigMirror.nPortIndex = OMX_BASE_FILTER_OUTPUTPORT_INDEX;
00314   outPort->omxConfigMirror.eMirror = OMX_MirrorNone;
00315 
00316   setHeader(&outPort->omxConfigScale, sizeof(OMX_CONFIG_SCALEFACTORTYPE));
00317   outPort->omxConfigScale.nPortIndex = OMX_BASE_FILTER_OUTPUTPORT_INDEX;
00318   outPort->omxConfigScale.xWidth = outPort->omxConfigScale.xHeight = 0x10000;
00319 
00320   setHeader(&outPort->omxConfigOutputPosition, sizeof(OMX_CONFIG_POINTTYPE));
00321   outPort->omxConfigOutputPosition.nPortIndex = OMX_BASE_FILTER_OUTPUTPORT_INDEX;
00322   outPort->omxConfigOutputPosition.nX = outPort->omxConfigOutputPosition.nY = 0;
00323 
00324   omx_ffmpeg_colorconv_component_Private->in_alloc_size = 0;
00325   omx_ffmpeg_colorconv_component_Private->conv_alloc_size = 0;
00326 
00327   omx_ffmpeg_colorconv_component_Private->in_buffer = NULL;
00328   omx_ffmpeg_colorconv_component_Private->conv_buffer = NULL;
00329 
00330   omx_ffmpeg_colorconv_component_Private->messageHandler = omx_video_colorconv_MessageHandler;
00331   omx_ffmpeg_colorconv_component_Private->destructor = omx_ffmpeg_colorconv_component_Destructor;
00332   omx_ffmpeg_colorconv_component_Private->BufferMgmtCallback = omx_ffmpeg_colorconv_component_BufferMgmtCallback;
00333   openmaxStandComp->SetParameter = omx_ffmpeg_colorconv_component_SetParameter;
00334   openmaxStandComp->GetParameter = omx_ffmpeg_colorconv_component_GetParameter;
00335   openmaxStandComp->SetConfig = omx_ffmpeg_colorconv_component_SetConfig;
00336   openmaxStandComp->GetConfig = omx_ffmpeg_colorconv_component_GetConfig;
00337   openmaxStandComp->UseEGLImage = omx_video_colorconv_UseEGLImage;
00338   noVideoColorConvInstance++;
00339 
00340   if(noVideoColorConvInstance > MAX_COMPONENT_VIDEOCOLORCONV) {
00341     return OMX_ErrorInsufficientResources;
00342   }
00343   return err;
00344 }
00345 
00348 OMX_ERRORTYPE omx_ffmpeg_colorconv_component_Destructor(OMX_COMPONENTTYPE *openmaxStandComp) {
00349   omx_ffmpeg_colorconv_component_PrivateType* omx_ffmpeg_colorconv_component_Private = openmaxStandComp->pComponentPrivate;
00350   OMX_U32 i;
00351 
00352   DEBUG(DEB_LEV_FUNCTION_NAME, "Destructor of video color converter component is called\n");
00353 
00354   /* frees port/s */
00355   if (omx_ffmpeg_colorconv_component_Private->ports) {
00356     for (i=0; i < omx_ffmpeg_colorconv_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts; i++) {
00357       if(omx_ffmpeg_colorconv_component_Private->ports[i])
00358         omx_ffmpeg_colorconv_component_Private->ports[i]->PortDestructor(omx_ffmpeg_colorconv_component_Private->ports[i]);
00359     }
00360     free(omx_ffmpeg_colorconv_component_Private->ports);
00361     omx_ffmpeg_colorconv_component_Private->ports=NULL;
00362   }
00363 
00364   omx_base_filter_Destructor(openmaxStandComp);
00365   noVideoColorConvInstance--;
00366 
00367   return OMX_ErrorNone;
00368 }
00369 
00370 
00374 OMX_ERRORTYPE omx_ffmpeg_colorconv_component_Init(OMX_COMPONENTTYPE *openmaxStandComp) {
00375 
00376   OMX_ERRORTYPE err = OMX_ErrorNone;
00377   omx_ffmpeg_colorconv_component_PrivateType* omx_ffmpeg_colorconv_component_Private = openmaxStandComp->pComponentPrivate;
00378   omx_ffmpeg_colorconv_component_PortType *inPort,*outPort;
00379   OMX_U32 in_width, in_height, out_width, out_height;
00380 
00381   inPort = (omx_ffmpeg_colorconv_component_PortType *) omx_ffmpeg_colorconv_component_Private->ports[OMX_BASE_FILTER_INPUTPORT_INDEX];
00382   outPort = (omx_ffmpeg_colorconv_component_PortType *) omx_ffmpeg_colorconv_component_Private->ports[OMX_BASE_FILTER_OUTPUTPORT_INDEX];
00383 
00384   in_width = inPort->sPortParam.format.video.nFrameWidth;
00385   in_height = inPort->sPortParam.format.video.nFrameHeight;
00386   out_width = outPort->sPortParam.format.video.nFrameWidth;
00387   out_height = outPort->sPortParam.format.video.nFrameHeight;
00388 
00389   omx_ffmpeg_colorconv_component_Private->in_alloc_size = avpicture_get_size(inPort->ffmpeg_pxlfmt, 
00390   inPort->sPortParam.format.video.nFrameWidth, inPort->sPortParam.format.video.nFrameHeight);
00391 
00392   omx_ffmpeg_colorconv_component_Private->in_buffer = malloc(omx_ffmpeg_colorconv_component_Private->in_alloc_size);
00393 
00394   if (omx_ffmpeg_colorconv_component_Private->in_buffer == NULL) {
00395     DEBUG(DEB_LEV_ERR, "\nError allocating internal input buffer!\n");
00396     return OMX_ErrorInsufficientResources;
00397   }
00398 
00399   omx_ffmpeg_colorconv_component_Private->conv_alloc_size = avpicture_get_size(outPort->ffmpeg_pxlfmt,
00400               inPort->sPortParam.format.video.nFrameWidth, inPort->sPortParam.format.video.nFrameHeight);
00401 
00402   omx_ffmpeg_colorconv_component_Private->conv_buffer = malloc(omx_ffmpeg_colorconv_component_Private->conv_alloc_size);
00403 
00404   if (omx_ffmpeg_colorconv_component_Private->conv_buffer == NULL) {
00405     DEBUG(DEB_LEV_ERR, "\nError allocating internal conversion buffer! size : %d \n", 
00406     omx_ffmpeg_colorconv_component_Private->conv_alloc_size);
00407     return OMX_ErrorInsufficientResources;
00408   } 
00409   av_register_all();
00410   omx_ffmpeg_colorconv_component_Private->in_frame = avcodec_alloc_frame();
00411   omx_ffmpeg_colorconv_component_Private->conv_frame = avcodec_alloc_frame();
00412 
00413   return err;
00414 };
00415 
00419 OMX_ERRORTYPE omx_ffmpeg_colorconv_component_Deinit(OMX_COMPONENTTYPE *openmaxStandComp) {
00420 
00421   OMX_ERRORTYPE err = OMX_ErrorNone;
00422   omx_ffmpeg_colorconv_component_PrivateType* omx_ffmpeg_colorconv_component_Private = openmaxStandComp->pComponentPrivate;
00423 
00424   if (omx_ffmpeg_colorconv_component_Private->in_buffer) {
00425     free(omx_ffmpeg_colorconv_component_Private->in_buffer);
00426     omx_ffmpeg_colorconv_component_Private->in_buffer = NULL;
00427   }
00428   if (omx_ffmpeg_colorconv_component_Private->conv_buffer) {
00429     free(omx_ffmpeg_colorconv_component_Private->conv_buffer);
00430     omx_ffmpeg_colorconv_component_Private->conv_buffer = NULL;
00431   }
00432   omx_ffmpeg_colorconv_component_Private->in_alloc_size = 0;
00433   omx_ffmpeg_colorconv_component_Private->conv_alloc_size = 0;
00434   if (omx_ffmpeg_colorconv_component_Private->in_frame) {
00435     av_free(omx_ffmpeg_colorconv_component_Private->in_frame);
00436     omx_ffmpeg_colorconv_component_Private->in_frame = NULL;
00437   }
00438   if (omx_ffmpeg_colorconv_component_Private->conv_frame) {
00439     av_free(omx_ffmpeg_colorconv_component_Private->conv_frame);
00440     omx_ffmpeg_colorconv_component_Private->conv_frame = NULL;
00441   }
00442 
00443   return err;
00444 }
00445 
00446 
00464 void omx_img_copy(OMX_U8* src_ptr, OMX_S32 src_stride, OMX_U32 src_width, OMX_U32 src_height, 
00465                   OMX_S32 src_offset_x, OMX_S32 src_offset_y,
00466                   OMX_U8* dest_ptr, OMX_S32 dest_stride, OMX_U32 dest_width,  OMX_U32 dest_height, 
00467                   OMX_S32 dest_offset_x, OMX_S32 dest_offset_y, 
00468                   OMX_S32 cpy_width, OMX_U32 cpy_height, OMX_COLOR_FORMATTYPE colorformat ) {
00469 
00470   OMX_U32 i;
00471   //  CAUTION: We don't do any checking of boundaries! (FIXME - see omx_ffmpeg_colorconv_component_BufferMgmtCallback)
00472   if (colorformat == OMX_COLOR_FormatYUV411Planar ||                    //  Input frame is planar, not interleaved
00473       colorformat == OMX_COLOR_FormatYUV411PackedPlanar ||              //  Feel free to add more formats if implementing them
00474       colorformat == OMX_COLOR_FormatYUV420Planar ||
00475       colorformat == OMX_COLOR_FormatYUV420PackedPlanar ||
00476       colorformat == OMX_COLOR_FormatYUV422Planar ||
00477       colorformat == OMX_COLOR_FormatYUV422PackedPlanar ) {
00478 
00479     OMX_U32 src_luma_width;         //  Width (in columns) of the source Y plane
00480     OMX_U32 src_luma_height;        //  Height (in rows) of source Y plane
00481     OMX_S32 src_luma_stride;        //  Stride in bytes of each source Y row
00482     OMX_U32 src_luma_offset_x;      //  Horizontal byte offset
00483     OMX_U32 src_luma_offset_y;      //  Vertical offset in rows from top of plane
00484     OMX_U32 src_luma_offset;        //  Total byte offset to rectangle
00485 
00486     OMX_U32 src_chroma_width;       //  Width (in columns) of source chroma planes
00487     OMX_U32 src_chroma_height;      //  Height (in rows) of source chroma planes
00488     OMX_S32 src_chroma_stride;      //  Stride in bytes of each source chroma row
00489     OMX_U32 src_chroma_offset_x;    //  Horizontal byte offset
00490     OMX_U32 src_chroma_offset_y;    //  Vertical offset in rows from top of plane
00491     OMX_U32 src_chroma_offset;      //  Bytes to crop rectangle from start of chroma plane
00492 
00493     OMX_U32 dest_luma_width;        //  Width (in columns) of the destination Y plane
00494     OMX_U32 dest_luma_height;       //  Height (in rows) of destination Y plane
00495     OMX_S32 dest_luma_stride;       //  Stride in bytes of each destination Y row
00496     OMX_U32 dest_luma_offset_x;     //  Horizontal byte offset
00497     OMX_U32 dest_luma_offset_y;     //  Vertical offset in rows from top of plane
00498     OMX_U32 dest_luma_offset;       //  Bytes to crop rectangle from start of Y plane
00499 
00500     OMX_U32 dest_chroma_width;      //  Width (in columns) of destination chroma planes
00501     OMX_U32 dest_chroma_height;     //  Height (in rows) of destination chroma planes
00502     OMX_S32 dest_chroma_stride;     //  Stride in bytes of each destination chroma row
00503     OMX_U32 dest_chroma_offset_x;   //  Horizontal byte offset
00504     OMX_U32 dest_chroma_offset_y;   //  Vertical offset in rows from top of plane
00505     OMX_U32 dest_chroma_offset;     //  Bytes to crop rectangle from start of chroma plane
00506 
00507     OMX_U32 luma_crop_width;        //  Width in bytes of a luma row in the crop rectangle
00508     OMX_U32 luma_crop_height;       //  Number of luma rows in the crop rectangle
00509     OMX_U32 chroma_crop_width;      //  Width in bytes of a chroma row in the crop rectangle
00510     OMX_U32 chroma_crop_height;     //  Number of chroma rows in crop rectangle
00511 
00512     switch (colorformat) {
00513       //  Watch out for odd or non-multiple-of-4 (4:1:1) luma resolutions (I don't check)    
00514       case OMX_COLOR_FormatYUV411Planar:    //  Planar vs. PackedPlanar will have to be handled differently if/when slicing is implemented
00515       case OMX_COLOR_FormatYUV411PackedPlanar:
00520         src_luma_width = src_width;
00521         src_luma_height = src_height;
00522         src_luma_stride = (OMX_S32) src_luma_width;
00523         src_luma_offset_x = src_offset_x;
00524         src_luma_offset_y = src_offset_y;
00525 
00526         src_chroma_width = src_luma_width  >> 2; 
00527         src_chroma_height = src_luma_height;
00528         src_chroma_stride = (OMX_S32) src_chroma_width;
00529         src_chroma_offset_x = src_luma_offset_x  >> 2; 
00530         src_chroma_offset_y = src_luma_offset_y;
00531 
00532         dest_luma_width = dest_width;
00533         dest_luma_height = dest_height;
00534         dest_luma_stride = (OMX_S32) dest_luma_width;
00535         dest_luma_offset_x = dest_offset_x;
00536         dest_luma_offset_y = dest_offset_y;
00537 
00538         dest_chroma_width = dest_luma_width  >> 2;
00539         dest_chroma_height = dest_luma_height;
00540         dest_chroma_stride = (OMX_S32) dest_chroma_width;
00541         dest_chroma_offset_x = dest_luma_offset_x  >> 2; 
00542         dest_chroma_offset_y = dest_luma_offset_y;
00543 
00544         luma_crop_width = (OMX_U32) abs(cpy_width);
00545         luma_crop_height = cpy_height;
00546         chroma_crop_width = luma_crop_width  >> 2; 
00547         chroma_crop_height = luma_crop_height;
00548         break;
00549 
00550       //  Planar vs. PackedPlanar will have to be handled differently if/when slicing is implemented
00551       case OMX_COLOR_FormatYUV420Planar:
00552       case OMX_COLOR_FormatYUV420PackedPlanar:
00553         src_luma_width = src_width;
00554         src_luma_height = src_height;
00555         src_luma_stride = (OMX_S32) src_luma_width;
00556         src_luma_offset_x = src_offset_x;
00557         src_luma_offset_y = src_offset_y;
00558 
00559         src_chroma_width = src_luma_width >> 1;
00560         src_chroma_height = src_luma_height >> 1;
00561         src_chroma_stride = (OMX_S32) src_chroma_width;
00562         src_chroma_offset_x = src_luma_offset_x >> 1;
00563         src_chroma_offset_y = src_luma_offset_y >> 1;
00564 
00565         dest_luma_width = dest_width;
00566         dest_luma_height = dest_height;
00567         dest_luma_stride = (OMX_S32) dest_luma_width;
00568         dest_luma_offset_x = dest_offset_x;
00569         dest_luma_offset_y = dest_offset_y;
00570 
00571         dest_chroma_width = dest_luma_width >> 1;
00572         dest_chroma_height = dest_luma_height >> 1;
00573         dest_chroma_stride = (OMX_S32) dest_chroma_width;
00574         dest_chroma_offset_x = dest_luma_offset_x >> 1;
00575         dest_chroma_offset_y = dest_luma_offset_y >> 1;
00576 
00577         luma_crop_width = cpy_width;
00578         luma_crop_height = cpy_height;
00579         chroma_crop_width = luma_crop_width >> 1;
00580         chroma_crop_height = luma_crop_height >> 1;
00581         break;
00582 
00583       //  Planar vs. PackedPlanar will have to be handled differently if/when slicing is implemented
00584       case OMX_COLOR_FormatYUV422Planar:
00585       case OMX_COLOR_FormatYUV422PackedPlanar:
00586         src_luma_width = src_width;
00587         src_luma_height = src_height;
00588         src_luma_stride = (OMX_S32) src_luma_width;
00589         src_luma_offset_x = src_offset_x;
00590         src_luma_offset_y = src_offset_y;
00591 
00592         src_chroma_width = src_luma_width >> 1;
00593         src_chroma_height = src_luma_height;
00594         src_chroma_stride = (OMX_S32) src_chroma_width;
00595         src_chroma_offset_x = src_luma_offset_x >> 1;
00596         src_chroma_offset_y = src_luma_offset_y;
00597 
00598         dest_luma_width = dest_width;
00599         dest_luma_height = dest_height;
00600         dest_luma_stride = (OMX_S32) dest_luma_width;
00601         dest_luma_offset_x = dest_offset_x;
00602         dest_luma_offset_y = dest_offset_y;
00603 
00604         dest_chroma_width = dest_luma_width >> 1;
00605         dest_chroma_height = dest_luma_height;
00606         dest_chroma_stride = (OMX_S32) dest_chroma_width;
00607         dest_chroma_offset_x = dest_luma_offset_x >> 1;
00608         dest_chroma_offset_y = dest_luma_offset_y;
00609 
00610         luma_crop_width = (OMX_U32) abs(cpy_width);
00611         luma_crop_height = cpy_height;
00612         chroma_crop_width = luma_crop_width >> 1;
00613         chroma_crop_height = luma_crop_height;
00614         break;
00615 
00616       default:
00617         DEBUG(DEB_LEV_ERR,"\n color format not supported --error \n");
00618         return;
00619     }
00620 
00622     OMX_U8* Y_input_ptr = src_ptr;
00623     OMX_U8* U_input_ptr = Y_input_ptr + ((OMX_U32) abs(src_luma_stride) * src_luma_height);
00624     OMX_U8* V_input_ptr = U_input_ptr + ((OMX_U32) abs(src_chroma_stride) * src_chroma_height);
00625 
00627     src_luma_offset = (src_luma_offset_y * (OMX_U32) abs(src_luma_stride)) + src_luma_offset_x;
00628     src_chroma_offset = (src_chroma_offset_y * (OMX_U32) abs(src_chroma_stride)) + src_chroma_offset_x;
00629 
00631     if (src_stride < 0) {
00632       src_luma_offset += ((OMX_U32) abs(src_luma_stride)) * (src_luma_height - 1);
00633       src_chroma_offset += ((OMX_U32) abs(src_chroma_stride)) * (src_chroma_height - 1);
00634 
00635       if (src_luma_stride > 0) {
00636         src_luma_stride *= -1;
00637       }
00638 
00639       if (src_chroma_stride > 0) {
00640         src_chroma_stride *= -1;
00641       }
00642     }
00643 
00645     OMX_U8* src_Y_ptr = Y_input_ptr + src_luma_offset;
00646     OMX_U8* src_U_ptr = U_input_ptr + src_chroma_offset;
00647     OMX_U8* src_V_ptr = V_input_ptr + src_chroma_offset;
00648 
00650     OMX_U8* Y_output_ptr = dest_ptr;
00651     OMX_U8* U_output_ptr = Y_output_ptr + ((OMX_U32) abs(dest_luma_stride) * dest_luma_height);
00652     OMX_U8* V_output_ptr = U_output_ptr + ((OMX_U32) abs(dest_chroma_stride) * dest_chroma_height);
00653 
00655     dest_luma_offset = (dest_luma_offset_y * (OMX_U32) abs(dest_luma_stride)) + dest_luma_offset_x;
00656     dest_chroma_offset = (dest_chroma_offset_y * (OMX_U32) abs(dest_chroma_stride)) + dest_chroma_offset_x;
00657 
00659     if (dest_stride < 0) {
00660       dest_luma_offset += ((OMX_U32) abs(dest_luma_stride)) * (dest_luma_height - 1);
00661       dest_chroma_offset += ((OMX_U32) abs(dest_chroma_stride)) * (dest_chroma_height - 1);
00662 
00663       if (dest_luma_stride > 0) {
00664         dest_luma_stride *= -1;
00665       }
00666 
00667       if (dest_chroma_stride > 0) {
00668         dest_chroma_stride *= -1;
00669       }
00670     }
00671 
00673     OMX_U8* dest_Y_ptr = Y_output_ptr + dest_luma_offset;
00674     OMX_U8* dest_U_ptr = U_output_ptr + dest_chroma_offset;
00675     OMX_U8* dest_V_ptr = V_output_ptr + dest_chroma_offset;
00676 
00677     //  Y
00678     for (i = 0; i < luma_crop_height; ++i, src_Y_ptr += src_luma_stride, dest_Y_ptr += dest_luma_stride) {
00679       memcpy(dest_Y_ptr, src_Y_ptr, luma_crop_width);   //  Copy Y rows into in_buffer
00680     }
00681     //  U & V
00682     for (i = 0; i < chroma_crop_height; ++i, src_U_ptr += src_chroma_stride, dest_U_ptr += dest_chroma_stride, src_V_ptr += src_chroma_stride, dest_V_ptr += dest_chroma_stride) {
00683       memcpy(dest_U_ptr, src_U_ptr, chroma_crop_width); //  Copy U rows into in_buffer
00684       memcpy(dest_V_ptr, src_V_ptr, chroma_crop_width); //  Copy V rows into in_buffer
00685     }
00686     // V
00687     //for (i = 0; i < chroma_crop_height; ++i, src_V_ptr += src_chroma_stride, dest_V_ptr += dest_chroma_stride) {
00688     //  memcpy(dest_V_ptr, src_V_ptr, chroma_crop_width);  //  Copy V rows into in_buffer
00689     //}
00690   } else {
00691     OMX_U32 cpy_byte_width = calcStride((OMX_U32) abs(cpy_width), colorformat);  //  Bytes width to copy
00692 
00693     OMX_U32 src_byte_offset_x = calcStride((OMX_U32) abs(src_offset_x), colorformat);
00694     OMX_U32 dest_byte_offset_x = calcStride((OMX_U32) abs(dest_offset_x), colorformat);
00695 
00696     OMX_U32 src_byte_offset_y = src_offset_y * (OMX_U32) abs(src_stride);
00697     OMX_U32 dest_byte_offset_y = dest_offset_y * (OMX_U32) abs(dest_stride);
00698 
00699     if (src_stride < 0) {
00700       //  If input stride is negative, start from bottom
00701       src_byte_offset_y += cpy_height * (OMX_U32) abs(src_stride);
00702     }
00703     if (dest_stride < 0) {
00704       //  If output stride is negative, start from bottom
00705       dest_byte_offset_y += cpy_height * (OMX_U32) abs(dest_stride);
00706     }
00707 
00708     OMX_U8* src_cpy_ptr = src_ptr + src_byte_offset_y + src_byte_offset_x;
00709     OMX_U8* dest_cpy_ptr = dest_ptr + dest_byte_offset_y + dest_byte_offset_x;
00710 
00711     for (i = 0; i < cpy_height; ++i, src_cpy_ptr += src_stride, dest_cpy_ptr += dest_stride) {
00712       memcpy(dest_cpy_ptr, src_cpy_ptr, cpy_byte_width);  //  Copy rows
00713     }
00714   }
00715 }
00716 
00717 
00720 void omx_ffmpeg_colorconv_component_BufferMgmtCallback(OMX_COMPONENTTYPE *openmaxStandComp, OMX_BUFFERHEADERTYPE* pInputBuffer, OMX_BUFFERHEADERTYPE* pOutputBuffer) {
00721 
00722   omx_ffmpeg_colorconv_component_PrivateType* omx_ffmpeg_colorconv_component_Private = openmaxStandComp->pComponentPrivate;
00723   omx_ffmpeg_colorconv_component_PortType *inPort = (omx_ffmpeg_colorconv_component_PortType *)omx_ffmpeg_colorconv_component_Private->ports[OMX_BASE_FILTER_INPUTPORT_INDEX];
00724   omx_ffmpeg_colorconv_component_PortType *outPort = (omx_ffmpeg_colorconv_component_PortType *)omx_ffmpeg_colorconv_component_Private->ports[OMX_BASE_FILTER_OUTPUTPORT_INDEX];
00725 
00726   OMX_COLOR_FORMATTYPE input_colorformat = inPort->sVideoParam.eColorFormat;
00727   OMX_S32 input_cpy_width = (OMX_S32) inPort->omxConfigCrop.nWidth;      //  Width (in columns) of the crop rectangle
00728   OMX_U32 input_cpy_height = inPort->omxConfigCrop.nHeight;              //  Height (in rows) of the crop rectangle
00729 
00730   OMX_U8* input_src_ptr = (OMX_U8*) (pInputBuffer->pBuffer);
00731   OMX_S32 input_src_stride = inPort->sPortParam.format.video.nStride;    //  Negative means bottom-to-top (think Windows bmp)
00732   OMX_U32 input_src_width = inPort->sPortParam.format.video.nFrameWidth;
00733   OMX_U32 input_src_height = inPort->sPortParam.format.video.nSliceHeight;
00734   struct SwsContext *imgConvertYuvCtx = NULL;
00735 
00741   OMX_S32 input_src_offset_x = inPort->omxConfigCrop.nLeft;  //  Offset (in columns) to left side of crop rectangle
00742   OMX_S32 input_src_offset_y = inPort->omxConfigCrop.nTop;    //  Offset (in rows) from top of the image to crop rectangle
00743 
00744   OMX_U8* input_dest_ptr = (OMX_U8*) omx_ffmpeg_colorconv_component_Private->in_buffer;
00745   OMX_S32 input_dest_stride = (input_src_stride < 0) ? -1 * calcStride(input_cpy_width, input_colorformat) : calcStride(input_cpy_width, input_colorformat);
00746   if (inPort->omxConfigMirror.eMirror == OMX_MirrorVertical || inPort->omxConfigMirror.eMirror == OMX_MirrorBoth) {
00747     input_dest_stride *= -1;
00748   }
00749   OMX_U32 input_dest_width = input_cpy_width;
00750   OMX_U32 input_dest_height = input_cpy_height;
00751   OMX_U32 input_dest_offset_x = 0;
00752   OMX_U32 input_dest_offset_y = 0;
00753 
00754   OMX_U8* output_src_ptr = (OMX_U8*) omx_ffmpeg_colorconv_component_Private->conv_buffer;
00755   OMX_COLOR_FORMATTYPE output_colorformat = outPort->sVideoParam.eColorFormat;
00756   OMX_U32 output_cpy_width = outPort->omxConfigCrop.nWidth;                   //  Width (in columns) of the crop rectangle
00757   OMX_U32 output_cpy_height = outPort->omxConfigCrop.nHeight;                 //  Height (in rows) of the crop rectangle
00758   OMX_S32 output_dest_stride = outPort->sPortParam.format.video.nStride;      //  Negative means bottom-to-top (think Windows bmp)  
00759   OMX_S32 output_src_stride = (output_dest_stride < 0) ? -1 * calcStride(input_cpy_width, output_colorformat) : calcStride(input_cpy_width, output_colorformat);
00760   if (outPort->omxConfigMirror.eMirror == OMX_MirrorVertical || outPort->omxConfigMirror.eMirror == OMX_MirrorBoth) {
00761     output_src_stride *= -1;
00762   }
00763   OMX_U32 output_src_width = input_cpy_width;
00764   OMX_U32 output_src_height = input_cpy_height;
00765   OMX_S32 output_src_offset_x = outPort->omxConfigCrop.nLeft;   //  Offset (in columns) to left side of crop rectangle
00766   OMX_S32 output_src_offset_y = outPort->omxConfigCrop.nTop;    //  Offset (in rows) from top of the image to crop rectangle
00767 
00768   OMX_U8* output_dest_ptr = (OMX_U8*) (pOutputBuffer->pBuffer);
00769   OMX_U32 output_dest_width = outPort->sPortParam.format.video.nFrameWidth;
00770 
00771   OMX_U32 output_dest_height = outPort->sPortParam.format.video.nSliceHeight;
00772   OMX_S32 output_dest_offset_x = outPort->omxConfigOutputPosition.nX;
00773   OMX_S32 output_dest_offset_y = outPort->omxConfigOutputPosition.nY;
00774 
00775   avpicture_fill((AVPicture*) omx_ffmpeg_colorconv_component_Private->in_frame, omx_ffmpeg_colorconv_component_Private->in_buffer, inPort->ffmpeg_pxlfmt, input_dest_width, input_dest_height);
00776   avpicture_fill((AVPicture*) omx_ffmpeg_colorconv_component_Private->conv_frame, omx_ffmpeg_colorconv_component_Private->conv_buffer, outPort->ffmpeg_pxlfmt, output_src_width, output_src_height);
00777 
00778   //  Copy image data into in_buffer
00779   omx_img_copy(input_src_ptr, input_src_stride, input_src_width, input_src_height, input_src_offset_x, input_src_offset_y,
00780                 input_dest_ptr, input_dest_stride, input_dest_width, input_dest_height, input_dest_offset_x, input_dest_offset_y,
00781                 input_cpy_width, input_cpy_height, input_colorformat);
00782 
00783   pInputBuffer->nFilledLen = 0;
00784 
00785   //  Use swscale to convert the colors into conv_buffer
00786   if ( !imgConvertYuvCtx ) {
00787     imgConvertYuvCtx = sws_getContext(input_src_width, 
00788                                       input_src_height, 
00789                                       inPort->ffmpeg_pxlfmt,
00790                                       input_dest_width,
00791                                       input_dest_height,
00792                                       outPort->ffmpeg_pxlfmt, SWS_FAST_BILINEAR, NULL, NULL, NULL );
00793   }
00794 
00795   sws_scale(imgConvertYuvCtx, omx_ffmpeg_colorconv_component_Private->in_frame->data, 
00796             omx_ffmpeg_colorconv_component_Private->in_frame->linesize, 0, 
00797             input_src_height, 
00798             omx_ffmpeg_colorconv_component_Private->conv_frame->data, 
00799             omx_ffmpeg_colorconv_component_Private->conv_frame->linesize );
00800 
00801   omx_img_copy( output_src_ptr, output_src_stride, output_src_width, output_src_height, 
00802                 output_src_offset_x, output_src_offset_y,output_dest_ptr, output_dest_stride, output_dest_width, 
00803                 output_dest_height, output_dest_offset_x, output_dest_offset_y,
00804                 output_cpy_width, output_cpy_height, output_colorformat);
00805 
00806   pOutputBuffer->nFilledLen = (OMX_U32) abs(output_dest_stride) * output_dest_height;
00807 
00808   DEBUG(DEB_LEV_FULL_SEQ, "in %s One output buffer %x len=%d is full returning in color converter\n", 
00809           __func__, (int)pOutputBuffer->pBuffer, (int)pOutputBuffer->nFilledLen);
00810 }
00811 
00812 
00813 OMX_ERRORTYPE omx_ffmpeg_colorconv_component_SetConfig(
00814   OMX_HANDLETYPE hComponent,
00815   OMX_INDEXTYPE nIndex,
00816   OMX_PTR pComponentConfigStructure) {
00817 
00818   OMX_U32 portIndex;
00819   // Possible configs to set
00820   OMX_CONFIG_RECTTYPE *omxConfigCrop;
00821   OMX_CONFIG_ROTATIONTYPE *omxConfigRotate;
00822   OMX_CONFIG_MIRRORTYPE *omxConfigMirror;
00823   OMX_CONFIG_SCALEFACTORTYPE *omxConfigScale;
00824   OMX_CONFIG_POINTTYPE *omxConfigOutputPosition;
00825   OMX_ERRORTYPE err = OMX_ErrorNone;
00826 
00827   /* Check which structure we are being fed and make control its header */
00828   OMX_COMPONENTTYPE *openmaxStandComp = (OMX_COMPONENTTYPE *)hComponent;
00829   omx_ffmpeg_colorconv_component_PrivateType* omx_ffmpeg_colorconv_component_Private = openmaxStandComp->pComponentPrivate;
00830   omx_ffmpeg_colorconv_component_PortType *pPort;
00831   if (pComponentConfigStructure == NULL) {
00832     return OMX_ErrorBadParameter;
00833   }
00834   DEBUG(DEB_LEV_SIMPLE_SEQ, "   Setting configuration %i\n", nIndex);  
00835   switch (nIndex) {
00836     case OMX_IndexConfigCommonInputCrop:
00837     case OMX_IndexConfigCommonOutputCrop:
00838       omxConfigCrop = (OMX_CONFIG_RECTTYPE*)pComponentConfigStructure;
00839       portIndex = omxConfigCrop->nPortIndex;
00840       if ((err = checkHeader(pComponentConfigStructure, sizeof(OMX_CONFIG_RECTTYPE))) != OMX_ErrorNone) { 
00841         break;
00842       }
00843       if ( (nIndex == OMX_IndexConfigCommonOutputCrop && portIndex == OMX_BASE_FILTER_OUTPUTPORT_INDEX)  ||
00844           (nIndex == OMX_IndexConfigCommonInputCrop && portIndex == OMX_BASE_FILTER_INPUTPORT_INDEX) ) {
00845         pPort = (omx_ffmpeg_colorconv_component_PortType *) omx_ffmpeg_colorconv_component_Private->ports[portIndex];
00846         pPort->omxConfigCrop.nLeft = omxConfigCrop->nLeft;
00847         pPort->omxConfigCrop.nTop = omxConfigCrop->nTop;
00848         pPort->omxConfigCrop.nWidth = omxConfigCrop->nWidth;
00849         pPort->omxConfigCrop.nHeight = omxConfigCrop->nHeight;
00850       } else if (portIndex <= 1) {
00851         return OMX_ErrorUnsupportedIndex;
00852       } else {
00853         return OMX_ErrorBadPortIndex;
00854       }
00855       break;
00856     case OMX_IndexConfigCommonRotate:
00857       omxConfigRotate = (OMX_CONFIG_ROTATIONTYPE*)pComponentConfigStructure;
00858       portIndex = omxConfigRotate->nPortIndex;
00859       if ((err = checkHeader(pComponentConfigStructure, sizeof(OMX_CONFIG_ROTATIONTYPE))) != OMX_ErrorNone) { 
00860         break;
00861       }
00862       if (portIndex <= 1) {
00863         pPort = (omx_ffmpeg_colorconv_component_PortType *) omx_ffmpeg_colorconv_component_Private->ports[portIndex];
00864         if (omxConfigRotate->nRotation != 0) {
00865           //  Rotation not supported (yet)
00866           return OMX_ErrorUnsupportedSetting;
00867         }
00868         pPort->omxConfigRotate.nRotation = omxConfigRotate->nRotation;
00869       } else {
00870         return OMX_ErrorBadPortIndex;
00871       }
00872       break;
00873     case OMX_IndexConfigCommonMirror:
00874       omxConfigMirror = (OMX_CONFIG_MIRRORTYPE*)pComponentConfigStructure;
00875       portIndex = omxConfigMirror->nPortIndex;
00876       if ((err = checkHeader(pComponentConfigStructure, sizeof(OMX_CONFIG_MIRRORTYPE))) != OMX_ErrorNone) { 
00877         break;
00878       }
00879       if (portIndex <= 1) {
00880         if (omxConfigMirror->eMirror == OMX_MirrorBoth || omxConfigMirror->eMirror == OMX_MirrorHorizontal)  {
00881           //  Horizontal mirroring not yet supported
00882           return OMX_ErrorUnsupportedSetting;
00883         }
00884         pPort = (omx_ffmpeg_colorconv_component_PortType *) omx_ffmpeg_colorconv_component_Private->ports[portIndex];
00885         pPort->omxConfigMirror.eMirror = omxConfigMirror->eMirror;
00886       } else {
00887         return OMX_ErrorBadPortIndex;
00888       }
00889       break;
00890     case OMX_IndexConfigCommonScale:
00891       omxConfigScale = (OMX_CONFIG_SCALEFACTORTYPE*)pComponentConfigStructure;
00892       portIndex = omxConfigScale->nPortIndex;
00893       if ((err = checkHeader(pComponentConfigStructure, sizeof(OMX_CONFIG_SCALEFACTORTYPE))) != OMX_ErrorNone) { 
00894         break;
00895       }
00896       if (portIndex <= 1) {
00897         if (omxConfigScale->xWidth != 0x10000 || omxConfigScale->xHeight != 0x10000) {
00898           //  Scaling not yet supported
00899           return OMX_ErrorUnsupportedSetting;
00900         }
00901         pPort = (omx_ffmpeg_colorconv_component_PortType *) omx_ffmpeg_colorconv_component_Private->ports[portIndex];
00902         pPort->omxConfigScale.xWidth = omxConfigScale->xWidth;
00903         pPort->omxConfigScale.xHeight = omxConfigScale->xHeight;
00904       } else {
00905         return OMX_ErrorBadPortIndex;
00906       }
00907       break;
00908     case OMX_IndexConfigCommonOutputPosition:
00909       omxConfigOutputPosition = (OMX_CONFIG_POINTTYPE*)pComponentConfigStructure;
00910       portIndex = omxConfigOutputPosition->nPortIndex;
00911       if ((err = checkHeader(pComponentConfigStructure, sizeof(OMX_CONFIG_POINTTYPE))) != OMX_ErrorNone) { 
00912         break;
00913       }
00914       if (portIndex == OMX_BASE_FILTER_OUTPUTPORT_INDEX) {
00915         pPort = (omx_ffmpeg_colorconv_component_PortType *) omx_ffmpeg_colorconv_component_Private->ports[portIndex];
00916         pPort->omxConfigOutputPosition.nX = omxConfigOutputPosition->nX;
00917         pPort->omxConfigOutputPosition.nY = omxConfigOutputPosition->nY;
00918       } else if (portIndex == OMX_BASE_FILTER_INPUTPORT_INDEX) {
00919         return OMX_ErrorUnsupportedIndex;
00920       } else {
00921         return OMX_ErrorBadPortIndex;
00922       }
00923       break;
00924     default: // delegate to superclass
00925       return omx_base_component_SetConfig(hComponent, nIndex, pComponentConfigStructure);
00926   }
00927   return err;
00928 }
00929 
00930 
00931 
00932 OMX_ERRORTYPE omx_ffmpeg_colorconv_component_GetConfig(
00933   OMX_HANDLETYPE hComponent,
00934   OMX_INDEXTYPE nIndex,
00935   OMX_PTR pComponentConfigStructure) {
00936 
00937   // Possible configs to ask for
00938   OMX_CONFIG_RECTTYPE *omxConfigCrop;
00939   OMX_CONFIG_ROTATIONTYPE *omxConfigRotate;
00940   OMX_CONFIG_MIRRORTYPE *omxConfigMirror;
00941   OMX_CONFIG_SCALEFACTORTYPE *omxConfigScale;
00942   OMX_CONFIG_POINTTYPE *omxConfigOutputPosition;
00943   OMX_ERRORTYPE err = OMX_ErrorNone;
00944 
00945   OMX_COMPONENTTYPE *openmaxStandComp = (OMX_COMPONENTTYPE *)hComponent;
00946   omx_ffmpeg_colorconv_component_PrivateType* omx_ffmpeg_colorconv_component_Private = openmaxStandComp->pComponentPrivate;
00947   omx_ffmpeg_colorconv_component_PortType *pPort;
00948   if (pComponentConfigStructure == NULL) {
00949     return OMX_ErrorBadParameter;
00950   }
00951   DEBUG(DEB_LEV_SIMPLE_SEQ, "   Getting configuration %i\n", nIndex);
00952   /* Check which structure we are being fed and fill its header */
00953   switch (nIndex) {
00954     case OMX_IndexConfigCommonInputCrop:
00955       omxConfigCrop = (OMX_CONFIG_RECTTYPE*)pComponentConfigStructure;
00956       if ((err = checkHeader(pComponentConfigStructure, sizeof(OMX_CONFIG_RECTTYPE))) != OMX_ErrorNone) { 
00957         break;
00958       }
00959       if (omxConfigCrop->nPortIndex == OMX_BASE_FILTER_INPUTPORT_INDEX) {
00960         pPort = (omx_ffmpeg_colorconv_component_PortType *)omx_ffmpeg_colorconv_component_Private->ports[omxConfigCrop->nPortIndex];
00961         memcpy(omxConfigCrop, &pPort->omxConfigCrop, sizeof(OMX_CONFIG_RECTTYPE));
00962       } else if (omxConfigCrop->nPortIndex == OMX_BASE_FILTER_OUTPUTPORT_INDEX) {
00963         return OMX_ErrorUnsupportedIndex;
00964       } else {
00965         return OMX_ErrorBadPortIndex;
00966       }
00967       break;    
00968     case OMX_IndexConfigCommonOutputCrop:
00969       omxConfigCrop = (OMX_CONFIG_RECTTYPE*)pComponentConfigStructure;
00970       if ((err = checkHeader(pComponentConfigStructure, sizeof(OMX_CONFIG_RECTTYPE))) != OMX_ErrorNone) { 
00971         break;
00972       }
00973       if (omxConfigCrop->nPortIndex == OMX_BASE_FILTER_OUTPUTPORT_INDEX) {
00974         pPort = (omx_ffmpeg_colorconv_component_PortType *)omx_ffmpeg_colorconv_component_Private->ports[omxConfigCrop->nPortIndex];
00975         memcpy(omxConfigCrop, &pPort->omxConfigCrop, sizeof(OMX_CONFIG_RECTTYPE));
00976       } else if (omxConfigCrop->nPortIndex == OMX_BASE_FILTER_INPUTPORT_INDEX) {
00977         return OMX_ErrorUnsupportedIndex;
00978       } else {
00979         return OMX_ErrorBadPortIndex;
00980       }
00981       break;    
00982     case OMX_IndexConfigCommonRotate:
00983       omxConfigRotate = (OMX_CONFIG_ROTATIONTYPE*)pComponentConfigStructure;
00984       if ((err = checkHeader(pComponentConfigStructure, sizeof(OMX_CONFIG_ROTATIONTYPE))) != OMX_ErrorNone) { 
00985         break;
00986       }
00987       if (omxConfigRotate->nPortIndex <= 1) {
00988         pPort = (omx_ffmpeg_colorconv_component_PortType *)omx_ffmpeg_colorconv_component_Private->ports[omxConfigRotate->nPortIndex];
00989         memcpy(omxConfigRotate, &pPort->omxConfigRotate, sizeof(OMX_CONFIG_ROTATIONTYPE));
00990       } else {
00991         return OMX_ErrorBadPortIndex;
00992       }
00993       break;    
00994     case OMX_IndexConfigCommonMirror:
00995       omxConfigMirror = (OMX_CONFIG_MIRRORTYPE*)pComponentConfigStructure;
00996       if ((err = checkHeader(pComponentConfigStructure, sizeof(OMX_CONFIG_MIRRORTYPE))) != OMX_ErrorNone) { 
00997         break;
00998       }
00999       if (omxConfigMirror->nPortIndex <= 1) {
01000         pPort = (omx_ffmpeg_colorconv_component_PortType *)omx_ffmpeg_colorconv_component_Private->ports[omxConfigMirror->nPortIndex];
01001         memcpy(omxConfigMirror, &pPort->omxConfigMirror, sizeof(OMX_CONFIG_MIRRORTYPE));
01002       } else {
01003         return OMX_ErrorBadPortIndex;
01004       }
01005       break;      
01006     case OMX_IndexConfigCommonScale:
01007       omxConfigScale = (OMX_CONFIG_SCALEFACTORTYPE*)pComponentConfigStructure;
01008       if ((err = checkHeader(pComponentConfigStructure, sizeof(OMX_CONFIG_SCALEFACTORTYPE))) != OMX_ErrorNone) { 
01009         break;
01010       }
01011       if (omxConfigScale->nPortIndex <= 1) {
01012         pPort = (omx_ffmpeg_colorconv_component_PortType *)omx_ffmpeg_colorconv_component_Private->ports[omxConfigScale->nPortIndex];
01013         memcpy(omxConfigScale, &pPort->omxConfigScale, sizeof(OMX_CONFIG_SCALEFACTORTYPE));
01014       } else {
01015         return OMX_ErrorBadPortIndex;
01016       }
01017       break;    
01018     case OMX_IndexConfigCommonOutputPosition:
01019       omxConfigOutputPosition = (OMX_CONFIG_POINTTYPE*)pComponentConfigStructure;
01020       if ((err = checkHeader(pComponentConfigStructure, sizeof(OMX_CONFIG_POINTTYPE))) != OMX_ErrorNone) { 
01021         break;
01022       }
01023       if (omxConfigOutputPosition->nPortIndex == OMX_BASE_FILTER_OUTPUTPORT_INDEX) {
01024         pPort = (omx_ffmpeg_colorconv_component_PortType *)omx_ffmpeg_colorconv_component_Private->ports[omxConfigOutputPosition->nPortIndex];
01025         memcpy(omxConfigOutputPosition, &pPort->omxConfigOutputPosition, sizeof(OMX_CONFIG_POINTTYPE));
01026       } else if (omxConfigOutputPosition->nPortIndex == OMX_BASE_FILTER_INPUTPORT_INDEX) {
01027         return OMX_ErrorUnsupportedIndex;
01028       } else {
01029         return OMX_ErrorBadPortIndex;
01030       }
01031       break;    
01032     default: // delegate to superclass
01033       return omx_base_component_GetConfig(hComponent, nIndex, pComponentConfigStructure);
01034   }
01035   return err;
01036 }
01037 
01038 
01039 OMX_ERRORTYPE omx_ffmpeg_colorconv_component_SetParameter(
01040   OMX_HANDLETYPE hComponent,
01041   OMX_INDEXTYPE nParamIndex,
01042   OMX_PTR ComponentParameterStructure) {
01043 
01044   OMX_ERRORTYPE err = OMX_ErrorNone;
01045   OMX_PARAM_PORTDEFINITIONTYPE *pPortDef;
01046   OMX_VIDEO_PARAM_PORTFORMATTYPE *pVideoPortFormat;
01047   OMX_U32 portIndex;
01048 
01049   /* Check which structure we are being fed and make control its header */
01050   OMX_COMPONENTTYPE *openmaxStandComp = (OMX_COMPONENTTYPE *)hComponent;
01051   omx_ffmpeg_colorconv_component_PrivateType* omx_ffmpeg_colorconv_component_Private = openmaxStandComp->pComponentPrivate;
01052   omx_ffmpeg_colorconv_component_PortType *pPort;
01053   if (ComponentParameterStructure == NULL) {
01054     return OMX_ErrorBadParameter;
01055   }  
01056   DEBUG(DEB_LEV_SIMPLE_SEQ, "   Setting parameter %i\n", nParamIndex);
01057   switch(nParamIndex) {
01058     case OMX_IndexParamPortDefinition:
01059       pPortDef = (OMX_PARAM_PORTDEFINITIONTYPE*) ComponentParameterStructure;
01060       portIndex = pPortDef->nPortIndex;
01061       err = omx_base_component_ParameterSanityCheck(hComponent, portIndex, pPortDef, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
01062       if(err!=OMX_ErrorNone) { 
01063         DEBUG(DEB_LEV_ERR, "In %s Parameter Check Error=%x\n",__func__,err); 
01064         break;
01065       } 
01066       pPort = (omx_ffmpeg_colorconv_component_PortType *) omx_ffmpeg_colorconv_component_Private->ports[portIndex];
01067       pPort->sPortParam.nBufferCountActual = pPortDef->nBufferCountActual;
01068 
01069       //  Copy stuff from OMX_VIDEO_PORTDEFINITIONTYPE structure
01070       pPort->sPortParam.format.video.nFrameWidth = pPortDef->format.video.nFrameWidth;
01071       pPort->sPortParam.format.video.nFrameHeight = pPortDef->format.video.nFrameHeight;
01072       pPort->sPortParam.format.video.nBitrate = pPortDef->format.video.nBitrate;
01073       pPort->sPortParam.format.video.xFramerate = pPortDef->format.video.xFramerate;
01074       pPort->sPortParam.format.video.bFlagErrorConcealment = pPortDef->format.video.bFlagErrorConcealment;  
01075       //  Figure out stride, slice height, min buffer size
01076       pPort->sPortParam.format.video.nStride = calcStride(pPort->sPortParam.format.video.nFrameWidth, pPort->sVideoParam.eColorFormat);
01077       pPort->sPortParam.format.video.nSliceHeight = pPort->sPortParam.format.video.nFrameHeight;  //  No support for slices yet
01078       // Read-only field by spec
01079       pPort->sPortParam.nBufferSize = (OMX_U32) abs(pPort->sPortParam.format.video.nStride) * pPort->sPortParam.format.video.nSliceHeight;
01080       pPort->omxConfigCrop.nWidth = pPort->sPortParam.format.video.nFrameWidth;
01081       pPort->omxConfigCrop.nHeight = pPort->sPortParam.format.video.nFrameHeight;
01082       break;
01083     case OMX_IndexParamVideoPortFormat:
01084       //  FIXME: How do we handle the nIndex member?
01085       pVideoPortFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE*)ComponentParameterStructure;
01086       portIndex = pVideoPortFormat->nPortIndex;
01087       err = omx_base_component_ParameterSanityCheck(hComponent, portIndex, pVideoPortFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
01088       if(err!=OMX_ErrorNone) { 
01089         DEBUG(DEB_LEV_ERR, "In %s Parameter Check Error=%x\n",__func__,err); 
01090         break;
01091       } 
01092       pPort = (omx_ffmpeg_colorconv_component_PortType *) omx_ffmpeg_colorconv_component_Private->ports[portIndex];
01093       if (pVideoPortFormat->eCompressionFormat != OMX_VIDEO_CodingUnused)  {
01094         //  No compression allowed
01095         return OMX_ErrorUnsupportedSetting;
01096       }
01097       pPort->sVideoParam.eCompressionFormat = pVideoPortFormat->eCompressionFormat;
01098       pPort->sVideoParam.eColorFormat = pVideoPortFormat->eColorFormat;
01099       pPort->ffmpeg_pxlfmt = find_ffmpeg_pxlfmt(pPort->sVideoParam.eColorFormat);
01100 
01101       if(pPort->ffmpeg_pxlfmt == PIX_FMT_NONE) {
01104         return OMX_ErrorBadParameter;          
01105       }
01106       //  Figure out stride, slice height, min buffer size
01107       pPort->sPortParam.format.video.nStride = calcStride(pPort->sPortParam.format.video.nFrameWidth, pPort->sVideoParam.eColorFormat);
01108       pPort->sPortParam.format.video.nSliceHeight = pPort->sPortParam.format.video.nFrameHeight;  //  No support for slices yet
01109       pPort->sPortParam.nBufferSize = (OMX_U32) abs(pPort->sPortParam.format.video.nStride) * pPort->sPortParam.format.video.nSliceHeight;
01110       break;
01111     default: /*Call the base component function*/
01112       return omx_base_component_SetParameter(hComponent, nParamIndex, ComponentParameterStructure);
01113   }
01114   return err;
01115 }
01116 
01117 OMX_ERRORTYPE omx_ffmpeg_colorconv_component_GetParameter(
01118   OMX_HANDLETYPE hComponent,
01119   OMX_INDEXTYPE nParamIndex,
01120   OMX_PTR ComponentParameterStructure) {
01121 
01122   OMX_VIDEO_PARAM_PORTFORMATTYPE *pVideoPortFormat;
01123   OMX_ERRORTYPE err = OMX_ErrorNone;
01124   OMX_COMPONENTTYPE *openmaxStandComp = (OMX_COMPONENTTYPE *)hComponent;
01125   omx_ffmpeg_colorconv_component_PrivateType* omx_ffmpeg_colorconv_component_Private = openmaxStandComp->pComponentPrivate;
01126   omx_ffmpeg_colorconv_component_PortType *pPort;
01127   if (ComponentParameterStructure == NULL) {
01128     return OMX_ErrorBadParameter;
01129   }
01130 
01131   DEBUG(DEB_LEV_SIMPLE_SEQ, "   Getting parameter %i\n", nParamIndex);
01132   /* Check which structure we are being fed and fill its header */
01133   switch(nParamIndex) {
01134     case OMX_IndexParamVideoInit:
01135       if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_PORT_PARAM_TYPE))) != OMX_ErrorNone) { 
01136         break;
01137       }
01138       memcpy(ComponentParameterStructure, &omx_ffmpeg_colorconv_component_Private->sPortTypesParam[OMX_PortDomainVideo], sizeof(OMX_PORT_PARAM_TYPE));
01139       break;    
01140     case OMX_IndexParamVideoPortFormat:
01141       pVideoPortFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE*)ComponentParameterStructure;
01142       if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE))) != OMX_ErrorNone) { 
01143         break;
01144       }
01145       if (pVideoPortFormat->nPortIndex <= 1) {
01146         pPort = (omx_ffmpeg_colorconv_component_PortType *)omx_ffmpeg_colorconv_component_Private->ports[pVideoPortFormat->nPortIndex];
01147         memcpy(pVideoPortFormat, &pPort->sVideoParam, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
01148       } else {
01149         return OMX_ErrorBadPortIndex;
01150       }
01151       break;    
01152     default: /*Call the base component function*/
01153       return omx_base_component_GetParameter(hComponent, nParamIndex, ComponentParameterStructure);
01154   }
01155   return err;
01156 }
01157 
01158 
01159 OMX_ERRORTYPE omx_video_colorconv_MessageHandler(OMX_COMPONENTTYPE* openmaxStandComp,internalRequestMessageType *message) {
01160   omx_ffmpeg_colorconv_component_PrivateType* omx_ffmpeg_colorconv_component_Private = (omx_ffmpeg_colorconv_component_PrivateType*)openmaxStandComp->pComponentPrivate;
01161   OMX_ERRORTYPE err = OMX_ErrorNone;
01162   OMX_STATETYPE eState;
01163 
01164   DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s\n", __func__);
01165   eState = omx_ffmpeg_colorconv_component_Private->state; //storing current state
01166 
01167   if (message->messageType == OMX_CommandStateSet) {
01168     if ((message->messageParam == OMX_StateExecuting ) && (omx_ffmpeg_colorconv_component_Private->state == OMX_StateIdle)) {
01169       err = omx_ffmpeg_colorconv_component_Init(openmaxStandComp);
01170       if(err!=OMX_ErrorNone) { 
01171         DEBUG(DEB_LEV_ERR, "In %s Video Color Converter Init Error=%x\n",__func__,err); 
01172         return err;
01173       } 
01174     }
01175   }
01176   // Execute the base message handling
01177   err = omx_base_component_MessageHandler(openmaxStandComp,message);
01178 
01179   if (message->messageType == OMX_CommandStateSet) {
01180     if ((message->messageParam == OMX_StateIdle ) && (omx_ffmpeg_colorconv_component_Private->state == OMX_StateIdle) && eState == OMX_StateExecuting) {
01181       err = omx_ffmpeg_colorconv_component_Deinit(openmaxStandComp);
01182       if(err!=OMX_ErrorNone) { 
01183         DEBUG(DEB_LEV_ERR, "In %s Video Color Converter Deinit Error=%x\n",__func__,err); 
01184         return err;
01185       } 
01186     }
01187   }
01188   return err;
01189 }
01190 
01191 OMX_ERRORTYPE omx_video_colorconv_UseEGLImage (
01192         OMX_HANDLETYPE hComponent,
01193         OMX_BUFFERHEADERTYPE** ppBufferHdr,
01194         OMX_U32 nPortIndex,
01195         OMX_PTR pAppPrivate,
01196         void* eglImage) {
01197   
01198   omx_ffmpeg_colorconv_component_PrivateType* omx_ffmpeg_colorconv_component_Private = (omx_ffmpeg_colorconv_component_PrivateType*)((OMX_COMPONENTTYPE*)hComponent)->pComponentPrivate;
01199   omx_base_PortType *pPort;
01200 
01201   if (nPortIndex >= omx_ffmpeg_colorconv_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts) {
01202     DEBUG(DEB_LEV_ERR, "In %s: wrong port index\n", __func__);
01203     return OMX_ErrorBadPortIndex;
01204   }
01205   pPort = omx_ffmpeg_colorconv_component_Private->ports[nPortIndex];
01206 
01207   return  pPort->Port_UseBuffer(pPort,
01208                                 ppBufferHdr,
01209                                 nPortIndex,
01210                                 pAppPrivate,
01211                                 pPort->sPortParam.nBufferSize,
01212                                 eglImage);
01213 }

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