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