gts3l: camera: (WIP) Add camera HAL from LineageOS/xiaomi_msm8996-common

Signed-off-by: Deokgyu Yang <secugyu@gmail.com>
Change-Id: I1eb5082082c7af4b7d8f98dbe5a1f8d9a20bebef
This commit is contained in:
Deokgyu Yang 2021-05-22 21:25:05 +09:00
parent e20779f55c
commit 209a9aec1c
119 changed files with 114447 additions and 335 deletions

View file

@ -227,8 +227,7 @@ BOARD_HAVE_SAMSUNG_WIFI := true
# Shims
TARGET_LD_SHIM_LIBS := \
/vendor/lib/libbauthserver.so|libbauthtzcommon_shim.so \
/vendor/lib64/libbauthserver.so|libbauthtzcommon_shim.so \
/vendor/lib/hw/camera.msm8996.so|/vendor/lib/libcameraclient_shim.so
/vendor/lib64/libbauthserver.so|libbauthtzcommon_shim.so
# inherit from the proprietary version
-include vendor/samsung/gts3llte/BoardConfigVendor.mk

View file

@ -1,4 +1,5 @@
# Copyright (C) 2016 The CyanogenMod Project
#
# Copyright (C) 2017-2018 The LineageOS Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -11,16 +12,6 @@
# 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.
#
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := libcameraclient.cpp
LOCAL_MODULE := libcameraclient_shim
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_VENDOR_MODULE := true
include $(BUILD_SHARED_LIBRARY)
include $(call first-makefiles-under,$(call my-dir))

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

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

@ -0,0 +1,147 @@
ifneq (,$(filter $(TARGET_ARCH), arm arm64))
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_COPY_HEADERS_TO := qcom/camera
LOCAL_COPY_HEADERS := QCameraFormat.h
LOCAL_SRC_FILES := \
util/QCameraBufferMaps.cpp \
util/QCameraCmdThread.cpp \
util/QCameraFlash.cpp \
util/QCameraPerf.cpp \
util/QCameraQueue.cpp \
util/QCameraDisplay.cpp \
util/QCameraCommon.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
LOCAL_CFLAGS := -Wall -Wextra -Werror -Wno-unused-parameter -Wno-unused-variable
#HAL 1.0 source
ifeq ($(TARGET_SUPPORT_HAL1),false)
LOCAL_CFLAGS += -DQCAMERA_HAL3_SUPPORT
else
LOCAL_CFLAGS += -DQCAMERA_HAL1_SUPPORT
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
endif
# System header file path prefix
LOCAL_CFLAGS += -DSYSTEM_HEADER_PREFIX=sys
LOCAL_CFLAGS += -DHAS_MULTIMEDIA_HINTS -D_ANDROID
ifeq (1,$(filter 1,$(shell echo "$$(( $(PLATFORM_SDK_VERSION) <= 23 ))" )))
LOCAL_CFLAGS += -DUSE_HAL_3_3
endif
#use media extension
ifeq ($(TARGET_USES_MEDIA_EXTENSIONS), true)
LOCAL_CFLAGS += -DUSE_MEDIA_EXTENSIONS
endif
#USE_DISPLAY_SERVICE from Android O onwards
#to receive vsync event from display
ifeq ($(filter OMR1 O 8.1.0, $(PLATFORM_VERSION)), )
USE_DISPLAY_SERVICE := true
LOCAL_CFLAGS += -DUSE_DISPLAY_SERVICE
LOCAL_CFLAGS += -std=c++11 -std=gnu++1y
else
LOCAL_CFLAGS += -std=c++11 -std=gnu++0x
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 \
$(call project-path-for,qcom-media)/libstagefrighthw \
$(call project-path-for,qcom-media)/mm-core/inc \
$(TARGET_OUT_HEADERS)/mm-camera-lib/cp/prebuilt
#HAL 1.0 Include paths
LOCAL_C_INCLUDES += \
$(LOCAL_PATH)/HAL
ifeq ($(TARGET_COMPILE_WITH_MSM_KERNEL),true)
LOCAL_HEADER_LIBRARIES := generated_kernel_headers
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 msm8953 msm8996 msmcobalt msmfalcon, $(TARGET_BOARD_PLATFORM)))
LOCAL_CFLAGS += -DVENUS_PRESENT
endif
ifneq (,$(filter msm8996 msmcobalt msmfalcon,$(TARGET_BOARD_PLATFORM)))
LOCAL_CFLAGS += -DUBWC_PRESENT
endif
#LOCAL_STATIC_LIBRARIES := libqcamera2_util
LOCAL_C_INCLUDES += \
$(TARGET_OUT_HEADERS)/qcom/display
LOCAL_C_INCLUDES += \
$(call project-path-for,qcom-display)/libqservice
LOCAL_SHARED_LIBRARIES := liblog libhardware libutils libcutils libdl libsync
LOCAL_SHARED_LIBRARIES += libmmcamera_interface libmmjpeg_interface libui libcamera_metadata
LOCAL_SHARED_LIBRARIES += libqdMetaData libqservice libbinder
ifeq ($(USE_DISPLAY_SERVICE),true)
LOCAL_SHARED_LIBRARIES += android.frameworks.displayservice@1.0 libhidlbase libhidltransport
else
LOCAL_SHARED_LIBRARIES += libgui
endif
ifeq ($(TARGET_TS_MAKEUP),true)
LOCAL_SHARED_LIBRARIES += libts_face_beautify_hal libts_detected_face_hal
endif
LOCAL_HEADER_LIBRARIES += media_plugin_headers
LOCAL_HEADER_LIBRARIES += libandroid_sensor_headers
LOCAL_HEADER_LIBRARIES += libcutils_headers
LOCAL_HEADER_LIBRARIES += libsystem_headers
LOCAL_HEADER_LIBRARIES += libhardware_headers
LOCAL_STATIC_LIBRARIES := android.hardware.camera.common@1.0-helper
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_MODULE := camera.$(TARGET_BOARD_PLATFORM)
LOCAL_VENDOR_MODULE := true
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,799 @@
/* 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 "hardware/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);
static bool matchTimestampNotifications(void *data, void *user_data);
virtual int32_t flushPreviewNotifications();
virtual int32_t flushVideoNotifications();
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 cancelLiveSnapshot_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);
bool isFrameSyncEnabled(void);
int32_t setFrameSyncEnabled(bool enable);
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, bool bRecordingHint);
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; };
bool bLiveSnapshot;
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,
bool bRecordingHint);
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_asd_decision_t asd_decision);
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(uint32_t frameID);
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;}
/*Start display skip. Skip starts after
skipCnt number of frames from current frame*/
void setDisplaySkip(bool enabled, uint8_t skipCnt = 0);
/*Caller can specify range frameID to skip.
if end is 0, all the frames after start will be skipped*/
void setDisplayFrameSkip(uint32_t start = 0, uint32_t end = 0);
/*Verifies if frameId is valid to skip*/
bool isDisplayFrameToSkip(uint32_t frameId);
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;
bool mFlashConfigured;
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;
bool mLowLightConfigured;
uint8_t mInstantAecFrameCount;
//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;
//Used to decide the next frameID to be skipped
uint32_t mLastPreviewFrameID;
//FrameID to start frame skip.
uint32_t mFrameSkipStart;
/*FrameID to stop frameskip. If this is not set,
all frames are skipped till we set this*/
uint32_t mFrameSkipEnd;
//The offset between BOOTTIME and MONOTONIC timestamps
nsecs_t mBootToMonoTimestampOffset;
};
}; // 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,172 @@
/* 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 "hardware/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);
bool isActive() { return m_bIsActive; }
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;
Mutex mStreamLock;
};
// 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,317 @@
/* Copyright (c) 2012-2017, 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>
//Media depedancies
#include "OMX_QCOMExtns.h"
// Display dependencies
#include "qdMetaData.h"
// Camera dependencies
#include "hardware/camera.h"
extern "C" {
#include "mm_camera_interface.h"
}
namespace qcamera {
class QCameraMemoryPool;
//OFFSET, SIZE, USAGE, TIMESTAMP, FORMAT
#define VIDEO_METADATA_NUM_INTS 5
//Buffer identity
//Note that this macro might have already been
//defined in OMX_QCOMExtns.h, in which case
//the local value below will not be used.
#ifndef VIDEO_METADATA_NUM_COMMON_INTS
#define VIDEO_METADATA_NUM_COMMON_INTS 1
#endif
enum QCameraMemType {
QCAMERA_MEM_TYPE_DEFAULT = 0,
QCAMERA_MEM_TYPE_SECURE = 1,
QCAMERA_MEM_TYPE_BATCH = (1 << 1),
QCAMERA_MEM_TYPE_COMPRESSED = (1 << 2),
};
typedef enum {
STATUS_IDLE,
STATUS_SKIPPED
} BufferStatus;
// 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,
void* cbCookie,
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];
void* mCallbackCookie;
};
// 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, void* cbCookie, 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);
int closeNativeHandle(const void *data, bool metadata);
native_handle_t *getNativeHandle(uint32_t index, bool metadata = true);
static int closeNativeHandle(const void *data);
private:
camera_memory_t *mMetadata[MM_CAMERA_MAX_NUM_FRAMES];
uint8_t mMetaBufCount;
int mUsage, mFormat;
native_handle_t *mNativeHandle[MM_CAMERA_MAX_NUM_FRAMES];
};
// Gralloc Memory is acquired from preview window
class QCameraGrallocMemory : public QCameraMemory {
enum {
BUFFER_NOT_OWNED,
BUFFER_OWNED,
};
public:
QCameraGrallocMemory(camera_request_memory getMemory, void* cbCookie);
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();
inline bool isBufSkipped(uint32_t index){return (mBufferStatus[index] == STATUS_SKIPPED);};
void setBufferStatus(uint32_t index, BufferStatus status);
private:
buffer_handle_t *mBufferHandle[MM_CAMERA_MAX_NUM_FRAMES];
int mLocalFlag[MM_CAMERA_MAX_NUM_FRAMES];
bool mBufferStatus[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;
typeof (MetaData_t::refreshrate) mMaxFPS;
camera_request_memory mGetMemory;
void* mCallbackCookie;
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,284 @@
/* 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 "hardware/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_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,308 @@
/* 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, bool bRecordingHint) = 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();
bool isInstantAECEnabled();
bool isInstantCaptureEnabled();
uint8_t getAecFrameBoundValue();
uint8_t getAecSkipDisplayFrameBound();
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();
cam_is_type_t getPreviewISType();
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(cam_feature_mask_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(cam_feature_mask_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, cam_feature_mask_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, bool lowLightEnabled);
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 setFrameSyncEnabled(bool enable);
bool isFrameSyncEnabled(void);
int32_t getRelatedCamCalibration(
cam_related_system_calibration_data_t* calib);
int32_t bundleRelatedCameras(bool sync, uint32_t sessionid);
uint8_t fdModeInVideo();
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();
int32_t setInstantAEC(uint8_t enable, bool initCommit);
int32_t getAnalysisInfo(
bool fdVideoEnabled,
bool hal3,
cam_feature_mask_t featureMask,
cam_analysis_info_t *pAnalysisInfo);
private:
QCameraParameters *mImpl;
mutable Mutex mLock;
};
}; // namespace qcamera
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,250 @@
/* 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
pthread_mutex_t m_reprocess_lock; // lock to ensure reprocess job is not freed early.
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,263 @@
/* 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_asd_decision_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 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_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 "hardware/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,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,661 @@
/* 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"
#include <sys/stat.h>
// Camera dependencies
#include "cam_intf.h"
#include "cam_types.h"
#include "hardware/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);
typedef void (*channel_cb_buffer_err)(QCamera3Channel* ch, uint32_t frameNumber,
camera3_buffer_status_t err,
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,
channel_cb_buffer_err cb_buf_err,
cam_padding_info_t *paddingInfo,
cam_feature_mask_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*/,
int &/*indexUsed*/){ return 0;};
virtual int32_t request(buffer_handle_t * /*buffer*/,
uint32_t /*frameNumber*/,
camera3_stream_buffer_t* /*pInputBuffer*/,
metadata_buffer_t* /*metadata*/,
int & /*indexUsed*/){ 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);
virtual int32_t timeoutFrame(__unused uint32_t frameNumber) = 0;
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,
cam_feature_mask_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;
channel_cb_buffer_err mChannelCbBufErr;
//cam_padding_info_t *mPaddingInfo;
cam_feature_mask_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 mFrmNum;
uint32_t mDumpFrmCnt;
uint32_t mSkipMode;
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,
channel_cb_buffer_err cb_buffer_err,
cam_padding_info_t *paddingInfo,
void *userData,
camera3_stream_t *stream,
cam_stream_type_t stream_type,
cam_feature_mask_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, int &indexUsed);
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);
virtual int32_t timeoutFrame(uint32_t frameNumber);
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;
android::List<mm_camera_super_buf_t *> mOutOfSequenceBuffers;
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,
channel_cb_buffer_err cb_buffer_err,
cam_padding_info_t *paddingInfo,
void *userData,
camera3_stream_t *stream,
cam_stream_type_t stream_type,
cam_feature_mask_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);
using QCamera3ProcessingChannel::request;
virtual int32_t request(buffer_handle_t *buffer, uint32_t frameNumber,
int &indexUsed);
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,
channel_cb_buffer_err cb_buffer_err,
cam_padding_info_t *paddingInfo,
cam_feature_mask_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,
int &indexUsed);
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 timeoutFrame(__unused uint32_t frameNumber) {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,
channel_cb_buffer_err cb_buffer_err,
cam_padding_info_t *paddingInfo,
void *userData,
camera3_stream_t *stream,
cam_feature_mask_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,
cam_feature_mask_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 timeoutFrame(__unused uint32_t frameNumber) {return NO_ERROR;};
virtual int32_t request(buffer_handle_t *buffer, uint32_t frameNumber,
int &indexUsed);
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,
channel_cb_buffer_err cb_buffer_err,
cam_padding_info_t *paddingInfo,
void *userData,
camera3_stream_t *stream,
cam_stream_type_t stream_type,
cam_feature_mask_t postprocess_mask,
QCamera3Channel *metadataChannel);
~QCamera3YUVChannel();
virtual int32_t initialize(cam_is_type_t isType);
using QCamera3ProcessingChannel::request;
virtual int32_t request(buffer_handle_t *buffer,
uint32_t frameNumber,
camera3_stream_buffer_t* pInputBuffer,
metadata_buffer_t* metadata, bool &needMetadata,
int &indexUsed);
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);
mm_camera_super_buf_t* getNextPendingCbBuffer();
};
/* 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,
channel_cb_buffer_err cb_buffer_err,
cam_padding_info_t *paddingInfo,
void *userData,
camera3_stream_t *stream,
cam_feature_mask_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,
int &indexUsed);
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();
virtual int32_t timeoutFrame(uint32_t frameNumber);
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,
channel_cb_buffer_err cb_buffer_err,
cam_padding_info_t *paddingInfo,
cam_feature_mask_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);
virtual int32_t timeoutFrame(__unused uint32_t frameNumber) {return NO_ERROR;};
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;
Mutex mOfflineBuffersLock;
Mutex mOfflineMetaBuffersLock;
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,
cam_feature_mask_t postprocess_mask,
cam_stream_type_t streamType,
cam_dimension_t *dim,
cam_format_t streamFormat,
uint8_t hw_analysis_supported,
cam_color_filter_arrangement_t color_arrangement,
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,
int &indexUsed);
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 timeoutFrame(__unused uint32_t frameNumber) {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 "hardware/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,558 @@
/* 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 <CameraMetadata.h>
#include <pthread.h>
#include <utils/KeyedVector.h>
#include <utils/List.h>
// Camera dependencies
#include "hardware/camera3.h"
#include "QCamera3Channel.h"
#include "QCamera3CropRegionMapper.h"
#include "QCamera3HALHeader.h"
#include "QCamera3Mem.h"
#include "QCameraPerf.h"
#include "QCameraCommon.h"
extern "C" {
#include "mm_camera_interface.h"
#include "mm_jpeg_interface.h"
}
using ::android::hardware::camera::common::V1_0::helper::CameraMetadata;
using namespace android;
namespace qcamera {
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
/* Time related macros */
#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;
typedef struct {
// Stream handle
camera3_stream_t *stream;
// Buffer handle
buffer_handle_t *buffer;
// Buffer status
camera3_buffer_status_t bufStatus = CAMERA3_BUFFER_STATUS_OK;
} PendingBufferInfo;
typedef struct {
// Frame number corresponding to request
uint32_t frame_number;
// Time when request queued into system
nsecs_t timestamp;
List<PendingBufferInfo> mPendingBufferList;
} PendingBuffersInRequest;
class PendingBuffersMap {
public:
// Number of outstanding buffers at flush
uint32_t numPendingBufsAtFlush;
// List of pending buffers per request
List<PendingBuffersInRequest> mPendingBuffersInRequest;
uint32_t get_num_overall_buffers();
void removeBuf(buffer_handle_t *buffer);
int32_t getBufErrStatus(buffer_handle_t *buffer);
};
class QCamera3HardwareInterface {
public:
/* static variable and functions accessed by camera service */
static camera3_device_ops_t mCameraOps;
//Id of each session in bundle/link
static uint32_t sessionId[MM_CAMERA_MAX_NUM_SENSORS];
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 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,
bool firstMetadataInBatch);
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 needJpegExifRotation();
bool needReprocess(cam_feature_mask_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);
static void setBufferErrorStatus(QCamera3Channel*, uint32_t frameNumber,
camera3_buffer_status_t err, void *userdata);
void setBufferErrorStatus(QCamera3Channel*, uint32_t frameNumber,
camera3_buffer_status_t err);
// Get dual camera related info
bool isDeviceLinked() {return mIsDeviceLinked;}
bool isMainCamera() {return mIsMainCamera;}
uint32_t getSensorMountAngle();
const cam_related_system_calibration_data_t *getRelatedCalibrationData();
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();
void handleBuffersDuringFlushLock(camera3_stream_buffer_t *buffer);
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,
bool firstMetadataInBatch);
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);
#ifndef USE_HAL_3_3
void updateTimeStampInPendingBuffers(uint32_t frameNumber, nsecs_t timestamp);
#endif
void enablePowerHint();
void disablePowerHint();
int32_t dynamicUpdateMetaStreamInfo();
int32_t startAllChannels();
int32_t stopAllChannels();
int32_t notifyErrorForPendingRequests();
void notifyError(uint32_t frameNumber,
camera3_error_msg_code_t errorCode);
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();
static void setPAAFSupport(cam_feature_mask_t& feature_mask,
cam_stream_type_t stream_type,
cam_color_filter_arrangement_t filter_arrangement);
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;
QCameraCommon mCommon;
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;
uint8_t m_debug_avtimer;
/* 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;
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;
cam_stream_ID_t mBatchedStreamsArray;
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;
public:
uint8_t mOpMode;
private:
uint32_t mFirstFrameNumberInBatch;
camera3_stream_t mDummyBatchStream;
bool mNeedSensorRestart;
uint32_t mMinInFlightRequests;
uint32_t mMaxInFlightRequests;
/* sensor output size with current stream configuration */
QCamera3CropRegionMapper mCropRegionMapper;
/* Ldaf calibration data */
bool mLdafCalibExist;
uint32_t mLdafCalib[2];
bool mPowerHintEnabled;
int32_t mLastCustIntentFrmNum;
CameraMetadata mCachedMetadata;
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;
//Dual camera related params
bool mIsDeviceLinked;
bool mIsMainCamera;
uint8_t mLinkedCameraId;
QCamera3HeapMemory *m_pRelCamSyncHeap;
cam_sync_related_sensors_event_info_t *m_pRelCamSyncBuf;
cam_sync_related_sensors_event_info_t m_relCamSyncInfo;
//The offset between BOOTTIME and MONOTONIC timestamps
nsecs_t mBootToMonoTimestampOffset;
bool mUseAVTimer;
};
}; // namespace qcamera
#endif /* __QCAMERA2HARDWAREINTERFACE_H__ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,161 @@
/* 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 "hardware/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;
virtual int32_t getOldestFrameNumber(uint32_t &index) = 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);
virtual int32_t getOldestFrameNumber(uint32_t &index);
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);
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);
virtual int32_t getOldestFrameNumber(uint32_t &index);
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,192 @@
/* 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 "hardware/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);
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, bool needJpegExifRotation);
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);
bool needsReprocess(qcamera_fwk_input_pp_data_t *frame);
private:
QCamera3ProcessingChannel *m_parent;
jpeg_encode_callback_t mJpegCB;
void * mJpegUserData;
mm_jpeg_ops_t mJpegHandle;
uint32_t mJpegClientHandle;
uint32_t mJpegSessionId;
cam_jpeg_metadata_t mJpegMetadata;
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,173 @@
/* 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,
cam_feature_mask_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 cancelBuffer(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);
int32_t timeoutFrame(int32_t bufIdx);
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;
QCameraQueue mTimeoutFrameQ;
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,544 @@
/* 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 : getOldestFrameNumber
*
* DESCRIPTION: We use this to fetch the frameNumber expected as per FIFO
*
*
* PARAMETERS :
* @index : index of the buffer
*
* RETURN : int32_t frameNumber
* positive/zero -- success
* negative failure
*==========================================================================*/
int32_t QCamera3StreamMem::getOldestFrameNumber(uint32_t &bufIdx)
{
Mutex::Autolock lock(mLock);
int32_t oldest = INT_MAX;
bool empty = true;
if (mHeapMem.getCnt()){
empty = false;
oldest = mHeapMem.getOldestFrameNumber(bufIdx);
}
if (mGrallocMem.getCnt()) {
uint32_t grallocBufIdx;
int32_t oldestGrallocFrameNumber = mGrallocMem.getOldestFrameNumber(grallocBufIdx);
if (empty || (!empty && (oldestGrallocFrameNumber < oldest))){
oldest = oldestGrallocFrameNumber;
bufIdx = grallocBufIdx;
}
empty = false;
}
if (empty )
return -1;
else
return oldest;
}
/*===========================================================================
* 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;
}
/*===========================================================================
* FUNCTION : getBufferIndex
*
* DESCRIPTION: We use this to fetch the buffer index based on frameNumber
*
* PARAMETERS :
* @frameNumber : frame Number
*
* RETURN : int32_t buffer index
* positive/zero -- success
* negative failure
*==========================================================================*/
int32_t QCamera3StreamMem::getBufferIndex(uint32_t frameNumber)
{
Mutex::Autolock lock(mLock);
int32_t index = mGrallocMem.getBufferIndex(frameNumber);
if (index < 0)
return mHeapMem.getBufferIndex(frameNumber);
else
return index;
}
}; //namespace qcamera

