#ifndef CAMERA_TEST_H #define CAMERA_TEST_H #ifdef ANDROID_API_JB_OR_LATER #include <gui/Surface.h> #include <gui/SurfaceComposerClient.h> #else #include <surfaceflinger/Surface.h> #include <surfaceflinger/ISurface.h> #include <surfaceflinger/ISurfaceComposer.h> #include <surfaceflinger/ISurfaceComposerClient.h> #include <surfaceflinger/SurfaceComposerClient.h> #endif #ifdef ANDROID_API_JB_OR_LATER # define CAMHAL_LOGV ALOGV # define CAMHAL_LOGE ALOGE # define PRINTOVER(arg...) ALOGD(#arg) # define LOG_FUNCTION_NAME ALOGD("%d: %s() ENTER", __LINE__, __FUNCTION__); # define LOG_FUNCTION_NAME_EXIT ALOGD("%d: %s() EXIT", __LINE__, __FUNCTION__); #else # define CAMHAL_LOGV LOGV # define CAMHAL_LOGE LOGE # define PRINTOVER(arg...) LOGD(#arg) # define LOG_FUNCTION_NAME LOGD("%d: %s() ENTER", __LINE__, __FUNCTION__); # define LOG_FUNCTION_NAME_EXIT LOGD("%d: %s() EXIT", __LINE__, __FUNCTION__); #endif #define KEY_GBCE "gbce" #define KEY_GLBCE "glbce" #define KEY_CAMERA "camera-index" #define KEY_SATURATION "saturation" #define KEY_BRIGHTNESS "brightness" #define KEY_TI_BURST "burst-capture" #define KEY_EXPOSURE "exposure" #define KEY_CONTRAST "contrast" #define KEY_SHARPNESS "sharpness" #define KEY_ISO "iso" #define KEY_CAF "caf" #define KEY_MODE "mode" #define KEY_VNF "vnf" #define KEY_VSTAB "vstab" #define KEY_COMPENSATION "exposure-compensation" #define KEY_SENSOR_ORIENTATION "sensor-orientation" #define KEY_IPP "ipp" #define KEY_BUFF_STARV "buff-starvation" #define KEY_METERING_MODE "meter-mode" #define KEY_AUTOCONVERGENCE "auto-convergence-mode" #define KEY_MANUAL_CONVERGENCE "manual-convergence" #define KEY_EXP_BRACKETING_RANGE "exp-bracketing-range" #define KEY_EXP_GAIN_BRACKETING_RANGE "exp-gain-bracketing-range" #define KEY_TEMP_BRACKETING "temporal-bracketing" #define KEY_TEMP_BRACKETING_POS "temporal-bracketing-range-positive" #define KEY_TEMP_BRACKETING_NEG "temporal-bracketing-range-negative" #define KEY_MEASUREMENT "measurement" #define KEY_S3D2D_PREVIEW_MODE "s3d2d-preview" #define KEY_S3D_PRV_FRAME_LAYOUT "s3d-prv-frame-layout" #define KEY_S3D_CAP_FRAME_LAYOUT "s3d-cap-frame-layout" #define KEY_EXIF_MODEL "exif-model" #define KEY_EXIF_MAKE "exif-make" #define KEY_AF_TIMEOUT "af-timeout" #define KEY_AUTO_EXPOSURE_LOCK "auto-exposure-lock" #define KEY_AUTO_WHITEBALANCE_LOCK "auto-whitebalance-lock" #define KEY_MECHANICAL_MISALIGNMENT_CORRECTION "mechanical-misalignment-correction" //TI extensions for enable/disable algos #define KEY_ALGO_FIXED_GAMMA "ti-algo-fixed-gamma" #define KEY_ALGO_NSF1 "ti-algo-nsf1" #define KEY_ALGO_NSF2 "ti-algo-nsf2" #define KEY_ALGO_SHARPENING "ti-algo-sharpening" #define KEY_ALGO_THREELINCOLORMAP "ti-algo-threelinecolormap" #define KEY_ALGO_GIC "ti-algo-gic" #define KEY_TAP_OUT_SURFACES "tap-out" #define KEY_TAP_IN_SURFACE "tap-in" #define BRACKETING_IDX_DEFAULT 0 #define BRACKETING_IDX_STREAM 1 #define BRACKETING_STREAM_BUFFERS 9 #define SDCARD_PATH "/sdcard/" #define SECONDARY_SENSOR "_SEC" #define S3D_SENSOR "_S3D" #define MAX_BURST 15 #define BURST_INC 5 #define TEMP_BRACKETING_MAX_RANGE 4 #define MEDIASERVER_DUMP "procmem -w $(ps | grep mediaserver | grep -Eo '[0-9]+' | head -n 1) | grep \"\\(Name\\|libcamera.so\\|libOMX\\|libomxcameraadapter.so\\|librcm.so\\|libnotify.so\\|libipcutils.so\\|libipc.so\\|libsysmgr.so\\|TOTAL\\)\"" #define MEMORY_DUMP "procrank -u" #define KEY_METERING_MODE "meter-mode" #define TEST_FOCUS_AREA "(-1000,500,-500,1000,1000),(500,500,1000,1000,1)" #define TEST_METERING_AREA "(-1000,500,-500,1000,1000),(500,500,1000,1000,1)" #define TEST_METERING_AREA_CENTER "(-250,-250,250,250,1000)" #define TEST_METERING_AREA_AVERAGE "(-1000,-1000,1000,1000,1000)" #define COMPENSATION_OFFSET 20 #define DELIMITER "|" #define MODEL "camera_test" #define MAKE "camera_test" #define BLAZE 0 #define BLAZE_TABLET1 1 #define BLAZE_TABLET2 2 #define MAX_LINES 80 #define MAX_SYMBOLS 65 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) typedef enum test_type { TEST_TYPE_REGRESSION, TEST_TYPE_FUNCTIONAL, TEST_TYPE_API, TEST_TYPE_ERROR, } test_type_t; typedef enum param_ExpBracketParamType_t { PARAM_EXP_BRACKET_PARAM_NONE, PARAM_EXP_BRACKET_PARAM_COMP, PARAM_EXP_BRACKET_PARAM_PAIR, } param_ExpBracketParamType; typedef enum param_ExpBracketValueType_t { PARAM_EXP_BRACKET_VALUE_NONE, PARAM_EXP_BRACKET_VALUE_ABS, PARAM_EXP_BRACKET_VALUE_REL, } param_ExpBracketValueType; typedef enum param_ExpBracketApplyType_t { PARAM_EXP_BRACKET_APPLY_NONE, PARAM_EXP_BRACKET_APPLY_ADJUST, PARAM_EXP_BRACKET_APPLY_FORCED, } param_ExpBracketApplyType; enum logging { LOGGING_LOGCAT = 0x01, LOGGING_SYSLINK = 0x02 }; typedef struct cmd_args { test_type_t test_type; const char *script_file_name; const char *output_path; int platform_id; int logging; } cmd_args_t; namespace android { class CameraHandler: public CameraListener { public: virtual void notify(int32_t msgType, int32_t ext1, int32_t ext2); virtual void postData(int32_t msgType, const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata); virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr); }; }; using namespace android; typedef struct pixel_format_t { int32_t pixelFormatDesc; const char *pixformat; }pixel_format; typedef struct output_format_t { output_format type; const char *desc; } outformat; typedef struct Vcapture_size_t { int width, height; const char *desc; } Vcapture_size; typedef struct param_Array_t { int width, height; char name[60]; } param_Array; typedef struct video_Codecs_t { video_encoder type; const char *desc; } video_Codecs; typedef struct audio_Codecs_t { audio_encoder type; const char *desc; } audio_Codecs; typedef struct V_bitRate_t { uint32_t bit_rate; const char *desc; } V_bitRate; typedef struct zoom_t { int idx; const char *zoom_description; } Zoom; typedef struct fps_ranges_t { int rangeMin; int rangeMax; } fps_Array; typedef struct buffer_info { int size; int width; int height; int format; size_t offset; Rect crop; sp<GraphicBuffer> buf; } buffer_info_t; typedef struct param_NamedExpBracketList_t { const char *desc; param_ExpBracketParamType_t param_type; param_ExpBracketValueType_t value_type; param_ExpBracketApplyType_t apply_type; const char *value; } param_NamedExpBracketList; char * get_cycle_cmd(const char *aSrc); void trim_script_cmd(char *cmd); int execute_functional_script(char *script); status_t dump_mem_status(); int openCamera(); int closeCamera(); void createBufferOutputSource(); void createBufferInputSource(); void requestBufferSourceReset(); void initDefaults(); void setDefaultExpGainPreset(ShotParameters ¶ms, int idx); void setSingleExpGainPreset(ShotParameters ¶ms, int idx, int exp, int gain); void setExpGainPreset(ShotParameters ¶ms, const char *input, bool force, param_ExpBracketParamType_t type, bool flush); void calcNextSingleExpGainPreset(int idx, int &exp, int &gain); void updateShotConfigFlushParam(); int startPreview(); void stopPreview(); int startRecording(); int stopRecording(); int closeRecorder(); int openRecorder(); int configureRecorder(); void printSupportedParams(); char *load_script(const char *config); int start_logging(int flags, int &pid); int stop_logging(int flags, int &pid); int execute_error_script(char *script); int getParametersFromCapabilities(); void getSizeParametersFromCapabilities(); int getDefaultParameter(const char* val, int numOptions, char **array); int getDefaultParameterResol(const char* val, int numOptions, param_Array **array); int getSupportedParameters(char* parameters, int* optionsCount, char ***elem); int getSupportedParametersCaptureSize(char* parameters, int *optionsCount, param_Array array[], int arraySize); int getSupportedParametersVideoCaptureSize(char* parameters, int *optionsCount, param_Array array[], int arraySize); int getSupportedParametersPreviewSize(char* parameters, int *optionsCount, param_Array array[], int arraySize); int getSupportedParametersThumbnailSize(char* parameters, int *optionsCount, param_Array array[], int arraySize); int getSupportedParametersNames(int width, int height, param_Array array[], int arraySize); int checkSupportedParamScript(char **array, int size, char *param); int checkSupportedParamScriptLayout(char **array, int size, char *param,int *index); int checkSupportedParamScriptResol(param_Array **array, int size, char *param, int *num); int checkSupportedParamScriptResol(param_Array **array, int size, int w, int h, int *num); int getSupportedParametersfps(char* parameters, int *optionsCount); int checkSupportedParamScriptfpsConst(int *array, int size, char *param, int *num); int checkSupportedParamScriptfpsRange(char **array, int size, char *param, int *num); int trySetVideoStabilization(bool toggle); int trySetVideoNoiseFilter(bool toggle); int trySetAutoExposureLock(bool toggle); int trySetAutoWhiteBalanceLock(bool toggle); bool isRawPixelFormat (const char *format); int deleteAllocatedMemory(); void initDefaultsSec(); const char KEY_S3D_PRV_FRAME_LAYOUT_VALUES[] = "s3d-prv-frame-layout-values"; const char KEY_S3D_CAP_FRAME_LAYOUT_VALUES[] = "s3d-cap-frame-layout-values"; const char KEY_SUPPORTED_PICTURE_TOPBOTTOM_SIZES[] = "supported-picture-topbottom-size-values"; const char KEY_SUPPORTED_PREVIEW_TOPBOTTOM_SIZES[] = "supported-preview-topbottom-size-values"; const char KEY_SUPPORTED_PICTURE_SIDEBYSIDE_SIZES[] = "supported-picture-sidebyside-size-values"; const char KEY_SUPPORTED_PREVIEW_SIDEBYSIDE_SIZES[] = "supported-preview-sidebyside-size-values"; const char KEY_SUPPORTED_PICTURE_SUBSAMPLED_SIZES[] = "supported-picture-subsampled-size-values"; const char KEY_SUPPORTED_PREVIEW_SUBSAMPLED_SIZES[] = "supported-preview-subsampled-size-values"; const char KEY_AUTOCONVERGENCE_MODE[] = "auto-convergence-mode"; const char KEY_AUTOCONVERGENCE_MODE_VALUES[] = "auto-convergence-mode-values"; const char KEY_MANUAL_EXPOSURE[] = "manual-exposure"; const char KEY_MANUAL_GAIN_ISO[] = "manual-gain-iso"; const char KEY_MANUAL_EXPOSURE_RIGHT[] = "manual-exposure-right"; const char KEY_MANUAL_GAIN_ISO_RIGHT[] = "manual-gain-iso-right"; const char KEY_SUPPORTED_MANUAL_CONVERGENCE_MIN[] = "supported-manual-convergence-min"; const char KEY_SUPPORTED_MANUAL_CONVERGENCE_MAX[] = "supported-manual-convergence-max"; const char KEY_SUPPORTED_MANUAL_CONVERGENCE_STEP[] = "supported-manual-convergence-step"; const char KEY_SUPPORTED_MANUAL_EXPOSURE_MIN[] = "supported-manual-exposure-min"; const char KEY_SUPPORTED_MANUAL_EXPOSURE_MAX[] = "supported-manual-exposure-max"; const char KEY_SUPPORTED_MANUAL_EXPOSURE_STEP[] = "supported-manual-exposure-step"; const char KEY_SUPPORTED_MANUAL_GAIN_ISO_MIN[] = "supported-manual-gain-iso-min"; const char KEY_SUPPORTED_MANUAL_GAIN_ISO_MAX[] = "supported-manual-gain-iso-max"; const char KEY_SUPPORTED_MANUAL_GAIN_ISO_STEP[] = "supported-manual-gain-iso-step"; class BufferSourceThread : public Thread { public: class Defer : public Thread { private: struct DeferContainer { sp<GraphicBuffer> graphicBuffer; uint8_t *mappedBuffer; unsigned int count; unsigned int slot; Rect crop; }; public: Defer(BufferSourceThread* bst) : Thread(false), mBST(bst), mExiting(false) { } virtual ~Defer() { Mutex::Autolock lock(mFrameQueueMutex); mExiting = true; while (!mDeferQueue.isEmpty()) { DeferContainer defer = mDeferQueue.itemAt(0); defer.graphicBuffer->unlock(); mDeferQueue.removeAt(0); } mFrameQueueCondition.signal(); } virtual void requestExit() { Thread::requestExit(); mExiting = true; mFrameQueueCondition.signal(); } virtual bool threadLoop() { Mutex::Autolock lock(mFrameQueueMutex); while (mDeferQueue.isEmpty() && !mExiting) { mFrameQueueCondition.wait(mFrameQueueMutex); } if (!mExiting) { DeferContainer defer = mDeferQueue.itemAt(0); printf ("=== handling buffer %d\n", defer.count); mBST->handleBuffer(defer.graphicBuffer, defer.mappedBuffer, defer.count, defer.crop); defer.graphicBuffer->unlock(); mDeferQueue.removeAt(0); mBST->onHandled(defer.graphicBuffer, defer.slot); return true; } return false; } void add(sp<GraphicBuffer> &gbuf, const Rect &crop, unsigned int count, unsigned int slot = 0) { Mutex::Autolock lock(mFrameQueueMutex); DeferContainer defer; defer.graphicBuffer = gbuf; defer.count = count; defer.slot = slot; defer.crop = crop; gbuf->lock(GRALLOC_USAGE_SW_READ_RARELY, (void**) &defer.mappedBuffer); mDeferQueue.add(defer); mFrameQueueCondition.signal(); } private: Vector<DeferContainer> mDeferQueue; Mutex mFrameQueueMutex; Condition mFrameQueueCondition; BufferSourceThread* mBST; bool mExiting; }; public: BufferSourceThread(sp<Camera> camera) : Thread(false), mCamera(camera), mDestroying(false), mRestartCapture(false), mExpBracketIdx(BRACKETING_IDX_DEFAULT), mExp(0), mGain(0), mCounter(0), kReturnedBuffersMaxCapacity(6) { mDeferThread = new Defer(this); mDeferThread->run(); } virtual ~BufferSourceThread() { mDestroying = true; for (unsigned int i = 0; i < mReturnedBuffers.size(); i++) { buffer_info_t info = mReturnedBuffers.itemAt(i); mReturnedBuffers.removeAt(i); } mDeferThread->requestExit(); mDeferThread.clear(); } virtual bool threadLoop() { return false;} virtual void requestExit() {}; virtual void setBuffer(android::ShotParameters ¶ms) {}; virtual void onHandled(sp<GraphicBuffer> &g, unsigned int slot) {}; bool setStreamCapture(bool restart, int expBracketIdx) { Mutex::Autolock lock(mToggleStateMutex); mExpBracketIdx = expBracketIdx; mRestartCapture = restart; return mRestartCapture; } buffer_info_t popBuffer() { buffer_info_t buffer; Mutex::Autolock lock(mReturnedBuffersMutex); if (!mReturnedBuffers.isEmpty()) { buffer = mReturnedBuffers.itemAt(0); mReturnedBuffers.removeAt(0); } return buffer; } bool hasBuffer() { Mutex::Autolock lock(mReturnedBuffersMutex); return !mReturnedBuffers.isEmpty(); } void handleBuffer(sp<GraphicBuffer> &, uint8_t *, unsigned int, const Rect &); Rect getCrop(sp<GraphicBuffer> &buffer, const float *mtx); void showMetadata(sp<IMemory> data); protected: void restartCapture() { Mutex::Autolock lock(mToggleStateMutex); if (mRestartCapture) { ShotParameters shotParams; calcNextSingleExpGainPreset(mExpBracketIdx, mExp, mGain), setSingleExpGainPreset(shotParams, mExpBracketIdx, mExp, mGain); shotParams.set(ShotParameters::KEY_BURST, 1); mCamera->takePictureWithParameters(0, shotParams.flatten()); } } protected: sp<Camera> mCamera; bool mDestroying; bool mRestartCapture; int mExpBracketIdx; int mExp; int mGain; sp<Defer> mDeferThread; unsigned int mCounter; private: Vector<buffer_info_t> mReturnedBuffers; Mutex mReturnedBuffersMutex; Mutex mToggleStateMutex; const unsigned int kReturnedBuffersMaxCapacity; }; class BufferSourceInput : public RefBase { public: BufferSourceInput(sp<Camera> camera) : mCamera(camera) { mTapOut = new BufferSourceThread(camera); mTapOut->run(); } virtual ~BufferSourceInput() { mTapOut->requestExit(); mTapOut.clear(); } virtual void setInput(buffer_info_t, const char *format, ShotParameters ¶ms); protected: sp<BufferSourceThread> mTapOut; sp<ANativeWindow> mWindowTapIn; sp<Camera> mCamera; }; #endif