1 /*
2 * xcam_plugin_dvs.cpp - Digital Video Stabilizer plugin
3 *
4 * Copyright (c) 2014-2016 Intel Corporation
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * Author: Zong Wei <wei.zong@intel.com>
19 */
20 #include <base/xcam_common.h>
21 #include <base/xcam_smart_description.h>
22 #include <base/xcam_smart_result.h>
23 #include <base/xcam_3a_result.h>
24 #include <base/xcam_buffer.h>
25
26 #include <smartptr.h>
27 #if HAVE_LIBDRM
28 #include <drm_display.h>
29 #endif
30 #include <dma_video_buffer.h>
31
32 #include <ocl/cl_utils.h>
33 #include <ocl/cl_context.h>
34 #include <ocl/cl_device.h>
35 #include <ocl/cl_memory.h>
36
37 #include <opencv2/core/ocl.hpp>
38
39 #include "libdvs/libdvs.h"
40
41 #define DVS_MOTION_FILTER_RADIUS 15
42
43 struct DvsBuffer : public DvsData
44 {
45 XCamVideoBuffer* buffer;
46
DvsBufferDvsBuffer47 DvsBuffer () { }
48
DvsBufferDvsBuffer49 DvsBuffer (XCamVideoBuffer* buf, cv::UMat& frame)
50 : buffer (buf)
51 {
52 buffer->ref(buffer);
53 data = frame;
54 }
55
~DvsBufferDvsBuffer56 ~DvsBuffer () {
57 buffer->unref(buffer);
58 }
59 };
60
dvs_create_context(XCamSmartAnalysisContext ** context,uint32_t * async_mode,XcamPostResultsFunc post_func)61 XCamReturn dvs_create_context(XCamSmartAnalysisContext **context, uint32_t *async_mode, XcamPostResultsFunc post_func)
62 {
63 XCAM_UNUSED (async_mode);
64 XCAM_UNUSED (post_func);
65
66 DvsInterface* theDVS = NULL;
67
68 theDVS = getDigitalVideoStabilizer();
69 if (theDVS == NULL) {
70 return XCAM_RETURN_ERROR_MEM;
71 }
72 theDVS->init(640, 480, false);
73
74 *context = (XCamSmartAnalysisContext *)theDVS;
75
76 cl_platform_id platform_id = XCam::CLDevice::instance()->get_platform_id();
77 char* platform_name = XCam::CLDevice::instance()->get_platform_name ();
78 cl_device_id device_id = XCam::CLDevice::instance()->get_device_id();
79 cl_context cl_context_id = XCam::CLDevice::instance()->get_context()->get_context_id();
80
81 clRetainContext (cl_context_id);
82 cv::ocl::attachContext (platform_name, platform_id, cl_context_id, device_id);
83
84 return XCAM_RETURN_NO_ERROR;
85 }
86
dvs_destroy_context(XCamSmartAnalysisContext * context)87 XCamReturn dvs_destroy_context(XCamSmartAnalysisContext *context)
88 {
89 DvsInterface *theDVS = (DvsInterface *)context;
90
91 theDVS->release ();
92
93 delete (theDVS);
94
95 return XCAM_RETURN_NO_ERROR;
96 }
97
dvs_update_params(XCamSmartAnalysisContext * context,const XCamSmartAnalysisParam * params)98 XCamReturn dvs_update_params(XCamSmartAnalysisContext *context, const XCamSmartAnalysisParam *params)
99 {
100 XCAM_UNUSED (context);
101 XCAM_UNUSED (params);
102
103 return XCAM_RETURN_NO_ERROR;
104 }
105
dvs_analyze(XCamSmartAnalysisContext * context,XCamVideoBuffer * buffer,XCam3aResultHead * results[],uint32_t * res_count)106 XCamReturn dvs_analyze(XCamSmartAnalysisContext *context, XCamVideoBuffer *buffer, XCam3aResultHead *results[], uint32_t *res_count)
107 {
108 DvsInterface *theDVS = (DvsInterface *)context;
109 DvsResult dvsResult;
110
111 if (buffer->info.format != V4L2_PIX_FMT_NV12 || buffer->mem_type != XCAM_MEM_TYPE_PRIVATE_BO)
112 return XCAM_RETURN_ERROR_PARAM;
113
114 int buffer_fd = xcam_video_buffer_get_fd(buffer);
115 XCam::VideoBufferInfo buffer_info;
116 buffer_info.init (buffer->info.format, buffer->info.width, buffer->info.height,
117 buffer->info.aligned_width, buffer->info.aligned_height, buffer->info.size);
118 XCam::SmartPtr<XCam::VideoBuffer> new_buffer = new XCam::DmaVideoBuffer(buffer_info, buffer_fd);
119
120 XCam::SmartPtr<XCam::VideoBuffer> video_buffer;
121 #if HAVE_LIBDRM
122 XCam::SmartPtr<XCam::DrmDisplay> display = XCam::DrmDisplay::instance ();
123 video_buffer = display->convert_to_drm_bo_buf (display, new_buffer);
124 #else
125 video_buffer = new_buffer;
126 #endif
127
128 XCam::SmartPtr<XCam::CLContext> cl_Context = XCam::CLDevice::instance()->get_context();
129 XCam::SmartPtr<XCam::CLBuffer> cl_buffer = XCam::convert_to_clbuffer (cl_Context, video_buffer);
130 cl_mem cl_mem_id = cl_buffer->get_mem_id();
131
132 clRetainMemObject(cl_mem_id);
133 cv::UMat frame;
134 cv::ocl::convertFromBuffer(cl_mem_id, buffer->info.strides[0], buffer->info.height, buffer->info.width, CV_8U, frame);
135
136 DvsBuffer* dvs_buf = new DvsBuffer(buffer, frame);
137 //set default config
138 DvsConfig config;
139 memset(&config, 0, sizeof(DvsConfig));
140 config.use_ocl = true;
141 config.frame_width = buffer->info.width;
142 config.frame_height = buffer->info.height;
143 config.radius = DVS_MOTION_FILTER_RADIUS;
144 config.stdev = 10.0f;
145 config.features = 1000;
146 config.minDistance = 20.0f;
147
148 theDVS->setConfig(&config);
149
150 theDVS->nextStabilizedMotion(dvs_buf, &dvsResult);
151
152 delete(dvs_buf);
153
154 if ((dvsResult.frame_id < 0) && (dvsResult.valid == false))
155 {
156 results[0] = NULL;
157 *res_count = 0;
158 XCAM_LOG_WARNING ("dvs_analyze not ready! ");
159 } else {
160 XCamDVSResult *dvs_result = (XCamDVSResult *)malloc(sizeof(XCamDVSResult));
161 memset(dvs_result, 0, sizeof(XCamDVSResult));
162
163 dvs_result->head.type = XCAM_3A_RESULT_DVS;
164 dvs_result->head.process_type = XCAM_IMAGE_PROCESS_POST;
165 dvs_result->head.version = 0x080;
166 dvs_result->frame_id = dvsResult.frame_id;
167 dvs_result->frame_width = dvsResult.frame_width;
168 dvs_result->frame_height = dvsResult.frame_height;
169 memcpy(dvs_result->proj_mat, dvsResult.proj_mat, sizeof(DvsResult::proj_mat));
170
171 results[0] = (XCam3aResultHead *)dvs_result;
172 *res_count = 1;
173 }
174
175 return XCAM_RETURN_NO_ERROR;
176 }
177
dvs_free_results(XCamSmartAnalysisContext * context,XCam3aResultHead * results[],uint32_t res_count)178 void dvs_free_results(XCamSmartAnalysisContext *context, XCam3aResultHead *results[], uint32_t res_count)
179 {
180 XCAM_UNUSED (context);
181 for (uint32_t i = 0; i < res_count; ++i) {
182 if (results[i]) {
183 free (results[i]);
184 }
185 }
186 }
187
188 XCAM_BEGIN_DECLARE
189
190 XCamSmartAnalysisDescription xcam_smart_analysis_desciption =
191 {
192 0x080,
193 sizeof (XCamSmartAnalysisDescription),
194 10,
195 "digital_video_stabilizer",
196 dvs_create_context,
197 dvs_destroy_context,
198 dvs_update_params,
199 dvs_analyze,
200 dvs_free_results,
201 };
202
203 XCAM_END_DECLARE
204
205