View file

@ -0,0 +1,99 @@
/* 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 getOldestFrameNumber(uint32_t &index);
int32_t getGrallocBufferIndex(uint32_t frameNumber);
int32_t getHeapBufferIndex(uint32_t frameNumber);
int32_t getBufferIndex(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,464 @@
/* 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 {
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_ISO_EXP_PRIORITY_END,
QCAMERA3_SATURATION_END,
QCAMERA3_EXPOSURE_METER_END,
QCAMERA3_AV_TIMER_END,
QCAMERA3_SENSOR_META_DATA_END,
QCAMERA3_DUALCAM_LINK_META_DATA_END,
QCAMERA3_DUALCAM_CALIB_META_DATA_END,
QCAMERA3_HAL_PRIVATEDATA_END,
QCAMERA3_JPEG_ENCODE_CROP_END,
QCAMERA3_SHARPNESS_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.iso_exp_priority",
"org.codeaurora.qcamera3.saturation",
"org.codeaurora.qcamera3.exposure_metering",
"org.codeaurora.qcamera3.av_timer",
"org.codeaurora.qcamera3.sensor_meta_data",
"org.codeaurora.qcamera3.dualcam_link_meta_data",
"org.codeaurora.qcamera3.dualcam_calib_meta_data",
"org.codeaurora.qcamera3.hal_private_data",
"org.codeaurora.qcamera3.jpeg_encode_crop",
"org.codeaurora.qcamera3.sharpness"
};
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_iso_exp_priority[QCAMERA3_ISO_EXP_PRIORITY_END -
QCAMERA3_ISO_EXP_PRIORITY_START] = {
{ "use_iso_exp_priority", TYPE_INT64 },
{ "select_priority", TYPE_INT32 }
};
vendor_tag_info qcamera3_saturation[QCAMERA3_SATURATION_END -
QCAMERA3_SATURATION_START] = {
{ "use_saturation", TYPE_INT32 }
};
vendor_tag_info qcamera3_exposure_metering[QCAMERA3_EXPOSURE_METER_END -
QCAMERA3_EXPOSURE_METER_START] = {
{ "exposure_metering_mode", 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 },
{"is_mono_only", TYPE_BYTE }
};
vendor_tag_info_t
qcamera3_dualcam_link_meta_data[QCAMERA3_DUALCAM_LINK_META_DATA_END -
QCAMERA3_DUALCAM_LINK_META_DATA_START] = {
{ "enable", TYPE_BYTE },
{ "is_main", TYPE_BYTE },
{ "related_camera_id", TYPE_INT32 }
};
vendor_tag_info_t
qcamera3_dualcam_calib_meta_data[QCAMERA3_DUALCAM_CALIB_META_DATA_END -
QCAMERA3_DUALCAM_CALIB_META_DATA_START] = {
{ "dualcam_calib_meta_data_blob", TYPE_BYTE }
};
vendor_tag_info_t
qcamera3_hal_privatedata[QCAMERA3_HAL_PRIVATEDATA_END -
QCAMERA3_HAL_PRIVATEDATA_START] = {
{ "reprocess_flags", TYPE_BYTE },
{ "reprocess_data_blob", TYPE_BYTE }
};
vendor_tag_info_t
qcamera3_jpep_encode_crop[QCAMERA3_JPEG_ENCODE_CROP_END -
QCAMERA3_JPEG_ENCODE_CROP_START] = {
{ "enable", TYPE_BYTE },
{ "rect", TYPE_INT32 },
{ "roi", TYPE_INT32}
};
vendor_tag_info_t qcamera3_sharpness[QCAMERA3_SHARPNESS_END -
QCAMERA3_SHARPNESS_START] = {
{"strength", TYPE_INT32 },
{"range", 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_iso_exp_priority,
qcamera3_saturation,
qcamera3_exposure_metering,
qcamera3_av_timer,
qcamera3_sensor_meta_data,
qcamera3_dualcam_link_meta_data,
qcamera3_dualcam_calib_meta_data,
qcamera3_hal_privatedata,
qcamera3_jpep_encode_crop,
qcamera3_sharpness
};
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_ISO_EXP_PRIORITY
(uint32_t)QCAMERA3_USE_ISO_EXP_PRIORITY,
(uint32_t)QCAMERA3_SELECT_PRIORITY,
// QCAMERA3_SATURATION
(uint32_t)QCAMERA3_USE_SATURATION,
// QCAMERA3_EXPOSURE_METERING
(uint32_t)QCAMERA3_EXPOSURE_METER,
//QCAMERA3_AVTIMER
(uint32_t)QCAMERA3_USE_AV_TIMER,
//QCAMERA3_SENSOR_META_DATA
(uint32_t)QCAMERA3_SENSOR_DYNAMIC_BLACK_LEVEL_PATTERN,
(uint32_t)QCAMERA3_SENSOR_IS_MONO_ONLY,
// QCAMERA3_DUALCAM_LINK_META_DATA
(uint32_t)QCAMERA3_DUALCAM_LINK_ENABLE,
(uint32_t)QCAMERA3_DUALCAM_LINK_IS_MAIN,
(uint32_t)QCAMERA3_DUALCAM_LINK_RELATED_CAMERA_ID,
// QCAMERA3_DUALCAM_CALIB_META_DATA
(uint32_t)QCAMERA3_DUALCAM_CALIB_META_DATA_BLOB,
// QCAMERA3_HAL_PRIVATEDATA
(uint32_t)QCAMERA3_HAL_PRIVATEDATA_REPROCESS_FLAGS,
(uint32_t)QCAMERA3_HAL_PRIVATEDATA_REPROCESS_DATA_BLOB,
// QCAMERA3_JPEG_ENCODE_CROP
(uint32_t)QCAMERA3_JPEG_ENCODE_CROP_ENABLE,
(uint32_t)QCAMERA3_JPEG_ENCODE_CROP_RECT,
(uint32_t)QCAMERA3_JPEG_ENCODE_CROP_ROI,
//QCAMERA3_SHARPNESS
(uint32_t)QCAMERA3_SHARPNESS_STRENGTH,
(uint32_t)QCAMERA3_SHARPNESS_RANGE
};
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,239 @@
/* 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 "system/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_ISO_EXP_PRIORITY,
QCAMERA3_SATURATION,
QCAMERA3_EXPOSURE_METERING_MODE,
QCAMERA3_AV_TIMER,
QCAMERA3_SENSOR_META_DATA,
QCAMERA3_DUALCAM_LINK_META_DATA,
QCAMERA3_DUALCAM_CALIB_META_DATA,
QCAMERA3_HAL_PRIVATEDATA,
QCAMERA3_JPEG_ENCODE_CROP,
QCAMERA3_SHARPNESS_DATA,
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_ISO_EXP_PRIORITY_START = QCAMERA3_ISO_EXP_PRIORITY << 16,
QCAMERA3_SATURATION_START = QCAMERA3_SATURATION << 16,
QCAMERA3_EXPOSURE_METER_START = QCAMERA3_EXPOSURE_METERING_MODE << 16,
QCAMERA3_AV_TIMER_START = QCAMERA3_AV_TIMER << 16,
QCAMERA3_SENSOR_META_DATA_START = QCAMERA3_SENSOR_META_DATA << 16,
QCAMERA3_DUALCAM_LINK_META_DATA_START = QCAMERA3_DUALCAM_LINK_META_DATA << 16,
QCAMERA3_DUALCAM_CALIB_META_DATA_START = QCAMERA3_DUALCAM_CALIB_META_DATA << 16,
QCAMERA3_HAL_PRIVATEDATA_START = QCAMERA3_HAL_PRIVATEDATA << 16,
QCAMERA3_JPEG_ENCODE_CROP_START = QCAMERA3_JPEG_ENCODE_CROP << 16,
QCAMERA3_SHARPNESS_START = QCAMERA3_SHARPNESS_DATA << 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_ISO_EXP_PRIORITY = QCAMERA3_ISO_EXP_PRIORITY_START,
QCAMERA3_SELECT_PRIORITY,
QCAMERA3_ISO_EXP_PRIORITY_END,
QCAMERA3_USE_SATURATION = QCAMERA3_SATURATION_START,
QCAMERA3_SATURATION_END,
QCAMERA3_EXPOSURE_METER = QCAMERA3_EXPOSURE_METER_START,
QCAMERA3_EXPOSURE_METER_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_IS_MONO_ONLY,
QCAMERA3_SENSOR_META_DATA_END,
QCAMERA3_DUALCAM_LINK_ENABLE = QCAMERA3_DUALCAM_LINK_META_DATA_START,
QCAMERA3_DUALCAM_LINK_IS_MAIN,
QCAMERA3_DUALCAM_LINK_RELATED_CAMERA_ID,
QCAMERA3_DUALCAM_LINK_META_DATA_END,
QCAMERA3_DUALCAM_CALIB_META_DATA_BLOB = QCAMERA3_DUALCAM_CALIB_META_DATA_START,
QCAMERA3_DUALCAM_CALIB_META_DATA_END,
QCAMERA3_HAL_PRIVATEDATA_REPROCESS_FLAGS = QCAMERA3_HAL_PRIVATEDATA_START,
QCAMERA3_HAL_PRIVATEDATA_REPROCESS_DATA_BLOB,
QCAMERA3_HAL_PRIVATEDATA_END,
/* Property Name: org.codeaurora.qcamera3.jpeg_encode_crop.enable
Type: byte
Description: If JPEG crop is enable
*/
QCAMERA3_JPEG_ENCODE_CROP_ENABLE = QCAMERA3_JPEG_ENCODE_CROP_START,
/* Property Name: org.codeaurora.qcamera3.jpeg_encode_crop.rect
Type: int32[4]
Description: Crop image into size width x height
from [left, top] coordinate
rect[0] = left
rect[1] = top
rect[2] = width
rect[3] = height
*/
QCAMERA3_JPEG_ENCODE_CROP_RECT,
/* Property Name: org.codeaurora.qcamera3.jpeg_encode_crop.roi
Type: int32[4]
Description: Scale the crop image into size width x height
from [left, top] coordinate.
roi[0] = left
roi[1] = top
roi[2] = width
roi[3] = height
*/
QCAMERA3_JPEG_ENCODE_CROP_ROI,
QCAMERA3_JPEG_ENCODE_CROP_END,
QCAMERA3_SHARPNESS_STRENGTH = QCAMERA3_SHARPNESS_START,
QCAMERA3_SHARPNESS_RANGE,
QCAMERA3_SHARPNESS_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,635 @@
/* 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>
#include <cutils/properties.h>
// Camera dependencies
#ifdef QCAMERA_HAL1_SUPPORT
#include "hardware/camera.h"
#include "HAL/QCamera2HWI.h"
#include "QCameraMuxer.h"
#endif
#include "hardware/camera3.h"
#include "HAL3/QCamera3HWI.h"
#include "util/QCameraFlash.h"
#include "QCamera2Factory.h"
extern "C" {
#include "mm_camera_dbg.h"
}
using namespace android;
namespace qcamera {
QCamera2Factory *gQCamera2Factory = NULL;
pthread_mutex_t gCamLock = PTHREAD_MUTEX_INITIALIZER;
#ifdef QCAMERA_HAL1_SUPPORT
QCameraMuxer *gQCameraMuxer = NULL;
#endif
//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()
{
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);
#ifndef QCAMERA_HAL1_SUPPORT
isHAL3Enabled = 1;
#endif
// 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);
#ifndef QCAMERA_HAL1_SUPPORT
bDualCamera = 0;
#endif
if(bDualCamera) {
LOGI("Enabling QCamera Muxer");
#ifdef QCAMERA_HAL1_SUPPORT
if (!gQCameraMuxer) {
QCameraMuxer::getCameraMuxer(&gQCameraMuxer, mNumOfCameras);
if (!gQCameraMuxer) {
LOGE("Error !! Failed to get QCameraMuxer");
}
}
#endif
}
#ifdef QCAMERA_HAL1_SUPPORT
if (!gQCameraMuxer && (mNumOfCameras > 0) &&(mNumOfCameras <= MM_CAMERA_MAX_NUM_SENSORS)) {
#else
if ((mNumOfCameras > 0) &&(mNumOfCameras <= MM_CAMERA_MAX_NUM_SENSORS)) {
#endif
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;
}
}
} 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;
}
#ifdef QCAMERA_HAL1_SUPPORT
if (gQCameraMuxer) {
delete gQCameraMuxer;
gQCameraMuxer = NULL;
}
#endif
}
/*===========================================================================
* 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;
if (!gQCamera2Factory) {
gQCamera2Factory = new QCamera2Factory();
if (!gQCamera2Factory) {
LOGE("Failed to allocate Camera2Factory object");
return 0;
}
}
#ifdef QCAMERA_HAL1_SUPPORT
if(gQCameraMuxer)
numCameras = gQCameraMuxer->get_number_of_cameras();
else
#endif
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;
#ifdef QCAMERA_HAL1_SUPPORT
if(gQCameraMuxer)
rc = gQCameraMuxer->get_camera_info(camera_id, info);
else
#endif
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;
#ifdef QCAMERA_HAL1_SUPPORT
if(gQCameraMuxer)
rc = gQCameraMuxer->set_callbacks(callbacks);
else
#endif
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;
}
#ifdef QCAMERA_HAL1_SUPPORT
if(gQCameraMuxer)
rc = gQCameraMuxer->open_legacy(module, id, halVersion, device);
else
#endif
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;
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;
}
}
#ifdef QCAMERA_HAL1_SUPPORT
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;
}
}
#endif
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;
}
#ifdef QCAMERA_HAL1_SUPPORT
if(gQCameraMuxer)
rc = gQCameraMuxer->camera_device_open(module, id, hw_device);
else
#endif
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)
{
#ifdef QCAMERA_HAL1_SUPPORT
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;
}
#endif
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) {
#ifdef QCAMERA_HAL1_SUPPORT
QCamera2HardwareInterface::getCapabilities(i, &info, &cam_type);
#endif
}
if(cam_type == CAM_TYPE_AUX) {
LOGH("Have Dual Camera HW Avaiable.");
rc = true;
break;
}
}
#ifdef QCAMERA_HAL1_SUPPORT
return rc;
#else
return false;
#endif
}
}; // 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 "hardware/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,44 @@
/* 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.
*
*/
/* Macros exposed to gralloc to query camera HAL for gralloc format to be
used for vedor specific camera formats. */
#define PREFERRED_IMPLEMENTATION_DEFINED_CAMERA_FORMAT HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS
#define PREFERRED_YCBCR_420_888_CAMERA_FORMAT HAL_PIXEL_FORMAT_NV21_ZSL
/* Macros exposed to camera HAL to get the preview and callback stream
formats. Please ensure that if the macros below are changed then the
corresponding change should be done in the above macros and vice versa
to prevent format mismatch between Gralloc and Camera HAL for stream
buffers */
#define PREVIEW_STREAM_FORMAT CAM_FORMAT_YUV_420_NV12_VENUS
#define CALLBACK_STREAM_FORMAT CAM_FORMAT_YUV_420_NV21

