diff options
author | Prateek Chaubey <chaubeyprateek@gmail.com> | 2018-01-07 20:55:14 +0530 |
---|---|---|
committer | Davide Garberi <dade.garberi@gmail.com> | 2018-01-19 14:09:15 +0100 |
commit | 6616278131edd80a12545085e06ee6b0e0a0a788 (patch) | |
tree | 0aef88ed11809a9d67f6abe4dc2ff782a14737e2 /camera/QCamera2/stack/mm-lib2d-interface | |
parent | cc4ccf34871da343111bf68d16ba4e4c67cac1dc (diff) |
msm8996-common: zuk: Import OSS Camera HAL
Tag: LA.HB.1.3.2-32600-8x96.0
Signed-off-by: Davide Garberi <dade.garberi@gmail.com>
Diffstat (limited to 'camera/QCamera2/stack/mm-lib2d-interface')
5 files changed, 1432 insertions, 0 deletions
diff --git a/camera/QCamera2/stack/mm-lib2d-interface/Android.mk b/camera/QCamera2/stack/mm-lib2d-interface/Android.mk new file mode 100644 index 0000000..696f04a --- /dev/null +++ b/camera/QCamera2/stack/mm-lib2d-interface/Android.mk @@ -0,0 +1,39 @@ +OLD_LOCAL_PATH := $(LOCAL_PATH) +LOCAL_PATH := $(call my-dir) + +include $(LOCAL_PATH)/../../../common.mk +include $(CLEAR_VARS) + +LOCAL_32_BIT_ONLY := $(BOARD_QTI_CAMERA_32BIT_ONLY) +LOCAL_CFLAGS+= -D_ANDROID_ -DQCAMERA_REDEFINE_LOG + +LOCAL_CFLAGS += -Wall -Wextra -Werror -Wno-unused-parameter + +LOCAL_C_INCLUDES+= $(kernel_includes) +LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) + +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_PRELINK_MODULE := false +LOCAL_SHARED_LIBRARIES := libdl libcutils liblog libmmcamera_interface +LOCAL_MODULE_TAGS := optional + +LOCAL_32_BIT_ONLY := $(BOARD_QTI_CAMERA_32BIT_ONLY) +include $(BUILD_SHARED_LIBRARY) + +LOCAL_PATH := $(OLD_LOCAL_PATH) diff --git a/camera/QCamera2/stack/mm-lib2d-interface/inc/mm_lib2d.h b/camera/QCamera2/stack/mm-lib2d-interface/inc/mm_lib2d.h new file mode 100644 index 0000000..d1e69b4 --- /dev/null +++ b/camera/QCamera2/stack/mm-lib2d-interface/inc/mm_lib2d.h @@ -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_ */ + + diff --git a/camera/QCamera2/stack/mm-lib2d-interface/src/mm_lib2d.c b/camera/QCamera2/stack/mm-lib2d-interface/src/mm_lib2d.c new file mode 100644 index 0000000..28ef27f --- /dev/null +++ b/camera/QCamera2/stack/mm-lib2d-interface/src/mm_lib2d.c @@ -0,0 +1,604 @@ +/* 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. + * + */ + +// 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; + + 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_mutex_init(&lib2d_obj->mutex, NULL); + pthread_cond_init(&lib2d_obj->cond, NULL); + + 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; +} + diff --git a/camera/QCamera2/stack/mm-lib2d-interface/test/Android.mk b/camera/QCamera2/stack/mm-lib2d-interface/test/Android.mk new file mode 100644 index 0000000..63cd5b7 --- /dev/null +++ b/camera/QCamera2/stack/mm-lib2d-interface/test/Android.mk @@ -0,0 +1,37 @@ +#lib2d sample test +OLD_LOCAL_PATH := $(LOCAL_PATH) +MM_LIB2D_TEST_PATH := $(call my-dir) + +include $(LOCAL_PATH)/../../common.mk +include $(CLEAR_VARS) +LOCAL_PATH := $(MM_LIB2D_TEST_PATH) +LOCAL_MODULE_TAGS := optional + +LOCAL_CFLAGS := -DCAMERA_ION_HEAP_ID=ION_IOMMU_HEAP_ID +LOCAL_CFLAGS += -Wall -Wextra -Werror -Wno-unused-parameter +LOCAL_CFLAGS += -D_ANDROID_ + +ifeq ($(strip $(TARGET_USES_ION)),true) +LOCAL_CFLAGS += -DUSE_ION +endif + +IMGLIB_HEADER_PATH := $(TARGET_OUT_INTERMEDIATES)/include/mm-camera/imglib + +LOCAL_C_INCLUDES += \ + $(IMGLIB_HEADER_PATH) \ + $(LOCAL_PATH)/../../common \ + $(LOCAL_PATH)/../inc + +LOCAL_C_INCLUDES+= $(kernel_includes) +LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) + +LOCAL_SRC_FILES := mm_lib2d_test.c + +LOCAL_32_BIT_ONLY := $(BOARD_QTI_CAMERA_32BIT_ONLY) +LOCAL_MODULE := mm-lib2d-interface-test +LOCAL_PRELINK_MODULE := false +LOCAL_SHARED_LIBRARIES := libcutils libdl libmmlib2d_interface + +include $(BUILD_EXECUTABLE) + +LOCAL_PATH := $(OLD_LOCAL_PATH) diff --git a/camera/QCamera2/stack/mm-lib2d-interface/test/mm_lib2d_test.c b/camera/QCamera2/stack/mm-lib2d-interface/test/mm_lib2d_test.c new file mode 100644 index 0000000..908a4a6 --- /dev/null +++ b/camera/QCamera2/stack/mm-lib2d-interface/test/mm_lib2d_test.c @@ -0,0 +1,543 @@ +/* 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 <dlfcn.h> +#include <stdbool.h> +#include <stdlib.h> +#include <sys/time.h> + +// Camera dependencies +#include "img_buffer.h" +#include "mm_lib2d.h" + + +#define ENABLE_OUTPUT_DUMP 1 +#define ALIGN4K 4032 +#define ALIGN(a, b) (((a) + (b)) & ~(b)) + + +/** 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); \ + printf(" ] written size %zu \n", __LINE__, len); \ + fclose(fp); \ + } else { \ + printf(" ] open %s failed \n", __LINE__, 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, p_addr2, 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); \ + printf(" ] written %zu %zu \n", __LINE__, len1, len2); \ + fclose(fp); \ + } else { \ + printf(" ] open %s failed \n", __LINE__, filename); \ + } \ +}) + +/** img_lib_buffert + * @ptr: handle to the imglib library + * @img_buffer_get: function pointer to img_buffer_get + * @img_buffer_release: function pointer to img_buffer_release + * @img_buffer_cacheops: function pointer to img_buffer_cacheops +**/ +typedef struct { + void *ptr; + int (*img_buffer_get)(img_buf_type_t type, int heapid, int8_t cached, int length, + img_mem_handle_t *p_handle); + int (*img_buffer_release)(img_mem_handle_t *p_handle); + int (*img_buffer_cacheops)(img_mem_handle_t *p_handle, img_cache_ops_t ops, + img_mem_alloc_type_t mem_alloc_type); +} img_lib_buffert; + +/** input_yuv_data + * @filename: input test filename + * @format: format of the input yuv frame + * @wdith: wdith of the input yuv frame + * @height: height of the input yuv frame + * @stride: stride of the input yuv frame + * @offset: offset to the yuv data in the input file +**/ +typedef struct input_yuv_data_t { + char filename[512]; + cam_format_t format; + int32_t wdith; + int32_t height; + int32_t stride; + int32_t offset; +} input_yuv_data; + +input_yuv_data input_nv21[] = { + {"sample0_768x512.yuv", CAM_FORMAT_YUV_420_NV21, 768, 512, 768, 0}, + {"sample1_3200x2400.yuv", CAM_FORMAT_YUV_420_NV21, 3200, 2400, 3200, 0}, + {"sample2_1920x1080.yuv", CAM_FORMAT_YUV_420_NV21, 1920, 1080, 1920, 0}, + {"sample3_3200x2400.yuv", CAM_FORMAT_YUV_420_NV21, 3200, 2400, 3200, 0}, + {"sample4_4208x3120.yuv", CAM_FORMAT_YUV_420_NV21, 4208, 3120, 4208, 0}, + {"sample5_1984x2592.yuv", CAM_FORMAT_YUV_420_NV21, 1984, 2592, 1984, 0}, + {"sample6_4000_3000.yuv", CAM_FORMAT_YUV_420_NV21, 4000, 3000, 4000, 0}, + {"sample7_3200_2400.yuv", CAM_FORMAT_YUV_420_NV21, 3200, 2400, 3200, 0}, + {"sample8_3008_4000.yuv", CAM_FORMAT_YUV_420_NV21, 3008, 4000, 3008, 0}, + {"sample9_5312x2988.yuv", CAM_FORMAT_YUV_420_NV21, 5312, 2988, 5312, 0}, + {"sample10_4128x3096.yuv", CAM_FORMAT_YUV_420_NV21, 4128, 3096, 4128, 0}, + {"sample11_4208x3120.yuv", CAM_FORMAT_YUV_420_NV21, 4208, 3120, 4208, 0}, + {"sample12_3200x2400.yuv", CAM_FORMAT_YUV_420_NV21, 3200, 2400, 3200, 0}, + {"sample13_width_1080_height_1440_stride_1088.yuv", CAM_FORMAT_YUV_420_NV21, 1080, 1440, 1088, 0}, + {"sample14_width_1080_height_1920_stride_1088.yuv", CAM_FORMAT_YUV_420_NV21, 1080, 1920, 1088, 0}, + {"sample15_width_1944_height_2592_stride_1984.yuv", CAM_FORMAT_YUV_420_NV21, 1944, 2592, 1984, 0}, + {"sample16_width_3000_height_4000_stride_3008.yuv", CAM_FORMAT_YUV_420_NV21, 3000, 4000, 3008, 0}, + {"sample17_width_3120_height_4208_stride_3136.yuv", CAM_FORMAT_YUV_420_NV21, 3120, 4208, 3136, 0}, + {"sample18_width_3200_height_2400_stride_3200.yuv", CAM_FORMAT_YUV_420_NV21, 3200, 2400, 3200, 0}, + {"sample19_width_1944_height_2592_stride_1984.yuv", CAM_FORMAT_YUV_420_NV21, 1944, 2592, 1984, 0}, +}; + +// assuming buffer format is always ARGB +void lib2d_dump_tga(void *addr, cam_format_t format, int width, + int height, int stride, char *fname) +{ + int i, j; + FILE *f; + unsigned char *pb = (unsigned char *)addr; + uint32_t *pd = (uint32_t *)addr; + int bpp = 32; + + f = fopen(fname, "wb"); + if (f) { + // header + fprintf(f, "%c%c%c%c", 0, 0, 2, 0); + fprintf(f, "%c%c%c%c", 0, 0, 0, 0); + fprintf(f, "%c%c%c%c", 0, 0, 0, 0); + fprintf(f, "%c%c%c%c", width & 0xff, width >> 8, height & 0xff, height >> 8); + fprintf(f, "%c%c", bpp, 32); + + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + fprintf(f, "%c%c%c%c", + pd[(i*stride>>2)+j] & 0xff, // b + (pd[(i*stride>>2)+j] >> 8) & 0xff, // g + (pd[(i*stride>>2)+j] >> 16) & 0xff, // r + (pd[(i*stride>>2)+j] >> 24) & 0xff); // a + } + } + fclose(f); + } +} + +/** + * Function: lib2d_test_client_cb + * + * Description: Callback that is called on completion of requested job. + * + * Input parameters: + * userdata - App userdata + * jobid - job id that is finished execution + * + * Return values: + * MM_LIB2D_SUCCESS + * MM_LIB2D_ERR_GENERAL + * + * Notes: none + **/ +lib2d_error lib2d_test_client_cb(void *userdata, int jobid) +{ + printf("%s %d, jobid=%d \n", __LINE__, jobid); + return MM_LIB2D_SUCCESS; +} + +/** + * Function: lib2d_test_load_input_yuv_data + * + * Description: Loads yuv data from input file. + * + * Input parameters: + * fileName - input yuv filename + * offset - offset to the yuv data in the input file + * y_size - y plane size in input yuv file + * crcb_size - crcb plane size in input yuv file + * crcb_offset - crcb offset in the memory at + * which crcb data need to be loaded + * addr - y plane memory address where y plane + * data need to be loaded. + * + * Return values: + * MM_LIB2D_SUCCESS + * MM_LIB2D_ERR_GENERAL + * + * Notes: none + **/ +lib2d_error lib2d_test_load_input_yuv_data(char *fileName, int offset, + int32_t y_size, int32_t crcb_size, int32_t crcb_offset, + void *addr) +{ + size_t i; + FILE *fp = 0; + void *y_ptr = addr; + void *crcb_ptr = (uint8_t *)addr + crcb_offset; + + printf("y_ptr=%p, crcb_ptr=%p \n", y_ptr, crcb_ptr); + + fp = fopen(fileName, "rb"); + if(fp) { + if(offset) { + fseek(fp, offset, SEEK_SET); + } + i = fread(y_ptr, 1, y_size, fp); + i = fread(crcb_ptr, 1, crcb_size, fp); + + fclose( fp ); + } else { + printf("failed to open file %s \n", fileName); + return MM_LIB2D_ERR_GENERAL; + } + + return MM_LIB2D_SUCCESS; +} + +/** + * Function: lib2d_test_load_input_yuv_data + * + * Description: Loads yuv data from input file. + * + * Input parameters: + * fileName - input yuv filename + * offset - offset to the yuv data in the input file + * input_yuv_stride - y plane stride in input yuv file + * y_plane_stride - y plane stride in buffer memory + * height - height of yuv image + * crcb_offset - crcb offset in the memory at + * which crcb data need to be loaded + * addr - y plane memory address where y plane + * data need to be loaded. + * + * Return values: + * MM_LIB2D_SUCCESS + * MM_LIB2D_ERR_GENERAL + * + * Notes: none + **/ +lib2d_error lib2d_test_load_input_yuv_data_linebyline(char *fileName, + int offset, int32_t input_yuv_stride, int32_t y_plane_stride, + int32_t height, int32_t crcb_offset, void *addr) +{ + size_t i; + FILE *fp = 0; + void *y_ptr = addr; + void *crcb_ptr = (uint8_t *)addr + crcb_offset; + + printf("y_ptr=%p, crcb_ptr=%p \n", y_ptr, crcb_ptr); + + fp = fopen(fileName, "rb"); + if(fp) { + if(offset) { + fseek(fp, offset, SEEK_SET); + } + if (input_yuv_stride == y_plane_stride) { + //load y plane + i = fread(y_ptr, 1, (input_yuv_stride * height), fp); + // load UV plane + i = fread(crcb_ptr, 1, (input_yuv_stride * height / 2), fp); + } else { + int line = 0; + // load Y plane + for (line = 0;line < height; line++) { + i = fread(y_ptr, 1, input_yuv_stride, fp); + y_ptr = (void *)((uint8_t *)y_ptr + y_plane_stride); + } + for (line = 0;line < height; line++) { + i = fread(crcb_ptr, 1, input_yuv_stride, fp); + crcb_ptr = (void *)((uint8_t *)crcb_ptr + y_plane_stride); + } + } + + fclose( fp ); + } else { + printf("failed to open file %s \n", fileName); + return MM_LIB2D_ERR_GENERAL; + } + + return MM_LIB2D_SUCCESS; +} + +/** + * Function: main + * + * Description: main function for execution + * + * Input parameters: + * argc - no.of input arguments + * argv - list of arguments + * + * Return values: + * 0 on success + * -1 on failure + * + * Notes: none + **/ +int main(int32_t argc, const char * argv[]) +{ + void *lib2d_handle = NULL; + lib2d_error lib2d_err = MM_LIB2D_SUCCESS; + mm_lib2d_buffer src_buffer = {0}; + mm_lib2d_buffer dst_buffer = {0}; + int8_t ret = IMG_SUCCESS; + int32_t width = 0; + int32_t height = 0; + int32_t input_yuv_stride = 0; + int32_t stride = 0; + int32_t y_plane_stride = 0; + int32_t crcb_plane_stride = 0; + int32_t y_plane_size = 0; + int32_t y_plane_size_align = 0; + int32_t crcb_plane_size = 0; + int32_t yuv_size = 0; + int32_t rgb_size = 0; + img_mem_handle_t m_yuv_memHandle = { 0 }; + img_mem_handle_t m_rgb_memHandle = { 0 }; + char filename_in[512] = { 0 }; + char filename_out[512] = { 0 }; + char filename_raw[512] = { 0 }; + int32_t offset = 0; + unsigned int total_tests = 1; + cam_format_t format = CAM_FORMAT_YUV_420_NV21; + unsigned int index; + const char *filename; + + // Open Imglib library and get the function pointers for + // buffer allocation, free, cacheops + img_lib_buffert img_lib; + img_lib.ptr = dlopen("libmmcamera_imglib.so", RTLD_NOW); + if (!img_lib.ptr) { + printf("%s ERROR: couldn't dlopen libmmcamera_imglib.so: %s", + dlerror()); + return -1; + } + + /* Get function pointer for functions to allocate ion memory */ + *(void **)&img_lib.img_buffer_get = + dlsym(img_lib.ptr, "img_buffer_get"); + *(void **)&img_lib.img_buffer_release = + dlsym(img_lib.ptr, "img_buffer_release"); + *(void **)&img_lib.img_buffer_cacheops = + dlsym(img_lib.ptr, "img_buffer_cacheops"); + + /* Validate function pointers */ + if ((img_lib.img_buffer_get == NULL) || + (img_lib.img_buffer_release == NULL) || + (img_lib.img_buffer_cacheops == NULL)) { + printf(" ERROR mapping symbols from libmmcamera_imglib.so"); + dlclose(img_lib.ptr); + return -1; + } + + lib2d_err = mm_lib2d_init(MM_LIB2D_SYNC_MODE, CAM_FORMAT_YUV_420_NV21, + CAM_FORMAT_8888_ARGB, &lib2d_handle); + if ((lib2d_err != MM_LIB2D_SUCCESS) || (lib2d_handle == NULL)) { + return -1; + } + + bool run_default = FALSE; + + if ( argc == 7) { + filename = argv[1]; + width = (uint32_t)atoi(argv[2]); + height = (uint32_t)atoi(argv[3]); + input_yuv_stride = (uint32_t)atoi(argv[4]); + offset = (uint32_t)atoi(argv[5]); + format = (uint32_t)atoi(argv[6]); + run_default = TRUE; + printf("Running user provided conversion \n"); + } + else { + total_tests = sizeof(input_nv21)/sizeof(input_yuv_data); + printf("usage: <binary> <filname> <width> <height> " + "<stride> <offset> <format> \n"); + } + + for (index = 0; index < total_tests; index++) + { + if(run_default == FALSE) { + filename = input_nv21[index].filename; + width = input_nv21[index].wdith; + height = input_nv21[index].height; + input_yuv_stride = input_nv21[index].stride; + offset = input_nv21[index].offset; + format = input_nv21[index].format; + } + + snprintf(filename_in, 512, "/data/lib2d/input/%s", filename); + snprintf(filename_out, 512, "/data/lib2d/output/%s.tga", filename); + snprintf(filename_raw, 512, "/data/lib2d/output/%s.rgba", filename); + + printf("-----------------Running test=%d/%d------------------------- \n", + index+1, total_tests); + printf("filename=%s, full path=%s, width=%d, height=%d, stride=%d \n", + filename, filename_in, width, height, stride); + + // Allocate NV12 buffer + y_plane_stride = ALIGN(width, 32); + y_plane_size = y_plane_stride * height; + y_plane_size_align = ALIGN(y_plane_size, ALIGN4K); + crcb_plane_stride = y_plane_stride; + crcb_plane_size = crcb_plane_stride * height / 2; + yuv_size = y_plane_size_align + crcb_plane_size; + ret = img_lib.img_buffer_get(IMG_BUFFER_ION_IOMMU, -1, TRUE, + yuv_size, &m_yuv_memHandle); + if (ret != IMG_SUCCESS) { + printf(" ] Error, img buf get failed \n"); + goto deinit; + } + + printf("%s %d yuv buffer properties : w=%d, h=%d, y_stride=%d, " + "crcb_stride=%d, y_size=%d, crcb_size=%d, yuv_size=%d, " + "crcb_offset=%d \n", + __LINE__, + width, height, y_plane_stride, crcb_plane_stride, y_plane_size, + crcb_plane_size, yuv_size, y_plane_size_align); + printf("%s %d yuv buffer properties : fd=%d, ptr=%p, size=%d \n", + __LINE__, m_yuv_memHandle.fd, m_yuv_memHandle.vaddr, + m_yuv_memHandle.length); + + // Allocate ARGB buffer + stride = width * 4; + stride = ALIGN(stride, 32); + rgb_size = stride * height; + ret = img_lib.img_buffer_get(IMG_BUFFER_ION_IOMMU, -1, TRUE, + rgb_size, &m_rgb_memHandle); + if (ret != IMG_SUCCESS) { + printf(" ] Error, img buf get failed"); + img_lib.img_buffer_release(&m_yuv_memHandle); + goto deinit; + } + + printf("%s %d rgb buffer properties : w=%d, h=%d, stride=%d, size=%d \n", + __LINE__, width, height, stride, rgb_size); + printf("%s %d rgb buffer properties : fd=%d, ptr=%p, size=%d \n", + __LINE__, m_rgb_memHandle.fd, m_rgb_memHandle.vaddr, + m_rgb_memHandle.length); + +#if 0 + lib2d_err = lib2d_test_load_input_yuv_data(filename_in, offset, + (input_yuv_stride * height), (input_yuv_stride * height / 2), y_plane_size_align, + m_yuv_memHandle.vaddr); + if (lib2d_err != MM_LIB2D_SUCCESS) { + printf(" ] Error loading the input buffer \n"); + goto release; + } +#else + lib2d_err = lib2d_test_load_input_yuv_data_linebyline(filename_in, offset, + input_yuv_stride, y_plane_stride,height, y_plane_size_align, + m_yuv_memHandle.vaddr); + if (lib2d_err != MM_LIB2D_SUCCESS) { + printf(" ] Error loading the input buffer \n"); + goto release; + } +#endif + // Setup source buffer + src_buffer.buffer_type = MM_LIB2D_BUFFER_TYPE_YUV; + src_buffer.yuv_buffer.fd = m_yuv_memHandle.fd; + src_buffer.yuv_buffer.format = format; + src_buffer.yuv_buffer.width = width; + src_buffer.yuv_buffer.height = height; + src_buffer.yuv_buffer.plane0 = m_yuv_memHandle.vaddr; + src_buffer.yuv_buffer.stride0 = y_plane_stride; + src_buffer.yuv_buffer.plane1 = (int8_t *)m_yuv_memHandle.vaddr + + y_plane_size_align; + src_buffer.yuv_buffer.stride1 = crcb_plane_stride; + + // Setup dst buffer + dst_buffer.buffer_type = MM_LIB2D_BUFFER_TYPE_RGB; + dst_buffer.rgb_buffer.fd = m_rgb_memHandle.fd; + dst_buffer.rgb_buffer.format = CAM_FORMAT_8888_ARGB; + dst_buffer.rgb_buffer.width = width; + dst_buffer.rgb_buffer.height = height; + dst_buffer.rgb_buffer.buffer = m_rgb_memHandle.vaddr; + dst_buffer.rgb_buffer.stride = stride; + + img_lib.img_buffer_cacheops(&m_yuv_memHandle, + IMG_CACHE_CLEAN_INV, IMG_INTERNAL); + + lib2d_err = mm_lib2d_start_job(lib2d_handle, &src_buffer, &dst_buffer, + index, NULL, lib2d_test_client_cb, 0); + if (lib2d_err != MM_LIB2D_SUCCESS) { + printf(" ] Error in mm_lib2d_start_job \n"); + goto release; + } + + img_lib.img_buffer_cacheops(&m_rgb_memHandle, + IMG_CACHE_CLEAN_INV, IMG_INTERNAL); + +#ifdef ENABLE_OUTPUT_DUMP + // Dump output files + // snprintf(filename_in, 512, "/data/lib2d/output/%s", filename); + // DUMP_TO_FILE2(filename_in, src_buffer.yuv_buffer.plane0, y_plane_size, src_buffer.yuv_buffer.plane1, crcb_plane_size); + // DUMP_TO_FILE(filename_raw, dst_buffer.rgb_buffer.buffer, rgb_size); + printf("Dumping output file %s \n", filename_out); + lib2d_dump_tga(dst_buffer.rgb_buffer.buffer, 1, + width, height, stride, filename_out); +#endif + + img_lib.img_buffer_release(&m_rgb_memHandle); + img_lib.img_buffer_release(&m_yuv_memHandle); + } + + mm_lib2d_deinit(lib2d_handle); + + return 0; + +release: + img_lib.img_buffer_release(&m_rgb_memHandle); + img_lib.img_buffer_release(&m_yuv_memHandle); +deinit: + mm_lib2d_deinit(lib2d_handle); + printf("%s %d some error happened, tests completed = %d/%d \n", + __LINE__, index - 1, total_tests); + return -1; +} + + |