diff options
author | Tyler Luu <tluu@ti.com> | 2011-10-18 19:52:30 -0500 |
---|---|---|
committer | Iliyan Malchev <malchev@google.com> | 2011-11-22 09:30:52 -0800 |
commit | ef73bec8a83a2fd7fbb072d009382c64eb2da0ee (patch) | |
tree | 4d667494f2c4f399343824e34f970bea973fa4ed /camera/OMXCameraAdapter | |
parent | 7bf511bf46760898e1429f38754821fff6287585 (diff) | |
download | hardware_ti_omap4xxx-ef73bec8a83a2fd7fbb072d009382c64eb2da0ee.zip hardware_ti_omap4xxx-ef73bec8a83a2fd7fbb072d009382c64eb2da0ee.tar.gz hardware_ti_omap4xxx-ef73bec8a83a2fd7fbb072d009382c64eb2da0ee.tar.bz2 |
CameraHal: Add more Exif data for video snapshot
Fixes b/5582076. Requires changes to Ducati and external/jhead.
1. Add API to get and set ancillary data metadata so
we can use the values to fill in Exif data.
2. Add support for additional tags.
Change-Id: I537e683839c59e92a4a20ff62653b6d46e303f53
Signed-off-by: Tyler Luu <tluu@ti.com>
Signed-off-by: Iliyan Malchev <malchev@google.com>
Diffstat (limited to 'camera/OMXCameraAdapter')
-rwxr-xr-x | camera/OMXCameraAdapter/OMXCameraAdapter.cpp | 60 | ||||
-rw-r--r-- | camera/OMXCameraAdapter/OMXCapture.cpp | 14 | ||||
-rwxr-xr-x | camera/OMXCameraAdapter/OMXExif.cpp | 128 | ||||
-rw-r--r-- | camera/OMXCameraAdapter/OMXFD.cpp | 23 |
4 files changed, 190 insertions, 35 deletions
diff --git a/camera/OMXCameraAdapter/OMXCameraAdapter.cpp b/camera/OMXCameraAdapter/OMXCameraAdapter.cpp index 01d37ea..c5dff6c 100755 --- a/camera/OMXCameraAdapter/OMXCameraAdapter.cpp +++ b/camera/OMXCameraAdapter/OMXCameraAdapter.cpp @@ -1757,7 +1757,6 @@ status_t OMXCameraAdapter::startPreview() OMX_ERRORTYPE eError = OMX_ErrorNone; OMXCameraPortParameters *mPreviewData = NULL; OMXCameraPortParameters *measurementData = NULL; - OMX_CONFIG_EXTRADATATYPE extraDataControl; LOG_FUNCTION_NAME; @@ -1869,15 +1868,7 @@ status_t OMXCameraAdapter::startPreview() // whether the preview frame is a snapshot if ( OMX_ErrorNone == eError) { - OMX_INIT_STRUCT_PTR (&extraDataControl, OMX_CONFIG_EXTRADATATYPE); - extraDataControl.nPortIndex = OMX_ALL; - extraDataControl.eExtraDataType = OMX_AncillaryData; - extraDataControl.bEnable = OMX_TRUE; - - eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, - ( OMX_INDEXTYPE ) OMX_IndexConfigOtherExtraDataControl, - &extraDataControl); - GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); + ret = setExtraData(true, OMX_ALL, OMX_AncillaryData); } @@ -2918,7 +2909,7 @@ OMX_ERRORTYPE OMXCameraAdapter::OMXCameraAdapterFillBufferDone(OMX_IN OMX_HANDLE CameraFrame cameraFrame; OMX_TI_PLATFORMPRIVATE *platformPrivate; OMX_OTHER_EXTRADATATYPE *extraData; - OMX_TI_ANCILLARYDATATYPE *ancillaryData; + OMX_TI_ANCILLARYDATATYPE *ancillaryData = NULL; bool snapshotFrame = false; res1 = res2 = NO_ERROR; @@ -2951,7 +2942,6 @@ OMX_ERRORTYPE OMXCameraAdapter::OMXCameraAdapterFillBufferDone(OMX_IN OMX_HANDLE } recalculateFPS(); - { Mutex::Autolock lock(mFaceDetectionLock); if ( mFaceDetectionRunning && !mFaceDetectionPaused ) { @@ -2977,6 +2967,16 @@ OMX_ERRORTYPE OMXCameraAdapter::OMXCameraAdapterFillBufferDone(OMX_IN OMX_HANDLE { typeOfFrame = CameraFrame::SNAPSHOT_FRAME; mask = (unsigned int)CameraFrame::SNAPSHOT_FRAME; + + // video snapshot gets ancillary data and wb info from last snapshot frame + mCaptureAncillaryData = ancillaryData; + mWhiteBalanceData = NULL; + extraData = getExtradata((OMX_OTHER_EXTRADATATYPE*) platformPrivate->pMetaDataBuffer, + (OMX_EXTRADATATYPE) OMX_WhiteBalance); + if ( NULL != extraData ) + { + mWhiteBalanceData = (OMX_TI_WHITEBALANCERESULTTYPE*) extraData->data; + } } else { @@ -3063,7 +3063,7 @@ OMX_ERRORTYPE OMXCameraAdapter::OMXCameraAdapterFillBufferDone(OMX_IN OMX_HANDLE // populate exif data and pass to subscribers via quirk // subscriber is in charge of freeing exif data ExifElementsTable* exif = new ExifElementsTable(); - setupEXIF_libjpeg(exif); + setupEXIF_libjpeg(exif, mCaptureAncillaryData, mWhiteBalanceData); cameraFrame.mQuirks |= CameraFrame::HAS_EXIF_DATA; cameraFrame.mCookie2 = (void*) exif; } @@ -3380,6 +3380,40 @@ bool OMXCameraAdapter::OMXCallbackHandler::Handler() return false; } +status_t OMXCameraAdapter::setExtraData(bool enable, OMX_U32 nPortIndex, OMX_EXT_EXTRADATATYPE eType) { + status_t ret = NO_ERROR; + OMX_ERRORTYPE eError = OMX_ErrorNone; + OMX_CONFIG_EXTRADATATYPE extraDataControl; + + LOG_FUNCTION_NAME; + + if (OMX_StateInvalid == mComponentState) { + CAMHAL_LOGEA("OMX component is in invalid state"); + return -EINVAL; + } + + OMX_INIT_STRUCT_PTR (&extraDataControl, OMX_CONFIG_EXTRADATATYPE); + + extraDataControl.nPortIndex = nPortIndex; + extraDataControl.eExtraDataType = eType; + extraDataControl.eCameraView = OMX_2D; + + if (enable) { + extraDataControl.bEnable = OMX_TRUE; + } else { + extraDataControl.bEnable = OMX_FALSE; + } + + eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, + (OMX_INDEXTYPE) OMX_IndexConfigOtherExtraDataControl, + &extraDataControl); + + LOG_FUNCTION_NAME_EXIT; + + return (ret | ErrorUtils::omxToAndroidError(eError)); +} + + OMX_OTHER_EXTRADATATYPE *OMXCameraAdapter::getExtradata(OMX_OTHER_EXTRADATATYPE *extraData, OMX_EXTRADATATYPE type) { if ( NULL != extraData ) diff --git a/camera/OMXCameraAdapter/OMXCapture.cpp b/camera/OMXCameraAdapter/OMXCapture.cpp index 9ba438c..43d0725 100644 --- a/camera/OMXCameraAdapter/OMXCapture.cpp +++ b/camera/OMXCameraAdapter/OMXCapture.cpp @@ -775,6 +775,12 @@ status_t OMXCameraAdapter::startImageCapture() } } + // need to enable wb data for video snapshot to fill in exif data + if ((ret == NO_ERROR) && (mCapMode == VIDEO_MODE)) { + // video snapshot uses wb data from snapshot frame + ret = setExtraData(true, mCameraAdapterParameters.mPrevPortIndex, OMX_WhiteBalance); + } + //OMX shutter callback events are only available in hq mode if ( (HIGH_QUALITY == mCapMode) || (HIGH_QUALITY_ZSL== mCapMode)) { @@ -866,6 +872,7 @@ status_t OMXCameraAdapter::startImageCapture() EXIT: CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError); + setExtraData(false, mCameraAdapterParameters.mPrevPortIndex, OMX_WhiteBalance); mWaitingForSnapshot = false; mCaptureSignalled = false; performCleanupAfterError(); @@ -945,6 +952,13 @@ status_t OMXCameraAdapter::stopImageCapture() goto EXIT; } } + + // had to enable wb data for video snapshot to fill in exif data + // now that we are done...disable + if ((ret == NO_ERROR) && (mCapMode == VIDEO_MODE)) { + ret = setExtraData(false, mCameraAdapterParameters.mPrevPortIndex, OMX_WhiteBalance); + } + CAMHAL_LOGDB("Capture set - 0x%x", eError); mCaptureSignalled = true; //set this to true if we exited because of timeout diff --git a/camera/OMXCameraAdapter/OMXExif.cpp b/camera/OMXCameraAdapter/OMXExif.cpp index 9744cf4..32bfd7d 100755 --- a/camera/OMXCameraAdapter/OMXExif.cpp +++ b/camera/OMXCameraAdapter/OMXExif.cpp @@ -497,7 +497,9 @@ status_t OMXCameraAdapter::setupEXIF() return ret; } -status_t OMXCameraAdapter::setupEXIF_libjpeg(ExifElementsTable* exifTable) +status_t OMXCameraAdapter::setupEXIF_libjpeg(ExifElementsTable* exifTable, + OMX_TI_ANCILLARYDATATYPE* pAncillaryData, + OMX_TI_WHITEBALANCERESULTTYPE* pWhiteBalanceData) { status_t ret = NO_ERROR; OMX_ERRORTYPE eError = OMX_ErrorNone; @@ -544,7 +546,6 @@ status_t OMXCameraAdapter::setupEXIF_libjpeg(ExifElementsTable* exifTable) pTime->tm_hour, pTime->tm_min, pTime->tm_sec ); - ret = exifTable->insertElement(TAG_DATETIME, temp_value); } } @@ -658,6 +659,129 @@ status_t OMXCameraAdapter::setupEXIF_libjpeg(ExifElementsTable* exifTable) } } + // fill in short and ushort tags + if (NO_ERROR == ret) { + char temp_value[2]; + temp_value[1] = '\0'; + + // AWB + if (mParameters3A.WhiteBallance == OMX_WhiteBalControlAuto) { + temp_value[0] = '0'; + } else { + temp_value[0] = '1'; + } + exifTable->insertElement(TAG_WHITEBALANCE, temp_value); + + // MeteringMode + // TODO(XXX): only supporting this metering mode at the moment, may change in future + temp_value[0] = '2'; + exifTable->insertElement(TAG_METERING_MODE, temp_value); + + // ExposureProgram + // TODO(XXX): only supporting this exposure program at the moment, may change in future + temp_value[0] = '3'; + exifTable->insertElement(TAG_EXPOSURE_PROGRAM, temp_value); + + // ColorSpace + temp_value[0] = '1'; + exifTable->insertElement(TAG_COLOR_SPACE, temp_value); + + temp_value[0] = '2'; + exifTable->insertElement(TAG_SENSING_METHOD, temp_value); + + temp_value[0] = '1'; + exifTable->insertElement(TAG_CUSTOM_RENDERED, temp_value); + } + + if (pAncillaryData && (NO_ERROR == ret)) { + unsigned int numerator = 0, denominator = 0; + char temp_value[256]; + unsigned int temp_num = 0; + + // DigitalZoomRatio + snprintf(temp_value, + sizeof(temp_value)/sizeof(char), + "%u/%u", + pAncillaryData->nDigitalZoomFactor, 1024); + exifTable->insertElement(TAG_DIGITALZOOMRATIO, temp_value); + + // ExposureTime + snprintf(temp_value, + sizeof(temp_value)/sizeof(char), + "%u/%u", + pAncillaryData->nExposureTime, 1000000); + exifTable->insertElement(TAG_EXPOSURETIME, temp_value); + + // ApertureValue and FNumber + snprintf(temp_value, + sizeof(temp_value)/sizeof(char), + "%u/%u", + pAncillaryData->nApertureValue, 100); + exifTable->insertElement(TAG_FNUMBER, temp_value); + exifTable->insertElement(TAG_APERTURE, temp_value); + + // ISO + snprintf(temp_value, + sizeof(temp_value)/sizeof(char), + "%u,0,0", + pAncillaryData->nCurrentISO); + exifTable->insertElement(TAG_ISO_EQUIVALENT, temp_value); + + // ShutterSpeed + snprintf(temp_value, + sizeof(temp_value)/sizeof(char), + "%f", + log(pAncillaryData->nExposureTime) / log(2)); + ExifElementsTable::stringToRational(temp_value, &numerator, &denominator); + snprintf(temp_value, sizeof(temp_value)/sizeof(char), "%u/%u", numerator, denominator); + exifTable->insertElement(TAG_SHUTTERSPEED, temp_value); + + // Flash + if (mParameters3A.FlashMode == OMX_IMAGE_FlashControlAuto) { + if(pAncillaryData->nFlashStatus) temp_num = 0x19; // Flash fired, auto mode + else temp_num = 0x18; // Flash did not fire, auto mode + } else if (mParameters3A.FlashMode == OMX_IMAGE_FlashControlOn) { + if(pAncillaryData->nFlashStatus) temp_num = 0x9; // Flash fired, compulsory flash mode + else temp_num = 0x10; // Flash did not fire, compulsory flash mode + } else if(pAncillaryData->nFlashStatus) { + temp_num = 0x1; // Flash fired + } else { + temp_num = 0x0; // Flash did not fire + } + snprintf(temp_value, + sizeof(temp_value)/sizeof(char), + "%u", temp_num); + exifTable->insertElement(TAG_FLASH, temp_value); + + if (pWhiteBalanceData) { + unsigned int lightsource = 0; + unsigned int colourtemp = pWhiteBalanceData->nColorTemperature; + bool flash_fired = (temp_num & 0x1); // value from flash above + + // stole this from framework/tools_library/src/tools_sys_exif_tags.c + if( colourtemp <= 3200 ) { + lightsource = 3; // Tungsten + } else if( colourtemp > 3200 && colourtemp <= 4800 ) { + lightsource = 2; // Fluorescent + } else if( colourtemp > 4800 && colourtemp <= 5500 ) { + lightsource = 1; // Daylight + } else if( colourtemp > 5500 && colourtemp <= 6500 ) { + lightsource = 9; // Fine weather + } else if( colourtemp > 6500 ) { + lightsource = 10; // Cloudy weather + } + + if(flash_fired) { + lightsource = 4; // Flash + } + + snprintf(temp_value, + sizeof(temp_value)/sizeof(char), + "%u", lightsource); + exifTable->insertElement(TAG_LIGHT_SOURCE, temp_value); + } + } + LOG_FUNCTION_NAME_EXIT; return ret; diff --git a/camera/OMXCameraAdapter/OMXFD.cpp b/camera/OMXCameraAdapter/OMXFD.cpp index 38c7a6e..938ccf6 100644 --- a/camera/OMXCameraAdapter/OMXFD.cpp +++ b/camera/OMXCameraAdapter/OMXFD.cpp @@ -125,7 +125,6 @@ status_t OMXCameraAdapter::setFaceDetection(bool enable, OMX_U32 orientation) { status_t ret = NO_ERROR; OMX_ERRORTYPE eError = OMX_ErrorNone; - OMX_CONFIG_EXTRADATATYPE extraDataControl; OMX_CONFIG_OBJDETECTIONTYPE objDetection; LOG_FUNCTION_NAME; @@ -170,27 +169,11 @@ status_t OMXCameraAdapter::setFaceDetection(bool enable, OMX_U32 orientation) if ( NO_ERROR == ret ) { - OMX_INIT_STRUCT_PTR (&extraDataControl, OMX_CONFIG_EXTRADATATYPE); - extraDataControl.nPortIndex = mCameraAdapterParameters.mPrevPortIndex; - extraDataControl.eExtraDataType = OMX_FaceDetection; - extraDataControl.eCameraView = OMX_2D; - if ( enable ) - { - extraDataControl.bEnable = OMX_TRUE; - } - else - { - extraDataControl.bEnable = OMX_FALSE; - } + ret = setExtraData(enable, mCameraAdapterParameters.mPrevPortIndex, OMX_FaceDetection); - eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, - ( OMX_INDEXTYPE ) OMX_IndexConfigOtherExtraDataControl, - &extraDataControl); - if ( OMX_ErrorNone != eError ) + if ( NO_ERROR != ret ) { - CAMHAL_LOGEB("Error while configuring face detection extra data 0x%x", - eError); - ret = -1; + CAMHAL_LOGEA("Error while configuring face detection extra data"); } else { |