View file

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

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,85 @@
/* 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
#include <stddef.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,94 @@
/* Copyright (c) 2012, 2017, 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_condattr_t cond_attr;
pthread_condattr_init(&cond_attr);
pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);
pthread_mutex_init(&(s->mutex), NULL);
pthread_cond_init(&(s->cond), &cond_attr);
pthread_condattr_destroy(&cond_attr);
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,942 @@
/* 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
* @user_expected_frame_id : Number of frames, camera interface
* will wait for getting the instant capture frame.
**/
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;
uint8_t user_expected_frame_id;
} 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);
/** cancel_buffer: fucntion definition for recalling a frame
* buffer from the kernel this is most likely when h/w
* failed to use this buffer and dropped the frame we use
* this API to recall the buffer and return it to the
* framework
* @camera_handle : camer handler
* @ch_id : channel handler
* @stream_id : stream handle
* @buf : a frame buffer to be queued back to kernel
* Return value: 0 -- success
* -1 -- failure
**/
int32_t (*cancel_buffer) (uint32_t camera_handle,
uint32_t ch_id,
uint32_t stream_id,
uint32_t buf_idx);
/** 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_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_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,408 @@
/* 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;
cam_bestats_buffer_exif_debug_t bestats_debug_params;
cam_bhist_buffer_exif_debug_t bhist_debug_params;
cam_q3a_tuning_info_t q3a_tuning_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;
uint8_t bestats_debug_params_valid;
uint8_t bhist_debug_params_valid;
uint8_t q3a_tuning_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;
/* Flag to indicate if multi picture metadata need to be added to Exif */
uint8_t enable_metadata;
} 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,62 @@
OLD_LOCAL_PATH := $(LOCAL_PATH)
LOCAL_PATH := $(call my-dir)
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 msm8953 msm8996 msmcobalt msmfalcon, $(TARGET_BOARD_PLATFORM)))
LOCAL_CFLAGS += -DVENUS_PRESENT
endif
ifneq (,$(filter msm8996 msmcobalt msmfalcon,$(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 \
$(call project-path-for,qcom-media)/media/mm-core/inc \
system/media/camera/include \
LOCAL_CFLAGS += -DCAMERA_ION_HEAP_ID=ION_IOMMU_HEAP_ID
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_SHARED_LIBRARIES := libdl libcutils liblog
LOCAL_HEADER_LIBRARIES := libhardware_headers
LOCAL_HEADER_LIBRARIES += media_plugin_headers
LOCAL_HEADER_LIBRARIES += generated_kernel_headers
LOCAL_MODULE_TAGS := optional
LOCAL_VENDOR_MODULE := true
LOCAL_32_BIT_ONLY := $(BOARD_QTI_CAMERA_32BIT_ONLY)
include $(BUILD_SHARED_LIBRARY)
LOCAL_PATH := $(OLD_LOCAL_PATH)

View file

@ -0,0 +1,786 @@
/* 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 "hardware/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_CANCEL_BUF,
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_frame;
uint32_t frame_idx;
/* unmatched meta idx needed in case of low priority queue */
uint32_t unmatched_meta_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 good_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;
//HACKED camera_info struct from hardware/libhardware/include/hardware/camera_common.h
typedef struct samsung_camera_info {
int facing;
int orientation;
uint32_t device_version;
const camera_metadata_t *static_camera_characteristics;
int resource_cost;
char** conflicting_devices;
size_t conflicting_devices_length;
volatile char samsung_reserved[20];//uknown addition by samsung
} samsung_camera_info_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 samsung_camera_info info[MM_CAMERA_MAX_NUM_SENSORS]; //hacked struct 20*5 bytes bigger in samsung blobs
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_cancel_buf(mm_camera_obj_t *my_obj,
uint32_t ch_id,
uint32_t stream_id,
uint32_t buf_idx);
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);
extern int32_t mm_channel_cancel_buf(mm_channel_t *my_obj,
uint32_t stream_id, uint32_t buf_idx);
/* 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,134 @@
/* 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;
/* values that persist.camera.global.debug can be set to */
/* all camera modules need to map their internal debug levels to this range */
typedef enum {
CAM_GLBL_DBG_NONE = 0,
CAM_GLBL_DBG_ERR = 1,
CAM_GLBL_DBG_WARN = 2,
CAM_GLBL_DBG_HIGH = 3,
CAM_GLBL_DBG_DEBUG = 4,
CAM_GLBL_DBG_LOW = 5,
CAM_GLBL_DBG_INFO = 6
} cam_global_debug_level_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,295 @@
/* 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>
#include <unistd.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, "/data/vendor/camera/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,704 @@
/* Copyright (c) 2012-2017, 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 <unistd.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) {
LOGW("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) {
LOGW("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 {
if ((MAX_STREAM_NUM_IN_BUNDLE <= idx) ||
(poll_cb->poll_entries[idx].handler != 0)) {
LOGE("invalid handler %d (%d)", poll_cb->poll_entries[idx].handler,
idx);
rc = -1;
} else {
LOGW("invalid handler %d (%d)", handler, idx);
rc = 0;
}
}
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;
pthread_condattr_t cond_attr;
//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_condattr_init(&cond_attr);
pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);
pthread_mutex_init(&poll_cb->mutex, NULL);
pthread_cond_init(&poll_cb->cond_v, &cond_attr);
pthread_condattr_destroy(&cond_attr);
/* 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) {
LOGD("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,81 @@
OLD_LOCAL_PATH := $(LOCAL_PATH)
LOCAL_PATH := $(call my-dir)
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_HEADER_LIBRARIES := generated_kernel_headers
LOCAL_HEADER_LIBRARIES += libutils_headers
LOCAL_HEADER_LIBRARIES += media_plugin_headers
LIB2D_ROTATION=false
LOCAL_C_INCLUDES += \
$(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 $(LIB2D_ROTATION)),true)
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../mm-lib2d-interface/inc
LOCAL_CFLAGS += -DLIB2D_ROTATION_ENABLE
endif
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
JPEG_PIPELINE_TARGET_LIST += msmcobalt
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_SHARED_LIBRARIES := libdl libcutils liblog libqomx_core libmmcamera_interface
ifeq ($(strip $(LIB2D_ROTATION)),true)
LOCAL_SHARED_LIBRARIES += libmmlib2d_interface
endif
LOCAL_MODULE_TAGS := optional
LOCAL_VENDOR_MODULE := true
LOCAL_32_BIT_ONLY := $(BOARD_QTI_CAMERA_32BIT_ONLY)
include $(BUILD_SHARED_LIBRARY)
LOCAL_PATH := $(OLD_LOCAL_PATH)

View file

@ -0,0 +1,539 @@
/* 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)
// Thumbnail src and dest aspect ratio diffrence tolerance
#define ASPECT_TOLERANCE 0.001
/** 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_BUFFERHEADERTYPE *p_in_rot_omx_buf[MM_JPEG_MAX_BUF];
OMX_BUFFERHEADERTYPE *p_in_rot_omx_thumb_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;
/* src rotate ion bufs */
buffer_t src_rot_ion_buffer[MM_JPEG_MAX_BUF];
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;
/* lib2d rotation flag*/
uint32_t lib2d_rotation_flag;
/* num of buf for input src rotation */
uint32_t num_src_rot_bufs;
/* src rotate img bufs */
mm_jpeg_buf_t src_rot_main_buf[MM_JPEG_MAX_BUF];
/* lib2d handle*/
void *lib2d_handle;
} 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;
/* Pointer to the session in progress*/
mm_jpeg_job_session_t *p_session_inprogress;
// dummy OMX handle
OMX_HANDLETYPE dummy_handle;
} 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,105 @@
/* 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);
/** buffer_clean:
*
* Arguments:
* @p_buffer: ION buffer
*
* Return:
* error val
*
* Description:
* clean the cached buffer
*
**/
int buffer_clean(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,652 @@
/* 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 = 0;
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 mode %d flash state %d",
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;
LOGW("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;
LOGW("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;
cam_asd_decision_t *scene_info = NULL;
IF_META_AVAILABLE(cam_asd_decision_t, scene_cap_type,
CAM_INTF_META_ASD_SCENE_INFO, p_meta) {
scene_info = (cam_asd_decision_t*)scene_cap_type;
val_short = (short) scene_info->detected_scene;
}
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;
}

View file

@ -0,0 +1,409 @@
/* 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.
*
*/
// To remove
#include <cutils/properties.h>
// System dependencies
#include <stdlib.h>
#include <pthread.h>
// JPEG dependencies
#include "mm_jpeg_dbg.h"
#include "mm_jpeg_interface.h"
#include "mm_jpeg.h"
#include "mm_jpeg_mpo.h"
static pthread_mutex_t g_intf_lock = PTHREAD_MUTEX_INITIALIZER;
static mm_jpeg_obj* g_jpeg_obj = NULL;
static pthread_mutex_t g_handler_lock = PTHREAD_MUTEX_INITIALIZER;
static uint16_t g_handler_history_count = 0; /* history count for handler */
volatile uint32_t gKpiDebugLevel = 0;
/** mm_jpeg_util_generate_handler:
*
* Arguments:
* @index: client index
*
* Return:
* handle value
*
* Description:
* utility function to generate handler
*
**/
uint32_t mm_jpeg_util_generate_handler(uint8_t index)
{
uint32_t handler = 0;
pthread_mutex_lock(&g_handler_lock);
g_handler_history_count++;
if (0 == g_handler_history_count) {
g_handler_history_count++;
}
handler = g_handler_history_count;
handler = (handler<<8) | index;
pthread_mutex_unlock(&g_handler_lock);
return handler;
}
/** mm_jpeg_util_get_index_by_handler:
*
* Arguments:
* @handler: handle value
*
* Return:
* client index
*
* Description:
* get client index
*
**/
uint8_t mm_jpeg_util_get_index_by_handler(uint32_t handler)
{
return (handler & 0x000000ff);
}
/** mm_jpeg_intf_start_job:
*
* Arguments:
* @client_hdl: client handle
* @job: jpeg job object
* @jobId: job id
*
* Return:
* 0 success, failure otherwise
*
* Description:
* start the jpeg job
*
**/
static int32_t mm_jpeg_intf_start_job(mm_jpeg_job_t* job, uint32_t* job_id)
{
int32_t rc = -1;
if (NULL == job ||
NULL == job_id) {
LOGE("invalid parameters for job or jobId");
return rc;
}
pthread_mutex_lock(&g_intf_lock);
if (NULL == g_jpeg_obj) {
/* mm_jpeg obj not exists, return error */
LOGE("mm_jpeg is not opened yet");
pthread_mutex_unlock(&g_intf_lock);
return rc;
}
rc = mm_jpeg_start_job(g_jpeg_obj, job, job_id);
pthread_mutex_unlock(&g_intf_lock);
return rc;
}
/** mm_jpeg_intf_create_session:
*
* Arguments:
* @client_hdl: client handle
* @p_params: encode parameters
* @p_session_id: session id
*
* Return:
* 0 success, failure otherwise
*
* Description:
* Create new jpeg session
*
**/
static int32_t mm_jpeg_intf_create_session(uint32_t client_hdl,
mm_jpeg_encode_params_t *p_params,
uint32_t *p_session_id)
{
int32_t rc = -1;
if (0 == client_hdl || NULL == p_params || NULL == p_session_id) {
LOGE("invalid client_hdl or jobId");
return rc;
}
pthread_mutex_lock(&g_intf_lock);
if (NULL == g_jpeg_obj) {
/* mm_jpeg obj not exists, return error */
LOGE("mm_jpeg is not opened yet");
pthread_mutex_unlock(&g_intf_lock);
return rc;
}
rc = mm_jpeg_create_session(g_jpeg_obj, client_hdl, p_params, p_session_id);
pthread_mutex_unlock(&g_intf_lock);
return rc;
}
/** mm_jpeg_intf_destroy_session:
*
* Arguments:
* @session_id: session id
*
* Return:
* 0 success, failure otherwise
*
* Description:
* Destroy jpeg session
*
**/
static int32_t mm_jpeg_intf_destroy_session(uint32_t session_id)
{
int32_t rc = -1;
if (0 == session_id) {
LOGE("invalid client_hdl or jobId");
return rc;
}
pthread_mutex_lock(&g_intf_lock);
if (NULL == g_jpeg_obj) {
/* mm_jpeg obj not exists, return error */
LOGE("mm_jpeg is not opened yet");
pthread_mutex_unlock(&g_intf_lock);
return rc;
}
rc = mm_jpeg_destroy_session_by_id(g_jpeg_obj, session_id);
pthread_mutex_unlock(&g_intf_lock);
return rc;
}
/** mm_jpeg_intf_abort_job:
*
* Arguments:
* @jobId: job id
*
* Return:
* 0 success, failure otherwise
*
* Description:
* Abort the jpeg job
*
**/
static int32_t mm_jpeg_intf_abort_job(uint32_t job_id)
{
int32_t rc = -1;
if (0 == job_id) {
LOGE("invalid jobId");
return rc;
}
pthread_mutex_lock(&g_intf_lock);
if (NULL == g_jpeg_obj) {
/* mm_jpeg obj not exists, return error */
LOGE("mm_jpeg is not opened yet");
pthread_mutex_unlock(&g_intf_lock);
return rc;
}
rc = mm_jpeg_abort_job(g_jpeg_obj, job_id);
pthread_mutex_unlock(&g_intf_lock);
return rc;
}
/** mm_jpeg_intf_close:
*
* Arguments:
* @client_hdl: client handle
*
* Return:
* 0 success, failure otherwise
*
* Description:
* Close the jpeg job
*
**/
static int32_t mm_jpeg_intf_close(uint32_t client_hdl)
{
int32_t rc = -1;
if (0 == client_hdl) {
LOGE("invalid client_hdl");
return rc;
}
pthread_mutex_lock(&g_intf_lock);
if (NULL == g_jpeg_obj) {
/* mm_jpeg obj not exists, return error */
LOGE("mm_jpeg is not opened yet");
pthread_mutex_unlock(&g_intf_lock);
return rc;
}
rc = mm_jpeg_close(g_jpeg_obj, client_hdl);
g_jpeg_obj->num_clients--;
if(0 == rc) {
if (0 == g_jpeg_obj->num_clients) {
/* No client, close jpeg internally */
rc = mm_jpeg_deinit(g_jpeg_obj);
free(g_jpeg_obj);
g_jpeg_obj = NULL;
}
}
pthread_mutex_unlock(&g_intf_lock);
return rc;
}
/** mm_jpeg_intf_compose_mpo:
*
* Arguments:
* @mpo_info : MPO Information
*
* Return:
* 0 success, failure otherwise
*
* Description:
* Compose MPO image from jpeg images
*
**/
static int32_t mm_jpeg_intf_compose_mpo(mm_jpeg_mpo_info_t *mpo_info)
{
int32_t rc = -1;
if (!mpo_info) {
LOGE("Invalid input");
return rc;
}
if (mpo_info->num_of_images > MM_JPEG_MAX_MPO_IMAGES) {
LOGE("Num of images exceeds max supported images in MPO");
return rc;
}
//Call MPo composition
rc = mm_jpeg_mpo_compose(mpo_info);
return rc;
}
/** jpeg_open:
*
* Arguments:
* @ops: ops table pointer
* @mpo_ops: mpo ops table ptr
* @picture_size: Max available dim
* @jpeg_metadata: Jpeg meta data
*
* Return:
* 0 failure, success otherwise
*
* Description:
* Open a jpeg client. Jpeg meta data will be cached
* but memory manegement has to be done by the cient.
*
**/
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)
{
int32_t rc = 0;
uint32_t clnt_hdl = 0;
mm_jpeg_obj* jpeg_obj = NULL;
char prop[PROPERTY_VALUE_MAX];
property_get("persist.camera.kpi.debug", prop, "0");
gKpiDebugLevel = atoi(prop);
pthread_mutex_lock(&g_intf_lock);
/* first time open */
if(NULL == g_jpeg_obj) {
jpeg_obj = (mm_jpeg_obj *)malloc(sizeof(mm_jpeg_obj));
if(NULL == jpeg_obj) {
LOGE("no mem");
pthread_mutex_unlock(&g_intf_lock);
return clnt_hdl;
}
/* initialize jpeg obj */
memset(jpeg_obj, 0, sizeof(mm_jpeg_obj));
/* by default reuse reproc source buffer if available */
if (mpo_ops == NULL) {
jpeg_obj->reuse_reproc_buffer = 1;
} else {
jpeg_obj->reuse_reproc_buffer = 0;
}
LOGH("reuse_reproc_buffer %d ",
jpeg_obj->reuse_reproc_buffer);
/* used for work buf calculation */
jpeg_obj->max_pic_w = picture_size.w;
jpeg_obj->max_pic_h = picture_size.h;
/*Cache OTP Data for the session*/
if (NULL != jpeg_metadata) {
jpeg_obj->jpeg_metadata = jpeg_metadata;
}
rc = mm_jpeg_init(jpeg_obj);
if(0 != rc) {
LOGE("mm_jpeg_init err = %d", rc);
free(jpeg_obj);
pthread_mutex_unlock(&g_intf_lock);
return clnt_hdl;
}
/* remember in global variable */
g_jpeg_obj = jpeg_obj;
}
/* open new client */
clnt_hdl = mm_jpeg_new_client(g_jpeg_obj);
if (clnt_hdl > 0) {
/* valid client */
if (NULL != ops) {
/* fill in ops tbl if ptr not NULL */
ops->start_job = mm_jpeg_intf_start_job;
ops->abort_job = mm_jpeg_intf_abort_job;
ops->create_session = mm_jpeg_intf_create_session;
ops->destroy_session = mm_jpeg_intf_destroy_session;
ops->close = mm_jpeg_intf_close;
}
if (NULL != mpo_ops) {
mpo_ops->compose_mpo = mm_jpeg_intf_compose_mpo;
}
} else {
/* failed new client */
LOGE("mm_jpeg_new_client failed");
if (0 == g_jpeg_obj->num_clients) {
/* no client, close jpeg */
mm_jpeg_deinit(g_jpeg_obj);
free(g_jpeg_obj);
g_jpeg_obj = NULL;
}
}
pthread_mutex_unlock(&g_intf_lock);
return clnt_hdl;
}

View file

@ -0,0 +1,206 @@
/* 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.
*
*/
// System dependencies
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <linux/msm_ion.h>
#define MMAN_H <SYSTEM_HEADER_PREFIX/mman.h>
#include MMAN_H
// JPEG dependencies
#include "mm_jpeg_ionbuf.h"
/** buffer_allocate:
*
* Arguments:
* @p_buffer: ION buffer
*
* Return:
* buffer address
*
* Description:
* allocates ION buffer
*
**/
void *buffer_allocate(buffer_t *p_buffer, int cached)
{
void *l_buffer = NULL;
int lrc = 0;
struct ion_handle_data lhandle_data;
p_buffer->alloc.len = p_buffer->size;
p_buffer->alloc.align = 4096;
p_buffer->alloc.flags = (cached) ? ION_FLAG_CACHED : 0;
p_buffer->alloc.heap_id_mask = 0x1 << ION_IOMMU_HEAP_ID;
p_buffer->ion_fd = open("/dev/ion", O_RDONLY);
if(p_buffer->ion_fd < 0) {
LOGE("Ion open failed");
goto ION_ALLOC_FAILED;
}
/* Make it page size aligned */
p_buffer->alloc.len = (p_buffer->alloc.len + 4095U) & (~4095U);
lrc = ioctl(p_buffer->ion_fd, ION_IOC_ALLOC, &p_buffer->alloc);
if (lrc < 0) {
LOGE("ION allocation failed len %zu",
p_buffer->alloc.len);
goto ION_ALLOC_FAILED;
}
p_buffer->ion_info_fd.handle = p_buffer->alloc.handle;
lrc = ioctl(p_buffer->ion_fd, ION_IOC_SHARE,
&p_buffer->ion_info_fd);
if (lrc < 0) {
LOGE("ION map failed %s", strerror(errno));
goto ION_MAP_FAILED;
}
p_buffer->p_pmem_fd = p_buffer->ion_info_fd.fd;
l_buffer = mmap(NULL, p_buffer->alloc.len, PROT_READ | PROT_WRITE,
MAP_SHARED,p_buffer->p_pmem_fd, 0);
if (l_buffer == MAP_FAILED) {
LOGE("ION_MMAP_FAILED: %s (%d)",
strerror(errno), errno);
goto ION_MAP_FAILED;
}
return l_buffer;
ION_MAP_FAILED:
lhandle_data.handle = p_buffer->ion_info_fd.handle;
ioctl(p_buffer->ion_fd, ION_IOC_FREE, &lhandle_data);
return NULL;
ION_ALLOC_FAILED:
return NULL;
}
/** buffer_deallocate:
*
* Arguments:
* @p_buffer: ION buffer
*
* Return:
* buffer address
*
* Description:
* deallocates ION buffer
*
**/
int buffer_deallocate(buffer_t *p_buffer)
{
int lrc = 0;
size_t lsize = (p_buffer->size + 4095U) & (~4095U);
struct ion_handle_data lhandle_data;
lrc = munmap(p_buffer->addr, lsize);
close(p_buffer->ion_info_fd.fd);
lhandle_data.handle = p_buffer->ion_info_fd.handle;
ioctl(p_buffer->ion_fd, ION_IOC_FREE, &lhandle_data);
close(p_buffer->ion_fd);
return lrc;
}
/** buffer_invalidate:
*
* Arguments:
* @p_buffer: ION buffer
*
* Return:
* error val
*
* Description:
* Invalidates the cached buffer
*
**/
int buffer_invalidate(buffer_t *p_buffer)
{
int lrc = 0;
struct ion_flush_data cache_inv_data;
struct ion_custom_data custom_data;
memset(&cache_inv_data, 0, sizeof(cache_inv_data));
memset(&custom_data, 0, sizeof(custom_data));
cache_inv_data.vaddr = p_buffer->addr;
cache_inv_data.fd = p_buffer->ion_info_fd.fd;
cache_inv_data.handle = p_buffer->ion_info_fd.handle;
cache_inv_data.length = (unsigned int)p_buffer->size;
custom_data.cmd = (unsigned int)ION_IOC_INV_CACHES;
custom_data.arg = (unsigned long)&cache_inv_data;
lrc = ioctl(p_buffer->ion_fd, ION_IOC_CUSTOM, &custom_data);
if (lrc < 0)
LOGW("Cache Invalidate failed: %s\n", strerror(errno));
return lrc;
}
/** buffer_clean:
*
* Arguments:
* @p_buffer: ION buffer
*
* Return:
* error val
*
* Description:
* Clean the cached buffer
*
**/
int buffer_clean(buffer_t *p_buffer)
{
int lrc = 0;
struct ion_flush_data cache_clean_data;
struct ion_custom_data custom_data;
memset(&cache_clean_data, 0, sizeof(cache_clean_data));
memset(&custom_data, 0, sizeof(custom_data));
cache_clean_data.vaddr = p_buffer->addr;
cache_clean_data.fd = p_buffer->ion_info_fd.fd;
cache_clean_data.handle = p_buffer->ion_info_fd.handle;
cache_clean_data.length = (unsigned int)p_buffer->size;
custom_data.cmd = (unsigned int)ION_IOC_CLEAN_CACHES;
custom_data.arg = (unsigned long)&cache_clean_data;
lrc = ioctl(p_buffer->ion_fd, ION_IOC_CUSTOM, &custom_data);
if (lrc < 0)
LOGW("Cache clean failed: %s\n", strerror(errno));
return lrc;
}

View file

