Home | History | Annotate | Download | only in soft
      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> &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
    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
    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
    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