• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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