@ -0,0 +1,414 @@
/* 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
// System dependencies
#include <pthread.h>
// JPEG dependencies
#include "mm_jpeg_dbg.h"
#include "mm_jpeg_mpo.h"
#define M_APP0 0xe0
#define M_APP1 0xe1
#define M_APP2 0xe2
#define M_EOI 0xd9
#define M_SOI 0xd8
/** READ_LONG:
* @b: Buffer start addr
* @o: Buffer offset to start reading
*
* Read long value from the specified buff addr at given offset
**/
#define READ_LONG(b, o) \
(uint32_t)(((uint32_t)b[o] << 24) + \
((uint32_t)b[o+1] << 16) + \
((uint32_t)b[o+2] << 8) + \
((uint32_t)b[o+3]))
/** READ_LONG_LITTLE:
* @b: Buffer start addr
* @o: Buffer offset to start reading
*
* Read long value from the specified buff addr at given offset
* in Little Endian
**/
#define READ_LONG_LITTLE(b, o) \
(uint32_t)(((uint32_t)b[o + 3] << 24) + \
((uint32_t) b[o + 2] << 16) + \
((uint32_t) b[o + 1] << 8) + \
(uint32_t) b[o]);
/** READ_LONG:
* @b: Buffer start addr
* @o: Buffer offset to start reading
*
* Read short value from the specified buff addr at given
* offset
**/
#define READ_SHORT(b, o) \
(uint16_t) (((uint16_t)b[o] << 8) + \
(uint16_t) b[o + 1]);
/*Mutex to serializa MPO composition*/
static pthread_mutex_t g_mpo_lock = PTHREAD_MUTEX_INITIALIZER;
/** mm_jpeg_mpo_write_long_little_endian
*
* Arguments:
* @buffer_addr: image start addr
* @buff_offset: offset in the buffer
* @buffer_size: Size of the buffer
* @value: Value to write
* @overflow : Overflow flag
*
* Return:
* None
*
* Description:
* Write value at the given offset
*
**/
void mm_jpeg_mpo_write_long_little_endian(uint8_t *buff_addr, uint32_t buff_offset,
uint32_t buffer_size, int value, uint8_t *overflow)
{
if (buff_offset + 3 >= buffer_size) {
*overflow = TRUE;
}
if (!(*overflow)) {
buff_addr[buff_offset + 3] = (uint8_t)((value >> 24) & 0xFF);
buff_addr[buff_offset + 2] = (uint8_t)((value >> 16) & 0xFF);
buff_addr[buff_offset + 1] = (uint8_t)((value >> 8) & 0xFF);
buff_addr[buff_offset] = (uint8_t)(value & 0xFF);
}
}
/** mm_jpeg_mpo_write_long
*
* Arguments:
* @buffer_addr: image start addr
* @buff_offset: offset in the buffer
* @buffer_size: Size of the buffer
* @value: Value to write
* @overflow : Overflow flag
*
* Return:
* None
*
* Description:
* Write value at the given offset
*
**/
void mm_jpeg_mpo_write_long(uint8_t *buff_addr, uint32_t buff_offset,
uint32_t buffer_size, int value, uint8_t *overflow)
{
if ((buff_offset + 3) >= buffer_size) {
*overflow = TRUE;
}
if (!(*overflow)) {
buff_addr[buff_offset] = (uint8_t)((value >> 24) & 0xFF);
buff_addr[buff_offset+1] = (uint8_t)((value >> 16) & 0xFF);
buff_addr[buff_offset+2] = (uint8_t)((value >> 8) & 0xFF);
buff_addr[buff_offset+3] = (uint8_t)(value & 0xFF);
}
}
/** mm_jpeg_mpo_get_app_marker
*
* Arguments:
* @buffer_addr: Jpeg image start addr
* @buffer_size: Size of the Buffer
* @app_marker: app_marker to find
*
* Return:
* Start offset of the specified app marker
*
* Description:
* Gets the start offset of the given app marker
*
**/
uint8_t *mm_jpeg_mpo_get_app_marker(uint8_t *buffer_addr, int buffer_size,
int app_marker)
{
int32_t byte;
uint8_t *p_current_addr = NULL, *p_start_offset = NULL;
uint16_t app_marker_size = 0;
p_current_addr = buffer_addr;
do {
do {
byte = *(p_current_addr);
p_current_addr++;
}
while ((byte != 0xFF) &&
(p_current_addr < (buffer_addr + (buffer_size - 1))));
//If 0xFF is not found at all, break
if (byte != 0xFF) {
LOGD("0xFF not found");
break;
}
//Read the next byte after 0xFF
byte = *(p_current_addr);
LOGD("Byte %x", byte);
if (byte == app_marker) {
LOGD("Byte %x", byte);
p_start_offset = ++p_current_addr;
break;
} else if (byte != M_SOI) {
app_marker_size = READ_SHORT(p_current_addr, 1);
LOGD("size %d", app_marker_size);
p_current_addr += app_marker_size;
}
}
while ((byte != M_EOI) &&
(p_current_addr < (buffer_addr + (buffer_size - 1))));
return p_start_offset;
}
/** mm_jpeg_mpo_get_mp_header
*
* Arguments:
* @app2_marker: app2_marker start offset
*
* Return:
* Start offset of the MP header
*
* Description:
* Get the start offset of the MP header (before the MP
* Endian field). All offsets in the MP header need to be
* specified wrt this start offset.
*
**/
uint8_t *mm_jpeg_mpo_get_mp_header(uint8_t *app2_start_offset)
{
uint8_t *mp_headr_start_offset = NULL;
if (app2_start_offset != NULL) {
mp_headr_start_offset = app2_start_offset + MP_APP2_FIELD_LENGTH_BYTES +
MP_FORMAT_IDENTIFIER_BYTES;
}
return mp_headr_start_offset;
}
/** mm_jpeg_mpo_update_header
*
* Arguments:
* @mpo_info: MPO Info
*
* Return:
* 0 - Success
* -1 - otherwise
*
* Description:
* Update the MP Index IFD of the first image with info
* about about all other images.
*
**/
int mm_jpeg_mpo_update_header(mm_jpeg_mpo_info_t *mpo_info)
{
uint8_t *app2_start_off_addr = NULL, *mp_headr_start_off_addr = NULL;
uint32_t mp_index_ifd_offset = 0, current_offset = 0, mp_entry_val_offset = 0;
uint8_t *aux_start_addr = NULL;
uint8_t overflow_flag = 0;
int i = 0, rc = -1;
uint32_t endianess = MPO_LITTLE_ENDIAN, offset_to_nxt_ifd = 8;
uint16_t ifd_tag_count = 0;
//Get the addr of the App Marker
app2_start_off_addr = mm_jpeg_mpo_get_app_marker(
mpo_info->output_buff.buf_vaddr, mpo_info->primary_image.buf_filled_len, M_APP2);
if (!app2_start_off_addr) {
LOGE("Cannot find App2 marker. MPO composition failed" );
return rc;
}
LOGD("app2_start_off_addr %p = %x",
app2_start_off_addr, *app2_start_off_addr);
//Get the addr of the MP Headr start offset.
//All offsets in the MP header are wrt to this addr
mp_headr_start_off_addr = mm_jpeg_mpo_get_mp_header(app2_start_off_addr);
if (!mp_headr_start_off_addr) {
LOGE("mp headr start offset is NULL. MPO composition failed" );
return rc;
}
LOGD("mp_headr_start_off_addr %x",
*mp_headr_start_off_addr);
current_offset = mp_headr_start_off_addr - mpo_info->output_buff.buf_vaddr;
endianess = READ_LONG(mpo_info->output_buff.buf_vaddr, current_offset);
LOGD("Endianess %d", endianess);
//Add offset to first ifd
current_offset += MP_ENDIAN_BYTES;
//Read the value to get MP Index IFD.
if (endianess == MPO_LITTLE_ENDIAN) {
offset_to_nxt_ifd = READ_LONG_LITTLE(mpo_info->output_buff.buf_vaddr,
current_offset);
} else {
offset_to_nxt_ifd = READ_LONG(mpo_info->output_buff.buf_vaddr,
current_offset);
}
LOGD("offset_to_nxt_ifd %d", offset_to_nxt_ifd);
current_offset = ((mp_headr_start_off_addr + offset_to_nxt_ifd) -
mpo_info->output_buff.buf_vaddr);
mp_index_ifd_offset = current_offset;
LOGD("mp_index_ifd_offset %d",
mp_index_ifd_offset);
//Traverse to MP Entry value
ifd_tag_count = READ_SHORT(mpo_info->output_buff.buf_vaddr, current_offset);
LOGD("Tag count in MP entry %d", ifd_tag_count);
current_offset += MP_INDEX_COUNT_BYTES;
/* Get MP Entry Value offset - Count * 12 (Each tag is 12 bytes)*/
current_offset += (ifd_tag_count * 12);
/*Add Offset to next IFD*/
current_offset += MP_INDEX_OFFSET_OF_NEXT_IFD_BYTES;
mp_entry_val_offset = current_offset;
LOGD("MP Entry value offset %d",
mp_entry_val_offset);
//Update image size for primary image
current_offset += MP_INDEX_ENTRY_INDIVIDUAL_IMAGE_ATTRIBUTE_BYTES;
if (endianess == MPO_LITTLE_ENDIAN) {
mm_jpeg_mpo_write_long_little_endian(mpo_info->output_buff.buf_vaddr,
current_offset, mpo_info->output_buff_size,
mpo_info->primary_image.buf_filled_len, &overflow_flag);
} else {
mm_jpeg_mpo_write_long(mpo_info->output_buff.buf_vaddr,
current_offset, mpo_info->output_buff_size,
mpo_info->primary_image.buf_filled_len, &overflow_flag);
}
aux_start_addr = mpo_info->output_buff.buf_vaddr +
mpo_info->primary_image.buf_filled_len;
for (i = 0; i < mpo_info->num_of_images - 1; i++) {
//Go to MP Entry val for each image
mp_entry_val_offset += MP_INDEX_ENTRY_VALUE_BYTES;
current_offset = mp_entry_val_offset;
//Update image size
current_offset += MP_INDEX_ENTRY_INDIVIDUAL_IMAGE_ATTRIBUTE_BYTES;
if (endianess == MPO_LITTLE_ENDIAN) {
mm_jpeg_mpo_write_long_little_endian(mpo_info->output_buff.buf_vaddr,
current_offset, mpo_info->output_buff_size,
mpo_info->aux_images[i].buf_filled_len, &overflow_flag);
} else {
mm_jpeg_mpo_write_long(mpo_info->output_buff.buf_vaddr,
current_offset, mpo_info->output_buff_size,
mpo_info->aux_images[i].buf_filled_len, &overflow_flag);
}
LOGD("aux[start_addr %x", *aux_start_addr);
//Update the offset
current_offset += MP_INDEX_ENTRY_INDIVIDUAL_IMAGE_SIZE_BYTES;
if (endianess == MPO_LITTLE_ENDIAN) {
mm_jpeg_mpo_write_long_little_endian(mpo_info->output_buff.buf_vaddr,
current_offset, mpo_info->output_buff_size,
aux_start_addr - mp_headr_start_off_addr, &overflow_flag);
} else {
mm_jpeg_mpo_write_long(mpo_info->output_buff.buf_vaddr,
current_offset, mpo_info->output_buff_size,
aux_start_addr - mp_headr_start_off_addr, &overflow_flag);
}
aux_start_addr += mpo_info->aux_images[i].buf_filled_len;
}
if (!overflow_flag) {
rc = 0;
}
return rc;
}
/** mm_jpeg_mpo_compose
*
* Arguments:
* @mpo_info: MPO Info
*
* Return:
* 0 - Success
* -1 - otherwise
*
* Description:
* Compose MPO image from multiple JPEG images
*
**/
int mm_jpeg_mpo_compose(mm_jpeg_mpo_info_t *mpo_info)
{
uint8_t *aux_write_offset = NULL;
int i = 0, rc = -1;
pthread_mutex_lock(&g_mpo_lock);
//Primary image needs to be copied to the o/p buffer if its not already
if (mpo_info->output_buff.buf_filled_len == 0) {
if (mpo_info->primary_image.buf_filled_len < mpo_info->output_buff_size) {
memcpy(mpo_info->output_buff.buf_vaddr, mpo_info->primary_image.buf_vaddr,
mpo_info->primary_image.buf_filled_len);
mpo_info->output_buff.buf_filled_len +=
mpo_info->primary_image.buf_filled_len;
} else {
LOGE("O/P buffer not large enough. MPO composition failed");
pthread_mutex_unlock(&g_mpo_lock);
return rc;
}
}
//Append each Aux image to the buffer
for (i = 0; i < mpo_info->num_of_images - 1; i++) {
if ((mpo_info->output_buff.buf_filled_len +
mpo_info->aux_images[i].buf_filled_len) <= mpo_info->output_buff_size) {
aux_write_offset = mpo_info->output_buff.buf_vaddr +
mpo_info->output_buff.buf_filled_len;
memcpy(aux_write_offset, mpo_info->aux_images[i].buf_vaddr,
mpo_info->aux_images[i].buf_filled_len);
mpo_info->output_buff.buf_filled_len +=
mpo_info->aux_images[i].buf_filled_len;
} else {
LOGE("O/P buffer not large enough. MPO composition failed");
pthread_mutex_unlock(&g_mpo_lock);
return rc;
}
}
rc = mm_jpeg_mpo_update_header(mpo_info);
pthread_mutex_unlock(&g_mpo_lock);
return rc;
}

View file

