omx_camera_source_component.c

Go to the documentation of this file.
00001 
00029 #include <fcntl.h>
00030 #include <errno.h>
00031 #include <sys/ioctl.h>
00032 #include <unistd.h>
00033 #include <sys/mman.h>
00034 #include <sys/time.h>
00035 #include <time.h>
00036 #include <string.h>
00037 
00038 #include <OMX_Core.h>
00039 #include <omx_comp_debug_levels.h>
00040 
00041 #include "omx_camera_source_component.h"
00042 
00043 #define DEFAULT_FRAME_RATE 15
00044 
00045 #define DEFAULT_FRAME_WIDTH 320 
00046 #define DEFAULT_FRAME_HEIGHT 240
00047 
00048 #define DEFAULT_COLOR_FORMAT OMX_COLOR_FormatYUV420PackedPlanar
00049 
00050 #define GET_SYSERR_STRING() strerror(errno)
00051 
00052 /* Thumbnail (snapshot) index from video captured frame */
00053 #define OMX_CAM_VC_SNAPSHOT_INDEX    5
00054 
00055 #define CLEAR(x) memset (&(x), 0, sizeof (x))
00056 
00057 
00058 
00059 /* V4L2 Mapping Queue Interface */
00060 #define OMX_MAPBUFQUEUE_ISEMPTY(_queue_) (0 == (_queue_).nBufCountTotal)
00061 #define OMX_MAPBUFQUEUE_ISFULL(_queue_) ((_queue_).nBufCountTotal > 0 && (_queue_).nNextCaptureIndex == (_queue_).nLastBufIndex)
00062 #define OMX_MAPBUFQUEUE_NOBUFCAPTURED(_queue_) (0 == (_queue_).nBufCountCaptured)
00063 #define OMX_MAPBUFQUEUE_HASBUFCAPTURED(_queue_) (!(OMX_MAPBUFQUEUE_NOBUFCAPTURED(_queue_)))
00064 #define OMX_MAPBUFQUEUE_NOBUFWAITTOCAPTURE(_queue_) (OMX_MAPBUFQUEUE_HASBUFCAPTURED(_queue_) && (_queue_).nNextWaitIndex == (_queue_).nNextCaptureIndex)
00065 #define OMX_MAPBUFQUEUE_HASBUFWAITTOCAPTURE(_queue_) (!(OMX_MAPBUFQUEUE_NOBUFWAITTOCAPTURE(_queue_)))
00066 
00067 #define OMX_MAPBUFQUEUE_GETMAXLEN(_queue_) ((_queue_).nFrame)
00068 
00069 #define OMX_MAPBUFQUEUE_GETNEXTCAPTURE(_queue_) ((_queue_).nNextCaptureIndex)
00070 #define OMX_MAPBUFQUEUE_GETNEXTWAIT(_queue_) ((_queue_).nNextWaitIndex)
00071 #define OMX_MAPBUFQUEUE_GETLASTBUFFER(_queue_) ((_queue_).nLastBufIndex)
00072 #define OMX_MAPBUFQUEUE_GETNEXTINDEX(_queue_, _curindex_) ((_curindex_ + 1) % (_queue_).nFrame)
00073 
00074 #define OMX_MAPBUFQUEUE_GETBUFCOUNTCAPTURED(_queue_) ((_queue_).nBufCountCaptured)
00075 
00076 #define OMX_MAPBUFQUEUE_GETBUFADDR(_queue_, _bufindex_) ((OMX_PTR) (_queue_).buffers[(_bufindex_)].pCapAddrStart)
00077 
00078 #define OMX_MAPBUFQUEUE_MAKEEMPTY(_queue_) do \
00079                                                                                { \
00080                                                                                    (_queue_).nNextCaptureIndex = 0; \
00081                                                                                    (_queue_).nNextWaitIndex = 0; \
00082                                                                                    (_queue_).nLastBufIndex = 0; \
00083                                                                                    (_queue_).nBufCountTotal = 0; \
00084                                                                                    (_queue_).nBufCountCaptured = 0; \
00085                                                                                } while (0)
00086 #define OMX_MAPBUFQUEUE_ENQUEUE(_queue_) do \
00087                                                                                { \
00088                                                                                    (_queue_).nNextCaptureIndex = ((_queue_).nNextCaptureIndex + 1) % (_queue_).nFrame; \
00089                                                                                    (_queue_).nBufCountTotal ++; \
00090                                                                                } while (0)
00091 #define OMX_MAPBUFQUEUE_DEQUEUE(_queue_) do \
00092                                                                                { \
00093                                                                                    (_queue_).nLastBufIndex = ((_queue_).nLastBufIndex + 1) % (_queue_).nFrame; \
00094                                                                                    (_queue_).nBufCountTotal --; \
00095                                                                                    (_queue_).nBufCountCaptured --; \
00096                                                                                } while (0)
00097 
00098 #define OMX_MAPBUFQUEUE_ADDCAPTUREDBUF(_queue_) do \
00099                                                                                { \
00100                                                                                    (_queue_).nNextWaitIndex = ((_queue_).nNextWaitIndex + 1) % (_queue_).nFrame; \
00101                                                                                    (_queue_).nBufCountCaptured ++; \
00102                                                                                } while (0)
00103 
00104 #define OMX_MAPBUFQUEUE_GETTIMESTAMP(_queue_, _bufindex_) ((_queue_).qTimeStampQueue[(_bufindex_)])
00105 #define OMX_MAPBUFQUEUE_SETTIMESTAMP(_queue_, _bufindex_, _timestamp_) do \
00106                                                                                { \
00107                                                                                    (_queue_).qTimeStampQueue[(_bufindex_)] = (OMX_TICKS)(_timestamp_); \
00108                                                                                } while (0)
00109 
00110 
00111 typedef struct CAM_SENSOR_OMXV4LCOLORTYPE
00112 {
00113   OMX_COLOR_FORMATTYPE eOmxColorFormat;
00114   V4L2_COLOR_FORMATTYPE sV4lColorFormat;
00115 } CAM_SENSOR_OMXV4LCOLORTYPE;
00116 
00117 
00118 typedef struct CAM_CAPTURE_FRAMESIZETYPE
00119 {
00120     OMX_U32 nWidth;
00121     OMX_U32 nHeight;
00122 } CAM_CAPTURE_FRAMESIZETYPE;
00123 
00124 
00125 static const CAM_SENSOR_OMXV4LCOLORTYPE g_SupportedColorTable[] = {
00126   {OMX_COLOR_FormatL8, {V4L2_PIX_FMT_GREY, 8}},
00127   {OMX_COLOR_Format16bitRGB565,{V4L2_PIX_FMT_RGB565,16}},
00128   {OMX_COLOR_Format24bitRGB888,{V4L2_PIX_FMT_RGB24,24}},
00129   {OMX_COLOR_FormatYCbYCr,{V4L2_PIX_FMT_YUYV,16}},
00130   {OMX_COLOR_FormatYUV422PackedPlanar,{V4L2_PIX_FMT_YUV422P,16}},
00131   {OMX_COLOR_FormatYUV420PackedPlanar,{V4L2_PIX_FMT_YUV420,12}}
00132 };
00133 
00134 
00135 /* Table for supported capture framsizes (based on the WebEye V2000 camera) */
00136 static const CAM_CAPTURE_FRAMESIZETYPE g_SupportedFramesizeTable[] =
00137 {
00138     {64, 48},
00139     {72, 64},
00140     {88, 72},
00141     {96, 128},
00142     {128, 96},
00143     {144, 176},
00144     {160, 120},
00145     {176, 144},
00146     {200, 80},
00147     {224, 96},
00148     {256, 144},
00149     {320, 240},
00150     {352, 288},
00151     {432, 256},
00152     {512, 376},
00153     {568, 400},
00154     {640, 480}
00155     /* more settings can be added ... */
00156 };
00157 
00158 static int camera_init_mmap(omx_camera_source_component_PrivateType* omx_camera_source_component_Private);
00159 
00160 static int xioctl(int fd, int request, void *arg)
00161 {
00162   int r;
00163 
00164   do
00165     r = ioctl(fd, request, arg);
00166   while (-1 == r && EINTR == errno);
00167 
00168   return r;
00169 }
00170 
00171 static OMX_ERRORTYPE omx_camera_source_component_GetParameter(
00172   OMX_IN  OMX_HANDLETYPE hComponent,
00173   OMX_IN  OMX_INDEXTYPE nParamIndex,
00174   OMX_INOUT  OMX_PTR ComponentParameterStructure);
00175 
00176 static OMX_ERRORTYPE omx_camera_source_component_SetParameter(
00177   OMX_IN  OMX_HANDLETYPE hComponent,
00178   OMX_IN  OMX_INDEXTYPE nParamIndex,
00179   OMX_IN  OMX_PTR ComponentParameterStructure);
00180 
00181 static OMX_ERRORTYPE omx_camera_source_component_GetConfig(
00182   OMX_IN  OMX_HANDLETYPE hComponent,
00183   OMX_IN  OMX_INDEXTYPE nConfigIndex,
00184   OMX_INOUT OMX_PTR pComponentConfigStructure);
00185 
00186 static OMX_ERRORTYPE omx_camera_source_component_SetConfig(
00187   OMX_IN  OMX_HANDLETYPE hComponent,
00188   OMX_IN  OMX_INDEXTYPE nConfigIndex,
00189   OMX_IN OMX_PTR pComponentConfigStructure);
00190 
00195 static void* omx_camera_source_component_BufferMgmtFunction (void* param);
00196 
00201 static OMX_ERRORTYPE omx_camera_source_component_DoStateSet(OMX_COMPONENTTYPE *openmaxStandComp, OMX_U32 destinationState);
00202 
00203 static OMX_ERRORTYPE camera_CheckSupportedColorFormat(OMX_IN OMX_COLOR_FORMATTYPE eColorFormat);
00204 static OMX_ERRORTYPE camera_CheckSupportedFramesize(
00205   OMX_IN OMX_U32 nFrameWidth,
00206   OMX_IN  OMX_U32 nFrameHeight);
00207 static OMX_ERRORTYPE camera_MapColorFormatOmxToV4l(
00208   OMX_IN OMX_COLOR_FORMATTYPE eOmxColorFormat,
00209   OMX_INOUT V4L2_COLOR_FORMATTYPE* pV4lColorFormat );
00210 
00211 static OMX_ERRORTYPE camera_MapColorFormatV4lToOmx(
00212   OMX_IN V4L2_COLOR_FORMATTYPE* pV4lColorFormat,
00213   OMX_INOUT OMX_COLOR_FORMATTYPE* pOmxColorFormat );
00214 
00215 static OMX_U32 camera_CalculateBufferSize(
00216   OMX_IN OMX_U32 nWidth,
00217   OMX_IN OMX_U32 nHeight,
00218   OMX_IN OMX_COLOR_FORMATTYPE eOmxColorFormat);
00219 
00220 static OMX_ERRORTYPE camera_SetConfigCapturing(
00221   OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private,
00222   OMX_IN OMX_CONFIG_BOOLEANTYPE *pCapturing );
00223 
00224 
00225 static OMX_ERRORTYPE camera_InitCameraDevice(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private);
00226 static OMX_ERRORTYPE camera_DeinitCameraDevice(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private);
00227 static OMX_ERRORTYPE camera_StartCameraDevice(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private);
00228 static OMX_ERRORTYPE camera_StopCameraDevice(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private);
00229 static OMX_ERRORTYPE camera_HandleThreadBufferCapture(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private);
00230 static OMX_ERRORTYPE camera_GenerateTimeStamp(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private);
00231 static OMX_ERRORTYPE camera_SendCapturedBuffers(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private);
00232 static OMX_ERRORTYPE camera_SendLastCapturedBuffer(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private);
00233 static OMX_ERRORTYPE camera_UpdateCapturedBufferQueue(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private);
00234 static OMX_ERRORTYPE camera_ProcessPortOneBuffer(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private,  OMX_IN OMX_U32 nPortIndex );
00235 static OMX_ERRORTYPE camera_DropLastCapturedBuffer(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private);
00236 static OMX_ERRORTYPE camera_ReformatVideoFrame(
00237   OMX_IN OMX_PTR              pSrcFrameAddr,
00238   OMX_IN OMX_U32              nSrcFrameWidth,
00239   OMX_IN OMX_U32              nSrcFrameHeight,
00240   OMX_IN V4L2_COLOR_FORMATTYPE sSrcV4l2ColorFormat,
00241   OMX_IN OMX_PTR              pDstFrameAddr,
00242   OMX_IN OMX_U32              nDstFrameWidth,
00243   OMX_IN OMX_U32              nDstFrameHeight,
00244   OMX_IN OMX_S32              nDstFrameStride,
00245   OMX_IN OMX_COLOR_FORMATTYPE eDstOmxColorFormat,
00246   OMX_IN OMX_BOOL bStrideAlign );
00247 static OMX_ERRORTYPE camera_AddTimeStamp(
00248   OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private,
00249   OMX_IN OMX_BUFFERHEADERTYPE *pBufHeader);
00250 static OMX_ERRORTYPE camera_UpdateThumbnailCondition(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private);
00251 static OMX_ERRORTYPE camera_HandleStillImageCapture(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private);
00252 static OMX_ERRORTYPE camera_HandleThumbnailCapture(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private);
00253 
00254 
00255 /* Check whether eColorFormat is supported */
00256 static OMX_ERRORTYPE camera_CheckSupportedColorFormat(OMX_IN OMX_COLOR_FORMATTYPE eColorFormat) {
00257   OMX_U32 i;
00258 
00259   for (i = 0; i < sizeof(g_SupportedColorTable)/sizeof(g_SupportedColorTable[0]); i++)
00260   {
00261     if (eColorFormat == g_SupportedColorTable[i].eOmxColorFormat)
00262     {
00263       return OMX_ErrorNone;
00264     }
00265   }
00266 
00267   /* Not found supported color format */
00268   return OMX_ErrorUnsupportedSetting;
00269 }
00270 
00271 
00272 /* Check whether the frame size (nFrameWidth, nFrameHeight) is supported */
00273 static OMX_ERRORTYPE camera_CheckSupportedFramesize(
00274   OMX_IN OMX_U32 nFrameWidth,
00275   OMX_IN  OMX_U32 nFrameHeight) {
00276   OMX_U32 i;
00277 
00278   for (i = 0; i < sizeof(g_SupportedFramesizeTable)/sizeof(g_SupportedFramesizeTable[0]); i++)
00279   {
00280     if (nFrameWidth == g_SupportedFramesizeTable[i].nWidth &&
00281          nFrameHeight == g_SupportedFramesizeTable[i].nHeight)
00282     {
00283       return OMX_ErrorNone;
00284     }
00285   }
00286 
00287   /* Not found supported frame size */
00288   return OMX_ErrorUnsupportedSetting;
00289 }
00290 
00291 /* Map OMX color format to V4L2 color format */
00292 static OMX_ERRORTYPE camera_MapColorFormatOmxToV4l(
00293   OMX_IN OMX_COLOR_FORMATTYPE eOmxColorFormat,
00294   OMX_INOUT V4L2_COLOR_FORMATTYPE* pV4lColorFormat ) {
00295   OMX_U32 i;
00296 
00297   for (i = 0; i < sizeof(g_SupportedColorTable)/sizeof(g_SupportedColorTable[0]); i++) {
00298     if (eOmxColorFormat == g_SupportedColorTable[i].eOmxColorFormat) {
00299       (*pV4lColorFormat) = g_SupportedColorTable[i].sV4lColorFormat;
00300       return OMX_ErrorNone;
00301     }
00302   }
00303 
00304   /* Not found supported color format */
00305   return OMX_ErrorUnsupportedSetting;
00306 }
00307 
00308 /* Map V4L2 color format to OMX color format */
00309 static OMX_ERRORTYPE camera_MapColorFormatV4lToOmx(
00310   OMX_IN V4L2_COLOR_FORMATTYPE* pV4lColorFormat,
00311   OMX_INOUT OMX_COLOR_FORMATTYPE* pOmxColorFormat ) {
00312   OMX_U32 i;
00313 
00314   for (i = 0; i < sizeof(g_SupportedColorTable)/sizeof(g_SupportedColorTable[0]); i++) {
00315     if (pV4lColorFormat->v4l2Pixfmt == g_SupportedColorTable[i].sV4lColorFormat.v4l2Pixfmt &&
00316         pV4lColorFormat->v4l2Depth == g_SupportedColorTable[i].sV4lColorFormat.v4l2Depth) {
00317       (*pOmxColorFormat) = g_SupportedColorTable[i].eOmxColorFormat;
00318       return OMX_ErrorNone;
00319     }
00320   }
00321 
00322   /* Not found supported color format */
00323   return OMX_ErrorUnsupportedSetting;
00324 }
00325 
00326 /* Calculate buffer size according to (width,height,color format) */
00327 static OMX_U32 camera_CalculateBufferSize(
00328   OMX_IN OMX_U32 nWidth,
00329   OMX_IN OMX_U32 nHeight,
00330   OMX_IN OMX_COLOR_FORMATTYPE eOmxColorFormat) {
00331   OMX_U32 i;
00332 
00333   for (i = 0; i < sizeof(g_SupportedColorTable)/sizeof(g_SupportedColorTable[0]); i++) {
00334     if (eOmxColorFormat == g_SupportedColorTable[i].eOmxColorFormat) {
00335       return (nWidth * nHeight * g_SupportedColorTable[i].sV4lColorFormat.v4l2Depth + 7) / 8;
00336     }
00337   }
00338 
00339   /* Not found supported color format, return 0 */
00340   return 0;
00341 }
00342 
00343 /* Set capturing configuration in OMX_SetConfig */
00344 static OMX_ERRORTYPE camera_SetConfigCapturing(
00345   OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private,
00346   OMX_IN OMX_CONFIG_BOOLEANTYPE *pCapturing ) {
00347   omx_camera_source_component_PortType *pCapturePort;
00348   struct timeval now;
00349   OMX_ERRORTYPE err = OMX_ErrorNone;  
00350 
00351   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
00352 
00353   pthread_mutex_lock(&omx_camera_source_component_Private->setconfig_mutex);
00354   if ( pCapturing->bEnabled != omx_camera_source_component_Private->bCapturingNext ) {
00355     if (pCapturing->bEnabled == OMX_TRUE) {
00356       omx_camera_source_component_Private->bIsFirstFrame = OMX_TRUE;
00357       gettimeofday(&now, NULL);
00358       omx_camera_source_component_Private->nRefWallTime = (OMX_TICKS)(now.tv_sec * 1000000 + now.tv_usec);
00359     }
00360     omx_camera_source_component_Private->bCapturingNext = pCapturing->bEnabled;
00361     pCapturePort = (omx_camera_source_component_PortType *)omx_camera_source_component_Private->ports[OMX_CAMPORT_INDEX_CP];
00362     if (PORT_IS_ENABLED(pCapturePort) &&
00363          pCapturing->bEnabled == OMX_FALSE &&
00364          omx_camera_source_component_Private->bAutoPause == OMX_TRUE) {
00365       /* In autopause mode, command camera component to pause state */
00366       if ((err = omx_camera_source_component_DoStateSet(omx_camera_source_component_Private->openmaxStandComp,
00367                      (OMX_U32)OMX_StatePause)) != OMX_ErrorNone ) {
00368         goto EXIT;
00369       }
00370     }
00371   }
00372 
00373 EXIT:
00374   pthread_mutex_unlock(&omx_camera_source_component_Private->setconfig_mutex);
00375   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
00376   return err;
00377 }
00378 
00379 /* Initialize the camera device */
00380 static OMX_ERRORTYPE camera_InitCameraDevice(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private) {
00381   omx_camera_source_component_PortType *pPreviewPort = (omx_camera_source_component_PortType *)omx_camera_source_component_Private->ports[OMX_CAMPORT_INDEX_VF];
00382   omx_camera_source_component_PortType *pCapturePort = (omx_camera_source_component_PortType *)omx_camera_source_component_Private->ports[OMX_CAMPORT_INDEX_CP];
00383   omx_camera_source_component_PortType *pThumbnailPort = (omx_camera_source_component_PortType *)omx_camera_source_component_Private->ports[OMX_CAMPORT_INDEX_CP_T];
00384   omx_camera_source_component_PortType *pPort = (omx_camera_source_component_PortType *)omx_camera_source_component_Private->ports[OMX_CAMPORT_INDEX_CP]; 
00385   OMX_ERRORTYPE err = OMX_ErrorNone;  
00386   
00387   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
00388 
00389   /* Open camera device file */
00390   omx_camera_source_component_Private->fdCam = open(V4L2DEV_FILENAME, O_RDWR  | O_NONBLOCK, 0);
00391   
00392   if ( omx_camera_source_component_Private->fdCam < 0 )
00393   {
00394     DEBUG(DEB_LEV_ERR, "%s: <ERROR> -- Open camera failed: %s\n",__func__,GET_SYSERR_STRING());
00395     err = OMX_ErrorHardware;
00396     goto ERR_HANDLE;
00397   }
00398 
00399   /* Query camera capability */
00400   if (-1 == xioctl(omx_camera_source_component_Private->fdCam, VIDIOC_QUERYCAP, &omx_camera_source_component_Private->cap)) {
00401     if (EINVAL == errno) {
00402       DEBUG(DEB_LEV_ERR, "%s is no V4L2 device\n", V4L2DEV_FILENAME);
00403       err = OMX_ErrorHardware;
00404       goto ERR_HANDLE;
00405     } else {
00406       DEBUG(DEB_LEV_ERR, "%s error %d, %s\n", "VIDIOC_QUERYCAP", errno, strerror(errno));
00407       err = OMX_ErrorHardware;
00408       goto ERR_HANDLE;
00409     }
00410   }
00411 
00412   if (!(omx_camera_source_component_Private->cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
00413     DEBUG(DEB_LEV_ERR, "%s is no video capture device\n", V4L2DEV_FILENAME);
00414     return OMX_ErrorHardware;
00415   }
00416   
00417   if (!(omx_camera_source_component_Private->cap.capabilities & V4L2_CAP_STREAMING)) {
00418     DEBUG(DEB_LEV_ERR, "%s does not support streaming i/o\n", V4L2DEV_FILENAME);
00419     return OMX_ErrorHardware;
00420   }
00421 
00422   /* Select video input, video standard and tune here. */
00423   omx_camera_source_component_Private->cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00424 
00425   if (-1 == xioctl(omx_camera_source_component_Private->fdCam, VIDIOC_CROPCAP, &omx_camera_source_component_Private->cropcap)) {
00426     /* Errors ignored. */
00427   }
00428 
00429   omx_camera_source_component_Private->crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00430   omx_camera_source_component_Private->crop.c = omx_camera_source_component_Private->cropcap.defrect;  /* reset to default */
00431 
00432   if (-1 == xioctl(omx_camera_source_component_Private->fdCam, VIDIOC_S_CROP, &omx_camera_source_component_Private->crop)) {
00433     switch (errno) {
00434     case EINVAL:
00435       /* Cropping not supported. */
00436       break;
00437     default:
00438       /* Errors ignored. */
00439       break;
00440     }
00441   }
00442 
00443   CLEAR(omx_camera_source_component_Private->fmt);
00444 
00445   /* Get V4L2 buffer map information */
00446   camera_init_mmap(omx_camera_source_component_Private);
00447 
00448   /* About camera color format settings.... */
00449 
00450   /* Get the camera sensor color format from an enabled port */
00451   if (PORT_IS_ENABLED(pPreviewPort)) {
00452     omx_camera_source_component_Private->eOmxColorFormat = pPreviewPort->sPortParam.format.video.eColorFormat;
00453   }
00454   else if (PORT_IS_ENABLED(pCapturePort)) {
00455     omx_camera_source_component_Private->eOmxColorFormat = pCapturePort->sPortParam.format.video.eColorFormat;
00456   }
00457   else if (PORT_IS_ENABLED(pThumbnailPort)) {
00458     omx_camera_source_component_Private->eOmxColorFormat = pThumbnailPort->sPortParam.format.video.eColorFormat;
00459   }
00460   else {
00461     omx_camera_source_component_Private->eOmxColorFormat = DEFAULT_COLOR_FORMAT;
00462   }
00463 
00464   if ((err = camera_MapColorFormatOmxToV4l(omx_camera_source_component_Private->eOmxColorFormat, &omx_camera_source_component_Private->sV4lColorFormat)) != OMX_ErrorNone) {
00465     DEBUG(DEB_LEV_ERR, "%s: <ERROR> -- map color from omx to v4l failed!\n",__func__);
00466     goto ERR_HANDLE;
00467   }
00468 
00470   /* First get original color format from camera device */
00471   omx_camera_source_component_Private->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00472   if (-1 == xioctl(omx_camera_source_component_Private->fdCam, VIDIOC_G_FMT, &omx_camera_source_component_Private->fmt)) {
00473     DEBUG(DEB_LEV_ERR, "%s error %d, %s\n", "VIDIOC_G_FMT", errno, strerror(errno));
00474     err = OMX_ErrorHardware;
00475     goto ERR_HANDLE;
00476   }
00477 
00478   DEBUG(DEB_LEV_SIMPLE_SEQ, "%s: v4l2_format.fmt.pix.pixelformat (Before set) = %c%c%c%c\n",__func__, 
00479     (char)(omx_camera_source_component_Private->fmt.fmt.pix.pixelformat),
00480     (char)(omx_camera_source_component_Private->fmt.fmt.pix.pixelformat>>8),
00481     (char)(omx_camera_source_component_Private->fmt.fmt.pix.pixelformat>>16),
00482     (char)(omx_camera_source_component_Private->fmt.fmt.pix.pixelformat>>24));
00483   DEBUG(DEB_LEV_SIMPLE_SEQ, "%s: v4l2_format.fmt.pix.field (Before set) = %d\n",__func__, omx_camera_source_component_Private->fmt.fmt.pix.field);
00484 
00485   /* Set color format and frame size to camera device */
00486   omx_camera_source_component_Private->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00487   omx_camera_source_component_Private->fmt.fmt.pix.width = pPort->sPortParam.format.video.nFrameWidth;
00488   omx_camera_source_component_Private->fmt.fmt.pix.height = pPort->sPortParam.format.video.nFrameHeight;
00489   omx_camera_source_component_Private->fmt.fmt.pix.pixelformat = omx_camera_source_component_Private->sV4lColorFormat.v4l2Pixfmt;
00490   omx_camera_source_component_Private->fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
00491 
00492   if (-1 == xioctl(omx_camera_source_component_Private->fdCam, VIDIOC_S_FMT, &omx_camera_source_component_Private->fmt)) {
00493     DEBUG(DEB_LEV_ERR, "%s error %d, %s\n", "VIDIOC_S_FMT", errno, strerror(errno));
00494     err = OMX_ErrorHardware;
00495     goto ERR_HANDLE;
00496   }
00497 
00498   DEBUG(DEB_LEV_SIMPLE_SEQ, "%s: v4l2_format.fmt.pix.pixelformat (After set) = %c%c%c%c\n",__func__, 
00499     (char)(omx_camera_source_component_Private->fmt.fmt.pix.pixelformat),
00500     (char)(omx_camera_source_component_Private->fmt.fmt.pix.pixelformat>>8),
00501     (char)(omx_camera_source_component_Private->fmt.fmt.pix.pixelformat>>16),
00502     (char)(omx_camera_source_component_Private->fmt.fmt.pix.pixelformat>>24));
00503   DEBUG(DEB_LEV_SIMPLE_SEQ, "%s: v4l2_format.fmt.pix.field (After set) = %d\n",__func__, omx_camera_source_component_Private->fmt.fmt.pix.field);
00504 
00505 
00506   /* Note VIDIOC_S_FMT may change width and height. */
00507   pPort->sPortParam.format.video.nFrameWidth = omx_camera_source_component_Private->fmt.fmt.pix.width;
00508   pPort->sPortParam.format.video.nFrameHeight = omx_camera_source_component_Private->fmt.fmt.pix.height;
00509 
00510   /*output frame size*/
00511   omx_camera_source_component_Private->oFrameSize = pPort->sPortParam.format.video.nFrameWidth*
00512                                                     pPort->sPortParam.format.video.nFrameHeight*
00513                                                     omx_camera_source_component_Private->sV4lColorFormat.v4l2Depth/8; /*Eg 12/8 for YUV420*/
00514 
00515   DEBUG(DEB_LEV_SIMPLE_SEQ,"Frame Width=%d, Height=%d, Frame Size=%d nFrame=%d\n",
00516     (int)pPort->sPortParam.format.video.nFrameWidth,
00517     (int)pPort->sPortParam.format.video.nFrameHeight,
00518     (int)omx_camera_source_component_Private->oFrameSize,
00519     (int)omx_camera_source_component_Private->sMapbufQueue.nFrame);
00520 
00521 
00522   /* Allocate time stamp queue */
00523   
00524   omx_camera_source_component_Private->sMapbufQueue.qTimeStampQueue = calloc(omx_camera_source_component_Private->sMapbufQueue.nFrame, sizeof(OMX_TICKS));
00525   if (omx_camera_source_component_Private->sMapbufQueue.qTimeStampQueue == NULL) {
00526     DEBUG(DEB_LEV_ERR, "%s: <ERROR> -- Allocate time stamp queue failed!\n",__func__);
00527     err = OMX_ErrorInsufficientResources;
00528     goto ERR_HANDLE;
00529   }
00530 
00531   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
00532   return err;
00533 
00534 ERR_HANDLE:
00535   camera_DeinitCameraDevice(omx_camera_source_component_Private);
00536 
00537   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
00538   return err;
00539 }
00540 
00541 /* Deinitialize the camera device */
00542 static OMX_ERRORTYPE camera_DeinitCameraDevice(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private) {
00543   OMX_ERRORTYPE err = OMX_ErrorNone;  
00544   OMX_U32 i;
00545 
00546   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
00547 
00548 
00549   if (omx_camera_source_component_Private->sMapbufQueue.qTimeStampQueue != NULL) {
00550     free(omx_camera_source_component_Private->sMapbufQueue.qTimeStampQueue);
00551     omx_camera_source_component_Private->sMapbufQueue.qTimeStampQueue = NULL;
00552   }
00553 
00554   if(omx_camera_source_component_Private->sMapbufQueue.buffers != NULL ) {
00555     for (i = 0; i < OMX_MAPBUFQUEUE_GETMAXLEN( omx_camera_source_component_Private->sMapbufQueue ); ++i) {
00556       DEBUG(DEB_LEV_PARAMS, "i=%d,addr=%x,length=%d\n",(int)i,
00557         (int)omx_camera_source_component_Private->sMapbufQueue.buffers[i].pCapAddrStart, 
00558         (int)omx_camera_source_component_Private->sMapbufQueue.buffers[i].length);
00559 
00560       if (-1 == munmap(omx_camera_source_component_Private->sMapbufQueue.buffers[i].pCapAddrStart, 
00561                        omx_camera_source_component_Private->sMapbufQueue.buffers[i].length)) {
00562         DEBUG(DEB_LEV_ERR, "%s error %d, %s\n", "munmap", errno, strerror(errno));
00563         err = OMX_ErrorHardware;
00564       }
00565     }
00566 
00567     free(omx_camera_source_component_Private->sMapbufQueue.buffers);
00568 
00569     omx_camera_source_component_Private->sMapbufQueue.buffers = NULL;
00570   }
00571 
00572   if ( omx_camera_source_component_Private->fdCam >= 0 ) {
00573     close(omx_camera_source_component_Private->fdCam);
00574     omx_camera_source_component_Private->fdCam = -1;
00575   }
00576 
00577   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
00578   return err;
00579 }
00580 
00581 /* Start the camera device */
00582 static OMX_ERRORTYPE camera_StartCameraDevice(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private) {
00583   struct timeval now;
00584   struct timespec sleepTime;
00585   OMX_U32 i = 0;
00586   OMX_ERRORTYPE err = OMX_ErrorNone;
00587   enum v4l2_buf_type type;
00588 
00589   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
00590 
00591   for ( i = 0; i < OMX_MAPBUFQUEUE_GETMAXLEN( omx_camera_source_component_Private->sMapbufQueue ); i++ ) {
00592     /* Instruct the camera hardware to start capture */
00593     DEBUG(DEB_LEV_SIMPLE_SEQ, "%s: Start to capture buffer [%d], [width, height] = [%d, %d], pixelformat = %d\n",__func__,(int)i, 
00594       omx_camera_source_component_Private->fmt.fmt.pix.width, 
00595       omx_camera_source_component_Private->fmt.fmt.pix.height, 
00596       omx_camera_source_component_Private->fmt.fmt.pix.pixelformat);
00597 
00598     if ( i == (OMX_MAPBUFQUEUE_GETMAXLEN( omx_camera_source_component_Private->sMapbufQueue ) - 1) ) {
00599       /* record last capture time */
00600       gettimeofday(&now, NULL);
00601       omx_camera_source_component_Private->nLastCaptureTimeInMilliSec = ((OMX_U32)now.tv_sec) * 1000 + ((OMX_U32)now.tv_usec) / 1000;
00602     }
00603 
00604     struct v4l2_buffer buf;
00605 
00606     CLEAR(buf);
00607 
00608     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00609     buf.memory = V4L2_MEMORY_MMAP;
00610     buf.index = i;
00611 
00612     if (-1 == xioctl(omx_camera_source_component_Private->fdCam, VIDIOC_QBUF, &buf)) {
00613       DEBUG(DEB_LEV_ERR, "%s: <ERROR> -- Instruct the camera hardware to start capture failed 1: %s\n",__func__,GET_SYSERR_STRING());
00614       err = OMX_ErrorHardware;
00615       goto EXIT;
00616     }
00617 
00618     OMX_MAPBUFQUEUE_ENQUEUE( omx_camera_source_component_Private->sMapbufQueue );
00619 
00620     if ( i != (OMX_MAPBUFQUEUE_GETMAXLEN( omx_camera_source_component_Private->sMapbufQueue ) - 1) )
00621     {
00622       /* Sleep for a frame interval */
00623       sleepTime.tv_sec = omx_camera_source_component_Private->nFrameIntervalInMilliSec / 1000;
00624       sleepTime.tv_nsec = (omx_camera_source_component_Private->nFrameIntervalInMilliSec % 1000) * 1000000;
00625       nanosleep(&sleepTime, NULL);
00626     }
00627   }
00628 
00629   type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00630 
00631   if (-1 == xioctl(omx_camera_source_component_Private->fdCam, VIDIOC_STREAMON, &type)) {
00632     DEBUG(DEB_LEV_ERR, "%s error %d, %s\n", "VIDIOC_STREAMON", errno, strerror(errno));
00633     err = OMX_ErrorHardware;
00634     goto EXIT;
00635   }
00636 
00637  
00638 EXIT:
00639   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
00640   return err;
00641 }
00642 
00643 /* Stop the camera device */
00644 static OMX_ERRORTYPE camera_StopCameraDevice(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private) {
00645   OMX_U32 i = 0;
00646   omx_camera_source_component_PortType *port;
00647   OMX_ERRORTYPE err = OMX_ErrorNone;  
00648   int ioErr = 0;
00649   enum v4l2_buf_type type;
00650 
00651   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
00652 
00653   /* Wait for un-processed buffers */
00654   i = OMX_MAPBUFQUEUE_GETNEXTWAIT( omx_camera_source_component_Private->sMapbufQueue );
00655 
00656   while ( OMX_MAPBUFQUEUE_HASBUFWAITTOCAPTURE( omx_camera_source_component_Private->sMapbufQueue ) ) {
00657     /* Wait the camera hardware to finish capturing */
00658     DEBUG(DEB_LEV_SIMPLE_SEQ, "%s: Wait on buffer [%d], [width, height] = [%d, %d], pixelformat = %d\n",__func__,(int)i, 
00659       omx_camera_source_component_Private->fmt.fmt.pix.width, 
00660       omx_camera_source_component_Private->fmt.fmt.pix.height, 
00661       omx_camera_source_component_Private->fmt.fmt.pix.pixelformat);
00662 
00663     type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00664 
00665     do {
00666       ioErr = xioctl(omx_camera_source_component_Private->fdCam, VIDIOC_STREAMOFF, &type);
00667     } while ( ioErr < 0 && EINTR == errno );
00668     if ( ioErr < 0 ) {
00669       DEBUG(DEB_LEV_ERR, "%s: <ERROR> -- Wait the camera hardware to finish capturing failed: %s\n",__func__,GET_SYSERR_STRING());
00670       err = OMX_ErrorHardware;
00671       goto EXIT;
00672     }
00673 
00674     OMX_MAPBUFQUEUE_ADDCAPTUREDBUF( omx_camera_source_component_Private->sMapbufQueue );
00675 
00676     i = OMX_MAPBUFQUEUE_GETNEXTINDEX( omx_camera_source_component_Private->sMapbufQueue, i );
00677   }
00678 
00679   /* Reset Mapping Buffer Queue */
00680   OMX_MAPBUFQUEUE_MAKEEMPTY( omx_camera_source_component_Private->sMapbufQueue );
00681 
00682   /* Reset port mapbuf queue index */
00683   for ( i = 0; i < NUM_CAMERAPORTS; i++ ) {
00684     port = (omx_camera_source_component_PortType *) omx_camera_source_component_Private->ports[i];
00685     port->nIndexMapbufQueue = 0;
00686   }
00687 
00688 
00689 EXIT:
00690   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
00691   return err;
00692 }
00693 
00694 
00695 
00700 OMX_ERRORTYPE omx_camera_source_component_Constructor(OMX_COMPONENTTYPE *openmaxStandComp,OMX_STRING cComponentName) {
00701   OMX_ERRORTYPE err = OMX_ErrorNone;  
00702   OMX_S32 i;
00703   omx_camera_source_component_PortType *port;
00704   omx_camera_source_component_PrivateType* omx_camera_source_component_Private;
00705 
00706   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
00707 
00709   if (!openmaxStandComp->pComponentPrivate) {
00710     DEBUG(DEB_LEV_FUNCTION_NAME, "In %s, allocating component\n", __func__);
00711     openmaxStandComp->pComponentPrivate = calloc(1, sizeof(omx_camera_source_component_PrivateType));
00712     if(openmaxStandComp->pComponentPrivate == NULL) {
00713       return OMX_ErrorInsufficientResources;
00714     }
00715   } else {
00716     DEBUG(DEB_LEV_FUNCTION_NAME, "In %s, Error Component %x Already Allocated\n", __func__, (int)openmaxStandComp->pComponentPrivate);
00717   }
00718 
00719   /* Call base source constructor */
00720   omx_camera_source_component_Private = (omx_camera_source_component_PrivateType *)openmaxStandComp->pComponentPrivate;
00721   err = omx_base_source_Constructor(openmaxStandComp, cComponentName);
00722 
00723   /* Overwrite default settings by base source */
00724   omx_camera_source_component_Private = (omx_camera_source_component_PrivateType *)openmaxStandComp->pComponentPrivate;
00725   omx_camera_source_component_Private->sPortTypesParam[OMX_PortDomainVideo].nStartPortNumber = 0;
00726   omx_camera_source_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts = NUM_CAMERAPORTS;
00727 
00728   omx_camera_source_component_Private->BufferMgmtFunction = omx_camera_source_component_BufferMgmtFunction;
00729 
00731   pthread_mutex_init(&omx_camera_source_component_Private->idle_state_mutex, NULL);
00732   pthread_cond_init(&omx_camera_source_component_Private->idle_wait_condition, NULL);
00733   pthread_cond_init(&omx_camera_source_component_Private->idle_process_condition, NULL);
00734   omx_camera_source_component_Private->bWaitingOnIdle = OMX_FALSE;
00735 
00736   pthread_mutex_init(&omx_camera_source_component_Private->setconfig_mutex, NULL);
00737 
00738   setHeader(&omx_camera_source_component_Private->sSensorMode, sizeof(OMX_PARAM_SENSORMODETYPE));
00739   omx_camera_source_component_Private->sSensorMode.nPortIndex = 0;
00740   omx_camera_source_component_Private->sSensorMode.nFrameRate = DEFAULT_FRAME_RATE; /* default 15 pps */
00741   omx_camera_source_component_Private->sSensorMode.bOneShot = OMX_FALSE; /* default video capture */
00742   setHeader(&omx_camera_source_component_Private->sSensorMode.sFrameSize, sizeof(OMX_FRAMESIZETYPE));
00743   omx_camera_source_component_Private->sSensorMode.sFrameSize.nPortIndex = 0;
00744   omx_camera_source_component_Private->sSensorMode.sFrameSize.nWidth = DEFAULT_FRAME_WIDTH;
00745   omx_camera_source_component_Private->sSensorMode.sFrameSize.nHeight = DEFAULT_FRAME_HEIGHT;
00746   omx_camera_source_component_Private->nFrameIntervalInMilliSec = 1000 / (omx_camera_source_component_Private->sSensorMode.nFrameRate);
00747 
00748   omx_camera_source_component_Private->eOmxColorFormat = DEFAULT_COLOR_FORMAT;
00749   omx_camera_source_component_Private->sV4lColorFormat.v4l2Pixfmt = V4L2_PIX_FMT_YUV420;
00750   omx_camera_source_component_Private->sV4lColorFormat.v4l2Depth = 12;
00751 
00752   omx_camera_source_component_Private->fdCam = -1;
00753   memset(&omx_camera_source_component_Private->sMapbufQueue,0, sizeof(OMX_V4L2_MAPBUFFER_QUEUETYPE));
00754   omx_camera_source_component_Private->sMapbufQueue.nFrame = 0;
00755   omx_camera_source_component_Private->bCapturing = OMX_FALSE;
00756   omx_camera_source_component_Private->bCapturingNext = OMX_FALSE;
00757   omx_camera_source_component_Private->bIsFirstFrame = OMX_FALSE;
00758   omx_camera_source_component_Private->bAutoPause = OMX_FALSE;
00759   omx_camera_source_component_Private->bThumbnailStart = OMX_FALSE;
00760   omx_camera_source_component_Private->nCapturedCount = 0;
00761   
00762 
00764   if (omx_camera_source_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts && !omx_camera_source_component_Private->ports) {
00765     omx_camera_source_component_Private->ports = calloc(omx_camera_source_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts, sizeof (omx_base_PortType *));
00766     if (!omx_camera_source_component_Private->ports) {
00767       return OMX_ErrorInsufficientResources;
00768     }
00769     for (i=0; i < omx_camera_source_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts; i++) {
00773       omx_camera_source_component_Private->ports[i] = (omx_base_PortType *)calloc(1, sizeof(omx_camera_source_component_PortType));
00774       if (!omx_camera_source_component_Private->ports[i]) {
00775         return OMX_ErrorInsufficientResources;
00776       }
00777     }
00778   }
00779 
00780   for (i=0; i<omx_camera_source_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts; i++) {
00782     base_video_port_Constructor(openmaxStandComp, &omx_camera_source_component_Private->ports[i], i, OMX_FALSE);
00783     port = (omx_camera_source_component_PortType *) omx_camera_source_component_Private->ports[i];
00785     port->sPortParam.nBufferSize = DEFAULT_FRAME_WIDTH*DEFAULT_FRAME_HEIGHT*3/2;
00786     port->sPortParam.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
00787     port->sPortParam.format.video.nFrameHeight = DEFAULT_FRAME_HEIGHT;
00788     port->sPortParam.format.video.nStride = DEFAULT_FRAME_WIDTH;
00789     port->sPortParam.format.video.nSliceHeight = DEFAULT_FRAME_HEIGHT;
00790     port->sPortParam.format.video.xFramerate = DEFAULT_FRAME_RATE;
00791     port->sPortParam.format.video.eColorFormat = DEFAULT_COLOR_FORMAT;
00792     port->nIndexMapbufQueue = 0;
00793   }
00794 
00796   omx_camera_source_component_Private->DoStateSet = &omx_camera_source_component_DoStateSet;
00797   omx_camera_source_component_Private->destructor = omx_camera_source_component_Destructor;
00798   openmaxStandComp->SetParameter = omx_camera_source_component_SetParameter;
00799   openmaxStandComp->GetParameter = omx_camera_source_component_GetParameter;
00800   openmaxStandComp->SetConfig = omx_camera_source_component_SetConfig;
00801   openmaxStandComp->GetConfig = omx_camera_source_component_GetConfig;
00802 
00803   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
00804   return err;
00805 }
00806 
00810 OMX_ERRORTYPE omx_camera_source_component_Destructor(OMX_COMPONENTTYPE *openmaxStandComp) {
00811   omx_camera_source_component_PrivateType *omx_camera_source_component_Private = (omx_camera_source_component_PrivateType *)openmaxStandComp->pComponentPrivate;  
00812   OMX_U32 i;
00813 
00814   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
00815 
00817   if (omx_camera_source_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts && omx_camera_source_component_Private->ports) {
00818     for (i = 0; i < omx_camera_source_component_Private->sPortTypesParam[OMX_PortDomainVideo].nPorts; i++) {
00819       if(omx_camera_source_component_Private->ports[i]) {
00820         base_port_Destructor(omx_camera_source_component_Private->ports[i]);
00821       }
00822     }
00823     free(omx_camera_source_component_Private->ports);
00824     omx_camera_source_component_Private->ports = NULL;
00825   }
00826 
00827   pthread_mutex_destroy(&omx_camera_source_component_Private->idle_state_mutex);
00828   pthread_cond_destroy(&omx_camera_source_component_Private->idle_wait_condition);
00829   pthread_cond_destroy(&omx_camera_source_component_Private->idle_process_condition);
00830 
00831   pthread_mutex_destroy(&omx_camera_source_component_Private->setconfig_mutex);
00832 
00833   camera_DeinitCameraDevice(omx_camera_source_component_Private);
00834 
00835   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, OMX_ErrorNone);
00836   return omx_base_source_Destructor(openmaxStandComp);;
00837 }
00838 
00843 static OMX_ERRORTYPE omx_camera_source_component_DoStateSet(OMX_COMPONENTTYPE *openmaxStandComp, OMX_U32 destinationState) {
00844   OMX_ERRORTYPE err = OMX_ErrorNone;  
00845   omx_camera_source_component_PrivateType *omx_camera_source_component_Private = (omx_camera_source_component_PrivateType *)openmaxStandComp->pComponentPrivate;
00846 
00847   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
00848 
00849   DEBUG(DEB_LEV_SIMPLE_SEQ, "%s: Before base DoStateSet: destinationState=%ld,omx_camera_source_component_Private->state=%d,omx_camera_source_component_Private->transientState=%d\n", __func__,destinationState,omx_camera_source_component_Private->state,omx_camera_source_component_Private->transientState);
00850 
00851   if (omx_camera_source_component_Private->state == OMX_StateLoaded && destinationState == OMX_StateIdle) {
00852     /* Loaded --> Idle */
00853     if ((err = camera_InitCameraDevice(omx_camera_source_component_Private)) != OMX_ErrorNone) {
00854       goto EXIT;
00855     }
00856   }
00857   else if (omx_camera_source_component_Private->state == OMX_StateIdle && destinationState == OMX_StateExecuting) {
00858     /* Idle --> Exec */
00859     pthread_mutex_lock(&omx_camera_source_component_Private->idle_state_mutex);
00860     if (!omx_camera_source_component_Private->bWaitingOnIdle) {
00861       pthread_cond_wait(&omx_camera_source_component_Private->idle_process_condition,&omx_camera_source_component_Private->idle_state_mutex);
00862     }
00863     pthread_mutex_unlock(&omx_camera_source_component_Private->idle_state_mutex);
00864   }
00865   else if (omx_camera_source_component_Private->state == OMX_StateIdle && destinationState == OMX_StateLoaded) {
00866     /* Idle --> Loaded*/
00867     pthread_mutex_lock(&omx_camera_source_component_Private->idle_state_mutex);
00868     if (!omx_camera_source_component_Private->bWaitingOnIdle) {
00869       pthread_cond_wait(&omx_camera_source_component_Private->idle_process_condition,&omx_camera_source_component_Private->idle_state_mutex);
00870     }
00871     camera_DeinitCameraDevice(omx_camera_source_component_Private);
00872     if (omx_camera_source_component_Private->bWaitingOnIdle) {
00873       pthread_cond_signal(&omx_camera_source_component_Private->idle_wait_condition);
00874     }
00875     pthread_mutex_unlock(&omx_camera_source_component_Private->idle_state_mutex);
00876   }
00877 
00878 
00879   omx_camera_source_component_Private->eLastState = omx_camera_source_component_Private->state;
00880   err = omx_base_component_DoStateSet(openmaxStandComp, destinationState);
00881   DEBUG(DEB_LEV_SIMPLE_SEQ, "%s: After base DoStateSet: destinationState=%ld,omx_camera_source_component_Private->state=%d,omx_camera_source_component_Private->transientState=%d\n", __func__,destinationState,omx_camera_source_component_Private->state,omx_camera_source_component_Private->transientState);
00882 
00883 
00884   if (omx_camera_source_component_Private->eLastState == OMX_StateIdle && omx_camera_source_component_Private->state == OMX_StateExecuting) {
00885     /* Idle --> Exec */
00886     pthread_mutex_lock(&omx_camera_source_component_Private->idle_state_mutex);
00887     if (omx_camera_source_component_Private->bWaitingOnIdle) {
00888       if ((err = camera_StartCameraDevice(omx_camera_source_component_Private)) != OMX_ErrorNone) {
00889         pthread_mutex_unlock(&omx_camera_source_component_Private->idle_state_mutex);
00890         goto EXIT;
00891       }
00892       pthread_cond_signal(&omx_camera_source_component_Private->idle_wait_condition);
00893     }
00894     pthread_mutex_unlock(&omx_camera_source_component_Private->idle_state_mutex);
00895   }
00896   else if (omx_camera_source_component_Private->eLastState == OMX_StateExecuting && omx_camera_source_component_Private->state == OMX_StateIdle) {
00897     /* Exec --> Idle */
00898     pthread_mutex_lock(&omx_camera_source_component_Private->idle_state_mutex);
00899     if (!omx_camera_source_component_Private->bWaitingOnIdle) {
00900       pthread_cond_wait(&omx_camera_source_component_Private->idle_process_condition,&omx_camera_source_component_Private->idle_state_mutex);
00901     }
00902     camera_StopCameraDevice(omx_camera_source_component_Private);
00903     pthread_mutex_unlock(&omx_camera_source_component_Private->idle_state_mutex);
00904   }
00905 
00906 
00907 EXIT:
00908   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
00909   return err;
00910 }
00911 
00912 
00918 static OMX_ERRORTYPE omx_camera_source_component_GetParameter(
00919   OMX_IN  OMX_HANDLETYPE hComponent,
00920   OMX_IN  OMX_INDEXTYPE nParamIndex,
00921   OMX_INOUT  OMX_PTR ComponentParameterStructure) {
00922 
00923   OMX_ERRORTYPE err = OMX_ErrorNone;  
00924   OMX_COMPONENTTYPE *openmaxStandComp;
00925   omx_camera_source_component_PrivateType* omx_camera_source_component_Private;
00926   omx_camera_source_component_PortType *pPort;
00927   OMX_VIDEO_PARAM_PORTFORMATTYPE *pVideoPortFormat;
00928   OMX_PARAM_SENSORMODETYPE *pSensorMode;
00929 
00930   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
00931 
00932   if (ComponentParameterStructure == NULL) {
00933     return OMX_ErrorBadParameter;
00934   }
00935 
00936   openmaxStandComp = (OMX_COMPONENTTYPE *)hComponent;
00937   omx_camera_source_component_Private = (omx_camera_source_component_PrivateType *)openmaxStandComp->pComponentPrivate;
00938 
00939   DEBUG(DEB_LEV_SIMPLE_SEQ, "%s: Getting parameter %i\n", __func__, nParamIndex);
00940 
00941   switch(nParamIndex) {
00942     case OMX_IndexParamVideoInit:
00943       if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_PORT_PARAM_TYPE))) != OMX_ErrorNone) {
00944         DEBUG(DEB_LEV_ERR, "%s (line %d): Check header failed!\n", __func__, __LINE__);
00945         break;
00946       }
00947       memcpy(ComponentParameterStructure,&omx_camera_source_component_Private->sPortTypesParam[OMX_PortDomainVideo],sizeof(OMX_PORT_PARAM_TYPE));
00948       break;
00949 
00950     case OMX_IndexParamVideoPortFormat:
00951       pVideoPortFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure;
00952       if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE))) != OMX_ErrorNone) {
00953         DEBUG(DEB_LEV_ERR, "%s (line %d): Check header failed!\n", __func__, __LINE__);
00954         break;
00955       }
00956       if (pVideoPortFormat->nPortIndex < NUM_CAMERAPORTS)
00957       {
00958         pPort = (omx_camera_source_component_PortType *) omx_camera_source_component_Private->ports[pVideoPortFormat->nPortIndex];
00959         pVideoPortFormat->eCompressionFormat = pPort->sPortParam.format.video.eCompressionFormat;
00960         pVideoPortFormat->eColorFormat = pPort->sPortParam.format.video.eColorFormat;
00961       }
00962       else
00963       {
00964         err = OMX_ErrorBadPortIndex;
00965       }
00966       break;
00967 
00968     case OMX_IndexParamCommonSensorMode:
00969       pSensorMode = (OMX_PARAM_SENSORMODETYPE *)ComponentParameterStructure;
00970       if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_PARAM_SENSORMODETYPE))) != OMX_ErrorNone) {
00971         DEBUG(DEB_LEV_ERR, "%s (line %d): Check header failed!\n", __func__, __LINE__);
00972         break;
00973       }
00974       memcpy(pSensorMode, &omx_camera_source_component_Private->sSensorMode, sizeof(OMX_PARAM_SENSORMODETYPE));
00975       break;
00976 
00977     default: /*Call the base component function*/
00978       err = omx_base_component_GetParameter(hComponent, nParamIndex, ComponentParameterStructure);
00979       break;
00980   }
00981 
00982   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
00983   return err;
00984 }
00985 
00991 static OMX_ERRORTYPE omx_camera_source_component_SetParameter(
00992   OMX_IN  OMX_HANDLETYPE hComponent,
00993   OMX_IN  OMX_INDEXTYPE nParamIndex,
00994   OMX_IN  OMX_PTR ComponentParameterStructure) {
00995 
00996   OMX_ERRORTYPE err = OMX_ErrorNone;  
00997   OMX_COMPONENTTYPE *openmaxStandComp;
00998   omx_camera_source_component_PrivateType* omx_camera_source_component_Private;
00999   omx_camera_source_component_PortType *pPort;
01000   OMX_PARAM_PORTDEFINITIONTYPE *pPortDef;
01001   OMX_VIDEO_PARAM_PORTFORMATTYPE *pVideoPortFormat;
01002   OMX_PARAM_SENSORMODETYPE *pSensorMode;
01003 
01004   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01005 
01006   if (ComponentParameterStructure == NULL) {
01007     return OMX_ErrorBadParameter;
01008   }
01009 
01010   openmaxStandComp = (OMX_COMPONENTTYPE *)hComponent;
01011   omx_camera_source_component_Private = (omx_camera_source_component_PrivateType *)openmaxStandComp->pComponentPrivate;
01012 
01013   DEBUG(DEB_LEV_SIMPLE_SEQ, "%s: Setting parameter %i\n", __func__, nParamIndex);
01014 
01015   switch(nParamIndex) {
01016     case OMX_IndexParamVideoInit:
01017       if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_PORT_PARAM_TYPE))) != OMX_ErrorNone) {
01018         DEBUG(DEB_LEV_ERR, "%s (line %d): Check header failed!\n", __func__, __LINE__);
01019         break;
01020       }
01021       memcpy(&omx_camera_source_component_Private->sPortTypesParam[OMX_PortDomainVideo],ComponentParameterStructure,sizeof(OMX_PORT_PARAM_TYPE));
01022       break;
01023 
01024     case OMX_IndexParamPortDefinition:
01025       pPortDef = (OMX_PARAM_PORTDEFINITIONTYPE *) ComponentParameterStructure;
01026       err = camera_CheckSupportedColorFormat(pPortDef->format.video.eColorFormat);
01027       if (err != OMX_ErrorNone) {
01028         DEBUG(DEB_LEV_ERR, "%s (line %d): Supported Color Format Check failed!\n", __func__, __LINE__);
01029         break;
01030       }
01031       err = camera_CheckSupportedFramesize(pPortDef->format.video.nFrameWidth, pPortDef->format.video.nFrameHeight);
01032       if (err != OMX_ErrorNone) {
01033         DEBUG(DEB_LEV_ERR, "%s (line %d): Supported Frame Size Check failed!\n", __func__, __LINE__);
01034         break;
01035       }
01036       /*Call the base component function*/
01037       err = omx_base_component_SetParameter(hComponent, nParamIndex, ComponentParameterStructure);
01038       if (err != OMX_ErrorNone) {
01039         DEBUG(DEB_LEV_ERR, "%s (line %d): Call base SetParameter failed!\n", __func__, __LINE__);
01040         break;
01041       }
01042       pPort = (omx_camera_source_component_PortType *) omx_camera_source_component_Private->ports[pPortDef->nPortIndex];
01043       memcpy(&pPort->sPortParam, pPortDef, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
01044       pPort->sPortParam.nBufferSize = camera_CalculateBufferSize(pPort->sPortParam.format.video.nFrameWidth, pPort->sPortParam.format.video.nFrameHeight, pPort->sPortParam.format.video.eColorFormat);
01045       break;
01046 
01047     case OMX_IndexParamVideoPortFormat:
01048       pVideoPortFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure;
01049       err = omx_base_component_ParameterSanityCheck(hComponent, pVideoPortFormat->nPortIndex, pVideoPortFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
01050       if (err != OMX_ErrorNone) {
01051         DEBUG(DEB_LEV_ERR, "%s (line %d): Parameter Sanity Check failed!\n", __func__, __LINE__);
01052         break;
01053       }
01054       err = camera_CheckSupportedColorFormat(pVideoPortFormat->eColorFormat);
01055       if (err != OMX_ErrorNone) {
01056         DEBUG(DEB_LEV_ERR, "%s (line %d): Supported Color Format Check failed!\n", __func__, __LINE__);
01057         break;
01058       }
01059       pPort = (omx_camera_source_component_PortType *) omx_camera_source_component_Private->ports[pVideoPortFormat->nPortIndex];
01060       pPort->sPortParam.format.video.eCompressionFormat = pVideoPortFormat->eCompressionFormat;
01061       pPort->sPortParam.format.video.eColorFormat = pVideoPortFormat->eColorFormat;
01062       break;
01063 
01064     case OMX_IndexParamCommonSensorMode:
01065       pSensorMode = (OMX_PARAM_SENSORMODETYPE *)ComponentParameterStructure;
01066       err = omx_base_component_ParameterSanityCheck(hComponent, pSensorMode->nPortIndex, pSensorMode, sizeof(OMX_PARAM_SENSORMODETYPE));
01067       if (err != OMX_ErrorNone) {
01068         DEBUG(DEB_LEV_ERR, "%s (line %d): Parameter Sanity Check failed!\n", __func__, __LINE__);
01069         break;
01070       }
01071       err = camera_CheckSupportedFramesize(pSensorMode->sFrameSize.nWidth, pSensorMode->sFrameSize.nHeight);
01072       if (err != OMX_ErrorNone) {
01073         DEBUG(DEB_LEV_ERR, "%s (line %d): Supported Frame Size Check failed!\n", __func__, __LINE__);
01074         break;
01075       }
01076       memcpy(&omx_camera_source_component_Private->sSensorMode, pSensorMode, sizeof(OMX_PARAM_SENSORMODETYPE));
01077       omx_camera_source_component_Private->nFrameIntervalInMilliSec = 1000 / (pSensorMode->nFrameRate);
01078       break;
01079 
01080     default: /*Call the base component function*/
01081       err = omx_base_component_SetParameter(hComponent, nParamIndex, ComponentParameterStructure);
01082       break;
01083   }
01084 
01085   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
01086   return err;
01087 }
01088 
01094 static OMX_ERRORTYPE omx_camera_source_component_GetConfig(
01095   OMX_IN  OMX_HANDLETYPE hComponent,
01096   OMX_IN  OMX_INDEXTYPE nConfigIndex,
01097   OMX_INOUT OMX_PTR pComponentConfigStructure) {
01098   OMX_ERRORTYPE err = OMX_ErrorNone;  
01099   OMX_COMPONENTTYPE *openmaxStandComp;
01100   omx_camera_source_component_PrivateType* omx_camera_source_component_Private;
01101   OMX_CONFIG_BOOLEANTYPE *pCapturing;
01102   OMX_CONFIG_BOOLEANTYPE *pAutoPause;
01103 
01104   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01105 
01106   if (pComponentConfigStructure == NULL) {
01107     return OMX_ErrorBadParameter;
01108   }
01109 
01110   openmaxStandComp = (OMX_COMPONENTTYPE *)hComponent;
01111   omx_camera_source_component_Private = (omx_camera_source_component_PrivateType *)openmaxStandComp->pComponentPrivate;
01112 
01113   DEBUG(DEB_LEV_SIMPLE_SEQ, "%s: Getting configuration %i\n", __func__, nConfigIndex);
01114 
01115   switch (nConfigIndex) {
01116     case OMX_IndexConfigCapturing:
01117       pCapturing = (OMX_CONFIG_BOOLEANTYPE *)pComponentConfigStructure;
01118       if ((err = checkHeader(pComponentConfigStructure, sizeof(OMX_CONFIG_BOOLEANTYPE))) != OMX_ErrorNone) {
01119         DEBUG(DEB_LEV_ERR, "%s (line %d): Check header failed!\n", __func__, __LINE__);
01120         break;
01121       }
01122       pCapturing->bEnabled = omx_camera_source_component_Private->bCapturingNext;
01123       break;
01124     case OMX_IndexAutoPauseAfterCapture:
01125       pAutoPause = (OMX_CONFIG_BOOLEANTYPE *)pComponentConfigStructure;
01126       if ((err = checkHeader(pComponentConfigStructure, sizeof(OMX_CONFIG_BOOLEANTYPE))) != OMX_ErrorNone) {
01127         DEBUG(DEB_LEV_ERR, "%s (line %d): Check header failed!\n", __func__, __LINE__);
01128         break;
01129       }
01130       pAutoPause->bEnabled = omx_camera_source_component_Private->bAutoPause;
01131       break;
01132     default:
01133       err = omx_base_component_GetConfig(hComponent, nConfigIndex, pComponentConfigStructure);
01134       break;
01135   }
01136 
01137   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
01138   return err;
01139 }
01140 
01146 static OMX_ERRORTYPE omx_camera_source_component_SetConfig(
01147   OMX_IN  OMX_HANDLETYPE hComponent,
01148   OMX_IN  OMX_INDEXTYPE nConfigIndex,
01149   OMX_IN OMX_PTR pComponentConfigStructure) {
01150   OMX_ERRORTYPE err = OMX_ErrorNone;  
01151   OMX_COMPONENTTYPE *openmaxStandComp;
01152   omx_camera_source_component_PrivateType* omx_camera_source_component_Private;
01153   OMX_CONFIG_BOOLEANTYPE *pCapturing;
01154   OMX_CONFIG_BOOLEANTYPE *pAutoPause;
01155 
01156   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01157 
01158   if (pComponentConfigStructure == NULL) {
01159     return OMX_ErrorBadParameter;
01160   }
01161 
01162   openmaxStandComp = (OMX_COMPONENTTYPE *)hComponent;
01163   omx_camera_source_component_Private = (omx_camera_source_component_PrivateType *)openmaxStandComp->pComponentPrivate;
01164 
01165   DEBUG(DEB_LEV_SIMPLE_SEQ, "%s: Setting configuration %i\n", __func__, nConfigIndex);
01166 
01167   switch (nConfigIndex) {
01168     case OMX_IndexConfigCapturing:
01169       pCapturing = (OMX_CONFIG_BOOLEANTYPE *)pComponentConfigStructure;
01170       if ((err = checkHeader(pComponentConfigStructure, sizeof(OMX_CONFIG_BOOLEANTYPE))) != OMX_ErrorNone) {
01171         DEBUG(DEB_LEV_ERR, "%s (line %d): Check header failed!\n", __func__, __LINE__);
01172         break;
01173       }
01174       err = camera_SetConfigCapturing( omx_camera_source_component_Private, pCapturing );
01175       break;
01176     case OMX_IndexAutoPauseAfterCapture:
01177       pAutoPause = (OMX_CONFIG_BOOLEANTYPE *)pComponentConfigStructure;
01178       if ((err = checkHeader(pComponentConfigStructure, sizeof(OMX_CONFIG_BOOLEANTYPE))) != OMX_ErrorNone) {
01179         DEBUG(DEB_LEV_ERR, "%s (line %d): Check header failed!\n", __func__, __LINE__);
01180         break;
01181       }
01182       pthread_mutex_lock(&omx_camera_source_component_Private->setconfig_mutex);
01183       omx_camera_source_component_Private->bAutoPause = pAutoPause->bEnabled;
01184       pthread_mutex_unlock(&omx_camera_source_component_Private->setconfig_mutex);
01185       break;
01186     default:
01187       err = omx_base_component_SetConfig(hComponent, nConfigIndex, pComponentConfigStructure);
01188       break;
01189   }
01190 
01191   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
01192   return err;
01193 }
01194 
01199 static void* omx_camera_source_component_BufferMgmtFunction (void* param) {
01200   OMX_COMPONENTTYPE *openmaxStandComp = (OMX_COMPONENTTYPE *)param;
01201   omx_camera_source_component_PrivateType *omx_camera_source_component_Private = (omx_camera_source_component_PrivateType*)openmaxStandComp->pComponentPrivate;
01202   omx_camera_source_component_PortType *pPreviewPort = (omx_camera_source_component_PortType *)omx_camera_source_component_Private->ports[OMX_CAMPORT_INDEX_VF];
01203   omx_camera_source_component_PortType *pCapturePort = (omx_camera_source_component_PortType *)omx_camera_source_component_Private->ports[OMX_CAMPORT_INDEX_CP];
01204   omx_camera_source_component_PortType *pThumbnailPort = (omx_camera_source_component_PortType *)omx_camera_source_component_Private->ports[OMX_CAMPORT_INDEX_CP_T];
01205   tsem_t* pPreviewBufSem = pPreviewPort->pBufferSem;
01206   tsem_t* pCaptureBufSem = pCapturePort->pBufferSem;
01207   tsem_t* pThumbnailBufSem = pThumbnailPort->pBufferSem;
01208   OMX_BUFFERHEADERTYPE* pPreviewBuffer=NULL;
01209   OMX_BUFFERHEADERTYPE* pCaptureBuffer=NULL;
01210   OMX_BUFFERHEADERTYPE* pThumbnailBuffer=NULL;
01211 
01212 
01213   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01214 
01215   while(omx_camera_source_component_Private->state == OMX_StateIdle ||
01216             omx_camera_source_component_Private->state == OMX_StateExecuting ||  
01217             omx_camera_source_component_Private->state == OMX_StatePause ||
01218             omx_camera_source_component_Private->transientState == OMX_TransStateLoadedToIdle) {
01219 
01220     /*Wait till the ports are being flushed*/
01221     pthread_mutex_lock(&omx_camera_source_component_Private->flush_mutex);
01222     while( PORT_IS_BEING_FLUSHED(pPreviewPort) || 
01223            PORT_IS_BEING_FLUSHED(pCapturePort) ||
01224            PORT_IS_BEING_FLUSHED(pThumbnailPort)) {
01225       pthread_mutex_unlock(&omx_camera_source_component_Private->flush_mutex);
01226       
01227       DEBUG(DEB_LEV_FULL_SEQ, "In %s 1 signalling flush all cond PrevewSemVal=%d,CaptureSemval=%d, ThumbnailSemval=%d\n", 
01228         __func__,pPreviewBufSem->semval,pCaptureBufSem->semval, pThumbnailBufSem->semval);
01229       DEBUG(DEB_LEV_FULL_SEQ, "In %s 1 signalling flush all cond pPreviewBuffer=0x%lX,pCaptureBuffer=0x%lX, pThumbnailBuffer=0x%lX\n", 
01230         __func__,(OMX_U32)pPreviewBuffer,(OMX_U32)pCaptureBuffer, (OMX_U32)pThumbnailBuffer);
01231 
01232       if(pPreviewBuffer!=NULL && PORT_IS_BEING_FLUSHED(pPreviewPort)) {
01233         pPreviewPort->ReturnBufferFunction((omx_base_PortType *)pPreviewPort,pPreviewBuffer);
01234         pPreviewBuffer=NULL;
01235         DEBUG(DEB_LEV_FULL_SEQ, "Ports are flushing,so returning Preview buffer\n");
01236       }
01237 
01238       if(pCaptureBuffer!=NULL && PORT_IS_BEING_FLUSHED(pCapturePort)) {
01239         pCapturePort->ReturnBufferFunction((omx_base_PortType *)pCapturePort,pCaptureBuffer);
01240         pCaptureBuffer=NULL;
01241         DEBUG(DEB_LEV_FULL_SEQ, "Ports are flushing,so returning Capture buffer\n");
01242       }
01243 
01244       if(pThumbnailBuffer!=NULL && PORT_IS_BEING_FLUSHED(pThumbnailPort)) {
01245         pThumbnailPort->ReturnBufferFunction((omx_base_PortType *)pThumbnailPort,pThumbnailBuffer);
01246         pThumbnailBuffer=NULL;
01247         DEBUG(DEB_LEV_FULL_SEQ, "Ports are flushing,so returning Thumbnail buffer\n");
01248       }
01249 
01250       DEBUG(DEB_LEV_FULL_SEQ, "In %s 2 signalling flush all cond PrevewSemVal=%d,CaptureSemval=%d, ThumbnailSemval=%d\n", 
01251         __func__,pPreviewBufSem->semval,pCaptureBufSem->semval, pThumbnailBufSem->semval);
01252       DEBUG(DEB_LEV_FULL_SEQ, "In %s 2 signalling flush all cond pPreviewBuffer=0x%lX,pCaptureBuffer=0x%lX, pThumbnailBuffer=0x%lX\n", 
01253         __func__,(OMX_U32)pPreviewBuffer,(OMX_U32)pCaptureBuffer, (OMX_U32)pThumbnailBuffer);
01254   
01255       pthread_mutex_lock(&omx_camera_source_component_Private->flush_mutex);
01256       pthread_cond_signal(&omx_camera_source_component_Private->flush_all_condition);
01257       pthread_cond_wait(&omx_camera_source_component_Private->flush_condition,&omx_camera_source_component_Private->flush_mutex);
01258     }
01259     pthread_mutex_unlock(&omx_camera_source_component_Private->flush_mutex);
01260 
01261     pthread_mutex_lock(&omx_camera_source_component_Private->setconfig_mutex);
01262     if (!omx_camera_source_component_Private->bCapturing && omx_camera_source_component_Private->bCapturingNext) {
01263       pCapturePort->nIndexMapbufQueue = OMX_MAPBUFQUEUE_GETLASTBUFFER(omx_camera_source_component_Private->sMapbufQueue);
01264     }
01265     else if (omx_camera_source_component_Private->bCapturing && !omx_camera_source_component_Private->bCapturingNext) {
01266       omx_camera_source_component_Private->nCapturedCount = 0;
01267     }
01268     omx_camera_source_component_Private->bCapturing = omx_camera_source_component_Private->bCapturingNext;
01269     pthread_mutex_unlock(&omx_camera_source_component_Private->setconfig_mutex);
01270 
01271     if(omx_camera_source_component_Private->state==OMX_StatePause &&
01272         !(PORT_IS_BEING_FLUSHED(pPreviewPort) || PORT_IS_BEING_FLUSHED(pCapturePort) || PORT_IS_BEING_FLUSHED(pThumbnailPort))) {
01273       /*Waiting at paused state*/
01274       DEBUG(DEB_LEV_FULL_SEQ, "In %s: wait at State %d\n", __func__, omx_camera_source_component_Private->state);
01275       tsem_wait(omx_camera_source_component_Private->bStateSem);
01276     }
01277 
01278     pthread_mutex_lock(&omx_camera_source_component_Private->idle_state_mutex);
01279     if(omx_camera_source_component_Private->state==OMX_StateIdle &&
01280         !(PORT_IS_BEING_FLUSHED(pPreviewPort) || PORT_IS_BEING_FLUSHED(pCapturePort) || PORT_IS_BEING_FLUSHED(pThumbnailPort))) {
01281       /*Waiting at idle state*/
01282       DEBUG(DEB_LEV_FULL_SEQ, "In %s: wait at State %d\n", __func__, omx_camera_source_component_Private->state);
01283       omx_camera_source_component_Private->bWaitingOnIdle = OMX_TRUE;
01284       pthread_cond_signal(&omx_camera_source_component_Private->idle_process_condition);
01285       pthread_cond_wait(&omx_camera_source_component_Private->idle_wait_condition,&omx_camera_source_component_Private->idle_state_mutex);
01286       if(omx_camera_source_component_Private->transientState == OMX_TransStateIdleToLoaded) {
01287         DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Buffer Management Thread is exiting\n",__func__);
01288         pthread_mutex_unlock(&omx_camera_source_component_Private->idle_state_mutex);
01289         break;
01290       }
01291     }
01292     omx_camera_source_component_Private->bWaitingOnIdle = OMX_FALSE;
01293     pthread_mutex_unlock(&omx_camera_source_component_Private->idle_state_mutex);
01294 
01295     /* After cemera does start, capture video data from camera */
01296     camera_HandleThreadBufferCapture( omx_camera_source_component_Private );
01297 
01298   }
01299 
01300 
01301   DEBUG(DEB_LEV_FUNCTION_NAME, "Exiting Buffer Management Thread: %s\n",__func__);
01302   return NULL;
01303 }
01304 
01305 /* Buffer capture routine for the buffer management thread */
01306 static OMX_ERRORTYPE camera_HandleThreadBufferCapture(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private) {
01307   OMX_U32 nCurTimeInMilliSec;
01308   OMX_S32 nTimeToWaitInMilliSec;
01309   struct timeval now;
01310   struct timespec sleepTime;
01311   OMX_ERRORTYPE err = OMX_ErrorNone;  
01312   struct v4l2_buffer buf;
01313   
01314   CLEAR(buf);
01315   
01316 
01317   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01318 
01319   DEBUG(DEB_LEV_FULL_SEQ, "%s: mapbuf queue index [last, wait, capture] = [%ld, %ld, %ld]\n", __func__,
01320               omx_camera_source_component_Private->sMapbufQueue.nLastBufIndex,
01321               omx_camera_source_component_Private->sMapbufQueue.nNextWaitIndex,
01322               omx_camera_source_component_Private->sMapbufQueue.nNextCaptureIndex );
01323 
01324   DEBUG(DEB_LEV_FULL_SEQ, "%s: mapbuf queue count [captured, total] = [%ld, %ld]\n", __func__,
01325               omx_camera_source_component_Private->sMapbufQueue.nBufCountCaptured,
01326               omx_camera_source_component_Private->sMapbufQueue.nBufCountTotal );
01327 
01328   /* Wait to sync buffer */
01329   if ( OMX_MAPBUFQUEUE_HASBUFWAITTOCAPTURE( omx_camera_source_component_Private->sMapbufQueue ) ) {
01330     
01331     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
01332     buf.memory = V4L2_MEMORY_MMAP;
01333 
01334     if (-1 == xioctl(omx_camera_source_component_Private->fdCam, VIDIOC_DQBUF, &buf)) {
01335       switch (errno) {
01336       case EAGAIN:
01337         return OMX_ErrorHardware;;
01338       case EIO:
01339         /* Could ignore EIO, see spec. */
01340         /* fall through */
01341 
01342       default:
01343         DEBUG(DEB_LEV_ERR,"In %s error VIDIOC_DQBUF\n",__func__);
01344         return OMX_ErrorHardware;;
01345       }
01346     }
01347 
01348     
01349     /* Generate time stamp for the new captured buffer */
01350     if ((err = camera_GenerateTimeStamp(omx_camera_source_component_Private)) != OMX_ErrorNone) {
01351       DEBUG(DEB_LEV_ERR, "%s: <ERROR> -- Generate time stamp failed!\n",__func__);
01352       goto EXIT;
01353     }
01354 
01355     OMX_MAPBUFQUEUE_ADDCAPTUREDBUF( omx_camera_source_component_Private->sMapbufQueue );
01356   }
01357 
01358   /* Try to send buffers */
01359   if ( OMX_MAPBUFQUEUE_HASBUFCAPTURED( omx_camera_source_component_Private->sMapbufQueue ) ) {
01360     camera_SendCapturedBuffers( omx_camera_source_component_Private );
01361   }
01362 
01363   /* Calculate waiting time */
01364   gettimeofday(&now, NULL);
01365   nCurTimeInMilliSec = ((OMX_U32)now.tv_sec) * 1000 + ((OMX_U32)now.tv_usec) / 1000;
01366   nTimeToWaitInMilliSec = (OMX_S32) (omx_camera_source_component_Private->nFrameIntervalInMilliSec -
01367                 (nCurTimeInMilliSec - omx_camera_source_component_Private->nLastCaptureTimeInMilliSec));
01368 
01369   DEBUG(DEB_LEV_FULL_SEQ, "%s: [current time, last capture time, time to wait]=[%lu, %lu, %ld]\n", __func__,
01370                 nCurTimeInMilliSec,omx_camera_source_component_Private->nLastCaptureTimeInMilliSec,nTimeToWaitInMilliSec);
01371 
01372   /* Wait some time according to frame rate */
01373   if ( nTimeToWaitInMilliSec > 0 ) {
01374     sleepTime.tv_sec = nTimeToWaitInMilliSec / 1000;
01375     sleepTime.tv_nsec = (nTimeToWaitInMilliSec % 1000) * 1000000;
01376     DEBUG(DEB_LEV_FULL_SEQ, "%s: Actually wait for %ld msec\n", __func__,
01377                 nTimeToWaitInMilliSec);
01378     nanosleep(&sleepTime, NULL);
01379   }
01380 
01381   /* record last capture time */
01382   gettimeofday(&now, NULL);
01383   omx_camera_source_component_Private->nLastCaptureTimeInMilliSec = ((OMX_U32)now.tv_sec) * 1000 + ((OMX_U32)now.tv_usec) / 1000;
01384 
01385   if ( OMX_MAPBUFQUEUE_GETBUFCOUNTCAPTURED( omx_camera_source_component_Private->sMapbufQueue ) >= OMX_MAPBUFQUEUE_GETMAXLEN( omx_camera_source_component_Private->sMapbufQueue ) / 2 &&
01386         OMX_MAPBUFQUEUE_ISFULL( omx_camera_source_component_Private->sMapbufQueue ) ) {
01387     /* Try to send otherwise drop the last captured buffer */
01388     camera_SendLastCapturedBuffer( omx_camera_source_component_Private );
01389     if ( OMX_MAPBUFQUEUE_ISFULL( omx_camera_source_component_Private->sMapbufQueue ) ) {
01390       /* If the mapbuf queue is still full, drop the last captured buffer */
01391       DEBUG(DEB_LEV_FULL_SEQ, "%s: Drop buffer [%ld]\n", __func__,
01392                 OMX_MAPBUFQUEUE_GETLASTBUFFER( omx_camera_source_component_Private->sMapbufQueue ));
01393       camera_DropLastCapturedBuffer( omx_camera_source_component_Private );
01394     }
01395   }
01396 
01397   /* Start to capture the next buffer */
01398   if ( !OMX_MAPBUFQUEUE_ISFULL( omx_camera_source_component_Private->sMapbufQueue ) ) {
01399     
01400     if (-1 == xioctl(omx_camera_source_component_Private->fdCam, VIDIOC_QBUF, &buf)) {
01401       DEBUG(DEB_LEV_ERR,"In %s error VIDIOC_DQBUF\n",__func__);
01402       err = OMX_ErrorHardware;
01403     }
01404 
01405     OMX_MAPBUFQUEUE_ENQUEUE( omx_camera_source_component_Private->sMapbufQueue );
01406   }
01407 
01408 EXIT:
01409   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
01410   return err;
01411 }
01412 
01413 /* Generate time stamp for the new captured buffer */
01414 static OMX_ERRORTYPE camera_GenerateTimeStamp(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private) {
01415   OMX_ERRORTYPE err = OMX_ErrorNone;  
01416   OMX_U32 nBufferIndex;
01417   struct timeval now;
01418   OMX_TICKS nCurrentWallTime;
01419   OMX_TICKS nTimeStamp;
01420 
01421   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01422 
01423   nBufferIndex = OMX_MAPBUFQUEUE_GETNEXTWAIT(omx_camera_source_component_Private->sMapbufQueue);
01424 
01425   gettimeofday(&now, NULL);
01426   nCurrentWallTime = (OMX_TICKS)(now.tv_sec * 1000000 + now.tv_usec);
01427 
01428   /* To protect nRefWallTime */
01429   pthread_mutex_lock(&omx_camera_source_component_Private->setconfig_mutex);
01430   nTimeStamp = nCurrentWallTime - omx_camera_source_component_Private->nRefWallTime;
01431   pthread_mutex_unlock(&omx_camera_source_component_Private->setconfig_mutex);
01432 
01433   OMX_MAPBUFQUEUE_SETTIMESTAMP(omx_camera_source_component_Private->sMapbufQueue, nBufferIndex, nTimeStamp);
01434 
01435   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
01436   return err;
01437 }
01438 
01439 /* Try to send captured buffers in mapbuf queue to each port.
01440  * Note: In this function, multiple buffers may be sent.
01441  */
01442 static OMX_ERRORTYPE camera_SendCapturedBuffers(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private) {
01443   omx_camera_source_component_PortType *port;
01444   OMX_U32 nBufferCountCur = 0;
01445   OMX_ERRORTYPE err = OMX_ErrorNone;  
01446   OMX_S32 nPortIndex;
01447 
01448   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01449 
01450   for (nPortIndex = OMX_CAMPORT_INDEX_CP; nPortIndex >= OMX_CAMPORT_INDEX_VF; nPortIndex--) {
01451     DEBUG(DEB_LEV_FULL_SEQ, "%s: try to send buffers to port [%ld]\n", __func__, nPortIndex);
01452     port = (omx_camera_source_component_PortType *) omx_camera_source_component_Private->ports[nPortIndex];
01453     if (PORT_IS_ENABLED(port) &&
01454          (omx_camera_source_component_Private->bCapturing || OMX_CAMPORT_INDEX_CP != nPortIndex)) {
01455       nBufferCountCur = port->pBufferSem->semval;
01456       DEBUG(DEB_LEV_FULL_SEQ, "%s: port [%ld] nBufferCountCur = %ld\n", __func__, nPortIndex, nBufferCountCur);
01457       DEBUG(DEB_LEV_FULL_SEQ, "%s: port [%ld] nIndexMapbufQueue = %ld\n", __func__, nPortIndex, port->nIndexMapbufQueue);
01458       DEBUG(DEB_LEV_FULL_SEQ, "%s: Before returning buffers, mapbuf queue index [last, wait, capture] = [%ld, %ld, %ld]\n", __func__,
01459                   omx_camera_source_component_Private->sMapbufQueue.nLastBufIndex,
01460                   omx_camera_source_component_Private->sMapbufQueue.nNextWaitIndex,
01461                   omx_camera_source_component_Private->sMapbufQueue.nNextCaptureIndex );
01462 
01463       while(nBufferCountCur > 0 &&
01464                 (port->nIndexMapbufQueue != OMX_MAPBUFQUEUE_GETNEXTWAIT( omx_camera_source_component_Private->sMapbufQueue ) ||
01465                   (OMX_MAPBUFQUEUE_ISFULL( omx_camera_source_component_Private->sMapbufQueue ) &&
01466                    OMX_MAPBUFQUEUE_NOBUFWAITTOCAPTURE( omx_camera_source_component_Private->sMapbufQueue)
01467                   )
01468                 )
01469               ) {
01470         DEBUG(DEB_LEV_FULL_SEQ, "%s: port [%ld] nBufferCountCur = %ld\n", __func__, nPortIndex, nBufferCountCur);
01471         camera_ProcessPortOneBuffer( omx_camera_source_component_Private, (OMX_U32) nPortIndex );
01472 
01473         port->nIndexMapbufQueue = OMX_MAPBUFQUEUE_GETNEXTINDEX( omx_camera_source_component_Private->sMapbufQueue,
01474                                                      port->nIndexMapbufQueue );
01475         nBufferCountCur--;
01476       }
01477     }
01478  }
01479 
01480   err = camera_UpdateCapturedBufferQueue( omx_camera_source_component_Private );
01481 
01482   DEBUG(DEB_LEV_FULL_SEQ, "%s: After returning buffers, mapbuf queue index [last, wait, capture] = [%ld, %ld, %ld]\n", __func__,
01483               omx_camera_source_component_Private->sMapbufQueue.nLastBufIndex,
01484               omx_camera_source_component_Private->sMapbufQueue.nNextWaitIndex,
01485               omx_camera_source_component_Private->sMapbufQueue.nNextCaptureIndex );
01486 
01487   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
01488   return err;
01489 }
01490 
01491 /* Try to send the last captured buffer in mapbuf queue to each port.
01492  * Note: In this function, only ONE buffer be sent.
01493  */
01494 static OMX_ERRORTYPE camera_SendLastCapturedBuffer(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private) {
01495   omx_camera_source_component_PortType *port;
01496   OMX_U32 nBufferCountCur = 0;
01497   OMX_ERRORTYPE err = OMX_ErrorNone;  
01498   OMX_S32 nPortIndex;
01499 
01500   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01501 
01502   for (nPortIndex = OMX_CAMPORT_INDEX_CP; nPortIndex >= OMX_CAMPORT_INDEX_VF; nPortIndex--) {
01503     DEBUG(DEB_LEV_FULL_SEQ, "%s: try to send buffers to port [%ld]\n", __func__, nPortIndex);
01504     port = (omx_camera_source_component_PortType *) omx_camera_source_component_Private->ports[nPortIndex];
01505     if (PORT_IS_ENABLED(port) &&
01506          (omx_camera_source_component_Private->bCapturing || OMX_CAMPORT_INDEX_CP != nPortIndex)) {
01507       nBufferCountCur = port->pBufferSem->semval;
01508       DEBUG(DEB_LEV_FULL_SEQ, "%s: port [%ld] nBufferCountCur = %ld\n", __func__, nPortIndex, nBufferCountCur);
01509       DEBUG(DEB_LEV_FULL_SEQ, "%s: port [%ld] nIndexMapbufQueue = %ld\n", __func__, nPortIndex, port->nIndexMapbufQueue);
01510       DEBUG(DEB_LEV_FULL_SEQ, "%s: Before returning buffers, mapbuf queue index [last, wait, capture] = [%ld, %ld, %ld]\n", __func__,
01511                   omx_camera_source_component_Private->sMapbufQueue.nLastBufIndex,
01512                   omx_camera_source_component_Private->sMapbufQueue.nNextWaitIndex,
01513                   omx_camera_source_component_Private->sMapbufQueue.nNextCaptureIndex );
01514 
01515       if(nBufferCountCur > 0 &&
01516           port->nIndexMapbufQueue == OMX_MAPBUFQUEUE_GETLASTBUFFER( omx_camera_source_component_Private->sMapbufQueue)) {
01517         DEBUG(DEB_LEV_FULL_SEQ, "%s: port [%ld] nBufferCountCur = %ld\n", __func__, nPortIndex, nBufferCountCur);
01518         camera_ProcessPortOneBuffer( omx_camera_source_component_Private, (OMX_U32) nPortIndex );
01519 
01520         port->nIndexMapbufQueue = OMX_MAPBUFQUEUE_GETNEXTINDEX( omx_camera_source_component_Private->sMapbufQueue,
01521                                                      port->nIndexMapbufQueue );
01522       }
01523     }
01524  }
01525 
01526   err = camera_UpdateCapturedBufferQueue( omx_camera_source_component_Private );
01527 
01528   DEBUG(DEB_LEV_FULL_SEQ, "%s: After returning buffers, mapbuf queue index [last, wait, capture] = [%ld, %ld, %ld]\n", __func__,
01529               omx_camera_source_component_Private->sMapbufQueue.nLastBufIndex,
01530               omx_camera_source_component_Private->sMapbufQueue.nNextWaitIndex,
01531               omx_camera_source_component_Private->sMapbufQueue.nNextCaptureIndex );
01532 
01533   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
01534   return err;
01535 }
01536 
01537 
01538 /* Update captured buffer queue in mapbuf queue */
01539 static OMX_ERRORTYPE camera_UpdateCapturedBufferQueue(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private) {
01540   omx_camera_source_component_PortType *pPreviewPort = (omx_camera_source_component_PortType *)omx_camera_source_component_Private->ports[OMX_CAMPORT_INDEX_VF];
01541   omx_camera_source_component_PortType *pCapturePort = (omx_camera_source_component_PortType *)omx_camera_source_component_Private->ports[OMX_CAMPORT_INDEX_CP];
01542   OMX_ERRORTYPE err = OMX_ErrorNone;  
01543 
01544   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01545 
01546   while ( OMX_MAPBUFQUEUE_HASBUFCAPTURED( omx_camera_source_component_Private->sMapbufQueue ) ) {
01547     if (PORT_IS_ENABLED(pPreviewPort) &&
01548          pPreviewPort->nIndexMapbufQueue == OMX_MAPBUFQUEUE_GETLASTBUFFER( omx_camera_source_component_Private->sMapbufQueue ) ) {
01549       break;
01550     }
01551 
01552     if (PORT_IS_ENABLED(pCapturePort) && omx_camera_source_component_Private->bCapturing &&
01553          pCapturePort->nIndexMapbufQueue == OMX_MAPBUFQUEUE_GETLASTBUFFER( omx_camera_source_component_Private->sMapbufQueue ) ) {
01554       break;
01555     }
01556 
01557     OMX_MAPBUFQUEUE_DEQUEUE( omx_camera_source_component_Private->sMapbufQueue );
01558   }
01559 
01560   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
01561   return err;
01562 }
01563 
01564 /* Process one buffer on the specified port */
01565 static OMX_ERRORTYPE camera_ProcessPortOneBuffer(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private,  OMX_IN OMX_U32 nPortIndex ) {
01566   omx_camera_source_component_PortType *port = (omx_camera_source_component_PortType *)omx_camera_source_component_Private->ports[nPortIndex];
01567   OMX_BUFFERHEADERTYPE* pBufHeader = NULL;
01568   OMX_BOOL bStrideAlign = OMX_FALSE;
01569   OMX_ERRORTYPE err = OMX_ErrorNone;  
01570 
01571   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01572 
01573   /* If buffer queue is not empty */
01574   if (port->pBufferSem->semval > 0) {
01575     /* Dequeue a buffer from buffer queue */
01576     tsem_down(port->pBufferSem);
01577     pBufHeader = dequeue(port->pBufferQueue);
01578     if(pBufHeader == NULL){
01579       DEBUG(DEB_LEV_ERR, "%s: <ERROR> --Had NULL buffer from port [%ld]!!\n", __func__, nPortIndex);
01580       err = OMX_ErrorBadParameter;
01581       goto EXIT;
01582     }
01583 
01584     if ( OMX_CAMPORT_INDEX_CP == nPortIndex ) {
01585       if ( OMX_FALSE == omx_camera_source_component_Private->sSensorMode.bOneShot ) {
01586         /* Video capture use case */
01587         if ((err = camera_AddTimeStamp(omx_camera_source_component_Private, pBufHeader)) != OMX_ErrorNone) {
01588           goto EXIT;
01589         }
01590 
01591         if ((err = camera_UpdateThumbnailCondition( omx_camera_source_component_Private )) != OMX_ErrorNone ) {
01592           goto EXIT;
01593         }
01594       }
01595       else {
01596         /* Still image capture use case */
01597         if ( (err = camera_HandleStillImageCapture( omx_camera_source_component_Private )) != OMX_ErrorNone ) {
01598           goto EXIT;
01599         }
01600       }
01601 
01602       if ( OMX_TRUE == omx_camera_source_component_Private->bThumbnailStart ) {
01603         /* Handle thumbnail image capture */
01604         if ( (err = camera_HandleThumbnailCapture( omx_camera_source_component_Private )) != OMX_ErrorNone ) {
01605           goto EXIT;
01606         }
01607       }
01608     }
01609 
01610     /* Translate color format and frame size */
01611     err = camera_ReformatVideoFrame( (OMX_PTR) OMX_MAPBUFQUEUE_GETBUFADDR(
01612                                                            omx_camera_source_component_Private->sMapbufQueue,
01613                                                            port->nIndexMapbufQueue  ),
01614                                                          omx_camera_source_component_Private->sSensorMode.sFrameSize.nWidth,
01615                                                          omx_camera_source_component_Private->sSensorMode.sFrameSize.nHeight,
01616                                                          omx_camera_source_component_Private->sV4lColorFormat,
01617                                                          (OMX_PTR) (pBufHeader->pBuffer + pBufHeader->nOffset),
01618                                                          port->sPortParam.format.video.nFrameWidth,
01619                                                          port->sPortParam.format.video.nFrameHeight,
01620                                                          port->sPortParam.format.video.nStride,
01621                                                          port->sPortParam.format.video.eColorFormat,
01622                                                          bStrideAlign );
01623 
01624     if ( err != OMX_ErrorNone ) {
01625       goto EXIT;
01626     }
01627 
01628     /* Return buffer */
01629     pBufHeader->nFilledLen = omx_camera_source_component_Private->oFrameSize;
01630     DEBUG(DEB_LEV_FULL_SEQ, "%s: return buffer [%ld] on port [%ld]: nFilledLen = %ld\n", __func__,
01631                 port->nIndexMapbufQueue, nPortIndex, pBufHeader->nFilledLen);
01632     port->ReturnBufferFunction((omx_base_PortType *)port, pBufHeader);
01633   }
01634 
01635 EXIT:
01636   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
01637   return err;
01638 }
01639 
01640 /* Drop the last captured buffer in mapbuf queue */
01641 static OMX_ERRORTYPE camera_DropLastCapturedBuffer(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private) {
01642   omx_camera_source_component_PortType *port;
01643   OMX_U32 i = 0;
01644   OMX_ERRORTYPE err = OMX_ErrorNone;  
01645 
01646   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01647 
01648   for ( i = OMX_CAMPORT_INDEX_VF; i <= OMX_CAMPORT_INDEX_CP; i++ ) {
01649     port = (omx_camera_source_component_PortType *) omx_camera_source_component_Private->ports[i];
01650     if ( PORT_IS_ENABLED( port ) &&
01651          port->nIndexMapbufQueue == OMX_MAPBUFQUEUE_GETLASTBUFFER(
01652          omx_camera_source_component_Private->sMapbufQueue ) ) {
01653       if ( OMX_CAMPORT_INDEX_CP != i || omx_camera_source_component_Private->bCapturing ) {
01654         port->nIndexMapbufQueue = OMX_MAPBUFQUEUE_GETNEXTINDEX( omx_camera_source_component_Private->sMapbufQueue,
01655                                                                             port->nIndexMapbufQueue );
01656       }
01657     }
01658   }
01659 
01660   OMX_MAPBUFQUEUE_DEQUEUE( omx_camera_source_component_Private->sMapbufQueue );
01661 
01662   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
01663   return err;
01664 }
01665 
01666 /* Reformat one frame in terms of frame size and color format from source to destination address.
01667  * Note: This function is currently implemented as a simple memory copy, because the color conversion
01668  * and image resizing can be performed by a color conversion component that is tunneled with the
01669  * camera component.
01670  */
01671 static OMX_ERRORTYPE camera_ReformatVideoFrame(
01672                                                     OMX_IN OMX_PTR pSrcFrameAddr,
01673                                                     OMX_IN OMX_U32 nSrcFrameWidth,
01674                                                     OMX_IN OMX_U32 nSrcFrameHeight,
01675                                                     OMX_IN V4L2_COLOR_FORMATTYPE sSrcV4l2ColorFormat,
01676                                                     OMX_IN OMX_PTR pDstFrameAddr,
01677                                                     OMX_IN OMX_U32 nDstFrameWidth,
01678                                                     OMX_IN OMX_U32 nDstFrameHeight,
01679                                                     OMX_IN OMX_S32 nDstFrameStride,
01680                                                     OMX_IN OMX_COLOR_FORMATTYPE eDstOmxColorFormat,
01681                                                     OMX_IN OMX_BOOL bStrideAlign ) {
01682   OMX_COLOR_FORMATTYPE eSrcOmxColorFormat;
01683   OMX_ERRORTYPE err = OMX_ErrorNone;  
01684 
01685   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01686 
01687   if ( (err = camera_MapColorFormatV4lToOmx( &sSrcV4l2ColorFormat,
01688          &eSrcOmxColorFormat )) != OMX_ErrorNone ) {
01689     DEBUG(DEB_LEV_ERR, "%s: <ERROR> -- Unsupported V4L2 color format (palette, depth) = (%d, %d)\n",__func__,sSrcV4l2ColorFormat.v4l2Pixfmt, sSrcV4l2ColorFormat.v4l2Depth);
01690     goto EXIT;
01691   }
01692 
01693   DEBUG(DEB_LEV_FULL_SEQ, "%s: src (width, height, color)=(%ld,%ld,%d)\n", __func__, nSrcFrameWidth, nSrcFrameHeight, eSrcOmxColorFormat);
01694   DEBUG(DEB_LEV_FULL_SEQ, "%s: dst (width, height, stride, color)=(%ld,%ld,%ld,%d)\n", __func__, nDstFrameWidth, nDstFrameHeight, nDstFrameStride, eDstOmxColorFormat);
01695 
01696   /* Now the camera does not support color conversion and frame resize;
01697      To do this job, Pls resort to a color conversion component */
01698   if (nSrcFrameWidth != nDstFrameWidth ||
01699        nSrcFrameHeight != nDstFrameHeight ||
01700        eSrcOmxColorFormat != eDstOmxColorFormat) {
01701     err = OMX_ErrorUnsupportedSetting;
01702     goto EXIT;
01703   }
01704 
01705   memcpy(pDstFrameAddr, pSrcFrameAddr, camera_CalculateBufferSize(nSrcFrameWidth, nSrcFrameHeight, eSrcOmxColorFormat));
01706 
01707 EXIT:
01708   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
01709   return err;
01710 }
01711 
01712 /* Add time stamp to a buffer header */
01713 static OMX_ERRORTYPE camera_AddTimeStamp(
01714   OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private,
01715   OMX_IN OMX_BUFFERHEADERTYPE *pBufHeader) {
01716   omx_camera_source_component_PortType *pCapturePort = (omx_camera_source_component_PortType *)omx_camera_source_component_Private->ports[OMX_CAMPORT_INDEX_CP];
01717   OMX_ERRORTYPE err = OMX_ErrorNone;  
01718 
01719   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01720 
01721   if (omx_camera_source_component_Private->bIsFirstFrame ) {
01722     pBufHeader->nFlags = OMX_BUFFERFLAG_STARTTIME;
01723     omx_camera_source_component_Private->bIsFirstFrame = OMX_FALSE;
01724     DEBUG(DEB_LEV_SIMPLE_SEQ, "%s: Set StartTime Flag!\n",__func__);
01725   }
01726   else {
01727     pBufHeader->nFlags = 0;
01728   }
01729 
01730   pBufHeader->nTimeStamp = OMX_MAPBUFQUEUE_GETTIMESTAMP(omx_camera_source_component_Private->sMapbufQueue, pCapturePort->nIndexMapbufQueue);
01731 
01732   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
01733   return err;
01734 }
01735 
01736 /* Update the condition for thumbnail to occur */
01737 static OMX_ERRORTYPE camera_UpdateThumbnailCondition(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private) {
01738   omx_camera_source_component_PortType *pThumbnailPort = (omx_camera_source_component_PortType *)omx_camera_source_component_Private->ports[OMX_CAMPORT_INDEX_CP_T];
01739   OMX_ERRORTYPE err = OMX_ErrorNone;  
01740 
01741   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01742 
01743   if ( OMX_FALSE == omx_camera_source_component_Private->sSensorMode.bOneShot ) {
01744     if ( omx_camera_source_component_Private->nCapturedCount < (OMX_CAM_VC_SNAPSHOT_INDEX + 1) ) {
01745       omx_camera_source_component_Private->nCapturedCount++;
01746     }
01747 
01748     if ( PORT_IS_ENABLED(pThumbnailPort) &&
01749          OMX_CAM_VC_SNAPSHOT_INDEX == omx_camera_source_component_Private->nCapturedCount ) {
01750       omx_camera_source_component_Private->bThumbnailStart = OMX_TRUE;
01751     }
01752   }
01753 
01754   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
01755   return err;
01756 }
01757 
01758 /* Handle still image capture use case */
01759 static OMX_ERRORTYPE camera_HandleStillImageCapture(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private) {
01760   omx_camera_source_component_PortType *pThumbnailPort = (omx_camera_source_component_PortType *)omx_camera_source_component_Private->ports[OMX_CAMPORT_INDEX_CP_T];
01761   OMX_ERRORTYPE err = OMX_ErrorNone;  
01762 
01763   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01764 
01765   pthread_mutex_lock(&omx_camera_source_component_Private->setconfig_mutex);
01766   omx_camera_source_component_Private->bIsFirstFrame = OMX_FALSE;
01767   omx_camera_source_component_Private->bCapturingNext = OMX_FALSE;
01768   if ( PORT_IS_ENABLED(pThumbnailPort)  ) {
01769     omx_camera_source_component_Private->bThumbnailStart = OMX_TRUE;
01770   }
01771 
01772   if (omx_camera_source_component_Private->bAutoPause) {
01773     /* In autopause mode, command camera component to pause state */
01774     if ((err = omx_camera_source_component_DoStateSet(omx_camera_source_component_Private->openmaxStandComp,
01775                    (OMX_U32)OMX_StatePause)) != OMX_ErrorNone ) {
01776       goto EXIT;
01777     }
01778   }
01779 
01780 EXIT:
01781   pthread_mutex_unlock(&omx_camera_source_component_Private->setconfig_mutex);
01782   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
01783   return err;
01784 }
01785 
01786 /* Handle thumbnail image capture */
01787 static OMX_ERRORTYPE camera_HandleThumbnailCapture(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private) {
01788   omx_camera_source_component_PortType *pThumbnailPort = (omx_camera_source_component_PortType *)omx_camera_source_component_Private->ports[OMX_CAMPORT_INDEX_CP_T];
01789   OMX_BUFFERHEADERTYPE* pBufHeader = NULL;
01790   OMX_ERRORTYPE err = OMX_ErrorNone;  
01791   OMX_BOOL bStrideAlign = OMX_FALSE;
01792 
01793   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01794 
01795   omx_camera_source_component_Private->bThumbnailStart = OMX_FALSE;
01796 
01797   /* If buffer queue on thumbnail port is not empty */
01798   if (pThumbnailPort->pBufferSem->semval > 0) {
01799     /* Dequeue a buffer from buffer queue */
01800     tsem_down(pThumbnailPort->pBufferSem);
01801     pBufHeader = dequeue(pThumbnailPort->pBufferQueue);
01802     if(pBufHeader == NULL){
01803       DEBUG(DEB_LEV_ERR, "%s: <ERROR> --Had NULL buffer from thumbnail port!!\n", __func__);
01804       err = OMX_ErrorBadParameter;
01805       goto EXIT;
01806     }
01807 
01808     /* Determine the buffer for thumbnail */
01809     while (OMX_MAPBUFQUEUE_GETNEXTINDEX( omx_camera_source_component_Private->sMapbufQueue,
01810                pThumbnailPort->nIndexMapbufQueue ) != OMX_MAPBUFQUEUE_GETNEXTWAIT( omx_camera_source_component_Private->sMapbufQueue )
01811              ) {
01812       pThumbnailPort->nIndexMapbufQueue =
01813               OMX_MAPBUFQUEUE_GETNEXTINDEX( omx_camera_source_component_Private->sMapbufQueue,pThumbnailPort->nIndexMapbufQueue );
01814     }
01815 
01816     /* Translate color format and frame size */
01817     err = camera_ReformatVideoFrame( (OMX_PTR) OMX_MAPBUFQUEUE_GETBUFADDR(
01818                                                            omx_camera_source_component_Private->sMapbufQueue,
01819                                                            pThumbnailPort->nIndexMapbufQueue ),
01820                                                          omx_camera_source_component_Private->sSensorMode.sFrameSize.nWidth,
01821                                                          omx_camera_source_component_Private->sSensorMode.sFrameSize.nHeight,
01822                                                          omx_camera_source_component_Private->sV4lColorFormat,
01823                                                          (OMX_PTR) (pBufHeader->pBuffer + pBufHeader->nOffset),
01824                                                          pThumbnailPort->sPortParam.format.video.nFrameWidth,
01825                                                          pThumbnailPort->sPortParam.format.video.nFrameHeight,
01826                                                          pThumbnailPort->sPortParam.format.video.nStride,
01827                                                          pThumbnailPort->sPortParam.format.video.eColorFormat,
01828                                                          bStrideAlign );
01829 
01830     if ( err != OMX_ErrorNone ) {
01831       goto EXIT;
01832     }
01833 
01834     /* Return buffer */
01835     pBufHeader->nFilledLen = omx_camera_source_component_Private->oFrameSize;
01836     DEBUG(DEB_LEV_FULL_SEQ, "%s: return buffer [%ld] on thumbnail port: nFilledLen = %ld\n", __func__,
01837                 pThumbnailPort->nIndexMapbufQueue, pBufHeader->nFilledLen);
01838     pThumbnailPort->ReturnBufferFunction((omx_base_PortType *)pThumbnailPort, pBufHeader);
01839   }
01840 
01841 EXIT:
01842   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
01843   return err;
01844 }
01845 
01846 static int camera_init_mmap(omx_camera_source_component_PrivateType* omx_camera_source_component_Private)
01847 {
01848   struct v4l2_requestbuffers req;
01849   OMX_U32 i;
01850 
01851   CLEAR(req);
01852 
01853   req.count = 4;
01854   req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
01855   req.memory = V4L2_MEMORY_MMAP;
01856 
01857   if (-1 == xioctl(omx_camera_source_component_Private->fdCam, VIDIOC_REQBUFS, &req)) {
01858     if (EINVAL == errno) {
01859       DEBUG(DEB_LEV_ERR, "%s does not support "
01860         "memory mapping\n", V4L2DEV_FILENAME);
01861       return OMX_ErrorHardware;
01862     } else {
01863       DEBUG(DEB_LEV_ERR, "%s error %d, %s\n", "VIDIOC_REQBUFS", errno, strerror(errno));
01864       return OMX_ErrorHardware;
01865     }
01866   }
01867 
01868   if (req.count < 2) {
01869     DEBUG(DEB_LEV_ERR, "Insufficient buffer memory on %s\n", V4L2DEV_FILENAME);
01870     return OMX_ErrorHardware;
01871   }
01872 
01873   omx_camera_source_component_Private->sMapbufQueue.nFrame = req.count;
01874 
01875   omx_camera_source_component_Private->sMapbufQueue.buffers = calloc(req.count, sizeof(*omx_camera_source_component_Private->sMapbufQueue.buffers));
01876 
01877   if (!omx_camera_source_component_Private->sMapbufQueue.buffers) {
01878     DEBUG(DEB_LEV_ERR,"Out of memory\n");
01879     return OMX_ErrorHardware;
01880   }
01881 
01882   for (i = 0; i < req.count; ++i) {
01883     struct v4l2_buffer buf;
01884 
01885     CLEAR(buf);
01886 
01887     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
01888     buf.memory = V4L2_MEMORY_MMAP;
01889     buf.index = i;
01890 
01891     if (-1 == xioctl(omx_camera_source_component_Private->fdCam, VIDIOC_QUERYBUF, &buf)) {
01892       DEBUG(DEB_LEV_ERR, "%s error %d, %s\n", "VIDIOC_QUERYBUF", errno, strerror(errno));
01893       return OMX_ErrorHardware;
01894     }
01895 
01896     omx_camera_source_component_Private->sMapbufQueue.buffers[i].length = buf.length;
01897     omx_camera_source_component_Private->sMapbufQueue.buffers[i].pCapAddrStart = mmap(NULL /* start anywhere */ ,
01898             buf.length,
01899             PROT_READ | PROT_WRITE /* required */ ,
01900             MAP_SHARED /* recommended */ ,
01901             omx_camera_source_component_Private->fdCam, buf.m.offset);
01902 
01903     if (MAP_FAILED == omx_camera_source_component_Private->sMapbufQueue.buffers[i].pCapAddrStart) {
01904       DEBUG(DEB_LEV_ERR, "%s error %d, %s\n", "mmap", errno, strerror(errno));
01905       return OMX_ErrorHardware;
01906     }
01907 
01908     DEBUG(DEB_LEV_PARAMS, "i=%d,addr=%x,length=%d\n",(int)i,
01909       (int)omx_camera_source_component_Private->sMapbufQueue.buffers[i].pCapAddrStart, 
01910       (int)omx_camera_source_component_Private->sMapbufQueue.buffers[i].length);
01911   }
01912 
01913   return OMX_ErrorNone;
01914 }
01915 

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