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 (at) 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 31 SoftGeoMapper::SoftGeoMapper (const char *name) 32 : SoftHandler (name) 33 { 34 } 35 36 SoftGeoMapper::~SoftGeoMapper () 37 { 38 } 39 40 bool 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 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 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 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 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 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 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 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> 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