@ -0,0 +1,186 @@
/* 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 <pthread.h>
// JPEG dependencies
#include "mm_jpeg_dbg.h"
#include "mm_jpeg.h"
int32_t mm_jpeg_queue_init(mm_jpeg_queue_t* queue)
{
pthread_mutex_init(&queue->lock, NULL);
cam_list_init(&queue->head.list);
queue->size = 0;
return 0;
}
int32_t mm_jpeg_queue_enq(mm_jpeg_queue_t* queue, mm_jpeg_q_data_t data)
{
mm_jpeg_q_node_t* node =
(mm_jpeg_q_node_t *)malloc(sizeof(mm_jpeg_q_node_t));
if (NULL == node) {
LOGE("No memory for mm_jpeg_q_node_t");
return -1;
}
memset(node, 0, sizeof(mm_jpeg_q_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;
}
int32_t mm_jpeg_queue_enq_head(mm_jpeg_queue_t* queue, mm_jpeg_q_data_t data)
{
struct cam_list *head = NULL;
struct cam_list *pos = NULL;
mm_jpeg_q_node_t* node =
(mm_jpeg_q_node_t *)malloc(sizeof(mm_jpeg_q_node_t));
if (NULL == node) {
LOGE("No memory for mm_jpeg_q_node_t");
return -1;
}
memset(node, 0, sizeof(mm_jpeg_q_node_t));
node->data = data;
head = &queue->head.list;
pos = head->next;
pthread_mutex_lock(&queue->lock);
cam_list_insert_before_node(&node->list, pos);
queue->size++;
pthread_mutex_unlock(&queue->lock);
return 0;
}
mm_jpeg_q_data_t mm_jpeg_queue_deq(mm_jpeg_queue_t* queue)
{
mm_jpeg_q_data_t data;
mm_jpeg_q_node_t* node = NULL;
struct cam_list *head = NULL;
struct cam_list *pos = NULL;
memset(&data, 0, sizeof(data));
pthread_mutex_lock(&queue->lock);
head = &queue->head.list;
pos = head->next;
if (pos != head) {
node = member_of(pos, mm_jpeg_q_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;
}
uint32_t mm_jpeg_queue_get_size(mm_jpeg_queue_t* queue)
{
uint32_t size = 0;
pthread_mutex_lock(&queue->lock);
size = queue->size;
pthread_mutex_unlock(&queue->lock);
return size;
}
int32_t mm_jpeg_queue_deinit(mm_jpeg_queue_t* queue)
{
mm_jpeg_queue_flush(queue);
pthread_mutex_destroy(&queue->lock);
return 0;
}
int32_t mm_jpeg_queue_flush(mm_jpeg_queue_t* queue)
{
mm_jpeg_q_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, mm_jpeg_q_node_t, list);
cam_list_del_node(&node->list);
queue->size--;
/* for now we only assume there is no ptr inside data
* so we free data directly */
if (NULL != node->data.p) {
free(node->data.p);
}
free(node);
pos = pos->next;
}
queue->size = 0;
pthread_mutex_unlock(&queue->lock);
return 0;
}
mm_jpeg_q_data_t mm_jpeg_queue_peek(mm_jpeg_queue_t* queue)
{
mm_jpeg_q_data_t data;
mm_jpeg_q_node_t* node = NULL;
struct cam_list *head = NULL;
struct cam_list *pos = NULL;
memset(&data, 0, sizeof(data));
pthread_mutex_lock(&queue->lock);
head = &queue->head.list;
pos = head->next;
if (pos != head) {
node = member_of(pos, mm_jpeg_q_node_t, list);
}
pthread_mutex_unlock(&queue->lock);
if (NULL != node) {
data = node->data;
}
return data;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,301 @@
/* 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.
*
*/
// System dependencies
#include <pthread.h>
// JPEG dependencies
#include "mm_jpeg_dbg.h"
#include "mm_jpeg_interface.h"
#include "mm_jpeg.h"
static pthread_mutex_t g_dec_intf_lock = PTHREAD_MUTEX_INITIALIZER;
static mm_jpeg_obj* g_jpegdec_obj = NULL;
/** mm_jpeg_intf_start_job:
*
* Arguments:
* @client_hdl: client handle
* @job: jpeg job object
* @jobId: job id
*
* Return:
* 0 success, failure otherwise
*
* Description:
* start the jpeg job
*
**/
static int32_t mm_jpegdec_intf_start_job(mm_jpeg_job_t* job, uint32_t* job_id)
{
int32_t rc = -1;
if (NULL == job ||
NULL == job_id) {
LOGE("invalid parameters for job or jobId");
return rc;
}
pthread_mutex_lock(&g_dec_intf_lock);
if (NULL == g_jpegdec_obj) {
/* mm_jpeg obj not exists, return error */
LOGE("mm_jpeg is not opened yet");
pthread_mutex_unlock(&g_dec_intf_lock);
return rc;
}
rc = mm_jpegdec_start_decode_job(g_jpegdec_obj, job, job_id);
pthread_mutex_unlock(&g_dec_intf_lock);
return rc;
}
/** mm_jpeg_intf_create_session:
*
* Arguments:
* @client_hdl: client handle
* @p_params: encode parameters
* @p_session_id: session id
*
* Return:
* 0 success, failure otherwise
*
* Description:
* Create new jpeg session
*
**/
static int32_t mm_jpegdec_intf_create_session(uint32_t client_hdl,
mm_jpeg_decode_params_t *p_params,
uint32_t *p_session_id)
{
int32_t rc = -1;
if (0 == client_hdl || NULL == p_params || NULL == p_session_id) {
LOGE("invalid client_hdl or jobId");
return rc;
}
pthread_mutex_lock(&g_dec_intf_lock);
if (NULL == g_jpegdec_obj) {
/* mm_jpeg obj not exists, return error */
LOGE("mm_jpeg is not opened yet");
pthread_mutex_unlock(&g_dec_intf_lock);
return rc;
}
rc = mm_jpegdec_create_session(g_jpegdec_obj, client_hdl, p_params, p_session_id);
pthread_mutex_unlock(&g_dec_intf_lock);
return rc;
}
/** mm_jpeg_intf_destroy_session:
*
* Arguments:
* @session_id: session id
*
* Return:
* 0 success, failure otherwise
*
* Description:
* Destroy jpeg session
*
**/
static int32_t mm_jpegdec_intf_destroy_session(uint32_t session_id)
{
int32_t rc = -1;
if (0 == session_id) {
LOGE("invalid client_hdl or jobId");
return rc;
}
pthread_mutex_lock(&g_dec_intf_lock);
if (NULL == g_jpegdec_obj) {
/* mm_jpeg obj not exists, return error */
LOGE("mm_jpeg is not opened yet");
pthread_mutex_unlock(&g_dec_intf_lock);
return rc;
}
rc = mm_jpegdec_destroy_session_by_id(g_jpegdec_obj, session_id);
pthread_mutex_unlock(&g_dec_intf_lock);
return rc;
}
/** mm_jpegdec_intf_abort_job:
*
* Arguments:
* @jobId: job id
*
* Return:
* 0 success, failure otherwise
*
* Description:
* Abort the jpeg job
*
**/
static int32_t mm_jpegdec_intf_abort_job(uint32_t job_id)
{
int32_t rc = -1;
if (0 == job_id) {
LOGE("invalid jobId");
return rc;
}
pthread_mutex_lock(&g_dec_intf_lock);
if (NULL == g_jpegdec_obj) {
/* mm_jpeg obj not exists, return error */
LOGE("mm_jpeg is not opened yet");
pthread_mutex_unlock(&g_dec_intf_lock);
return rc;
}
rc = mm_jpegdec_abort_job(g_jpegdec_obj, job_id);
pthread_mutex_unlock(&g_dec_intf_lock);
return rc;
}
/** mm_jpeg_intf_close:
*
* Arguments:
* @client_hdl: client handle
*
* Return:
* 0 success, failure otherwise
*
* Description:
* Close the jpeg job
*
**/
static int32_t mm_jpegdec_intf_close(uint32_t client_hdl)
{
int32_t rc = -1;
if (0 == client_hdl) {
LOGE("invalid client_hdl");
return rc;
}
pthread_mutex_lock(&g_dec_intf_lock);
if (NULL == g_jpegdec_obj) {
/* mm_jpeg obj not exists, return error */
LOGE("mm_jpeg is not opened yet");
pthread_mutex_unlock(&g_dec_intf_lock);
return rc;
}
rc = mm_jpeg_close(g_jpegdec_obj, client_hdl);
g_jpegdec_obj->num_clients--;
if(0 == rc) {
if (0 == g_jpegdec_obj->num_clients) {
/* No client, close jpeg internally */
rc = mm_jpegdec_deinit(g_jpegdec_obj);
free(g_jpegdec_obj);
g_jpegdec_obj = NULL;
}
}
pthread_mutex_unlock(&g_dec_intf_lock);
return rc;
}
/** jpegdec_open:
*
* Arguments:
* @ops: ops table pointer
*
* Return:
* 0 failure, success otherwise
*
* Description:
* Open a jpeg client
*
**/
uint32_t jpegdec_open(mm_jpegdec_ops_t *ops)
{
int32_t rc = 0;
uint32_t clnt_hdl = 0;
mm_jpeg_obj* jpeg_obj = NULL;
pthread_mutex_lock(&g_dec_intf_lock);
/* first time open */
if(NULL == g_jpegdec_obj) {
jpeg_obj = (mm_jpeg_obj *)malloc(sizeof(mm_jpeg_obj));
if(NULL == jpeg_obj) {
LOGE("no mem");
pthread_mutex_unlock(&g_dec_intf_lock);
return clnt_hdl;
}
/* initialize jpeg obj */
memset(jpeg_obj, 0, sizeof(mm_jpeg_obj));
rc = mm_jpegdec_init(jpeg_obj);
if(0 != rc) {
LOGE("mm_jpeg_init err = %d", rc);
free(jpeg_obj);
pthread_mutex_unlock(&g_dec_intf_lock);
return clnt_hdl;
}
/* remember in global variable */
g_jpegdec_obj = jpeg_obj;
}
/* open new client */
clnt_hdl = mm_jpeg_new_client(g_jpegdec_obj);
if (clnt_hdl > 0) {
/* valid client */
if (NULL != ops) {
/* fill in ops tbl if ptr not NULL */
ops->start_job = mm_jpegdec_intf_start_job;
ops->abort_job = mm_jpegdec_intf_abort_job;
ops->create_session = mm_jpegdec_intf_create_session;
ops->destroy_session = mm_jpegdec_intf_destroy_session;
ops->close = mm_jpegdec_intf_close;
}
} else {
/* failed new client */
LOGE("mm_jpeg_new_client failed");
if (0 == g_jpegdec_obj->num_clients) {
/* no client, close jpeg */
mm_jpegdec_deinit(g_jpegdec_obj);
free(g_jpegdec_obj);
g_jpegdec_obj = NULL;
}
}
pthread_mutex_unlock(&g_dec_intf_lock);
return clnt_hdl;
}

View file

@ -0,0 +1,38 @@
OLD_LOCAL_PATH := $(LOCAL_PATH)
LOCAL_PATH := $(call my-dir)
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_HEADER_LIBRARIES := generated_kernel_headers
LOCAL_HEADER_LIBRARIES += libutils_headers
IMGLIB_HEADER_PATH := $(TARGET_OUT_INTERMEDIATES)/include/mm-camera/imglib
LOCAL_C_INCLUDES += \
$(IMGLIB_HEADER_PATH) \
$(LOCAL_PATH)/inc \
$(LOCAL_PATH)/../common \
$(LOCAL_PATH)/../mm-camera-interface/inc \
ifeq ($(strip $(TARGET_USES_ION)),true)
LOCAL_CFLAGS += -DUSE_ION
endif
LOCAL_SRC_FILES := \
src/mm_lib2d.c
LOCAL_MODULE := libmmlib2d_interface
LOCAL_SHARED_LIBRARIES := libdl libcutils liblog libmmcamera_interface
LOCAL_MODULE_TAGS := optional
LOCAL_VENDOR_MODULE := true
LOCAL_32_BIT_ONLY := $(BOARD_QTI_CAMERA_32BIT_ONLY)
include $(BUILD_SHARED_LIBRARY)
LOCAL_PATH := $(OLD_LOCAL_PATH)

View file

@ -0,0 +1,209 @@
/* 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_LIB2D_H_
#define MM_LIB2D_H_
#include "cam_types.h"
#ifdef QCAMERA_REDEFINE_LOG
#ifndef CAM_MODULE
#define CAM_MODULE CAM_NO_MODULE
#endif
// Camera dependencies
#include "mm_camera_dbg.h"
#endif
/** lib2d_error
* @MM_LIB2D_SUCCESS: Success
* @MM_LIB2D_ERR_GENERAL: General Error
* @MM_LIB2D_ERR_MEMORY: Insufficient memory error
* @MM_LIB2D_ERR_BAD_PARAM: Bad params error
**/
typedef enum lib2d_error_t {
MM_LIB2D_SUCCESS,
MM_LIB2D_ERR_GENERAL,
MM_LIB2D_ERR_MEMORY,
MM_LIB2D_ERR_BAD_PARAM,
} lib2d_error;
/** lib2d_mode
* @MM_LIB2D_SYNC_MODE: Synchronous mode
* @MM_LIB2D_ASYNC_MODE: Asynchronous mode
**/
typedef enum mm_lib2d_mode_t {
MM_LIB2D_SYNC_MODE,
MM_LIB2D_ASYNC_MODE,
} lib2d_mode;
/** mm_lib2d_buffer_type
* @MM_LIB2D_BUFFER_TYPE_RGB: RGB Buffer type
* @MM_LIB2D_BUFFER_TYPE_YUV: YUV buffer type
**/
typedef enum mm_lib2d_buffer_type_t {
MM_LIB2D_BUFFER_TYPE_RGB,
MM_LIB2D_BUFFER_TYPE_YUV,
} mm_lib2d_buffer_type;
/** mm_lib2d_rgb_buffer
* @fd: handle to the buffer memory
* @format: RGB color format
* @width: defines width in pixels
* @height: defines height in pixels
* @buffer: pointer to the RGB buffer
* @phys: gpu mapped physical address
* @stride: defines stride in bytes
**/
typedef struct mm_lib2d_rgb_buffer_t {
int32_t fd;
cam_format_t format;
uint32_t width;
uint32_t height;
void *buffer;
void *phys;
int32_t stride;
} mm_lib2d_rgb_buffer;
/** mm_lib2d_yuv_buffer
* @fd: handle to the buffer memory
* @format: YUV color format
* @width: defines width in pixels
* @height: defines height in pixels
* @plane0: holds the whole buffer if YUV format is not planar
* @phys0: gpu mapped physical address
* @stride0: stride in bytes
* @plane1: holds UV or VU plane for planar interleaved
* @phys2: gpu mapped physical address
* @stride1: stride in bytes
* @plane2: holds the 3. plane, ignored if YUV format is not planar
* @phys2: gpu mapped physical address
* @stride2: stride in bytes
**/
typedef struct mm_lib2d_yuv_buffer_t {
int32_t fd;
cam_format_t format;
uint32_t width;
uint32_t height;
void *plane0;
void *phys0;
int32_t stride0;
void *plane1;
void *phys1;
int32_t stride1;
void *plane2;
void *phys2;
int32_t stride2;
} mm_lib2d_yuv_buffer;
/** mm_lib2d_buffer
* @buffer_type: Buffer type. whether RGB or YUV
* @rgb_buffer: RGB buffer handle
* @yuv_buffer: YUV buffer handle
**/
typedef struct mm_lib2d_buffer_t {
mm_lib2d_buffer_type buffer_type;
union {
mm_lib2d_rgb_buffer rgb_buffer;
mm_lib2d_yuv_buffer yuv_buffer;
};
} mm_lib2d_buffer;
/** lib2d_client_cb
* @userdata: App userdata
* @jobid: job id
**/
typedef lib2d_error (*lib2d_client_cb) (void *userdata, int jobid);
/**
* Function: mm_lib2d_init
*
* Description: Initialization function for Lib2D. src_format, dst_format
* are hints to the underlying component to initialize.
*
* Input parameters:
* mode - Mode (sync/async) in which App wants lib2d to run.
* src_format - source surface format
* dst_format - Destination surface format
* my_obj - handle that will be returned on succesful Init. App has to
* call other lib2d functions by passing this handle.
*
* Return values:
* MM_LIB2D_SUCCESS
* MM_LIB2D_ERR_MEMORY
* MM_LIB2D_ERR_BAD_PARAM
* MM_LIB2D_ERR_GENERAL
*
* Notes: none
**/
lib2d_error mm_lib2d_init(lib2d_mode mode, cam_format_t src_format,
cam_format_t dst_format, void **lib2d_obj_handle);
/**
* Function: mm_lib2d_deinit
*
* Description: De-Initialization function for Lib2D
*
* Input parameters:
* lib2d_obj_handle - handle tto the lib2d object
*
* Return values:
* MM_LIB2D_SUCCESS
* MM_LIB2D_ERR_GENERAL
*
* Notes: none
**/
lib2d_error mm_lib2d_deinit(void *lib2d_obj_handle);
/**
* Function: mm_lib2d_start_job
*
* Description: Start executing the job
*
* Input parameters:
* lib2d_obj_handle - handle tto the lib2d object
* src_buffer - pointer to the source buffer
* dst_buffer - pointer to the destination buffer
* jobid - job id of this request
* userdata - userdata that will be pass through callback function
* cb - callback function that will be called on completion of this job
* rotation - rotation to be applied
*
* Return values:
* MM_LIB2D_SUCCESS
* MM_LIB2D_ERR_MEMORY
* MM_LIB2D_ERR_GENERAL
*
* Notes: none
**/
lib2d_error mm_lib2d_start_job(void *lib2d_obj_handle,
mm_lib2d_buffer* src_buffer, mm_lib2d_buffer* dst_buffer,
int jobid, void *userdata, lib2d_client_cb cb, uint32_t rotation);
#endif /* MM_LIB2D_H_ */

View file

@ -0,0 +1,609 @@
/* Copyright (c) 2015-2017, 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 <utils/Log.h>
// System dependencies
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <pthread.h>
#include <sys/ioctl.h>
#include <sys/prctl.h>
#include <sys/stat.h>
#include <sys/types.h>
// Camera dependencies
#include "img_common.h"
#include "img_comp.h"
#include "img_comp_factory.h"
#include "img_buffer.h"
#include "lib2d.h"
#include "mm_lib2d.h"
#include "img_meta.h"
/** lib2d_job_private_info
* @jobid: Job id of this process request
* @userdata: Client userdata that will be passed on callback
* @lib2d_client_cb: Application's callback function pointer
* which will be called upon completion of current job.
**/
typedef struct lib2d_job_private_info_t {
int jobid;
void *userdata;
lib2d_error (*lib2d_client_cb) (void *userdata, int jobid);
} lib2d_job_private_info;
/** img_lib_t
* @ptr: handle to imglib library
* @img_core_get_comp: function pointer for img_core_get_comp
* @img_wait_for_completion: function pointer for img_wait_for_completion
**/
typedef struct {
void *ptr;
int (*img_core_get_comp) (img_comp_role_t role, char *name,
img_core_ops_t *p_ops);
int (*img_wait_for_completion) (pthread_cond_t *p_cond,
pthread_mutex_t *p_mutex, int32_t ms);
} img_lib_t;
/** mm_lib2d_obj
* @core_ops: image core ops structure handle
* @comp: component structure handle
* @comp_mode: underlying component mode
* @lib2d_mode: lib2d mode requested by client
* @img_lib: imglib library, function ptrs handle
* @mutex: lib2d mutex used for synchronization
* @cond: librd cond used for synchronization
**/
typedef struct mm_lib2d_obj_t {
img_core_ops_t core_ops;
img_component_ops_t comp;
img_comp_mode_t comp_mode;
lib2d_mode lib2d_mode;
img_lib_t img_lib;
pthread_mutex_t mutex;
pthread_cond_t cond;
} mm_lib2d_obj;
/**
* Function: lib2d_event_handler
*
* Description: Event handler. All the component events
* are received here.
*
* Input parameters:
* p_appdata - lib2d test object
* p_event - pointer to the event
*
* Return values:
* IMG_SUCCESS
* IMG_ERR_INVALID_INPUT
*
* Notes: none
**/
int lib2d_event_handler(void* p_appdata, img_event_t *p_event)
{
mm_lib2d_obj *lib2d_obj = (mm_lib2d_obj *)p_appdata;
if ((NULL == p_event) || (NULL == p_appdata)) {
LOGE("invalid event");
return IMG_ERR_INVALID_INPUT;
}
LOGD("type %d", p_event->type);
switch (p_event->type) {
case QIMG_EVT_DONE:
pthread_cond_signal(&lib2d_obj->cond);
break;
default:;
}
return IMG_SUCCESS;
}
/**
* Function: lib2d_callback_handler
*
* Description: Callback handler. Registered with Component
* on IMG_COMP_INIT. Will be called when processing
* of current request is completed. If component running in
* async mode, this is where client will know the execution
* is finished for in, out frames.
*
* Input parameters:
* p_appdata - lib2d test object
* p_in_frame - pointer to input frame
* p_out_frame - pointer to output frame
* p_meta - pointer to meta data
*
* Return values:
* IMG_SUCCESS
* IMG_ERR_GENERAL
*
* Notes: none
**/
int lib2d_callback_handler(void *userdata, img_frame_t *p_in_frame,
img_frame_t *p_out_frame, img_meta_t *p_meta)
{
lib2d_job_private_info *job_info = NULL;
if (NULL == userdata) {
LOGE("invalid event");
return IMG_ERR_INVALID_INPUT;
}
// assert(p_in_frame->private_data == p_out_frame->private_data);
job_info = (lib2d_job_private_info *)p_in_frame->private_data;
if (job_info->lib2d_client_cb != NULL) {
job_info->lib2d_client_cb(job_info->userdata, job_info->jobid);
}
free(p_in_frame->private_data);
free(p_in_frame);
free(p_out_frame);
free(p_meta);
return IMG_SUCCESS;
}
/**
* Function: lib2d_fill_img_frame
*
* Description: Setup img_frame_t for given buffer
*
* Input parameters:
* p_frame - pointer to img_frame_t that needs to be setup
* lib2d_buffer - pointer to input buffer
* jobid - job id
*
* Return values:
* MM_LIB2D_SUCCESS
* MM_LIB2D_ERR_GENERAL
*
* Notes: none
**/
lib2d_error lib2d_fill_img_frame(img_frame_t *p_frame,
mm_lib2d_buffer* lib2d_buffer, int jobid)
{
// use job id for now
p_frame->frame_cnt = jobid;
p_frame->idx = jobid;
p_frame->frame_id = jobid;
if (lib2d_buffer->buffer_type == MM_LIB2D_BUFFER_TYPE_RGB) {
mm_lib2d_rgb_buffer *rgb_buffer = &lib2d_buffer->rgb_buffer;
p_frame->info.num_planes = 1;
p_frame->info.width = rgb_buffer->width;
p_frame->info.height = rgb_buffer->height;
p_frame->frame[0].plane_cnt = 1;
p_frame->frame[0].plane[0].plane_type = PLANE_ARGB;
p_frame->frame[0].plane[0].addr = rgb_buffer->buffer;
p_frame->frame[0].plane[0].stride = rgb_buffer->stride;
p_frame->frame[0].plane[0].length = (rgb_buffer->stride *
rgb_buffer->height);
p_frame->frame[0].plane[0].fd = rgb_buffer->fd;
p_frame->frame[0].plane[0].height = rgb_buffer->height;
p_frame->frame[0].plane[0].width = rgb_buffer->width;
p_frame->frame[0].plane[0].offset = 0;
p_frame->frame[0].plane[0].scanline = rgb_buffer->height;
} else if (lib2d_buffer->buffer_type == MM_LIB2D_BUFFER_TYPE_YUV) {
mm_lib2d_yuv_buffer *yuv_buffer = &lib2d_buffer->yuv_buffer;
p_frame->info.num_planes = 2;
p_frame->info.width = yuv_buffer->width;
p_frame->info.height = yuv_buffer->height;
p_frame->frame[0].plane_cnt = 2;
p_frame->frame[0].plane[0].plane_type = PLANE_Y;
p_frame->frame[0].plane[0].addr = yuv_buffer->plane0;
p_frame->frame[0].plane[0].stride = yuv_buffer->stride0;
p_frame->frame[0].plane[0].length = (yuv_buffer->stride0 *
yuv_buffer->height);
p_frame->frame[0].plane[0].fd = yuv_buffer->fd;
p_frame->frame[0].plane[0].height = yuv_buffer->height;
p_frame->frame[0].plane[0].width = yuv_buffer->width;
p_frame->frame[0].plane[0].offset = 0;
p_frame->frame[0].plane[0].scanline = yuv_buffer->height;
if (yuv_buffer->format == CAM_FORMAT_YUV_420_NV12) {
p_frame->frame[0].plane[1].plane_type = PLANE_CB_CR;
} else if(yuv_buffer->format == CAM_FORMAT_YUV_420_NV21) {
p_frame->frame[0].plane[1].plane_type = PLANE_CR_CB;
}
p_frame->frame[0].plane[1].addr = yuv_buffer->plane1;
p_frame->frame[0].plane[1].stride = yuv_buffer->stride1;
p_frame->frame[0].plane[1].length = (yuv_buffer->stride1 *
yuv_buffer->height / 2);
p_frame->frame[0].plane[1].fd = yuv_buffer->fd;
p_frame->frame[0].plane[1].height = yuv_buffer->height;
p_frame->frame[0].plane[1].width = yuv_buffer->width;
p_frame->frame[0].plane[1].offset = 0;
p_frame->frame[0].plane[1].scanline = yuv_buffer->height;
} else {
return MM_LIB2D_ERR_GENERAL;
}
return MM_LIB2D_SUCCESS;
}
/**
* Function: mm_lib2d_init
*
* Description: Initialization function for Lib2D. src_format, dst_format
* are hints to the underlying component to initialize.
*
* Input parameters:
* mode - Mode (sync/async) in which App wants lib2d to run.
* src_format - source surface format
* dst_format - Destination surface format
* my_obj - handle that will be returned on succesful Init. App has to
* call other lib2d functions by passing this handle.
*
* Return values:
* MM_LIB2D_SUCCESS
* MM_LIB2D_ERR_MEMORY
* MM_LIB2D_ERR_BAD_PARAM
* MM_LIB2D_ERR_GENERAL
*
* Notes: none
**/
lib2d_error mm_lib2d_init(lib2d_mode mode, cam_format_t src_format,
cam_format_t dst_format, void **my_obj)
{
int32_t rc = IMG_SUCCESS;
mm_lib2d_obj *lib2d_obj = NULL;
img_core_ops_t *p_core_ops = NULL;
img_component_ops_t *p_comp = NULL;
pthread_condattr_t cond_attr;
if (my_obj == NULL) {
return MM_LIB2D_ERR_BAD_PARAM;
}
// validate src_format, dst_format to check whether we support these.
// Currently support NV21 to ARGB conversions only. Others not tested.
if ((src_format != CAM_FORMAT_YUV_420_NV21) ||
(dst_format != CAM_FORMAT_8888_ARGB)) {
LOGE("Formats conversion from %d to %d not supported",
src_format, dst_format);
}
lib2d_obj = malloc(sizeof(mm_lib2d_obj));
if (lib2d_obj == NULL) {
return MM_LIB2D_ERR_MEMORY;
}
// Open libmmcamera_imglib
lib2d_obj->img_lib.ptr = dlopen("libmmcamera_imglib.so", RTLD_NOW);
if (!lib2d_obj->img_lib.ptr) {
LOGE("ERROR: couldn't dlopen libmmcamera_imglib.so: %s",
dlerror());
goto FREE_LIB2D_OBJ;
}
/* Get function pointer for functions supported by C2D */
*(void **)&lib2d_obj->img_lib.img_core_get_comp =
dlsym(lib2d_obj->img_lib.ptr, "img_core_get_comp");
*(void **)&lib2d_obj->img_lib.img_wait_for_completion =
dlsym(lib2d_obj->img_lib.ptr, "img_wait_for_completion");
/* Validate function pointers */
if ((lib2d_obj->img_lib.img_core_get_comp == NULL) ||
(lib2d_obj->img_lib.img_wait_for_completion == NULL)) {
LOGE(" ERROR mapping symbols from libc2d2.so");
goto FREE_LIB2D_OBJ;
}
p_core_ops = &lib2d_obj->core_ops;
p_comp = &lib2d_obj->comp;
pthread_condattr_init(&cond_attr);
pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);
pthread_mutex_init(&lib2d_obj->mutex, NULL);
pthread_cond_init(&lib2d_obj->cond, &cond_attr);
pthread_condattr_destroy(&cond_attr);
rc = lib2d_obj->img_lib.img_core_get_comp(IMG_COMP_LIB2D,
"qti.lib2d", p_core_ops);
if (rc != IMG_SUCCESS) {
LOGE("rc %d", rc);
goto FREE_LIB2D_OBJ;
}
rc = IMG_COMP_LOAD(p_core_ops, NULL);
if (rc != IMG_SUCCESS) {
LOGE("rc %d", rc);
goto FREE_LIB2D_OBJ;
}
rc = IMG_COMP_CREATE(p_core_ops, p_comp);
if (rc != IMG_SUCCESS) {
LOGE("rc %d", rc);
goto COMP_UNLOAD;
}
rc = IMG_COMP_INIT(p_comp, (void *)lib2d_obj, lib2d_callback_handler);
if (rc != IMG_SUCCESS) {
LOGE("rc %d", rc);
goto COMP_UNLOAD;
}
rc = IMG_COMP_SET_CB(p_comp, lib2d_event_handler);
if (rc != IMG_SUCCESS) {
LOGE("rc %d", rc);
goto COMP_DEINIT;
}
lib2d_obj->lib2d_mode = mode;
img_comp_mode_t comp_mode;
if (lib2d_obj->lib2d_mode == MM_LIB2D_SYNC_MODE) {
comp_mode = IMG_SYNC_MODE;
} else {
comp_mode = IMG_ASYNC_MODE;
}
// Set source format
rc = IMG_COMP_SET_PARAM(p_comp, QLIB2D_SOURCE_FORMAT, (void *)&src_format);
if (rc != IMG_SUCCESS) {
LOGE("rc %d", rc);
goto COMP_DEINIT;
}
// Set destination format
rc = IMG_COMP_SET_PARAM(p_comp, QLIB2D_DESTINATION_FORMAT,
(void *)&dst_format);
if (rc != IMG_SUCCESS) {
LOGE("rc %d", rc);
goto COMP_DEINIT;
}
// Try setting the required mode.
rc = IMG_COMP_SET_PARAM(p_comp, QIMG_PARAM_MODE, (void *)&comp_mode);
if (rc != IMG_SUCCESS) {
LOGE("rc %d", rc);
goto COMP_DEINIT;
}
// Get the mode to make sure whether the component is really running
// in the mode what we set.
rc = IMG_COMP_GET_PARAM(p_comp, QIMG_PARAM_MODE,
(void *)&lib2d_obj->comp_mode);
if (rc != IMG_SUCCESS) {
LOGE("rc %d", rc);
goto COMP_DEINIT;
}
if (comp_mode != lib2d_obj->comp_mode) {
LOGD("Component is running in %d mode",
lib2d_obj->comp_mode);
}
*my_obj = (void *)lib2d_obj;
return MM_LIB2D_SUCCESS;
COMP_DEINIT :
rc = IMG_COMP_DEINIT(p_comp);
if (rc != IMG_SUCCESS) {
LOGE("rc %d", rc);
return MM_LIB2D_ERR_GENERAL;
}
COMP_UNLOAD :
rc = IMG_COMP_UNLOAD(p_core_ops);
if (rc != IMG_SUCCESS) {
LOGE("rc %d", rc);
return MM_LIB2D_ERR_GENERAL;
}
FREE_LIB2D_OBJ :
free(lib2d_obj);
return MM_LIB2D_ERR_GENERAL;
}
/**
* Function: mm_lib2d_deinit
*
* Description: De-Initialization function for Lib2D
*
* Input parameters:
* lib2d_obj_handle - handle tto the lib2d object
*
* Return values:
* MM_LIB2D_SUCCESS
* MM_LIB2D_ERR_GENERAL
*
* Notes: none
**/
lib2d_error mm_lib2d_deinit(void *lib2d_obj_handle)
{
mm_lib2d_obj *lib2d_obj = (mm_lib2d_obj *)lib2d_obj_handle;
int rc = IMG_SUCCESS;
img_core_ops_t *p_core_ops = &lib2d_obj->core_ops;
img_component_ops_t *p_comp = &lib2d_obj->comp;
rc = IMG_COMP_DEINIT(p_comp);
if (rc != IMG_SUCCESS) {
LOGE("rc %d", rc);
return MM_LIB2D_ERR_GENERAL;
}
rc = IMG_COMP_UNLOAD(p_core_ops);
if (rc != IMG_SUCCESS) {
LOGE("rc %d", rc);
return MM_LIB2D_ERR_GENERAL;
}
dlclose(lib2d_obj->img_lib.ptr);
free(lib2d_obj);
return MM_LIB2D_SUCCESS;
}
/**
* Function: mm_lib2d_start_job
*
* Description: Start executing the job
*
* Input parameters:
* lib2d_obj_handle - handle tto the lib2d object
* src_buffer - pointer to the source buffer
* dst_buffer - pointer to the destination buffer
* jobid - job id of this request
* userdata - userdata that will be pass through callback function
* cb - callback function that will be called on completion of this job
* rotation - rotation to be applied
*
* Return values:
* MM_LIB2D_SUCCESS
* MM_LIB2D_ERR_MEMORY
* MM_LIB2D_ERR_GENERAL
*
* Notes: none
**/
lib2d_error mm_lib2d_start_job(void *lib2d_obj_handle,
mm_lib2d_buffer* src_buffer, mm_lib2d_buffer* dst_buffer,
int jobid, void *userdata, lib2d_client_cb cb, uint32_t rotation)
{
mm_lib2d_obj *lib2d_obj = (mm_lib2d_obj *)lib2d_obj_handle;
int rc = IMG_SUCCESS;
img_component_ops_t *p_comp = &lib2d_obj->comp;
img_frame_t *p_in_frame = malloc(sizeof(img_frame_t));
if (p_in_frame == NULL) {
return MM_LIB2D_ERR_MEMORY;
}
img_frame_t *p_out_frame = malloc(sizeof(img_frame_t));
if (p_out_frame == NULL) {
free(p_in_frame);
return MM_LIB2D_ERR_MEMORY;
}
img_meta_t *p_meta = malloc(sizeof(img_meta_t));
if (p_meta == NULL) {
free(p_in_frame);
free(p_out_frame);
return MM_LIB2D_ERR_MEMORY;
}
lib2d_job_private_info *p_job_info = malloc(sizeof(lib2d_job_private_info));
if (p_out_frame == NULL) {
free(p_in_frame);
free(p_out_frame);
free(p_meta);
return MM_LIB2D_ERR_MEMORY;
}
memset(p_in_frame, 0x0, sizeof(img_frame_t));
memset(p_out_frame, 0x0, sizeof(img_frame_t));
memset(p_meta, 0x0, sizeof(img_meta_t));
memset(p_job_info, 0x0, sizeof(lib2d_job_private_info));
// Fill up job info private data structure that can be used in callback to
// inform back to the client.
p_job_info->jobid = jobid;
p_job_info->userdata = userdata;
p_job_info->lib2d_client_cb = cb;
p_in_frame->private_data = (void *)p_job_info;
p_out_frame->private_data = (void *)p_job_info;
// convert the input info into component understandble data structures
// Prepare Input, output frames
lib2d_fill_img_frame(p_in_frame, src_buffer, jobid);
lib2d_fill_img_frame(p_out_frame, dst_buffer, jobid);
p_meta->frame_id = jobid;
p_meta->rotation.device_rotation = (int32_t)rotation;
p_meta->rotation.frame_rotation = (int32_t)rotation;
// call set_param to set the source, destination formats
rc = IMG_COMP_Q_BUF(p_comp, p_in_frame, IMG_IN);
if (rc != IMG_SUCCESS) {
LOGE("rc %d", rc);
goto ERROR;
}
rc = IMG_COMP_Q_BUF(p_comp, p_out_frame, IMG_OUT);
if (rc != IMG_SUCCESS) {
LOGE("rc %d", rc);
goto ERROR;
}
rc = IMG_COMP_Q_META_BUF(p_comp, p_meta);
if (rc != IMG_SUCCESS) {
LOGE("rc %d", rc);
goto ERROR;
}
rc = IMG_COMP_START(p_comp, NULL);
if (rc != IMG_SUCCESS) {
LOGE("rc %d", rc);
goto ERROR;
}
if (lib2d_obj->lib2d_mode == MM_LIB2D_SYNC_MODE) {
if (lib2d_obj->comp_mode == IMG_ASYNC_MODE) {
LOGD("before wait rc %d", rc);
rc = lib2d_obj->img_lib.img_wait_for_completion(&lib2d_obj->cond,
&lib2d_obj->mutex, 10000);
if (rc != IMG_SUCCESS) {
LOGE("rc %d", rc);
goto ERROR;
}
}
}
rc = IMG_COMP_ABORT(p_comp, NULL);
if (IMG_ERROR(rc)) {
LOGE("comp abort failed %d", rc);
return rc;
}
return MM_LIB2D_SUCCESS;
ERROR:
free(p_in_frame);
free(p_out_frame);
free(p_meta);
free(p_job_info);
return MM_LIB2D_ERR_GENERAL;
}

