1 /*
2 * soft_geo_mapper.cpp - soft geometry mapper 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 "soft_geo_mapper.h"
22 #include "soft_geo_tasks_priv.h"
23
24 #define XCAM_GEO_MAP_ALIGNMENT_X 8
25 #define XCAM_GEO_MAP_ALIGNMENT_Y 2
26
27 namespace XCam {
28
29 DECLARE_WORK_CALLBACK (CbGeoMapTask, SoftGeoMapper, remap_task_done);
30
SoftGeoMapper(const char * name)31 SoftGeoMapper::SoftGeoMapper (const char *name)
32 : SoftHandler (name)
33 {
34 }
35
~SoftGeoMapper()36 SoftGeoMapper::~SoftGeoMapper ()
37 {
38 }
39
40 bool
set_lookup_table(const PointFloat2 * data,uint32_t width,uint32_t height)41 SoftGeoMapper::set_lookup_table (const PointFloat2 *data, uint32_t width, uint32_t height)
42 {
43 XCAM_FAIL_RETURN(
44 ERROR, width > 1 && height > 1 && data, false,
45 "SoftGeoMapper(%s) set loop up table need w>1 and h>1, but width:%d, height:%d",
46 XCAM_STR (get_name ()), width, height);
47
48 _lookup_table = new Float2Image (width, height);
49
50 XCAM_FAIL_RETURN(
51 ERROR, _lookup_table.ptr () && _lookup_table->is_valid (), false,
52 "SoftGeoMapper(%s) set loop up table failed in data allocation",
53 XCAM_STR (get_name ()));
54
55 for (uint32_t i = 0; i < height; ++i) {
56 Float2 *ret = _lookup_table->get_buf_ptr (0, i);
57 const PointFloat2 *line = &data[i * width];
58 for (uint32_t j = 0; j < width; ++j) {
59 ret[j].x = line [j].x;
60 ret[j].y = line [j].y;
61 }
62 }
63 return true;
64 }
65
66 XCamReturn
remap(const SmartPtr<VideoBuffer> & in,SmartPtr<VideoBuffer> & out_buf)67 SoftGeoMapper::remap (
68 const SmartPtr<VideoBuffer> &in,
69 SmartPtr<VideoBuffer> &out_buf)
70 {
71 SmartPtr<ImageHandler::Parameters> param = new ImageHandler::Parameters (in, out_buf);
72 XCamReturn ret = execute_buffer (param, true);
73 if (xcam_ret_is_ok (ret) && !out_buf.ptr ()) {
74 out_buf = param->out_buf;
75 }
76 return ret;
77 }
78
79 XCamReturn
configure_resource(const SmartPtr<Parameters> & param)80 SoftGeoMapper::configure_resource (const SmartPtr<Parameters> ¶m)
81 {
82 XCAM_FAIL_RETURN(
83 ERROR, _lookup_table.ptr () && _lookup_table->is_valid (), XCAM_RETURN_ERROR_PARAM,
84 "SoftGeoMapper(%s) configure failed, look_up_table was not set correctly",
85 XCAM_STR (get_name ()));
86
87 const VideoBufferInfo &in_info = param->in_buf->get_video_info ();
88 XCAM_FAIL_RETURN (
89 ERROR, in_info.format == V4L2_PIX_FMT_NV12, XCAM_RETURN_ERROR_PARAM,
90 "SoftGeoMapper(:%s) only support format(NV12) but input format is %s",
91 XCAM_STR(get_name ()), xcam_fourcc_to_string (in_info.format));
92
93 Float2 factors;
94 get_factors (factors.x, factors.y);
95 if (XCAM_DOUBLE_EQUAL_AROUND (factors.x, 0.0f) ||
96 XCAM_DOUBLE_EQUAL_AROUND (factors.y, 0.0f)) {
97 auto_calculate_factors (_lookup_table->get_width (), _lookup_table->get_height ());
98 }
99
100 uint32_t width, height;
101 get_output_size (width, height);
102 VideoBufferInfo out_info;
103 out_info.init (
104 in_info.format, width, height,
105 XCAM_ALIGN_UP (width, XCAM_GEO_MAP_ALIGNMENT_X),
106 XCAM_ALIGN_UP (height, XCAM_GEO_MAP_ALIGNMENT_Y));
107 set_out_video_info (out_info);
108
109 XCAM_ASSERT (!_map_task.ptr ());
110 _map_task = new XCamSoftTasks::GeoMapTask (new CbGeoMapTask(this));
111 XCAM_ASSERT (_map_task.ptr ());
112
113 return XCAM_RETURN_NO_ERROR;
114 }
115
116 XCamReturn
start_remap_task(const SmartPtr<ImageHandler::Parameters> & param)117 SoftGeoMapper::start_remap_task (const SmartPtr<ImageHandler::Parameters> ¶m)
118 {
119 XCAM_ASSERT (_map_task.ptr ());
120 XCAM_ASSERT (_lookup_table.ptr ());
121
122 Float2 factors;
123 get_factors (factors.x, factors.y);
124
125 SmartPtr<VideoBuffer> in_buf = param->in_buf, out_buf = param->out_buf;
126 SmartPtr<XCamSoftTasks::GeoMapTask::Args> args = new XCamSoftTasks::GeoMapTask::Args (param);
127 args->in_luma = new UcharImage (in_buf, 0);
128 args->in_uv = new Uchar2Image (in_buf, 1);
129 args->out_luma = new UcharImage (out_buf, 0);
130 args->out_uv = new Uchar2Image (out_buf, 1);
131 args->lookup_table = _lookup_table;
132 args->factors = factors;
133
134 uint32_t thread_x = 2, thread_y = 2;
135 WorkSize work_unit = _map_task->get_work_uint ();
136 WorkSize global_size (
137 xcam_ceil (args->out_luma->get_width (), work_unit.value[0]) / work_unit.value[0],
138 xcam_ceil (args->out_luma->get_height (), work_unit.value[1]) / work_unit.value[1]);
139 WorkSize local_size (
140 xcam_ceil(global_size.value[0], thread_x) / thread_x ,
141 xcam_ceil(global_size.value[1], thread_y) / thread_y);
142
143 _map_task->set_local_size (local_size);
144 _map_task->set_global_size (global_size);
145
146 param->in_buf.release ();
147 return _map_task->work (args);
148 }
149
150 XCamReturn
start_work(const SmartPtr<ImageHandler::Parameters> & param)151 SoftGeoMapper::start_work (const SmartPtr<ImageHandler::Parameters> ¶m)
152 {
153 XCamReturn ret = XCAM_RETURN_NO_ERROR;
154
155 XCAM_ASSERT (param->out_buf.ptr ());
156
157 ret = start_remap_task (param);
158 XCAM_FAIL_RETURN (
159 ERROR, xcam_ret_is_ok (ret), ret,
160 "geo_mapper:%s start_work failed on idx0", XCAM_STR (get_name ()));
161
162 param->in_buf.release ();
163
164 return ret;
165 };
166
167 XCamReturn
terminate()168 SoftGeoMapper::terminate ()
169 {
170 if (_map_task.ptr ()) {
171 _map_task->stop ();
172 _map_task.release ();
173 }
174 return SoftHandler::terminate ();
175 }
176
177 void
remap_task_done(const SmartPtr<Worker> & worker,const SmartPtr<Worker::Arguments> & base,const XCamReturn error)178 SoftGeoMapper::remap_task_done (
179 const SmartPtr<Worker> &worker, const SmartPtr<Worker::Arguments> &base, const XCamReturn error)
180 {
181 XCAM_UNUSED (worker);
182 XCAM_ASSERT (worker.ptr () == _map_task.ptr ());
183 SmartPtr<XCamSoftTasks::GeoMapTask::Args> args = base.dynamic_cast_ptr<XCamSoftTasks::GeoMapTask::Args> ();
184 XCAM_ASSERT (args.ptr ());
185 const SmartPtr<ImageHandler::Parameters> param = args->get_param ();
186
187 if (!check_work_continue (param, error))
188 return;
189
190 work_well_done (param, error);
191 }
192
create_soft_geo_mapper()193 SmartPtr<SoftHandler> create_soft_geo_mapper ()
194 {
195 SmartPtr<SoftHandler> mapper = new SoftGeoMapper ();
196 XCAM_ASSERT (mapper.ptr ());
197 return mapper;
198 }
199
200 SmartPtr<GeoMapper>
create_soft_geo_mapper()201 GeoMapper::create_soft_geo_mapper ()
202 {
203 SmartPtr<SoftHandler> handler = XCam::create_soft_geo_mapper ();
204 return handler.dynamic_cast_ptr<GeoMapper> ();
205 }
206
207 }
208