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

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