View file

@ -0,0 +1,246 @@
/* 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 LOG_TAG "QCameraBufferMaps"
// System dependencies
#include <utils/Errors.h>
#include <stdlib.h>
#include <string.h>
// Camera dependencies
#include "QCameraBufferMaps.h"
using namespace android;
namespace qcamera {
/*===========================================================================
* FUNCTION : QCameraBufferMaps
*
* DESCRIPTION: default constructor of QCameraBufferMaps
*
* PARAMETERS : None
*
* RETURN : None
*==========================================================================*/
QCameraBufferMaps::QCameraBufferMaps()
{
memset(&mBufMapList, 0, sizeof(mBufMapList));
}
/*===========================================================================
* FUNCTION : QCameraBufferMaps
*
* DESCRIPTION: copy constructor of QCameraBufferMaps
*
* PARAMETERS :
* @pBufferMaps : object to be copied
*
* RETURN : None
*==========================================================================*/
QCameraBufferMaps::QCameraBufferMaps(const QCameraBufferMaps& pBufferMaps)
{
memcpy(&mBufMapList, &pBufferMaps.mBufMapList, sizeof(mBufMapList));
}
/*===========================================================================
* FUNCTION : QCameraBufferMaps
*
* DESCRIPTION: constructor of QCameraBufferMaps
*
* PARAMETERS :
* @pBufMapList : list of buffer maps
*
* RETURN : None
*==========================================================================*/
QCameraBufferMaps::QCameraBufferMaps(const cam_buf_map_type_list& pBufMapList)
{
memcpy(&mBufMapList, &pBufMapList, sizeof(mBufMapList));
}
/*===========================================================================
* FUNCTION : QCameraBufferMaps
*
* DESCRIPTION: constructor of QCameraBufferMaps
*
* PARAMETERS :
* @pType : Type of buffer
* @pStreamId : Stream id
* @pFrameIndex : Frame index
* @pPlaneIndex : Plane index
* @pCookie : Could be job_id to identify mapping job
* @pFd : Origin file descriptor
* @pSize : Size of the buffer
*
* RETURN : None
*==========================================================================*/
QCameraBufferMaps::QCameraBufferMaps(cam_mapping_buf_type pType,
uint32_t pStreamId,
uint32_t pFrameIndex,
int32_t pPlaneIndex,
uint32_t pCookie,
int32_t pFd,
size_t pSize)
{
memset(&mBufMapList, 0, sizeof(mBufMapList));
enqueue(pType, pStreamId, pFrameIndex, pPlaneIndex, pCookie, pFd, pSize);
}
/*===========================================================================
* FUNCTION : ~QCameraBufferMaps
*
* DESCRIPTION: destructor of QCameraBufferMaps
*
* PARAMETERS : None
*
* RETURN : None
*==========================================================================*/
QCameraBufferMaps::~QCameraBufferMaps()
{
}
/*===========================================================================
* FUNCTION : operator=
*
* DESCRIPTION: assignment operator of QCameraBufferMaps
*
* PARAMETERS :
* @pBufferMaps : object to be copied
*
* RETURN : *this, with updated contents
*==========================================================================*/
QCameraBufferMaps& QCameraBufferMaps::operator=(const QCameraBufferMaps& pBufferMaps)
{
if (&pBufferMaps != this) {
memcpy(&mBufMapList, &pBufferMaps.mBufMapList, sizeof(mBufMapList));
}
return *this;
}
/*===========================================================================
* FUNCTION : enqueue
*
* DESCRIPTION: Add a buffer map
*
* PARAMETERS :
* @pType : Type of buffer
* @pStreamId : Stream id
* @pFrameIndex : Frame index
* @pPlaneIndex : Plane index
* @pCookie : Could be job_id to identify mapping job
* @pFd : Origin file descriptor
* @pSize : Size of the buffer
*
* RETURN : int32_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
uint32_t QCameraBufferMaps::enqueue(cam_mapping_buf_type pType,
uint32_t pStreamId,
uint32_t pFrameIndex,
int32_t pPlaneIndex,
uint32_t pCookie,
int32_t pFd,
size_t pSize)
{
uint32_t pos = mBufMapList.length++;
mBufMapList.buf_maps[pos].type = pType;
mBufMapList.buf_maps[pos].stream_id = pStreamId;
mBufMapList.buf_maps[pos].frame_idx = pFrameIndex;
mBufMapList.buf_maps[pos].plane_idx = pPlaneIndex;
mBufMapList.buf_maps[pos].cookie = pCookie;
mBufMapList.buf_maps[pos].fd = pFd;
mBufMapList.buf_maps[pos].size = pSize;
return NO_ERROR;
}
/*===========================================================================
* FUNCTION : getCamBufMapList
*
* DESCRIPTION: Populate the list
*
* PARAMETERS :
* @pBufMapList : [output] the list of buffer maps
*
* RETURN : int32_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
uint32_t QCameraBufferMaps::getCamBufMapList(cam_buf_map_type_list& pBufMapList) const
{
memcpy(&pBufMapList, &mBufMapList, sizeof(pBufMapList));
return NO_ERROR;
}
/*===========================================================================
* FUNCTION : makeSingletonBufMapList
*
* DESCRIPTION: Create a buffer map list of a single element
*
* PARAMETERS :
* @pType : Type of buffer
* @pStreamId : Stream id
* @pFrameIndex : Frame index
* @pPlaneIndex : Plane index
* @pCookie : Could be job_id to identify mapping job
* @pFd : Origin file descriptor
* @pSize : Size of the buffer
* @pBufMapList : [output] the list of buffer maps
*
* RETURN : int32_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
uint32_t QCameraBufferMaps::makeSingletonBufMapList(cam_mapping_buf_type pType,
uint32_t pStreamId,
uint32_t pFrameIndex,
int32_t pPlaneIndex,
uint32_t pCookie,
int32_t pFd,
size_t pSize,
cam_buf_map_type_list& pBufMapList)
{
uint32_t rc = NO_ERROR;
QCameraBufferMaps bufferMaps(pType,
pStreamId,
pFrameIndex,
pPlaneIndex,
pCookie,
pFd,
pSize);
rc = bufferMaps.getCamBufMapList(pBufMapList);
return rc;
}
}; // namespace qcamera

View file

@ -0,0 +1,80 @@
/* 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 __QCAMERA_BUFFERMAPS_H__
#define __QCAMERA_BUFFERMAPS_H__
// Camera dependencies
#include "cam_types.h"
namespace qcamera {
class QCameraBufferMaps {
public:
QCameraBufferMaps();
QCameraBufferMaps(const QCameraBufferMaps& pBufferMaps);
QCameraBufferMaps(const cam_buf_map_type_list& pBufMapList);
QCameraBufferMaps(cam_mapping_buf_type pType,
uint32_t pStreamId,
uint32_t pFrameIndex,
int32_t pPlaneIndex,
uint32_t pCookie,
int32_t pFd,
size_t pSize);
~QCameraBufferMaps();
QCameraBufferMaps& operator=(const QCameraBufferMaps& pBufferMaps);
uint32_t enqueue(cam_mapping_buf_type pType,
uint32_t pStreamId,
uint32_t pFrameIndex,
int32_t pPlaneIndex,
uint32_t pCookie,
int32_t pFd,
size_t pSize);
uint32_t getCamBufMapList(cam_buf_map_type_list& pBufMapList) const;
static uint32_t makeSingletonBufMapList(cam_mapping_buf_type pType,
uint32_t pStreamId,
uint32_t pFrameIndex,
int32_t pPlaneIndex,
uint32_t pCookie,
int32_t pFd,
size_t pSize,
cam_buf_map_type_list& pBufMapList);
private:
cam_buf_map_type_list mBufMapList;
};
}; // namespace qcamera
#endif /* __QCAMERA_BUFFERMAPS_H__ */

View file

@ -0,0 +1,225 @@
/* 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 <string.h>
#include <utils/Errors.h>
#define PRCTL_H <SYSTEM_HEADER_PREFIX/prctl.h>
#include PRCTL_H
// Camera dependencies
#include "QCameraCmdThread.h"
extern "C" {
#include "mm_camera_dbg.h"
}
using namespace android;
namespace qcamera {
/*===========================================================================
* FUNCTION : QCameraCmdThread
*
* DESCRIPTION: default constructor of QCameraCmdThread
*
* PARAMETERS : None
*
* RETURN : None
*==========================================================================*/
QCameraCmdThread::QCameraCmdThread() :
cmd_queue()
{
cmd_pid = 0;
cam_sem_init(&sync_sem, 0);
cam_sem_init(&cmd_sem, 0);
}
/*===========================================================================
* FUNCTION : ~QCameraCmdThread
*
* DESCRIPTION: deconstructor of QCameraCmdThread
*
* PARAMETERS : None
*
* RETURN : None
*==========================================================================*/
QCameraCmdThread::~QCameraCmdThread()
{
exit();
cam_sem_destroy(&sync_sem);
cam_sem_destroy(&cmd_sem);
}
/*===========================================================================
* FUNCTION : launch
*
* DESCRIPTION: launch Cmd Thread
*
* PARAMETERS :
* @start_routine : thread routine function ptr
* @user_data : user data ptr
*
* RETURN : int32_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
int32_t QCameraCmdThread::launch(void *(*start_routine)(void *),
void* user_data)
{
/* launch the thread */
pthread_create(&cmd_pid,
NULL,
start_routine,
user_data);
return NO_ERROR;
}
/*===========================================================================
* FUNCTION : setName
*
* DESCRIPTION: name the cmd thread
*
* PARAMETERS :
* @name : desired name for the thread
*
* RETURN : int32_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
int32_t QCameraCmdThread::setName(const char* name)
{
/* name the thread */
prctl(PR_SET_NAME, (unsigned long)name, 0, 0, 0);
return NO_ERROR;
}
/*===========================================================================
* FUNCTION : sendCmd
*
* DESCRIPTION: send a command to the Cmd Thread
*
* PARAMETERS :
* @cmd : command to be executed.
* @sync_cmd: flag to indicate if this is a synchorinzed cmd. If true, this call
* will wait until signal is set after the command is completed.
* @priority: flag to indicate if this is a cmd with priority. If true, the cmd
* will be enqueued to the head with priority.
*
* RETURN : int32_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
int32_t QCameraCmdThread::sendCmd(camera_cmd_type_t cmd, uint8_t sync_cmd, uint8_t priority)
{
camera_cmd_t *node = (camera_cmd_t *)malloc(sizeof(camera_cmd_t));
if (NULL == node) {
LOGE("No memory for camera_cmd_t");
return NO_MEMORY;
}
memset(node, 0, sizeof(camera_cmd_t));
node->cmd = cmd;
if (priority) {
if (!cmd_queue.enqueueWithPriority((void *)node)) {
free(node);
node = NULL;
}
} else {
if (!cmd_queue.enqueue((void *)node)) {
free(node);
node = NULL;
}
}
cam_sem_post(&cmd_sem);
/* if is a sync call, need to wait until it returns */
if (sync_cmd) {
cam_sem_wait(&sync_sem);
}
return NO_ERROR;
}
/*===========================================================================
* FUNCTION : getCmd
*
* DESCRIPTION: dequeue a cmommand from cmd queue
*
* PARAMETERS : None
*
* RETURN : cmd dequeued
*==========================================================================*/
camera_cmd_type_t QCameraCmdThread::getCmd()
{
camera_cmd_type_t cmd = CAMERA_CMD_TYPE_NONE;
camera_cmd_t *node = (camera_cmd_t *)cmd_queue.dequeue();
if (NULL == node) {
LOGD("No notify avail");
return CAMERA_CMD_TYPE_NONE;
} else {
cmd = node->cmd;
free(node);
}
return cmd;
}
/*===========================================================================
* FUNCTION : exit
*
* DESCRIPTION: exit the CMD thread
*
* PARAMETERS : None
*
* RETURN : int32_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
int32_t QCameraCmdThread::exit()
{
int32_t rc = NO_ERROR;
if (cmd_pid == 0) {
return rc;
}
rc = sendCmd(CAMERA_CMD_TYPE_EXIT, 0, 1);
if (NO_ERROR != rc) {
LOGE("Error during exit, rc = %d", rc);
return rc;
}
/* wait until cmd thread exits */
if (pthread_join(cmd_pid, NULL) != 0) {
LOGD("pthread dead already\n");
}
cmd_pid = 0;
return rc;
}
}; // namespace qcamera

