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
00053 #define OMX_CAM_VC_SNAPSHOT_INDEX 5
00054
00055 #define CLEAR(x) memset (&(x), 0, sizeof (x))
00056
00057
00058
00059
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
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
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
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
00268 return OMX_ErrorUnsupportedSetting;
00269 }
00270
00271
00272
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
00288 return OMX_ErrorUnsupportedSetting;
00289 }
00290
00291
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
00305 return OMX_ErrorUnsupportedSetting;
00306 }
00307
00308
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
00323 return OMX_ErrorUnsupportedSetting;
00324 }
00325
00326
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
00340 return 0;
00341 }
00342
00343
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
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
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
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
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
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
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;
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
00436 break;
00437 default:
00438
00439 break;
00440 }
00441 }
00442
00443 CLEAR(omx_camera_source_component_Private->fmt);
00444
00445
00446 camera_init_mmap(omx_camera_source_component_Private);
00447
00448
00449
00450
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
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
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
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
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;
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
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
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
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
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
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
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
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
00654 i = OMX_MAPBUFQUEUE_GETNEXTWAIT( omx_camera_source_component_Private->sMapbufQueue );
00655
00656 while ( OMX_MAPBUFQUEUE_HASBUFWAITTOCAPTURE( omx_camera_source_component_Private->sMapbufQueue ) ) {
00657
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
00680 OMX_MAPBUFQUEUE_MAKEEMPTY( omx_camera_source_component_Private->sMapbufQueue );
00681
00682
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
00720 omx_camera_source_component_Private = (omx_camera_source_component_PrivateType *)openmaxStandComp->pComponentPrivate;
00721 err = omx_base_source_Constructor(openmaxStandComp, cComponentName);
00722
00723
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;
00739 omx_camera_source_component_Private->sSensorMode.bOneShot = OMX_FALSE;
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
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
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
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
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
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:
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
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:
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
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
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
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
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
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
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
01338
01339
01340 default:
01341 DEBUG(DEB_LEV_ERR,"In %s error VIDIOC_DQBUF\n",__func__);
01342 return OMX_ErrorHardware;;
01343 }
01344 }
01345
01346
01347
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
01357 if ( OMX_MAPBUFQUEUE_HASBUFCAPTURED( omx_camera_source_component_Private->sMapbufQueue ) ) {
01358 camera_SendCapturedBuffers( omx_camera_source_component_Private );
01359 }
01360
01361
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
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
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
01386 camera_SendLastCapturedBuffer( omx_camera_source_component_Private );
01387 if ( OMX_MAPBUFQUEUE_ISFULL( omx_camera_source_component_Private->sMapbufQueue ) ) {
01388
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
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
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
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
01438
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
01490
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
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
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
01572 if (port->pBufferSem->semval > 0) {
01573
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
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
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
01602 if ( (err = camera_HandleThumbnailCapture( omx_camera_source_component_Private )) != OMX_ErrorNone ) {
01603 goto EXIT;
01604 }
01605 }
01606 }
01607
01608
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
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
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
01665
01666
01667
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
01695
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
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
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
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
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
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
01796 if (pThumbnailPort->pBufferSem->semval > 0) {
01797
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
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
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
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 ,
01896 buf.length,
01897 PROT_READ | PROT_WRITE ,
01898 MAP_SHARED ,
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