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.nPorts = NUM_CAMERAPORTS;
00726   omx_camera_source_component_Private->BufferMgmtFunction = omx_camera_source_component_BufferMgmtFunction;
00727 
00729   pthread_mutex_init(&omx_camera_source_component_Private->idle_state_mutex, NULL);
00730   pthread_cond_init(&omx_camera_source_component_Private->idle_wait_condition, NULL);
00731   pthread_cond_init(&omx_camera_source_component_Private->idle_process_condition, NULL);
00732   omx_camera_source_component_Private->bWaitingOnIdle = OMX_FALSE;
00733 
00734   pthread_mutex_init(&omx_camera_source_component_Private->setconfig_mutex, NULL);
00735 
00736   setHeader(&omx_camera_source_component_Private->sSensorMode, sizeof(OMX_PARAM_SENSORMODETYPE));
00737   omx_camera_source_component_Private->sSensorMode.nPortIndex = 0;
00738   omx_camera_source_component_Private->sSensorMode.nFrameRate = DEFAULT_FRAME_RATE; /* default 15 pps */
00739   omx_camera_source_component_Private->sSensorMode.bOneShot = OMX_FALSE; /* default video capture */
00740   setHeader(&omx_camera_source_component_Private->sSensorMode.sFrameSize, sizeof(OMX_FRAMESIZETYPE));
00741   omx_camera_source_component_Private->sSensorMode.sFrameSize.nPortIndex = 0;
00742   omx_camera_source_component_Private->sSensorMode.sFrameSize.nWidth = DEFAULT_FRAME_WIDTH;
00743   omx_camera_source_component_Private->sSensorMode.sFrameSize.nHeight = DEFAULT_FRAME_HEIGHT;
00744   omx_camera_source_component_Private->nFrameIntervalInMilliSec = 1000 / (omx_camera_source_component_Private->sSensorMode.nFrameRate);
00745 
00746   omx_camera_source_component_Private->eOmxColorFormat = DEFAULT_COLOR_FORMAT;
00747   omx_camera_source_component_Private->sV4lColorFormat.v4l2Pixfmt = V4L2_PIX_FMT_YUV420;
00748   omx_camera_source_component_Private->sV4lColorFormat.v4l2Depth = 12;
00749 
00750   omx_camera_source_component_Private->fdCam = -1;
00751   memset(&omx_camera_source_component_Private->sMapbufQueue,0, sizeof(OMX_V4L2_MAPBUFFER_QUEUETYPE));
00752   omx_camera_source_component_Private->sMapbufQueue.nFrame = 0;
00753   omx_camera_source_component_Private->bCapturing = OMX_FALSE;
00754   omx_camera_source_component_Private->bCapturingNext = OMX_FALSE;
00755   omx_camera_source_component_Private->bIsFirstFrame = OMX_FALSE;
00756   omx_camera_source_component_Private->bAutoPause = OMX_FALSE;
00757   omx_camera_source_component_Private->bThumbnailStart = OMX_FALSE;
00758   omx_camera_source_component_Private->nCapturedCount = 0;
00759   
00760 
00762   if (omx_camera_source_component_Private->sPortTypesParam.nPorts && !omx_camera_source_component_Private->ports) {
00763     omx_camera_source_component_Private->ports = calloc(omx_camera_source_component_Private->sPortTypesParam.nPorts, sizeof (omx_base_PortType *));
00764     if (!omx_camera_source_component_Private->ports) {
00765       return OMX_ErrorInsufficientResources;
00766     }
00767     for (i=0; i < omx_camera_source_component_Private->sPortTypesParam.nPorts; i++) {
00771       omx_camera_source_component_Private->ports[i] = (omx_base_PortType *)calloc(1, sizeof(omx_camera_source_component_PortType));
00772       if (!omx_camera_source_component_Private->ports[i]) {
00773         return OMX_ErrorInsufficientResources;
00774       }
00775     }
00776   }
00777 
00778   for (i=0; i<omx_camera_source_component_Private->sPortTypesParam.nPorts; i++) {
00780     base_video_port_Constructor(openmaxStandComp, &omx_camera_source_component_Private->ports[i], i, OMX_FALSE);
00781     port = (omx_camera_source_component_PortType *) omx_camera_source_component_Private->ports[i];
00783     port->sPortParam.nBufferSize = DEFAULT_FRAME_WIDTH*DEFAULT_FRAME_HEIGHT*3/2;
00784     port->sPortParam.format.video.nFrameWidth = DEFAULT_FRAME_WIDTH;
00785     port->sPortParam.format.video.nFrameHeight = DEFAULT_FRAME_HEIGHT;
00786     port->sPortParam.format.video.nStride = DEFAULT_FRAME_WIDTH;
00787     port->sPortParam.format.video.nSliceHeight = DEFAULT_FRAME_HEIGHT;
00788     port->sPortParam.format.video.xFramerate = DEFAULT_FRAME_RATE;
00789     port->sPortParam.format.video.eColorFormat = DEFAULT_COLOR_FORMAT;
00790     port->nIndexMapbufQueue = 0;
00791   }
00792 
00794   omx_camera_source_component_Private->DoStateSet = &omx_camera_source_component_DoStateSet;
00795   omx_camera_source_component_Private->destructor = omx_camera_source_component_Destructor;
00796   openmaxStandComp->SetParameter = omx_camera_source_component_SetParameter;
00797   openmaxStandComp->GetParameter = omx_camera_source_component_GetParameter;
00798   openmaxStandComp->SetConfig = omx_camera_source_component_SetConfig;
00799   openmaxStandComp->GetConfig = omx_camera_source_component_GetConfig;
00800 
00801   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
00802   return err;
00803 }
00804 
00808 OMX_ERRORTYPE omx_camera_source_component_Destructor(OMX_COMPONENTTYPE *openmaxStandComp) {
00809   omx_camera_source_component_PrivateType *omx_camera_source_component_Private = (omx_camera_source_component_PrivateType *)openmaxStandComp->pComponentPrivate;  
00810   OMX_U32 i;
00811 
00812   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
00813 
00815   if (omx_camera_source_component_Private->sPortTypesParam.nPorts && omx_camera_source_component_Private->ports) {
00816     for (i = 0; i < omx_camera_source_component_Private->sPortTypesParam.nPorts; i++) {
00817       if(omx_camera_source_component_Private->ports[i]) {
00818         base_port_Destructor(omx_camera_source_component_Private->ports[i]);
00819       }
00820     }
00821     free(omx_camera_source_component_Private->ports);
00822     omx_camera_source_component_Private->ports = NULL;
00823   }
00824 
00825   pthread_mutex_destroy(&omx_camera_source_component_Private->idle_state_mutex);
00826   pthread_cond_destroy(&omx_camera_source_component_Private->idle_wait_condition);
00827   pthread_cond_destroy(&omx_camera_source_component_Private->idle_process_condition);
00828 
00829   pthread_mutex_destroy(&omx_camera_source_component_Private->setconfig_mutex);
00830 
00831   camera_DeinitCameraDevice(omx_camera_source_component_Private);
00832 
00833   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, OMX_ErrorNone);
00834   return omx_base_source_Destructor(openmaxStandComp);;
00835 }
00836 
00841 static OMX_ERRORTYPE omx_camera_source_component_DoStateSet(OMX_COMPONENTTYPE *openmaxStandComp, OMX_U32 destinationState) {
00842   OMX_ERRORTYPE err = OMX_ErrorNone;  
00843   omx_camera_source_component_PrivateType *omx_camera_source_component_Private = (omx_camera_source_component_PrivateType *)openmaxStandComp->pComponentPrivate;
00844 
00845   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
00846 
00847   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);
00848 
00849   if (omx_camera_source_component_Private->state == OMX_StateLoaded && destinationState == OMX_StateIdle) {
00850     /* Loaded --> Idle */
00851     if ((err = camera_InitCameraDevice(omx_camera_source_component_Private)) != OMX_ErrorNone) {
00852       goto EXIT;
00853     }
00854   }
00855   else if (omx_camera_source_component_Private->state == OMX_StateIdle && destinationState == OMX_StateExecuting) {
00856     /* Idle --> Exec */
00857     pthread_mutex_lock(&omx_camera_source_component_Private->idle_state_mutex);
00858     if (!omx_camera_source_component_Private->bWaitingOnIdle) {
00859       pthread_cond_wait(&omx_camera_source_component_Private->idle_process_condition,&omx_camera_source_component_Private->idle_state_mutex);
00860     }
00861     pthread_mutex_unlock(&omx_camera_source_component_Private->idle_state_mutex);
00862   }
00863   else if (omx_camera_source_component_Private->state == OMX_StateIdle && destinationState == OMX_StateLoaded) {
00864     /* Idle --> Loaded*/
00865     pthread_mutex_lock(&omx_camera_source_component_Private->idle_state_mutex);
00866     if (!omx_camera_source_component_Private->bWaitingOnIdle) {
00867       pthread_cond_wait(&omx_camera_source_component_Private->idle_process_condition,&omx_camera_source_component_Private->idle_state_mutex);
00868     }
00869     camera_DeinitCameraDevice(omx_camera_source_component_Private);
00870     if (omx_camera_source_component_Private->bWaitingOnIdle) {
00871       pthread_cond_signal(&omx_camera_source_component_Private->idle_wait_condition);
00872     }
00873     pthread_mutex_unlock(&omx_camera_source_component_Private->idle_state_mutex);
00874   }
00875 
00876 
00877   omx_camera_source_component_Private->eLastState = omx_camera_source_component_Private->state;
00878   err = omx_base_component_DoStateSet(openmaxStandComp, destinationState);
00879   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);
00880 
00881 
00882   if (omx_camera_source_component_Private->eLastState == OMX_StateIdle && omx_camera_source_component_Private->state == OMX_StateExecuting) {
00883     /* Idle --> Exec */
00884     pthread_mutex_lock(&omx_camera_source_component_Private->idle_state_mutex);
00885     if (omx_camera_source_component_Private->bWaitingOnIdle) {
00886       if ((err = camera_StartCameraDevice(omx_camera_source_component_Private)) != OMX_ErrorNone) {
00887         pthread_mutex_unlock(&omx_camera_source_component_Private->idle_state_mutex);
00888         goto EXIT;
00889       }
00890       pthread_cond_signal(&omx_camera_source_component_Private->idle_wait_condition);
00891     }
00892     pthread_mutex_unlock(&omx_camera_source_component_Private->idle_state_mutex);
00893   }
00894   else if (omx_camera_source_component_Private->eLastState == OMX_StateExecuting && omx_camera_source_component_Private->state == OMX_StateIdle) {
00895     /* Exec --> Idle */
00896     pthread_mutex_lock(&omx_camera_source_component_Private->idle_state_mutex);
00897     if (!omx_camera_source_component_Private->bWaitingOnIdle) {
00898       pthread_cond_wait(&omx_camera_source_component_Private->idle_process_condition,&omx_camera_source_component_Private->idle_state_mutex);
00899     }
00900     camera_StopCameraDevice(omx_camera_source_component_Private);
00901     pthread_mutex_unlock(&omx_camera_source_component_Private->idle_state_mutex);
00902   }
00903 
00904 
00905 EXIT:
00906   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
00907   return err;
00908 }
00909 
00910 
00916 static OMX_ERRORTYPE omx_camera_source_component_GetParameter(
00917   OMX_IN  OMX_HANDLETYPE hComponent,
00918   OMX_IN  OMX_INDEXTYPE nParamIndex,
00919   OMX_INOUT  OMX_PTR ComponentParameterStructure) {
00920 
00921   OMX_ERRORTYPE err = OMX_ErrorNone;  
00922   OMX_COMPONENTTYPE *openmaxStandComp;
00923   omx_camera_source_component_PrivateType* omx_camera_source_component_Private;
00924   omx_camera_source_component_PortType *pPort;
00925   OMX_VIDEO_PARAM_PORTFORMATTYPE *pVideoPortFormat;
00926   OMX_PARAM_SENSORMODETYPE *pSensorMode;
00927 
00928   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
00929 
00930   if (ComponentParameterStructure == NULL) {
00931     return OMX_ErrorBadParameter;
00932   }
00933 
00934   openmaxStandComp = (OMX_COMPONENTTYPE *)hComponent;
00935   omx_camera_source_component_Private = (omx_camera_source_component_PrivateType *)openmaxStandComp->pComponentPrivate;
00936 
00937   DEBUG(DEB_LEV_SIMPLE_SEQ, "%s: Getting parameter %i\n", __func__, nParamIndex);
00938 
00939   switch(nParamIndex) {
00940     case OMX_IndexParamVideoInit:
00941       if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_PORT_PARAM_TYPE))) != OMX_ErrorNone) {
00942         DEBUG(DEB_LEV_ERR, "%s (line %d): Check header failed!\n", __func__, __LINE__);
00943         break;
00944       }
00945       memcpy(ComponentParameterStructure,&omx_camera_source_component_Private->sPortTypesParam,sizeof(OMX_PORT_PARAM_TYPE));
00946       break;
00947 
00948     case OMX_IndexParamVideoPortFormat:
00949       pVideoPortFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure;
00950       if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE))) != OMX_ErrorNone) {
00951         DEBUG(DEB_LEV_ERR, "%s (line %d): Check header failed!\n", __func__, __LINE__);
00952         break;
00953       }
00954       if (pVideoPortFormat->nPortIndex < NUM_CAMERAPORTS)
00955       {
00956         pPort = (omx_camera_source_component_PortType *) omx_camera_source_component_Private->ports[pVideoPortFormat->nPortIndex];
00957         pVideoPortFormat->eCompressionFormat = pPort->sPortParam.format.video.eCompressionFormat;
00958         pVideoPortFormat->eColorFormat = pPort->sPortParam.format.video.eColorFormat;
00959       }
00960       else
00961       {
00962         err = OMX_ErrorBadPortIndex;
00963       }
00964       break;
00965 
00966     case OMX_IndexParamCommonSensorMode:
00967       pSensorMode = (OMX_PARAM_SENSORMODETYPE *)ComponentParameterStructure;
00968       if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_PARAM_SENSORMODETYPE))) != OMX_ErrorNone) {
00969         DEBUG(DEB_LEV_ERR, "%s (line %d): Check header failed!\n", __func__, __LINE__);
00970         break;
00971       }
00972       memcpy(pSensorMode, &omx_camera_source_component_Private->sSensorMode, sizeof(OMX_PARAM_SENSORMODETYPE));
00973       break;
00974 
00975     default: /*Call the base component function*/
00976       err = omx_base_component_GetParameter(hComponent, nParamIndex, ComponentParameterStructure);
00977       break;
00978   }
00979 
00980   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
00981   return err;
00982 }
00983 
00989 static OMX_ERRORTYPE omx_camera_source_component_SetParameter(
00990   OMX_IN  OMX_HANDLETYPE hComponent,
00991   OMX_IN  OMX_INDEXTYPE nParamIndex,
00992   OMX_IN  OMX_PTR ComponentParameterStructure) {
00993 
00994   OMX_ERRORTYPE err = OMX_ErrorNone;  
00995   OMX_COMPONENTTYPE *openmaxStandComp;
00996   omx_camera_source_component_PrivateType* omx_camera_source_component_Private;
00997   omx_camera_source_component_PortType *pPort;
00998   OMX_PARAM_PORTDEFINITIONTYPE *pPortDef;
00999   OMX_VIDEO_PARAM_PORTFORMATTYPE *pVideoPortFormat;
01000   OMX_PARAM_SENSORMODETYPE *pSensorMode;
01001 
01002   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01003 
01004   if (ComponentParameterStructure == NULL) {
01005     return OMX_ErrorBadParameter;
01006   }
01007 
01008   openmaxStandComp = (OMX_COMPONENTTYPE *)hComponent;
01009   omx_camera_source_component_Private = (omx_camera_source_component_PrivateType *)openmaxStandComp->pComponentPrivate;
01010 
01011   DEBUG(DEB_LEV_SIMPLE_SEQ, "%s: Setting parameter %i\n", __func__, nParamIndex);
01012 
01013   switch(nParamIndex) {
01014     case OMX_IndexParamVideoInit:
01015       if ((err = checkHeader(ComponentParameterStructure, sizeof(OMX_PORT_PARAM_TYPE))) != OMX_ErrorNone) {
01016         DEBUG(DEB_LEV_ERR, "%s (line %d): Check header failed!\n", __func__, __LINE__);
01017         break;
01018       }
01019       memcpy(&omx_camera_source_component_Private->sPortTypesParam,ComponentParameterStructure,sizeof(OMX_PORT_PARAM_TYPE));
01020       break;
01021 
01022     case OMX_IndexParamPortDefinition:
01023       pPortDef = (OMX_PARAM_PORTDEFINITIONTYPE *) ComponentParameterStructure;
01024       err = camera_CheckSupportedColorFormat(pPortDef->format.video.eColorFormat);
01025       if (err != OMX_ErrorNone) {
01026         DEBUG(DEB_LEV_ERR, "%s (line %d): Supported Color Format Check failed!\n", __func__, __LINE__);
01027         break;
01028       }
01029       err = camera_CheckSupportedFramesize(pPortDef->format.video.nFrameWidth, pPortDef->format.video.nFrameHeight);
01030       if (err != OMX_ErrorNone) {
01031         DEBUG(DEB_LEV_ERR, "%s (line %d): Supported Frame Size Check failed!\n", __func__, __LINE__);
01032         break;
01033       }
01034       /*Call the base component function*/
01035       err = omx_base_component_SetParameter(hComponent, nParamIndex, ComponentParameterStructure);
01036       if (err != OMX_ErrorNone) {
01037         DEBUG(DEB_LEV_ERR, "%s (line %d): Call base SetParameter failed!\n", __func__, __LINE__);
01038         break;
01039       }
01040       pPort = (omx_camera_source_component_PortType *) omx_camera_source_component_Private->ports[pPortDef->nPortIndex];
01041       memcpy(&pPort->sPortParam, pPortDef, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
01042       pPort->sPortParam.nBufferSize = camera_CalculateBufferSize(pPort->sPortParam.format.video.nFrameWidth, pPort->sPortParam.format.video.nFrameHeight, pPort->sPortParam.format.video.eColorFormat);
01043       break;
01044 
01045     case OMX_IndexParamVideoPortFormat:
01046       pVideoPortFormat = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)ComponentParameterStructure;
01047       err = omx_base_component_ParameterSanityCheck(hComponent, pVideoPortFormat->nPortIndex, pVideoPortFormat, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
01048       if (err != OMX_ErrorNone) {
01049         DEBUG(DEB_LEV_ERR, "%s (line %d): Parameter Sanity Check failed!\n", __func__, __LINE__);
01050         break;
01051       }
01052       err = camera_CheckSupportedColorFormat(pVideoPortFormat->eColorFormat);
01053       if (err != OMX_ErrorNone) {
01054         DEBUG(DEB_LEV_ERR, "%s (line %d): Supported Color Format Check failed!\n", __func__, __LINE__);
01055         break;
01056       }
01057       pPort = (omx_camera_source_component_PortType *) omx_camera_source_component_Private->ports[pVideoPortFormat->nPortIndex];
01058       pPort->sPortParam.format.video.eCompressionFormat = pVideoPortFormat->eCompressionFormat;
01059       pPort->sPortParam.format.video.eColorFormat = pVideoPortFormat->eColorFormat;
01060       break;
01061 
01062     case OMX_IndexParamCommonSensorMode:
01063       pSensorMode = (OMX_PARAM_SENSORMODETYPE *)ComponentParameterStructure;
01064       err = omx_base_component_ParameterSanityCheck(hComponent, pSensorMode->nPortIndex, pSensorMode, sizeof(OMX_PARAM_SENSORMODETYPE));
01065       if (err != OMX_ErrorNone) {
01066         DEBUG(DEB_LEV_ERR, "%s (line %d): Parameter Sanity Check failed!\n", __func__, __LINE__);
01067         break;
01068       }
01069       err = camera_CheckSupportedFramesize(pSensorMode->sFrameSize.nWidth, pSensorMode->sFrameSize.nHeight);
01070       if (err != OMX_ErrorNone) {
01071         DEBUG(DEB_LEV_ERR, "%s (line %d): Supported Frame Size Check failed!\n", __func__, __LINE__);
01072         break;
01073       }
01074       memcpy(&omx_camera_source_component_Private->sSensorMode, pSensorMode, sizeof(OMX_PARAM_SENSORMODETYPE));
01075       omx_camera_source_component_Private->nFrameIntervalInMilliSec = 1000 / (pSensorMode->nFrameRate);
01076       break;
01077 
01078     default: /*Call the base component function*/
01079       err = omx_base_component_SetParameter(hComponent, nParamIndex, ComponentParameterStructure);
01080       break;
01081   }
01082 
01083   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
01084   return err;
01085 }
01086 
01092 static OMX_ERRORTYPE omx_camera_source_component_GetConfig(
01093   OMX_IN  OMX_HANDLETYPE hComponent,
01094   OMX_IN  OMX_INDEXTYPE nConfigIndex,
01095   OMX_INOUT OMX_PTR pComponentConfigStructure) {
01096   OMX_ERRORTYPE err = OMX_ErrorNone;  
01097   OMX_COMPONENTTYPE *openmaxStandComp;
01098   omx_camera_source_component_PrivateType* omx_camera_source_component_Private;
01099   OMX_CONFIG_BOOLEANTYPE *pCapturing;
01100   OMX_CONFIG_BOOLEANTYPE *pAutoPause;
01101 
01102   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01103 
01104   if (pComponentConfigStructure == NULL) {
01105     return OMX_ErrorBadParameter;
01106   }
01107 
01108   openmaxStandComp = (OMX_COMPONENTTYPE *)hComponent;
01109   omx_camera_source_component_Private = (omx_camera_source_component_PrivateType *)openmaxStandComp->pComponentPrivate;
01110 
01111   DEBUG(DEB_LEV_SIMPLE_SEQ, "%s: Getting configuration %i\n", __func__, nConfigIndex);
01112 
01113   switch (nConfigIndex) {
01114     case OMX_IndexConfigCapturing:
01115       pCapturing = (OMX_CONFIG_BOOLEANTYPE *)pComponentConfigStructure;
01116       if ((err = checkHeader(pComponentConfigStructure, sizeof(OMX_CONFIG_BOOLEANTYPE))) != OMX_ErrorNone) {
01117         DEBUG(DEB_LEV_ERR, "%s (line %d): Check header failed!\n", __func__, __LINE__);
01118         break;
01119       }
01120       pCapturing->bEnabled = omx_camera_source_component_Private->bCapturingNext;
01121       break;
01122     case OMX_IndexAutoPauseAfterCapture:
01123       pAutoPause = (OMX_CONFIG_BOOLEANTYPE *)pComponentConfigStructure;
01124       if ((err = checkHeader(pComponentConfigStructure, sizeof(OMX_CONFIG_BOOLEANTYPE))) != OMX_ErrorNone) {
01125         DEBUG(DEB_LEV_ERR, "%s (line %d): Check header failed!\n", __func__, __LINE__);
01126         break;
01127       }
01128       pAutoPause->bEnabled = omx_camera_source_component_Private->bAutoPause;
01129       break;
01130     default:
01131       err = omx_base_component_GetConfig(hComponent, nConfigIndex, pComponentConfigStructure);
01132       break;
01133   }
01134 
01135   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
01136   return err;
01137 }
01138 
01144 static OMX_ERRORTYPE omx_camera_source_component_SetConfig(
01145   OMX_IN  OMX_HANDLETYPE hComponent,
01146   OMX_IN  OMX_INDEXTYPE nConfigIndex,
01147   OMX_IN OMX_PTR pComponentConfigStructure) {
01148   OMX_ERRORTYPE err = OMX_ErrorNone;  
01149   OMX_COMPONENTTYPE *openmaxStandComp;
01150   omx_camera_source_component_PrivateType* omx_camera_source_component_Private;
01151   OMX_CONFIG_BOOLEANTYPE *pCapturing;
01152   OMX_CONFIG_BOOLEANTYPE *pAutoPause;
01153 
01154   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01155 
01156   if (pComponentConfigStructure == NULL) {
01157     return OMX_ErrorBadParameter;
01158   }
01159 
01160   openmaxStandComp = (OMX_COMPONENTTYPE *)hComponent;
01161   omx_camera_source_component_Private = (omx_camera_source_component_PrivateType *)openmaxStandComp->pComponentPrivate;
01162 
01163   DEBUG(DEB_LEV_SIMPLE_SEQ, "%s: Setting configuration %i\n", __func__, nConfigIndex);
01164 
01165   switch (nConfigIndex) {
01166     case OMX_IndexConfigCapturing:
01167       pCapturing = (OMX_CONFIG_BOOLEANTYPE *)pComponentConfigStructure;
01168       if ((err = checkHeader(pComponentConfigStructure, sizeof(OMX_CONFIG_BOOLEANTYPE))) != OMX_ErrorNone) {
01169         DEBUG(DEB_LEV_ERR, "%s (line %d): Check header failed!\n", __func__, __LINE__);
01170         break;
01171       }
01172       err = camera_SetConfigCapturing( omx_camera_source_component_Private, pCapturing );
01173       break;
01174     case OMX_IndexAutoPauseAfterCapture:
01175       pAutoPause = (OMX_CONFIG_BOOLEANTYPE *)pComponentConfigStructure;
01176       if ((err = checkHeader(pComponentConfigStructure, sizeof(OMX_CONFIG_BOOLEANTYPE))) != OMX_ErrorNone) {
01177         DEBUG(DEB_LEV_ERR, "%s (line %d): Check header failed!\n", __func__, __LINE__);
01178         break;
01179       }
01180       pthread_mutex_lock(&omx_camera_source_component_Private->setconfig_mutex);
01181       omx_camera_source_component_Private->bAutoPause = pAutoPause->bEnabled;
01182       pthread_mutex_unlock(&omx_camera_source_component_Private->setconfig_mutex);
01183       break;
01184     default:
01185       err = omx_base_component_SetConfig(hComponent, nConfigIndex, pComponentConfigStructure);
01186       break;
01187   }
01188 
01189   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
01190   return err;
01191 }
01192 
01197 static void* omx_camera_source_component_BufferMgmtFunction (void* param) {
01198   OMX_COMPONENTTYPE *openmaxStandComp = (OMX_COMPONENTTYPE *)param;
01199   omx_camera_source_component_PrivateType *omx_camera_source_component_Private = (omx_camera_source_component_PrivateType*)openmaxStandComp->pComponentPrivate;
01200   omx_camera_source_component_PortType *pPreviewPort = (omx_camera_source_component_PortType *)omx_camera_source_component_Private->ports[OMX_CAMPORT_INDEX_VF];
01201   omx_camera_source_component_PortType *pCapturePort = (omx_camera_source_component_PortType *)omx_camera_source_component_Private->ports[OMX_CAMPORT_INDEX_CP];
01202   omx_camera_source_component_PortType *pThumbnailPort = (omx_camera_source_component_PortType *)omx_camera_source_component_Private->ports[OMX_CAMPORT_INDEX_CP_T];
01203   tsem_t* pPreviewBufSem = pPreviewPort->pBufferSem;
01204   tsem_t* pCaptureBufSem = pCapturePort->pBufferSem;
01205   tsem_t* pThumbnailBufSem = pThumbnailPort->pBufferSem;
01206   OMX_BUFFERHEADERTYPE* pPreviewBuffer=NULL;
01207   OMX_BUFFERHEADERTYPE* pCaptureBuffer=NULL;
01208   OMX_BUFFERHEADERTYPE* pThumbnailBuffer=NULL;
01209 
01210 
01211   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01212 
01213   while(omx_camera_source_component_Private->state == OMX_StateIdle ||
01214             omx_camera_source_component_Private->state == OMX_StateExecuting ||  
01215             omx_camera_source_component_Private->state == OMX_StatePause ||
01216             omx_camera_source_component_Private->transientState == OMX_TransStateLoadedToIdle) {
01217 
01218     /*Wait till the ports are being flushed*/
01219     pthread_mutex_lock(&omx_camera_source_component_Private->flush_mutex);
01220     while( PORT_IS_BEING_FLUSHED(pPreviewPort) || 
01221            PORT_IS_BEING_FLUSHED(pCapturePort) ||
01222            PORT_IS_BEING_FLUSHED(pThumbnailPort)) {
01223       pthread_mutex_unlock(&omx_camera_source_component_Private->flush_mutex);
01224       
01225       DEBUG(DEB_LEV_FULL_SEQ, "In %s 1 signalling flush all cond PrevewSemVal=%d,CaptureSemval=%d, ThumbnailSemval=%d\n", 
01226         __func__,pPreviewBufSem->semval,pCaptureBufSem->semval, pThumbnailBufSem->semval);
01227       DEBUG(DEB_LEV_FULL_SEQ, "In %s 1 signalling flush all cond pPreviewBuffer=0x%lX,pCaptureBuffer=0x%lX, pThumbnailBuffer=0x%lX\n", 
01228         __func__,(OMX_U32)pPreviewBuffer,(OMX_U32)pCaptureBuffer, (OMX_U32)pThumbnailBuffer);
01229 
01230       if(pPreviewBuffer!=NULL && PORT_IS_BEING_FLUSHED(pPreviewPort)) {
01231         pPreviewPort->ReturnBufferFunction((omx_base_PortType *)pPreviewPort,pPreviewBuffer);
01232         pPreviewBuffer=NULL;
01233         DEBUG(DEB_LEV_FULL_SEQ, "Ports are flushing,so returning Preview buffer\n");
01234       }
01235 
01236       if(pCaptureBuffer!=NULL && PORT_IS_BEING_FLUSHED(pCapturePort)) {
01237         pCapturePort->ReturnBufferFunction((omx_base_PortType *)pCapturePort,pCaptureBuffer);
01238         pCaptureBuffer=NULL;
01239         DEBUG(DEB_LEV_FULL_SEQ, "Ports are flushing,so returning Capture buffer\n");
01240       }
01241 
01242       if(pThumbnailBuffer!=NULL && PORT_IS_BEING_FLUSHED(pThumbnailPort)) {
01243         pThumbnailPort->ReturnBufferFunction((omx_base_PortType *)pThumbnailPort,pThumbnailBuffer);
01244         pThumbnailBuffer=NULL;
01245         DEBUG(DEB_LEV_FULL_SEQ, "Ports are flushing,so returning Thumbnail buffer\n");
01246       }
01247 
01248       DEBUG(DEB_LEV_FULL_SEQ, "In %s 2 signalling flush all cond PrevewSemVal=%d,CaptureSemval=%d, ThumbnailSemval=%d\n", 
01249         __func__,pPreviewBufSem->semval,pCaptureBufSem->semval, pThumbnailBufSem->semval);
01250       DEBUG(DEB_LEV_FULL_SEQ, "In %s 2 signalling flush all cond pPreviewBuffer=0x%lX,pCaptureBuffer=0x%lX, pThumbnailBuffer=0x%lX\n", 
01251         __func__,(OMX_U32)pPreviewBuffer,(OMX_U32)pCaptureBuffer, (OMX_U32)pThumbnailBuffer);
01252   
01253       pthread_mutex_lock(&omx_camera_source_component_Private->flush_mutex);
01254       pthread_cond_signal(&omx_camera_source_component_Private->flush_all_condition);
01255       pthread_cond_wait(&omx_camera_source_component_Private->flush_condition,&omx_camera_source_component_Private->flush_mutex);
01256     }
01257     pthread_mutex_unlock(&omx_camera_source_component_Private->flush_mutex);
01258 
01259     pthread_mutex_lock(&omx_camera_source_component_Private->setconfig_mutex);
01260     if (!omx_camera_source_component_Private->bCapturing && omx_camera_source_component_Private->bCapturingNext) {
01261       pCapturePort->nIndexMapbufQueue = OMX_MAPBUFQUEUE_GETLASTBUFFER(omx_camera_source_component_Private->sMapbufQueue);
01262     }
01263     else if (omx_camera_source_component_Private->bCapturing && !omx_camera_source_component_Private->bCapturingNext) {
01264       omx_camera_source_component_Private->nCapturedCount = 0;
01265     }
01266     omx_camera_source_component_Private->bCapturing = omx_camera_source_component_Private->bCapturingNext;
01267     pthread_mutex_unlock(&omx_camera_source_component_Private->setconfig_mutex);
01268 
01269     if(omx_camera_source_component_Private->state==OMX_StatePause &&
01270         !(PORT_IS_BEING_FLUSHED(pPreviewPort) || PORT_IS_BEING_FLUSHED(pCapturePort) || PORT_IS_BEING_FLUSHED(pThumbnailPort))) {
01271       /*Waiting at paused state*/
01272       DEBUG(DEB_LEV_FULL_SEQ, "In %s: wait at State %d\n", __func__, omx_camera_source_component_Private->state);
01273       tsem_wait(omx_camera_source_component_Private->bStateSem);
01274     }
01275 
01276     pthread_mutex_lock(&omx_camera_source_component_Private->idle_state_mutex);
01277     if(omx_camera_source_component_Private->state==OMX_StateIdle &&
01278         !(PORT_IS_BEING_FLUSHED(pPreviewPort) || PORT_IS_BEING_FLUSHED(pCapturePort) || PORT_IS_BEING_FLUSHED(pThumbnailPort))) {
01279       /*Waiting at idle state*/
01280       DEBUG(DEB_LEV_FULL_SEQ, "In %s: wait at State %d\n", __func__, omx_camera_source_component_Private->state);
01281       omx_camera_source_component_Private->bWaitingOnIdle = OMX_TRUE;
01282       pthread_cond_signal(&omx_camera_source_component_Private->idle_process_condition);
01283       pthread_cond_wait(&omx_camera_source_component_Private->idle_wait_condition,&omx_camera_source_component_Private->idle_state_mutex);
01284       if(omx_camera_source_component_Private->transientState == OMX_TransStateIdleToLoaded) {
01285         DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Buffer Management Thread is exiting\n",__func__);
01286         pthread_mutex_unlock(&omx_camera_source_component_Private->idle_state_mutex);
01287         break;
01288       }
01289     }
01290     omx_camera_source_component_Private->bWaitingOnIdle = OMX_FALSE;
01291     pthread_mutex_unlock(&omx_camera_source_component_Private->idle_state_mutex);
01292 
01293     /* After cemera does start, capture video data from camera */
01294     camera_HandleThreadBufferCapture( omx_camera_source_component_Private );
01295 
01296   }
01297 
01298 
01299   DEBUG(DEB_LEV_FUNCTION_NAME, "Exiting Buffer Management Thread: %s\n",__func__);
01300   return NULL;
01301 }
01302 
01303 /* Buffer capture routine for the buffer management thread */
01304 static OMX_ERRORTYPE camera_HandleThreadBufferCapture(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private) {
01305   OMX_U32 nCurTimeInMilliSec;
01306   OMX_S32 nTimeToWaitInMilliSec;
01307   struct timeval now;
01308   struct timespec sleepTime;
01309   OMX_ERRORTYPE err = OMX_ErrorNone;  
01310   struct v4l2_buffer buf;
01311   
01312   CLEAR(buf);
01313   
01314 
01315   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01316 
01317   DEBUG(DEB_LEV_FULL_SEQ, "%s: mapbuf queue index [last, wait, capture] = [%ld, %ld, %ld]\n", __func__,
01318               omx_camera_source_component_Private->sMapbufQueue.nLastBufIndex,
01319               omx_camera_source_component_Private->sMapbufQueue.nNextWaitIndex,
01320               omx_camera_source_component_Private->sMapbufQueue.nNextCaptureIndex );
01321 
01322   DEBUG(DEB_LEV_FULL_SEQ, "%s: mapbuf queue count [captured, total] = [%ld, %ld]\n", __func__,
01323               omx_camera_source_component_Private->sMapbufQueue.nBufCountCaptured,
01324               omx_camera_source_component_Private->sMapbufQueue.nBufCountTotal );
01325 
01326   /* Wait to sync buffer */
01327   if ( OMX_MAPBUFQUEUE_HASBUFWAITTOCAPTURE( omx_camera_source_component_Private->sMapbufQueue ) ) {
01328     
01329     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
01330     buf.memory = V4L2_MEMORY_MMAP;
01331 
01332     if (-1 == xioctl(omx_camera_source_component_Private->fdCam, VIDIOC_DQBUF, &buf)) {
01333       switch (errno) {
01334       case EAGAIN:
01335         return OMX_ErrorHardware;;
01336       case EIO:
01337         /* Could ignore EIO, see spec. */
01338         /* fall through */
01339 
01340       default:
01341         DEBUG(DEB_LEV_ERR,"In %s error VIDIOC_DQBUF\n",__func__);
01342         return OMX_ErrorHardware;;
01343       }
01344     }
01345 
01346     
01347     /* Generate time stamp for the new captured buffer */
01348     if ((err = camera_GenerateTimeStamp(omx_camera_source_component_Private)) != OMX_ErrorNone) {
01349       DEBUG(DEB_LEV_ERR, "%s: <ERROR> -- Generate time stamp failed!\n",__func__);
01350       goto EXIT;
01351     }
01352 
01353     OMX_MAPBUFQUEUE_ADDCAPTUREDBUF( omx_camera_source_component_Private->sMapbufQueue );
01354   }
01355 
01356   /* Try to send buffers */
01357   if ( OMX_MAPBUFQUEUE_HASBUFCAPTURED( omx_camera_source_component_Private->sMapbufQueue ) ) {
01358     camera_SendCapturedBuffers( omx_camera_source_component_Private );
01359   }
01360 
01361   /* Calculate waiting time */
01362   gettimeofday(&now, NULL);
01363   nCurTimeInMilliSec = ((OMX_U32)now.tv_sec) * 1000 + ((OMX_U32)now.tv_usec) / 1000;
01364   nTimeToWaitInMilliSec = (OMX_S32) (omx_camera_source_component_Private->nFrameIntervalInMilliSec -
01365                 (nCurTimeInMilliSec - omx_camera_source_component_Private->nLastCaptureTimeInMilliSec));
01366 
01367   DEBUG(DEB_LEV_FULL_SEQ, "%s: [current time, last capture time, time to wait]=[%lu, %lu, %ld]\n", __func__,
01368                 nCurTimeInMilliSec,omx_camera_source_component_Private->nLastCaptureTimeInMilliSec,nTimeToWaitInMilliSec);
01369 
01370   /* Wait some time according to frame rate */
01371   if ( nTimeToWaitInMilliSec > 0 ) {
01372     sleepTime.tv_sec = nTimeToWaitInMilliSec / 1000;
01373     sleepTime.tv_nsec = (nTimeToWaitInMilliSec % 1000) * 1000000;
01374     DEBUG(DEB_LEV_FULL_SEQ, "%s: Actually wait for %ld msec\n", __func__,
01375                 nTimeToWaitInMilliSec);
01376     nanosleep(&sleepTime, NULL);
01377   }
01378 
01379   /* record last capture time */
01380   gettimeofday(&now, NULL);
01381   omx_camera_source_component_Private->nLastCaptureTimeInMilliSec = ((OMX_U32)now.tv_sec) * 1000 + ((OMX_U32)now.tv_usec) / 1000;
01382 
01383   if ( OMX_MAPBUFQUEUE_GETBUFCOUNTCAPTURED( omx_camera_source_component_Private->sMapbufQueue ) >= OMX_MAPBUFQUEUE_GETMAXLEN( omx_camera_source_component_Private->sMapbufQueue ) / 2 &&
01384         OMX_MAPBUFQUEUE_ISFULL( omx_camera_source_component_Private->sMapbufQueue ) ) {
01385     /* Try to send otherwise drop the last captured buffer */
01386     camera_SendLastCapturedBuffer( omx_camera_source_component_Private );
01387     if ( OMX_MAPBUFQUEUE_ISFULL( omx_camera_source_component_Private->sMapbufQueue ) ) {
01388       /* If the mapbuf queue is still full, drop the last captured buffer */
01389       DEBUG(DEB_LEV_FULL_SEQ, "%s: Drop buffer [%ld]\n", __func__,
01390                 OMX_MAPBUFQUEUE_GETLASTBUFFER( omx_camera_source_component_Private->sMapbufQueue ));
01391       camera_DropLastCapturedBuffer( omx_camera_source_component_Private );
01392     }
01393   }
01394 
01395   /* Start to capture the next buffer */
01396   if ( !OMX_MAPBUFQUEUE_ISFULL( omx_camera_source_component_Private->sMapbufQueue ) ) {
01397     
01398     if (-1 == xioctl(omx_camera_source_component_Private->fdCam, VIDIOC_QBUF, &buf)) {
01399       DEBUG(DEB_LEV_ERR,"In %s error VIDIOC_DQBUF\n",__func__);
01400       err = OMX_ErrorHardware;
01401     }
01402 
01403     OMX_MAPBUFQUEUE_ENQUEUE( omx_camera_source_component_Private->sMapbufQueue );
01404   }
01405 
01406 EXIT:
01407   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
01408   return err;
01409 }
01410 
01411 /* Generate time stamp for the new captured buffer */
01412 static OMX_ERRORTYPE camera_GenerateTimeStamp(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private) {
01413   OMX_ERRORTYPE err = OMX_ErrorNone;  
01414   OMX_U32 nBufferIndex;
01415   struct timeval now;
01416   OMX_TICKS nCurrentWallTime;
01417   OMX_TICKS nTimeStamp;
01418 
01419   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01420 
01421   nBufferIndex = OMX_MAPBUFQUEUE_GETNEXTWAIT(omx_camera_source_component_Private->sMapbufQueue);
01422 
01423   gettimeofday(&now, NULL);
01424   nCurrentWallTime = (OMX_TICKS)(now.tv_sec * 1000000 + now.tv_usec);
01425 
01426   /* To protect nRefWallTime */
01427   pthread_mutex_lock(&omx_camera_source_component_Private->setconfig_mutex);
01428   nTimeStamp = nCurrentWallTime - omx_camera_source_component_Private->nRefWallTime;
01429   pthread_mutex_unlock(&omx_camera_source_component_Private->setconfig_mutex);
01430 
01431   OMX_MAPBUFQUEUE_SETTIMESTAMP(omx_camera_source_component_Private->sMapbufQueue, nBufferIndex, nTimeStamp);
01432 
01433   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
01434   return err;
01435 }
01436 
01437 /* Try to send captured buffers in mapbuf queue to each port.
01438  * Note: In this function, multiple buffers may be sent.
01439  */
01440 static OMX_ERRORTYPE camera_SendCapturedBuffers(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private) {
01441   omx_camera_source_component_PortType *port;
01442   OMX_U32 nBufferCountCur = 0;
01443   OMX_ERRORTYPE err = OMX_ErrorNone;  
01444   OMX_S32 nPortIndex;
01445 
01446   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01447 
01448   for (nPortIndex = OMX_CAMPORT_INDEX_CP; nPortIndex >= OMX_CAMPORT_INDEX_VF; nPortIndex--) {
01449     DEBUG(DEB_LEV_FULL_SEQ, "%s: try to send buffers to port [%ld]\n", __func__, nPortIndex);
01450     port = (omx_camera_source_component_PortType *) omx_camera_source_component_Private->ports[nPortIndex];
01451     if (PORT_IS_ENABLED(port) &&
01452          (omx_camera_source_component_Private->bCapturing || OMX_CAMPORT_INDEX_CP != nPortIndex)) {
01453       nBufferCountCur = port->pBufferSem->semval;
01454       DEBUG(DEB_LEV_FULL_SEQ, "%s: port [%ld] nBufferCountCur = %ld\n", __func__, nPortIndex, nBufferCountCur);
01455       DEBUG(DEB_LEV_FULL_SEQ, "%s: port [%ld] nIndexMapbufQueue = %ld\n", __func__, nPortIndex, port->nIndexMapbufQueue);
01456       DEBUG(DEB_LEV_FULL_SEQ, "%s: Before returning buffers, mapbuf queue index [last, wait, capture] = [%ld, %ld, %ld]\n", __func__,
01457                   omx_camera_source_component_Private->sMapbufQueue.nLastBufIndex,
01458                   omx_camera_source_component_Private->sMapbufQueue.nNextWaitIndex,
01459                   omx_camera_source_component_Private->sMapbufQueue.nNextCaptureIndex );
01460 
01461       while(nBufferCountCur > 0 &&
01462                 (port->nIndexMapbufQueue != OMX_MAPBUFQUEUE_GETNEXTWAIT( omx_camera_source_component_Private->sMapbufQueue ) ||
01463                   (OMX_MAPBUFQUEUE_ISFULL( omx_camera_source_component_Private->sMapbufQueue ) &&
01464                    OMX_MAPBUFQUEUE_NOBUFWAITTOCAPTURE( omx_camera_source_component_Private->sMapbufQueue)
01465                   )
01466                 )
01467               ) {
01468         DEBUG(DEB_LEV_FULL_SEQ, "%s: port [%ld] nBufferCountCur = %ld\n", __func__, nPortIndex, nBufferCountCur);
01469         camera_ProcessPortOneBuffer( omx_camera_source_component_Private, (OMX_U32) nPortIndex );
01470 
01471         port->nIndexMapbufQueue = OMX_MAPBUFQUEUE_GETNEXTINDEX( omx_camera_source_component_Private->sMapbufQueue,
01472                                                      port->nIndexMapbufQueue );
01473         nBufferCountCur--;
01474       }
01475     }
01476  }
01477 
01478   err = camera_UpdateCapturedBufferQueue( omx_camera_source_component_Private );
01479 
01480   DEBUG(DEB_LEV_FULL_SEQ, "%s: After returning buffers, mapbuf queue index [last, wait, capture] = [%ld, %ld, %ld]\n", __func__,
01481               omx_camera_source_component_Private->sMapbufQueue.nLastBufIndex,
01482               omx_camera_source_component_Private->sMapbufQueue.nNextWaitIndex,
01483               omx_camera_source_component_Private->sMapbufQueue.nNextCaptureIndex );
01484 
01485   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
01486   return err;
01487 }
01488 
01489 /* Try to send the last captured buffer in mapbuf queue to each port.
01490  * Note: In this function, only ONE buffer be sent.
01491  */
01492 static OMX_ERRORTYPE camera_SendLastCapturedBuffer(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private) {
01493   omx_camera_source_component_PortType *port;
01494   OMX_U32 nBufferCountCur = 0;
01495   OMX_ERRORTYPE err = OMX_ErrorNone;  
01496   OMX_S32 nPortIndex;
01497 
01498   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01499 
01500   for (nPortIndex = OMX_CAMPORT_INDEX_CP; nPortIndex >= OMX_CAMPORT_INDEX_VF; nPortIndex--) {
01501     DEBUG(DEB_LEV_FULL_SEQ, "%s: try to send buffers to port [%ld]\n", __func__, nPortIndex);
01502     port = (omx_camera_source_component_PortType *) omx_camera_source_component_Private->ports[nPortIndex];
01503     if (PORT_IS_ENABLED(port) &&
01504          (omx_camera_source_component_Private->bCapturing || OMX_CAMPORT_INDEX_CP != nPortIndex)) {
01505       nBufferCountCur = port->pBufferSem->semval;
01506       DEBUG(DEB_LEV_FULL_SEQ, "%s: port [%ld] nBufferCountCur = %ld\n", __func__, nPortIndex, nBufferCountCur);
01507       DEBUG(DEB_LEV_FULL_SEQ, "%s: port [%ld] nIndexMapbufQueue = %ld\n", __func__, nPortIndex, port->nIndexMapbufQueue);
01508       DEBUG(DEB_LEV_FULL_SEQ, "%s: Before returning buffers, mapbuf queue index [last, wait, capture] = [%ld, %ld, %ld]\n", __func__,
01509                   omx_camera_source_component_Private->sMapbufQueue.nLastBufIndex,
01510                   omx_camera_source_component_Private->sMapbufQueue.nNextWaitIndex,
01511                   omx_camera_source_component_Private->sMapbufQueue.nNextCaptureIndex );
01512 
01513       if(nBufferCountCur > 0 &&
01514           port->nIndexMapbufQueue == OMX_MAPBUFQUEUE_GETLASTBUFFER( omx_camera_source_component_Private->sMapbufQueue)) {
01515         DEBUG(DEB_LEV_FULL_SEQ, "%s: port [%ld] nBufferCountCur = %ld\n", __func__, nPortIndex, nBufferCountCur);
01516         camera_ProcessPortOneBuffer( omx_camera_source_component_Private, (OMX_U32) nPortIndex );
01517 
01518         port->nIndexMapbufQueue = OMX_MAPBUFQUEUE_GETNEXTINDEX( omx_camera_source_component_Private->sMapbufQueue,
01519                                                      port->nIndexMapbufQueue );
01520       }
01521     }
01522  }
01523 
01524   err = camera_UpdateCapturedBufferQueue( omx_camera_source_component_Private );
01525 
01526   DEBUG(DEB_LEV_FULL_SEQ, "%s: After returning buffers, mapbuf queue index [last, wait, capture] = [%ld, %ld, %ld]\n", __func__,
01527               omx_camera_source_component_Private->sMapbufQueue.nLastBufIndex,
01528               omx_camera_source_component_Private->sMapbufQueue.nNextWaitIndex,
01529               omx_camera_source_component_Private->sMapbufQueue.nNextCaptureIndex );
01530 
01531   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
01532   return err;
01533 }
01534 
01535 
01536 /* Update captured buffer queue in mapbuf queue */
01537 static OMX_ERRORTYPE camera_UpdateCapturedBufferQueue(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private) {
01538   omx_camera_source_component_PortType *pPreviewPort = (omx_camera_source_component_PortType *)omx_camera_source_component_Private->ports[OMX_CAMPORT_INDEX_VF];
01539   omx_camera_source_component_PortType *pCapturePort = (omx_camera_source_component_PortType *)omx_camera_source_component_Private->ports[OMX_CAMPORT_INDEX_CP];
01540   OMX_ERRORTYPE err = OMX_ErrorNone;  
01541 
01542   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01543 
01544   while ( OMX_MAPBUFQUEUE_HASBUFCAPTURED( omx_camera_source_component_Private->sMapbufQueue ) ) {
01545     if (PORT_IS_ENABLED(pPreviewPort) &&
01546          pPreviewPort->nIndexMapbufQueue == OMX_MAPBUFQUEUE_GETLASTBUFFER( omx_camera_source_component_Private->sMapbufQueue ) ) {
01547       break;
01548     }
01549 
01550     if (PORT_IS_ENABLED(pCapturePort) && omx_camera_source_component_Private->bCapturing &&
01551          pCapturePort->nIndexMapbufQueue == OMX_MAPBUFQUEUE_GETLASTBUFFER( omx_camera_source_component_Private->sMapbufQueue ) ) {
01552       break;
01553     }
01554 
01555     OMX_MAPBUFQUEUE_DEQUEUE( omx_camera_source_component_Private->sMapbufQueue );
01556   }
01557 
01558   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
01559   return err;
01560 }
01561 
01562 /* Process one buffer on the specified port */
01563 static OMX_ERRORTYPE camera_ProcessPortOneBuffer(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private,  OMX_IN OMX_U32 nPortIndex ) {
01564   omx_camera_source_component_PortType *port = (omx_camera_source_component_PortType *)omx_camera_source_component_Private->ports[nPortIndex];
01565   OMX_BUFFERHEADERTYPE* pBufHeader = NULL;
01566   OMX_BOOL bStrideAlign = OMX_FALSE;
01567   OMX_ERRORTYPE err = OMX_ErrorNone;  
01568 
01569   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01570 
01571   /* If buffer queue is not empty */
01572   if (port->pBufferSem->semval > 0) {
01573     /* Dequeue a buffer from buffer queue */
01574     tsem_down(port->pBufferSem);
01575     pBufHeader = dequeue(port->pBufferQueue);
01576     if(pBufHeader == NULL){
01577       DEBUG(DEB_LEV_ERR, "%s: <ERROR> --Had NULL buffer from port [%ld]!!\n", __func__, nPortIndex);
01578       err = OMX_ErrorBadParameter;
01579       goto EXIT;
01580     }
01581 
01582     if ( OMX_CAMPORT_INDEX_CP == nPortIndex ) {
01583       if ( OMX_FALSE == omx_camera_source_component_Private->sSensorMode.bOneShot ) {
01584         /* Video capture use case */
01585         if ((err = camera_AddTimeStamp(omx_camera_source_component_Private, pBufHeader)) != OMX_ErrorNone) {
01586           goto EXIT;
01587         }
01588 
01589         if ((err = camera_UpdateThumbnailCondition( omx_camera_source_component_Private )) != OMX_ErrorNone ) {
01590           goto EXIT;
01591         }
01592       }
01593       else {
01594         /* Still image capture use case */
01595         if ( (err = camera_HandleStillImageCapture( omx_camera_source_component_Private )) != OMX_ErrorNone ) {
01596           goto EXIT;
01597         }
01598       }
01599 
01600       if ( OMX_TRUE == omx_camera_source_component_Private->bThumbnailStart ) {
01601         /* Handle thumbnail image capture */
01602         if ( (err = camera_HandleThumbnailCapture( omx_camera_source_component_Private )) != OMX_ErrorNone ) {
01603           goto EXIT;
01604         }
01605       }
01606     }
01607 
01608     /* Translate color format and frame size */
01609     err = camera_ReformatVideoFrame( (OMX_PTR) OMX_MAPBUFQUEUE_GETBUFADDR(
01610                                                            omx_camera_source_component_Private->sMapbufQueue,
01611                                                            port->nIndexMapbufQueue  ),
01612                                                          omx_camera_source_component_Private->sSensorMode.sFrameSize.nWidth,
01613                                                          omx_camera_source_component_Private->sSensorMode.sFrameSize.nHeight,
01614                                                          omx_camera_source_component_Private->sV4lColorFormat,
01615                                                          (OMX_PTR) (pBufHeader->pBuffer + pBufHeader->nOffset),
01616                                                          port->sPortParam.format.video.nFrameWidth,
01617                                                          port->sPortParam.format.video.nFrameHeight,
01618                                                          port->sPortParam.format.video.nStride,
01619                                                          port->sPortParam.format.video.eColorFormat,
01620                                                          bStrideAlign );
01621 
01622     if ( err != OMX_ErrorNone ) {
01623       goto EXIT;
01624     }
01625 
01626     /* Return buffer */
01627     pBufHeader->nFilledLen = omx_camera_source_component_Private->oFrameSize;
01628     DEBUG(DEB_LEV_FULL_SEQ, "%s: return buffer [%ld] on port [%ld]: nFilledLen = %ld\n", __func__,
01629                 port->nIndexMapbufQueue, nPortIndex, pBufHeader->nFilledLen);
01630     port->ReturnBufferFunction((omx_base_PortType *)port, pBufHeader);
01631   }
01632 
01633 EXIT:
01634   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
01635   return err;
01636 }
01637 
01638 /* Drop the last captured buffer in mapbuf queue */
01639 static OMX_ERRORTYPE camera_DropLastCapturedBuffer(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private) {
01640   omx_camera_source_component_PortType *port;
01641   OMX_U32 i = 0;
01642   OMX_ERRORTYPE err = OMX_ErrorNone;  
01643 
01644   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01645 
01646   for ( i = OMX_CAMPORT_INDEX_VF; i <= OMX_CAMPORT_INDEX_CP; i++ ) {
01647     port = (omx_camera_source_component_PortType *) omx_camera_source_component_Private->ports[i];
01648     if ( PORT_IS_ENABLED( port ) &&
01649          port->nIndexMapbufQueue == OMX_MAPBUFQUEUE_GETLASTBUFFER(
01650          omx_camera_source_component_Private->sMapbufQueue ) ) {
01651       if ( OMX_CAMPORT_INDEX_CP != i || omx_camera_source_component_Private->bCapturing ) {
01652         port->nIndexMapbufQueue = OMX_MAPBUFQUEUE_GETNEXTINDEX( omx_camera_source_component_Private->sMapbufQueue,
01653                                                                             port->nIndexMapbufQueue );
01654       }
01655     }
01656   }
01657 
01658   OMX_MAPBUFQUEUE_DEQUEUE( omx_camera_source_component_Private->sMapbufQueue );
01659 
01660   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
01661   return err;
01662 }
01663 
01664 /* Reformat one frame in terms of frame size and color format from source to destination address.
01665  * Note: This function is currently implemented as a simple memory copy, because the color conversion
01666  * and image resizing can be performed by a color conversion component that is tunneled with the
01667  * camera component.
01668  */
01669 static OMX_ERRORTYPE camera_ReformatVideoFrame(
01670                                                     OMX_IN OMX_PTR pSrcFrameAddr,
01671                                                     OMX_IN OMX_U32 nSrcFrameWidth,
01672                                                     OMX_IN OMX_U32 nSrcFrameHeight,
01673                                                     OMX_IN V4L2_COLOR_FORMATTYPE sSrcV4l2ColorFormat,
01674                                                     OMX_IN OMX_PTR pDstFrameAddr,
01675                                                     OMX_IN OMX_U32 nDstFrameWidth,
01676                                                     OMX_IN OMX_U32 nDstFrameHeight,
01677                                                     OMX_IN OMX_S32 nDstFrameStride,
01678                                                     OMX_IN OMX_COLOR_FORMATTYPE eDstOmxColorFormat,
01679                                                     OMX_IN OMX_BOOL bStrideAlign ) {
01680   OMX_COLOR_FORMATTYPE eSrcOmxColorFormat;
01681   OMX_ERRORTYPE err = OMX_ErrorNone;  
01682 
01683   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01684 
01685   if ( (err = camera_MapColorFormatV4lToOmx( &sSrcV4l2ColorFormat,
01686          &eSrcOmxColorFormat )) != OMX_ErrorNone ) {
01687     DEBUG(DEB_LEV_ERR, "%s: <ERROR> -- Unsupported V4L2 color format (palette, depth) = (%d, %d)\n",__func__,sSrcV4l2ColorFormat.v4l2Pixfmt, sSrcV4l2ColorFormat.v4l2Depth);
01688     goto EXIT;
01689   }
01690 
01691   DEBUG(DEB_LEV_FULL_SEQ, "%s: src (width, height, color)=(%ld,%ld,%d)\n", __func__, nSrcFrameWidth, nSrcFrameHeight, eSrcOmxColorFormat);
01692   DEBUG(DEB_LEV_FULL_SEQ, "%s: dst (width, height, stride, color)=(%ld,%ld,%ld,%d)\n", __func__, nDstFrameWidth, nDstFrameHeight, nDstFrameStride, eDstOmxColorFormat);
01693 
01694   /* Now the camera does not support color conversion and frame resize;
01695      To do this job, Pls resort to a color conversion component */
01696   if (nSrcFrameWidth != nDstFrameWidth ||
01697        nSrcFrameHeight != nDstFrameHeight ||
01698        eSrcOmxColorFormat != eDstOmxColorFormat) {
01699     err = OMX_ErrorUnsupportedSetting;
01700     goto EXIT;
01701   }
01702 
01703   memcpy(pDstFrameAddr, pSrcFrameAddr, camera_CalculateBufferSize(nSrcFrameWidth, nSrcFrameHeight, eSrcOmxColorFormat));
01704 
01705 EXIT:
01706   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
01707   return err;
01708 }
01709 
01710 /* Add time stamp to a buffer header */
01711 static OMX_ERRORTYPE camera_AddTimeStamp(
01712   OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private,
01713   OMX_IN OMX_BUFFERHEADERTYPE *pBufHeader) {
01714   omx_camera_source_component_PortType *pCapturePort = (omx_camera_source_component_PortType *)omx_camera_source_component_Private->ports[OMX_CAMPORT_INDEX_CP];
01715   OMX_ERRORTYPE err = OMX_ErrorNone;  
01716 
01717   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01718 
01719   if (omx_camera_source_component_Private->bIsFirstFrame ) {
01720     pBufHeader->nFlags = OMX_BUFFERFLAG_STARTTIME;
01721     omx_camera_source_component_Private->bIsFirstFrame = OMX_FALSE;
01722     DEBUG(DEB_LEV_SIMPLE_SEQ, "%s: Set StartTime Flag!\n",__func__);
01723   }
01724   else {
01725     pBufHeader->nFlags = 0;
01726   }
01727 
01728   pBufHeader->nTimeStamp = OMX_MAPBUFQUEUE_GETTIMESTAMP(omx_camera_source_component_Private->sMapbufQueue, pCapturePort->nIndexMapbufQueue);
01729 
01730   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
01731   return err;
01732 }
01733 
01734 /* Update the condition for thumbnail to occur */
01735 static OMX_ERRORTYPE camera_UpdateThumbnailCondition(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private) {
01736   omx_camera_source_component_PortType *pThumbnailPort = (omx_camera_source_component_PortType *)omx_camera_source_component_Private->ports[OMX_CAMPORT_INDEX_CP_T];
01737   OMX_ERRORTYPE err = OMX_ErrorNone;  
01738 
01739   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01740 
01741   if ( OMX_FALSE == omx_camera_source_component_Private->sSensorMode.bOneShot ) {
01742     if ( omx_camera_source_component_Private->nCapturedCount < (OMX_CAM_VC_SNAPSHOT_INDEX + 1) ) {
01743       omx_camera_source_component_Private->nCapturedCount++;
01744     }
01745 
01746     if ( PORT_IS_ENABLED(pThumbnailPort) &&
01747          OMX_CAM_VC_SNAPSHOT_INDEX == omx_camera_source_component_Private->nCapturedCount ) {
01748       omx_camera_source_component_Private->bThumbnailStart = OMX_TRUE;
01749     }
01750   }
01751 
01752   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
01753   return err;
01754 }
01755 
01756 /* Handle still image capture use case */
01757 static OMX_ERRORTYPE camera_HandleStillImageCapture(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private) {
01758   omx_camera_source_component_PortType *pThumbnailPort = (omx_camera_source_component_PortType *)omx_camera_source_component_Private->ports[OMX_CAMPORT_INDEX_CP_T];
01759   OMX_ERRORTYPE err = OMX_ErrorNone;  
01760 
01761   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01762 
01763   pthread_mutex_lock(&omx_camera_source_component_Private->setconfig_mutex);
01764   omx_camera_source_component_Private->bIsFirstFrame = OMX_FALSE;
01765   omx_camera_source_component_Private->bCapturingNext = OMX_FALSE;
01766   if ( PORT_IS_ENABLED(pThumbnailPort)  ) {
01767     omx_camera_source_component_Private->bThumbnailStart = OMX_TRUE;
01768   }
01769 
01770   if (omx_camera_source_component_Private->bAutoPause) {
01771     /* In autopause mode, command camera component to pause state */
01772     if ((err = omx_camera_source_component_DoStateSet(omx_camera_source_component_Private->openmaxStandComp,
01773                    (OMX_U32)OMX_StatePause)) != OMX_ErrorNone ) {
01774       goto EXIT;
01775     }
01776   }
01777 
01778 EXIT:
01779   pthread_mutex_unlock(&omx_camera_source_component_Private->setconfig_mutex);
01780   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
01781   return err;
01782 }
01783 
01784 /* Handle thumbnail image capture */
01785 static OMX_ERRORTYPE camera_HandleThumbnailCapture(OMX_IN omx_camera_source_component_PrivateType *omx_camera_source_component_Private) {
01786   omx_camera_source_component_PortType *pThumbnailPort = (omx_camera_source_component_PortType *)omx_camera_source_component_Private->ports[OMX_CAMPORT_INDEX_CP_T];
01787   OMX_BUFFERHEADERTYPE* pBufHeader = NULL;
01788   OMX_ERRORTYPE err = OMX_ErrorNone;  
01789   OMX_BOOL bStrideAlign = OMX_FALSE;
01790 
01791   DEBUG(DEB_LEV_FUNCTION_NAME, "In %s for camera component\n",__func__);
01792 
01793   omx_camera_source_component_Private->bThumbnailStart = OMX_FALSE;
01794 
01795   /* If buffer queue on thumbnail port is not empty */
01796   if (pThumbnailPort->pBufferSem->semval > 0) {
01797     /* Dequeue a buffer from buffer queue */
01798     tsem_down(pThumbnailPort->pBufferSem);
01799     pBufHeader = dequeue(pThumbnailPort->pBufferQueue);
01800     if(pBufHeader == NULL){
01801       DEBUG(DEB_LEV_ERR, "%s: <ERROR> --Had NULL buffer from thumbnail port!!\n", __func__);
01802       err = OMX_ErrorBadParameter;
01803       goto EXIT;
01804     }
01805 
01806     /* Determine the buffer for thumbnail */
01807     while (OMX_MAPBUFQUEUE_GETNEXTINDEX( omx_camera_source_component_Private->sMapbufQueue,
01808                pThumbnailPort->nIndexMapbufQueue ) != OMX_MAPBUFQUEUE_GETNEXTWAIT( omx_camera_source_component_Private->sMapbufQueue )
01809              ) {
01810       pThumbnailPort->nIndexMapbufQueue =
01811               OMX_MAPBUFQUEUE_GETNEXTINDEX( omx_camera_source_component_Private->sMapbufQueue,pThumbnailPort->nIndexMapbufQueue );
01812     }
01813 
01814     /* Translate color format and frame size */
01815     err = camera_ReformatVideoFrame( (OMX_PTR) OMX_MAPBUFQUEUE_GETBUFADDR(
01816                                                            omx_camera_source_component_Private->sMapbufQueue,
01817                                                            pThumbnailPort->nIndexMapbufQueue ),
01818                                                          omx_camera_source_component_Private->sSensorMode.sFrameSize.nWidth,
01819                                                          omx_camera_source_component_Private->sSensorMode.sFrameSize.nHeight,
01820                                                          omx_camera_source_component_Private->sV4lColorFormat,
01821                                                          (OMX_PTR) (pBufHeader->pBuffer + pBufHeader->nOffset),
01822                                                          pThumbnailPort->sPortParam.format.video.nFrameWidth,
01823                                                          pThumbnailPort->sPortParam.format.video.nFrameHeight,
01824                                                          pThumbnailPort->sPortParam.format.video.nStride,
01825                                                          pThumbnailPort->sPortParam.format.video.eColorFormat,
01826                                                          bStrideAlign );
01827 
01828     if ( err != OMX_ErrorNone ) {
01829       goto EXIT;
01830     }
01831 
01832     /* Return buffer */
01833     pBufHeader->nFilledLen = omx_camera_source_component_Private->oFrameSize;
01834     DEBUG(DEB_LEV_FULL_SEQ, "%s: return buffer [%ld] on thumbnail port: nFilledLen = %ld\n", __func__,
01835                 pThumbnailPort->nIndexMapbufQueue, pBufHeader->nFilledLen);
01836     pThumbnailPort->ReturnBufferFunction((omx_base_PortType *)pThumbnailPort, pBufHeader);
01837   }
01838 
01839 EXIT:
01840   DEBUG(DEB_LEV_FUNCTION_NAME, "Out of %s for camera component, return code: 0x%X\n",__func__, err);
01841   return err;
01842 }
01843 
01844 static int camera_init_mmap(omx_camera_source_component_PrivateType* omx_camera_source_component_Private)
01845 {
01846   struct v4l2_requestbuffers req;
01847   OMX_U32 i;
01848 
01849   CLEAR(req);
01850 
01851   req.count = 4;
01852   req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
01853   req.memory = V4L2_MEMORY_MMAP;
01854 
01855   if (-1 == xioctl(omx_camera_source_component_Private->fdCam, VIDIOC_REQBUFS, &req)) {
01856     if (EINVAL == errno) {
01857       DEBUG(DEB_LEV_ERR, "%s does not support "
01858         "memory mapping\n", V4L2DEV_FILENAME);
01859       return OMX_ErrorHardware;
01860     } else {
01861       DEBUG(DEB_LEV_ERR, "%s error %d, %s\n", "VIDIOC_REQBUFS", errno, strerror(errno));
01862       return OMX_ErrorHardware;
01863     }
01864   }
01865 
01866   if (req.count < 2) {
01867     DEBUG(DEB_LEV_ERR, "Insufficient buffer memory on %s\n", V4L2DEV_FILENAME);
01868     return OMX_ErrorHardware;
01869   }
01870 
01871   omx_camera_source_component_Private->sMapbufQueue.nFrame = req.count;
01872 
01873   omx_camera_source_component_Private->sMapbufQueue.buffers = calloc(req.count, sizeof(*omx_camera_source_component_Private->sMapbufQueue.buffers));
01874 
01875   if (!omx_camera_source_component_Private->sMapbufQueue.buffers) {
01876     DEBUG(DEB_LEV_ERR,"Out of memory\n");
01877     return OMX_ErrorHardware;
01878   }
01879 
01880   for (i = 0; i < req.count; ++i) {
01881     struct v4l2_buffer buf;
01882 
01883     CLEAR(buf);
01884 
01885     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
01886     buf.memory = V4L2_MEMORY_MMAP;
01887     buf.index = i;
01888 
01889     if (-1 == xioctl(omx_camera_source_component_Private->fdCam, VIDIOC_QUERYBUF, &buf)) {
01890       DEBUG(DEB_LEV_ERR, "%s error %d, %s\n", "VIDIOC_QUERYBUF", errno, strerror(errno));
01891       return OMX_ErrorHardware;
01892     }
01893 
01894     omx_camera_source_component_Private->sMapbufQueue.buffers[i].length = buf.length;
01895     omx_camera_source_component_Private->sMapbufQueue.buffers[i].pCapAddrStart = mmap(NULL /* start anywhere */ ,
01896             buf.length,
01897             PROT_READ | PROT_WRITE /* required */ ,
01898             MAP_SHARED /* recommended */ ,
01899             omx_camera_source_component_Private->fdCam, buf.m.offset);
01900 
01901     if (MAP_FAILED == omx_camera_source_component_Private->sMapbufQueue.buffers[i].pCapAddrStart) {
01902       DEBUG(DEB_LEV_ERR, "%s error %d, %s\n", "mmap", errno, strerror(errno));
01903       return OMX_ErrorHardware;
01904     }
01905 
01906     DEBUG(DEB_LEV_PARAMS, "i=%d,addr=%x,length=%d\n",(int)i,
01907       (int)omx_camera_source_component_Private->sMapbufQueue.buffers[i].pCapAddrStart, 
01908       (int)omx_camera_source_component_Private->sMapbufQueue.buffers[i].length);
01909   }
01910 
01911   return OMX_ErrorNone;
01912 }
01913 

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