• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * xcam_handle.cpp - xcam handle implementation
3  *
4  *  Copyright (c) 2017 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: Wind Yuan <feng.yuan@intel.com>
19  */
20 
21 #include <xcam_utils.h>
22 #include <xcam_handle.h>
23 #include <dma_video_buffer.h>
24 #include "context_priv.h"
25 #include <stdarg.h>
26 #if HAVE_LIBDRM
27 #include <drm_bo_buffer.h>
28 #endif
29 
30 using namespace XCam;
31 
32 XCamHandle *
xcam_create_handle(const char * name)33 xcam_create_handle (const char *name)
34 {
35     ContextBase *context = NULL;
36 
37     if (handle_name_equal (name, HandleType3DNR)) {
38         context = new NR3DContext;
39     } else if (handle_name_equal (name, HandleTypeWaveletNR)) {
40         context = new NRWaveletContext;
41     } else if (handle_name_equal (name, HandleTypeFisheye)) {
42         context = new FisheyeContext;
43     } else if (handle_name_equal (name, HandleTypeDefog)) {
44         context = new DefogContext;
45     } else if (handle_name_equal (name, HandleTypeDVS)) {
46         context = new DVSContext;
47     } else if (handle_name_equal (name, HandleTypeStitch)) {
48         context = new StitchContext;
49     } else {
50         XCAM_LOG_ERROR ("create handle failed with unsupported type:%s", name);
51         return NULL;
52     }
53 
54     return HANDLE_CAST (context);
55 }
56 
57 void
xcam_destroy_handle(XCamHandle * handle)58 xcam_destroy_handle (XCamHandle *handle)
59 {
60     if (handle)
61         delete CONTEXT_BASE_CAST (handle);
62 }
63 
64 XCamReturn
xcam_handle_init(XCamHandle * handle)65 xcam_handle_init (XCamHandle *handle)
66 {
67     ContextBase *context = CONTEXT_BASE_CAST (handle);
68     SmartPtr<CLImageHandler> handler_ptr;
69     XCamReturn ret = XCAM_RETURN_NO_ERROR;
70 
71     XCAM_FAIL_RETURN (
72         ERROR, context, XCAM_RETURN_ERROR_PARAM,
73         "xcam_handler_init failed, handle can NOT be NULL, did you have xcam_create_handler first?");
74 
75     ret = context->init_handler ();
76     XCAM_FAIL_RETURN (
77         ERROR, ret == XCAM_RETURN_NO_ERROR, ret,
78         "xcam_handler_init, create handle ptr(%s) failed", context->get_type_name ());
79 
80     return XCAM_RETURN_NO_ERROR;
81 }
82 
83 XCamReturn
xcam_handle_uinit(XCamHandle * handle)84 xcam_handle_uinit (XCamHandle *handle)
85 {
86     ContextBase *context = CONTEXT_BASE_CAST (handle);
87 
88     XCAM_FAIL_RETURN (
89         ERROR, context, XCAM_RETURN_ERROR_PARAM,
90         "xcam_handler_uinit failed, handle can NOT be NULL");
91 
92     return context->uinit_handler ();
93 }
94 
95 XCamReturn
xcam_handle_get_usage(XCamHandle * handle,char * usage_buf,int * usage_len)96 xcam_handle_get_usage (XCamHandle *handle, char *usage_buf, int *usage_len)
97 {
98     ContextBase *context = CONTEXT_BASE_CAST (handle);
99     XCAM_FAIL_RETURN (
100         ERROR, context, XCAM_RETURN_ERROR_PARAM,
101         "xcam_handle_get_usage failed, handle can NOT be NULL");
102 
103     const char *usage = context->get_usage ();
104     int len = strlen (usage) + 1;
105     if (len < *usage_len)
106         len = *usage_len;
107     strncpy (usage_buf, usage, len - 1);
108     *usage_len = len;
109     return XCAM_RETURN_NO_ERROR;
110 }
111 
112 XCamReturn
xcam_handle_set_parameters(XCamHandle * handle,const char * field,...)113 xcam_handle_set_parameters (
114     XCamHandle *handle, const char *field, ...)
115 {
116     ContextBase *context = CONTEXT_BASE_CAST (handle);
117     ContextParams params;
118 
119     XCAM_FAIL_RETURN (
120         ERROR, context, XCAM_RETURN_ERROR_PARAM,
121         "xcam_handle_set_parameters failed, handle can NOT be NULL");
122 
123     const char *vfield, *vvalue;
124     vfield = field;
125     va_list args;
126     va_start (args, field);
127     while (vfield) {
128         vvalue = va_arg (args, const char *);
129         XCAM_FAIL_RETURN (
130             ERROR, vvalue, XCAM_RETURN_ERROR_PARAM,
131             "xcam_handle(%s) set_parameters failed, param(field:%s) value should never be NULL",
132             context->get_type_name (), vfield);
133 
134         params[vfield] = vvalue;
135         vfield = va_arg (args, const char *);
136     }
137     va_end (args);
138 
139     return context->set_parameters (params);
140 }
141 
142 SmartPtr<VideoBuffer>
external_buf_to_drm_buf(XCamVideoBuffer * buf)143 external_buf_to_drm_buf (XCamVideoBuffer *buf)
144 {
145 #if HAVE_LIBDRM
146     SmartPtr<DrmDisplay> display = DrmDisplay::instance ();
147     SmartPtr<DmaVideoBuffer> dma_buf;
148     SmartPtr<VideoBuffer> drm_buf;
149     SmartPtr<VideoBuffer> video_buf;
150 
151     dma_buf = external_buf_to_dma_buf (buf);
152 
153     XCAM_FAIL_RETURN (
154         ERROR, dma_buf.ptr (), NULL,
155         "external_buf_to_drm_buf failed");
156 
157     video_buf = dma_buf;
158     XCAM_ASSERT (display.ptr ());
159     drm_buf = display->convert_to_drm_bo_buf (display, video_buf);
160     return drm_buf;
161 #else
162     XCAM_LOG_ERROR ("VideoBuffer doesn't support drm buf");
163 
164     XCAM_UNUSED (buf);
165     return NULL;
166 #endif
167 }
168 
169 SmartPtr<VideoBuffer>
copy_external_buf_to_drm_buf(XCamHandle * handle,XCamVideoBuffer * buf)170 copy_external_buf_to_drm_buf (XCamHandle *handle, XCamVideoBuffer *buf)
171 {
172     if (!handle || !buf) {
173         XCAM_LOG_WARNING ("xcam handle can NOT be NULL");
174         return NULL;
175     }
176 
177     ContextBase *context = CONTEXT_BASE_CAST (handle);
178     if (!context) {
179         XCAM_LOG_WARNING ("xcam handle context can NOT be NULL");
180         return NULL;
181     }
182 
183     const XCamVideoBufferInfo src_info = buf->info;
184     uint8_t* src = buf->map (buf);
185     uint8_t* p_src = src;
186     if (!src) {
187         XCAM_LOG_WARNING ("xcam handle map buffer failed");
188         return NULL;
189     }
190     uint32_t height = src_info.height;
191 
192     SmartPtr<BufferPool> buf_pool = context->get_input_buffer_pool();
193     XCAM_ASSERT (buf_pool.ptr ());
194     SmartPtr<VideoBuffer> video_buf = buf_pool->get_buffer (buf_pool);
195     XCAM_ASSERT (video_buf.ptr ());
196     const XCamVideoBufferInfo dest_info = video_buf->get_video_info ();
197 
198     uint8_t* dest = video_buf->map ();
199     uint8_t* p_dest = dest;
200 
201     for (uint32_t index = 0; index < src_info.components; index++) {
202         src += (int32_t)src_info.offsets[index];
203         p_src = src;
204 
205         dest += dest_info.offsets[index];
206         p_dest = dest;
207         if (src_info.format == V4L2_PIX_FMT_NV12) {
208             height = height >> index;
209         }
210         for (uint32_t i = 0; i < height; i++) {
211             memcpy (p_dest, p_src, src_info.strides[index]);
212             p_src += src_info.strides[index];
213             p_dest += dest_info.strides[index];
214         }
215     }
216 
217     buf->unmap (buf);
218     video_buf->unmap ();
219 
220     return video_buf;
221 }
222 
223 XCamReturn
xcam_handle_execute(XCamHandle * handle,XCamVideoBuffer * buf_in,XCamVideoBuffer ** buf_out)224 xcam_handle_execute (XCamHandle *handle, XCamVideoBuffer *buf_in, XCamVideoBuffer **buf_out)
225 {
226     ContextBase *context = CONTEXT_BASE_CAST (handle);
227     SmartPtr<VideoBuffer> input, output;
228 
229     XCAM_FAIL_RETURN (
230         ERROR, context && buf_in && buf_out, XCAM_RETURN_ERROR_PARAM,
231         "xcam_handle_execute failed, either of handle/buf_in/buf_out can NOT be NULL");
232 
233     XCAM_FAIL_RETURN (
234         ERROR, context->get_handler().ptr (), XCAM_RETURN_ERROR_PARAM,
235         "context (%s) failed, handler was not initialized", context->get_type_name ());
236 
237     if (buf_in->mem_type == XCAM_MEM_TYPE_GPU) {
238         input = external_buf_to_drm_buf (buf_in);
239     } else {
240         input = copy_external_buf_to_drm_buf (handle, buf_in);
241     }
242     XCAM_FAIL_RETURN (
243         ERROR, input.ptr (), XCAM_RETURN_ERROR_MEM,
244         "xcam_handle(%s) execute failed, buf_in convert to DRM buffer failed.",
245         context->get_type_name ());
246 
247     if (*buf_out) {
248         output = external_buf_to_drm_buf (*buf_out);
249         XCAM_FAIL_RETURN (
250             ERROR, output.ptr (), XCAM_RETURN_ERROR_MEM,
251             "xcam_handle(%s) execute failed, buf_out set but convert to DRM buffer failed.",
252             context->get_type_name ());
253     }
254 
255     XCamReturn ret = context->execute (input, output);
256 
257     XCAM_FAIL_RETURN (
258         ERROR, ret == XCAM_RETURN_NO_ERROR || ret == XCAM_RETURN_BYPASS,
259         ret,
260         "context (%s) failed, handler execute failed", context->get_type_name ());
261 
262     if (*buf_out == NULL && output.ptr ()) {
263         XCamVideoBuffer *new_buf = convert_to_external_buffer (output);
264         XCAM_FAIL_RETURN (
265             ERROR, new_buf, XCAM_RETURN_ERROR_MEM,
266             "xcam_handle(%s) execute failed, out buffer can't convert to external buffer.",
267             context->get_type_name ());
268         *buf_out = new_buf;
269     }
270     return ret;
271 }
272