omx_videosrc_component.c

Go to the documentation of this file.
00001 
00031 #include <assert.h>
00032 #include <omxcore.h>
00033 #include <omx_base_video_port.h>
00034 #include <omx_videosrc_component.h>
00035 
00036 #define MAX_COMPONENT_VIDEOSRC 1
00037 
00039 static OMX_U32 noViderSrcInstance=0;
00040 
00041 #define DEFAULT_FILENAME_LENGTH 256
00042 
00043 #define CLEAR(x) memset (&(x), 0, sizeof (x))
00044 
00045 static unsigned int n_buffers = 0;
00046 
00047 static int xioctl(int fd, int request, void *arg);
00048 static int init_device(omx_videosrc_component_PrivateType* omx_videosrc_component_Private);
00049 static int uninit_device(omx_videosrc_component_PrivateType* omx_videosrc_component_Private);
00050 static int start_capturing(omx_videosrc_component_PrivateType* omx_videosrc_component_Private);
00051 static int stop_capturing(omx_videosrc_component_PrivateType* omx_videosrc_component_Private);
00052 static int init_mmap(omx_videosrc_component_PrivateType* omx_videosrc_component_Private);
00053 
00054 static int errno_return(const char *s)
00055 {
00056   DEBUG(DEB_LEV_ERR, "%s error %d, %s\n", s, errno, strerror(errno));
00057   return OMX_ErrorHardware;
00058 }
00059 
00060 
00063 OMX_ERRORTYPE omx_videosrc_component_Constructor(OMX_COMPONENTTYPE *openmaxStandComp,OMX_STRING cComponentName) {
00064  
00065   OMX_ERRORTYPE err = OMX_ErrorNone;  
00066   omx_base_video_PortType *pPort;
00067   omx_videosrc_component_PrivateType* omx_videosrc_component_Private;
00068   OMX_U32 i;
00069 
00070   DEBUG(DEB_LEV_FUNCTION_NAME,"In %s \n",__func__);
00071 
00072   if (!openmaxStandComp->pComponentPrivate) {
00073     openmaxStandComp->pComponentPrivate = calloc(1, sizeof(omx_videosrc_component_PrivateType));
00074     if(openmaxStandComp->pComponentPrivate == NULL) {
00075       return OMX_ErrorInsufficientResources;
00076     }
00077   }
00078 
00079   omx_videosrc_component_Private = openmaxStandComp->pComponentPrivate;
00080   omx_videosrc_component_Private->ports = NULL;
00081   omx_videosrc_component_Private->deviceHandle = -1;
00082   
00083   err = omx_base_source_Constructor(openmaxStandComp, cComponentName);
00084   
00085   omx_videosrc_component_Private->sPortTypesParam[OMX_PortDomainVideo].nStartPortNumber = 0;
00086   omx_videosrc_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts = 1;
00087 
00089   if (omx_videosrc_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts && !omx_videosrc_component_Private->ports) {
00090     omx_videosrc_component_Private->ports = calloc(omx_videosrc_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts, sizeof(omx_base_PortType *));
00091     if (!omx_videosrc_component_Private->ports) {
00092       return OMX_ErrorInsufficientResources;
00093     }
00094     for (i=0; i < omx_videosrc_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts; i++) {
00095       omx_videosrc_component_Private->ports[i] = calloc(1, sizeof(omx_base_video_PortType));
00096       if (!omx_videosrc_component_Private->ports[i]) {
00097         return OMX_ErrorInsufficientResources;
00098       }
00099     }
00100   }
00101 
00102   base_video_port_Constructor(openmaxStandComp, &omx_videosrc_component_Private->ports[0], 0, OMX_FALSE);
00103   omx_videosrc_component_Private->ports[0]->Port_AllocateBuffer = videosrc_port_AllocateBuffer;
00104   omx_videosrc_component_Private->ports[0]->Port_FreeBuffer = videosrc_port_FreeBuffer;
00105   omx_videosrc_component_Private->ports[0]->Port_AllocateTunnelBuffer = videosrc_port_AllocateTunnelBuffer;
00106   omx_videosrc_component_Private->ports[0]->Port_FreeTunnelBuffer = videosrc_port_FreeTunnelBuffer;
00107 
00108   pPort = (omx_base_video_PortType *) omx_videosrc_component_Private->ports[OMX_BASE_SOURCE_OUTPUTPORT_INDEX];
00109   
00110   pPort->sPortParam.format.video.nFrameWidth = 320;
00111   pPort->sPortParam.format.video.nFrameHeight= 240;
00112   pPort->sPortParam.format.video.eColorFormat= OMX_COLOR_FormatYUV420Planar;
00113   pPort->sVideoParam.eColorFormat = OMX_COLOR_FormatYUV420Planar;
00114 
00115   pPort->sPortParam.nBufferSize = pPort->sPortParam.format.video.nFrameWidth*
00116                                   pPort->sPortParam.format.video.nFrameHeight*3; // RGB888
00117   omx_videosrc_component_Private->iFrameSize = pPort->sPortParam.nBufferSize;
00118 
00119   omx_videosrc_component_Private->BufferMgmtCallback = omx_videosrc_component_BufferMgmtCallback;
00120   omx_videosrc_component_Private->destructor = omx_videosrc_component_Destructor;
00121   omx_videosrc_component_Private->messageHandler = omx_videosrc_component_MessageHandler;
00122 
00123   noViderSrcInstance++;
00124   if(noViderSrcInstance > MAX_COMPONENT_VIDEOSRC) {
00125     return OMX_ErrorInsufficientResources;
00126   }
00127 
00128   openmaxStandComp->SetParameter  = omx_videosrc_component_SetParameter;
00129   openmaxStandComp->GetParameter  = omx_videosrc_component_GetParameter;
00130 
00131   /* Write in the default paramenters */
00132   omx_videosrc_component_Private->videoReady = OMX_FALSE;
00133   if(!omx_videosrc_component_Private->videoSyncSem) {
00134     omx_videosrc_component_Private->videoSyncSem = calloc(1,sizeof(tsem_t));
00135     if(omx_videosrc_component_Private->videoSyncSem == NULL) return OMX_ErrorInsufficientResources;
00136     tsem_init(omx_videosrc_component_Private->videoSyncSem, 0);
00137   }
00138 
00139   omx_videosrc_component_Private->bOutBufferMemoryMapped = OMX_FALSE;
00140 
00141   /* Test if Camera Attached */
00142   omx_videosrc_component_Private->deviceHandle = open(VIDEO_DEV_NAME, O_RDWR /* required */  | O_NONBLOCK, 0);
00143   if (omx_videosrc_component_Private->deviceHandle < 0) {
00144     DEBUG(DEB_LEV_ERR, "In %s Unable to open video capture device %s! errno=%d  ENODEV : %d \n", 
00145       __func__,VIDEO_DEV_NAME,errno,ENODEV);
00146     return OMX_ErrorHardware;
00147   } 
00148 
00149   omx_videosrc_component_Private->pixel_format = V4L2_PIX_FMT_YUV420;
00150 
00151   err = init_device(omx_videosrc_component_Private);
00152 
00153   err = init_mmap(omx_videosrc_component_Private);
00154 
00155   return err;
00156 }
00157 
00160 OMX_ERRORTYPE omx_videosrc_component_Destructor(OMX_COMPONENTTYPE *openmaxStandComp) {
00161   omx_videosrc_component_PrivateType* omx_videosrc_component_Private = openmaxStandComp->pComponentPrivate;
00162   OMX_ERRORTYPE err = OMX_ErrorNone;  
00163   OMX_U32 i;
00164   
00165   if(omx_videosrc_component_Private->videoSyncSem) {
00166     tsem_deinit(omx_videosrc_component_Private->videoSyncSem);
00167     free(omx_videosrc_component_Private->videoSyncSem);
00168     omx_videosrc_component_Private->videoSyncSem=NULL;
00169   }
00170 
00171   err = uninit_device(omx_videosrc_component_Private);
00172  
00173   if(omx_videosrc_component_Private->deviceHandle != -1) {
00174     if(-1 == close(omx_videosrc_component_Private->deviceHandle)) {
00175       DEBUG(DEB_LEV_ERR, "In %s Closing video capture device failed \n",__func__);
00176     }
00177     omx_videosrc_component_Private->deviceHandle = -1;
00178   }
00179 
00180   /* frees port/s */
00181   if (omx_videosrc_component_Private->ports) {
00182     for (i=0; i < omx_videosrc_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts; i++) {
00183       if(omx_videosrc_component_Private->ports[i])
00184         omx_videosrc_component_Private->ports[i]->PortDestructor(omx_videosrc_component_Private->ports[i]);
00185     }
00186     free(omx_videosrc_component_Private->ports);
00187     omx_videosrc_component_Private->ports=NULL;
00188   }
00189 
00190   noViderSrcInstance--;
00191   DEBUG(DEB_LEV_FUNCTION_NAME,"In %s \n",__func__);
00192 
00193   return omx_base_source_Destructor(openmaxStandComp);
00194 }
00195 
00198 OMX_ERRORTYPE omx_videosrc_component_Init(OMX_COMPONENTTYPE *openmaxStandComp) {
00199 
00200   omx_videosrc_component_PrivateType* omx_videosrc_component_Private = openmaxStandComp->pComponentPrivate;
00201   omx_base_video_PortType *pPort = (omx_base_video_PortType *)omx_videosrc_component_Private->ports[OMX_BASE_SOURCE_OUTPUTPORT_INDEX];
00202   OMX_ERRORTYPE err = OMX_ErrorNone;  
00203 
00204   DEBUG(DEB_LEV_FUNCTION_NAME,"In %s \n",__func__);
00205 
00206   /* Presently V4L2_PIX_FMT_YUV420 format is supported by the camera */
00207   switch(pPort->sPortParam.format.video.eColorFormat) {
00208   case OMX_COLOR_FormatYUV420Planar:
00209   case OMX_COLOR_FormatYUV420PackedPlanar:
00210     omx_videosrc_component_Private->pixel_format = V4L2_PIX_FMT_YUV420;
00211     break;
00212   case OMX_COLOR_Format16bitRGB565:
00213     omx_videosrc_component_Private->pixel_format = V4L2_PIX_FMT_RGB565 ;       // 565 16 bit RGB //
00214     omx_videosrc_component_Private->iFrameSize = pPort->sPortParam.format.video.nFrameWidth*
00215                                                  pPort->sPortParam.format.video.nFrameHeight*2;
00216     omx_videosrc_component_Private->iFrameSize = pPort->sPortParam.format.video.nFrameWidth*
00217                                                pPort->sPortParam.format.video.nFrameHeight*2;
00218     break;
00219   case OMX_COLOR_Format24bitRGB888:
00220     omx_videosrc_component_Private->pixel_format = V4L2_PIX_FMT_RGB24  ;       // 24bit RGB //
00221     omx_videosrc_component_Private->iFrameSize = pPort->sPortParam.format.video.nFrameWidth*
00222                                                  pPort->sPortParam.format.video.nFrameHeight*3;
00223     break;
00224   case OMX_COLOR_Format32bitARGB8888:
00225     omx_videosrc_component_Private->pixel_format = V4L2_PIX_FMT_RGB32     ;       // 32bit RGB //
00226     omx_videosrc_component_Private->iFrameSize = pPort->sPortParam.format.video.nFrameWidth*
00227                                                  pPort->sPortParam.format.video.nFrameHeight*4;
00228     break;
00229   case OMX_COLOR_FormatYUV422Planar:
00230     omx_videosrc_component_Private->pixel_format = V4L2_PIX_FMT_YUV422P   ;      // YUV 4:2:2 Planar //
00231     omx_videosrc_component_Private->iFrameSize = pPort->sPortParam.format.video.nFrameWidth*
00232                                                  pPort->sPortParam.format.video.nFrameHeight*2;
00233     break;
00234   case OMX_COLOR_FormatYUV411Planar:
00235     omx_videosrc_component_Private->pixel_format = V4L2_PIX_FMT_YUV411P   ;      // YUV 4:1:1 Planar //
00236     break;
00237   default:
00238     omx_videosrc_component_Private->pixel_format = V4L2_PIX_FMT_YUV420;
00239     break;
00240   }
00241 
00243   omx_videosrc_component_Private->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00244   omx_videosrc_component_Private->fmt.fmt.pix.width = pPort->sPortParam.format.video.nFrameWidth;
00245   omx_videosrc_component_Private->fmt.fmt.pix.height = pPort->sPortParam.format.video.nFrameHeight;
00246   omx_videosrc_component_Private->fmt.fmt.pix.pixelformat = omx_videosrc_component_Private->pixel_format;
00247   omx_videosrc_component_Private->fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
00248 
00249   if (-1 == xioctl(omx_videosrc_component_Private->deviceHandle, VIDIOC_S_FMT, &omx_videosrc_component_Private->fmt))
00250     return errno_return("VIDIOC_S_FMT");
00251 
00252   // Note VIDIOC_S_FMT may change width and height. //
00253   pPort->sPortParam.format.video.nFrameWidth = omx_videosrc_component_Private->fmt.fmt.pix.width;
00254   pPort->sPortParam.format.video.nFrameHeight = omx_videosrc_component_Private->fmt.fmt.pix.height;
00255 
00256   /*output frame size*/
00257   omx_videosrc_component_Private->iFrameSize = pPort->sPortParam.format.video.nFrameWidth*
00258                                                pPort->sPortParam.format.video.nFrameHeight*3/2;
00259 
00260   DEBUG(DEB_ALL_MESS,"Frame Width=%d, Height=%d, Frame Size=%d n_buffers=%d\n",
00261     (int)pPort->sPortParam.format.video.nFrameWidth,
00262     (int)pPort->sPortParam.format.video.nFrameHeight,
00263     (int)omx_videosrc_component_Private->iFrameSize,n_buffers);
00264 
00266   omx_videosrc_component_Private->bIsEOSSent = OMX_FALSE;
00267   
00268   err = start_capturing(omx_videosrc_component_Private);
00269 
00270   omx_videosrc_component_Private->videoReady = OMX_TRUE;
00271 
00272   /*Indicate that video is ready*/
00273   tsem_up(omx_videosrc_component_Private->videoSyncSem);
00274 
00275   
00276 
00277   return err;
00278 }
00279 
00282 OMX_ERRORTYPE omx_videosrc_component_Deinit(OMX_COMPONENTTYPE *openmaxStandComp) {
00283 
00284   omx_videosrc_component_PrivateType* omx_videosrc_component_Private = openmaxStandComp->pComponentPrivate;
00285 
00286   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s \n",__func__);
00287 
00288   stop_capturing(omx_videosrc_component_Private);
00289 
00291   omx_videosrc_component_Private->videoReady = OMX_FALSE;
00292   tsem_reset(omx_videosrc_component_Private->videoSyncSem);
00293 
00294   return OMX_ErrorNone;
00295 }
00296 
00301 void omx_videosrc_component_BufferMgmtCallback(OMX_COMPONENTTYPE *openmaxStandComp, OMX_BUFFERHEADERTYPE* pOutputBuffer) {
00302 
00303   omx_videosrc_component_PrivateType* omx_videosrc_component_Private = openmaxStandComp->pComponentPrivate;
00304   struct v4l2_buffer buf;
00305   
00306   CLEAR(buf);
00307   
00308   DEBUG(DEB_LEV_FUNCTION_NAME,"In %s \n",__func__);
00309 
00310   if (omx_videosrc_component_Private->videoReady == OMX_FALSE) {
00311     if(omx_videosrc_component_Private->state == OMX_StateExecuting) {
00312       /*wait for video to be ready*/
00313       tsem_down(omx_videosrc_component_Private->videoSyncSem);
00314     } else {
00315       return;
00316     }
00317   }
00318 
00319   pOutputBuffer->nOffset = 0;
00320   pOutputBuffer->nFilledLen = 0;
00321 
00322   buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00323   buf.memory = V4L2_MEMORY_MMAP;
00324 
00325   if (-1 == xioctl(omx_videosrc_component_Private->deviceHandle, VIDIOC_DQBUF, &buf)) {
00326     switch (errno) {
00327     case EAGAIN:
00328         return;
00329       case EIO:
00330         /* Could ignore EIO, see spec. */
00331         /* fall through */
00332 
00333       default:
00334       DEBUG(DEB_LEV_ERR,"In %s error VIDIOC_DQBUF\n",__func__);
00335         return;
00336     }
00337   }
00338 
00339   assert(buf.index < n_buffers);
00340 
00341   if(omx_videosrc_component_Private->bOutBufferMemoryMapped == OMX_FALSE) { /* In case OMX_UseBuffer copy frame to buffer metadata */
00342     memcpy(pOutputBuffer->pBuffer,omx_videosrc_component_Private->buffers[buf.index].start,omx_videosrc_component_Private->iFrameSize);
00343   }
00344 
00345   pOutputBuffer->nFilledLen = omx_videosrc_component_Private->iFrameSize;
00346 
00347   DEBUG(DEB_LEV_FULL_SEQ,"Camera output buffer nFilledLen=%d buf.length=%d\n",(int)pOutputBuffer->nFilledLen,buf.length);
00348 
00349   if (-1 == xioctl(omx_videosrc_component_Private->deviceHandle, VIDIOC_QBUF, &buf)) {
00350     DEBUG(DEB_LEV_ERR,"In %s error VIDIOC_DQBUF\n",__func__);
00351   }
00352 
00354   return;
00355 }
00356 
00357 OMX_ERRORTYPE omx_videosrc_component_SetParameter(
00358   OMX_IN  OMX_HANDLETYPE hComponent,
00359   OMX_IN  OMX_INDEXTYPE nParamIndex,
00360   OMX_IN  OMX_PTR ComponentParameterStructure) {
00361 
00362   OMX_ERRORTYPE err = OMX_ErrorNone;
00363   OMX_VIDEO_PARAM_PORTFORMATTYPE *pVideoPortFormat;
00364   OMX_U32 portIndex;
00365 
00366   /* Check which structure we are being fed and make control its header */
00367   OMX_COMPONENTTYPE *openmaxStandComp = (OMX_COMPONENTTYPE*)hComponent;
00368   omx_videosrc_component_PrivateType* omx_videosrc_component_Private = openmaxStandComp->pComponentPrivate;
00369   omx_base_video_PortType* pPort = (omx_base_video_PortType *) omx_videosrc_component_Private->ports[OMX_BASE_SOURCE_OUTPUTPORT_INDEX];
00370 
00371   if(ComponentParameterStructure == NULL) {
00372     return OMX_ErrorBadParameter;
00373   }
00374 
00375   DEBUG(DEB_LEV_SIMPLE_SEQ, "   Setting parameter %i\n", nParamIndex);
00376 
00377   switch(nParamIndex) {
00378   case OMX_IndexParamVideoPortFormat:
00379     pVideoPortFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE*)ComponentParameterStructure;
00380     portIndex = pVideoPortFormat->nPortIndex;
00381     /*Check Structure Header and verify component state*/
00382     err = omx_base_component_ParameterSanityCheck(hComponent, portIndex, pVideoPortFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
00383     if(err!=OMX_ErrorNone) { 
00384       DEBUG(DEB_LEV_ERR, "In %s Parameter Check Error=%x\n",__func__,err); 
00385       break;
00386     }
00387     if (portIndex < 1) {
00388       memcpy(&pPort->sVideoParam,pVideoPortFormat,sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
00389     } else {
00390       return OMX_ErrorBadPortIndex;
00391     }
00392     break;
00393   case OMX_IndexParamPortDefinition: 
00394     err = omx_base_component_SetParameter(hComponent, nParamIndex, ComponentParameterStructure);
00395     if(err == OMX_ErrorNone) {
00396       if(pPort->sPortParam.format.video.nFrameWidth > 640 || pPort->sPortParam.format.video.nFrameWidth <160 || 
00397         pPort->sPortParam.format.video.nFrameHeight > 480 || pPort->sPortParam.format.video.nFrameHeight < 120) {
00398         pPort->sPortParam.format.video.nFrameWidth = 160;
00399         pPort->sPortParam.format.video.nFrameHeight = 120;
00400         DEBUG(DEB_LEV_ERR, "In %s Frame Width Range[160..640] Frame Height Range[120..480]\n",__func__); 
00401         return OMX_ErrorBadParameter;
00402       } else {
00403         pPort->sPortParam.nBufferSize = pPort->sPortParam.format.video.nFrameWidth*
00404                                   pPort->sPortParam.format.video.nFrameHeight*3/2; // YUV
00405       }
00406     }
00407   default: /*Call the base component function*/
00408     return omx_base_component_SetParameter(hComponent, nParamIndex, ComponentParameterStructure);
00409   }
00410   return err;
00411 }
00412 
00413 OMX_ERRORTYPE omx_videosrc_component_GetParameter(
00414   OMX_IN  OMX_HANDLETYPE hComponent,
00415   OMX_IN  OMX_INDEXTYPE nParamIndex,
00416   OMX_INOUT OMX_PTR ComponentParameterStructure) {
00417 
00418   OMX_ERRORTYPE err = OMX_ErrorNone;
00419   OMX_VIDEO_PARAM_PORTFORMATTYPE *pVideoPortFormat;  
00420   OMX_COMPONENTTYPE *openmaxStandComp = (OMX_COMPONENTTYPE*)hComponent;
00421   omx_videosrc_component_PrivateType* omx_videosrc_component_Private = openmaxStandComp->pComponentPrivate;
00422   omx_base_video_PortType *pPort = (omx_base_video_PortType *) omx_videosrc_component_Private->ports[OMX_BASE_SOURCE_OUTPUTPORT_INDEX];  
00423   if (ComponentParameterStructure == NULL) {
00424     return OMX_ErrorBadParameter;
00425   }
00426 
00427   DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Getting parameter %08x\n",__func__, nParamIndex);
00428   
00429   /* Check which structure we are being fed and fill its header */
00430   switch(nParamIndex) {
00431   case OMX_IndexParamVideoInit:
00432     if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_PORT_PARAM_TYPE))) != OMX_ErrorNone) { 
00433       break;
00434     }
00435     memcpy(ComponentParameterStructure, &omx_videosrc_component_Private->sPortTypesParam[OMX_PortDomainVideo], sizeof(OMX_PORT_PARAM_TYPE));
00436     break;    
00437   case OMX_IndexParamVideoPortFormat:
00438     pVideoPortFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE*)ComponentParameterStructure;
00439     if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE))) != OMX_ErrorNone) { 
00440       break;
00441     }
00442     if (pVideoPortFormat->nPortIndex < 1) {
00443       memcpy(pVideoPortFormat, &pPort->sVideoParam, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
00444     } else {
00445       return OMX_ErrorBadPortIndex;
00446     }
00447     break;  
00448   case OMX_IndexVendorFileReadInputFilename : 
00449     strcpy((char *)ComponentParameterStructure, "still no filename");
00450     break;
00451   default: /*Call the base component function*/
00452     return omx_base_component_GetParameter(hComponent, nParamIndex, ComponentParameterStructure);
00453   }
00454   return err;
00455 }
00456 
00460 OMX_ERRORTYPE omx_videosrc_component_MessageHandler(OMX_COMPONENTTYPE* openmaxStandComp,internalRequestMessageType *message) {
00461   omx_videosrc_component_PrivateType* omx_videosrc_component_Private = (omx_videosrc_component_PrivateType*)openmaxStandComp->pComponentPrivate;
00462   OMX_ERRORTYPE err = OMX_ErrorNone;
00463   OMX_STATETYPE oldState = omx_videosrc_component_Private->state;
00464 
00465   DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s\n", __func__);
00466 
00467   /* Execute the base message handling */
00468   err = omx_base_component_MessageHandler(openmaxStandComp,message);
00469 
00470   if (message->messageType == OMX_CommandStateSet && err == OMX_ErrorNone){ 
00471     if ((message->messageParam == OMX_StateExecuting) && (oldState == OMX_StateIdle)) {    
00472       err = omx_videosrc_component_Init(openmaxStandComp);
00473       if(err!=OMX_ErrorNone) { 
00474         DEBUG(DEB_LEV_ERR, "In %s Video Source Init Failed Error=%x\n",__func__,err); 
00475       }
00476     } else if ((message->messageParam == OMX_StateIdle) && (oldState == OMX_StateExecuting)) {
00477       err = omx_videosrc_component_Deinit(openmaxStandComp);
00478       if(err!=OMX_ErrorNone) { 
00479         DEBUG(DEB_LEV_ERR, "In %s Video Source Deinit Failed Error=%x\n",__func__,err); 
00480       }
00481     }
00482   }
00483   return err;
00484 }
00485 
00486 OMX_ERRORTYPE videosrc_port_AllocateBuffer(
00487   omx_base_PortType *openmaxStandPort,
00488   OMX_BUFFERHEADERTYPE** pBuffer,
00489   OMX_U32 nPortIndex,
00490   OMX_PTR pAppPrivate,
00491   OMX_U32 nSizeBytes) {
00492   
00493   int i;
00494   OMX_COMPONENTTYPE* omxComponent = openmaxStandPort->standCompContainer;
00495   omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate;
00496   omx_videosrc_component_PrivateType* omx_videosrc_component_Private = (omx_videosrc_component_PrivateType*)omx_base_component_Private;
00497   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00498 
00499   if (nPortIndex != openmaxStandPort->sPortParam.nPortIndex) {
00500     return OMX_ErrorBadPortIndex;
00501   }
00502   if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) {
00503     return OMX_ErrorBadPortIndex;
00504   }
00505 
00506   if (omx_base_component_Private->transientState != OMX_TransStateLoadedToIdle) {
00507     if (!openmaxStandPort->bIsTransientToEnabled) {
00508       DEBUG(DEB_LEV_ERR, "In %s: The port is not allowed to receive buffers\n", __func__);
00509       return OMX_ErrorIncorrectStateTransition;
00510     }
00511   }
00512 
00513   if(nSizeBytes < openmaxStandPort->sPortParam.nBufferSize) {
00514     DEBUG(DEB_LEV_ERR, "In %s: Requested Buffer Size %lu is less than Minimum Buffer Size %lu\n", __func__, nSizeBytes, openmaxStandPort->sPortParam.nBufferSize);
00515     return OMX_ErrorIncorrectStateTransition;
00516   }
00517   
00518   for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++){
00519     if (openmaxStandPort->bBufferStateAllocated[i] == BUFFER_FREE) {
00520       openmaxStandPort->pInternalBufferStorage[i] = calloc(1,sizeof(OMX_BUFFERHEADERTYPE));
00521       if (!openmaxStandPort->pInternalBufferStorage[i]) {
00522         return OMX_ErrorInsufficientResources;
00523       }
00524       setHeader(openmaxStandPort->pInternalBufferStorage[i], sizeof(OMX_BUFFERHEADERTYPE));
00525       /* Map the buffer with the device's memory area*/
00526       if(i > n_buffers) {
00527         DEBUG(DEB_LEV_ERR, "In %s returning error i=%d, nframe=%d\n", __func__,i,n_buffers);
00528         return OMX_ErrorInsufficientResources;
00529       }
00530       
00531       omx_videosrc_component_Private->bOutBufferMemoryMapped = OMX_TRUE;
00532       openmaxStandPort->pInternalBufferStorage[i]->pBuffer = omx_videosrc_component_Private->buffers[i].start;
00533       openmaxStandPort->pInternalBufferStorage[i]->nAllocLen = (int)nSizeBytes;
00534       openmaxStandPort->pInternalBufferStorage[i]->pPlatformPrivate = openmaxStandPort;
00535       openmaxStandPort->pInternalBufferStorage[i]->pAppPrivate = pAppPrivate;
00536       *pBuffer = openmaxStandPort->pInternalBufferStorage[i];
00537       openmaxStandPort->bBufferStateAllocated[i] = BUFFER_ALLOCATED;
00538       openmaxStandPort->bBufferStateAllocated[i] |= HEADER_ALLOCATED;
00539       if (openmaxStandPort->sPortParam.eDir == OMX_DirInput) {
00540         openmaxStandPort->pInternalBufferStorage[i]->nInputPortIndex = openmaxStandPort->sPortParam.nPortIndex;
00541       } else {
00542         openmaxStandPort->pInternalBufferStorage[i]->nOutputPortIndex = openmaxStandPort->sPortParam.nPortIndex;
00543       }
00544       openmaxStandPort->nNumAssignedBuffers++;
00545       DEBUG(DEB_LEV_PARAMS, "openmaxStandPort->nNumAssignedBuffers %i\n", (int)openmaxStandPort->nNumAssignedBuffers);
00546 
00547       if (openmaxStandPort->sPortParam.nBufferCountActual == openmaxStandPort->nNumAssignedBuffers) {
00548         openmaxStandPort->sPortParam.bPopulated = OMX_TRUE;
00549         openmaxStandPort->bIsFullOfBuffers = OMX_TRUE;
00550         DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s nPortIndex=%d\n",__func__,(int)nPortIndex);
00551         tsem_up(openmaxStandPort->pAllocSem);
00552       }
00553       return OMX_ErrorNone;
00554     }
00555   }
00556   DEBUG(DEB_LEV_ERR, "In %s Error: no available buffers\n",__func__);
00557   return OMX_ErrorInsufficientResources;
00558 }
00559 OMX_ERRORTYPE videosrc_port_FreeBuffer(
00560   omx_base_PortType *openmaxStandPort,
00561   OMX_U32 nPortIndex,
00562   OMX_BUFFERHEADERTYPE* pBuffer) {
00563 
00564   int i;
00565   OMX_COMPONENTTYPE* omxComponent = openmaxStandPort->standCompContainer;
00566   omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate;
00567   omx_videosrc_component_PrivateType* omx_videosrc_component_Private = (omx_videosrc_component_PrivateType*)omx_base_component_Private;
00568   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00569 
00570   if (nPortIndex != openmaxStandPort->sPortParam.nPortIndex) {
00571     return OMX_ErrorBadPortIndex;
00572   }
00573   if (PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) {
00574     return OMX_ErrorBadPortIndex;
00575   }
00576 
00577   if (omx_base_component_Private->transientState != OMX_TransStateIdleToLoaded) {
00578     if (!openmaxStandPort->bIsTransientToDisabled) {
00579       DEBUG(DEB_LEV_FULL_SEQ, "In %s: The port is not allowed to free the buffers\n", __func__);
00580       (*(omx_base_component_Private->callbacks->EventHandler))
00581         (omxComponent,
00582         omx_base_component_Private->callbackData,
00583         OMX_EventError, /* The command was completed */
00584         OMX_ErrorPortUnpopulated, /* The commands was a OMX_CommandStateSet */
00585         nPortIndex, /* The state has been changed in message->messageParam2 */
00586         NULL);
00587     }
00588   }
00589   
00590   for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++){
00591     if (openmaxStandPort->bBufferStateAllocated[i] & (BUFFER_ASSIGNED | BUFFER_ALLOCATED)) {
00592 
00593       openmaxStandPort->bIsFullOfBuffers = OMX_FALSE;
00594       if (openmaxStandPort->bBufferStateAllocated[i] & BUFFER_ALLOCATED) {
00595         if(openmaxStandPort->pInternalBufferStorage[i]->pBuffer){
00596           DEBUG(DEB_LEV_PARAMS, "In %s freeing %i pBuffer=%x\n",__func__, (int)i, (int)openmaxStandPort->pInternalBufferStorage[i]->pBuffer);
00597           openmaxStandPort->pInternalBufferStorage[i]->pBuffer=NULL;
00598           omx_videosrc_component_Private->bOutBufferMemoryMapped = OMX_FALSE;
00599         }
00600       } else if (openmaxStandPort->bBufferStateAllocated[i] & BUFFER_ASSIGNED) {
00601         free(pBuffer);
00602         pBuffer=NULL;
00603       }
00604       if(openmaxStandPort->bBufferStateAllocated[i] & HEADER_ALLOCATED) {
00605         free(openmaxStandPort->pInternalBufferStorage[i]);
00606         openmaxStandPort->pInternalBufferStorage[i]=NULL;
00607       }
00608 
00609       openmaxStandPort->bBufferStateAllocated[i] = BUFFER_FREE;
00610 
00611       openmaxStandPort->nNumAssignedBuffers--;
00612       DEBUG(DEB_LEV_PARAMS, "openmaxStandPort->nNumAssignedBuffers %i\n", (int)openmaxStandPort->nNumAssignedBuffers);
00613 
00614       if (openmaxStandPort->nNumAssignedBuffers == 0) {
00615         openmaxStandPort->sPortParam.bPopulated = OMX_FALSE;
00616         openmaxStandPort->bIsEmptyOfBuffers = OMX_TRUE;
00617         tsem_up(openmaxStandPort->pAllocSem);
00618       }
00619       return OMX_ErrorNone;
00620     }
00621   }
00622   return OMX_ErrorInsufficientResources;
00623 }
00624 
00625 OMX_ERRORTYPE videosrc_port_AllocateTunnelBuffer(omx_base_PortType *openmaxStandPort,OMX_IN OMX_U32 nPortIndex,OMX_IN OMX_U32 nSizeBytes)
00626 {
00627   int i;
00628   OMX_COMPONENTTYPE* omxComponent = openmaxStandPort->standCompContainer;
00629   omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate;
00630   omx_videosrc_component_PrivateType* omx_videosrc_component_Private = (omx_videosrc_component_PrivateType*)omx_base_component_Private;
00631   OMX_U8* pBuffer=NULL;
00632   OMX_ERRORTYPE eError=OMX_ErrorNone;
00633   OMX_U32 numRetry=0;
00634   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00635 
00636   if (nPortIndex != openmaxStandPort->sPortParam.nPortIndex) {
00637     DEBUG(DEB_LEV_ERR, "In %s: Bad Port Index\n", __func__);
00638     return OMX_ErrorBadPortIndex;
00639   }
00640   if (! PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) {
00641     DEBUG(DEB_LEV_ERR, "In %s: Port is not tunneled Flag=%x\n", __func__, (int)openmaxStandPort->nTunnelFlags);
00642     return OMX_ErrorBadPortIndex;
00643   }
00644 
00645   if (omx_base_component_Private->transientState != OMX_TransStateLoadedToIdle) {
00646     if (!openmaxStandPort->bIsTransientToEnabled) {
00647       DEBUG(DEB_LEV_ERR, "In %s: The port is not allowed to receive buffers\n", __func__);
00648       return OMX_ErrorIncorrectStateTransition;
00649     }
00650   }
00651   
00652   for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++){
00653     if (openmaxStandPort->bBufferStateAllocated[i] == BUFFER_FREE) {
00654       /* Map the buffer with the device's memory area*/
00655       if(i > n_buffers) {
00656         DEBUG(DEB_LEV_ERR, "In %s returning error i=%d, nframe=%d\n", __func__,i,n_buffers);
00657         return OMX_ErrorInsufficientResources;
00658       }
00659       omx_videosrc_component_Private->bOutBufferMemoryMapped = OMX_TRUE;
00660       pBuffer = omx_videosrc_component_Private->buffers[i].start;
00661 
00662       /*Retry more than once, if the tunneled component is not in Loaded->Idle State*/
00663       while(numRetry <TUNNEL_USE_BUFFER_RETRY) {
00664         eError=OMX_UseBuffer(openmaxStandPort->hTunneledComponent,&openmaxStandPort->pInternalBufferStorage[i],
00665                              openmaxStandPort->nTunneledPort,NULL,nSizeBytes,pBuffer); 
00666         if(eError!=OMX_ErrorNone) {
00667           DEBUG(DEB_LEV_FULL_SEQ,"Tunneled Component Couldn't Use buffer %i From Comp=%s Retry=%d\n",
00668           i,omx_base_component_Private->name,(int)numRetry);
00669 
00670           if((eError ==  OMX_ErrorIncorrectStateTransition) && numRetry<TUNNEL_USE_BUFFER_RETRY) {
00671             DEBUG(DEB_LEV_FULL_SEQ,"Waiting for next try %i \n",(int)numRetry);
00672             usleep(TUNNEL_USE_BUFFER_RETRY_USLEEP_TIME);
00673             numRetry++;
00674             continue;
00675           }
00676           return eError;
00677         }
00678         else {
00679           break;
00680         }
00681       }
00682       openmaxStandPort->bBufferStateAllocated[i] = BUFFER_ALLOCATED;
00683       openmaxStandPort->nNumAssignedBuffers++;
00684       DEBUG(DEB_LEV_PARAMS, "openmaxStandPort->nNumAssignedBuffers %i\n", (int)openmaxStandPort->nNumAssignedBuffers);
00685 
00686       if (openmaxStandPort->sPortParam.nBufferCountActual == openmaxStandPort->nNumAssignedBuffers) {
00687         openmaxStandPort->sPortParam.bPopulated = OMX_TRUE;
00688         openmaxStandPort->bIsFullOfBuffers = OMX_TRUE;
00689         DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s nPortIndex=%d\n",__func__, (int)nPortIndex);
00690       }
00691       queue(openmaxStandPort->pBufferQueue, openmaxStandPort->pInternalBufferStorage[i]);
00692     }
00693   }
00694   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s Allocated all buffers\n",__func__);
00695   return OMX_ErrorNone;
00696 }
00697 
00698 OMX_ERRORTYPE videosrc_port_FreeTunnelBuffer(omx_base_PortType *openmaxStandPort,OMX_U32 nPortIndex)
00699 {
00700   int i;
00701   OMX_COMPONENTTYPE* omxComponent = openmaxStandPort->standCompContainer;
00702   omx_base_component_PrivateType* omx_base_component_Private = (omx_base_component_PrivateType*)omxComponent->pComponentPrivate;
00703   omx_videosrc_component_PrivateType* omx_videosrc_component_Private = (omx_videosrc_component_PrivateType*)omx_base_component_Private;
00704   OMX_ERRORTYPE eError=OMX_ErrorNone;
00705   OMX_U32 numRetry=0;
00706   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n", __func__);
00707 
00708   if (nPortIndex != openmaxStandPort->sPortParam.nPortIndex) {
00709     DEBUG(DEB_LEV_ERR, "In %s: Bad Port Index\n", __func__);
00710     return OMX_ErrorBadPortIndex;
00711   }
00712   if (! PORT_IS_TUNNELED_N_BUFFER_SUPPLIER(openmaxStandPort)) {
00713     DEBUG(DEB_LEV_ERR, "In %s: Port is not tunneled\n", __func__);
00714     return OMX_ErrorBadPortIndex;
00715   }
00716 
00717   if (omx_base_component_Private->transientState != OMX_TransStateIdleToLoaded) {
00718     if (!openmaxStandPort->bIsTransientToDisabled) {
00719       DEBUG(DEB_LEV_FULL_SEQ, "In %s: The port is not allowed to free the buffers\n", __func__);
00720       (*(omx_base_component_Private->callbacks->EventHandler))
00721         (omxComponent,
00722         omx_base_component_Private->callbackData,
00723         OMX_EventError, /* The command was completed */
00724         OMX_ErrorPortUnpopulated, /* The commands was a OMX_CommandStateSet */
00725         nPortIndex, /* The state has been changed in message->messageParam2 */
00726         NULL);
00727     }
00728   }
00729 
00730   for(i=0; i < openmaxStandPort->sPortParam.nBufferCountActual; i++){
00731     if (openmaxStandPort->bBufferStateAllocated[i] & (BUFFER_ASSIGNED | BUFFER_ALLOCATED)) {
00732 
00733       openmaxStandPort->bIsFullOfBuffers = OMX_FALSE;
00734       if (openmaxStandPort->bBufferStateAllocated[i] & BUFFER_ALLOCATED) {
00735         openmaxStandPort->pInternalBufferStorage[i]->pBuffer = NULL;
00736         omx_videosrc_component_Private->bOutBufferMemoryMapped = OMX_FALSE;
00737       }
00738       /*Retry more than once, if the tunneled component is not in Idle->Loaded State*/
00739       while(numRetry <TUNNEL_USE_BUFFER_RETRY) {
00740         eError=OMX_FreeBuffer(openmaxStandPort->hTunneledComponent,openmaxStandPort->nTunneledPort,openmaxStandPort->pInternalBufferStorage[i]);
00741         if(eError!=OMX_ErrorNone) {
00742           DEBUG(DEB_LEV_ERR,"Tunneled Component Couldn't free buffer %i \n",i);
00743           if((eError ==  OMX_ErrorIncorrectStateTransition) && numRetry<TUNNEL_USE_BUFFER_RETRY) {
00744             DEBUG(DEB_LEV_ERR,"Waiting for next try %i \n",(int)numRetry);
00745             usleep(TUNNEL_USE_BUFFER_RETRY_USLEEP_TIME);
00746             numRetry++;
00747             continue;
00748           }
00749           return eError;
00750         } else {
00751           break;
00752         }
00753       }
00754       openmaxStandPort->bBufferStateAllocated[i] = BUFFER_FREE;
00755 
00756       openmaxStandPort->nNumAssignedBuffers--;
00757       DEBUG(DEB_LEV_PARAMS, "openmaxStandPort->nNumAssignedBuffers %i\n", (int)openmaxStandPort->nNumAssignedBuffers);
00758 
00759       if (openmaxStandPort->nNumAssignedBuffers == 0) {
00760         openmaxStandPort->sPortParam.bPopulated = OMX_FALSE;
00761         openmaxStandPort->bIsEmptyOfBuffers = OMX_TRUE;
00762         //tsem_up(openmaxStandPort->pAllocSem);
00763       }
00764     }
00765   }
00766   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s Qelem=%d BSem=%d\n", __func__,openmaxStandPort->pBufferQueue->nelem,openmaxStandPort->pBufferSem->semval);
00767   return OMX_ErrorNone;
00768 }
00769 
00770 static int xioctl(int fd, int request, void *arg)
00771 {
00772   int r;
00773 
00774   do
00775     r = ioctl(fd, request, arg);
00776   while (-1 == r && EINTR == errno);
00777 
00778   return r;
00779 }
00780 
00781 static int init_device(omx_videosrc_component_PrivateType* omx_videosrc_component_Private)
00782 {
00783 
00784   if (-1 == xioctl(omx_videosrc_component_Private->deviceHandle, VIDIOC_QUERYCAP, &omx_videosrc_component_Private->cap)) {
00785     if (EINVAL == errno) {
00786         DEBUG(DEB_LEV_ERR, "%s is no V4L2 device\n", VIDEO_DEV_NAME);
00787         return OMX_ErrorHardware;
00788     } else {
00789         return errno_return("VIDIOC_QUERYCAP");
00790       }
00791   }
00792 
00793   if (!(omx_videosrc_component_Private->cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
00794     DEBUG(DEB_LEV_ERR, "%s is no video capture device\n", VIDEO_DEV_NAME);
00795     return OMX_ErrorHardware;
00796   }
00797   
00798   if (!(omx_videosrc_component_Private->cap.capabilities & V4L2_CAP_STREAMING)) {
00799       DEBUG(DEB_LEV_ERR, "%s does not support streaming i/o\n", VIDEO_DEV_NAME);
00800       return OMX_ErrorHardware;
00801     }
00802 
00803   /* Select video input, video standard and tune here. */
00804   omx_videosrc_component_Private->cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00805 
00806   if (-1 == xioctl(omx_videosrc_component_Private->deviceHandle, VIDIOC_CROPCAP, &omx_videosrc_component_Private->cropcap)) {
00807     /* Errors ignored. */
00808   }
00809 
00810   omx_videosrc_component_Private->crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00811   omx_videosrc_component_Private->crop.c = omx_videosrc_component_Private->cropcap.defrect; /* reset to default */
00812 
00813   if (-1 == xioctl(omx_videosrc_component_Private->deviceHandle, VIDIOC_S_CROP, &omx_videosrc_component_Private->crop)) {
00814     switch (errno) {
00815     case EINVAL:
00816         /* Cropping not supported. */
00817         break;
00818       default:
00819         /* Errors ignored. */
00820         break;
00821       }
00822   }
00823 
00824   CLEAR(omx_videosrc_component_Private->fmt);
00825   
00826   return OMX_ErrorNone;
00827 }
00828 
00829 static int start_capturing(omx_videosrc_component_PrivateType* omx_videosrc_component_Private)
00830 {
00831   unsigned int i;
00832   enum v4l2_buf_type type;
00833 
00834   for (i = 0; i < n_buffers; ++i)
00835     {
00836       struct v4l2_buffer buf;
00837 
00838       CLEAR(buf);
00839 
00840       buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00841       buf.memory = V4L2_MEMORY_MMAP;
00842       buf.index = i;
00843 
00844       if (-1 == xioctl(omx_videosrc_component_Private->deviceHandle, VIDIOC_QBUF, &buf))
00845         return errno_return("VIDIOC_QBUF");
00846     }
00847 
00848   type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00849 
00850   if (-1 == xioctl(omx_videosrc_component_Private->deviceHandle, VIDIOC_STREAMON, &type))
00851       return errno_return("VIDIOC_STREAMON");
00852    
00853   return OMX_ErrorNone;
00854 }
00855 
00856 static int stop_capturing(omx_videosrc_component_PrivateType* omx_videosrc_component_Private)
00857 {
00858   enum v4l2_buf_type type;
00859 
00860   type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00861 
00862   if (-1 == xioctl(omx_videosrc_component_Private->deviceHandle, VIDIOC_STREAMOFF, &type))
00863     return errno_return("VIDIOC_STREAMOFF");
00864     
00865   return OMX_ErrorNone;
00866 }
00867 
00868 static int uninit_device(omx_videosrc_component_PrivateType* omx_videosrc_component_Private)
00869 {
00870   unsigned int i;
00871   
00872   for (i = 0; i < n_buffers; ++i) {
00873     if (-1 == munmap(omx_videosrc_component_Private->buffers[i].start, omx_videosrc_component_Private->buffers[i].length))
00874       return errno_return("munmap");
00875   }
00876 
00877   free(omx_videosrc_component_Private->buffers);
00878 
00879   return OMX_ErrorNone;
00880 }
00881 
00882 static int init_mmap(omx_videosrc_component_PrivateType* omx_videosrc_component_Private)
00883 {
00884   struct v4l2_requestbuffers req;
00885 
00886   CLEAR(req);
00887 
00888   req.count = 4;
00889   req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00890   req.memory = V4L2_MEMORY_MMAP;
00891 
00892   if (-1 == xioctl(omx_videosrc_component_Private->deviceHandle, VIDIOC_REQBUFS, &req)) {
00893     if (EINVAL == errno) {
00894       DEBUG(DEB_LEV_ERR, "%s does not support "
00895         "memory mapping\n", VIDEO_DEV_NAME);
00896       return OMX_ErrorHardware;
00897     } else {
00898       return errno_return("VIDIOC_REQBUFS");
00899     }
00900   }
00901 
00902   if (req.count < 2) {
00903     DEBUG(DEB_LEV_ERR, "Insufficient buffer memory on %s\n", VIDEO_DEV_NAME);
00904     return OMX_ErrorHardware;
00905   }
00906 
00907   omx_videosrc_component_Private->buffers = calloc(req.count, sizeof(*omx_videosrc_component_Private->buffers));
00908 
00909   if (!omx_videosrc_component_Private->buffers) {
00910     DEBUG(DEB_LEV_ERR,"Out of memory\n");
00911     return OMX_ErrorHardware;
00912   }
00913 
00914   for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
00915     struct v4l2_buffer buf;
00916 
00917     CLEAR(buf);
00918 
00919     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00920     buf.memory = V4L2_MEMORY_MMAP;
00921     buf.index = n_buffers;
00922 
00923     if (-1 == xioctl(omx_videosrc_component_Private->deviceHandle, VIDIOC_QUERYBUF, &buf))
00924         return errno_return("VIDIOC_QUERYBUF");
00925 
00926     omx_videosrc_component_Private->buffers[n_buffers].length = buf.length;
00927     omx_videosrc_component_Private->buffers[n_buffers].start = mmap(NULL /* start anywhere */ ,
00928                     buf.length,
00929                     PROT_READ | PROT_WRITE /* required */ ,
00930                     MAP_SHARED /* recommended */ ,
00931                     omx_videosrc_component_Private->deviceHandle, buf.m.offset);
00932 
00933     if (MAP_FAILED == omx_videosrc_component_Private->buffers[n_buffers].start)
00934       return errno_return("mmap");
00935   }
00936 
00937   return OMX_ErrorNone;
00938 }

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