/*
** Copyright 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_QUALCOMM_CAMERA_HARDWARE_H
#define ANDROID_HARDWARE_QUALCOMM_CAMERA_HARDWARE_H
#include <camera/CameraHardwareInterface.h>
#include <binder/MemoryBase.h>
#include <binder/MemoryHeapBase.h>
extern "C" {
#include <linux/android_pmem.h>
}
namespace android {
class QualcommCameraHardware : public CameraHardwareInterface {
public:
virtual sp<IMemoryHeap> getPreviewHeap() const;
virtual sp<IMemoryHeap> getRawHeap() const;
virtual status_t dump(int fd, const Vector<String16>& args) const;
virtual status_t startPreview(preview_callback cb, void* user);
virtual void stopPreview();
virtual bool previewEnabled();
virtual status_t startRecording(recording_callback cb, void* user);
virtual void stopRecording();
virtual bool recordingEnabled();
virtual void releaseRecordingFrame(const sp<IMemory>& mem);
virtual status_t autoFocus(autofocus_callback, void *user);
virtual status_t takePicture(shutter_callback,
raw_callback,
jpeg_callback,
void* user);
virtual status_t cancelPicture(bool cancel_shutter,
bool cancel_raw, bool cancel_jpeg);
virtual status_t setParameters(const CameraParameters& params);
virtual CameraParameters getParameters() const;
virtual void release();
static sp<CameraHardwareInterface> createInstance();
static sp<QualcommCameraHardware> getInstance();
void* get_preview_mem(uint32_t size, uint32_t *phy_addr, uint32_t index);
void* get_raw_mem(uint32_t size, uint32_t *phy_addr, uint32_t index);
void free_preview_mem(uint32_t *phy_addr, uint32_t size, uint32_t index);
void free_raw_mem(uint32_t *phy_addr, uint32_t size, uint32_t index);
private:
QualcommCameraHardware();
virtual ~QualcommCameraHardware();
status_t startPreviewInternal(preview_callback pcb, void *puser,
recording_callback rcb, void *ruser);
void stopPreviewInternal();
static wp<QualcommCameraHardware> singleton;
/* These constants reflect the number of buffers that libqcamera requires
for preview and raw, and need to be updated when libqcamera
changes.
*/
static const int kPreviewBufferCount = 4;
static const int kRawBufferCount = 1;
static const int kJpegBufferCount = 1;
static const int kRawFrameHeaderSize = 0x48;
//TODO: put the picture dimensions in the CameraParameters object;
CameraParameters mParameters;
int mPreviewHeight;
int mPreviewWidth;
int mRawHeight;
int mRawWidth;
void receivePreviewFrame(camera_frame_type *frame);
static void stop_camera_cb(camera_cb_type cb,
const void *client_data,
camera_func_type func,
int32_t parm4);
static void camera_cb(camera_cb_type cb,
const void *client_data,
camera_func_type func,
int32_t parm4);
// This class represents a heap which maintains several contiguous
// buffers. The heap may be backed by pmem (when pmem_pool contains
// the name of a /dev/pmem* file), or by ashmem (when pmem_pool == NULL).
struct MemPool : public RefBase {
MemPool(int buffer_size, int num_buffers,
int frame_size,
int frame_offset,
const char *name);
virtual ~MemPool() = 0;
void completeInitialization();
bool initialized() const {
return mHeap != NULL && mHeap->base() != MAP_FAILED;
}
virtual status_t dump(int fd, const Vector<String16>& args) const;
int mBufferSize;
int mNumBuffers;
int mFrameSize;
int mFrameOffset;
sp<MemoryHeapBase> mHeap;
sp<MemoryBase> *mBuffers;
const char *mName;
};
struct AshmemPool : public MemPool {
AshmemPool(int buffer_size, int num_buffers,
int frame_size,
int frame_offset,
const char *name);
};
struct PmemPool : public MemPool {
PmemPool(const char *pmem_pool,
int buffer_size, int num_buffers,
int frame_size,
int frame_offset,
const char *name);
virtual ~PmemPool() { }
int mFd;
uint32_t mAlignedSize;
struct pmem_region mSize;
};
struct PreviewPmemPool : public PmemPool {
virtual ~PreviewPmemPool();
PreviewPmemPool(int buffer_size, int num_buffers,
int frame_size,
int frame_offset,
const char *name);
};
struct RawPmemPool : public PmemPool {
virtual ~RawPmemPool();
RawPmemPool(const char *pmem_pool,
int buffer_size, int num_buffers,
int frame_size,
int frame_offset,
const char *name);
};
sp<PreviewPmemPool> mPreviewHeap;
sp<RawPmemPool> mRawHeap;
sp<AshmemPool> mJpegHeap;
void startCameraIfNecessary();
bool initPreview();
void deinitPreview();
bool initRaw(bool initJpegHeap);
void initDefaultParameters();
void initCameraParameters();
void setCameraDimensions();
// The states described by qualcomm_camera_state are very similar to the
// CAMERA_FUNC_xxx notifications reported by libqcamera. The differences
// are that they reflect not only the response from libqcamera, but also
// the requests made by the clients of this object. For example,
// QCS_PREVIEW_REQUESTED is a state that we enter when we call
// QualcommCameraHardware::startPreview(), and stay in until libqcamera
// confirms that it has received the start-preview command (but not
// actually initiated preview yet).
//
// NOTE: keep those values small; they are used internally as indices
// into a array of strings.
// NOTE: if you add to this enumeration, make sure you update
// getCameraStateStr().
enum qualcomm_camera_state {
QCS_INIT,
QCS_IDLE,
QCS_ERROR,
QCS_PREVIEW_IN_PROGRESS,
QCS_WAITING_RAW,
QCS_WAITING_JPEG,
/* internal states */
QCS_INTERNAL_PREVIEW_STOPPING,
QCS_INTERNAL_PREVIEW_REQUESTED,
QCS_INTERNAL_RAW_REQUESTED,
QCS_INTERNAL_STOPPING,
};
volatile qualcomm_camera_state mCameraState;
static const char* const getCameraStateStr(qualcomm_camera_state s);
qualcomm_camera_state change_state(qualcomm_camera_state new_state,
bool lock = true);
void notifyShutter();
void receiveJpegPictureFragment(JPEGENC_CBrtnType *encInfo);
void receivePostLpmRawPicture(camera_frame_type *frame);
void receiveRawPicture(camera_frame_type *frame);
void receiveJpegPicture(void);
Mutex mLock; // API lock -- all public methods
Mutex mCallbackLock;
Mutex mStateLock;
Condition mStateWait;
/* mJpegSize keeps track of the size of the accumulated JPEG. We clear it
when we are about to take a picture, so at any time it contains either
zero, or the size of the last JPEG picture taken.
*/
uint32_t mJpegSize;
camera_handle_type camera_handle;
camera_encode_properties_type encode_properties;
camera_position_type pt;
shutter_callback mShutterCallback;
raw_callback mRawPictureCallback;
jpeg_callback mJpegPictureCallback;
void *mPictureCallbackCookie;
autofocus_callback mAutoFocusCallback;
void *mAutoFocusCallbackCookie;
preview_callback mPreviewCallback;
void *mPreviewCallbackCookie;
recording_callback mRecordingCallback;
void *mRecordingCallbackCookie;
bool setCallbacks(preview_callback pcb, void *pu,
recording_callback rcb, void *ru);
int mPreviewFrameSize;
int mRawSize;
int mJpegMaxSize;
// hack to prevent black frame on first preview
int mPreviewCount;
#if DLOPEN_LIBQCAMERA == 1
void *libqcamera;
#endif
};
}; // namespace android
#endif