summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVishal Bhoj <vishal.bhoj@linaro.org>2012-01-31 22:13:09 +0530
committerVishal Bhoj <vishal.bhoj@linaro.org>2012-01-31 22:16:05 +0530
commit1ad0e928edf6f046572b3f32eb5ee23d8d7f3f79 (patch)
tree5c4a1c48e7f64ddccbe801a6ba3d16d69e7464ea
parent120c22ceb513ca37685854e467fb4cb482840d1c (diff)
downloadcommon-linaro_android_4.0.3.tar.gz
camera: Initial changes for ICS supportlinaro_android_4.0.3
Preview,Image capture and apps like skype, linphone, hangouts are working. Recording fails. Change-Id: I4587c31014e40b87146a2cafb294cc33e532a26f Signed-off-by: Vishal Bhoj <vishal.bhoj@linaro.org>
-rw-r--r--libcamera/Android.mk59
-rw-r--r--libcamera/CameraHal.h1266
-rw-r--r--libcamera/CameraHal_Module.cpp429
-rw-r--r--libcamera/CameraHardware.cpp163
-rw-r--r--libcamera/CameraHardware.h56
-rw-r--r--libcamera/CameraHardwareInterface.h231
-rw-r--r--libcamera/V4L2Camera.cpp28
-rw-r--r--libcamera/V4L2Camera.h6
-rw-r--r--libcamera/V4L2CameraHal.h151
-rw-r--r--libcamera/rgbconvert.c50
10 files changed, 2319 insertions, 120 deletions
diff --git a/libcamera/Android.mk b/libcamera/Android.mk
index 9e7dc3e..1275cfa 100644
--- a/libcamera/Android.mk
+++ b/libcamera/Android.mk
@@ -1,28 +1,37 @@
-ifneq ($(USE_CAMERA_STUB),true)
-
-LOCAL_PATH := $(call my-dir)
-
+LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
- CameraHardware.cpp \
- V4L2Camera.cpp \
- convert.S
-
-LOCAL_C_INCLUDES += external/jpeg
-
-LOCAL_MODULE := libcamera
-LOCAL_MODULE_TAGS := optional
-LOCAL_PRELINK_MODULE := false
-
-LOCAL_SHARED_LIBRARIES := \
- libui \
- libjpeg \
- libutils \
- libbinder \
- libcutils \
- libcamera_client
+LOCAL_SRC_FILES:= \
+ CameraHal_Module.cpp \
+ V4L2Camera.cpp \
+ CameraHardware.cpp \
+ convert.S \
+ rgbconvert.c
+
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/inc/ \
+ hardware/ti/omap4xxx/hwc \
+ frameworks/base/include/ui \
+ frameworks/base/include/utils \
+ 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 \
+ external/jpeg \
+ external/jhead
+
+LOCAL_SHARED_LIBRARIES:= \
+ libui \
+ libbinder \
+ libutils \
+ libcutils \
+ libcamera_client \
+ libcameraservice \
+ libgui \
+ libjpeg \
+ libexif
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
+LOCAL_MODULE:= camera.$(TARGET_BOARD_PLATFORM)
+LOCAL_MODULE_TAGS:= optional
include $(BUILD_SHARED_LIBRARY)
-
-endif
diff --git a/libcamera/CameraHal.h b/libcamera/CameraHal.h
new file mode 100644
index 0000000..1ec08cf
--- /dev/null
+++ b/libcamera/CameraHal.h
@@ -0,0 +1,1266 @@
+/*
+ * 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.
+ */
+
+
+
+#ifndef ANDROID_HARDWARE_CAMERA_HARDWARE_H
+#define ANDROID_HARDWARE_CAMERA_HARDWARE_H
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <utils/Log.h>
+#include <utils/threads.h>
+#include <linux/videodev2.h>
+#include "binder/MemoryBase.h"
+#include "binder/MemoryHeapBase.h"
+#include <utils/threads.h>
+#include <camera/CameraParameters.h>
+#include <hardware/camera.h>
+//#include "MessageQueue.h"
+//#include "Semaphore.h"
+//#include "CameraProperties.h"
+//#include "DebugUtils.h"
+//#include "SensorListener.h"
+
+#include <ui/GraphicBufferAllocator.h>
+#include <ui/GraphicBuffer.h>
+
+#define MIN_WIDTH 640
+#define MIN_HEIGHT 480
+#define PICTURE_WIDTH 3264 /* 5mp - 2560. 8mp - 3280 */ /* Make sure it is a multiple of 16. */
+#define PICTURE_HEIGHT 2448 /* 5mp - 2048. 8mp - 2464 */ /* Make sure it is a multiple of 16. */
+#define PREVIEW_WIDTH 176
+#define PREVIEW_HEIGHT 144
+#define PIXEL_FORMAT V4L2_PIX_FMT_UYVY
+
+#define VIDEO_FRAME_COUNT_MAX 8 //NUM_OVERLAY_BUFFERS_REQUESTED
+#define MAX_CAMERA_BUFFERS 8 //NUM_OVERLAY_BUFFERS_REQUESTED
+#define MAX_ZOOM 3
+#define THUMB_WIDTH 80
+#define THUMB_HEIGHT 60
+#define PIX_YUV422I 0
+#define PIX_YUV420P 1
+
+#define SATURATION_OFFSET 100
+#define SHARPNESS_OFFSET 100
+#define CONTRAST_OFFSET 100
+
+#define CAMHAL_GRALLOC_USAGE GRALLOC_USAGE_HW_TEXTURE | \
+ GRALLOC_USAGE_HW_RENDER | \
+ GRALLOC_USAGE_SW_READ_RARELY | \
+ GRALLOC_USAGE_SW_WRITE_NEVER
+
+//Enables Absolute PPM measurements in logcat
+#define PPM_INSTRUMENTATION_ABS 1
+
+#define LOCK_BUFFER_TRIES 5
+#define HAL_PIXEL_FORMAT_NV12 0x100
+
+#define CAMHAL_LOGI LOGI
+
+//Uncomment to enable more verbose/debug logs
+//#define DEBUG_LOG
+
+///Camera HAL Logging Functions
+#ifndef DEBUG_LOG
+
+#define CAMHAL_LOGDA(str)
+#define CAMHAL_LOGDB(str, ...)
+#define CAMHAL_LOGVA(str)
+#define CAMHAL_LOGVB(str, ...)
+
+#define CAMHAL_LOGEA LOGE
+#define CAMHAL_LOGEB LOGE
+
+#undef LOG_FUNCTION_NAME
+#undef LOG_FUNCTION_NAME_EXIT
+#define LOG_FUNCTION_NAME
+#define LOG_FUNCTION_NAME_EXIT
+
+#else
+
+#define CAMHAL_LOGDA DBGUTILS_LOGDA
+#define CAMHAL_LOGDB DBGUTILS_LOGDB
+#define CAMHAL_LOGVA DBGUTILS_LOGVA
+#define CAMHAL_LOGVB DBGUTILS_LOGVB
+
+#define CAMHAL_LOGEA DBGUTILS_LOGEA
+#define CAMHAL_LOGEB DBGUTILS_LOGEB
+
+#endif
+
+
+
+#define NONNEG_ASSIGN(x,y) \
+ if(x > -1) \
+ y = x
+
+namespace android {
+
+#define PARAM_BUFFER 6000
+
+///Forward declarations
+class CameraHal;
+class CameraFrame;
+class CameraHalEvent;
+class DisplayFrame;
+
+class CameraArea : public RefBase
+{
+public:
+
+ CameraArea(ssize_t top,
+ ssize_t left,
+ ssize_t bottom,
+ ssize_t right,
+ size_t weight) : mTop(top),
+ mLeft(left),
+ mBottom(bottom),
+ mRight(right),
+ mWeight(weight) {}
+
+ status_t transfrom(size_t width,
+ size_t height,
+ size_t &top,
+ size_t &left,
+ size_t &areaWidth,
+ size_t &areaHeight);
+
+ bool isValid()
+ {
+ return ( ( 0 != mTop ) || ( 0 != mLeft ) || ( 0 != mBottom ) || ( 0 != mRight) );
+ }
+
+ bool isZeroArea()
+ {
+ return ( (0 == mTop ) && ( 0 == mLeft ) && ( 0 == mBottom )
+ && ( 0 == mRight ) && ( 0 == mWeight ));
+ }
+
+ size_t getWeight()
+ {
+ return mWeight;
+ }
+
+ bool compare(const sp<CameraArea> &area);
+
+ static status_t parseAreas(const char *area,
+ size_t areaLength,
+ Vector< sp<CameraArea> > &areas);
+
+ static status_t checkArea(ssize_t top,
+ ssize_t left,
+ ssize_t bottom,
+ ssize_t right,
+ ssize_t weight);
+
+ static bool areAreasDifferent(Vector< sp<CameraArea> > &, Vector< sp<CameraArea> > &);
+
+protected:
+ static const ssize_t TOP = -1000;
+ static const ssize_t LEFT = -1000;
+ static const ssize_t BOTTOM = 1000;
+ static const ssize_t RIGHT = 1000;
+ static const ssize_t WEIGHT_MIN = 1;
+ static const ssize_t WEIGHT_MAX = 1000;
+
+ ssize_t mTop;
+ ssize_t mLeft;
+ ssize_t mBottom;
+ ssize_t mRight;
+ size_t mWeight;
+};
+
+class CameraFDResult : public RefBase
+{
+public:
+
+ CameraFDResult() : mFaceData(NULL) {};
+ CameraFDResult(camera_frame_metadata_t *faces) : mFaceData(faces) {};
+
+ virtual ~CameraFDResult() {
+ if ( ( NULL != mFaceData ) && ( NULL != mFaceData->faces ) ) {
+ free(mFaceData->faces);
+ free(mFaceData);
+ mFaceData=NULL;
+ }
+
+ if(( NULL != mFaceData ))
+ {
+ free(mFaceData);
+ mFaceData = NULL;
+ }
+ }
+
+ camera_frame_metadata_t *getFaceResult() { return mFaceData; };
+
+ static const ssize_t TOP = -1000;
+ static const ssize_t LEFT = -1000;
+ static const ssize_t BOTTOM = 1000;
+ static const ssize_t RIGHT = 1000;
+ static const ssize_t INVALID_DATA = -2000;
+
+private:
+
+ camera_frame_metadata_t *mFaceData;
+};
+
+class CameraFrame
+{
+ public:
+
+ enum FrameType
+ {
+ PREVIEW_FRAME_SYNC = 0x1, ///SYNC implies that the frame needs to be explicitly returned after consuming in order to be filled by camera again
+ PREVIEW_FRAME = 0x2 , ///Preview frame includes viewfinder and snapshot frames
+ IMAGE_FRAME_SYNC = 0x4, ///Image Frame is the image capture output frame
+ IMAGE_FRAME = 0x8,
+ VIDEO_FRAME_SYNC = 0x10, ///Timestamp will be updated for these frames
+ VIDEO_FRAME = 0x20,
+ FRAME_DATA_SYNC = 0x40, ///Any extra data assosicated with the frame. Always synced with the frame
+ FRAME_DATA= 0x80,
+ RAW_FRAME = 0x100,
+ SNAPSHOT_FRAME = 0x200,
+ ALL_FRAMES = 0xFFFF ///Maximum of 16 frame types supported
+ };
+
+ enum FrameQuirks
+ {
+ ENCODE_RAW_YUV422I_TO_JPEG = 0x1 << 0,
+ HAS_EXIF_DATA = 0x1 << 1,
+ };
+
+ //default contrustor
+ CameraFrame():
+ mCookie(NULL),
+ mCookie2(NULL),
+ mBuffer(NULL),
+ mFrameType(0),
+ mTimestamp(0),
+ mWidth(0),
+ mHeight(0),
+ mOffset(0),
+ mAlignment(0),
+ mFd(0),
+ mLength(0),
+ mFrameMask(0),
+ mQuirks(0) {
+
+ mYuv[0] = NULL;
+ mYuv[1] = NULL;
+ }
+
+ //copy constructor
+ CameraFrame(const CameraFrame &frame) :
+ mCookie(frame.mCookie),
+ mCookie2(frame.mCookie2),
+ mBuffer(frame.mBuffer),
+ mFrameType(frame.mFrameType),
+ mTimestamp(frame.mTimestamp),
+ mWidth(frame.mWidth),
+ mHeight(frame.mHeight),
+ mOffset(frame.mOffset),
+ mAlignment(frame.mAlignment),
+ mFd(frame.mFd),
+ mLength(frame.mLength),
+ mFrameMask(frame.mFrameMask),
+ mQuirks(frame.mQuirks) {
+
+ mYuv[0] = frame.mYuv[0];
+ mYuv[1] = frame.mYuv[1];
+ }
+
+ void *mCookie;
+ void *mCookie2;
+ void *mBuffer;
+ int mFrameType;
+ nsecs_t mTimestamp;
+ unsigned int mWidth, mHeight;
+ uint32_t mOffset;
+ unsigned int mAlignment;
+ int mFd;
+ size_t mLength;
+ unsigned mFrameMask;
+ unsigned int mQuirks;
+ unsigned int mYuv[2];
+ ///@todo add other member vars like stride etc
+};
+
+enum CameraHalError
+{
+ CAMERA_ERROR_FATAL = 0x1, //Fatal errors can only be recovered by restarting media server
+ CAMERA_ERROR_HARD = 0x2, // Hard errors are hardware hangs that may be recoverable by resetting the hardware internally within the adapter
+ CAMERA_ERROR_SOFT = 0x4, // Soft errors are non fatal errors that can be recovered from without needing to stop use-case
+};
+
+///Common Camera Hal Event class which is visible to CameraAdapter,DisplayAdapter and AppCallbackNotifier
+///@todo Rename this class to CameraEvent
+class CameraHalEvent
+{
+public:
+ //Enums
+ enum CameraHalEventType {
+ NO_EVENTS = 0x0,
+ EVENT_FOCUS_LOCKED = 0x1,
+ EVENT_FOCUS_ERROR = 0x2,
+ EVENT_ZOOM_INDEX_REACHED = 0x4,
+ EVENT_SHUTTER = 0x8,
+ EVENT_FACE = 0x10,
+ ///@remarks Future enum related to display, like frame displayed event, could be added here
+ ALL_EVENTS = 0xFFFF ///Maximum of 16 event types supported
+ };
+
+ ///Class declarations
+ ///@remarks Add a new class for a new event type added above
+
+ //Shutter event specific data
+ typedef struct ShutterEventData_t {
+ bool shutterClosed;
+ }ShutterEventData;
+
+ ///Focus event specific data
+ typedef struct FocusEventData_t {
+ bool focusLocked;
+ bool focusError;
+ int currentFocusValue;
+ } FocusEventData;
+
+ ///Zoom specific event data
+ typedef struct ZoomEventData_t {
+ int currentZoomIndex;
+ bool targetZoomIndexReached;
+ } ZoomEventData;
+
+ typedef struct FaceData_t {
+ ssize_t top;
+ ssize_t left;
+ ssize_t bottom;
+ ssize_t right;
+ size_t score;
+ } FaceData;
+
+ typedef sp<CameraFDResult> FaceEventData;
+
+ class CameraHalEventData : public RefBase{
+
+ public:
+
+ CameraHalEvent::FocusEventData focusEvent;
+ CameraHalEvent::ZoomEventData zoomEvent;
+ CameraHalEvent::ShutterEventData shutterEvent;
+ CameraHalEvent::FaceEventData faceEvent;
+ };
+
+ //default contrustor
+ CameraHalEvent():
+ mCookie(NULL),
+ mEventType(NO_EVENTS) {}
+
+ //copy constructor
+ CameraHalEvent(const CameraHalEvent &event) :
+ mCookie(event.mCookie),
+ mEventType(event.mEventType),
+ mEventData(event.mEventData) {};
+
+ void* mCookie;
+ CameraHalEventType mEventType;
+ sp<CameraHalEventData> mEventData;
+
+};
+
+/// Have a generic callback class based on template - to adapt CameraFrame and Event
+typedef void (*frame_callback) (CameraFrame *cameraFrame);
+typedef void (*event_callback) (CameraHalEvent *event);
+
+//signals CameraHAL to relase image buffers
+typedef void (*release_image_buffers_callback) (void *userData);
+typedef void (*end_image_capture_callback) (void *userData);
+
+/**
+ * Interface class implemented by classes that have some events to communicate to dependendent classes
+ * Dependent classes use this interface for registering for events
+ */
+class MessageNotifier
+{
+public:
+ static const uint32_t EVENT_BIT_FIELD_POSITION;
+ static const uint32_t FRAME_BIT_FIELD_POSITION;
+
+ ///@remarks Msg type comes from CameraFrame and CameraHalEvent classes
+ /// MSB 16 bits is for events and LSB 16 bits is for frame notifications
+ /// FrameProvider and EventProvider classes act as helpers to event/frame
+ /// consumers to call this api
+ virtual void enableMsgType(int32_t msgs, frame_callback frameCb=NULL, event_callback eventCb=NULL, void* cookie=NULL) = 0;
+ virtual void disableMsgType(int32_t msgs, void* cookie) = 0;
+
+ virtual ~MessageNotifier() {};
+};
+
+class ErrorNotifier : public virtual RefBase
+{
+public:
+ virtual void errorNotify(int error) = 0;
+
+ virtual ~ErrorNotifier() {};
+};
+
+
+/**
+ * Interace class abstraction for Camera Adapter to act as a frame provider
+ * This interface is fully implemented by Camera Adapter
+ */
+class FrameNotifier : public MessageNotifier
+{
+public:
+ virtual void returnFrame(void* frameBuf, CameraFrame::FrameType frameType) = 0;
+ virtual void addFramePointers(void *frameBuf, void *buf) = 0;
+ virtual void removeFramePointers() = 0;
+
+ virtual ~FrameNotifier() {};
+};
+
+/** * Wrapper class around Frame Notifier, which is used by display and notification classes for interacting with Camera Adapter
+ */
+class FrameProvider
+{
+ FrameNotifier* mFrameNotifier;
+ void* mCookie;
+ frame_callback mFrameCallback;
+
+public:
+ FrameProvider(FrameNotifier *fn, void* cookie, frame_callback frameCallback)
+ :mFrameNotifier(fn), mCookie(cookie),mFrameCallback(frameCallback) { }
+
+ int enableFrameNotification(int32_t frameTypes);
+ int disableFrameNotification(int32_t frameTypes);
+ int returnFrame(void *frameBuf, CameraFrame::FrameType frameType);
+ void addFramePointers(void *frameBuf, void *buf);
+ void removeFramePointers();
+};
+
+/** Wrapper class around MessageNotifier, which is used by display and notification classes for interacting with
+ * Camera Adapter
+ */
+class EventProvider
+{
+public:
+ MessageNotifier* mEventNotifier;
+ void* mCookie;
+ event_callback mEventCallback;
+
+public:
+ EventProvider(MessageNotifier *mn, void* cookie, event_callback eventCallback)
+ :mEventNotifier(mn), mCookie(cookie), mEventCallback(eventCallback) {}
+
+ int enableEventNotification(int32_t eventTypes);
+ int disableEventNotification(int32_t eventTypes);
+};
+
+/*
+ * Interface for providing buffers
+ */
+class BufferProvider
+{
+public:
+ virtual void* allocateBuffer(int width, int height, const char* format, int &bytes, int numBufs) = 0;
+
+ //additional methods used for memory mapping
+ virtual uint32_t * getOffsets() = 0;
+ virtual int getFd() = 0;
+
+ virtual int freeBuffer(void* buf) = 0;
+
+ virtual ~BufferProvider() {}
+};
+
+/**
+ * Class for handling data and notify callbacks to application
+ */
+class AppCallbackNotifier: public ErrorNotifier , public virtual RefBase
+{
+
+public:
+
+ ///Constants
+ static const int NOTIFIER_TIMEOUT;
+ static const int32_t MAX_BUFFERS = 8;
+
+ enum NotifierCommands
+ {
+ NOTIFIER_CMD_PROCESS_EVENT,
+ NOTIFIER_CMD_PROCESS_FRAME,
+ NOTIFIER_CMD_PROCESS_ERROR
+ };
+
+ enum NotifierState
+ {
+ NOTIFIER_STOPPED,
+ NOTIFIER_STARTED,
+ NOTIFIER_EXITED
+ };
+
+public:
+
+ ~AppCallbackNotifier();
+
+ ///Initialzes the callback notifier, creates any resources required
+ status_t initialize();
+
+ ///Starts the callbacks to application
+ status_t start();
+
+ ///Stops the callbacks from going to application
+ status_t stop();
+
+ void setEventProvider(int32_t eventMask, MessageNotifier * eventProvider);
+ void setFrameProvider(FrameNotifier *frameProvider);
+
+ //All sub-components of Camera HAL call this whenever any error happens
+ virtual void errorNotify(int error);
+
+ status_t startPreviewCallbacks(CameraParameters &params, void *buffers, uint32_t *offsets, int fd, size_t length, size_t count);
+ status_t stopPreviewCallbacks();
+
+ status_t enableMsgType(int32_t msgType);
+ status_t disableMsgType(int32_t msgType);
+
+ //API for enabling/disabling measurement data
+ void setMeasurements(bool enable);
+
+ //thread loops
+ bool notificationThread();
+
+ ///Notification callback functions
+ static void frameCallbackRelay(CameraFrame* caFrame);
+ static void eventCallbackRelay(CameraHalEvent* chEvt);
+ void frameCallback(CameraFrame* caFrame);
+ void eventCallback(CameraHalEvent* chEvt);
+ void flushAndReturnFrames();
+
+ void setCallbacks(CameraHal *cameraHal,
+ camera_notify_callback notify_cb,
+ camera_data_callback data_cb,
+ camera_data_timestamp_callback data_cb_timestamp,
+ camera_request_memory get_memory,
+ void *user);
+
+ //Set Burst mode
+ void setBurst(bool burst);
+
+ //Notifications from CameraHal for video recording case
+ status_t startRecording();
+ status_t stopRecording();
+ status_t initSharedVideoBuffers(void *buffers, uint32_t *offsets, int fd, size_t length, size_t count, void *vidBufs);
+ status_t releaseRecordingFrame(const void *opaque);
+
+ status_t useMetaDataBufferMode(bool enable);
+
+ void EncoderDoneCb(void*, void*, CameraFrame::FrameType type, void* cookie1, void* cookie2);
+
+ void useVideoBuffers(bool useVideoBuffers);
+
+ bool getUesVideoBuffers();
+ void setVideoRes(int width, int height);
+
+ void flushEventQueue();
+
+ //Internal class definitions
+ class NotificationThread : public Thread {
+ AppCallbackNotifier* mAppCallbackNotifier;
+ TIUTILS::MessageQueue mNotificationThreadQ;
+ public:
+ enum NotificationThreadCommands
+ {
+ NOTIFIER_START,
+ NOTIFIER_STOP,
+ NOTIFIER_EXIT,
+ };
+ public:
+ NotificationThread(AppCallbackNotifier* nh)
+ : Thread(false), mAppCallbackNotifier(nh) { }
+ virtual bool threadLoop() {
+ return mAppCallbackNotifier->notificationThread();
+ }
+
+ TIUTILS::MessageQueue &msgQ() { return mNotificationThreadQ;}
+ };
+
+ //Friend declarations
+ friend class NotificationThread;
+
+private:
+ void notifyEvent();
+ void notifyFrame();
+ bool processMessage();
+ void releaseSharedVideoBuffers();
+ status_t dummyRaw();
+ void copyAndSendPictureFrame(CameraFrame* frame, int32_t msgType);
+ void copyAndSendPreviewFrame(CameraFrame* frame, int32_t msgType);
+
+private:
+ mutable Mutex mLock;
+ mutable Mutex mBurstLock;
+ CameraHal* mCameraHal;
+ camera_notify_callback mNotifyCb;
+ camera_data_callback mDataCb;
+ camera_data_timestamp_callback mDataCbTimestamp;
+ camera_request_memory mRequestMemory;
+ void *mCallbackCookie;
+
+ //Keeps Video MemoryHeaps and Buffers within
+ //these objects
+ KeyedVector<unsigned int, unsigned int> mVideoHeaps;
+ KeyedVector<unsigned int, unsigned int> mVideoBuffers;
+ KeyedVector<unsigned int, unsigned int> mVideoMap;
+
+ //Keeps list of Gralloc handles and associated Video Metadata Buffers
+ KeyedVector<uint32_t, uint32_t> mVideoMetadataBufferMemoryMap;
+ KeyedVector<uint32_t, uint32_t> mVideoMetadataBufferReverseMap;
+
+ bool mBufferReleased;
+
+ sp< NotificationThread> mNotificationThread;
+ EventProvider *mEventProvider;
+ FrameProvider *mFrameProvider;
+ TIUTILS::MessageQueue mEventQ;
+ TIUTILS::MessageQueue mFrameQ;
+ NotifierState mNotifierState;
+
+ bool mPreviewing;
+ camera_memory_t* mPreviewMemory;
+ unsigned char* mPreviewBufs[MAX_BUFFERS];
+ int mPreviewBufCount;
+ const char *mPreviewPixelFormat;
+ KeyedVector<unsigned int, sp<MemoryHeapBase> > mSharedPreviewHeaps;
+ KeyedVector<unsigned int, sp<MemoryBase> > mSharedPreviewBuffers;
+
+ //Burst mode active
+ bool mBurst;
+ mutable Mutex mRecordingLock;
+ bool mRecording;
+ bool mMeasurementEnabled;
+
+ bool mUseMetaDataBufferMode;
+ bool mRawAvailable;
+
+ bool mUseVideoBuffers;
+
+ int mVideoWidth;
+ int mVideoHeight;
+
+};
+
+
+/**
+ * Class used for allocating memory for JPEG bit stream buffers, output buffers of camera in no overlay case
+ */
+class MemoryManager : public BufferProvider, public virtual RefBase
+{
+public:
+ MemoryManager():mIonFd(0){ }
+
+ ///Initializes the memory manager creates any resources required
+ status_t initialize() { return NO_ERROR; }
+
+ int setErrorHandler(ErrorNotifier *errorNotifier);
+ virtual void* allocateBuffer(int width, int height, const char* format, int &bytes, int numBufs);
+ virtual uint32_t * getOffsets();
+ virtual int getFd() ;
+ virtual int freeBuffer(void* buf);
+
+private:
+
+ sp<ErrorNotifier> mErrorNotifier;
+ int mIonFd;
+ KeyedVector<unsigned int, unsigned int> mIonHandleMap;
+ KeyedVector<unsigned int, unsigned int> mIonFdMap;
+ KeyedVector<unsigned int, unsigned int> mIonBufLength;
+};
+
+
+
+
+/**
+ * CameraAdapter interface class
+ * Concrete classes derive from this class and provide implementations based on the specific camera h/w interface
+ */
+
+class CameraAdapter: public FrameNotifier, public virtual RefBase
+{
+protected:
+ enum AdapterActiveStates {
+ INTIALIZED_ACTIVE = 1 << 0,
+ LOADED_PREVIEW_ACTIVE = 1 << 1,
+ PREVIEW_ACTIVE = 1 << 2,
+ LOADED_CAPTURE_ACTIVE = 1 << 3,
+ CAPTURE_ACTIVE = 1 << 4,
+ BRACKETING_ACTIVE = 1 << 5,
+ AF_ACTIVE = 1 << 6,
+ ZOOM_ACTIVE = 1 << 7,
+ VIDEO_ACTIVE = 1 << 8,
+ };
+public:
+ typedef struct
+ {
+ void *mBuffers;
+ uint32_t *mOffsets;
+ int mFd;
+ size_t mLength;
+ size_t mCount;
+ size_t mMaxQueueable;
+ } BuffersDescriptor;
+
+ enum CameraCommands
+ {
+ CAMERA_START_PREVIEW = 0,
+ CAMERA_STOP_PREVIEW = 1,
+ CAMERA_START_VIDEO = 2,
+ CAMERA_STOP_VIDEO = 3,
+ CAMERA_START_IMAGE_CAPTURE = 4,
+ CAMERA_STOP_IMAGE_CAPTURE = 5,
+ CAMERA_PERFORM_AUTOFOCUS = 6,
+ CAMERA_CANCEL_AUTOFOCUS = 7,
+ CAMERA_PREVIEW_FLUSH_BUFFERS = 8,
+ CAMERA_START_SMOOTH_ZOOM = 9,
+ CAMERA_STOP_SMOOTH_ZOOM = 10,
+ CAMERA_USE_BUFFERS_PREVIEW = 11,
+ CAMERA_SET_TIMEOUT = 12,
+ CAMERA_CANCEL_TIMEOUT = 13,
+ CAMERA_START_BRACKET_CAPTURE = 14,
+ CAMERA_STOP_BRACKET_CAPTURE = 15,
+ CAMERA_QUERY_RESOLUTION_PREVIEW = 16,
+ CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE = 17,
+ CAMERA_QUERY_BUFFER_SIZE_PREVIEW_DATA = 18,
+ CAMERA_USE_BUFFERS_IMAGE_CAPTURE = 19,
+ CAMERA_USE_BUFFERS_PREVIEW_DATA = 20,
+ CAMERA_TIMEOUT_EXPIRED = 21,
+ CAMERA_START_FD = 22,
+ CAMERA_STOP_FD = 23,
+ CAMERA_SWITCH_TO_EXECUTING = 24,
+ };
+
+ enum CameraMode
+ {
+ CAMERA_PREVIEW,
+ CAMERA_IMAGE_CAPTURE,
+ CAMERA_VIDEO,
+ CAMERA_MEASUREMENT
+ };
+
+ enum AdapterState {
+ INTIALIZED_STATE = INTIALIZED_ACTIVE,
+ LOADED_PREVIEW_STATE = LOADED_PREVIEW_ACTIVE | INTIALIZED_ACTIVE,
+ PREVIEW_STATE = PREVIEW_ACTIVE | INTIALIZED_ACTIVE,
+ LOADED_CAPTURE_STATE = LOADED_CAPTURE_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE,
+ CAPTURE_STATE = CAPTURE_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE,
+ BRACKETING_STATE = BRACKETING_ACTIVE | CAPTURE_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE ,
+ AF_STATE = AF_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE,
+ ZOOM_STATE = ZOOM_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE,
+ VIDEO_STATE = VIDEO_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE,
+ VIDEO_AF_STATE = VIDEO_ACTIVE | AF_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,
+ };
+
+public:
+
+ ///Initialzes the camera adapter creates any resources required
+ virtual int initialize(CameraProperties::Properties*) = 0;
+
+ virtual int setErrorHandler(ErrorNotifier *errorNotifier) = 0;
+
+ //Message/Frame notification APIs
+ virtual void enableMsgType(int32_t msgs,
+ frame_callback callback = NULL,
+ event_callback eventCb = NULL,
+ void *cookie = NULL) = 0;
+ virtual void disableMsgType(int32_t msgs, void* cookie) = 0;
+ virtual void returnFrame(void* frameBuf, CameraFrame::FrameType frameType) = 0;
+ virtual void addFramePointers(void *frameBuf, void *buf) = 0;
+ virtual void removeFramePointers() = 0;
+
+ //APIs to configure Camera adapter and get the current parameter set
+ virtual int setParameters(const CameraParameters& params) = 0;
+ virtual void getParameters(CameraParameters& params) = 0;
+
+ //API to flush the buffers from Camera
+ status_t flushBuffers()
+ {
+ return sendCommand(CameraAdapter::CAMERA_PREVIEW_FLUSH_BUFFERS);
+ }
+
+ //Registers callback for returning image buffers back to CameraHAL
+ virtual int registerImageReleaseCallback(release_image_buffers_callback callback, void *user_data) = 0;
+
+ //Registers callback, which signals a completed image capture
+ virtual int registerEndCaptureCallback(end_image_capture_callback callback, void *user_data) = 0;
+
+ //API to send a command to the camera
+ virtual status_t sendCommand(CameraCommands operation, int value1=0, int value2=0, int value3=0) = 0;
+
+ virtual ~CameraAdapter() {};
+
+ //Retrieves the current Adapter state
+ virtual AdapterState getState() = 0;
+
+ //Retrieves the next Adapter state
+ virtual AdapterState getNextState() = 0;
+
+ // Receive orientation events from CameraHal
+ virtual void onOrientationEvent(uint32_t orientation, uint32_t tilt) = 0;
+
+ // Rolls the state machine back to INTIALIZED_STATE from the current state
+ virtual status_t rollbackToInitializedState() = 0;
+
+ // Retrieves the current Adapter state - for internal use (not locked)
+ virtual status_t getState(AdapterState &state) = 0;
+ // Retrieves the next Adapter state - for internal use (not locked)
+ virtual status_t getNextState(AdapterState &state) = 0;
+
+protected:
+ //The first two methods will try to switch the adapter state.
+ //Every call to setState() should be followed by a corresponding
+ //call to commitState(). If the state switch fails, then it will
+ //get reset to the previous state via rollbackState().
+ virtual status_t setState(CameraCommands operation) = 0;
+ virtual status_t commitState() = 0;
+ virtual status_t rollbackState() = 0;
+};
+
+class DisplayAdapter : public BufferProvider, public virtual RefBase
+{
+public:
+ typedef struct S3DParameters_t
+ {
+ int mode;
+ int framePacking;
+ int order;
+ int subSampling;
+ } S3DParameters;
+
+ ///Initializes the display adapter creates any resources required
+ virtual int initialize() = 0;
+
+ virtual int setPreviewWindow(struct preview_stream_ops *window) = 0;
+ virtual int setFrameProvider(FrameNotifier *frameProvider) = 0;
+ virtual int setErrorHandler(ErrorNotifier *errorNotifier) = 0;
+ virtual int enableDisplay(int width, int height, struct timeval *refTime = NULL, S3DParameters *s3dParams = NULL) = 0;
+ virtual int disableDisplay(bool cancel_buffer = true) = 0;
+ //Used for Snapshot review temp. pause
+ virtual int pauseDisplay(bool pause) = 0;
+
+#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
+ //Used for shot to snapshot measurement
+ virtual int setSnapshotTimeRef(struct timeval *refTime = NULL) = 0;
+#endif
+
+ virtual int useBuffers(void *bufArr, int num) = 0;
+ virtual bool supportsExternalBuffering() = 0;
+
+ // Get max queueable buffers display supports
+ // This function should only be called after
+ // allocateBuffer
+ virtual int maxQueueableBuffers(unsigned int& queueable) = 0;
+};
+
+static void releaseImageBuffers(void *userData);
+
+static void endImageCapture(void *userData);
+
+ /**
+ Implementation of the Android Camera hardware abstraction layer
+
+ This class implements the interface methods defined in CameraHardwareInterface
+ for the OMAP4 platform
+
+*/
+class CameraHal
+
+{
+
+public:
+ ///Constants
+ static const int NO_BUFFERS_PREVIEW;
+ static const int NO_BUFFERS_IMAGE_CAPTURE;
+ static const uint32_t VFR_SCALE = 1000;
+
+
+ /*--------------------Interface Methods---------------------------------*/
+
+ //@{
+public:
+
+ /** Set the notification and data callbacks */
+ void setCallbacks(camera_notify_callback notify_cb,
+ camera_data_callback data_cb,
+ camera_data_timestamp_callback data_cb_timestamp,
+ camera_request_memory get_memory,
+ void *user);
+
+ /** Receives orientation events from SensorListener **/
+ void onOrientationEvent(uint32_t orientation, uint32_t tilt);
+
+ /**
+ * The following three functions all take a msgtype,
+ * which is a bitmask of the messages defined in
+ * include/ui/Camera.h
+ */
+
+ /**
+ * Enable a message, or set of messages.
+ */
+ void enableMsgType(int32_t msgType);
+
+ /**
+ * Disable a message, or a set of messages.
+ */
+ void disableMsgType(int32_t msgType);
+
+ /**
+ * Query whether a message, or a set of messages, is enabled.
+ * Note that this is operates as an AND, if any of the messages
+ * queried are off, this will return false.
+ */
+ int msgTypeEnabled(int32_t msgType);
+
+ /**
+ * Start preview mode.
+ */
+ int startPreview();
+
+ /**
+ * Only used if overlays are used for camera preview.
+ */
+ int setPreviewWindow(struct preview_stream_ops *window);
+
+ /**
+ * Stop a previously started preview.
+ */
+ void stopPreview();
+
+ /**
+ * Returns true if preview is enabled.
+ */
+ bool previewEnabled();
+
+ /**
+ * Start record mode. When a record image is available a CAMERA_MSG_VIDEO_FRAME
+ * message is sent with the corresponding frame. Every record frame must be released
+ * by calling releaseRecordingFrame().
+ */
+ int startRecording();
+
+ /**
+ * Stop a previously started recording.
+ */
+ void stopRecording();
+
+ /**
+ * Returns true if recording is enabled.
+ */
+ int recordingEnabled();
+
+ /**
+ * Release a record frame previously returned by CAMERA_MSG_VIDEO_FRAME.
+ */
+ void releaseRecordingFrame(const void *opaque);
+
+ /**
+ * Start auto focus, the notification callback routine is called
+ * with CAMERA_MSG_FOCUS once when focusing is complete. autoFocus()
+ * will be called again if another auto focus is needed.
+ */
+ int autoFocus();
+
+ /**
+ * Cancels auto-focus function. If the auto-focus is still in progress,
+ * this function will cancel it. Whether the auto-focus is in progress
+ * or not, this function will return the focus position to the default.
+ * If the camera does not support auto-focus, this is a no-op.
+ */
+ int cancelAutoFocus();
+
+ /**
+ * Take a picture.
+ */
+ int takePicture();
+
+ /**
+ * Cancel a picture that was started with takePicture. Calling this
+ * method when no picture is being taken is a no-op.
+ */
+ int cancelPicture();
+
+ /** Set the camera parameters. */
+ int setParameters(const char* params);
+ int setParameters(const CameraParameters& params);
+
+ /** Return the camera parameters. */
+ char* getParameters();
+ void putParameters(char *);
+
+ /**
+ * Send command to camera driver.
+ */
+ int sendCommand(int32_t cmd, int32_t arg1, int32_t arg2);
+
+ /**
+ * Release the hardware resources owned by this object. Note that this is
+ * *not* done in the destructor.
+ */
+ void release();
+
+ /**
+ * Dump state of the camera hardware
+ */
+ int dump(int fd) const;
+
+
+ status_t storeMetaDataInBuffers(bool enable);
+
+ //@}
+
+/*--------------------Internal Member functions - Public---------------------------------*/
+
+public:
+ /** @name internalFunctionsPublic */
+ //@{
+
+ /** Constructor of CameraHal */
+ CameraHal(int cameraId);
+
+ // Destructor of CameraHal
+ ~CameraHal();
+
+ /** Initialize CameraHal */
+ status_t initialize(CameraProperties::Properties*);
+
+ /** Deinitialize CameraHal */
+ void deinitialize();
+
+#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
+
+ //Uses the constructor timestamp as a reference to calcluate the
+ // elapsed time
+ static void PPM(const char *);
+ //Uses a user provided timestamp as a reference to calcluate the
+ // elapsed time
+ static void PPM(const char *, struct timeval*, ...);
+
+#endif
+
+ /** Free image bufs */
+ status_t freeImageBufs();
+
+ //Signals the end of image capture
+ status_t signalEndImageCapture();
+
+ //Events
+ static void eventCallbackRelay(CameraHalEvent* event);
+ void eventCallback(CameraHalEvent* event);
+ void setEventProvider(int32_t eventMask, MessageNotifier * eventProvider);
+
+/*--------------------Internal Member functions - Private---------------------------------*/
+private:
+
+ /** @name internalFunctionsPrivate */
+ //@{
+
+ /** Set the camera parameters specific to Video Recording. */
+ bool setVideoModeParameters(const CameraParameters&);
+
+ /** Reset the camera parameters specific to Video Recording. */
+ bool resetVideoModeParameters();
+
+ /** Restart the preview with setParameter. */
+ status_t restartPreview();
+
+ status_t parseResolution(const char *resStr, int &width, int &height);
+
+ void insertSupportedParams();
+
+ /** Allocate preview data buffers */
+ status_t allocPreviewDataBufs(size_t size, size_t bufferCount);
+
+ /** Free preview data buffers */
+ status_t freePreviewDataBufs();
+
+ /** Allocate preview buffers */
+ status_t allocPreviewBufs(int width, int height, const char* previewFormat, unsigned int bufferCount, unsigned int &max_queueable);
+
+ /** Allocate video buffers */
+ status_t allocVideoBufs(uint32_t width, uint32_t height, uint32_t bufferCount);
+
+ /** Allocate image capture buffers */
+ status_t allocImageBufs(unsigned int width, unsigned int height, size_t length, const char* previewFormat, unsigned int bufferCount);
+
+ /** Free preview buffers */
+ status_t freePreviewBufs();
+
+ /** Free video bufs */
+ status_t freeVideoBufs(void *bufs);
+
+ //Check if a given resolution is supported by the current camera
+ //instance
+ bool isResolutionValid(unsigned int width, unsigned int height, const char *supportedResolutions);
+
+ //Check if a given parameter is supported by the current camera
+ // instance
+ bool isParameterValid(const char *param, const char *supportedParams);
+ bool isParameterValid(int param, const char *supportedParams);
+ status_t doesSetParameterNeedUpdate(const char *new_param, const char *old_params, bool &update);
+
+ /** Initialize default parameters */
+ void initDefaultParameters();
+
+ void dumpProperties(CameraProperties::Properties& cameraProps);
+
+ status_t startImageBracketing();
+
+ status_t stopImageBracketing();
+
+ void setShutter(bool enable);
+
+ void forceStopPreview();
+
+ void selectFPSRange(int framerate, int *min_fps, int *max_fps);
+
+ void setPreferredPreviewRes(int width, int height);
+ void resetPreviewRes(CameraParameters *mParams, int width, int height);
+
+ //@}
+
+
+/*----------Member variables - Public ---------------------*/
+public:
+ int32_t mMsgEnabled;
+ bool mRecordEnabled;
+ nsecs_t mCurrentTime;
+ bool mFalsePreview;
+ bool mPreviewEnabled;
+ uint32_t mTakePictureQueue;
+ bool mBracketingEnabled;
+ bool mBracketingRunning;
+ //User shutter override
+ bool mShutterEnabled;
+ bool mMeasurementEnabled;
+ //Google's parameter delimiter
+ static const char PARAMS_DELIMITER[];
+
+ CameraAdapter *mCameraAdapter;
+ sp<AppCallbackNotifier> mAppCallbackNotifier;
+ sp<DisplayAdapter> mDisplayAdapter;
+ sp<MemoryManager> mMemoryManager;
+
+ sp<IMemoryHeap> mPictureHeap;
+
+ int* mGrallocHandles;
+ bool mFpsRangeChangedByApp;
+
+
+
+
+
+///static member vars
+
+#if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
+
+ //Timestamp from the CameraHal constructor
+ static struct timeval ppm_start;
+ //Timestamp of the autoFocus command
+ static struct timeval mStartFocus;
+ //Timestamp of the startPreview command
+ static struct timeval mStartPreview;
+ //Timestamp of the takePicture command
+ static struct timeval mStartCapture;
+
+#endif
+
+/*----------Member variables - Private ---------------------*/
+private:
+ bool mDynamicPreviewSwitch;
+ //keeps paused state of display
+ bool mDisplayPaused;
+ //Index of current camera adapter
+ int mCameraIndex;
+
+ mutable Mutex mLock;
+
+ sp<SensorListener> mSensorListener;
+
+ void* mCameraAdapterHandle;
+
+ CameraParameters mParameters;
+ bool mPreviewRunning;
+ bool mPreviewStateOld;
+ bool mRecordingEnabled;
+ EventProvider *mEventProvider;
+
+ int32_t *mPreviewDataBufs;
+ uint32_t *mPreviewDataOffsets;
+ int mPreviewDataFd;
+ int mPreviewDataLength;
+ int32_t *mImageBufs;
+ uint32_t *mImageOffsets;
+ int mImageFd;
+ int mImageLength;
+ int32_t *mPreviewBufs;
+ uint32_t *mPreviewOffsets;
+ int mPreviewLength;
+ int mPreviewFd;
+ int32_t *mVideoBufs;
+ uint32_t *mVideoOffsets;
+ int mVideoFd;
+ int mVideoLength;
+
+ int mBracketRangePositive;
+ int mBracketRangeNegative;
+
+ ///@todo Rename this as preview buffer provider
+ BufferProvider *mBufProvider;
+ BufferProvider *mVideoBufProvider;
+
+
+ CameraProperties::Properties* mCameraProperties;
+
+ bool mPreviewStartInProgress;
+
+ bool mSetPreviewWindowCalled;
+
+ uint32_t mPreviewWidth;
+ uint32_t mPreviewHeight;
+ int32_t mMaxZoomSupported;
+
+ int mVideoWidth;
+ int mVideoHeight;
+
+};
+
+
+}; // namespace android
+
+#endif
diff --git a/libcamera/CameraHal_Module.cpp b/libcamera/CameraHal_Module.cpp
new file mode 100644
index 0000000..d322673
--- /dev/null
+++ b/libcamera/CameraHal_Module.cpp
@@ -0,0 +1,429 @@
+/*
+ * 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 CameraHal.cpp
+*
+* This file maps the Camera Hardware Interface to V4L2.
+*
+*/
+
+#define LOG_TAG "****CameraHAL"
+
+#include <utils/threads.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <utils/Log.h>
+#include <utils/threads.h>
+#include <linux/videodev2.h>
+#include "binder/MemoryBase.h"
+#include "binder/MemoryHeapBase.h"
+#include <utils/threads.h>
+#include <camera/CameraParameters.h>
+#include <hardware/camera.h>
+#include <sys/ioctl.h>
+#include <utils/threads.h>
+#include "CameraHardware.h"
+#include <binder/MemoryBase.h>
+#include <binder/MemoryHeapBase.h>
+#include <utils/threads.h>
+#include "V4L2Camera.h"
+#define LOG_FUNCTION_NAME LOGD("%d: %s() ENTER", __LINE__, __FUNCTION__);
+
+using namespace android;
+static CameraHardware *V4L2CameraHardware;
+static int camera_device_open(const hw_module_t* module, const char* name,
+ hw_device_t** device);
+static int camera_device_close(hw_device_t* device);
+static int camera_get_number_of_cameras(void);
+static int camera_get_camera_info(int camera_id, struct camera_info *info);
+static struct hw_module_methods_t camera_module_methods = {
+ open: camera_device_open
+};
+
+camera_module_t HAL_MODULE_INFO_SYM = {
+ common: {
+ tag: HARDWARE_MODULE_TAG,
+ version_major: 1,
+ version_minor: 0,
+ id: CAMERA_HARDWARE_MODULE_ID,
+ name: "V4L2 CameraHal Module",
+ author: "Linaro",
+ methods: &camera_module_methods,
+ dso: NULL, /* remove compilation warnings */
+ reserved: {0}, /* remove compilation warnings */
+ },
+ get_number_of_cameras: camera_get_number_of_cameras,
+ get_camera_info: camera_get_camera_info,
+};
+
+typedef struct V4L2_camera_device {
+ camera_device_t base;
+ /* TI specific "private" data can go here (base.priv) */
+ int cameraid;
+} V4l2_camera_device_t;
+
+
+/*******************************************************************
+ * implementation of camera_device_ops functions
+ *******************************************************************/
+
+int camera_set_preview_window(struct camera_device * device,
+ struct preview_stream_ops *window)
+{
+ int rv = -EINVAL;
+ LOG_FUNCTION_NAME
+ if(!device)
+ return rv;
+
+ if(window==NULL)
+ {
+ LOGW("window is NULL");
+ V4L2CameraHardware->setPreviewWindow(window);
+ return -1;
+ }
+
+ V4L2CameraHardware->setPreviewWindow(window);
+ LOGD("Exiting the function");
+ return 0;
+}
+
+void camera_set_callbacks(struct camera_device * device,
+ camera_notify_callback notify_cb,
+ camera_data_callback data_cb,
+ camera_data_timestamp_callback data_cb_timestamp,
+ camera_request_memory get_memory,
+ void *user)
+{
+ V4l2_camera_device_t* V4l2_dev = NULL;
+ LOG_FUNCTION_NAME
+ V4L2CameraHardware->setCallbacks(notify_cb,data_cb,data_cb_timestamp,get_memory,user);
+}
+
+void camera_enable_msg_type(struct camera_device * device, int32_t msg_type)
+{
+ V4l2_camera_device_t* V4l2_dev = NULL;
+
+ LOG_FUNCTION_NAME
+ V4L2CameraHardware->enableMsgType(msg_type);
+}
+
+void camera_disable_msg_type(struct camera_device * device, int32_t msg_type)
+{
+ V4l2_camera_device_t* V4l2_dev = NULL;
+ LOG_FUNCTION_NAME
+ V4L2CameraHardware->disableMsgType(msg_type);
+}
+
+int camera_msg_type_enabled(struct camera_device * device, int32_t msg_type)
+{
+ V4l2_camera_device_t* V4l2_dev = NULL;
+ LOG_FUNCTION_NAME
+ return V4L2CameraHardware->msgTypeEnabled(msg_type);
+}
+
+int camera_start_preview(struct camera_device * device)
+{
+ LOG_FUNCTION_NAME
+ return V4L2CameraHardware->startPreview();
+}
+
+void camera_stop_preview(struct camera_device * device)
+{
+LOG_FUNCTION_NAME
+V4L2CameraHardware->stopPreview();
+}
+
+int camera_preview_enabled(struct camera_device * device)
+{
+ LOG_FUNCTION_NAME
+ if(V4L2CameraHardware->previewEnabled())
+ {
+ LOGW("----Preview Enabled----");
+ return 1;
+ }
+ else
+ {
+ LOGW("----Preview not Enabled----");
+ return 0;
+ }
+}
+
+int camera_store_meta_data_in_buffers(struct camera_device * device, int enable)
+{
+ int rv = -EINVAL;
+ LOG_FUNCTION_NAME
+ return rv;
+}
+
+int camera_start_recording(struct camera_device * device)
+{
+LOG_FUNCTION_NAME
+ return V4L2CameraHardware->startRecording();
+}
+
+void camera_stop_recording(struct camera_device * device)
+{
+LOG_FUNCTION_NAME
+ V4L2CameraHardware->stopRecording();
+}
+
+int camera_recording_enabled(struct camera_device * device)
+{
+ LOG_FUNCTION_NAME
+ return V4L2CameraHardware->recordingEnabled();
+}
+
+void camera_release_recording_frame(struct camera_device * device,
+ const void *opaque)
+{
+ LOG_FUNCTION_NAME
+ return V4L2CameraHardware->releaseRecordingFrame(opaque);
+}
+
+int camera_auto_focus(struct camera_device * device)
+{
+ LOG_FUNCTION_NAME
+ return V4L2CameraHardware->autoFocus();
+}
+
+int camera_cancel_auto_focus(struct camera_device * device)
+{
+LOG_FUNCTION_NAME
+ return V4L2CameraHardware->cancelAutoFocus();
+}
+
+int camera_take_picture(struct camera_device * device)
+{
+LOG_FUNCTION_NAME
+ return V4L2CameraHardware->takePicture();
+}
+
+int camera_cancel_picture(struct camera_device * device)
+{
+ int rv = 0;// -EINVAL;
+ LOG_FUNCTION_NAME
+ return V4L2CameraHardware->cancelPicture();
+}
+
+int camera_set_parameters(struct camera_device * device, const char *params)
+{
+ LOG_FUNCTION_NAME
+ CameraParameters *camParams = new CameraParameters();
+ String8 *params_str8 = new String8(params);
+ camParams->unflatten(*params_str8);
+ return V4L2CameraHardware->setParameters(*camParams);
+}
+
+char* camera_get_parameters(struct camera_device * device)
+{
+ char* param = NULL ;
+#if 1
+ String8 params_str8 = V4L2CameraHardware->getParameters().flatten();
+ // camera service frees this string...
+ param = (char*) malloc(sizeof(char) * (params_str8.length()+1));
+ strcpy(param, params_str8.string());
+ LOGD("%s",param);
+#endif
+ LOG_FUNCTION_NAME
+ return param;
+}
+
+static void camera_put_parameters(struct camera_device *device, char *params)
+{
+ LOG_FUNCTION_NAME
+ CameraParameters *camParams = new CameraParameters();
+ String8 *params_str8 = new String8(params);
+ camParams->unflatten(*params_str8);
+ V4L2CameraHardware->setParameters(*camParams);
+}
+
+int camera_send_command(struct camera_device * device,
+ int32_t cmd, int32_t arg1, int32_t arg2)
+{
+ int rv =0;// -EINVAL;
+ LOG_FUNCTION_NAME
+ return rv;
+}
+
+void camera_release(struct camera_device * device)
+{
+LOG_FUNCTION_NAME
+ V4L2CameraHardware->release();
+}
+
+
+int camera_dump(struct camera_device * device, int fd)
+{
+ int rv = 0;//-EINVAL;
+ LOG_FUNCTION_NAME
+ return rv;
+}
+
+extern "C" void heaptracker_free_leaked_memory(void);
+
+int camera_device_close(hw_device_t* device)
+{
+ int ret = 0;
+ LOG_FUNCTION_NAME
+ delete V4L2CameraHardware;
+ V4L2CameraHardware=NULL;
+ return ret;
+}
+
+/*******************************************************************
+ * implementation of camera_module functions
+ *******************************************************************/
+
+/* open device handle to one of the cameras
+ *
+ * assume camera service will keep singleton of each camera
+ * so this function will always only be called once per camera instance
+ */
+
+int camera_device_open(const hw_module_t* module, const char* name,
+ hw_device_t** device)
+{
+ int rv = 0;
+ int num_cameras = 1;
+ int cameraid;
+ V4l2_camera_device_t* camera_device = NULL;
+ camera_device_ops_t* camera_ops = NULL;
+
+ LOG_FUNCTION_NAME
+
+
+ LOGI("camera_device open");
+
+ if (name != NULL) {
+ cameraid = atoi(name);
+
+ if(cameraid > num_cameras)
+ {
+ LOGE("camera service provided cameraid out of bounds, "
+ "cameraid = %d, num supported = %d",
+ cameraid, num_cameras);
+ rv = -EINVAL;
+ goto fail;
+ }
+
+
+ camera_device = (V4l2_camera_device_t*)malloc(sizeof(*camera_device));
+ if(!camera_device)
+ {
+ LOGE("camera_device allocation fail");
+ rv = -ENOMEM;
+ goto fail;
+ }
+
+ camera_ops = (camera_device_ops_t*)malloc(sizeof(*camera_ops));
+ if(!camera_ops)
+ {
+ LOGE("camera_ops allocation fail");
+ rv = -ENOMEM;
+ goto fail;
+ }
+
+ memset(camera_device, 0, sizeof(*camera_device));
+ memset(camera_ops, 0, sizeof(*camera_ops));
+
+ camera_device->base.common.tag = HARDWARE_DEVICE_TAG;
+ camera_device->base.common.version = 0;
+ camera_device->base.common.module = (hw_module_t *)(module);
+ camera_device->base.common.close = camera_device_close;
+ camera_device->base.ops = camera_ops;
+
+ camera_ops->set_preview_window = camera_set_preview_window;
+ camera_ops->set_callbacks = camera_set_callbacks;
+ camera_ops->enable_msg_type = camera_enable_msg_type;
+ camera_ops->disable_msg_type = camera_disable_msg_type;
+ camera_ops->msg_type_enabled = camera_msg_type_enabled;
+ camera_ops->start_preview = camera_start_preview;
+ camera_ops->stop_preview = camera_stop_preview;
+ camera_ops->preview_enabled = camera_preview_enabled;
+ camera_ops->store_meta_data_in_buffers = camera_store_meta_data_in_buffers;
+ camera_ops->start_recording = camera_start_recording;
+ camera_ops->stop_recording = camera_stop_recording;
+ camera_ops->recording_enabled = camera_recording_enabled;
+ camera_ops->release_recording_frame = camera_release_recording_frame;
+ camera_ops->auto_focus = camera_auto_focus;
+ camera_ops->cancel_auto_focus = camera_cancel_auto_focus;
+ camera_ops->take_picture = camera_take_picture;
+ camera_ops->cancel_picture = camera_cancel_picture;
+ camera_ops->set_parameters = camera_set_parameters;
+ camera_ops->get_parameters = camera_get_parameters;
+ camera_ops->put_parameters = camera_put_parameters;
+ camera_ops->send_command = camera_send_command;
+ camera_ops->release = camera_release;
+ camera_ops->dump = camera_dump;
+
+ *device = &camera_device->base.common;
+
+ // -------- TI specific stuff --------
+
+ camera_device->cameraid = cameraid;
+ V4L2CameraHardware = new CameraHardware(0);
+ }
+
+ return rv;
+
+fail:
+ if(camera_device) {
+ free(camera_device);
+ camera_device = NULL;
+ }
+ if(camera_ops) {
+ free(camera_ops);
+ camera_ops = NULL;
+ }
+ *device = NULL;
+ return rv;
+}
+
+int camera_get_number_of_cameras(void)
+{
+LOG_FUNCTION_NAME
+ int num_cameras =2;// MAX_CAMERAS_SUPPORTED;
+ return num_cameras;
+}
+
+int camera_get_camera_info(int camera_id, struct camera_info *info)
+{
+ LOG_FUNCTION_NAME
+ int rv = 0;
+ int face_value = CAMERA_FACING_FRONT;
+ int orientation = 0;
+ const char *valstr = NULL;
+ if(camera_id == 0) {
+ info->facing = CAMERA_FACING_BACK;
+ LOGD("cameraHal BACK %d",camera_id);
+ }
+ else {
+ LOGD("cameraHal Front %d",camera_id);
+ info->facing = face_value;
+ }
+ info->orientation = orientation;
+ LOGD("cameraHal %d",camera_id);
+ return rv;
+}
diff --git a/libcamera/CameraHardware.cpp b/libcamera/CameraHardware.cpp
index 1c30f0d..8c90fa4 100644
--- a/libcamera/CameraHardware.cpp
+++ b/libcamera/CameraHardware.cpp
@@ -24,18 +24,26 @@
#include "CameraHardware.h"
#include <fcntl.h>
#include <sys/mman.h>
-
+#include <cutils/native_handle.h>
+#include <hal_public.h>
+#include <ui/GraphicBufferMapper.h>
+#include <gui/ISurfaceTexture.h>
#define MIN_WIDTH 320
#define MIN_HEIGHT 240
#define CAM_SIZE "320x240"
#define PIXEL_FORMAT V4L2_PIX_FMT_YUYV
+#define CAMHAL_GRALLOC_USAGE GRALLOC_USAGE_HW_TEXTURE | \
+ GRALLOC_USAGE_HW_RENDER | \
+ GRALLOC_USAGE_SW_READ_RARELY | \
+ GRALLOC_USAGE_SW_WRITE_NEVER
+
extern "C" {
void yuyv422_to_yuv420sp(unsigned char*,unsigned char*,int,int);
+ void convertYUYVtoRGB565(unsigned char *buf, unsigned char *rgb, int width, int height);
}
namespace android {
-wp<CameraHardwareInterface> CameraHardware::singleton;
const char supportedFpsRanges [] = "(8000,8000),(8000,10000),(10000,10000),(8000,15000),(15000,15000),(8000,20000),(20000,20000),(24000,24000),(25000,25000),(8000,30000),(30000,30000)";
@@ -59,6 +67,7 @@ CameraHardware::CameraHardware(int cameraId)
mMsgEnabled(0)
{
initDefaultParameters();
+ mNativeWindow=NULL;
}
void CameraHardware::initDefaultParameters()
@@ -71,6 +80,7 @@ void CameraHardware::initDefaultParameters()
p.set(p.KEY_SUPPORTED_PREVIEW_SIZES, CAM_SIZE);
p.set(p.KEY_SUPPORTED_PREVIEW_SIZES, "640x480");
p.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,CameraParameters::PIXEL_FORMAT_YUV420SP);
+ p.set(CameraParameters::KEY_FOCUS_MODE,0);
p.setPictureSize(MIN_WIDTH, MIN_HEIGHT);
p.setPictureFormat("jpeg");
p.set(p.KEY_SUPPORTED_PICTURE_SIZES, CAM_SIZE);
@@ -82,7 +92,6 @@ void CameraHardware::initDefaultParameters()
CameraHardware::~CameraHardware()
{
- singleton.clear();
}
sp<IMemoryHeap> CameraHardware::getPreviewHeap() const
@@ -97,18 +106,53 @@ sp<IMemoryHeap> CameraHardware::getRawHeap() const
// ---------------------------------------------------------------------------
-void CameraHardware::setCallbacks(notify_callback notify_cb,
- data_callback data_cb,
- data_callback_timestamp data_cb_timestamp,
+void CameraHardware::setCallbacks(camera_notify_callback notify_cb,
+ camera_data_callback data_cb,
+ camera_data_timestamp_callback data_cb_timestamp,
+ camera_request_memory get_memory,
void *arg)
{
Mutex::Autolock lock(mLock);
mNotifyFn = notify_cb;
mDataFn = data_cb;
+ mRequestMemory = get_memory;
mTimestampFn = data_cb_timestamp;
mUser = arg;
}
+int CameraHardware::setPreviewWindow( preview_stream_ops_t *window)
+{
+ int err;
+ Mutex::Autolock lock(mLock);
+ if(mNativeWindow)
+ mNativeWindow=NULL;
+ if(window==NULL)
+ {
+ LOGW("Window is Null");
+ return 0;
+ }
+ int width, height;
+ mParameters.getPreviewSize(&width, &height);
+ mNativeWindow=window;
+ mNativeWindow->set_usage(mNativeWindow,CAMHAL_GRALLOC_USAGE);
+ mNativeWindow->set_buffers_geometry(
+ mNativeWindow,
+ width,
+ height,
+ HAL_PIXEL_FORMAT_RGB_565);
+ err = mNativeWindow->set_buffer_count(mNativeWindow, 3);
+ if (err != 0) {
+ LOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err), -err);
+
+ if ( ENODEV == err ) {
+ LOGE("Preview surface abandoned!");
+ mNativeWindow = NULL;
+ }
+ }
+
+ return 0;
+}
+
void CameraHardware::enableMsgType(int32_t msgType)
{
Mutex::Autolock lock(mLock);
@@ -132,19 +176,48 @@ bool CameraHardware::msgTypeEnabled(int32_t msgType)
int CameraHardware::previewThread()
{
int width, height;
+ int err;
+ IMG_native_handle_t** hndl2hndl;
+ IMG_native_handle_t* handle;
+ int stride;
mParameters.getPreviewSize(&width, &height);
- if (!previewStopped) {
+ int framesize= width * height * 1.5 ; //yuv420sp
+
+ if (!previewStopped) {
+ mLock.lock();
+ if (mNativeWindow != NULL)
+ {
+ if ((err = mNativeWindow->dequeue_buffer(mNativeWindow,(buffer_handle_t**) &hndl2hndl,&stride)) != 0) {
+ LOGW("Surface::dequeueBuffer returned error %d", err);
+ return -1;
+ }
+ mNativeWindow->lock_buffer(mNativeWindow, (buffer_handle_t*) hndl2hndl);
+ GraphicBufferMapper &mapper = GraphicBufferMapper::get();
+
+ Rect bounds(width, height);
+ void *tempbuf;
+ void *dst;
+ if(0 == mapper.lock((buffer_handle_t)*hndl2hndl,CAMHAL_GRALLOC_USAGE, bounds, &dst));
+ {
// Get preview frame
- camera.GrabPreviewFrame(mHeap->getBase());
+ tempbuf=camera.GrabPreviewFrame();
+ convertYUYVtoRGB565((unsigned char *)tempbuf,(unsigned char *)dst, width, height);
+ mapper.unlock((buffer_handle_t)*hndl2hndl);
+ mNativeWindow->enqueue_buffer(mNativeWindow,(buffer_handle_t*) hndl2hndl);
if ((mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) ||
(mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)) {
+ camera_memory_t* picture = mRequestMemory(-1, framesize, 1, NULL);
+ yuyv422_to_yuv420sp((unsigned char *)tempbuf,(unsigned char *) picture->data, width, height);
if ((mMsgEnabled & CAMERA_MSG_VIDEO_FRAME ) && mRecordRunning ) {
- yuyv422_to_yuv420sp((unsigned char *)mHeap->getBase(), (unsigned char*)mRecordHeap->getBase(), width, height);
nsecs_t timeStamp = systemTime(SYSTEM_TIME_MONOTONIC);
- mTimestampFn(timeStamp, CAMERA_MSG_VIDEO_FRAME,mRecordBuffer, mUser);
+ //mTimestampFn(timeStamp, CAMERA_MSG_VIDEO_FRAME,mRecordBuffer, mUser);
}
- mDataFn(CAMERA_MSG_PREVIEW_FRAME,mBuffer, mUser);
+ mDataFn(CAMERA_MSG_PREVIEW_FRAME,picture,0,NULL,mUser);
}
+ camera.ReleasePreviewFrame();
+ }
+ }
+ mLock.unlock();
}
return NO_ERROR;
@@ -155,12 +228,16 @@ status_t CameraHardware::startPreview()
int ret;
int width, height;
int i;
+ IMG_native_handle_t** hndl2hndl;
+ IMG_native_handle_t* handle;
+ int stride;
char devnode[12];
Mutex::Autolock lock(mLock);
if (mPreviewThread != 0) {
//already running
return INVALID_OPERATION;
}
+#if 1
LOGI("startPreview: in startpreview \n");
mParameters.getPreviewSize(&width, &height);
for( i=0; i<10; i++) {
@@ -197,6 +274,7 @@ status_t CameraHardware::startPreview()
previewStopped = false;
mPreviewThread = new PreviewThread(this);
+#endif
return NO_ERROR;
}
@@ -230,7 +308,8 @@ void CameraHardware::stopPreview()
bool CameraHardware::previewEnabled()
{
- return mPreviewThread != 0;
+ Mutex::Autolock lock(mLock);
+ return ((mPreviewThread != 0) );
}
status_t CameraHardware::startRecording()
@@ -254,8 +333,9 @@ bool CameraHardware::recordingEnabled()
return mRecordRunning;
}
-void CameraHardware::releaseRecordingFrame(const sp<IMemory>& mem)
+void CameraHardware::releaseRecordingFrame(const void *opaque)
{
+
}
// ---------------------------------------------------------------------------
@@ -305,6 +385,7 @@ int CameraHardware::pictureThread()
struct v4l2_capability cap;
int i;
char devnode[12];
+ camera_memory_t* picture = NULL;
if (mMsgEnabled & CAMERA_MSG_SHUTTER)
@@ -330,10 +411,11 @@ int CameraHardware::pictureThread()
camera.Init();
camera.StartStreaming();
-
+ //TODO xxx : Optimize the memory capture call. Too many memcpy
if (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE) {
LOGD ("mJpegPictureCallback");
- mDataFn(CAMERA_MSG_COMPRESSED_IMAGE, camera.GrabJpegFrame(),mUser);
+ picture = camera.GrabJpegFrame(mRequestMemory);
+ mDataFn(CAMERA_MSG_COMPRESSED_IMAGE,picture,0,NULL ,mUser);
}
camera.Uninit();
@@ -347,8 +429,6 @@ status_t CameraHardware::takePicture()
{
LOGD ("takepicture");
stopPreview();
- //if (createThread(beginPictureThread, this) == false)
- // return -1;
pictureThread();
@@ -370,11 +450,6 @@ status_t CameraHardware::setParameters(const CameraParameters& params)
{
Mutex::Autolock lock(mLock);
- if (strcmp(params.getPreviewFormat(), "yuv422sp") != 0) {
- LOGE("Only yuv422sp preview is supported");
- return -1;
- }
-
if (strcmp(params.getPictureFormat(), "jpeg") != 0) {
LOGE("Only jpeg still pictures are supported");
return -1;
@@ -393,6 +468,7 @@ status_t CameraHardware::setParameters(const CameraParameters& params)
mParameters = params;
mParameters.setPreviewSize(w,h);
mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, supportedFpsRanges);
+ mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, "320x240,352x288,640x480,720x480,720x576,848x480");
return NO_ERROR;
}
@@ -417,47 +493,4 @@ void CameraHardware::release()
close(camera_device);
}
-sp<CameraHardwareInterface> CameraHardware::createInstance(int cameraId)
-{
- if (singleton != 0) {
- sp<CameraHardwareInterface> hardware = singleton.promote();
- if (hardware != 0) {
- return hardware;
- }
- }
- sp<CameraHardwareInterface> hardware(new CameraHardware(cameraId));
- singleton = hardware;
- return hardware;
-}
-
-static CameraInfo sCameraInfo[] = {
- {
- facing: CAMERA_FACING_BACK,
- orientation: 0
- },
-/*
- {
- facing: CAMERA_FACING_FRONT,
- orientation: 0
- }
-*/
-};
-
-extern "C" int HAL_getNumberOfCameras()
-{
- return sizeof(sCameraInfo) / sizeof(sCameraInfo[0]);
-}
-
-extern "C" void HAL_getCameraInfo(int cameraId, struct CameraInfo* cameraInfo)
-{
-LOGD("HAL_getCameraInfo: %d", cameraId);
- memcpy(cameraInfo, &sCameraInfo[cameraId], sizeof(CameraInfo));
-}
-
-extern "C" sp<CameraHardwareInterface> HAL_openCameraHardware(int cameraId)
-{
-LOGD("HAL_openCameraHardware: %d", cameraId);
- return CameraHardware::createInstance(cameraId);
-}
-
}; // namespace android
diff --git a/libcamera/CameraHardware.h b/libcamera/CameraHardware.h
index 7491cce..b523668 100644
--- a/libcamera/CameraHardware.h
+++ b/libcamera/CameraHardware.h
@@ -22,31 +22,60 @@
#define ANDROID_HARDWARE_CAMERA_HARDWARE_H
#include <utils/threads.h>
-#include <camera/CameraHardwareInterface.h>
#include <binder/MemoryBase.h>
#include <binder/MemoryHeapBase.h>
#include <utils/threads.h>
+#include <utils/threads.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <utils/Log.h>
+#include <utils/threads.h>
+#include <linux/videodev2.h>
+#include "binder/MemoryBase.h"
+#include "binder/MemoryHeapBase.h"
+#include <utils/threads.h>
+#include <camera/CameraParameters.h>
+#include <hardware/camera.h>
+#include <sys/ioctl.h>
+#include <utils/threads.h>
+#include <binder/MemoryBase.h>
+#include <binder/MemoryHeapBase.h>
+#include <utils/threads.h>
+#include "V4L2Camera.h"
+
+#include <hardware/camera.h>
+
#include <sys/ioctl.h>
#include "V4L2Camera.h"
namespace android {
-class CameraHardware : public CameraHardwareInterface {
+class CameraHardware {
public:
virtual sp<IMemoryHeap> getPreviewHeap() const;
virtual sp<IMemoryHeap> getRawHeap() const;
virtual status_t startPreview();
- virtual void setCallbacks(notify_callback notify_cb,
- data_callback data_cb,
- data_callback_timestamp data_cb_timestamp,
+ virtual void setCallbacks(camera_notify_callback notify_cb,
+ camera_data_callback data_cb,
+ camera_data_timestamp_callback data_cb_timestamp,
+ camera_request_memory get_memory,
void* arg);
/**
* Enable a message, or set of messages.
*/
virtual void enableMsgType(int32_t msgType);
+ virtual int setPreviewWindow( struct preview_stream_ops *window);
/**
* Disable a message, or a set of messages.
*/
@@ -65,7 +94,7 @@ public:
virtual status_t startRecording();
virtual void stopRecording();
virtual bool recordingEnabled();
- virtual void releaseRecordingFrame(const sp<IMemory>& mem);
+ virtual void releaseRecordingFrame(const void* opaque);
virtual status_t autoFocus();
virtual status_t cancelAutoFocus();
@@ -76,14 +105,12 @@ public:
virtual CameraParameters getParameters() const;
virtual void release();
virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2);
+ CameraHardware(int cameraId);
- static sp<CameraHardwareInterface> createInstance(int cameraId);
+ virtual ~CameraHardware();
private:
- CameraHardware(int cameraId);
- virtual ~CameraHardware();
- static wp<CameraHardwareInterface> singleton;
static const int kBufferCount = 4;
@@ -112,8 +139,9 @@ private:
static int beginPictureThread(void *cookie);
int pictureThread();
-
+ camera_request_memory mRequestMemory;
mutable Mutex mLock;
+ preview_stream_ops_t* mNativeWindow;
int mCameraId;
CameraParameters mParameters;
@@ -143,9 +171,9 @@ private:
int nQueued;
int nDequeued;
V4L2Camera camera;
- notify_callback mNotifyFn;
- data_callback mDataFn;
- data_callback_timestamp mTimestampFn;
+ camera_notify_callback mNotifyFn;
+ camera_data_callback mDataFn;
+ camera_data_timestamp_callback mTimestampFn;
void* mUser;
int32_t mMsgEnabled;
diff --git a/libcamera/CameraHardwareInterface.h b/libcamera/CameraHardwareInterface.h
new file mode 100644
index 0000000..35c5aa1
--- /dev/null
+++ b/libcamera/CameraHardwareInterface.h
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_CAMERA_HARDWARE_INTERFACE_H
+#define ANDROID_HARDWARE_CAMERA_HARDWARE_INTERFACE_H
+
+#include <binder/IMemory.h>
+#include <utils/RefBase.h>
+#include <surfaceflinger/ISurface.h>
+#include <camera/Camera.h>
+#include <camera/CameraParameters.h>
+
+namespace android {
+
+class Overlay;
+
+/**
+ * The size of image for display.
+ */
+typedef struct image_rect_struct
+{
+ uint32_t width; /* Image width */
+ uint32_t height; /* Image height */
+} image_rect_type;
+
+
+typedef void (*notify_callback)(int32_t msgType,
+ int32_t ext1,
+ int32_t ext2,
+ void* user);
+
+typedef void (*data_callback)(int32_t msgType,
+ const sp<IMemory>& dataPtr,
+ void* user);
+
+typedef void (*data_callback_timestamp)(nsecs_t timestamp,
+ int32_t msgType,
+ const sp<IMemory>& dataPtr,
+ void* user);
+
+/**
+ * CameraHardwareInterface.h defines the interface to the
+ * camera hardware abstraction layer, used for setting and getting
+ * parameters, live previewing, and taking pictures.
+ *
+ * It is a referenced counted interface with RefBase as its base class.
+ * CameraService calls openCameraHardware() to retrieve a strong pointer to the
+ * instance of this interface and may be called multiple times. The
+ * following steps describe a typical sequence:
+ *
+ * -# After CameraService calls openCameraHardware(), getParameters() and
+ * setParameters() are used to initialize the camera instance.
+ * CameraService calls getPreviewHeap() to establish access to the
+ * preview heap so it can be registered with SurfaceFlinger for
+ * efficient display updating while in preview mode.
+ * -# startPreview() is called. The camera instance then periodically
+ * sends the message CAMERA_MSG_PREVIEW_FRAME (if enabled) each time
+ * a new preview frame is available. If data callback code needs to use
+ * this memory after returning, it must copy the data.
+ *
+ * Prior to taking a picture, CameraService calls autofocus(). When auto
+ * focusing has completed, the camera instance sends a CAMERA_MSG_FOCUS notification,
+ * which informs the application whether focusing was successful. The camera instance
+ * only sends this message once and it is up to the application to call autoFocus()
+ * again if refocusing is desired.
+ *
+ * CameraService calls takePicture() to request the camera instance take a
+ * picture. At this point, if a shutter, postview, raw, and/or compressed callback
+ * is desired, the corresponding message must be enabled. As with CAMERA_MSG_PREVIEW_FRAME,
+ * any memory provided in a data callback must be copied if it's needed after returning.
+ */
+class CameraHardwareInterface : public virtual RefBase {
+public:
+ virtual ~CameraHardwareInterface() { }
+
+ /** Return the IMemoryHeap for the preview image heap */
+ virtual sp<IMemoryHeap> getPreviewHeap() const = 0;
+
+ /** Return the IMemoryHeap for the raw image heap */
+ virtual sp<IMemoryHeap> getRawHeap() const = 0;
+
+ /** Set the notification and data callbacks */
+ virtual void setCallbacks(notify_callback notify_cb,
+ data_callback data_cb,
+ data_callback_timestamp data_cb_timestamp,
+ void* user) = 0;
+
+ /**
+ * The following three functions all take a msgtype,
+ * which is a bitmask of the messages defined in
+ * include/ui/Camera.h
+ */
+
+ /**
+ * Enable a message, or set of messages.
+ */
+ virtual void enableMsgType(int32_t msgType) = 0;
+
+ /**
+ * Disable a message, or a set of messages.
+ */
+ virtual void disableMsgType(int32_t msgType) = 0;
+
+ /**
+ * Query whether a message, or a set of messages, is enabled.
+ * Note that this is operates as an AND, if any of the messages
+ * queried are off, this will return false.
+ */
+ virtual bool msgTypeEnabled(int32_t msgType) = 0;
+
+ /**
+ * Start preview mode.
+ */
+ virtual status_t startPreview() = 0;
+
+ /**
+ * Only used if overlays are used for camera preview.
+ */
+ virtual bool useOverlay() {return false;}
+ virtual status_t setOverlay(const sp<Overlay> &overlay) {return BAD_VALUE;}
+
+ /**
+ * Stop a previously started preview.
+ */
+ virtual void stopPreview() = 0;
+
+ /**
+ * Returns true if preview is enabled.
+ */
+ virtual bool previewEnabled() = 0;
+
+ /**
+ * Start record mode. When a record image is available a CAMERA_MSG_VIDEO_FRAME
+ * message is sent with the corresponding frame. Every record frame must be released
+ * by calling releaseRecordingFrame().
+ */
+ virtual status_t startRecording() = 0;
+
+ /**
+ * Stop a previously started recording.
+ */
+ virtual void stopRecording() = 0;
+
+ /**
+ * Returns true if recording is enabled.
+ */
+ virtual bool recordingEnabled() = 0;
+
+ /**
+ * Release a record frame previously returned by CAMERA_MSG_VIDEO_FRAME.
+ */
+ virtual void releaseRecordingFrame(const sp<IMemory>& mem) = 0;
+
+ /**
+ * Start auto focus, the notification callback routine is called
+ * with CAMERA_MSG_FOCUS once when focusing is complete. autoFocus()
+ * will be called again if another auto focus is needed.
+ */
+ virtual status_t autoFocus() = 0;
+
+ /**
+ * Cancels auto-focus function. If the auto-focus is still in progress,
+ * this function will cancel it. Whether the auto-focus is in progress
+ * or not, this function will return the focus position to the default.
+ * If the camera does not support auto-focus, this is a no-op.
+ */
+ virtual status_t cancelAutoFocus() = 0;
+
+ /**
+ * Take a picture.
+ */
+ virtual status_t takePicture() = 0;
+
+ /**
+ * Cancel a picture that was started with takePicture. Calling this
+ * method when no picture is being taken is a no-op.
+ */
+ virtual status_t cancelPicture() = 0;
+
+ /**
+ * Set the camera parameters. This returns BAD_VALUE if any parameter is
+ * invalid or not supported. */
+ virtual status_t setParameters(const CameraParameters& params) = 0;
+
+ /** Return the camera parameters. */
+ virtual CameraParameters getParameters() const = 0;
+
+ /**
+ * Send command to camera driver.
+ */
+ virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) = 0;
+
+ /**
+ * Release the hardware resources owned by this object. Note that this is
+ * *not* done in the destructor.
+ */
+ virtual void release() = 0;
+
+ /**
+ * Dump state of the camera hardware
+ */
+ virtual status_t dump(int fd, const Vector<String16>& args) const = 0;
+};
+
+/**
+ * The functions need to be provided by the camera HAL.
+ *
+ * If getNumberOfCameras() returns N, the valid cameraId for getCameraInfo()
+ * and openCameraHardware() is 0 to N-1.
+ */
+extern "C" int HAL_getNumberOfCameras();
+extern "C" void HAL_getCameraInfo(int cameraId, struct CameraInfo* cameraInfo);
+/* HAL should return NULL if it fails to open camera hardware. */
+extern "C" sp<CameraHardwareInterface> HAL_openCameraHardware(int cameraId);
+
+}; // namespace android
+
+#endif
diff --git a/libcamera/V4L2Camera.cpp b/libcamera/V4L2Camera.cpp
index 78e17b0..90fc123 100644
--- a/libcamera/V4L2Camera.cpp
+++ b/libcamera/V4L2Camera.cpp
@@ -17,6 +17,7 @@
extern "C" { /* Android jpeglib.h missed extern "C" */
#include <jpeglib.h>
+ void convertYUYVtoRGB565(unsigned char *buf, unsigned char *rgb, int width, int height);
}
namespace android {
@@ -198,7 +199,7 @@ int V4L2Camera::StopStreaming ()
return 0;
}
-void V4L2Camera::GrabPreviewFrame (void *previewBuffer)
+void * V4L2Camera::GrabPreviewFrame ()
{
unsigned char *tmpBuffer;
int ret;
@@ -209,21 +210,22 @@ void V4L2Camera::GrabPreviewFrame (void *previewBuffer)
/* DQ */
ret = ioctl(fd, VIDIOC_DQBUF, &videoIn->buf);
if (ret < 0) {
- //LOGE("GrabPreviewFrame: VIDIOC_DQBUF Failed");
-
- return;
+ LOGE("GrabPreviewFrame: VIDIOC_DQBUF Failed");
+ return NULL;
}
nDequeued++;
+ return videoIn->mem[videoIn->buf.index];
+}
- memcpy (previewBuffer, videoIn->mem[videoIn->buf.index], (size_t) videoIn->buf.bytesused);
+void V4L2Camera::ReleasePreviewFrame ()
+{
+ int ret;
ret = ioctl(fd, VIDIOC_QBUF, &videoIn->buf);
+ nQueued++;
if (ret < 0) {
LOGE("GrabPreviewFrame: VIDIOC_QBUF Failed");
return;
}
-
- nQueued++;
-
}
@@ -296,7 +298,7 @@ int MemoryStream::readPipe()
return 0;
}
-sp<IMemory> V4L2Camera::GrabJpegFrame ()
+camera_memory_t* V4L2Camera::GrabJpegFrame (camera_request_memory mRequestMemory)
{
int ret;
@@ -327,13 +329,11 @@ sp<IMemory> V4L2Camera::GrabJpegFrame ()
saveYUYVtoJPEG((unsigned char *)videoIn->mem[videoIn->buf.index], videoIn->width, videoIn->height, strm, 100);
strm.closeStream();
size_t fileSize = strm.getOffset();
-
- sp<MemoryHeapBase> mjpegPictureHeap = new MemoryHeapBase(fileSize);
- sp<MemoryBase> jpegmemBase = new MemoryBase(mjpegPictureHeap, 0, fileSize);
- memcpy(mjpegPictureHeap->base(), tmpBuf, fileSize);
+ camera_memory_t* picture = mRequestMemory(-1,fileSize,1,NULL);
+ memcpy(picture->data, tmpBuf, fileSize);
delete[] tmpBuf;
- return jpegmemBase;
+ return picture;
}
return NULL;
diff --git a/libcamera/V4L2Camera.h b/libcamera/V4L2Camera.h
index 97255ec..03aa0c7 100644
--- a/libcamera/V4L2Camera.h
+++ b/libcamera/V4L2Camera.h
@@ -17,6 +17,7 @@
#include <binder/MemoryHeapBase.h>
#include <linux/videodev.h>
+#include <hardware/camera.h>
namespace android {
struct vdIn {
@@ -47,9 +48,10 @@ public:
int StartStreaming ();
int StopStreaming ();
- void GrabPreviewFrame (void *previewBuffer);
+ void * GrabPreviewFrame ();
+ void ReleasePreviewFrame ();
sp<IMemory> GrabRawFrame ();
- sp<IMemory> GrabJpegFrame ();
+ camera_memory_t* GrabJpegFrame (camera_request_memory mRequestMemory);
private:
struct vdIn *videoIn;
diff --git a/libcamera/V4L2CameraHal.h b/libcamera/V4L2CameraHal.h
new file mode 100644
index 0000000..e55d78d
--- /dev/null
+++ b/libcamera/V4L2CameraHal.h
@@ -0,0 +1,151 @@
+
+#include <utils/threads.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <utils/Log.h>
+#include <utils/threads.h>
+#include <linux/videodev2.h>
+#include "binder/MemoryBase.h"
+#include "binder/MemoryHeapBase.h"
+#include <utils/threads.h>
+#include <camera/CameraParameters.h>
+#include <hardware/camera.h>
+#include <sys/ioctl.h>
+#include <utils/threads.h>
+
+using namespace android;
+ class PreviewThread : public Thread {
+ //CameraHardware* mHardware;
+ public:
+ PreviewThread(/*CameraHardware* hw*/)
+ : Thread(false)/*, mHardware(hw)*/ { }
+ virtual void onFirstRef() {
+ run("CameraPreviewThread", PRIORITY_URGENT_DISPLAY);
+ }
+ virtual bool threadLoop() {
+ //mHardware->previewThread();
+ // loop until we need to quit
+ return true;
+ }
+ };
+class V4L2CameraHal : public RefBase
+{
+ V4L2Camera camera;
+
+ // protected by mLock
+ sp<PreviewThread> mPreviewThread;
+ static CameraParameters mParameters;
+ static int32_t mMsgEnabled;
+/**
+ * Enable a message, or set of messages.
+ */
+ virtual void enableMsgType(int32_t msgType);
+
+ /**
+ * Disable a message, or a set of messages.
+ */
+ virtual void disableMsgType(int32_t msgType);
+
+ /**
+ * Query whether a message, or a set of messages, is enabled.
+ * Note that this is operates as an AND, if any of the messages
+ * queried are off, this will return false.
+ */
+ virtual bool msgTypeEnabled(int32_t msgType);
+
+ virtual void stopPreview();
+ virtual bool previewEnabled();
+
+ virtual status_t startRecording();
+ virtual void stopRecording();
+ virtual bool recordingEnabled();
+ virtual void releaseRecordingFrame(const sp<IMemory>& mem);
+
+ virtual status_t autoFocus();
+ virtual status_t cancelAutoFocus();
+ virtual status_t takePicture();
+ virtual status_t cancelPicture();
+ virtual status_t dump(int fd, const Vector<String16>& args) const;
+ virtual status_t setParameters(const CameraParameters& params);
+ virtual CameraParameters getParameters() const;
+ virtual void release();
+ virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2);
+private:
+ virtual ~CameraHardware();
+
+ static wp<CameraHardwareInterface> singleton;
+
+ static const int kBufferCount = 4;
+
+ class PreviewThread : public Thread {
+ CameraHardware* mHardware;
+ public:
+ PreviewThread(CameraHardware* hw)
+ : Thread(false), mHardware(hw) { }
+ virtual void onFirstRef() {
+ run("CameraPreviewThread", PRIORITY_URGENT_DISPLAY);
+ }
+ virtual bool threadLoop() {
+ mHardware->previewThread();
+ // loop until we need to quit
+ return true;
+ }
+ };
+
+ void initDefaultParameters();
+ bool initHeapLocked();
+
+ int previewThread();
+
+ static int beginAutoFocusThread(void *cookie);
+ int autoFocusThread();
+
+ static int beginPictureThread(void *cookie);
+ int pictureThread();
+
+ mutable Mutex mLock;
+
+ int mCameraId;
+ CameraParameters mParameters;
+
+ sp<MemoryHeapBase> mHeap;
+ sp<MemoryBase> mBuffer;
+
+ sp<MemoryHeapBase> mPreviewHeap;
+ sp<MemoryHeapBase> mRawHeap;
+ sp<MemoryHeapBase> mRecordHeap;
+ sp<MemoryBase> mRecordBuffer;
+
+ bool mPreviewRunning;
+ bool mRecordRunning;
+ int mPreviewFrameSize;
+
+ // protected by mLock
+ sp<PreviewThread> mPreviewThread;
+
+ // only used from PreviewThread
+ int mCurrentPreviewFrame;
+
+ void * framebuffer;
+ bool previewStopped;
+ int camera_device;
+ void* mem[4];
+ int nQueued;
+ int nDequeued;
+ V4L2Camera camera;
+ notify_callback mNotifyFn;
+ data_callback mDataFn;
+ data_callback_timestamp mTimestampFn;
+ void* mUser;
+ int32_t mMsgEnabled;
+
+
+}
diff --git a/libcamera/rgbconvert.c b/libcamera/rgbconvert.c
new file mode 100644
index 0000000..d1e832b
--- /dev/null
+++ b/libcamera/rgbconvert.c
@@ -0,0 +1,50 @@
+static void yuv_to_rgb16(unsigned char y, unsigned char u, unsigned char v, unsigned char *rgb)
+{
+ int r,g,b;
+ int z;
+ int rgb16;
+
+ z = 0;
+
+ r = 1.164 * (y - 16) + 1.596 * (v - 128);
+ g = 1.164 * (y - 16) - 0.813 * (v - 128) - 0.391 * (u -128);
+ b = 1.164 * (y - 16) + 2.018 * (u - 128);
+
+ if (r > 255) r = 255;
+ if (g > 255) g = 255;
+ if (b > 255) b = 255;
+
+ if (r < 0) r = 0;
+ if (g < 0) g = 0;
+ if (b < 0) b = 0;
+
+ rgb16 = (int)(((r >> 3)<<11) | ((g >> 2) << 5)| ((b >> 3) << 0));
+
+ *rgb = (unsigned char)(rgb16 & 0xFF);
+ rgb++;
+ *rgb = (unsigned char)((rgb16 & 0xFF00) >> 8);
+
+}
+
+
+void convertYUYVtoRGB565(unsigned char *buf, unsigned char *rgb, int width, int height)
+{
+ int x,y,z=0;
+ int blocks;
+
+ blocks = (width * height) * 2;
+
+ for (y = 0; y < blocks; y+=4) {
+ unsigned char Y1, Y2, U, V;
+
+ Y1 = buf[y + 0];
+ U = buf[y + 1];
+ Y2 = buf[y + 2];
+ V = buf[y + 3];
+
+ yuv_to_rgb16(Y1, U, V, &rgb[y]);
+ yuv_to_rgb16(Y2, U, V, &rgb[y + 2]);
+ }
+
+}
+