blob: 37a99b1ba0a7a662a22530ea056abade9bfd7d47 [file] [log] [blame]
Wind Yuanf2b7a8a2017-03-07 06:29:00 -05001/*
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"
Yinhang Liu6987f2b2017-09-30 10:39:58 +080025#include <stdarg.h>
Yinhang Liud6566762017-12-18 19:48:53 +080026#if HAVE_LIBDRM
27#include <drm_bo_buffer.h>
28#endif
Wind Yuanf2b7a8a2017-03-07 06:29:00 -050029
30using namespace XCam;
31
32XCamHandle *
33xcam_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
57void
58xcam_destroy_handle (XCamHandle *handle)
59{
60 if (handle)
61 delete CONTEXT_BASE_CAST (handle);
62}
63
64XCamReturn
65xcam_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
83XCamReturn
84xcam_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
95XCamReturn
96xcam_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
112XCamReturn
113xcam_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
Yinhang Liu6b5f7102017-09-15 16:04:47 +0800142SmartPtr<VideoBuffer>
Wind Yuanf2b7a8a2017-03-07 06:29:00 -0500143external_buf_to_drm_buf (XCamVideoBuffer *buf)
144{
Yinhang Liu6987f2b2017-09-30 10:39:58 +0800145#if HAVE_LIBDRM
Wind Yuanf2b7a8a2017-03-07 06:29:00 -0500146 SmartPtr<DrmDisplay> display = DrmDisplay::instance ();
147 SmartPtr<DmaVideoBuffer> dma_buf;
Yinhang Liu6b5f7102017-09-15 16:04:47 +0800148 SmartPtr<VideoBuffer> drm_buf;
Wind Yuanf2b7a8a2017-03-07 06:29:00 -0500149 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
zongwave3e73fa22017-03-24 17:50:33 +0800157 video_buf = dma_buf;
Wind Yuanf2b7a8a2017-03-07 06:29:00 -0500158 XCAM_ASSERT (display.ptr ());
159 drm_buf = display->convert_to_drm_bo_buf (display, video_buf);
Yinhang Liud6566762017-12-18 19:48:53 +0800160 return drm_buf;
Yinhang Liu6987f2b2017-09-30 10:39:58 +0800161#else
162 XCAM_LOG_ERROR ("VideoBuffer doesn't support drm buf");
163
164 XCAM_UNUSED (buf);
165 return NULL;
166#endif
Wind Yuanf2b7a8a2017-03-07 06:29:00 -0500167}
168
Yinhang Liu6b5f7102017-09-15 16:04:47 +0800169SmartPtr<VideoBuffer>
zongwave3e73fa22017-03-24 17:50:33 +0800170copy_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
Yinhang Liu6b5f7102017-09-15 16:04:47 +0800192 SmartPtr<BufferPool> buf_pool = context->get_input_buffer_pool();
zongwave3e73fa22017-03-24 17:50:33 +0800193 XCAM_ASSERT (buf_pool.ptr ());
Yinhang Liu6b5f7102017-09-15 16:04:47 +0800194 SmartPtr<VideoBuffer> video_buf = buf_pool->get_buffer (buf_pool);
195 XCAM_ASSERT (video_buf.ptr ());
zongwave3e73fa22017-03-24 17:50:33 +0800196 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++) {
zongwavee99f3f02017-03-28 13:27:25 +0800202 src += (int32_t)src_info.offsets[index];
zongwave3e73fa22017-03-24 17:50:33 +0800203 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
Yinhang Liu6b5f7102017-09-15 16:04:47 +0800220 return video_buf;
zongwave3e73fa22017-03-24 17:50:33 +0800221}
222
Wind Yuanf2b7a8a2017-03-07 06:29:00 -0500223XCamReturn
224xcam_handle_execute (XCamHandle *handle, XCamVideoBuffer *buf_in, XCamVideoBuffer **buf_out)
225{
226 ContextBase *context = CONTEXT_BASE_CAST (handle);
Yinhang Liu6b5f7102017-09-15 16:04:47 +0800227 SmartPtr<VideoBuffer> input, output;
Wind Yuanf2b7a8a2017-03-07 06:29:00 -0500228
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
zongwave3e73fa22017-03-24 17:50:33 +0800237 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 }
Wind Yuanf2b7a8a2017-03-07 06:29:00 -0500242 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 ()) {
Wind Yuan6d144ce2017-08-16 18:29:29 +0800263 XCamVideoBuffer *new_buf = convert_to_external_buffer (output);
Wind Yuanf2b7a8a2017-03-07 06:29:00 -0500264 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}