summaryrefslogtreecommitdiffstats
path: root/camera
diff options
context:
space:
mode:
authorTyler Luu <tluu@ti.com>2011-08-31 21:12:17 -0500
committerIliyan Malchev <malchev@google.com>2011-09-02 14:49:15 -0700
commitee6bb64f60c228d711dc1d6875d8f4b0ed88b6cf (patch)
tree415e047ef28613e12c264f48cbc1e76f2183b7fa /camera
parentbc0e345c35480fb8036a766f47a7ed65e98947c5 (diff)
downloadhardware_ti_omap4xxx-ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cf.zip
hardware_ti_omap4xxx-ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cf.tar.gz
hardware_ti_omap4xxx-ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cf.tar.bz2
CameraHal: Initial support for video snapshot
Adds support for capturing an image while recording in video mode. Sets up Ducati to return a YUV422I buffer and encode is performed in AppCallbackNotifier with Encoder_libjpeg class. Change-Id: Ia351fc99dab63a12add8c6c960b186bbe5be275a Signed-off-by: Tyler Luu <tluu@ti.com>
Diffstat (limited to 'camera')
-rw-r--r--camera/Android.mk5
-rw-r--r--camera/AppCallbackNotifier.cpp125
-rw-r--r--camera/BaseCameraAdapter.cpp53
-rw-r--r--camera/CameraHal.cpp50
-rw-r--r--camera/Encoder_libjpeg.cpp158
-rw-r--r--camera/OMXCameraAdapter/OMXCameraAdapter.cpp24
-rw-r--r--camera/OMXCameraAdapter/OMXCapture.cpp39
-rw-r--r--camera/inc/CameraHal.h20
-rw-r--r--camera/inc/Encoder_libjpeg.h90
9 files changed, 523 insertions, 41 deletions
diff --git a/camera/Android.mk b/camera/Android.mk
index 948c33c..21209d1 100644
--- a/camera/Android.mk
+++ b/camera/Android.mk
@@ -13,6 +13,7 @@ OMAP4_CAMERA_HAL_SRC := \
ANativeWindowDisplayAdapter.cpp \
CameraProperties.cpp \
MemoryManager.cpp \
+ Encoder_libjpeg.cpp \
SensorListener.cpp
OMAP4_CAMERA_COMMON_SRC:= \
@@ -63,7 +64,8 @@ LOCAL_C_INCLUDES += \
hardware/ti/omap4xxx/domx/omx_core/inc \
hardware/ti/omap4xxx/domx/mm_osal/inc \
frameworks/base/include/media/stagefright \
- frameworks/base/include/media/stagefright/openmax
+ frameworks/base/include/media/stagefright/openmax \
+ external/jpeg
LOCAL_SHARED_LIBRARIES:= \
libui \
@@ -78,6 +80,7 @@ LOCAL_SHARED_LIBRARIES:= \
libgui \
libdomx \
libion \
+ libjpeg
LOCAL_CFLAGS := -fno-short-enums -DCOPY_IMAGE_BUFFER
diff --git a/camera/AppCallbackNotifier.cpp b/camera/AppCallbackNotifier.cpp
index c209612..e6b112a 100644
--- a/camera/AppCallbackNotifier.cpp
+++ b/camera/AppCallbackNotifier.cpp
@@ -22,6 +22,7 @@
#include "CameraHal.h"
#include "VideoMetadata.h"
+#include "Encoder_libjpeg.h"
#include <MetadataBufferType.h>
#include <ui/GraphicBuffer.h>
#include <ui/GraphicBufferMapper.h>
@@ -31,13 +32,72 @@ namespace android {
const int AppCallbackNotifier::NOTIFIER_TIMEOUT = -1;
+void AppCallbackNotifierEncoderCallback(size_t jpeg_size,
+ uint8_t* src,
+ CameraFrame::FrameType type,
+ void* cookie1,
+ void* cookie2,
+ void* cookie3)
+{
+ if (cookie1) {
+ AppCallbackNotifier* cb = (AppCallbackNotifier*) cookie1;
+ cb->EncoderDoneCb(jpeg_size, src, type, cookie2);
+ }
+}
+
/*--------------------NotificationHandler Class STARTS here-----------------------------*/
+void AppCallbackNotifier::EncoderDoneCb(size_t jpeg_size, uint8_t* src, CameraFrame::FrameType type, void* cookie1)
+{
+ camera_memory_t* encoded_mem = NULL;
+
+ LOG_FUNCTION_NAME;
+
+ Mutex::Autolock lock(mLock);
+
+ encoded_mem = (camera_memory_t*) cookie1;
+
+ // TODO(XXX): Need to temporarily allocate another chunk of memory and then memcpy
+ // encoded buffer since MemoryHeapBase and MemoryBase are passed as
+ // one camera_memory_t structure. How fix this?
+
+ camera_memory_t* picture = mRequestMemory(-1, jpeg_size, 1, NULL);
+
+ if(picture && picture->data && encoded_mem && encoded_mem->data) {
+ memcpy(picture->data, encoded_mem->data, jpeg_size);
+ }
+
+ {
+ Mutex::Autolock lock(mBurstLock);
+#if 0 //TODO: enable burst mode later
+ if ( mBurst )
+ {
+ `(CAMERA_MSG_BURST_IMAGE, JPEGPictureMemBase, mCallbackCookie);
+ }
+ else
+#endif
+ {
+ mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, picture, 0, NULL, mCallbackCookie);
+ }
+ }
+
+ if (encoded_mem) {
+ encoded_mem->release(encoded_mem);
+ }
+
+ if (picture) {
+ picture->release(picture);
+ }
+
+ mFrameProvider->returnFrame(src, type);
+
+ LOG_FUNCTION_NAME_EXIT;
+}
+
/**
* NotificationHandler class
*/
-
///Initialization function for AppCallbackNotifier
status_t AppCallbackNotifier::initialize()
{
@@ -573,6 +633,59 @@ void AppCallbackNotifier::notifyFrame()
}
}
+ else if ( (CameraFrame::IMAGE_FRAME == frame->mFrameType) &&
+ (NULL != mCameraHal) &&
+ (NULL != mDataCb) &&
+ (CameraFrame::ENCODE_RAW_YUV422I_TO_JPEG & frame->mQuirks) )
+ {
+ Mutex::Autolock lock(mLock);
+
+ int encode_quality = 100;
+ const char* valstr = NULL;
+ camera_memory_t* raw_picture = mRequestMemory(-1, frame->mLength, 1, NULL);
+
+ if(raw_picture) {
+ buf = raw_picture->data;
+ }
+
+ valstr = mParameters.get(CameraParameters::KEY_JPEG_QUALITY);
+ if (valstr) {
+ encode_quality = atoi(valstr);
+ if (encode_quality < 0 || encode_quality > 100) {
+ encode_quality = 100;
+ }
+ }
+
+ CAMHAL_LOGVB("encoder(%p, %d, %p, %d, %d, %d, %d,%p,%d,%p,%p, %d)",
+ (uint8_t*)frame->mBuffer,
+ frame->mLength,
+ (uint8_t*)buf,
+ frame->mLength,
+ encode_quality,
+ frame->mWidth,
+ frame->mHeight,
+ AppCallbackNotifierEncoderCallback,
+ frame->mFrameType,
+ this,
+ raw_picture,
+ NULL);
+
+ sp<Encoder_libjpeg> encoder = new Encoder_libjpeg((uint8_t*)frame->mBuffer,
+ frame->mLength,
+ (uint8_t*)buf,
+ frame->mLength,
+ encode_quality,
+ frame->mWidth,
+ frame->mHeight,
+ AppCallbackNotifierEncoderCallback,
+ (CameraFrame::FrameType)frame->mFrameType,
+ this,
+ raw_picture,
+ NULL);
+ encoder->run();
+ encoder.clear();
+
+ }
else if ( ( CameraFrame::IMAGE_FRAME == frame->mFrameType ) &&
( NULL != mCameraHal ) &&
( NULL != mDataCb) )
@@ -1133,6 +1246,16 @@ void AppCallbackNotifier::setBurst(bool burst)
LOG_FUNCTION_NAME_EXIT;
}
+int AppCallbackNotifier::setParameters(const CameraParameters& params)
+{
+ LOG_FUNCTION_NAME;
+
+ mParameters = params
+
+ LOG_FUNCTION_NAME_EXIT;
+ return NO_ERROR;
+}
+
status_t AppCallbackNotifier::stopPreviewCallbacks()
{
sp<MemoryHeapBase> heap;
diff --git a/camera/BaseCameraAdapter.cpp b/camera/BaseCameraAdapter.cpp
index cd20346..ec149bf 100644
--- a/camera/BaseCameraAdapter.cpp
+++ b/camera/BaseCameraAdapter.cpp
@@ -1786,6 +1786,18 @@ status_t BaseCameraAdapter::setState(CameraCommands operation)
mNextState = VIDEO_ZOOM_STATE;
break;
+ case CAMERA_USE_BUFFERS_IMAGE_CAPTURE:
+ CAMHAL_LOGDB("Adapter state switch VIDEO_STATE->VIDEO_LOADED_CAPTURE_STATE event = 0x%x",
+ operation);
+ mNextState = VIDEO_LOADED_CAPTURE_STATE;
+ break;
+
+ case CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE:
+ CAMHAL_LOGDB("Adapter state switch VIDEO_STATE->VIDEO_STATE event = 0x%x",
+ operation);
+ mNextState = VIDEO_STATE;
+ break;
+
default:
CAMHAL_LOGEB("Adapter state switch VIDEO_STATE Invalid Op! event = 0x%x",
operation);
@@ -1796,6 +1808,47 @@ status_t BaseCameraAdapter::setState(CameraCommands operation)
break;
+ case VIDEO_LOADED_CAPTURE_STATE:
+
+ switch ( operation )
+ {
+
+ case CAMERA_START_IMAGE_CAPTURE:
+ CAMHAL_LOGDB("Adapter state switch LOADED_CAPTURE_STATE->CAPTURE_STATE event = 0x%x",
+ operation);
+ mNextState = VIDEO_CAPTURE_STATE;
+ break;
+
+ default:
+ CAMHAL_LOGEB("Adapter state switch LOADED_CAPTURE_STATE Invalid Op! event = 0x%x",
+ operation);
+ ret = INVALID_OPERATION;
+ break;
+
+ }
+
+ break;
+
+ case VIDEO_CAPTURE_STATE:
+
+ switch ( operation )
+ {
+ case CAMERA_STOP_IMAGE_CAPTURE:
+ CAMHAL_LOGDB("Adapter state switch CAPTURE_STATE->PREVIEW_STATE event = 0x%x",
+ operation);
+ mNextState = VIDEO_STATE;
+ break;
+
+ default:
+ CAMHAL_LOGEB("Adapter state switch CAPTURE_STATE Invalid Op! event = 0x%x",
+ operation);
+ ret = INVALID_OPERATION;
+ break;
+
+ }
+
+ break;
+
case AF_ZOOM_STATE:
switch ( operation )
diff --git a/camera/CameraHal.cpp b/camera/CameraHal.cpp
index 4830ebf..c770b7a 100644
--- a/camera/CameraHal.cpp
+++ b/camera/CameraHal.cpp
@@ -2224,6 +2224,7 @@ status_t CameraHal::takePicture( )
CameraFrame frame;
CameraAdapter::BuffersDescriptor desc;
int burst;
+ const char *valstr = NULL;
unsigned int bufferCount = 1;
Mutex::Autolock lock(mLock);
@@ -2239,15 +2240,27 @@ status_t CameraHal::takePicture( )
if(!previewEnabled() && !mDisplayPaused)
{
LOG_FUNCTION_NAME_EXIT;
+ CAMHAL_LOGEA("Preview not started...");
return NO_INIT;
}
- //If capture has already started, then queue this call for later execution
- if ( mCameraAdapter->getState() == CameraAdapter::CAPTURE_STATE &&
- mCameraAdapter->getNextState() != CameraAdapter::PREVIEW_STATE) {
+ // return error if we are already capturing
+ if ( (mCameraAdapter->getState() == CameraAdapter::CAPTURE_STATE &&
+ mCameraAdapter->getNextState() != CameraAdapter::PREVIEW_STATE) ||
+ (mCameraAdapter->getState() == CameraAdapter::VIDEO_CAPTURE_STATE &&
+ mCameraAdapter->getNextState() != CameraAdapter::VIDEO_STATE) ) {
+ CAMHAL_LOGEA("Already capturing an image...");
return NO_INIT;
}
+ // we only support video snapshot if we are in video mode (recording hint is set)
+ valstr = mParameters.get(TICameraParameters::KEY_CAP_MODE);
+ if ( (mCameraAdapter->getState() == CameraAdapter::VIDEO_STATE) &&
+ (valstr && strcmp(valstr, TICameraParameters::VIDEO_MODE)) ) {
+ CAMHAL_LOGEA("Trying to capture while recording without recording hint set...");
+ return INVALID_OPERATION;
+ }
+
if ( !mBracketingRunning )
{
@@ -2273,26 +2286,27 @@ status_t CameraHal::takePicture( )
}
}
- //Pause Preview during capture
- if ( (NO_ERROR == ret) && ( NULL != mDisplayAdapter.get() ) && ( burst < 1 ) )
- {
- mDisplayPaused = true;
- mPreviewEnabled = false;
- ret = mDisplayAdapter->pauseDisplay(mDisplayPaused);
+ // pause preview during normal image capture
+ // do not pause preview if recording (video state)
+ if (NO_ERROR == ret &&
+ NULL != mDisplayAdapter.get() &&
+ burst < 1) {
+ if (mCameraAdapter->getState() != CameraAdapter::VIDEO_STATE) {
+ mDisplayPaused = true;
+ mPreviewEnabled = false;
+ ret = mDisplayAdapter->pauseDisplay(mDisplayPaused);
+ // since preview is paused we should stop sending preview frames too
+ if(mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) {
+ mAppCallbackNotifier->disableMsgType (CAMERA_MSG_PREVIEW_FRAME);
+ }
+ }
#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
-
mDisplayAdapter->setSnapshotTimeRef(&mStartCapture);
-
#endif
- // since preview is paused we should stop sending preview frames too
- if(mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME)
- {
- mAppCallbackNotifier->disableMsgType (CAMERA_MSG_PREVIEW_FRAME);
- }
- }
+ }
- if ( (NO_ERROR == ret) && ( NULL != mCameraAdapter ) )
+ if ( (NO_ERROR == ret) && (NULL != mCameraAdapter) )
{
if ( NO_ERROR == ret )
ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE,
diff --git a/camera/Encoder_libjpeg.cpp b/camera/Encoder_libjpeg.cpp
new file mode 100644
index 0000000..dfdd934
--- /dev/null
+++ b/camera/Encoder_libjpeg.cpp
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) Texas Instruments - http://www.ti.com/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @file Encoder_libjpeg.cpp
+*
+* This file encodes a YUV422I buffer to a jpeg
+* TODO(XXX): Need to support formats other than yuv422i
+* Change interface to pre/post-proc algo framework
+*
+*/
+
+#define LOG_TAG "CameraHAL"
+
+#include "CameraHal.h"
+#include "Encoder_libjpeg.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <errno.h>
+
+extern "C" {
+ #include "jpeglib.h"
+ #include "jerror.h"
+}
+
+namespace android {
+
+struct libjpeg_destination_mgr : jpeg_destination_mgr {
+ libjpeg_destination_mgr(uint8_t* input, int size);
+
+ uint8_t* buf;
+ int bufsize;
+ size_t jpegsize;
+};
+
+static void libjpeg_init_destination (j_compress_ptr cinfo) {
+ libjpeg_destination_mgr* dest = (libjpeg_destination_mgr*)cinfo->dest;
+
+ dest->next_output_byte = dest->buf;
+ dest->free_in_buffer = dest->bufsize;
+ dest->jpegsize = 0;
+}
+
+static boolean libjpeg_empty_output_buffer(j_compress_ptr cinfo) {
+ libjpeg_destination_mgr* dest = (libjpeg_destination_mgr*)cinfo->dest;
+
+ dest->next_output_byte = dest->buf;
+ dest->free_in_buffer = dest->bufsize;
+ return TRUE; // ?
+}
+
+static void libjpeg_term_destination (j_compress_ptr cinfo) {
+ libjpeg_destination_mgr* dest = (libjpeg_destination_mgr*)cinfo->dest;
+ dest->jpegsize = dest->bufsize - dest->free_in_buffer;
+}
+
+libjpeg_destination_mgr::libjpeg_destination_mgr(uint8_t* input, int size) {
+ this->init_destination = libjpeg_init_destination;
+ this->empty_output_buffer = libjpeg_empty_output_buffer;
+ this->term_destination = libjpeg_term_destination;
+
+ this->buf = input;
+ this->bufsize = size;
+}
+
+/* private static functions */
+
+static void uyvy_to_yuv(uint8_t* dst, uint32_t* src, int width) {
+ // TODO(XXX): optimize later
+ while ((width-=2) >= 0) {
+ uint8_t u0 = (src[0] >> 0) & 0xFF;
+ uint8_t y0 = (src[0] >> 8) & 0xFF;
+ uint8_t v0 = (src[0] >> 16) & 0xFF;
+ uint8_t y1 = (src[0] >> 24) & 0xFF;
+ dst[0] = y0;
+ dst[1] = u0;
+ dst[2] = v0;
+ dst[3] = y1;
+ dst[4] = u0;
+ dst[5] = v0;
+ dst += 6;
+ src++;
+ }
+}
+
+/* private member functions */
+size_t Encoder_libjpeg::encode() {
+ jpeg_compress_struct cinfo;
+ jpeg_error_mgr jerr;
+ jpeg_destination_mgr jdest;
+ uint8_t* row_tmp = NULL;
+ uint8_t* row_src = NULL;
+ int bpp = 2; // TODO(XXX): hardcoded for uyvy
+
+ cinfo.err = jpeg_std_error(&jerr);
+
+ jpeg_create_compress(&cinfo);
+
+ libjpeg_destination_mgr dest_mgr(mDest, mDestSize);
+
+ CAMHAL_LOGDB("encoding... \n\t"
+ "width: %d \n\t"
+ "height:%d \n\t"
+ "dest %p \n\t"
+ "dest size:%d \n\t"
+ "mSrc %p",
+ mWidth, mHeight, mDest, mDestSize, mSrc);
+
+ cinfo.dest = &dest_mgr;
+ cinfo.image_width = mWidth;
+ cinfo.image_height = mHeight;
+ cinfo.input_components = 3;
+ cinfo.in_color_space = JCS_YCbCr;
+ cinfo.input_gamma = 1;
+
+ jpeg_set_defaults(&cinfo);
+ jpeg_set_quality(&cinfo, mQuality, TRUE);
+ cinfo.dct_method = JDCT_IFAST;
+
+ jpeg_start_compress(&cinfo, TRUE);
+
+ row_tmp = (uint8_t*)malloc(mWidth * 3);
+ row_src = mSrc;
+
+ while (cinfo.next_scanline < cinfo.image_height) {
+ JSAMPROW row[1]; /* pointer to JSAMPLE row[s] */
+
+ uyvy_to_yuv(row_tmp, (uint32_t*)row_src, mWidth);
+ row[0] = row_tmp;
+ jpeg_write_scanlines(&cinfo, row, 1);
+ row_src = row_src + mWidth*bpp;
+ }
+
+ jpeg_finish_compress(&cinfo);
+ jpeg_destroy_compress(&cinfo);
+
+ return dest_mgr.jpegsize;
+}
+
+} // namespace android
diff --git a/camera/OMXCameraAdapter/OMXCameraAdapter.cpp b/camera/OMXCameraAdapter/OMXCameraAdapter.cpp
index 9bd3643..6211c51 100644
--- a/camera/OMXCameraAdapter/OMXCameraAdapter.cpp
+++ b/camera/OMXCameraAdapter/OMXCameraAdapter.cpp
@@ -2712,7 +2712,7 @@ OMX_ERRORTYPE OMXCameraAdapter::OMXCameraAdapterFillBufferDone(OMX_IN OMX_HANDLE
pPortParam);
}
- if( mWaitingForSnapshot )
+ if( mWaitingForSnapshot && (mCapturedFrames > 0) )
{
typeOfFrame = CameraFrame::SNAPSHOT_FRAME;
}
@@ -2739,8 +2739,8 @@ OMX_ERRORTYPE OMXCameraAdapter::OMXCameraAdapterFillBufferDone(OMX_IN OMX_HANDLE
{
mSnapshotCount++;
- if ( ( mSnapshotCount == 1 ) &&
- ( HIGH_SPEED == mCapMode ) )
+ if ( (mSnapshotCount == 1) &&
+ ((HIGH_SPEED == mCapMode) || (VIDEO_MODE == mCapMode)) )
{
notifyShutterSubscribers();
}
@@ -2763,11 +2763,26 @@ OMX_ERRORTYPE OMXCameraAdapter::OMXCameraAdapterFillBufferDone(OMX_IN OMX_HANDLE
}
else if( pBuffHeader->nOutputPortIndex == OMX_CAMERA_PORT_IMAGE_OUT_IMAGE )
{
+ CameraFrame cameraFrame;
+ OMX_COLOR_FORMATTYPE pixFormat;
+ const char *valstr = NULL;
- if ( OMX_COLOR_FormatUnused == mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex].mColorFormat )
+ pixFormat = mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex].mColorFormat;
+ valstr = mParams.getPictureFormat();
+
+ if ( OMX_COLOR_FormatUnused == pixFormat )
{
typeOfFrame = CameraFrame::IMAGE_FRAME;
}
+ else if ( pixFormat == OMX_COLOR_FormatCbYCrY &&
+ ((valstr && !strcmp(valstr, CameraParameters::PIXEL_FORMAT_JPEG)) ||
+ !valstr) )
+ {
+ // signals to callbacks that this needs to be coverted to jpeg
+ // before returning to framework
+ typeOfFrame = CameraFrame::IMAGE_FRAME;
+ cameraFrame.mQuirks |= CameraFrame::ENCODE_RAW_YUV422I_TO_JPEG;
+ }
else
{
typeOfFrame = CameraFrame::RAW_FRAME;
@@ -2804,7 +2819,6 @@ OMX_ERRORTYPE OMXCameraAdapter::OMXCameraAdapterFillBufferDone(OMX_IN OMX_HANDLE
mCapturedFrames--;
- CameraFrame cameraFrame;
stat |= initCameraFrame(cameraFrame,
pBuffHeader,
typeOfFrame,
diff --git a/camera/OMXCameraAdapter/OMXCapture.cpp b/camera/OMXCameraAdapter/OMXCapture.cpp
index f6e26c9..6bec221 100644
--- a/camera/OMXCameraAdapter/OMXCapture.cpp
+++ b/camera/OMXCameraAdapter/OMXCapture.cpp
@@ -125,6 +125,16 @@ status_t OMXCameraAdapter::setParametersCapture(const CameraParameters &params,
pixFormat = OMX_COLOR_FormatUnused;
}
+ // JPEG capture is not supported in video mode by OMX Camera
+ // Set capture format to yuv422i...jpeg encode will
+ // be done on A9
+ valstr = params.get(TICameraParameters::KEY_CAP_MODE);
+ if ( (valstr && !strcmp(valstr, (const char *) TICameraParameters::VIDEO_MODE)) &&
+ (pixFormat == OMX_COLOR_FormatUnused) ) {
+ CAMHAL_LOGDA("Capturing in video mode...selecting yuv422i");
+ pixFormat = OMX_COLOR_FormatCbYCrY;
+ }
+
if ( pixFormat != cap->mColorFormat )
{
updateImagePortParams = true;
@@ -746,37 +756,38 @@ status_t OMXCameraAdapter::startImageCapture()
}
- if ( NO_ERROR == ret )
- {
+ if ( NO_ERROR == ret ) {
capData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex];
///Queue all the buffers on capture port
- for ( int index = 0 ; index < capData->mNumBufs ; index++ )
- {
+ for ( int index = 0 ; index < capData->mNumBufs ; index++ ) {
CAMHAL_LOGDB("Queuing buffer on Capture port - 0x%x",
( unsigned int ) capData->mBufferHeader[index]->pBuffer);
eError = OMX_FillThisBuffer(mCameraAdapterParameters.mHandleComp,
(OMX_BUFFERHEADERTYPE*)capData->mBufferHeader[index]);
GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
- }
+ }
mWaitingForSnapshot = true;
mCaptureSignalled = false;
- OMX_INIT_STRUCT_PTR (&bOMX, OMX_CONFIG_BOOLEANTYPE);
- bOMX.bEnabled = OMX_TRUE;
-
- /// sending Capturing Command to the component
- eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
- OMX_IndexConfigCapturing,
- &bOMX);
+ // Capturing command is not needed when capturing in video mode
+ // Only need to queue buffers on image ports
+ if (mCapMode != VIDEO_MODE) {
+ OMX_INIT_STRUCT_PTR (&bOMX, OMX_CONFIG_BOOLEANTYPE);
+ bOMX.bEnabled = OMX_TRUE;
- CAMHAL_LOGDB("Capture set - 0x%x", eError);
+ /// sending Capturing Command to the component
+ eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp,
+ OMX_IndexConfigCapturing,
+ &bOMX);
- GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
+ CAMHAL_LOGDB("Capture set - 0x%x", eError);
+ GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
}
+ }
//OMX shutter callback events are only available in hq mode
if ( (HIGH_QUALITY == mCapMode) || (HIGH_QUALITY_ZSL== mCapMode))
diff --git a/camera/inc/CameraHal.h b/camera/inc/CameraHal.h
index 8c09701..475f7fa 100644
--- a/camera/inc/CameraHal.h
+++ b/camera/inc/CameraHal.h
@@ -229,6 +229,11 @@ class CameraFrame
ALL_FRAMES = 0xFFFF ///Maximum of 16 frame types supported
};
+ enum FrameQuirks
+ {
+ ENCODE_RAW_YUV422I_TO_JPEG = 0x1 << 0,
+ };
+
//default contrustor
CameraFrame():
mCookie(NULL),
@@ -240,7 +245,8 @@ class CameraFrame
mOffset(0),
mAlignment(0),
mFd(0),
- mLength(0) {}
+ mLength(0),
+ mQuirks(0) {}
//copy constructor
CameraFrame(const CameraFrame &frame) :
@@ -253,7 +259,8 @@ class CameraFrame
mOffset(frame.mOffset),
mAlignment(frame.mAlignment),
mFd(frame.mFd),
- mLength(frame.mLength) {}
+ mLength(frame.mLength),
+ mQuirks(frame.mQuirks) {}
void *mCookie;
void *mBuffer;
@@ -264,6 +271,7 @@ class CameraFrame
unsigned int mAlignment;
int mFd;
size_t mLength;
+ unsigned int mQuirks;
///@todo add other member vars like stride etc
};
@@ -516,6 +524,8 @@ public:
//Set Burst mode
void setBurst(bool burst);
+ int setParameters(const CameraParameters& params);
+
//Notifications from CameraHal for video recording case
status_t startRecording();
status_t stopRecording();
@@ -524,6 +534,8 @@ public:
status_t useMetaDataBufferMode(bool enable);
+ void EncoderDoneCb(size_t jpeg_size, uint8_t* src, CameraFrame::FrameType type, void* cookie1);
+
//Internal class definitions
class NotificationThread : public Thread {
AppCallbackNotifier* mAppCallbackNotifier;
@@ -600,6 +612,8 @@ private:
bool mUseMetaDataBufferMode;
+ CameraParameters mParameters;
+
};
@@ -709,6 +723,8 @@ public:
ZOOM_STATE = ZOOM_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE,
VIDEO_STATE = VIDEO_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE,
VIDEO_ZOOM_STATE = VIDEO_ACTIVE | ZOOM_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE,
+ VIDEO_LOADED_CAPTURE_STATE = VIDEO_ACTIVE | LOADED_CAPTURE_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE,
+ VIDEO_CAPTURE_STATE = VIDEO_ACTIVE | CAPTURE_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE,
AF_ZOOM_STATE = AF_ACTIVE | ZOOM_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE,
BRACKETING_ZOOM_STATE = BRACKETING_ACTIVE | ZOOM_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE,
};
diff --git a/camera/inc/Encoder_libjpeg.h b/camera/inc/Encoder_libjpeg.h
new file mode 100644
index 0000000..24ce672
--- /dev/null
+++ b/camera/inc/Encoder_libjpeg.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) Texas Instruments - http://www.ti.com/
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+* @file Encoder_libjpeg.h
+*
+* This defines API for camerahal to encode YUV using libjpeg
+*
+*/
+
+#ifndef ANDROID_CAMERA_HARDWARE_ENCODER_LIBJPEG_H
+#define ANDROID_CAMERA_HARDWARE_ENCODER_LIBJPEG_H
+
+#include <utils/threads.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+/**
+ * libjpeg encoder class - uses libjpeg to encode yuv
+ */
+
+typedef void (*encoder_libjpeg_callback_t) (size_t jpeg_size,
+ uint8_t* src,
+ CameraFrame::FrameType type,
+ void* cookie1,
+ void* cookie2,
+ void* cookie3);
+
+class Encoder_libjpeg : public Thread {
+ public:
+ Encoder_libjpeg(uint8_t* src,
+ int src_size,
+ uint8_t* dst,
+ int dst_size,
+ int quality,
+ int width,
+ int height,
+ encoder_libjpeg_callback_t cb,
+ CameraFrame::FrameType type,
+ void* cookie1,
+ void* cookie2,
+ void* cookie3)
+ : Thread(false), mSrc(src), mDest(dst), mSrcSize(src_size), mDestSize(dst_size),
+ mQuality(quality), mWidth(width), mHeight(height), mCb(cb), mCookie1(cookie1),
+ mCookie2(cookie2), mCookie3(cookie3), mType(type) {
+ this->incStrong(this);
+ }
+
+ ~Encoder_libjpeg() {
+ }
+
+ virtual bool threadLoop() {
+ size_t size = encode();
+ mCb(size, mSrc, mType, mCookie1, mCookie2, mCookie3);
+ // encoder thread runs, self-destructs, and then exits
+ this->decStrong(this);
+ return false;
+ }
+
+ private:
+ uint8_t* mSrc;
+ uint8_t* mDest;
+ int mSrcSize, mDestSize;
+ int mQuality, mWidth, mHeight;
+ encoder_libjpeg_callback_t mCb;
+ void* mCookie1;
+ void* mCookie2;
+ void* mCookie3;
+ CameraFrame::FrameType mType;
+
+ size_t encode();
+};
+
+}
+
+#endif