land: Import OSS camera HAL

CAF revision: AU_LINUX_ANDROID_LA.UM.5.1_RB1.06.00.01.192.038

Change-Id: I87589fea5e9c00c3bdc9c79cc6b2d6453c3d09b3
This commit is contained in:
Zhao Wei Liew 2017-02-12 05:24:36 +08:00
parent 0890fce6dc
commit 669d233045
144 changed files with 133605 additions and 0 deletions

26
camera/Android.mk Normal file
View file

@ -0,0 +1,26 @@
MM_V4L2_DRIVER_LIST += msm8960
MM_V4L2_DRIVER_LIST += msm8974
MM_V4L2_DRIVER_LIST += msm8916
MM_V4L2_DRIVER_LIST += msm8226
MM_V4L2_DRIVER_LIST += msm8610
MM_V4L2_DRIVER_LIST += apq8084
MM_V4L2_DRIVER_LIST += mpq8092
MM_V4L2_DRIVER_LIST += msm_bronze
MM_V4L2_DRIVER_LIST += msm8916
MM_V4L2_DRIVER_LIST += msm8994
MM_V4L2_DRIVER_LIST += msm8084
MM_V4L2_DRIVER_LIST += msm8909
MM_V4L2_DRIVER_LIST += msm8952
MM_V4L2_DRIVER_LIST += msm8996
MM_V4L2_DRIVER_LIST += msm8992
MM_V4L2_DRIVER_LIST += msm8937
MM_V4L2_DRIVER_LIST += titanium
MM_V4L2_DRIVER_LIST += msmcobalt
ifneq (,$(filter $(MM_V4L2_DRIVER_LIST),$(TARGET_BOARD_PLATFORM)))
ifneq ($(strip $(USE_CAMERA_STUB)),true)
ifneq ($(BUILD_TINY_ANDROID),true)
include $(call all-subdir-makefiles)
endif
endif
endif

47
camera/CleanSpec.mk Normal file
View file

@ -0,0 +1,47 @@
# Copyright (C) 2007 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.
#
# If you don't need to do a full clean build but would like to touch
# a file or delete some intermediate files, add a clean step to the end
# of the list. These steps will only be run once, if they haven't been
# run before.
#
# E.g.:
# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
#
# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
# files that are missing or have been moved.
#
# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
# Use $(OUT_DIR) to refer to the "out" directory.
#
# If you need to re-do something that's already mentioned, just copy
# the command and add it to the bottom of the list. E.g., if a change
# that you made last week required touching a file and a change you
# made today requires touching the same file, just copy the old
# touch step and add it to the end of the list.
#
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
# ************************************************
# For example:
#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
$(call add-clean-step, find $(OUT_DIR) -name "camera.msm8960*" -print0 | xargs -0 rm -rf)

View file

113
camera/QCamera2/Android.mk Normal file
View file

@ -0,0 +1,113 @@
ifneq (,$(filter $(TARGET_ARCH), arm arm64))
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
util/QCameraBufferMaps.cpp \
util/QCameraCmdThread.cpp \
util/QCameraDisplay.cpp \
util/QCameraFlash.cpp \
util/QCameraPerf.cpp \
util/QCameraQueue.cpp \
QCamera2Hal.cpp \
QCamera2Factory.cpp
#HAL 3.0 source
LOCAL_SRC_FILES += \
HAL3/QCamera3HWI.cpp \
HAL3/QCamera3Mem.cpp \
HAL3/QCamera3Stream.cpp \
HAL3/QCamera3Channel.cpp \
HAL3/QCamera3VendorTags.cpp \
HAL3/QCamera3PostProc.cpp \
HAL3/QCamera3CropRegionMapper.cpp \
HAL3/QCamera3StreamMem.cpp
#HAL 1.0 source
LOCAL_SRC_FILES += \
HAL/QCamera2HWI.cpp \
HAL/QCameraMuxer.cpp \
HAL/QCameraMem.cpp \
HAL/QCameraStateMachine.cpp \
HAL/QCameraChannel.cpp \
HAL/QCameraStream.cpp \
HAL/QCameraPostProc.cpp \
HAL/QCamera2HWICallbacks.cpp \
HAL/QCameraParameters.cpp \
HAL/QCameraParametersIntf.cpp \
HAL/QCameraThermalAdapter.cpp
LOCAL_CFLAGS := -Wall -Wextra -Werror
# System header file path prefix
LOCAL_CFLAGS += -DSYSTEM_HEADER_PREFIX=sys
LOCAL_CFLAGS += -DHAS_MULTIMEDIA_HINTS -D_ANDROID
ifeq ($(TARGET_USES_AOSP),true)
LOCAL_CFLAGS += -DVANILLA_HAL
endif
#HAL 1.0 Flags
LOCAL_CFLAGS += -DDEFAULT_DENOISE_MODE_ON -DHAL3 -DQCAMERA_REDEFINE_LOG
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/../mm-image-codec/qexif \
$(LOCAL_PATH)/../mm-image-codec/qomx_core \
$(LOCAL_PATH)/include \
$(LOCAL_PATH)/stack/common \
$(LOCAL_PATH)/stack/mm-camera-interface/inc \
$(LOCAL_PATH)/util \
$(LOCAL_PATH)/HAL3 \
hardware/libhardware/include/hardware \
hardware/qcom/media/libstagefrighthw \
hardware/qcom/media/mm-core/inc \
system/core/include/cutils \
system/core/include/system \
system/media/camera/include/system
#HAL 1.0 Include paths
LOCAL_C_INCLUDES += \
hardware/qcom/camera/QCamera2/HAL
ifeq ($(TARGET_COMPILE_WITH_MSM_KERNEL),true)
LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
endif
ifeq ($(TARGET_TS_MAKEUP),true)
LOCAL_CFLAGS += -DTARGET_TS_MAKEUP
LOCAL_C_INCLUDES += $(LOCAL_PATH)/HAL/tsMakeuplib/include
endif
ifneq (,$(filter msm8974 msm8916 msm8226 msm8610 msm8916 apq8084 msm8084 msm8994 msm8992 msm8952 msm8937 titanium msm8996,$(TARGET_BOARD_PLATFORM)))
LOCAL_CFLAGS += -DVENUS_PRESENT
endif
ifneq (,$(filter msm8996,$(TARGET_BOARD_PLATFORM)))
LOCAL_CFLAGS += -DUBWC_PRESENT
endif
#LOCAL_STATIC_LIBRARIES := libqcamera2_util
LOCAL_C_INCLUDES += \
$(TARGET_OUT_HEADERS)/qcom/display
LOCAL_C_INCLUDES += \
hardware/qcom/display/libqservice
LOCAL_SHARED_LIBRARIES := libcamera_client liblog libhardware libutils libcutils libdl libsync libgui
LOCAL_SHARED_LIBRARIES += libmmcamera_interface libmmjpeg_interface libui libcamera_metadata
LOCAL_SHARED_LIBRARIES += libqdMetaData libqservice libbinder
ifeq ($(TARGET_TS_MAKEUP),true)
LOCAL_SHARED_LIBRARIES += libts_face_beautify_hal libts_detected_face_hal
endif
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_MODULE := camera.$(TARGET_BOARD_PLATFORM)
LOCAL_CLANG := false
LOCAL_MODULE_TAGS := optional
LOCAL_32_BIT_ONLY := $(BOARD_QTI_CAMERA_32BIT_ONLY)
include $(BUILD_SHARED_LIBRARY)
include $(call first-makefiles-under,$(LOCAL_PATH))
endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,773 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __QCAMERA2HARDWAREINTERFACE_H__
#define __QCAMERA2HARDWAREINTERFACE_H__
// System dependencies
#include <utils/Mutex.h>
#include <utils/Condition.h>
// Camera dependencies
#include "camera.h"
#include "QCameraAllocator.h"
#include "QCameraChannel.h"
#include "QCameraCmdThread.h"
#include "QCameraDisplay.h"
#include "QCameraMem.h"
#include "QCameraParameters.h"
#include "QCameraParametersIntf.h"
#include "QCameraPerf.h"
#include "QCameraPostProc.h"
#include "QCameraQueue.h"
#include "QCameraStream.h"
#include "QCameraStateMachine.h"
#include "QCameraThermalAdapter.h"
#ifdef TARGET_TS_MAKEUP
#include "ts_makeup_engine.h"
#include "ts_detectface_engine.h"
#endif
extern "C" {
#include "mm_camera_interface.h"
#include "mm_jpeg_interface.h"
}
#include "QCameraTrace.h"
namespace qcamera {
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
typedef enum {
QCAMERA_CH_TYPE_ZSL,
QCAMERA_CH_TYPE_CAPTURE,
QCAMERA_CH_TYPE_PREVIEW,
QCAMERA_CH_TYPE_VIDEO,
QCAMERA_CH_TYPE_SNAPSHOT,
QCAMERA_CH_TYPE_RAW,
QCAMERA_CH_TYPE_METADATA,
QCAMERA_CH_TYPE_ANALYSIS,
QCAMERA_CH_TYPE_CALLBACK,
QCAMERA_CH_TYPE_MAX
} qcamera_ch_type_enum_t;
typedef struct {
int32_t msg_type;
int32_t ext1;
int32_t ext2;
} qcamera_evt_argm_t;
#define QCAMERA_DUMP_FRM_PREVIEW 1
#define QCAMERA_DUMP_FRM_VIDEO (1<<1)
#define QCAMERA_DUMP_FRM_SNAPSHOT (1<<2)
#define QCAMERA_DUMP_FRM_THUMBNAIL (1<<3)
#define QCAMERA_DUMP_FRM_RAW (1<<4)
#define QCAMERA_DUMP_FRM_JPEG (1<<5)
#define QCAMERA_DUMP_FRM_INPUT_REPROCESS (1<<6)
#define QCAMERA_DUMP_FRM_MASK_ALL 0x000000ff
#define QCAMERA_ION_USE_CACHE true
#define QCAMERA_ION_USE_NOCACHE false
#define MAX_ONGOING_JOBS 25
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define EXIF_ASCII_PREFIX_SIZE 8 //(sizeof(ExifAsciiPrefix))
typedef enum {
QCAMERA_NOTIFY_CALLBACK,
QCAMERA_DATA_CALLBACK,
QCAMERA_DATA_TIMESTAMP_CALLBACK,
QCAMERA_DATA_SNAPSHOT_CALLBACK
} qcamera_callback_type_m;
typedef void (*camera_release_callback)(void *user_data,
void *cookie,
int32_t cb_status);
typedef void (*jpeg_data_callback)(int32_t msg_type,
const camera_memory_t *data, unsigned int index,
camera_frame_metadata_t *metadata, void *user,
uint32_t frame_idx, camera_release_callback release_cb,
void *release_cookie, void *release_data);
typedef struct {
qcamera_callback_type_m cb_type; // event type
int32_t msg_type; // msg type
int32_t ext1; // extended parameter
int32_t ext2; // extended parameter
camera_memory_t * data; // ptr to data memory struct
unsigned int index; // index of the buf in the whole buffer
int64_t timestamp; // buffer timestamp
camera_frame_metadata_t *metadata; // meta data
void *user_data; // any data needs to be released after callback
void *cookie; // release callback cookie
camera_release_callback release_cb; // release callback
uint32_t frame_index; // frame index for the buffer
} qcamera_callback_argm_t;
class QCameraCbNotifier {
public:
QCameraCbNotifier(QCamera2HardwareInterface *parent) :
mNotifyCb (NULL),
mDataCb (NULL),
mDataCbTimestamp (NULL),
mCallbackCookie (NULL),
mJpegCb(NULL),
mJpegCallbackCookie(NULL),
mParent (parent),
mDataQ(releaseNotifications, this),
mActive(false){}
virtual ~QCameraCbNotifier();
virtual int32_t notifyCallback(qcamera_callback_argm_t &cbArgs);
virtual void setCallbacks(camera_notify_callback notifyCb,
camera_data_callback dataCb,
camera_data_timestamp_callback dataCbTimestamp,
void *callbackCookie);
virtual void setJpegCallBacks(
jpeg_data_callback jpegCb, void *callbackCookie);
virtual int32_t startSnapshots();
virtual void stopSnapshots();
virtual void exit();
static void * cbNotifyRoutine(void * data);
static void releaseNotifications(void *data, void *user_data);
static bool matchSnapshotNotifications(void *data, void *user_data);
static bool matchPreviewNotifications(void *data, void *user_data);
virtual int32_t flushPreviewNotifications();
private:
camera_notify_callback mNotifyCb;
camera_data_callback mDataCb;
camera_data_timestamp_callback mDataCbTimestamp;
void *mCallbackCookie;
jpeg_data_callback mJpegCb;
void *mJpegCallbackCookie;
QCamera2HardwareInterface *mParent;
QCameraQueue mDataQ;
QCameraCmdThread mProcTh;
bool mActive;
};
class QCamera2HardwareInterface : public QCameraAllocator,
public QCameraThermalCallback, public QCameraAdjustFPS
{
public:
/* static variable and functions accessed by camera service */
static camera_device_ops_t mCameraOps;
static int set_preview_window(struct camera_device *,
struct preview_stream_ops *window);
static void set_CallBacks(struct camera_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);
static void enable_msg_type(struct camera_device *, int32_t msg_type);
static void disable_msg_type(struct camera_device *, int32_t msg_type);
static int msg_type_enabled(struct camera_device *, int32_t msg_type);
static int start_preview(struct camera_device *);
static void stop_preview(struct camera_device *);
static int preview_enabled(struct camera_device *);
static int store_meta_data_in_buffers(struct camera_device *, int enable);
static int restart_start_preview(struct camera_device *);
static int restart_stop_preview(struct camera_device *);
static int pre_start_recording(struct camera_device *);
static int start_recording(struct camera_device *);
static void stop_recording(struct camera_device *);
static int recording_enabled(struct camera_device *);
static void release_recording_frame(struct camera_device *, const void *opaque);
static int auto_focus(struct camera_device *);
static int cancel_auto_focus(struct camera_device *);
static int pre_take_picture(struct camera_device *);
static int take_picture(struct camera_device *);
int takeLiveSnapshot_internal();
int takeBackendPic_internal(bool *JpegMemOpt, char *raw_format);
void clearIntPendingEvents();
void checkIntPicPending(bool JpegMemOpt, char *raw_format);
static int cancel_picture(struct camera_device *);
static int set_parameters(struct camera_device *, const char *parms);
static int stop_after_set_params(struct camera_device *);
static int commit_params(struct camera_device *);
static int restart_after_set_params(struct camera_device *);
static char* get_parameters(struct camera_device *);
static void put_parameters(struct camera_device *, char *);
static int send_command(struct camera_device *,
int32_t cmd, int32_t arg1, int32_t arg2);
static int send_command_restart(struct camera_device *,
int32_t cmd, int32_t arg1, int32_t arg2);
static void release(struct camera_device *);
static int dump(struct camera_device *, int fd);
static int close_camera_device(hw_device_t *);
static int register_face_image(struct camera_device *,
void *img_ptr,
cam_pp_offline_src_config_t *config);
static int prepare_preview(struct camera_device *);
static int prepare_snapshot(struct camera_device *device);
public:
QCamera2HardwareInterface(uint32_t cameraId);
virtual ~QCamera2HardwareInterface();
int openCamera(struct hw_device_t **hw_device);
// Dual camera specific oprations
int bundleRelatedCameras(bool syncOn,
uint32_t related_sensor_session_id);
int getCameraSessionId(uint32_t* session_id);
const cam_sync_related_sensors_event_info_t* getRelatedCamSyncInfo(
void);
int32_t setRelatedCamSyncInfo(
cam_sync_related_sensors_event_info_t* info);
int32_t setMpoComposition(bool enable);
bool getMpoComposition(void);
bool getRecordingHintValue(void);
int32_t setRecordingHintValue(int32_t value);
bool isPreviewRestartNeeded(void) { return mPreviewRestartNeeded; };
static int getCapabilities(uint32_t cameraId,
struct camera_info *info, cam_sync_type_t *cam_type);
static int initCapabilities(uint32_t cameraId, mm_camera_vtbl_t *cameraHandle);
cam_capability_t *getCamHalCapabilities();
// Implementation of QCameraAllocator
virtual QCameraMemory *allocateStreamBuf(cam_stream_type_t stream_type,
size_t size, int stride, int scanline, uint8_t &bufferCnt);
virtual int32_t allocateMoreStreamBuf(QCameraMemory *mem_obj,
size_t size, uint8_t &bufferCnt);
virtual QCameraHeapMemory *allocateStreamInfoBuf(cam_stream_type_t stream_type);
virtual QCameraHeapMemory *allocateMiscBuf(cam_stream_info_t *streamInfo);
virtual QCameraMemory *allocateStreamUserBuf(cam_stream_info_t *streamInfo);
virtual void waitForDeferredAlloc(cam_stream_type_t stream_type);
// Implementation of QCameraThermalCallback
virtual int thermalEvtHandle(qcamera_thermal_level_enum_t *level,
void *userdata, void *data);
virtual int recalcFPSRange(int &minFPS, int &maxFPS,
const float &minVideoFPS, const float &maxVideoFPS,
cam_fps_range_t &adjustedRange);
friend class QCameraStateMachine;
friend class QCameraPostProcessor;
friend class QCameraCbNotifier;
friend class QCameraMuxer;
void setJpegCallBacks(jpeg_data_callback jpegCb,
void *callbackCookie);
int32_t initJpegHandle();
int32_t deinitJpegHandle();
int32_t setJpegHandleInfo(mm_jpeg_ops_t *ops,
mm_jpeg_mpo_ops_t *mpo_ops, uint32_t pJpegClientHandle);
int32_t getJpegHandleInfo(mm_jpeg_ops_t *ops,
mm_jpeg_mpo_ops_t *mpo_ops, uint32_t *pJpegClientHandle);
uint32_t getCameraId() { return mCameraId; };
private:
int setPreviewWindow(struct preview_stream_ops *window);
int 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);
int enableMsgType(int32_t msg_type);
int disableMsgType(int32_t msg_type);
int msgTypeEnabled(int32_t msg_type);
int msgTypeEnabledWithLock(int32_t msg_type);
int startPreview();
int stopPreview();
int storeMetaDataInBuffers(int enable);
int preStartRecording();
int startRecording();
int stopRecording();
int releaseRecordingFrame(const void *opaque);
int autoFocus();
int cancelAutoFocus();
int preTakePicture();
int takePicture();
int stopCaptureChannel(bool destroy);
int cancelPicture();
int takeLiveSnapshot();
int takePictureInternal();
int cancelLiveSnapshot();
char* getParameters() {return mParameters.getParameters(); }
int putParameters(char *);
int sendCommand(int32_t cmd, int32_t &arg1, int32_t &arg2);
int release();
int dump(int fd);
int registerFaceImage(void *img_ptr,
cam_pp_offline_src_config_t *config,
int32_t &faceID);
int32_t longShot();
uint32_t deferPPInit();
int openCamera();
int closeCamera();
int processAPI(qcamera_sm_evt_enum_t api, void *api_payload);
int processEvt(qcamera_sm_evt_enum_t evt, void *evt_payload);
int processSyncEvt(qcamera_sm_evt_enum_t evt, void *evt_payload);
void lockAPI();
void waitAPIResult(qcamera_sm_evt_enum_t api_evt, qcamera_api_result_t *apiResult);
void unlockAPI();
void signalAPIResult(qcamera_api_result_t *result);
void signalEvtResult(qcamera_api_result_t *result);
int calcThermalLevel(qcamera_thermal_level_enum_t level,
const int minFPSi, const int maxFPSi,
const float &minVideoFPS, const float &maxVideoFPS,
cam_fps_range_t &adjustedRange,
enum msm_vfe_frame_skip_pattern &skipPattern);
int updateThermalLevel(void *level);
// update entris to set parameters and check if restart is needed
int updateParameters(const char *parms, bool &needRestart);
// send request to server to set parameters
int commitParameterChanges();
bool isCaptureShutterEnabled();
bool needDebugFps();
bool isRegularCapture();
bool isCACEnabled();
bool is4k2kResolution(cam_dimension_t* resolution);
bool isPreviewRestartEnabled();
bool needReprocess();
bool needRotationReprocess();
void debugShowVideoFPS();
void debugShowPreviewFPS();
void dumpJpegToFile(const void *data, size_t size, uint32_t index);
void dumpFrameToFile(QCameraStream *stream,
mm_camera_buf_def_t *frame, uint32_t dump_type, const char *misc = NULL);
void dumpMetadataToFile(QCameraStream *stream,
mm_camera_buf_def_t *frame,char *type);
void releaseSuperBuf(mm_camera_super_buf_t *super_buf);
void playShutter();
void getThumbnailSize(cam_dimension_t &dim);
uint32_t getJpegQuality();
QCameraExif *getExifData();
cam_sensor_t getSensorType();
bool isLowPowerMode();
int32_t processAutoFocusEvent(cam_auto_focus_data_t &focus_data);
int32_t processZoomEvent(cam_crop_data_t &crop_info);
int32_t processPrepSnapshotDoneEvent(cam_prep_snapshot_state_t prep_snapshot_state);
int32_t processASDUpdate(cam_auto_scene_t scene);
int32_t processJpegNotify(qcamera_jpeg_evt_payload_t *jpeg_job);
int32_t processHDRData(cam_asd_hdr_scene_data_t hdr_scene);
int32_t processRetroAECUnlock();
int32_t processZSLCaptureDone();
int32_t processSceneData(cam_scene_mode_type scene);
int32_t transAwbMetaToParams(cam_awb_params_t &awb_params);
int32_t processFocusPositionInfo(cam_focus_pos_info_t &cur_pos_info);
int32_t processAEInfo(cam_3a_params_t &ae_params);
int32_t sendEvtNotify(int32_t msg_type, int32_t ext1, int32_t ext2);
int32_t sendDataNotify(int32_t msg_type,
camera_memory_t *data,
uint8_t index,
camera_frame_metadata_t *metadata,
uint32_t frame_idx);
int32_t sendPreviewCallback(QCameraStream *stream,
QCameraMemory *memory, uint32_t idx);
int32_t selectScene(QCameraChannel *pChannel,
mm_camera_super_buf_t *recvd_frame);
int32_t addChannel(qcamera_ch_type_enum_t ch_type);
int32_t startChannel(qcamera_ch_type_enum_t ch_type);
int32_t stopChannel(qcamera_ch_type_enum_t ch_type);
int32_t delChannel(qcamera_ch_type_enum_t ch_type, bool destroy = true);
int32_t addPreviewChannel();
int32_t addSnapshotChannel();
int32_t addVideoChannel();
int32_t addZSLChannel();
int32_t addCaptureChannel();
int32_t addRawChannel();
int32_t addMetaDataChannel();
int32_t addAnalysisChannel();
QCameraReprocessChannel *addReprocChannel(QCameraChannel *pInputChannel,
int8_t cur_channel_index = 0);
QCameraReprocessChannel *addOfflineReprocChannel(
cam_pp_offline_src_config_t &img_config,
cam_pp_feature_config_t &pp_feature,
stream_cb_routine stream_cb,
void *userdata);
int32_t addCallbackChannel();
int32_t addStreamToChannel(QCameraChannel *pChannel,
cam_stream_type_t streamType,
stream_cb_routine streamCB,
void *userData);
int32_t preparePreview();
void unpreparePreview();
int32_t prepareRawStream(QCameraChannel *pChannel);
QCameraChannel *getChannelByHandle(uint32_t channelHandle);
mm_camera_buf_def_t *getSnapshotFrame(mm_camera_super_buf_t *recvd_frame);
int32_t processFaceDetectionResult(cam_faces_data_t *fd_data);
bool needPreviewFDCallback(uint8_t num_faces);
int32_t processHistogramStats(cam_hist_stats_t &stats_data);
int32_t setHistogram(bool histogram_en);
int32_t setFaceDetection(bool enabled);
int32_t prepareHardwareForSnapshot(int32_t afNeeded);
bool needProcessPreviewFrame();
bool needSendPreviewCallback();
bool isNoDisplayMode() {return mParameters.isNoDisplayMode();};
bool isZSLMode() {return mParameters.isZSLMode();};
bool isRdiMode() {return mParameters.isRdiMode();};
uint8_t numOfSnapshotsExpected() {
return mParameters.getNumOfSnapshots();};
bool isSecureMode() {return mParameters.isSecureMode();};
bool isLongshotEnabled() { return mLongshotEnabled; };
bool isHFRMode() {return mParameters.isHfrMode();};
bool isLiveSnapshot() {return m_stateMachine.isRecording();};
void setRetroPicture(bool enable) { bRetroPicture = enable; };
bool isRetroPicture() {return bRetroPicture; };
bool isHDRMode() {return mParameters.isHDREnabled();};
uint8_t getBufNumRequired(cam_stream_type_t stream_type);
bool needFDMetadata(qcamera_ch_type_enum_t channel_type);
int32_t configureOnlineRotation(QCameraChannel &ch);
int32_t declareSnapshotStreams();
int32_t unconfigureAdvancedCapture();
int32_t configureAdvancedCapture();
int32_t configureAFBracketing(bool enable = true);
int32_t configureHDRBracketing();
int32_t stopAdvancedCapture(QCameraPicChannel *pChannel);
int32_t startAdvancedCapture(QCameraPicChannel *pChannel);
int32_t configureOptiZoom();
int32_t configureStillMore();
int32_t configureAEBracketing();
int32_t updatePostPreviewParameters();
inline void setOutputImageCount(uint32_t aCount) {mOutputCount = aCount;}
inline uint32_t getOutputImageCount() {return mOutputCount;}
bool processUFDumps(qcamera_jpeg_evt_payload_t *evt);
void captureDone();
int32_t updateMetadata(metadata_buffer_t *pMetaData);
void fillFacesData(cam_faces_data_t &faces_data, metadata_buffer_t *metadata);
int32_t getPPConfig(cam_pp_feature_config_t &pp_config,
int8_t curIndex = 0, bool multipass = FALSE);
virtual uint32_t scheduleBackgroundTask(BackgroundTask* bgTask);
virtual int32_t waitForBackgroundTask(uint32_t &taskId);
bool needDeferred(cam_stream_type_t stream_type);
static void camEvtHandle(uint32_t camera_handle,
mm_camera_event_t *evt,
void *user_data);
static void jpegEvtHandle(jpeg_job_status_t status,
uint32_t client_hdl,
uint32_t jobId,
mm_jpeg_output_t *p_buf,
void *userdata);
static void *evtNotifyRoutine(void *data);
// functions for different data notify cb
static void zsl_channel_cb(mm_camera_super_buf_t *recvd_frame, void *userdata);
static void capture_channel_cb_routine(mm_camera_super_buf_t *recvd_frame,
void *userdata);
static void postproc_channel_cb_routine(mm_camera_super_buf_t *recvd_frame,
void *userdata);
static void rdi_mode_stream_cb_routine(mm_camera_super_buf_t *frame,
QCameraStream *stream,
void *userdata);
static void nodisplay_preview_stream_cb_routine(mm_camera_super_buf_t *frame,
QCameraStream *stream,
void *userdata);
static void preview_stream_cb_routine(mm_camera_super_buf_t *frame,
QCameraStream *stream,
void *userdata);
static void synchronous_stream_cb_routine(mm_camera_super_buf_t *frame,
QCameraStream *stream, void *userdata);
static void postview_stream_cb_routine(mm_camera_super_buf_t *frame,
QCameraStream *stream,
void *userdata);
static void video_stream_cb_routine(mm_camera_super_buf_t *frame,
QCameraStream *stream,
void *userdata);
static void snapshot_channel_cb_routine(mm_camera_super_buf_t *frame,
void *userdata);
static void raw_channel_cb_routine(mm_camera_super_buf_t *frame,
void *userdata);
static void raw_stream_cb_routine(mm_camera_super_buf_t *frame,
QCameraStream *stream,
void *userdata);
static void preview_raw_stream_cb_routine(mm_camera_super_buf_t * super_frame,
QCameraStream * stream,
void * userdata);
static void snapshot_raw_stream_cb_routine(mm_camera_super_buf_t * super_frame,
QCameraStream * stream,
void * userdata);
static void metadata_stream_cb_routine(mm_camera_super_buf_t *frame,
QCameraStream *stream,
void *userdata);
static void callback_stream_cb_routine(mm_camera_super_buf_t *frame,
QCameraStream *stream, void *userdata);
static void reprocess_stream_cb_routine(mm_camera_super_buf_t *frame,
QCameraStream *stream,
void *userdata);
static void releaseCameraMemory(void *data,
void *cookie,
int32_t cbStatus);
static void returnStreamBuffer(void *data,
void *cookie,
int32_t cbStatus);
static void getLogLevel();
int32_t startRAWChannel(QCameraChannel *pChannel);
int32_t stopRAWChannel();
inline bool getNeedRestart() {return m_bNeedRestart;}
inline void setNeedRestart(bool needRestart) {m_bNeedRestart = needRestart;}
private:
camera_device_t mCameraDevice;
uint32_t mCameraId;
mm_camera_vtbl_t *mCameraHandle;
bool mCameraOpened;
cam_jpeg_metadata_t mJpegMetadata;
bool m_bRelCamCalibValid;
preview_stream_ops_t *mPreviewWindow;
QCameraParametersIntf mParameters;
int32_t mMsgEnabled;
int mStoreMetaDataInFrame;
camera_notify_callback mNotifyCb;
camera_data_callback mDataCb;
camera_data_timestamp_callback mDataCbTimestamp;
camera_request_memory mGetMemory;
jpeg_data_callback mJpegCb;
void *mCallbackCookie;
void *mJpegCallbackCookie;
bool m_bMpoEnabled;
QCameraStateMachine m_stateMachine; // state machine
bool m_smThreadActive;
QCameraPostProcessor m_postprocessor; // post processor
QCameraThermalAdapter &m_thermalAdapter;
QCameraCbNotifier m_cbNotifier;
QCameraPerfLock m_perfLock;
pthread_mutex_t m_lock;
pthread_cond_t m_cond;
api_result_list *m_apiResultList;
QCameraMemoryPool m_memoryPool;
pthread_mutex_t m_evtLock;
pthread_cond_t m_evtCond;
qcamera_api_result_t m_evtResult;
QCameraChannel *m_channels[QCAMERA_CH_TYPE_MAX]; // array holding channel ptr
bool m_bPreviewStarted; //flag indicates first preview frame callback is received
bool m_bRecordStarted; //flag indicates Recording is started for first time
// Signifies if ZSL Retro Snapshots are enabled
bool bRetroPicture;
// Signifies AEC locked during zsl snapshots
bool m_bLedAfAecLock;
cam_af_state_t m_currentFocusState;
uint32_t mDumpFrmCnt; // frame dump count
uint32_t mDumpSkipCnt; // frame skip count
mm_jpeg_exif_params_t mExifParams;
qcamera_thermal_level_enum_t mThermalLevel;
bool mActiveAF;
bool m_HDRSceneEnabled;
bool mLongshotEnabled;
pthread_t mLiveSnapshotThread;
pthread_t mIntPicThread;
bool mFlashNeeded;
uint32_t mDeviceRotation;
uint32_t mCaptureRotation;
uint32_t mJpegExifRotation;
bool mUseJpegExifRotation;
bool mIs3ALocked;
bool mPrepSnapRun;
int32_t mZoomLevel;
// Flag to indicate whether preview restart needed (for dual camera mode)
bool mPreviewRestartNeeded;
int mVFrameCount;
int mVLastFrameCount;
nsecs_t mVLastFpsTime;
double mVFps;
int mPFrameCount;
int mPLastFrameCount;
nsecs_t mPLastFpsTime;
double mPFps;
//eztune variables for communication with eztune server at backend
bool m_bIntJpegEvtPending;
bool m_bIntRawEvtPending;
char m_BackendFileName[QCAMERA_MAX_FILEPATH_LENGTH];
size_t mBackendFileSize;
pthread_mutex_t m_int_lock;
pthread_cond_t m_int_cond;
enum DeferredWorkCmd {
CMD_DEF_ALLOCATE_BUFF,
CMD_DEF_PPROC_START,
CMD_DEF_PPROC_INIT,
CMD_DEF_METADATA_ALLOC,
CMD_DEF_CREATE_JPEG_SESSION,
CMD_DEF_PARAM_ALLOC,
CMD_DEF_PARAM_INIT,
CMD_DEF_GENERIC,
CMD_DEF_MAX
};
typedef struct {
QCameraChannel *ch;
cam_stream_type_t type;
} DeferAllocBuffArgs;
typedef struct {
uint8_t bufferCnt;
size_t size;
} DeferMetadataAllocArgs;
typedef struct {
jpeg_encode_callback_t jpeg_cb;
void *user_data;
} DeferPProcInitArgs;
typedef union {
DeferAllocBuffArgs allocArgs;
QCameraChannel *pprocArgs;
DeferMetadataAllocArgs metadataAllocArgs;
DeferPProcInitArgs pprocInitArgs;
BackgroundTask *genericArgs;
} DeferWorkArgs;
typedef struct {
uint32_t mDefJobId;
//Job status is needed to check job was successful or failed
//Error code when job was not sucessful and there is error
//0 when is initialized.
//for sucessfull job, do not need to maintain job status
int32_t mDefJobStatus;
} DefOngoingJob;
DefOngoingJob mDefOngoingJobs[MAX_ONGOING_JOBS];
struct DefWork
{
DefWork(DeferredWorkCmd cmd_,
uint32_t id_,
DeferWorkArgs args_)
: cmd(cmd_),
id(id_),
args(args_){};
DeferredWorkCmd cmd;
uint32_t id;
DeferWorkArgs args;
};
QCameraCmdThread mDeferredWorkThread;
QCameraQueue mCmdQueue;
Mutex mDefLock;
Condition mDefCond;
uint32_t queueDeferredWork(DeferredWorkCmd cmd,
DeferWorkArgs args);
uint32_t dequeueDeferredWork(DefWork* dw, int32_t jobStatus);
int32_t waitDeferredWork(uint32_t &job_id);
static void *deferredWorkRoutine(void *obj);
bool checkDeferredWork(uint32_t &job_id);
int32_t getDefJobStatus(uint32_t &job_id);
uint32_t mReprocJob;
uint32_t mJpegJob;
uint32_t mMetadataAllocJob;
uint32_t mInitPProcJob;
uint32_t mParamAllocJob;
uint32_t mParamInitJob;
uint32_t mOutputCount;
uint32_t mInputCount;
bool mAdvancedCaptureConfigured;
bool mHDRBracketingEnabled;
int32_t mNumPreviewFaces;
// Jpeg Handle shared between HWI instances
mm_jpeg_ops_t mJpegHandle;
// MPO handle shared between HWI instances
// this is needed for MPO composition of related
// cam images
mm_jpeg_mpo_ops_t mJpegMpoHandle;
uint32_t mJpegClientHandle;
bool mJpegHandleOwner;
//ts add for makeup
#ifdef TARGET_TS_MAKEUP
TSRect mFaceRect;
bool TsMakeupProcess_Preview(mm_camera_buf_def_t *pFrame,QCameraStream * pStream);
bool TsMakeupProcess_Snapshot(mm_camera_buf_def_t *pFrame,QCameraStream * pStream);
bool TsMakeupProcess(mm_camera_buf_def_t *frame,QCameraStream * stream,TSRect& faceRect);
#endif
QCameraMemory *mMetadataMem;
static uint32_t sNextJobId;
//Gralloc memory details
pthread_mutex_t mGrallocLock;
uint8_t mEnqueuedBuffers;
bool mCACDoneReceived;
//GPU library to read buffer padding details.
void *lib_surface_utils;
int (*LINK_get_surface_pixel_alignment)();
uint32_t mSurfaceStridePadding;
//QCamera Display Object
QCameraDisplay mCameraDisplay;
bool m_bNeedRestart;
Mutex mMapLock;
Condition mMapCond;
// Count to determine the number of preview frames ignored for displaying.
uint8_t mIgnoredPreviewCount;
};
}; // namespace qcamera
#endif /* __QCAMERA2HARDWAREINTERFACE_H__ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,63 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __QCAMERA_ALLOCATOR__
#define __QCAMERA_ALLOCATOR__
extern "C" {
#include "mm_camera_interface.h"
}
namespace qcamera {
class QCameraMemory;
class QCameraHeapMemory;
typedef struct {
int32_t (*bgFunction) (void *);
void* bgArgs;
} BackgroundTask;
class QCameraAllocator {
public:
virtual QCameraMemory *allocateStreamBuf(cam_stream_type_t stream_type,
size_t size, int stride, int scanline, uint8_t &bufferCnt) = 0;
virtual int32_t allocateMoreStreamBuf(QCameraMemory *mem_obj,
size_t size, uint8_t &bufferCnt) = 0;
virtual QCameraHeapMemory *allocateStreamInfoBuf(cam_stream_type_t stream_type) = 0;
virtual QCameraHeapMemory *allocateMiscBuf(cam_stream_info_t *streamInfo) = 0;
virtual QCameraMemory *allocateStreamUserBuf(cam_stream_info_t *streamInfo) = 0;
virtual void waitForDeferredAlloc(cam_stream_type_t stream_type) = 0;
virtual uint32_t scheduleBackgroundTask(BackgroundTask* bgTask) = 0;
virtual int32_t waitForBackgroundTask(uint32_t &taskId) = 0;
virtual ~QCameraAllocator() {}
};
}; /* namespace qcamera */
#endif /* __QCAMERA_ALLOCATOR__ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,171 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __QCAMERA_CHANNEL_H__
#define __QCAMERA_CHANNEL_H__
#include "camera.h"
#include "QCameraMem.h"
#include "QCameraParameters.h"
#include "QCameraStream.h"
extern "C" {
#include "mm_camera_interface.h"
}
namespace qcamera {
class QCameraChannel
{
public:
QCameraChannel(uint32_t cam_handle,
mm_camera_ops_t *cam_ops);
QCameraChannel();
virtual ~QCameraChannel();
virtual int32_t init(mm_camera_channel_attr_t *attr,
mm_camera_buf_notify_t dataCB, // data CB for channel data
void *userData);
// Owner of memory is transferred from the caller to the caller with this call.
virtual int32_t addStream(QCameraAllocator& allocator,
QCameraHeapMemory *streamInfoBuf, QCameraHeapMemory *miscBuf,
uint8_t minStreamBufnum, cam_padding_info_t *paddingInfo,
stream_cb_routine stream_cb, void *userdata, bool bDynAllocBuf,
bool bDeffAlloc = false, cam_rotation_t online_rotation = ROTATE_0);
virtual int32_t linkStream(QCameraChannel *ch, QCameraStream *stream);
virtual int32_t start();
virtual int32_t stop();
virtual int32_t bufDone(mm_camera_super_buf_t *recvd_frame);
virtual int32_t bufDone(mm_camera_super_buf_t *recvd_frame, uint32_t stream_id);
virtual int32_t processZoomDone(preview_stream_ops_t *previewWindow,
cam_crop_data_t &crop_info);
QCameraStream *getStreamByHandle(uint32_t streamHandle);
uint32_t getMyHandle() const {return m_handle;};
uint32_t getNumOfStreams() const {return (uint32_t) mStreams.size();};
QCameraStream *getStreamByIndex(uint32_t index);
QCameraStream *getStreamByServerID(uint32_t serverID);
int32_t UpdateStreamBasedParameters(QCameraParametersIntf &param);
void deleteChannel();
int32_t setStreamSyncCB (cam_stream_type_t stream_type,
stream_cb_routine stream_cb);
protected:
uint32_t m_camHandle;
mm_camera_ops_t *m_camOps;
bool m_bIsActive;
bool m_bAllowDynBufAlloc; // if buf allocation can be in two steps
uint32_t m_handle;
Vector<QCameraStream *> mStreams;
mm_camera_buf_notify_t mDataCB;
void *mUserData;
};
// burst pic channel: i.e. zsl burst mode
class QCameraPicChannel : public QCameraChannel
{
public:
QCameraPicChannel(uint32_t cam_handle,
mm_camera_ops_t *cam_ops);
QCameraPicChannel();
virtual ~QCameraPicChannel();
int32_t takePicture(mm_camera_req_buf_t *buf);
int32_t cancelPicture();
int32_t stopAdvancedCapture(mm_camera_advanced_capture_t type);
int32_t startAdvancedCapture(mm_camera_advanced_capture_t type,
cam_capture_frame_config_t *config = NULL);
int32_t flushSuperbuffer(uint32_t frame_idx);
};
// video channel class
class QCameraVideoChannel : public QCameraChannel
{
public:
QCameraVideoChannel(uint32_t cam_handle,
mm_camera_ops_t *cam_ops);
QCameraVideoChannel();
virtual ~QCameraVideoChannel();
int32_t takePicture(mm_camera_req_buf_t *buf);
int32_t cancelPicture();
int32_t releaseFrame(const void *opaque, bool isMetaData);
};
// reprocess channel class
class QCameraReprocessChannel : public QCameraChannel
{
public:
QCameraReprocessChannel(uint32_t cam_handle,
mm_camera_ops_t *cam_ops);
QCameraReprocessChannel();
virtual ~QCameraReprocessChannel();
int32_t addReprocStreamsFromSource(QCameraAllocator& allocator,
cam_pp_feature_config_t &config,
QCameraChannel *pSrcChannel,
uint8_t minStreamBufNum,
uint8_t burstNum,
cam_padding_info_t *paddingInfo,
QCameraParametersIntf &param,
bool contStream,
bool offline);
// online reprocess
int32_t doReprocess(mm_camera_super_buf_t *frame,
QCameraParametersIntf &param, QCameraStream *pMetaStream,
uint8_t meta_buf_index);
// offline reprocess
int32_t doReprocess(int buf_fd, size_t buf_length, int32_t &ret_val);
int32_t doReprocessOffline(mm_camera_super_buf_t *frame,
mm_camera_buf_def_t *meta_buf, QCameraParametersIntf &param);
int32_t doReprocessOffline(mm_camera_buf_def_t *frame,
mm_camera_buf_def_t *meta_buf, QCameraStream *pStream = NULL);
int32_t stop();
QCameraChannel *getSrcChannel(){return m_pSrcChannel;};
int8_t getReprocCount(){return mPassCount;};
void setReprocCount(int8_t count) {mPassCount = count;};
private:
QCameraStream *getStreamBySrouceHandle(uint32_t srcHandle);
typedef struct {
QCameraStream *stream;
cam_mapping_buf_type type;
uint32_t index;
} OfflineBuffer;
uint32_t mSrcStreamHandles[MAX_STREAM_NUM_IN_BUNDLE];
QCameraChannel *m_pSrcChannel; // ptr to source channel for reprocess
android::List<OfflineBuffer> mOfflineBuffers;
int8_t mPassCount;
};
}; // namespace qcamera
#endif /* __QCAMERA_CHANNEL_H__ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,291 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __QCAMERA2HWI_MEM_H__
#define __QCAMERA2HWI_MEM_H__
// System dependencies
#include <linux/msm_ion.h>
#include <utils/Mutex.h>
#include <utils/List.h>
// Display dependencies
#include "qdMetaData.h"
// Camera dependencies
#include "camera.h"
extern "C" {
#include "mm_camera_interface.h"
}
namespace qcamera {
class QCameraMemoryPool;
//OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT
#define VIDEO_METADATA_NUM_INTS 5
enum QCameraMemType {
QCAMERA_MEM_TYPE_DEFAULT = 0,
QCAMERA_MEM_TYPE_SECURE = 1,
QCAMERA_MEM_TYPE_BATCH = (1 << 1),
QCAMERA_MEM_TYPE_COMPRESSED = (1 << 2),
};
// Base class for all memory types. Abstract.
class QCameraMemory {
public:
int cleanCache(uint32_t index)
{
return cacheOps(index, ION_IOC_CLEAN_CACHES);
}
int invalidateCache(uint32_t index)
{
return cacheOps(index, ION_IOC_INV_CACHES);
}
int cleanInvalidateCache(uint32_t index)
{
return cacheOps(index, ION_IOC_CLEAN_INV_CACHES);
}
int getFd(uint32_t index) const;
ssize_t getSize(uint32_t index) const;
uint8_t getCnt() const;
virtual uint8_t getMappable() const;
virtual uint8_t checkIfAllBuffersMapped() const;
virtual int allocate(uint8_t count, size_t size, uint32_t is_secure) = 0;
virtual void deallocate() = 0;
virtual int allocateMore(uint8_t count, size_t size) = 0;
virtual int cacheOps(uint32_t index, unsigned int cmd) = 0;
virtual int getRegFlags(uint8_t *regFlags) const = 0;
virtual camera_memory_t *getMemory(uint32_t index,
bool metadata) const = 0;
virtual int getMatchBufIndex(const void *opaque, bool metadata) const = 0;
virtual void *getPtr(uint32_t index) const= 0;
QCameraMemory(bool cached,
QCameraMemoryPool *pool = NULL,
cam_stream_type_t streamType = CAM_STREAM_TYPE_DEFAULT,
QCameraMemType buf_Type = QCAMERA_MEM_TYPE_DEFAULT);
virtual ~QCameraMemory();
virtual void reset();
void getBufDef(const cam_frame_len_offset_t &offset,
mm_camera_buf_def_t &bufDef, uint32_t index) const;
int32_t getUserBufDef(const cam_stream_user_buf_info_t &buf_info,
mm_camera_buf_def_t &bufDef, uint32_t index,
const cam_frame_len_offset_t &plane_offset,
mm_camera_buf_def_t *planebufDef, QCameraMemory *bufs) const;
protected:
friend class QCameraMemoryPool;
struct QCameraMemInfo {
int fd;
int main_ion_fd;
ion_user_handle_t handle;
size_t size;
bool cached;
unsigned int heap_id;
};
int alloc(int count, size_t size, unsigned int heap_id,
uint32_t is_secure);
void dealloc();
static int allocOneBuffer(struct QCameraMemInfo &memInfo,
unsigned int heap_id, size_t size, bool cached, uint32_t is_secure);
static void deallocOneBuffer(struct QCameraMemInfo &memInfo);
int cacheOpsInternal(uint32_t index, unsigned int cmd, void *vaddr);
bool m_bCached;
uint8_t mBufferCount;
struct QCameraMemInfo mMemInfo[MM_CAMERA_MAX_NUM_FRAMES];
QCameraMemoryPool *mMemoryPool;
cam_stream_type_t mStreamType;
QCameraMemType mBufType;
};
class QCameraMemoryPool {
public:
QCameraMemoryPool();
virtual ~QCameraMemoryPool();
int allocateBuffer(struct QCameraMemory::QCameraMemInfo &memInfo,
unsigned int heap_id, size_t size, bool cached,
cam_stream_type_t streamType, uint32_t is_secure);
void releaseBuffer(struct QCameraMemory::QCameraMemInfo &memInfo,
cam_stream_type_t streamType);
void clear();
protected:
int findBufferLocked(struct QCameraMemory::QCameraMemInfo &memInfo,
unsigned int heap_id, size_t size, bool cached,
cam_stream_type_t streamType);
android::List<QCameraMemory::QCameraMemInfo> mPools[CAM_STREAM_TYPE_MAX];
pthread_mutex_t mLock;
};
// Internal heap memory is used for memories used internally
// They are allocated from /dev/ion.
class QCameraHeapMemory : public QCameraMemory {
public:
QCameraHeapMemory(bool cached);
virtual ~QCameraHeapMemory();
virtual int allocate(uint8_t count, size_t size, uint32_t is_secure);
virtual int allocateMore(uint8_t count, size_t size);
virtual void deallocate();
virtual int cacheOps(uint32_t index, unsigned int cmd);
virtual int getRegFlags(uint8_t *regFlags) const;
virtual camera_memory_t *getMemory(uint32_t index, bool metadata) const;
virtual int getMatchBufIndex(const void *opaque, bool metadata) const;
virtual void *getPtr(uint32_t index) const;
private:
void *mPtr[MM_CAMERA_MAX_NUM_FRAMES];
};
class QCameraMetadataStreamMemory : public QCameraHeapMemory {
public:
QCameraMetadataStreamMemory(bool cached);
virtual ~QCameraMetadataStreamMemory();
virtual int getRegFlags(uint8_t *regFlags) const;
};
// Externel heap memory is used for memories shared with
// framework. They are allocated from /dev/ion or gralloc.
class QCameraStreamMemory : public QCameraMemory {
public:
QCameraStreamMemory(camera_request_memory getMemory,
bool cached,
QCameraMemoryPool *pool = NULL,
cam_stream_type_t streamType = CAM_STREAM_TYPE_DEFAULT,
cam_stream_buf_type buf_Type = CAM_STREAM_BUF_TYPE_MPLANE);
virtual ~QCameraStreamMemory();
virtual int allocate(uint8_t count, size_t size, uint32_t is_secure);
virtual int allocateMore(uint8_t count, size_t size);
virtual void deallocate();
virtual int cacheOps(uint32_t index, unsigned int cmd);
virtual int getRegFlags(uint8_t *regFlags) const;
virtual camera_memory_t *getMemory(uint32_t index, bool metadata) const;
virtual int getMatchBufIndex(const void *opaque, bool metadata) const;
virtual void *getPtr(uint32_t index) const;
protected:
camera_request_memory mGetMemory;
camera_memory_t *mCameraMemory[MM_CAMERA_MAX_NUM_FRAMES];
};
// Externel heap memory is used for memories shared with
// framework. They are allocated from /dev/ion or gralloc.
class QCameraVideoMemory : public QCameraStreamMemory {
public:
QCameraVideoMemory(camera_request_memory getMemory, bool cached,
QCameraMemType bufType = QCAMERA_MEM_TYPE_DEFAULT);
virtual ~QCameraVideoMemory();
virtual int allocate(uint8_t count, size_t size, uint32_t is_secure);
virtual int allocateMore(uint8_t count, size_t size);
virtual void deallocate();
virtual camera_memory_t *getMemory(uint32_t index, bool metadata) const;
virtual int getMatchBufIndex(const void *opaque, bool metadata) const;
int allocateMeta(uint8_t buf_cnt, int numFDs, int numInts);
void deallocateMeta();
void setVideoInfo(int usage, cam_format_t format);
int getUsage(){return mUsage;};
int getFormat(){return mFormat;};
int convCamtoOMXFormat(cam_format_t format);
private:
camera_memory_t *mMetadata[MM_CAMERA_MAX_NUM_FRAMES];
uint8_t mMetaBufCount;
int mUsage, mFormat;
};
// Gralloc Memory is acquired from preview window
class QCameraGrallocMemory : public QCameraMemory {
enum {
BUFFER_NOT_OWNED,
BUFFER_OWNED,
};
public:
QCameraGrallocMemory(camera_request_memory getMemory);
void setNativeWindow(preview_stream_ops_t *anw);
virtual ~QCameraGrallocMemory();
virtual int allocate(uint8_t count, size_t size, uint32_t is_secure);
virtual int allocateMore(uint8_t count, size_t size);
virtual void deallocate();
virtual int cacheOps(uint32_t index, unsigned int cmd);
virtual int getRegFlags(uint8_t *regFlags) const;
virtual camera_memory_t *getMemory(uint32_t index, bool metadata) const;
virtual int getMatchBufIndex(const void *opaque, bool metadata) const;
virtual void *getPtr(uint32_t index) const;
virtual void setMappable(uint8_t mappable);
virtual uint8_t getMappable() const;
virtual uint8_t checkIfAllBuffersMapped() const;
void setWindowInfo(preview_stream_ops_t *window, int width, int height,
int stride, int scanline, int format, int maxFPS, int usage = 0);
// Enqueue/display buffer[index] onto the native window,
// and dequeue one buffer from it.
// Returns the buffer index of the dequeued buffer.
int displayBuffer(uint32_t index);
void setMaxFPS(int maxFPS);
int32_t enqueueBuffer(uint32_t index, nsecs_t timeStamp = 0);
int32_t dequeueBuffer();
private:
buffer_handle_t *mBufferHandle[MM_CAMERA_MAX_NUM_FRAMES];
int mLocalFlag[MM_CAMERA_MAX_NUM_FRAMES];
struct private_handle_t *mPrivateHandle[MM_CAMERA_MAX_NUM_FRAMES];
preview_stream_ops_t *mWindow;
int mWidth, mHeight, mFormat, mStride, mScanline, mUsage, mMaxFPS;
camera_request_memory mGetMemory;
camera_memory_t *mCameraMemory[MM_CAMERA_MAX_NUM_FRAMES];
int mMinUndequeuedBuffers;
enum ColorSpace_t mColorSpace;
uint8_t mMappableBuffers;
pthread_mutex_t mLock;
uint8_t mEnqueuedBuffers;
};
}; // namespace qcamera
#endif /* __QCAMERA2HWI_MEM_H__ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,285 @@
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __QCAMERAMUXER_H__
#define __QCAMERAMUXER_H__
#include "camera.h"
#include "QCamera2HWI.h"
#include "QCamera3HWI.h"
namespace qcamera {
/* Struct@ qcamera_physical_descriptor_t
*
* Description@ This structure specifies various attributes
* physical cameras enumerated on the device
*/
typedef struct {
// Userspace Physical Camera ID
uint32_t id;
// Server Camera ID
uint32_t camera_server_id;
// Device version
uint32_t device_version;
// Specifies type of camera
cam_sync_type_t type;
// Specifies mode of Camera
cam_sync_mode_t mode;
// Camera Info
camera_info cam_info;
// Reference to HWI
QCamera2HardwareInterface *hwi;
// Reference to camera device structure
camera_device_t* dev;
} qcamera_physical_descriptor_t;
/* Struct@ qcamera_logical_descriptor_t
*
* Description@ This structure stores information about logical cameras
* and corresponding data of the physical camera that are part of
* this logical camera
*/
typedef struct {
// Camera Device to be shared to Frameworks
camera_device_t dev;
// Device version
uint32_t device_version;
// Logical Camera ID
uint32_t id;
// Logical Camera Facing
int32_t facing;
// Number of Physical camera present in this logical camera
uint32_t numCameras;
// To signify if the LINK/UNLINK established between physical cameras
bool bSyncOn;
// index of the primary physical camera session in the bundle
uint8_t nPrimaryPhyCamIndex;
// Signifies Physical Camera ID of each camera
uint32_t pId[MAX_NUM_CAMERA_PER_BUNDLE];
// Signifies server camera ID of each camera
uint32_t sId[MAX_NUM_CAMERA_PER_BUNDLE];
// Signifies type of each camera
cam_sync_type_t type[MAX_NUM_CAMERA_PER_BUNDLE];
// Signifies mode of each camera
cam_sync_mode_t mode[MAX_NUM_CAMERA_PER_BUNDLE];
} qcamera_logical_descriptor_t;
/* Struct@ cam_compose_jpeg_info_t
*
* Description@ This structure stores information about individual Jpeg images
* received from multiple related physical camera instances. These images would then be
* composed together into a single MPO image later.
*/
typedef struct {
// msg_type is same as data callback msg_type
int32_t msg_type;
// ptr to actual data buffer
camera_memory_t *buffer;
// index of the buffer same as received in data callback
unsigned int index;
// metadata associated with the buffer
camera_frame_metadata_t *metadata;
// user contains the caller's identity
// this contains a reference to the physical cam structure
// of the HWI instance which had requested for this data buffer
void *user;
// this indicates validity of the buffer
// this flag is used by multiple threads to check validity of
// Jpegs received by other threads
bool valid;
// frame id of the Jpeg. this is needed for frame sync between aux
// and main camera sessions
uint32_t frame_idx;
// release callback function to release this Jpeg memory later after
// composition is completed
camera_release_callback release_cb;
// cookie for the release callback function
void *release_cookie;
// release data info for what needs to be released
void *release_data;
}cam_compose_jpeg_info_t;
/* Class@ QCameraMuxer
*
* Description@ Muxer interface
* a) Manages the grouping of the physical cameras into a logical camera
* b) Muxes the operational calls from Frameworks to HWI
* c) Composes MPO from JPEG
*/
class QCameraMuxer {
public:
/* Public Methods */
QCameraMuxer(uint32_t num_of_cameras);
virtual ~QCameraMuxer();
static void getCameraMuxer(QCameraMuxer** pCamMuxer,
uint32_t num_of_cameras);
static int get_number_of_cameras();
static int get_camera_info(int camera_id, struct camera_info *info);
static int set_callbacks(const camera_module_callbacks_t *callbacks);
static int open_legacy(const struct hw_module_t* module,
const char* id, uint32_t halVersion, struct hw_device_t** device);
static int camera_device_open(const struct hw_module_t* module,
const char* id,
struct hw_device_t** device);
static int close_camera_device( hw_device_t *);
/* Operation methods directly accessed by Camera Service */
static camera_device_ops_t mCameraMuxerOps;
/* Start of operational methods */
static int set_preview_window(struct camera_device *,
struct preview_stream_ops *window);
static void set_callBacks(struct camera_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);
static void enable_msg_type(struct camera_device *, int32_t msg_type);
static void disable_msg_type(struct camera_device *, int32_t msg_type);
static int msg_type_enabled(struct camera_device *, int32_t msg_type);
static int start_preview(struct camera_device *);
static void stop_preview(struct camera_device *);
static int preview_enabled(struct camera_device *);
static int store_meta_data_in_buffers(struct camera_device *,
int enable);
static int start_recording(struct camera_device *);
static void stop_recording(struct camera_device *);
static int recording_enabled(struct camera_device *);
static void release_recording_frame(struct camera_device *,
const void *opaque);
static int auto_focus(struct camera_device *);
static int cancel_auto_focus(struct camera_device *);
static int take_picture(struct camera_device *);
static int cancel_picture(struct camera_device *);
static int set_parameters(struct camera_device *, const char *parms);
static char* get_parameters(struct camera_device *);
static void put_parameters(struct camera_device *, char *);
static int send_command(struct camera_device *,
int32_t cmd, int32_t arg1, int32_t arg2);
static void release(struct camera_device *);
static int dump(struct camera_device *, int fd);
/* End of operational methods */
static void jpeg_data_callback(int32_t msg_type,
const camera_memory_t *data, unsigned int index,
camera_frame_metadata_t *metadata, void *user,
uint32_t frame_idx, camera_release_callback release_cb,
void *release_cookie, void *release_data);
// add notify error msgs to the notifer queue of the primary related cam instance
static int32_t sendEvtNotify(int32_t msg_type, int32_t ext1, int32_t ext2);
// function to compose all JPEG images from all physical related camera instances
void composeMpo(cam_compose_jpeg_info_t* main_Jpeg,
cam_compose_jpeg_info_t* aux_Jpeg);
static void* composeMpoRoutine(void* data);
static bool matchFrameId(void *data, void *user_data, void *match_data);
static bool findPreviousJpegs(void *data, void *user_data, void *match_data);
static void releaseJpegInfo(void *data, void *user_data);
public:
/* Public Members Variables */
// Jpeg and Mpo ops need to be shared between 2 HWI instances
// hence these are cached in the muxer alongwith Jpeg handle
mm_jpeg_ops_t mJpegOps;
mm_jpeg_mpo_ops_t mJpegMpoOps;
uint32_t mJpegClientHandle;
// Stores Camera Data Callback function
camera_data_callback mDataCb;
// Stores Camera GetMemory Callback function
camera_request_memory mGetMemoryCb;
private:
/* Private Member Variables */
qcamera_physical_descriptor_t *m_pPhyCamera;
qcamera_logical_descriptor_t *m_pLogicalCamera;
const camera_module_callbacks_t *m_pCallbacks;
bool m_bDualCameraEnabled;
bool m_bAuxCameraExposed;
uint8_t m_nPhyCameras;
uint8_t m_nLogicalCameras;
// Main Camera session Jpeg Queue
QCameraQueue m_MainJpegQ;
// Aux Camera session Jpeg Queue
QCameraQueue m_AuxJpegQ;
// thread for mpo composition
QCameraCmdThread m_ComposeMpoTh;
// Final Mpo Jpeg Buffer
camera_memory_t *m_pRelCamMpoJpeg;
// Lock needed to synchronize between multiple composition requests
pthread_mutex_t m_JpegLock;
// this callback cookie would be used for sending Final mpo Jpeg to the framework
void *m_pMpoCallbackCookie;
// this callback cookie would be used for caching main related cam phy instance
// this is needed for error scenarios
// incase of error, we use this cookie to get HWI instance and send errors in notify cb
void *m_pJpegCallbackCookie;
// flag to indicate whether we need to dump dual camera snapshots
bool m_bDumpImages;
// flag to indicate whether MPO is enabled or not
bool m_bMpoEnabled;
// Signifies if frame sync is enabled
bool m_bFrameSyncEnabled;
// flag to indicate whether recording hint is internally set.
bool m_bRecordingHintInternallySet;
/* Private Member Methods */
int setupLogicalCameras();
int cameraDeviceOpen(int camera_id, struct hw_device_t **hw_device);
int getNumberOfCameras();
int getCameraInfo(int camera_id, struct camera_info *info,
cam_sync_type_t *p_cam_type);
int32_t setCallbacks(const camera_module_callbacks_t *callbacks);
int32_t setDataCallback(camera_data_callback data_cb);
int32_t setMemoryCallback(camera_request_memory get_memory);
qcamera_logical_descriptor_t* getLogicalCamera(
struct camera_device * device);
qcamera_physical_descriptor_t* getPhysicalCamera(
qcamera_logical_descriptor_t* log_cam, uint32_t index);
int32_t getActiveNumOfPhyCam(
qcamera_logical_descriptor_t* log_cam, int& numOfAcitvePhyCam);
int32_t setMpoCallbackCookie(void* mpoCbCookie);
void* getMpoCallbackCookie();
int32_t setMainJpegCallbackCookie(void* jpegCbCookie);
void* getMainJpegCallbackCookie();
void setJpegHandle(uint32_t handle) { mJpegClientHandle = handle;};
// function to store single JPEG from 1 related physical camera instance
int32_t storeJpeg(cam_sync_type_t cam_type, int32_t msg_type,
const camera_memory_t *data, unsigned int index,
camera_frame_metadata_t *metadata, void *user,
uint32_t frame_idx, camera_release_callback release_cb,
void *release_cookie, void *release_data);
};// End namespace qcamera
}
#endif /* __QCAMERAMUXER_H__ */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,294 @@
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef ANDROID_HARDWARE_QCAMERA_PARAMETERS_INTF_H
#define ANDROID_HARDWARE_QCAMERA_PARAMETERS_INTF_H
#include <utils/String8.h>
#include <utils/Mutex.h>
#include "cam_intf.h"
#include "cam_types.h"
#include "QCameraThermalAdapter.h"
extern "C" {
#include <mm_camera_interface.h>
#include <mm_jpeg_interface.h>
}
using namespace android;
namespace qcamera {
typedef cam_manual_capture_type QCameraManualCaptureModes;
class QCameraAdjustFPS
{
public:
virtual int recalcFPSRange(int &minFPS, int &maxFPS,
const float &minVideoFPS, const float &maxVideoFPs,
cam_fps_range_t &adjustedRange) = 0;
virtual ~QCameraAdjustFPS() {}
};
class QCameraParameters;
class QCameraParametersIntf
{
public:
// member variables
QCameraParametersIntf();
~QCameraParametersIntf();
int32_t allocate();
int32_t init(cam_capability_t *capabilities,
mm_camera_vtbl_t *mmOps,
QCameraAdjustFPS *adjustFPS);
void deinit();
int32_t updateParameters(const String8& params, bool &needRestart);
int32_t commitParameters();
char* getParameters();
void getPreviewFpsRange(int *min_fps, int *max_fps) const;
#ifdef TARGET_TS_MAKEUP
bool getTsMakeupInfo(int &whiteLevel, int &cleanLevel) const;
#endif
int getPreviewHalPixelFormat();
int32_t getStreamRotation(cam_stream_type_t streamType,
cam_pp_feature_config_t &featureConfig,
cam_dimension_t &dim);
int32_t getStreamFormat(cam_stream_type_t streamType,
cam_format_t &format);
int32_t getStreamDimension(cam_stream_type_t streamType,
cam_dimension_t &dim);
void getThumbnailSize(int *width, int *height) const;
uint8_t getZSLBurstInterval();
uint8_t getZSLQueueDepth();
uint8_t getZSLBackLookCount();
uint8_t getMaxUnmatchedFramesInQueue();
bool isZSLMode();
bool isRdiMode();
bool isSecureMode();
bool isNoDisplayMode();
bool isWNREnabled();
bool isTNRSnapshotEnabled();
int32_t getCDSMode();
bool isLTMForSeeMoreEnabled();
bool isHfrMode();
void getHfrFps(cam_fps_range_t &pFpsRange);
uint8_t getNumOfSnapshots();
uint8_t getNumOfRetroSnapshots();
uint8_t getNumOfExtraHDRInBufsIfNeeded();
uint8_t getNumOfExtraHDROutBufsIfNeeded();
bool getRecordingHintValue();
uint32_t getJpegQuality();
uint32_t getRotation();
uint32_t getDeviceRotation();
uint32_t getJpegExifRotation();
bool useJpegExifRotation();
int32_t getEffectValue();
int32_t getExifDateTime(String8 &dateTime, String8 &subsecTime);
int32_t getExifFocalLength(rat_t *focalLenght);
uint16_t getExifIsoSpeed();
int32_t getExifGpsProcessingMethod(char *gpsProcessingMethod,
uint32_t &count);
int32_t getExifLatitude(rat_t *latitude, char *latRef);
int32_t getExifLongitude(rat_t *longitude, char *lonRef);
int32_t getExifAltitude(rat_t *altitude, char *altRef);
int32_t getExifGpsDateTimeStamp(char *gpsDateStamp,
uint32_t bufLen, rat_t *gpsTimeStamp);
bool isVideoBuffersCached();
int32_t updateFocusDistances(cam_focus_distances_info_t *focusDistances);
bool isAEBracketEnabled();
int32_t setAEBracketing();
bool isFpsDebugEnabled();
bool isHistogramEnabled();
bool isSceneSelectionEnabled();
int32_t setSelectedScene(cam_scene_mode_type scene);
cam_scene_mode_type getSelectedScene();
bool isFaceDetectionEnabled();
int32_t setFaceDetectionOption(bool enabled);
int32_t setHistogram(bool enabled);
int32_t setFaceDetection(bool enabled, bool initCommit);
int32_t setFrameSkip(enum msm_vfe_frame_skip_pattern pattern);
qcamera_thermal_mode getThermalMode();
int32_t updateRecordingHintValue(int32_t value);
int32_t setHDRAEBracket(cam_exp_bracketing_t hdrBracket);
bool isHDREnabled();
bool isAutoHDREnabled();
int32_t stopAEBracket();
int32_t updateRAW(cam_dimension_t max_dim);
bool isDISEnabled();
cam_is_type_t getISType();
uint8_t getMobicatMask();
cam_focus_mode_type getFocusMode() const;
int32_t setNumOfSnapshot();
int32_t adjustPreviewFpsRange(cam_fps_range_t *fpsRange);
bool isJpegPictureFormat();
bool isNV16PictureFormat();
bool isNV21PictureFormat();
cam_denoise_process_type_t getDenoiseProcessPlate(cam_intf_parm_type_t type);
int32_t getMaxPicSize(cam_dimension_t &dim);
int getFlipMode(cam_stream_type_t streamType);
bool isSnapshotFDNeeded();
bool isHDR1xFrameEnabled();
bool isYUVFrameInfoNeeded();
const char*getFrameFmtString(cam_format_t fmt);
bool isHDR1xExtraBufferNeeded();
bool isHDROutputCropEnabled();
bool isPreviewFlipChanged();
bool isVideoFlipChanged();
bool isSnapshotFlipChanged();
void setHDRSceneEnable(bool bflag);
int32_t updateAWBParams(cam_awb_params_t &awb_params);
const char *getASDStateString(cam_auto_scene_t scene);
bool isHDRThumbnailProcessNeeded();
void setMinPpMask(uint32_t min_pp_mask);
bool setStreamConfigure(bool isCapture,
bool previewAsPostview, bool resetConfig);
int32_t addOnlineRotation(uint32_t rotation, uint32_t streamId,
int32_t device_rotation);
uint8_t getNumOfExtraBuffersForImageProc();
uint8_t getNumOfExtraBuffersForVideo();
uint8_t getNumOfExtraBuffersForPreview();
uint32_t getExifBufIndex(uint32_t captureIndex);
bool needThumbnailReprocess(uint32_t *pFeatureMask);
bool isUbiFocusEnabled();
bool isChromaFlashEnabled();
bool isHighQualityNoiseReductionMode();
bool isTruePortraitEnabled();
size_t getTPMaxMetaSize();
bool isSeeMoreEnabled();
bool isStillMoreEnabled();
bool isOptiZoomEnabled();
int32_t commitAFBracket(cam_af_bracketing_t afBracket);
int32_t set3ALock(bool lock3A);
int32_t setAndCommitZoom(int zoom_level);
uint8_t getBurstCountForAdvancedCapture();
uint32_t getNumberInBufsForSingleShot();
uint32_t getNumberOutBufsForSingleShot();
int32_t setLongshotEnable(bool enable);
String8 dump();
bool isUbiRefocus();
uint32_t getRefocusMaxMetaSize();
uint8_t getRefocusOutputCount();
bool generateThumbFromMain();
void updateCurrentFocusPosition(cam_focus_pos_info_t &cur_pos_info);
void updateAEInfo(cam_3a_params_t &ae_params);
bool isDisplayFrameNeeded();
bool isAdvCamFeaturesEnabled();
int32_t setAecLock(const char *aecStr);
int32_t updateDebugLevel();
bool is4k2kVideoResolution();
bool isUBWCEnabled();
int getBrightness();
int32_t updateOisValue(bool oisValue);
int32_t setIntEvent(cam_int_evt_params_t params);
bool getofflineRAW();
int32_t updatePpFeatureMask(cam_stream_type_t stream_type);
int32_t getStreamPpMask(cam_stream_type_t stream_type, uint32_t &pp_mask);
int32_t getSharpness();
int32_t getEffect();
int32_t updateFlashMode(cam_flash_mode_t flash_mode);
int32_t configureAEBracketing(cam_capture_frame_config_t &frame_config);
int32_t configureHDRBracketing(cam_capture_frame_config_t &frame_config);
int32_t configFrameCapture(bool commitSettings);
int32_t resetFrameCapture(bool commitSettings);
cam_still_more_t getStillMoreSettings();
void setStillMoreSettings(cam_still_more_t stillmore_config);
cam_still_more_t getStillMoreCapability();
cam_dyn_img_data_t getDynamicImgData();
void setDynamicImgData(cam_dyn_img_data_t d);
int32_t getParmZoomLevel();
int8_t getReprocCount();
int8_t getCurPPCount();
void setReprocCount();
bool isPostProcScaling();
bool isLLNoiseEnabled();
void setCurPPCount(int8_t count);
int32_t setToneMapMode(uint32_t value, bool initCommit);
void setTintless(bool enable);
uint8_t getLongshotStages();
int8_t getBufBatchCount();
int8_t getVideoBatchSize();
int32_t setManualCaptureMode(
QCameraManualCaptureModes value = CAM_MANUAL_CAPTURE_TYPE_OFF);
QCameraManualCaptureModes getManualCaptureMode();
int64_t getExposureTime();
cam_capture_frame_config_t getCaptureFrameConfig();
void setJpegRotation(int rotation);
uint32_t getJpegRotation();
void setLowLightLevel(cam_low_light_mode_t value);
cam_low_light_mode_t getLowLightLevel();
bool getLowLightCapture();
/* Dual camera specific */
bool getDcrf();
int32_t setRelatedCamSyncInfo(
cam_sync_related_sensors_event_info_t* info);
const cam_sync_related_sensors_event_info_t*
getRelatedCamSyncInfo(void);
int32_t getRelatedCamCalibration(
cam_related_system_calibration_data_t* calib);
int32_t bundleRelatedCameras(bool sync, uint32_t sessionid);
bool isFDInVideoEnabled();
bool isOEMFeatEnabled();
int32_t setZslMode(bool value);
int32_t updateZSLModeValue(bool value);
bool isReprocScaleEnabled();
bool isUnderReprocScaling();
int32_t getPicSizeFromAPK(int &width, int &height);
int32_t checkFeatureConcurrency();
private:
QCameraParameters *mImpl;
mutable Mutex mLock;
};
}; // namespace qcamera
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,249 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __QCAMERA_POSTPROC_H__
#define __QCAMERA_POSTPROC_H__
// Camera dependencies
#include "QCamera2HWI.h"
extern "C" {
#include "mm_camera_interface.h"
#include "mm_jpeg_interface.h"
}
#define MAX_JPEG_BURST 2
#define CAM_PP_CHANNEL_MAX 8
namespace qcamera {
class QCameraExif;
class QCamera2HardwareInterface;
typedef struct {
uint32_t jobId; // job ID
uint32_t client_hdl; // handle of jpeg client (obtained when open jpeg)
mm_camera_super_buf_t *src_frame;// source frame (need to be returned back to kernel
//after done)
mm_camera_super_buf_t *src_reproc_frame; // original source
//frame for reproc if not NULL
metadata_buffer_t *metadata; // source frame metadata
bool reproc_frame_release; // false release original buffer, true don't release it
mm_camera_buf_def_t *src_reproc_bufs;
QCameraExif *pJpegExifObj;
uint8_t offline_buffer;
mm_camera_buf_def_t *offline_reproc_buf; //HAL processed buffer
} qcamera_jpeg_data_t;
typedef struct {
int8_t reprocCount;
mm_camera_super_buf_t *src_frame; // source frame that needs post process
mm_camera_super_buf_t *src_reproc_frame;// source frame (need to be
//returned back to kernel after done)
}qcamera_pp_request_t;
typedef struct {
uint32_t jobId; // job ID
int8_t reprocCount; //Current pass count
int8_t ppChannelIndex; //Reprocess channel object index
mm_camera_super_buf_t *src_frame;// source frame
bool reproc_frame_release; // false release original buffer
// true don't release it
mm_camera_buf_def_t *src_reproc_bufs;
mm_camera_super_buf_t *src_reproc_frame;// source frame (need to be
//returned back to kernel after done)
uint8_t offline_buffer;
mm_camera_buf_def_t *offline_reproc_buf; //HAL processed buffer
} qcamera_pp_data_t;
typedef struct {
uint32_t jobId; // job ID (obtained when start_jpeg_job)
jpeg_job_status_t status; // jpeg encoding status
mm_jpeg_output_t out_data; // ptr to jpeg output buf
} qcamera_jpeg_evt_payload_t;
typedef struct {
camera_memory_t * data; // ptr to data memory struct
mm_camera_super_buf_t * frame; // ptr to frame
QCameraMemory * streamBufs; //ptr to stream buffers
bool unlinkFile; // unlink any stored buffers on error
} qcamera_release_data_t;
typedef struct {
int32_t msg_type; // msg type of data notify
camera_memory_t * data; // ptr to data memory struct
unsigned int index; // index of the buf in the whole buffer
camera_frame_metadata_t *metadata; // ptr to meta data
qcamera_release_data_t release_data; // any data needs to be release after notify
} qcamera_data_argm_t;
#define MAX_EXIF_TABLE_ENTRIES 17
class QCameraExif
{
public:
QCameraExif();
virtual ~QCameraExif();
int32_t addEntry(exif_tag_id_t tagid,
exif_tag_type_t type,
uint32_t count,
void *data);
uint32_t getNumOfEntries() {return m_nNumEntries;};
QEXIF_INFO_DATA *getEntries() {return m_Entries;};
private:
QEXIF_INFO_DATA m_Entries[MAX_EXIF_TABLE_ENTRIES]; // exif tags for JPEG encoder
uint32_t m_nNumEntries; // number of valid entries
};
class QCameraPostProcessor
{
public:
QCameraPostProcessor(QCamera2HardwareInterface *cam_ctrl);
virtual ~QCameraPostProcessor();
int32_t init(jpeg_encode_callback_t jpeg_cb, void *user_data);
int32_t deinit();
int32_t start(QCameraChannel *pSrcChannel);
int32_t stop();
bool validatePostProcess(mm_camera_super_buf_t *frame);
int32_t processData(mm_camera_super_buf_t *frame);
int32_t processRawData(mm_camera_super_buf_t *frame);
int32_t processPPData(mm_camera_super_buf_t *frame);
int32_t processJpegEvt(qcamera_jpeg_evt_payload_t *evt);
int32_t getJpegPaddingReq(cam_padding_info_t &padding_info);
QCameraReprocessChannel * getReprocChannel(uint8_t index);
inline bool getJpegMemOpt() {return mJpegMemOpt;}
inline void setJpegMemOpt(bool val) {mJpegMemOpt = val;}
int32_t setJpegHandle(mm_jpeg_ops_t *pJpegHandle,
mm_jpeg_mpo_ops_t* pJpegMpoHandle, uint32_t clientHandle);
int32_t createJpegSession(QCameraChannel *pSrcChannel);
int8_t getPPChannelCount() {return mPPChannelCount;};
mm_camera_buf_def_t *getOfflinePPInputBuffer(
mm_camera_super_buf_t *src_frame);
QCameraMemory *mOfflineDataBufs;
private:
int32_t sendDataNotify(int32_t msg_type,
camera_memory_t *data,
uint8_t index,
camera_frame_metadata_t *metadata,
qcamera_release_data_t *release_data,
uint32_t super_buf_frame_idx = 0);
int32_t sendEvtNotify(int32_t msg_type, int32_t ext1, int32_t ext2);
qcamera_jpeg_data_t *findJpegJobByJobId(uint32_t jobId);
mm_jpeg_color_format getColorfmtFromImgFmt(cam_format_t img_fmt);
mm_jpeg_format_t getJpegImgTypeFromImgFmt(cam_format_t img_fmt);
int32_t getJpegEncodingConfig(mm_jpeg_encode_params_t& encode_parm,
QCameraStream *main_stream,
QCameraStream *thumb_stream);
int32_t encodeData(qcamera_jpeg_data_t *jpeg_job_data,
uint8_t &needNewSess);
int32_t queryStreams(QCameraStream **main,
QCameraStream **thumb,
QCameraStream **reproc,
mm_camera_buf_def_t **main_image,
mm_camera_buf_def_t **thumb_image,
mm_camera_super_buf_t *main_frame,
mm_camera_super_buf_t *reproc_frame);
int32_t syncStreamParams(mm_camera_super_buf_t *frame,
mm_camera_super_buf_t *reproc_frame);
void releaseSuperBuf(mm_camera_super_buf_t *super_buf);
void releaseSuperBuf(mm_camera_super_buf_t *super_buf,
cam_stream_type_t stream_type);
static void releaseNotifyData(void *user_data,
void *cookie,
int32_t cb_status);
void releaseJpegJobData(qcamera_jpeg_data_t *job);
static void releaseSaveJobData(void *data, void *user_data);
static void releaseRawData(void *data, void *user_data);
int32_t processRawImageImpl(mm_camera_super_buf_t *recvd_frame);
static void releaseJpegData(void *data, void *user_data);
static void releasePPInputData(void *data, void *user_data);
static void releaseOngoingPPData(void *data, void *user_data);
static void *dataProcessRoutine(void *data);
static void *dataSaveRoutine(void *data);
int32_t setYUVFrameInfo(mm_camera_super_buf_t *recvd_frame);
static bool matchJobId(void *data, void *user_data, void *match_data);
static int getJpegMemory(omx_jpeg_ouput_buf_t *out_buf);
static int releaseJpegMemory(omx_jpeg_ouput_buf_t *out_buf);
int32_t doReprocess();
int32_t stopCapture();
private:
QCamera2HardwareInterface *m_parent;
jpeg_encode_callback_t mJpegCB;
void * mJpegUserData;
mm_jpeg_ops_t mJpegHandle;
mm_jpeg_mpo_ops_t mJpegMpoHandle; // handle for mpo composition for dualcam
uint32_t mJpegClientHandle;
uint32_t mJpegSessionId;
void * m_pJpegOutputMem[MM_JPEG_MAX_BUF];
QCameraExif * m_pJpegExifObj;
uint32_t m_bThumbnailNeeded;
int8_t mPPChannelCount;
QCameraReprocessChannel *mPPChannels[CAM_PP_CHANNEL_MAX];
camera_memory_t * m_DataMem; // save frame mem pointer
int8_t m_bInited; // if postproc is inited
QCameraQueue m_inputPPQ; // input queue for postproc
QCameraQueue m_ongoingPPQ; // ongoing postproc queue
QCameraQueue m_inputJpegQ; // input jpeg job queue
QCameraQueue m_ongoingJpegQ; // ongoing jpeg job queue
QCameraQueue m_inputRawQ; // input raw job queue
QCameraQueue m_inputSaveQ; // input save job queue
QCameraCmdThread m_dataProcTh; // thread for data processing
QCameraCmdThread m_saveProcTh; // thread for storing buffers
uint32_t mSaveFrmCnt; // save frame counter
static const char *STORE_LOCATION; // path for storing buffers
bool mUseSaveProc; // use store thread
bool mUseJpegBurst; // use jpeg burst encoding mode
bool mJpegMemOpt;
uint32_t m_JpegOutputMemCount;
uint8_t mNewJpegSessionNeeded;
int32_t m_bufCountPPQ;
Vector<mm_camera_buf_def_t *> m_InputMetadata; // store input metadata buffers for AOST cases
size_t m_PPindex; // counter for each incoming AOST buffer
public:
cam_dimension_t m_dst_dim;
};
}; // namespace qcamera
#endif /* __QCAMERA_POSTPROC_H__ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,267 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __QCAMERA_STATEMACHINE_H__
#define __QCAMERA_STATEMACHINE_H__
// System dependencies
#include <pthread.h>
// Camera dependencies
#include "QCameraQueue.h"
#include "QCameraChannel.h"
#include "cam_semaphore.h"
extern "C" {
#include "mm_camera_interface.h"
}
namespace qcamera {
class QCamera2HardwareInterface;
typedef enum {
/*******BEGIN OF: API EVT*********/
QCAMERA_SM_EVT_SET_PREVIEW_WINDOW = 1, // set preview window
QCAMERA_SM_EVT_SET_CALLBACKS, // set callbacks
QCAMERA_SM_EVT_ENABLE_MSG_TYPE, // enable msg type
QCAMERA_SM_EVT_DISABLE_MSG_TYPE, // disable msg type
QCAMERA_SM_EVT_MSG_TYPE_ENABLED, // query certain msg type is enabled
QCAMERA_SM_EVT_SET_PARAMS, // set parameters
QCAMERA_SM_EVT_SET_PARAMS_STOP, // stop camera after set params, if necessary
QCAMERA_SM_EVT_SET_PARAMS_COMMIT, // commit set params
QCAMERA_SM_EVT_SET_PARAMS_RESTART, // restart after set params, if necessary
QCAMERA_SM_EVT_GET_PARAMS, // get parameters
QCAMERA_SM_EVT_PUT_PARAMS, // put parameters, release param buf
QCAMERA_SM_EVT_PREPARE_PREVIEW, // prepare preview (zsl, camera mode, camcorder mode)
QCAMERA_SM_EVT_START_PREVIEW, // start preview (zsl, camera mode, camcorder mode)
QCAMERA_SM_EVT_START_NODISPLAY_PREVIEW, // start no display preview (zsl, camera mode, camcorder mode)
QCAMERA_SM_EVT_STOP_PREVIEW, // stop preview (zsl, camera mode, camcorder mode)
QCAMERA_SM_EVT_PREVIEW_ENABLED, // query if preview is running
QCAMERA_SM_EVT_STORE_METADATA_IN_BUFS, // request to store meta data in video buffers
QCAMERA_SM_EVT_PRE_START_RECORDING, // pre start recording, to prepare for recording
QCAMERA_SM_EVT_START_RECORDING, // start recording
QCAMERA_SM_EVT_STOP_RECORDING, // stop recording
QCAMERA_SM_EVT_RECORDING_ENABLED, // query if recording is running
QCAMERA_SM_EVT_RELEASE_RECORIDNG_FRAME, // release recording frame
QCAMERA_SM_EVT_PREPARE_SNAPSHOT, // prepare snapshot in case LED needs to be flashed
QCAMERA_SM_EVT_PRE_TAKE_PICTURE, // pre take picutre (to restart preview if necessary)
QCAMERA_SM_EVT_TAKE_PICTURE, // take picutre (zsl, regualr capture, live snapshot
QCAMERA_SM_EVT_CANCEL_PICTURE, // cancel picture
QCAMERA_SM_EVT_START_AUTO_FOCUS, // start auto focus
QCAMERA_SM_EVT_STOP_AUTO_FOCUS, // stop auto focus
QCAMERA_SM_EVT_SEND_COMMAND, // send command
QCAMERA_SM_EVT_RELEASE, // release camera resource
QCAMERA_SM_EVT_DUMP, // dump
QCAMERA_SM_EVT_REG_FACE_IMAGE, // register a face image in imaging lib
/*******END OF: API EVT*********/
QCAMERA_SM_EVT_EVT_INTERNAL, // internal evt notify
QCAMERA_SM_EVT_EVT_NOTIFY, // evt notify from server
QCAMERA_SM_EVT_JPEG_EVT_NOTIFY, // evt notify from jpeg
QCAMERA_SM_EVT_SNAPSHOT_DONE, // internal evt that snapshot is done
QCAMERA_SM_EVT_THERMAL_NOTIFY, // evt notify from thermal daemon
QCAMERA_SM_EVT_STOP_CAPTURE_CHANNEL, // stop capture channel
QCAMERA_SM_EVT_RESTART_PERVIEW, // internal preview restart
QCAMERA_SM_EVT_DELAYED_RESTART, // preview restart needs delay (dual camera mode)
QCAMERA_SM_EVT_SEND_COMMAND_RESTART, // restart after send command (if necessary)
QCAMERA_SM_EVT_RESTART_START_PREVIEW, // preview start as part of restart (dual camera mode)
QCAMERA_SM_EVT_RESTART_STOP_PREVIEW, // preview stop as part of restart (dual camera mode)
QCAMERA_SM_EVT_MAX
} qcamera_sm_evt_enum_t;
typedef enum {
QCAMERA_API_RESULT_TYPE_DEF, // default type, no additional info
QCAMERA_API_RESULT_TYPE_ENABLE_FLAG, // msg_enabled, preview_enabled, recording_enabled
QCAMERA_API_RESULT_TYPE_PARAMS, // returned parameters in string
QCAMERA_API_RESULT_TYPE_HANDLE, // returned handle in int
QCAMERA_API_RESULT_TYPE_MAX
} qcamera_api_result_type_t;
typedef struct {
int32_t status; // api call status
qcamera_sm_evt_enum_t request_api; // api evt requested
qcamera_api_result_type_t result_type; // result type
union {
int enabled; // result_type == QCAMERA_API_RESULT_TYPE_ENABLE_FLAG
char *params; // result_type == QCAMERA_API_RESULT_TYPE_PARAMS
int handle; // result_type ==QCAMERA_API_RESULT_TYPE_HANDLE
};
} qcamera_api_result_t;
typedef struct api_result_list {
qcamera_api_result_t result;
struct api_result_list *next;
}api_result_list;
// definition for payload type of setting callback
typedef struct {
camera_notify_callback notify_cb;
camera_data_callback data_cb;
camera_data_timestamp_callback data_cb_timestamp;
camera_request_memory get_memory;
void *user;
} qcamera_sm_evt_setcb_payload_t;
// definition for payload type of sending command
typedef struct {
int32_t cmd;
int32_t arg1;
int32_t arg2;
} qcamera_sm_evt_command_payload_t;
// definition for payload type of sending command
typedef struct {
void *img_ptr;
cam_pp_offline_src_config_t *config;
} qcamera_sm_evt_reg_face_payload_t;
typedef enum {
QCAMERA_INTERNAL_EVT_FOCUS_UPDATE, // focus updating result
QCAMERA_INTERNAL_EVT_PREP_SNAPSHOT_DONE, // prepare snapshot done
QCAMERA_INTERNAL_EVT_FACE_DETECT_RESULT, // face detection result
QCAMERA_INTERNAL_EVT_HISTOGRAM_STATS, // histogram
QCAMERA_INTERNAL_EVT_CROP_INFO, // crop info
QCAMERA_INTERNAL_EVT_ASD_UPDATE, // asd update result
QCAMERA_INTERNAL_EVT_READY_FOR_SNAPSHOT, // Ready for Prepare Snapshot
QCAMERA_INTERNAL_EVT_LED_MODE_OVERRIDE, // Led mode override
QCAMERA_INTERNAL_EVT_AWB_UPDATE, // awb update result
QCAMERA_INTERNAL_EVT_AE_UPDATE, // ae update result
QCAMERA_INTERNAL_EVT_FOCUS_POS_UPDATE, // focus position update result
QCAMERA_INTERNAL_EVT_HDR_UPDATE, // HDR scene update
QCAMERA_INTERNAL_EVT_RETRO_AEC_UNLOCK, // retro burst AEC unlock event
QCAMERA_INTERNAL_EVT_ZSL_CAPTURE_DONE, // ZSL capture done event
QCAMERA_INTERNAL_EVT_MAX
} qcamera_internal_evt_type_t;
typedef struct {
qcamera_internal_evt_type_t evt_type;
union {
cam_auto_focus_data_t focus_data;
cam_prep_snapshot_state_t prep_snapshot_state;
cam_faces_data_t faces_data;
cam_hist_stats_t stats_data;
cam_crop_data_t crop_data;
cam_auto_scene_t asd_data;
cam_flash_mode_t led_data;
cam_awb_params_t awb_data;
cam_3a_params_t ae_data;
cam_focus_pos_info_t focus_pos;
cam_asd_hdr_scene_data_t hdr_data;
};
} qcamera_sm_internal_evt_payload_t;
class QCameraStateMachine
{
public:
QCameraStateMachine(QCamera2HardwareInterface *ctrl);
virtual ~QCameraStateMachine();
int32_t procAPI(qcamera_sm_evt_enum_t evt, void *api_payload);
int32_t procEvt(qcamera_sm_evt_enum_t evt, void *evt_payload);
bool isPreviewRunning(); // check if preview is running
bool isPreviewReady(); // check if preview is ready
bool isCaptureRunning(); // check if image capture is running
bool isNonZSLCaptureRunning(); // check if image capture is running in non ZSL mode
String8 dump(); //returns the state information in a string
bool isPrepSnapStateRunning();
bool isRecording();
void releaseThread();
bool isDisplayFrameNeeded() { return m_bDisplayFrame; };
int32_t setDisplayFrame(bool enabled) {m_bDisplayFrame=enabled; return 0;};
bool isPreviewCallbackNeeded() { return m_bPreviewCallbackNeeded; };
int32_t setPreviewCallbackNeeded(bool enabled) {m_bPreviewCallbackNeeded=enabled; return 0;};
private:
typedef enum {
QCAMERA_SM_STATE_PREVIEW_STOPPED, // preview is stopped
QCAMERA_SM_STATE_PREVIEW_READY, // preview started but preview window is not set yet
QCAMERA_SM_STATE_PREVIEWING, // previewing
QCAMERA_SM_STATE_PREPARE_SNAPSHOT, // prepare snapshot in case aec estimation is
// needed for LED flash
QCAMERA_SM_STATE_PIC_TAKING, // taking picture (preview stopped)
QCAMERA_SM_STATE_RECORDING, // recording (preview running)
QCAMERA_SM_STATE_VIDEO_PIC_TAKING, // taking live snapshot during recording (preview running)
QCAMERA_SM_STATE_PREVIEW_PIC_TAKING // taking ZSL/live snapshot (recording stopped but preview running)
} qcamera_state_enum_t;
typedef enum
{
QCAMERA_SM_CMD_TYPE_API, // cmd from API
QCAMERA_SM_CMD_TYPE_EVT, // cmd from mm-camera-interface/mm-jpeg-interface event
QCAMERA_SM_CMD_TYPE_EXIT, // cmd for exiting statemachine cmdThread
QCAMERA_SM_CMD_TYPE_MAX
} qcamera_sm_cmd_type_t;
typedef struct {
qcamera_sm_cmd_type_t cmd; // cmd type (where it comes from)
qcamera_sm_evt_enum_t evt; // event type
void *evt_payload; // ptr to payload
} qcamera_sm_cmd_t;
int32_t stateMachine(qcamera_sm_evt_enum_t evt, void *payload);
int32_t procEvtPreviewStoppedState(qcamera_sm_evt_enum_t evt, void *payload);
int32_t procEvtPreviewReadyState(qcamera_sm_evt_enum_t evt, void *payload);
int32_t procEvtPreviewingState(qcamera_sm_evt_enum_t evt, void *payload);
int32_t procEvtPrepareSnapshotState(qcamera_sm_evt_enum_t evt, void *payload);
int32_t procEvtPicTakingState(qcamera_sm_evt_enum_t evt, void *payload);
int32_t procEvtRecordingState(qcamera_sm_evt_enum_t evt, void *payload);
int32_t procEvtVideoPicTakingState(qcamera_sm_evt_enum_t evt, void *payload);
int32_t procEvtPreviewPicTakingState(qcamera_sm_evt_enum_t evt, void *payload);
// main statemachine process routine
static void *smEvtProcRoutine(void *data);
int32_t applyDelayedMsgs();
QCamera2HardwareInterface *m_parent; // ptr to HWI
qcamera_state_enum_t m_state; // statemachine state
QCameraQueue api_queue; // cmd queue for APIs
QCameraQueue evt_queue; // cmd queue for evt from mm-camera-intf/mm-jpeg-intf
pthread_t cmd_pid; // cmd thread ID
cam_semaphore_t cmd_sem; // semaphore for cmd thread
bool m_bDelayPreviewMsgs; // Delay preview callback enable during ZSL snapshot
bool m_bPreviewNeedsRestart; // Preview needs restart
bool m_bPreviewDelayedRestart; // Preview delayed restart
int32_t m_DelayedMsgs;
bool m_RestoreZSL;
bool m_bDisplayFrame;
bool m_bPreviewCallbackNeeded;
};
}; // namespace qcamera
#endif /* __QCAMERA_STATEMACHINE_H__ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,272 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __QCAMERA_STREAM_H__
#define __QCAMERA_STREAM_H__
// Camera dependencies
#include "camera.h"
#include "QCameraCmdThread.h"
#include "QCameraMem.h"
#include "QCameraAllocator.h"
extern "C" {
#include "mm_camera_interface.h"
}
namespace qcamera {
class QCameraStream;
typedef void (*stream_cb_routine)(mm_camera_super_buf_t *frame,
QCameraStream *stream,
void *userdata);
#define CAMERA_MAX_CONSUMER_BATCH_BUFFER_SIZE 16
#define CAMERA_MIN_VIDEO_BATCH_BUFFERS 3
class QCameraStream
{
public:
QCameraStream(QCameraAllocator &allocator,
uint32_t camHandle, uint32_t chId,
mm_camera_ops_t *camOps, cam_padding_info_t *paddingInfo,
bool deffered = false, cam_rotation_t online_rotation = ROTATE_0);
virtual ~QCameraStream();
virtual int32_t init(QCameraHeapMemory *streamInfoBuf,
QCameraHeapMemory *miscBuf,
uint8_t minStreamBufNum,
stream_cb_routine stream_cb,
void *userdata,
bool bDynallocBuf);
virtual int32_t processZoomDone(preview_stream_ops_t *previewWindow,
cam_crop_data_t &crop_info);
virtual int32_t bufDone(uint32_t index);
virtual int32_t bufDone(const void *opaque, bool isMetaData);
virtual int32_t processDataNotify(mm_camera_super_buf_t *bufs);
virtual int32_t start();
virtual int32_t stop();
/* Used for deffered allocation of buffers */
virtual int32_t allocateBuffers();
virtual int32_t mapBuffers();
virtual int32_t releaseBuffs();
static void dataNotifyCB(mm_camera_super_buf_t *recvd_frame, void *userdata);
static void dataNotifySYNCCB(mm_camera_super_buf_t *recvd_frame,
void *userdata);
static void *dataProcRoutine(void *data);
static void *BufAllocRoutine(void *data);
uint32_t getMyHandle() const {return mHandle;}
bool isTypeOf(cam_stream_type_t type);
bool isOrignalTypeOf(cam_stream_type_t type);
int32_t getFrameOffset(cam_frame_len_offset_t &offset);
int32_t getCropInfo(cam_rect_t &crop);
int32_t setCropInfo(cam_rect_t crop);
int32_t getFrameDimension(cam_dimension_t &dim);
int32_t getFormat(cam_format_t &fmt);
QCameraMemory *getStreamBufs() {return mStreamBufs;};
QCameraHeapMemory *getStreamInfoBuf() {return mStreamInfoBuf;};
QCameraHeapMemory *getMiscBuf() {return mMiscBuf;};
uint32_t getMyServerID();
cam_stream_type_t getMyType();
cam_stream_type_t getMyOriginalType();
int32_t acquireStreamBufs();
int32_t mapBuf(uint8_t buf_type, uint32_t buf_idx,
int32_t plane_idx, int fd, size_t size,
mm_camera_map_unmap_ops_tbl_t *ops_tbl = NULL);
int32_t mapBufs(cam_buf_map_type_list bufMapList,
mm_camera_map_unmap_ops_tbl_t *ops_tbl = NULL);
int32_t mapNewBuffer(uint32_t index);
int32_t unmapBuf(uint8_t buf_type, uint32_t buf_idx, int32_t plane_idx,
mm_camera_map_unmap_ops_tbl_t *ops_tbl = NULL);
int32_t setParameter(cam_stream_parm_buffer_t &param);
int32_t getParameter(cam_stream_parm_buffer_t &param);
int32_t syncRuntimeParams();
cam_stream_parm_buffer_t getOutputCrop() { return m_OutputCrop;};
cam_stream_parm_buffer_t getImgProp() { return m_ImgProp;};
static void releaseFrameData(void *data, void *user_data);
int32_t configStream();
bool isDeffered() const { return mDefferedAllocation; }
bool isSyncCBEnabled() {return mSyncCBEnabled;};
void deleteStream();
uint8_t getBufferCount() { return mNumBufs; }
uint32_t getChannelHandle() { return mChannelHandle; }
int32_t getNumQueuedBuf();
uint32_t mDumpFrame;
uint32_t mDumpMetaFrame;
uint32_t mDumpSkipCnt;
void cond_wait();
void cond_signal(bool forceExit = false);
int32_t setSyncDataCB(stream_cb_routine data_cb);
//Stream time stamp. We need this for preview stream to update display
nsecs_t mStreamTimestamp;
//Frame Buffer will be stored here in case framework batch mode.
camera_memory_t *mCurMetaMemory; // Current metadata buffer ptr
int8_t mCurBufIndex; // Buffer count filled in current metadata
int8_t mCurMetaIndex; // Active metadata buffer index
nsecs_t mFirstTimeStamp; // Timestamp of first frame in Metadata.
// Buffer storage structure.
typedef struct {
bool consumerOwned; // Metadata is with Consumer if TRUE
uint8_t numBuffers; // Num of buffer need to released
uint8_t buf_index[CAMERA_MAX_CONSUMER_BATCH_BUFFER_SIZE];
} MetaMemory;
MetaMemory mStreamMetaMemory[CAMERA_MIN_VIDEO_BATCH_BUFFERS];
private:
uint32_t mCamHandle;
uint32_t mChannelHandle;
uint32_t mHandle; // stream handle from mm-camera-interface
mm_camera_ops_t *mCamOps;
cam_stream_info_t *mStreamInfo; // ptr to stream info buf
mm_camera_stream_mem_vtbl_t mMemVtbl;
uint8_t mNumBufs;
uint8_t mNumPlaneBufs;
uint8_t mNumBufsNeedAlloc;
uint8_t *mRegFlags;
stream_cb_routine mDataCB;
stream_cb_routine mSYNCDataCB;
void *mUserData;
QCameraQueue mDataQ;
QCameraCmdThread mProcTh; // thread for dataCB
QCameraHeapMemory *mStreamInfoBuf;
QCameraHeapMemory *mMiscBuf;
QCameraMemory *mStreamBufs;
QCameraMemory *mStreamBatchBufs;
QCameraAllocator &mAllocator;
mm_camera_buf_def_t *mBufDefs;
mm_camera_buf_def_t *mPlaneBufDefs;
cam_frame_len_offset_t mFrameLenOffset;
cam_padding_info_t mPaddingInfo;
cam_rect_t mCropInfo;
cam_rotation_t mOnlineRotation;
pthread_mutex_t mCropLock; // lock to protect crop info
pthread_mutex_t mParameterLock; // lock to sync access to parameters
bool mStreamBufsAcquired;
bool m_bActive; // if stream mProcTh is active
bool mDynBufAlloc; // allow buf allocation in 2 steps
pthread_t mBufAllocPid;
mm_camera_map_unmap_ops_tbl_t m_MemOpsTbl;
cam_stream_parm_buffer_t m_OutputCrop;
cam_stream_parm_buffer_t m_ImgProp;
static int32_t get_bufs(
cam_frame_len_offset_t *offset,
uint8_t *num_bufs,
uint8_t **initial_reg_flag,
mm_camera_buf_def_t **bufs,
mm_camera_map_unmap_ops_tbl_t *ops_tbl,
void *user_data);
static int32_t get_bufs_deffered(
cam_frame_len_offset_t *offset,
uint8_t *num_bufs,
uint8_t **initial_reg_flag,
mm_camera_buf_def_t **bufs,
mm_camera_map_unmap_ops_tbl_t *ops_tbl,
void *user_data);
static int32_t put_bufs(
mm_camera_map_unmap_ops_tbl_t *ops_tbl,
void *user_data);
static int32_t put_bufs_deffered(
mm_camera_map_unmap_ops_tbl_t *ops_tbl,
void *user_data);
static int32_t set_config_ops(
mm_camera_map_unmap_ops_tbl_t *ops_tbl,
void *user_data);
static int32_t invalidate_buf(uint32_t index, void *user_data);
static int32_t clean_invalidate_buf(uint32_t index, void *user_data);
static int32_t backgroundAllocate(void* data);
static int32_t backgroundMap(void* data);
int32_t getBufs(cam_frame_len_offset_t *offset,
uint8_t *num_bufs,
uint8_t **initial_reg_flag,
mm_camera_buf_def_t **bufs,
mm_camera_map_unmap_ops_tbl_t *ops_tbl);
int32_t getBufsDeferred(cam_frame_len_offset_t *offset,
uint8_t *num_bufs,
uint8_t **initial_reg_flag,
mm_camera_buf_def_t **bufs,
mm_camera_map_unmap_ops_tbl_t *ops_tbl);
int32_t putBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl);
int32_t putBufsDeffered();
/* Used for deffered allocation of buffers */
int32_t allocateBatchBufs(cam_frame_len_offset_t *offset,
uint8_t *num_bufs, uint8_t **initial_reg_flag,
mm_camera_buf_def_t **bufs, mm_camera_map_unmap_ops_tbl_t *ops_tbl);
int32_t releaseBatchBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl);
int32_t invalidateBuf(uint32_t index);
int32_t cleanInvalidateBuf(uint32_t index);
int32_t calcOffset(cam_stream_info_t *streamInfo);
int32_t unmapStreamInfoBuf();
int32_t releaseStreamInfoBuf();
int32_t releaseMiscBuf();
int32_t mapBufs(QCameraMemory *heapBuf, cam_mapping_buf_type bufType,
mm_camera_map_unmap_ops_tbl_t *ops_tbl = NULL);
int32_t unMapBuf(QCameraMemory *heapBuf, cam_mapping_buf_type bufType,
mm_camera_map_unmap_ops_tbl_t *ops_tbl = NULL);
bool mDefferedAllocation;
bool wait_for_cond;
pthread_mutex_t m_lock;
pthread_cond_t m_cond;
BackgroundTask mAllocTask;
uint32_t mAllocTaskId;
BackgroundTask mMapTask;
uint32_t mMapTaskId;
bool mSyncCBEnabled;
};
}; // namespace qcamera
#endif /* __QCAMERA_STREAM_H__ */

View file

@ -0,0 +1,177 @@
/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#define LOG_TAG "QCameraThermalAdapter"
// System dependencies
#include <dlfcn.h>
#include <utils/Errors.h>
// Camera dependencies
#include "QCamera2HWI.h"
#include "QCameraThermalAdapter.h"
extern "C" {
#include "mm_camera_dbg.h"
}
using namespace android;
namespace qcamera {
QCameraThermalAdapter& QCameraThermalAdapter::getInstance()
{
static QCameraThermalAdapter instance;
return instance;
}
QCameraThermalAdapter::QCameraThermalAdapter() :
mCallback(NULL),
mHandle(NULL),
mRegister(NULL),
mUnregister(NULL),
mCameraHandle(0),
mCamcorderHandle(0)
{
}
int QCameraThermalAdapter::init(QCameraThermalCallback *thermalCb)
{
const char *error = NULL;
int rc = NO_ERROR;
LOGD("E");
mHandle = dlopen("/vendor/lib/libthermalclient.so", RTLD_NOW);
if (!mHandle) {
error = dlerror();
LOGE("dlopen failed with error %s",
error ? error : "");
rc = UNKNOWN_ERROR;
goto error;
}
*(void **)&mRegister = dlsym(mHandle, "thermal_client_register_callback");
if (!mRegister) {
error = dlerror();
LOGE("dlsym failed with error code %s",
error ? error: "");
rc = UNKNOWN_ERROR;
goto error2;
}
*(void **)&mUnregister = dlsym(mHandle, "thermal_client_unregister_callback");
if (!mUnregister) {
error = dlerror();
LOGE("dlsym failed with error code %s",
error ? error: "");
rc = UNKNOWN_ERROR;
goto error2;
}
mCallback = thermalCb;
// Register camera and camcorder callbacks
mCameraHandle = mRegister(mStrCamera, thermalCallback, NULL);
if (mCameraHandle < 0) {
LOGE("thermal_client_register_callback failed %d",
mCameraHandle);
rc = UNKNOWN_ERROR;
goto error2;
}
mCamcorderHandle = mRegister(mStrCamcorder, thermalCallback, NULL);
if (mCamcorderHandle < 0) {
LOGE("thermal_client_register_callback failed %d",
mCamcorderHandle);
rc = UNKNOWN_ERROR;
goto error3;
}
LOGD("X");
return rc;
error3:
mCamcorderHandle = 0;
mUnregister(mCameraHandle);
error2:
mCameraHandle = 0;
dlclose(mHandle);
mHandle = NULL;
error:
LOGD("X");
return rc;
}
void QCameraThermalAdapter::deinit()
{
LOGD("E");
if (mUnregister) {
if (mCameraHandle) {
mUnregister(mCameraHandle);
mCameraHandle = 0;
}
if (mCamcorderHandle) {
mUnregister(mCamcorderHandle);
mCamcorderHandle = 0;
}
}
if (mHandle)
dlclose(mHandle);
mHandle = NULL;
mRegister = NULL;
mUnregister = NULL;
mCallback = NULL;
LOGD("X");
}
char QCameraThermalAdapter::mStrCamera[] = "camera";
char QCameraThermalAdapter::mStrCamcorder[] = "camcorder";
int QCameraThermalAdapter::thermalCallback(int level,
void *userdata, void *data)
{
int rc = 0;
LOGD("E");
QCameraThermalCallback *mcb = getInstance().mCallback;
if (mcb) {
mcb->setThermalLevel((qcamera_thermal_level_enum_t) level);
rc = mcb->thermalEvtHandle(mcb->getThermalLevel(), userdata, data);
}
LOGD("X");
return rc;
}
qcamera_thermal_level_enum_t *QCameraThermalCallback::getThermalLevel() {
return &mLevel;
}
void QCameraThermalCallback::setThermalLevel(qcamera_thermal_level_enum_t level) {
mLevel = level;
}
}; //namespace qcamera

View file

@ -0,0 +1,91 @@
/* Copyright (c) 2013, 2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __QCAMERA_THERMAL_ADAPTER__
#define __QCAMERA_THERMAL_ADAPTER__
namespace qcamera {
typedef enum {
QCAMERA_THERMAL_NO_ADJUSTMENT = 0,
QCAMERA_THERMAL_SLIGHT_ADJUSTMENT,
QCAMERA_THERMAL_BIG_ADJUSTMENT,
QCAMERA_THERMAL_MAX_ADJUSTMENT,
QCAMERA_THERMAL_SHUTDOWN = 10
} qcamera_thermal_level_enum_t;
typedef enum {
QCAMERA_THERMAL_ADJUST_FPS,
QCAMERA_THERMAL_ADJUST_FRAMESKIP,
} qcamera_thermal_mode;
class QCameraThermalCallback
{
public:
virtual int thermalEvtHandle(qcamera_thermal_level_enum_t *level,
void *userdata, void *data) = 0;
virtual ~QCameraThermalCallback() {}
qcamera_thermal_level_enum_t *getThermalLevel();
void setThermalLevel(qcamera_thermal_level_enum_t level);
private:
qcamera_thermal_level_enum_t mLevel;
};
class QCameraThermalAdapter
{
public:
static QCameraThermalAdapter& getInstance();
int init(QCameraThermalCallback *thermalCb);
void deinit();
private:
static char mStrCamera[];
static char mStrCamcorder[];
static int thermalCallback(int level, void *userdata, void *data);
QCameraThermalCallback *mCallback;
void *mHandle;
int (*mRegister)(char *name,
int (*callback)(int, void *userdata, void *data), void *data);
int (*mUnregister)(int handle);
int mCameraHandle;
int mCamcorderHandle;
QCameraThermalAdapter();
QCameraThermalAdapter(QCameraThermalAdapter const& copy); // not implemented
QCameraThermalAdapter& operator=(QCameraThermalAdapter const& copy); // not implemented
};
}; // namespace qcamera
#endif /* __QCAMERA_THERMAL_ADAPTER__ */

View file

@ -0,0 +1,47 @@
/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __QCAMERA2EXTERNAL_H__
#define __QCAMERA2EXTERNAL_H__
// System dependencies
#include <utils/Errors.h>
// Display dependencies
#include "QServiceUtils.h"
namespace qcamera {
inline android::status_t setCameraLaunchStatus(uint32_t on) {
return ::setCameraLaunchStatus(on);
}
}; // namespace qcamera
#endif /* __QCAMERA2EXTERNAL_H__ */

View file

@ -0,0 +1,63 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
qcamera_test.cpp \
LOCAL_SHARED_LIBRARIES:= \
libdl \
libui \
libutils \
libcutils \
libbinder \
libmedia \
libui \
libgui \
libcamera_client \
libskia \
libstagefright \
libstagefright_foundation \
ifneq (1,$(filter 1,$(shell echo "$$(( $(PLATFORM_SDK_VERSION) >= 18 ))" )))
LOCAL_SHARED_LIBRARIES += \
libmedia_native \
LOCAL_32_BIT_ONLY := $(BOARD_QTI_CAMERA_32BIT_ONLY)
LOCAL_CFLAGS += -DUSE_JB_MR1
endif
LOCAL_C_INCLUDES += \
frameworks/base/include/ui \
frameworks/base/include/surfaceflinger \
frameworks/base/include/camera \
frameworks/base/include/media \
external/skia/include/core \
external/skia/include/images \
$(TARGET_OUT_HEADERS)/qcom/display \
hardware/qcom/camera/QCamera2/stack/common \
frameworks/av/include/media/stagefright \
frameworks/native/include/media/openmax \
$(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
LOCAL_MODULE:= camera_test
LOCAL_MODULE_TAGS:= tests
LOCAL_CFLAGS += -Wall -Wextra -Werror -Wno-unused-parameter
LOCAL_CFLAGS += -O0
ifeq (1,$(filter 1,$(shell echo "$$(( $(PLATFORM_SDK_VERSION) >= 20 ))" )))
LOCAL_CFLAGS += -DUSE_SDK_20_OR_HIGHER
ifeq ($(TARGET_USES_AOSP),true)
LOCAL_CFLAGS += -DVANILLA_HAL
endif
endif
#include $(BUILD_EXECUTABLE)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,100 @@
/*
* Copyright (C) 2014,2015 Thundersoft Corporation
* All rights Reserved
*
* 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 __TS_DETECTFACE_ENGINE_H__
#define __TS_DETECTFACE_ENGINE_H__
#include "ts_makeup_data.h"
#include "ts_makeup_image.h"
typedef void* TSHandle;
/*===========================================================================
* FUNCTION : ts_detectface_create_context
*
* DESCRIPTION: create context.The method MUST call at first time.
*
*
* RETURN : TSHandle as the context handle
*
*==========================================================================*/
TSHandle ts_detectface_create_context();
/*===========================================================================
* FUNCTION : ts_detectface_destroy_context
*
* DESCRIPTION: destroy context. The method MUST call at last time.
* Before you MUST call ts_detectface_create_context method
* to create context and get context handle.
*
* PARAMETERS :
* @param[in] contexTSHandle : The context handle pointer.
*
*
*==========================================================================*/
void ts_detectface_destroy_context(TSHandle* contexTSHandle);
/*===========================================================================
* FUNCTION : ts_detectface_detect
*
* DESCRIPTION: start detect.Before you MUST call ts_detectface_create_context method
* to create context and get context handle.
*
* PARAMETERS :
* @param[in] contexTSHandle : The context handle.
* @param[in] pInData : The TSMakeupData pointer.MUST not NULL.
*
* RETURN : int If less than zero failed, otherwise the number of the detected faces.
*
*==========================================================================*/
int ts_detectface_detect(TSHandle contexTSHandle, TSMakeupData *pInData);
/*===========================================================================
* FUNCTION : ts_detectface_detectEx
*
* DESCRIPTION: start detect.Before you MUST call ts_detectface_create_context method
* to create context and get context handle.
*
* PARAMETERS :
* @param[in] contexTSHandle : The context handle.
* @param[in] pInData : The TSMakeupDataEx pointer.MUST not NULL.
*
* RETURN : int If less than zero failed, otherwise the number of the detected faces.
*
*==========================================================================*/
int ts_detectface_detectEx(TSHandle contexTSHandle, TSMakeupDataEx *pInData);
/*===========================================================================
* FUNCTION : ts_detectface_get_face_info
*
* DESCRIPTION: get detected face information.Before you MUST call ts_detectface_detect method
* to detect face.
*
* PARAMETERS :
* @param[in] contexTSHandle : The context handle.
* @param[in] index : The face index.MUST > 0.
* @param[out] pFaceRect : The face rects.MUST not NULL.
* @param[out] leftEye : The left eye rect.
* @param[out] rightEye : The right eye rect.
* @param[out] pMouth : The mount rect.
*
* RETURN : TS_OK if success, otherwise failed.
*
*==========================================================================*/
int ts_detectface_get_face_info(TSHandle contexTSHandle, int index, TSRect *pFaceRect, TSRect *leftEye, TSRect *rightEye, TSRect *pMouth);
#endif // __TS_DETECTFACE_ENGINE_H__

View file

@ -0,0 +1,49 @@
/*
* Copyright (C) 2014,2015 Thundersoft Corporation
* All rights Reserved
*
* 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 __TS_MAKEUP_DATA_H__
#define __TS_MAKEUP_DATA_H__
#define TS_OK (0x00000000) //Successful
#define TS_ERROR_PARAM (0x00000001) //Parameters error
#define TS_ERROR_IO (0x00000002) //Input or output error
#define TS_ERROR_INTERNAL (0x00000003) //Internal error
#define TS_NO_MEMORY (0x00000004) //No memory error
/*
* Data struct : rectangle
*/
typedef struct __tag_tsrect
{
long left;
long top;
long right;
long bottom;
} TSRect;
/*
* Data struct : point
*/
typedef struct __tag_tsmakeuppoint
{
long x;
long y;
} TSPoint;
#endif // __TS_MAKEUP_DATA_H__

View file

@ -0,0 +1,95 @@
/*
* Copyright (C) 2014,2015 Thundersoft Corporation
* All rights Reserved
*
* 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 __TS_MAKEUP_ENGINI_H__
#define __TS_MAKEUP_ENGINI_H__
#include "ts_makeup_data.h"
#include "ts_makeup_image.h"
/*
* FUNCTION : ts_makeup_get_supported_face_num
*
* DESCRIPTION: get supported face number
*
* RETURN : The supported face number
*
*/
int ts_makeup_get_supported_face_num();
/*
* FUNCTION : ts_makeup_skin_beauty
*
* DESCRIPTION: skin beauty method.
*
* PARAMETERS :
* @param[in] pInData : The TSMakeupData pointer.MUST not NULL.
* @param[out] pOutData : The TSMakeupData pointer.MUST not NULL.
* @param[in] pFaceRect : The face rect.MUST not NULL.
* @param[in] cleanLevel : Skin clean level, value range [0,100].
* @param[in] whiteLevel : Skin white level, value range [0,100].
* RETURN : TS_OK if success, otherwise failed.
*
*/
int ts_makeup_skin_beauty(TSMakeupData *pInData, TSMakeupData *pOutData, const TSRect *pFaceRect, int cleanLevel,int whiteLevel);
/*
* FUNCTION : ts_makeup_skin_beautyEx
*
* DESCRIPTION: skin beauty method.
*
* PARAMETERS :
* @param[in] pInData : The TSMakeupDataEx pointer.MUST not NULL.
* @param[out] pOutData : The TSMakeupDataEx pointer.MUST not NULL.
* @param[in] pFaceRect : The face rect.MUST not NULL.
* @param[in] cleanLevel : Skin clean level, value range [0,100].
* @param[in] whiteLevel : Skin white level, value range [0,100].
* RETURN : TS_OK if success, otherwise failed.
*
*/
int ts_makeup_skin_beautyEx(TSMakeupDataEx *pInData, TSMakeupDataEx *pOutData, const TSRect *pFaceRect, int cleanLevel, int whiteLevel);
/*
* FUNCTION : ts_makeup_finish
*
* DESCRIPTION: Finish makeup,call this method at last time.
* This method MUST be called After ts_makeup_skin_clean and ts_makeup_skin_whiten
*
*/
void ts_makeup_finish();
/*
* FUNCTION : ts_makeup_warp_face
*
* DESCRIPTION: do warp face.
*
* PARAMETERS :
* @param[in] pInData : The TSMakeupData pointer.MUST not NULL.
* @param[out] pOutData : The TSMakeupData pointer.MUST not NULL.
* @param[in] pLeftEye : The left eye rect pointer.MUST not NULL.
* @param[in] pRightEye : The right eye rect pointer.MUST not NULL.
* @param[in] pMouth : The mouth rect pointer.MUST not NULL.
* @param[in] bigEyeLevel : The big eye level, value range [0,100].
* @param[in] trimFaceLevel : The trim face level, value range [0,100].
*
* RETURN : TS_OK if success, otherwise failed.
*
*/
int ts_makeup_warp_face(TSMakeupData *pInData, TSMakeupData *pOutData,
const TSRect *pLeftEye, const TSRect *pRightEye, const TSRect *pMouth, int bigEyeLevel, int trimFaceLevel);
#endif // __TS_MAKEUP_ENGINI_H__

View file

@ -0,0 +1,46 @@
/*
* Copyright (C) 2014,2015 Thundersoft Corporation
* All rights Reserved
*
* 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 __TS_MAKEUP_IMGAGE_H__
#define __TS_MAKEUP_IMGAGE_H__
/*
* Data struct : TSMakeupData
*/
typedef struct __tag_tsmakeupdata
{
int frameWidth; //NV21 Frame width.MUST > 0.
int frameHeight; //NV21 Frame height. MUST > 0.
unsigned char *yBuf; //NV21 Y buffer pointer.MUST not null.
unsigned char *uvBuf; //NV21 UV buffer pointer.MUST not null.
}TSMakeupData;
/*
* Data struct : TSMakeupDataEx
*/
typedef struct __tag_tsmakeupdataEx
{
int frameWidth; //NV21 Frame width.MUST > 0.
int frameHeight; //NV21 Frame height. MUST > 0.
unsigned char *yBuf; //NV21 Y buffer pointer.MUST not null.
unsigned char *uvBuf; //NV21 UV buffer pointer.MUST not null.
int yStride; //NV21 Y buffer stride len
int uvStride; //NV21 uv buffer stride len
}TSMakeupDataEx;
#endif // __TS_MAKEUP_IMGAGE_H__

View file

@ -0,0 +1,450 @@
/* Copyright (c) 2011-2014, 2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#define ALOG_NIDEBUG 0
#define LOG_TAG "QualcommCamera"
// System dependencies
#include <utils/threads.h>
#include <binder/IMemory.h>
#include <binder/MemoryBase.h>
#include <binder/MemoryHeapBase.h>
#include <utils/RefBase.h>
extern "C" {
#define TIME_H <SYSTEM_HEADER_PREFIX/time.h>
#include TIME_H
}
// Camera dependencies
#include "QualcommCamera.h"
#include "QCamera2Factory.h"
#include "QCamera2HWI.h"
/* HAL function implementation goes here*/
/**
* 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.
*/
static hw_module_methods_t camera_module_methods = {
open: camera_device_open,
};
static hw_module_t camera_common = {
tag: HARDWARE_MODULE_TAG,
module_api_version: CAMERA_MODULE_API_VERSION_1_0,
hal_api_version: HARDWARE_HAL_API_VERSION,
id: CAMERA_HARDWARE_MODULE_ID,
name: "QCamera Module",
author: "Quic on behalf of CAF",
methods: &camera_module_methods,
dso: NULL,
reserved: {0},
};
using namespace qcamera;
namespace android {
typedef struct {
camera_device hw_dev;
QCamera2HardwareInterface *hardware;
int camera_released;
int cameraId;
} camera_hardware_t;
typedef struct {
camera_memory_t mem;
int32_t msgType;
sp<IMemory> dataPtr;
void* user;
unsigned int index;
} q_cam_memory_t;
QCamera2HardwareInterface *util_get_Hal_obj( struct camera_device * device)
{
QCamera2HardwareInterface *hardware = NULL;
if(device && device->priv){
camera_hardware_t *camHal = (camera_hardware_t *)device->priv;
hardware = camHal->hardware;
}
return hardware;
}
extern "C" int get_number_of_cameras()
{
/* try to query every time we get the call!*/
ALOGE("Q%s: E");
return QCamera2Factory::get_number_of_cameras();
}
extern "C" int get_camera_info(int camera_id, struct camera_info *info)
{
int rc = -1;
ALOGE("Q%s: E");
if(info) {
QCamera2Factory::get_camera_info(camera_id, info);
}
LOGD("Q%s: X");
return rc;
}
/* HAL should return NULL if it fails to open camera hardware. */
extern "C" int camera_device_open(
const struct hw_module_t* module, const char* id,
struct hw_device_t** hw_device)
{
int rc = -1;
camera_device *device = NULL;
if(module && id && hw_device) {
if (!strcmp(module->name, camera_common.name)) {
int cameraId = atoi(id);
camera_hardware_t *camHal =
(camera_hardware_t *) malloc(sizeof (camera_hardware_t));
if(!camHal) {
*hw_device = NULL;
ALOGE(" end in no mem");
return rc;
}
/* we have the camera_hardware obj malloced */
memset(camHal, 0, sizeof (camera_hardware_t));
camHal->hardware = new QCamera2HardwareInterface((uint32_t)cameraId);
if (camHal->hardware) {
camHal->cameraId = cameraId;
device = &camHal->hw_dev;
device->common.close = close_camera_device;
device->ops = &QCamera2HardwareInterface::mCameraOps;
device->priv = (void *)camHal;
rc = 0;
} else {
if (camHal->hardware) {
delete camHal->hardware;
camHal->hardware = NULL;
}
free(camHal);
device = NULL;
goto EXIT;
}
}
}
/* pass actual hw_device ptr to framework. This amkes that we actally be use memberof() macro */
*hw_device = (hw_device_t*)&device->common;
EXIT:
ALOGE(" end rc %d", rc);
return rc;
}
extern "C" int close_camera_device( hw_device_t *hw_dev)
{
ALOGE("Q%s: device =%p E", hw_dev);
int rc = -1;
camera_device_t *device = (camera_device_t *)hw_dev;
if(device) {
camera_hardware_t *camHal = (camera_hardware_t *)device->priv;
if(camHal ) {
QCamera2HardwareInterface *hardware = util_get_Hal_obj( device);
if(!camHal->camera_released) {
if(hardware != NULL) {
hardware->release(device);
}
}
if(hardware != NULL)
delete hardware;
free(camHal);
}
rc = 0;
}
return rc;
}
int set_preview_window(struct camera_device * device,
struct preview_stream_ops *window)
{
int rc = -1;
QCamera2HardwareInterface *hardware = util_get_Hal_obj(device);
if(hardware != NULL) {
rc = hardware->set_preview_window(device, window);
}
return rc;
}
void 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)
{
ALOGE("Q%s: E");
QCamera2HardwareInterface *hardware = util_get_Hal_obj(device);
if(hardware != NULL){
hardware->set_CallBacks(device, notify_cb,data_cb, data_cb_timestamp, get_memory, user);
}
}
void enable_msg_type(struct camera_device * device, int32_t msg_type)
{
QCamera2HardwareInterface *hardware = util_get_Hal_obj(device);
if(hardware != NULL){
hardware->enable_msg_type(device, msg_type);
}
}
void disable_msg_type(struct camera_device * device, int32_t msg_type)
{
QCamera2HardwareInterface *hardware = util_get_Hal_obj(device);
ALOGE("Q%s: E");
if(hardware != NULL){
hardware->disable_msg_type(device, msg_type);
}
}
int msg_type_enabled(struct camera_device * device, int32_t msg_type)
{
ALOGE("Q%s: E");
int rc = -1;
QCamera2HardwareInterface *hardware = util_get_Hal_obj(device);
if(hardware != NULL){
rc = hardware->msg_type_enabled(device, msg_type);
}
return rc;
}
int start_preview(struct camera_device * device)
{
ALOGE("Q%s: E");
int rc = -1;
QCamera2HardwareInterface *hardware = util_get_Hal_obj(device);
if(hardware != NULL){
rc = hardware->start_preview(device);
}
ALOGE("Q%s: X");
return rc;
}
void stop_preview(struct camera_device * device)
{
ALOGE("Q%s: E");
QCamera2HardwareInterface *hardware = util_get_Hal_obj(device);
if(hardware != NULL){
hardware->stop_preview(device);
}
}
int preview_enabled(struct camera_device * device)
{
ALOGE("Q%s: E");
int rc = -1;
QCamera2HardwareInterface *hardware = util_get_Hal_obj(device);
if(hardware != NULL){
rc = hardware->preview_enabled(device);
}
return rc;
}
int store_meta_data_in_buffers(struct camera_device * device, int enable)
{
ALOGE("Q%s: E");
int rc = -1;
QCamera2HardwareInterface *hardware = util_get_Hal_obj(device);
if(hardware != NULL){
rc = hardware->store_meta_data_in_buffers(device, enable);
}
return rc;
}
int start_recording(struct camera_device * device)
{
ALOGE("Q%s: E");
int rc = -1;
QCamera2HardwareInterface *hardware = util_get_Hal_obj(device);
if(hardware != NULL){
rc = hardware->start_recording(device);
}
return rc;
}
void stop_recording(struct camera_device * device)
{
ALOGE("Q%s: E");
QCamera2HardwareInterface *hardware = util_get_Hal_obj(device);
if(hardware != NULL){
hardware->stop_recording(device);
}
}
int recording_enabled(struct camera_device * device)
{
ALOGE("Q%s: E");
int rc = -1;
QCamera2HardwareInterface *hardware = util_get_Hal_obj(device);
if(hardware != NULL){
rc = hardware->recording_enabled(device);
}
return rc;
}
void release_recording_frame(struct camera_device * device,
const void *opaque)
{
LOGD("Q%s: E");
QCamera2HardwareInterface *hardware = util_get_Hal_obj(device);
if(hardware != NULL){
hardware->release_recording_frame(device, opaque);
}
}
int auto_focus(struct camera_device * device)
{
ALOGE("Q%s: E");
int rc = -1;
QCamera2HardwareInterface *hardware = util_get_Hal_obj(device);
if(hardware != NULL){
rc = hardware->auto_focus(device);
}
return rc;
}
int cancel_auto_focus(struct camera_device * device)
{
ALOGE("Q%s: E");
int rc = -1;
QCamera2HardwareInterface *hardware = util_get_Hal_obj(device);
if(hardware != NULL){
rc = hardware->cancel_auto_focus(device);
}
return rc;
}
int take_picture(struct camera_device * device)
{
ALOGE("Q%s: E");
int rc = -1;
QCamera2HardwareInterface *hardware = util_get_Hal_obj(device);
if(hardware != NULL){
rc = hardware->take_picture(device);
}
return rc;
}
int cancel_picture(struct camera_device * device)
{
ALOGE("Q%s: E");
int rc = -1;
QCamera2HardwareInterface *hardware = util_get_Hal_obj(device);
if(hardware != NULL){
rc = hardware->cancel_picture(device);
}
return rc;
}
int set_parameters(struct camera_device * device, const char *parms)
{
ALOGE("Q%s: E");
int rc = -1;
QCamera2HardwareInterface *hardware = util_get_Hal_obj(device);
if(hardware != NULL && parms){
rc = hardware->set_parameters(device, parms);
}
return rc;
}
char* get_parameters(struct camera_device * device)
{
ALOGE("Q%s: E");
QCamera2HardwareInterface *hardware = util_get_Hal_obj(device);
if(hardware != NULL){
char *parms = NULL;
parms = hardware->get_parameters(device);
return parms;
}
return NULL;
}
void put_parameters(struct camera_device * device, char *parm)
{
ALOGE("Q%s: E");
QCamera2HardwareInterface *hardware = util_get_Hal_obj(device);
if(hardware != NULL){
hardware->put_parameters(device, parm);
}
}
int send_command(struct camera_device * device,
int32_t cmd, int32_t arg1, int32_t arg2)
{
ALOGE("Q%s: E");
int rc = -1;
QCamera2HardwareInterface *hardware = util_get_Hal_obj(device);
if(hardware != NULL){
rc = hardware->send_command(device, cmd, arg1, arg2);
}
return rc;
}
void release(struct camera_device * device)
{
ALOGE("Q%s: E");
QCamera2HardwareInterface *hardware = util_get_Hal_obj(device);
if(hardware != NULL){
camera_hardware_t *camHal = (camera_hardware_t *)device->priv;
hardware->release(device);
camHal->camera_released = true;
}
}
int dump(struct camera_device * device, int fd)
{
ALOGE("Q%s: E");
int rc = -1;
QCamera2HardwareInterface *hardware = util_get_Hal_obj(device);
if(hardware != NULL){
rc = hardware->dump(device, fd);
}
return rc;
}
}; // namespace android

View file

@ -0,0 +1,107 @@
/* Copyright (c) 2011-2013, 2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef ANDROID_HARDWARE_QUALCOMM_CAMERA_H
#define ANDROID_HARDWARE_QUALCOMM_CAMERA_H
// Camera dependencies
#include "QCamera2HWI.h"
extern "C" {
int get_number_of_cameras();
int get_camera_info(int camera_id, struct camera_info *info);
int camera_device_open(const struct hw_module_t* module, const char* id,
struct hw_device_t** device);
hw_device_t * open_camera_device(int cameraId);
int close_camera_device( hw_device_t *);
namespace android {
int set_preview_window(struct camera_device *,
struct preview_stream_ops *window);
void set_CallBacks(struct camera_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);
void enable_msg_type(struct camera_device *, int32_t msg_type);
void disable_msg_type(struct camera_device *, int32_t msg_type);
int msg_type_enabled(struct camera_device *, int32_t msg_type);
int start_preview(struct camera_device *);
void stop_preview(struct camera_device *);
int preview_enabled(struct camera_device *);
int store_meta_data_in_buffers(struct camera_device *, int enable);
int start_recording(struct camera_device *);
void stop_recording(struct camera_device *);
int recording_enabled(struct camera_device *);
void release_recording_frame(struct camera_device *,
const void *opaque);
int auto_focus(struct camera_device *);
int cancel_auto_focus(struct camera_device *);
int take_picture(struct camera_device *);
int cancel_picture(struct camera_device *);
int set_parameters(struct camera_device *, const char *parms);
char* get_parameters(struct camera_device *);
void put_parameters(struct camera_device *, char *);
int send_command(struct camera_device *,
int32_t cmd, int32_t arg1, int32_t arg2);
void release(struct camera_device *);
int dump(struct camera_device *, int fd);
}; // namespace android
} //extern "C"
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,625 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __QCAMERA3_CHANNEL_H__
#define __QCAMERA3_CHANNEL_H__
// System dependencies
#include <utils/List.h>
#include <utils/Mutex.h>
#include <utils/Vector.h>
#include "gralloc_priv.h"
// Camera dependencies
#include "cam_intf.h"
#include "cam_types.h"
#include "camera3.h"
#include "QCamera3HALHeader.h"
#include "QCamera3Mem.h"
#include "QCamera3PostProc.h"
#include "QCamera3Stream.h"
#include "QCamera3StreamMem.h"
extern "C" {
#include "mm_camera_interface.h"
#include "mm_jpeg_interface.h"
}
using namespace android;
#define MIN_STREAMING_BUFFER_NUM 7+11
#define QCAMERA_DUMP_FRM_PREVIEW 1
#define QCAMERA_DUMP_FRM_VIDEO (1<<1)
#define QCAMERA_DUMP_FRM_SNAPSHOT (1<<2)
#define QCAMERA_DUMP_FRM_CALLBACK (1<<3)
#define QCAMERA_DUMP_FRM_INPUT_REPROCESS (1<<6)
typedef int64_t nsecs_t;
namespace qcamera {
typedef void (*channel_cb_routine)(mm_camera_super_buf_t *metadata,
camera3_stream_buffer_t *buffer,
uint32_t frame_number, bool isInputBuffer,
void *userdata);
class QCamera3Channel
{
public:
QCamera3Channel(uint32_t cam_handle,
uint32_t channel_handle,
mm_camera_ops_t *cam_ops,
channel_cb_routine cb_routine,
cam_padding_info_t *paddingInfo,
uint32_t postprocess_mask,
void *userData, uint32_t numBuffers);
virtual ~QCamera3Channel();
virtual int32_t start();
virtual int32_t stop();
virtual int32_t setBatchSize(uint32_t);
virtual int32_t queueBatchBuf();
virtual int32_t setPerFrameMapUnmap(bool enable);
int32_t bufDone(mm_camera_super_buf_t *recvd_frame);
int32_t setBundleInfo(const cam_bundle_config_t &bundleInfo);
virtual uint32_t getStreamTypeMask();
uint32_t getStreamID(uint32_t streamMask);
void destroy();
virtual int32_t initialize(cam_is_type_t isType) = 0;
virtual int32_t request(buffer_handle_t * /*buffer*/,
uint32_t /*frameNumber*/){ return 0;};
virtual int32_t request(buffer_handle_t * /*buffer*/,
uint32_t /*frameNumber*/,
camera3_stream_buffer_t* /*pInputBuffer*/,
metadata_buffer_t* /*metadata*/){ return 0;};
virtual void streamCbRoutine(mm_camera_super_buf_t *super_frame,
QCamera3Stream *stream) = 0;
virtual int32_t registerBuffer(buffer_handle_t *buffer, cam_is_type_t isType) = 0;
virtual QCamera3StreamMem *getStreamBufs(uint32_t len) = 0;
virtual void putStreamBufs() = 0;
virtual int32_t flush();
QCamera3Stream *getStreamByHandle(uint32_t streamHandle);
uint32_t getMyHandle() const {return m_handle;};
uint32_t getNumOfStreams() const {return m_numStreams;};
uint32_t getNumBuffers() const {return mNumBuffers;};
QCamera3Stream *getStreamByIndex(uint32_t index);
static void streamCbRoutine(mm_camera_super_buf_t *super_frame,
QCamera3Stream *stream, void *userdata);
void dumpYUV(mm_camera_buf_def_t *frame, cam_dimension_t dim,
cam_frame_len_offset_t offset, uint8_t name);
bool isUBWCEnabled();
cam_format_t getStreamDefaultFormat(cam_stream_type_t type);
void *mUserData;
cam_padding_info_t mPaddingInfo;
QCamera3Stream *mStreams[MAX_STREAM_NUM_IN_BUNDLE];
uint32_t m_numStreams;
protected:
int32_t addStream(cam_stream_type_t streamType,
cam_format_t streamFormat,
cam_dimension_t streamDim,
cam_rotation_t streamRotation,
uint8_t minStreamBufnum,
uint32_t postprocessMask,
cam_is_type_t isType,
uint32_t batchSize = 0);
int32_t allocateStreamInfoBuf(camera3_stream_t *stream);
uint32_t m_camHandle;
mm_camera_ops_t *m_camOps;
bool m_bIsActive;
uint32_t m_handle;
mm_camera_buf_notify_t mDataCB;
QCamera3HeapMemory *mStreamInfoBuf;
channel_cb_routine mChannelCB;
//cam_padding_info_t *mPaddingInfo;
uint32_t mPostProcMask;
uint32_t mYUVDump;
cam_is_type_t mIsType;
uint32_t mNumBuffers;
/* Enable unmapping of buffer before issuing buffer callback. Default value
* for this flag is true and is selectively set to false for the usecases
* such as HFR to avoid any performance hit due to mapping/unmapping */
bool mPerFrameMapUnmapEnable;
uint32_t frm_num;
uint32_t dumpFrmCnt;
uint32_t skip_mode;
uint32_t mDumpSkipCnt;
};
/* QCamera3ProcessingChannel is used to handle all streams that are directly
* generated by hardware and given to frameworks without any postprocessing at HAL.
* It also handles input streams that require reprocessing by hardware and then
* returned to frameworks. */
class QCamera3ProcessingChannel : public QCamera3Channel
{
public:
QCamera3ProcessingChannel(uint32_t cam_handle,
uint32_t channel_handle,
mm_camera_ops_t *cam_ops,
channel_cb_routine cb_routine,
cam_padding_info_t *paddingInfo,
void *userData,
camera3_stream_t *stream,
cam_stream_type_t stream_type,
uint32_t postprocess_mask,
QCamera3Channel *metadataChannel,
uint32_t numBuffers = MAX_INFLIGHT_REQUESTS);
~QCamera3ProcessingChannel();
virtual int32_t initialize(cam_is_type_t isType);
virtual int32_t request(buffer_handle_t *buffer,
uint32_t frameNumber,
camera3_stream_buffer_t* pInputBuffer,
metadata_buffer_t* metadata);
virtual void streamCbRoutine(mm_camera_super_buf_t *super_frame,
QCamera3Stream *stream);
virtual QCamera3StreamMem *getStreamBufs(uint32_t len);
virtual void putStreamBufs();
virtual int32_t registerBuffer(buffer_handle_t *buffer, cam_is_type_t isType);
virtual int32_t stop();
virtual reprocess_type_t getReprocessType() = 0;
virtual void reprocessCbRoutine(buffer_handle_t *resultBuffer,
uint32_t resultFrameNumber);
int32_t queueReprocMetadata(mm_camera_super_buf_t *metadata);
int32_t metadataBufDone(mm_camera_super_buf_t *recvd_frame);
int32_t translateStreamTypeAndFormat(camera3_stream_t *stream,
cam_stream_type_t &streamType,
cam_format_t &streamFormat);
int32_t setReprocConfig(reprocess_config_t &reproc_cfg,
camera3_stream_buffer_t *pInputBuffer,
metadata_buffer_t *metadata,
cam_format_t streamFormat, cam_dimension_t dim);
int32_t setFwkInputPPData(qcamera_fwk_input_pp_data_t *src_frame,
camera3_stream_buffer_t *pInputBuffer,
reprocess_config_t *reproc_cfg,
metadata_buffer_t *metadata,
buffer_handle_t *output_buffer,
uint32_t frameNumber);
int32_t checkStreamCbErrors(mm_camera_super_buf_t *super_frame,
QCamera3Stream *stream);
int32_t getStreamSize(cam_dimension_t &dim);
QCamera3PostProcessor m_postprocessor; // post processor
void showDebugFPS(int32_t streamType);
protected:
uint8_t mDebugFPS;
int mFrameCount;
int mLastFrameCount;
nsecs_t mLastFpsTime;
bool isWNREnabled() {return m_bWNROn;};
void startPostProc(const reprocess_config_t &reproc_cfg);
void issueChannelCb(buffer_handle_t *resultBuffer,
uint32_t resultFrameNumber);
int32_t releaseOfflineMemory(uint32_t resultFrameNumber);
QCamera3StreamMem mMemory; //output buffer allocated by fwk
camera3_stream_t *mCamera3Stream;
uint32_t mNumBufs;
cam_stream_type_t mStreamType;
cam_format_t mStreamFormat;
uint8_t mIntent;
bool mPostProcStarted;
bool mInputBufferConfig; // Set when the processing channel is configured
// for processing input(framework) buffers
QCamera3Channel *m_pMetaChannel;
mm_camera_super_buf_t *mMetaFrame;
QCamera3StreamMem mOfflineMemory; //reprocessing input buffer
QCamera3StreamMem mOfflineMetaMemory; //reprocessing metadata buffer
List<uint32_t> mFreeOfflineMetaBuffersList;
Mutex mFreeOfflineMetaBuffersLock;
private:
bool m_bWNROn;
};
/* QCamera3RegularChannel is used to handle all streams that are directly
* generated by hardware and given to frameworks without any postprocessing at HAL.
* Examples are: all IMPLEMENTATION_DEFINED streams, CPU_READ streams. */
class QCamera3RegularChannel : public QCamera3ProcessingChannel
{
public:
QCamera3RegularChannel(uint32_t cam_handle,
uint32_t channel_handle,
mm_camera_ops_t *cam_ops,
channel_cb_routine cb_routine,
cam_padding_info_t *paddingInfo,
void *userData,
camera3_stream_t *stream,
cam_stream_type_t stream_type,
uint32_t postprocess_mask,
QCamera3Channel *metadataChannel,
uint32_t numBuffers = MAX_INFLIGHT_REQUESTS);
virtual ~QCamera3RegularChannel();
virtual int32_t setBatchSize(uint32_t batchSize);
virtual uint32_t getStreamTypeMask();
virtual int32_t queueBatchBuf();
virtual int32_t initialize(cam_is_type_t isType);
virtual int32_t request(buffer_handle_t *buffer, uint32_t frameNumber);
virtual reprocess_type_t getReprocessType();
private:
int32_t initialize(struct private_handle_t *priv_handle);
uint32_t mBatchSize;
cam_rotation_t mRotation;
};
/* QCamera3MetadataChannel is for metadata stream generated by camera daemon. */
class QCamera3MetadataChannel : public QCamera3Channel
{
public:
QCamera3MetadataChannel(uint32_t cam_handle,
uint32_t channel_handle,
mm_camera_ops_t *cam_ops,
channel_cb_routine cb_routine,
cam_padding_info_t *paddingInfo,
uint32_t postprocess_mask,
void *userData,
uint32_t numBuffers = MIN_STREAMING_BUFFER_NUM);
virtual ~QCamera3MetadataChannel();
virtual int32_t initialize(cam_is_type_t isType);
virtual int32_t request(buffer_handle_t *buffer, uint32_t frameNumber);
virtual void streamCbRoutine(mm_camera_super_buf_t *super_frame,
QCamera3Stream *stream);
virtual QCamera3StreamMem *getStreamBufs(uint32_t le);
virtual void putStreamBufs();
virtual int32_t registerBuffer(buffer_handle_t * /*buffer*/, cam_is_type_t /*isType*/)
{ return NO_ERROR; };
private:
QCamera3StreamMem *mMemory;
};
/* QCamera3RawChannel is for opaqueu/cross-platform raw stream containing
* vendor specific bayer data or 16-bit unpacked bayer data */
class QCamera3RawChannel : public QCamera3RegularChannel
{
public:
QCamera3RawChannel(uint32_t cam_handle,
uint32_t channel_handle,
mm_camera_ops_t *cam_ops,
channel_cb_routine cb_routine,
cam_padding_info_t *paddingInfo,
void *userData,
camera3_stream_t *stream,
uint32_t postprocess_mask,
QCamera3Channel *metadataChannel,
bool raw_16 = false,
uint32_t numBuffers = MAX_INFLIGHT_REQUESTS);
virtual ~QCamera3RawChannel();
virtual int32_t initialize(cam_is_type_t isType);
virtual void streamCbRoutine(mm_camera_super_buf_t *super_frame,
QCamera3Stream *stream);
virtual reprocess_type_t getReprocessType();
private:
bool mRawDump;
bool mIsRaw16;
void dumpRawSnapshot(mm_camera_buf_def_t *frame);
void convertLegacyToRaw16(mm_camera_buf_def_t *frame);
void convertMipiToRaw16(mm_camera_buf_def_t *frame);
};
/*
* QCamera3RawDumpChannel is for internal use only for Raw dump
*/
class QCamera3RawDumpChannel : public QCamera3Channel
{
public:
QCamera3RawDumpChannel(uint32_t cam_handle,
uint32_t channel_handle,
mm_camera_ops_t *cam_ops,
cam_dimension_t rawDumpSize,
cam_padding_info_t *paddingInfo,
void *userData,
uint32_t postprocess_mask, uint32_t numBuffers = 3U);
virtual ~QCamera3RawDumpChannel();
virtual int32_t initialize(cam_is_type_t isType);
virtual void streamCbRoutine(mm_camera_super_buf_t *super_frame,
QCamera3Stream *stream);
virtual QCamera3StreamMem *getStreamBufs(uint32_t le);
virtual void putStreamBufs();
virtual int32_t registerBuffer(buffer_handle_t * /*buffer*/, cam_is_type_t /*isType*/)
{ return NO_ERROR; };
virtual int32_t request(buffer_handle_t *buffer, uint32_t frameNumber);
void dumpRawSnapshot(mm_camera_buf_def_t *frame);
public:
cam_dimension_t mDim;
private:
bool mRawDump;
QCamera3StreamMem *mMemory;
};
/* QCamera3YUVChannel is used to handle flexible YUV streams that are directly
* generated by hardware and given to frameworks without any postprocessing at HAL.
* It is also used to handle input buffers that generate YUV outputs */
class QCamera3YUVChannel : public QCamera3ProcessingChannel
{
public:
QCamera3YUVChannel(uint32_t cam_handle,
uint32_t channel_handle,
mm_camera_ops_t *cam_ops,
channel_cb_routine cb_routine,
cam_padding_info_t *paddingInfo,
void *userData,
camera3_stream_t *stream,
cam_stream_type_t stream_type,
uint32_t postprocess_mask,
QCamera3Channel *metadataChannel);
~QCamera3YUVChannel();
virtual int32_t initialize(cam_is_type_t isType);
virtual int32_t request(buffer_handle_t *buffer,
uint32_t frameNumber,
camera3_stream_buffer_t* pInputBuffer,
metadata_buffer_t* metadata, bool &needMetadata);
virtual reprocess_type_t getReprocessType();
virtual void streamCbRoutine(mm_camera_super_buf_t *super_frame,
QCamera3Stream *stream);
virtual void putStreamBufs();
virtual void reprocessCbRoutine(buffer_handle_t *resultBuffer,
uint32_t resultFrameNumber);
private:
typedef struct {
uint32_t frameNumber;
bool offlinePpFlag;
buffer_handle_t *output;
mm_camera_super_buf_t *callback_buffer;
} PpInfo;
// Whether offline postprocessing is required for this channel
bool mBypass;
uint32_t mFrameLen;
// Current edge, noise, and crop region setting
cam_edge_application_t mEdgeMode;
uint32_t mNoiseRedMode;
cam_crop_region_t mCropRegion;
// Mutex to protect mOfflinePpFlagMap and mFreeHeapBufferList
Mutex mOfflinePpLock;
// Map between free number and whether the request needs to be
// postprocessed.
List<PpInfo> mOfflinePpInfoList;
// Heap buffer index list
List<uint32_t> mFreeHeapBufferList;
private:
bool needsFramePostprocessing(metadata_buffer_t* meta);
int32_t handleOfflinePpCallback(uint32_t resultFrameNumber,
Vector<mm_camera_super_buf_t *>& pendingCbs);
};
/* QCamera3PicChannel is for JPEG stream, which contains a YUV stream generated
* by the hardware, and encoded to a JPEG stream */
class QCamera3PicChannel : public QCamera3ProcessingChannel
{
public:
QCamera3PicChannel(uint32_t cam_handle,
uint32_t channel_handle,
mm_camera_ops_t *cam_ops,
channel_cb_routine cb_routine,
cam_padding_info_t *paddingInfo,
void *userData,
camera3_stream_t *stream,
uint32_t postprocess_mask,
bool is4KVideo,
bool isInputStreamConfigured,
QCamera3Channel *metadataChannel,
uint32_t numBuffers = MAX_INFLIGHT_REQUESTS);
~QCamera3PicChannel();
virtual int32_t initialize(cam_is_type_t isType);
virtual int32_t flush();
virtual int32_t request(buffer_handle_t *buffer,
uint32_t frameNumber,
camera3_stream_buffer_t* pInputBuffer,
metadata_buffer_t* metadata);
virtual void streamCbRoutine(mm_camera_super_buf_t *super_frame,
QCamera3Stream *stream);
virtual QCamera3StreamMem *getStreamBufs(uint32_t le);
virtual void putStreamBufs();
virtual reprocess_type_t getReprocessType();
QCamera3Exif *getExifData(metadata_buffer_t *metadata,
jpeg_settings_t *jpeg_settings);
void overrideYuvSize(uint32_t width, uint32_t height);
static void jpegEvtHandle(jpeg_job_status_t status,
uint32_t /*client_hdl*/,
uint32_t jobId,
mm_jpeg_output_t *p_output,
void *userdata);
static void dataNotifyCB(mm_camera_super_buf_t *recvd_frame,
void *userdata);
private:
int32_t queueJpegSetting(uint32_t out_buf_index, metadata_buffer_t *metadata);
public:
cam_dimension_t m_max_pic_dim;
private:
uint32_t mNumSnapshotBufs;
uint32_t mYuvWidth, mYuvHeight;
int32_t mCurrentBufIndex;
bool mInputBufferHint;
QCamera3StreamMem *mYuvMemory;
// Keep a list of free buffers
Mutex mFreeBuffersLock;
List<uint32_t> mFreeBufferList;
uint32_t mFrameLen;
};
// reprocess channel class
class QCamera3ReprocessChannel : public QCamera3Channel
{
public:
QCamera3ReprocessChannel(uint32_t cam_handle,
uint32_t channel_handle,
mm_camera_ops_t *cam_ops,
channel_cb_routine cb_routine,
cam_padding_info_t *paddingInfo,
uint32_t postprocess_mask,
void *userData, void *ch_hdl);
QCamera3ReprocessChannel();
virtual ~QCamera3ReprocessChannel();
// offline reprocess
virtual int32_t start();
virtual int32_t stop();
int32_t doReprocessOffline(qcamera_fwk_input_pp_data_t *frame,
bool isPriorityFrame = false);
int32_t doReprocess(int buf_fd, size_t buf_length, int32_t &ret_val,
mm_camera_super_buf_t *meta_buf);
int32_t overrideMetadata(qcamera_hal3_pp_buffer_t *pp_buffer,
mm_camera_buf_def_t *meta_buffer,
jpeg_settings_t *jpeg_settings,
qcamera_fwk_input_pp_data_t &fwk_frame);
int32_t overrideFwkMetadata(qcamera_fwk_input_pp_data_t *frame);
virtual QCamera3StreamMem *getStreamBufs(uint32_t len);
virtual void putStreamBufs();
virtual int32_t initialize(cam_is_type_t isType);
int32_t unmapOfflineBuffers(bool all);
int32_t bufDone(mm_camera_super_buf_t *recvd_frame);
virtual void streamCbRoutine(mm_camera_super_buf_t *super_frame,
QCamera3Stream *stream);
static void dataNotifyCB(mm_camera_super_buf_t *recvd_frame,
void* userdata);
int32_t addReprocStreamsFromSource(cam_pp_feature_config_t &pp_config,
const reprocess_config_t &src_config,
cam_is_type_t is_type,
QCamera3Channel *pMetaChannel);
QCamera3Stream *getStreamBySrcHandle(uint32_t srcHandle);
QCamera3Stream *getSrcStreamBySrcHandle(uint32_t srcHandle);
virtual int32_t registerBuffer(buffer_handle_t * buffer, cam_is_type_t isType);
public:
void *inputChHandle;
private:
typedef struct {
QCamera3Stream *stream;
cam_mapping_buf_type type;
uint32_t index;
} OfflineBuffer;
int32_t resetToCamPerfNormal(uint32_t frameNumber);
android::List<OfflineBuffer> mOfflineBuffers;
android::List<OfflineBuffer> mOfflineMetaBuffers;
int32_t mOfflineBuffersIndex;
int32_t mOfflineMetaIndex;
uint32_t mFrameLen;
Mutex mFreeBuffersLock; // Lock for free heap buffers
List<int32_t> mFreeBufferList; // Free heap buffers list
reprocess_type_t mReprocessType;
uint32_t mSrcStreamHandles[MAX_STREAM_NUM_IN_BUNDLE];
QCamera3ProcessingChannel *m_pSrcChannel; // ptr to source channel for reprocess
QCamera3Channel *m_pMetaChannel;
QCamera3StreamMem *mMemory;
QCamera3StreamMem mGrallocMemory;
Vector<uint32_t> mPriorityFrames;
Mutex mPriorityFramesLock;
bool mReprocessPerfMode;
};
/* QCamera3SupportChannel is for HAL internal consumption only */
class QCamera3SupportChannel : public QCamera3Channel
{
public:
QCamera3SupportChannel(uint32_t cam_handle,
uint32_t channel_handle,
mm_camera_ops_t *cam_ops,
cam_padding_info_t *paddingInfo,
uint32_t postprocess_mask,
cam_stream_type_t streamType,
cam_dimension_t *dim,
cam_format_t streamFormat,
uint8_t hw_analysis_supported,
void *userData,
uint32_t numBuffers = MIN_STREAMING_BUFFER_NUM
);
virtual ~QCamera3SupportChannel();
virtual int32_t initialize(cam_is_type_t isType);
virtual int32_t request(buffer_handle_t *buffer, uint32_t frameNumber);
virtual void streamCbRoutine(mm_camera_super_buf_t *super_frame,
QCamera3Stream *stream);
virtual QCamera3StreamMem *getStreamBufs(uint32_t le);
virtual void putStreamBufs();
virtual int32_t registerBuffer(buffer_handle_t * /*buffer*/, cam_is_type_t /*isType*/)
{ return NO_ERROR; };
static cam_dimension_t kDim;
private:
QCamera3StreamMem *mMemory;
cam_dimension_t mDim;
cam_stream_type_t mStreamType;
cam_format_t mStreamFormat;
};
}; // namespace qcamera
#endif /* __QCAMERA_CHANNEL_H__ */

View file

@ -0,0 +1,272 @@
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#define ATRACE_TAG ATRACE_TAG_CAMERA
#define LOG_TAG "QCamera3CropRegionMapper"
// Camera dependencies
#include "QCamera3CropRegionMapper.h"
#include "QCamera3HWI.h"
extern "C" {
#include "mm_camera_dbg.h"
}
using namespace android;
namespace qcamera {
/*===========================================================================
* FUNCTION : QCamera3CropRegionMapper
*
* DESCRIPTION: Constructor
*
* PARAMETERS : None
*
* RETURN : None
*==========================================================================*/
QCamera3CropRegionMapper::QCamera3CropRegionMapper()
: mSensorW(0),
mSensorH(0),
mActiveArrayW(0),
mActiveArrayH(0)
{
}
/*===========================================================================
* FUNCTION : ~QCamera3CropRegionMapper
*
* DESCRIPTION: destructor
*
* PARAMETERS : none
*
* RETURN : none
*==========================================================================*/
QCamera3CropRegionMapper::~QCamera3CropRegionMapper()
{
}
/*===========================================================================
* FUNCTION : update
*
* DESCRIPTION: update sensor active array size and sensor output size
*
* PARAMETERS :
* @active_array_w : active array width
* @active_array_h : active array height
* @sensor_w : sensor output width
* @sensor_h : sensor output height
*
* RETURN : none
*==========================================================================*/
void QCamera3CropRegionMapper::update(uint32_t active_array_w,
uint32_t active_array_h, uint32_t sensor_w,
uint32_t sensor_h)
{
// Sanity check
if (active_array_w == 0 || active_array_h == 0 ||
sensor_w == 0 || sensor_h == 0) {
LOGE("active_array size and sensor output size must be non zero");
return;
}
if (active_array_w < sensor_w || active_array_h < sensor_h) {
LOGE("invalid input: active_array [%d, %d], sensor size [%d, %d]",
active_array_w, active_array_h, sensor_w, sensor_h);
return;
}
mSensorW = sensor_w;
mSensorH = sensor_h;
mActiveArrayW = active_array_w;
mActiveArrayH = active_array_h;
LOGH("active_array: %d x %d, sensor size %d x %d",
mActiveArrayW, mActiveArrayH, mSensorW, mSensorH);
}
/*===========================================================================
* FUNCTION : toActiveArray
*
* DESCRIPTION: Map crop rectangle from sensor output space to active array space
*
* PARAMETERS :
* @crop_left : x coordinate of top left corner of rectangle
* @crop_top : y coordinate of top left corner of rectangle
* @crop_width : width of rectangle
* @crop_height : height of rectangle
*
* RETURN : none
*==========================================================================*/
void QCamera3CropRegionMapper::toActiveArray(int32_t& crop_left, int32_t& crop_top,
int32_t& crop_width, int32_t& crop_height)
{
if (mSensorW == 0 || mSensorH == 0 ||
mActiveArrayW == 0 || mActiveArrayH == 0) {
LOGE("sensor/active array sizes are not initialized!");
return;
}
crop_left = crop_left * mActiveArrayW / mSensorW;
crop_top = crop_top * mActiveArrayH / mSensorH;
crop_width = crop_width * mActiveArrayW / mSensorW;
crop_height = crop_height * mActiveArrayH / mSensorH;
boundToSize(crop_left, crop_top, crop_width, crop_height,
mActiveArrayW, mActiveArrayH);
}
/*===========================================================================
* FUNCTION : toSensor
*
* DESCRIPTION: Map crop rectangle from active array space to sensor output space
*
* PARAMETERS :
* @crop_left : x coordinate of top left corner of rectangle
* @crop_top : y coordinate of top left corner of rectangle
* @crop_width : width of rectangle
* @crop_height : height of rectangle
*
* RETURN : none
*==========================================================================*/
void QCamera3CropRegionMapper::toSensor(int32_t& crop_left, int32_t& crop_top,
int32_t& crop_width, int32_t& crop_height)
{
if (mSensorW == 0 || mSensorH == 0 ||
mActiveArrayW == 0 || mActiveArrayH == 0) {
LOGE("sensor/active array sizes are not initialized!");
return;
}
crop_left = crop_left * mSensorW / mActiveArrayW;
crop_top = crop_top * mSensorH / mActiveArrayH;
crop_width = crop_width * mSensorW / mActiveArrayW;
crop_height = crop_height * mSensorH / mActiveArrayH;
LOGD("before bounding left %d, top %d, width %d, height %d",
crop_left, crop_top, crop_width, crop_height);
boundToSize(crop_left, crop_top, crop_width, crop_height,
mSensorW, mSensorH);
LOGD("after bounding left %d, top %d, width %d, height %d",
crop_left, crop_top, crop_width, crop_height);
}
/*===========================================================================
* FUNCTION : boundToSize
*
* DESCRIPTION: Bound a particular rectangle inside a bounding box
*
* PARAMETERS :
* @left : x coordinate of top left corner of rectangle
* @top : y coordinate of top left corner of rectangle
* @width : width of rectangle
* @height : height of rectangle
* @bound_w : width of bounding box
* @bound_y : height of bounding box
*
* RETURN : none
*==========================================================================*/
void QCamera3CropRegionMapper::boundToSize(int32_t& left, int32_t& top,
int32_t& width, int32_t& height, int32_t bound_w, int32_t bound_h)
{
if (left < 0) {
left = 0;
}
if (top < 0) {
top = 0;
}
if ((left + width) > bound_w) {
width = bound_w - left;
}
if ((top + height) > bound_h) {
height = bound_h - top;
}
}
/*===========================================================================
* FUNCTION : toActiveArray
*
* DESCRIPTION: Map co-ordinate from sensor output space to active array space
*
* PARAMETERS :
* @x : x coordinate
* @y : y coordinate
*
* RETURN : none
*==========================================================================*/
void QCamera3CropRegionMapper::toActiveArray(uint32_t& x, uint32_t& y)
{
if (mSensorW == 0 || mSensorH == 0 ||
mActiveArrayW == 0 || mActiveArrayH == 0) {
LOGE("sensor/active array sizes are not initialized!");
return;
}
if ((x > static_cast<uint32_t>(mSensorW)) ||
(y > static_cast<uint32_t>(mSensorH))) {
LOGE("invalid co-ordinate (%d, %d) in (0, 0, %d, %d) space",
x, y, mSensorW, mSensorH);
return;
}
x = x * mActiveArrayW / mSensorW;
y = y * mActiveArrayH / mSensorH;
}
/*===========================================================================
* FUNCTION : toSensor
*
* DESCRIPTION: Map co-ordinate from active array space to sensor output space
*
* PARAMETERS :
* @x : x coordinate
* @y : y coordinate
*
* RETURN : none
*==========================================================================*/
void QCamera3CropRegionMapper::toSensor(uint32_t& x, uint32_t& y)
{
if (mSensorW == 0 || mSensorH == 0 ||
mActiveArrayW == 0 || mActiveArrayH == 0) {
LOGE("sensor/active array sizes are not initialized!");
return;
}
if ((x > static_cast<uint32_t>(mActiveArrayW)) ||
(y > static_cast<uint32_t>(mActiveArrayH))) {
LOGE("invalid co-ordinate (%d, %d) in (0, 0, %d, %d) space",
x, y, mSensorW, mSensorH);
return;
}
x = x * mSensorW / mActiveArrayW;
y = y * mSensorH / mActiveArrayH;
}
}; //end namespace android

View file

@ -0,0 +1,65 @@
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __QCAMERA3CROPREGIONMAPPER_H__
#define __QCAMERA3CROPREGIONMAPPER_H__
// System dependencies
#include <utils/Errors.h>
using namespace android;
namespace qcamera {
class QCamera3CropRegionMapper {
public:
QCamera3CropRegionMapper();
virtual ~QCamera3CropRegionMapper();
void update(uint32_t active_array_w, uint32_t active_array_h,
uint32_t sensor_w, uint32_t sensor_h);
void toActiveArray(int32_t& crop_left, int32_t& crop_top,
int32_t& crop_width, int32_t& crop_height);
void toSensor(int32_t& crop_left, int32_t& crop_top,
int32_t& crop_width, int32_t& crop_height);
void toActiveArray(uint32_t& x, uint32_t& y);
void toSensor(uint32_t& x, uint32_t& y);
private:
/* sensor output size */
int32_t mSensorW, mSensorH;
int32_t mActiveArrayW, mActiveArrayH;
void boundToSize(int32_t& left, int32_t& top, int32_t& width,
int32_t& height, int32_t bound_w, int32_t bound_h);
};
}; // namespace qcamera
#endif /* __QCAMERA3CROPREGIONMAPPER_H__ */

View file

@ -0,0 +1,96 @@
/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __QCAMERA_HALHEADER_H__
#define __QCAMERA_HALHEADER_H__
// System dependencies
#include "gralloc.h"
// Camera dependencies
#include "cam_types.h"
using namespace android;
namespace qcamera {
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define IS_USAGE_ZSL(usage) (((usage) & (GRALLOC_USAGE_HW_CAMERA_ZSL)) \
== (GRALLOC_USAGE_HW_CAMERA_ZSL))
class QCamera3ProcessingChannel;
typedef enum {
INVALID,
VALID,
} stream_status_t;
typedef enum {
REPROCESS_TYPE_NONE,
REPROCESS_TYPE_JPEG,
REPROCESS_TYPE_YUV,
REPROCESS_TYPE_PRIVATE,
REPROCESS_TYPE_RAW
} reprocess_type_t;
typedef struct {
uint32_t out_buf_index;
int32_t jpeg_orientation;
uint8_t jpeg_quality;
uint8_t jpeg_thumb_quality;
cam_dimension_t thumbnail_size;
uint8_t gps_timestamp_valid;
int64_t gps_timestamp;
uint8_t gps_coordinates_valid;
double gps_coordinates[3];
char gps_processing_method[GPS_PROCESSING_METHOD_SIZE];
uint8_t image_desc_valid;
char image_desc[EXIF_IMAGE_DESCRIPTION_SIZE];
} jpeg_settings_t;
typedef struct {
int32_t iso_speed;
int64_t exposure_time;
} metadata_response_t;
typedef struct {
cam_stream_type_t stream_type;
cam_format_t stream_format;
cam_dimension_t input_stream_dim;
cam_stream_buf_plane_info_t input_stream_plane_info;
cam_dimension_t output_stream_dim;
cam_padding_info_t *padding;
reprocess_type_t reprocess_type;
QCamera3ProcessingChannel *src_channel;
} reprocess_config_t;
};//namespace qcamera
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,502 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __QCAMERA3HARDWAREINTERFACE_H__
#define __QCAMERA3HARDWAREINTERFACE_H__
// System dependencies
#include <camera/CameraMetadata.h>
#include <pthread.h>
#include <utils/KeyedVector.h>
#include <utils/List.h>
// Camera dependencies
#include "camera3.h"
#include "QCamera3Channel.h"
#include "QCamera3CropRegionMapper.h"
#include "QCamera3HALHeader.h"
#include "QCamera3Mem.h"
#include "QCameraPerf.h"
extern "C" {
#include "mm_camera_interface.h"
#include "mm_jpeg_interface.h"
}
using namespace android;
namespace qcamera {
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
/* Time related macros */
typedef int64_t nsecs_t;
#define NSEC_PER_SEC 1000000000LLU
#define NSEC_PER_USEC 1000LLU
#define NSEC_PER_33MSEC 33000000LLU
typedef enum {
SET_ENABLE,
SET_CONTROLENABLE,
SET_RELOAD_CHROMATIX,
SET_STATUS,
} optype_t;
#define MODULE_ALL 0
extern volatile uint32_t gCamHal3LogLevel;
class QCamera3MetadataChannel;
class QCamera3PicChannel;
class QCamera3HeapMemory;
class QCamera3Exif;
typedef struct {
camera3_stream_t *stream;
camera3_stream_buffer_set_t buffer_set;
stream_status_t status;
int registered;
QCamera3ProcessingChannel *channel;
} stream_info_t;
class QCamera3HardwareInterface {
public:
/* static variable and functions accessed by camera service */
static camera3_device_ops_t mCameraOps;
static int initialize(const struct camera3_device *,
const camera3_callback_ops_t *callback_ops);
static int configure_streams(const struct camera3_device *,
camera3_stream_configuration_t *stream_list);
static const camera_metadata_t* construct_default_request_settings(
const struct camera3_device *, int type);
static int process_capture_request(const struct camera3_device *,
camera3_capture_request_t *request);
static void dump(const struct camera3_device *, int fd);
static int flush(const struct camera3_device *);
static int close_camera_device(struct hw_device_t* device);
public:
QCamera3HardwareInterface(uint32_t cameraId,
const camera_module_callbacks_t *callbacks);
virtual ~QCamera3HardwareInterface();
static void camEvtHandle(uint32_t camera_handle, mm_camera_event_t *evt,
void *user_data);
int openCamera(struct hw_device_t **hw_device);
camera_metadata_t* translateCapabilityToMetadata(int type);
static int getCamInfo(uint32_t cameraId, struct camera_info *info);
static int initCapabilities(uint32_t cameraId);
static int initStaticMetadata(uint32_t cameraId);
static void makeTable(cam_dimension_t *dimTable, size_t size,
size_t max_size, int32_t *sizeTable);
static void makeFPSTable(cam_fps_range_t *fpsTable, size_t size,
size_t max_size, int32_t *fpsRangesTable);
static void makeOverridesList(cam_scene_mode_overrides_t *overridesTable,
size_t size, size_t max_size, uint8_t *overridesList,
uint8_t *supported_indexes, uint32_t camera_id);
static size_t filterJpegSizes(int32_t *jpegSizes, int32_t *processedSizes,
size_t processedSizesCnt, size_t maxCount, cam_rect_t active_array_size,
uint8_t downscale_factor);
static void convertToRegions(cam_rect_t rect, int32_t* region, int weight);
static void convertFromRegions(cam_area_t &roi, const camera_metadata_t *settings,
uint32_t tag);
static bool resetIfNeededROI(cam_area_t* roi, const cam_crop_region_t* scalerCropRegion);
static void convertLandmarks(cam_face_landmarks_info_t face, int32_t* landmarks);
static int32_t getScalarFormat(int32_t format);
static int32_t getSensorSensitivity(int32_t iso_mode);
double computeNoiseModelEntryS(int32_t sensitivity);
double computeNoiseModelEntryO(int32_t sensitivity);
static void captureResultCb(mm_camera_super_buf_t *metadata,
camera3_stream_buffer_t *buffer, uint32_t frame_number,
bool isInputBuffer, void *userdata);
int initialize(const camera3_callback_ops_t *callback_ops);
int configureStreams(camera3_stream_configuration_t *stream_list);
int configureStreamsPerfLocked(camera3_stream_configuration_t *stream_list);
int processCaptureRequest(camera3_capture_request_t *request);
void dump(int fd);
int flushPerf();
int setFrameParameters(camera3_capture_request_t *request,
cam_stream_ID_t streamID, int blob_request, uint32_t snapshotStreamId);
int32_t setReprocParameters(camera3_capture_request_t *request,
metadata_buffer_t *reprocParam, uint32_t snapshotStreamId);
int translateToHalMetadata(const camera3_capture_request_t *request,
metadata_buffer_t *parm, uint32_t snapshotStreamId);
camera_metadata_t* translateCbUrgentMetadataToResultMetadata (
metadata_buffer_t *metadata);
camera_metadata_t* translateFromHalMetadata(metadata_buffer_t *metadata,
nsecs_t timestamp, int32_t request_id,
const CameraMetadata& jpegMetadata, uint8_t pipeline_depth,
uint8_t capture_intent, bool pprocDone, uint8_t fwk_cacMode);
camera_metadata_t* saveRequestSettings(const CameraMetadata& jpegMetadata,
camera3_capture_request_t *request);
int initParameters();
void deinitParameters();
QCamera3ReprocessChannel *addOfflineReprocChannel(const reprocess_config_t &config,
QCamera3ProcessingChannel *inputChHandle);
bool needRotationReprocess();
bool needReprocess(uint32_t postprocess_mask);
bool needJpegRotation();
cam_denoise_process_type_t getWaveletDenoiseProcessPlate();
cam_denoise_process_type_t getTemporalDenoiseProcessPlate();
void captureResultCb(mm_camera_super_buf_t *metadata,
camera3_stream_buffer_t *buffer, uint32_t frame_number,
bool isInputBuffer);
cam_dimension_t calcMaxJpegDim();
bool needOnlineRotation();
uint32_t getJpegQuality();
QCamera3Exif *getExifData();
mm_jpeg_exif_params_t get3AExifParams();
uint8_t getMobicatMask();
static void getFlashInfo(const int cameraId,
bool& hasFlash,
char (&flashNode)[QCAMERA_MAX_FILEPATH_LENGTH]);
const char *getEepromVersionInfo();
const uint32_t *getLdafCalib();
void get3AVersion(cam_q3a_version_t &swVersion);
template <typename fwkType, typename halType> struct QCameraMap {
fwkType fwk_name;
halType hal_name;
};
typedef struct {
const char *const desc;
cam_cds_mode_type_t val;
} QCameraPropMap;
private:
// State transition conditions:
// "\" means not applicable
// "x" means not valid
// +------------+----------+----------+-------------+------------+---------+-------+--------+
// | | CLOSED | OPENED | INITIALIZED | CONFIGURED | STARTED | ERROR | DEINIT |
// +------------+----------+----------+-------------+------------+---------+-------+--------+
// | CLOSED | \ | open | x | x | x | x | x |
// +------------+----------+----------+-------------+------------+---------+-------+--------+
// | OPENED | close | \ | initialize | x | x | error | x |
// +------------+----------+----------+-------------+------------+---------+-------+--------+
// |INITIALIZED | close | x | \ | configure | x | error | x |
// +------------+----------+----------+-------------+------------+---------+-------+--------+
// | CONFIGURED | close | x | x | configure | request | error | x |
// +------------+----------+----------+-------------+------------+---------+-------+--------+
// | STARTED | close | x | x | configure | \ | error | x |
// +------------+----------+----------+-------------+------------+---------+-------+--------+
// | ERROR | close | x | x | x | x | \ | any |
// +------------+----------+----------+-------------+------------+---------+-------+--------+
// | DEINIT | close | x | x | x | x | x | \ |
// +------------+----------+----------+-------------+------------+---------+-------+--------+
typedef enum {
CLOSED,
OPENED,
INITIALIZED,
CONFIGURED,
STARTED,
ERROR,
DEINIT
} State;
int openCamera();
int closeCamera();
int flush(bool restartChannels);
static size_t calcMaxJpegSize(uint32_t camera_id);
cam_dimension_t getMaxRawSize(uint32_t camera_id);
static void addStreamConfig(Vector<int32_t> &available_stream_configs,
int32_t scalar_format, const cam_dimension_t &dim,
int32_t config_type);
int validateCaptureRequest(camera3_capture_request_t *request);
int validateStreamDimensions(camera3_stream_configuration_t *streamList);
int validateStreamRotations(camera3_stream_configuration_t *streamList);
void deriveMinFrameDuration();
int32_t handlePendingReprocResults(uint32_t frame_number);
int64_t getMinFrameDuration(const camera3_capture_request_t *request);
void handleMetadataWithLock(mm_camera_super_buf_t *metadata_buf,
bool free_and_bufdone_meta_buf);
void handleBatchMetadata(mm_camera_super_buf_t *metadata_buf,
bool free_and_bufdone_meta_buf);
void handleBufferWithLock(camera3_stream_buffer_t *buffer,
uint32_t frame_number);
void handleInputBufferWithLock(uint32_t frame_number);
void unblockRequestIfNecessary();
void dumpMetadataToFile(tuning_params_t &meta, uint32_t &dumpFrameCount,
bool enabled, const char *type, uint32_t frameNumber);
static void getLogLevel();
void cleanAndSortStreamInfo();
void extractJpegMetadata(CameraMetadata& jpegMetadata,
const camera3_capture_request_t *request);
bool isSupportChannelNeeded(camera3_stream_configuration_t *streamList,
cam_stream_size_info_t stream_config_info);
int32_t setMobicat();
int32_t getSensorOutputSize(cam_dimension_t &sensor_dim);
int32_t setHalFpsRange(const CameraMetadata &settings,
metadata_buffer_t *hal_metadata);
int32_t extractSceneMode(const CameraMetadata &frame_settings, uint8_t metaMode,
metadata_buffer_t *hal_metadata);
int32_t numOfSizesOnEncoder(const camera3_stream_configuration_t *streamList,
const cam_dimension_t &maxViewfinderSize);
void addToPPFeatureMask(int stream_format, uint32_t stream_idx);
void updateFpsInPreviewBuffer(metadata_buffer_t *metadata, uint32_t frame_number);
void enablePowerHint();
void disablePowerHint();
int32_t dynamicUpdateMetaStreamInfo();
int32_t startAllChannels();
int32_t stopAllChannels();
int32_t notifyErrorForPendingRequests();
int32_t getReprocessibleOutputStreamId(uint32_t &id);
int32_t handleCameraDeviceError();
bool isOnEncoder(const cam_dimension_t max_viewfinder_size,
uint32_t width, uint32_t height);
void hdrPlusPerfLock(mm_camera_super_buf_t *metadata_buf);
static bool supportBurstCapture(uint32_t cameraId);
int32_t setBundleInfo();
camera3_device_t mCameraDevice;
uint32_t mCameraId;
mm_camera_vtbl_t *mCameraHandle;
bool mCameraInitialized;
camera_metadata_t *mDefaultMetadata[CAMERA3_TEMPLATE_COUNT];
const camera3_callback_ops_t *mCallbackOps;
QCamera3MetadataChannel *mMetadataChannel;
QCamera3PicChannel *mPictureChannel;
QCamera3RawChannel *mRawChannel;
QCamera3SupportChannel *mSupportChannel;
QCamera3SupportChannel *mAnalysisChannel;
QCamera3RawDumpChannel *mRawDumpChannel;
QCamera3RegularChannel *mDummyBatchChannel;
QCameraPerfLock m_perfLock;
uint32_t mChannelHandle;
void saveExifParams(metadata_buffer_t *metadata);
mm_jpeg_exif_params_t mExifParams;
//First request yet to be processed after configureStreams
bool mFirstConfiguration;
bool mFlush;
bool mFlushPerf;
bool mEnableRawDump;
QCamera3HeapMemory *mParamHeap;
metadata_buffer_t* mParameters;
metadata_buffer_t* mPrevParameters;
CameraMetadata mCurJpegMeta;
bool m_bIsVideo;
bool m_bIs4KVideo;
bool m_bEisSupportedSize;
bool m_bEisEnable;
typedef struct {
cam_dimension_t dim;
int format;
uint32_t usage;
} InputStreamInfo;
InputStreamInfo mInputStreamInfo;
uint8_t m_MobicatMask;
uint8_t m_bTnrEnabled;
int8_t mSupportedFaceDetectMode;
uint8_t m_bTnrPreview;
uint8_t m_bTnrVideo;
/* Data structure to store pending request */
typedef struct {
camera3_stream_t *stream;
camera3_stream_buffer_t *buffer;
// metadata needs to be consumed by the corresponding stream
// in order to generate the buffer.
bool need_metadata;
} RequestedBufferInfo;
typedef struct {
uint32_t frame_number;
uint32_t num_buffers;
int32_t request_id;
List<RequestedBufferInfo> buffers;
int blob_request;
uint8_t bUrgentReceived;
nsecs_t timestamp;
camera3_stream_buffer_t *input_buffer;
const camera_metadata_t *settings;
CameraMetadata jpegMetadata;
uint8_t pipeline_depth;
uint32_t partial_result_cnt;
uint8_t capture_intent;
uint8_t fwkCacMode;
bool shutter_notified;
} PendingRequestInfo;
typedef struct {
uint32_t frame_number;
uint32_t stream_ID;
} PendingFrameDropInfo;
// Store the Pending buffers for Flushing
typedef struct {
// Frame number pertaining to the buffer
uint32_t frame_number;
camera3_stream_t *stream;
// Buffer handle
buffer_handle_t *buffer;
} PendingBufferInfo;
typedef struct {
// Total number of buffer requests pending
uint32_t num_buffers;
// List of pending buffers
List<PendingBufferInfo> mPendingBufferList;
} PendingBuffersMap;
typedef struct {
camera3_notify_msg_t notify_msg;
camera3_stream_buffer_t buffer;
uint32_t frame_number;
} PendingReprocessResult;
typedef KeyedVector<uint32_t, Vector<PendingBufferInfo> > FlushMap;
typedef List<QCamera3HardwareInterface::PendingRequestInfo>::iterator
pendingRequestIterator;
typedef List<QCamera3HardwareInterface::RequestedBufferInfo>::iterator
pendingBufferIterator;
List<PendingReprocessResult> mPendingReprocessResultList;
List<PendingRequestInfo> mPendingRequestsList;
List<PendingFrameDropInfo> mPendingFrameDropList;
/* Use last frame number of the batch as key and first frame number of the
* batch as value for that key */
KeyedVector<uint32_t, uint32_t> mPendingBatchMap;
PendingBuffersMap mPendingBuffersMap;
pthread_cond_t mRequestCond;
uint32_t mPendingLiveRequest;
bool mWokenUpByDaemon;
int32_t mCurrentRequestId;
cam_stream_size_info_t mStreamConfigInfo;
//mutex for serialized access to camera3_device_ops_t functions
pthread_mutex_t mMutex;
//condition used to signal flush after buffers have returned
pthread_cond_t mBuffersCond;
List<stream_info_t*> mStreamInfo;
int64_t mMinProcessedFrameDuration;
int64_t mMinJpegFrameDuration;
int64_t mMinRawFrameDuration;
uint32_t mMetaFrameCount;
bool mUpdateDebugLevel;
const camera_module_callbacks_t *mCallbacks;
uint8_t mCaptureIntent;
uint8_t mCacMode;
metadata_buffer_t mReprocMeta; //scratch meta buffer
/* 0: Not batch, non-zero: Number of image buffers in a batch */
uint8_t mBatchSize;
// Used only in batch mode
uint8_t mToBeQueuedVidBufs;
// Fixed video fps
float mHFRVideoFps;
uint8_t mOpMode;
uint32_t mFirstFrameNumberInBatch;
camera3_stream_t mDummyBatchStream;
bool mNeedSensorRestart;
/* sensor output size with current stream configuration */
QCamera3CropRegionMapper mCropRegionMapper;
/* Ldaf calibration data */
bool mLdafCalibExist;
uint32_t mLdafCalib[2];
bool mPowerHintEnabled;
int32_t mLastCustIntentFrmNum;
static const QCameraMap<camera_metadata_enum_android_control_effect_mode_t,
cam_effect_mode_type> EFFECT_MODES_MAP[];
static const QCameraMap<camera_metadata_enum_android_control_awb_mode_t,
cam_wb_mode_type> WHITE_BALANCE_MODES_MAP[];
static const QCameraMap<camera_metadata_enum_android_control_scene_mode_t,
cam_scene_mode_type> SCENE_MODES_MAP[];
static const QCameraMap<camera_metadata_enum_android_control_af_mode_t,
cam_focus_mode_type> FOCUS_MODES_MAP[];
static const QCameraMap<camera_metadata_enum_android_color_correction_aberration_mode_t,
cam_aberration_mode_t> COLOR_ABERRATION_MAP[];
static const QCameraMap<camera_metadata_enum_android_control_ae_antibanding_mode_t,
cam_antibanding_mode_type> ANTIBANDING_MODES_MAP[];
static const QCameraMap<camera_metadata_enum_android_lens_state_t,
cam_af_lens_state_t> LENS_STATE_MAP[];
static const QCameraMap<camera_metadata_enum_android_control_ae_mode_t,
cam_flash_mode_t> AE_FLASH_MODE_MAP[];
static const QCameraMap<camera_metadata_enum_android_flash_mode_t,
cam_flash_mode_t> FLASH_MODES_MAP[];
static const QCameraMap<camera_metadata_enum_android_statistics_face_detect_mode_t,
cam_face_detect_mode_t> FACEDETECT_MODES_MAP[];
static const QCameraMap<camera_metadata_enum_android_lens_info_focus_distance_calibration_t,
cam_focus_calibration_t> FOCUS_CALIBRATION_MAP[];
static const QCameraMap<camera_metadata_enum_android_sensor_test_pattern_mode_t,
cam_test_pattern_mode_t> TEST_PATTERN_MAP[];
static const QCameraMap<camera_metadata_enum_android_sensor_reference_illuminant1_t,
cam_illuminat_t> REFERENCE_ILLUMINANT_MAP[];
static const QCameraMap<int32_t,
cam_hfr_mode_t> HFR_MODE_MAP[];
static const QCameraPropMap CDS_MAP[];
pendingRequestIterator erasePendingRequest(pendingRequestIterator i);
//GPU library to read buffer padding details.
void *lib_surface_utils;
int (*LINK_get_surface_pixel_alignment)();
uint32_t mSurfaceStridePadding;
State mState;
};
}; // namespace qcamera
#endif /* __QCAMERA2HARDWAREINTERFACE_H__ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,159 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __QCAMERA3HWI_MEM_H__
#define __QCAMERA3HWI_MEM_H__
// System dependencies
#include <linux/msm_ion.h>
#include <utils/Mutex.h>
// Camera dependencies
#include "camera3.h"
extern "C" {
#include "mm_camera_interface.h"
}
using namespace android;
namespace qcamera {
// Base class for all memory types. Abstract.
class QCamera3Memory {
public:
int cleanCache(uint32_t index)
{
return cacheOps(index, ION_IOC_CLEAN_CACHES);
}
int invalidateCache(uint32_t index)
{
return cacheOps(index, ION_IOC_INV_CACHES);
}
int cleanInvalidateCache(uint32_t index)
{
return cacheOps(index, ION_IOC_CLEAN_INV_CACHES);
}
int getFd(uint32_t index);
ssize_t getSize(uint32_t index);
uint32_t getCnt();
virtual int cacheOps(uint32_t index, unsigned int cmd) = 0;
virtual int getMatchBufIndex(void *object) = 0;
virtual void *getPtr(uint32_t index) = 0;
virtual int32_t markFrameNumber(uint32_t index, uint32_t frameNumber) = 0;
virtual int32_t getFrameNumber(uint32_t index) = 0;
virtual int32_t getBufferIndex(uint32_t frameNumber) = 0;
QCamera3Memory();
virtual ~QCamera3Memory();
int32_t getBufDef(const cam_frame_len_offset_t &offset,
mm_camera_buf_def_t &bufDef, uint32_t index);
protected:
struct QCamera3MemInfo {
int fd;
int main_ion_fd;
ion_user_handle_t handle;
size_t size;
};
int cacheOpsInternal(uint32_t index, unsigned int cmd, void *vaddr);
virtual void *getPtrLocked(uint32_t index) = 0;
uint32_t mBufferCount;
struct QCamera3MemInfo mMemInfo[MM_CAMERA_MAX_NUM_FRAMES];
void *mPtr[MM_CAMERA_MAX_NUM_FRAMES];
int32_t mCurrentFrameNumbers[MM_CAMERA_MAX_NUM_FRAMES];
Mutex mLock;
};
// Internal heap memory is used for memories used internally
// They are allocated from /dev/ion. Examples are: capabilities,
// parameters, metadata, and internal YUV data for jpeg encoding.
class QCamera3HeapMemory : public QCamera3Memory {
public:
QCamera3HeapMemory(uint32_t maxCnt);
virtual ~QCamera3HeapMemory();
int allocate(size_t size);
int allocateOne(size_t size);
void deallocate();
virtual int cacheOps(uint32_t index, unsigned int cmd);
virtual int getMatchBufIndex(void *object);
virtual void *getPtr(uint32_t index);
virtual int32_t markFrameNumber(uint32_t index, uint32_t frameNumber);
virtual int32_t getFrameNumber(uint32_t index);
virtual int32_t getBufferIndex(uint32_t frameNumber);
protected:
virtual void *getPtrLocked(uint32_t index);
private:
int allocOneBuffer(struct QCamera3MemInfo &memInfo,
unsigned int heap_id, size_t size);
void deallocOneBuffer(struct QCamera3MemInfo &memInfo);
bool mQueueAll;
uint32_t mMaxCnt;
};
// Gralloc Memory shared with frameworks
class QCamera3GrallocMemory : public QCamera3Memory {
public:
QCamera3GrallocMemory(uint32_t startIdx);
virtual ~QCamera3GrallocMemory();
int registerBuffer(buffer_handle_t *buffer, cam_stream_type_t type);
int32_t unregisterBuffer(size_t idx);
void unregisterBuffers();
virtual int cacheOps(uint32_t index, unsigned int cmd);
virtual int getMatchBufIndex(void *object);
virtual void *getPtr(uint32_t index);
virtual int32_t markFrameNumber(uint32_t index, uint32_t frameNumber);
virtual int32_t getFrameNumber(uint32_t index);
virtual int32_t getBufferIndex(uint32_t frameNumber);
void *getBufferHandle(uint32_t index);
protected:
virtual void *getPtrLocked(uint32_t index);
private:
int32_t unregisterBufferLocked(size_t idx);
int32_t getFreeIndexLocked();
buffer_handle_t *mBufferHandle[MM_CAMERA_MAX_NUM_FRAMES];
struct private_handle_t *mPrivateHandle[MM_CAMERA_MAX_NUM_FRAMES];
uint32_t mStartIdx;
};
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,191 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __QCamera3_POSTPROC_H__
#define __QCamera3_POSTPROC_H__
// Camera dependencies
#include "camera3.h"
#include "QCamera3HALHeader.h"
#include "QCameraCmdThread.h"
#include "QCameraQueue.h"
extern "C" {
#include "mm_camera_interface.h"
#include "mm_jpeg_interface.h"
}
namespace qcamera {
class QCamera3Exif;
class QCamera3ProcessingChannel;
class QCamera3ReprocessChannel;
class QCamera3Stream;
class QCamera3StreamMem;
typedef struct {
camera3_stream_buffer_t src_frame;// source frame
mm_camera_buf_def_t metadata_buffer;
mm_camera_buf_def_t input_buffer;
reprocess_config_t reproc_config;
buffer_handle_t *output_buffer;
uint32_t frameNumber;
} qcamera_fwk_input_pp_data_t;
typedef struct {
uint32_t jobId; // job ID
uint32_t client_hdl; // handle of jpeg client (obtained when open jpeg)
mm_camera_super_buf_t *src_frame;// source frame (need to be returned back to kernel after done)
mm_camera_super_buf_t *src_reproc_frame; // original source frame for reproc if not NULL
qcamera_fwk_input_pp_data_t *fwk_frame; // source framework buffer
qcamera_fwk_input_pp_data_t *fwk_src_buffer; // original framework source frame for reproc
QCamera3Exif *pJpegExifObj;
metadata_buffer_t *metadata;
mm_camera_super_buf_t *src_metadata;
jpeg_settings_t *jpeg_settings;
} qcamera_hal3_jpeg_data_t;
typedef struct {
uint32_t jobId; // job ID
mm_camera_super_buf_t *src_frame;// source frame (need to be returned back to kernel after done)
qcamera_fwk_input_pp_data_t *fwk_src_frame;// source frame
metadata_buffer_t *metadata;
jpeg_settings_t *jpeg_settings;
mm_camera_super_buf_t *src_metadata;
} qcamera_hal3_pp_data_t;
typedef struct {
mm_camera_super_buf_t *input;
buffer_handle_t *output;
uint32_t frameNumber;
} qcamera_hal3_pp_buffer_t;
#define MAX_HAL3_EXIF_TABLE_ENTRIES 23
class QCamera3Exif
{
public:
QCamera3Exif();
virtual ~QCamera3Exif();
int32_t addEntry(exif_tag_id_t tagid,
exif_tag_type_t type,
uint32_t count,
void *data);
uint32_t getNumOfEntries() {return m_nNumEntries;};
QEXIF_INFO_DATA *getEntries() {return m_Entries;};
private:
QEXIF_INFO_DATA m_Entries[MAX_HAL3_EXIF_TABLE_ENTRIES]; // exif tags for JPEG encoder
uint32_t m_nNumEntries; // number of valid entries
};
class QCamera3PostProcessor
{
public:
QCamera3PostProcessor(QCamera3ProcessingChannel *ch_ctrl);
virtual ~QCamera3PostProcessor();
int32_t init(QCamera3StreamMem *mMemory,
uint32_t postprocess_mask);
int32_t initJpeg(jpeg_encode_callback_t jpeg_cb,
cam_dimension_t *m_max_pic_dim,
void *user_data);
int32_t deinit();
int32_t start(const reprocess_config_t &config);
int32_t stop();
int32_t flush();
int32_t processData(qcamera_fwk_input_pp_data_t *frame);
int32_t processData(mm_camera_super_buf_t *input,
buffer_handle_t *output, uint32_t frameNumber);
int32_t processData(mm_camera_super_buf_t *input);
int32_t processPPData(mm_camera_super_buf_t *frame);
int32_t processPPMetadata(mm_camera_super_buf_t *reproc_meta);
int32_t processJpegSettingData(jpeg_settings_t *jpeg_settings);
qcamera_hal3_pp_data_t *dequeuePPJob(uint32_t frameNumber);
qcamera_hal3_jpeg_data_t *findJpegJobByJobId(uint32_t jobId);
void releaseJpegJobData(qcamera_hal3_jpeg_data_t *job);
int32_t releaseOfflineBuffers(bool all);
void releasePPJobData(qcamera_hal3_pp_data_t *job);
private:
int32_t sendEvtNotify(int32_t msg_type, int32_t ext1, int32_t ext2);
mm_jpeg_color_format getColorfmtFromImgFmt(cam_format_t img_fmt);
mm_jpeg_format_t getJpegImgTypeFromImgFmt(cam_format_t img_fmt);
int32_t getJpegEncodeConfig(mm_jpeg_encode_params_t& encode_parm,
QCamera3Stream *main_stream,
jpeg_settings_t *jpeg_settings);
int32_t getFWKJpegEncodeConfig(mm_jpeg_encode_params_t& encode_parm,
qcamera_fwk_input_pp_data_t *frame,
jpeg_settings_t *jpeg_settings);
QCamera3Exif * getExifData(metadata_buffer_t *metadata,
jpeg_settings_t *jpeg_settings);
int32_t encodeData(qcamera_hal3_jpeg_data_t *jpeg_job_data,
uint8_t &needNewSess);
int32_t encodeFWKData(qcamera_hal3_jpeg_data_t *jpeg_job_data,
uint8_t &needNewSess);
void releaseSuperBuf(mm_camera_super_buf_t *super_buf);
static void releaseNotifyData(void *user_data, void *cookie);
int32_t processRawImageImpl(mm_camera_super_buf_t *recvd_frame);
static void releaseJpegData(void *data, void *user_data);
static void releasePPInputData(void *data, void *user_data);
static void releaseMetadata(void *data, void *user_data);
static void releaseOngoingPPData(void *data, void *user_data);
static void *dataProcessRoutine(void *data);
private:
QCamera3ProcessingChannel *m_parent;
jpeg_encode_callback_t mJpegCB;
void * mJpegUserData;
mm_jpeg_ops_t mJpegHandle;
uint32_t mJpegClientHandle;
uint32_t mJpegSessionId;
uint32_t mPostProcMask;
uint32_t m_bThumbnailNeeded;
QCamera3StreamMem *mOutputMem;
QCamera3ReprocessChannel * m_pReprocChannel;
QCameraQueue m_inputPPQ; // input queue for postproc
QCameraQueue m_inputFWKPPQ; // framework input queue for postproc
QCameraQueue m_ongoingPPQ; // ongoing postproc queue
QCameraQueue m_inputJpegQ; // input jpeg job queue
QCameraQueue m_ongoingJpegQ; // ongoing jpeg job queue
QCameraQueue m_inputRawQ; // input raw job queue
QCameraQueue m_inputMetaQ; // input meta queue
QCameraQueue m_jpegSettingsQ; // input jpeg setting queue
QCameraCmdThread m_dataProcTh; // thread for data processing
pthread_mutex_t mReprocJobLock;
};
}; // namespace qcamera
#endif /* __QCamera3_POSTPROC_H__ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,170 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __QCAMERA3_STREAM_H__
#define __QCAMERA3_STREAM_H__
// System dependencies
#include <utils/Mutex.h>
// Camera dependencies
#include "QCamera3Mem.h"
#include "QCamera3StreamMem.h"
#include "QCameraCmdThread.h"
#include "QCameraQueue.h"
extern "C" {
#include "mm_camera_interface.h"
}
namespace qcamera {
class QCamera3Channel;
class QCamera3Stream;
typedef void (*hal3_stream_cb_routine)(mm_camera_super_buf_t *frame,
QCamera3Stream *stream,
void *userdata);
class QCamera3Stream
{
public:
QCamera3Stream(uint32_t camHandle,
uint32_t chId,
mm_camera_ops_t *camOps,
cam_padding_info_t *paddingInfo,
QCamera3Channel *channel);
virtual ~QCamera3Stream();
virtual int32_t init(cam_stream_type_t streamType,
cam_format_t streamFormat,
cam_dimension_t streamDim,
cam_rotation_t streamRotation,
cam_stream_reproc_config_t* reprocess_config,
uint8_t minStreamBufNum,
uint32_t postprocess_mask,
cam_is_type_t is_type,
uint32_t batchSize,
hal3_stream_cb_routine stream_cb,
void *userdata);
virtual int32_t bufDone(uint32_t index);
virtual int32_t bufRelease(int32_t index);
virtual int32_t processDataNotify(mm_camera_super_buf_t *bufs);
virtual int32_t start();
virtual int32_t stop();
virtual int32_t queueBatchBuf();
static void dataNotifyCB(mm_camera_super_buf_t *recvd_frame, void *userdata);
static void *dataProcRoutine(void *data);
uint32_t getMyHandle() const {return mHandle;}
cam_stream_type_t getMyType() const;
int32_t getFrameOffset(cam_frame_len_offset_t &offset);
int32_t getFrameDimension(cam_dimension_t &dim);
int32_t getFormat(cam_format_t &fmt);
QCamera3StreamMem *getStreamBufs() {return mStreamBufs;};
uint32_t getMyServerID();
int32_t mapBuf(uint8_t buf_type, uint32_t buf_idx,
int32_t plane_idx, int fd, size_t size);
int32_t unmapBuf(uint8_t buf_type, uint32_t buf_idx, int32_t plane_idx);
int32_t setParameter(cam_stream_parm_buffer_t &param);
cam_stream_info_t* getStreamInfo() const {return mStreamInfo; };
static void releaseFrameData(void *data, void *user_data);
private:
uint32_t mCamHandle;
uint32_t mChannelHandle;
uint32_t mHandle; // stream handle from mm-camera-interface
mm_camera_ops_t *mCamOps;
cam_stream_info_t *mStreamInfo; // ptr to stream info buf
mm_camera_stream_mem_vtbl_t mMemVtbl;
mm_camera_map_unmap_ops_tbl_t *mMemOps;
uint8_t mNumBufs;
hal3_stream_cb_routine mDataCB;
void *mUserData;
QCameraQueue mDataQ;
QCameraCmdThread mProcTh; // thread for dataCB
QCamera3HeapMemory *mStreamInfoBuf;
QCamera3StreamMem *mStreamBufs;
mm_camera_buf_def_t *mBufDefs;
cam_frame_len_offset_t mFrameLenOffset;
cam_padding_info_t mPaddingInfo;
QCamera3Channel *mChannel;
Mutex mLock; //Lock controlling access to 'mBufDefs'
uint32_t mBatchSize; // 0: No batch, non-0: Number of imaage bufs in a batch
uint8_t mNumBatchBufs; //Number of batch buffers which can hold image bufs
QCamera3HeapMemory *mStreamBatchBufs; //Pointer to batch buffers memory
mm_camera_buf_def_t *mBatchBufDefs; //Pointer to array of batch bufDefs
mm_camera_buf_def_t *mCurrentBatchBufDef; //batch buffer in progress during
//aggregation
uint32_t mBufsStaged; //Number of image buffers aggregated into
//currentBatchBufDef
QCameraQueue mFreeBatchBufQ; //Buffer queue containing empty batch buffers
static int32_t get_bufs(
cam_frame_len_offset_t *offset,
uint8_t *num_bufs,
uint8_t **initial_reg_flag,
mm_camera_buf_def_t **bufs,
mm_camera_map_unmap_ops_tbl_t *ops_tbl,
void *user_data);
static int32_t put_bufs(
mm_camera_map_unmap_ops_tbl_t *ops_tbl,
void *user_data);
static int32_t invalidate_buf(uint32_t index, void *user_data);
static int32_t clean_invalidate_buf(uint32_t index, void *user_data);
int32_t getBufs(cam_frame_len_offset_t *offset,
uint8_t *num_bufs,
uint8_t **initial_reg_flag,
mm_camera_buf_def_t **bufs,
mm_camera_map_unmap_ops_tbl_t *ops_tbl);
int32_t putBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl);
int32_t invalidateBuf(uint32_t index);
int32_t cleanInvalidateBuf(uint32_t index);
int32_t getBatchBufs(
uint8_t *num_bufs, uint8_t **initial_reg_flag,
mm_camera_buf_def_t **bufs,
mm_camera_map_unmap_ops_tbl_t *ops_tbl);
int32_t putBatchBufs(mm_camera_map_unmap_ops_tbl_t *ops_tbl);
int32_t getBatchBufDef(mm_camera_buf_def_t& batchBufDef,
int32_t index);
int32_t aggregateBufToBatch(mm_camera_buf_def_t& bufDef);
int32_t handleBatchBuffer(mm_camera_super_buf_t *superBuf);
static const char* mStreamNames[CAM_STREAM_TYPE_MAX];
void flushFreeBatchBufQ();
};
}; // namespace qcamera
#endif /* __QCAMERA3_STREAM_H__ */

View file

@ -0,0 +1,477 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#define LOG_TAG "QCamera3StreamMem"
// System dependencies
#include "gralloc_priv.h"
// Camera dependencies
#include "QCamera3StreamMem.h"
using namespace android;
namespace qcamera {
/*===========================================================================
* FUNCTION : QCamera3StreamMem
*
* DESCRIPTION: default constructor of QCamera3StreamMem
*
* PARAMETERS : none
*
* RETURN : None
*==========================================================================*/
QCamera3StreamMem::QCamera3StreamMem(uint32_t maxHeapBuffer, bool queueHeapBuffers) :
mHeapMem(maxHeapBuffer),
mGrallocMem(maxHeapBuffer),
mMaxHeapBuffers(maxHeapBuffer),
mQueueHeapBuffers(queueHeapBuffers)
{
}
/*===========================================================================
* FUNCTION : QCamera3StreamMem
*
* DESCRIPTION: destructor of QCamera3StreamMem
*
* PARAMETERS : none
*
* RETURN : None
*==========================================================================*/
QCamera3StreamMem::~QCamera3StreamMem()
{
clear();
}
/*===========================================================================
* FUNCTION : getCnt
*
* DESCRIPTION: query number of buffers allocated/registered
*
* PARAMETERS : none
*
* RETURN : number of buffers allocated
*==========================================================================*/
uint32_t QCamera3StreamMem::getCnt()
{
Mutex::Autolock lock(mLock);
return (mHeapMem.getCnt() + mGrallocMem.getCnt());
}
/*===========================================================================
* FUNCTION : getRegFlags
*
* DESCRIPTION: query initial reg flags
*
* PARAMETERS :
* @regFlags: initial reg flags of the allocated/registered buffers
*
* RETURN : int32_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
int QCamera3StreamMem::getRegFlags(uint8_t * regFlags)
{
// Assume that all buffers allocated can be queued.
for (uint32_t i = 0; i < mHeapMem.getCnt(); i ++)
regFlags[i] = (mQueueHeapBuffers ? 1 : 0);
return NO_ERROR;
}
/*===========================================================================
* FUNCTION : getFd
*
* DESCRIPTION: return file descriptor of the indexed buffer
*
* PARAMETERS :
* @index : index of the buffer
*
* RETURN : file descriptor
*==========================================================================*/
int QCamera3StreamMem::getFd(uint32_t index)
{
Mutex::Autolock lock(mLock);
if (index < mMaxHeapBuffers)
return mHeapMem.getFd(index);
else
return mGrallocMem.getFd(index);
}
/*===========================================================================
* FUNCTION : getSize
*
* DESCRIPTION: return buffer size of the indexed buffer
*
* PARAMETERS :
* @index : index of the buffer
*
* RETURN : buffer size
*==========================================================================*/
ssize_t QCamera3StreamMem::getSize(uint32_t index)
{
Mutex::Autolock lock(mLock);
if (index < mMaxHeapBuffers)
return mHeapMem.getSize(index);
else
return mGrallocMem.getSize(index);
}
/*===========================================================================
* FUNCTION : invalidateCache
*
* DESCRIPTION: invalidate the cache of the indexed buffer
*
* PARAMETERS :
* @index : index of the buffer
*
* RETURN : int32_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
int QCamera3StreamMem::invalidateCache(uint32_t index)
{
Mutex::Autolock lock(mLock);
if (index < mMaxHeapBuffers)
return mHeapMem.invalidateCache(index);
else
return mGrallocMem.invalidateCache(index);
}
/*===========================================================================
* FUNCTION : cleanInvalidateCache
*
* DESCRIPTION: clean and invalidate the cache of the indexed buffer
*
* PARAMETERS :
* @index : index of the buffer
*
* RETURN : int32_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
int QCamera3StreamMem::cleanInvalidateCache(uint32_t index)
{
Mutex::Autolock lock(mLock);
if (index < mMaxHeapBuffers)
return mHeapMem.cleanInvalidateCache(index);
else
return mGrallocMem.cleanInvalidateCache(index);
}
/*===========================================================================
* FUNCTION : getBufDef
*
* DESCRIPTION: query detailed buffer information
*
* PARAMETERS :
* @offset : [input] frame buffer offset
* @bufDef : [output] reference to struct to store buffer definition
* @index : [input] index of the buffer
*
* RETURN : int32_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
int32_t QCamera3StreamMem::getBufDef(const cam_frame_len_offset_t &offset,
mm_camera_buf_def_t &bufDef, uint32_t index)
{
int32_t ret = NO_ERROR;
if (index < mMaxHeapBuffers)
ret = mHeapMem.getBufDef(offset, bufDef, index);
else
ret = mGrallocMem.getBufDef(offset, bufDef, index);
bufDef.mem_info = (void *)this;
return ret;
}
/*===========================================================================
* FUNCTION : getPtr
*
* DESCRIPTION: return virtual address of the indexed buffer
*
* PARAMETERS :
* @index : index of the buffer
*
* RETURN : virtual address
*==========================================================================*/
void* QCamera3StreamMem::getPtr(uint32_t index)
{
Mutex::Autolock lock(mLock);
if (index < mMaxHeapBuffers)
return mHeapMem.getPtr(index);
else
return mGrallocMem.getPtr(index);
}
/*===========================================================================
* FUNCTION : valid
*
* DESCRIPTION: return whether there is a valid buffer at the current index
*
* PARAMETERS :
* @index : index of the buffer
*
* RETURN : true if there is a buffer, false otherwise
*==========================================================================*/
bool QCamera3StreamMem::valid(uint32_t index)
{
Mutex::Autolock lock(mLock);
if (index < mMaxHeapBuffers)
return (mHeapMem.getSize(index) > 0);
else
return (mGrallocMem.getSize(index) > 0);
}
/*===========================================================================
* FUNCTION : registerBuffer
*
* DESCRIPTION: registers frameworks-allocated gralloc buffer_handle_t
*
* PARAMETERS :
* @buffers : buffer_handle_t pointer
* @type : cam_stream_type_t
*
* RETURN : int32_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
int QCamera3StreamMem::registerBuffer(buffer_handle_t *buffer,
cam_stream_type_t type)
{
Mutex::Autolock lock(mLock);
return mGrallocMem.registerBuffer(buffer, type);
}
/*===========================================================================
* FUNCTION : unregisterBuffer
*
* DESCRIPTION: unregister buffer
*
* PARAMETERS :
* @idx : unregister buffer at index 'idx'
*
* RETURN : int32_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
int32_t QCamera3StreamMem::unregisterBuffer(size_t idx)
{
Mutex::Autolock lock(mLock);
return mGrallocMem.unregisterBuffer(idx);
}
/*===========================================================================
* FUNCTION : getMatchBufIndex
*
* DESCRIPTION: query buffer index by object ptr
*
* PARAMETERS :
* @opaque : opaque ptr
*
* RETURN : buffer index if match found,
* -1 if failed
*==========================================================================*/
int QCamera3StreamMem::getMatchBufIndex(void *object)
{
Mutex::Autolock lock(mLock);
return mGrallocMem.getMatchBufIndex(object);
}
/*===========================================================================
* FUNCTION : getBufferHandle
*
* DESCRIPTION: return framework pointer
*
* PARAMETERS :
* @index : index of the buffer
*
* RETURN : buffer ptr if match found
NULL if failed
*==========================================================================*/
void *QCamera3StreamMem::getBufferHandle(uint32_t index)
{
Mutex::Autolock lock(mLock);
return mGrallocMem.getBufferHandle(index);
}
/*===========================================================================
* FUNCTION : unregisterBuffers
*
* DESCRIPTION: unregister buffers
*
* PARAMETERS : none
*
* RETURN : none
*==========================================================================*/
void QCamera3StreamMem::unregisterBuffers()
{
Mutex::Autolock lock(mLock);
mGrallocMem.unregisterBuffers();
}
/*===========================================================================
* FUNCTION : allocate
*
* DESCRIPTION: allocate requested number of buffers of certain size
*
* PARAMETERS :
* @count : number of buffers to be allocated
* @size : lenght of the buffer to be allocated
*
* RETURN : int32_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
int QCamera3StreamMem::allocateAll(size_t size)
{
Mutex::Autolock lock(mLock);
return mHeapMem.allocate(size);
}
int QCamera3StreamMem::allocateOne(size_t size)
{
Mutex::Autolock lock(mLock);
return mHeapMem.allocateOne(size);
}
/*===========================================================================
* FUNCTION : deallocate
*
* DESCRIPTION: deallocate heap buffers
*
* PARAMETERS : none
*
* RETURN : none
*==========================================================================*/
void QCamera3StreamMem::deallocate()
{
Mutex::Autolock lock(mLock);
mHeapMem.deallocate();
}
/*===========================================================================
* FUNCTION : markFrameNumber
*
* DESCRIPTION: We use this function from the request call path to mark the
* buffers with the frame number they are intended for this info
* is used later when giving out callback & it is duty of PP to
* ensure that data for that particular frameNumber/Request is
* written to this buffer.
* PARAMETERS :
* @index : index of the buffer
* @frame# : Frame number from the framework
*
* RETURN : int32_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
int32_t QCamera3StreamMem::markFrameNumber(uint32_t index, uint32_t frameNumber)
{
Mutex::Autolock lock(mLock);
if (index < mMaxHeapBuffers)
return mHeapMem.markFrameNumber(index, frameNumber);
else
return mGrallocMem.markFrameNumber(index, frameNumber);
}
/*===========================================================================
* FUNCTION : getFrameNumber
*
* DESCRIPTION: We use this to fetch the frameNumber for the request with which
* this buffer was given to HAL
*
*
* PARAMETERS :
* @index : index of the buffer
*
* RETURN : int32_t frameNumber
* positive/zero -- success
* negative failure
*==========================================================================*/
int32_t QCamera3StreamMem::getFrameNumber(uint32_t index)
{
Mutex::Autolock lock(mLock);
if (index < mMaxHeapBuffers)
return mHeapMem.getFrameNumber(index);
else
return mGrallocMem.getFrameNumber(index);
}
/*===========================================================================
* FUNCTION : getGrallocBufferIndex
*
* DESCRIPTION: We use this to fetch the gralloc buffer index based on frameNumber
*
* PARAMETERS :
* @frameNumber : frame Number
*
* RETURN : int32_t buffer index
* positive/zero -- success
* negative failure
*==========================================================================*/
int32_t QCamera3StreamMem::getGrallocBufferIndex(uint32_t frameNumber)
{
Mutex::Autolock lock(mLock);
int32_t index = mGrallocMem.getBufferIndex(frameNumber);
return index;
}
/*===========================================================================
* FUNCTION : getHeapBufferIndex
*
* DESCRIPTION: We use this to fetch the heap buffer index based on frameNumber
*
* PARAMETERS :
* @frameNumber : frame Number
*
* RETURN : int32_t buffer index
* positive/zero -- success
* negative failure
*==========================================================================*/
int32_t QCamera3StreamMem::getHeapBufferIndex(uint32_t frameNumber)
{
Mutex::Autolock lock(mLock);
int32_t index = mHeapMem.getBufferIndex(frameNumber);
return index;
}
}; //namespace qcamera

View file

@ -0,0 +1,97 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __QCAMERA3_STREAMMEM_H__
#define __QCAMERA3_STREAMMEM_H__
// System dependencies
#include <utils/Mutex.h>
// Camera dependencies
#include "QCamera3Mem.h"
extern "C" {
#include "mm_camera_interface.h"
}
using namespace android;
namespace qcamera {
class QCamera3StreamMem {
public:
QCamera3StreamMem(uint32_t maxHeapBuffer, bool queueAll = true);
virtual ~QCamera3StreamMem();
uint32_t getCnt();
int getRegFlags(uint8_t *regFlags);
// Helper function to access individual QCamera3Buffer object
int getFd(uint32_t index);
ssize_t getSize(uint32_t index);
int invalidateCache(uint32_t index);
int cleanInvalidateCache(uint32_t index);
int32_t getBufDef(const cam_frame_len_offset_t &offset,
mm_camera_buf_def_t &bufDef, uint32_t index);
void *getPtr(uint32_t index);
bool valid(uint32_t index);
// Gralloc buffer related functions
int registerBuffer(buffer_handle_t *buffer, cam_stream_type_t type);
int unregisterBuffer(uint32_t index);
int getMatchBufIndex(void *object);
void *getBufferHandle(uint32_t index);
void unregisterBuffers(); //TODO: relace with unififed clear() function?
// Heap buffer related functions
int allocateAll(size_t size);
int allocateOne(size_t size);
void deallocate(); //TODO: replace with unified clear() function?
// Clear function: unregister for gralloc buffer, and deallocate for heap buffer
void clear() {unregisterBuffers(); deallocate(); }
// Frame number getter and setter
int32_t markFrameNumber(uint32_t index, uint32_t frameNumber);
int32_t getFrameNumber(uint32_t index);
int32_t getGrallocBufferIndex(uint32_t frameNumber);
int32_t getHeapBufferIndex(uint32_t frameNumber);
private:
//variables
QCamera3HeapMemory mHeapMem;
QCamera3GrallocMemory mGrallocMem;
uint32_t mMaxHeapBuffers;
Mutex mLock;
bool mQueueHeapBuffers;
};
};
#endif // __QCAMERA3_STREAMMEM_H__

View file

@ -0,0 +1,370 @@
/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#define LOG_TAG "QCamera3VendorTags"
// Camera dependencies
#include "QCamera3HWI.h"
#include "QCamera3VendorTags.h"
extern "C" {
#include "mm_camera_dbg.h"
}
using namespace android;
namespace qcamera {
const int QCAMERA3_SECTION_COUNT = QCAMERA3_SECTIONS_END - VENDOR_SECTION;
enum qcamera3_ext_tags qcamera3_ext3_section_bounds[QCAMERA3_SECTIONS_END -
VENDOR_SECTION] = {
QCAMERA3_PRIVATEDATA_END,
QCAMERA3_CDS_END,
QCAMERA3_OPAQUE_RAW_END,
QCAMERA3_CROP_END,
QCAMERA3_TUNING_META_DATA_END,
QCAMERA3_TEMPORAL_DENOISE_END,
QCAMERA3_AV_TIMER_END,
QCAMERA3_SENSOR_META_DATA_END,
NEXUS_EXPERIMENTAL_2015_END,
} ;
typedef struct vendor_tag_info {
const char *tag_name;
uint8_t tag_type;
} vendor_tag_info_t;
const char *qcamera3_ext_section_names[QCAMERA3_SECTIONS_END -
VENDOR_SECTION] = {
"org.codeaurora.qcamera3.privatedata",
"org.codeaurora.qcamera3.CDS",
"org.codeaurora.qcamera3.opaque_raw",
"org.codeaurora.qcamera3.crop",
"org.codeaurora.qcamera3.tuning_meta_data",
"org.codeaurora.qcamera3.temporal_denoise",
"org.codeaurora.qcamera3.av_timer",
"org.codeaurora.qcamera3.sensor_meta_data",
"com.google.nexus.experimental2015"
};
vendor_tag_info_t qcamera3_privatedata[QCAMERA3_PRIVATEDATA_END - QCAMERA3_PRIVATEDATA_START] = {
{ "privatedata_reprocess", TYPE_INT32 }
};
vendor_tag_info_t qcamera3_cds[QCAMERA3_CDS_END - QCAMERA3_CDS_START] = {
{ "cds_mode", TYPE_INT32 },
{ "cds_info", TYPE_BYTE }
};
vendor_tag_info_t qcamera3_opaque_raw[QCAMERA3_OPAQUE_RAW_END -
QCAMERA3_OPAQUE_RAW_START] = {
{ "opaque_raw_strides", TYPE_INT32 },
{ "opaque_raw_format", TYPE_BYTE }
};
vendor_tag_info_t qcamera3_crop[QCAMERA3_CROP_END- QCAMERA3_CROP_START] = {
{ "count", TYPE_INT32 },
{ "data", TYPE_INT32},
{ "roimap", TYPE_INT32 }
};
vendor_tag_info_t qcamera3_tuning_meta_data[QCAMERA3_TUNING_META_DATA_END -
QCAMERA3_TUNING_META_DATA_START] = {
{ "tuning_meta_data_blob", TYPE_INT32 }
};
vendor_tag_info_t qcamera3_temporal_denoise[QCAMERA3_TEMPORAL_DENOISE_END -
QCAMERA3_TEMPORAL_DENOISE_START] = {
{ "enable", TYPE_BYTE },
{ "process_type", TYPE_INT32 }
};
vendor_tag_info qcamera3_av_timer[QCAMERA3_AV_TIMER_END -
QCAMERA3_AV_TIMER_START] = {
{"use_av_timer", TYPE_BYTE }
};
vendor_tag_info qcamera3_sensor_meta_data[QCAMERA3_SENSOR_META_DATA_END -
QCAMERA3_SENSOR_META_DATA_START] = {
{"dynamic_black_level_pattern", TYPE_FLOAT }
};
vendor_tag_info_t nexus_experimental_2015[NEXUS_EXPERIMENTAL_2015_END -
NEXUS_EXPERIMENTAL_2015_START] = {
{"sensor.dynamicBlackLevel", TYPE_FLOAT },
{"sensor.info.opticallyShieldedRegions", TYPE_INT32 }
};
vendor_tag_info_t *qcamera3_tag_info[QCAMERA3_SECTIONS_END -
VENDOR_SECTION] = {
qcamera3_privatedata,
qcamera3_cds,
qcamera3_opaque_raw,
qcamera3_crop,
qcamera3_tuning_meta_data,
qcamera3_temporal_denoise,
qcamera3_av_timer,
qcamera3_sensor_meta_data,
nexus_experimental_2015,
};
uint32_t qcamera3_all_tags[] = {
// QCAMERA3_PRIVATEDATA
(uint32_t)QCAMERA3_PRIVATEDATA_REPROCESS,
// QCAMERA3_CDS
(uint32_t)QCAMERA3_CDS_MODE,
(uint32_t)QCAMERA3_CDS_INFO,
// QCAMERA3_OPAQUE_RAW
(uint32_t)QCAMERA3_OPAQUE_RAW_STRIDES,
(uint32_t)QCAMERA3_OPAQUE_RAW_FORMAT,
// QCAMERA3_CROP
(uint32_t)QCAMERA3_CROP_COUNT_REPROCESS,
(uint32_t)QCAMERA3_CROP_REPROCESS,
(uint32_t)QCAMERA3_CROP_ROI_MAP_REPROCESS,
// QCAMERA3_TUNING_META_DATA
(uint32_t)QCAMERA3_TUNING_META_DATA_BLOB,
// QCAMERA3_TEMPORAL_DENOISE
(uint32_t)QCAMERA3_TEMPORAL_DENOISE_ENABLE,
(uint32_t)QCAMERA3_TEMPORAL_DENOISE_PROCESS_TYPE,
//QCAMERA3_AVTIMER
(uint32_t)QCAMERA3_USE_AV_TIMER,
//QCAMERA3_SENSOR_META_DATA
(uint32_t)QCAMERA3_SENSOR_DYNAMIC_BLACK_LEVEL_PATTERN,
//NEXUS_EXPERIMENTAL_2015
(uint32_t)NEXUS_EXPERIMENTAL_2015_SENSOR_DYNAMIC_BLACK_LEVEL,
(uint32_t)NEXUS_EXPERIMENTAL_2015_SENSOR_INFO_OPTICALLY_SHIELDED_REGIONS,
};
const vendor_tag_ops_t* QCamera3VendorTags::Ops = NULL;
/*===========================================================================
* FUNCTION : get_vendor_tag_ops
*
* DESCRIPTION: Get the metadata vendor tag function pointers
*
* PARAMETERS :
* @ops : function pointer table to be filled by HAL
*
*
* RETURN : NONE
*==========================================================================*/
void QCamera3VendorTags::get_vendor_tag_ops(
vendor_tag_ops_t* ops)
{
LOGL("E");
Ops = ops;
ops->get_tag_count = get_tag_count;
ops->get_all_tags = get_all_tags;
ops->get_section_name = get_section_name;
ops->get_tag_name = get_tag_name;
ops->get_tag_type = get_tag_type;
ops->reserved[0] = NULL;
LOGL("X");
return;
}
/*===========================================================================
* FUNCTION : get_tag_count
*
* DESCRIPTION: Get number of vendor tags supported
*
* PARAMETERS :
* @ops : Vendor tag ops data structure
*
*
* RETURN : Number of vendor tags supported
*==========================================================================*/
int QCamera3VendorTags::get_tag_count(
const vendor_tag_ops_t * ops)
{
size_t count = 0;
if (ops == Ops)
count = sizeof(qcamera3_all_tags)/sizeof(qcamera3_all_tags[0]);
LOGL("count is %d", count);
return (int)count;
}
/*===========================================================================
* FUNCTION : get_all_tags
*
* DESCRIPTION: Fill array with all supported vendor tags
*
* PARAMETERS :
* @ops : Vendor tag ops data structure
* @tag_array: array of metadata tags
*
* RETURN : Success: the section name of the specific tag
* Failure: NULL
*==========================================================================*/
void QCamera3VendorTags::get_all_tags(
const vendor_tag_ops_t * ops,
uint32_t *g_array)
{
if (ops != Ops)
return;
for (size_t i = 0;
i < sizeof(qcamera3_all_tags)/sizeof(qcamera3_all_tags[0]);
i++) {
g_array[i] = qcamera3_all_tags[i];
LOGD("g_array[%d] is %d", i, g_array[i]);
}
}
/*===========================================================================
* FUNCTION : get_section_name
*
* DESCRIPTION: Get section name for vendor tag
*
* PARAMETERS :
* @ops : Vendor tag ops structure
* @tag : Vendor specific tag
*
*
* RETURN : Success: the section name of the specific tag
* Failure: NULL
*==========================================================================*/
const char* QCamera3VendorTags::get_section_name(
const vendor_tag_ops_t * ops,
uint32_t tag)
{
LOGL("E");
if (ops != Ops)
return NULL;
const char *ret;
uint32_t section = tag >> 16;
if (section < VENDOR_SECTION || section >= QCAMERA3_SECTIONS_END)
ret = NULL;
else
ret = qcamera3_ext_section_names[section - VENDOR_SECTION];
if (ret)
LOGL("section_name[%d] is %s", tag, ret);
LOGL("X");
return ret;
}
/*===========================================================================
* FUNCTION : get_tag_name
*
* DESCRIPTION: Get name of a vendor specific tag
*
* PARAMETERS :
* @tag : Vendor specific tag
*
*
* RETURN : Success: the name of the specific tag
* Failure: NULL
*==========================================================================*/
const char* QCamera3VendorTags::get_tag_name(
const vendor_tag_ops_t * ops,
uint32_t tag)
{
LOGL("E");
const char *ret;
uint32_t section = tag >> 16;
uint32_t section_index = section - VENDOR_SECTION;
uint32_t tag_index = tag & 0xFFFF;
if (ops != Ops) {
ret = NULL;
goto done;
}
if (section < VENDOR_SECTION || section >= QCAMERA3_SECTIONS_END)
ret = NULL;
else if (tag >= (uint32_t)qcamera3_ext3_section_bounds[section_index])
ret = NULL;
else
ret = qcamera3_tag_info[section_index][tag_index].tag_name;
if (ret)
LOGL("tag name for tag %d is %s", tag, ret);
LOGL("X");
done:
return ret;
}
/*===========================================================================
* FUNCTION : get_tag_type
*
* DESCRIPTION: Get type of a vendor specific tag
*
* PARAMETERS :
* @tag : Vendor specific tag
*
*
* RETURN : Success: the type of the specific tag
* Failure: -1
*==========================================================================*/
int QCamera3VendorTags::get_tag_type(
const vendor_tag_ops_t *ops,
uint32_t tag)
{
LOGL("E");
int ret;
uint32_t section = tag >> 16;
uint32_t section_index = section - VENDOR_SECTION;
uint32_t tag_index = tag & 0xFFFF;
if (ops != Ops) {
ret = -1;
goto done;
}
if (section < VENDOR_SECTION || section >= QCAMERA3_SECTIONS_END)
ret = -1;
else if (tag >= (uint32_t )qcamera3_ext3_section_bounds[section_index])
ret = -1;
else
ret = qcamera3_tag_info[section_index][tag_index].tag_type;
LOGL("tag type for tag %d is %d", tag, ret);
LOGL("X");
done:
return ret;
}
}; //end namespace qcamera

View file

@ -0,0 +1,175 @@
/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __QCAMERA3VENDORTAGS_H__
#define __QCAMERA3VENDORTAGS_H__
// Camera dependencies
#include "camera_metadata.h"
namespace qcamera {
enum qcamera3_ext_section {
QCAMERA3_PRIVATEDATA = VENDOR_SECTION,
QCAMERA3_CDS,
QCAMERA3_OPAQUE_RAW,
QCAMERA3_CROP,
QCAMERA3_TUNING_META_DATA,
QCAMERA3_TEMPORAL_DENOISE,
QCAMERA3_AV_TIMER,
QCAMERA3_SENSOR_META_DATA,
NEXUS_EXPERIMENTAL_2015,
QCAMERA3_SECTIONS_END
};
enum qcamera3_ext_section_ranges {
QCAMERA3_PRIVATEDATA_START = QCAMERA3_PRIVATEDATA << 16,
QCAMERA3_CDS_START = QCAMERA3_CDS << 16,
QCAMERA3_OPAQUE_RAW_START = QCAMERA3_OPAQUE_RAW << 16,
QCAMERA3_CROP_START = QCAMERA3_CROP << 16,
QCAMERA3_TUNING_META_DATA_START = QCAMERA3_TUNING_META_DATA << 16,
QCAMERA3_TEMPORAL_DENOISE_START = QCAMERA3_TEMPORAL_DENOISE << 16,
QCAMERA3_AV_TIMER_START = QCAMERA3_AV_TIMER << 16,
QCAMERA3_SENSOR_META_DATA_START = QCAMERA3_SENSOR_META_DATA << 16,
NEXUS_EXPERIMENTAL_2015_START = NEXUS_EXPERIMENTAL_2015 <<16
};
enum qcamera3_ext_tags {
QCAMERA3_PRIVATEDATA_REPROCESS = QCAMERA3_PRIVATEDATA_START,
QCAMERA3_PRIVATEDATA_END,
QCAMERA3_CDS_MODE = QCAMERA3_CDS_START,
QCAMERA3_CDS_INFO,
QCAMERA3_CDS_END,
//Property Name: org.codeaurora.qcamera3.opaque_raw.opaque_raw_strides
//
//Type: int32 * n * 3 [public]
//
//Description: Distance in bytes from the beginning of one row of opaque
//raw image data to the beginning of next row.
//
//Details: The strides are listed as (raw_width, raw_height, stride)
//triplets. For each supported raw size, there will be a stride associated
//with it.
QCAMERA3_OPAQUE_RAW_STRIDES = QCAMERA3_OPAQUE_RAW_START,
//Property Name: org.codeaurora.qcamera3.opaque_raw.opaque_raw_format
//
//Type: byte(enum) [public]
// * LEGACY - The legacy raw format where 8, 10, or 12-bit
// raw data is packed into a 64-bit word.
// * MIPI - raw format matching the data packing described
// in MIPI CSI-2 specification. In memory, the data
// is constructed by packing sequentially received pixels
// into least significant parts of the words first.
// Within each pixel, the least significant bits are also
// placed towards the least significant part of the word.
//
//Details: Lay out of opaque raw data in memory is decided by two factors:
// opaque_raw_format and bit depth (implied by whiteLevel). Below
// list illustrates their relationship:
// LEGACY8: P7(7:0) P6(7:0) P5(7:0) P4(7:0) P3(7:0) P2(7:0) P1(7:0) P0(7:0)
// 8 pixels occupy 8 bytes, no padding needed
// min_stride = CEILING8(raw_width)
// LEGACY10: 0000 P5(9:0) P4(9:0) P3(9:0) P2(9:0) P1(9:0) P0(9:0)
// 6 pixels occupy 8 bytes, 4 bits padding at MSB
// min_stride = (raw_width+5)/6 * 8
// LEGACY12: 0000 P4(11:0) P3(11:0) P2(11:0) P1(11:0) P0(11:0)
// 5 pixels occupy 8 bytes, 4 bits padding at MSB
// min_stride = (raw_width+4)/5 * 8
// MIPI8: P0(7:0)
// 1 pixel occupy 1 byte
// min_stride = raw_width
// MIPI10: P3(1:0) P2(1:0) P1(1:0) P0(1:0) P3(9:2) P2(9:2) P1(9:2) P0(9:2)
// 4 pixels occupy 5 bytes
// min_stride = (raw_width+3)/4 * 5
// MIPI12: P1(3:0) P0(3:0) P1(11:4) P0(11:4)
// 2 pixels occupy 3 bytes
// min_stride = (raw_width+1)/2 * 3
//Note that opaque_raw_stride needs to be at least the required minimum
//stride from the table above. ISP hardware may need more generous stride
//setting. For example, for LEGACY8, the actual stride may be
//CEILING16(raw_width) due to bus burst length requirement.
QCAMERA3_OPAQUE_RAW_FORMAT,
QCAMERA3_OPAQUE_RAW_END,
QCAMERA3_CROP_COUNT_REPROCESS = QCAMERA3_CROP_START,
QCAMERA3_CROP_REPROCESS,
QCAMERA3_CROP_ROI_MAP_REPROCESS,
QCAMERA3_CROP_END,
QCAMERA3_TUNING_META_DATA_BLOB = QCAMERA3_TUNING_META_DATA_START,
QCAMERA3_TUNING_META_DATA_END,
QCAMERA3_TEMPORAL_DENOISE_ENABLE = QCAMERA3_TEMPORAL_DENOISE_START,
QCAMERA3_TEMPORAL_DENOISE_PROCESS_TYPE,
QCAMERA3_TEMPORAL_DENOISE_END,
QCAMERA3_USE_AV_TIMER = QCAMERA3_AV_TIMER_START,
QCAMERA3_AV_TIMER_END,
QCAMERA3_SENSOR_DYNAMIC_BLACK_LEVEL_PATTERN = QCAMERA3_SENSOR_META_DATA_START,
QCAMERA3_SENSOR_META_DATA_END,
NEXUS_EXPERIMENTAL_2015_SENSOR_DYNAMIC_BLACK_LEVEL = NEXUS_EXPERIMENTAL_2015_START,
NEXUS_EXPERIMENTAL_2015_SENSOR_INFO_OPTICALLY_SHIELDED_REGIONS,
NEXUS_EXPERIMENTAL_2015_END
};
// QCAMERA3_OPAQUE_RAW_FORMAT
typedef enum qcamera3_ext_opaque_raw_format {
QCAMERA3_OPAQUE_RAW_FORMAT_LEGACY,
QCAMERA3_OPAQUE_RAW_FORMAT_MIPI
} qcamera3_ext_opaque_raw_format_t;
class QCamera3VendorTags {
public:
static void get_vendor_tag_ops(vendor_tag_ops_t* ops);
static int get_tag_count(
const vendor_tag_ops_t *ops);
static void get_all_tags(
const vendor_tag_ops_t *ops,
uint32_t *tag_array);
static const char* get_section_name(
const vendor_tag_ops_t *ops,
uint32_t tag);
static const char* get_tag_name(
const vendor_tag_ops_t *ops,
uint32_t tag);
static int get_tag_type(
const vendor_tag_ops_t *ops,
uint32_t tag);
static const vendor_tag_ops_t *Ops;
};
}; // namespace qcamera
#endif /* __QCAMERA3VENDORTAGS_H__ */

View file

@ -0,0 +1,47 @@
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __QCAMERA3EXTERNAL_H__
#define __QCAMERA3EXTERNAL_H__
// System dependencies
#include <utils/Errors.h>
// Display dependencies
#include "QServiceUtils.h"
namespace qcamera {
inline android::status_t setCameraLaunchStatus(uint32_t on) {
return ::setCameraLaunchStatus(on);
}
}; // namespace qcamera
#endif /* __QCAMERA3EXTERNAL_H__ */

View file

@ -0,0 +1,607 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#define LOG_TAG "QCamera2Factory"
// System dependencies
#include <stdlib.h>
#include <utils/Errors.h>
// Camera dependencies
#include "camera.h"
#include "camera3.h"
#include "HAL/QCamera2HWI.h"
#include "HAL3/QCamera3HWI.h"
#include "util/QCameraFlash.h"
#include "QCamera2Factory.h"
#include "QCameraMuxer.h"
extern "C" {
#include "mm_camera_dbg.h"
}
using namespace android;
namespace qcamera {
QCamera2Factory *gQCamera2Factory = NULL;
QCameraMuxer *gQCameraMuxer = NULL;
pthread_mutex_t gCamLock = PTHREAD_MUTEX_INITIALIZER;
//Total number of cameras opened simultaneously.
//This variable updation is protected by gCamLock.
uint8_t gNumCameraSessions = 0;
volatile uint32_t gKpiDebugLevel = 1;
/*===========================================================================
* FUNCTION : QCamera2Factory
*
* DESCRIPTION: default constructor of QCamera2Factory
*
* PARAMETERS : none
*
* RETURN : None
*==========================================================================*/
QCamera2Factory::QCamera2Factory()
{
camera_info info;
mHalDescriptors = NULL;
mCallbacks = NULL;
mNumOfCameras = get_num_of_cameras();
int bDualCamera = 0;
char propDefault[PROPERTY_VALUE_MAX];
char prop[PROPERTY_VALUE_MAX];
property_get("persist.camera.HAL3.enabled", prop, "1");
int isHAL3Enabled = atoi(prop);
// Signifies whether system has to enable dual camera mode
snprintf(propDefault, PROPERTY_VALUE_MAX, "%d", isDualCamAvailable(isHAL3Enabled));
property_get("persist.camera.dual.camera", prop, propDefault);
bDualCamera = atoi(prop);
LOGH("dualCamera:%d ", bDualCamera);
if(bDualCamera) {
LOGI("Enabling QCamera Muxer");
if (!gQCameraMuxer) {
QCameraMuxer::getCameraMuxer(&gQCameraMuxer, mNumOfCameras);
if (!gQCameraMuxer) {
LOGE("Error !! Failed to get QCameraMuxer");
}
}
}
if (!gQCameraMuxer && (mNumOfCameras > 0) &&
(mNumOfCameras <= MM_CAMERA_MAX_NUM_SENSORS)) {
mHalDescriptors = new hal_desc[mNumOfCameras];
if ( NULL != mHalDescriptors) {
uint32_t cameraId = 0;
for (int i = 0; i < mNumOfCameras ; i++, cameraId++) {
mHalDescriptors[i].cameraId = cameraId;
// Set Device version to 3.x when both HAL3 is enabled & its BAYER sensor
if (isHAL3Enabled && !(is_yuv_sensor(cameraId))) {
mHalDescriptors[i].device_version =
CAMERA_DEVICE_API_VERSION_3_0;
} else {
mHalDescriptors[i].device_version =
CAMERA_DEVICE_API_VERSION_1_0;
}
//Query camera at this point in order
//to avoid any delays during subsequent
//calls to 'getCameraInfo()'
getCameraInfo(i, &info);
}
} else {
LOGE("Not enough resources to allocate HAL descriptor table!");
}
} else {
LOGI("%d camera devices detected!", mNumOfCameras);
}
}
/*===========================================================================
* FUNCTION : ~QCamera2Factory
*
* DESCRIPTION: deconstructor of QCamera2Factory
*
* PARAMETERS : none
*
* RETURN : None
*==========================================================================*/
QCamera2Factory::~QCamera2Factory()
{
if ( NULL != mHalDescriptors ) {
delete [] mHalDescriptors;
}
if (gQCameraMuxer) {
delete gQCameraMuxer;
gQCameraMuxer = NULL;
}
}
/*===========================================================================
* FUNCTION : get_number_of_cameras
*
* DESCRIPTION: static function to query number of cameras detected
*
* PARAMETERS : none
*
* RETURN : number of cameras detected
*==========================================================================*/
int QCamera2Factory::get_number_of_cameras()
{
int numCameras = 0;
int rc = NO_ERROR;
if (!gQCamera2Factory) {
gQCamera2Factory = new QCamera2Factory();
if (!gQCamera2Factory) {
LOGE("Failed to allocate Camera2Factory object");
return 0;
}
}
if(gQCameraMuxer)
numCameras = gQCameraMuxer->get_number_of_cameras();
else
numCameras = gQCamera2Factory->getNumberOfCameras();
LOGH("num of cameras: %d", numCameras);
return numCameras;
}
/*===========================================================================
* FUNCTION : get_camera_info
*
* DESCRIPTION: static function to query camera information with its ID
*
* PARAMETERS :
* @camera_id : camera ID
* @info : ptr to camera info struct
*
* RETURN : int32_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
int QCamera2Factory::get_camera_info(int camera_id, struct camera_info *info)
{
int rc = NO_ERROR;
if(gQCameraMuxer)
rc = gQCameraMuxer->get_camera_info(camera_id, info);
else
rc = gQCamera2Factory->getCameraInfo(camera_id, info);
return rc;
}
/*===========================================================================
* FUNCTION : set_callbacks
*
* DESCRIPTION: static function to set callbacks function to camera module
*
* PARAMETERS :
* @callbacks : ptr to callback functions
*
* RETURN : NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
int QCamera2Factory::set_callbacks(const camera_module_callbacks_t *callbacks)
{
int rc = NO_ERROR;
if(gQCameraMuxer)
rc = gQCameraMuxer->set_callbacks(callbacks);
else
rc = gQCamera2Factory->setCallbacks(callbacks);
return rc;
}
/*===========================================================================
* FUNCTION : open_legacy
*
* DESCRIPTION: Function to open older hal version implementation
*
* PARAMETERS :
* @hw_device : ptr to struct storing camera hardware device info
* @camera_id : camera ID
* @halVersion: Based on camera_module_t.common.module_api_version
*
* RETURN : 0 -- success
* none-zero failure code
*==========================================================================*/
int QCamera2Factory::open_legacy(const struct hw_module_t* module,
const char* id, uint32_t halVersion, struct hw_device_t** device)
{
int rc = NO_ERROR;
if (module != &HAL_MODULE_INFO_SYM.common) {
LOGE("Invalid module. Trying to open %p, expect %p",
module, &HAL_MODULE_INFO_SYM.common);
return INVALID_OPERATION;
}
if (!id) {
LOGE("Invalid camera id");
return BAD_VALUE;
}
if(gQCameraMuxer)
rc = gQCameraMuxer->open_legacy(module, id, halVersion, device);
else
rc = gQCamera2Factory->openLegacy(atoi(id), halVersion, device);
return rc;
}
/*===========================================================================
* FUNCTION : set_torch_mode
*
* DESCRIPTION: Attempt to turn on or off the torch mode of the flash unit.
*
* PARAMETERS :
* @camera_id : camera ID
* @on : Indicates whether to turn the flash on or off
*
* RETURN : 0 -- success
* none-zero failure code
*==========================================================================*/
int QCamera2Factory::set_torch_mode(const char* camera_id, bool on)
{
return gQCamera2Factory->setTorchMode(camera_id, on);
}
/*===========================================================================
* FUNCTION : getNumberOfCameras
*
* DESCRIPTION: query number of cameras detected
*
* PARAMETERS : none
*
* RETURN : number of cameras detected
*==========================================================================*/
int QCamera2Factory::getNumberOfCameras()
{
return mNumOfCameras;
}
/*===========================================================================
* FUNCTION : getCameraInfo
*
* DESCRIPTION: query camera information with its ID
*
* PARAMETERS :
* @camera_id : camera ID
* @info : ptr to camera info struct
*
* RETURN : int32_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
int QCamera2Factory::getCameraInfo(int camera_id, struct camera_info *info)
{
int rc;
cam_sync_type_t cam_type = CAM_TYPE_MAIN;
if (!mNumOfCameras || camera_id >= mNumOfCameras || !info ||
(camera_id < 0)) {
LOGE("Error getting camera info!! mNumOfCameras = %d,"
"camera_id = %d, info = %p",
mNumOfCameras, camera_id, info);
return -ENODEV;
}
if ( NULL == mHalDescriptors ) {
LOGE("Hal descriptor table is not initialized!");
return NO_INIT;
}
LOGI("Camera id %d API version %d",
camera_id, mHalDescriptors[camera_id].device_version);
// Need ANDROID_FLASH_INFO_AVAILABLE property for flashlight widget to
// work and so get the static data regardless of HAL version
rc = QCamera3HardwareInterface::getCamInfo(
mHalDescriptors[camera_id].cameraId, info);
if (mHalDescriptors[camera_id].device_version ==
CAMERA_DEVICE_API_VERSION_1_0) {
info->device_version = CAMERA_DEVICE_API_VERSION_1_0;
}
return rc;
}
/*===========================================================================
* FUNCTION : setCallbacks
*
* DESCRIPTION: set callback functions to send asynchronous notifications to
* frameworks.
*
* PARAMETERS :
* @callbacks : callback function pointer
*
* RETURN :
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
int QCamera2Factory::setCallbacks(const camera_module_callbacks_t *callbacks)
{
int rc = NO_ERROR;
mCallbacks = callbacks;
rc = QCameraFlash::getInstance().registerCallbacks(callbacks);
if (rc != 0) {
LOGE("Failed to register callbacks with flash module!");
}
return rc;
}
/*===========================================================================
* FUNCTION : cameraDeviceOpen
*
* DESCRIPTION: open a camera device with its ID
*
* PARAMETERS :
* @camera_id : camera ID
* @hw_device : ptr to struct storing camera hardware device info
*
* RETURN : int32_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
int QCamera2Factory::cameraDeviceOpen(int camera_id,
struct hw_device_t **hw_device)
{
int rc = NO_ERROR;
if (camera_id < 0 || camera_id >= mNumOfCameras)
return -ENODEV;
if ( NULL == mHalDescriptors ) {
LOGE("Hal descriptor table is not initialized!");
return NO_INIT;
}
LOGI("Open camera id %d API version %d",
camera_id, mHalDescriptors[camera_id].device_version);
if ( mHalDescriptors[camera_id].device_version == CAMERA_DEVICE_API_VERSION_3_0 ) {
QCamera3HardwareInterface *hw = new QCamera3HardwareInterface(mHalDescriptors[camera_id].cameraId,
mCallbacks);
if (!hw) {
LOGE("Allocation of hardware interface failed");
return NO_MEMORY;
}
rc = hw->openCamera(hw_device);
if (rc != 0) {
delete hw;
}
} else if (mHalDescriptors[camera_id].device_version == CAMERA_DEVICE_API_VERSION_1_0) {
QCamera2HardwareInterface *hw = new QCamera2HardwareInterface((uint32_t)camera_id);
if (!hw) {
LOGE("Allocation of hardware interface failed");
return NO_MEMORY;
}
rc = hw->openCamera(hw_device);
if (rc != NO_ERROR) {
delete hw;
}
} else {
LOGE("Device version for camera id %d invalid %d",
camera_id,
mHalDescriptors[camera_id].device_version);
return BAD_VALUE;
}
return rc;
}
/*===========================================================================
* FUNCTION : camera_device_open
*
* DESCRIPTION: static function to open a camera device by its ID
*
* PARAMETERS :
* @camera_id : camera ID
* @hw_device : ptr to struct storing camera hardware device info
*
* RETURN : int32_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
int QCamera2Factory::camera_device_open(
const struct hw_module_t *module, const char *id,
struct hw_device_t **hw_device)
{
int rc = NO_ERROR;
if (module != &HAL_MODULE_INFO_SYM.common) {
LOGE("Invalid module. Trying to open %p, expect %p",
module, &HAL_MODULE_INFO_SYM.common);
return INVALID_OPERATION;
}
if (!id) {
LOGE("Invalid camera id");
return BAD_VALUE;
}
if(gQCameraMuxer)
rc = gQCameraMuxer->camera_device_open(module, id, hw_device);
else
rc = gQCamera2Factory->cameraDeviceOpen(atoi(id), hw_device);
return rc;
}
struct hw_module_methods_t QCamera2Factory::mModuleMethods = {
open: QCamera2Factory::camera_device_open,
};
/*===========================================================================
* FUNCTION : openLegacy
*
* DESCRIPTION: Function to open older hal version implementation
*
* PARAMETERS :
* @camera_id : camera ID
* @halVersion: Based on camera_module_t.common.module_api_version
* @hw_device : ptr to struct storing camera hardware device info
*
* RETURN : 0 -- success
* none-zero failure code
*==========================================================================*/
int QCamera2Factory::openLegacy(
int32_t cameraId, uint32_t halVersion, struct hw_device_t** hw_device)
{
int rc = NO_ERROR;
LOGI("openLegacy halVersion: %d", halVersion);
//Assumption: all cameras can support legacy API version
if (cameraId < 0 || cameraId >= gQCamera2Factory->getNumberOfCameras())
return -ENODEV;
switch(halVersion)
{
case CAMERA_DEVICE_API_VERSION_1_0:
{
QCamera2HardwareInterface *hw =
new QCamera2HardwareInterface((uint32_t)cameraId);
if (!hw) {
LOGE("Allocation of hardware interface failed");
return NO_MEMORY;
}
rc = hw->openCamera(hw_device);
if (rc != NO_ERROR) {
delete hw;
}
break;
}
default:
LOGE("Device API version: %d for camera id %d invalid",
halVersion, cameraId);
return BAD_VALUE;
}
return rc;
}
/*===========================================================================
* FUNCTION : setTorchMode
*
* DESCRIPTION: Attempt to turn on or off the torch mode of the flash unit.
*
* PARAMETERS :
* @camera_id : camera ID
* @on : Indicates whether to turn the flash on or off
*
* RETURN : 0 -- success
* none-zero failure code
*==========================================================================*/
int QCamera2Factory::setTorchMode(const char* camera_id, bool on)
{
int retVal(0);
long cameraIdLong(-1);
int cameraIdInt(-1);
char* endPointer = NULL;
errno = 0;
QCameraFlash& flash = QCameraFlash::getInstance();
cameraIdLong = strtol(camera_id, &endPointer, 10);
if ((errno == ERANGE) ||
(cameraIdLong < 0) ||
(cameraIdLong >= static_cast<long>(get_number_of_cameras())) ||
(endPointer == camera_id) ||
(*endPointer != '\0')) {
retVal = -EINVAL;
} else if (on) {
cameraIdInt = static_cast<int>(cameraIdLong);
retVal = flash.initFlash(cameraIdInt);
if (retVal == 0) {
retVal = flash.setFlashMode(cameraIdInt, on);
if ((retVal == 0) && (mCallbacks != NULL)) {
mCallbacks->torch_mode_status_change(mCallbacks,
camera_id,
TORCH_MODE_STATUS_AVAILABLE_ON);
} else if (retVal == -EALREADY) {
// Flash is already on, so treat this as a success.
retVal = 0;
}
}
} else {
cameraIdInt = static_cast<int>(cameraIdLong);
retVal = flash.setFlashMode(cameraIdInt, on);
if (retVal == 0) {
retVal = flash.deinitFlash(cameraIdInt);
if ((retVal == 0) && (mCallbacks != NULL)) {
mCallbacks->torch_mode_status_change(mCallbacks,
camera_id,
TORCH_MODE_STATUS_AVAILABLE_OFF);
}
} else if (retVal == -EALREADY) {
// Flash is already off, so treat this as a success.
retVal = 0;
}
}
return retVal;
}
/*===========================================================================
* FUNCTION : isDualCamAvailable
*
* DESCRIPTION: Function to check whether we have dual Camera HW available
*
* PARAMETERS :
* @hal3Enabled : HAL3 enable flag
*
* RETURN : bool - true : have Dual Camera HW available
* false : not have Dual Camera HW available
*==========================================================================*/
bool QCamera2Factory::isDualCamAvailable(int hal3Enabled)
{
bool rc = FALSE;
int i = 0;
camera_info info;
cam_sync_type_t cam_type = CAM_TYPE_MAIN;
for (i = 0; i < mNumOfCameras; i++) {
if (!hal3Enabled) {
QCamera2HardwareInterface::getCapabilities(i, &info, &cam_type);
}
if(cam_type == CAM_TYPE_AUX) {
LOGH("Have Dual Camera HW Avaiable.");
rc = TRUE;
break;
}
}
return rc;
}
}; // namespace qcamera

View file

@ -0,0 +1,80 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __QCAMERA2FACTORY_H__
#define __QCAMERA2FACTORY_H__
// Camera dependencies
#include "camera_common.h"
namespace qcamera {
typedef struct {
uint32_t cameraId;
uint32_t device_version;
} hal_desc;
class QCamera2Factory
{
public:
QCamera2Factory();
virtual ~QCamera2Factory();
static int get_number_of_cameras();
static int get_camera_info(int camera_id, struct camera_info *info);
static int set_callbacks(const camera_module_callbacks_t *callbacks);
static int open_legacy(const struct hw_module_t* module,
const char* id, uint32_t halVersion, struct hw_device_t** device);
static int set_torch_mode(const char* camera_id, bool on);
bool isDualCamAvailable(int hal3Enabled);
private:
int getNumberOfCameras();
int getCameraInfo(int camera_id, struct camera_info *info);
int setCallbacks(const camera_module_callbacks_t *callbacks);
int cameraDeviceOpen(int camera_id, struct hw_device_t **hw_device);
static int camera_device_open(const struct hw_module_t *module, const char *id,
struct hw_device_t **hw_device);
static int openLegacy(
int32_t cameraId, uint32_t halVersion, struct hw_device_t** hw_device);
int setTorchMode(const char* camera_id, bool on);
public:
static struct hw_module_methods_t mModuleMethods;
private:
int mNumOfCameras;
hal_desc *mHalDescriptors;
const camera_module_callbacks_t *mCallbacks;
};
}; /*namespace qcamera*/
extern camera_module_t HAL_MODULE_INFO_SYM;
#endif /* __QCAMERA2FACTORY_H__ */

View file

@ -0,0 +1,56 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
// Camera dependencies
#include "QCamera2Factory.h"
#include "HAL3/QCamera3VendorTags.h"
static hw_module_t camera_common = {
tag: HARDWARE_MODULE_TAG,
module_api_version: CAMERA_MODULE_API_VERSION_2_4,
hal_api_version: HARDWARE_HAL_API_VERSION,
id: CAMERA_HARDWARE_MODULE_ID,
name: "QCamera Module",
author: "Qualcomm Innovation Center Inc",
methods: &qcamera::QCamera2Factory::mModuleMethods,
dso: NULL,
reserved: {0}
};
camera_module_t HAL_MODULE_INFO_SYM = {
common: camera_common,
get_number_of_cameras: qcamera::QCamera2Factory::get_number_of_cameras,
get_camera_info: qcamera::QCamera2Factory::get_camera_info,
set_callbacks: qcamera::QCamera2Factory::set_callbacks,
get_vendor_tag_ops: qcamera::QCamera3VendorTags::get_vendor_tag_ops,
open_legacy: qcamera::QCamera2Factory::open_legacy,
set_torch_mode: qcamera::QCamera2Factory::set_torch_mode,
init : NULL,
reserved: {0}
};

View file

@ -0,0 +1,5 @@
LOCAL_PATH:= $(call my-dir)
include $(LOCAL_PATH)/mm-camera-interface/Android.mk
include $(LOCAL_PATH)/mm-jpeg-interface/Android.mk
include $(LOCAL_PATH)/mm-jpeg-interface/test/Android.mk
include $(LOCAL_PATH)/mm-camera-test/Android.mk

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,84 @@
/* Copyright (c) 2012, 2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/* This file is a slave copy from /vendor/qcom/propreitary/mm-cammera/common,
* Please do not modify it directly here. */
#ifndef __CAMLIST_H
#define __CAMLIST_H
// System dependency
#include <stdlib.h>
#define member_of(ptr, type, member) ({ \
const typeof(((type *)0)->member) *__mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type,member));})
struct cam_list {
struct cam_list *next, *prev;
};
static inline void cam_list_init(struct cam_list *ptr)
{
ptr->next = ptr;
ptr->prev = ptr;
}
static inline void cam_list_add_tail_node(struct cam_list *item,
struct cam_list *head)
{
struct cam_list *prev = head->prev;
head->prev = item;
item->next = head;
item->prev = prev;
prev->next = item;
}
static inline void cam_list_insert_before_node(struct cam_list *item,
struct cam_list *node)
{
item->next = node;
item->prev = node->prev;
item->prev->next = item;
node->prev = item;
}
static inline void cam_list_del_node(struct cam_list *ptr)
{
struct cam_list *prev = ptr->prev;
struct cam_list *next = ptr->next;
next->prev = ptr->prev;
prev->next = ptr->next;
ptr->next = ptr;
ptr->prev = ptr;
}
#endif /* __CAMLIST_H */

View file

@ -0,0 +1,134 @@
/* Copyright (c) 2012, 2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
// System dependencies
#include <pthread.h>
// Camera dependencies
#include "cam_list.h"
typedef struct {
struct cam_list list;
void *data;
} cam_node_t;
typedef struct {
cam_node_t head; /* dummy head */
uint32_t size;
pthread_mutex_t lock;
} cam_queue_t;
static inline int32_t cam_queue_init(cam_queue_t *queue)
{
pthread_mutex_init(&queue->lock, NULL);
cam_list_init(&queue->head.list);
queue->size = 0;
return 0;
}
static inline int32_t cam_queue_enq(cam_queue_t *queue, void *data)
{
cam_node_t *node =
(cam_node_t *)malloc(sizeof(cam_node_t));
if (NULL == node) {
return -1;
}
memset(node, 0, sizeof(cam_node_t));
node->data = data;
pthread_mutex_lock(&queue->lock);
cam_list_add_tail_node(&node->list, &queue->head.list);
queue->size++;
pthread_mutex_unlock(&queue->lock);
return 0;
}
static inline void *cam_queue_deq(cam_queue_t *queue)
{
cam_node_t *node = NULL;
void *data = NULL;
struct cam_list *head = NULL;
struct cam_list *pos = NULL;
pthread_mutex_lock(&queue->lock);
head = &queue->head.list;
pos = head->next;
if (pos != head) {
node = member_of(pos, cam_node_t, list);
cam_list_del_node(&node->list);
queue->size--;
}
pthread_mutex_unlock(&queue->lock);
if (NULL != node) {
data = node->data;
free(node);
}
return data;
}
static inline int32_t cam_queue_flush(cam_queue_t *queue)
{
cam_node_t *node = NULL;
struct cam_list *head = NULL;
struct cam_list *pos = NULL;
pthread_mutex_lock(&queue->lock);
head = &queue->head.list;
pos = head->next;
while(pos != head) {
node = member_of(pos, cam_node_t, list);
pos = pos->next;
cam_list_del_node(&node->list);
queue->size--;
/* TODO later to consider ptr inside data */
/* for now we only assume there is no ptr inside data
* so we free data directly */
if (NULL != node->data) {
free(node->data);
}
free(node);
}
queue->size = 0;
pthread_mutex_unlock(&queue->lock);
return 0;
}
static inline int32_t cam_queue_deinit(cam_queue_t *queue)
{
cam_queue_flush(queue);
pthread_mutex_destroy(&queue->lock);
return 0;
}

View file

@ -0,0 +1,88 @@
/* Copyright (c) 2012, 2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __QCAMERA_SEMAPHORE_H__
#define __QCAMERA_SEMAPHORE_H__
// System dependencies
#include <pthread.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Implement semaphore with mutex and conditional variable.
* Reason being, POSIX semaphore on Android are not used or
* well tested.
*/
typedef struct {
int val;
pthread_mutex_t mutex;
pthread_cond_t cond;
} cam_semaphore_t;
static inline void cam_sem_init(cam_semaphore_t *s, int n)
{
pthread_mutex_init(&(s->mutex), NULL);
pthread_cond_init(&(s->cond), NULL);
s->val = n;
}
static inline void cam_sem_post(cam_semaphore_t *s)
{
pthread_mutex_lock(&(s->mutex));
s->val++;
pthread_cond_signal(&(s->cond));
pthread_mutex_unlock(&(s->mutex));
}
static inline int cam_sem_wait(cam_semaphore_t *s)
{
int rc = 0;
pthread_mutex_lock(&(s->mutex));
while (s->val == 0)
rc = pthread_cond_wait(&(s->cond), &(s->mutex));
s->val--;
pthread_mutex_unlock(&(s->mutex));
return rc;
}
static inline void cam_sem_destroy(cam_semaphore_t *s)
{
pthread_mutex_destroy(&(s->mutex));
pthread_cond_destroy(&(s->cond));
s->val = 0;
}
#ifdef __cplusplus
}
#endif
#endif /* __QCAMERA_SEMAPHORE_H__ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,920 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __MM_CAMERA_INTERFACE_H__
#define __MM_CAMERA_INTERFACE_H__
// System dependencies
#include <media/msmb_camera.h>
// Camera dependencies
#include "cam_intf.h"
#include "cam_queue.h"
#define MM_CAMERA_MAX_NUM_SENSORS MSM_MAX_CAMERA_SENSORS
#define MM_CAMERA_MAX_NUM_FRAMES CAM_MAX_NUM_BUFS_PER_STREAM
/* num of channels allowed in a camera obj */
#define MM_CAMERA_CHANNEL_MAX 16
#define PAD_TO_SIZE(size, padding) \
((size + (typeof(size))(padding - 1)) & \
(typeof(size))(~(padding - 1)))
#define CEIL_DIVISION(n, d) ((n+d-1)/d)
/** CAM_DUMP_TO_FILE:
* @filename: file name
* @name:filename
* @index: index of the file
* @extn: file extension
* @p_addr: address of the buffer
* @len: buffer length
*
* dump the image to the file
**/
#define CAM_DUMP_TO_FILE(path, name, index, extn, p_addr, len) ({ \
size_t rc = 0; \
char filename[FILENAME_MAX]; \
if (index >= 0) \
snprintf(filename, FILENAME_MAX, "%s/%s%d.%s", path, name, index, extn); \
else \
snprintf(filename, FILENAME_MAX, "%s/%s.%s", path, name, extn); \
FILE *fp = fopen(filename, "w+"); \
if (fp) { \
rc = fwrite(p_addr, 1, len, fp); \
LOGE("written size %d", len); \
fclose(fp); \
} else { \
LOGE("open %s failed", filename); \
} \
})
/* Declaring Buffer structure */
struct mm_camera_buf_def;
/** mm_camera_plane_def_t : structure for frame plane info
* @num_planes : num of planes for the frame buffer, to be
* filled during mem allocation
* @planes : plane info for the frame buffer, to be filled
* during mem allocation
**/
typedef struct {
int8_t num_planes;
struct v4l2_plane planes[VIDEO_MAX_PLANES];
} mm_camera_plane_buf_def_t;
/** mm_camera_user_buf_def_t : structure for frame plane info
* @num_buffers : num of buffers in this user defined structure
* @bufs_used : actual number of buffer filled
* @buf_in_use : flag to notify buffer usage status.
* @plane_buf : Plane buffer array pointer.
**/
typedef struct {
uint8_t num_buffers;
uint8_t bufs_used; /*Num of Buffer filled by Kernel*/
uint8_t buf_in_use; /* Container buffer is freed to fill*/
int32_t buf_idx[MSM_CAMERA_MAX_USER_BUFF_CNT];
struct mm_camera_buf_def *plane_buf;
} mm_camera_user_buf_def_t;
/** mm_camera_buf_def_t: structure for stream frame buf
* @stream_id : stream handler to uniquely identify a stream
* object
* @buf_idx : index of the buf within the stream bufs, to be
* filled during mem allocation
* @timespec_ts : time stamp, to be filled when DQBUF is
* called
* @frame_idx : frame sequence num, to be filled when DQBUF
* @plane_buf : Frame plane definition
* @fd : file descriptor of the frame buffer, to be filled
* during mem allocation
* @buffer : pointer to the frame buffer, to be filled during
* mem allocation
* @frame_len : length of the whole frame, to be filled during
* mem allocation
* @mem_info : user specific pointer to additional mem info
* @flags: v4l2_buffer flags, used to report error in data buffers
**/
typedef struct mm_camera_buf_def {
uint32_t stream_id;
cam_stream_type_t stream_type;
cam_stream_buf_type buf_type;
uint32_t buf_idx;
uint8_t is_uv_subsampled;
struct timespec ts;
uint32_t frame_idx;
union {
mm_camera_plane_buf_def_t planes_buf;
mm_camera_user_buf_def_t user_buf;
};
int fd;
void *buffer;
size_t frame_len;
void *mem_info;
uint32_t flags;
} mm_camera_buf_def_t;
/** mm_camera_super_buf_t: super buf structure for bundled
* stream frames
* @camera_handle : camera handler to uniquely identify
* a camera object
* @ch_id : channel handler to uniquely ideentify a channel
* object
* @num_bufs : number of buffers in the super buf, should not
* exceeds MAX_STREAM_NUM_IN_BUNDLE
* @bufs : array of buffers in the bundle
**/
typedef struct {
uint32_t camera_handle;
uint32_t ch_id;
uint32_t num_bufs;
uint8_t bUnlockAEC;
uint8_t bReadyForPrepareSnapshot;
mm_camera_buf_def_t* bufs[MAX_STREAM_NUM_IN_BUNDLE];
} mm_camera_super_buf_t;
/** mm_camera_req_buf_type_t
* Request type for super buf from channel
**/
typedef enum {
MM_CAMERA_REQ_SUPER_BUF,
MM_CAMERA_REQ_FRAME_SYNC_BUF
} mm_camera_req_buf_type_t;
/** mm_camera_req_buf_t: Attributes for super buf request
*
* @type : type of super buf requested
* @num_buf_requested : num of super bufs requested
* @num_retro_buf_requested : number of retro bufs requested
* @primary_only : specifies if only primary camera frame for a dual
* camera is requested
**/
typedef struct {
mm_camera_req_buf_type_t type;
uint32_t num_buf_requested;
uint32_t num_retro_buf_requested;
uint8_t primary_only;
} mm_camera_req_buf_t;
/** mm_camera_event_t: structure for event
* @server_event_type : event type from serer
* @status : status of an event, value could be
* CAM_STATUS_SUCCESS
* CAM_STATUS_FAILED
**/
typedef struct {
cam_event_type_t server_event_type;
uint32_t status;
} mm_camera_event_t;
/** mm_camera_event_notify_t: function definition for event
* notify handling
* @camera_handle : camera handler
* @evt : pointer to an event struct
* @user_data: user data pointer
**/
typedef void (*mm_camera_event_notify_t)(uint32_t camera_handle,
mm_camera_event_t *evt,
void *user_data);
/** mm_camera_buf_notify_t: function definition for frame notify
* handling
* @mm_camera_super_buf_t : received frame buffers
* @user_data: user data pointer
**/
typedef void (*mm_camera_buf_notify_t) (mm_camera_super_buf_t *bufs,
void *user_data);
/** map_stream_buf_op_t: function definition for operation of
* mapping stream buffers via domain socket
* @frame_idx : buffer index within stream buffers
* @plane_idx : plane index. If all planes share the same
* fd, plane_idx = -1; otherwise, plean_idx is
* the index to plane (0..num_of_planes)
* @fd : file descriptor of the stream buffer
* @size: size of the stream buffer
* @userdata : user data pointer
**/
typedef int32_t (*map_stream_buf_op_t) (uint32_t frame_idx,
int32_t plane_idx,
int fd,
size_t size,
cam_mapping_buf_type type,
void *userdata);
typedef int32_t (*map_stream_bufs_op_t) (const cam_buf_map_type_list *buf_map_list,
void *userdata);
/** unmap_stream_buf_op_t: function definition for operation of
* unmapping stream buffers via domain
* socket
* @frame_idx : buffer index within stream buffers
* @plane_idx : plane index. If all planes share the same
* fd, plane_idx = -1; otherwise, plean_idx is
* the index to plane (0..num_of_planes)
* @userdata : user data pointer
**/
typedef int32_t (*unmap_stream_buf_op_t) (uint32_t frame_idx,
int32_t plane_idx,
cam_mapping_buf_type type,
void *userdata);
/** mm_camera_map_unmap_ops_tbl_t: virtual table
* for mapping/unmapping stream buffers via
* domain socket
* @map_ops : operation for mapping
* @unmap_ops : operation for unmapping
* @userdata: user data pointer
**/
typedef struct {
map_stream_buf_op_t map_ops;
map_stream_bufs_op_t bundled_map_ops;
unmap_stream_buf_op_t unmap_ops;
void *userdata;
} mm_camera_map_unmap_ops_tbl_t;
/** mm_camera_stream_mem_vtbl_t: virtual table for stream
* memory allocation and deallocation
* @get_bufs : function definition for allocating
* stream buffers
* @put_bufs : function definition for deallocating
* stream buffers
* @user_data: user data pointer
**/
typedef struct {
void *user_data;
int32_t (*set_config_ops) (mm_camera_map_unmap_ops_tbl_t *ops_tbl,
void *user_data);
int32_t (*get_bufs) (cam_frame_len_offset_t *offset,
uint8_t *num_bufs,
uint8_t **initial_reg_flag,
mm_camera_buf_def_t **bufs,
mm_camera_map_unmap_ops_tbl_t *ops_tbl,
void *user_data);
int32_t (*put_bufs) (mm_camera_map_unmap_ops_tbl_t *ops_tbl,
void *user_data);
int32_t (*invalidate_buf)(uint32_t index, void *user_data);
int32_t (*clean_invalidate_buf)(uint32_t index, void *user_data);
} mm_camera_stream_mem_vtbl_t;
/** mm_camera_stream_config_t: structure for stream
* configuration
* @stream_info : pointer to a stream info structure
* @padding_info: padding info obtained from querycapability
* @mem_tbl : memory operation table for
* allocating/deallocating stream buffers
* @stream_cb_sync : SYNC callback handling stream frame notify
* @stream_cb : ASYNC callback handling stream frame notify
* @userdata : user data pointer
**/
typedef struct {
cam_stream_info_t *stream_info;
cam_padding_info_t padding_info;
mm_camera_stream_mem_vtbl_t mem_vtbl;
mm_camera_buf_notify_t stream_cb_sync;
mm_camera_buf_notify_t stream_cb;
void *userdata;
} mm_camera_stream_config_t;
/** mm_camera_super_buf_notify_mode_t: enum for super uffer
* notification mode
* @MM_CAMERA_SUPER_BUF_NOTIFY_BURST :
* ZSL use case: get burst of frames
* @MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS :
* get continuous frames: when the super buf is ready
* dispatch it to HAL
**/
typedef enum {
MM_CAMERA_SUPER_BUF_NOTIFY_BURST = 0,
MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS,
MM_CAMERA_SUPER_BUF_NOTIFY_MAX
} mm_camera_super_buf_notify_mode_t;
/** mm_camera_super_buf_priority_t: enum for super buffer
* matching priority
* @MM_CAMERA_SUPER_BUF_PRIORITY_NORMAL :
* Save the frame no matter focused or not. Currently only
* this type is supported.
* @MM_CAMERA_SUPER_BUF_PRIORITY_FOCUS :
* only queue the frame that is focused. Will enable meta
* data header to carry focus info
* @MM_CAMERA_SUPER_BUF_PRIORITY_EXPOSURE_BRACKETING :
* after shutter, only queue matched exposure index
**/
typedef enum {
MM_CAMERA_SUPER_BUF_PRIORITY_NORMAL = 0,
MM_CAMERA_SUPER_BUF_PRIORITY_FOCUS,
MM_CAMERA_SUPER_BUF_PRIORITY_EXPOSURE_BRACKETING,
MM_CAMERA_SUPER_BUF_PRIORITY_LOW,/* Bundled metadata frame may not match*/
MM_CAMERA_SUPER_BUF_PRIORITY_MAX
} mm_camera_super_buf_priority_t;
/** mm_camera_advanced_capture_t: enum for advanced capture type.
* @MM_CAMERA_AF_BRACKETING :
* to enable AF Bracketig.
* @MM_CAMERA_AE_BRACKETING :
* to enable AF Bracketing.
* @MM_CAMERA_FLASH_BRACKETING :
* to enable Flash Bracketing.
* @MM_CAMERA_ZOOM_1X :
* to enable zoom 1x capture request
**/
typedef enum {
MM_CAMERA_AF_BRACKETING = 0,
MM_CAMERA_AE_BRACKETING,
MM_CAMERA_FLASH_BRACKETING,
MM_CAMERA_ZOOM_1X,
MM_CAMERA_FRAME_CAPTURE,
} mm_camera_advanced_capture_t;
/** mm_camera_stream_cb_type: enum for stream buffer callback type.
* @MM_CAMERA_STREAM_CB_TYPE_ASYNC :
* callback is async type. buffer process done in client thread context
* @MM_CAMERA_STREAM_CB_TYPE_SYNC :
* callback is sync type. buffer process done interface thread context
**/
typedef enum {
MM_CAMERA_STREAM_CB_TYPE_ASYNC,
MM_CAMERA_STREAM_CB_TYPE_SYNC,
} mm_camera_stream_cb_type;
/** mm_camera_channel_attr_t: structure for defining channel
* attributes
* @notify_mode : notify mode: burst or continuous
* @water_mark : queue depth. Only valid for burst mode
* @look_back : look back how many frames from last buf.
* Only valid for burst mode
* @post_frame_skip : after send first frame to HAL, how many
* frames needing to be skipped for next
* delivery. Only valid for burst mode
* @max_unmatched_frames : max number of unmatched frames in
* queue
* @enable_frame_sync: Enables frame sync for dual camera
* @priority : save matched priority frames only
**/
typedef struct {
mm_camera_super_buf_notify_mode_t notify_mode;
uint8_t water_mark;
uint8_t look_back;
uint8_t post_frame_skip;
uint8_t max_unmatched_frames;
uint8_t enable_frame_sync;
mm_camera_super_buf_priority_t priority;
} mm_camera_channel_attr_t;
typedef struct {
/** query_capability: fucntion definition for querying static
* camera capabilities
* @camera_handle : camer handler
* Return value: 0 -- success
* -1 -- failure
* Note: would assume cam_capability_t is already mapped
**/
int32_t (*query_capability) (uint32_t camera_handle);
/** register_event_notify: fucntion definition for registering
* for event notification
* @camera_handle : camer handler
* @evt_cb : callback for event notify
* @user_data : user data poiner
* Return value: 0 -- success
* -1 -- failure
**/
int32_t (*register_event_notify) (uint32_t camera_handle,
mm_camera_event_notify_t evt_cb,
void *user_data);
/** close_camera: fucntion definition for closing a camera
* @camera_handle : camer handler
* Return value: 0 -- success
* -1 -- failure
**/
int32_t (*close_camera) (uint32_t camera_handle);
/** map_buf: fucntion definition for mapping a camera buffer
* via domain socket
* @camera_handle : camer handler
* @buf_type : type of mapping buffers, can be value of
* CAM_MAPPING_BUF_TYPE_CAPABILITY
* CAM_MAPPING_BUF_TYPE_SETPARM_BUF
* CAM_MAPPING_BUF_TYPE_GETPARM_BUF
* @fd : file descriptor of the stream buffer
* @size : size of the stream buffer
* Return value: 0 -- success
* -1 -- failure
**/
int32_t (*map_buf) (uint32_t camera_handle,
uint8_t buf_type,
int fd,
size_t size);
/** map_bufs: function definition for mapping multiple camera buffers
* via domain socket
* @camera_handle : camera handler
* @buf_map_list : list of buffers to map
* Return value: 0 -- success
* -1 -- failure
**/
int32_t (*map_bufs) (uint32_t camera_handle,
const cam_buf_map_type_list *buf_map_list);
/** unmap_buf: fucntion definition for unmapping a camera buffer
* via domain socket
* @camera_handle : camer handler
* @buf_type : type of mapping buffers, can be value of
* CAM_MAPPING_BUF_TYPE_CAPABILITY
* CAM_MAPPING_BUF_TYPE_SETPARM_BUF
* CAM_MAPPING_BUF_TYPE_GETPARM_BUF
* Return value: 0 -- success
* -1 -- failure
**/
int32_t (*unmap_buf) (uint32_t camera_handle,
uint8_t buf_type);
/** set_parms: fucntion definition for setting camera
* based parameters to server
* @camera_handle : camer handler
* @parms : batch for parameters to be set, stored in
* parm_buffer_t
* Return value: 0 -- success
* -1 -- failure
* Note: would assume parm_buffer_t is already mapped, and
* according parameter entries to be set are filled in the
* buf before this call
**/
int32_t (*set_parms) (uint32_t camera_handle,
parm_buffer_t *parms);
/** get_parms: fucntion definition for querying camera
* based parameters from server
* @camera_handle : camer handler
* @parms : batch for parameters to be queried, stored in
* parm_buffer_t
* Return value: 0 -- success
* -1 -- failure
* Note: would assume parm_buffer_t is already mapped, and
* according parameter entries to be queried are filled in
* the buf before this call
**/
int32_t (*get_parms) (uint32_t camera_handle,
parm_buffer_t *parms);
/** do_auto_focus: fucntion definition for performing auto focus
* @camera_handle : camer handler
* Return value: 0 -- success
* -1 -- failure
* Note: if this call success, we will always assume there will
* be an auto_focus event following up.
**/
int32_t (*do_auto_focus) (uint32_t camera_handle);
/** cancel_auto_focus: fucntion definition for cancelling
* previous auto focus request
* @camera_handle : camer handler
* Return value: 0 -- success
* -1 -- failure
**/
int32_t (*cancel_auto_focus) (uint32_t camera_handle);
/** prepare_snapshot: fucntion definition for preparing hardware
* for snapshot.
* @camera_handle : camer handler
* @do_af_flag : flag indicating if AF needs to be done
* 0 -- no AF needed
* 1 -- AF needed
* Return value: 0 -- success
* -1 -- failure
**/
int32_t (*prepare_snapshot) (uint32_t camera_handle,
int32_t do_af_flag);
/** start_zsl_snapshot: function definition for starting
* zsl snapshot.
* @camera_handle : camer handler
* @ch_id : channel id
* Return value: 0 -- success
* -1 -- failure
**/
int32_t (*start_zsl_snapshot) (uint32_t camera_handle, uint32_t ch_id);
/** stop_zsl_snapshot: function definition for stopping
* zsl snapshot.
* @camera_handle : camer handler
* @ch_id : channel id
* Return value: 0 -- success
* -1 -- failure
**/
int32_t (*stop_zsl_snapshot) (uint32_t camera_handle, uint32_t ch_id);
/** add_channel: fucntion definition for adding a channel
* @camera_handle : camer handler
* @ch_id : channel handler
* @attr : pointer to channel attribute structure
* @channel_cb : callbak to handle bundled super buffer
* @userdata : user data pointer
* Return value: channel id, zero is invalid ch_id
* Note: attr, channel_cb, and userdata can be NULL if no
* superbufCB is needed
**/
uint32_t (*add_channel) (uint32_t camera_handle,
mm_camera_channel_attr_t *attr,
mm_camera_buf_notify_t channel_cb,
void *userdata);
/** delete_channel: fucntion definition for deleting a channel
* @camera_handle : camer handler
* @ch_id : channel handler
* Return value: 0 -- success
* -1 -- failure
**/
int32_t (*delete_channel) (uint32_t camera_handle,
uint32_t ch_id);
/** get_bundle_info: function definition for querying bundle
* info of the channel
* @camera_handle : camera handler
* @ch_id : channel handler
* @bundle_info : bundle info to be filled in
* Return value: 0 -- success
* -1 -- failure
**/
int32_t (*get_bundle_info) (uint32_t camera_handle,
uint32_t ch_id,
cam_bundle_config_t *bundle_info);
/** add_stream: fucntion definition for adding a stream
* @camera_handle : camer handler
* @ch_id : channel handler
* Return value: stream_id. zero is invalid stream_id
**/
uint32_t (*add_stream) (uint32_t camera_handle,
uint32_t ch_id);
/** delete_stream: fucntion definition for deleting a stream
* @camera_handle : camer handler
* @ch_id : channel handler
* @stream_id : stream handler
* Return value: 0 -- success
* -1 -- failure
**/
int32_t (*delete_stream) (uint32_t camera_handle,
uint32_t ch_id,
uint32_t stream_id);
/** link_stream: function definition for linking a stream
* @camera_handle : camera handle
* @ch_id : channel handle from which the stream originates
* @stream_id : stream handle
* @linked_ch_id: channel handle in which the stream will be linked
* Return value: 0 -- success
* -1 -- failure
**/
int32_t (*link_stream) (uint32_t camera_handle,
uint32_t ch_id,
uint32_t stream_id,
uint32_t linked_ch_id);
/** config_stream: fucntion definition for configuring a stream
* @camera_handle : camer handler
* @ch_id : channel handler
* @stream_id : stream handler
* @confid : pointer to a stream configuration structure
* Return value: 0 -- success
* -1 -- failure
**/
int32_t (*config_stream) (uint32_t camera_handle,
uint32_t ch_id,
uint32_t stream_id,
mm_camera_stream_config_t *config);
/** map_stream_buf: fucntion definition for mapping
* stream buffer via domain socket
* @camera_handle : camer handler
* @ch_id : channel handler
* @stream_id : stream handler
* @buf_type : type of mapping buffers, can be value of
* CAM_MAPPING_BUF_TYPE_STREAM_BUF
* CAM_MAPPING_BUF_TYPE_STREAM_INFO
* CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
* @buf_idx : buffer index within the stream buffers
* @plane_idx : plane index. If all planes share the same fd,
* plane_idx = -1; otherwise, plean_idx is the
* index to plane (0..num_of_planes)
* @fd : file descriptor of the stream buffer
* @size : size of the stream buffer
* Return value: 0 -- success
* -1 -- failure
**/
int32_t (*map_stream_buf) (uint32_t camera_handle,
uint32_t ch_id,
uint32_t stream_id,
uint8_t buf_type,
uint32_t buf_idx,
int32_t plane_idx,
int fd,
size_t size);
/** map_stream_bufs: function definition for mapping multiple
* stream buffers via domain socket
* @camera_handle : camera handler
* @ch_id : channel handler
* @buf_map_list : list of buffers to map
* Return value: 0 -- success
* -1 -- failure
**/
int32_t (*map_stream_bufs) (uint32_t camera_handle,
uint32_t ch_id,
const cam_buf_map_type_list *buf_map_list);
/** unmap_stream_buf: fucntion definition for unmapping
* stream buffer via domain socket
* @camera_handle : camer handler
* @ch_id : channel handler
* @stream_id : stream handler
* @buf_type : type of mapping buffers, can be value of
* CAM_MAPPING_BUF_TYPE_STREAM_BUF
* CAM_MAPPING_BUF_TYPE_STREAM_INFO
* CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
* @buf_idx : buffer index within the stream buffers
* @plane_idx : plane index. If all planes share the same fd,
* plane_idx = -1; otherwise, plean_idx is the
* index to plane (0..num_of_planes)
* Return value: 0 -- success
* -1 -- failure
**/
int32_t (*unmap_stream_buf) (uint32_t camera_handle,
uint32_t ch_id,
uint32_t stream_id,
uint8_t buf_type,
uint32_t buf_idx,
int32_t plane_idx);
/** set_stream_parms: fucntion definition for setting stream
* specific parameters to server
* @camera_handle : camer handler
* @ch_id : channel handler
* @stream_id : stream handler
* @parms : batch for parameters to be set
* Return value: 0 -- success
* -1 -- failure
* Note: would assume parm buffer is already mapped, and
* according parameter entries to be set are filled in the
* buf before this call
**/
int32_t (*set_stream_parms) (uint32_t camera_handle,
uint32_t ch_id,
uint32_t s_id,
cam_stream_parm_buffer_t *parms);
/** get_stream_parms: fucntion definition for querying stream
* specific parameters from server
* @camera_handle : camer handler
* @ch_id : channel handler
* @stream_id : stream handler
* @parms : batch for parameters to be queried
* Return value: 0 -- success
* -1 -- failure
* Note: would assume parm buffer is already mapped, and
* according parameter entries to be queried are filled in
* the buf before this call
**/
int32_t (*get_stream_parms) (uint32_t camera_handle,
uint32_t ch_id,
uint32_t s_id,
cam_stream_parm_buffer_t *parms);
/** start_channel: fucntion definition for starting a channel
* @camera_handle : camer handler
* @ch_id : channel handler
* Return value: 0 -- success
* -1 -- failure
* This call will start all streams belongs to the channel
**/
int32_t (*start_channel) (uint32_t camera_handle,
uint32_t ch_id);
/** stop_channel: fucntion definition for stopping a channel
* @camera_handle : camer handler
* @ch_id : channel handler
* Return value: 0 -- success
* -1 -- failure
* This call will stop all streams belongs to the channel
**/
int32_t (*stop_channel) (uint32_t camera_handle,
uint32_t ch_id);
/** qbuf: fucntion definition for queuing a frame buffer back to
* kernel for reuse
* @camera_handle : camer handler
* @ch_id : channel handler
* @buf : a frame buffer to be queued back to kernel
* Return value: 0 -- success
* -1 -- failure
**/
int32_t (*qbuf) (uint32_t camera_handle,
uint32_t ch_id,
mm_camera_buf_def_t *buf);
/** get_queued_buf_count: fucntion definition for querying queued buf count
* @camera_handle : camer handler
* @ch_id : channel handler
* @stream_id : stream handler
* Return value: queued buf count
**/
int32_t (*get_queued_buf_count) (uint32_t camera_handle,
uint32_t ch_id,
uint32_t stream_id);
/** request_super_buf: fucntion definition for requesting frames
* from superbuf queue in burst mode
* @camera_handle : camer handler
* @ch_id : channel handler
* @buf : provides info related to the super buf request
* Return value: 0 -- success
* -1 -- failure
**/
int32_t (*request_super_buf) (uint32_t camera_handle,
uint32_t ch_id,
mm_camera_req_buf_t *buf);
/** cancel_super_buf_request: fucntion definition for canceling
* frames dispatched from superbuf queue in
* burst mode
* @camera_handle : camer handler
* @ch_id : channel handler
* Return value: 0 -- success
* -1 -- failure
**/
int32_t (*cancel_super_buf_request) (uint32_t camera_handle,
uint32_t ch_id);
/** flush_super_buf_queue: function definition for flushing out
* all frames in the superbuf queue up to frame_idx,
* even if frames with frame_idx come in later than
* this call.
* @camera_handle : camer handler
* @ch_id : channel handler
* @frame_idx : frame index up until which all superbufs are flushed
* Return value: 0 -- success
* -1 -- failure
**/
int32_t (*flush_super_buf_queue) (uint32_t camera_handle,
uint32_t ch_id, uint32_t frame_idx);
/** configure_notify_mode: function definition for configuring the
* notification mode of channel
* @camera_handle : camera handler
* @ch_id : channel handler
* @notify_mode : notification mode
* Return value: 0 -- success
* -1 -- failure
**/
int32_t (*configure_notify_mode) (uint32_t camera_handle,
uint32_t ch_id,
mm_camera_super_buf_notify_mode_t notify_mode);
/** process_advanced_capture: function definition for start/stop advanced capture
* for snapshot.
* @camera_handle : camera handle
* @ch_id : channel handler
* @type : advanced capture type.
* @trigger : flag indicating if advanced capture needs to be done
* 0 -- stop advanced capture
* 1 -- start advanced capture
* @in_value: Input value. Configaration
* Return value: 0 -- success
* -1 -- failure
**/
int32_t (*process_advanced_capture) (uint32_t camera_handle,
uint32_t ch_id, mm_camera_advanced_capture_t type,
int8_t start_flag, void *in_value);
/** get_session_id: gets the backend session id from the kernel
* @camera_handle : camera handle
* @sessionid : session id to be retrieved
* Return value: 0 -- success
* -1 -- failure
* Note: if this call succeeds, we will get a valid session id
**/
int32_t (*get_session_id) (uint32_t camera_handle,
uint32_t* sessionid);
/** sync_related_sensors: sends sync cmd
* @camera_handle : camera handle
* @related_cam_info : related cam info to be sent to server
* Return value: 0 -- success
* -1 -- failure
* Note: if this call succeeds, we will get linking established in back end
**/
int32_t (*sync_related_sensors) (uint32_t camera_handle,
cam_sync_related_sensors_event_info_t*
related_cam_info);
/** flush: function definition for flush
* @camera_handle: camera handler
* Return value: 0 -- success
* -1 -- failure
**/
int32_t (*flush) (uint32_t camera_handle);
/** register_stream_buf_cb: fucntion definition for registering special stream callbacks
* @camera_handle : camer handler
* @ch_id : channel handler
* @stream_id : stream handler
* @buf_cb : callback function pointer
* @cb_type : Callback type SYNC/ASYNC
* @userdata : user data pointer
* Return value: 0 -- success
* - 1 -- failure
**/
int32_t (*register_stream_buf_cb) (uint32_t camera_handle,
uint32_t ch_id, uint32_t stream_id, mm_camera_buf_notify_t buf_cb,
mm_camera_stream_cb_type cb_type, void *userdata);
} mm_camera_ops_t;
/** mm_camera_vtbl_t: virtual table for camera operations
* @camera_handle : camera handler which uniquely identifies a
* camera object
* @ops : API call table
**/
typedef struct {
uint32_t camera_handle;
mm_camera_ops_t *ops;
} mm_camera_vtbl_t;
/* return number of cameras */
uint8_t get_num_of_cameras();
/* return reference pointer of camera vtbl */
int32_t camera_open(uint8_t camera_idx, mm_camera_vtbl_t **camera_obj);
/* helper functions */
int32_t mm_stream_calc_offset_preview(cam_stream_info_t *stream_info,
cam_dimension_t *dim,
cam_padding_info_t *padding,
cam_stream_buf_plane_info_t *buf_planes);
int32_t mm_stream_calc_offset_post_view(cam_format_t fmt,
cam_dimension_t *dim,
cam_stream_buf_plane_info_t *buf_planes);
int32_t mm_stream_calc_offset_snapshot(cam_format_t fmt,
cam_dimension_t *dim,
cam_padding_info_t *padding,
cam_stream_buf_plane_info_t *buf_planes);
int32_t mm_stream_calc_offset_raw(cam_format_t fmt,
cam_dimension_t *dim,
cam_padding_info_t *padding,
cam_stream_buf_plane_info_t *buf_planes);
int32_t mm_stream_calc_offset_video(cam_format_t fmt,
cam_dimension_t *dim,
cam_stream_buf_plane_info_t *buf_planes);
int32_t mm_stream_calc_offset_metadata(cam_dimension_t *dim,
cam_padding_info_t *padding,
cam_stream_buf_plane_info_t *buf_planes);
int32_t mm_stream_calc_offset_postproc(cam_stream_info_t *stream_info,
cam_padding_info_t *padding,
cam_stream_buf_plane_info_t *buf_planes);
int32_t mm_stream_calc_offset_analysis(cam_format_t fmt,
cam_dimension_t *dim,
cam_padding_info_t *padding,
cam_stream_buf_plane_info_t *buf_planes);
uint32_t mm_stream_calc_lcm (int32_t num1, int32_t num2);
struct camera_info *get_cam_info(uint32_t camera_id, cam_sync_type_t *pCamType);
uint8_t is_yuv_sensor(uint32_t camera_id);
#endif /*__MM_CAMERA_INTERFACE_H__*/

View file

@ -0,0 +1,399 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef MM_JPEG_INTERFACE_H_
#define MM_JPEG_INTERFACE_H_
// System dependencies
#include <stdbool.h>
// Camera dependencies
#include "QOMX_JpegExtensions.h"
#include "cam_intf.h"
#define MM_JPEG_MAX_PLANES 3
#define MM_JPEG_MAX_BUF CAM_MAX_NUM_BUFS_PER_STREAM
#define QUANT_SIZE 64
#define QTABLE_MAX 2
#define MM_JPEG_MAX_MPO_IMAGES 2
typedef enum {
MM_JPEG_FMT_YUV,
MM_JPEG_FMT_BITSTREAM
} mm_jpeg_format_t;
typedef enum {
MM_JPEG_TYPE_JPEG,
MM_JPEG_TYPE_MPO
} mm_jpeg_image_type_t;
typedef struct {
cam_ae_exif_debug_t ae_debug_params;
cam_awb_exif_debug_t awb_debug_params;
cam_af_exif_debug_t af_debug_params;
cam_asd_exif_debug_t asd_debug_params;
cam_stats_buffer_exif_debug_t stats_debug_params;
uint8_t ae_debug_params_valid;
uint8_t awb_debug_params_valid;
uint8_t af_debug_params_valid;
uint8_t asd_debug_params_valid;
uint8_t stats_debug_params_valid;
} mm_jpeg_debug_exif_params_t;
typedef struct {
cam_3a_params_t cam_3a_params;
uint8_t cam_3a_params_valid;
cam_sensor_params_t sensor_params;
mm_jpeg_debug_exif_params_t *debug_params;
} mm_jpeg_exif_params_t;
typedef struct {
/* Indicates if it is a single jpeg or part of a multi picture sequence*/
mm_jpeg_image_type_t type;
/*Indicates if image is the primary image in a sequence of images.
Applicable only to multi picture formats*/
uint8_t is_primary;
/*Number of images in the sequence*/
uint32_t num_of_images;
} mm_jpeg_multi_image_t;
typedef struct {
uint32_t sequence; /* for jpeg bit streams, assembling is based on sequence. sequence starts from 0 */
uint8_t *buf_vaddr; /* ptr to buf */
int fd; /* fd of buf */
size_t buf_size; /* total size of buf (header + image) */
mm_jpeg_format_t format; /* buffer format*/
cam_frame_len_offset_t offset; /* offset of all the planes */
uint32_t index; /* index used to identify the buffers */
} mm_jpeg_buf_t;
typedef struct {
uint8_t *buf_vaddr; /* ptr to buf */
int fd; /* fd of buf */
size_t buf_filled_len; /* used for output image. filled by the client */
} mm_jpeg_output_t;
typedef enum {
MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V2,
MM_JPEG_COLOR_FORMAT_YCBCRLP_H2V2,
MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V1,
MM_JPEG_COLOR_FORMAT_YCBCRLP_H2V1,
MM_JPEG_COLOR_FORMAT_YCRCBLP_H1V2,
MM_JPEG_COLOR_FORMAT_YCBCRLP_H1V2,
MM_JPEG_COLOR_FORMAT_YCRCBLP_H1V1,
MM_JPEG_COLOR_FORMAT_YCBCRLP_H1V1,
MM_JPEG_COLOR_FORMAT_MONOCHROME,
MM_JPEG_COLOR_FORMAT_BITSTREAM_H2V2,
MM_JPEG_COLOR_FORMAT_BITSTREAM_H2V1,
MM_JPEG_COLOR_FORMAT_BITSTREAM_H1V2,
MM_JPEG_COLOR_FORMAT_BITSTREAM_H1V1,
MM_JPEG_COLOR_FORMAT_MAX
} mm_jpeg_color_format;
typedef enum {
JPEG_JOB_STATUS_DONE = 0,
JPEG_JOB_STATUS_ERROR
} jpeg_job_status_t;
typedef void (*jpeg_encode_callback_t)(jpeg_job_status_t status,
uint32_t client_hdl,
uint32_t jobId,
mm_jpeg_output_t *p_output,
void *userData);
typedef struct {
/* src img dimension */
cam_dimension_t src_dim;
/* jpeg output dimension */
cam_dimension_t dst_dim;
/* crop information */
cam_rect_t crop;
} mm_jpeg_dim_t;
typedef struct {
/* num of buf in src img */
uint32_t num_src_bufs;
/* num of src tmb bufs */
uint32_t num_tmb_bufs;
/* num of buf in src img */
uint32_t num_dst_bufs;
/* should create thumbnail from main image or not */
uint32_t encode_thumbnail;
/* src img bufs */
mm_jpeg_buf_t src_main_buf[MM_JPEG_MAX_BUF];
/* this will be used only for bitstream */
mm_jpeg_buf_t src_thumb_buf[MM_JPEG_MAX_BUF];
/* this will be used only for bitstream */
mm_jpeg_buf_t dest_buf[MM_JPEG_MAX_BUF];
/* mainimage color format */
mm_jpeg_color_format color_format;
/* thumbnail color format */
mm_jpeg_color_format thumb_color_format;
/* jpeg quality: range 0~100 */
uint32_t quality;
/* jpeg thumbnail quality: range 0~100 */
uint32_t thumb_quality;
/* buf to exif entries, caller needs to
* take care of the memory manage with insider ptr */
QOMX_EXIF_INFO exif_info;
/*Callback registered to be called after encode*/
jpeg_encode_callback_t jpeg_cb;
/*Appdata passed by the user*/
void* userdata;
/* thumbnail dimension */
mm_jpeg_dim_t thumb_dim;
/* rotation informaiton */
uint32_t rotation;
/* thumb rotation informaiton */
uint32_t thumb_rotation;
/* main image dimension */
mm_jpeg_dim_t main_dim;
/* enable encoder burst mode */
uint32_t burst_mode;
/* get memory function ptr */
int (*get_memory)( omx_jpeg_ouput_buf_t *p_out_buf);
/* release memory function ptr */
int (*put_memory)( omx_jpeg_ouput_buf_t *p_out_buf);
/* Flag to indicate whether to generate thumbnail from postview */
bool thumb_from_postview;
} mm_jpeg_encode_params_t;
typedef struct {
/* num of buf in src img */
uint32_t num_src_bufs;
/* num of buf in src img */
uint32_t num_dst_bufs;
/* src img bufs */
mm_jpeg_buf_t src_main_buf[MM_JPEG_MAX_BUF];
/* this will be used only for bitstream */
mm_jpeg_buf_t dest_buf[MM_JPEG_MAX_BUF];
/* color format */
mm_jpeg_color_format color_format;
jpeg_encode_callback_t jpeg_cb;
void* userdata;
} mm_jpeg_decode_params_t;
typedef struct {
/* active indices of the buffers for encoding */
int32_t src_index;
int32_t dst_index;
uint32_t thumb_index;
mm_jpeg_dim_t thumb_dim;
/* rotation informaiton */
uint32_t rotation;
/* main image dimension */
mm_jpeg_dim_t main_dim;
/*session id*/
uint32_t session_id;
/* jpeg output buffer ref count */
int32_t ref_count;
/* allocated jpeg output buffer */
void *alloc_out_buffer;
/*Metadata stream*/
metadata_buffer_t *p_metadata;
/*HAL version*/
cam_hal_version_t hal_version;
/* buf to exif entries, caller needs to
* take care of the memory manage with insider ptr */
QOMX_EXIF_INFO exif_info;
/* 3a parameters */
mm_jpeg_exif_params_t cam_exif_params;
/* jpeg encoder QTable */
uint8_t qtable_set[QTABLE_MAX];
OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE qtable[QTABLE_MAX];
/* flag to enable/disable mobicat */
uint8_t mobicat_mask;
/*Info associated with multiple image sequence*/
mm_jpeg_multi_image_t multi_image_info;
/* work buf */
mm_jpeg_buf_t work_buf;
} mm_jpeg_encode_job_t;
typedef struct {
/* active indices of the buffers for encoding */
int32_t src_index;
int32_t dst_index;
uint32_t tmb_dst_index;
/* rotation informaiton */
uint32_t rotation;
/* main image */
mm_jpeg_dim_t main_dim;
/*session id*/
uint32_t session_id;
} mm_jpeg_decode_job_t;
typedef enum {
JPEG_JOB_TYPE_ENCODE,
JPEG_JOB_TYPE_DECODE,
JPEG_JOB_TYPE_MAX
} mm_jpeg_job_type_t;
typedef struct {
mm_jpeg_job_type_t job_type;
union {
mm_jpeg_encode_job_t encode_job;
mm_jpeg_decode_job_t decode_job;
};
} mm_jpeg_job_t;
typedef struct {
uint32_t w;
uint32_t h;
} mm_dimension;
typedef struct {
/*Primary image in the MPO sequence*/
mm_jpeg_output_t primary_image;
/*All auxillary images in the sequence*/
mm_jpeg_output_t aux_images[MM_JPEG_MAX_MPO_IMAGES - 1];
/*Total number of images in the MPO sequence*/
int num_of_images;
/*Output MPO buffer*/
mm_jpeg_output_t output_buff;
/*Size of the allocated output buffer*/
size_t output_buff_size;
} mm_jpeg_mpo_info_t;
typedef struct {
/* config a job -- async call */
int (*start_job)(mm_jpeg_job_t* job, uint32_t* job_id);
/* abort a job -- sync call */
int (*abort_job)(uint32_t job_id);
/* create a session */
int (*create_session)(uint32_t client_hdl,
mm_jpeg_encode_params_t *p_params, uint32_t *p_session_id);
/* destroy session */
int (*destroy_session)(uint32_t session_id);
/* close a jpeg client -- sync call */
int (*close) (uint32_t clientHdl);
} mm_jpeg_ops_t;
typedef struct {
/* config a job -- async call */
int (*start_job)(mm_jpeg_job_t* job, uint32_t* job_id);
/* abort a job -- sync call */
int (*abort_job)(uint32_t job_id);
/* create a session */
int (*create_session)(uint32_t client_hdl,
mm_jpeg_decode_params_t *p_params, uint32_t *p_session_id);
/* destroy session */
int (*destroy_session)(uint32_t session_id);
/* close a jpeg client -- sync call */
int (*close) (uint32_t clientHdl);
} mm_jpegdec_ops_t;
typedef struct {
/* Get Mpo size*/
int (*get_mpo_size)(mm_jpeg_output_t jpeg_buffer[MM_JPEG_MAX_MPO_IMAGES],
int num_of_images);
/* Compose MPO*/
int (*compose_mpo)(mm_jpeg_mpo_info_t *mpo_info);
} mm_jpeg_mpo_ops_t;
/* open a jpeg client -- sync call
* returns client_handle.
* failed if client_handle=0
* jpeg ops tbl and mpo ops tbl will be filled in if open succeeds
* and jpeg meta data will be cached */
uint32_t jpeg_open(mm_jpeg_ops_t *ops, mm_jpeg_mpo_ops_t *mpo_ops,
mm_dimension picture_size,
cam_jpeg_metadata_t *jpeg_metadata);
/* open a jpeg client -- sync call
* returns client_handle.
* failed if client_handle=0
* jpeg ops tbl will be filled in if open succeeds */
uint32_t jpegdec_open(mm_jpegdec_ops_t *ops);
#endif /* MM_JPEG_INTERFACE_H_ */

View file

@ -0,0 +1,64 @@
OLD_LOCAL_PATH := $(LOCAL_PATH)
LOCAL_PATH := $(call my-dir)
include $(LOCAL_PATH)/../../../common.mk
include $(CLEAR_VARS)
MM_CAM_FILES := \
src/mm_camera_interface.c \
src/mm_camera.c \
src/mm_camera_channel.c \
src/mm_camera_stream.c \
src/mm_camera_thread.c \
src/mm_camera_sock.c
# System header file path prefix
LOCAL_CFLAGS += -DSYSTEM_HEADER_PREFIX=sys
ifeq ($(strip $(TARGET_USES_ION)),true)
LOCAL_CFLAGS += -DUSE_ION
endif
ifneq (,$(filter msm8974 msm8916 msm8226 msm8610 msm8916 apq8084 msm8084 msm8994 msm8992 msm8952 msm8937 titanium msm8996,$(TARGET_BOARD_PLATFORM)))
LOCAL_CFLAGS += -DVENUS_PRESENT
endif
ifneq (,$(filter msm8996,$(TARGET_BOARD_PLATFORM)))
LOCAL_CFLAGS += -DUBWC_PRESENT
endif
LOCAL_CFLAGS += -D_ANDROID_ -DQCAMERA_REDEFINE_LOG
LOCAL_COPY_HEADERS_TO := mm-camera-interface
LOCAL_COPY_HEADERS += ../common/cam_intf.h
LOCAL_COPY_HEADERS += ../common/cam_types.h
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/inc \
$(LOCAL_PATH)/../common \
hardware/libhardware/include/hardware \
hardware/qcom/media/mm-core/inc \
system/media/camera/include \
LOCAL_CFLAGS += -DCAMERA_ION_HEAP_ID=ION_IOMMU_HEAP_ID
LOCAL_C_INCLUDES+= $(kernel_includes)
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
ifneq (1,$(filter 1,$(shell echo "$$(( $(PLATFORM_SDK_VERSION) >= 17 ))" )))
LOCAL_CFLAGS += -include bionic/libc/kernel/common/linux/socket.h
LOCAL_CFLAGS += -include bionic/libc/kernel/common/linux/un.h
endif
LOCAL_CFLAGS += -Wall -Wextra -Werror
LOCAL_SRC_FILES := $(MM_CAM_FILES)
LOCAL_MODULE := libmmcamera_interface
LOCAL_CLANG := false
LOCAL_PRELINK_MODULE := false
LOCAL_SHARED_LIBRARIES := libdl libcutils liblog
LOCAL_MODULE_TAGS := optional
LOCAL_32_BIT_ONLY := $(BOARD_QTI_CAMERA_32BIT_ONLY)
include $(BUILD_SHARED_LIBRARY)
LOCAL_PATH := $(OLD_LOCAL_PATH)

View file

@ -0,0 +1,765 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __MM_CAMERA_H__
#define __MM_CAMERA_H__
// System dependencies
#include <poll.h>
// Camera dependencies
#include "camera_common.h"
#include "cam_semaphore.h"
#include "mm_camera_interface.h"
/**********************************************************************************
* Data structure declarations
***********************************************************************************/
/* num of callbacks allowed for an event type */
#define MM_CAMERA_EVT_ENTRY_MAX 4
/* num of data callbacks allowed in a stream obj */
#define MM_CAMERA_STREAM_BUF_CB_MAX 4
/* num of data poll threads allowed in a channel obj */
#define MM_CAMERA_CHANNEL_POLL_THREAD_MAX 1
#define MM_CAMERA_DEV_NAME_LEN 32
#define MM_CAMERA_DEV_OPEN_TRIES 20
#define MM_CAMERA_DEV_OPEN_RETRY_SLEEP 20
#define THREAD_NAME_SIZE 15
/* Future frame idx, large enough to make sure capture
* settings can be applied and small enough to still capture an image */
#define MM_CAMERA_MAX_FUTURE_FRAME_WAIT 100
#define WAIT_TIMEOUT 5
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
struct mm_channel;
struct mm_stream;
struct mm_camera_obj;
typedef int64_t nsecs_t;
typedef enum
{
MM_CAMERA_CMD_TYPE_DATA_CB, /* dataB CMD */
MM_CAMERA_CMD_TYPE_EVT_CB, /* evtCB CMD */
MM_CAMERA_CMD_TYPE_EXIT, /* EXIT */
MM_CAMERA_CMD_TYPE_REQ_DATA_CB,/* request data */
MM_CAMERA_CMD_TYPE_SUPER_BUF_DATA_CB, /* superbuf dataB CMD */
MM_CAMERA_CMD_TYPE_CONFIG_NOTIFY, /* configure notify mode */
MM_CAMERA_CMD_TYPE_START_ZSL, /* start zsl snapshot for channel */
MM_CAMERA_CMD_TYPE_STOP_ZSL, /* stop zsl snapshot for channel */
MM_CAMERA_CMD_TYPE_FLUSH_QUEUE, /* flush queue */
MM_CAMERA_CMD_TYPE_GENERAL, /* general cmd */
MM_CAMERA_CMD_TYPE_MAX
} mm_camera_cmdcb_type_t;
typedef struct {
uint32_t stream_id;
uint32_t frame_idx;
uint32_t flags;
mm_camera_buf_def_t *buf; /* ref to buf */
} mm_camera_buf_info_t;
typedef enum {
MM_CAMERA_GENERIC_CMD_TYPE_AE_BRACKETING,
MM_CAMERA_GENERIC_CMD_TYPE_AF_BRACKETING,
MM_CAMERA_GENERIC_CMD_TYPE_FLASH_BRACKETING,
MM_CAMERA_GENERIC_CMD_TYPE_ZOOM_1X,
MM_CAMERA_GENERIC_CMD_TYPE_CAPTURE_SETTING,
} mm_camera_generic_cmd_type_t;
typedef struct {
mm_camera_generic_cmd_type_t type;
uint32_t payload[32];
union {
cam_capture_frame_config_t frame_config;
};
} mm_camera_generic_cmd_t;
typedef struct {
uint32_t frame_idx;
cam_stream_type_t stream_type;
} mm_camera_flush_cmd_t;
typedef struct {
mm_camera_cmdcb_type_t cmd_type;
union {
mm_camera_buf_info_t buf; /* frame buf if dataCB */
mm_camera_event_t evt; /* evt if evtCB */
mm_camera_super_buf_t superbuf; /* superbuf if superbuf dataCB*/
mm_camera_req_buf_t req_buf; /* num of buf requested */
mm_camera_flush_cmd_t flush_cmd; /* frame idx boundary for flush superbuf queue*/
mm_camera_super_buf_notify_mode_t notify_mode; /* notification mode */
mm_camera_generic_cmd_t gen_cmd;
} u;
} mm_camera_cmdcb_t;
typedef void (*mm_camera_cmd_cb_t)(mm_camera_cmdcb_t * cmd_cb, void* user_data);
typedef struct {
uint8_t is_active; /*indicates whether thread is active or not */
cam_queue_t cmd_queue; /* cmd queue (queuing dataCB, asyncCB, or exitCMD) */
pthread_t cmd_pid; /* cmd thread ID */
cam_semaphore_t cmd_sem; /* semaphore for cmd thread */
cam_semaphore_t sync_sem; /* semaphore for synchronization with cmd thread */
mm_camera_cmd_cb_t cb; /* cb for cmd */
void* user_data; /* user_data for cb */
char threadName[THREAD_NAME_SIZE];
} mm_camera_cmd_thread_t;
typedef enum {
MM_CAMERA_POLL_TYPE_EVT,
MM_CAMERA_POLL_TYPE_DATA,
MM_CAMERA_POLL_TYPE_MAX
} mm_camera_poll_thread_type_t;
/* function ptr defined for poll notify CB,
* registered at poll thread with poll fd */
typedef void (*mm_camera_poll_notify_t)(void *user_data);
typedef struct {
int32_t fd;
mm_camera_poll_notify_t notify_cb;
uint32_t handler;
void* user_data;
} mm_camera_poll_entry_t;
typedef struct {
mm_camera_poll_thread_type_t poll_type;
/* array to store poll fd and cb info
* for MM_CAMERA_POLL_TYPE_EVT, only index 0 is valid;
* for MM_CAMERA_POLL_TYPE_DATA, depends on valid stream fd */
mm_camera_poll_entry_t poll_entries[MAX_STREAM_NUM_IN_BUNDLE];
int32_t pfds[2];
pthread_t pid;
int32_t state;
int timeoutms;
uint32_t cmd;
struct pollfd poll_fds[MAX_STREAM_NUM_IN_BUNDLE + 1];
uint8_t num_fds;
pthread_mutex_t mutex;
pthread_cond_t cond_v;
int32_t status;
char threadName[THREAD_NAME_SIZE];
//void *my_obj;
} mm_camera_poll_thread_t;
/* mm_stream */
typedef enum {
MM_STREAM_STATE_NOTUSED = 0, /* not used */
MM_STREAM_STATE_INITED, /* inited */
MM_STREAM_STATE_ACQUIRED, /* acquired, fd opened */
MM_STREAM_STATE_CFG, /* fmt & dim configured */
MM_STREAM_STATE_BUFFED, /* buf allocated */
MM_STREAM_STATE_REG, /* buf regged, stream off */
MM_STREAM_STATE_ACTIVE, /* active */
MM_STREAM_STATE_MAX
} mm_stream_state_type_t;
typedef enum {
MM_STREAM_EVT_ACQUIRE,
MM_STREAM_EVT_RELEASE,
MM_STREAM_EVT_SET_FMT,
MM_STREAM_EVT_GET_BUF,
MM_STREAM_EVT_PUT_BUF,
MM_STREAM_EVT_REG_BUF,
MM_STREAM_EVT_UNREG_BUF,
MM_STREAM_EVT_START,
MM_STREAM_EVT_STOP,
MM_STREAM_EVT_QBUF,
MM_STREAM_EVT_SET_PARM,
MM_STREAM_EVT_GET_PARM,
MM_STREAM_EVT_DO_ACTION,
MM_STREAM_EVT_GET_QUEUED_BUF_COUNT,
MM_STREAM_EVT_MAX
} mm_stream_evt_type_t;
typedef struct {
mm_camera_buf_notify_t cb;
void *user_data;
/* cb_count = -1: infinite
* cb_count > 0: register only for required times */
int8_t cb_count;
mm_camera_stream_cb_type cb_type;
} mm_stream_data_cb_t;
typedef struct {
/* buf reference count */
uint8_t buf_refcnt;
/* This flag is to indicate if after allocation,
* the corresponding buf needs to qbuf into kernel
* (e.g. for preview usecase, display needs to hold two bufs,
* so no need to qbuf these two bufs initially) */
uint8_t initial_reg_flag;
/* indicate if buf is in kernel(1) or client(0) */
uint8_t in_kernel;
/*indicate if this buffer is mapped to daemon*/
int8_t map_status;
} mm_stream_buf_status_t;
typedef struct mm_stream {
uint32_t my_hdl; /* local stream id */
uint32_t server_stream_id; /* stream id from server */
int32_t fd;
mm_stream_state_type_t state;
/* stream info*/
cam_stream_info_t *stream_info;
/* padding info */
cam_padding_info_t padding_info;
/* offset */
cam_frame_len_offset_t frame_offset;
pthread_mutex_t cmd_lock; /* lock to protect cmd_thread */
mm_camera_cmd_thread_t cmd_thread;
/* dataCB registered on this stream obj */
pthread_mutex_t cb_lock; /* cb lock to protect buf_cb */
mm_stream_data_cb_t buf_cb[MM_CAMERA_STREAM_BUF_CB_MAX];
/* stream buffer management */
pthread_mutex_t buf_lock;
uint8_t buf_num; /* num of buffers allocated */
mm_camera_buf_def_t* buf; /* ptr to buf array */
mm_stream_buf_status_t buf_status[CAM_MAX_NUM_BUFS_PER_STREAM]; /* ptr to buf status array */
uint8_t plane_buf_num; /* num of plane buffers allocated Used only in Batch mode*/
mm_camera_buf_def_t *plane_buf; /*Pointer to plane buffer array Used only in Batch mode */
int32_t cur_buf_idx; /* Current container buffer active filling. Used only in Batch mode*/
uint8_t cur_bufs_staged; /*Number of plane buf freed by HAL for this usr buf*/
/* reference to parent channel_obj */
struct mm_channel* ch_obj;
uint8_t is_bundled; /* flag if stream is bundled */
/* reference to linked channel_obj */
struct mm_channel* linked_obj;
struct mm_stream * linked_stream; /* original stream */
uint8_t is_linked; /* flag if stream is linked */
mm_camera_stream_mem_vtbl_t mem_vtbl; /* mem ops tbl */
mm_camera_map_unmap_ops_tbl_t map_ops;
int8_t queued_buffer_count;
/*latest timestamp of this stream frame received & last frameID*/
uint32_t prev_frameID;
nsecs_t prev_timestamp;
/* Need to wait for buffer mapping before stream-on*/
pthread_cond_t buf_cond;
} mm_stream_t;
/* mm_channel */
typedef enum {
MM_CHANNEL_STATE_NOTUSED = 0, /* not used */
MM_CHANNEL_STATE_STOPPED, /* stopped */
MM_CHANNEL_STATE_ACTIVE, /* active, at least one stream active */
MM_CHANNEL_STATE_PAUSED, /* paused */
MM_CHANNEL_STATE_MAX
} mm_channel_state_type_t;
typedef enum {
MM_CHANNEL_EVT_ADD_STREAM,
MM_CHANNEL_EVT_DEL_STREAM,
MM_CHANNEL_EVT_LINK_STREAM,
MM_CHANNEL_EVT_CONFIG_STREAM,
MM_CHANNEL_EVT_GET_BUNDLE_INFO,
MM_CHANNEL_EVT_START,
MM_CHANNEL_EVT_STOP,
MM_CHANNEL_EVT_PAUSE,
MM_CHANNEL_EVT_RESUME,
MM_CHANNEL_EVT_REQUEST_SUPER_BUF,
MM_CHANNEL_EVT_CANCEL_REQUEST_SUPER_BUF,
MM_CHANNEL_EVT_FLUSH_SUPER_BUF_QUEUE,
MM_CHANNEL_EVT_CONFIG_NOTIFY_MODE,
MM_CHANNEL_EVT_START_ZSL_SNAPSHOT,
MM_CHANNEL_EVT_STOP_ZSL_SNAPSHOT,
MM_CHANNEL_EVT_MAP_STREAM_BUF,
MM_CHANNEL_EVT_UNMAP_STREAM_BUF,
MM_CHANNEL_EVT_SET_STREAM_PARM,
MM_CHANNEL_EVT_GET_STREAM_PARM,
MM_CHANNEL_EVT_DO_STREAM_ACTION,
MM_CHANNEL_EVT_DELETE,
MM_CHANNEL_EVT_AF_BRACKETING,
MM_CHANNEL_EVT_AE_BRACKETING,
MM_CHANNEL_EVT_FLASH_BRACKETING,
MM_CHANNEL_EVT_ZOOM_1X,
MM_CAMERA_EVT_CAPTURE_SETTING,
MM_CHANNEL_EVT_GET_STREAM_QUEUED_BUF_COUNT,
MM_CHANNEL_EVT_MAP_STREAM_BUFS,
MM_CHANNEL_EVT_REG_STREAM_BUF_CB
} mm_channel_evt_type_t;
typedef struct {
uint32_t stream_id;
mm_camera_stream_config_t *config;
} mm_evt_paylod_config_stream_t;
typedef struct {
uint32_t stream_id;
cam_stream_parm_buffer_t *parms;
} mm_evt_paylod_set_get_stream_parms_t;
typedef struct {
uint32_t stream_id;
void *actions;
} mm_evt_paylod_do_stream_action_t;
typedef struct {
uint32_t stream_id;
mm_stream_data_cb_t buf_cb;
} mm_evt_paylod_reg_stream_buf_cb;
typedef struct {
uint8_t num_of_bufs;
mm_camera_buf_info_t super_buf[MAX_STREAM_NUM_IN_BUNDLE];
uint8_t matched;
uint8_t expected;
uint32_t frame_idx;
} mm_channel_queue_node_t;
typedef struct {
cam_queue_t que;
uint8_t num_streams;
/* container for bundled stream handlers */
uint32_t bundled_streams[MAX_STREAM_NUM_IN_BUNDLE];
mm_camera_channel_attr_t attr;
uint32_t expected_frame_id;
uint32_t match_cnt;
uint32_t expected_frame_id_without_led;
uint32_t led_on_start_frame_id;
uint32_t led_off_start_frame_id;
uint32_t led_on_num_frames;
uint32_t once;
uint32_t frame_skip_count;
uint32_t nomatch_frame_id;
} mm_channel_queue_t;
typedef struct {
uint8_t is_active; /* flag to indicate if bundle is valid */
/* queue to store bundled super buffers */
mm_channel_queue_t superbuf_queue;
mm_camera_buf_notify_t super_buf_notify_cb;
void *user_data;
} mm_channel_bundle_t;
/* Nodes used for frame sync */
typedef struct {
/* Frame idx */
uint32_t frame_idx;
/* Frame present for corresponding channel*/
uint32_t frame_valid[MAX_NUM_CAMERA_PER_BUNDLE];
/* Frame present in all channels*/
uint32_t matched;
} mm_channel_sync_node_t;
/* Frame sync information */
typedef struct {
/* Number of camera channels that need to be synced*/
uint8_t num_cam;
/* position of the next node to be updated */
uint8_t pos;
/* circular node array used to store frame information */
mm_channel_sync_node_t node[MM_CAMERA_FRAME_SYNC_NODES];
/* Channel corresponding to each camera */
struct mm_channel *ch_obj[MAX_NUM_CAMERA_PER_BUNDLE];
/* Cb corresponding to each camera */
mm_camera_buf_notify_t cb[MAX_NUM_CAMERA_PER_BUNDLE];
} mm_channel_frame_sync_info_t;
/* Node information for multiple superbuf callbacks
* This can be used to batch nodes before sending to upper layer */
typedef struct {
/* Number of nodes to be sent*/
uint8_t num_nodes;
/* queue node information*/
mm_channel_queue_node_t *node[MAX_NUM_CAMERA_PER_BUNDLE];
/* channel information*/
struct mm_channel *ch_obj[MAX_NUM_CAMERA_PER_BUNDLE];
} mm_channel_node_info_t;
typedef enum {
MM_CHANNEL_BRACKETING_STATE_OFF,
MM_CHANNEL_BRACKETING_STATE_WAIT_GOOD_FRAME_IDX,
MM_CHANNEL_BRACKETING_STATE_ACTIVE,
} mm_channel_bracketing_state_t;
typedef struct mm_channel {
uint32_t my_hdl;
mm_channel_state_type_t state;
pthread_mutex_t ch_lock; /* channel lock */
/* stream bundle info in the channel */
mm_channel_bundle_t bundle;
/* num of pending suferbuffers */
uint32_t pending_cnt;
uint32_t pending_retro_cnt;
mm_camera_req_buf_type_t req_type;
uint32_t bWaitForPrepSnapshotDone;
uint32_t unLockAEC;
/* num of pending suferbuffers */
uint8_t stopZslSnapshot;
/* cmd thread for superbuffer dataCB and async stop*/
mm_camera_cmd_thread_t cmd_thread;
/* cb thread for sending data cb */
mm_camera_cmd_thread_t cb_thread;
/* data poll thread
* currently one data poll thread per channel
* could extended to support one data poll thread per stream in the channel */
mm_camera_poll_thread_t poll_thread[MM_CAMERA_CHANNEL_POLL_THREAD_MAX];
/* container for all streams in channel */
mm_stream_t streams[MAX_STREAM_NUM_IN_BUNDLE];
/* reference to parent cam_obj */
struct mm_camera_obj* cam_obj;
/* manual zsl snapshot control */
uint8_t manualZSLSnapshot;
/* control for zsl led */
uint8_t startZSlSnapshotCalled;
uint8_t needLEDFlash;
mm_channel_bracketing_state_t bracketingState;
uint8_t isFlashBracketingEnabled;
uint8_t isZoom1xFrameRequested;
uint32_t burstSnapNum;
char threadName[THREAD_NAME_SIZE];
/*Buffer diverted*/
uint8_t diverted_frame_id;
uint32_t sessionid;
/*Frame capture configaration*/
uint8_t isConfigCapture;
uint8_t cur_capture_idx;
uint32_t capture_frame_id[MAX_CAPTURE_BATCH_NUM];
cam_capture_frame_config_t frameConfig;
uint8_t needLowLightZSL;
} mm_channel_t;
typedef struct {
mm_channel_t *ch;
uint32_t stream_id;
} mm_camera_stream_link_t;
/* struct to store information about pp cookie*/
typedef struct {
uint32_t cam_hdl;
uint32_t ch_hdl;
uint32_t stream_hdl;
mm_channel_queue_node_t* super_buf;
} mm_channel_pp_info_t;
/* mm_camera */
typedef struct {
mm_camera_event_notify_t evt_cb;
void *user_data;
} mm_camera_evt_entry_t;
typedef struct {
mm_camera_evt_entry_t evt[MM_CAMERA_EVT_ENTRY_MAX];
/* reg_count <=0: infinite
* reg_count > 0: register only for required times */
int reg_count;
} mm_camera_evt_obj_t;
typedef struct mm_camera_obj {
uint32_t my_hdl;
int ref_count;
int32_t ctrl_fd;
int32_t ds_fd; /* domain socket fd */
pthread_mutex_t cam_lock;
pthread_mutex_t cb_lock; /* lock for evt cb */
mm_channel_t ch[MM_CAMERA_CHANNEL_MAX];
mm_camera_evt_obj_t evt;
mm_camera_poll_thread_t evt_poll_thread; /* evt poll thread */
mm_camera_cmd_thread_t evt_thread; /* thread for evt CB */
mm_camera_vtbl_t vtbl;
pthread_mutex_t evt_lock;
pthread_cond_t evt_cond;
mm_camera_event_t evt_rcvd;
pthread_mutex_t msg_lock; /* lock for sending msg through socket */
uint32_t sessionid; /* Camera server session id */
} mm_camera_obj_t;
typedef struct {
int8_t num_cam;
char video_dev_name[MM_CAMERA_MAX_NUM_SENSORS][MM_CAMERA_DEV_NAME_LEN];
mm_camera_obj_t *cam_obj[MM_CAMERA_MAX_NUM_SENSORS];
struct camera_info info[MM_CAMERA_MAX_NUM_SENSORS];
cam_sync_type_t cam_type[MM_CAMERA_MAX_NUM_SENSORS];
cam_sync_mode_t cam_mode[MM_CAMERA_MAX_NUM_SENSORS];
uint8_t is_yuv[MM_CAMERA_MAX_NUM_SENSORS]; // 1=CAM_SENSOR_YUV, 0=CAM_SENSOR_RAW
} mm_camera_ctrl_t;
typedef enum {
mm_camera_async_call,
mm_camera_sync_call
} mm_camera_call_type_t;
/**********************************************************************************
* external function declare
***********************************************************************************/
/* utility functions */
/* set int32_t value */
extern int32_t mm_camera_util_s_ctrl(int32_t fd,
uint32_t id,
int32_t *value);
/* get int32_t value */
extern int32_t mm_camera_util_g_ctrl(int32_t fd,
uint32_t id,
int32_t *value);
/* send msg throught domain socket for fd mapping */
extern int32_t mm_camera_util_sendmsg(mm_camera_obj_t *my_obj,
void *msg,
size_t buf_size,
int sendfd);
/* send msg through domain socket for bundled fd mapping */
extern int32_t mm_camera_util_bundled_sendmsg(mm_camera_obj_t *my_obj,
void *msg,
size_t buf_size,
int sendfds[CAM_MAX_NUM_BUFS_PER_STREAM],
int numfds);
/* Check if hardware target is A family */
uint8_t mm_camera_util_chip_is_a_family(void);
/* mm-camera */
extern int32_t mm_camera_open(mm_camera_obj_t *my_obj);
extern int32_t mm_camera_close(mm_camera_obj_t *my_obj);
extern int32_t mm_camera_register_event_notify(mm_camera_obj_t *my_obj,
mm_camera_event_notify_t evt_cb,
void * user_data);
extern int32_t mm_camera_qbuf(mm_camera_obj_t *my_obj,
uint32_t ch_id,
mm_camera_buf_def_t *buf);
extern int32_t mm_camera_get_queued_buf_count(mm_camera_obj_t *my_obj,
uint32_t ch_id, uint32_t stream_id);
extern int32_t mm_camera_query_capability(mm_camera_obj_t *my_obj);
extern int32_t mm_camera_set_parms(mm_camera_obj_t *my_obj,
parm_buffer_t *parms);
extern int32_t mm_camera_get_parms(mm_camera_obj_t *my_obj,
parm_buffer_t *parms);
extern int32_t mm_camera_map_buf(mm_camera_obj_t *my_obj,
uint8_t buf_type,
int fd,
size_t size);
extern int32_t mm_camera_map_bufs(mm_camera_obj_t *my_obj,
const cam_buf_map_type_list *buf_map_list);
extern int32_t mm_camera_unmap_buf(mm_camera_obj_t *my_obj,
uint8_t buf_type);
extern int32_t mm_camera_do_auto_focus(mm_camera_obj_t *my_obj);
extern int32_t mm_camera_cancel_auto_focus(mm_camera_obj_t *my_obj);
extern int32_t mm_camera_prepare_snapshot(mm_camera_obj_t *my_obj,
int32_t do_af_flag);
extern int32_t mm_camera_start_zsl_snapshot(mm_camera_obj_t *my_obj);
extern int32_t mm_camera_stop_zsl_snapshot(mm_camera_obj_t *my_obj);
extern int32_t mm_camera_flush(mm_camera_obj_t *my_obj);
extern int32_t mm_camera_start_zsl_snapshot_ch(mm_camera_obj_t *my_obj,
uint32_t ch_id);
extern int32_t mm_camera_stop_zsl_snapshot_ch(mm_camera_obj_t *my_obj,
uint32_t ch_id);
extern uint32_t mm_camera_add_channel(mm_camera_obj_t *my_obj,
mm_camera_channel_attr_t *attr,
mm_camera_buf_notify_t channel_cb,
void *userdata);
extern int32_t mm_camera_del_channel(mm_camera_obj_t *my_obj,
uint32_t ch_id);
extern int32_t mm_camera_get_bundle_info(mm_camera_obj_t *my_obj,
uint32_t ch_id,
cam_bundle_config_t *bundle_info);
extern uint32_t mm_camera_add_stream(mm_camera_obj_t *my_obj,
uint32_t ch_id);
extern int32_t mm_camera_del_stream(mm_camera_obj_t *my_obj,
uint32_t ch_id,
uint32_t stream_id);
extern uint32_t mm_camera_link_stream(mm_camera_obj_t *my_obj,
uint32_t ch_id,
uint32_t stream_id,
uint32_t linked_ch_id);
extern int32_t mm_camera_reg_stream_buf_cb(mm_camera_obj_t *my_obj,
uint32_t ch_id, uint32_t stream_id, mm_camera_buf_notify_t buf_cb,
mm_camera_stream_cb_type cb_type, void *userdata);
extern int32_t mm_camera_config_stream(mm_camera_obj_t *my_obj,
uint32_t ch_id,
uint32_t stream_id,
mm_camera_stream_config_t *config);
extern int32_t mm_camera_start_channel(mm_camera_obj_t *my_obj,
uint32_t ch_id);
extern int32_t mm_camera_stop_channel(mm_camera_obj_t *my_obj,
uint32_t ch_id);
extern int32_t mm_camera_request_super_buf(mm_camera_obj_t *my_obj,
uint32_t ch_id, mm_camera_req_buf_t *buf);
extern int32_t mm_camera_cancel_super_buf_request(mm_camera_obj_t *my_obj,
uint32_t ch_id);
extern int32_t mm_camera_flush_super_buf_queue(mm_camera_obj_t *my_obj,
uint32_t ch_id,
uint32_t frame_idx);
extern int32_t mm_camera_config_channel_notify(mm_camera_obj_t *my_obj,
uint32_t ch_id,
mm_camera_super_buf_notify_mode_t notify_mode);
extern int32_t mm_camera_set_stream_parms(mm_camera_obj_t *my_obj,
uint32_t ch_id,
uint32_t s_id,
cam_stream_parm_buffer_t *parms);
extern int32_t mm_camera_get_stream_parms(mm_camera_obj_t *my_obj,
uint32_t ch_id,
uint32_t s_id,
cam_stream_parm_buffer_t *parms);
extern int32_t mm_camera_register_event_notify_internal(mm_camera_obj_t *my_obj,
mm_camera_event_notify_t evt_cb,
void * user_data);
extern int32_t mm_camera_map_stream_buf(mm_camera_obj_t *my_obj,
uint32_t ch_id,
uint32_t stream_id,
uint8_t buf_type,
uint32_t buf_idx,
int32_t plane_idx,
int fd,
size_t size);
extern int32_t mm_camera_map_stream_bufs(mm_camera_obj_t *my_obj,
uint32_t ch_id,
const cam_buf_map_type_list *buf_map_list);
extern int32_t mm_camera_unmap_stream_buf(mm_camera_obj_t *my_obj,
uint32_t ch_id,
uint32_t stream_id,
uint8_t buf_type,
uint32_t buf_idx,
int32_t plane_idx);
extern int32_t mm_camera_do_stream_action(mm_camera_obj_t *my_obj,
uint32_t ch_id,
uint32_t stream_id,
void *actions);
extern int32_t mm_camera_get_session_id(mm_camera_obj_t *my_obj,
uint32_t* sessionid);
extern int32_t mm_camera_sync_related_sensors(mm_camera_obj_t *my_obj,
cam_sync_related_sensors_event_info_t *parms);
/* mm_channel */
extern int32_t mm_channel_fsm_fn(mm_channel_t *my_obj,
mm_channel_evt_type_t evt,
void * in_val,
void * out_val);
extern int32_t mm_channel_init(mm_channel_t *my_obj,
mm_camera_channel_attr_t *attr,
mm_camera_buf_notify_t channel_cb,
void *userdata);
/* qbuf is a special case that not going through state machine.
* This is to avoid deadlock when trying to aquire ch_lock,
* from the context of dataCB, but async stop is holding ch_lock */
extern int32_t mm_channel_qbuf(mm_channel_t *my_obj,
mm_camera_buf_def_t *buf);
/* mm_stream */
extern int32_t mm_stream_fsm_fn(mm_stream_t *my_obj,
mm_stream_evt_type_t evt,
void * in_val,
void * out_val);
/* Function to register special callback for stream buffer*/
extern int32_t mm_stream_reg_buf_cb(mm_stream_t *my_obj,
mm_stream_data_cb_t val);
extern int32_t mm_stream_map_buf(mm_stream_t *my_obj,
uint8_t buf_type,
uint32_t frame_idx,
int32_t plane_idx,
int fd,
size_t size);
extern int32_t mm_stream_map_bufs(mm_stream_t *my_obj,
const cam_buf_map_type_list *buf_map_list);
extern int32_t mm_stream_unmap_buf(mm_stream_t *my_obj,
uint8_t buf_type,
uint32_t frame_idx,
int32_t plane_idx);
/* utiltity fucntion declared in mm-camera-inteface2.c
* and need be used by mm-camera and below*/
uint32_t mm_camera_util_generate_handler(uint8_t index);
const char * mm_camera_util_get_dev_name(uint32_t cam_handler);
uint8_t mm_camera_util_get_index_by_handler(uint32_t handler);
/* poll/cmd thread functions */
extern int32_t mm_camera_poll_thread_launch(
mm_camera_poll_thread_t * poll_cb,
mm_camera_poll_thread_type_t poll_type);
extern int32_t mm_camera_poll_thread_release(mm_camera_poll_thread_t *poll_cb);
extern int32_t mm_camera_poll_thread_add_poll_fd(
mm_camera_poll_thread_t * poll_cb,
uint32_t handler,
int32_t fd,
mm_camera_poll_notify_t nofity_cb,
void *userdata,
mm_camera_call_type_t);
extern int32_t mm_camera_poll_thread_del_poll_fd(
mm_camera_poll_thread_t * poll_cb,
uint32_t handler,
mm_camera_call_type_t);
extern int32_t mm_camera_poll_thread_commit_updates(
mm_camera_poll_thread_t * poll_cb);
extern int32_t mm_camera_cmd_thread_launch(
mm_camera_cmd_thread_t * cmd_thread,
mm_camera_cmd_cb_t cb,
void* user_data);
extern int32_t mm_camera_cmd_thread_name(const char* name);
extern int32_t mm_camera_cmd_thread_release(mm_camera_cmd_thread_t * cmd_thread);
extern int32_t mm_camera_channel_advanced_capture(mm_camera_obj_t *my_obj,
uint32_t ch_id, mm_camera_advanced_capture_t type,
uint32_t trigger, void *in_value);
#endif /* __MM_CAMERA_H__ */

View file

@ -0,0 +1,122 @@
/* Copyright (c) 2012, 2014, 2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __MM_CAMERA_DBG_H__
#define __MM_CAMERA_DBG_H__
// System dependencies
#include <utils/Log.h>
#ifdef QCAMERA_REDEFINE_LOG
// Camera dependencies
#include "cam_types.h"
typedef enum {
CAM_NO_MODULE,
CAM_HAL_MODULE,
CAM_MCI_MODULE,
CAM_JPEG_MODULE,
CAM_LAST_MODULE
} cam_modules_t;
extern int g_cam_log[CAM_LAST_MODULE][CAM_GLBL_DBG_INFO + 1];
#define FATAL_IF(cond, ...) LOG_ALWAYS_FATAL_IF(cond, ## __VA_ARGS__)
#undef CLOGx
#define CLOGx(module, level, fmt, args...) \
{\
if (g_cam_log[module][level]) { \
mm_camera_debug_log(module, level, __func__, __LINE__, fmt, ##args); \
}\
}
#undef CLOGI
#define CLOGI(module, fmt, args...) \
CLOGx(module, CAM_GLBL_DBG_INFO, fmt, ##args)
#undef CLOGD
#define CLOGD(module, fmt, args...) \
CLOGx(module, CAM_GLBL_DBG_DEBUG, fmt, ##args)
#undef CLOGL
#define CLOGL(module, fmt, args...) \
CLOGx(module, CAM_GLBL_DBG_LOW, fmt, ##args)
#undef CLOGW
#define CLOGW(module, fmt, args...) \
CLOGx(module, CAM_GLBL_DBG_WARN, fmt, ##args)
#undef CLOGH
#define CLOGH(module, fmt, args...) \
CLOGx(module, CAM_GLBL_DBG_HIGH, fmt, ##args)
#undef CLOGE
#define CLOGE(module, fmt, args...) \
CLOGx(module, CAM_GLBL_DBG_ERR, fmt, ##args)
#ifndef CAM_MODULE
#define CAM_MODULE CAM_MCI_MODULE
#endif
#undef LOGD
#define LOGD(fmt, args...) CLOGD(CAM_MODULE, fmt, ##args)
#undef LOGL
#define LOGL(fmt, args...) CLOGL(CAM_MODULE, fmt, ##args)
#undef LOGW
#define LOGW(fmt, args...) CLOGW(CAM_MODULE, fmt, ##args)
#undef LOGH
#define LOGH(fmt, args...) CLOGH(CAM_MODULE, fmt, ##args)
#undef LOGE
#define LOGE(fmt, args...) CLOGE(CAM_MODULE, fmt, ##args)
#undef LOGI
#define LOGI(fmt, args...) CLOGI(CAM_MODULE, fmt, ##args)
/* reads and updates camera logging properties */
void mm_camera_set_dbg_log_properties(void);
/* generic logger function */
void mm_camera_debug_log(const cam_modules_t module,
const cam_global_debug_level_t level,
const char *func, const int line, const char *fmt, ...);
#else
#undef LOGD
#define LOGD(fmt, args...) ALOGD(fmt, ##args)
#undef LOGL
#define LOGL(fmt, args...) ALOGD(fmt, ##args)
#undef LOGW
#define LOGW(fmt, args...) ALOGW(fmt, ##args)
#undef LOGH
#define LOGH(fmt, args...) ALOGD(fmt, ##args)
#undef LOGE
#define LOGE(fmt, args...) ALOGE(fmt, ##args)
#undef LOGI
#define LOGI(fmt, args...) ALOGV(fmt, ##args)
#endif
#endif /* __MM_CAMERA_DBG_H__ */

View file

@ -0,0 +1,76 @@
/* Copyright (c) 2012-2014, 2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __MM_CAMERA_SOCKET_H__
#define __MM_CAMERA_SOCKET_H__
// System dependencies
#define SOCKET_H <SYSTEM_HEADER_PREFIX/socket.h>
#include SOCKET_H
#define UN_H <SYSTEM_HEADER_PREFIX/un.h>
#include UN_H
// Camera dependencies
#include "cam_types.h"
typedef enum {
MM_CAMERA_SOCK_TYPE_UDP,
MM_CAMERA_SOCK_TYPE_TCP,
} mm_camera_sock_type_t;
typedef union {
struct sockaddr addr;
struct sockaddr_un addr_un;
} mm_camera_sock_addr_t;
int mm_camera_socket_create(int cam_id, mm_camera_sock_type_t sock_type);
int mm_camera_socket_sendmsg(
int fd,
void *msg,
size_t buf_size,
int sendfd);
int mm_camera_socket_bundle_sendmsg(
int fd,
void *msg,
size_t buf_size,
int sendfds[CAM_MAX_NUM_BUFS_PER_STREAM],
int num_fds);
int mm_camera_socket_recvmsg(
int fd,
void *msg,
uint32_t buf_size,
int *rcvdfd);
void mm_camera_socket_close(int fd);
#endif /*__MM_CAMERA_SOCKET_H__*/

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,294 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
// System dependencies
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
// Camera dependencies
#include "mm_camera_dbg.h"
#include "mm_camera_sock.h"
/*===========================================================================
* FUNCTION : mm_camera_socket_create
*
* DESCRIPTION: opens a domain socket tied to camera ID and socket type
* @cam_id : camera ID
* @sock_type: socket type, TCP/UDP
*
* RETURN : fd related to the domain socket
*==========================================================================*/
int mm_camera_socket_create(int cam_id, mm_camera_sock_type_t sock_type)
{
int socket_fd;
mm_camera_sock_addr_t sock_addr;
int sktype;
int rc;
switch (sock_type)
{
case MM_CAMERA_SOCK_TYPE_UDP:
sktype = SOCK_DGRAM;
break;
case MM_CAMERA_SOCK_TYPE_TCP:
sktype = SOCK_STREAM;
break;
default:
LOGE("unknown socket type =%d", sock_type);
return -1;
}
socket_fd = socket(AF_UNIX, sktype, 0);
if (socket_fd < 0) {
LOGE("error create socket fd =%d", socket_fd);
return socket_fd;
}
memset(&sock_addr, 0, sizeof(sock_addr));
sock_addr.addr_un.sun_family = AF_UNIX;
snprintf(sock_addr.addr_un.sun_path,
UNIX_PATH_MAX, QCAMERA_DUMP_FRM_LOCATION"cam_socket%d", cam_id);
rc = connect(socket_fd, &sock_addr.addr, sizeof(sock_addr.addr_un));
if (0 != rc) {
close(socket_fd);
socket_fd = -1;
LOGE("socket_fd=%d %s ", socket_fd, strerror(errno));
}
LOGD("socket_fd=%d %s", socket_fd,
sock_addr.addr_un.sun_path);
return socket_fd;
}
/*===========================================================================
* FUNCTION : mm_camera_socket_close
*
* DESCRIPTION: close domain socket by its fd
* @fd : file descriptor for the domain socket to be closed
*
* RETURN : none
*==========================================================================*/
void mm_camera_socket_close(int fd)
{
if (fd >= 0) {
close(fd);
}
}
/*===========================================================================
* FUNCTION : mm_camera_socket_sendmsg
*
* DESCRIPTION: send msg through domain socket
* @fd : socket fd
* @msg : pointer to msg to be sent over domain socket
* @sendfd : file descriptors to be sent
*
* RETURN : the total bytes of sent msg
*==========================================================================*/
int mm_camera_socket_sendmsg(
int fd,
void *msg,
size_t buf_size,
int sendfd)
{
struct msghdr msgh;
struct iovec iov[1];
struct cmsghdr * cmsghp = NULL;
char control[CMSG_SPACE(sizeof(int))];
if (msg == NULL) {
LOGD("msg is NULL");
return -1;
}
memset(&msgh, 0, sizeof(msgh));
msgh.msg_name = NULL;
msgh.msg_namelen = 0;
iov[0].iov_base = msg;
iov[0].iov_len = buf_size;
msgh.msg_iov = iov;
msgh.msg_iovlen = 1;
LOGD("iov_len=%llu",
(unsigned long long int)iov[0].iov_len);
msgh.msg_control = NULL;
msgh.msg_controllen = 0;
/* if sendfd is valid, we need to pass it through control msg */
if( sendfd >= 0) {
msgh.msg_control = control;
msgh.msg_controllen = sizeof(control);
cmsghp = CMSG_FIRSTHDR(&msgh);
if (cmsghp != NULL) {
LOGD("Got ctrl msg pointer");
cmsghp->cmsg_level = SOL_SOCKET;
cmsghp->cmsg_type = SCM_RIGHTS;
cmsghp->cmsg_len = CMSG_LEN(sizeof(int));
*((int *)CMSG_DATA(cmsghp)) = sendfd;
LOGD("cmsg data=%d", *((int *) CMSG_DATA(cmsghp)));
} else {
LOGD("ctrl msg NULL");
return -1;
}
}
return sendmsg(fd, &(msgh), 0);
}
/*===========================================================================
* FUNCTION : mm_camera_socket_bundle_sendmsg
*
* DESCRIPTION: send msg through domain socket
* @fd : socket fd
* @msg : pointer to msg to be sent over domain socket
* @sendfds : file descriptors to be sent
* @numfds : num of file descriptors to be sent
*
* RETURN : the total bytes of sent msg
*==========================================================================*/
int mm_camera_socket_bundle_sendmsg(
int fd,
void *msg,
size_t buf_size,
int sendfds[CAM_MAX_NUM_BUFS_PER_STREAM],
int numfds)
{
struct msghdr msgh;
struct iovec iov[1];
struct cmsghdr * cmsghp = NULL;
char control[CMSG_SPACE(sizeof(int) * numfds)];
int *fds_ptr = NULL;
if (msg == NULL) {
LOGD("msg is NULL");
return -1;
}
memset(&msgh, 0, sizeof(msgh));
msgh.msg_name = NULL;
msgh.msg_namelen = 0;
iov[0].iov_base = msg;
iov[0].iov_len = buf_size;
msgh.msg_iov = iov;
msgh.msg_iovlen = 1;
LOGD("iov_len=%llu",
(unsigned long long int)iov[0].iov_len);
msgh.msg_control = NULL;
msgh.msg_controllen = 0;
/* if numfds is valid, we need to pass it through control msg */
if (numfds > 0) {
msgh.msg_control = control;
msgh.msg_controllen = sizeof(control);
cmsghp = CMSG_FIRSTHDR(&msgh);
if (cmsghp != NULL) {
cmsghp->cmsg_level = SOL_SOCKET;
cmsghp->cmsg_type = SCM_RIGHTS;
cmsghp->cmsg_len = CMSG_LEN(sizeof(int) * numfds);
fds_ptr = (int*) CMSG_DATA(cmsghp);
memcpy(fds_ptr, sendfds, sizeof(int) * numfds);
} else {
LOGE("ctrl msg NULL");
return -1;
}
}
return sendmsg(fd, &(msgh), 0);
}
/*===========================================================================
* FUNCTION : mm_camera_socket_recvmsg
*
* DESCRIPTION: receive msg from domain socket.
* @fd : socket fd
* @msg : pointer to mm_camera_sock_msg_packet_t to hold incoming msg,
* need be allocated by the caller
* @buf_size: the size of the buf that holds incoming msg
* @rcvdfd : pointer to hold recvd file descriptor if not NULL.
*
* RETURN : the total bytes of received msg
*==========================================================================*/
int mm_camera_socket_recvmsg(
int fd,
void *msg,
uint32_t buf_size,
int *rcvdfd)
{
struct msghdr msgh;
struct iovec iov[1];
struct cmsghdr *cmsghp = NULL;
char control[CMSG_SPACE(sizeof(int))];
int rcvd_fd = -1;
int rcvd_len = 0;
if ( (msg == NULL) || (buf_size <= 0) ) {
LOGE("msg buf is NULL");
return -1;
}
memset(&msgh, 0, sizeof(msgh));
msgh.msg_name = NULL;
msgh.msg_namelen = 0;
msgh.msg_control = control;
msgh.msg_controllen = sizeof(control);
iov[0].iov_base = msg;
iov[0].iov_len = buf_size;
msgh.msg_iov = iov;
msgh.msg_iovlen = 1;
if ( (rcvd_len = recvmsg(fd, &(msgh), 0)) <= 0) {
LOGE("recvmsg failed");
return rcvd_len;
}
LOGD("msg_ctrl %p len %zd", msgh.msg_control,
msgh.msg_controllen);
if( ((cmsghp = CMSG_FIRSTHDR(&msgh)) != NULL) &&
(cmsghp->cmsg_len == CMSG_LEN(sizeof(int))) ) {
if (cmsghp->cmsg_level == SOL_SOCKET &&
cmsghp->cmsg_type == SCM_RIGHTS) {
LOGD("CtrlMsg is valid");
rcvd_fd = *((int *) CMSG_DATA(cmsghp));
LOGD("Receieved fd=%d", rcvd_fd);
} else {
LOGE("Unexpected Control Msg. Line=%d");
}
}
if (rcvdfd) {
*rcvdfd = rcvd_fd;
}
return rcvd_len;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,695 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <pthread.h>
#include <errno.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/prctl.h>
#include <fcntl.h>
#include <poll.h>
#include <cam_semaphore.h>
#include "mm_camera_dbg.h"
#include "mm_camera_interface.h"
#include "mm_camera.h"
typedef enum {
/* poll entries updated */
MM_CAMERA_PIPE_CMD_POLL_ENTRIES_UPDATED,
/* poll entries updated asynchronous */
MM_CAMERA_PIPE_CMD_POLL_ENTRIES_UPDATED_ASYNC,
/* commit updates */
MM_CAMERA_PIPE_CMD_COMMIT,
/* exit */
MM_CAMERA_PIPE_CMD_EXIT,
/* max count */
MM_CAMERA_PIPE_CMD_MAX
} mm_camera_pipe_cmd_type_t;
typedef enum {
MM_CAMERA_POLL_TASK_STATE_STOPPED,
MM_CAMERA_POLL_TASK_STATE_POLL, /* polling pid in polling state. */
MM_CAMERA_POLL_TASK_STATE_MAX
} mm_camera_poll_task_state_type_t;
typedef struct {
uint32_t cmd;
mm_camera_event_t event;
} mm_camera_sig_evt_t;
/*===========================================================================
* FUNCTION : mm_camera_poll_sig_async
*
* DESCRIPTION: Asynchoronous call to send a command through pipe.
*
* PARAMETERS :
* @poll_cb : ptr to poll thread object
* @cmd : command to be sent
*
* RETURN : int32_t type of status
* 0 -- success
* -1 -- failure
*==========================================================================*/
static int32_t mm_camera_poll_sig_async(mm_camera_poll_thread_t *poll_cb,
uint32_t cmd)
{
/* send through pipe */
/* get the mutex */
mm_camera_sig_evt_t cmd_evt;
LOGD("E cmd = %d",cmd);
memset(&cmd_evt, 0, sizeof(cmd_evt));
cmd_evt.cmd = cmd;
pthread_mutex_lock(&poll_cb->mutex);
/* reset the statue to false */
poll_cb->status = FALSE;
/* send cmd to worker */
ssize_t len = write(poll_cb->pfds[1], &cmd_evt, sizeof(cmd_evt));
if (len < 1) {
LOGE("len = %lld, errno = %d",
(long long int)len, errno);
/* Avoid waiting for the signal */
pthread_mutex_unlock(&poll_cb->mutex);
return 0;
}
LOGD("begin IN mutex write done, len = %lld",
(long long int)len);
pthread_mutex_unlock(&poll_cb->mutex);
LOGD("X");
return 0;
}
/*===========================================================================
* FUNCTION : mm_camera_poll_sig
*
* DESCRIPTION: synchorinzed call to send a command through pipe.
*
* PARAMETERS :
* @poll_cb : ptr to poll thread object
* @cmd : command to be sent
*
* RETURN : int32_t type of status
* 0 -- success
* -1 -- failure
*==========================================================================*/
static int32_t mm_camera_poll_sig(mm_camera_poll_thread_t *poll_cb,
uint32_t cmd)
{
/* send through pipe */
/* get the mutex */
mm_camera_sig_evt_t cmd_evt;
LOGD("E cmd = %d",cmd);
memset(&cmd_evt, 0, sizeof(cmd_evt));
cmd_evt.cmd = cmd;
pthread_mutex_lock(&poll_cb->mutex);
/* reset the statue to false */
poll_cb->status = FALSE;
/* send cmd to worker */
ssize_t len = write(poll_cb->pfds[1], &cmd_evt, sizeof(cmd_evt));
if(len < 1) {
LOGE("len = %lld, errno = %d",
(long long int)len, errno);
/* Avoid waiting for the signal */
pthread_mutex_unlock(&poll_cb->mutex);
return 0;
}
LOGD("begin IN mutex write done, len = %lld",
(long long int)len);
/* wait till worker task gives positive signal */
if (FALSE == poll_cb->status) {
LOGD("wait");
pthread_cond_wait(&poll_cb->cond_v, &poll_cb->mutex);
}
/* done */
pthread_mutex_unlock(&poll_cb->mutex);
LOGD("X");
return 0;
}
/*===========================================================================
* FUNCTION : mm_camera_poll_sig
*
* DESCRIPTION: signal the status of done
*
* PARAMETERS :
* @poll_cb : ptr to poll thread object
*
* RETURN : none
*==========================================================================*/
static void mm_camera_poll_sig_done(mm_camera_poll_thread_t *poll_cb)
{
pthread_mutex_lock(&poll_cb->mutex);
poll_cb->status = TRUE;
pthread_cond_signal(&poll_cb->cond_v);
LOGD("done, in mutex");
pthread_mutex_unlock(&poll_cb->mutex);
}
/*===========================================================================
* FUNCTION : mm_camera_poll_set_state
*
* DESCRIPTION: set a polling state
*
* PARAMETERS :
* @poll_cb : ptr to poll thread object
* @state : polling state (stopped/polling)
*
* RETURN : none
*==========================================================================*/
static void mm_camera_poll_set_state(mm_camera_poll_thread_t *poll_cb,
mm_camera_poll_task_state_type_t state)
{
poll_cb->state = state;
}
/*===========================================================================
* FUNCTION : mm_camera_poll_proc_pipe
*
* DESCRIPTION: polling thread routine to process pipe
*
* PARAMETERS :
* @poll_cb : ptr to poll thread object
*
* RETURN : none
*==========================================================================*/
static void mm_camera_poll_proc_pipe(mm_camera_poll_thread_t *poll_cb)
{
ssize_t read_len;
int i;
mm_camera_sig_evt_t cmd_evt;
read_len = read(poll_cb->pfds[0], &cmd_evt, sizeof(cmd_evt));
LOGD("read_fd = %d, read_len = %d, expect_len = %d cmd = %d",
poll_cb->pfds[0], (int)read_len, (int)sizeof(cmd_evt), cmd_evt.cmd);
switch (cmd_evt.cmd) {
case MM_CAMERA_PIPE_CMD_POLL_ENTRIES_UPDATED:
case MM_CAMERA_PIPE_CMD_POLL_ENTRIES_UPDATED_ASYNC:
/* we always have index 0 for pipe read */
poll_cb->num_fds = 0;
poll_cb->poll_fds[poll_cb->num_fds].fd = poll_cb->pfds[0];
poll_cb->poll_fds[poll_cb->num_fds].events = POLLIN|POLLRDNORM|POLLPRI;
poll_cb->num_fds++;
if (MM_CAMERA_POLL_TYPE_EVT == poll_cb->poll_type &&
poll_cb->num_fds < MAX_STREAM_NUM_IN_BUNDLE) {
if (poll_cb->poll_entries[0].fd >= 0) {
/* fd is valid, we update poll_fds */
poll_cb->poll_fds[poll_cb->num_fds].fd = poll_cb->poll_entries[0].fd;
poll_cb->poll_fds[poll_cb->num_fds].events = POLLIN|POLLRDNORM|POLLPRI;
poll_cb->num_fds++;
}
} else if (MM_CAMERA_POLL_TYPE_DATA == poll_cb->poll_type &&
poll_cb->num_fds <= MAX_STREAM_NUM_IN_BUNDLE) {
for(i = 0; i < MAX_STREAM_NUM_IN_BUNDLE; i++) {
if(poll_cb->poll_entries[i].fd >= 0) {
/* fd is valid, we update poll_fds to this fd */
poll_cb->poll_fds[poll_cb->num_fds].fd = poll_cb->poll_entries[i].fd;
poll_cb->poll_fds[poll_cb->num_fds].events = POLLIN|POLLRDNORM|POLLPRI;
poll_cb->num_fds++;
} else {
/* fd is invalid, we set the entry to -1 to prevent polling.
* According to spec, polling will not poll on entry with fd=-1.
* If this is not the case, we need to skip these invalid fds
* when updating this array.
* We still keep fd=-1 in this array because this makes easier to
* map cb associated with this fd once incoming data avail by directly
* using the index-1(0 is reserved for pipe read, so need to reduce index by 1) */
poll_cb->poll_fds[poll_cb->num_fds].fd = -1;
poll_cb->poll_fds[poll_cb->num_fds].events = 0;
poll_cb->num_fds++;
}
}
}
if (cmd_evt.cmd != MM_CAMERA_PIPE_CMD_POLL_ENTRIES_UPDATED_ASYNC)
mm_camera_poll_sig_done(poll_cb);
break;
case MM_CAMERA_PIPE_CMD_COMMIT:
mm_camera_poll_sig_done(poll_cb);
break;
case MM_CAMERA_PIPE_CMD_EXIT:
default:
mm_camera_poll_set_state(poll_cb, MM_CAMERA_POLL_TASK_STATE_STOPPED);
mm_camera_poll_sig_done(poll_cb);
break;
}
}
/*===========================================================================
* FUNCTION : mm_camera_poll_fn
*
* DESCRIPTION: polling thread routine
*
* PARAMETERS :
* @poll_cb : ptr to poll thread object
*
* RETURN : none
*==========================================================================*/
static void *mm_camera_poll_fn(mm_camera_poll_thread_t *poll_cb)
{
int rc = 0, i;
if (NULL == poll_cb) {
LOGE("poll_cb is NULL!\n");
return NULL;
}
LOGD("poll type = %d, num_fd = %d poll_cb = %p\n",
poll_cb->poll_type, poll_cb->num_fds,poll_cb);
do {
for(i = 0; i < poll_cb->num_fds; i++) {
poll_cb->poll_fds[i].events = POLLIN|POLLRDNORM|POLLPRI;
}
rc = poll(poll_cb->poll_fds, poll_cb->num_fds, poll_cb->timeoutms);
if(rc > 0) {
if ((poll_cb->poll_fds[0].revents & POLLIN) &&
(poll_cb->poll_fds[0].revents & POLLRDNORM)) {
/* if we have data on pipe, we only process pipe in this iteration */
LOGD("cmd received on pipe\n");
mm_camera_poll_proc_pipe(poll_cb);
} else {
for(i=1; i<poll_cb->num_fds; i++) {
/* Checking for ctrl events */
if ((poll_cb->poll_type == MM_CAMERA_POLL_TYPE_EVT) &&
(poll_cb->poll_fds[i].revents & POLLPRI)) {
LOGD("mm_camera_evt_notify\n");
if (NULL != poll_cb->poll_entries[i-1].notify_cb) {
poll_cb->poll_entries[i-1].notify_cb(poll_cb->poll_entries[i-1].user_data);
}
}
if ((MM_CAMERA_POLL_TYPE_DATA == poll_cb->poll_type) &&
(poll_cb->poll_fds[i].revents & POLLIN) &&
(poll_cb->poll_fds[i].revents & POLLRDNORM)) {
LOGD("mm_stream_data_notify\n");
if (NULL != poll_cb->poll_entries[i-1].notify_cb) {
poll_cb->poll_entries[i-1].notify_cb(poll_cb->poll_entries[i-1].user_data);
}
}
}
}
} else {
/* in error case sleep 10 us and then continue. hard coded here */
usleep(10);
continue;
}
} while ((poll_cb != NULL) && (poll_cb->state == MM_CAMERA_POLL_TASK_STATE_POLL));
return NULL;
}
/*===========================================================================
* FUNCTION : mm_camera_poll_thread
*
* DESCRIPTION: polling thread entry function
*
* PARAMETERS :
* @data : ptr to poll thread object
*
* RETURN : none
*==========================================================================*/
static void *mm_camera_poll_thread(void *data)
{
mm_camera_poll_thread_t *poll_cb = (mm_camera_poll_thread_t *)data;
mm_camera_cmd_thread_name(poll_cb->threadName);
/* add pipe read fd into poll first */
poll_cb->poll_fds[poll_cb->num_fds++].fd = poll_cb->pfds[0];
mm_camera_poll_sig_done(poll_cb);
mm_camera_poll_set_state(poll_cb, MM_CAMERA_POLL_TASK_STATE_POLL);
return mm_camera_poll_fn(poll_cb);
}
/*===========================================================================
* FUNCTION : mm_camera_poll_thread
*
* DESCRIPTION: notify the polling thread that entries for polling fd have
* been updated
*
* PARAMETERS :
* @poll_cb : ptr to poll thread object
*
* RETURN : none
*==========================================================================*/
int32_t mm_camera_poll_thread_notify_entries_updated(mm_camera_poll_thread_t * poll_cb)
{
/* send poll entries updated signal to poll thread */
return mm_camera_poll_sig(poll_cb, MM_CAMERA_PIPE_CMD_POLL_ENTRIES_UPDATED);
}
/*===========================================================================
* FUNCTION : mm_camera_poll_thread_commit_updates
*
* DESCRIPTION: sync with all previously pending async updates
*
* PARAMETERS :
* @poll_cb : ptr to poll thread object
*
* RETURN : int32_t type of status
* 0 -- success
* -1 -- failure
*==========================================================================*/
int32_t mm_camera_poll_thread_commit_updates(mm_camera_poll_thread_t * poll_cb)
{
return mm_camera_poll_sig(poll_cb, MM_CAMERA_PIPE_CMD_COMMIT);
}
/*===========================================================================
* FUNCTION : mm_camera_poll_thread_add_poll_fd
*
* DESCRIPTION: add a new fd into polling thread
*
* PARAMETERS :
* @poll_cb : ptr to poll thread object
* @handler : stream handle if channel data polling thread,
* 0 if event polling thread
* @fd : file descriptor need to be added into polling thread
* @notify_cb : callback function to handle if any notify from fd
* @userdata : user data ptr
* @call_type : Whether its Synchronous or Asynchronous call
*
* RETURN : none
*==========================================================================*/
int32_t mm_camera_poll_thread_add_poll_fd(mm_camera_poll_thread_t * poll_cb,
uint32_t handler,
int32_t fd,
mm_camera_poll_notify_t notify_cb,
void* userdata,
mm_camera_call_type_t call_type)
{
int32_t rc = -1;
uint8_t idx = 0;
if (MM_CAMERA_POLL_TYPE_DATA == poll_cb->poll_type) {
/* get stream idx from handler if CH type */
idx = mm_camera_util_get_index_by_handler(handler);
} else {
/* for EVT type, only idx=0 is valid */
idx = 0;
}
if (MAX_STREAM_NUM_IN_BUNDLE > idx) {
poll_cb->poll_entries[idx].fd = fd;
poll_cb->poll_entries[idx].handler = handler;
poll_cb->poll_entries[idx].notify_cb = notify_cb;
poll_cb->poll_entries[idx].user_data = userdata;
/* send poll entries updated signal to poll thread */
if (call_type == mm_camera_sync_call ) {
rc = mm_camera_poll_sig(poll_cb, MM_CAMERA_PIPE_CMD_POLL_ENTRIES_UPDATED);
} else {
rc = mm_camera_poll_sig_async(poll_cb, MM_CAMERA_PIPE_CMD_POLL_ENTRIES_UPDATED_ASYNC );
}
} else {
LOGE("invalid handler %d (%d)",
handler, idx);
}
return rc;
}
/*===========================================================================
* FUNCTION : mm_camera_poll_thread_del_poll_fd
*
* DESCRIPTION: delete a fd from polling thread
*
* PARAMETERS :
* @poll_cb : ptr to poll thread object
* @handler : stream handle if channel data polling thread,
* 0 if event polling thread
*
* RETURN : int32_t type of status
* 0 -- success
* -1 -- failure
*==========================================================================*/
int32_t mm_camera_poll_thread_del_poll_fd(mm_camera_poll_thread_t * poll_cb,
uint32_t handler,
mm_camera_call_type_t call_type)
{
int32_t rc = -1;
uint8_t idx = 0;
if (MM_CAMERA_POLL_TYPE_DATA == poll_cb->poll_type) {
/* get stream idx from handler if CH type */
idx = mm_camera_util_get_index_by_handler(handler);
} else {
/* for EVT type, only idx=0 is valid */
idx = 0;
}
if ((MAX_STREAM_NUM_IN_BUNDLE > idx) &&
(handler == poll_cb->poll_entries[idx].handler)) {
/* reset poll entry */
poll_cb->poll_entries[idx].fd = -1; /* set fd to invalid */
poll_cb->poll_entries[idx].handler = 0;
poll_cb->poll_entries[idx].notify_cb = NULL;
/* send poll entries updated signal to poll thread */
if (call_type == mm_camera_sync_call ) {
rc = mm_camera_poll_sig(poll_cb, MM_CAMERA_PIPE_CMD_POLL_ENTRIES_UPDATED);
} else {
rc = mm_camera_poll_sig_async(poll_cb, MM_CAMERA_PIPE_CMD_POLL_ENTRIES_UPDATED_ASYNC );
}
} else {
/* The error might be due to async update. We only report error for EVT type*/
if (MM_CAMERA_POLL_TYPE_DATA != poll_cb->poll_type)
LOGE("invalid handler %d (%d)", handler, idx);
return -1;
}
return rc;
}
int32_t mm_camera_poll_thread_launch(mm_camera_poll_thread_t * poll_cb,
mm_camera_poll_thread_type_t poll_type)
{
int32_t rc = 0;
size_t i = 0, cnt = 0;
poll_cb->poll_type = poll_type;
//Initialize poll_fds
cnt = sizeof(poll_cb->poll_fds) / sizeof(poll_cb->poll_fds[0]);
for (i = 0; i < cnt; i++) {
poll_cb->poll_fds[i].fd = -1;
}
//Initialize poll_entries
cnt = sizeof(poll_cb->poll_entries) / sizeof(poll_cb->poll_entries[0]);
for (i = 0; i < cnt; i++) {
poll_cb->poll_entries[i].fd = -1;
}
//Initialize pipe fds
poll_cb->pfds[0] = -1;
poll_cb->pfds[1] = -1;
rc = pipe(poll_cb->pfds);
if(rc < 0) {
LOGE("pipe open rc=%d\n", rc);
return -1;
}
poll_cb->timeoutms = -1; /* Infinite seconds */
LOGD("poll_type = %d, read fd = %d, write fd = %d timeout = %d",
poll_cb->poll_type,
poll_cb->pfds[0], poll_cb->pfds[1],poll_cb->timeoutms);
pthread_mutex_init(&poll_cb->mutex, NULL);
pthread_cond_init(&poll_cb->cond_v, NULL);
/* launch the thread */
pthread_mutex_lock(&poll_cb->mutex);
poll_cb->status = 0;
pthread_create(&poll_cb->pid, NULL, mm_camera_poll_thread, (void *)poll_cb);
if(!poll_cb->status) {
pthread_cond_wait(&poll_cb->cond_v, &poll_cb->mutex);
}
pthread_mutex_unlock(&poll_cb->mutex);
LOGD("End");
return rc;
}
int32_t mm_camera_poll_thread_release(mm_camera_poll_thread_t *poll_cb)
{
int32_t rc = 0;
if(MM_CAMERA_POLL_TASK_STATE_STOPPED == poll_cb->state) {
LOGE("err, poll thread is not running.\n");
return rc;
}
/* send exit signal to poll thread */
mm_camera_poll_sig(poll_cb, MM_CAMERA_PIPE_CMD_EXIT);
/* wait until poll thread exits */
if (pthread_join(poll_cb->pid, NULL) != 0) {
LOGE("pthread dead already\n");
}
/* close pipe */
if(poll_cb->pfds[0] >= 0) {
close(poll_cb->pfds[0]);
}
if(poll_cb->pfds[1] >= 0) {
close(poll_cb->pfds[1]);
}
pthread_mutex_destroy(&poll_cb->mutex);
pthread_cond_destroy(&poll_cb->cond_v);
memset(poll_cb, 0, sizeof(mm_camera_poll_thread_t));
poll_cb->pfds[0] = -1;
poll_cb->pfds[1] = -1;
return rc;
}
static void *mm_camera_cmd_thread(void *data)
{
int running = 1;
int ret;
mm_camera_cmd_thread_t *cmd_thread =
(mm_camera_cmd_thread_t *)data;
mm_camera_cmdcb_t* node = NULL;
mm_camera_cmd_thread_name(cmd_thread->threadName);
do {
do {
ret = cam_sem_wait(&cmd_thread->cmd_sem);
if (ret != 0 && errno != EINVAL) {
LOGE("cam_sem_wait error (%s)",
strerror(errno));
return NULL;
}
} while (ret != 0);
/* we got notified about new cmd avail in cmd queue */
node = (mm_camera_cmdcb_t*)cam_queue_deq(&cmd_thread->cmd_queue);
while (node != NULL) {
switch (node->cmd_type) {
case MM_CAMERA_CMD_TYPE_EVT_CB:
case MM_CAMERA_CMD_TYPE_DATA_CB:
case MM_CAMERA_CMD_TYPE_REQ_DATA_CB:
case MM_CAMERA_CMD_TYPE_SUPER_BUF_DATA_CB:
case MM_CAMERA_CMD_TYPE_CONFIG_NOTIFY:
case MM_CAMERA_CMD_TYPE_START_ZSL:
case MM_CAMERA_CMD_TYPE_STOP_ZSL:
case MM_CAMERA_CMD_TYPE_GENERAL:
case MM_CAMERA_CMD_TYPE_FLUSH_QUEUE:
if (NULL != cmd_thread->cb) {
cmd_thread->cb(node, cmd_thread->user_data);
}
break;
case MM_CAMERA_CMD_TYPE_EXIT:
default:
running = 0;
break;
}
free(node);
node = (mm_camera_cmdcb_t*)cam_queue_deq(&cmd_thread->cmd_queue);
} /* (node != NULL) */
} while (running);
return NULL;
}
int32_t mm_camera_cmd_thread_launch(mm_camera_cmd_thread_t * cmd_thread,
mm_camera_cmd_cb_t cb,
void* user_data)
{
int32_t rc = 0;
cam_sem_init(&cmd_thread->cmd_sem, 0);
cam_sem_init(&cmd_thread->sync_sem, 0);
cam_queue_init(&cmd_thread->cmd_queue);
cmd_thread->cb = cb;
cmd_thread->user_data = user_data;
cmd_thread->is_active = TRUE;
/* launch the thread */
pthread_create(&cmd_thread->cmd_pid,
NULL,
mm_camera_cmd_thread,
(void *)cmd_thread);
return rc;
}
int32_t mm_camera_cmd_thread_name(const char* name)
{
int32_t rc = 0;
/* name the thread */
if (name && strlen(name))
prctl(PR_SET_NAME, (unsigned long)name, 0, 0, 0);
return rc;
}
int32_t mm_camera_cmd_thread_stop(mm_camera_cmd_thread_t * cmd_thread)
{
int32_t rc = 0;
mm_camera_cmdcb_t* node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
if (NULL == node) {
LOGE("No memory for mm_camera_cmdcb_t");
return -1;
}
memset(node, 0, sizeof(mm_camera_cmdcb_t));
node->cmd_type = MM_CAMERA_CMD_TYPE_EXIT;
cam_queue_enq(&cmd_thread->cmd_queue, node);
cam_sem_post(&cmd_thread->cmd_sem);
/* wait until cmd thread exits */
if (pthread_join(cmd_thread->cmd_pid, NULL) != 0) {
LOGD("pthread dead already\n");
}
return rc;
}
int32_t mm_camera_cmd_thread_destroy(mm_camera_cmd_thread_t * cmd_thread)
{
int32_t rc = 0;
cam_queue_deinit(&cmd_thread->cmd_queue);
cam_sem_destroy(&cmd_thread->cmd_sem);
cam_sem_destroy(&cmd_thread->sync_sem);
memset(cmd_thread, 0, sizeof(mm_camera_cmd_thread_t));
return rc;
}
int32_t mm_camera_cmd_thread_release(mm_camera_cmd_thread_t * cmd_thread)
{
int32_t rc = 0;
rc = mm_camera_cmd_thread_stop(cmd_thread);
if (0 == rc) {
rc = mm_camera_cmd_thread_destroy(cmd_thread);
}
return rc;
}

View file

@ -0,0 +1,195 @@
OLD_LOCAL_PATH := $(LOCAL_PATH)
LOCAL_PATH:=$(call my-dir)
# Build command line test app: mm-qcamera-app
include $(LOCAL_PATH)/../../../common.mk
include $(CLEAR_VARS)
LOCAL_CFLAGS:= \
-DAMSS_VERSION=$(AMSS_VERSION) \
$(mmcamera_debug_defines) \
$(mmcamera_debug_cflags) \
$(USE_SERVER_TREE)
ifeq ($(strip $(TARGET_USES_ION)),true)
LOCAL_CFLAGS += -DUSE_ION
endif
LOCAL_CFLAGS += -D_ANDROID_ -DQCAMERA_REDEFINE_LOG
# System header file path prefix
LOCAL_CFLAGS += -DSYSTEM_HEADER_PREFIX=sys
LOCAL_SRC_FILES:= \
src/mm_qcamera_main_menu.c \
src/mm_qcamera_app.c \
src/mm_qcamera_unit_test.c \
src/mm_qcamera_video.c \
src/mm_qcamera_preview.c \
src/mm_qcamera_snapshot.c \
src/mm_qcamera_rdi.c \
src/mm_qcamera_reprocess.c\
src/mm_qcamera_queue.c \
src/mm_qcamera_socket.c \
src/mm_qcamera_commands.c
# src/mm_qcamera_dual_test.c \
LOCAL_C_INCLUDES:=$(LOCAL_PATH)/inc
LOCAL_C_INCLUDES+= \
frameworks/native/include/media/openmax \
$(LOCAL_PATH)/../common \
$(LOCAL_PATH)/../mm-camera-interface/inc \
$(LOCAL_PATH)/../../../mm-image-codec/qexif \
$(LOCAL_PATH)/../../../mm-image-codec/qomx_core
LOCAL_C_INCLUDES+= $(kernel_includes)
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
LOCAL_CFLAGS += -DCAMERA_ION_HEAP_ID=ION_IOMMU_HEAP_ID
ifeq ($(TARGET_BOARD_PLATFORM),msm8974)
LOCAL_CFLAGS += -DCAMERA_ION_FALLBACK_HEAP_ID=ION_IOMMU_HEAP_ID
LOCAL_CFLAGS += -DCAMERA_GRALLOC_CACHING_ID=0
LOCAL_CFLAGS += -DNUM_RECORDING_BUFFERS=9
else ifeq ($(filter $(TARGET_BOARD_PLATFORM), apq8084 msm8084),$(TARGET_BOARD_PLATFORM))
LOCAL_CFLAGS += -DCAMERA_ION_FALLBACK_HEAP_ID=ION_IOMMU_HEAP_ID
LOCAL_CFLAGS += -DCAMERA_GRALLOC_CACHING_ID=0
LOCAL_CFLAGS += -DNUM_RECORDING_BUFFERS=9
else ifeq ($(TARGET_BOARD_PLATFORM),msm8994)
LOCAL_CFLAGS += -DCAMERA_ION_FALLBACK_HEAP_ID=ION_IOMMU_HEAP_ID
LOCAL_CFLAGS += -DCAMERA_GRALLOC_CACHING_ID=0
LOCAL_CFLAGS += -DNUM_RECORDING_BUFFERS=9
else ifeq ($(TARGET_BOARD_PLATFORM),msm8916 msm8952 msm8937 titanium)
LOCAL_CFLAGS += -DCAMERA_ION_FALLBACK_HEAP_ID=ION_IOMMU_HEAP_ID
LOCAL_CFLAGS += -DCAMERA_GRALLOC_CACHING_ID=0
LOCAL_CFLAGS += -DNUM_RECORDING_BUFFERS=9
else ifeq ($(TARGET_BOARD_PLATFORM),msm8226)
LOCAL_CFLAGS += -DCAMERA_ION_FALLBACK_HEAP_ID=ION_IOMMU_HEAP_ID
LOCAL_CFLAGS += -DCAMERA_GRALLOC_CACHING_ID=0
LOCAL_CFLAGS += -DNUM_RECORDING_BUFFERS=9
else ifeq ($(TARGET_BOARD_PLATFORM),msm8610)
LOCAL_CFLAGS += -DCAMERA_ION_FALLBACK_HEAP_ID=ION_IOMMU_HEAP_ID
LOCAL_CFLAGS += -DCAMERA_GRALLOC_CACHING_ID=0
LOCAL_CFLAGS += -DNUM_RECORDING_BUFFERS=9
else ifeq ($(TARGET_BOARD_PLATFORM),msm8960)
LOCAL_CFLAGS += -DCAMERA_ION_FALLBACK_HEAP_ID=ION_IOMMU_HEAP_ID
LOCAL_CFLAGS += -DCAMERA_GRALLOC_CACHING_ID=0
LOCAL_CFLAGS += -DNUM_RECORDING_BUFFERS=5
else ifneq (,$(filter msm8660,$(TARGET_BOARD_PLATFORM)))
LOCAL_CFLAGS += -DCAMERA_ION_FALLBACK_HEAP_ID=ION_IOMMU_HEAP_ID # EBI
LOCAL_CFLAGS += -DCAMERA_GRALLOC_CACHING_ID=0
LOCAL_CFLAGS += -DNUM_RECORDING_BUFFERS=5
else
LOCAL_CFLAGS += -DCAMERA_GRALLOC_CACHING_ID=GRALLOC_USAGE_PRIVATE_UNCACHED #uncached
LOCAL_CFLAGS += -DCAMERA_ION_FALLBACK_HEAP_ID=ION_CAMERA_HEAP_ID
LOCAL_CFLAGS += -DNUM_RECORDING_BUFFERS=5
endif
LOCAL_CFLAGS += -Wall -Wextra -Werror
LOCAL_SHARED_LIBRARIES:= \
libcutils libdl libmmcamera_interface
LOCAL_MODULE_TAGS := optional
LOCAL_32_BIT_ONLY := $(BOARD_QTI_CAMERA_32BIT_ONLY)
LOCAL_MODULE:= mm-qcamera-app
LOCAL_CLANG := false
include $(BUILD_EXECUTABLE)
# Build tuning library
include $(CLEAR_VARS)
LOCAL_CFLAGS:= \
-DAMSS_VERSION=$(AMSS_VERSION) \
$(mmcamera_debug_defines) \
$(mmcamera_debug_cflags) \
$(USE_SERVER_TREE)
ifeq ($(strip $(TARGET_USES_ION)),true)
LOCAL_CFLAGS += -DUSE_ION
endif
LOCAL_CFLAGS += -D_ANDROID_ -DQCAMERA_REDEFINE_LOG
# System header file path prefix
LOCAL_CFLAGS += -DSYSTEM_HEADER_PREFIX=sys
LOCAL_SRC_FILES:= \
src/mm_qcamera_main_menu.c \
src/mm_qcamera_app.c \
src/mm_qcamera_unit_test.c \
src/mm_qcamera_video.c \
src/mm_qcamera_preview.c \
src/mm_qcamera_snapshot.c \
src/mm_qcamera_rdi.c \
src/mm_qcamera_reprocess.c\
src/mm_qcamera_queue.c \
src/mm_qcamera_socket.c \
src/mm_qcamera_commands.c
# src/mm_qcamera_dual_test.c \
LOCAL_C_INCLUDES:=$(LOCAL_PATH)/inc
LOCAL_C_INCLUDES+= \
frameworks/native/include/media/openmax \
$(LOCAL_PATH)/../common \
$(LOCAL_PATH)/../mm-camera-interface/inc \
$(LOCAL_PATH)/../../../mm-image-codec/qexif \
$(LOCAL_PATH)/../../../mm-image-codec/qomx_core
LOCAL_C_INCLUDES+= $(kernel_includes)
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
LOCAL_CFLAGS += -DCAMERA_ION_HEAP_ID=ION_IOMMU_HEAP_ID
ifeq ($(TARGET_BOARD_PLATFORM),msm8974)
LOCAL_CFLAGS += -DCAMERA_ION_FALLBACK_HEAP_ID=ION_IOMMU_HEAP_ID
LOCAL_CFLAGS += -DCAMERA_GRALLOC_CACHING_ID=0
LOCAL_CFLAGS += -DNUM_RECORDING_BUFFERS=9
else ifeq ($(filter $(TARGET_BOARD_PLATFORM), apq8084 msm8084),$(TARGET_BOARD_PLATFORM))
LOCAL_CFLAGS += -DCAMERA_ION_FALLBACK_HEAP_ID=ION_IOMMU_HEAP_ID
LOCAL_CFLAGS += -DCAMERA_GRALLOC_CACHING_ID=0
LOCAL_CFLAGS += -DNUM_RECORDING_BUFFERS=9
else ifeq ($(TARGET_BOARD_PLATFORM),msm8994)
LOCAL_CFLAGS += -DCAMERA_ION_FALLBACK_HEAP_ID=ION_IOMMU_HEAP_ID
LOCAL_CFLAGS += -DCAMERA_GRALLOC_CACHING_ID=0
LOCAL_CFLAGS += -DNUM_RECORDING_BUFFERS=9
else ifeq ($(TARGET_BOARD_PLATFORM),msm8916 msm8952 msm8937 titanium)
LOCAL_CFLAGS += -DCAMERA_ION_FALLBACK_HEAP_ID=ION_IOMMU_HEAP_ID
LOCAL_CFLAGS += -DCAMERA_GRALLOC_CACHING_ID=0
LOCAL_CFLAGS += -DNUM_RECORDING_BUFFERS=9
else ifeq ($(TARGET_BOARD_PLATFORM),msm8226)
LOCAL_CFLAGS += -DCAMERA_ION_FALLBACK_HEAP_ID=ION_IOMMU_HEAP_ID
LOCAL_CFLAGS += -DCAMERA_GRALLOC_CACHING_ID=0
LOCAL_CFLAGS += -DNUM_RECORDING_BUFFERS=9
else ifeq ($(TARGET_BOARD_PLATFORM),msm8610)
LOCAL_CFLAGS += -DCAMERA_ION_FALLBACK_HEAP_ID=ION_IOMMU_HEAP_ID
LOCAL_CFLAGS += -DCAMERA_GRALLOC_CACHING_ID=0
LOCAL_CFLAGS += -DNUM_RECORDING_BUFFERS=9
else ifeq ($(TARGET_BOARD_PLATFORM),msm8960)
LOCAL_CFLAGS += -DCAMERA_ION_FALLBACK_HEAP_ID=ION_IOMMU_HEAP_ID
LOCAL_CFLAGS += -DCAMERA_GRALLOC_CACHING_ID=0
LOCAL_CFLAGS += -DNUM_RECORDING_BUFFERS=5
else ifneq (,$(filter msm8660,$(TARGET_BOARD_PLATFORM)))
LOCAL_CFLAGS += -DCAMERA_ION_FALLBACK_HEAP_ID=ION_IOMMU_HEAP_ID # EBI
LOCAL_CFLAGS += -DCAMERA_GRALLOC_CACHING_ID=0
LOCAL_CFLAGS += -DNUM_RECORDING_BUFFERS=5
else
LOCAL_CFLAGS += -DCAMERA_GRALLOC_CACHING_ID=GRALLOC_USAGE_PRIVATE_UNCACHED #uncached
LOCAL_CFLAGS += -DCAMERA_ION_FALLBACK_HEAP_ID=ION_CAMERA_HEAP_ID
LOCAL_CFLAGS += -DNUM_RECORDING_BUFFERS=5
endif
LOCAL_CFLAGS += -Wall -Wextra -Werror
LOCAL_SHARED_LIBRARIES:= \
libcutils libdl libmmcamera_interface
LOCAL_MODULE_TAGS := optional
LOCAL_32_BIT_ONLY := $(BOARD_QTI_CAMERA_32BIT_ONLY)
LOCAL_MODULE:= libmm-qcamera
LOCAL_CLANG := false
include $(BUILD_SHARED_LIBRARY)
LOCAL_PATH := $(OLD_LOCAL_PATH)

View file

@ -0,0 +1,533 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __MM_QCAMERA_APP_H__
#define __MM_QCAMERA_APP_H__
// System dependencies
#include <pthread.h>
#include <linux/msm_ion.h>
#include <linux/msm_mdp.h>
// Camera dependencies
#include "mm_camera_interface.h"
#include "mm_jpeg_interface.h"
#include "mm_qcamera_socket.h"
#define MM_QCAMERA_APP_INTERATION 1
#define MM_APP_MAX_DUMP_FRAME_NUM 1000
#define PREVIEW_BUF_NUM 7
#define SNAPSHOT_BUF_NUM 10
#define VIDEO_BUF_NUM 7
#define ISP_PIX_BUF_NUM 9
#define STATS_BUF_NUM 4
#define RDI_BUF_NUM 8
#define CAPTURE_BUF_NUM 5
#define DEFAULT_PREVIEW_FORMAT CAM_FORMAT_YUV_420_NV21
#define DEFAULT_PREVIEW_WIDTH 1280
#define DEFAULT_PREVIEW_HEIGHT 960
#define DEFAULT_PREVIEW_PADDING CAM_PAD_TO_WORD
#define DEFAULT_VIDEO_FORMAT CAM_FORMAT_YUV_420_NV12
#define DEFAULT_VIDEO_WIDTH 800
#define DEFAULT_VIDEO_HEIGHT 480
#define DEFAULT_VIDEO_PADDING CAM_PAD_TO_2K
#define DEFAULT_SNAPSHOT_FORMAT CAM_FORMAT_YUV_420_NV21
#define DEFAULT_RAW_FORMAT CAM_FORMAT_BAYER_MIPI_RAW_10BPP_GBRG
#define DEFAULT_SNAPSHOT_WIDTH 4160
#define DEFAULT_SNAPSHOT_HEIGHT 3120
#define DEFAULT_SNAPSHOT_PADDING CAM_PAD_TO_WORD
#define DEFAULT_OV_FORMAT MDP_Y_CRCB_H2V2
#define DEFAULT_OV_FORMAT_BPP 3/2
#define DEFAULT_CAMERA_FORMAT_BPP 3/2
#define FB_PATH "/dev/graphics/fb0"
#define BACKLIGHT_CONTROL "/sys/class/leds/lcd-backlight/brightness"
#define BACKLIGHT_LEVEL "205"
#define ENABLE_REPROCESSING 1
#define INVALID_KEY_PRESS 0
#define BASE_OFFSET ('Z' - 'A' + 1)
#define BASE_OFFSET_NUM ('Z' - 'A' + 2)
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
typedef enum {
TUNE_CMD_INIT,
TUNE_CMD_GET_LIST,
TUNE_CMD_GET_PARAMS,
TUNE_CMD_SET_PARAMS,
TUNE_CMD_MISC,
TUNE_CMD_DEINIT,
} mm_camera_tune_cmd_t;
typedef enum {
TUNE_PREVCMD_INIT,
TUNE_PREVCMD_SETDIM,
TUNE_PREVCMD_GETINFO,
TUNE_PREVCMD_GETCHUNKSIZE,
TUNE_PREVCMD_GETFRAME,
TUNE_PREVCMD_UNSUPPORTED,
TUNE_PREVCMD_DEINIT,
} mm_camera_tune_prevcmd_t;
typedef void (*cam_stream_user_cb) (mm_camera_buf_def_t *frame);
typedef void (*prev_callback) (mm_camera_buf_def_t *preview_frame);
typedef struct {
char *send_buf;
uint32_t send_len;
void *next;
} eztune_prevcmd_rsp;
typedef struct {
int (*command_process) (void *recv, mm_camera_tune_cmd_t cmd,
void *param, char *send_buf, uint32_t send_len);
int (*prevcommand_process) (void *recv, mm_camera_tune_prevcmd_t cmd,
void *param, char **send_buf, uint32_t *send_len);
void (*prevframe_callback) (mm_camera_buf_def_t *preview_frame);
} mm_camera_tune_func_t;
typedef struct {
mm_camera_tune_func_t *func_tbl;
void *lib_handle;
}mm_camera_tuning_lib_params_t;
typedef enum {
MM_CAMERA_OK,
MM_CAMERA_E_GENERAL,
MM_CAMERA_E_NO_MEMORY,
MM_CAMERA_E_NOT_SUPPORTED,
MM_CAMERA_E_INVALID_INPUT,
MM_CAMERA_E_INVALID_OPERATION, /* 5 */
MM_CAMERA_E_ENCODE,
MM_CAMERA_E_BUFFER_REG,
MM_CAMERA_E_PMEM_ALLOC,
MM_CAMERA_E_CAPTURE_FAILED,
MM_CAMERA_E_CAPTURE_TIMEOUT, /* 10 */
} mm_camera_status_type_t;
typedef enum {
MM_CHANNEL_TYPE_ZSL, /* preview, and snapshot main */
MM_CHANNEL_TYPE_CAPTURE, /* snapshot main, and postview */
MM_CHANNEL_TYPE_PREVIEW, /* preview only */
MM_CHANNEL_TYPE_SNAPSHOT, /* snapshot main only */
MM_CHANNEL_TYPE_VIDEO, /* video only */
MM_CHANNEL_TYPE_RDI, /* rdi only */
MM_CHANNEL_TYPE_REPROCESS,/* offline reprocess */
MM_CHANNEL_TYPE_MAX
} mm_camera_channel_type_t;
typedef struct {
int fd;
int main_ion_fd;
ion_user_handle_t handle;
size_t size;
parm_buffer_t *data;
} mm_camera_app_meminfo_t;
typedef struct {
mm_camera_buf_def_t buf;
mm_camera_app_meminfo_t mem_info;
} mm_camera_app_buf_t;
typedef struct {
uint32_t s_id;
mm_camera_stream_config_t s_config;
cam_frame_len_offset_t offset;
uint8_t num_of_bufs;
uint32_t multipleOf;
mm_camera_app_buf_t s_bufs[MM_CAMERA_MAX_NUM_FRAMES];
mm_camera_app_buf_t s_info_buf;
} mm_camera_stream_t;
typedef struct {
uint32_t ch_id;
uint8_t num_streams;
mm_camera_stream_t streams[MAX_STREAM_NUM_IN_BUNDLE];
} mm_camera_channel_t;
typedef void (*release_data_fn)(void* data, void *user_data);
typedef struct {
struct cam_list list;
void* data;
} camera_q_node;
typedef struct {
camera_q_node m_head;
int m_size;
pthread_mutex_t m_lock;
release_data_fn m_dataFn;
void * m_userData;
} mm_camera_queue_t;
typedef struct {
uint16_t user_input_display_width;
uint16_t user_input_display_height;
} USER_INPUT_DISPLAY_T;
typedef struct {
mm_camera_vtbl_t *cam;
uint8_t num_channels;
mm_camera_channel_t channels[MM_CHANNEL_TYPE_MAX];
mm_jpeg_ops_t jpeg_ops;
uint32_t jpeg_hdl;
mm_camera_app_buf_t cap_buf;
mm_camera_app_buf_t parm_buf;
uint32_t current_jpeg_sess_id;
mm_camera_super_buf_t* current_job_frames;
uint32_t current_job_id;
mm_camera_app_buf_t jpeg_buf;
int fb_fd;
struct fb_var_screeninfo vinfo;
struct mdp_overlay data_overlay;
uint32_t slice_size;
uint32_t buffer_width, buffer_height;
uint32_t buffer_size;
cam_format_t buffer_format;
uint32_t frame_size;
uint32_t frame_count;
int encodeJpeg;
int zsl_enabled;
int8_t focus_supported;
cam_stream_user_cb user_preview_cb;
cam_stream_user_cb user_metadata_cb;
parm_buffer_t *params_buffer;
USER_INPUT_DISPLAY_T preview_resolution;
//Reprocess params&stream
int8_t enable_reproc;
int32_t reproc_sharpness;
cam_denoise_param_t reproc_wnr;
int8_t enable_CAC;
mm_camera_queue_t pp_frames;
mm_camera_stream_t *reproc_stream;
metadata_buffer_t *metadata;
int8_t is_chromatix_reload;
} mm_camera_test_obj_t;
typedef struct {
void *ptr;
void* ptr_jpeg;
uint8_t (*get_num_of_cameras) ();
int32_t (*mm_camera_open) (uint8_t camera_idx, mm_camera_vtbl_t **camera_vtbl);
uint32_t (*jpeg_open)(mm_jpeg_ops_t *ops, mm_jpeg_mpo_ops_t *mpo_ops,
mm_dimension picture_size,
cam_jpeg_metadata_t *jpeg_metadata);
} hal_interface_lib_t;
typedef struct {
uint8_t num_cameras;
hal_interface_lib_t hal_lib;
} mm_camera_app_t;
typedef struct {
uint32_t width;
uint32_t height;
} mm_camera_lib_snapshot_params;
typedef enum {
MM_CAMERA_LIB_NO_ACTION = 0,
MM_CAMERA_LIB_RAW_CAPTURE,
MM_CAMERA_LIB_JPEG_CAPTURE,
MM_CAMERA_LIB_SET_FOCUS_MODE,
MM_CAMERA_LIB_DO_AF,
MM_CAMERA_LIB_CANCEL_AF,
MM_CAMERA_LIB_LOCK_AE,
MM_CAMERA_LIB_UNLOCK_AE,
MM_CAMERA_LIB_LOCK_AWB,
MM_CAMERA_LIB_UNLOCK_AWB,
MM_CAMERA_LIB_GET_CHROMATIX,
MM_CAMERA_LIB_SET_RELOAD_CHROMATIX,
MM_CAMERA_LIB_GET_AFTUNE,
MM_CAMERA_LIB_SET_RELOAD_AFTUNE,
MM_CAMERA_LIB_SET_AUTOFOCUS_TUNING,
MM_CAMERA_LIB_ZSL_ENABLE,
MM_CAMERA_LIB_EV,
MM_CAMERA_LIB_ANTIBANDING,
MM_CAMERA_LIB_SET_VFE_COMMAND,
MM_CAMERA_LIB_SET_POSTPROC_COMMAND,
MM_CAMERA_LIB_SET_3A_COMMAND,
MM_CAMERA_LIB_AEC_ENABLE,
MM_CAMERA_LIB_AEC_DISABLE,
MM_CAMERA_LIB_AF_ENABLE,
MM_CAMERA_LIB_AF_DISABLE,
MM_CAMERA_LIB_AWB_ENABLE,
MM_CAMERA_LIB_AWB_DISABLE,
MM_CAMERA_LIB_AEC_FORCE_LC,
MM_CAMERA_LIB_AEC_FORCE_GAIN,
MM_CAMERA_LIB_AEC_FORCE_EXP,
MM_CAMERA_LIB_AEC_FORCE_SNAP_LC,
MM_CAMERA_LIB_AEC_FORCE_SNAP_GAIN,
MM_CAMERA_LIB_AEC_FORCE_SNAP_EXP,
MM_CAMERA_LIB_WB,
MM_CAMERA_LIB_EXPOSURE_METERING,
MM_CAMERA_LIB_BRIGHTNESS,
MM_CAMERA_LIB_CONTRAST,
MM_CAMERA_LIB_SATURATION,
MM_CAMERA_LIB_SHARPNESS,
MM_CAMERA_LIB_ISO,
MM_CAMERA_LIB_ZOOM,
MM_CAMERA_LIB_BESTSHOT,
MM_CAMERA_LIB_FLASH,
MM_CAMERA_LIB_FPS_RANGE,
MM_CAMERA_LIB_WNR_ENABLE,
MM_CAMERA_LIB_SET_TINTLESS,
} mm_camera_lib_commands;
typedef struct {
int32_t stream_width, stream_height;
cam_focus_mode_type af_mode;
} mm_camera_lib_params;
typedef struct {
tuneserver_protocol_t *proto;
int clientsocket_id;
prserver_protocol_t *pr_proto;
int pr_clientsocket_id;
mm_camera_tuning_lib_params_t tuning_params;
} tuningserver_t;
typedef struct {
mm_camera_app_t app_ctx;
mm_camera_test_obj_t test_obj;
mm_camera_lib_params current_params;
int stream_running;
tuningserver_t tsctrl;
} mm_camera_lib_ctx;
typedef mm_camera_lib_ctx mm_camera_lib_handle;
typedef int (*mm_app_test_t) (mm_camera_app_t *cam_apps);
typedef struct {
mm_app_test_t f;
int r;
} mm_app_tc_t;
extern int mm_app_unit_test_entry(mm_camera_app_t *cam_app);
extern int mm_app_dual_test_entry(mm_camera_app_t *cam_app);
extern int setmetainfoCommand(mm_camera_test_obj_t *test_obj,
cam_stream_size_info_t *value);
extern void mm_app_dump_frame(mm_camera_buf_def_t *frame,
char *name,
char *ext,
uint32_t frame_idx);
extern void mm_app_dump_jpeg_frame(const void * data,
size_t size,
char* name,
char* ext,
uint32_t index);
extern int mm_camera_app_timedwait(uint8_t seconds);
extern int mm_camera_app_wait();
extern void mm_camera_app_done();
extern int mm_app_alloc_bufs(mm_camera_app_buf_t* app_bufs,
cam_frame_len_offset_t *frame_offset_info,
uint8_t num_bufs,
uint8_t is_streambuf,
size_t multipleOf);
extern int mm_app_release_bufs(uint8_t num_bufs,
mm_camera_app_buf_t* app_bufs);
extern int mm_app_stream_initbuf(cam_frame_len_offset_t *frame_offset_info,
uint8_t *num_bufs,
uint8_t **initial_reg_flag,
mm_camera_buf_def_t **bufs,
mm_camera_map_unmap_ops_tbl_t *ops_tbl,
void *user_data);
extern int32_t mm_app_stream_deinitbuf(mm_camera_map_unmap_ops_tbl_t *ops_tbl,
void *user_data);
extern int mm_app_cache_ops(mm_camera_app_meminfo_t *mem_info, int cmd);
extern int32_t mm_app_stream_clean_invalidate_buf(uint32_t index, void *user_data);
extern int32_t mm_app_stream_invalidate_buf(uint32_t index, void *user_data);
extern int mm_app_open(mm_camera_app_t *cam_app,
int cam_id,
mm_camera_test_obj_t *test_obj);
extern int mm_app_close(mm_camera_test_obj_t *test_obj);
extern mm_camera_channel_t * mm_app_add_channel(
mm_camera_test_obj_t *test_obj,
mm_camera_channel_type_t ch_type,
mm_camera_channel_attr_t *attr,
mm_camera_buf_notify_t channel_cb,
void *userdata);
extern int mm_app_del_channel(mm_camera_test_obj_t *test_obj,
mm_camera_channel_t *channel);
extern mm_camera_stream_t * mm_app_add_stream(mm_camera_test_obj_t *test_obj,
mm_camera_channel_t *channel);
extern int mm_app_del_stream(mm_camera_test_obj_t *test_obj,
mm_camera_channel_t *channel,
mm_camera_stream_t *stream);
extern int mm_app_config_stream(mm_camera_test_obj_t *test_obj,
mm_camera_channel_t *channel,
mm_camera_stream_t *stream,
mm_camera_stream_config_t *config);
extern int mm_app_start_channel(mm_camera_test_obj_t *test_obj,
mm_camera_channel_t *channel);
extern int mm_app_stop_channel(mm_camera_test_obj_t *test_obj,
mm_camera_channel_t *channel);
extern mm_camera_channel_t *mm_app_get_channel_by_type(
mm_camera_test_obj_t *test_obj,
mm_camera_channel_type_t ch_type);
extern int mm_app_start_preview(mm_camera_test_obj_t *test_obj);
extern int mm_app_stop_preview(mm_camera_test_obj_t *test_obj);
extern int mm_app_start_preview_zsl(mm_camera_test_obj_t *test_obj);
extern int mm_app_stop_preview_zsl(mm_camera_test_obj_t *test_obj);
extern mm_camera_channel_t * mm_app_add_preview_channel(
mm_camera_test_obj_t *test_obj);
extern mm_camera_stream_t * mm_app_add_raw_stream(mm_camera_test_obj_t *test_obj,
mm_camera_channel_t *channel,
mm_camera_buf_notify_t stream_cb,
void *userdata,
uint8_t num_bufs,
uint8_t num_burst);
extern int mm_app_stop_and_del_channel(mm_camera_test_obj_t *test_obj,
mm_camera_channel_t *channel);
extern mm_camera_channel_t * mm_app_add_snapshot_channel(
mm_camera_test_obj_t *test_obj);
extern mm_camera_stream_t * mm_app_add_snapshot_stream(
mm_camera_test_obj_t *test_obj,
mm_camera_channel_t *channel,
mm_camera_buf_notify_t stream_cb,
void *userdata,
uint8_t num_bufs,
uint8_t num_burst);
extern mm_camera_stream_t * mm_app_add_metadata_stream(mm_camera_test_obj_t *test_obj,
mm_camera_channel_t *channel,
mm_camera_buf_notify_t stream_cb,
void *userdata,
uint8_t num_bufs);
extern int mm_app_start_record_preview(mm_camera_test_obj_t *test_obj);
extern int mm_app_stop_record_preview(mm_camera_test_obj_t *test_obj);
extern int mm_app_start_record(mm_camera_test_obj_t *test_obj);
extern int mm_app_stop_record(mm_camera_test_obj_t *test_obj);
extern int mm_app_start_live_snapshot(mm_camera_test_obj_t *test_obj);
extern int mm_app_stop_live_snapshot(mm_camera_test_obj_t *test_obj);
extern int mm_app_start_capture(mm_camera_test_obj_t *test_obj,
uint8_t num_snapshots);
extern int mm_app_stop_capture(mm_camera_test_obj_t *test_obj);
extern int mm_app_start_capture_raw(mm_camera_test_obj_t *test_obj,
uint8_t num_snapshots);
extern int mm_app_stop_capture_raw(mm_camera_test_obj_t *test_obj);
extern int mm_app_start_rdi(mm_camera_test_obj_t *test_obj, uint8_t num_burst);
extern int mm_app_stop_rdi(mm_camera_test_obj_t *test_obj);
extern int mm_app_initialize_fb(mm_camera_test_obj_t *test_obj);
extern int mm_app_close_fb(mm_camera_test_obj_t *test_obj);
extern int mm_app_fb_write(mm_camera_test_obj_t *test_obj, char *buffer);
extern int mm_app_overlay_display(mm_camera_test_obj_t *test_obj, int bufferFd);
extern int mm_app_allocate_ion_memory(mm_camera_app_buf_t *buf, unsigned int ion_type);
extern int mm_app_deallocate_ion_memory(mm_camera_app_buf_t *buf);
extern int mm_app_set_params(mm_camera_test_obj_t *test_obj,
cam_intf_parm_type_t param_type,
int32_t value);
extern int mm_app_set_preview_fps_range(mm_camera_test_obj_t *test_obj,
cam_fps_range_t *fpsRange);
extern int mm_app_set_face_detection(mm_camera_test_obj_t *test_obj,
cam_fd_set_parm_t *fd_set_parm);
extern int mm_app_set_metadata_usercb(mm_camera_test_obj_t *test_obj,
cam_stream_user_cb usercb);
extern int mm_app_set_face_detection(mm_camera_test_obj_t *test_obj,
cam_fd_set_parm_t *fd_set_parm);
extern int mm_app_set_flash_mode(mm_camera_test_obj_t *test_obj,
cam_flash_mode_t flashMode);
/* JIG camera lib interface */
int mm_camera_lib_open(mm_camera_lib_handle *handle, int cam_id);
int mm_camera_lib_get_caps(mm_camera_lib_handle *handle,
cam_capability_t *caps);
int mm_camera_lib_start_stream(mm_camera_lib_handle *handle);
int mm_camera_lib_send_command(mm_camera_lib_handle *handle,
mm_camera_lib_commands cmd,
void *data, void *out_data);
int mm_camera_lib_stop_stream(mm_camera_lib_handle *handle);
int mm_camera_lib_number_of_cameras(mm_camera_lib_handle *handle);
int mm_camera_lib_close(mm_camera_lib_handle *handle);
int32_t mm_camera_load_tuninglibrary(
mm_camera_tuning_lib_params_t *tuning_param);
int mm_camera_lib_set_preview_usercb(
mm_camera_lib_handle *handle, cam_stream_user_cb cb);
//
int mm_app_start_regression_test(int run_tc);
int mm_app_load_hal(mm_camera_app_t *my_cam_app);
extern int createEncodingSession(mm_camera_test_obj_t *test_obj,
mm_camera_stream_t *m_stream,
mm_camera_buf_def_t *m_frame);
extern int encodeData(mm_camera_test_obj_t *test_obj, mm_camera_super_buf_t* recvd_frame,
mm_camera_stream_t *m_stream);
extern int mm_app_take_picture(mm_camera_test_obj_t *test_obj, uint8_t);
extern mm_camera_channel_t * mm_app_add_reprocess_channel(mm_camera_test_obj_t *test_obj,
mm_camera_stream_t *source_stream);
extern int mm_app_start_reprocess(mm_camera_test_obj_t *test_obj);
extern int mm_app_stop_reprocess(mm_camera_test_obj_t *test_obj);
extern int mm_app_do_reprocess(mm_camera_test_obj_t *test_obj,
mm_camera_buf_def_t *frame,
uint32_t meta_idx,
mm_camera_super_buf_t *super_buf,
mm_camera_stream_t *src_meta);
extern void mm_app_release_ppinput(void *data, void *user_data);
extern int mm_camera_queue_init(mm_camera_queue_t *queue,
release_data_fn data_rel_fn,
void *user_data);
extern int mm_qcamera_queue_release(mm_camera_queue_t *queue);
extern int mm_qcamera_queue_isempty(mm_camera_queue_t *queue);
extern int mm_qcamera_queue_enqueue(mm_camera_queue_t *queue, void *data);
extern void* mm_qcamera_queue_dequeue(mm_camera_queue_t *queue,
int bFromHead);
extern void mm_qcamera_queue_flush(mm_camera_queue_t *queue);
#endif /* __MM_QCAMERA_APP_H__ */

View file

@ -0,0 +1,68 @@
/* Copyright (c) 2013, 2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __MM_QCAMERA_COMMANDS_H__
#define __MM_QCAMERA_COMMANDS_H__
// Camera dependencies
#include "mm_qcamera_socket.h"
#include "mm_qcamera_app.h"
int tuneserver_close_cam(mm_camera_lib_handle *lib_handle);
int tuneserver_stop_cam(mm_camera_lib_handle *lib_handle);
int tuneserver_open_cam(mm_camera_lib_handle *lib_handle);
int tuneserver_initialize_tuningp(void * ctrl, int client_socket_id,
char *send_buf, uint32_t send_len);
int tuneserver_deinitialize_tuningp(void * ctrl, int client_socket_id,
char *send_buf, uint32_t send_len);
int tuneserver_process_get_list_cmd(void * ctrl, void *recv_cmd,
char *send_buf, uint32_t send_len);
int tuneserver_process_misc_cmd(void * ctrl, void *recv_cmd,
char *send_buf, uint32_t send_len);
int tuneserver_process_get_params_cmd(void * ctrl, void *recv_cmd,
char *send_buf, uint32_t send_len);
int tuneserver_process_set_params_cmd(void * ctrl, void *recv_cmd,
char *send_buf, uint32_t send_len);
int tuneserver_initialize_prevtuningp(void * ctrl,
int pr_client_socket_id, cam_dimension_t dimension,
char **send_buf, uint32_t *send_len);
int tuneserver_deinitialize_prevtuningp(void * ctrl,
char **send_buf, uint32_t *send_len);
int tuneserver_preview_getinfo(void * ctrl,
char **send_buf, uint32_t *send_len);
int tuneserver_preview_getchunksize(void * ctrl,
char **send_buf, uint32_t *send_len);
int tuneserver_preview_getframe(void * ctrl,
char **send_buf, uint32_t *send_len);
int tuneserver_preview_unsupported(void * ctrl,
char **send_buf, uint32_t *send_len);
#endif /*__MM_QCAMERA_COMMANDS_H__*/

View file

@ -0,0 +1,38 @@
/* Copyright (c) 2012, 2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __MM_QCAMERA_DBG_H__
#define __MM_QCAMERA_DBG_H__
#ifdef QCAMERA_REDEFINE_LOG
#define CAM_MODULE CAM_HAL_MODULE
#include "mm_camera_dbg.h"
#endif
#endif /* __MM_QCAMERA_DBG_H__ */

View file

@ -0,0 +1,439 @@
/* Copyright (c) 2013, 2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __MM_QCAMERA_MAIN_MENU_H__
#define __MM_QCAMERA_MAIN_MENU_H__
// Camera dependencies
#include "mm_camera_interface.h"
#include "mm_jpeg_interface.h"
#define VIDEO_BUFFER_SIZE (PREVIEW_WIDTH * PREVIEW_HEIGHT * 3/2)
#define THUMBNAIL_BUFFER_SIZE (THUMBNAIL_WIDTH * THUMBNAIL_HEIGHT * 3/2)
#define SNAPSHOT_BUFFER_SIZE (PICTURE_WIDTH * PICTURE_HEIGHT * 3/2)
/*===========================================================================
* Macro
*===========================================================================*/
#define PREVIEW_FRAMES_NUM 5
#define VIDEO_FRAMES_NUM 5
#define THUMBNAIL_FRAMES_NUM 1
#define SNAPSHOT_FRAMES_NUM 1
#define MAX_NUM_FORMAT 32
typedef enum
{
START_PREVIEW,
STOP_PREVIEW,
SET_WHITE_BALANCE,
SET_TINTLESS_ENABLE,
SET_TINTLESS_DISABLE,
SET_EXP_METERING,
GET_CTRL_VALUE,
TOGGLE_AFR,
SET_ISO,
BRIGHTNESS_GOTO_SUBMENU,
CONTRAST_GOTO_SUBMENU,
EV_GOTO_SUBMENU,
SATURATION_GOTO_SUBMENU,
SET_ZOOM,
SET_SHARPNESS,
TAKE_JPEG_SNAPSHOT,
START_RECORDING,
STOP_RECORDING,
BEST_SHOT,
LIVE_SHOT,
FLASH_MODES,
TOGGLE_ZSL,
TAKE_RAW_SNAPSHOT,
SWITCH_SNAP_RESOLUTION,
TOGGLE_WNR,
EXIT
} Camera_main_menu_t;
typedef enum
{
ACTION_NO_ACTION,
ACTION_START_PREVIEW,
ACTION_STOP_PREVIEW,
ACTION_SET_WHITE_BALANCE,
ACTION_SET_TINTLESS_ENABLE,
ACTION_SET_TINTLESS_DISABLE,
ACTION_SET_EXP_METERING,
ACTION_GET_CTRL_VALUE,
ACTION_TOGGLE_AFR,
ACTION_SET_ISO,
ACTION_BRIGHTNESS_INCREASE,
ACTION_BRIGHTNESS_DECREASE,
ACTION_CONTRAST_INCREASE,
ACTION_CONTRAST_DECREASE,
ACTION_EV_INCREASE,
ACTION_EV_DECREASE,
ACTION_SATURATION_INCREASE,
ACTION_SATURATION_DECREASE,
ACTION_SET_ZOOM,
ACTION_SHARPNESS_INCREASE,
ACTION_SHARPNESS_DECREASE,
ACTION_TAKE_JPEG_SNAPSHOT,
ACTION_START_RECORDING,
ACTION_STOP_RECORDING,
ACTION_SET_BESTSHOT_MODE,
ACTION_TAKE_LIVE_SNAPSHOT,
ACTION_SET_FLASH_MODE,
ACTION_SWITCH_CAMERA,
ACTION_TOGGLE_ZSL,
ACTION_TAKE_RAW_SNAPSHOT,
ACTION_SWITCH_RESOLUTION,
ACTION_TOGGLE_WNR,
ACTION_EXIT
} camera_action_t;
#define INVALID_KEY_PRESS 0
#define BASE_OFFSET ('Z' - 'A' + 1)
#define BASE_OFFSET_NUM ('Z' - 'A' + 2)
#define PAD_TO_WORD(a) (((a)+3)&~3)
#define SQCIF_WIDTH 128
#define SQCIF_HEIGHT 96
#define QCIF_WIDTH 176
#define QCIF_HEIGHT 144
#define QVGA_WIDTH 320
#define QVGA_HEIGHT 240
#define HD_THUMBNAIL_WIDTH 256
#define HD_THUMBNAIL_HEIGHT 144
#define CIF_WIDTH 352
#define CIF_HEIGHT 288
#define VGA_WIDTH 640
#define VGA_HEIGHT 480
#define WVGA_WIDTH 800
#define WVGA_HEIGHT 480
#define WVGA_PLUS_WIDTH 960
#define WVGA_PLUS_HEIGHT 720
#define MP1_WIDTH 1280
#define MP1_HEIGHT 960
#define MP2_WIDTH 1600
#define MP2_HEIGHT 1200
#define MP3_WIDTH 2048
#define MP3_HEIGHT 1536
#define MP5_WIDTH 2592
#define MP5_HEIGHT 1944
#define MP8_WIDTH 3264
#define MP8_HEIGHT 2448
#define MP12_WIDTH 4000
#define MP12_HEIGHT 3000
#define SVGA_WIDTH 800
#define SVGA_HEIGHT 600
#define XGA_WIDTH 1024
#define XGA_HEIGHT 768
#define HD720_WIDTH 1280
#define HD720_HEIGHT 720
#define HD720_PLUS_WIDTH 1440
#define HD720_PLUS_HEIGHT 1080
#define WXGA_WIDTH 1280
#define WXGA_HEIGHT 768
#define HD1080_WIDTH 1920
#define HD1080_HEIGHT 1080
#define ONEMP_WIDTH 1280
#define SXGA_WIDTH 1280
#define UXGA_WIDTH 1600
#define QXGA_WIDTH 2048
#define FIVEMP_WIDTH 2560
#define ONEMP_HEIGHT 960
#define SXGA_HEIGHT 1024
#define UXGA_HEIGHT 1200
#define QXGA_HEIGHT 1536
#define FIVEMP_HEIGHT 1920
typedef enum
{
RESOLUTION_MIN,
QCIF = RESOLUTION_MIN,
QVGA,
VGA,
WVGA,
WVGA_PLUS ,
HD720,
HD720_PLUS,
HD1080,
RESOLUTION_PREVIEW_VIDEO_MAX = HD1080,
WXGA,
MP1,
MP2,
MP3,
MP5,
MP8,
MP12,
RESOLUTION_MAX = MP12,
} Camera_Resolution;
typedef struct{
uint16_t width;
uint16_t height;
char * name;
char * str_name;
int supported;
} DIMENSION_TBL_T;
typedef enum {
WHITE_BALANCE_STATE,
WHITE_BALANCE_TEMPERATURE,
BRIGHTNESS_CTRL,
EV,
CONTRAST_CTRL,
SATURATION_CTRL,
SHARPNESS_CTRL
} Get_Ctrl_modes;
typedef enum {
AUTO_EXP_FRAME_AVG,
AUTO_EXP_CENTER_WEIGHTED,
AUTO_EXP_SPOT_METERING,
AUTO_EXP_SMART_METERING,
AUTO_EXP_USER_METERING,
AUTO_EXP_SPOT_METERING_ADV,
AUTO_EXP_CENTER_WEIGHTED_ADV,
AUTO_EXP_MAX
} Exp_Metering_modes;
typedef enum {
ISO_AUTO,
ISO_DEBLUR,
ISO_100,
ISO_200,
ISO_400,
ISO_800,
ISO_1600,
ISO_MAX
} ISO_modes;
typedef enum {
BESTSHOT_AUTO,
BESTSHOT_ACTION,
BESTSHOT_PORTRAIT,
BESTSHOT_LANDSCAPE,
BESTSHOT_NIGHT,
BESTSHOT_NIGHT_PORTRAIT,
BESTSHOT_THEATRE,
BESTSHOT_BEACH,
BESTSHOT_SNOW,
BESTSHOT_SUNSET,
BESTSHOT_ANTISHAKE,
BESTSHOT_FIREWORKS,
BESTSHOT_SPORTS,
BESTSHOT_PARTY,
BESTSHOT_CANDLELIGHT,
BESTSHOT_ASD,
BESTSHOT_BACKLIGHT,
BESTSHOT_FLOWERS,
BESTSHOT_AR,
BESTSHOT_HDR,
BESTSHOT_MAX
}Bestshot_modes;
typedef enum {
FLASH_MODE_OFF,
FLASH_MODE_AUTO,
FLASH_MODE_ON,
FLASH_MODE_TORCH,
FLASH_MODE_MAX,
}Flash_modes;
typedef enum {
WB_AUTO,
WB_INCANDESCENT,
WB_FLUORESCENT,
WB_WARM_FLUORESCENT,
WB_DAYLIGHT,
WB_CLOUDY_DAYLIGHT,
WB_TWILIGHT,
WB_SHADE,
WB_MAX
} White_Balance_modes;
typedef enum
{
MENU_ID_MAIN,
MENU_ID_WHITEBALANCECHANGE,
MENU_ID_EXPMETERINGCHANGE,
MENU_ID_GET_CTRL_VALUE,
MENU_ID_TOGGLEAFR,
MENU_ID_ISOCHANGE,
MENU_ID_BRIGHTNESSCHANGE,
MENU_ID_CONTRASTCHANGE,
MENU_ID_EVCHANGE,
MENU_ID_SATURATIONCHANGE,
MENU_ID_ZOOMCHANGE,
MENU_ID_SHARPNESSCHANGE,
MENU_ID_BESTSHOT,
MENU_ID_FLASHMODE,
MENU_ID_SENSORS,
MENU_ID_SWITCH_RES,
MENU_ID_INVALID,
} menu_id_change_t;
typedef enum
{
DECREASE_ZOOM,
INCREASE_ZOOM,
INCREASE_STEP_ZOOM,
DECREASE_STEP_ZOOM,
} Camera_Zoom;
typedef enum
{
INC_CONTRAST,
DEC_CONTRAST,
} Camera_Contrast_changes;
typedef enum
{
INC_BRIGHTNESS,
DEC_BRIGHTNESS,
} Camera_Brightness_changes;
typedef enum
{
INCREASE_EV,
DECREASE_EV,
} Camera_EV_changes;
typedef enum {
INC_SATURATION,
DEC_SATURATION,
} Camera_Saturation_changes;
typedef enum
{
INC_ISO,
DEC_ISO,
} Camera_ISO_changes;
typedef enum
{
INC_SHARPNESS,
DEC_SHARPNESS,
} Camera_Sharpness_changes;
typedef enum {
ZOOM_IN,
ZOOM_OUT,
} Zoom_direction;
typedef struct{
Camera_main_menu_t main_menu;
char * menu_name;
} CAMERA_MAIN_MENU_TBL_T;
typedef struct{
char * menu_name;
int present;
} CAMERA_SENSOR_MENU_TLB_T;
typedef struct{
Camera_Resolution cs_id;
uint16_t width;
uint16_t height;
char * name;
char * str_name;
} PREVIEW_DIMENSION_TBL_T;
typedef struct {
White_Balance_modes wb_id;
char * wb_name;
} WHITE_BALANCE_TBL_T;
typedef struct {
Get_Ctrl_modes get_ctrl_id;
char * get_ctrl_name;
} GET_CTRL_TBL_T;
typedef struct{
Exp_Metering_modes exp_metering_id;
char * exp_metering_name;
} EXP_METERING_TBL_T;
typedef struct {
Bestshot_modes bs_id;
char *name;
} BESTSHOT_MODE_TBT_T;
typedef struct {
Flash_modes bs_id;
char *name;
} FLASH_MODE_TBL_T;
typedef struct {
ISO_modes iso_modes;
char *iso_modes_name;
} ISO_TBL_T;
typedef struct {
Zoom_direction zoom_direction;
char * zoom_direction_name;
} ZOOM_TBL_T;
typedef struct {
Camera_Sharpness_changes sharpness_change;
char *sharpness_change_name;
} SHARPNESS_TBL_T;
typedef struct {
Camera_Brightness_changes bc_id;
char * brightness_name;
} CAMERA_BRIGHTNESS_TBL_T;
typedef struct {
Camera_Contrast_changes cc_id;
char * contrast_name;
} CAMERA_CONTRST_TBL_T;
typedef struct {
Camera_EV_changes ec_id;
char * EV_name;
} CAMERA_EV_TBL_T;
typedef struct {
Camera_Saturation_changes sc_id;
char * saturation_name;
} CAMERA_SATURATION_TBL_T;
typedef struct {
Camera_Sharpness_changes bc_id;
char * sharpness_name;
} CAMERA_SHARPNESS_TBL_T;
#endif /* __MM_QCAMERA_MAIN_MENU_H__ */

View file

@ -0,0 +1,113 @@
/* Copyright (c) 2013-2014, 2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __MM_QCAMERA_SOCKET_H__
#define __MM_QCAMERA_SOCKET_H__
// System dependencies
#include <arpa/inet.h>
#undef __FD_SET
#define __FD_SET(fd, fdsetp) \
(((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] |= (1LU<<((fd) & 31)))
#undef __FD_CLR
#define __FD_CLR(fd, fdsetp) \
(((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] &= ~(1LU<<((fd) & 31)))
#undef __FD_ISSET
#define __FD_ISSET(fd, fdsetp) \
((((fd_set *)(fdsetp))->fds_bits[(fd) >> 5] & (1LU<<((fd) & 31))) != 0)
#undef __FD_ZERO
#define __FD_ZERO(fdsetp) \
(memset (fdsetp, 0, sizeof (*(fd_set *)(fdsetp))))
#define TUNESERVER_MAX_RECV 2048
#define TUNESERVER_MAX(a, b) (((a) > (b)) ? (a) : (b))
#define TUNESERVER_GET_LIST 1014
#define TUNESERVER_GET_PARMS 1015
#define TUNESERVER_SET_PARMS 1016
#define TUNESERVER_MISC_CMDS 1021
#define TUNE_PREV_GET_INFO 0x0001
#define TUNE_PREV_CH_CNK_SIZE 0x0002
#define TUNE_PREV_GET_PREV_FRAME 0x0003
#define TUNE_PREV_GET_JPG_SNAP 0x0004
#define TUNE_PREV_GET_RAW_SNAP 0x0005
#define TUNE_PREV_GET_RAW_PREV 0x0006
typedef struct {
char data[128];
} tuneserver_misc_cmd;
typedef enum {
TUNESERVER_RECV_COMMAND = 1,
TUNESERVER_RECV_PAYLOAD_SIZE,
TUNESERVER_RECV_PAYLOAD,
TUNESERVER_RECV_RESPONSE,
TUNESERVERER_RECV_INVALID,
} tuneserver_recv_cmd_t;
typedef struct {
uint16_t current_cmd;
tuneserver_recv_cmd_t next_recv_code;
uint32_t next_recv_len;
void *recv_buf;
uint32_t recv_len;
uint32_t send_len;
void *send_buf;
} tuneserver_protocol_t;
typedef enum {
TUNE_PREV_RECV_COMMAND = 1,
TUNE_PREV_RECV_NEWCNKSIZE,
TUNE_PREV_RECV_INVALID
} tune_prev_cmd_t;
typedef struct _eztune_preview_protocol_t {
uint16_t current_cmd;
tune_prev_cmd_t next_recv_code;
uint32_t next_recv_len;
int32_t send_len;
char* send_buf;
uint32_t send_buf_size;
uint32_t new_cnk_size;
uint32_t new_cmd_available;
} prserver_protocol_t;
typedef union {
struct sockaddr addr;
struct sockaddr_in addr_in;
} mm_qcamera_sock_addr_t;
int eztune_server_start(void *lib_handle);
#endif /*__MM_QCAMERA_SOCKET_H__*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,291 @@
/* Copyright (c) 2012-2013, 2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
// To remove
#include <cutils/properties.h>
// Camera dependencies
#include "mm_qcamera_commands.h"
#include "mm_qcamera_dbg.h"
int tuneserver_initialize_prevtuningp(void * ctrl,
int pr_client_socket_id, cam_dimension_t dimension,
char **send_buf, uint32_t *send_len)
{
int result = 0;
mm_camera_lib_handle *lib_handle = (mm_camera_lib_handle *) ctrl;
tuningserver_t *tctrl = &lib_handle->tsctrl;
LOGD("E");
if (tctrl->tuning_params.func_tbl->prevcommand_process == NULL) {
LOGE("prevcommand_process is NULL");
return -1;
}
result = tctrl->tuning_params.func_tbl->prevcommand_process(
NULL, TUNE_PREVCMD_INIT, (void *)&pr_client_socket_id,
send_buf, send_len);
result = tctrl->tuning_params.func_tbl->prevcommand_process(
NULL, TUNE_PREVCMD_SETDIM, (void *)&dimension,
send_buf, send_len);
mm_camera_lib_set_preview_usercb(lib_handle,
(tctrl->tuning_params.func_tbl->prevframe_callback));
return result;
}
int tuneserver_deinitialize_prevtuningp(void * ctrl,
char **send_buf, uint32_t *send_len)
{
int result = 0;
tuningserver_t *tctrl = (tuningserver_t *) ctrl;
LOGD("E");
result = tctrl->tuning_params.func_tbl->prevcommand_process(
&tctrl->pr_proto, TUNE_PREVCMD_DEINIT, NULL, send_buf, send_len);
return result;
}
int tuneserver_preview_getinfo(void * ctrl, char **send_buf, uint32_t *send_len)
{
int result = 0;
tuningserver_t *tctrl = (tuningserver_t *) ctrl;
LOGD("E");
result = tctrl->tuning_params.func_tbl->prevcommand_process(
&tctrl->pr_proto, TUNE_PREVCMD_GETINFO, NULL, send_buf, send_len);
return result;
}
int tuneserver_preview_getchunksize(void * ctrl,
char **send_buf, uint32_t *send_len)
{
int result = 0;
tuningserver_t *tctrl = (tuningserver_t *) ctrl;
LOGD("E");
result = tctrl->tuning_params.func_tbl->prevcommand_process(
&tctrl->pr_proto, TUNE_PREVCMD_GETCHUNKSIZE,
(void *)&tctrl->pr_proto->new_cnk_size, send_buf, send_len);
return result;
}
int tuneserver_preview_getframe(void * ctrl,
char **send_buf, uint32_t *send_len)
{
int result = 0;
tuningserver_t *tctrl = (tuningserver_t *) ctrl;
LOGD("E");
result = tctrl->tuning_params.func_tbl->prevcommand_process(
&tctrl->pr_proto, TUNE_PREVCMD_GETFRAME, NULL, send_buf, send_len);
return result;
}
int tuneserver_preview_unsupported(void * ctrl,
char **send_buf, uint32_t *send_len)
{
int result = 0;
tuningserver_t *tctrl = (tuningserver_t *) ctrl;
LOGD("E");
result = tctrl->tuning_params.func_tbl->prevcommand_process(
&tctrl->pr_proto, TUNE_PREVCMD_UNSUPPORTED, NULL, send_buf, send_len);
return result;
}
int tuneserver_initialize_tuningp(void * ctrl, int client_socket_id,
char *send_buf, uint32_t send_len)
{
int result = 0;
mm_camera_lib_handle *lib_handle = (mm_camera_lib_handle *) ctrl;
tuningserver_t *tctrl = &lib_handle->tsctrl;
LOGD("E");
result = tctrl->tuning_params.func_tbl->command_process(
lib_handle, TUNE_CMD_INIT, &client_socket_id, send_buf, send_len);
return result;
}
int tuneserver_deinitialize_tuningp(void * ctrl, int client_socket_id,
char *send_buf, uint32_t send_len)
{
int result = 0;
tuningserver_t *tctrl = (tuningserver_t *) ctrl;
LOGD("E");
result = tctrl->tuning_params.func_tbl->command_process(
NULL, TUNE_CMD_DEINIT, &client_socket_id, send_buf, send_len);
return result;
}
int tuneserver_process_get_list_cmd(void * ctrl, void *recv_cmd,
char *send_buf, uint32_t send_len)
{
int result = 0;
tuningserver_t *tctrl = (tuningserver_t *) ctrl;
LOGD("E");
result = tctrl->tuning_params.func_tbl->command_process(
recv_cmd, TUNE_CMD_GET_LIST, NULL, send_buf, send_len);
return result;
}
int tuneserver_process_get_params_cmd(void * ctrl, void *recv_cmd,
char *send_buf, uint32_t send_len)
{
int result = 0;
tuningserver_t *tctrl = (tuningserver_t *) ctrl;
LOGD("E");
result = tctrl->tuning_params.func_tbl->command_process
(recv_cmd, TUNE_CMD_GET_PARAMS, NULL, send_buf, send_len);
return result;
}
int tuneserver_process_set_params_cmd(void * ctrl, void *recv_cmd,
char *send_buf, uint32_t send_len)
{
int result = 0;
tuningserver_t *tctrl = (tuningserver_t *) ctrl;
LOGD("E");
result = tctrl->tuning_params.func_tbl->command_process(
recv_cmd, TUNE_CMD_SET_PARAMS, NULL, send_buf, send_len);
return result;
}
int tuneserver_process_misc_cmd(void * ctrl, void *recv_cmd,
char *send_buf, uint32_t send_len)
{
int result = 0;
tuningserver_t *tctrl = (tuningserver_t *) ctrl;
LOGD("E");
result = tctrl->tuning_params.func_tbl->command_process(
recv_cmd, TUNE_CMD_MISC, NULL, send_buf, send_len);
return result;
}
/** tuneserver_close_cam
* @lib_handle: the camera handle object
*
* closes the camera
*
* Return: >=0 on success, -1 on failure.
**/
int tuneserver_close_cam(mm_camera_lib_handle *lib_handle)
{
int result = 0;
result = mm_camera_lib_close(lib_handle);
if (result < 0) {
printf(" Camera close failed\n");
} else {
printf("Camera is closed \n");
}
return result;
}
#if 0
/** tuneserver_start_cam
* @lib_handle: the camera handle object
*
* starts the camera
*
* Return: >=0 on success, -1 on failure.
**/
static int tuneserver_start_cam(mm_camera_lib_handle *lib_handle)
{
int result = 0;
result = mm_camera_lib_start_stream(lib_handle);
if (result < 0) {
printf(" Camera start failed\n");
goto error1;
}
return result;
error1:
mm_camera_lib_close(lib_handle);
return result;
}
#endif
/** tuneserver_stop_cam
* @lib_handle: the camera handle object
*
* stops the camera
*
* Return: >=0 on success, -1 on failure.
**/
int tuneserver_stop_cam(mm_camera_lib_handle *lib_handle)
{
int result = 0;
result = mm_camera_lib_stop_stream(lib_handle);
if (result < 0) {
printf(" Camera stop failed\n");
}
// result = mm_camera_lib_close(lib_handle);
return result;
}
/** tuneserver_open_cam
* @lib_handle: the camera handle object
*
* opens the camera
*
* Return: >=0 on success, -1 on failure.
**/
#if 1
int tuneserver_open_cam(mm_camera_lib_handle *lib_handle)
{
int result = 0;
LOGD("E");
result = mm_camera_load_tuninglibrary(&lib_handle->tsctrl.tuning_params);
if (result < 0) {
LOGE(" tuning library open failed\n");
}
return result;
}
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,168 @@
/* Copyright (c) 2012, 2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
// Camera dependencies
#include "mm_qcamera_app.h"
#include "mm_qcamera_dbg.h"
int mm_camera_queue_init(mm_camera_queue_t *queue,
release_data_fn data_rel_fn,
void *user_data)
{
if ( NULL == queue ) {
return -1;
}
pthread_mutex_init(&queue->m_lock, NULL);
cam_list_init(&queue->m_head.list);
queue->m_size = 0;
queue->m_dataFn = data_rel_fn;
queue->m_userData = user_data;
return MM_CAMERA_OK;
}
int mm_qcamera_queue_release(mm_camera_queue_t *queue)
{
if ( NULL == queue ) {
return -1;
}
mm_qcamera_queue_flush(queue);
pthread_mutex_destroy(&queue->m_lock);
return MM_CAMERA_OK;
}
int mm_qcamera_queue_isempty(mm_camera_queue_t *queue)
{
if ( NULL == queue ) {
return 0;
}
int flag = 1;
pthread_mutex_lock(&queue->m_lock);
if (queue->m_size > 0) {
flag = 0;
}
pthread_mutex_unlock(&queue->m_lock);
return flag;
}
int mm_qcamera_queue_enqueue(mm_camera_queue_t *queue, void *data)
{
if ( NULL == queue ) {
return -1;
}
camera_q_node *node =
(camera_q_node *)malloc(sizeof(camera_q_node));
if (NULL == node) {
LOGE(" No memory for camera_q_node");
return 0;
}
memset(node, 0, sizeof(camera_q_node));
node->data = data;
pthread_mutex_lock(&queue->m_lock);
cam_list_add_tail_node(&node->list, &queue->m_head.list);
queue->m_size++;
pthread_mutex_unlock(&queue->m_lock);
return 1;
}
void* mm_qcamera_queue_dequeue(mm_camera_queue_t *queue, int bFromHead)
{
if ( NULL == queue ) {
return NULL;
}
camera_q_node* node = NULL;
void* data = NULL;
struct cam_list *head = NULL;
struct cam_list *pos = NULL;
pthread_mutex_lock(&queue->m_lock);
head = &queue->m_head.list;
if (bFromHead) {
pos = head->next;
} else {
pos = head->prev;
}
if (pos != head) {
node = member_of(pos, camera_q_node, list);
cam_list_del_node(&node->list);
queue->m_size--;
}
pthread_mutex_unlock(&queue->m_lock);
if (NULL != node) {
data = node->data;
free(node);
}
return data;
}
void mm_qcamera_queue_flush(mm_camera_queue_t *queue)
{
camera_q_node* node = NULL;
struct cam_list *head = NULL;
struct cam_list *pos = NULL;
if ( NULL == queue ) {
return;
}
pthread_mutex_lock(&queue->m_lock);
head = &queue->m_head.list;
pos = head->next;
while(pos != head) {
node = member_of(pos, camera_q_node, list);
pos = pos->next;
cam_list_del_node(&node->list);
queue->m_size--;
if (NULL != node->data) {
if (queue->m_dataFn) {
queue->m_dataFn(node->data, queue->m_userData);
}
free(node->data);
}
free(node);
}
queue->m_size = 0;
pthread_mutex_unlock(&queue->m_lock);
}

View file

@ -0,0 +1,345 @@
/*
Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of The Linux Foundation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// System dependencies
#include <fcntl.h>
// Camera dependencies
#include "mm_qcamera_app.h"
#include "mm_qcamera_dbg.h"
static uint32_t rdi_len = 0;
static void mm_app_rdi_dump_frame(mm_camera_buf_def_t *frame,
char *name,
char *ext,
uint32_t frame_idx)
{
char file_name[FILENAME_MAX];
int file_fd;
int i;
if (frame != NULL) {
snprintf(file_name, sizeof(file_name),
QCAMERA_DUMP_FRM_LOCATION"%s_%03u.%s", name, frame_idx, ext);
file_fd = open(file_name, O_RDWR | O_CREAT, 0777);
if (file_fd < 0) {
LOGE(" cannot open file %s \n", file_name);
} else {
for (i = 0; i < frame->planes_buf.num_planes; i++) {
write(file_fd,
(uint8_t *)frame->buffer + frame->planes_buf.planes[i].data_offset,
rdi_len);
}
close(file_fd);
LOGD(" dump rdi frame %s", file_name);
}
}
}
static void mm_app_rdi_notify_cb(mm_camera_super_buf_t *bufs,
void *user_data)
{
char file_name[FILENAME_MAX];
mm_camera_buf_def_t *frame = bufs->bufs[0];
mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
LOGD(" BEGIN - length=%zu, frame idx = %d stream_id=%d\n",
frame->frame_len, frame->frame_idx, frame->stream_id);
snprintf(file_name, sizeof(file_name), "RDI_dump_%d", pme->cam->camera_handle);
mm_app_rdi_dump_frame(frame, file_name, "raw", frame->frame_idx);
if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
bufs->ch_id,
frame)) {
LOGE(" Failed in RDI Qbuf\n");
}
mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info,
ION_IOC_INV_CACHES);
LOGD(" END\n");
}
mm_camera_stream_t * mm_app_add_rdi_stream(mm_camera_test_obj_t *test_obj,
mm_camera_channel_t *channel,
mm_camera_buf_notify_t stream_cb,
void *userdata,
uint8_t num_bufs,
uint8_t num_burst)
{
int rc = MM_CAMERA_OK;
size_t i;
mm_camera_stream_t *stream = NULL;
cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
cam_format_t fmt = CAM_FORMAT_MAX;
cam_stream_buf_plane_info_t *buf_planes;
cam_stream_size_info_t abc ;
memset (&abc , 0, sizeof (cam_stream_size_info_t));
LOGE(" raw_dim w:%d height:%d\n", cam_cap->raw_dim[0].width, cam_cap->raw_dim[0].height);
for (i = 0;i < cam_cap->supported_raw_fmt_cnt;i++) {
LOGE(" supported_raw_fmts[%zd]=%d\n",
i, (int)cam_cap->supported_raw_fmts[i]);
if (((CAM_FORMAT_BAYER_MIPI_RAW_8BPP_GBRG <= cam_cap->supported_raw_fmts[i]) &&
(CAM_FORMAT_BAYER_MIPI_RAW_12BPP_BGGR >= cam_cap->supported_raw_fmts[i])) ||
(cam_cap->supported_raw_fmts[i] == CAM_FORMAT_META_RAW_8BIT) ||
(cam_cap->supported_raw_fmts[i] == CAM_FORMAT_JPEG_RAW_8BIT))
{
fmt = cam_cap->supported_raw_fmts[i];
LOGE(" fmt=%d\n", fmt);
}
}
if (CAM_FORMAT_MAX == fmt) {
LOGE(" rdi format not supported\n");
return NULL;
}
abc.num_streams = 1;
abc.postprocess_mask[0] = 0;
abc.stream_sizes[0].width = cam_cap->raw_dim[0].width;
abc.stream_sizes[0].height = cam_cap->raw_dim[0].height;
abc.type[0] = CAM_STREAM_TYPE_RAW;
abc.buffer_info.min_buffers = num_bufs;
abc.buffer_info.max_buffers = num_bufs;
abc.is_type = IS_TYPE_NONE;
rc = setmetainfoCommand(test_obj, &abc);
if (rc != MM_CAMERA_OK) {
LOGE(" meta info command failed\n");
}
stream = mm_app_add_stream(test_obj, channel);
if (NULL == stream) {
LOGE(" add stream failed\n");
return NULL;
}
stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
stream->s_config.mem_vtbl.clean_invalidate_buf =
mm_app_stream_clean_invalidate_buf;
stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
stream->s_config.mem_vtbl.user_data = (void *)stream;
stream->s_config.stream_cb = stream_cb;
stream->s_config.stream_cb_sync = NULL;
stream->s_config.userdata = userdata;
stream->num_of_bufs = num_bufs;
stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_RAW;
if (num_burst == 0) {
stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
} else {
stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
stream->s_config.stream_info->num_of_burst = num_burst;
}
stream->s_config.stream_info->fmt = DEFAULT_RAW_FORMAT;
LOGD(" RAW: w: %d, h: %d ",
cam_cap->raw_dim[0].width, cam_cap->raw_dim[0].height);
stream->s_config.stream_info->dim.width = cam_cap->raw_dim[0].width;
stream->s_config.stream_info->dim.height = cam_cap->raw_dim[0].height;
stream->s_config.padding_info = cam_cap->padding_info;
rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
if (MM_CAMERA_OK != rc) {
LOGE("config rdi stream err=%d\n", rc);
return NULL;
}
buf_planes = &stream->s_config.stream_info->buf_planes;
rdi_len = buf_planes->plane_info.mp[0].len;
LOGD(" plane_info %dx%d len:%d frame_len:%d\n",
buf_planes->plane_info.mp[0].stride, buf_planes->plane_info.mp[0].scanline,
buf_planes->plane_info.mp[0].len, buf_planes->plane_info.frame_len);
return stream;
}
mm_camera_stream_t * mm_app_add_rdi_snapshot_stream(mm_camera_test_obj_t *test_obj,
mm_camera_channel_t *channel,
mm_camera_buf_notify_t stream_cb,
void *userdata,
uint8_t num_bufs,
uint8_t num_burst)
{
int rc = MM_CAMERA_OK;
mm_camera_stream_t *stream = NULL;
cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
stream = mm_app_add_stream(test_obj, channel);
if (NULL == stream) {
LOGE(" add stream failed\n");
return NULL;
}
stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
stream->s_config.mem_vtbl.clean_invalidate_buf =
mm_app_stream_clean_invalidate_buf;
stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
stream->s_config.mem_vtbl.user_data = (void *)stream;
stream->s_config.stream_cb = stream_cb;
stream->s_config.stream_cb_sync = NULL;
stream->s_config.userdata = userdata;
stream->num_of_bufs = num_bufs;
stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_SNAPSHOT;
if (num_burst == 0) {
stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
} else {
stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
stream->s_config.stream_info->num_of_burst = num_burst;
}
stream->s_config.stream_info->fmt = DEFAULT_SNAPSHOT_FORMAT;
stream->s_config.stream_info->dim.width = DEFAULT_SNAPSHOT_WIDTH;
stream->s_config.stream_info->dim.height = DEFAULT_SNAPSHOT_HEIGHT;
stream->s_config.padding_info = cam_cap->padding_info;
rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
if (MM_CAMERA_OK != rc) {
LOGE("config rdi stream err=%d\n", rc);
return NULL;
}
return stream;
}
mm_camera_channel_t * mm_app_add_rdi_channel(mm_camera_test_obj_t *test_obj, uint8_t num_burst)
{
mm_camera_channel_t *channel = NULL;
mm_camera_stream_t *stream = NULL;
channel = mm_app_add_channel(test_obj,
MM_CHANNEL_TYPE_RDI,
NULL,
NULL,
NULL);
if (NULL == channel) {
LOGE(" add channel failed");
return NULL;
}
stream = mm_app_add_rdi_stream(test_obj,
channel,
mm_app_rdi_notify_cb,
(void *)test_obj,
RDI_BUF_NUM,
num_burst);
if (NULL == stream) {
LOGE(" add stream failed\n");
mm_app_del_channel(test_obj, channel);
return NULL;
}
LOGD(" channel=%d stream=%d\n", channel->ch_id, stream->s_id);
return channel;
}
int mm_app_stop_and_del_rdi_channel(mm_camera_test_obj_t *test_obj,
mm_camera_channel_t *channel)
{
int rc = MM_CAMERA_OK;
mm_camera_stream_t *stream = NULL;
uint8_t i;
cam_stream_size_info_t abc ;
memset (&abc , 0, sizeof (cam_stream_size_info_t));
rc = mm_app_stop_channel(test_obj, channel);
if (MM_CAMERA_OK != rc) {
LOGE("Stop RDI failed rc=%d\n", rc);
}
if (channel->num_streams <= MAX_STREAM_NUM_IN_BUNDLE) {
for (i = 0; i < channel->num_streams; i++) {
stream = &channel->streams[i];
rc = mm_app_del_stream(test_obj, channel, stream);
if (MM_CAMERA_OK != rc) {
LOGE("del stream(%d) failed rc=%d\n", i, rc);
}
}
} else {
LOGE(" num_streams = %d. Should not be more than %d\n",
channel->num_streams, MAX_STREAM_NUM_IN_BUNDLE);
}
rc = setmetainfoCommand(test_obj, &abc);
if (rc != MM_CAMERA_OK) {
LOGE(" meta info command failed\n");
}
rc = mm_app_del_channel(test_obj, channel);
if (MM_CAMERA_OK != rc) {
LOGE("delete channel failed rc=%d\n", rc);
}
return rc;
}
int mm_app_start_rdi(mm_camera_test_obj_t *test_obj, uint8_t num_burst)
{
int rc = MM_CAMERA_OK;
mm_camera_channel_t *channel = NULL;
channel = mm_app_add_rdi_channel(test_obj, num_burst);
if (NULL == channel) {
LOGE(" add channel failed");
return -MM_CAMERA_E_GENERAL;
}
rc = mm_app_start_channel(test_obj, channel);
if (MM_CAMERA_OK != rc) {
LOGE("start rdi failed rc=%d\n", rc);
mm_app_del_channel(test_obj, channel);
return rc;
}
return rc;
}
int mm_app_stop_rdi(mm_camera_test_obj_t *test_obj)
{
int rc = MM_CAMERA_OK;
mm_camera_channel_t *channel =
mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_RDI);
rc = mm_app_stop_and_del_rdi_channel(test_obj, channel);
if (MM_CAMERA_OK != rc) {
LOGE("Stop RDI failed rc=%d\n", rc);
}
return rc;
}

View file

@ -0,0 +1,349 @@
/*
Copyright (c) 2012-2014, 2016, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of The Linux Foundation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// Camera dependencies
#include "mm_qcamera_app.h"
#include "mm_qcamera_dbg.h"
static void mm_app_reprocess_notify_cb(mm_camera_super_buf_t *bufs,
void *user_data)
{
mm_camera_buf_def_t *frame = bufs->bufs[0];
mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
mm_camera_channel_t *channel = NULL;
mm_camera_stream_t *m_stream = NULL;
mm_camera_buf_def_t *m_frame = NULL;
mm_camera_super_buf_t *src_frame;
int i = 0;
int rc = 0;
LOGE(" BEGIN - length=%zu, frame idx = %d\n",
frame->frame_len, frame->frame_idx);
/* find channel */
for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
if (pme->channels[i].ch_id == bufs->ch_id) {
channel = &pme->channels[i];
break;
}
}
if (NULL == channel) {
LOGE(" Wrong channel id (%d)", bufs->ch_id);
return;
}
// We have only one stream and buffer
// in the reprocess channel.
m_stream = &channel->streams[0];
m_frame = bufs->bufs[0];
if ( pme->encodeJpeg ) {
pme->jpeg_buf.buf.buffer = (uint8_t *)malloc(m_frame->frame_len);
if ( NULL == pme->jpeg_buf.buf.buffer ) {
LOGE(" error allocating jpeg output buffer");
goto exit;
}
pme->jpeg_buf.buf.frame_len = m_frame->frame_len;
/* create a new jpeg encoding session */
rc = createEncodingSession(pme, m_stream, m_frame);
if (0 != rc) {
LOGE(" error creating jpeg session");
free(pme->jpeg_buf.buf.buffer);
goto exit;
}
/* start jpeg encoding job */
LOGE("Encoding reprocessed frame!!");
rc = encodeData(pme, bufs, m_stream);
pme->encodeJpeg = 0;
} else {
if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
bufs->ch_id,
frame)) {
LOGE(" Failed in Reprocess Qbuf\n");
}
mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info,
ION_IOC_INV_CACHES);
}
exit:
// Release source frame
src_frame = ( mm_camera_super_buf_t * ) mm_qcamera_queue_dequeue(&pme->pp_frames, 1);
if ( NULL != src_frame ) {
mm_app_release_ppinput((void *) src_frame, (void *) pme);
}
LOGE(" END\n");
}
mm_camera_stream_t * mm_app_add_reprocess_stream_from_source(mm_camera_test_obj_t *test_obj,
mm_camera_channel_t *channel,
mm_camera_stream_t *source,
mm_camera_buf_notify_t stream_cb,
cam_pp_feature_config_t pp_config,
void *userdata,
uint8_t num_bufs)
{
int rc = MM_CAMERA_OK;
mm_camera_stream_t *stream = NULL;
cam_capability_t *cam_cap = NULL;
cam_stream_info_t *source_stream_info;
if ( ( NULL == test_obj ) ||
( NULL == channel ) ||
( NULL == source ) ) {
LOGE(" Invalid input\n");
return NULL;
}
cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
stream = mm_app_add_stream(test_obj, channel);
if (NULL == stream) {
LOGE(" add stream failed\n");
return NULL;
}
stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
stream->s_config.mem_vtbl.clean_invalidate_buf =
mm_app_stream_clean_invalidate_buf;
stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
stream->s_config.mem_vtbl.user_data = (void *)stream;
stream->s_config.stream_cb = stream_cb;
stream->s_config.stream_cb_sync = NULL;
stream->s_config.userdata = userdata;
stream->num_of_bufs = num_bufs;
stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
source_stream_info = (cam_stream_info_t *) source->s_info_buf.buf.buffer;
memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_OFFLINE_PROC;
stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
stream->s_config.stream_info->fmt = source_stream_info->fmt;
stream->s_config.stream_info->dim = source_stream_info->dim;
stream->s_config.padding_info = cam_cap->padding_info;
stream->s_config.stream_info->reprocess_config.pp_type = CAM_ONLINE_REPROCESS_TYPE;
stream->s_config.stream_info->reprocess_config.online.input_stream_id = source->s_config.stream_info->stream_svr_id;
stream->s_config.stream_info->reprocess_config.online.input_stream_type = source->s_config.stream_info->stream_type;
stream->s_config.stream_info->reprocess_config.pp_feature_config = pp_config;
rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
if (MM_CAMERA_OK != rc) {
LOGE("config preview stream err=%d\n", rc);
return NULL;
}
return stream;
}
mm_camera_channel_t * mm_app_add_reprocess_channel(mm_camera_test_obj_t *test_obj,
mm_camera_stream_t *source_stream)
{
mm_camera_channel_t *channel = NULL;
mm_camera_stream_t *stream = NULL;
if ( NULL == source_stream ) {
LOGE(" add reprocess stream failed\n");
return NULL;
}
channel = mm_app_add_channel(test_obj,
MM_CHANNEL_TYPE_REPROCESS,
NULL,
NULL,
NULL);
if (NULL == channel) {
LOGE(" add channel failed");
return NULL;
}
// pp feature config
cam_pp_feature_config_t pp_config;
memset(&pp_config, 0, sizeof(cam_pp_feature_config_t));
cam_capability_t *caps = ( cam_capability_t * ) ( test_obj->cap_buf.buf.buffer );
if (caps->qcom_supported_feature_mask & CAM_QCOM_FEATURE_SHARPNESS) {
pp_config.feature_mask |= CAM_QCOM_FEATURE_SHARPNESS;
pp_config.sharpness = test_obj->reproc_sharpness;
}
if (test_obj->reproc_wnr.denoise_enable) {
pp_config.feature_mask |= CAM_QCOM_FEATURE_DENOISE2D;
pp_config.denoise2d = test_obj->reproc_wnr;
}
if (test_obj->enable_CAC) {
pp_config.feature_mask |= CAM_QCOM_FEATURE_CAC;
}
uint8_t minStreamBufNum = source_stream->num_of_bufs;
stream = mm_app_add_reprocess_stream_from_source(test_obj,
channel,
source_stream,
mm_app_reprocess_notify_cb,
pp_config,
(void *)test_obj,
minStreamBufNum);
if (NULL == stream) {
LOGE(" add reprocess stream failed\n");
mm_app_del_channel(test_obj, channel);
return NULL;
}
test_obj->reproc_stream = stream;
return channel;
}
int mm_app_start_reprocess(mm_camera_test_obj_t *test_obj)
{
int rc = MM_CAMERA_OK;
mm_camera_channel_t *r_ch = NULL;
mm_camera_queue_init(&test_obj->pp_frames,
mm_app_release_ppinput,
( void * ) test_obj);
r_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_REPROCESS);
if (MM_CAMERA_OK != rc) {
LOGE(" No initialized reprocess channel d rc=%d\n", rc);
return rc;
}
rc = mm_app_start_channel(test_obj, r_ch);
if (MM_CAMERA_OK != rc) {
LOGE("start reprocess failed rc=%d\n", rc);
mm_app_del_channel(test_obj, r_ch);
return rc;
}
return rc;
}
int mm_app_stop_reprocess(mm_camera_test_obj_t *test_obj)
{
int rc = MM_CAMERA_OK;
mm_camera_channel_t *r_ch = NULL;
r_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_REPROCESS);
if (MM_CAMERA_OK != rc) {
LOGE(" No initialized reprocess channel d rc=%d\n", rc);
return rc;
}
rc = mm_app_stop_and_del_channel(test_obj, r_ch);
if (MM_CAMERA_OK != rc) {
LOGE("Stop Preview failed rc=%d\n", rc);
}
mm_qcamera_queue_release(&test_obj->pp_frames);
test_obj->reproc_stream = NULL;
return rc;
}
int mm_app_do_reprocess(mm_camera_test_obj_t *test_obj,
mm_camera_buf_def_t *frame,
uint32_t meta_idx,
mm_camera_super_buf_t *super_buf,
mm_camera_stream_t *src_meta)
{
int rc = MM_CAMERA_OK;
mm_camera_channel_t *r_ch = NULL;
mm_camera_super_buf_t *src_buf = NULL;
if ( ( NULL == test_obj ) ||
( NULL == frame ) ||
( NULL == super_buf )) {
LOGE(" Invalid input rc=%d\n", rc);
return rc;
}
if ( NULL == test_obj->reproc_stream ) {
LOGE(" No reprocess stream rc=%d\n", rc);
return rc;
}
r_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_REPROCESS);
if (MM_CAMERA_OK != rc) {
LOGE(" No reprocess channel rc=%d\n", rc);
return rc;
}
src_buf = ( mm_camera_super_buf_t * ) malloc(sizeof(mm_camera_super_buf_t));
if ( NULL == src_buf ) {
LOGE(" No resources for src frame rc=%d\n", rc);
return -1;
}
memcpy(src_buf, super_buf, sizeof(mm_camera_super_buf_t));
mm_qcamera_queue_enqueue(&test_obj->pp_frames, src_buf);
cam_stream_parm_buffer_t param;
memset(&param, 0, sizeof(cam_stream_parm_buffer_t));
param.type = CAM_STREAM_PARAM_TYPE_DO_REPROCESS;
param.reprocess.buf_index = frame->buf_idx;
param.reprocess.frame_idx = frame->frame_idx;
if (src_meta != NULL) {
param.reprocess.meta_present = 1;
param.reprocess.meta_stream_handle = src_meta->s_config.stream_info->stream_svr_id;
param.reprocess.meta_buf_index = meta_idx;
} else {
LOGE(" No metadata source stream rc=%d\n", rc);
}
test_obj->reproc_stream->s_config.stream_info->parm_buf = param;
rc = test_obj->cam->ops->set_stream_parms(test_obj->cam->camera_handle,
r_ch->ch_id,
test_obj->reproc_stream->s_id,
&test_obj->reproc_stream->s_config.stream_info->parm_buf);
return rc;
}
void mm_app_release_ppinput(void *data, void *user_data)
{
uint32_t i = 0;
mm_camera_super_buf_t *recvd_frame = ( mm_camera_super_buf_t * ) data;
mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
for ( i = 0 ; i < recvd_frame->num_bufs ; i++) {
if (MM_CAMERA_OK != pme->cam->ops->qbuf(pme->cam->camera_handle,
recvd_frame->ch_id,
recvd_frame->bufs[i])) {
LOGE(" Failed in Qbuf\n");
}
mm_app_cache_ops((mm_camera_app_meminfo_t *) recvd_frame->bufs[i]->mem_info,
ION_IOC_INV_CACHES);
}
}

View file

@ -0,0 +1,710 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
// Camera dependencies
#include "mm_qcamera_app.h"
#include "mm_qcamera_dbg.h"
/* This callback is received once the complete JPEG encoding is done */
static void jpeg_encode_cb(jpeg_job_status_t status,
uint32_t client_hdl,
uint32_t jobId,
mm_jpeg_output_t *p_buf,
void *userData)
{
uint32_t i = 0;
mm_camera_test_obj_t *pme = NULL;
LOGD(" BEGIN\n");
pme = (mm_camera_test_obj_t *)userData;
if (pme->jpeg_hdl != client_hdl ||
jobId != pme->current_job_id ||
!pme->current_job_frames) {
LOGE(" NULL current job frames or not matching job ID (%d, %d)",
jobId, pme->current_job_id);
return;
}
/* dump jpeg img */
LOGE(" job %d, status=%d", jobId, status);
if (status == JPEG_JOB_STATUS_DONE && p_buf != NULL) {
mm_app_dump_jpeg_frame(p_buf->buf_vaddr, p_buf->buf_filled_len, "jpeg", "jpg", jobId);
}
/* buf done current encoding frames */
pme->current_job_id = 0;
for (i = 0; i < pme->current_job_frames->num_bufs; i++) {
if (MM_CAMERA_OK != pme->cam->ops->qbuf(pme->current_job_frames->camera_handle,
pme->current_job_frames->ch_id,
pme->current_job_frames->bufs[i])) {
LOGE(" Failed in Qbuf\n");
}
mm_app_cache_ops((mm_camera_app_meminfo_t *) pme->current_job_frames->bufs[i]->mem_info,
ION_IOC_INV_CACHES);
}
free(pme->jpeg_buf.buf.buffer);
free(pme->current_job_frames);
pme->current_job_frames = NULL;
/* signal snapshot is done */
mm_camera_app_done();
}
int encodeData(mm_camera_test_obj_t *test_obj, mm_camera_super_buf_t* recvd_frame,
mm_camera_stream_t *m_stream)
{
cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
int rc = -MM_CAMERA_E_GENERAL;
mm_jpeg_job_t job;
/* remember current frames being encoded */
test_obj->current_job_frames =
(mm_camera_super_buf_t *)malloc(sizeof(mm_camera_super_buf_t));
if (!test_obj->current_job_frames) {
LOGE(" No memory for current_job_frames");
return rc;
}
*(test_obj->current_job_frames) = *recvd_frame;
memset(&job, 0, sizeof(job));
job.job_type = JPEG_JOB_TYPE_ENCODE;
job.encode_job.session_id = test_obj->current_jpeg_sess_id;
// TODO: Rotation should be set according to
// sensor&device orientation
job.encode_job.rotation = 0;
if (cam_cap->position == CAM_POSITION_BACK) {
job.encode_job.rotation = 270;
}
/* fill in main src img encode param */
job.encode_job.main_dim.src_dim = m_stream->s_config.stream_info->dim;
job.encode_job.main_dim.dst_dim = m_stream->s_config.stream_info->dim;
job.encode_job.src_index = 0;
job.encode_job.thumb_dim.src_dim = m_stream->s_config.stream_info->dim;
job.encode_job.thumb_dim.dst_dim.width = DEFAULT_PREVIEW_WIDTH;
job.encode_job.thumb_dim.dst_dim.height = DEFAULT_PREVIEW_HEIGHT;
/* fill in sink img param */
job.encode_job.dst_index = 0;
if (test_obj->metadata != NULL) {
job.encode_job.p_metadata = test_obj->metadata;
} else {
LOGE(" Metadata null, not set for jpeg encoding");
}
rc = test_obj->jpeg_ops.start_job(&job, &test_obj->current_job_id);
if ( 0 != rc ) {
free(test_obj->current_job_frames);
test_obj->current_job_frames = NULL;
}
return rc;
}
int createEncodingSession(mm_camera_test_obj_t *test_obj,
mm_camera_stream_t *m_stream,
mm_camera_buf_def_t *m_frame)
{
mm_jpeg_encode_params_t encode_param;
memset(&encode_param, 0, sizeof(mm_jpeg_encode_params_t));
encode_param.jpeg_cb = jpeg_encode_cb;
encode_param.userdata = (void*)test_obj;
encode_param.encode_thumbnail = 0;
encode_param.quality = 85;
encode_param.color_format = MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V2;
encode_param.thumb_color_format = MM_JPEG_COLOR_FORMAT_YCRCBLP_H2V2;
/* fill in main src img encode param */
encode_param.num_src_bufs = 1;
encode_param.src_main_buf[0].index = 0;
encode_param.src_main_buf[0].buf_size = m_frame->frame_len;
encode_param.src_main_buf[0].buf_vaddr = (uint8_t *)m_frame->buffer;
encode_param.src_main_buf[0].fd = m_frame->fd;
encode_param.src_main_buf[0].format = MM_JPEG_FMT_YUV;
encode_param.src_main_buf[0].offset = m_stream->offset;
/* fill in sink img param */
encode_param.num_dst_bufs = 1;
encode_param.dest_buf[0].index = 0;
encode_param.dest_buf[0].buf_size = test_obj->jpeg_buf.buf.frame_len;
encode_param.dest_buf[0].buf_vaddr = (uint8_t *)test_obj->jpeg_buf.buf.buffer;
encode_param.dest_buf[0].fd = test_obj->jpeg_buf.buf.fd;
encode_param.dest_buf[0].format = MM_JPEG_FMT_YUV;
/* main dimension */
encode_param.main_dim.src_dim = m_stream->s_config.stream_info->dim;
encode_param.main_dim.dst_dim = m_stream->s_config.stream_info->dim;
return test_obj->jpeg_ops.create_session(test_obj->jpeg_hdl,
&encode_param,
&test_obj->current_jpeg_sess_id);
}
/** mm_app_snapshot_metadata_notify_cb
* @bufs: Pointer to super buffer
* @user_data: Pointer to user data
*
*
**/
static void mm_app_snapshot_metadata_notify_cb(mm_camera_super_buf_t *bufs,
void *user_data)
{
uint32_t i = 0;
mm_camera_channel_t *channel = NULL;
mm_camera_stream_t *p_stream = NULL;
mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
mm_camera_buf_def_t *frame;
metadata_buffer_t *pMetadata;
if (NULL == bufs || NULL == user_data) {
LOGE(" bufs or user_data are not valid ");
return;
}
frame = bufs->bufs[0];
/* find channel */
for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
if (pme->channels[i].ch_id == bufs->ch_id) {
channel = &pme->channels[i];
break;
}
}
if (NULL == channel) {
LOGE(" Channel object is null");
return;
}
/* find meta stream */
for (i = 0; i < channel->num_streams; i++) {
if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_METADATA) {
p_stream = &channel->streams[i];
break;
}
}
if (NULL == p_stream) {
LOGE(" cannot find metadata stream");
return;
}
/* find meta frame */
for (i = 0; i < bufs->num_bufs; i++) {
if (bufs->bufs[i]->stream_id == p_stream->s_id) {
frame = bufs->bufs[i];
break;
}
}
if (!pme->metadata) {
/* The app will free the metadata, we don't need to bother here */
pme->metadata = malloc(sizeof(metadata_buffer_t));
if (NULL == pme->metadata) {
LOGE(" malloc failed");
return;
}
}
memcpy(pme->metadata , frame->buffer, sizeof(metadata_buffer_t));
pMetadata = (metadata_buffer_t *)frame->buffer;
IF_META_AVAILABLE(cam_auto_focus_data_t, focus_data,
CAM_INTF_META_AUTOFOCUS_DATA, pMetadata) {
if (focus_data->focus_state == CAM_AF_STATE_FOCUSED_LOCKED) {
LOGE(" AutoFocus Done Call Back Received\n");
mm_camera_app_done();
} else if (focus_data->focus_state == CAM_AF_STATE_NOT_FOCUSED_LOCKED) {
LOGE(" AutoFocus failed\n");
mm_camera_app_done();
}
}
if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
bufs->ch_id,
frame)) {
LOGE(" Failed in Preview Qbuf\n");
}
mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info,
ION_IOC_INV_CACHES);
}
static void mm_app_snapshot_notify_cb_raw(mm_camera_super_buf_t *bufs,
void *user_data)
{
int rc;
uint32_t i = 0;
mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
mm_camera_channel_t *channel = NULL;
mm_camera_stream_t *m_stream = NULL;
mm_camera_buf_def_t *m_frame = NULL;
LOGD(" BEGIN\n");
/* find channel */
for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
if (pme->channels[i].ch_id == bufs->ch_id) {
channel = &pme->channels[i];
break;
}
}
if (NULL == channel) {
LOGE(" Wrong channel id (%d)", bufs->ch_id);
rc = -1;
goto EXIT;
}
/* find snapshot stream */
for (i = 0; i < channel->num_streams; i++) {
if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_RAW) {
m_stream = &channel->streams[i];
break;
}
}
if (NULL == m_stream) {
LOGE(" cannot find snapshot stream");
rc = -1;
goto EXIT;
}
/* find snapshot frame */
for (i = 0; i < bufs->num_bufs; i++) {
if (bufs->bufs[i]->stream_id == m_stream->s_id) {
m_frame = bufs->bufs[i];
break;
}
}
if (NULL == m_frame) {
LOGE(" main frame is NULL");
rc = -1;
goto EXIT;
}
mm_app_dump_frame(m_frame, "main", "raw", m_frame->frame_idx);
EXIT:
for (i=0; i<bufs->num_bufs; i++) {
if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
bufs->ch_id,
bufs->bufs[i])) {
LOGE(" Failed in Qbuf\n");
}
}
mm_camera_app_done();
LOGD(" END\n");
}
static void mm_app_snapshot_notify_cb(mm_camera_super_buf_t *bufs,
void *user_data)
{
int rc = 0;
uint32_t i = 0;
mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
mm_camera_channel_t *channel = NULL;
mm_camera_stream_t *p_stream = NULL;
mm_camera_stream_t *m_stream = NULL;
mm_camera_buf_def_t *p_frame = NULL;
mm_camera_buf_def_t *m_frame = NULL;
/* find channel */
for (i = 0; i < MM_CHANNEL_TYPE_MAX; i++) {
if (pme->channels[i].ch_id == bufs->ch_id) {
channel = &pme->channels[i];
break;
}
}
if (NULL == channel) {
LOGE(" Wrong channel id (%d)", bufs->ch_id);
rc = -1;
goto error;
}
/* find snapshot stream */
for (i = 0; i < channel->num_streams; i++) {
if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_SNAPSHOT) {
m_stream = &channel->streams[i];
break;
}
}
if (NULL == m_stream) {
LOGE(" cannot find snapshot stream");
rc = -1;
goto error;
}
/* find snapshot frame */
for (i = 0; i < bufs->num_bufs; i++) {
if (bufs->bufs[i]->stream_id == m_stream->s_id) {
m_frame = bufs->bufs[i];
break;
}
}
if (NULL == m_frame) {
LOGE(" main frame is NULL");
rc = -1;
goto error;
}
mm_app_dump_frame(m_frame, "main", "yuv", m_frame->frame_idx);
/* find postview stream */
for (i = 0; i < channel->num_streams; i++) {
if (channel->streams[i].s_config.stream_info->stream_type == CAM_STREAM_TYPE_POSTVIEW) {
p_stream = &channel->streams[i];
break;
}
}
if (NULL != p_stream) {
/* find preview frame */
for (i = 0; i < bufs->num_bufs; i++) {
if (bufs->bufs[i]->stream_id == p_stream->s_id) {
p_frame = bufs->bufs[i];
break;
}
}
if (NULL != p_frame) {
mm_app_dump_frame(p_frame, "postview", "yuv", p_frame->frame_idx);
}
}
mm_app_cache_ops((mm_camera_app_meminfo_t *)m_frame->mem_info,
ION_IOC_CLEAN_INV_CACHES);
pme->jpeg_buf.buf.buffer = (uint8_t *)malloc(m_frame->frame_len);
if ( NULL == pme->jpeg_buf.buf.buffer ) {
LOGE(" error allocating jpeg output buffer");
goto error;
}
pme->jpeg_buf.buf.frame_len = m_frame->frame_len;
/* create a new jpeg encoding session */
rc = createEncodingSession(pme, m_stream, m_frame);
if (0 != rc) {
LOGE(" error creating jpeg session");
free(pme->jpeg_buf.buf.buffer);
goto error;
}
/* start jpeg encoding job */
rc = encodeData(pme, bufs, m_stream);
if (0 != rc) {
LOGE(" error creating jpeg session");
free(pme->jpeg_buf.buf.buffer);
goto error;
}
error:
/* buf done rcvd frames in error case */
if ( 0 != rc ) {
for (i=0; i<bufs->num_bufs; i++) {
if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
bufs->ch_id,
bufs->bufs[i])) {
LOGE(" Failed in Qbuf\n");
}
mm_app_cache_ops((mm_camera_app_meminfo_t *)bufs->bufs[i]->mem_info,
ION_IOC_INV_CACHES);
}
}
LOGD(" END\n");
}
mm_camera_channel_t * mm_app_add_snapshot_channel(mm_camera_test_obj_t *test_obj)
{
mm_camera_channel_t *channel = NULL;
mm_camera_stream_t *stream = NULL;
channel = mm_app_add_channel(test_obj,
MM_CHANNEL_TYPE_SNAPSHOT,
NULL,
NULL,
NULL);
if (NULL == channel) {
LOGE(" add channel failed");
return NULL;
}
stream = mm_app_add_snapshot_stream(test_obj,
channel,
mm_app_snapshot_notify_cb,
(void *)test_obj,
1,
1);
if (NULL == stream) {
LOGE(" add snapshot stream failed\n");
mm_app_del_channel(test_obj, channel);
return NULL;
}
return channel;
}
mm_camera_stream_t * mm_app_add_postview_stream(mm_camera_test_obj_t *test_obj,
mm_camera_channel_t *channel,
mm_camera_buf_notify_t stream_cb,
void *userdata,
uint8_t num_bufs,
uint8_t num_burst)
{
int rc = MM_CAMERA_OK;
mm_camera_stream_t *stream = NULL;
cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
stream = mm_app_add_stream(test_obj, channel);
if (NULL == stream) {
LOGE(" add stream failed\n");
return NULL;
}
stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
stream->s_config.mem_vtbl.clean_invalidate_buf =
mm_app_stream_clean_invalidate_buf;
stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
stream->s_config.mem_vtbl.user_data = (void *)stream;
stream->s_config.stream_cb = stream_cb;
stream->s_config.stream_cb_sync = NULL;
stream->s_config.userdata = userdata;
stream->num_of_bufs = num_bufs;
stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_POSTVIEW;
if (num_burst == 0) {
stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
} else {
stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_BURST;
stream->s_config.stream_info->num_of_burst = num_burst;
}
stream->s_config.stream_info->fmt = DEFAULT_PREVIEW_FORMAT;
stream->s_config.stream_info->dim.width = DEFAULT_PREVIEW_WIDTH;
stream->s_config.stream_info->dim.height = DEFAULT_PREVIEW_HEIGHT;
stream->s_config.padding_info = cam_cap->padding_info;
rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
if (MM_CAMERA_OK != rc) {
LOGE("config postview stream err=%d\n", rc);
return NULL;
}
return stream;
}
int mm_app_start_capture_raw(mm_camera_test_obj_t *test_obj, uint8_t num_snapshots)
{
int32_t rc = MM_CAMERA_OK;
mm_camera_channel_t *channel = NULL;
mm_camera_stream_t *s_main = NULL;
mm_camera_channel_attr_t attr;
memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_BURST;
attr.max_unmatched_frames = 3;
channel = mm_app_add_channel(test_obj,
MM_CHANNEL_TYPE_CAPTURE,
&attr,
mm_app_snapshot_notify_cb_raw,
test_obj);
if (NULL == channel) {
LOGE(" add channel failed");
return -MM_CAMERA_E_GENERAL;
}
test_obj->buffer_format = DEFAULT_RAW_FORMAT;
s_main = mm_app_add_raw_stream(test_obj,
channel,
mm_app_snapshot_notify_cb_raw,
test_obj,
num_snapshots,
num_snapshots);
if (NULL == s_main) {
LOGE(" add main snapshot stream failed\n");
mm_app_del_channel(test_obj, channel);
return rc;
}
rc = mm_app_start_channel(test_obj, channel);
if (MM_CAMERA_OK != rc) {
LOGE("start zsl failed rc=%d\n", rc);
mm_app_del_stream(test_obj, channel, s_main);
mm_app_del_channel(test_obj, channel);
return rc;
}
return rc;
}
int mm_app_stop_capture_raw(mm_camera_test_obj_t *test_obj)
{
int rc = MM_CAMERA_OK;
mm_camera_channel_t *ch = NULL;
int i;
cam_stream_size_info_t abc ;
memset (&abc , 0, sizeof (cam_stream_size_info_t));
ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_CAPTURE);
rc = mm_app_stop_channel(test_obj, ch);
if (MM_CAMERA_OK != rc) {
LOGE("stop recording failed rc=%d\n", rc);
}
for ( i = 0 ; i < ch->num_streams ; i++ ) {
mm_app_del_stream(test_obj, ch, &ch->streams[i]);
}
rc = setmetainfoCommand(test_obj, &abc);
if (rc != MM_CAMERA_OK) {
LOGE(" meta info command failed\n");
}
mm_app_del_channel(test_obj, ch);
return rc;
}
int mm_app_start_capture(mm_camera_test_obj_t *test_obj,
uint8_t num_snapshots)
{
int32_t rc = MM_CAMERA_OK;
mm_camera_channel_t *channel = NULL;
mm_camera_stream_t *s_main = NULL;
mm_camera_stream_t *s_post = NULL;
mm_camera_channel_attr_t attr;
memset(&attr, 0, sizeof(mm_camera_channel_attr_t));
attr.notify_mode = MM_CAMERA_SUPER_BUF_NOTIFY_CONTINUOUS;
attr.max_unmatched_frames = 3;
channel = mm_app_add_channel(test_obj,
MM_CHANNEL_TYPE_CAPTURE,
&attr,
mm_app_snapshot_notify_cb,
test_obj);
if (NULL == channel) {
LOGE(" add channel failed");
return -MM_CAMERA_E_GENERAL;
}
s_main = mm_app_add_snapshot_stream(test_obj,
channel,
mm_app_snapshot_notify_cb,
(void *)test_obj,
CAPTURE_BUF_NUM,
num_snapshots);
if (NULL == s_main) {
LOGE(" add main snapshot stream failed\n");
mm_app_del_channel(test_obj, channel);
return rc;
}
s_post = mm_app_add_postview_stream(test_obj,
channel,
NULL,
NULL,
CAPTURE_BUF_NUM,
num_snapshots);
if (NULL == s_main) {
LOGE(" add main postview stream failed\n");
mm_app_del_channel(test_obj, channel);
return rc;
}
rc = mm_app_start_channel(test_obj, channel);
if (MM_CAMERA_OK != rc) {
LOGE("start zsl failed rc=%d\n", rc);
mm_app_del_stream(test_obj, channel, s_main);
mm_app_del_channel(test_obj, channel);
return rc;
}
return rc;
}
int mm_app_stop_capture(mm_camera_test_obj_t *test_obj)
{
int rc = MM_CAMERA_OK;
mm_camera_channel_t *ch = NULL;
ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_CAPTURE);
rc = mm_app_stop_and_del_channel(test_obj, ch);
if (MM_CAMERA_OK != rc) {
LOGE("stop capture channel failed rc=%d\n", rc);
}
return rc;
}
int mm_app_take_picture(mm_camera_test_obj_t *test_obj, uint8_t is_burst_mode)
{
LOGH("\nEnter %s!!\n");
int rc = MM_CAMERA_OK;
uint8_t num_snapshot = 1;
int num_rcvd_snapshot = 0;
if (is_burst_mode)
num_snapshot = 6;
//stop preview before starting capture.
rc = mm_app_stop_preview(test_obj);
if (rc != MM_CAMERA_OK) {
LOGE(" stop preview failed before capture!!, err=%d\n", rc);
return rc;
}
rc = mm_app_start_capture(test_obj, num_snapshot);
if (rc != MM_CAMERA_OK) {
LOGE(" mm_app_start_capture(), err=%d\n", rc);
return rc;
}
while (num_rcvd_snapshot < num_snapshot) {
LOGH("\nWaiting mm_camera_app_wait !!\n");
mm_camera_app_wait();
num_rcvd_snapshot++;
}
rc = mm_app_stop_capture(test_obj);
if (rc != MM_CAMERA_OK) {
LOGE(" mm_app_stop_capture(), err=%d\n", rc);
return rc;
}
//start preview after capture.
rc = mm_app_start_preview(test_obj);
if (rc != MM_CAMERA_OK) {
LOGE(" start preview failed after capture!!, err=%d\n",rc);
}
return rc;
}

View file

@ -0,0 +1,879 @@
/* Copyright (c) 2012-2014, 2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
// System dependencies
#include <errno.h>
// Camera dependencies
#include "mm_qcamera_socket.h"
#include "mm_qcamera_commands.h"
#include "mm_qcamera_dbg.h"
#define IP_ADDR "127.0.0.1"
#define TUNING_CHROMATIX_PORT 55555
#define TUNING_PREVIEW_PORT 55556
#define CURRENT_COMMAND_ACK_SUCCESS 1
#define CURRENT_COMMAND_ACK_FAILURE 2
pthread_t eztune_thread_id;
static ssize_t tuneserver_send_command_rsp(tuningserver_t *tsctrl,
char *send_buf, uint32_t send_len)
{
ssize_t rc;
/* send ack back to client upon req */
if (send_len <= 0) {
LOGE("Invalid send len \n");
return -1;
}
if (send_buf == NULL) {
LOGE("Invalid send buf \n");
return -1;
}
rc = send(tsctrl->clientsocket_id, send_buf, send_len, 0);
if (rc < 0) {
LOGE("RSP send returns error %s\n", strerror(errno));
} else {
rc = 0;
}
if (send_buf != NULL) {
free(send_buf);
send_buf = NULL;
}
return rc;
}
static void release_eztune_prevcmd_rsp(eztune_prevcmd_rsp *pHead)
{
if (pHead != NULL ) {
release_eztune_prevcmd_rsp((eztune_prevcmd_rsp *)pHead->next);
free(pHead);
}
}
static ssize_t tuneserver_ack(uint16_t a, uint32_t b, tuningserver_t *tsctrl)
{
ssize_t rc;
char ack_1[6];
/*Ack the command here*/
memcpy(ack_1, &a, 2);
memcpy(ack_1+2, &b, 4);
/* send echo back to client upon accept */
rc = send(tsctrl->clientsocket_id, &ack_1, sizeof(ack_1), 0);
if (rc < 0) {
LOGE(" eztune_server_run: send returns error %s\n",
strerror(errno));
return rc;
} else if (rc < (int32_t)sizeof(ack_1)) {
/*Shouldn't hit this for packets <1K; need to re-send if we do*/
}
return 0;
}
static ssize_t tuneserver_send_command_ack( uint8_t ack,
tuningserver_t *tsctrl)
{
ssize_t rc;
/* send ack back to client upon req */
rc = send(tsctrl->clientsocket_id, &ack, sizeof(ack), 0);
if (rc < 0) {
LOGE("ACK send returns error %s\n", strerror(errno));
return rc;
}
return 0;
}
/** tuneserver_process_command
* @tsctrl: the server control object
*
* Processes the command that the client sent
*
* Return: >=0 on success, -1 on failure.
**/
static int32_t tuneserver_process_command(tuningserver_t *tsctrl,
char *send_buf, uint32_t send_len)
{
tuneserver_protocol_t *p = tsctrl->proto;
int result = 0;
LOGD(" Current command is %d\n", p->current_cmd);
switch (p->current_cmd) {
case TUNESERVER_GET_LIST:
if(tuneserver_send_command_ack(CURRENT_COMMAND_ACK_SUCCESS, tsctrl)) {
LOGE(" Ack Failed for cmd %d\n", p->current_cmd);
return -1;
}
result = tuneserver_process_get_list_cmd(tsctrl, p->recv_buf,
send_buf, send_len);
if (result < 0) {
LOGE(" RSP processing Failed for cmd %d\n", p->current_cmd);
return -1;
}
if(tuneserver_send_command_rsp(tsctrl, send_buf, send_len)) {
LOGE(" RSP Failed for cmd %d\n", p->current_cmd);
return -1;
}
break;
case TUNESERVER_GET_PARMS:
if(tuneserver_send_command_ack(CURRENT_COMMAND_ACK_SUCCESS, tsctrl)) {
LOGE(" Ack Failed for cmd %d\n", p->current_cmd);
return -1;
}
result = tuneserver_process_get_params_cmd(tsctrl, p->recv_buf,
send_buf, send_len);
if (result < 0) {
LOGE(" RSP processing Failed for cmd %d\n", p->current_cmd);
return -1;
}
if(tuneserver_send_command_rsp(tsctrl, send_buf, send_len)) {
LOGE(" RSP Failed for cmd %d\n", p->current_cmd);
return -1;
}
break;
case TUNESERVER_SET_PARMS:
if(tuneserver_send_command_ack(CURRENT_COMMAND_ACK_SUCCESS, tsctrl)) {
LOGE(" Ack Failed for cmd %d\n", p->current_cmd);
return -1;
}
result = tuneserver_process_set_params_cmd(tsctrl, p->recv_buf,
send_buf, send_len);
if (result < 0) {
LOGE(" RSP processing Failed for cmd %d\n", p->current_cmd);
return -1;
}
if(tuneserver_send_command_rsp(tsctrl, send_buf, send_len)) {
LOGE(" RSP Failed for cmd %d\n", p->current_cmd);
return -1;
}
break;
case TUNESERVER_MISC_CMDS: {
if(tuneserver_send_command_ack(CURRENT_COMMAND_ACK_SUCCESS, tsctrl)) {
LOGE(" Ack Failed for cmd %d\n", p->current_cmd);
return -1;
}
result = tuneserver_process_misc_cmd(tsctrl, p->recv_buf,
send_buf, send_len);
if (result < 0) {
LOGE(" RSP processing Failed for cmd %d\n", p->current_cmd);
return -1;
}
if(tuneserver_send_command_rsp(tsctrl, send_buf, send_len)) {
LOGE(" RSP Failed for cmd %d\n", p->current_cmd);
return -1;
}
break;
}
default:
if(tuneserver_send_command_ack(CURRENT_COMMAND_ACK_SUCCESS, tsctrl)) {
LOGE(" Ack Failed for cmd %d\n", p->current_cmd);
return -1;
}
LOGE(" p->current_cmd: default\n");
result = -1;
break;
}
return result;
}
/** tuneserver_process_client_message
* @recv_buffer: received message from the client
* @tsctrl: the server control object
*
* Processes the message from client and prepares for next
* message.
*
* Return: >=0 on success, -1 on failure.
**/
static int32_t tuneserver_process_client_message(void *recv_buffer,
tuningserver_t *tsctrl)
{
int rc = 0;
tuneserver_protocol_t *p = tsctrl->proto;
switch (tsctrl->proto->next_recv_code) {
case TUNESERVER_RECV_COMMAND:
p->current_cmd = *(uint16_t *)recv_buffer;
p->next_recv_code = TUNESERVER_RECV_PAYLOAD_SIZE;
p->next_recv_len = sizeof(uint32_t);
break;
case TUNESERVER_RECV_PAYLOAD_SIZE:
p->next_recv_code = TUNESERVER_RECV_PAYLOAD;
p->next_recv_len = *(uint32_t *)recv_buffer;
p->recv_len = p->next_recv_len;
if (p->next_recv_len > TUNESERVER_MAX_RECV)
return -1;
if (p->next_recv_len == 0) {
p->next_recv_code = TUNESERVER_RECV_RESPONSE;
p->next_recv_len = sizeof(uint32_t);
}
break;
case TUNESERVER_RECV_PAYLOAD:
p->recv_buf = malloc(p->next_recv_len);
if (!p->recv_buf) {
LOGE("Error allocating memory for recv_buf %s\n",
strerror(errno));
return -1;
}
memcpy(p->recv_buf, recv_buffer, p->next_recv_len);
p->next_recv_code = TUNESERVER_RECV_RESPONSE;
p->next_recv_len = sizeof(uint32_t);
/*Process current command at this point*/
break;
case TUNESERVER_RECV_RESPONSE:
p->next_recv_code = TUNESERVER_RECV_COMMAND;
p->next_recv_len = 2;
p->send_len = *(uint32_t *)recv_buffer;
p->send_buf = (char *)calloc(p->send_len, sizeof(char *));
if (!p->send_buf) {
LOGE("Error allocating memory for send_buf %s\n",
strerror(errno));
return -1;
}
rc = tuneserver_process_command(tsctrl, p->send_buf, p->send_len);
free(p->recv_buf);
p->recv_buf = NULL;
p->recv_len = 0;
break;
default:
LOGE(" p->next_recv_code: default\n");
rc = -1;
break;
}
return rc;
}
/** tuneserver_ack_onaccept_initprotocol
* @tsctrl: the server control object
*
* Acks a connection from the cient and sets up the
* protocol object to start receiving commands.
*
* Return: >=0 on success, -1 on failure.
**/
static ssize_t tuneserver_ack_onaccept_initprotocol(tuningserver_t *tsctrl)
{
ssize_t rc = 0;
uint32_t ack_status;
LOGE("starts\n");
/*
if(tsctrl->camera_running) {
ack_status = 1;
} else {
ack_status = 2;
}
*/
ack_status = 1;
rc = tuneserver_ack(1, ack_status, tsctrl);
tsctrl->proto = malloc(sizeof(tuneserver_protocol_t));
if (!tsctrl->proto) {
LOGE(" malloc returns NULL with error %s\n", strerror(errno));
return -1;
}
tsctrl->proto->current_cmd = 0xFFFF;
tsctrl->proto->next_recv_code = TUNESERVER_RECV_COMMAND;
tsctrl->proto->next_recv_len = 2;
tsctrl->proto->recv_buf = NULL;
tsctrl->proto->send_buf = NULL;
LOGD("X\n");
return rc;
}
/** tuneserver_check_status
* @tsctrl: the server control object
*
* Checks if camera is running and stops it.
*
* Return: >=0 on success, -1 on failure.
**/
#if 0
static void tuneserver_check_status(tuningserver_t *tsctrl)
{
if (tsctrl->camera_running == 1) {
/*TODO: Stop camera here*/
tuneserver_stop_cam(&tsctrl->lib_handle);
}
tsctrl->camera_running = 0;
tuneserver_close_cam(&tsctrl->lib_handle);
}
#endif
static ssize_t prevserver_send_command_rsp(tuningserver_t *tsctrl,
char *send_buf, uint32_t send_len)
{
ssize_t rc;
/* send ack back to client upon req */
if (send_len <= 0) {
LOGE("Invalid send len \n");
return -1;
}
if (send_buf == NULL) {
LOGE("Invalid send buf \n");
return -1;
}
rc = send(tsctrl->pr_clientsocket_id, send_buf, send_len, 0);
if (rc < 0) {
LOGE("RSP send returns error %s\n", strerror(errno));
} else {
rc = 0;
}
if (send_buf != NULL) {
free(send_buf);
send_buf = NULL;
}
return rc;
}
static void prevserver_init_protocol(tuningserver_t *tsctrl)
{
tsctrl->pr_proto = malloc(sizeof(prserver_protocol_t));
if (!tsctrl->pr_proto) {
LOGE(" malloc returns NULL with error %s\n",
strerror(errno));
return;
}
tsctrl->pr_proto->current_cmd = 0xFFFF;
tsctrl->pr_proto->next_recv_code = TUNE_PREV_RECV_COMMAND;
tsctrl->pr_proto->next_recv_len = 2;
}
static int32_t prevserver_process_command(
tuningserver_t *tsctrl, char **send_buf, uint32_t *send_len)
{
prserver_protocol_t *p = tsctrl->pr_proto;
int result = 0;
eztune_prevcmd_rsp *rsp_ptr=NULL, *rspn_ptr=NULL, *head_ptr=NULL;
LOGD(" Current command is %d\n", p->current_cmd);
switch (p->current_cmd) {
case TUNE_PREV_GET_INFO:
result = tuneserver_preview_getinfo(tsctrl, send_buf, send_len);
if (result < 0) {
LOGE(" RSP processing Failed for cmd %d\n",
p->current_cmd);
return -1;
}
rsp_ptr = (eztune_prevcmd_rsp *)*send_buf;
if ((!rsp_ptr) || (!rsp_ptr->send_buf)) {
LOGE(" RSP ptr is NULL %d\n", p->current_cmd);
return -1;
}
if (prevserver_send_command_rsp(tsctrl,
rsp_ptr->send_buf, rsp_ptr->send_len)) {
LOGE(" RSP Failed for TUNE_PREV_GET_INFO ver cmd %d\n",
p->current_cmd);
return -1;
}
rspn_ptr = (eztune_prevcmd_rsp *)rsp_ptr->next;
if ((!rspn_ptr) || (!rspn_ptr->send_buf)) {
LOGE(" RSP1 ptr is NULL %d\n", p->current_cmd);
return -1;
}
if (prevserver_send_command_rsp(tsctrl,
rspn_ptr->send_buf, rspn_ptr->send_len)) {
LOGE(" RSP Failed for TUNE_PREV_GET_INFO caps cmd %d\n",
p->current_cmd);
return -1;
}
free(rspn_ptr);
free(rsp_ptr);
break;
case TUNE_PREV_CH_CNK_SIZE:
result = tuneserver_preview_getchunksize(tsctrl, send_buf, send_len);
if (result < 0) {
LOGE(" RSP processing Failed for cmd %d\n", p->current_cmd);
return -1;
}
if (prevserver_send_command_rsp(tsctrl, *send_buf, *send_len)) {
LOGE(" RSP Failed for TUNE_PREV_CH_CNK_SIZE cmd %d\n",
p->current_cmd);
return -1;
}
break;
case TUNE_PREV_GET_PREV_FRAME:
result = tuneserver_preview_getframe(tsctrl, send_buf, send_len);
if (result < 0) {
LOGE(" RSP processing Failed for cmd %d\n", p->current_cmd);
return -1;
}
rsp_ptr = (eztune_prevcmd_rsp *)*send_buf;
if ((!rsp_ptr) || (!rsp_ptr->send_buf)) {
LOGE(" RSP ptr is NULL %d\n", p->current_cmd);
return -1;
}
head_ptr = rsp_ptr;
while (rsp_ptr != NULL) {
if ((!rsp_ptr) || (!rsp_ptr->send_buf)) {
LOGE(" RSP ptr is NULL %d\n", p->current_cmd);
return -1;
}
if (prevserver_send_command_rsp(tsctrl,
rsp_ptr->send_buf, rsp_ptr->send_len)) {
LOGE(" RSP Failed for TUNE_PREV_GET_INFO ver cmd %d\n",
p->current_cmd);
return -1;
}
rsp_ptr = (eztune_prevcmd_rsp *)rsp_ptr->next;
}
release_eztune_prevcmd_rsp(head_ptr);
break;
case TUNE_PREV_GET_JPG_SNAP:
case TUNE_PREV_GET_RAW_SNAP:
case TUNE_PREV_GET_RAW_PREV:
result = tuneserver_preview_unsupported(tsctrl, send_buf, send_len);
if (result < 0) {
LOGE("RSP processing Failed for cmd %d\n", p->current_cmd);
return -1;
}
if (prevserver_send_command_rsp(tsctrl, *send_buf, *send_len)) {
LOGE("RSP Failed for UNSUPPORTED cmd %d\n", p->current_cmd);
return -1;
}
break;
default:
LOGE(" p->current_cmd: default\n");
result = -1;
break;
}
return result;
}
/** previewserver_process_client_message
* @recv_buffer: received message from the client
* @tsctrl: the server control object
*
* Processes the message from client and prepares for next
* message.
*
* Return: >=0 on success, -1 on failure.
**/
static int32_t prevserver_process_client_message(void *recv_buffer,
tuningserver_t *tsctrl)
{
int rc = 0;
prserver_protocol_t *p = tsctrl->pr_proto;
LOGD("command = %d", p->next_recv_code);
switch (p->next_recv_code) {
case TUNE_PREV_RECV_COMMAND:
p->current_cmd = *(uint16_t *)recv_buffer;
if(p->current_cmd != TUNE_PREV_CH_CNK_SIZE) {
rc = prevserver_process_command(tsctrl,
&p->send_buf, (uint32_t *)&p->send_len);
break;
}
p->next_recv_code = TUNE_PREV_RECV_NEWCNKSIZE;
p->next_recv_len = sizeof(uint32_t);
LOGD("TUNE_PREV_COMMAND X\n");
break;
case TUNE_PREV_RECV_NEWCNKSIZE:
p->new_cnk_size = *(uint32_t *)recv_buffer;
p->next_recv_code = TUNE_PREV_RECV_COMMAND;
p->next_recv_len = 2;
rc = prevserver_process_command(tsctrl,
&p->send_buf, (uint32_t *)&p->send_len);
break;
default:
LOGE("prev_proc->next_recv_code: default\n");
rc = -1;
break;
}
return rc;
}
/** tunning_server_socket_listen
* @ip_addr: the ip addr to listen
* @port: the port to listen
*
* Setup a listen socket for eztune.
*
* Return: >0 on success, <=0 on failure.
**/
int tunning_server_socket_listen(const char* ip_addr, uint16_t port)
{
int sock_fd = -1;
mm_qcamera_sock_addr_t server_addr;
int result;
int option;
int socket_flag;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.addr_in.sin_family = AF_INET;
server_addr.addr_in.sin_port = (__be16) htons(port);
server_addr.addr_in.sin_addr.s_addr = inet_addr(ip_addr);
if (server_addr.addr_in.sin_addr.s_addr == INADDR_NONE) {
LOGE("[ERR] %s invalid address.\n");
return -1;
}
/* Create an AF_INET stream socket to receive incoming connection ON */
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if (sock_fd < 0) {
LOGE("[ERR] %s socket failed\n");
return sock_fd;
}
// set listen socket to non-block, but why??
socket_flag = fcntl(sock_fd, F_GETFL, 0);
fcntl(sock_fd, F_SETFL, socket_flag | O_NONBLOCK);
/* reuse in case it is in timeout */
option = 1;
result = setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR,
&option, sizeof(option));
if (result < 0) {
LOGE("eztune setsockopt failed");
close(sock_fd);
sock_fd = -1;
return sock_fd;
}
result = bind(sock_fd, &server_addr.addr, sizeof(server_addr.addr_in));
if (result < 0) {
LOGE("eztune socket bind failed");
close(sock_fd);
sock_fd = -1;
return sock_fd;
}
result = listen(sock_fd, 1);
if (result < 0) {
LOGE("eztune socket listen failed");
close(sock_fd);
sock_fd = -1;
return sock_fd;
}
LOGH("%s. sock_fd: %d, listen at port: %d\n", sock_fd, port);
return sock_fd;
}
/** main
*
* Creates the server, and starts waiting for
* connections/messages from a prospective
* client
*
**/
void *eztune_proc(void *data)
{
int server_socket = -1, client_socket = -1;
int prev_server_socket = -1, prev_client_socket = -1;
mm_qcamera_sock_addr_t addr_client_inet;
socklen_t addr_client_len = sizeof(addr_client_inet.addr_in);
int result;
fd_set tsfds;
int num_fds = 0;
ssize_t recv_bytes;
char buf[TUNESERVER_MAX_RECV];
mm_camera_lib_handle *lib_handle = (mm_camera_lib_handle *)data;
LOGE(">>> Starting tune server <<< \n");
// for eztune chromatix params
server_socket = tunning_server_socket_listen(IP_ADDR, TUNING_CHROMATIX_PORT);
if (server_socket <= 0) {
LOGE("[ERR] fail to setup listen socket for eztune chromatix parms...");
return NULL;
}
prev_server_socket = tunning_server_socket_listen(IP_ADDR, TUNING_PREVIEW_PORT);
if (prev_server_socket <= 0) {
LOGE("[ERR] fail to setup listen socket for eztune preview...\n");
return NULL;
}
num_fds = TUNESERVER_MAX(server_socket, prev_server_socket);
LOGH("num_fds = %d\n", num_fds);
do {
FD_ZERO(&tsfds);
FD_SET(server_socket, &tsfds);
FD_SET(prev_server_socket, &tsfds);
if (client_socket > 0) {
FD_SET(client_socket, &tsfds);
}
if (prev_client_socket > 0) {
FD_SET( prev_client_socket, &tsfds);
}
/* no timeout */
result = select(num_fds + 1, &tsfds, NULL, NULL, NULL);
if (result < 0) {
LOGE("[ERR] select failed: %s\n", strerror(errno));
continue;
}
/*
** (1) CHROMATIX SERVER
*/
if (FD_ISSET(server_socket, &tsfds)) {
LOGD("Receiving New client connection\n");
client_socket = accept(server_socket,
&addr_client_inet.addr, &addr_client_len);
if (client_socket == -1) {
LOGE("accept failed %s", strerror(errno));
continue;
}
if (client_socket >= FD_SETSIZE) {
LOGE("client_socket is out of range. client_socket=%d",client_socket);
continue;
}
LOGE("accept a new connect on 55555, sd(%d)\n", client_socket);
num_fds = TUNESERVER_MAX(num_fds, client_socket);
// open camera and get handle - this is needed to
// be able to set parameters without starting
// preview stream
/*if (!tsctrl.camera_running) {
result = tuneserver_open_cam(&tsctrl.lib_handle, &tsctrl);
if(result) {
printf("\n Camera Open Fail !!! \n");
close(server_socket);
return EXIT_FAILURE;
}
}*/
result = tuneserver_open_cam(lib_handle);
if(result) {
LOGE("\n Tuning Library open failed!!!\n");
close(server_socket);
return NULL;
}
lib_handle->tsctrl.clientsocket_id = client_socket;
if (tuneserver_ack_onaccept_initprotocol(&lib_handle->tsctrl) < 0) {
LOGE(" Error while acking\n");
close(client_socket);
continue;
}
tuneserver_initialize_tuningp(lib_handle, client_socket,
lib_handle->tsctrl.proto->send_buf, lib_handle->tsctrl.proto->send_len);
}
if (FD_ISSET(client_socket, &tsfds)) {
if (lib_handle->tsctrl.proto == NULL) {
LOGE(" Cannot receive msg without connect\n");
continue;
}
/*Receive message and process it*/
recv_bytes = recv(client_socket, (void *)buf,
lib_handle->tsctrl.proto->next_recv_len, 0);
LOGD("Receive %lld bytes \n", (long long int) recv_bytes);
if (recv_bytes == -1) {
LOGE(" Receive failed with error %s\n", strerror(errno));
//tuneserver_check_status(&tsctrl);
continue;
} else if (recv_bytes == 0) {
LOGE("connection has been terminated\n");
tuneserver_deinitialize_tuningp(&lib_handle->tsctrl, client_socket,
lib_handle->tsctrl.proto->send_buf,
lib_handle->tsctrl.proto->send_len);
free(lib_handle->tsctrl.proto);
lib_handle->tsctrl.proto = NULL;
close(client_socket);
client_socket = -1;
//tuneserver_check_status(&tsctrl);
} else {
LOGD(" Processing socket command\n");
result = tuneserver_process_client_message(buf, &lib_handle->tsctrl);
if (result < 0) {
LOGE("Protocol violated\n");
free(lib_handle->tsctrl.proto);
lib_handle->tsctrl.proto = NULL;
close(client_socket);
client_socket = -1;
//tuneserver_check_status(&tsctrl);
continue;
}
}
}
/*
** (2) PREVIEW SERVER
*/
if (FD_ISSET(prev_server_socket, &tsfds)) {
LOGD("Receiving New Preview client connection\n");
prev_client_socket = accept(prev_server_socket,
&addr_client_inet.addr, &addr_client_len);
if (prev_client_socket == -1) {
LOGE("accept failed %s", strerror(errno));
continue;
}
if (prev_client_socket >= FD_SETSIZE) {
LOGE("prev_client_socket is out of range. prev_client_socket=%d",prev_client_socket);
continue;
}
lib_handle->tsctrl.pr_clientsocket_id = prev_client_socket;
LOGD("Accepted a new connection, fd(%d)\n", prev_client_socket);
num_fds = TUNESERVER_MAX(num_fds, prev_client_socket);
// start camera
/*if (!tsctrl.camera_running) {
result = 0;
result = tuneserver_open_cam(&tsctrl.lib_handle, &tsctrl);
if(result) {
printf("\n Camera Open Fail !!! \n");
return EXIT_FAILURE;
}
}*/
cam_dimension_t dim;
//dim.width = lib_handle->test_obj.buffer_width;
//dim.height = lib_handle->test_obj.buffer_height;
dim.width = DEFAULT_PREVIEW_WIDTH;
dim.height = DEFAULT_PREVIEW_HEIGHT;
LOGD("preview dimension info: w(%d), h(%d)\n", dim.width, dim.height);
// we have to make sure that camera is running, before init connection,
// because we need to know the frame size for allocating the memory.
prevserver_init_protocol(&lib_handle->tsctrl);
result = tuneserver_initialize_prevtuningp(lib_handle, prev_client_socket,
dim, (char **)&lib_handle->tsctrl.proto->send_buf,
&lib_handle->tsctrl.proto->send_len);
if (result < 0) {
LOGE("tuneserver_initialize_prevtuningp error!");
close(prev_client_socket);
prev_client_socket = -1;
}
}
if (FD_ISSET(prev_client_socket, &tsfds)) {
recv_bytes = recv(prev_client_socket, (void *)buf,
lib_handle->tsctrl.pr_proto->next_recv_len, 0);
LOGD("prev_client_socket=%d\n", prev_client_socket);
LOGD("next_recv_len=%d\n", buf[0]+buf[1]*256);
if (recv_bytes <= 0) {
if (recv_bytes == 0) {
LOGE("client close the connection.\n");
} else {
LOGE("receive error: %s\n", strerror(errno));
}
//tuneserver_check_status(&tsctrl);
// if recv error, we should close the connection, free the proto data,
// AND wait for a new connecton..
// close_connection();
// stop_camera()
// cleanup_proto_data();
tuneserver_deinitialize_prevtuningp(&lib_handle->tsctrl,
(char **)&lib_handle->tsctrl.proto->send_buf,
&lib_handle->tsctrl.proto->send_len);
close(prev_client_socket);
prev_client_socket = -1;
} else {
result = prevserver_process_client_message((void *)buf,
&lib_handle->tsctrl);
if (result < 0) {
LOGE("Protocol violated\n");
//free(tsctrl->preivew_proto);
//free(tsctrl);
//max_fd = ezt_parms_listen_sd + 1;
tuneserver_deinitialize_prevtuningp(&lib_handle->tsctrl,
(char **)&lib_handle->tsctrl.proto->send_buf,
&lib_handle->tsctrl.proto->send_len);
close(prev_client_socket);
prev_client_socket = -1;
//tuneserver_check_status(&tsctrl);
}
//sleep(1);
}
}
} while (1);
if (server_socket >= 0) {
close(server_socket);
}
if (client_socket >= 0) {
close(client_socket);
}
if (prev_server_socket >= 0) {
close(prev_server_socket);
}
if (prev_client_socket >= 0) {
close(prev_client_socket);
}
return EXIT_SUCCESS;
}
int eztune_server_start (void *lib_handle)
{
return pthread_create(&eztune_thread_id, NULL, eztune_proc, lib_handle);
}

View file

@ -0,0 +1,695 @@
/* Copyright (c) 2013, 2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
// Camera dependencies
#include "mm_qcamera_app.h"
#include "mm_qcamera_dbg.h"
#define MM_QCAMERA_APP_UTEST_MAX_MAIN_LOOP 1
#define MM_QCAMERA_APP_UTEST_OUTER_LOOP 1
#define MM_QCAMERA_APP_UTEST_INNER_LOOP 1
#define MM_QCAM_APP_TEST_NUM 128
static mm_app_tc_t mm_app_tc[MM_QCAM_APP_TEST_NUM];
int mm_app_tc_open_close(mm_camera_app_t *cam_app)
{
int rc = MM_CAMERA_OK;
int i;
mm_camera_test_obj_t test_obj;
printf("\n Verifying open/close cameras...\n");
for (i = 0; i < cam_app->num_cameras; i++) {
memset(&test_obj, 0, sizeof(mm_camera_test_obj_t));
rc = mm_app_open(cam_app, i, &test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_open() cam_idx=%d, err=%d\n",
i, rc);
break;
}
sleep(1);
rc = mm_app_close(&test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_close() cam_idx=%d, err=%d\n",
i, rc);
break;
}
}
if (rc == MM_CAMERA_OK) {
printf("\nPassed\n");
} else {
printf("\nFailed\n");
}
LOGD("END, rc = %d\n", rc);
return rc;
}
int mm_app_tc_start_stop_preview(mm_camera_app_t *cam_app)
{
int rc = MM_CAMERA_OK;
int i, j;
mm_camera_test_obj_t test_obj;
printf("\n Verifying start/stop preview...\n");
for (i = 0; i < cam_app->num_cameras; i++) {
memset(&test_obj, 0, sizeof(mm_camera_test_obj_t));
rc = mm_app_open(cam_app, i, &test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_open() cam_idx=%d, err=%d\n",
i, rc);
break;
}
for (j = 0; j < MM_QCAMERA_APP_UTEST_INNER_LOOP; j++) {
rc = mm_app_start_preview(&test_obj);
if (rc != MM_CAMERA_OK) {
LOGE(" mm_app_start_preview() cam_idx=%d, err=%d\n",
i, rc);
break;
}
sleep(1);
rc = mm_app_stop_preview(&test_obj);
if (rc != MM_CAMERA_OK) {
LOGE(" mm_app_stop_preview() cam_idx=%d, err=%d\n",
i, rc);
break;
}
}
rc |= mm_app_close(&test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_close() cam_idx=%d, err=%d\n",
i, rc);
break;
}
}
if (rc == MM_CAMERA_OK) {
printf("\nPassed\n");
} else {
printf("\nFailed\n");
}
LOGD("END, rc = %d\n", rc);
return rc;
}
int mm_app_tc_start_stop_zsl(mm_camera_app_t *cam_app)
{
int rc = MM_CAMERA_OK;
int i, j;
mm_camera_test_obj_t test_obj;
printf("\n Verifying start/stop preview...\n");
for (i = 0; i < cam_app->num_cameras; i++) {
memset(&test_obj, 0, sizeof(mm_camera_test_obj_t));
rc = mm_app_open(cam_app, i, &test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_open() cam_idx=%d, err=%d\n",
i, rc);
break;
}
for (j = 0; j < 1; j++) {
rc = mm_app_start_preview_zsl(&test_obj);
if (rc != MM_CAMERA_OK) {
LOGE(" mm_app_start_preview_zsl() cam_idx=%d, err=%d\n",
i, rc);
break;
}
sleep(1);
rc = mm_app_stop_preview_zsl(&test_obj);
if (rc != MM_CAMERA_OK) {
LOGE(" mm_app_stop_preview_zsl() cam_idx=%d, err=%d\n",
i, rc);
break;
}
}
rc = mm_app_close(&test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_close() cam_idx=%d, err=%d\n",
i, rc);
break;
}
}
if (rc == MM_CAMERA_OK) {
printf("\nPassed\n");
} else {
printf("\nFailed\n");
}
LOGD("END, rc = %d\n", rc);
return rc;
}
int mm_app_tc_start_stop_video_preview(mm_camera_app_t *cam_app)
{
int rc = MM_CAMERA_OK;
int i, j;
mm_camera_test_obj_t test_obj;
printf("\n Verifying start/stop video preview...\n");
for (i = 0; i < cam_app->num_cameras; i++) {
memset(&test_obj, 0, sizeof(mm_camera_test_obj_t));
rc = mm_app_open(cam_app, i, &test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_open() cam_idx=%d, err=%d\n",
i, rc);
break;
}
for (j = 0; j < MM_QCAMERA_APP_UTEST_INNER_LOOP; j++) {
rc = mm_app_start_record_preview(&test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_start_record_preview() cam_idx=%d, err=%d\n",
i, rc);
break;
}
sleep(1);
rc = mm_app_stop_record_preview(&test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_stop_record_preview() cam_idx=%d, err=%d\n",
i, rc);
break;
}
}
rc = mm_app_close(&test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_close() cam_idx=%d, err=%d\n",
i, rc);
break;
}
}
if (rc == MM_CAMERA_OK) {
printf("\nPassed\n");
} else {
printf("\nFailed\n");
}
LOGD("END, rc = %d\n", rc);
return rc;
}
int mm_app_tc_start_stop_video_record(mm_camera_app_t *cam_app)
{
int rc = MM_CAMERA_OK;
int i, j;
mm_camera_test_obj_t test_obj;
printf("\n Verifying start/stop recording...\n");
for (i = 0; i < cam_app->num_cameras; i++) {
memset(&test_obj, 0, sizeof(mm_camera_test_obj_t));
rc = mm_app_open(cam_app, i, &test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_open() cam_idx=%d, err=%d\n",
i, rc);
break;
}
rc = mm_app_start_record_preview(&test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_start_record_preview() cam_idx=%d, err=%d\n",
i, rc);
mm_app_close(&test_obj);
break;
}
sleep(1);
for (j = 0; j < MM_QCAMERA_APP_UTEST_INNER_LOOP; j++) {
rc = mm_app_start_record(&test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_start_record() cam_idx=%d, err=%d\n",
i, rc);
break;
}
sleep(1);
rc = mm_app_stop_record(&test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_stop_record() cam_idx=%d, err=%d\n",
i, rc);
break;
}
}
if (rc != MM_CAMERA_OK) {
LOGE("start/stop record cam_idx=%d, err=%d\n",
i, rc);
mm_app_stop_record_preview(&test_obj);
mm_app_close(&test_obj);
break;
}
rc = mm_app_stop_record_preview(&test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_stop_record_preview() cam_idx=%d, err=%d\n",
i, rc);
mm_app_close(&test_obj);
break;
}
rc = mm_app_close(&test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_close() cam_idx=%d, err=%d\n",
i, rc);
break;
}
}
if (rc == MM_CAMERA_OK) {
printf("\nPassed\n");
} else {
printf("\nFailed\n");
}
LOGD("END, rc = %d\n", rc);
return rc;
}
int mm_app_tc_start_stop_live_snapshot(mm_camera_app_t *cam_app)
{
int rc = MM_CAMERA_OK;
int i, j;
mm_camera_test_obj_t test_obj;
printf("\n Verifying start/stop live snapshot...\n");
for (i = 0; i < cam_app->num_cameras; i++) {
memset(&test_obj, 0, sizeof(mm_camera_test_obj_t));
rc = mm_app_open(cam_app, i, &test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_open() cam_idx=%d, err=%d\n",
i, rc);
break;
}
rc = mm_app_start_record_preview(&test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_start_record_preview() cam_idx=%d, err=%d\n",
i, rc);
mm_app_close(&test_obj);
break;
}
sleep(1);
rc = mm_app_start_record(&test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_start_record() cam_idx=%d, err=%d\n",
i, rc);
mm_app_stop_record_preview(&test_obj);
mm_app_close(&test_obj);
break;
}
sleep(1);
for (j = 0; j < MM_QCAMERA_APP_UTEST_INNER_LOOP; j++) {
rc = mm_app_start_live_snapshot(&test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_start_live_snapshot() cam_idx=%d, err=%d\n",
i, rc);
break;
}
/* wait for jpeg is done */
mm_camera_app_wait();
rc = mm_app_stop_live_snapshot(&test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_stop_live_snapshot() cam_idx=%d, err=%d\n",
i, rc);
break;
}
}
if (rc != MM_CAMERA_OK) {
LOGE("start/stop live snapshot cam_idx=%d, err=%d\n",
i, rc);
mm_app_stop_record(&test_obj);
mm_app_stop_record_preview(&test_obj);
mm_app_close(&test_obj);
break;
}
rc = mm_app_stop_record(&test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_stop_record() cam_idx=%d, err=%d\n",
i, rc);
mm_app_stop_record_preview(&test_obj);
mm_app_close(&test_obj);
break;
}
sleep(1);
rc = mm_app_stop_record_preview(&test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_stop_record_preview() cam_idx=%d, err=%d\n",
i, rc);
mm_app_close(&test_obj);
break;
}
rc = mm_app_close(&test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_close() cam_idx=%d, err=%d\n",
i, rc);
break;
}
}
if (rc == MM_CAMERA_OK) {
printf("\nPassed\n");
} else {
printf("\nFailed\n");
}
LOGD("END, rc = %d\n", rc);
return rc;
}
int mm_app_tc_capture_raw(mm_camera_app_t *cam_app)
{
int rc = MM_CAMERA_OK;
int i, j;
mm_camera_test_obj_t test_obj;
uint8_t num_snapshot = 1;
uint8_t num_rcvd_snapshot = 0;
printf("\n Verifying raw capture...\n");
for (i = 0; i < cam_app->num_cameras; i++) {
memset(&test_obj, 0, sizeof(mm_camera_test_obj_t));
rc = mm_app_open(cam_app, i, &test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_open() cam_idx=%d, err=%d\n",
i, rc);
break;
}
for (j = 0; j < MM_QCAMERA_APP_UTEST_INNER_LOOP; j++) {
rc = mm_app_start_capture_raw(&test_obj, num_snapshot);
if (rc != MM_CAMERA_OK) {
LOGE(" mm_app_start_capture() cam_idx=%d, err=%d\n",
i, rc);
break;
}
while (num_rcvd_snapshot < num_snapshot) {
mm_camera_app_wait();
num_rcvd_snapshot++;
}
rc = mm_app_stop_capture_raw(&test_obj);
if (rc != MM_CAMERA_OK) {
LOGE(" mm_app_stop_capture() cam_idx=%d, err=%d\n",
i, rc);
break;
}
}
rc |= mm_app_close(&test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_close() cam_idx=%d, err=%d\n",
i, rc);
break;
}
}
if (rc == MM_CAMERA_OK) {
printf("\nPassed\n");
} else {
printf("\nFailed\n");
}
LOGD("END, rc = %d\n", rc);
return rc;
}
int mm_app_tc_capture_regular(mm_camera_app_t *cam_app)
{
int rc = MM_CAMERA_OK;
int i, j;
mm_camera_test_obj_t test_obj;
uint8_t num_snapshot = 1;
uint8_t num_rcvd_snapshot = 0;
printf("\n Verifying capture...\n");
for (i = 0; i < cam_app->num_cameras; i++) {
memset(&test_obj, 0, sizeof(mm_camera_test_obj_t));
rc = mm_app_open(cam_app, i, &test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_open() cam_idx=%d, err=%d\n",
i, rc);
break;
}
for (j = 0; j < MM_QCAMERA_APP_UTEST_INNER_LOOP; j++) {
rc = mm_app_start_capture(&test_obj, num_snapshot);
if (rc != MM_CAMERA_OK) {
LOGE(" mm_app_start_capture() cam_idx=%d, err=%d\n",
i, rc);
break;
}
while (num_rcvd_snapshot < num_snapshot) {
mm_camera_app_wait();
num_rcvd_snapshot++;
}
rc = mm_app_stop_capture(&test_obj);
if (rc != MM_CAMERA_OK) {
LOGE(" mm_app_stop_capture() cam_idx=%d, err=%d\n",
i, rc);
break;
}
}
rc = mm_app_close(&test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_close() cam_idx=%d, err=%d\n",
i, rc);
break;
}
}
if (rc == MM_CAMERA_OK) {
printf("\nPassed\n");
} else {
printf("\nFailed\n");
}
LOGD("END, rc = %d\n", rc);
return rc;
}
int mm_app_tc_capture_burst(mm_camera_app_t *cam_app)
{
int rc = MM_CAMERA_OK;
int i, j;
mm_camera_test_obj_t test_obj;
uint8_t num_snapshot = 3;
uint8_t num_rcvd_snapshot = 0;
printf("\n Verifying capture...\n");
for (i = 0; i < cam_app->num_cameras; i++) {
memset(&test_obj, 0, sizeof(mm_camera_test_obj_t));
rc = mm_app_open(cam_app, i, &test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_open() cam_idx=%d, err=%d\n",
i, rc);
break;
}
for (j = 0; j < MM_QCAMERA_APP_UTEST_INNER_LOOP; j++) {
rc = mm_app_start_capture(&test_obj, num_snapshot);
if (rc != MM_CAMERA_OK) {
LOGE(" mm_app_start_capture() cam_idx=%d, err=%d\n",
i, rc);
break;
}
while (num_rcvd_snapshot < num_snapshot) {
mm_camera_app_wait();
num_rcvd_snapshot++;
}
rc = mm_app_stop_capture(&test_obj);
if (rc != MM_CAMERA_OK) {
LOGE(" mm_app_stop_capture() cam_idx=%d, err=%d\n",
i, rc);
break;
}
}
rc = mm_app_close(&test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_close() cam_idx=%d, err=%d\n",
i, rc);
break;
}
}
if (rc == MM_CAMERA_OK) {
printf("\nPassed\n");
} else {
printf("\nFailed\n");
}
LOGD("END, rc = %d\n", rc);
return rc;
}
int mm_app_tc_rdi_burst(mm_camera_app_t *cam_app)
{
int rc = MM_CAMERA_OK, rc2 = MM_CAMERA_OK;
int i, j;
mm_camera_test_obj_t test_obj;
printf("\n Verifying rdi burst (3) capture...\n");
for (i = 0; i < cam_app->num_cameras; i++) {
memset(&test_obj, 0, sizeof(mm_camera_test_obj_t));
rc = mm_app_open(cam_app, i, &test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_open() cam_idx=%d, err=%d\n",
i, rc);
break;
}
for (j = 0; j < MM_QCAMERA_APP_UTEST_INNER_LOOP; j++) {
rc = mm_app_start_rdi(&test_obj, 3);
if (rc != MM_CAMERA_OK) {
LOGE(" mm_app_start_preview() cam_idx=%d, err=%d\n",
i, rc);
break;
}
sleep(1);
rc = mm_app_stop_rdi(&test_obj);
if (rc != MM_CAMERA_OK) {
LOGE(" mm_app_stop_preview() cam_idx=%d, err=%d\n",
i, rc);
break;
}
}
rc2 = mm_app_close(&test_obj);
if (rc2 != MM_CAMERA_OK) {
LOGE("mm_app_close() cam_idx=%d, err=%d\n",
i, rc2);
if (rc == MM_CAMERA_OK) {
rc = rc2;
}
break;
}
}
if (rc == MM_CAMERA_OK) {
printf("\nPassed\n");
} else {
printf("\nFailed\n");
}
LOGD("END, rc = %d\n", rc);
return rc;
}
int mm_app_tc_rdi_cont(mm_camera_app_t *cam_app)
{
int rc = MM_CAMERA_OK, rc2 = MM_CAMERA_OK;
int i, j;
mm_camera_test_obj_t test_obj;
printf("\n Verifying rdi continuous capture...\n");
for (i = 0; i < cam_app->num_cameras; i++) {
memset(&test_obj, 0, sizeof(mm_camera_test_obj_t));
rc = mm_app_open(cam_app, i, &test_obj);
if (rc != MM_CAMERA_OK) {
LOGE("mm_app_open() cam_idx=%d, err=%d\n",
i, rc);
break;
}
for (j = 0; j < MM_QCAMERA_APP_UTEST_INNER_LOOP; j++) {
rc = mm_app_start_rdi(&test_obj, 0);
if (rc != MM_CAMERA_OK) {
LOGE(" mm_app_start_preview() cam_idx=%d, err=%d\n",
i, rc);
break;
}
sleep(1);
rc = mm_app_stop_rdi(&test_obj);
if (rc != MM_CAMERA_OK) {
LOGE(" mm_app_stop_preview() cam_idx=%d, err=%d\n",
i, rc);
break;
}
}
rc2 = mm_app_close(&test_obj);
if (rc2 != MM_CAMERA_OK) {
LOGE("mm_app_close() cam_idx=%d, err=%d\n",
i, rc2);
if (rc == MM_CAMERA_OK) {
rc = rc2;
}
break;
}
}
if (rc == MM_CAMERA_OK) {
printf("\nPassed\n");
} else {
printf("\nFailed\n");
}
LOGD("END, rc = %d\n", rc);
return rc;
}
int mm_app_gen_test_cases()
{
int tc = 0;
memset(mm_app_tc, 0, sizeof(mm_app_tc));
if (tc < MM_QCAM_APP_TEST_NUM) mm_app_tc[tc++].f = mm_app_tc_open_close;
if (tc < MM_QCAM_APP_TEST_NUM) mm_app_tc[tc++].f = mm_app_tc_start_stop_preview;
//if (tc < MM_QCAM_APP_TEST_NUM) mm_app_tc[tc++].f = mm_app_tc_start_stop_zsl;
//if (tc < MM_QCAM_APP_TEST_NUM) mm_app_tc[tc++].f = mm_app_tc_start_stop_video_preview;
//if (tc < MM_QCAM_APP_TEST_NUM) mm_app_tc[tc++].f = mm_app_tc_start_stop_video_record;
//if (tc < MM_QCAM_APP_TEST_NUM) mm_app_tc[tc++].f = mm_app_tc_start_stop_live_snapshot;
//if (tc < MM_QCAM_APP_TEST_NUM) mm_app_tc[tc++].f = mm_app_tc_capture_regular;
//if (tc < MM_QCAM_APP_TEST_NUM) mm_app_tc[tc++].f = mm_app_tc_capture_burst;
//if (tc < MM_QCAM_APP_TEST_NUM) mm_app_tc[tc++].f = mm_app_tc_rdi_cont;
//if (tc < MM_QCAM_APP_TEST_NUM) mm_app_tc[tc++].f = mm_app_tc_rdi_burst;
return tc;
}
int mm_app_unit_test_entry(mm_camera_app_t *cam_app)
{
int rc = MM_CAMERA_OK;
int i, j, tc = 0;
tc = mm_app_gen_test_cases();
LOGD("Running %d test cases\n",tc);
for (i = 0; i < tc; i++) {
for (j = 0; j < MM_QCAMERA_APP_UTEST_OUTER_LOOP; j++) {
mm_app_tc[i].r = mm_app_tc[i].f(cam_app);
if (mm_app_tc[i].r != MM_CAMERA_OK) {
printf(" test case %d (iteration %d) error = %d, abort unit testing engine!!!!\n",
i, j, mm_app_tc[i].r);
rc = mm_app_tc[i].r;
goto end;
}
}
}
end:
printf("nTOTAL_TSET_CASE = %d, NUM_TEST_RAN = %d, rc=%d\n", tc, i, rc);
return rc;
}

View file

@ -0,0 +1,258 @@
/*
Copyright (c) 2012-2014, 2016, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of The Linux Foundation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// Camera dependencies
#include "mm_qcamera_app.h"
#include "mm_qcamera_dbg.h"
static void mm_app_video_notify_cb(mm_camera_super_buf_t *bufs,
void *user_data)
{
char file_name[64];
mm_camera_buf_def_t *frame = bufs->bufs[0];
mm_camera_test_obj_t *pme = (mm_camera_test_obj_t *)user_data;
LOGD("BEGIN - length=%zu, frame idx = %d\n",
frame->frame_len, frame->frame_idx);
snprintf(file_name, sizeof(file_name), "V_C%d", pme->cam->camera_handle);
mm_app_dump_frame(frame, file_name, "yuv", frame->frame_idx);
if (MM_CAMERA_OK != pme->cam->ops->qbuf(bufs->camera_handle,
bufs->ch_id,
frame)) {
LOGE("Failed in Preview Qbuf\n");
}
mm_app_cache_ops((mm_camera_app_meminfo_t *)frame->mem_info,
ION_IOC_INV_CACHES);
LOGD("END\n");
}
mm_camera_stream_t * mm_app_add_video_stream(mm_camera_test_obj_t *test_obj,
mm_camera_channel_t *channel,
mm_camera_buf_notify_t stream_cb,
void *userdata,
uint8_t num_bufs)
{
int rc = MM_CAMERA_OK;
mm_camera_stream_t *stream = NULL;
cam_capability_t *cam_cap = (cam_capability_t *)(test_obj->cap_buf.buf.buffer);
stream = mm_app_add_stream(test_obj, channel);
if (NULL == stream) {
LOGE("add stream failed\n");
return NULL;
}
stream->s_config.mem_vtbl.get_bufs = mm_app_stream_initbuf;
stream->s_config.mem_vtbl.put_bufs = mm_app_stream_deinitbuf;
stream->s_config.mem_vtbl.clean_invalidate_buf =
mm_app_stream_clean_invalidate_buf;
stream->s_config.mem_vtbl.invalidate_buf = mm_app_stream_invalidate_buf;
stream->s_config.mem_vtbl.user_data = (void *)stream;
stream->s_config.stream_cb = stream_cb;
stream->s_config.stream_cb_sync = NULL;
stream->s_config.userdata = userdata;
stream->num_of_bufs = num_bufs;
stream->s_config.stream_info = (cam_stream_info_t *)stream->s_info_buf.buf.buffer;
memset(stream->s_config.stream_info, 0, sizeof(cam_stream_info_t));
stream->s_config.stream_info->stream_type = CAM_STREAM_TYPE_VIDEO;
stream->s_config.stream_info->streaming_mode = CAM_STREAMING_MODE_CONTINUOUS;
stream->s_config.stream_info->fmt = DEFAULT_VIDEO_FORMAT;
stream->s_config.stream_info->dim.width = DEFAULT_VIDEO_WIDTH;
stream->s_config.stream_info->dim.height = DEFAULT_VIDEO_HEIGHT;
stream->s_config.padding_info = cam_cap->padding_info;
rc = mm_app_config_stream(test_obj, channel, stream, &stream->s_config);
if (MM_CAMERA_OK != rc) {
LOGE("config preview stream err=%d\n", rc);
return NULL;
}
return stream;
}
mm_camera_channel_t * mm_app_add_video_channel(mm_camera_test_obj_t *test_obj)
{
mm_camera_channel_t *channel = NULL;
mm_camera_stream_t *stream = NULL;
channel = mm_app_add_channel(test_obj,
MM_CHANNEL_TYPE_VIDEO,
NULL,
NULL,
NULL);
if (NULL == channel) {
LOGE("add channel failed");
return NULL;
}
stream = mm_app_add_video_stream(test_obj,
channel,
mm_app_video_notify_cb,
(void *)test_obj,
1);
if (NULL == stream) {
LOGE("add video stream failed\n");
mm_app_del_channel(test_obj, channel);
return NULL;
}
return channel;
}
int mm_app_start_record_preview(mm_camera_test_obj_t *test_obj)
{
int rc = MM_CAMERA_OK;
mm_camera_channel_t *p_ch = NULL;
mm_camera_channel_t *v_ch = NULL;
mm_camera_channel_t *s_ch = NULL;
p_ch = mm_app_add_preview_channel(test_obj);
if (NULL == p_ch) {
LOGE("add preview channel failed");
return -MM_CAMERA_E_GENERAL;
}
v_ch = mm_app_add_video_channel(test_obj);
if (NULL == v_ch) {
LOGE("add video channel failed");
mm_app_del_channel(test_obj, p_ch);
return -MM_CAMERA_E_GENERAL;
}
s_ch = mm_app_add_snapshot_channel(test_obj);
if (NULL == s_ch) {
LOGE("add snapshot channel failed");
mm_app_del_channel(test_obj, p_ch);
mm_app_del_channel(test_obj, v_ch);
return -MM_CAMERA_E_GENERAL;
}
rc = mm_app_start_channel(test_obj, p_ch);
if (MM_CAMERA_OK != rc) {
LOGE("start preview failed rc=%d\n", rc);
mm_app_del_channel(test_obj, p_ch);
mm_app_del_channel(test_obj, v_ch);
mm_app_del_channel(test_obj, s_ch);
return rc;
}
return rc;
}
int mm_app_stop_record_preview(mm_camera_test_obj_t *test_obj)
{
int rc = MM_CAMERA_OK;
mm_camera_channel_t *p_ch = NULL;
mm_camera_channel_t *v_ch = NULL;
mm_camera_channel_t *s_ch = NULL;
p_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_PREVIEW);
v_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_VIDEO);
s_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_SNAPSHOT);
rc = mm_app_stop_and_del_channel(test_obj, p_ch);
if (MM_CAMERA_OK != rc) {
LOGE("Stop Preview failed rc=%d\n", rc);
}
rc = mm_app_stop_and_del_channel(test_obj, v_ch);
if (MM_CAMERA_OK != rc) {
LOGE("Stop Preview failed rc=%d\n", rc);
}
rc = mm_app_stop_and_del_channel(test_obj, s_ch);
if (MM_CAMERA_OK != rc) {
LOGE("Stop Preview failed rc=%d\n", rc);
}
return rc;
}
int mm_app_start_record(mm_camera_test_obj_t *test_obj)
{
int rc = MM_CAMERA_OK;
mm_camera_channel_t *v_ch = NULL;
v_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_VIDEO);
rc = mm_app_start_channel(test_obj, v_ch);
if (MM_CAMERA_OK != rc) {
LOGE("start recording failed rc=%d\n", rc);
}
return rc;
}
int mm_app_stop_record(mm_camera_test_obj_t *test_obj)
{
int rc = MM_CAMERA_OK;
mm_camera_channel_t *v_ch = NULL;
v_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_VIDEO);
rc = mm_app_stop_channel(test_obj, v_ch);
if (MM_CAMERA_OK != rc) {
LOGE("stop recording failed rc=%d\n", rc);
}
return rc;
}
int mm_app_start_live_snapshot(mm_camera_test_obj_t *test_obj)
{
int rc = MM_CAMERA_OK;
mm_camera_channel_t *s_ch = NULL;
s_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_SNAPSHOT);
rc = mm_app_start_channel(test_obj, s_ch);
if (MM_CAMERA_OK != rc) {
LOGE("start recording failed rc=%d\n", rc);
}
return rc;
}
int mm_app_stop_live_snapshot(mm_camera_test_obj_t *test_obj)
{
int rc = MM_CAMERA_OK;
mm_camera_channel_t *s_ch = NULL;
s_ch = mm_app_get_channel_by_type(test_obj, MM_CHANNEL_TYPE_SNAPSHOT);
rc = mm_app_stop_channel(test_obj, s_ch);
if (MM_CAMERA_OK != rc) {
LOGE("stop recording failed rc=%d\n", rc);
}
return rc;
}

View file

@ -0,0 +1,71 @@
OLD_LOCAL_PATH := $(LOCAL_PATH)
LOCAL_PATH := $(call my-dir)
include $(LOCAL_PATH)/../../../common.mk
include $(CLEAR_VARS)
LOCAL_32_BIT_ONLY := $(BOARD_QTI_CAMERA_32BIT_ONLY)
LOCAL_CFLAGS+= -D_ANDROID_ -DQCAMERA_REDEFINE_LOG
LOCAL_CFLAGS += -Wall -Wextra -Werror -Wno-unused-parameter
LOCAL_C_INCLUDES+= $(kernel_includes)
LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
LOCAL_C_INCLUDES += \
frameworks/native/include/media/openmax \
$(LOCAL_PATH)/inc \
$(LOCAL_PATH)/../common \
$(LOCAL_PATH)/../mm-camera-interface/inc \
$(LOCAL_PATH)/../../.. \
$(LOCAL_PATH)/../../../mm-image-codec/qexif \
$(LOCAL_PATH)/../../../mm-image-codec/qomx_core
ifeq ($(strip $(TARGET_USES_ION)),true)
LOCAL_CFLAGS += -DUSE_ION
endif
ifneq (,$(filter msm8610,$(TARGET_BOARD_PLATFORM)))
LOCAL_CFLAGS+= -DLOAD_ADSP_RPC_LIB
endif
DUAL_JPEG_TARGET_LIST := msm8974
DUAL_JPEG_TARGET_LIST += msm8994
ifneq (,$(filter $(DUAL_JPEG_TARGET_LIST),$(TARGET_BOARD_PLATFORM)))
LOCAL_CFLAGS+= -DMM_JPEG_CONCURRENT_SESSIONS_COUNT=2
else
LOCAL_CFLAGS+= -DMM_JPEG_CONCURRENT_SESSIONS_COUNT=1
endif
JPEG_PIPELINE_TARGET_LIST := msm8994
JPEG_PIPELINE_TARGET_LIST += msm8992
JPEG_PIPELINE_TARGET_LIST += msm8996
ifneq (,$(filter $(JPEG_PIPELINE_TARGET_LIST),$(TARGET_BOARD_PLATFORM)))
LOCAL_CFLAGS+= -DMM_JPEG_USE_PIPELINE
endif
# System header file path prefix
LOCAL_CFLAGS += -DSYSTEM_HEADER_PREFIX=sys
LOCAL_SRC_FILES := \
src/mm_jpeg_queue.c \
src/mm_jpeg_exif.c \
src/mm_jpeg.c \
src/mm_jpeg_interface.c \
src/mm_jpeg_ionbuf.c \
src/mm_jpegdec_interface.c \
src/mm_jpegdec.c \
src/mm_jpeg_mpo_composer.c
LOCAL_MODULE := libmmjpeg_interface
LOCAL_CLANG := false
LOCAL_PRELINK_MODULE := false
LOCAL_SHARED_LIBRARIES := libdl libcutils liblog libqomx_core libmmcamera_interface
LOCAL_MODULE_TAGS := optional
LOCAL_32_BIT_ONLY := $(BOARD_QTI_CAMERA_32BIT_ONLY)
include $(BUILD_SHARED_LIBRARY)
LOCAL_PATH := $(OLD_LOCAL_PATH)

View file

@ -0,0 +1,515 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef MM_JPEG_H_
#define MM_JPEG_H_
// OpenMAX dependencies
#include "OMX_Types.h"
#include "OMX_Index.h"
#include "OMX_Core.h"
#include "OMX_Component.h"
#include "QOMX_JpegExtensions.h"
// JPEG dependencies
#include "mm_jpeg_interface.h"
#include "mm_jpeg_ionbuf.h"
// Camera dependencies
#include "cam_list.h"
#include "cam_semaphore.h"
#define MM_JPEG_MAX_THREADS 30
#define MM_JPEG_CIRQ_SIZE 30
#define MM_JPEG_MAX_SESSION 10
#define MAX_EXIF_TABLE_ENTRIES 50
#define MAX_JPEG_SIZE 20000000
#define MAX_OMX_HANDLES (5)
/** mm_jpeg_abort_state_t:
* @MM_JPEG_ABORT_NONE: Abort is not issued
* @MM_JPEG_ABORT_INIT: Abort is issued from the client
* @MM_JPEG_ABORT_DONE: Abort is completed
*
* State representing the abort state
**/
typedef enum {
MM_JPEG_ABORT_NONE,
MM_JPEG_ABORT_INIT,
MM_JPEG_ABORT_DONE,
} mm_jpeg_abort_state_t;
/* define max num of supported concurrent jpeg jobs by OMX engine.
* Current, only one per time */
#define NUM_MAX_JPEG_CNCURRENT_JOBS 2
#define JOB_ID_MAGICVAL 0x1
#define JOB_HIST_MAX 10000
/** DUMP_TO_FILE:
* @filename: file name
* @p_addr: address of the buffer
* @len: buffer length
*
* dump the image to the file
**/
#define DUMP_TO_FILE(filename, p_addr, len) ({ \
size_t rc = 0; \
FILE *fp = fopen(filename, "w+"); \
if (fp) { \
rc = fwrite(p_addr, 1, len, fp); \
LOGE("written size %zu", len); \
fclose(fp); \
} else { \
LOGE("open %s failed", filename); \
} \
})
/** DUMP_TO_FILE2:
* @filename: file name
* @p_addr: address of the buffer
* @len: buffer length
*
* dump the image to the file if the memory is non-contiguous
**/
#define DUMP_TO_FILE2(filename, p_addr1, len1, paddr2, len2) ({ \
size_t rc = 0; \
FILE *fp = fopen(filename, "w+"); \
if (fp) { \
rc = fwrite(p_addr1, 1, len1, fp); \
rc = fwrite(p_addr2, 1, len2, fp); \
LOGE("written %zu %zu", len1, len2); \
fclose(fp); \
} else { \
LOGE("open %s failed", filename); \
} \
})
/** MM_JPEG_CHK_ABORT:
* @p: client pointer
* @ret: return value
* @label: label to jump to
*
* check the abort failure
**/
#define MM_JPEG_CHK_ABORT(p, ret, label) ({ \
if (MM_JPEG_ABORT_INIT == p->abort_state) { \
LOGE("jpeg abort"); \
ret = OMX_ErrorNone; \
goto label; \
} \
})
#define GET_CLIENT_IDX(x) ((x) & 0xff)
#define GET_SESSION_IDX(x) (((x) >> 8) & 0xff)
#define GET_JOB_IDX(x) (((x) >> 16) & 0xff)
typedef struct {
union {
int i_data[MM_JPEG_CIRQ_SIZE];
void *p_data[MM_JPEG_CIRQ_SIZE];
};
int front;
int rear;
int count;
pthread_mutex_t lock;
} mm_jpeg_cirq_t;
/** cirq_reset:
*
* Arguments:
* @q: circular queue
*
* Return:
* none
*
* Description:
* Resets the circular queue
*
**/
static inline void cirq_reset(mm_jpeg_cirq_t *q)
{
q->front = 0;
q->rear = 0;
q->count = 0;
pthread_mutex_init(&q->lock, NULL);
}
/** cirq_empty:
*
* Arguments:
* @q: circular queue
*
* Return:
* none
*
* Description:
* check if the curcular queue is empty
*
**/
#define cirq_empty(q) (q->count == 0)
/** cirq_full:
*
* Arguments:
* @q: circular queue
*
* Return:
* none
*
* Description:
* check if the curcular queue is full
*
**/
#define cirq_full(q) (q->count == MM_JPEG_CIRQ_SIZE)
/** cirq_enqueue:
*
* Arguments:
* @q: circular queue
* @data: data to be inserted
*
* Return:
* true/false
*
* Description:
* enqueue an element into circular queue
*
**/
#define cirq_enqueue(q, type, data) ({ \
int rc = 0; \
pthread_mutex_lock(&q->lock); \
if (cirq_full(q)) { \
rc = -1; \
} else { \
q->type[q->rear] = data; \
q->rear = (q->rear + 1) % MM_JPEG_CIRQ_SIZE; \
q->count++; \
} \
pthread_mutex_unlock(&q->lock); \
rc; \
})
/** cirq_dequeue:
*
* Arguments:
* @q: circular queue
* @data: data to be popped
*
* Return:
* true/false
*
* Description:
* dequeue an element from the circular queue
*
**/
#define cirq_dequeue(q, type, data) ({ \
int rc = 0; \
pthread_mutex_lock(&q->lock); \
if (cirq_empty(q)) { \
pthread_mutex_unlock(&q->lock); \
rc = -1; \
} else { \
data = q->type[q->front]; \
q->count--; \
} \
pthread_mutex_unlock(&q->lock); \
rc; \
})
typedef union {
uint32_t u32;
void* p;
} mm_jpeg_q_data_t;
typedef struct {
struct cam_list list;
mm_jpeg_q_data_t data;
} mm_jpeg_q_node_t;
typedef struct {
mm_jpeg_q_node_t head; /* dummy head */
uint32_t size;
pthread_mutex_t lock;
} mm_jpeg_queue_t;
typedef enum {
MM_JPEG_CMD_TYPE_JOB, /* job cmd */
MM_JPEG_CMD_TYPE_EXIT, /* EXIT cmd for exiting jobMgr thread */
MM_JPEG_CMD_TYPE_DECODE_JOB,
MM_JPEG_CMD_TYPE_MAX
} mm_jpeg_cmd_type_t;
typedef struct mm_jpeg_job_session {
uint32_t client_hdl; /* client handler */
uint32_t jobId; /* job ID */
uint32_t sessionId; /* session ID */
mm_jpeg_encode_params_t params; /* encode params */
mm_jpeg_decode_params_t dec_params; /* encode params */
mm_jpeg_encode_job_t encode_job; /* job description */
mm_jpeg_decode_job_t decode_job;
pthread_t encode_pid; /* encode thread handler*/
void *jpeg_obj; /* ptr to mm_jpeg_obj */
jpeg_job_status_t job_status; /* job status */
int state_change_pending; /* flag to indicate if state change is pending */
OMX_ERRORTYPE error_flag; /* variable to indicate error during encoding */
mm_jpeg_abort_state_t abort_state; /* variable to indicate abort during encoding */
/* OMX related */
OMX_HANDLETYPE omx_handle; /* handle to omx engine */
OMX_CALLBACKTYPE omx_callbacks; /* callbacks to omx engine */
/* buffer headers */
OMX_BUFFERHEADERTYPE *p_in_omx_buf[MM_JPEG_MAX_BUF];
OMX_BUFFERHEADERTYPE *p_in_omx_thumb_buf[MM_JPEG_MAX_BUF];
OMX_BUFFERHEADERTYPE *p_out_omx_buf[MM_JPEG_MAX_BUF];
OMX_PARAM_PORTDEFINITIONTYPE inputPort;
OMX_PARAM_PORTDEFINITIONTYPE outputPort;
OMX_PARAM_PORTDEFINITIONTYPE inputTmbPort;
/* event locks */
pthread_mutex_t lock;
pthread_cond_t cond;
QEXIF_INFO_DATA exif_info_local[MAX_EXIF_TABLE_ENTRIES]; //all exif tags for JPEG encoder
int exif_count_local;
mm_jpeg_cirq_t cb_q;
int32_t ebd_count;
int32_t fbd_count;
/* this flag represents whether the job is active */
OMX_BOOL active;
/* this flag indicates if the configration is complete */
OMX_BOOL config;
/* job history count to generate unique id */
unsigned int job_hist;
OMX_BOOL encoding;
buffer_t work_buffer;
OMX_EVENTTYPE omxEvent;
int event_pending;
uint8_t *meta_enc_key;
size_t meta_enc_keylen;
struct mm_jpeg_job_session *next_session;
uint32_t curr_out_buf_idx;
uint32_t num_omx_sessions;
OMX_BOOL auto_out_buf;
mm_jpeg_queue_t *session_handle_q;
mm_jpeg_queue_t *out_buf_q;
int thumb_from_main;
uint32_t job_index;
} mm_jpeg_job_session_t;
typedef struct {
mm_jpeg_encode_job_t encode_job;
uint32_t job_id;
uint32_t client_handle;
} mm_jpeg_encode_job_info_t;
typedef struct {
mm_jpeg_decode_job_t decode_job;
uint32_t job_id;
uint32_t client_handle;
} mm_jpeg_decode_job_info_t;
typedef struct {
mm_jpeg_cmd_type_t type;
union {
mm_jpeg_encode_job_info_t enc_info;
mm_jpeg_decode_job_info_t dec_info;
};
} mm_jpeg_job_q_node_t;
typedef struct {
uint8_t is_used; /* flag: if is a valid client */
uint32_t client_handle; /* client handle */
mm_jpeg_job_session_t session[MM_JPEG_MAX_SESSION];
pthread_mutex_t lock; /* job lock */
} mm_jpeg_client_t;
typedef struct {
pthread_t pid; /* job cmd thread ID */
cam_semaphore_t job_sem; /* semaphore for job cmd thread */
mm_jpeg_queue_t job_queue; /* queue for job to do */
} mm_jpeg_job_cmd_thread_t;
#define MAX_JPEG_CLIENT_NUM 8
typedef struct mm_jpeg_obj_t {
/* ClientMgr */
int num_clients; /* num of clients */
mm_jpeg_client_t clnt_mgr[MAX_JPEG_CLIENT_NUM]; /* client manager */
/* JobMkr */
pthread_mutex_t job_lock; /* job lock */
mm_jpeg_job_cmd_thread_t job_mgr; /* job mgr thread including todo_q*/
mm_jpeg_queue_t ongoing_job_q; /* queue for ongoing jobs */
buffer_t ionBuffer[MM_JPEG_CONCURRENT_SESSIONS_COUNT];
/* Max pic dimension for work buf calc*/
uint32_t max_pic_w;
uint32_t max_pic_h;
#ifdef LOAD_ADSP_RPC_LIB
void *adsprpc_lib_handle;
#endif
uint32_t work_buf_cnt;
uint32_t num_sessions;
uint32_t reuse_reproc_buffer;
cam_jpeg_metadata_t *jpeg_metadata;
} mm_jpeg_obj;
/** mm_jpeg_pending_func_t:
*
* Intermediate function for transition change
**/
typedef OMX_ERRORTYPE (*mm_jpeg_transition_func_t)(void *);
extern int32_t mm_jpeg_init(mm_jpeg_obj *my_obj);
extern int32_t mm_jpeg_deinit(mm_jpeg_obj *my_obj);
extern uint32_t mm_jpeg_new_client(mm_jpeg_obj *my_obj);
extern int32_t mm_jpeg_start_job(mm_jpeg_obj *my_obj,
mm_jpeg_job_t* job,
uint32_t* jobId);
extern int32_t mm_jpeg_abort_job(mm_jpeg_obj *my_obj,
uint32_t jobId);
extern int32_t mm_jpeg_close(mm_jpeg_obj *my_obj,
uint32_t client_hdl);
extern int32_t mm_jpeg_create_session(mm_jpeg_obj *my_obj,
uint32_t client_hdl,
mm_jpeg_encode_params_t *p_params,
uint32_t* p_session_id);
extern int32_t mm_jpeg_destroy_session_by_id(mm_jpeg_obj *my_obj,
uint32_t session_id);
extern int32_t mm_jpegdec_init(mm_jpeg_obj *my_obj);
extern int32_t mm_jpegdec_deinit(mm_jpeg_obj *my_obj);
extern int32_t mm_jpeg_jobmgr_thread_release(mm_jpeg_obj * my_obj);
extern int32_t mm_jpeg_jobmgr_thread_launch(mm_jpeg_obj *my_obj);
extern int32_t mm_jpegdec_start_decode_job(mm_jpeg_obj *my_obj,
mm_jpeg_job_t* job,
uint32_t* jobId);
extern int32_t mm_jpegdec_create_session(mm_jpeg_obj *my_obj,
uint32_t client_hdl,
mm_jpeg_decode_params_t *p_params,
uint32_t* p_session_id);
extern int32_t mm_jpegdec_destroy_session_by_id(mm_jpeg_obj *my_obj,
uint32_t session_id);
extern int32_t mm_jpegdec_abort_job(mm_jpeg_obj *my_obj,
uint32_t jobId);
int32_t mm_jpegdec_process_decoding_job(mm_jpeg_obj *my_obj,
mm_jpeg_job_q_node_t* job_node);
/* utiltity fucntion declared in mm-camera-inteface2.c
* and need be used by mm-camera and below*/
uint32_t mm_jpeg_util_generate_handler(uint8_t index);
uint8_t mm_jpeg_util_get_index_by_handler(uint32_t handler);
/* basic queue functions */
extern int32_t mm_jpeg_queue_init(mm_jpeg_queue_t* queue);
extern int32_t mm_jpeg_queue_enq(mm_jpeg_queue_t* queue,
mm_jpeg_q_data_t data);
extern int32_t mm_jpeg_queue_enq_head(mm_jpeg_queue_t* queue,
mm_jpeg_q_data_t data);
extern mm_jpeg_q_data_t mm_jpeg_queue_deq(mm_jpeg_queue_t* queue);
extern int32_t mm_jpeg_queue_deinit(mm_jpeg_queue_t* queue);
extern int32_t mm_jpeg_queue_flush(mm_jpeg_queue_t* queue);
extern uint32_t mm_jpeg_queue_get_size(mm_jpeg_queue_t* queue);
extern mm_jpeg_q_data_t mm_jpeg_queue_peek(mm_jpeg_queue_t* queue);
extern int32_t addExifEntry(QOMX_EXIF_INFO *p_exif_info, exif_tag_id_t tagid,
exif_tag_type_t type, uint32_t count, void *data);
extern int32_t releaseExifEntry(QEXIF_INFO_DATA *p_exif_data);
extern int process_meta_data(metadata_buffer_t *p_meta,
QOMX_EXIF_INFO *exif_info, mm_jpeg_exif_params_t *p_cam3a_params,
cam_hal_version_t hal_version);
OMX_ERRORTYPE mm_jpeg_session_change_state(mm_jpeg_job_session_t* p_session,
OMX_STATETYPE new_state,
mm_jpeg_transition_func_t p_exec);
int map_jpeg_format(mm_jpeg_color_format color_fmt);
OMX_BOOL mm_jpeg_session_abort(mm_jpeg_job_session_t *p_session);
/**
*
* special queue functions for job queue
**/
mm_jpeg_job_q_node_t* mm_jpeg_queue_remove_job_by_client_id(
mm_jpeg_queue_t* queue, uint32_t client_hdl);
mm_jpeg_job_q_node_t* mm_jpeg_queue_remove_job_by_job_id(
mm_jpeg_queue_t* queue, uint32_t job_id);
mm_jpeg_job_q_node_t* mm_jpeg_queue_remove_job_by_session_id(
mm_jpeg_queue_t* queue, uint32_t session_id);
mm_jpeg_job_q_node_t* mm_jpeg_queue_remove_job_unlk(
mm_jpeg_queue_t* queue, uint32_t job_id);
/** mm_jpeg_queue_func_t:
*
* Intermediate function for queue operation
**/
typedef void (*mm_jpeg_queue_func_t)(void *);
/** mm_jpeg_exif_flash_mode:
*
* Exif flash mode values
**/
typedef enum {
MM_JPEG_EXIF_FLASH_MODE_ON = 0x1,
MM_JPEG_EXIF_FLASH_MODE_OFF = 0x2,
MM_JPEG_EXIF_FLASH_MODE_AUTO = 0x3,
MM_JPEG_EXIF_FLASH_MODE_MAX
} mm_jpeg_exif_flash_mode;
#endif /* MM_JPEG_H_ */

View file

@ -0,0 +1,55 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __MM_JPEG_DBG_H__
#define __MM_JPEG_DBG_H__
#ifdef QCAMERA_REDEFINE_LOG
#define CAM_MODULE CAM_JPEG_MODULE
#include "mm_camera_dbg.h"
#endif
extern volatile uint32_t gKpiDebugLevel;
#ifndef KPI_DEBUG
#define KPI_DEBUG
#define ATRACE_TAG ATRACE_TAG_CAMERA
#include <cutils/trace.h>
#define KPI_APT 1
#define KPI_DBG 2
#define KPI_ATRACE_INT(name,val) ({\
if (gKpiDebugLevel >= KPI_APT) { \
atrace_int(ATRACE_TAG, name, val); \
}\
})
#endif
#endif /* __MM_JPEG_DBG_H__ */

View file

@ -0,0 +1,127 @@
/* Copyright (c) 2013, 2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef MM_JPEG_INLINES_H_
#define MM_JPEG_INLINES_H_
// JPEG dependencies
#include "mm_jpeg.h"
/** mm_jpeg_get_session:
*
* Arguments:
* @my_obj: jpeg object
* @client_idx: client index
*
* Return:
* job index
*
* Description:
* Get job index by client id
*
**/
static inline mm_jpeg_job_session_t *mm_jpeg_get_session(mm_jpeg_obj *my_obj, uint32_t job_id)
{
mm_jpeg_job_session_t *p_session = NULL;
int client_idx = GET_CLIENT_IDX(job_id);
int session_idx= GET_SESSION_IDX(job_id);
LOGD("client_idx %d session_idx %d",
client_idx, session_idx);
if ((session_idx >= MM_JPEG_MAX_SESSION) ||
(client_idx >= MAX_JPEG_CLIENT_NUM)) {
LOGE("invalid job id %x",
job_id);
return NULL;
}
pthread_mutex_lock(&my_obj->clnt_mgr[client_idx].lock);
p_session = &my_obj->clnt_mgr[client_idx].session[session_idx];
pthread_mutex_unlock(&my_obj->clnt_mgr[client_idx].lock);
return p_session;
}
/** mm_jpeg_get_job_idx:
*
* Arguments:
* @my_obj: jpeg object
* @client_idx: client index
*
* Return:
* job index
*
* Description:
* Get job index by client id
*
**/
static inline int mm_jpeg_get_new_session_idx(mm_jpeg_obj *my_obj, int client_idx,
mm_jpeg_job_session_t **pp_session)
{
int i = 0;
int index = -1;
for (i = 0; i < MM_JPEG_MAX_SESSION; i++) {
pthread_mutex_lock(&my_obj->clnt_mgr[client_idx].lock);
if (!my_obj->clnt_mgr[client_idx].session[i].active) {
*pp_session = &my_obj->clnt_mgr[client_idx].session[i];
my_obj->clnt_mgr[client_idx].session[i].active = OMX_TRUE;
index = i;
pthread_mutex_unlock(&my_obj->clnt_mgr[client_idx].lock);
break;
}
pthread_mutex_unlock(&my_obj->clnt_mgr[client_idx].lock);
}
return index;
}
/** mm_jpeg_get_job_idx:
*
* Arguments:
* @my_obj: jpeg object
* @client_idx: client index
*
* Return:
* job index
*
* Description:
* Get job index by client id
*
**/
static inline void mm_jpeg_remove_session_idx(mm_jpeg_obj *my_obj, uint32_t job_id)
{
int client_idx = GET_CLIENT_IDX(job_id);
int session_idx= GET_SESSION_IDX(job_id);
LOGD("client_idx %d session_idx %d",
client_idx, session_idx);
pthread_mutex_lock(&my_obj->clnt_mgr[client_idx].lock);
my_obj->clnt_mgr[client_idx].session[session_idx].active = OMX_FALSE;
pthread_mutex_unlock(&my_obj->clnt_mgr[client_idx].lock);
}
#endif /* MM_JPEG_INLINES_H_ */

View file

@ -0,0 +1,91 @@
/* Copyright (c) 2013-2014, 2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef __MM_JPEG_IONBUF_H__
#define __MM_JPEG_IONBUF_H__
// System dependencies
#include <linux/msm_ion.h>
// JPEG dependencies
#include "mm_jpeg_dbg.h"
typedef struct {
struct ion_fd_data ion_info_fd;
struct ion_allocation_data alloc;
int p_pmem_fd;
size_t size;
int ion_fd;
uint8_t *addr;
} buffer_t;
/** buffer_allocate:
*
* Arguments:
* @p_buffer: ION buffer
*
* Return:
* buffer address
*
* Description:
* allocates ION buffer
*
**/
void* buffer_allocate(buffer_t *p_buffer, int cached);
/** buffer_deallocate:
*
* Arguments:
* @p_buffer: ION buffer
*
* Return:
* error val
*
* Description:
* deallocates ION buffer
*
**/
int buffer_deallocate(buffer_t *p_buffer);
/** buffer_invalidate:
*
* Arguments:
* @p_buffer: ION buffer
*
* Return:
* error val
*
* Description:
* Invalidates the cached buffer
*
**/
int buffer_invalidate(buffer_t *p_buffer);
#endif

View file

@ -0,0 +1,45 @@
/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef MM_JPEG_MPO_H_
#define MM_JPEG_MPO_H_
// JPEG dependencies
#include "mm_jpeg_interface.h"
#include "qmpo.h"
#define TRUE 1
#define FALSE 0
extern int mm_jpeg_mpo_compose(mm_jpeg_mpo_info_t *mpo_info);
extern int get_mpo_size(mm_jpeg_output_t jpeg_buffer[MM_JPEG_MAX_MPO_IMAGES],
int num_of_images);
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,650 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
// System dependencies
#include <pthread.h>
#include <string.h>
#include <math.h>
// JPEG dependencies
#include "mm_jpeg_dbg.h"
#include "mm_jpeg.h"
#define LOWER(a) ((a) & 0xFFFF)
#define UPPER(a) (((a)>>16) & 0xFFFF)
#define CHANGE_ENDIAN_16(a) ((0x00FF & ((a)>>8)) | (0xFF00 & ((a)<<8)))
#define ROUND(a) \
((a >= 0) ? (uint32_t)(a + 0.5) : (uint32_t)(a - 0.5))
/** addExifEntry:
*
* Arguments:
* @exif_info : Exif info struct
* @p_session: job session
* @tagid : exif tag ID
* @type : data type
* @count : number of data in uint of its type
* @data : input data ptr
*
* Retrun : int32_t type of status
* 0 -- success
* none-zero failure code
*
* Description:
* Function to add an entry to exif data
*
**/
int32_t addExifEntry(QOMX_EXIF_INFO *p_exif_info, exif_tag_id_t tagid,
exif_tag_type_t type, uint32_t count, void *data)
{
int32_t rc = 0;
uint32_t numOfEntries = (uint32_t)p_exif_info->numOfEntries;
QEXIF_INFO_DATA *p_info_data = p_exif_info->exif_data;
if(numOfEntries >= MAX_EXIF_TABLE_ENTRIES) {
LOGE("Number of entries exceeded limit");
return -1;
}
p_info_data[numOfEntries].tag_id = tagid;
p_info_data[numOfEntries].tag_entry.type = type;
p_info_data[numOfEntries].tag_entry.count = count;
p_info_data[numOfEntries].tag_entry.copy = 1;
switch (type) {
case EXIF_BYTE: {
if (count > 1) {
uint8_t *values = (uint8_t *)malloc(count);
if (values == NULL) {
LOGE("No memory for byte array");
rc = -1;
} else {
memcpy(values, data, count);
p_info_data[numOfEntries].tag_entry.data._bytes = values;
}
} else {
p_info_data[numOfEntries].tag_entry.data._byte = *(uint8_t *)data;
}
}
break;
case EXIF_ASCII: {
char *str = NULL;
str = (char *)malloc(count + 1);
if (str == NULL) {
LOGE("No memory for ascii string");
rc = -1;
} else {
memset(str, 0, count + 1);
memcpy(str, data, count);
p_info_data[numOfEntries].tag_entry.data._ascii = str;
}
}
break;
case EXIF_SHORT: {
if (count > 1) {
uint16_t *values = (uint16_t *)malloc(count * sizeof(uint16_t));
if (values == NULL) {
LOGE("No memory for short array");
rc = -1;
} else {
memcpy(values, data, count * sizeof(uint16_t));
p_info_data[numOfEntries].tag_entry.data._shorts = values;
}
} else {
p_info_data[numOfEntries].tag_entry.data._short = *(uint16_t *)data;
}
}
break;
case EXIF_LONG: {
if (count > 1) {
uint32_t *values = (uint32_t *)malloc(count * sizeof(uint32_t));
if (values == NULL) {
LOGE("No memory for long array");
rc = -1;
} else {
memcpy(values, data, count * sizeof(uint32_t));
p_info_data[numOfEntries].tag_entry.data._longs = values;
}
} else {
p_info_data[numOfEntries].tag_entry.data._long = *(uint32_t *)data;
}
}
break;
case EXIF_RATIONAL: {
if (count > 1) {
rat_t *values = (rat_t *)malloc(count * sizeof(rat_t));
if (values == NULL) {
LOGE("No memory for rational array");
rc = -1;
} else {
memcpy(values, data, count * sizeof(rat_t));
p_info_data[numOfEntries].tag_entry.data._rats = values;
}
} else {
p_info_data[numOfEntries].tag_entry.data._rat = *(rat_t *)data;
}
}
break;
case EXIF_UNDEFINED: {
uint8_t *values = (uint8_t *)malloc(count);
if (values == NULL) {
LOGE("No memory for undefined array");
rc = -1;
} else {
memcpy(values, data, count);
p_info_data[numOfEntries].tag_entry.data._undefined = values;
}
}
break;
case EXIF_SLONG: {
if (count > 1) {
int32_t *values = (int32_t *)malloc(count * sizeof(int32_t));
if (values == NULL) {
LOGE("No memory for signed long array");
rc = -1;
} else {
memcpy(values, data, count * sizeof(int32_t));
p_info_data[numOfEntries].tag_entry.data._slongs = values;
}
} else {
p_info_data[numOfEntries].tag_entry.data._slong = *(int32_t *)data;
}
}
break;
case EXIF_SRATIONAL: {
if (count > 1) {
srat_t *values = (srat_t *)malloc(count * sizeof(srat_t));
if (values == NULL) {
LOGE("No memory for signed rational array");
rc = -1;
} else {
memcpy(values, data, count * sizeof(srat_t));
p_info_data[numOfEntries].tag_entry.data._srats = values;
}
} else {
p_info_data[numOfEntries].tag_entry.data._srat = *(srat_t *)data;
}
}
break;
}
// Increase number of entries
p_exif_info->numOfEntries++;
return rc;
}
/** releaseExifEntry
*
* Arguments:
* @p_exif_data : Exif info struct
*
* Retrun : int32_t type of status
* 0 -- success
* none-zero failure code
*
* Description:
* Function to release an entry from exif data
*
**/
int32_t releaseExifEntry(QEXIF_INFO_DATA *p_exif_data)
{
switch (p_exif_data->tag_entry.type) {
case EXIF_BYTE: {
if (p_exif_data->tag_entry.count > 1 &&
p_exif_data->tag_entry.data._bytes != NULL) {
free(p_exif_data->tag_entry.data._bytes);
p_exif_data->tag_entry.data._bytes = NULL;
}
}
break;
case EXIF_ASCII: {
if (p_exif_data->tag_entry.data._ascii != NULL) {
free(p_exif_data->tag_entry.data._ascii);
p_exif_data->tag_entry.data._ascii = NULL;
}
}
break;
case EXIF_SHORT: {
if (p_exif_data->tag_entry.count > 1 &&
p_exif_data->tag_entry.data._shorts != NULL) {
free(p_exif_data->tag_entry.data._shorts);
p_exif_data->tag_entry.data._shorts = NULL;
}
}
break;
case EXIF_LONG: {
if (p_exif_data->tag_entry.count > 1 &&
p_exif_data->tag_entry.data._longs != NULL) {
free(p_exif_data->tag_entry.data._longs);
p_exif_data->tag_entry.data._longs = NULL;
}
}
break;
case EXIF_RATIONAL: {
if (p_exif_data->tag_entry.count > 1 &&
p_exif_data->tag_entry.data._rats != NULL) {
free(p_exif_data->tag_entry.data._rats);
p_exif_data->tag_entry.data._rats = NULL;
}
}
break;
case EXIF_UNDEFINED: {
if (p_exif_data->tag_entry.data._undefined != NULL) {
free(p_exif_data->tag_entry.data._undefined);
p_exif_data->tag_entry.data._undefined = NULL;
}
}
break;
case EXIF_SLONG: {
if (p_exif_data->tag_entry.count > 1 &&
p_exif_data->tag_entry.data._slongs != NULL) {
free(p_exif_data->tag_entry.data._slongs);
p_exif_data->tag_entry.data._slongs = NULL;
}
}
break;
case EXIF_SRATIONAL: {
if (p_exif_data->tag_entry.count > 1 &&
p_exif_data->tag_entry.data._srats != NULL) {
free(p_exif_data->tag_entry.data._srats);
p_exif_data->tag_entry.data._srats = NULL;
}
}
break;
} /*end of switch*/
return 0;
}
/** process_sensor_data:
*
* Arguments:
* @p_sensor_params : ptr to sensor data
*
* Return : int32_t type of status
* NO_ERROR -- success
* none-zero failure code
*
* Description:
* process sensor data
*
* Notes: this needs to be filled for the metadata
**/
int process_sensor_data(cam_sensor_params_t *p_sensor_params,
QOMX_EXIF_INFO *exif_info)
{
int rc = 0;
rat_t val_rat;
if (NULL == p_sensor_params) {
LOGE("Sensor params are null");
return 0;
}
LOGD("From metadata aperture = %f ",
p_sensor_params->aperture_value );
if (p_sensor_params->aperture_value >= 1.0) {
double apex_value;
apex_value = (double)2.0 * log(p_sensor_params->aperture_value) / log(2.0);
val_rat.num = (uint32_t)(apex_value * 100);
val_rat.denom = 100;
rc = addExifEntry(exif_info, EXIFTAGID_APERTURE, EXIF_RATIONAL, 1, &val_rat);
if (rc) {
LOGE(": Error adding Exif Entry");
}
val_rat.num = (uint32_t)(p_sensor_params->aperture_value * 100);
val_rat.denom = 100;
rc = addExifEntry(exif_info, EXIFTAGID_F_NUMBER, EXIF_RATIONAL, 1, &val_rat);
if (rc) {
LOGE(": Error adding Exif Entry");
}
}
/*Flash*/
short val_short;
int flash_mode_exif, flash_fired;
if (p_sensor_params->flash_state == CAM_FLASH_STATE_FIRED) {
flash_fired = 1;
} else {
flash_fired = 0;
}
LOGD("Flash value %d flash mode %d flash state %d", val_short,
p_sensor_params->flash_mode, p_sensor_params->flash_state);
switch(p_sensor_params->flash_mode) {
case CAM_FLASH_MODE_OFF:
flash_mode_exif = MM_JPEG_EXIF_FLASH_MODE_OFF;
break;
case CAM_FLASH_MODE_ON:
flash_mode_exif = MM_JPEG_EXIF_FLASH_MODE_ON;
break;
case CAM_FLASH_MODE_AUTO:
flash_mode_exif = MM_JPEG_EXIF_FLASH_MODE_AUTO;
break;
default:
flash_mode_exif = MM_JPEG_EXIF_FLASH_MODE_AUTO;
LOGE(": Unsupported flash mode");
}
val_short = (short)(flash_fired | (flash_mode_exif << 3));
rc = addExifEntry(exif_info, EXIFTAGID_FLASH, EXIF_SHORT, 1, &val_short);
if (rc) {
LOGE(": Error adding flash exif entry");
}
/* Sensing Method */
val_short = (short) p_sensor_params->sensing_method;
rc = addExifEntry(exif_info, EXIFTAGID_SENSING_METHOD, EXIF_SHORT,
sizeof(val_short)/2, &val_short);
if (rc) {
LOGE(": Error adding flash Exif Entry");
}
/* Focal Length in 35 MM Film */
val_short = (short)
((p_sensor_params->focal_length * p_sensor_params->crop_factor) + 0.5f);
rc = addExifEntry(exif_info, EXIFTAGID_FOCAL_LENGTH_35MM, EXIF_SHORT,
1, &val_short);
if (rc) {
LOGE(": Error adding Exif Entry");
}
/* F Number */
val_rat.num = (uint32_t)(p_sensor_params->f_number * 100);
val_rat.denom = 100;
rc = addExifEntry(exif_info, EXIFTAGTYPE_F_NUMBER, EXIF_RATIONAL, 1, &val_rat);
if (rc) {
LOGE(": Error adding Exif Entry");
}
return rc;
}
/** process_3a_data:
*
* Arguments:
* @p_3a_params : ptr to 3a data
* @exif_info : Exif info struct
*
* Return : int32_t type of status
* NO_ERROR -- success
* none-zero failure code
*
* Description:
* process 3a data
*
* Notes: this needs to be filled for the metadata
**/
int process_3a_data(cam_3a_params_t *p_3a_params, QOMX_EXIF_INFO *exif_info)
{
int rc = 0;
srat_t val_srat;
rat_t val_rat;
double shutter_speed_value;
if (NULL == p_3a_params) {
LOGE("3A params are null");
return 0;
}
LOGD("exp_time %f, iso_value %d, wb_mode %d",
p_3a_params->exp_time, p_3a_params->iso_value, p_3a_params->wb_mode);
/* Exposure time */
if (p_3a_params->exp_time <= 0.0f) {
val_rat.num = 0;
val_rat.denom = 0;
} else if (p_3a_params->exp_time < 1.0f) {
val_rat.num = 1;
val_rat.denom = ROUND(1.0/p_3a_params->exp_time);
} else {
val_rat.num = ROUND(p_3a_params->exp_time);
val_rat.denom = 1;
}
LOGD("numer %d denom %d %zd", val_rat.num, val_rat.denom,
sizeof(val_rat) / (8));
rc = addExifEntry(exif_info, EXIFTAGID_EXPOSURE_TIME, EXIF_RATIONAL,
(sizeof(val_rat)/(8)), &val_rat);
if (rc) {
LOGE(": Error adding Exif Entry Exposure time");
}
/* Shutter Speed*/
if (p_3a_params->exp_time > 0) {
shutter_speed_value = log10(1/p_3a_params->exp_time)/log10(2);
val_srat.num = (int32_t)(shutter_speed_value * 1000);
val_srat.denom = 1000;
} else {
val_srat.num = 0;
val_srat.denom = 0;
}
rc = addExifEntry(exif_info, EXIFTAGID_SHUTTER_SPEED, EXIF_SRATIONAL,
(sizeof(val_srat)/(8)), &val_srat);
if (rc) {
LOGE(": Error adding Exif Entry");
}
/*ISO*/
short val_short;
val_short = (short)p_3a_params->iso_value;
rc = addExifEntry(exif_info, EXIFTAGID_ISO_SPEED_RATING, EXIF_SHORT,
sizeof(val_short)/2, &val_short);
if (rc) {
LOGE(": Error adding Exif Entry");
}
/*WB mode*/
if (p_3a_params->wb_mode == CAM_WB_MODE_AUTO)
val_short = 0;
else
val_short = 1;
rc = addExifEntry(exif_info, EXIFTAGID_WHITE_BALANCE, EXIF_SHORT,
sizeof(val_short)/2, &val_short);
if (rc) {
LOGE(": Error adding Exif Entry");
}
/* Metering Mode */
val_short = (short) p_3a_params->metering_mode;
rc = addExifEntry(exif_info,EXIFTAGID_METERING_MODE, EXIF_SHORT,
sizeof(val_short)/2, &val_short);
if (rc) {
LOGE(": Error adding Exif Entry");
}
/*Exposure Program*/
val_short = (short) p_3a_params->exposure_program;
rc = addExifEntry(exif_info,EXIFTAGID_EXPOSURE_PROGRAM, EXIF_SHORT,
sizeof(val_short)/2, &val_short);
if (rc) {
LOGE(": Error adding Exif Entry");
}
/*Exposure Mode */
val_short = (short) p_3a_params->exposure_mode;
rc = addExifEntry(exif_info,EXIFTAGID_EXPOSURE_MODE, EXIF_SHORT,
sizeof(val_short)/2, &val_short);
if (rc) {
LOGE(": Error adding Exif Entry");
}
/*Scenetype*/
uint8_t val_undef;
val_undef = (uint8_t) p_3a_params->scenetype;
rc = addExifEntry(exif_info,EXIFTAGID_SCENE_TYPE, EXIF_UNDEFINED,
sizeof(val_undef), &val_undef);
if (rc) {
LOGE(": Error adding Exif Entry");
}
LOGD("brightness %f",
p_3a_params->brightness);
/* Brightness Value*/
val_srat.num = (int32_t) (p_3a_params->brightness * 100.0f);
val_srat.denom = 100;
rc = addExifEntry(exif_info,EXIFTAGID_BRIGHTNESS, EXIF_SRATIONAL,
(sizeof(val_srat)/(8)), &val_srat);
if (rc) {
LOGE(": Error adding Exif Entry");
}
return rc;
}
/** process_meta_data
*
* Arguments:
* @p_meta : ptr to metadata
* @exif_info: Exif info struct
* @mm_jpeg_exif_params: exif params
*
* Return : int32_t type of status
* NO_ERROR -- success
* none-zero failure code
*
* Description:
* Extract exif data from the metadata
**/
int process_meta_data(metadata_buffer_t *p_meta, QOMX_EXIF_INFO *exif_info,
mm_jpeg_exif_params_t *p_cam_exif_params, cam_hal_version_t hal_version)
{
int rc = 0;
cam_sensor_params_t p_sensor_params;
cam_3a_params_t p_3a_params;
bool is_3a_meta_valid = false, is_sensor_meta_valid = false;
memset(&p_3a_params, 0, sizeof(cam_3a_params_t));
memset(&p_sensor_params, 0, sizeof(cam_sensor_params_t));
if (p_meta) {
/* for HAL V1*/
if (hal_version == CAM_HAL_V1) {
IF_META_AVAILABLE(cam_3a_params_t, l_3a_params, CAM_INTF_META_AEC_INFO,
p_meta) {
p_3a_params = *l_3a_params;
is_3a_meta_valid = true;
}
IF_META_AVAILABLE(int32_t, wb_mode, CAM_INTF_PARM_WHITE_BALANCE, p_meta) {
p_3a_params.wb_mode = *wb_mode;
}
IF_META_AVAILABLE(cam_sensor_params_t, l_sensor_params,
CAM_INTF_META_SENSOR_INFO, p_meta) {
p_sensor_params = *l_sensor_params;
is_sensor_meta_valid = true;
}
} else {
/* HAL V3 */
IF_META_AVAILABLE(int32_t, iso, CAM_INTF_META_SENSOR_SENSITIVITY, p_meta) {
p_3a_params.iso_value= *iso;
} else {
LOGE("Cannot extract Iso value");
}
IF_META_AVAILABLE(int64_t, sensor_exposure_time,
CAM_INTF_META_SENSOR_EXPOSURE_TIME, p_meta) {
p_3a_params.exp_time =
(float)((double)(*sensor_exposure_time) / 1000000000.0);
} else {
LOGE("Cannot extract Exp time value");
}
IF_META_AVAILABLE(int32_t, wb_mode, CAM_INTF_PARM_WHITE_BALANCE, p_meta) {
p_3a_params.wb_mode = *wb_mode;
} else {
LOGE("Cannot extract white balance mode");
}
/* Process sensor data */
IF_META_AVAILABLE(float, aperture, CAM_INTF_META_LENS_APERTURE, p_meta) {
p_sensor_params.aperture_value = *aperture;
} else {
LOGE("Cannot extract Aperture value");
}
IF_META_AVAILABLE(uint32_t, flash_mode, CAM_INTF_META_FLASH_MODE, p_meta) {
p_sensor_params.flash_mode = *flash_mode;
} else {
LOGE("Cannot extract flash mode value");
}
IF_META_AVAILABLE(int32_t, flash_state, CAM_INTF_META_FLASH_STATE, p_meta) {
p_sensor_params.flash_state = (cam_flash_state_t) *flash_state;
} else {
LOGE("Cannot extract flash state value");
}
}
}
/* take the cached values if meta is invalid */
if ((!is_3a_meta_valid) && (hal_version == CAM_HAL_V1)) {
p_3a_params = p_cam_exif_params->cam_3a_params;
LOGE("Warning using cached values for 3a");
}
if ((!is_sensor_meta_valid) && (hal_version == CAM_HAL_V1)) {
p_sensor_params = p_cam_exif_params->sensor_params;
LOGE("Warning using cached values for sensor");
}
if ((hal_version != CAM_HAL_V1) || (p_sensor_params.sens_type != CAM_SENSOR_YUV)) {
rc = process_3a_data(&p_3a_params, exif_info);
if (rc) {
LOGE("Failed to add 3a exif params");
}
}
rc = process_sensor_data(&p_sensor_params, exif_info);
if (rc) {
LOGE("Failed to extract sensor params");
}
if (p_meta) {
short val_short = 0;
IF_META_AVAILABLE(cam_auto_scene_t, scene_cap_type,
CAM_INTF_META_ASD_SCENE_CAPTURE_TYPE, p_meta) {
val_short = (short) *scene_cap_type;
}
rc = addExifEntry(exif_info, EXIFTAGID_SCENE_CAPTURE_TYPE, EXIF_SHORT,
sizeof(val_short)/2, &val_short);
if (rc) {
LOGE(": Error adding ASD Exif Entry");
}
} else {
LOGE(": Error adding ASD Exif Entry, no meta");
}
return rc;
}

Some files were not shown because too many files have changed in this diff Show more