View file

@ -0,0 +1,77 @@
/* 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_CMD_THREAD_H__
#define __QCAMERA_CMD_THREAD_H__
// System dependencies
#include <pthread.h>
// Camera dependencies
#include "cam_semaphore.h"
#include "cam_types.h"
#include "QCameraQueue.h"
namespace qcamera {
typedef enum
{
CAMERA_CMD_TYPE_NONE,
CAMERA_CMD_TYPE_START_DATA_PROC,
CAMERA_CMD_TYPE_STOP_DATA_PROC,
CAMERA_CMD_TYPE_DO_NEXT_JOB,
CAMERA_CMD_TYPE_EXIT,
CAMERA_CMD_TYPE_TIMEOUT,
CAMERA_CMD_TYPE_MAX
} camera_cmd_type_t;
typedef struct {
camera_cmd_type_t cmd;
} camera_cmd_t;
class QCameraCmdThread {
public:
QCameraCmdThread();
~QCameraCmdThread();
int32_t launch(void *(*start_routine)(void *), void* user_data);
int32_t setName(const char* name);
int32_t exit();
int32_t sendCmd(camera_cmd_type_t cmd, uint8_t sync_cmd, uint8_t priority);
camera_cmd_type_t getCmd();
QCameraQueue cmd_queue; /* cmd queue */
pthread_t cmd_pid; /* cmd thread ID */
cam_semaphore_t cmd_sem; /* semaphore for cmd thread */
cam_semaphore_t sync_sem; /* semaphore for synchronized call signal */
};
}; // namespace qcamera
#endif /* __QCAMERA_CMD_THREAD_H__ */

View file

@ -0,0 +1,257 @@
/* 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.
*
*/
#define LOG_TAG "QCameraCommon"
// System dependencies
#include <utils/Errors.h>
#include <stdlib.h>
#include <string.h>
#include <utils/Log.h>
// Camera dependencies
#include "QCameraCommon.h"
using namespace android;
namespace qcamera {
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
/*===========================================================================
* FUNCTION : QCameraCommon
*
* DESCRIPTION: default constructor of QCameraCommon
*
* PARAMETERS : None
*
* RETURN : None
*==========================================================================*/
QCameraCommon::QCameraCommon() :
m_pCapability(NULL)
{
}
/*===========================================================================
* FUNCTION : ~QCameraCommon
*
* DESCRIPTION: destructor of QCameraCommon
*
* PARAMETERS : None
*
* RETURN : None
*==========================================================================*/
QCameraCommon::~QCameraCommon()
{
}
/*===========================================================================
* FUNCTION : init
*
* DESCRIPTION: Init function for QCameraCommon
*
* PARAMETERS :
* @pCapability : Capabilities
*
* RETURN : int32_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
int32_t QCameraCommon::init(cam_capability_t *pCapability)
{
m_pCapability = pCapability;
return NO_ERROR;
}
/*===========================================================================
* FUNCTION : calculateLCM
*
* DESCRIPTION: Get the LCM of 2 numbers
*
* PARAMETERS :
* @num1 : First number
* @num2 : second number
*
* RETURN : int32_t type (LCM)
*
*==========================================================================*/
uint32_t QCameraCommon::calculateLCM(int32_t num1, int32_t num2)
{
uint32_t lcm = 0;
uint32_t temp = 0;
if ((num1 < 1) && (num2 < 1)) {
return 0;
} else if (num1 < 1) {
return num2;
} else if (num2 < 1) {
return num1;
}
if (num1 > num2) {
lcm = num1;
} else {
lcm = num2;
}
temp = lcm;
while (1) {
if (((lcm % num1) == 0) && ((lcm % num2) == 0)) {
break;
}
lcm += temp;
}
return lcm;
}
/*===========================================================================
* FUNCTION : getAnalysisInfo
*
* DESCRIPTION: Get the Analysis information based on
* current mode and feature mask
*
* PARAMETERS :
* @fdVideoEnabled : Whether fdVideo enabled currently
* @hal3 : Whether hal3 or hal1
* @featureMask : Feature mask
* @pAnalysis_info : Analysis info to be filled
*
* RETURN : int32_t type of status
* NO_ERROR -- success
* none-zero failure code
*==========================================================================*/
int32_t QCameraCommon::getAnalysisInfo(
bool fdVideoEnabled,
bool hal3,
cam_feature_mask_t featureMask,
cam_analysis_info_t *pAnalysisInfo)
{
if (!pAnalysisInfo) {
return BAD_VALUE;
}
pAnalysisInfo->valid = 0;
if ((fdVideoEnabled == TRUE) && (hal3 == FALSE) &&
(m_pCapability->analysis_info[CAM_ANALYSIS_INFO_FD_VIDEO].hw_analysis_supported) &&
(m_pCapability->analysis_info[CAM_ANALYSIS_INFO_FD_VIDEO].valid)) {
*pAnalysisInfo =
m_pCapability->analysis_info[CAM_ANALYSIS_INFO_FD_VIDEO];
} else if (m_pCapability->analysis_info[CAM_ANALYSIS_INFO_FD_STILL].valid) {
*pAnalysisInfo =
m_pCapability->analysis_info[CAM_ANALYSIS_INFO_FD_STILL];
if (hal3 == TRUE) {
pAnalysisInfo->analysis_max_res = pAnalysisInfo->analysis_recommended_res;
}
}
if ((featureMask & CAM_QCOM_FEATURE_PAAF) &&
(m_pCapability->analysis_info[CAM_ANALYSIS_INFO_PAAF].valid)) {
cam_analysis_info_t *pPaafInfo =
&m_pCapability->analysis_info[CAM_ANALYSIS_INFO_PAAF];
if (!pAnalysisInfo->valid) {
*pAnalysisInfo = *pPaafInfo;
} else {
pAnalysisInfo->analysis_max_res.width =
MAX(pAnalysisInfo->analysis_max_res.width,
pPaafInfo->analysis_max_res.width);
pAnalysisInfo->analysis_max_res.height =
MAX(pAnalysisInfo->analysis_max_res.height,
pPaafInfo->analysis_max_res.height);
pAnalysisInfo->analysis_padding_info.height_padding =
calculateLCM(pAnalysisInfo->analysis_padding_info.height_padding,
pPaafInfo->analysis_padding_info.height_padding);
pAnalysisInfo->analysis_padding_info.width_padding =
calculateLCM(pAnalysisInfo->analysis_padding_info.width_padding,
pPaafInfo->analysis_padding_info.width_padding);
pAnalysisInfo->analysis_padding_info.plane_padding =
calculateLCM(pAnalysisInfo->analysis_padding_info.plane_padding,
pPaafInfo->analysis_padding_info.plane_padding);
pAnalysisInfo->analysis_padding_info.min_stride =
MAX(pAnalysisInfo->analysis_padding_info.min_stride,
pPaafInfo->analysis_padding_info.min_stride);
pAnalysisInfo->analysis_padding_info.min_stride =
ALIGN(pAnalysisInfo->analysis_padding_info.min_stride,
pAnalysisInfo->analysis_padding_info.width_padding);
pAnalysisInfo->analysis_padding_info.min_scanline =
MAX(pAnalysisInfo->analysis_padding_info.min_scanline,
pPaafInfo->analysis_padding_info.min_scanline);
pAnalysisInfo->analysis_padding_info.min_scanline =
ALIGN(pAnalysisInfo->analysis_padding_info.min_scanline,
pAnalysisInfo->analysis_padding_info.height_padding);
pAnalysisInfo->hw_analysis_supported |=
pPaafInfo->hw_analysis_supported;
}
}
return pAnalysisInfo->valid ? NO_ERROR : BAD_VALUE;
}
/*===========================================================================
* FUNCTION : getBootToMonoTimeOffset
*
* DESCRIPTION: Calculate offset that is used to convert from
* clock domain of boot to monotonic
*
* PARAMETERS :
* None
*
* RETURN : clock offset between boottime and monotonic time.
*
*==========================================================================*/
nsecs_t QCameraCommon::getBootToMonoTimeOffset()
{
// try three times to get the clock offset, choose the one
// with the minimum gap in measurements.
const int tries = 3;
nsecs_t bestGap, measured;
for (int i = 0; i < tries; ++i) {
const nsecs_t tmono = systemTime(SYSTEM_TIME_MONOTONIC);
const nsecs_t tbase = systemTime(SYSTEM_TIME_BOOTTIME);
const nsecs_t tmono2 = systemTime(SYSTEM_TIME_MONOTONIC);
const nsecs_t gap = tmono2 - tmono;
if (i == 0 || gap < bestGap) {
bestGap = gap;
measured = tbase - ((tmono + tmono2) >> 1);
}
}
return measured;
}
}; // namespace qcamera

View file

@ -0,0 +1,64 @@
/* 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 __QCAMERA_COMMON_H__
#define __QCAMERA_COMMON_H__
#include <utils/Timers.h>
// Camera dependencies
#include "cam_types.h"
#include "cam_intf.h"
namespace qcamera {
#define ALIGN(a, b) (((a) + (b)) & ~(b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
class QCameraCommon {
public:
QCameraCommon();
~QCameraCommon();
int32_t init(cam_capability_t *cap);
int32_t getAnalysisInfo(
bool fdVideoEnabled, bool hal3, cam_feature_mask_t featureMask,
cam_analysis_info_t *pAnalysisInfo);
static uint32_t calculateLCM(int32_t num1, int32_t num2);
static nsecs_t getBootToMonoTimeOffset();
private:
cam_capability_t *m_pCapability;
};
}; // namespace qcamera
#endif /* __QCAMERA_COMMON_H__ */

View file

@ -0,0 +1,401 @@
/* Copyright (c) 2015-2018, 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 "QCameraDisplay"
// Camera dependencies
#include <cutils/properties.h>
extern "C" {
#include "mm_camera_dbg.h"
}
#include "QCameraDisplay.h"
#define CAMERA_VSYNC_WAIT_MS 33 // Used by vsync thread to wait for vsync timeout.
#define DISPLAY_EVENT_RECEIVER_ARRAY_SIZE 1
#define DISPLAY_DEFAULT_FPS 60
#ifdef USE_DISPLAY_SERVICE
using ::android::frameworks::displayservice::V1_0::IDisplayEventReceiver;
using ::android::frameworks::displayservice::V1_0::IDisplayService;
using ::android::frameworks::displayservice::V1_0::IEventCallback;
using ::android::frameworks::displayservice::V1_0::Status;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::sp;
#else //USE_DISPLAY_SERVICE
#include <utils/Errors.h>
#include <utils/Looper.h>
using ::android::status_t;
using ::android::NO_ERROR;
using ::android::Looper;
#define ALOOPER_EVENT_INPUT android::Looper::EVENT_INPUT
#endif //USE_DISPLAY_SERVICE
namespace qcamera {
#ifndef USE_DISPLAY_SERVICE
/*===========================================================================
* FUNCTION : vsyncEventReceiverCamera
*
* DESCRIPTION: Computes average vsync interval. Called by display
* event handler for every vsync event.
*
* PARAMETERS :
* @fd : file descriptor
* @events : events
* @data : pointer to user data provided during call back registration.
*
* RETURN : always returns 1
*==========================================================================*/
int QCameraDisplay::vsyncEventReceiverCamera(__unused int fd,
__unused int events, void* data) {
android::DisplayEventReceiver::Event buffer[DISPLAY_EVENT_RECEIVER_ARRAY_SIZE];
QCameraDisplay* pQCameraDisplay = (QCameraDisplay *) data;
ssize_t n;
while ((n = pQCameraDisplay->mDisplayEventReceiver.getEvents(buffer,
DISPLAY_EVENT_RECEIVER_ARRAY_SIZE)) > 0) {
for (int i = 0 ; i < n ; i++) {
if (buffer[i].header.type == android::DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
pQCameraDisplay->computeAverageVsyncInterval(buffer[i].header.timestamp);
}
}
}
return 1;
}
/*===========================================================================
* FUNCTION : vsyncThreadCamera
*
* DESCRIPTION: Thread registers a call back function for every vsync event
* waits on the looper for the next vsync.
*
* PARAMETERS :
* @data : receives vsync_info_t structure.
*
* RETURN : NULL.Just to fullfill the type requirement of thread function.
*==========================================================================*/
void* QCameraDisplay::vsyncThreadCamera(void * data)
{
QCameraDisplay* pQCameraDisplay = (QCameraDisplay *) data;
android::sp<Looper> looper;
looper = new android::Looper(false);
status_t status = pQCameraDisplay->mDisplayEventReceiver.initCheck();
if (status != NO_ERROR) {
LOGE("Initialization of DisplayEventReceiver failed with status: %d", status);
return NULL;
}
looper->addFd(pQCameraDisplay->mDisplayEventReceiver.getFd(), 0, ALOOPER_EVENT_INPUT,
QCameraDisplay::vsyncEventReceiverCamera, pQCameraDisplay);
pQCameraDisplay->mDisplayEventReceiver.setVsyncRate(1);
while(pQCameraDisplay->mThreadExit == 0)
{
looper->pollOnce(CAMERA_VSYNC_WAIT_MS);
}
return NULL;
}
#endif //USE_DISPLAY_SERVICE
/*===========================================================================
* FUNCTION : QCameraDisplay
*
* DESCRIPTION: constructor of QCameraDisplay
*
* PARAMETERS : none
*
* RETURN : none
*==========================================================================*/
QCameraDisplay::QCameraDisplay()
: mVsyncTimeStamp(0),
mAvgVsyncInterval(0),
mOldTimeStamp(0),
mVsyncHistoryIndex(0),
mAdditionalVsyncOffsetForWiggle(0),
mNum_vsync_from_vfe_isr_to_presentation_timestamp(0),
mSet_timestamp_num_ns_prior_to_vsync(0),
mVfe_and_mdp_freq_wiggle_filter_max_ns(0),
mVfe_and_mdp_freq_wiggle_filter_min_ns(0),
#ifndef USE_DISPLAY_SERVICE
mThreadExit(0)
#else //USE_DISPLAY_SERVICE
m_bInitDone(false),
m_bSyncing(false)
#endif //USE_DISPLAY_SERVICE
{
#ifdef USE_DISPLAY_SERVICE
mDisplayService = nullptr;
mDisplayEventReceiver = nullptr;
#else //USE_DISPLAY_SERVICE
int rc = NO_ERROR;
memset(&mVsyncIntervalHistory, 0, sizeof(mVsyncIntervalHistory));
rc = pthread_create(&mVsyncThreadCameraHandle, NULL, vsyncThreadCamera, (void *)this);
if (rc == NO_ERROR) {
pthread_setname_np(mVsyncThreadCameraHandle, "CAM_Vsync");
#endif //USE_DISPLAY_SERVICE
char value[PROPERTY_VALUE_MAX];
nsecs_t default_vsync_interval;
// Read a list of properties used for tuning
property_get("persist.camera.disp.num_vsync", value, "4");
mNum_vsync_from_vfe_isr_to_presentation_timestamp = atoi(value);
property_get("persist.camera.disp.ms_to_vsync", value, "2");
mSet_timestamp_num_ns_prior_to_vsync = atoi(value) * NSEC_PER_MSEC;
property_get("persist.camera.disp.filter_max", value, "2");
mVfe_and_mdp_freq_wiggle_filter_max_ns = atoi(value) * NSEC_PER_MSEC;
property_get("persist.camera.disp.filter_min", value, "4");
mVfe_and_mdp_freq_wiggle_filter_min_ns = atoi(value) * NSEC_PER_MSEC;
property_get("persist.camera.disp.fps", value, "60");
if (atoi(value) > 0) {
default_vsync_interval= s2ns(1) / atoi(value);
} else {
default_vsync_interval= s2ns(1) / DISPLAY_DEFAULT_FPS;
}
for (int i=0; i < CAMERA_NUM_VSYNC_INTERVAL_HISTORY; i++) {
mVsyncIntervalHistory[i] = default_vsync_interval;
}
LOGD("display jitter num_vsync_from_vfe_isr_to_presentation_timestamp %u \
set_timestamp_num_ns_prior_to_vsync %llu",
mNum_vsync_from_vfe_isr_to_presentation_timestamp,
mSet_timestamp_num_ns_prior_to_vsync);
LOGD("display jitter vfe_and_mdp_freq_wiggle_filter_max_ns %llu \
vfe_and_mdp_freq_wiggle_filter_min_ns %llu",
mVfe_and_mdp_freq_wiggle_filter_max_ns,
mVfe_and_mdp_freq_wiggle_filter_min_ns);
#ifndef USE_DISPLAY_SERVICE
} else {
mVsyncThreadCameraHandle = 0;
}
#endif //USE_DISPLAY_SERVICE
}
/*===========================================================================
* FUNCTION : ~QCameraDisplay
*
* DESCRIPTION: destructor of QCameraDisplay
*
* PARAMETERS : none
*
* RETURN : none
*==========================================================================*/
QCameraDisplay::~QCameraDisplay()
{
#ifndef USE_DISPLAY_SERVICE
mThreadExit = 1;
if (mVsyncThreadCameraHandle != 0) {
pthread_join(mVsyncThreadCameraHandle, NULL);
}
#endif //USE_DISPLAY_SERVICE
}
#ifdef USE_DISPLAY_SERVICE
/*===========================================================================
* FUNCTION : init
*
* DESCRIPTION: Get the display service and register for the callback. OnVsync
* and onHotPlug callback will we called based on setVsyncRate
* parameter. Check isInitDone to see if init is success or not.
*
* PARAMETERS : none
*
* RETURN : none.
*==========================================================================*/
void
QCameraDisplay::init()
{
//get the display service and register for Event receiver.
mDisplayService = android::frameworks::displayservice::V1_0::IDisplayService::getService();
if(mDisplayService == nullptr)
{
LOGE("Camera failed to get Displayservice for vsync.");
return;
}
Return<sp<IDisplayEventReceiver>> ret = mDisplayService->getEventReceiver();
mDisplayEventReceiver = ret;
if(!ret.isOk() || (mDisplayEventReceiver == nullptr))
{
LOGE("Failed to get display event receiver");
return;
}
m_bInitDone = true;
}
/*===========================================================================
* FUNCTION : startVsync
*
* DESCRIPTION: Start or stop the onVsync or onHotPlug callback.
*
* PARAMETERS : true to start callback or false to stop callback
*
* RETURN : true in success, false in error case.
*==========================================================================*/
bool
QCameraDisplay::startVsync(bool bStart)
{
if(!m_bInitDone || mDisplayEventReceiver == nullptr)
{
LOGE("ERROR: Display event callbacks is not registered");
return false;
}
if(bStart)
{
Return<Status> retVal = mDisplayEventReceiver->init(this /*setting callbacks*/ );
if(!retVal.isOk() || (Status::SUCCESS != static_cast<Status>(retVal)) )
{
LOGE("Failed to register display vsync callback");
return false;
}
retVal = mDisplayEventReceiver->setVsyncRate(1 /*send callback after this many events*/);
if(!retVal.isOk() || (Status::SUCCESS != static_cast<Status>(retVal)) )
{
LOGE("Failed to start vsync events");
return false;
}
}
else
{
Return<Status> retVal = mDisplayEventReceiver->setVsyncRate(0 /*send callback after this many events*/);
if(!retVal.isOk() || (Status::SUCCESS != static_cast<Status>(retVal)) )
{
LOGE("Failed to stop vsync events");
return false;
}
}
LOGI("Display sync event %s", (bStart)?"started":"stopped");
m_bSyncing = (bStart)?true:false;
return true; //sync rate is set
}
#endif //USE_DISPLAY_SERVICE
/*===========================================================================
* FUNCTION : computeAverageVsyncInterval
*
* DESCRIPTION: Computes average vsync interval using current and previously
* stored vsync data.
*
* PARAMETERS : current vsync time stamp
*
* RETURN : none
*==========================================================================*/
void QCameraDisplay::computeAverageVsyncInterval(nsecs_t currentVsyncTimeStamp)
{
nsecs_t sum;
nsecs_t vsyncMaxOutlier;
nsecs_t vsyncMinOutlier;
mVsyncTimeStamp = currentVsyncTimeStamp;
if (mOldTimeStamp) {
// Compute average vsync interval using current and previously stored vsync data.
// Leave the max and min vsync interval from history in computing the average.
mVsyncIntervalHistory[mVsyncHistoryIndex] = currentVsyncTimeStamp - mOldTimeStamp;
mVsyncHistoryIndex++;
mVsyncHistoryIndex = mVsyncHistoryIndex % CAMERA_NUM_VSYNC_INTERVAL_HISTORY;
sum = mVsyncIntervalHistory[0];
vsyncMaxOutlier = mVsyncIntervalHistory[0];
vsyncMinOutlier = mVsyncIntervalHistory[0];
for (int j=1; j<CAMERA_NUM_VSYNC_INTERVAL_HISTORY; j++) {
sum += mVsyncIntervalHistory[j];
if (vsyncMaxOutlier < mVsyncIntervalHistory[j]) {
vsyncMaxOutlier = mVsyncIntervalHistory[j];
} else if (vsyncMinOutlier > mVsyncIntervalHistory[j]) {
vsyncMinOutlier = mVsyncIntervalHistory[j];
}
}
sum = sum - vsyncMaxOutlier - vsyncMinOutlier;
mAvgVsyncInterval = sum / (CAMERA_NUM_VSYNC_INTERVAL_HISTORY - 2);
}
mOldTimeStamp = currentVsyncTimeStamp;
}
/*===========================================================================
* FUNCTION : computePresentationTimeStamp
*
* DESCRIPTION: Computes presentation time stamp using vsync interval
* and last vsync time stamp and few other tunable variables
* to place the time stamp at the expected future vsync
*
* PARAMETERS : current frame time stamp set by VFE when buffer copy done.
*
* RETURN : time stamp in future or 0 in case of failure.
*==========================================================================*/
nsecs_t QCameraDisplay::computePresentationTimeStamp(nsecs_t frameTimeStamp)
{
nsecs_t moveToNextVsync;
nsecs_t keepInCurrentVsync;
nsecs_t timeDifference = 0;
nsecs_t presentationTimeStamp = 0;
int expectedVsyncOffset = 0;
int vsyncOffset;
#ifdef USE_DISPLAY_SERVICE
if(!isSyncing())
{
return 0;
}
#endif //USE_DISPLAY_SERVICE
if ( (mAvgVsyncInterval != 0) && (mVsyncTimeStamp != 0) ) {
// Compute presentation time stamp in future as per the following formula
// future time stamp = vfe time stamp + N * average vsync interval
// Adjust the time stamp so that it is placed few milliseconds before
// the expected vsync.
// Adjust the time stamp for the period where vsync time stamp and VFE
// timstamp cross over due difference in fps.
presentationTimeStamp = frameTimeStamp +
(mNum_vsync_from_vfe_isr_to_presentation_timestamp * mAvgVsyncInterval);
if (presentationTimeStamp > mVsyncTimeStamp) {
timeDifference = presentationTimeStamp - mVsyncTimeStamp;
moveToNextVsync = mAvgVsyncInterval - mVfe_and_mdp_freq_wiggle_filter_min_ns;
keepInCurrentVsync = mAvgVsyncInterval - mVfe_and_mdp_freq_wiggle_filter_max_ns;
vsyncOffset = timeDifference % mAvgVsyncInterval;
expectedVsyncOffset = mAvgVsyncInterval -
mSet_timestamp_num_ns_prior_to_vsync - vsyncOffset;
if (vsyncOffset > moveToNextVsync) {
mAdditionalVsyncOffsetForWiggle = mAvgVsyncInterval;
} else if (vsyncOffset < keepInCurrentVsync) {
mAdditionalVsyncOffsetForWiggle = 0;
}
LOGD("vsyncTimeStamp: %llu presentationTimeStamp: %llu expectedVsyncOffset: %d \
timeDifference: %llu vsyncffset: %d avgvsync: %llu \
additionalvsyncOffsetForWiggle: %llu",
mVsyncTimeStamp, presentationTimeStamp, expectedVsyncOffset,
timeDifference, vsyncOffset, mAvgVsyncInterval,
mAdditionalVsyncOffsetForWiggle);
}
presentationTimeStamp = presentationTimeStamp + expectedVsyncOffset +
mAdditionalVsyncOffsetForWiggle;
}
return presentationTimeStamp;
}
}; // namespace qcamera

