/* * 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 <hardware/camera.h> #include <utils/Log.h> #include <utils/threads.h> #include <utils/threads.h> #include <binder/MemoryBase.h> #include <binder/MemoryHeapBase.h> #include <camera/CameraParameters.h> #ifdef OMAP_ENHANCEMENT_CPCAM #include <camera/CameraMetadata.h> #include <camera/ShotParameters.h> #endif #include <ui/GraphicBufferAllocator.h> #include <ui/GraphicBuffer.h> /* For IMG_native_handle_t */ #include <ui/GraphicBufferMapper.h> #include <hal_public.h> #include <ion/ion.h> #include "Common.h" #include "MessageQueue.h" #include "Semaphore.h" #include "CameraProperties.h" #include "SensorListener.h" //temporarily define format here #define HAL_PIXEL_FORMAT_TI_NV12 0x100 #define HAL_PIXEL_FORMAT_TI_Y8 0x103 #define HAL_PIXEL_FORMAT_TI_Y16 0x104 #define HAL_PIXEL_FORMAT_TI_UYVY 0x105 #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 FRAME_RATE_HIGH_HD 60 #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 OP_STR_SIZE 100 #define NONNEG_ASSIGN(x,y) \ if(x > -1) \ y = x #define CAMHAL_SIZE_OF_ARRAY(x) static_cast<int>(sizeof(x)/sizeof(x[0])) namespace Ti { namespace Camera { #ifdef CAMERAHAL_USE_RAW_IMAGE_SAVING extern const char * const kRawImagesOutputDirPath; extern const char * const kYuvImagesOutputDirPath; #endif #define V4L_CAMERA_NAME_USB "USBCAMERA" #define OMX_CAMERA_NAME_OV "OV5640" #define OMX_CAMERA_NAME_SONY "IMX060" ///Forward declarations class CameraHal; class CameraFrame; class CameraHalEvent; class DisplayFrame; class FpsRange { public: static int compare(const FpsRange * left, const FpsRange * right); FpsRange(int min, int max); FpsRange(); bool operator==(const FpsRange & fpsRange) const; bool isNull() const; bool isFixed() const; int min() const; int max() const; private: int mMin; int mMax; }; inline int FpsRange::compare(const FpsRange * const left, const FpsRange * const right) { if ( left->max() < right->max() ) { return -1; } if ( left->max() > right->max() ) { return 1; } if ( left->min() < right->min() ) { return -1; } if ( left->min() > right->min() ) { return 1; } return 0; } inline FpsRange::FpsRange(const int min, const int max) : mMin(min), mMax(max) {} inline FpsRange::FpsRange() : mMin(-1), mMax(-1) {} inline bool FpsRange::operator==(const FpsRange & fpsRange) const { return mMin == fpsRange.mMin && mMax == fpsRange.mMax; } inline bool FpsRange::isNull() const { return mMin == -1 || mMax == -1; } inline bool FpsRange::isFixed() const { return mMin == mMax; } inline int FpsRange::min() const { return mMin; } inline int FpsRange::max() const { return mMax; } class CameraArea : public android::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 android::sp<CameraArea> &area); static status_t parseAreas(const char *area, size_t areaLength, android::Vector< android::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(android::Vector< android::sp<CameraArea> > &, android::Vector< android::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 CameraMetadataResult : public android::RefBase { public: #ifdef OMAP_ENHANCEMENT_CPCAM CameraMetadataResult(camera_memory_t * extMeta) : mExtendedMetadata(extMeta) { mMetadata.faces = NULL; mMetadata.number_of_faces = 0; #ifdef OMAP_ENHANCEMENT mMetadata.analog_gain = 0; mMetadata.exposure_time = 0; #endif }; #endif CameraMetadataResult() { mMetadata.faces = NULL; mMetadata.number_of_faces = 0; #ifdef OMAP_ENHANCEMENT_CPCAM mMetadata.analog_gain = 0; mMetadata.exposure_time = 0; #endif #ifdef OMAP_ENHANCEMENT_CPCAM mExtendedMetadata = NULL; #endif } virtual ~CameraMetadataResult() { if ( NULL != mMetadata.faces ) { free(mMetadata.faces); } #ifdef OMAP_ENHANCEMENT_CPCAM if ( NULL != mExtendedMetadata ) { mExtendedMetadata->release(mExtendedMetadata); } #endif } camera_frame_metadata_t *getMetadataResult() { return &mMetadata; }; #ifdef OMAP_ENHANCEMENT_CPCAM camera_memory_t *getExtendedMetadata() { return mExtendedMetadata; }; #endif 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 mMetadata; #ifdef OMAP_ENHANCEMENT_CPCAM camera_memory_t *mExtendedMetadata; #endif }; typedef enum { CAMERA_BUFFER_NONE = 0, CAMERA_BUFFER_GRALLOC, CAMERA_BUFFER_ANW, CAMERA_BUFFER_MEMORY, CAMERA_BUFFER_ION } CameraBufferType; typedef struct _CameraBuffer { CameraBufferType type; /* opaque is the generic drop-in replacement for the pointers * that were used previously */ void *opaque; /* opaque has different meanings depending on the buffer type: * GRALLOC - gralloc_handle_t * ANW - a pointer to the buffer_handle_t (which corresponds to * the ANativeWindowBuffer *) * MEMORY - address of allocated memory * ION - address of mapped ion allocation * * FIXME opaque should be split into several fields: * - handle/pointer we got from the allocator * - handle/value we pass to OMX * - pointer to mapped memory (if the buffer is mapped) */ /* mapped holds ptr to mapped memory in userspace */ void *mapped; /* These are specific to ION buffers */ struct ion_handle * ion_handle; int ion_fd; int fd; size_t size; int index; /* These describe the camera buffer */ int width; int stride; int height; const char *format; #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS struct timeval ppmStamp; #endif /* These are for buffers which include borders */ int offset; // where valid data starts int actual_size; // size of the entire buffer with borders } CameraBuffer; void * camera_buffer_get_omx_ptr (CameraBuffer *buffer); 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, REPROCESS_INPUT_FRAME = 0x400, ALL_FRAMES = 0xFFFF ///Maximum of 16 frame types supported }; enum FrameQuirks { ENCODE_RAW_YUV422I_TO_JPEG = 0x1 << 0, HAS_EXIF_DATA = 0x1 << 1, FORMAT_YUV422I_YUYV = 0x1 << 2, FORMAT_YUV422I_UYVY = 0x1 << 3, }; //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] = 0; mYuv[1] = 0; #ifdef OMAP_ENHANCEMENT_CPCAM mMetaData = 0; #endif } void *mCookie; void *mCookie2; CameraBuffer *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]; #ifdef OMAP_ENHANCEMENT_CPCAM android::sp<CameraMetadataResult> mMetaData; #endif ///@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_METADATA = 0x10, ///@remarks Future enum related to display, like frame displayed event, could be added here ALL_EVENTS = 0xFFFF ///Maximum of 16 event types supported }; enum FocusStatus { FOCUS_STATUS_SUCCESS = 0x1, FOCUS_STATUS_FAIL = 0x2, FOCUS_STATUS_PENDING = 0x4, FOCUS_STATUS_DONE = 0x8, }; ///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 { FocusStatus focusStatus; 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 android::sp<CameraMetadataResult> MetaEventData; class CameraHalEventData : public android::RefBase{ public: CameraHalEvent::FocusEventData focusEvent; CameraHalEvent::ZoomEventData zoomEvent; CameraHalEvent::ShutterEventData shutterEvent; CameraHalEvent::MetaEventData metadataEvent; }; //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; android::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 android::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(CameraBuffer* frameBuf, CameraFrame::FrameType frameType) = 0; virtual void addFramePointers(CameraBuffer *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(CameraBuffer *frameBuf, CameraFrame::FrameType frameType); void addFramePointers(CameraBuffer *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 CameraBuffer * allocateBufferList(int width, int height, const char* format, int &bytes, int numBufs) = 0; // gets a buffer list from BufferProvider when buffers are sent from external source and already pre-allocated // only call this function for an input source into CameraHal. If buffers are not from a pre-allocated source // this function will return NULL and numBufs of -1 virtual CameraBuffer *getBufferList(int *numBufs) = 0; //additional methods used for memory mapping virtual uint32_t * getOffsets() = 0; virtual int getFd() = 0; virtual CameraBuffer * getBuffers(bool reset = false) { return NULL; } virtual unsigned int getSize() {return 0; } virtual int getBufferCount() {return -1; } virtual int freeBufferList(CameraBuffer * buf) = 0; virtual ~BufferProvider() {} }; /** * Class for handling data and notify callbacks to application */ class AppCallbackNotifier: public ErrorNotifier , public virtual android::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(android::CameraParameters ¶ms, CameraBuffer *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(CameraBuffer *buffers, uint32_t *offsets, int fd, size_t length, size_t count, CameraBuffer *vidBufs); status_t releaseRecordingFrame(const void *opaque); status_t useMetaDataBufferMode(bool enable); void EncoderDoneCb(void*, void*, CameraFrame::FrameType type, void* cookie1, void* cookie2, void *cookie3); void useVideoBuffers(bool useVideoBuffers); bool getUesVideoBuffers(); void setVideoRes(int width, int height); void flushEventQueue(); //Internal class definitions class NotificationThread : public android::Thread { AppCallbackNotifier* mAppCallbackNotifier; Utils::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(); } Utils::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); size_t calculateBufferSize(size_t width, size_t height, const char *pixelFormat); const char* getContstantForPixelFormat(const char *pixelFormat); private: mutable android::Mutex mLock; mutable android::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 android::KeyedVector<unsigned int, unsigned int> mVideoHeaps; android::KeyedVector<unsigned int, unsigned int> mVideoBuffers; android::KeyedVector<void *, CameraBuffer *> mVideoMap; //Keeps list of Gralloc handles and associated Video Metadata Buffers android::KeyedVector<void *, camera_memory_t *> mVideoMetadataBufferMemoryMap; android::KeyedVector<void *, CameraBuffer *> mVideoMetadataBufferReverseMap; bool mBufferReleased; android::sp< NotificationThread> mNotificationThread; EventProvider *mEventProvider; FrameProvider *mFrameProvider; Utils::MessageQueue mEventQ; Utils::MessageQueue mFrameQ; NotifierState mNotifierState; bool mPreviewing; camera_memory_t* mPreviewMemory; CameraBuffer mPreviewBuffers[MAX_BUFFERS]; int mPreviewBufCount; int mPreviewWidth; int mPreviewHeight; int mPreviewStride; const char *mPreviewPixelFormat; android::KeyedVector<unsigned int, android::sp<android::MemoryHeapBase> > mSharedPreviewHeaps; android::KeyedVector<unsigned int, android::sp<android::MemoryBase> > mSharedPreviewBuffers; //Burst mode active bool mBurst; mutable android::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 android::RefBase { public: MemoryManager(); ~MemoryManager(); status_t initialize(); int setErrorHandler(ErrorNotifier *errorNotifier); virtual CameraBuffer * allocateBufferList(int width, int height, const char* format, int &bytes, int numBufs); virtual CameraBuffer *getBufferList(int *numBufs); virtual uint32_t * getOffsets(); virtual int getFd() ; virtual int freeBufferList(CameraBuffer * buflist); private: android::sp<ErrorNotifier> mErrorNotifier; int mIonFd; }; /** * 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 android::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, LOADED_REPROCESS_ACTIVE = 1 << 9, REPROCESS_ACTIVE = 1 << 10, }; public: typedef struct { CameraBuffer *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, CAMERA_USE_BUFFERS_VIDEO_CAPTURE = 25, #ifdef OMAP_ENHANCEMENT_CPCAM CAMERA_USE_BUFFERS_REPROCESS = 26, CAMERA_START_REPROCESS = 27, #endif #ifdef OMAP_ENHANCEMENT_VTC CAMERA_SETUP_TUNNEL = 28, CAMERA_DESTROY_TUNNEL = 29, #endif CAMERA_PREVIEW_INITIALIZATION = 30, }; enum CameraMode { CAMERA_PREVIEW, CAMERA_IMAGE_CAPTURE, CAMERA_VIDEO, CAMERA_MEASUREMENT, CAMERA_REPROCESS, }; 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, LOADED_REPROCESS_STATE = LOADED_REPROCESS_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE, LOADED_REPROCESS_CAPTURE_STATE = LOADED_REPROCESS_ACTIVE | LOADED_CAPTURE_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE, REPROCESS_STATE = REPROCESS_ACTIVE | CAPTURE_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(CameraBuffer* frameBuf, CameraFrame::FrameType frameType) = 0; virtual void addFramePointers(CameraBuffer *frameBuf, void *buf) = 0; virtual void removeFramePointers() = 0; //APIs to configure Camera adapter and get the current parameter set virtual int setParameters(const android::CameraParameters& params) = 0; virtual void getParameters(android::CameraParameters& params) = 0; //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, int value4=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; virtual status_t setSharedAllocator(camera_request_memory shmem_alloc) = 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 android::RefBase { public: DisplayAdapter(); #ifdef OMAP_ENHANCEMENT preview_stream_extended_ops_t * extendedOps() const { return mExtendedOps; } void setExtendedOps(preview_stream_extended_ops_t * extendedOps); #endif ///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) = 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 bool supportsExternalBuffering() = 0; // Get max queueable buffers display supports // This function should only be called after // allocateBufferList virtual status_t maxQueueableBuffers(unsigned int& queueable) = 0; // Get min buffers display needs at any given time virtual status_t minUndequeueableBuffers(int& unqueueable) = 0; // Given a vector of DisplayAdapters find the one corresponding to str virtual bool match(const char * str) { return false; } private: #ifdef OMAP_ENHANCEMENT preview_stream_extended_ops_t * mExtendedOps; #endif }; 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 int NO_BUFFERS_IMAGE_CAPTURE_SYSTEM_HEAP; 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(); /** * Set preview mode related initialization. * Only used when slice based processing is enabled. */ int cameraPreviewInitialization(); /** * Only used if overlays are used for camera preview. */ int setPreviewWindow(struct preview_stream_ops *window); #ifdef OMAP_ENHANCEMENT_CPCAM void setExtendedPreviewStreamOps(preview_stream_extended_ops_t *ops); /** * Set a tap-in or tap-out point. */ int setBufferSource(struct preview_stream_ops *tapin, struct preview_stream_ops *tapout); #endif /** * Release a tap-in or tap-out point. */ int releaseBufferSource(struct preview_stream_ops *tapin, struct preview_stream_ops *tapout); /** * 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(const char* params); /** * 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 android::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; #ifdef OMAP_ENHANCEMENT_CPCAM /** * start a reprocessing operation. */ int reprocess(const char* params); /** * cancels current reprocessing operation */ int cancel_reprocess(); #endif 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); static const char* getPixelFormatConstant(const char* parameters_format); static size_t calculateBufferSize(const char* parameters_format, int width, int height); static void getXYFromOffset(unsigned int *x, unsigned int *y, unsigned int offset, unsigned int stride, const char* format); static unsigned int getBPP(const char* format); /*--------------------Internal Member functions - Private---------------------------------*/ private: /** @name internalFunctionsPrivate */ //@{ /** Set the camera parameters specific to Video Recording. */ bool setVideoModeParameters(const android::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); /** Allocate Raw buffers */ status_t allocRawBufs(int width, int height, const char* previewFormat, int bufferCount); /** Free preview buffers */ status_t freePreviewBufs(); /** Free video bufs */ status_t freeVideoBufs(CameraBuffer *bufs); /** Free RAW bufs */ status_t freeRawBufs(); //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 variable frame rate range is supported by the current camera //instance bool isFpsRangeValid(int fpsMin, int fpsMax, const char *supportedFpsRanges); //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 getPreferredPreviewRes(int *width, int *height); void resetPreviewRes(android::CameraParameters *params); // Internal __takePicture function - used in public takePicture() and reprocess() int __takePicture(const char* params, struct timeval *captureStart = NULL); //@} status_t setTapoutLocked(struct preview_stream_ops *out); status_t releaseTapoutLocked(struct preview_stream_ops *out); status_t setTapinLocked(struct preview_stream_ops *in); status_t releaseTapinLocked(struct preview_stream_ops *in); /*----------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; android::sp<AppCallbackNotifier> mAppCallbackNotifier; android::sp<DisplayAdapter> mDisplayAdapter; android::sp<MemoryManager> mMemoryManager; android::Vector< android::sp<DisplayAdapter> > mOutAdapters; android::Vector< android::sp<DisplayAdapter> > mInAdapters; // TODO(XXX): Even though we support user setting multiple BufferSourceAdapters now // only one tap in surface and one tap out surface is supported at a time. android::sp<DisplayAdapter> mBufferSourceAdapter_In; android::sp<DisplayAdapter> mBufferSourceAdapter_Out; #ifdef OMAP_ENHANCEMENT preview_stream_extended_ops_t * mExtendedPreviewStreamOps; #endif android::sp<android::IMemoryHeap> mPictureHeap; int* mGrallocHandles; bool mFpsRangeChangedByApp; int mRawWidth; int mRawHeight; bool mRawCapture; ///static member vars static const int SW_SCALING_FPS_LIMIT; #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; #ifdef OMAP_ENHANCEMENT_VTC bool mTunnelSetup; bool mVTCUseCase; #endif //Index of current camera adapter int mCameraIndex; mutable android::Mutex mLock; android::sp<SensorListener> mSensorListener; void* mCameraAdapterHandle; android::CameraParameters mParameters; bool mPreviewRunning; bool mPreviewStateOld; bool mRecordingEnabled; EventProvider *mEventProvider; CameraBuffer *mPreviewDataBuffers; uint32_t *mPreviewDataOffsets; int mPreviewDataFd; int mPreviewDataLength; CameraBuffer *mImageBuffers; uint32_t *mImageOffsets; int mImageFd; int mImageLength; unsigned int mImageCount; CameraBuffer *mPreviewBuffers; uint32_t *mPreviewOffsets; int mPreviewLength; int mPreviewFd; CameraBuffer *mVideoBuffers; 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 mPreviewInitializationDone; bool mSetPreviewWindowCalled; uint32_t mPreviewWidth; uint32_t mPreviewHeight; int32_t mMaxZoomSupported; int mVideoWidth; int mVideoHeight; android::String8 mCapModeBackup; }; } // namespace Camera } // namespace Ti #endif