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