aboutsummaryrefslogtreecommitdiff
path: root/camera/QCamera2/stack/mm-lib2d-interface
diff options
context:
space:
mode:
authorPrateek Chaubey <chaubeyprateek@gmail.com>2018-01-07 20:55:14 +0530
committerDavide Garberi <dade.garberi@gmail.com>2018-01-19 14:09:15 +0100
commit6616278131edd80a12545085e06ee6b0e0a0a788 (patch)
tree0aef88ed11809a9d67f6abe4dc2ff782a14737e2 /camera/QCamera2/stack/mm-lib2d-interface
parentcc4ccf34871da343111bf68d16ba4e4c67cac1dc (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')
-rw-r--r--camera/QCamera2/stack/mm-lib2d-interface/Android.mk39
-rw-r--r--camera/QCamera2/stack/mm-lib2d-interface/inc/mm_lib2d.h209
-rw-r--r--camera/QCamera2/stack/mm-lib2d-interface/src/mm_lib2d.c604
-rw-r--r--camera/QCamera2/stack/mm-lib2d-interface/test/Android.mk37
-rw-r--r--camera/QCamera2/stack/mm-lib2d-interface/test/mm_lib2d_test.c543
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;
+}
+
+