View file

@ -0,0 +1,126 @@
/* Copyright (c) 2015-2018, 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 __QCAMERADISPLAY_H__
#define __QCAMERADISPLAY_H__
#ifdef USE_DISPLAY_SERVICE
#ifdef LIKELY
#undef LIKELY
#undef UNLIKELY
#endif //LIKELY
#include <android/frameworks/displayservice/1.0/IDisplayService.h>
#include <android/frameworks/displayservice/1.0/IEventCallback.h>
#include <android/frameworks/displayservice/1.0/IDisplayEventReceiver.h>
#include <android/looper.h>
#include <utils/Looper.h>
using ::android::frameworks::displayservice::V1_0::IDisplayEventReceiver;
using ::android::frameworks::displayservice::V1_0::IDisplayService;
using ::android::frameworks::displayservice::V1_0::IEventCallback;
using ::android::frameworks::displayservice::V1_0::Status;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::sp;
#else //USE_DISPLAY_SERVICE
#include <utils/Timers.h>
#include <gui/DisplayEventReceiver.h>
#endif //USE_DISPLAY_SERVICE
namespace qcamera {
#define CAMERA_NUM_VSYNC_INTERVAL_HISTORY 8
#define NSEC_PER_MSEC 1000000LLU
#ifdef USE_DISPLAY_SERVICE
class QCameraDisplay : public IEventCallback {
#else //USE_DISPLAY_SERVICE
class QCameraDisplay {
#endif //USE_DISPLAY_SERVICE
public:
QCameraDisplay();
~QCameraDisplay();
#ifdef USE_DISPLAY_SERVICE
void init();
bool isInited() { return m_bInitDone; }
bool isSyncing() {return m_bSyncing; }
bool startVsync(bool start);
Return<void> onVsync(uint64_t timestamp, uint32_t count) override {
ALOGV("onVsync: timestamp=%llu count=%d", timestamp, count);
computeAverageVsyncInterval(timestamp);
return Void();
}
Return<void> onHotplug(uint64_t timestamp, bool connected) override {
ALOGV("onHotplug: timestamp=%llu connected=%s", timestamp, connected ? "true" : "false");
return Void();
}
#else //USE_DISPLAY_SERVICE
static int vsyncEventReceiverCamera(int fd, int events, void* data);
static void* vsyncThreadCamera(void * data);
#endif //USE_DISPLAY_SERVICE
void computeAverageVsyncInterval(nsecs_t currentVsyncTimeStamp);
nsecs_t computePresentationTimeStamp(nsecs_t frameTimeStamp);
private:
nsecs_t mVsyncTimeStamp;
nsecs_t mAvgVsyncInterval;
nsecs_t mOldTimeStamp;
nsecs_t mVsyncIntervalHistory[CAMERA_NUM_VSYNC_INTERVAL_HISTORY];
nsecs_t mVsyncHistoryIndex;
nsecs_t mAdditionalVsyncOffsetForWiggle;
// Tunable property. Increasing this will increase the frame delay and will loose
// the real time display.
uint32_t mNum_vsync_from_vfe_isr_to_presentation_timestamp;
// Tunable property. Set the time stamp x ns prior to expected vsync so that
// it will be picked in that vsync
nsecs_t mSet_timestamp_num_ns_prior_to_vsync;
// Tunable property for filtering timestamp wiggle when VFE ISR crosses
// over MDP ISR over a period. Typical scenario is VFE is running at
// 30.2 fps vs display running at 60 fps.
nsecs_t mVfe_and_mdp_freq_wiggle_filter_max_ns;
nsecs_t mVfe_and_mdp_freq_wiggle_filter_min_ns;
#ifdef USE_DISPLAY_SERVICE
bool m_bInitDone;
bool m_bSyncing;
sp<IDisplayEventReceiver> mDisplayEventReceiver;
sp<IDisplayService> mDisplayService;
#else //USE_DISPLAY_SERVICE
pthread_t mVsyncThreadCameraHandle;
uint32_t mThreadExit;
android::DisplayEventReceiver mDisplayEventReceiver;
#endif //USE_DISPLAY_SERVICE
};
}; // namespace qcamera
#endif /* __QCAMERADISPLAY_H__ */

View file

@ -0,0 +1,413 @@
/* 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.
*
*/
// System dependencies
#include <stdio.h>
#include <fcntl.h>
#include <media/msm_cam_sensor.h>
// Camera dependencies
#include "HAL3/QCamera3HWI.h"
#include "QCameraFlash.h"
extern "C" {
#include "mm_camera_dbg.h"
}
#define STRING_LENGTH_OF_64_BIT_NUMBER 21
volatile uint32_t gCamHal3LogLevel = 1;
namespace qcamera {
/*===========================================================================
* FUNCTION : getInstance
*
* DESCRIPTION: Get and create the QCameraFlash singleton.
*
* PARAMETERS : None
*
* RETURN : None
*==========================================================================*/
QCameraFlash& QCameraFlash::getInstance()
{
static QCameraFlash flashInstance;
return flashInstance;
}
/*===========================================================================
* FUNCTION : QCameraFlash
*
* DESCRIPTION: default constructor of QCameraFlash
*
* PARAMETERS : None
*
* RETURN : None
*==========================================================================*/
QCameraFlash::QCameraFlash() : m_callbacks(NULL)
{
memset(&m_flashOn, 0, sizeof(m_flashOn));
memset(&m_cameraOpen, 0, sizeof(m_cameraOpen));
for (int pos = 0; pos < MM_CAMERA_MAX_NUM_SENSORS; pos++) {
m_flashFds[pos] = -1;
}
}
/*===========================================================================
* FUNCTION : ~QCameraFlash
*
* DESCRIPTION: deconstructor of QCameraFlash
*
* PARAMETERS : None
*
* RETURN : None
*==========================================================================*/
QCameraFlash::~QCameraFlash()
{
for (int pos = 0; pos < MM_CAMERA_MAX_NUM_SENSORS; pos++) {
if (m_flashFds[pos] >= 0)
{
setFlashMode(pos, false);
close(m_flashFds[pos]);
m_flashFds[pos] = -1;
}
}
}
/*===========================================================================
* FUNCTION : registerCallbacks
*
* DESCRIPTION: provide flash module with reference to callbacks to framework
*
* PARAMETERS : None
*
* RETURN : None
*==========================================================================*/
int32_t QCameraFlash::registerCallbacks(
const camera_module_callbacks_t* callbacks)
{
int32_t retVal = 0;
m_callbacks = callbacks;
return retVal;
}
/*===========================================================================
* FUNCTION : initFlash
*
* DESCRIPTION: Reserve and initialize the flash unit associated with a
* given camera id. This function is blocking until the
* operation completes or fails. Each flash unit can be "inited"
* by only one process at a time.
*
* PARAMETERS :
* @camera_id : Camera id of the flash.
*
* RETURN :
* 0 : success
* -EBUSY : The flash unit or the resource needed to turn on the
* the flash is busy, typically because the flash is
* already in use.
* -EINVAL : No flash present at camera_id.
*==========================================================================*/
int32_t QCameraFlash::initFlash(const int camera_id)
{
int32_t retVal = 0;
bool hasFlash = false;
char flashNode[QCAMERA_MAX_FILEPATH_LENGTH];
char flashPath[QCAMERA_MAX_FILEPATH_LENGTH] = "/dev/";
if (camera_id < 0 || camera_id >= MM_CAMERA_MAX_NUM_SENSORS) {
LOGE("Invalid camera id: %d", camera_id);
return -EINVAL;
}
QCamera3HardwareInterface::getFlashInfo(camera_id,
hasFlash,
flashNode);
strlcat(flashPath,
flashNode,
sizeof(flashPath));
if (!hasFlash) {
LOGE("No flash available for camera id: %d",
camera_id);
retVal = -ENOSYS;
} else if (m_cameraOpen[camera_id]) {
LOGE("Camera in use for camera id: %d",
camera_id);
retVal = -EBUSY;
} else if (m_flashFds[camera_id] >= 0) {
LOGD("Flash is already inited for camera id: %d",
camera_id);
} else {
m_flashFds[camera_id] = open(flashPath, O_RDWR | O_NONBLOCK);
if (m_flashFds[camera_id] < 0) {
LOGE("Unable to open node '%s'",
flashPath);
retVal = -EBUSY;
} else {
struct msm_flash_cfg_data_t cfg;
struct msm_flash_init_info_t init_info;
memset(&cfg, 0, sizeof(struct msm_flash_cfg_data_t));
memset(&init_info, 0, sizeof(struct msm_flash_init_info_t));
init_info.flash_driver_type = FLASH_DRIVER_DEFAULT;
cfg.cfg.flash_init_info = &init_info;
cfg.cfg_type = CFG_FLASH_INIT;
retVal = ioctl(m_flashFds[camera_id],
VIDIOC_MSM_FLASH_CFG,
&cfg);
if (retVal < 0) {
LOGE("Unable to init flash for camera id: %d",
camera_id);
close(m_flashFds[camera_id]);
m_flashFds[camera_id] = -1;
}
/* wait for PMIC to init */
usleep(5000);
}
}
LOGD("X, retVal = %d", retVal);
return retVal;
}
/*===========================================================================
* FUNCTION : setFlashMode
*
* DESCRIPTION: Turn on or off the flash associated with a given handle.
* This function is blocking until the operation completes or
* fails.
*
* PARAMETERS :
* @camera_id : Camera id of the flash
* @on : Whether to turn flash on (true) or off (false)
*
* RETURN :
* 0 : success
* -EINVAL : No camera present at camera_id, or it is not inited.
* -EALREADY: Flash is already in requested state
*==========================================================================*/
int32_t QCameraFlash::setFlashMode(const int camera_id, const bool mode)
{
int32_t retVal = 0;
struct msm_flash_cfg_data_t cfg;
if (camera_id < 0 || camera_id >= MM_CAMERA_MAX_NUM_SENSORS) {
LOGE("Invalid camera id: %d", camera_id);
retVal = -EINVAL;
} else if (mode == m_flashOn[camera_id]) {
LOGD("flash %d is already in requested state: %d",
camera_id,
mode);
retVal = -EALREADY;
} else if (m_flashFds[camera_id] < 0) {
LOGE("called for uninited flash: %d", camera_id);
retVal = -EINVAL;
} else {
memset(&cfg, 0, sizeof(struct msm_flash_cfg_data_t));
for (int i = 0; i < MAX_LED_TRIGGERS; i++)
cfg.flash_current[i] = QCAMERA_TORCH_CURRENT_VALUE;
cfg.cfg_type = mode ? CFG_FLASH_LOW: CFG_FLASH_OFF;
retVal = ioctl(m_flashFds[camera_id],
VIDIOC_MSM_FLASH_CFG,
&cfg);
if (retVal < 0) {
LOGE("Unable to change flash mode to %d for camera id: %d",
mode, camera_id);
} else
{
m_flashOn[camera_id] = mode;
}
}
return retVal;
}
/*===========================================================================
* FUNCTION : deinitFlash
*
* DESCRIPTION: Release the flash unit associated with a given camera
* position. This function is blocking until the operation
* completes or fails.
*
* PARAMETERS :
* @camera_id : Camera id of the flash.
*
* RETURN :
* 0 : success
* -EINVAL : No camera present at camera_id or not inited.
*==========================================================================*/
int32_t QCameraFlash::deinitFlash(const int camera_id)
{
int32_t retVal = 0;
if (camera_id < 0 || camera_id >= MM_CAMERA_MAX_NUM_SENSORS) {
LOGE("Invalid camera id: %d", camera_id);
retVal = -EINVAL;
} else if (m_flashFds[camera_id] < 0) {
LOGE("called deinitFlash for uninited flash");
retVal = -EINVAL;
} else {
setFlashMode(camera_id, false);
struct msm_flash_cfg_data_t cfg;
cfg.cfg_type = CFG_FLASH_RELEASE;
retVal = ioctl(m_flashFds[camera_id],
VIDIOC_MSM_FLASH_CFG,
&cfg);
if (retVal < 0) {
LOGE("Failed to release flash for camera id: %d",
camera_id);
}
close(m_flashFds[camera_id]);
m_flashFds[camera_id] = -1;
}
return retVal;
}
/*===========================================================================
* FUNCTION : reserveFlashForCamera
*
* DESCRIPTION: Give control of the flash to the camera, and notify
* framework that the flash has become unavailable.
*
* PARAMETERS :
* @camera_id : Camera id of the flash.
*
* RETURN :
* 0 : success
* -EINVAL : No camera present at camera_id or not inited.
* -ENOSYS : No callback available for torch_mode_status_change.
*==========================================================================*/
int32_t QCameraFlash::reserveFlashForCamera(const int camera_id)
{
int32_t retVal = 0;
if (camera_id < 0 || camera_id >= MM_CAMERA_MAX_NUM_SENSORS) {
LOGE("Invalid camera id: %d", camera_id);
retVal = -EINVAL;
} else if (m_cameraOpen[camera_id]) {
LOGD("Flash already reserved for camera id: %d",
camera_id);
} else {
if (m_flashOn[camera_id]) {
setFlashMode(camera_id, false);
deinitFlash(camera_id);
}
m_cameraOpen[camera_id] = true;
bool hasFlash = false;
char flashNode[QCAMERA_MAX_FILEPATH_LENGTH];
QCamera3HardwareInterface::getFlashInfo(camera_id,
hasFlash,
flashNode);
if (m_callbacks == NULL ||
m_callbacks->torch_mode_status_change == NULL) {
LOGE("Callback is not defined!");
retVal = -ENOSYS;
} else if (!hasFlash) {
LOGD("Suppressing callback "
"because no flash exists for camera id: %d",
camera_id);
} else {
char cameraIdStr[STRING_LENGTH_OF_64_BIT_NUMBER];
snprintf(cameraIdStr, STRING_LENGTH_OF_64_BIT_NUMBER,
"%d", camera_id);
m_callbacks->torch_mode_status_change(m_callbacks,
cameraIdStr,
TORCH_MODE_STATUS_NOT_AVAILABLE);
}
}
return retVal;
}
/*===========================================================================
* FUNCTION : releaseFlashFromCamera
*
* DESCRIPTION: Release control of the flash from the camera, and notify
* framework that the flash has become available.
*
* PARAMETERS :
* @camera_id : Camera id of the flash.
*
* RETURN :
* 0 : success
* -EINVAL : No camera present at camera_id or not inited.
* -ENOSYS : No callback available for torch_mode_status_change.
*==========================================================================*/
int32_t QCameraFlash::releaseFlashFromCamera(const int camera_id)
{
int32_t retVal = 0;
if (camera_id < 0 || camera_id >= MM_CAMERA_MAX_NUM_SENSORS) {
LOGE("Invalid camera id: %d", camera_id);
retVal = -EINVAL;
} else if (!m_cameraOpen[camera_id]) {
LOGD("Flash not reserved for camera id: %d",
camera_id);
} else {
m_cameraOpen[camera_id] = false;
bool hasFlash = false;
char flashNode[QCAMERA_MAX_FILEPATH_LENGTH];
QCamera3HardwareInterface::getFlashInfo(camera_id,
hasFlash,
flashNode);
if (m_callbacks == NULL ||
m_callbacks->torch_mode_status_change == NULL) {
LOGE("Callback is not defined!");
retVal = -ENOSYS;
} else if (!hasFlash) {
LOGD("Suppressing callback "
"because no flash exists for camera id: %d",
camera_id);
} else {
char cameraIdStr[STRING_LENGTH_OF_64_BIT_NUMBER];
snprintf(cameraIdStr, STRING_LENGTH_OF_64_BIT_NUMBER,
"%d", camera_id);
m_callbacks->torch_mode_status_change(m_callbacks,
cameraIdStr,
TORCH_MODE_STATUS_AVAILABLE_OFF);
}
}
return retVal;
}
}; // namespace qcamera

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