aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2019-11-13 19:57:19 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2019-11-13 19:57:19 +0000
commit0940eea50f612285288f22259443410aa5052e3c (patch)
treeb04baa77f748351ecd3d0788fbcf7acf248e34ce
parentecea4993be3fdd0bb18255484158104e7a0268a0 (diff)
parent553504d7c452d5b83a758b228d704c97aa5a4e4b (diff)
downloadlibxcam-0940eea50f612285288f22259443410aa5052e3c.tar.gz
Merge "Upgrade libxcam to release_1.2.2"
-rw-r--r--.gitignore1
-rw-r--r--AUTHORS3
-rw-r--r--COPYING2
-rw-r--r--ChangeLog65
-rw-r--r--LICENSE2
-rw-r--r--METADATA19
-rw-r--r--Makefile.am23
-rw-r--r--README.md90
-rw-r--r--capi/Makefile.am54
-rw-r--r--capi/context_priv.cpp9
-rw-r--r--capi/context_priv.h2
-rw-r--r--clx_kernel/Makefile.am39
-rw-r--r--configure.ac143
-rw-r--r--doc/xcam_framework_20170407.pngbin32233 -> 0 bytes
-rw-r--r--doc/xcam_framework_20181017.pngbin0 -> 40558 bytes
-rw-r--r--doc/xcam_framework_20190329.pngbin0 -> 46189 bytes
-rw-r--r--doc/yocto/libxcam_sample.bb6
-rw-r--r--modules/Makefile.am26
-rw-r--r--modules/dnn/Makefile.am52
-rwxr-xr-xmodules/dnn/dnn_inference_engine.cpp878
-rwxr-xr-xmodules/dnn/dnn_inference_engine.h280
-rw-r--r--modules/dnn/dnn_object_detection.cpp264
-rw-r--r--modules/dnn/dnn_object_detection.h53
-rw-r--r--modules/gles/Makefile.am81
-rw-r--r--modules/gles/egl/egl_base.cpp195
-rw-r--r--modules/gles/egl/egl_base.h61
-rw-r--r--modules/gles/egl/egl_utils.cpp87
-rw-r--r--modules/gles/egl/egl_utils.h40
-rw-r--r--modules/gles/gl_blender.cpp852
-rw-r--r--modules/gles/gl_blender.h98
-rw-r--r--modules/gles/gl_blender_shaders_priv.cpp398
-rw-r--r--modules/gles/gl_blender_shaders_priv.h182
-rw-r--r--modules/gles/gl_buffer.cpp246
-rw-r--r--modules/gles/gl_buffer.h110
-rw-r--r--modules/gles/gl_command.cpp265
-rw-r--r--modules/gles/gl_command.h206
-rw-r--r--modules/gles/gl_compute_program.cpp178
-rw-r--r--modules/gles/gl_compute_program.h70
-rw-r--r--modules/gles/gl_copy_handler.cpp228
-rw-r--r--modules/gles/gl_copy_handler.h93
-rw-r--r--modules/gles/gl_geomap_handler.cpp403
-rw-r--r--modules/gles/gl_geomap_handler.h130
-rw-r--r--modules/gles/gl_image_handler.cpp41
-rw-r--r--modules/gles/gl_image_handler.h47
-rw-r--r--modules/gles/gl_image_shader.cpp191
-rw-r--r--modules/gles/gl_image_shader.h81
-rw-r--r--modules/gles/gl_program.cpp247
-rw-r--r--modules/gles/gl_program.h79
-rw-r--r--modules/gles/gl_shader.cpp86
-rw-r--r--modules/gles/gl_shader.h78
-rw-r--r--modules/gles/gl_stitcher.cpp894
-rw-r--r--modules/gles/gl_stitcher.h91
-rw-r--r--modules/gles/gl_utils.cpp41
-rw-r--r--modules/gles/gl_utils.h32
-rw-r--r--modules/gles/gl_video_buffer.cpp160
-rw-r--r--modules/gles/gl_video_buffer.h63
-rw-r--r--modules/gles/gles_std.cpp58
-rw-r--r--modules/gles/gles_std.h48
-rw-r--r--modules/isp/Makefile.am87
-rw-r--r--modules/isp/aiq_handler.cpp3
-rw-r--r--modules/isp/hybrid_analyzer.cpp5
-rw-r--r--modules/isp/isp_poll_thread.cpp4
-rw-r--r--modules/ocl/Makefile.am160
-rw-r--r--modules/ocl/cl_3a_stats_context.cpp4
-rw-r--r--modules/ocl/cl_bayer_basic_handler.cpp11
-rw-r--r--modules/ocl/cl_defog_dcp_handler.cpp2
-rw-r--r--modules/ocl/cl_fisheye_handler.cpp30
-rw-r--r--modules/ocl/cl_fisheye_handler.h25
-rw-r--r--modules/ocl/cl_geo_map_handler.cpp23
-rw-r--r--modules/ocl/cl_geo_map_handler.h29
-rw-r--r--modules/ocl/cl_image_360_stitch.cpp296
-rw-r--r--modules/ocl/cl_image_360_stitch.h19
-rw-r--r--modules/ocl/cl_image_handler.cpp20
-rw-r--r--modules/ocl/cl_image_handler.h2
-rw-r--r--modules/ocl/cl_image_processor.cpp10
-rw-r--r--modules/ocl/cl_image_scaler.cpp9
-rw-r--r--modules/ocl/cl_kernel.cpp28
-rw-r--r--modules/ocl/cl_post_image_processor.cpp12
-rw-r--r--modules/ocl/cl_post_image_processor.h3
-rw-r--r--modules/ocl/cl_retinex_handler.cpp9
-rw-r--r--modules/ocl/cl_utils.cpp4
-rw-r--r--modules/ocl/cl_video_buffer.cpp1
-rw-r--r--modules/ocl/cl_video_buffer.h2
-rw-r--r--modules/ocl/cv_base_class.cpp67
-rw-r--r--modules/ocl/cv_base_class.h52
-rw-r--r--modules/ocl/cv_context.cpp82
-rw-r--r--modules/ocl/cv_context.h62
-rw-r--r--modules/ocl/cv_feature_match.h79
-rw-r--r--modules/ocv/Makefile.am29
-rw-r--r--modules/ocv/cv_capi_feature_match.cpp (renamed from modules/soft/cv_capi_feature_match.cpp)92
-rw-r--r--modules/ocv/cv_capi_feature_match.h74
-rw-r--r--modules/ocv/cv_edgetaper.cpp (renamed from modules/ocl/cv_edgetaper.cpp)15
-rw-r--r--modules/ocv/cv_edgetaper.h (renamed from modules/ocl/cv_edgetaper.h)12
-rw-r--r--modules/ocv/cv_feature_match.cpp (renamed from modules/ocl/cv_feature_match.cpp)249
-rw-r--r--modules/ocv/cv_feature_match.h88
-rw-r--r--modules/ocv/cv_feature_match_cluster.cpp316
-rw-r--r--modules/ocv/cv_feature_match_cluster.h55
-rw-r--r--modules/ocv/cv_image_deblurring.cpp (renamed from modules/ocl/cv_image_deblurring.cpp)6
-rw-r--r--modules/ocv/cv_image_deblurring.h (renamed from modules/ocl/cv_image_deblurring.h)14
-rw-r--r--modules/ocv/cv_image_process_helper.cpp (renamed from modules/ocl/cv_image_process_helper.cpp)7
-rw-r--r--modules/ocv/cv_image_process_helper.h (renamed from modules/ocl/cv_image_process_helper.h)9
-rw-r--r--modules/ocv/cv_image_sharp.cpp (renamed from modules/ocl/cv_image_sharp.cpp)7
-rw-r--r--modules/ocv/cv_image_sharp.h (renamed from modules/ocl/cv_image_sharp.h)8
-rw-r--r--modules/ocv/cv_std.h27
-rw-r--r--modules/ocv/cv_utils.cpp97
-rw-r--r--modules/ocv/cv_utils.h41
-rw-r--r--modules/ocv/cv_wiener_filter.cpp (renamed from modules/ocl/cv_wiener_filter.cpp)2
-rw-r--r--modules/ocv/cv_wiener_filter.h (renamed from modules/ocl/cv_wiener_filter.h)8
-rw-r--r--modules/render/Makefile.am52
-rw-r--r--modules/render/render_osg_camera_manipulator.cpp172
-rw-r--r--modules/render/render_osg_camera_manipulator.h123
-rw-r--r--modules/render/render_osg_model.cpp342
-rw-r--r--modules/render/render_osg_model.h125
-rw-r--r--modules/render/render_osg_shader.h93
-rw-r--r--modules/render/render_osg_viewer.cpp137
-rw-r--r--modules/render/render_osg_viewer.h73
-rw-r--r--modules/soft/Makefile.am90
-rw-r--r--modules/soft/cv_capi_feature_match.h82
-rw-r--r--modules/soft/soft_blender.cpp21
-rw-r--r--modules/soft/soft_blender.h2
-rw-r--r--modules/soft/soft_blender_tasks_priv.h2
-rw-r--r--modules/soft/soft_geo_mapper.cpp285
-rw-r--r--modules/soft/soft_geo_mapper.h78
-rw-r--r--modules/soft/soft_geo_tasks_priv.cpp369
-rw-r--r--modules/soft/soft_geo_tasks_priv.h70
-rw-r--r--modules/soft/soft_handler.cpp47
-rw-r--r--modules/soft/soft_handler.h12
-rw-r--r--modules/soft/soft_stitcher.cpp290
-rw-r--r--modules/soft/soft_worker.cpp58
-rw-r--r--modules/soft/soft_worker.h25
-rw-r--r--modules/vulkan/Makefile.am76
-rw-r--r--modules/vulkan/vk_blender.cpp1537
-rw-r--r--modules/vulkan/vk_blender.h120
-rw-r--r--modules/vulkan/vk_cmdbuf.cpp172
-rw-r--r--modules/vulkan/vk_cmdbuf.h106
-rw-r--r--modules/vulkan/vk_copy_handler.cpp270
-rw-r--r--modules/vulkan/vk_copy_handler.h90
-rw-r--r--modules/vulkan/vk_descriptor.cpp220
-rw-r--r--modules/vulkan/vk_descriptor.h163
-rw-r--r--modules/vulkan/vk_device.cpp471
-rw-r--r--modules/vulkan/vk_device.h120
-rw-r--r--modules/vulkan/vk_geomap_handler.cpp314
-rw-r--r--modules/vulkan/vk_geomap_handler.h78
-rw-r--r--modules/vulkan/vk_handler.cpp60
-rw-r--r--modules/vulkan/vk_handler.h57
-rw-r--r--modules/vulkan/vk_instance.cpp230
-rw-r--r--modules/vulkan/vk_instance.h77
-rw-r--r--modules/vulkan/vk_memory.cpp182
-rw-r--r--modules/vulkan/vk_memory.h134
-rw-r--r--modules/vulkan/vk_pipeline.cpp293
-rw-r--r--modules/vulkan/vk_pipeline.h127
-rw-r--r--modules/vulkan/vk_shader.cpp60
-rw-r--r--modules/vulkan/vk_shader.h71
-rw-r--r--modules/vulkan/vk_stitcher.cpp824
-rw-r--r--modules/vulkan/vk_stitcher.h80
-rw-r--r--modules/vulkan/vk_sync.cpp55
-rw-r--r--modules/vulkan/vk_sync.h56
-rw-r--r--modules/vulkan/vk_video_buf_allocator.cpp164
-rw-r--r--modules/vulkan/vk_video_buf_allocator.h58
-rw-r--r--modules/vulkan/vk_worker.cpp218
-rw-r--r--modules/vulkan/vk_worker.h112
-rw-r--r--modules/vulkan/vulkan_common.cpp77
-rw-r--r--modules/vulkan/vulkan_common.h33
-rw-r--r--modules/vulkan/vulkan_std.h43
-rw-r--r--plugins/3a/Makefile.am12
-rw-r--r--plugins/3a/aiq/Makefile.am35
-rw-r--r--plugins/3a/aiq/aiq_wrapper.cpp14
-rw-r--r--plugins/3a/hybrid/Makefile.am23
-rw-r--r--plugins/Makefile.am4
-rw-r--r--plugins/smart/Makefile.am10
-rw-r--r--plugins/smart/dvs/Makefile.am51
-rw-r--r--plugins/smart/dvs/libdvs/Makefile.am41
-rw-r--r--plugins/smart/dvs/libdvs/stabilizer.cpp24
-rw-r--r--plugins/smart/dvs/libdvs/test-image-stabilization.cpp2
-rw-r--r--plugins/smart/dvs/xcam_plugin_dvs.cpp9
-rw-r--r--plugins/smart/sample/Makefile.am36
-rw-r--r--plugins/smart/sample/sample_smart_analysis.cpp3
-rw-r--r--shaders/Makefile.am9
-rw-r--r--shaders/cl/kernel_3d_denoise.cl (renamed from cl_kernel/kernel_3d_denoise.cl)0
-rw-r--r--shaders/cl/kernel_3d_denoise_slm.cl (renamed from cl_kernel/kernel_3d_denoise_slm.cl)0
-rw-r--r--shaders/cl/kernel_bayer_basic.cl (renamed from cl_kernel/kernel_bayer_basic.cl)0
-rw-r--r--shaders/cl/kernel_bayer_pipe.cl (renamed from cl_kernel/kernel_bayer_pipe.cl)0
-rw-r--r--shaders/cl/kernel_bi_filter.cl (renamed from cl_kernel/kernel_bi_filter.cl)0
-rw-r--r--shaders/cl/kernel_csc.cl (renamed from cl_kernel/kernel_csc.cl)0
-rw-r--r--shaders/cl/kernel_defog_dcp.cl (renamed from cl_kernel/kernel_defog_dcp.cl)0
-rw-r--r--shaders/cl/kernel_demo.cl (renamed from cl_kernel/kernel_demo.cl)0
-rw-r--r--shaders/cl/kernel_fisheye.cl (renamed from cl_kernel/kernel_fisheye.cl)0
-rw-r--r--shaders/cl/kernel_gauss.cl (renamed from cl_kernel/kernel_gauss.cl)0
-rw-r--r--shaders/cl/kernel_gauss_lap_pyramid.cl (renamed from cl_kernel/kernel_gauss_lap_pyramid.cl)0
-rw-r--r--shaders/cl/kernel_geo_map.cl (renamed from cl_kernel/kernel_geo_map.cl)46
-rw-r--r--shaders/cl/kernel_image_scaler.cl (renamed from cl_kernel/kernel_image_scaler.cl)0
-rw-r--r--shaders/cl/kernel_image_warp.cl (renamed from cl_kernel/kernel_image_warp.cl)0
-rw-r--r--shaders/cl/kernel_min_filter.cl (renamed from cl_kernel/kernel_min_filter.cl)0
-rwxr-xr-xshaders/cl/kernel_newtonemapping.cl (renamed from cl_kernel/kernel_newtonemapping.cl)0
-rw-r--r--shaders/cl/kernel_retinex.cl (renamed from cl_kernel/kernel_retinex.cl)0
-rw-r--r--shaders/cl/kernel_rgb_pipe.cl (renamed from cl_kernel/kernel_rgb_pipe.cl)0
-rw-r--r--shaders/cl/kernel_tnr.cl (renamed from cl_kernel/kernel_tnr.cl)0
-rw-r--r--shaders/cl/kernel_tonemapping.cl (renamed from cl_kernel/kernel_tonemapping.cl)0
-rw-r--r--shaders/cl/kernel_wavelet_coeff.cl (renamed from cl_kernel/kernel_wavelet_coeff.cl)0
-rw-r--r--shaders/cl/kernel_wavelet_denoise.cl (renamed from cl_kernel/kernel_wavelet_denoise.cl)0
-rw-r--r--shaders/cl/kernel_wavelet_haar.cl (renamed from cl_kernel/kernel_wavelet_haar.cl)0
-rw-r--r--shaders/cl/kernel_wire_frame.cl (renamed from cl_kernel/kernel_wire_frame.cl)0
-rw-r--r--shaders/cl/kernel_yuv_pipe.cl (renamed from cl_kernel/kernel_yuv_pipe.cl)0
-rw-r--r--shaders/clx/.gitignore (renamed from clx_kernel/.gitignore)0
-rw-r--r--shaders/clx/Makefile.am39
-rw-r--r--shaders/glsl/shader_blend_pyr.comp.sl91
-rw-r--r--shaders/glsl/shader_copy.comp.sl28
-rw-r--r--shaders/glsl/shader_gauss_scale_pyr.comp.sl174
-rw-r--r--shaders/glsl/shader_geomap.comp.sl238
-rw-r--r--shaders/glsl/shader_lap_trans_pyr.comp.sl162
-rw-r--r--shaders/glsl/shader_reconstruct_pyr.comp.sl219
-rw-r--r--shaders/glslx/.gitignore1
-rw-r--r--shaders/glslx/Makefile.am20
-rw-r--r--shaders/spv/shader_blend_pyr.comp93
-rw-r--r--shaders/spv/shader_blend_pyr.comp.spv228
-rw-r--r--shaders/spv/shader_copy.comp28
-rw-r--r--shaders/spv/shader_copy.comp.spv66
-rw-r--r--shaders/spv/shader_gauss_scale_pyr.comp176
-rw-r--r--shaders/spv/shader_gauss_scale_pyr.comp.spv891
-rw-r--r--shaders/spv/shader_geomap.comp238
-rw-r--r--shaders/spv/shader_geomap.comp.spv847
-rw-r--r--shaders/spv/shader_lap_trans_pyr.comp162
-rw-r--r--shaders/spv/shader_lap_trans_pyr.comp.spv536
-rw-r--r--shaders/spv/shader_reconstruct_pyr.comp220
-rw-r--r--shaders/spv/shader_reconstruct_pyr.comp.spv670
-rw-r--r--tests/.gitignore4
-rw-r--r--tests/Makefile.am295
-rw-r--r--tests/test-cl-image.cpp13
-rw-r--r--tests/test-device-manager.cpp8
-rw-r--r--tests/test-dnn-inference.cpp497
-rw-r--r--tests/test-gles-handler.cpp313
-rw-r--r--tests/test-image-blend.cpp13
-rw-r--r--tests/test-image-deblurring.cpp16
-rw-r--r--tests/test-image-stitching.cpp143
-rw-r--r--tests/test-pipe-manager.cpp6
-rw-r--r--tests/test-render-surround-view.cpp688
-rw-r--r--tests/test-soft-image.cpp664
-rw-r--r--tests/test-surround-view.cpp769
-rw-r--r--tests/test-video-stabilization.cpp12
-rw-r--r--tests/test-vk-handler.cpp340
-rw-r--r--tests/test_common.h3
-rw-r--r--tests/test_stream.h333
-rwxr-xr-xtools/add-quotation-marks.sh (renamed from tools/cl-double-quotation.sh)20
-rw-r--r--wrapper/Makefile.am3
-rw-r--r--wrapper/gstreamer/Makefile.am142
-rw-r--r--wrapper/gstreamer/gstxcamfilter.cpp40
-rw-r--r--wrapper/gstreamer/gstxcamfilter.h1
-rw-r--r--wrapper/gstreamer/gstxcamsrc.cpp28
-rw-r--r--wrapper/gstreamer/gstxcamsrc.h1
-rw-r--r--wrapper/gstreamer/interface/Makefile.am24
-rw-r--r--xcore/Makefile.am224
-rw-r--r--xcore/base/xcam_common.h2
-rw-r--r--xcore/base/xcam_defs.h17
-rw-r--r--xcore/buffer_pool.h6
-rw-r--r--xcore/drm_bo_buffer.h2
-rw-r--r--xcore/drm_display.cpp6
-rw-r--r--xcore/dynamic_analyzer.cpp5
-rw-r--r--xcore/fake_poll_thread.cpp5
-rw-r--r--xcore/image_file_handle.cpp6
-rw-r--r--xcore/image_handler.cpp121
-rw-r--r--xcore/image_handler.h22
-rw-r--r--xcore/image_processor.cpp9
-rw-r--r--xcore/interface/blender.h3
-rw-r--r--xcore/interface/data_types.h13
-rw-r--r--xcore/interface/feature_match.cpp84
-rw-r--r--xcore/interface/feature_match.h43
-rw-r--r--xcore/interface/geo_mapper.h6
-rw-r--r--xcore/interface/stitcher.cpp10
-rw-r--r--xcore/interface/stitcher.h35
-rw-r--r--xcore/once_map_video_buffer_priv.cpp97
-rw-r--r--xcore/poll_thread.cpp9
-rw-r--r--xcore/surview_fisheye_dewarp.cpp9
-rw-r--r--xcore/surview_fisheye_dewarp.h3
-rw-r--r--xcore/vec_mat.h20
-rw-r--r--xcore/worker.cpp27
-rw-r--r--xcore/worker.h23
-rw-r--r--xcore/xcam_analyzer.cpp4
-rw-r--r--xcore/xcam_utils.cpp52
-rw-r--r--xcore/xcam_utils.h7
279 files changed, 27694 insertions, 2761 deletions
diff --git a/.gitignore b/.gitignore
index 1620cc7..606ff44 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,6 +19,7 @@ config.*
/pkgconfig/*.pc
.deps
.libs
+.dirstamp
# Object files
*.o
diff --git a/AUTHORS b/AUTHORS
index e2fd75b..f91df7d 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -4,11 +4,12 @@ Maintainers:
Wind Yuan <feng.yuan@intel.com>
Contributors: (orders by first name)
+Andrey Parfenov <a1994ndrey@gmail.com>
Fei Wang <feix.w.wang@intel.com>
Jia Meng <jia.meng@intel.com>
John Ye <john.ye@intel.com>
Juan Zhao <juan.j.zhao@intel.com>
-Junkai Wu <wujunkai166@gmail.com>
+Junkai Wu <wujunkai166@gmail.com> <junkai.wu@intel.com>
Sameer Kibey <sameer.kibey@intel.com>
Shincy Tu <shincy.tu@intel.com>
Wei Zong <wei.zong@intel.com>
diff --git a/COPYING b/COPYING
index 744d243..6a2f304 100644
--- a/COPYING
+++ b/COPYING
@@ -1,5 +1,5 @@
- Copyright (c) 2014-2015 Intel Corporation
+ Copyright (c) 2014-2019 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/ChangeLog b/ChangeLog
index 7182275..e869496 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,68 @@
+2019/04/02: release libxcam version 1.2.2
+ * DNN inference framwork enabling.
+ - enable pedestrian and vehicle detection based on OpenVino
+
+ * OpenCV feature match enabled for image stitching pipeline (GLES/Vulkan/CPU)
+ - support three versions of feature match: default, cluster, capi
+
+ * Abstract OpenCV source in ocv module, and build into a separate static library
+
+2018/12/19: release libxcam version 1.2.1
+ * Vulkan surround-view stitching enabling.
+ - enable features of multi-band blender and geometry remap.
+ - enable Vulkan image stitching. (feature-match may support later)
+
+ * Surrond-view texture rendering.
+ - enable 3D surround view scene rendering and manipulation.
+
+ * require OpenSceneGraph minimal version 3.3.2
+
+2018/10/16: release libxcam version 1.2.0
+ * GLES compute framework enabling.
+ - enable GL image processing framework.
+ - enable features of multi-band blender, geometry remap and data-copy.
+
+ * GLES surround-view stitching enabling.
+ - GLES stitching enabled (feature-match may support later).
+ - performance optimized on compute shaders.
+
+ * Vulkan compute framework enabling.
+ - enabled Vulkan image processing under xcam framework.
+ - vk-copy-handler as sample code.
+
+ * suggest OpenCV version [3.0.0 - 3.4.3]
+ * support CPU stitching based on dual-const and dual-curve scaling factors.
+ * support OpenCL stitching based on auto-scale in vertical 2D-direction.
+ * change test-soft-image to test-surround-view
+
+2018/03/01: release libxcam version 1.1.0
+ * CPU stitching enabled for automotive surround view in Linux/Android.
+ - enable CPU multi-thread image processing framework.
+ - enable multi-band blender, geometry remap, data-copy, OpenCV feature match.
+ - enable 3D-bowl model stitching.
+ - support generic Android platform.
+ - CPU version of surround view stitching upstream to Android Open Source Project.
+
+ * surround-view OpenCL stitching feature enabled and quality improvement.
+ - add dewarp process based on bowl view model in geometry map.
+ - support multiple (4) cameras stitching.
+ - add new selection method based on clustering in feature match to improve quality of stitching.
+ - auto scale in x direction is done and y direction is WIP.
+ - quality tune on different datasets, both indoor and outdoor.
+
+ * support standard OpenCL 2.0+ driver (VPG OCL driver)
+ - support standard OpenCL buffer.
+ - remove libdrm dependency.
+ - drm preview removed from test-device-manager, test-pipe-manager and usb camera.
+
+ * enable deblurring feature based on OpenCV. (GSoC program)
+ - based on deconvolution algorithm filters
+ - support noise estimation
+ - support edgetaper
+
+ * sourround view solution will be integrated into Android EVS (exterior view system) WIP
+ * add sample recipe for yocto build (libxcam/doc/yocto).
+
2017/07/10: release libxcam version 1.0.0
* 360 video stitching performance and quality improvement.
- enable geometry map to improve performance.
diff --git a/LICENSE b/LICENSE
index 744d243..6a2f304 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,5 +1,5 @@
- Copyright (c) 2014-2015 Intel Corporation
+ Copyright (c) 2014-2019 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/METADATA b/METADATA
index 4459c63..149456a 100644
--- a/METADATA
+++ b/METADATA
@@ -1,18 +1,15 @@
name: "LibXCam"
-description:
- "libXCam is a project for extended camera and computer "
- "vision features. This library can work on GPU, CPU and "
- "other HW platforms to improve image/video quality. "
- "OpenCL as one of the common parallel computing languages "
- "is used to improve performance in different platforms. "
- "Other shading language supports are in roadmap."
-
+description: "libXCam is a project for extended camera and computer vision features. This library can work on GPU, CPU and other HW platforms to improve image/video quality. OpenCL as one of the common parallel computing languages is used to improve performance in different platforms. Other shading language supports are in roadmap."
third_party {
url {
type: GIT
- value: "https://github.com/01org/libxcam.git"
+ value: "https://github.com/intel/libxcam"
}
- version: "1.0.0"
- last_upgrade_date { year: 2017 month: 9 day: 11 }
+ version: "release_1.2.2"
license_type: NOTICE
+ last_upgrade_date {
+ year: 2019
+ month: 4
+ day: 4
+ }
}
diff --git a/Makefile.am b/Makefile.am
index 3f59882..4285b9d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,23 +1,6 @@
-if HAVE_LIBCL
-CLX_KERNEL_DIR = clx_kernel
-else
-CLX_KERNEL_DIR =
-endif
-
-if HAVE_LIBCL
-TESTS_DIR = tests
-else
-if ENABLE_IA_AIQ
-TESTS_DIR = tests
-else
-TESTS_DIR =
-endif
-endif
-
if ENABLE_CAPI
CAPI_DIR = capi
-else
-CAPI_DIR =
endif
-SUBDIRS = xcore $(CLX_KERNEL_DIR) modules plugins \
- wrapper $(CAPI_DIR) $(TESTS_DIR) pkgconfig
+
+SUBDIRS = xcore shaders modules plugins \
+ wrapper $(CAPI_DIR) tests pkgconfig
diff --git a/README.md b/README.md
index 5958597..095724d 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
## libXCam
-Copyright (C) 2014-2017 Intel Corporation
+Copyright (C) 2014-2019 Intel Corporation
libxcam core source code under the terms of Apache License, Version 2.0
@@ -12,48 +12,60 @@ library makes GPU/CPU/ISP working together to improve image quality.
OpenCL is used to improve performance in different platforms.
#### Features:
- * Image processing features.
+ * Image processing features
- Advanced features
- - 360 Image stiching: generate 360 degree panorama photography by
- stitching multiple neighbor fisheye images.
- - Digital Video Stabilization:
+ - Automotive surround view(360) stitching (OpenCL/CPU/GLES)
+ - Support bowl view 3D model stitching by 4 video input.
+ - Enable geometry remap for WFoV camera calibration(intrinsic and extrinsic data).
+ - Quality and performance improved (OpenCL/CPU/GLES).
+ - CPU version upstreamed into AOSP for automotive surround view.
+ - Enable Vulkan to improve performance.
+ - 360 video stitching (Equirectangular mode via OpenCL)
+ - Support 2-fisheye (>180 degree) video stream stitching.
+ - Performance and quality improved.
+ - DNN inference framework
+ - Support pedestrian and vehicle detection.
+ - Digital Video Stabilization
- OpenCV feature-matched based video stabilization.
- gyroscope 3-DoF (orientation) based video stabilization.
- - Blender: multi-band blender.
- - Noise reduction.
+ - Blender: multi-band blender (OpenCL/CPU/GLES)
+ - Noise reduction (OpenCL)
- adaptive NR based on wavelet-haar and Bayersian shrinkage.
- 3D-NR with inter-block and intra-block reference.
- wavelet-hat NR (obsolete).
- - Wide dynamic range (WDR).
+ - Wide dynamic range (WDR) (OpenCL)
- histogram adjustment tone-mapping.
- gaussian-based tone-mapping (obsolete).
- - Fog removal: retinex and dark channel prior algorithm.
+ - Fog removal: retinex and dark channel prior algorithm (OpenCL)
- dark channel prior algorithm based defog.
- multi-scale retinex based defog (obsolete).
- - Basic pipeline from bayer to YUV/RGB format.
+ - Basic pipeline from bayer to YUV/RGB format (OpenCL / AtomISP)
- Gamma correction, MACC, color space, demosaicing, simple bilateral
noise reduction, edge enhancement and temporal noise reduction.
- - 3A features.
+ - 3A features
- Auto whitebalance, auto exposure, auto focus, black level correction,
color correction, 3a-statistics calculation.
- * Support 3rd party 3A lib which can be loaded dynamically.
+ * Support 3rd party 3A lib which can be loaded dynamically
- hybrid 3a plugin.
- * Support 3a analysis tuning framework for different features.
- * Support smart analysis framework.
+ * Support 3a analysis tuning framework for different features
+ * Support smart analysis framework
- Face detection interface/plugin.
- * Enable gstreamer plugin.
+ * Enable gstreamer plugin
- xcamsrc, capture from usb/isp camera, process 3a/basic/advanced features.
- xcamfilter, improve image quality by advanced features and smart analysis.
#### Prerequisite:
* install gcc/g++, automake, autoconf, libtool, gawk, pkg-config
* Linux kernel > 3.10
- * install libdrm-dev
* install ocl-icd-dev, ocl-icd-opencl-dev
- * If --enable-libcl, need compile ocl driver <https://www.freedesktop.org/wiki/Software/Beignet/>
- * If --enable-opencv, need compile opencv <http://opencv.org> (or: <https://github.com/opencv/opencv/wiki>)
* If --enable-gst, need install libgstreamer1.0-dev, libgstreamer-plugins-base1.0-dev
- * If --enable-aiq, need get ia_imaging lib which we don't support.
+ * If --enable-aiq, need get ia_imaging lib which we don't support
+ * If --enable-libcl, need compile [OpenCL](https://www.freedesktop.org/wiki/Software/Beignet) driver
+ * If --enable-opencv, suggest [OpenCV](http://opencv.org) versions [3.0.0 - 3.4.3] (or: [OpenCV Wiki](https://github.com/opencv/opencv/wiki))
+ * If --enable-render, need compile [OpenSceneGraph](https://github.com/openscenegraph/OpenSceneGraph) library with configure option "-DOSG_WINDOWING_SYSTEM=X11"
+ * If --enable-gles, need to install [Mesa3D](https://www.mesa3d.org) library
+ * If --enable-vulkan, need to install [Mesa3D](https://www.mesa3d.org) library
+ * If --enable-dnn, need to install OpenVino SDK
#### Building and installing:
* Environment variable settings<BR>
@@ -73,27 +85,53 @@ OpenCL is used to improve performance in different platforms.
--prefix=PREFIX install architecture-independent files in PREFIX [default=/usr/local]
--enable-debug enable debug, [default=no]
--enable-profiling enable profiling, [default=no]
- --enable-drm enable drm buffer, [default=yes]
+ --enable-drm enable drm buffer, [default=no]
--enable-aiq enable Aiq 3A algorithm build, [default=no]
--enable-gst enable gstreamer plugin build, [default=no]
--enable-libcl enable libcl image processor, [default=yes]
--enable-opencv enable opencv library, [default=no]
+ --enable-capi enable libxcam-capi library, [default=no]
--enable-docs build Doxygen documentation [default=no]
--enable-3alib enable 3A lib build, [default=no]
--enable-smartlib enable smart analysis lib build, [default=no]
+ --enable-gles enable gles, [default=no]
+ --enable-vulkan enable vulkan, [default=no]
+ --enable-render enable 3D texture render, [default=no]
+ --enable-dnn enable dnn inference, [default=no]
For example:
- $ ./autogen.sh --prefix=/usr --enable-3alib --enable-aiq --enable-gst --enable-drm \
- --enable-libcl --enable-opencv --enable-profiling --enable-smartlib
+ $ ./autogen.sh --prefix=/usr --enable-gst --enable-libcl --enable-opencv \
+ --enable-smartlib --enable-profiling --enable-gles --enable-render --enable-dnn
* $ make
* $ sudo make install
#### Testing:
- * For detailed test cases, please refer to:<BR>
- <https://github.com/01org/libxcam/wiki/Tests>
+ * For detailed test cases, please go to [tests](https://github.com/intel/libxcam/wiki/Tests) page
#### Reporting Bugs:
- * Bugs or suggestions can be reported on the github issues page:<BR>
- <https://github.com/01org/libxcam/issues>
+ * Bugs or suggestions can be reported on the github [issues](https://github.com/intel/libxcam/issues) page
+ * Security issues, please send email to wei.zong@intel.com directly
+
+#### Mailing list
+ * To post a message to all the list members, please send email to libxcam@lists.01.org
+ * To register libxcam public maillist, please go to [registration](https://lists.01.org/mailman/listinfo/libxcam) page
+
+#### Maintainer:
+ * Wind Yuan <feng.yuan@intel.com>
+ * Wei Zong <wei.zong@intel.com>
+
+#### Contributors: (orders by first name)
+ * Andrey Parfenov <a1994ndrey@gmail.com>
+ * Fei Wang <feix.w.wang@intel.com>
+ * Jia Meng <jia.meng@intel.com>
+ * John Ye <john.ye@intel.com>
+ * Juan Zhao <juan.j.zhao@intel.com>
+ * Junkai Wu <junkai.wu@intel.com>
+ * Sameer Kibey <sameer.kibey@intel.com>
+ * Shincy Tu <shincy.tu@intel.com>
+ * Wei Zong <wei.zong@intel.com>
+ * Yan Zhang <yan.y.zhang@intel.com>
+ * Yao Wang <yao.y.wang@intel.com>
+ * Yinhang Liu <yinhangx.liu@intel.com>
diff --git a/capi/Makefile.am b/capi/Makefile.am
index 029fd7a..6b04110 100644
--- a/capi/Makefile.am
+++ b/capi/Makefile.am
@@ -1,53 +1,51 @@
lib_LTLIBRARIES = libxcam_capi.la
-XCAMCAPI_LIBS = \
- $(LIBCL_LIBS) \
- -ldl \
+XCAMCAPI_CXXFLAGS = \
+ $(XCAM_CXXFLAGS) \
+ $(LIBCL_CFLAGS) \
+ -I$(top_srcdir)/xcore \
+ -I$(top_srcdir)/modules \
$(NULL)
-XCAMCAPI_CXXFLAGS = \
- $(XCAM_CXXFLAGS) \
- $(LIBCL_CFLAGS) \
- -I$(top_srcdir)/xcore \
- -I$(top_srcdir)/modules \
+XCAMCAPI_LIBS = \
+ $(LIBCL_LIBS) -ldl \
+ $(top_builddir)/xcore/libxcam_core.la \
+ $(top_builddir)/modules/ocl/libxcam_ocl.la \
$(NULL)
if HAVE_LIBDRM
XCAMCAPI_CXXFLAGS += $(LIBDRM_CFLAGS)
-XCAMCAPI_LIBS += \
- -ldrm_intel \
- $(LIBDRM_LIBS) \
+XCAMCAPI_LIBS += \
+ -ldrm_intel \
+ $(LIBDRM_LIBS) \
$(NULL)
endif
-xcam_ocl_sources = \
- xcam_handle.cpp \
- context_priv.cpp \
- $(NULL)
+xcam_ocl_sources = \
+ xcam_handle.cpp \
+ context_priv.cpp \
+ $(NULL)
-libxcam_capi_la_SOURCES = \
- $(xcam_ocl_sources) \
+libxcam_capi_la_SOURCES = \
+ $(xcam_ocl_sources) \
$(NULL)
-libxcam_capi_la_CXXFLAGS = \
- $(XCAMCAPI_CXXFLAGS) \
+libxcam_capi_la_CXXFLAGS = \
+ $(XCAMCAPI_CXXFLAGS) \
$(NULL)
-libxcam_capi_la_LIBADD = \
- $(top_builddir)/modules/ocl/libxcam_ocl.la \
- $(top_builddir)/xcore/libxcam_core.la \
- $(XCAMCAPI_LIBS) \
+libxcam_capi_la_LIBADD = \
+ $(XCAMCAPI_LIBS) \
$(NULL)
-libxcam_capi_la_LDFLAGS = \
- $(XCAM_LT_LDFLAGS) \
- $(PTHREAD_LDFLAGS) \
+libxcam_capi_la_LDFLAGS = \
+ $(XCAM_LT_LDFLAGS) \
$(NULL)
libxcam_capiincludedir = $(includedir)/xcam/capi
nobase_libxcam_capiinclude_HEADERS = \
- xcam_handle.h \
- $(NULL)
+ xcam_handle.h \
+ $(NULL)
libxcam_capi_la_LIBTOOLFLAGS = --tag=disable-static
diff --git a/capi/context_priv.cpp b/capi/context_priv.cpp
index ecbffa6..2e685c1 100644
--- a/capi/context_priv.cpp
+++ b/capi/context_priv.cpp
@@ -59,8 +59,9 @@ ContextBase::ContextBase (HandleType type)
, _alloc_out_buf (false)
{
if (!_inbuf_pool.ptr()) {
- _inbuf_pool = new CLVideoBufferPool ();
- XCAM_ASSERT (_inbuf_pool.ptr ());
+ SmartPtr<BufferPool> pool = new CLVideoBufferPool ();
+ XCAM_ASSERT (pool.ptr ());
+ _inbuf_pool = pool;
}
}
@@ -222,10 +223,6 @@ StitchContext::create_handler (SmartPtr<CLContext> &context)
image_360->set_output_size (sttch_width, sttch_height);
XCAM_LOG_INFO ("stitch output size width:%d height:%d", sttch_width, sttch_height);
-#if HAVE_OPENCV
- image_360->set_feature_match_ocl (_fm_ocl);
-#endif
-
return image_360;
}
diff --git a/capi/context_priv.h b/capi/context_priv.h
index fe5c0a9..eb7514f 100644
--- a/capi/context_priv.h
+++ b/capi/context_priv.h
@@ -165,7 +165,6 @@ public:
, _need_seam (false)
, _fisheye_map (false)
, _need_lsc (false)
- , _fm_ocl (false)
, _scale_mode (CLBlenderScaleLocal)
, _res_mode (StitchRes1080P)
{}
@@ -176,7 +175,6 @@ private:
bool _need_seam;
bool _fisheye_map;
bool _need_lsc;
- bool _fm_ocl;
CLBlenderScaleMode _scale_mode;
StitchResMode _res_mode;
};
diff --git a/clx_kernel/Makefile.am b/clx_kernel/Makefile.am
deleted file mode 100644
index c87cf1a..0000000
--- a/clx_kernel/Makefile.am
+++ /dev/null
@@ -1,39 +0,0 @@
-clx_kernel_sources = \
- kernel_csc.clx \
- kernel_demo.clx \
- kernel_defog_dcp.clx \
- kernel_min_filter.clx \
- kernel_bi_filter.clx \
- kernel_tnr.clx \
- kernel_bayer_pipe.clx \
- kernel_bayer_basic.clx \
- kernel_fisheye.clx \
- kernel_rgb_pipe.clx \
- kernel_yuv_pipe.clx \
- kernel_tonemapping.clx \
- kernel_newtonemapping.clx \
- kernel_image_scaler.clx \
- kernel_retinex.clx \
- kernel_gauss.clx \
- kernel_gauss_lap_pyramid.clx \
- kernel_geo_map.clx \
- kernel_wavelet_denoise.clx \
- kernel_wavelet_haar.clx \
- kernel_wavelet_coeff.clx \
- kernel_wire_frame.clx \
- kernel_3d_denoise.clx \
- kernel_3d_denoise_slm.clx \
- kernel_image_warp.clx \
- $(NULL)
-
-cl_quotation_sh = \
- $(top_srcdir)/tools/cl-double-quotation.sh
-
-cl_kernel_dir = $(top_srcdir)/cl_kernel
-
-all-local: $(clx_kernel_sources)
-
-$(clx_kernel_sources): %.clx: $(cl_kernel_dir)/%.cl
- @$(cl_quotation_sh) $< $@
-
-CLEANFILES = $(clx_kernel_sources)
diff --git a/configure.ac b/configure.ac
index e98ad18..6c8c363 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,8 +2,8 @@
# Process this file with autoconf to produce a configure script.
m4_define([xcam_major_version], [1])
-m4_define([xcam_minor_version], [1])
-m4_define([xcam_micro_version], [0])
+m4_define([xcam_minor_version], [2])
+m4_define([xcam_micro_version], [2])
m4_define([xcam_version], [xcam_major_version.xcam_minor_version.xcam_micro_version])
AC_PREREQ([2.60])
@@ -27,6 +27,13 @@ XCAM_LT_LDFLAGS="-version-number $XCAM_LT_VERSION"
AC_SUBST(XCAM_LT_VERSION)
AC_SUBST(XCAM_LT_LDFLAGS)
+#xcam required OpenCV version
+XCAM_REQUIRE_CV_MIN=3.0.0
+XCAM_REQUIRE_CV_MAX=3.4.3
+
+#xcam required OpenSceneGraph version
+XCAM_REQUIRE_OSG_MIN=3.3.2
+
# Checks for programs.
AC_PROG_CC
AC_PROG_CXX
@@ -65,6 +72,16 @@ AC_ARG_ENABLE(libcl,
[enable libcl image processor, @<:@default=yes@:>@]),
[], [enable_libcl="yes"])
+AC_ARG_ENABLE([gles],
+ AS_HELP_STRING([--enable-gles],
+ [enable gles, @<:@default=no@:>@]),
+ [], [enable_gles="no"])
+
+AC_ARG_ENABLE([vulkan],
+ AS_HELP_STRING([--enable-vulkan],
+ [enable vulkan, @<:@default=no@:>@]),
+ [], [enable_vulkan="no"])
+
AC_ARG_ENABLE(opencv,
AS_HELP_STRING([--enable-opencv],
[enable opencv library, @<:@default=no@:>@]),
@@ -72,8 +89,18 @@ AC_ARG_ENABLE(opencv,
AC_ARG_ENABLE(capi,
AS_HELP_STRING([--enable-capi],
- [enable libxcam-capi library, @<:@default=yes@:>@]),
- [], [enable_capi="yes"])
+ [enable libxcam-capi library, @<:@default=no@:>@]),
+ [], [enable_capi="no"])
+
+AC_ARG_ENABLE([render],
+ AS_HELP_STRING([--enable-render],
+ [enable texture render with OpenSceneGraph library, @<:@default=no@:>@]),
+ [], [enable_render="no"])
+
+AC_ARG_ENABLE([dnn],
+ AS_HELP_STRING([--enable-dnn],
+ [enable dnn with OpenVino library, @<:@default=no@:>@]),
+ [], [enable_dnn="no"])
# documentation
AC_ARG_ENABLE(docs,
@@ -118,6 +145,51 @@ if test "$enable_libcl" = "yes"; then
PKG_CHECK_MODULES(LIBCL, [libcl], [HAVE_LIBCL=1], [HAVE_LIBCL=0])
fi
+# check gl
+HAVE_GLES=0
+if test "$enable_gles" = "yes"; then
+ PKG_CHECK_MODULES(LIBGL, [gl], [HAVE_GLES=1], [HAVE_GLES=0])
+fi
+
+# check vulkan
+HAVE_VULKAN=0
+if test "$enable_vulkan" = "yes"; then
+ PKG_CHECK_MODULES(LIBVULKAN, [vulkan], [HAVE_VULKAN=1], [HAVE_VULKAN=0])
+fi
+
+# check open sence graph
+ENABLE_RENDER=0
+if test "$enable_render" = "yes"; then
+ PKG_CHECK_MODULES(
+ [LIBOSG],
+ [openscenegraph-osg >= $XCAM_REQUIRE_OSG_MIN],
+ [HAVE_OSG=1],
+ [HAVE_OSG=0])
+
+ XCAM_OSG_VERSION=`$PKG_CONFIG --modversion openscenegraph-osg`
+ AC_MSG_NOTICE(OpenSceneGraph version: $XCAM_OSG_VERSION)
+
+ if test "$HAVE_OSG" -eq 1; then
+ ENABLE_RENDER=1
+ else
+ AC_MSG_WARN(OpenSceneGraph required version: >= $XCAM_REQUIRE_OSG_MIN)
+ ENABLE_RENDER=0
+ fi
+fi
+
+ENABLE_DNN=0
+if test "$enable_dnn" = "yes"; then
+ if test -z $OPENVINO_IE_INC_PATH; then
+ AC_MSG_WARN(Please export OPENVINO_IE_INC_PATH environment variables)
+ AC_MSG_ERROR(OpenVino inc path has not been set ... disable DNN module!)
+ fi
+ if test -z $OPENVINO_IE_LIBS_PATH; then
+ AC_MSG_WARN(Please export OPENVINO_IE_LIBS_PATH environment variables)
+ AC_MSG_ERROR(OpenVino library path has not been set ... disable DNN module!)
+ fi
+ ENABLE_DNN=1
+fi
+
if test "$enable_libcl" = "yes" && test "$HAVE_LIBCL" -eq 0; then
PKG_CHECK_MODULES(LIBCL, [OpenCL], [HAVE_LIBCL=1], [HAVE_LIBCL=0])
fi
@@ -143,12 +215,21 @@ if test "$HAVE_LIBCL" -eq 1; then
fi
fi
-# check opencv minimum version number
+# check opencv version number
HAVE_OPENCV=0
if test "$enable_opencv" = "yes"; then
- OPENCV_VERSION_STR=`$PKG_CONFIG --modversion opencv`
- PKG_CHECK_MODULES([OPENCV], [opencv >= 3.0.0], [HAVE_OPENCV=1], [HAVE_OPENCV=0])
- echo "OpenCV version:"$OPENCV_VERSION_STR "minimum required version:3.0.0" "have opencv:"$HAVE_OPENCV
+ PKG_CHECK_MODULES(
+ [OPENCV],
+ [opencv >= $XCAM_REQUIRE_CV_MIN opencv <= $XCAM_REQUIRE_CV_MAX],
+ [HAVE_OPENCV=1],
+ [HAVE_OPENCV=0])
+
+ XCAM_CV_VERSION=`$PKG_CONFIG --modversion opencv`
+ AC_MSG_NOTICE(OpenCV version: $XCAM_CV_VERSION)
+
+ if test "$HAVE_OPENCV" -eq 0; then
+ AC_MSG_ERROR(OpenCV required version: >= $XCAM_REQUIRE_CV_MIN && <= $XCAM_REQUIRE_CV_MAX)
+ fi
fi
# check opencv videostab module
@@ -193,7 +274,8 @@ fi
# check capi build
ENABLE_CAPI=0
-if test "$enable_capi" = "yes"; then
+if test "$enable_capi" = "yes" && test "$HAVE_LIBCL" -eq 1; then
+ AC_MSG_NOTICE(enable capi && have libcl: $HAVE_LIBCL)
ENABLE_CAPI=1
fi
@@ -305,7 +387,7 @@ fi
AM_CONDITIONAL([ENABLE_GST], [test "$ENABLE_GST" -eq 1])
dnl set XCAM_CFLAGS and XCAM_CXXFLAGS
-XCAM_CFLAGS=" -fPIC -DSTDC99 -W -Wall -D_REENTRANT -Wformat -Wformat-security -fstack-protector"
+XCAM_CFLAGS=" -fPIC -Wall -fstack-protector"
if test "$enable_debug" = "yes"; then
XCAM_CFLAGS="$XCAM_CFLAGS -g -DDEBUG"
fi
@@ -313,9 +395,6 @@ XCAM_CXXFLAGS="$XCAM_CFLAGS -std=c++0x"
AC_SUBST(XCAM_CFLAGS)
AC_SUBST(XCAM_CXXFLAGS)
-PTHREAD_LDFLAGS="$PTHREAD_LDFLAGS -pthread"
-AC_SUBST(PTHREAD_LDFLAGS)
-
# define macor in config.h
AC_DEFINE_UNQUOTED([ENABLE_PROFILING], $ENABLE_PROFILING,
[enable profiling])
@@ -328,6 +407,22 @@ AC_DEFINE_UNQUOTED([HAVE_LIBCL], $HAVE_LIBCL,
[have libcl])
AM_CONDITIONAL([HAVE_LIBCL], [test "$HAVE_LIBCL" -eq 1])
+AC_DEFINE_UNQUOTED([HAVE_GLES], $HAVE_GLES,
+ [have gles])
+AM_CONDITIONAL([HAVE_GLES], [test "$HAVE_GLES" -eq 1])
+
+AC_DEFINE_UNQUOTED([HAVE_VULKAN], $HAVE_VULKAN,
+ [have vulkan])
+AM_CONDITIONAL([HAVE_VULKAN], [test "$HAVE_VULKAN" -eq 1])
+
+AC_DEFINE_UNQUOTED([ENABLE_RENDER], $ENABLE_RENDER,
+ [enable texture render])
+AM_CONDITIONAL([ENABLE_RENDER], [test "$ENABLE_RENDER" -eq 1])
+
+AC_DEFINE_UNQUOTED([ENABLE_DNN], $ENABLE_DNN,
+ [enable dnn])
+AM_CONDITIONAL([ENABLE_DNN], [test "$ENABLE_DNN" -eq 1])
+
AC_DEFINE_UNQUOTED([HAVE_OPENCV], $HAVE_OPENCV,
[have opencv])
AM_CONDITIONAL([HAVE_OPENCV], [test "$HAVE_OPENCV" -eq 1])
@@ -354,12 +449,19 @@ AM_CONDITIONAL([ENABLE_IA_AIQ], [test "$ENABLE_IA_AIQ" -eq 1])
AM_CONDITIONAL([USE_LOCAL_AIQ], [test "$USE_LOCAL_AIQ" -eq 1])
AC_CONFIG_FILES([Makefile
- clx_kernel/Makefile
+ shaders/Makefile
+ shaders/clx/Makefile
+ shaders/glslx/Makefile
xcore/Makefile
modules/Makefile
+ modules/ocv/Makefile
modules/soft/Makefile
modules/isp/Makefile
modules/ocl/Makefile
+ modules/gles/Makefile
+ modules/vulkan/Makefile
+ modules/render/Makefile
+ modules/dnn/Makefile
wrapper/Makefile
wrapper/gstreamer/Makefile
wrapper/gstreamer/interface/Makefile
@@ -383,8 +485,13 @@ if test "$HAVE_LIBDRM" -eq 1; then have_drm="yes"; else have_drm="no"; fi
if test "$USE_LOCAL_AIQ" -eq 1; then use_local_aiq="yes"; else use_local_aiq="no"; fi
if test "$USE_LOCAL_ATOMISP" -eq 1; then use_local_atomisp="yes"; else use_local_atomisp="no"; fi
if test "$HAVE_LIBCL" -eq 1; then have_libcl="yes"; else have_libcl="no"; fi
+if test "$HAVE_GLES" -eq 1; then have_gles="yes"; else have_gles="no"; fi
+if test "$HAVE_VULKAN" -eq 1; then have_vulkan="yes"; else have_vulkan="no"; fi
if test "$HAVE_OPENCV" -eq 1; then have_opencv="yes"; else have_opencv="no"; fi
+if test "$ENABLE_RENDER" -eq 1; then enable_render="yes"; else enable_render="no"; fi
+if test "$ENABLE_DNN" -eq 1; then enable_dnn="yes"; else enable_dnn="no"; fi
if test "$ENABLE_DVS" -eq 1; then enable_dvs="yes"; else enable_dvs="no"; fi
+if test "$ENABLE_CAPI" -eq 1; then enable_capi="yes"; else enable_capi="no"; fi
echo "
libxcam configuration summary
@@ -396,8 +503,12 @@ echo "
build aiq analyzer : $enable_aiq
use local aiq : $use_local_aiq
use local atomisp : $use_local_atomisp
- have opencl lib : $have_libcl
- have opencv lib : $have_opencv
+ enable OpenCV : $have_opencv
+ enable OpenCL : $have_libcl
+ enable GLES : $have_gles
+ enable Vulkan : $have_vulkan
+ enable OSG render : $enable_render
+ enable DNN : $enable_dnn
enable 3a lib : $enable_3alib
enable smart analysis lib : $enable_smartlib
enable dvs : $enable_dvs
diff --git a/doc/xcam_framework_20170407.png b/doc/xcam_framework_20170407.png
deleted file mode 100644
index ea7b7ee..0000000
--- a/doc/xcam_framework_20170407.png
+++ /dev/null
Binary files differ
diff --git a/doc/xcam_framework_20181017.png b/doc/xcam_framework_20181017.png
new file mode 100644
index 0000000..1419323
--- /dev/null
+++ b/doc/xcam_framework_20181017.png
Binary files differ
diff --git a/doc/xcam_framework_20190329.png b/doc/xcam_framework_20190329.png
new file mode 100644
index 0000000..4bcacf1
--- /dev/null
+++ b/doc/xcam_framework_20190329.png
Binary files differ
diff --git a/doc/yocto/libxcam_sample.bb b/doc/yocto/libxcam_sample.bb
index 0ebdd31..26c728e 100644
--- a/doc/yocto/libxcam_sample.bb
+++ b/doc/yocto/libxcam_sample.bb
@@ -1,6 +1,6 @@
SUMMARY = "Libxcam"
DESCRIPTION = "Libxcam: Extended camera features and cross platform computer vision project"
-HOMEPAGE = "https://github.com/01org/libxcam/wiki"
+HOMEPAGE = "https://github.com/intel/libxcam/wiki"
LICENSE = "Apache-2.0"
PR = "r0"
@@ -8,7 +8,7 @@ S = "${WORKDIR}/git"
LIC_FILES_CHKSUM = "file://${S}/LICENSE;md5=a739187a9544e0731270d11a8f5be792"
-SRC_URI = "git://github.com/01org/libxcam.git;branch=master"
+SRC_URI = "git://github.com/intel/libxcam.git;branch=master"
SRCREV = "${AUTOREV}"
DEPENDS = "glib-2.0 libdrm beignet opencv gstreamer1.0 gstreamer1.0-plugins-base"
@@ -19,7 +19,7 @@ EXTRA_OECONF = "--enable-gst --enable-drm --enable-libcl --enable-smartlib --ena
CFLAGS += "-fPIE -fPIC"
CFLAGS += "-O2 -D_FORTIFY_SOURCE=2"
-CFLAGS += "-Wformat -Wformat-security"
+CFLAGS += "-Wall -Wno-unused-parameter"
CFLAGS += "-fstack-protector"
LDFLAGS += "-z noexecstack"
diff --git a/modules/Makefile.am b/modules/Makefile.am
index fd362f8..b4eda9b 100644
--- a/modules/Makefile.am
+++ b/modules/Makefile.am
@@ -1,13 +1,29 @@
+if HAVE_OPENCV
+OCV_DIR = ocv
+endif
+
if HAVE_LIBCL
OCL_DIR = ocl
-else
-OCL_DIR =
+endif
+
+if HAVE_GLES
+GLES_DIR = gles
+endif
+
+if HAVE_VULKAN
+VULKAN_DIR = vulkan
+endif
+
+if ENABLE_RENDER
+RENDER_DIR = render
endif
if ENABLE_IA_AIQ
ISP_DIR = isp
-else
-ISP_DIR =
endif
-SUBDIRS = soft $(ISP_DIR) $(OCL_DIR)
+if ENABLE_DNN
+DNN_DIR = dnn
+endif
+
+SUBDIRS = $(OCV_DIR) soft $(OCL_DIR) $(GLES_DIR) $(VULKAN_DIR) $(RENDER_DIR) $(ISP_DIR) $(DNN_DIR)
diff --git a/modules/dnn/Makefile.am b/modules/dnn/Makefile.am
new file mode 100644
index 0000000..bcad5fd
--- /dev/null
+++ b/modules/dnn/Makefile.am
@@ -0,0 +1,52 @@
+lib_LTLIBRARIES = libxcam_dnn.la
+
+XCAM_DNN_CXXFLAGS = \
+ $(XCAM_CXXFLAGS) \
+ -I$(top_srcdir)/xcore \
+ -I$(top_srcdir)/modules \
+ -I$(OPENVINO_IE_INC_PATH)/include \
+ -I$(OPENVINO_IE_INC_PATH)/src/extension \
+ -I$(OPENVINO_IE_INC_PATH)/samples/common/format_reader \
+ $(NULL)
+
+XCAM_DNN_LIBS = \
+ $(top_builddir)/xcore/libxcam_core.la \
+ -L$(OPENVINO_IE_LIBS_PATH) \
+ -linference_engine \
+ -lclDNN64 \
+ -lclDNNPlugin \
+ -lcpu_extension \
+ -lMKLDNNPlugin \
+ -lformat_reader \
+ $(NULL)
+
+xcam_dnn_sources = \
+ dnn_inference_engine.cpp \
+ dnn_object_detection.cpp \
+ $(NULL)
+
+libxcam_dnn_la_SOURCES = \
+ $(xcam_dnn_sources) \
+ $(NULL)
+
+libxcam_dnn_la_CXXFLAGS = \
+ $(XCAM_DNN_CXXFLAGS) \
+ $(NULL)
+
+libxcam_dnn_la_LIBADD = \
+ $(XCAM_DNN_LIBS) \
+ $(NULL)
+
+libxcam_dnn_la_LDFLAGS = \
+ $(XCAM_LT_LDFLAGS) \
+ -Wl,-rpath,$(OPENVINO_IE_LIBS_PATH) \
+ $(NULL)
+
+libxcam_dnnincludedir = $(includedir)/xcam/dnn
+
+nobase_libxcam_dnninclude_HEADERS = \
+ dnn_inference_engine.h \
+ dnn_object_detection.h \
+ $(NULL)
+
+libxcam_dnn_la_LIBTOOLFLAGS = --tag=disable-static
diff --git a/modules/dnn/dnn_inference_engine.cpp b/modules/dnn/dnn_inference_engine.cpp
new file mode 100755
index 0000000..8453161
--- /dev/null
+++ b/modules/dnn/dnn_inference_engine.cpp
@@ -0,0 +1,878 @@
+/*
+ * dnn_inference_engine.cpp - dnn inference engine
+ *
+ * Copyright (c) 2019 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Zong Wei <wei.zong@intel.com>
+ */
+
+#include <iomanip>
+
+#include <format_reader_ptr.h>
+#include <ext_list.hpp>
+
+#include "dnn_inference_engine.h"
+
+using namespace std;
+using namespace InferenceEngine;
+
+namespace XCam {
+
+DnnInferenceEngine::DnnInferenceEngine (DnnInferConfig& config)
+ : _model_created (false)
+ , _model_loaded (false)
+ , _input_image_width (0)
+ , _input_image_height (0)
+{
+ XCAM_LOG_DEBUG ("DnnInferenceEngine::DnnInferenceEngine");
+
+ create_model (config);
+}
+
+
+DnnInferenceEngine::~DnnInferenceEngine ()
+{
+
+}
+
+XCamReturn
+DnnInferenceEngine::create_model (DnnInferConfig& config)
+{
+ XCAM_LOG_DEBUG ("DnnInferenceEngine::create_model");
+ if (_model_created) {
+ XCAM_LOG_INFO ("model already created!");
+ return XCAM_RETURN_NO_ERROR;
+ }
+
+ // 1. Read the Intermediate Representation
+ XCAM_LOG_DEBUG ("pre-trained model file name: %s", config.model_filename);
+ if (NULL == config.model_filename) {
+ XCAM_LOG_ERROR ("Model file name is empty!");
+ return XCAM_RETURN_ERROR_PARAM;
+ }
+
+ _network_reader.ReadNetwork (get_filename_prefix (config.model_filename) + ".xml");
+ _network_reader.ReadWeights (get_filename_prefix (config.model_filename) + ".bin");
+
+ // 2. read network from model
+ _network = _network_reader.getNetwork ();
+
+ // 3. Select Plugin - Select the plugin on which to load your network.
+ // 3.1. Create the plugin with the InferenceEngine::PluginDispatcher load helper class.
+ if (NULL == config.plugin_path) {
+ InferenceEngine::PluginDispatcher dispatcher ({""});
+ _plugin = dispatcher.getPluginByDevice (getDeviceName (get_device_from_id (config.target_id)));
+ } else {
+ InferenceEngine::PluginDispatcher dispatcher ({config.plugin_path});
+ _plugin = dispatcher.getPluginByDevice (getDeviceName (get_device_from_id (config.target_id)));
+ }
+
+ // 3.2. Pass per device loading configurations specific to this device,
+ // and register extensions to this device.
+ if (DnnInferDeviceCPU == config.target_id) {
+ /**
+ * cpu_extensions library is compiled from "extension" folder containing
+ * custom MKLDNNPlugin layer implementations. These layers are not supported
+ * by mkldnn, but they can be useful for inferring custom topologies.
+ **/
+ _plugin.AddExtension (std::make_shared<Extensions::Cpu::CpuExtensions>());
+
+ if (NULL != config.cpu_ext_path) {
+ std::string cpu_ext_path (config.cpu_ext_path);
+ // CPU(MKLDNN) extensions are loaded as a shared library and passed as a pointer to base extension
+ auto extensionPtr = InferenceEngine::make_so_pointer<InferenceEngine::IExtension>(cpu_ext_path);
+ _plugin.AddExtension (extensionPtr);
+ XCAM_LOG_DEBUG ("CPU Extension loaded: %s", cpu_ext_path);
+ }
+ } else if (DnnInferDeviceGPU == config.target_id) {
+ if (NULL != config.cldnn_ext_path) {
+ std::string cldnn_ext_path (config.cldnn_ext_path);
+ // clDNN Extensions are loaded from an .xml description and OpenCL kernel files
+ _plugin.SetConfig ({ { InferenceEngine::PluginConfigParams::KEY_CONFIG_FILE, cldnn_ext_path } });
+ XCAM_LOG_DEBUG ("GPU Extension loaded: %s", cldnn_ext_path);
+ }
+ }
+
+ if (config.perf_counter > 0) {
+ _plugin.SetConfig ({ { InferenceEngine::PluginConfigParams::KEY_PERF_COUNT, InferenceEngine::PluginConfigParams::YES } });
+ }
+
+ _model_created = true;
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+DnnInferenceEngine::load_model (DnnInferConfig& config)
+{
+ XCAM_LOG_DEBUG ("DnnInferenceEngine::load_model");
+ if (! _model_created) {
+ XCAM_LOG_ERROR ("Please create the model firstly!");
+ return XCAM_RETURN_ERROR_ORDER;
+ }
+ if (_model_loaded) {
+ XCAM_LOG_INFO ("model already loaded!");
+ return XCAM_RETURN_NO_ERROR;
+ }
+
+ InferenceEngine::ExecutableNetwork execute_network = _plugin.LoadNetwork (_network, {});
+
+ _infer_request = execute_network.CreateInferRequest ();
+
+ _model_loaded = true;
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+DnnInferenceEngine::get_info (DnnInferenceEngineInfo& info, DnnInferInfoType type)
+{
+ XCAM_LOG_DEBUG ("DnnInferenceEngine::get_info type %d", type);
+
+ if (! _model_created) {
+ XCAM_LOG_ERROR ("Please create the model firstly!");
+ return XCAM_RETURN_ERROR_ORDER;
+ }
+
+ info.type = type;
+ if (DnnInferInfoEngine == type) {
+ info.major = GetInferenceEngineVersion ()->apiVersion.major;
+ info.minor = GetInferenceEngineVersion ()->apiVersion.minor;
+ } else if (DnnInferInfoPlugin == type) {
+ const InferenceEngine::Version *plugin_version = NULL;
+ static_cast<InferenceEngine::InferenceEnginePluginPtr>(_plugin)->GetVersion (plugin_version);
+
+ info.major = plugin_version->apiVersion.major;
+ info.minor = plugin_version->apiVersion.minor;
+ info.desc = plugin_version->description;
+ } else if (DnnInferInfoNetwork == type) {
+ info.major = _network_reader.getVersion ();
+ info.desc = _network_reader.getDescription ().c_str ();
+ info.name = _network_reader.getName ().c_str ();
+ } else {
+ XCAM_LOG_WARNING ("DnnInferenceEngine::get_info type %d not supported!", type);
+ }
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+DnnInferenceEngine::set_batch_size (const size_t size)
+{
+ if (! _model_created) {
+ XCAM_LOG_ERROR ("Please create the model firstly!");
+ return XCAM_RETURN_ERROR_ORDER;
+ }
+
+ _network.setBatchSize (size);
+ return XCAM_RETURN_NO_ERROR;
+}
+
+size_t
+DnnInferenceEngine::get_batch_size ()
+{
+ if (! _model_created) {
+ XCAM_LOG_ERROR ("Please create the model firstly!");
+ return -1;
+ }
+
+ return _network.getBatchSize ();
+}
+
+XCamReturn
+DnnInferenceEngine::start (bool sync)
+{
+ XCAM_LOG_DEBUG ("Start inference sync(%d)", sync);
+
+ if (! _model_loaded) {
+ XCAM_LOG_ERROR ("Please load the model firstly!");
+ return XCAM_RETURN_ERROR_ORDER;
+ }
+
+ if (sync) {
+ _infer_request.Infer ();
+ } else {
+ _infer_request.StartAsync ();
+ _infer_request.Wait (IInferRequest::WaitMode::RESULT_READY);
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+size_t
+DnnInferenceEngine::get_input_size ()
+{
+ if (! _model_created) {
+ XCAM_LOG_ERROR ("Please create the model firstly!");
+ return -1;
+ }
+
+ InputsDataMap inputs_info (_network.getInputsInfo());
+ return inputs_info.size ();
+}
+
+size_t
+DnnInferenceEngine::get_output_size ()
+{
+ if (! _model_created) {
+ XCAM_LOG_ERROR ("Please create the model firstly!");
+ return -1;
+ }
+
+ OutputsDataMap outputs_info (_network.getOutputsInfo());
+ return outputs_info.size ();
+}
+
+XCamReturn
+DnnInferenceEngine::set_input_presion (uint32_t idx, DnnInferPrecisionType precision)
+{
+ if (! _model_created) {
+ XCAM_LOG_ERROR ("Please create the model firstly!");
+ return XCAM_RETURN_ERROR_ORDER;
+ }
+
+ uint32_t id = 0;
+ InputsDataMap inputs_info (_network.getInputsInfo ());
+
+ if (idx > inputs_info.size ()) {
+ XCAM_LOG_ERROR ("Input is out of range");
+ return XCAM_RETURN_ERROR_PARAM;
+ }
+
+ for (auto & item : inputs_info) {
+ if (id == idx) {
+ Precision input_precision = convert_precision_type (precision);
+ item.second->setPrecision (input_precision);
+ break;
+ }
+ id++;
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+DnnInferPrecisionType
+DnnInferenceEngine::get_input_presion (uint32_t idx)
+{
+ if (! _model_created) {
+ XCAM_LOG_ERROR ("Please create the model firstly!");
+ return DnnInferPrecisionUnspecified;
+ }
+
+ uint32_t id = 0;
+ InputsDataMap inputs_info (_network.getInputsInfo ());
+
+ if (idx > inputs_info.size ()) {
+ XCAM_LOG_ERROR ("Input is out of range");
+ return DnnInferPrecisionUnspecified;
+ }
+
+ for (auto & item : inputs_info) {
+ if (id == idx) {
+ Precision input_precision = item.second->getPrecision ();
+ return convert_precision_type (input_precision);
+ }
+ id++;
+ }
+ return DnnInferPrecisionUnspecified;
+}
+
+XCamReturn
+DnnInferenceEngine::set_output_presion (uint32_t idx, DnnInferPrecisionType precision)
+{
+ if (! _model_created) {
+ XCAM_LOG_ERROR ("Please create the model firstly!");
+ return XCAM_RETURN_ERROR_ORDER;
+ }
+
+ uint32_t id = 0;
+ OutputsDataMap outputs_info (_network.getOutputsInfo ());
+
+ if (idx > outputs_info.size ()) {
+ XCAM_LOG_ERROR ("Output is out of range");
+ return XCAM_RETURN_ERROR_PARAM;
+ }
+
+ for (auto & item : outputs_info) {
+ if (id == idx) {
+ Precision output_precision = convert_precision_type (precision);
+ item.second->setPrecision (output_precision);
+ break;
+ }
+ id++;
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+DnnInferPrecisionType
+DnnInferenceEngine::get_output_presion (uint32_t idx)
+{
+ if (! _model_created) {
+ XCAM_LOG_ERROR ("Please create the model firstly!");
+ return DnnInferPrecisionUnspecified;
+ }
+
+ uint32_t id = 0;
+ OutputsDataMap outputs_info (_network.getOutputsInfo ());
+
+ if (idx > outputs_info.size ()) {
+ XCAM_LOG_ERROR ("Input is out of range");
+ return DnnInferPrecisionUnspecified;
+ }
+
+ for (auto & item : outputs_info) {
+ if (id == idx) {
+ Precision output_precision = item.second->getPrecision ();
+ return convert_precision_type (output_precision);
+ }
+ id++;
+ }
+ return DnnInferPrecisionUnspecified;
+}
+
+XCamReturn
+DnnInferenceEngine::set_input_layout (uint32_t idx, DnnInferLayoutType layout)
+{
+ if (! _model_created) {
+ XCAM_LOG_ERROR ("Please create the model firstly!");
+ return XCAM_RETURN_ERROR_ORDER;
+ }
+ uint32_t id = 0;
+ InputsDataMap inputs_info (_network.getInputsInfo ());
+
+ if (idx > inputs_info.size ()) {
+ XCAM_LOG_ERROR ("Input is out of range");
+ return XCAM_RETURN_ERROR_PARAM;
+ }
+
+ for (auto & item : inputs_info) {
+ if (id == idx) {
+ /** Creating first input blob **/
+ Layout input_layout = convert_layout_type (layout);
+ item.second->setLayout (input_layout);
+ break;
+ }
+ id++;
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+DnnInferenceEngine::set_output_layout (uint32_t idx, DnnInferLayoutType layout)
+{
+ if (! _model_created) {
+ XCAM_LOG_ERROR ("Please create the model firstly!");
+ return XCAM_RETURN_ERROR_ORDER;
+ }
+
+ uint32_t id = 0;
+ OutputsDataMap outputs_info (_network.getOutputsInfo ());
+
+ if (idx > outputs_info.size ()) {
+ XCAM_LOG_ERROR ("Output is out of range");
+ return XCAM_RETURN_ERROR_PARAM;
+ }
+
+ for (auto & item : outputs_info) {
+ if (id == idx) {
+ Layout output_layout = convert_layout_type (layout);
+ item.second->setLayout (output_layout);
+ break;
+ }
+ id++;
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+DnnInferenceEngine::set_model_input_info (DnnInferInputOutputInfo& info)
+{
+ XCAM_LOG_DEBUG ("DnnInferenceEngine::set_model_input_info");
+
+ if (!_model_created) {
+ XCAM_LOG_ERROR ("Please create the model firstly!");
+ return XCAM_RETURN_ERROR_ORDER;
+ }
+
+ InputsDataMap inputs_info (_network.getInputsInfo ());
+
+ if (info.numbers != inputs_info.size ()) {
+ XCAM_LOG_ERROR ("Input size is not matched with model info numbers %d !", info.numbers);
+ return XCAM_RETURN_ERROR_PARAM;
+ }
+ int id = 0;
+
+ for (auto & item : inputs_info) {
+ Precision precision = convert_precision_type (info.precision[id]);
+ item.second->setPrecision (precision);
+ Layout layout = convert_layout_type (info.layout[id]);
+ item.second->setLayout (layout);
+ id++;
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+DnnInferenceEngine::set_model_output_info (DnnInferInputOutputInfo& info)
+{
+ if (!_model_created) {
+ XCAM_LOG_ERROR ("Please create the model firstly!");
+ return XCAM_RETURN_ERROR_ORDER;
+ }
+
+ OutputsDataMap outputs_info (_network.getOutputsInfo ());
+
+ if (info.numbers != outputs_info.size()) {
+ XCAM_LOG_ERROR ("Output size is not matched with model!");
+ return XCAM_RETURN_ERROR_PARAM;
+ }
+
+ int id = 0;
+ for (auto & item : outputs_info) {
+ Precision precision = convert_precision_type (info.precision[id]);
+ item.second->setPrecision (precision);
+ Layout layout = convert_layout_type (info.layout[id]);
+ item.second->setLayout (layout);
+ id++;
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+DnnInferenceEngine::set_input_blob (uint32_t idx, DnnInferData& data)
+{
+ unsigned int id = 0;
+ std::string item_name;
+ InputsDataMap inputs_info (_network.getInputsInfo ());
+
+ if (idx > inputs_info.size()) {
+ XCAM_LOG_ERROR ("Input is out of range");
+ return XCAM_RETURN_ERROR_PARAM;
+ }
+
+ for (auto & item : inputs_info) {
+ if (id == idx) {
+ item_name = item.first;
+ break;
+ }
+ id++;
+ }
+
+ if (item_name.empty ()) {
+ XCAM_LOG_ERROR ("item name is empty!");
+ return XCAM_RETURN_ERROR_PARAM;
+ }
+
+ if (data.batch_idx > get_batch_size ()) {
+ XCAM_LOG_ERROR ("Too many input, it is bigger than batch size!");
+ return XCAM_RETURN_ERROR_PARAM;
+ }
+
+ Blob::Ptr blob = _infer_request.GetBlob (item_name);
+ if (data.precision == DnnInferPrecisionFP32) {
+ if (data.data_type == DnnInferDataTypeImage) {
+ copy_image_to_blob<PrecisionTrait<Precision::FP32>::value_type>(data, blob, data.batch_idx);
+ } else {
+ copy_data_to_blob<PrecisionTrait<Precision::FP32>::value_type>(data, blob, data.batch_idx);
+ }
+ } else {
+ if (data.data_type == DnnInferDataTypeImage) {
+ copy_image_to_blob<uint8_t>(data, blob, data.batch_idx);
+ } else {
+ copy_data_to_blob<uint8_t>(data, blob, data.batch_idx);
+ }
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+DnnInferenceEngine::set_inference_data (std::vector<std::string> images)
+{
+ if (!_model_created) {
+ XCAM_LOG_ERROR ("Please create the model firstly!");
+ return XCAM_RETURN_ERROR_ORDER;
+ }
+
+ uint32_t idx = 0;
+ InputsDataMap inputs_info (_network.getInputsInfo ());
+
+ for (auto & i : images) {
+ FormatReader::ReaderPtr reader (i.c_str ());
+ if (reader.get () == NULL) {
+ XCAM_LOG_WARNING ("Image %d cannot be read!", i);
+ continue;
+ }
+
+ _input_image_width = reader->width ();
+ _input_image_height = reader->height ();
+
+ uint32_t image_width = 0;
+ uint32_t image_height = 0;
+
+ for (auto & item : inputs_info) {
+ image_width = inputs_info[item.first]->getDims()[0];
+ image_height = inputs_info[item.first]->getDims()[1];
+ }
+
+ std::shared_ptr<unsigned char> data (reader->getData (image_width, image_height));
+
+ if (data.get () != NULL) {
+ DnnInferData image;
+ image.width = image_width;
+ image.height = image_height;
+ image.width_stride = image_width;
+ image.height_stride = image_height;
+ image.buffer = data.get ();
+ image.channel_num = 3;
+ image.batch_idx = idx;
+ image.image_format = DnnInferImageFormatBGRPacked;
+
+ // set precision & data type
+ image.precision = get_input_presion (idx);
+ image.data_type = DnnInferDataTypeImage;
+
+ set_input_blob (idx, image);
+
+ idx ++;
+ } else {
+ XCAM_LOG_WARNING ("Valid input images were not found!");
+ continue;
+ }
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+std::shared_ptr<uint8_t>
+DnnInferenceEngine::read_inference_image (std::string image)
+{
+ FormatReader::ReaderPtr reader (image.c_str ());
+ if (reader.get () == NULL) {
+ XCAM_LOG_WARNING ("Image cannot be read!");
+ return NULL;
+ }
+
+ uint32_t image_width = reader->width ();
+ uint32_t image_height = reader->height ();
+
+ std::shared_ptr<uint8_t> data (reader->getData (image_width, image_height));
+
+ if (data.get () != NULL) {
+ return data;
+ } else {
+ XCAM_LOG_WARNING ("Valid input images were not found!");
+ return NULL;
+ }
+}
+
+InferenceEngine::TargetDevice
+DnnInferenceEngine::get_device_from_string (const std::string &device_name)
+{
+ return InferenceEngine::TargetDeviceInfo::fromStr (device_name);
+}
+
+InferenceEngine::TargetDevice
+DnnInferenceEngine::get_device_from_id (DnnInferTargetDeviceType device)
+{
+ switch (device) {
+ case DnnInferDeviceDefault:
+ return InferenceEngine::TargetDevice::eDefault;
+ case DnnInferDeviceBalanced:
+ return InferenceEngine::TargetDevice::eBalanced;
+ case DnnInferDeviceCPU:
+ return InferenceEngine::TargetDevice::eCPU;
+ case DnnInferDeviceGPU:
+ return InferenceEngine::TargetDevice::eGPU;
+ case DnnInferDeviceFPGA:
+ return InferenceEngine::TargetDevice::eFPGA;
+ case DnnInferDeviceMyriad:
+ return InferenceEngine::TargetDevice::eMYRIAD;
+ case DnnInferDeviceHetero:
+ return InferenceEngine::TargetDevice::eHETERO;
+ default:
+ return InferenceEngine::TargetDevice::eCPU;
+ }
+}
+
+InferenceEngine::Layout
+DnnInferenceEngine::estimate_layout_type (const int ch_num)
+{
+ if (ch_num == 4) {
+ return InferenceEngine::Layout::NCHW;
+ } else if (ch_num == 3) {
+ return InferenceEngine::Layout::CHW;
+ } else if (ch_num == 2) {
+ return InferenceEngine::Layout::NC;
+ } else {
+ return InferenceEngine::Layout::ANY;
+ }
+}
+
+InferenceEngine::Layout
+DnnInferenceEngine::convert_layout_type (DnnInferLayoutType layout)
+{
+ switch (layout) {
+ case DnnInferLayoutNCHW:
+ return InferenceEngine::Layout::NCHW;
+ case DnnInferLayoutNHWC:
+ return InferenceEngine::Layout::NHWC;
+ case DnnInferLayoutOIHW:
+ return InferenceEngine::Layout::OIHW;
+ case DnnInferLayoutC:
+ return InferenceEngine::Layout::C;
+ case DnnInferLayoutCHW:
+ return InferenceEngine::Layout::CHW;
+ case DnnInferLayoutHW:
+ return InferenceEngine::Layout::HW;
+ case DnnInferLayoutNC:
+ return InferenceEngine::Layout::NC;
+ case DnnInferLayoutCN:
+ return InferenceEngine::Layout::CN;
+ case DnnInferLayoutBlocked:
+ return InferenceEngine::Layout::BLOCKED;
+ case DnnInferLayoutAny:
+ return InferenceEngine::Layout::ANY;
+ default:
+ return InferenceEngine::Layout::ANY;
+ }
+}
+
+DnnInferLayoutType
+DnnInferenceEngine::convert_layout_type (InferenceEngine::Layout layout)
+{
+ switch (layout) {
+ case InferenceEngine::Layout::NCHW:
+ return DnnInferLayoutNCHW;
+ case InferenceEngine::Layout::NHWC:
+ return DnnInferLayoutNHWC;
+ case InferenceEngine::Layout::OIHW:
+ return DnnInferLayoutOIHW;
+ case InferenceEngine::Layout::C:
+ return DnnInferLayoutC;
+ case InferenceEngine::Layout::CHW:
+ return DnnInferLayoutCHW;
+ case InferenceEngine::Layout::HW:
+ return DnnInferLayoutHW;
+ case InferenceEngine::Layout::NC:
+ return DnnInferLayoutNC;
+ case InferenceEngine::Layout::CN:
+ return DnnInferLayoutCN;
+ case InferenceEngine::Layout::BLOCKED:
+ return DnnInferLayoutBlocked;
+ case InferenceEngine::Layout::ANY:
+ return DnnInferLayoutAny;
+ default:
+ return DnnInferLayoutAny;
+ }
+}
+
+InferenceEngine::Precision
+DnnInferenceEngine::convert_precision_type (DnnInferPrecisionType precision)
+{
+ switch (precision) {
+ case DnnInferPrecisionMixed:
+ return InferenceEngine::Precision::MIXED;
+ case DnnInferPrecisionFP32:
+ return InferenceEngine::Precision::FP32;
+ case DnnInferPrecisionFP16:
+ return InferenceEngine::Precision::FP16;
+ case DnnInferPrecisionQ78:
+ return InferenceEngine::Precision::Q78;
+ case DnnInferPrecisionI16:
+ return InferenceEngine::Precision::I16;
+ case DnnInferPrecisionU8:
+ return InferenceEngine::Precision::U8;
+ case DnnInferPrecisionI8:
+ return InferenceEngine::Precision::I8;
+ case DnnInferPrecisionU16:
+ return InferenceEngine::Precision::U16;
+ case DnnInferPrecisionI32:
+ return InferenceEngine::Precision::I32;
+ case DnnInferPrecisionCustom:
+ return InferenceEngine::Precision::CUSTOM;
+ case DnnInferPrecisionUnspecified:
+ return InferenceEngine::Precision::UNSPECIFIED;
+ default:
+ return InferenceEngine::Precision::UNSPECIFIED;
+ }
+}
+
+DnnInferPrecisionType
+DnnInferenceEngine::convert_precision_type (InferenceEngine::Precision precision)
+{
+ switch (precision) {
+ case InferenceEngine::Precision::MIXED:
+ return DnnInferPrecisionMixed;
+ case InferenceEngine::Precision::FP32:
+ return DnnInferPrecisionFP32;
+ case InferenceEngine::Precision::FP16:
+ return DnnInferPrecisionFP16;
+ case InferenceEngine::Precision::Q78:
+ return DnnInferPrecisionQ78;
+ case InferenceEngine::Precision::I16:
+ return DnnInferPrecisionI16;
+ case InferenceEngine::Precision::U8:
+ return DnnInferPrecisionU8;
+ case InferenceEngine::Precision::I8:
+ return DnnInferPrecisionI8;
+ case InferenceEngine::Precision::U16:
+ return DnnInferPrecisionU16;
+ case InferenceEngine::Precision::I32:
+ return DnnInferPrecisionI32;
+ case InferenceEngine::Precision::CUSTOM:
+ return DnnInferPrecisionCustom;
+ case InferenceEngine::Precision::UNSPECIFIED:
+ return DnnInferPrecisionUnspecified;
+ default:
+ return DnnInferPrecisionUnspecified;
+ }
+}
+
+std::string
+DnnInferenceEngine::get_filename_prefix (const std::string &file_path)
+{
+ auto pos = file_path.rfind ('.');
+ if (pos == std::string::npos) {
+ return file_path;
+ }
+
+ return file_path.substr (0, pos);
+}
+
+template <typename T> XCamReturn
+DnnInferenceEngine::copy_image_to_blob (const DnnInferData& data, Blob::Ptr& blob, int batch_index)
+{
+ SizeVector blob_size = blob.get()->dims ();
+ const size_t width = blob_size[0];
+ const size_t height = blob_size[1];
+ const size_t channels = blob_size[2];
+ const size_t image_size = width * height;
+ unsigned char* buffer = (unsigned char*)data.buffer;
+ T* blob_data = blob->buffer ().as<T*>();
+
+ if (width != data.width || height != data.height) {
+ XCAM_LOG_ERROR ("Input Image size (%dx%d) is not matched with model required size (%dx%d)!",
+ data.width, data.height, width, height);
+ return XCAM_RETURN_ERROR_PARAM;
+ }
+
+ int batch_offset = batch_index * height * width * channels;
+
+ if (DnnInferImageFormatBGRPlanar == data.image_format) {
+ // B G R planar input image
+ size_t image_stride_size = data.height_stride * data.width_stride;
+
+ if (data.width == data.width_stride &&
+ data.height == data.height_stride) {
+ std::memcpy (blob_data + batch_offset, buffer, image_size * channels);
+ } else if (data.width == data.width_stride) {
+ for (size_t ch = 0; ch < channels; ++ch) {
+ std::memcpy (blob_data + batch_offset + ch * image_size, buffer + ch * image_stride_size, image_size);
+ }
+ } else {
+ for (size_t ch = 0; ch < channels; ++ch) {
+ for (size_t h = 0; h < height; h++) {
+ std::memcpy (blob_data + batch_offset + ch * image_size + h * width, buffer + ch * image_stride_size + h * data.width_stride, width);
+ }
+ }
+ }
+ } else if (DnnInferImageFormatBGRPacked == data.image_format) {
+ for (size_t pid = 0; pid < image_size; pid++) {
+ for (size_t ch = 0; ch < channels; ++ch) {
+ blob_data[batch_offset + ch * image_size + pid] = buffer[pid * channels + ch];
+ }
+ }
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+template <typename T> XCamReturn
+DnnInferenceEngine::copy_data_to_blob (const DnnInferData& data, Blob::Ptr& blob, int batch_index)
+{
+ SizeVector blob_size = blob.get ()->dims ();
+ T * buffer = (T *)data.buffer;
+ T* blob_data = blob->buffer ().as<T*>();
+
+ int batch_offset = batch_index * data.size;
+
+ memcpy (blob_data + batch_offset, buffer, data.size);
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+void
+DnnInferenceEngine::print_performance_counts (const std::map<std::string, InferenceEngine::InferenceEngineProfileInfo>& performance_map)
+{
+ long long total_time = 0;
+ XCAM_LOG_DEBUG ("performance counts:");
+ for (const auto & it : performance_map) {
+ std::string to_print(it.first);
+ const int max_layer_name = 30;
+
+ if (it.first.length () >= max_layer_name) {
+ to_print = it.first.substr (0, max_layer_name - 4);
+ to_print += "...";
+ }
+
+ std::cout << std::setw(max_layer_name) << std::left << to_print;
+ switch (it.second.status) {
+ case InferenceEngine::InferenceEngineProfileInfo::EXECUTED:
+ std::cout << std::setw (15) << std::left << "EXECUTED";
+ break;
+ case InferenceEngine::InferenceEngineProfileInfo::NOT_RUN:
+ std::cout << std::setw (15) << std::left << "NOT_RUN";
+ break;
+ case InferenceEngine::InferenceEngineProfileInfo::OPTIMIZED_OUT:
+ std::cout << std::setw(15) << std::left << "OPTIMIZED_OUT";
+ break;
+ }
+ std::cout << std::setw (30) << std::left << "layerType: " + std::string (it.second.layer_type) + " ";
+ std::cout << std::setw (20) << std::left << "realTime: " + std::to_string (it.second.realTime_uSec);
+ std::cout << std::setw (20) << std::left << " cpu: " + std::to_string (it.second.cpu_uSec);
+ std::cout << " execType: " << it.second.exec_type << std::endl;
+ if (it.second.realTime_uSec > 0) {
+ total_time += it.second.realTime_uSec;
+ }
+ }
+ std::cout << std::setw (20) << std::left << "Total time: " + std::to_string (total_time) << " microseconds" << std::endl;
+}
+
+void
+DnnInferenceEngine::print_log (uint32_t flag)
+{
+ std::map<std::string, InferenceEngine::InferenceEngineProfileInfo> perfomance_map;
+
+ if (flag == DnnInferLogLevelNone) {
+ return;
+ }
+
+ if (flag & DnnInferLogLevelEngine) {
+ static_cast<InferenceEngine::InferenceEnginePluginPtr>(_plugin)->GetPerformanceCounts (perfomance_map, NULL);
+ print_performance_counts (perfomance_map);
+ }
+
+ if (flag & DnnInferLogLevelLayer) {
+ perfomance_map = _infer_request.GetPerformanceCounts ();
+ print_performance_counts (perfomance_map);
+ }
+}
+
+} // namespace XCam
diff --git a/modules/dnn/dnn_inference_engine.h b/modules/dnn/dnn_inference_engine.h
new file mode 100755
index 0000000..ed8ed36
--- /dev/null
+++ b/modules/dnn/dnn_inference_engine.h
@@ -0,0 +1,280 @@
+/*
+ * dnn_inference_engine.h - dnn inference engine
+ *
+ * Copyright (c) 2019 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Zong Wei <wei.zong@intel.com>
+ */
+
+#ifndef _XCMA_DNN_INFERENCE_ENGINE_H_
+#define _XCMA_DNN_INFERENCE_ENGINE_H_
+
+#pragma once
+
+#include <vector>
+#include <string>
+#include <inference_engine.hpp>
+
+#include <xcam_std.h>
+
+namespace XCam {
+
+enum DnnInferTargetDeviceType {
+ DnnInferDeviceDefault = 0,
+ DnnInferDeviceBalanced = 1,
+ DnnInferDeviceCPU = 2,
+ DnnInferDeviceGPU = 3,
+ DnnInferDeviceFPGA = 4,
+ DnnInferDeviceMyriad = 5,
+ DnnInferDeviceHetero = 8
+};
+
+enum DnnInferPrecisionType {
+ DnnInferPrecisionMixed = 0,
+ DnnInferPrecisionFP32 = 10,
+ DnnInferPrecisionFP16 = 11,
+ DnnInferPrecisionQ78 = 20,
+ DnnInferPrecisionI16 = 30,
+ DnnInferPrecisionU8 = 40,
+ DnnInferPrecisionI8 = 50,
+ DnnInferPrecisionU16 = 60,
+ DnnInferPrecisionI32 = 70,
+ DnnInferPrecisionCustom = 80,
+ DnnInferPrecisionUnspecified = 255
+};
+
+enum DnnInferLayoutType {
+ DnnInferLayoutAny = 0,
+ DnnInferLayoutNCHW = 1,
+ DnnInferLayoutNHWC = 2,
+ DnnInferLayoutOIHW = 64,
+ DnnInferLayoutC = 96,
+ DnnInferLayoutCHW = 128,
+ DnnInferLayoutHW = 192,
+ DnnInferLayoutNC = 193,
+ DnnInferLayoutCN = 194,
+ DnnInferLayoutBlocked = 200
+};
+
+enum DnnInferMemoryType {
+ DnnInferMemoryDefault = 0,
+ DnnInferMemoryHost = 1,
+ DnnInferMemoryGPU = 2,
+ DnnInferMemoryMYRIAD = 3,
+ DnnInferMemoryShared = 4
+};
+
+enum DnnInferImageFormatType {
+ DnnInferImageFormatBGRPacked = 0,
+ DnnInferImageFormatBGRPlanar,
+ DnnInferImageFormatRGBPacked,
+ DnnInferImageFormatRGBPlanar,
+ DnnInferImageFormatGrayPlanar,
+ DnnInferImageFormatGeneric1D,
+ DnnInferImageFormatGeneric2D,
+ DnnInferImageFormatUnknown = -1
+};
+
+enum DnnInferMode {
+ DnnInferModeSync = 0,
+ DnnInferModeAsync = 1
+};
+
+enum DnnInferDataType {
+ DnnInferDataTypeNonImage = 0,
+ DnnInferDataTypeImage = 1
+};
+
+enum DnnInferLogLevel {
+ DnnInferLogLevelNone = 0x0,
+ DnnInferLogLevelEngine = 0x1,
+ DnnInferLogLevelLayer = 0x2
+};
+
+enum DnnInferInfoType {
+ DnnInferInfoEngine = 0x0,
+ DnnInferInfoPlugin = 0x1,
+ DnnInferInfoNetwork = 0x2
+};
+
+struct DnnInferImageSize {
+ uint32_t image_width;
+ uint32_t image_height;
+
+ DnnInferImageSize () {
+ image_width = 0;
+ image_height = 0;
+ }
+};
+
+struct DnnInferenceEngineInfo {
+ DnnInferInfoType type;
+ int32_t major;
+ int32_t minor;
+ const char* desc;
+ const char* name;
+
+ DnnInferenceEngineInfo () {
+ type = DnnInferInfoEngine;
+ major = 0;
+ minor = 0;
+ desc = NULL;
+ name = NULL;
+ };
+};
+
+#define DNN_INFER_MAX_INPUT_OUTPUT 10
+struct DnnInferInputOutputInfo {
+ uint32_t width[DNN_INFER_MAX_INPUT_OUTPUT];
+ uint32_t height[DNN_INFER_MAX_INPUT_OUTPUT];
+ uint32_t channels[DNN_INFER_MAX_INPUT_OUTPUT];
+ uint32_t object_size[DNN_INFER_MAX_INPUT_OUTPUT];
+ DnnInferPrecisionType precision[DNN_INFER_MAX_INPUT_OUTPUT];
+ DnnInferLayoutType layout[DNN_INFER_MAX_INPUT_OUTPUT];
+ DnnInferDataType data_type[DNN_INFER_MAX_INPUT_OUTPUT];
+ uint32_t batch_size;
+ uint32_t numbers;
+};
+
+struct DnnInferData {
+ void * buffer;
+ uint32_t size;
+ uint32_t width;
+ uint32_t height;
+ uint32_t width_stride;
+ uint32_t height_stride;
+ uint32_t channel_num;
+ uint32_t batch_idx;
+ DnnInferPrecisionType precision;
+ DnnInferMemoryType mem_type;
+ DnnInferImageFormatType image_format;
+ DnnInferDataType data_type;
+
+ DnnInferData () {
+ buffer = NULL;
+ };
+};
+
+struct DnnInferConfig {
+ DnnInferTargetDeviceType target_id;
+ DnnInferInputOutputInfo input_infos;
+ DnnInferInputOutputInfo output_infos;
+
+ char * plugin_path;
+ char * cpu_ext_path;
+ char * cldnn_ext_path;
+ char * model_filename;
+ char * output_layer_name;
+ uint32_t perf_counter;
+ uint32_t infer_req_num;
+
+ DnnInferConfig () {
+ plugin_path = NULL;
+ cpu_ext_path = NULL;
+ cldnn_ext_path = NULL;
+ model_filename = NULL;
+ output_layer_name = NULL;
+ };
+};
+
+class DnnInferenceEngine {
+public:
+ explicit DnnInferenceEngine (DnnInferConfig& config);
+ virtual ~DnnInferenceEngine ();
+
+ XCamReturn create_model (DnnInferConfig& config);
+ XCamReturn load_model (DnnInferConfig& config);
+
+ XCamReturn get_info (DnnInferenceEngineInfo& info, DnnInferInfoType type);
+
+ XCamReturn set_batch_size (const size_t size);
+ size_t get_batch_size ();
+
+ bool ready_to_start () const {
+ return _model_created && _model_loaded;
+ };
+
+ XCamReturn start (bool sync = true);
+
+ size_t get_input_size ();
+ size_t get_output_size ();
+
+ XCamReturn set_input_presion (uint32_t idx, DnnInferPrecisionType precision);
+ DnnInferPrecisionType get_input_presion (uint32_t idx);
+ XCamReturn set_output_presion (uint32_t idx, DnnInferPrecisionType precision);
+ DnnInferPrecisionType get_output_presion (uint32_t idx);
+
+ XCamReturn set_input_layout (uint32_t idx, DnnInferLayoutType layout);
+ XCamReturn set_output_layout (uint32_t idx, DnnInferLayoutType layout);
+
+ uint32_t get_input_image_height () const {
+ return _input_image_height;
+ };
+ uint32_t get_input_image_width () const {
+ return _input_image_width;
+ };
+
+ virtual XCamReturn set_model_input_info (DnnInferInputOutputInfo& info) = 0;
+ virtual XCamReturn get_model_input_info (DnnInferInputOutputInfo& info) = 0;
+
+ virtual XCamReturn set_model_output_info (DnnInferInputOutputInfo& info) = 0;
+ virtual XCamReturn get_model_output_info (DnnInferInputOutputInfo& info) = 0;
+
+ virtual XCamReturn set_inference_data (std::vector<std::string> images) = 0;
+ virtual void* get_inference_results (uint32_t idx, uint32_t& size) = 0;
+
+ std::shared_ptr<uint8_t> read_inference_image (std::string image);
+ void print_log (uint32_t flag);
+
+protected:
+
+ InferenceEngine::TargetDevice get_device_from_string (const std::string& device_name);
+ InferenceEngine::TargetDevice get_device_from_id (DnnInferTargetDeviceType device);
+
+ InferenceEngine::Layout estimate_layout_type (const int ch_num);
+ InferenceEngine::Layout convert_layout_type (DnnInferLayoutType layout);
+ DnnInferLayoutType convert_layout_type (InferenceEngine::Layout layout);
+
+ InferenceEngine::Precision convert_precision_type (DnnInferPrecisionType precision);
+ DnnInferPrecisionType convert_precision_type (InferenceEngine::Precision precision);
+
+ std::string get_filename_prefix (const std::string &file_path);
+
+ void print_performance_counts (const std::map<std::string, InferenceEngine::InferenceEngineProfileInfo>& performance_map);
+
+ XCamReturn set_input_blob (uint32_t idx, DnnInferData& data);
+
+private:
+ template <typename T> XCamReturn copy_image_to_blob (const DnnInferData& data, InferenceEngine::Blob::Ptr& blob, int batch_index);
+ template <typename T> XCamReturn copy_data_to_blob (const DnnInferData& data, InferenceEngine::Blob::Ptr& blob, int batch_index);
+
+protected:
+
+ bool _model_created;
+ bool _model_loaded;
+
+ uint32_t _input_image_width;
+ uint32_t _input_image_height;
+
+ InferenceEngine::InferencePlugin _plugin;
+ InferenceEngine::CNNNetReader _network_reader;
+ InferenceEngine::CNNNetwork _network;
+ InferenceEngine::InferRequest _infer_request;
+ std::vector<InferenceEngine::CNNLayerPtr> _layers;
+};
+
+} // namespace XCam
+
+#endif //_XCMA_DNN_INFERENCE_ENGINE_H_
diff --git a/modules/dnn/dnn_object_detection.cpp b/modules/dnn/dnn_object_detection.cpp
new file mode 100644
index 0000000..42bf29d
--- /dev/null
+++ b/modules/dnn/dnn_object_detection.cpp
@@ -0,0 +1,264 @@
+/*
+ * dnn_object_detection.cpp - object detection
+ *
+ * Copyright (c) 2019 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Zong Wei <wei.zong@intel.com>
+ */
+
+#include <format_reader_ptr.h>
+
+#include "dnn_object_detection.h"
+
+using namespace std;
+using namespace InferenceEngine;
+
+namespace XCam {
+
+DnnObjectDetection::DnnObjectDetection (DnnInferConfig& config)
+ : DnnInferenceEngine (config)
+{
+ XCAM_LOG_DEBUG ("DnnObjectDetection::DnnObjectDetection");
+
+ create_model (config);
+}
+
+
+DnnObjectDetection::~DnnObjectDetection ()
+{
+
+}
+
+XCamReturn
+DnnObjectDetection::get_model_input_info (DnnInferInputOutputInfo& info)
+{
+ if (!_model_created) {
+ XCAM_LOG_ERROR ("Please create the model firstly!");
+ return XCAM_RETURN_ERROR_ORDER;
+ }
+
+ int id = 0;
+ InputsDataMap inputs_info (_network.getInputsInfo ());
+
+ for (auto & item : inputs_info) {
+ auto& input = item.second;
+ const InferenceEngine::SizeVector input_dims = input->getDims ();
+
+ info.width[id] = input_dims[0];
+ info.height[id] = input_dims[1];
+ info.channels[id] = input_dims[2];
+ info.object_size[id] = input_dims[3];
+ info.precision[id] = convert_precision_type (input->getPrecision());
+ info.layout[id] = convert_layout_type (input->getLayout());
+
+ item.second->setPrecision(Precision::U8);
+
+ id++;
+ }
+ info.batch_size = get_batch_size ();
+ info.numbers = inputs_info.size ();
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+DnnObjectDetection::set_model_input_info (DnnInferInputOutputInfo& info)
+{
+ XCAM_LOG_DEBUG ("DnnObjectDetection::set_model_input_info");
+
+ if (!_model_created) {
+ XCAM_LOG_ERROR ("Please create the model firstly!");
+ return XCAM_RETURN_ERROR_ORDER;
+ }
+
+ InputsDataMap inputs_info (_network.getInputsInfo ());
+ if (info.numbers != inputs_info.size ()) {
+ XCAM_LOG_ERROR ("Input size is not matched with model info numbers %d !", info.numbers);
+ return XCAM_RETURN_ERROR_PARAM;
+ }
+ int id = 0;
+
+ for (auto & item : inputs_info) {
+ Precision precision = convert_precision_type (info.precision[id]);
+ item.second->setPrecision (precision);
+ Layout layout = convert_layout_type (info.layout[id]);
+ item.second->setLayout (layout);
+ id++;
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+DnnObjectDetection::get_model_output_info (DnnInferInputOutputInfo& info)
+{
+ if (!_model_created) {
+ XCAM_LOG_ERROR ("Please create the model firstly!");
+ return XCAM_RETURN_ERROR_ORDER;
+ }
+
+ int id = 0;
+ std::string output_name;
+ OutputsDataMap outputs_info (_network.getOutputsInfo ());
+ DataPtr output_info;
+ for (const auto& out : outputs_info) {
+ if (out.second->creatorLayer.lock()->type == "DetectionOutput") {
+ output_name = out.first;
+ output_info = out.second;
+ break;
+ }
+ }
+ if (output_info.get ()) {
+ const InferenceEngine::SizeVector output_dims = output_info->getTensorDesc().getDims();
+
+ info.width[id] = output_dims[0];
+ info.height[id] = output_dims[1];
+ info.channels[id] = output_dims[2];
+ info.object_size[id] = output_dims[3];
+
+ info.precision[id] = convert_precision_type (output_info->getPrecision());
+ info.layout[id] = convert_layout_type (output_info->getLayout());
+
+ info.batch_size = 1;
+ info.numbers = outputs_info.size ();
+ } else {
+ XCAM_LOG_ERROR ("Get output info error!");
+ return XCAM_RETURN_ERROR_UNKNOWN;
+ }
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+DnnObjectDetection::set_model_output_info (DnnInferInputOutputInfo& info)
+{
+ if (!_model_created) {
+ XCAM_LOG_ERROR ("Please create the model firstly!");
+ return XCAM_RETURN_ERROR_ORDER;
+ }
+
+ OutputsDataMap outputs_info (_network.getOutputsInfo ());
+ if (info.numbers != outputs_info.size ()) {
+ XCAM_LOG_ERROR ("Output size is not matched with model!");
+ return XCAM_RETURN_ERROR_PARAM;
+ }
+
+ int id = 0;
+ for (auto & item : outputs_info) {
+ Precision precision = convert_precision_type (info.precision[id]);
+ item.second->setPrecision (precision);
+ Layout layout = convert_layout_type (info.layout[id]);
+ item.second->setLayout (layout);
+ id++;
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+DnnObjectDetection::set_inference_data (std::vector<std::string> images)
+{
+ if (!_model_created) {
+ XCAM_LOG_ERROR ("Please create the model firstly!");
+ return XCAM_RETURN_ERROR_ORDER;
+ }
+
+ uint32_t idx = 0;
+ InputsDataMap inputs_info (_network.getInputsInfo ());
+
+ for (auto & i : images) {
+ FormatReader::ReaderPtr reader (i.c_str ());
+ if (reader.get () == NULL) {
+ XCAM_LOG_WARNING ("Image %d cannot be read!", i);
+ continue;
+ }
+
+ _input_image_width = reader->width ();
+ _input_image_height = reader->height ();
+
+ uint32_t image_width = 0;
+ uint32_t image_height = 0;
+
+ for (auto & item : inputs_info) {
+ image_width = inputs_info[item.first]->getDims ()[0];
+ image_height = inputs_info[item.first]->getDims ()[1];
+ }
+
+ std::shared_ptr<unsigned char> data (reader->getData (image_width, image_height));
+
+ if (data.get () != NULL) {
+ DnnInferData image;
+ image.width = image_width;
+ image.height = image_height;
+ image.width_stride = image_width;
+ image.height_stride = image_height;
+ image.buffer = data.get ();
+ image.channel_num = 3;
+ image.batch_idx = idx;
+ image.image_format = DnnInferImageFormatBGRPacked;
+
+ // set precision & data type
+ image.precision = get_input_presion (idx);
+ image.data_type = DnnInferDataTypeImage;
+
+ set_input_blob (idx, image);
+
+ idx ++;
+ } else {
+ XCAM_LOG_WARNING ("Valid input images were not found!");
+ continue;
+ }
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+void*
+DnnObjectDetection::get_inference_results (uint32_t idx, uint32_t& size)
+{
+ if (! _model_created || ! _model_loaded) {
+ XCAM_LOG_ERROR ("Please create and load the model firstly!");
+ return NULL;
+ }
+ uint32_t id = 0;
+ std::string item_name;
+
+ OutputsDataMap outputs_info (_network.getOutputsInfo ());
+ if (idx > outputs_info.size ()) {
+ XCAM_LOG_ERROR ("Output is out of range");
+ return NULL;
+ }
+
+ for (auto & item : outputs_info) {
+ if (item.second->creatorLayer.lock()->type == "DetectionOutput") {
+ item_name = item.first;
+ break;
+ }
+ id++;
+ }
+
+ if (item_name.empty ()) {
+ XCAM_LOG_ERROR ("item name is empty!");
+ return NULL;
+ }
+
+ const Blob::Ptr blob = _infer_request.GetBlob (item_name);
+ float* output_result = static_cast<PrecisionTrait<Precision::FP32>::value_type*>(blob->buffer ());
+
+ size = blob->byteSize ();
+
+ return (reinterpret_cast<void *>(output_result));
+}
+
+} // namespace XCam
diff --git a/modules/dnn/dnn_object_detection.h b/modules/dnn/dnn_object_detection.h
new file mode 100644
index 0000000..6980858
--- /dev/null
+++ b/modules/dnn/dnn_object_detection.h
@@ -0,0 +1,53 @@
+/*
+ * dnn_object_detection.h - object detection
+ *
+ * Copyright (c) 2019 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Zong Wei <wei.zong@intel.com>
+ */
+
+#ifndef _XCMA_DNN_OBJECT_DETECTION_H_
+#define _XCMA_DNN_OBJECT_DETECTION_H_
+
+#pragma once
+
+#include <string>
+#include <inference_engine.hpp>
+
+#include <xcam_std.h>
+#include "dnn_inference_engine.h"
+
+namespace XCam {
+
+class DnnObjectDetection
+ : public DnnInferenceEngine
+{
+public:
+ explicit DnnObjectDetection (DnnInferConfig& config);
+ virtual ~DnnObjectDetection ();
+
+ XCamReturn set_model_input_info (DnnInferInputOutputInfo& info);
+ XCamReturn get_model_input_info (DnnInferInputOutputInfo& info);
+
+ XCamReturn set_model_output_info (DnnInferInputOutputInfo& info);
+ XCamReturn get_model_output_info (DnnInferInputOutputInfo& info);
+
+ XCamReturn set_inference_data (std::vector<std::string> images);
+ void* get_inference_results (uint32_t idx, uint32_t& size);
+};
+
+} // namespace XCam
+
+#endif //_XCMA_DNN_INFERENCE_ENGINE_H_
diff --git a/modules/gles/Makefile.am b/modules/gles/Makefile.am
new file mode 100644
index 0000000..8bdf406
--- /dev/null
+++ b/modules/gles/Makefile.am
@@ -0,0 +1,81 @@
+lib_LTLIBRARIES = libxcam_gles.la
+
+XCAM_GLES_CXXFLAGS = \
+ $(XCAM_CXXFLAGS) \
+ $(LIBGL_CFLAGS) \
+ -I$(top_srcdir)/xcore \
+ -I$(top_srcdir)/modules \
+ -I$(top_builddir)/shaders/glslx \
+ $(NULL)
+
+XCAM_GLES_LIBS = \
+ $(LIBGL_LIBS) -lEGL \
+ $(top_builddir)/xcore/libxcam_core.la \
+ $(NULL)
+
+if HAVE_OPENCV
+XCAM_GLES_LIBS += $(top_builddir)/modules/ocv/libxcam_ocv.la
+endif
+
+xcam_gles_sources = \
+ gles_std.cpp \
+ gl_buffer.cpp \
+ gl_program.cpp \
+ gl_shader.cpp \
+ gl_video_buffer.cpp \
+ gl_compute_program.cpp \
+ gl_command.cpp \
+ gl_utils.cpp \
+ gl_image_shader.cpp \
+ gl_image_handler.cpp \
+ gl_copy_handler.cpp \
+ gl_geomap_handler.cpp \
+ gl_blender_shaders_priv.cpp \
+ gl_blender.cpp \
+ gl_stitcher.cpp \
+ egl/egl_utils.cpp \
+ egl/egl_base.cpp \
+ $(NULL)
+
+libxcam_gles_la_SOURCES = \
+ $(xcam_gles_sources) \
+ $(NULL)
+
+libxcam_gles_la_CXXFLAGS = \
+ $(XCAM_GLES_CXXFLAGS) \
+ $(NULL)
+
+libxcam_gles_la_LIBADD = \
+ $(XCAM_GLES_LIBS) \
+ $(NULL)
+
+libxcam_gles_la_LDFLAGS = \
+ $(XCAM_LT_LDFLAGS) \
+ $(NULL)
+
+libxcam_glesincludedir = $(includedir)/xcam/gles
+
+nobase_libxcam_glesinclude_HEADERS = \
+ gles_std.h \
+ gl_buffer.h \
+ gl_program.h \
+ gl_shader.h \
+ gl_video_buffer.h \
+ gl_compute_program.h \
+ gl_command.h \
+ gl_utils.h \
+ gl_image_shader.h \
+ gl_image_handler.h \
+ gl_copy_handler.h \
+ gl_geomap_handler.h \
+ gl_blender.h \
+ gl_stitcher.h \
+ egl/egl_utils.h \
+ egl/egl_base.h \
+ $(NULL)
+
+noinst_HEADERS = \
+ gl_blender_shaders_priv.h \
+ $(NULL)
+
+libxcam_gles_la_LIBTOOLFLAGS = --tag=disable-static
diff --git a/modules/gles/egl/egl_base.cpp b/modules/gles/egl/egl_base.cpp
new file mode 100644
index 0000000..6ee0b4c
--- /dev/null
+++ b/modules/gles/egl/egl_base.cpp
@@ -0,0 +1,195 @@
+/*
+ * egl_base.cpp - EGL base implementation
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#include "egl_base.h"
+
+namespace XCam {
+
+EGLBase::EGLBase ()
+ : _display (EGL_NO_DISPLAY)
+ , _context (EGL_NO_CONTEXT)
+ , _surface (EGL_NO_SURFACE)
+{
+}
+
+EGLBase::~EGLBase ()
+{
+ if (_display != EGL_NO_DISPLAY) {
+ if (_context != EGL_NO_CONTEXT) {
+ destroy_context (_display, _context);
+ _context = EGL_NO_CONTEXT;
+ }
+
+ if (_surface != EGL_NO_SURFACE) {
+ destroy_surface (_display, _surface);
+ _surface = EGL_NO_SURFACE;
+ }
+
+ terminate (_display);
+ _display = EGL_NO_DISPLAY;
+ }
+}
+
+bool
+EGLBase::init ()
+{
+ bool ret = get_display (EGL_DEFAULT_DISPLAY, _display);
+ XCAM_FAIL_RETURN (ERROR, ret, false, "EGLInit: get display failed");
+
+ EGLint major, minor;
+ ret = initialize (_display, &major, &minor);
+ XCAM_FAIL_RETURN (ERROR, ret, false, "EGLInit: EGL initialize failed");
+ XCAM_LOG_INFO ("EGL version: %d.%d", major, minor);
+
+ EGLConfig configs;
+ EGLint num_config;
+ EGLint cfg_attribs[] = {EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR, EGL_NONE};
+ ret = choose_config (_display, cfg_attribs, &configs, 1, &num_config);
+ XCAM_FAIL_RETURN (ERROR, ret, false, "EGLInit: choose config failed");
+
+ EGLint ctx_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE};
+ ret = create_context (_display, configs, EGL_NO_CONTEXT, ctx_attribs, _context);
+ XCAM_FAIL_RETURN (ERROR, ret, false, "EGLInit: create context failed");
+
+ ret = make_current (_display, _surface, _surface, _context);
+ XCAM_FAIL_RETURN (ERROR, ret, false, "EGLInit: make current failed");
+
+ return true;
+}
+
+bool
+EGLBase::get_display (NativeDisplayType native_display, EGLDisplay &display)
+{
+ display = eglGetDisplay (native_display);
+ XCAM_FAIL_RETURN (
+ ERROR, display != EGL_NO_DISPLAY, false,
+ "EGLInit: get display failed");
+ return true;
+}
+
+bool
+EGLBase::initialize (EGLDisplay display, EGLint *major, EGLint *minor)
+{
+ EGLBoolean ret = eglInitialize (display, major, minor);
+ XCAM_FAIL_RETURN (
+ ERROR, ret == EGL_TRUE, false,
+ "EGLInit: initialize failed, error flag: %s",
+ EGL::error_string (EGL::get_error ()));
+ return true;
+}
+
+bool
+EGLBase::choose_config (
+ EGLDisplay display, EGLint const *attribs, EGLConfig *configs,
+ EGLint config_size, EGLint *num_config)
+{
+ EGLBoolean ret = eglChooseConfig (display, attribs, configs, config_size, num_config);
+ XCAM_FAIL_RETURN (
+ ERROR, ret == EGL_TRUE, false,
+ "EGLInit: choose config failed, error flag: %s",
+ EGL::error_string (EGL::get_error ()));
+ return true;
+}
+
+bool
+EGLBase::create_context (
+ EGLDisplay display, EGLConfig config, EGLContext share_context, EGLint const *attribs,
+ EGLContext &context)
+{
+ context = eglCreateContext (display, config, share_context, attribs);
+ XCAM_FAIL_RETURN (
+ ERROR, context != EGL_NO_CONTEXT, false,
+ "EGLInit: create context failed, error flag: %s",
+ EGL::error_string (EGL::get_error ()));
+ return true;
+}
+
+bool
+EGLBase::create_window_surface (
+ EGLDisplay display, EGLConfig config, NativeWindowType native_window, EGLint const *attribs,
+ EGLSurface &surface)
+{
+ surface = eglCreateWindowSurface (display, config, native_window, attribs);
+ XCAM_FAIL_RETURN (
+ ERROR, surface != EGL_NO_SURFACE, false,
+ "EGLInit: create window surface failed, error flag: %s",
+ EGL::error_string (EGL::get_error ()));
+ return true;
+}
+
+bool
+EGLBase::make_current (EGLDisplay display, EGLSurface draw, EGLSurface read, EGLContext context)
+{
+ EGLBoolean ret = eglMakeCurrent (display, draw, read, context);
+ XCAM_FAIL_RETURN (
+ ERROR, ret == EGL_TRUE, false,
+ "EGLInit: make current failed, error flag: %s",
+ EGL::error_string (EGL::get_error ()));
+ return true;
+}
+
+bool
+EGLBase::swap_buffers (EGLDisplay display, EGLSurface surface)
+{
+ EGLBoolean ret = eglSwapBuffers (display, surface);
+ XCAM_FAIL_RETURN (
+ ERROR, ret == EGL_TRUE, false,
+ "EGLInit: swap buffers failed, error flag: %s",
+ EGL::error_string (EGL::get_error ()));
+ return true;
+}
+
+bool
+EGLBase::destroy_context (EGLDisplay display, EGLContext &context)
+{
+ EGLBoolean ret = eglDestroyContext (display, context);
+ XCAM_FAIL_RETURN (
+ ERROR, ret == EGL_TRUE, false,
+ "EGLInit: destroy context failed, error flag: %s",
+ EGL::error_string (EGL::get_error ()));
+ XCAM_FAIL_RETURN (ERROR, ret == EGL_TRUE, false, "EGLInit: destroy context failed");
+ return true;
+}
+
+bool
+EGLBase::destroy_surface (EGLDisplay display, EGLSurface &surface)
+{
+ EGLBoolean ret = eglDestroySurface (display, surface);
+ XCAM_FAIL_RETURN (
+ ERROR, ret == EGL_TRUE, false,
+ "EGLInit: destroy surface failed, error flag: %s",
+ EGL::error_string (EGL::get_error ()));
+ XCAM_FAIL_RETURN (ERROR, ret == EGL_TRUE, false, "EGLInit: destroy surface failed");
+ return true;
+}
+
+bool
+EGLBase::terminate (EGLDisplay display)
+{
+ EGLBoolean ret = eglTerminate (display);
+ XCAM_FAIL_RETURN (
+ ERROR, ret == EGL_TRUE, false,
+ "EGLInit: terminate failed, error flag: %s",
+ EGL::error_string (EGL::get_error ()));
+ XCAM_FAIL_RETURN (ERROR, ret == EGL_TRUE, false, "EGLInit: terminate failed");
+ return true;
+}
+
+}
diff --git a/modules/gles/egl/egl_base.h b/modules/gles/egl/egl_base.h
new file mode 100644
index 0000000..baa9a10
--- /dev/null
+++ b/modules/gles/egl/egl_base.h
@@ -0,0 +1,61 @@
+/*
+ * egl_base.h - EGL base class
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#ifndef XCAM_EGL_BASE_H
+#define XCAM_EGL_BASE_H
+
+#include <gles/egl/egl_utils.h>
+
+namespace XCam {
+
+class EGLBase {
+public:
+ explicit EGLBase ();
+ ~EGLBase ();
+
+ bool init ();
+
+ bool get_display (NativeDisplayType native_display, EGLDisplay &display);
+ bool initialize (EGLDisplay display, EGLint *major, EGLint *minor);
+ bool choose_config (
+ EGLDisplay display, EGLint const *attribs, EGLConfig *configs,
+ EGLint config_size, EGLint *num_config);
+ bool create_context (
+ EGLDisplay display, EGLConfig config, EGLContext share_context, EGLint const *attribs,
+ EGLContext &context);
+ bool create_window_surface (
+ EGLDisplay display, EGLConfig config, NativeWindowType native_window, EGLint const *attribs,
+ EGLSurface &surface);
+ bool make_current (EGLDisplay display, EGLSurface draw, EGLSurface read, EGLContext context);
+ bool swap_buffers (EGLDisplay display, EGLSurface surface);
+
+ bool destroy_context (EGLDisplay display, EGLContext &context);
+ bool destroy_surface (EGLDisplay display, EGLSurface &surface);
+ bool terminate (EGLDisplay display);
+
+private:
+ EGLDisplay _display;
+ EGLContext _context;
+ EGLSurface _surface;
+};
+
+}
+
+#endif // XCAM_EGL_BASE_H
diff --git a/modules/gles/egl/egl_utils.cpp b/modules/gles/egl/egl_utils.cpp
new file mode 100644
index 0000000..71bc4a7
--- /dev/null
+++ b/modules/gles/egl/egl_utils.cpp
@@ -0,0 +1,87 @@
+/*
+ * egl_utils.cpp - EGL utilities
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#include "egl_utils.h"
+
+namespace XCam {
+namespace EGL {
+
+const char *
+error_string (EGLint flag)
+{
+ static char str[64] = {'\0'};
+
+ switch (flag)
+ {
+ case EGL_SUCCESS:
+ snprintf (str, sizeof (str), "0x%04x:%s", flag, "EGL_SUCCESS");
+ break;
+ case EGL_NOT_INITIALIZED:
+ snprintf (str, sizeof (str), "0x%04x:%s", flag, "EGL_NOT_INITIALIZED");
+ break;
+ case EGL_BAD_ACCESS:
+ snprintf (str, sizeof (str), "0x%04x:%s", flag, "EGL_BAD_ACCESS");
+ break;
+ case EGL_BAD_ALLOC:
+ snprintf (str, sizeof (str), "0x%04x:%s", flag, "EGL_BAD_ALLOC");
+ break;
+ case EGL_BAD_ATTRIBUTE:
+ snprintf (str, sizeof (str), "0x%04x:%s", flag, "EGL_BAD_ATTRIBUTE");
+ break;
+ case EGL_BAD_CONTEXT:
+ snprintf (str, sizeof (str), "0x%04x:%s", flag, "EGL_BAD_CONTEXT");
+ break;
+ case EGL_BAD_CONFIG:
+ snprintf (str, sizeof (str), "0x%04x:%s", flag, "EGL_BAD_CONFIG");
+ break;
+ case EGL_BAD_CURRENT_SURFACE:
+ snprintf (str, sizeof (str), "0x%04x:%s", flag, "EGL_BAD_CURRENT_SURFACE");
+ break;
+ case EGL_BAD_DISPLAY:
+ snprintf (str, sizeof (str), "0x%04x:%s", flag, "EGL_BAD_DISPLAY");
+ break;
+ case EGL_BAD_SURFACE:
+ snprintf (str, sizeof (str), "0x%04x:%s", flag, "EGL_BAD_SURFACE");
+ break;
+ case EGL_BAD_MATCH:
+ snprintf (str, sizeof (str), "0x%04x:%s", flag, "EGL_BAD_MATCH");
+ break;
+ case EGL_BAD_PARAMETER:
+ snprintf (str, sizeof (str), "0x%04x:%s", flag, "EGL_BAD_PARAMETER");
+ break;
+ case EGL_BAD_NATIVE_PIXMAP:
+ snprintf (str, sizeof (str), "0x%04x:%s", flag, "EGL_BAD_NATIVE_PIXMAP");
+ break;
+ case EGL_BAD_NATIVE_WINDOW:
+ snprintf (str, sizeof (str), "0x%04x:%s", flag, "EGL_BAD_NATIVE_WINDOW");
+ break;
+ case EGL_CONTEXT_LOST:
+ snprintf (str, sizeof (str), "0x%04x:%s", flag, "EGL_CONTEXT_LOST");
+ break;
+ default:
+ snprintf (str, sizeof (str), "unknown flag:0x%04x", flag);
+ XCAM_LOG_ERROR ("%s", str);
+ }
+
+ return str;
+}
+
+}
+}
diff --git a/modules/gles/egl/egl_utils.h b/modules/gles/egl/egl_utils.h
new file mode 100644
index 0000000..601f171
--- /dev/null
+++ b/modules/gles/egl/egl_utils.h
@@ -0,0 +1,40 @@
+/*
+ * egl_utils.h - EGL utilities
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#ifndef XCAM_EGL_UTILS_H
+#define XCAM_EGL_UTILS_H
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <xcam_std.h>
+
+namespace XCam {
+namespace EGL {
+
+inline EGLint get_error ()
+{
+ return eglGetError ();
+}
+
+const char *error_string (EGLint flag);
+
+}
+}
+#endif // XCAM_EGL_UTILS_H
diff --git a/modules/gles/gl_blender.cpp b/modules/gles/gl_blender.cpp
new file mode 100644
index 0000000..7f83a47
--- /dev/null
+++ b/modules/gles/gl_blender.cpp
@@ -0,0 +1,852 @@
+/*
+ * gl_blender.cpp - gl blender implementation
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#include "xcam_utils.h"
+#include "image_file_handle.h"
+#include "gl_utils.h"
+#include "gl_video_buffer.h"
+#include "gl_blender_shaders_priv.h"
+#include "gl_blender.h"
+#include <map>
+
+#define OVERLAP_POOL_SIZE 6
+#define LAP_POOL_SIZE 4
+
+#define GAUSS_RADIUS 2
+#define GAUSS_DIAMETER ((GAUSS_RADIUS)*2+1)
+
+const float gauss_coeffs[GAUSS_DIAMETER] = {0.152f, 0.222f, 0.252f, 0.222f, 0.152f};
+
+#define DUMP_BUFFER 0
+
+#define CHECK_RET(ret, format, ...) \
+ if ((ret) < XCAM_RETURN_NO_ERROR) { \
+ XCAM_LOG_ERROR (format, ## __VA_ARGS__); \
+ }
+
+namespace XCam {
+
+using namespace XCamGLShaders;
+
+#if DUMP_BUFFER
+#define dump_buf dump_buf_perfix_path
+
+static void
+dump_level_buf (const SmartPtr<VideoBuffer> &buf, const char *name, uint32_t level, uint32_t idx)
+{
+ XCAM_ASSERT (name);
+
+ char file_name[256];
+ snprintf (file_name, 256, "%s-L%d-Idx%d", name, level, idx);
+ dump_buf_perfix_path (buf, file_name);
+}
+#else
+static void
+dump_level_buf (const SmartPtr<VideoBuffer> &buf, ...) {
+ XCAM_UNUSED (buf);
+}
+
+static void
+dump_buf (const SmartPtr<VideoBuffer> &buf, ...) {
+ XCAM_UNUSED (buf);
+}
+#endif
+
+DECLARE_WORK_CALLBACK (CbGaussScalePyr, GLBlender, gauss_scale_done);
+DECLARE_WORK_CALLBACK (CbLapTransPyr, GLBlender, lap_trans_done);
+DECLARE_WORK_CALLBACK (CbBlendPyr, GLBlender, blend_done);
+DECLARE_WORK_CALLBACK (CbReconstructPyr, GLBlender, reconstruct_done);
+
+namespace GLBlenderPriv {
+
+typedef std::map<void*, SmartPtr<GLBlendPyrShader::Args>> MapBlendArgs;
+typedef std::map<void*, SmartPtr<GLReconstructPyrShader::Args>> MapReconstructArgs;
+
+struct PyramidResource {
+ SmartPtr<BufferPool> overlap_pool;
+ SmartPtr<GLGaussScalePyrShader> gauss_scale[GLBlender::BufIdxCount];
+ SmartPtr<GLLapTransPyrShader> lap_trans[GLBlender::BufIdxCount];
+ SmartPtr<GLReconstructPyrShader> reconstruct;
+ SmartPtr<GLBuffer> coef_mask;
+ MapReconstructArgs reconstruct_args;
+};
+
+class BlenderPrivConfig {
+public:
+ PyramidResource pyr_layer[XCAM_GL_PYRAMID_MAX_LEVEL];
+ uint32_t pyr_levels;
+
+ SmartPtr<GLBlendPyrShader> top_level_blend;
+ SmartPtr<BufferPool> first_lap_pool;
+ SmartPtr<GLBuffer> first_mask;
+
+ Mutex map_args_mutex;
+ MapBlendArgs blend_args;
+
+private:
+ GLBlender *_blender;
+ SmartPtr<GLComputeProgram> _sync_prog;
+
+public:
+ BlenderPrivConfig (GLBlender *blender, uint32_t level)
+ : pyr_levels (level - 1)
+ , _blender (blender)
+ {
+ XCAM_ASSERT (level >= 2 && level <= XCAM_GL_PYRAMID_MAX_LEVEL);
+ }
+
+ XCamReturn init_first_masks (uint32_t width, uint32_t height);
+ XCamReturn scale_down_masks (uint32_t level, uint32_t width, uint32_t height);
+
+ XCamReturn start_gauss_scale (
+ const SmartPtr<ImageHandler::Parameters> &param,
+ const SmartPtr<VideoBuffer> &in_buf,
+ uint32_t level, GLBlender::BufIdx idx);
+
+ XCamReturn start_lap_trans (
+ const SmartPtr<ImageHandler::Parameters> &param,
+ const SmartPtr<GLGaussScalePyrShader::Args> &gauss_scale_args,
+ uint32_t level, GLBlender::BufIdx idx);
+
+ XCamReturn start_blend (
+ const SmartPtr<ImageHandler::Parameters> &param,
+ const SmartPtr<VideoBuffer> &buf, GLBlender::BufIdx idx);
+
+ XCamReturn start_reconstruct_by_lap (
+ const SmartPtr<ImageHandler::Parameters> &param,
+ const SmartPtr<VideoBuffer> &lap,
+ uint32_t level, GLBlender::BufIdx idx);
+ XCamReturn start_reconstruct_by_gauss (
+ const SmartPtr<ImageHandler::Parameters> &param,
+ const SmartPtr<VideoBuffer> &prev_blend_buf, uint32_t level);
+ XCamReturn start_reconstruct (const SmartPtr<GLReconstructPyrShader::Args> &args, uint32_t level);
+ XCamReturn stop ();
+
+ const SmartPtr<GLComputeProgram> &get_sync_prog ();
+};
+
+XCamReturn
+BlenderPrivConfig::stop ()
+{
+ for (uint32_t i = 0; i < pyr_levels; ++i) {
+ pyr_layer[i].gauss_scale[GLBlender::Idx0].release ();
+ pyr_layer[i].gauss_scale[GLBlender::Idx1].release ();
+ pyr_layer[i].lap_trans[GLBlender::Idx0].release ();
+ pyr_layer[i].lap_trans[GLBlender::Idx1].release ();
+ pyr_layer[i].reconstruct.release ();
+
+ if (pyr_layer[i].overlap_pool.ptr ()) {
+ pyr_layer[i].overlap_pool->stop ();
+ }
+ }
+
+ top_level_blend.release ();
+ if (first_lap_pool.ptr ()) {
+ first_lap_pool->stop ();
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+const SmartPtr<GLComputeProgram> &
+BlenderPrivConfig::get_sync_prog ()
+{
+ if (_sync_prog.ptr ())
+ return _sync_prog;
+
+ _sync_prog = GLComputeProgram::create_compute_program ("sync_program");
+ XCAM_FAIL_RETURN (ERROR, _sync_prog.ptr (), _sync_prog, "create sync program failed");
+
+ return _sync_prog;
+}
+
+XCamReturn
+BlenderPrivConfig::init_first_masks (uint32_t width, uint32_t height)
+{
+ XCAM_ASSERT (!first_mask.ptr ());
+ XCAM_ASSERT (width && (width % GL_BLENDER_ALIGN_X == 0));
+ XCAM_FAIL_RETURN (
+ ERROR, height == 1, XCAM_RETURN_ERROR_PARAM,
+ "blender(%s) mask buffer only supports one-dimensional array", XCAM_STR (_blender->get_name ()));
+
+ uint32_t buf_size = width * sizeof (uint8_t);
+ SmartPtr<GLBuffer> buf = GLBuffer::create_buffer (GL_SHADER_STORAGE_BUFFER, NULL, buf_size);
+ XCAM_ASSERT (buf.ptr ());
+
+ GLBufferDesc desc;
+ desc.width = width;
+ desc.height = 1;
+ desc.size = buf_size;
+ buf->set_buffer_desc (desc);
+
+ std::vector<float> gauss_table;
+ uint32_t quater = width / 4;
+ XCAM_ASSERT (quater > 1);
+
+ get_gauss_table (quater, (quater + 1) / 4.0f, gauss_table, false);
+ for (uint32_t i = 0; i < gauss_table.size (); ++i) {
+ float value = ((i < quater) ? (128.0f * (2.0f - gauss_table[i])) : (128.0f * gauss_table[i]));
+ value = XCAM_CLAMP (value, 0.0f, 255.0f);
+ gauss_table[i] = value;
+ }
+
+ uint8_t *mask_ptr = (uint8_t *) buf->map_range (0, buf_size, GL_MAP_WRITE_BIT);
+ XCAM_FAIL_RETURN (ERROR, mask_ptr, XCAM_RETURN_ERROR_PARAM, "map range failed");
+
+ uint32_t gauss_start_pos = (width - gauss_table.size ()) / 2;
+ uint32_t idx = 0;
+ for (idx = 0; idx < gauss_start_pos; ++idx) {
+ mask_ptr[idx] = 255;
+ }
+ for (uint32_t i = 0; i < gauss_table.size (); ++idx, ++i) {
+ mask_ptr[idx] = (uint8_t) gauss_table[i];
+ }
+ for (; idx < width; ++idx) {
+ mask_ptr[idx] = 0;
+ }
+ buf->unmap ();
+
+ first_mask = buf;
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+BlenderPrivConfig::scale_down_masks (uint32_t level, uint32_t width, uint32_t height)
+{
+ XCAM_ASSERT (width && (width % GL_BLENDER_ALIGN_X == 0));
+ XCAM_FAIL_RETURN (
+ ERROR, height == 1, XCAM_RETURN_ERROR_PARAM,
+ "blender(%s) mask buffer only supports one-dimensional array", XCAM_STR (_blender->get_name ()));
+
+ uint32_t buf_size = width * sizeof (uint8_t);
+ SmartPtr<GLBuffer> buf = GLBuffer::create_buffer (GL_SHADER_STORAGE_BUFFER, NULL, buf_size);
+ XCAM_ASSERT (buf.ptr ());
+
+ GLBufferDesc desc;
+ desc.width = width;
+ desc.height = 1;
+ desc.size = buf_size;
+ buf->set_buffer_desc (desc);
+
+ SmartPtr<GLBuffer> prev_mask;
+ if (level == 0) {
+ prev_mask = first_mask;
+ } else {
+ prev_mask = pyr_layer[level - 1].coef_mask;
+ }
+ XCAM_ASSERT (prev_mask.ptr ());
+
+ const GLBufferDesc prev_desc = prev_mask->get_buffer_desc ();
+ uint8_t *prev_ptr = (uint8_t *) prev_mask->map_range (0, prev_desc.size, GL_MAP_READ_BIT);
+ XCAM_FAIL_RETURN (ERROR, prev_ptr, XCAM_RETURN_ERROR_PARAM, "map range failed");
+
+ uint8_t *cur_ptr = (uint8_t *) buf->map_range (0, desc.size, GL_MAP_WRITE_BIT);
+ XCAM_FAIL_RETURN (ERROR, cur_ptr, XCAM_RETURN_ERROR_PARAM, "map range failed");
+
+ for (uint32_t i = 0; i < desc.width; ++i) {
+ int prev_start = i * 2 - 2;
+ float sum = 0.0f;
+
+ for (int j = 0; j < GAUSS_DIAMETER; ++j) {
+ int prev_idx = XCAM_CLAMP (prev_start + j, 0, (int)prev_desc.width);
+ sum += prev_ptr[prev_idx] * gauss_coeffs[j];
+ }
+
+ cur_ptr[i] = XCAM_CLAMP (sum, 0.0f, 255.0f);
+ }
+
+ buf->unmap ();
+ prev_mask->unmap ();
+
+ pyr_layer[level].coef_mask = buf;
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+BlenderPrivConfig::start_gauss_scale (
+ const SmartPtr<ImageHandler::Parameters> &param,
+ const SmartPtr<VideoBuffer> &in_buf,
+ uint32_t level, GLBlender::BufIdx idx)
+{
+ XCAM_ASSERT (in_buf.ptr ());
+ XCAM_ASSERT (level < pyr_levels);
+ XCAM_ASSERT (idx < GLBlender::BufIdxCount);
+ XCAM_ASSERT (pyr_layer[level].gauss_scale[idx].ptr ());
+ XCAM_ASSERT (pyr_layer[level].overlap_pool.ptr ());
+
+ SmartPtr<VideoBuffer> out_buf = pyr_layer[level].overlap_pool->get_buffer ();
+ XCAM_FAIL_RETURN (
+ ERROR, out_buf.ptr (), XCAM_RETURN_ERROR_MEM,
+ "blender(%s) start_gauss_scale failed, output buffer is empty, level:%d, idx:%d",
+ XCAM_STR (_blender->get_name ()), level, (int)idx);
+
+ SmartPtr<GLGaussScalePyrShader::Args> args = new GLGaussScalePyrShader::Args (param, level, idx);
+ XCAM_ASSERT (args.ptr ());
+ args->in_glbuf = get_glbuffer (in_buf);
+ args->out_glbuf = get_glbuffer (out_buf);
+ args->out_video_buf = out_buf;
+
+ if (level == 0) {
+ const Rect area = _blender->get_input_merge_area (idx);
+ XCAM_FAIL_RETURN (
+ ERROR,
+ area.pos_y == 0 && area.width && area.height &&
+ area.pos_x % GL_BLENDER_ALIGN_X == 0 &&
+ area.width % GL_BLENDER_ALIGN_X == 0 &&
+ area.height % GL_BLENDER_ALIGN_Y == 0,
+ XCAM_RETURN_ERROR_PARAM,
+ "blender(%s) invalid input merge area, pos_x:%d, pos_y:%d, width:%d, height:%d, level:%d, idx:%d",
+ XCAM_STR (_blender->get_name ()), area.pos_x, area.pos_y, area.width, area.height, level, (int)idx);
+
+ args->merge_area = area;
+ } else {
+ const VideoBufferInfo &info = in_buf->get_video_info ();
+ XCAM_FAIL_RETURN (
+ ERROR,
+ info.width && info.height &&
+ info.width % GL_BLENDER_ALIGN_X == 0 &&
+ info.height % GL_BLENDER_ALIGN_Y == 0,
+ XCAM_RETURN_ERROR_PARAM,
+ "blender(%s) invalid buffer info, width:%d, height:%d, level:%d, idx:%d",
+ XCAM_STR (_blender->get_name ()), info.width, info.height, level, (int)idx);
+
+ args->merge_area = Rect (0, 0, info.width, info.height);
+ }
+
+ return pyr_layer[level].gauss_scale[idx]->work (args);
+}
+
+XCamReturn
+BlenderPrivConfig::start_lap_trans (
+ const SmartPtr<ImageHandler::Parameters> &param,
+ const SmartPtr<GLGaussScalePyrShader::Args> &gauss_scale_args,
+ uint32_t level, GLBlender::BufIdx idx)
+{
+ XCAM_ASSERT (level < pyr_levels);
+ XCAM_ASSERT (pyr_layer[level].lap_trans[idx].ptr ());
+ XCAM_ASSERT (idx < GLBlender::BufIdxCount);
+
+ SmartPtr<VideoBuffer> out_buf;
+ if (level == 0) {
+ XCAM_ASSERT (first_lap_pool.ptr ());
+ out_buf = first_lap_pool->get_buffer ();
+ } else {
+ XCAM_ASSERT (pyr_layer[level - 1].overlap_pool.ptr ());
+ out_buf = pyr_layer[level - 1].overlap_pool->get_buffer ();
+ }
+ XCAM_FAIL_RETURN (
+ ERROR, out_buf.ptr (), XCAM_RETURN_ERROR_MEM,
+ "blender(%s) start_lap_trans failed, output buffer is empty, level:%d, idx:%d",
+ XCAM_STR (_blender->get_name ()), level, (int)idx);
+
+ SmartPtr<GLLapTransPyrShader::Args> args = new GLLapTransPyrShader::Args (param, level, idx);
+ XCAM_ASSERT (args.ptr ());
+ args->in_glbuf = gauss_scale_args->in_glbuf;
+ args->gaussscale_glbuf = gauss_scale_args->out_glbuf;
+ args->out_glbuf = get_glbuffer (out_buf);
+ args->merge_area = gauss_scale_args->merge_area;
+ args->out_video_buf = out_buf;
+
+ return pyr_layer[level].lap_trans[idx]->work (args);
+}
+
+XCamReturn
+BlenderPrivConfig::start_blend (
+ const SmartPtr<ImageHandler::Parameters> &param,
+ const SmartPtr<VideoBuffer> &buf, GLBlender::BufIdx idx)
+{
+ XCAM_ASSERT (idx < GLBlender::BufIdxCount);
+ XCAM_ASSERT (top_level_blend.ptr ());
+
+ uint32_t top_level = pyr_levels - 1;
+ XCAM_ASSERT (pyr_layer[top_level].overlap_pool.ptr ());
+ XCAM_ASSERT (pyr_layer[top_level].coef_mask.ptr ());
+
+ SmartPtr<GLBlendPyrShader::Args> args;
+ {
+ SmartLock locker (map_args_mutex);
+ MapBlendArgs::iterator i = blend_args.find (param.ptr ());
+ if (i == blend_args.end ()) {
+ args = new GLBlendPyrShader::Args (param);
+ XCAM_ASSERT (args.ptr ());
+ blend_args.insert (std::make_pair((void*)param.ptr (), args));
+ XCAM_LOG_DEBUG ("blender(%s) init blend args, idx:%d", XCAM_STR (_blender->get_name ()), (int)idx);
+ } else {
+ args = (*i).second;
+ }
+
+ if (idx == GLBlender::Idx0) {
+ args->in0_glbuf = get_glbuffer (buf);
+ } else {
+ args->in1_glbuf = get_glbuffer (buf);
+ }
+
+ if (!args->in0_glbuf.ptr () || !args->in1_glbuf.ptr ())
+ return XCAM_RETURN_BYPASS;
+
+ blend_args.erase (i);
+ }
+
+ args->mask_glbuf = pyr_layer[top_level].coef_mask;
+
+ SmartPtr<VideoBuffer> out_buf = pyr_layer[top_level].overlap_pool->get_buffer ();
+ XCAM_FAIL_RETURN (
+ ERROR, out_buf.ptr (), XCAM_RETURN_ERROR_MEM,
+ "blender(%s) start_blend failed, output buffer is empty, idx:%d",
+ XCAM_STR (_blender->get_name ()), (int)idx);
+ args->out_glbuf = get_glbuffer (out_buf);
+ args->out_video_buf = out_buf;
+
+ return top_level_blend->work (args);
+}
+
+XCamReturn
+BlenderPrivConfig::start_reconstruct (
+ const SmartPtr<GLReconstructPyrShader::Args> &args, uint32_t level)
+{
+ XCAM_ASSERT (args.ptr ());
+ XCAM_ASSERT (level < pyr_levels);
+ XCAM_ASSERT (pyr_layer[level].reconstruct.ptr ());
+ XCAM_ASSERT (args->lap0_glbuf.ptr () && args->lap1_glbuf.ptr () && args->prev_blend_glbuf.ptr ());
+
+ SmartPtr<VideoBuffer> out_buf;
+ if (level == 0) {
+ const SmartPtr<ImageHandler::Parameters> param = args->get_param ();
+ XCAM_ASSERT (param.ptr () && param->out_buf.ptr ());
+ out_buf = param->out_buf;
+
+ XCAM_ASSERT (first_mask.ptr ());
+ args->mask_glbuf = first_mask;
+
+ const Rect area = _blender->get_merge_window ();
+ XCAM_FAIL_RETURN (
+ ERROR,
+ area.pos_y == 0 && area.width && area.height &&
+ area.pos_x % GL_BLENDER_ALIGN_X == 0 &&
+ area.width % GL_BLENDER_ALIGN_X == 0 &&
+ area.height % GL_BLENDER_ALIGN_Y == 0,
+ XCAM_RETURN_ERROR_PARAM,
+ "blender(%s) invalid output merge area, pos_x:%d, pos_y:%d, width:%d, height:%d, level:%d",
+ XCAM_STR (_blender->get_name ()), area.pos_x, area.pos_y, area.width, area.height, level);
+
+ args->merge_area = area;
+ } else {
+ out_buf = pyr_layer[level - 1].overlap_pool->get_buffer ();
+ XCAM_FAIL_RETURN (
+ ERROR, out_buf.ptr (), XCAM_RETURN_ERROR_MEM,
+ "blender(%s) start_reconstruct failed, out buffer is empty, level:%d",
+ XCAM_STR (_blender->get_name ()), level);
+
+ XCAM_ASSERT (pyr_layer[level - 1].coef_mask.ptr ());
+ args->mask_glbuf = pyr_layer[level - 1].coef_mask;
+
+ const VideoBufferInfo &info = out_buf->get_video_info ();
+ XCAM_FAIL_RETURN (
+ ERROR,
+ info.width && info.height &&
+ info.width % GL_BLENDER_ALIGN_X == 0 &&
+ info.height % GL_BLENDER_ALIGN_Y == 0,
+ XCAM_RETURN_ERROR_PARAM,
+ "blender(%s) invalid buffer info, width:%d, height:%d, level:%d",
+ XCAM_STR (_blender->get_name ()), info.width, info.height, level);
+
+ args->merge_area = Rect (0, 0, info.width, info.height);
+ }
+ args->out_glbuf = get_glbuffer (out_buf);
+ args->out_video_buf = out_buf;
+
+ return pyr_layer[level].reconstruct->work (args);
+}
+
+XCamReturn
+BlenderPrivConfig::start_reconstruct_by_gauss (
+ const SmartPtr<ImageHandler::Parameters> &param,
+ const SmartPtr<VideoBuffer> &prev_blend_buf, uint32_t level)
+{
+ XCAM_ASSERT (prev_blend_buf.ptr ());
+ XCAM_ASSERT (level < pyr_levels);
+
+ SmartPtr<GLReconstructPyrShader::Args> args;
+ {
+ SmartLock locker (map_args_mutex);
+ MapReconstructArgs::iterator i = pyr_layer[level].reconstruct_args.find (param.ptr ());
+ if (i == pyr_layer[level].reconstruct_args.end ()) {
+ args = new GLReconstructPyrShader::Args (param, level);
+ XCAM_ASSERT (args.ptr ());
+ pyr_layer[level].reconstruct_args.insert (std::make_pair((void*)param.ptr (), args));
+ XCAM_LOG_DEBUG ("blender(%s) init reconstruct_args, level:%d", XCAM_STR (_blender->get_name ()), level);
+ } else {
+ args = (*i).second;
+ }
+
+ args->prev_blend_glbuf = get_glbuffer (prev_blend_buf);
+
+ if (!args->lap0_glbuf.ptr () || !args->lap1_glbuf.ptr ())
+ return XCAM_RETURN_BYPASS;
+
+ pyr_layer[level].reconstruct_args.erase (i);
+ }
+
+ return start_reconstruct (args, level);
+}
+
+XCamReturn
+BlenderPrivConfig::start_reconstruct_by_lap (
+ const SmartPtr<ImageHandler::Parameters> &param,
+ const SmartPtr<VideoBuffer> &lap,
+ uint32_t level, GLBlender::BufIdx idx)
+{
+ XCAM_ASSERT (lap.ptr ());
+ XCAM_ASSERT (level < pyr_levels);
+ XCAM_ASSERT (idx < GLBlender::BufIdxCount);
+
+ SmartPtr<GLReconstructPyrShader::Args> args;
+ {
+ SmartLock locker (map_args_mutex);
+ MapReconstructArgs::iterator i = pyr_layer[level].reconstruct_args.find (param.ptr ());
+ if (i == pyr_layer[level].reconstruct_args.end ()) {
+ args = new GLReconstructPyrShader::Args (param, level);
+ XCAM_ASSERT (args.ptr ());
+ pyr_layer[level].reconstruct_args.insert (std::make_pair((void*)param.ptr (), args));
+ XCAM_LOG_DEBUG ("blender(%s) init reconstruct_args, level:%d", XCAM_STR (_blender->get_name ()), level);
+ } else {
+ args = (*i).second;
+ }
+
+ if (idx == GLBlender::Idx0)
+ args->lap0_glbuf = get_glbuffer (lap);
+ else
+ args->lap1_glbuf = get_glbuffer (lap);
+
+ if (!args->lap0_glbuf.ptr () || !args->lap1_glbuf.ptr () || !args->prev_blend_glbuf.ptr ())
+ return XCAM_RETURN_BYPASS;
+
+ pyr_layer[level].reconstruct_args.erase (i);
+ }
+
+ return start_reconstruct (args, level);
+}
+
+}
+
+GLBlender::GLBlender (const char *name)
+ : GLImageHandler (name)
+ , Blender (GL_BLENDER_ALIGN_X, GL_BLENDER_ALIGN_Y)
+{
+ SmartPtr<GLBlenderPriv::BlenderPrivConfig> config =
+ new GLBlenderPriv::BlenderPrivConfig (this, XCAM_GL_PYRAMID_DEFAULT_LEVEL);
+ XCAM_ASSERT (config.ptr ());
+ _priv_config = config;
+}
+
+GLBlender::~GLBlender ()
+{
+}
+
+XCamReturn
+GLBlender::finish ()
+{
+ const SmartPtr<GLComputeProgram> prog = _priv_config->get_sync_prog ();
+ XCAM_ASSERT (prog.ptr ());
+ prog->finish ();
+
+ return GLImageHandler::finish ();
+}
+
+XCamReturn
+GLBlender::terminate ()
+{
+ _priv_config->stop ();
+ return GLImageHandler::terminate ();
+}
+
+XCamReturn
+GLBlender::blend (
+ const SmartPtr<VideoBuffer> &in0,
+ const SmartPtr<VideoBuffer> &in1,
+ SmartPtr<VideoBuffer> &out_buf)
+{
+ XCAM_ASSERT (in0.ptr () && in1.ptr ());
+
+ SmartPtr<BlenderParam> param = new BlenderParam (in0, in1, out_buf);
+ XCAM_ASSERT (param.ptr ());
+
+ XCamReturn ret = execute_buffer (param, true);
+
+ finish ();
+ if (xcam_ret_is_ok (ret) && !out_buf.ptr ()) {
+ out_buf = param->out_buf;
+ }
+
+ return ret;
+}
+
+XCamReturn
+GLBlender::start_work (const SmartPtr<ImageHandler::Parameters> &base)
+{
+ XCAM_ASSERT (base.ptr ());
+ SmartPtr<BlenderParam> param = base.dynamic_cast_ptr<BlenderParam> ();
+ XCAM_ASSERT (param.ptr ());
+ XCAM_ASSERT (param->in_buf.ptr () && param->in1_buf.ptr () && param->out_buf.ptr ());
+
+ dump_level_buf (param->in_buf, "input", 0, 0);
+ dump_level_buf (param->in1_buf, "input", 0, 1);
+
+ // start gauss scale level:0 idx:0
+ XCamReturn ret = _priv_config->start_gauss_scale (param, param->in_buf, 0, GLBlender::Idx0);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "blender(%s) start gauss scale failed, level:0 idx:0", XCAM_STR (get_name ()));
+
+ // start gauss scale level:0 idx:1
+ ret = _priv_config->start_gauss_scale (param, param->in1_buf, 0, GLBlender::Idx1);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "blender(%s) start gauss scale failed, level:0 idx:1", XCAM_STR (get_name ()));
+
+ return ret;
+};
+
+XCamReturn
+GLBlender::configure_resource (const SmartPtr<Parameters> &param)
+{
+ XCAM_ASSERT (param.ptr () && param->in_buf.ptr ());
+ XCAM_ASSERT (_priv_config->pyr_levels <= XCAM_GL_PYRAMID_MAX_LEVEL);
+
+ const VideoBufferInfo &in0_info = param->in_buf->get_video_info ();
+ XCAM_FAIL_RETURN (
+ ERROR, in0_info.format == V4L2_PIX_FMT_NV12, XCAM_RETURN_ERROR_PARAM,
+ "blender(%s) only support NV12 format, but input format is %s",
+ XCAM_STR(get_name ()), xcam_fourcc_to_string (in0_info.format));
+
+ Rect in0_area, in1_area, out_area;
+ in0_area = get_input_merge_area (Idx0);
+ in1_area = get_input_merge_area (Idx1);
+ out_area = get_merge_window ();
+ XCAM_FAIL_RETURN (
+ ERROR,
+ in0_area.width && in0_area.height &&
+ in0_area.width == in1_area.width && in0_area.height == in1_area.height &&
+ in0_area.width == out_area.width && in0_area.height == out_area.height,
+ XCAM_RETURN_ERROR_PARAM,
+ "blender(%s) invalid input/output overlap area, input0:%dx%d, input1:%dx%d, output:%dx%d",
+ XCAM_STR(get_name ()), in0_area.width, in0_area.height,
+ in1_area.width, in1_area.height, out_area.width, out_area.height);
+
+ VideoBufferInfo out_info;
+ uint32_t out_width, out_height;
+ get_output_size (out_width, out_height);
+ XCAM_FAIL_RETURN (
+ ERROR, out_width && out_height, XCAM_RETURN_ERROR_PARAM,
+ "blender(%s) invalid output size, output size:%dx%d",
+ XCAM_STR(get_name ()), out_width, out_height);
+
+ out_info.init (
+ in0_info.format, out_width, out_height,
+ XCAM_ALIGN_UP (out_width, GL_BLENDER_ALIGN_X), XCAM_ALIGN_UP (out_height, GL_BLENDER_ALIGN_Y));
+ set_out_video_info (out_info);
+
+ VideoBufferInfo overlap_info;
+ Rect merge_size = get_merge_window ();
+ XCAM_FAIL_RETURN (
+ ERROR,
+ merge_size.width && merge_size.height &&
+ merge_size.width % GL_BLENDER_ALIGN_X == 0 &&
+ merge_size.height % GL_BLENDER_ALIGN_Y == 0,
+ XCAM_RETURN_ERROR_PARAM,
+ "blender(%s) invalid merge size, width:%d, height:%d",
+ XCAM_STR (get_name ()), merge_size.width, merge_size.height);
+
+ overlap_info.init (in0_info.format, merge_size.width, merge_size.height);
+ SmartPtr<BufferPool> first_lap_pool = new GLVideoBufferPool (overlap_info);
+ XCAM_ASSERT (first_lap_pool.ptr ());
+ XCAM_FAIL_RETURN (
+ ERROR, first_lap_pool->reserve (LAP_POOL_SIZE), XCAM_RETURN_ERROR_MEM,
+ "blender(%s) reserve lap buffer pool failed, overlap size:%dx%d",
+ XCAM_STR(get_name ()), overlap_info.width, overlap_info.height);
+ _priv_config->first_lap_pool = first_lap_pool;
+
+ SmartPtr<Worker::Callback> gauss_scale_cb = new CbGaussScalePyr (this);
+ SmartPtr<Worker::Callback> lap_trans_cb = new CbLapTransPyr (this);
+ SmartPtr<Worker::Callback> reconstruct_cb = new CbReconstructPyr (this);
+ XCAM_ASSERT (gauss_scale_cb.ptr () && lap_trans_cb.ptr () && reconstruct_cb.ptr ());
+
+ XCamReturn ret = _priv_config->init_first_masks (merge_size.width, 1);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "blender(%s) init first masks failed", XCAM_STR (get_name ()));
+
+ for (uint32_t i = 0; i < _priv_config->pyr_levels; ++i) {
+ merge_size.width = XCAM_ALIGN_UP ((merge_size.width + 1) / 2, GL_BLENDER_ALIGN_X);
+ merge_size.height = XCAM_ALIGN_UP ((merge_size.height + 1) / 2, GL_BLENDER_ALIGN_Y);
+ overlap_info.init (in0_info.format, merge_size.width, merge_size.height);
+
+ SmartPtr<BufferPool> pool = new GLVideoBufferPool (overlap_info);
+ XCAM_ASSERT (pool.ptr ());
+ XCAM_FAIL_RETURN (
+ ERROR, pool->reserve (OVERLAP_POOL_SIZE), XCAM_RETURN_ERROR_MEM,
+ "blender(%s) reserve buffer pool failed, overlap size:%dx%d",
+ XCAM_STR(get_name ()), overlap_info.width, overlap_info.height);
+ _priv_config->pyr_layer[i].overlap_pool = pool;
+
+ ret = _priv_config->scale_down_masks (i, merge_size.width, 1);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "blender(%s) scale down masks failed, level:%d", XCAM_STR (get_name ()), i);
+
+ _priv_config->pyr_layer[i].gauss_scale[GLBlender::Idx0] = create_gauss_scale_pyr_shader (gauss_scale_cb);
+ XCAM_ASSERT (_priv_config->pyr_layer[i].gauss_scale[GLBlender::Idx0].ptr ());
+ _priv_config->pyr_layer[i].gauss_scale[GLBlender::Idx1] = create_gauss_scale_pyr_shader (gauss_scale_cb);
+ XCAM_ASSERT (_priv_config->pyr_layer[i].gauss_scale[GLBlender::Idx1].ptr ());
+ _priv_config->pyr_layer[i].lap_trans[GLBlender::Idx0] = create_lap_trans_pyr_shader (lap_trans_cb);
+ XCAM_ASSERT (_priv_config->pyr_layer[i].lap_trans[GLBlender::Idx0].ptr ());
+ _priv_config->pyr_layer[i].lap_trans[GLBlender::Idx1] = create_lap_trans_pyr_shader (lap_trans_cb);
+ XCAM_ASSERT (_priv_config->pyr_layer[i].lap_trans[GLBlender::Idx1].ptr ());
+ _priv_config->pyr_layer[i].reconstruct = create_reconstruct_pyr_shader (reconstruct_cb);
+ XCAM_ASSERT (_priv_config->pyr_layer[i].reconstruct.ptr ());
+ }
+
+ SmartPtr<Worker::Callback> blend_cb = new CbBlendPyr (this);
+ XCAM_ASSERT (blend_cb.ptr ());
+ _priv_config->top_level_blend = create_blend_pyr_shader (blend_cb);
+ XCAM_ASSERT (_priv_config->top_level_blend.ptr ());
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+void
+GLBlender::gauss_scale_done (
+ const SmartPtr<Worker> &worker, const SmartPtr<Worker::Arguments> &base, const XCamReturn error)
+{
+ XCAM_UNUSED (worker);
+ XCAM_UNUSED (error);
+ XCAM_ASSERT (base.ptr ());
+
+ SmartPtr<GLGaussScalePyrShader::Args> args = base.dynamic_cast_ptr<GLGaussScalePyrShader::Args> ();
+ XCAM_ASSERT (args.ptr ());
+ uint32_t level = args->level;
+ XCAM_ASSERT (level < _priv_config->pyr_levels);
+ uint32_t next_level = level + 1;
+ BufIdx idx = args->idx;
+
+ const SmartPtr<ImageHandler::Parameters> param = args->get_param ();
+ XCAM_ASSERT (param.ptr ());
+
+ dump_level_buf (args->out_video_buf, "gauss-scale", level, idx);
+
+ XCamReturn ret = _priv_config->start_lap_trans (param, args, level, idx);
+ CHECK_RET (ret, "execute laplace transformation failed, level:%d idx:%d", level, idx);
+
+ if (next_level == _priv_config->pyr_levels) { // top level
+ ret = _priv_config->start_blend (param, args->out_video_buf, idx);
+ CHECK_RET (ret, "execute blend failed, level:%d idx:%d", next_level, idx);
+ } else {
+ ret = _priv_config->start_gauss_scale (param, args->out_video_buf, next_level, idx);
+ CHECK_RET (ret, "execute gauss scale failed, level:%d idx:%d", next_level, idx);
+ }
+}
+
+void
+GLBlender::lap_trans_done (
+ const SmartPtr<Worker> &worker, const SmartPtr<Worker::Arguments> &base, const XCamReturn error)
+{
+ XCAM_UNUSED (worker);
+ XCAM_UNUSED (error);
+ XCAM_ASSERT (base.ptr ());
+
+ SmartPtr<GLLapTransPyrShader::Args> args = base.dynamic_cast_ptr<GLLapTransPyrShader::Args> ();
+ XCAM_ASSERT (args.ptr ());
+ uint32_t level = args->level;
+ XCAM_ASSERT (level < _priv_config->pyr_levels);
+ BufIdx idx = args->idx;
+
+ const SmartPtr<ImageHandler::Parameters> param = args->get_param ();
+ XCAM_ASSERT (param.ptr ());
+
+ dump_level_buf (args->out_video_buf, "lap", level, idx);
+
+ XCamReturn ret = _priv_config->start_reconstruct_by_lap (param, args->out_video_buf, level, idx);
+ CHECK_RET (ret, "execute reconstruct by lap failed, level:%d idx:%d", level, idx);
+}
+
+void
+GLBlender::blend_done (
+ const SmartPtr<Worker> &worker, const SmartPtr<Worker::Arguments> &base, const XCamReturn error)
+{
+ XCAM_UNUSED (worker);
+ XCAM_UNUSED (error);
+ XCAM_ASSERT (base.ptr ());
+
+ SmartPtr<GLBlendPyrShader::Args> args = base.dynamic_cast_ptr<GLBlendPyrShader::Args> ();
+ XCAM_ASSERT (args.ptr ());
+ const SmartPtr<ImageHandler::Parameters> param = args->get_param ();
+ XCAM_ASSERT (param.ptr ());
+
+ dump_buf (args->out_video_buf, "blend-top");
+
+ XCamReturn ret = _priv_config->start_reconstruct_by_gauss (param, args->out_video_buf, _priv_config->pyr_levels - 1);
+ CHECK_RET (ret, "execute reconstruct by gauss failed, level:%d", _priv_config->pyr_levels - 1);
+}
+
+void
+GLBlender::reconstruct_done (
+ const SmartPtr<Worker> &worker, const SmartPtr<Worker::Arguments> &base, const XCamReturn error)
+{
+ XCAM_UNUSED (worker);
+ XCAM_ASSERT (base.ptr ());
+
+ SmartPtr<GLReconstructPyrShader::Args> args = base.dynamic_cast_ptr<GLReconstructPyrShader::Args> ();
+ XCAM_ASSERT (args.ptr ());
+ uint32_t level = args->level;
+ XCAM_ASSERT (level < _priv_config->pyr_levels);
+
+ const SmartPtr<ImageHandler::Parameters> param = args->get_param ();
+ XCAM_ASSERT (param.ptr ());
+
+ dump_level_buf (args->out_video_buf, "reconstruct", level, 0);
+
+ if (level == 0) {
+ execute_done (param, error);
+ return;
+ }
+
+ XCamReturn ret = _priv_config->start_reconstruct_by_gauss (param, args->out_video_buf, level - 1);
+ CHECK_RET (ret, "execute reconstruct by gauss failed, level:%d", level - 1);
+}
+
+SmartPtr<GLImageHandler>
+create_gl_blender ()
+{
+ SmartPtr<GLBlender> blender = new GLBlender();
+ XCAM_ASSERT (blender.ptr ());
+ return blender;
+}
+
+SmartPtr<Blender>
+Blender::create_gl_blender ()
+{
+ SmartPtr<GLImageHandler> handler = XCam::create_gl_blender ();
+ return handler.dynamic_cast_ptr<Blender> ();
+}
+
+}
diff --git a/modules/gles/gl_blender.h b/modules/gles/gl_blender.h
new file mode 100644
index 0000000..54d5a27
--- /dev/null
+++ b/modules/gles/gl_blender.h
@@ -0,0 +1,98 @@
+/*
+ * gl_blender.h - gl blender class
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#ifndef XCAM_GL_BLENDER_H
+#define XCAM_GL_BLENDER_H
+
+#include <interface/blender.h>
+#include <gles/gl_image_handler.h>
+
+#define XCAM_GL_PYRAMID_MAX_LEVEL 4
+#define XCAM_GL_PYRAMID_DEFAULT_LEVEL 2
+
+namespace XCam {
+
+namespace GLBlenderPriv {
+class BlenderPrivConfig;
+};
+
+class GLBlender
+ : public GLImageHandler, public Blender
+{
+ friend class GLBlenderPriv::BlenderPrivConfig;
+ friend SmartPtr<GLImageHandler> create_gl_blender ();
+
+public:
+ struct BlenderParam : ImageHandler::Parameters {
+ SmartPtr<VideoBuffer> in1_buf;
+
+ BlenderParam (
+ const SmartPtr<VideoBuffer> &in0,
+ const SmartPtr<VideoBuffer> &in1,
+ const SmartPtr<VideoBuffer> &out)
+ : Parameters (in0, out)
+ , in1_buf (in1)
+ {}
+ };
+
+ enum BufIdx {
+ Idx0 = 0,
+ Idx1,
+ BufIdxCount
+ };
+
+public:
+ ~GLBlender ();
+
+ //derived from GLHandler
+ virtual XCamReturn finish ();
+ virtual XCamReturn terminate ();
+
+ void gauss_scale_done (
+ const SmartPtr<Worker> &worker, const SmartPtr<Worker::Arguments> &base, const XCamReturn error);
+ void lap_trans_done (
+ const SmartPtr<Worker> &worker, const SmartPtr<Worker::Arguments> &base, const XCamReturn error);
+ void blend_done (
+ const SmartPtr<Worker> &worker, const SmartPtr<Worker::Arguments> &base, const XCamReturn error);
+ void reconstruct_done (
+ const SmartPtr<Worker> &worker, const SmartPtr<Worker::Arguments> &base, const XCamReturn error);
+
+protected:
+ explicit GLBlender (const char *name = "GLBlender");
+
+ //derived from Blender interface
+ XCamReturn blend (
+ const SmartPtr<VideoBuffer> &in0,
+ const SmartPtr<VideoBuffer> &in1,
+ SmartPtr<VideoBuffer> &out_buf);
+
+ //derived from SoftHandler
+ XCamReturn configure_resource (const SmartPtr<Parameters> &param);
+ XCamReturn start_work (const SmartPtr<Parameters> &param);
+
+private:
+ SmartPtr<GLBlenderPriv::BlenderPrivConfig> _priv_config;
+};
+
+extern SmartPtr<GLImageHandler> create_gl_blender ();
+}
+
+#endif // XCAM_GL_BLENDER_H
diff --git a/modules/gles/gl_blender_shaders_priv.cpp b/modules/gles/gl_blender_shaders_priv.cpp
new file mode 100644
index 0000000..db23416
--- /dev/null
+++ b/modules/gles/gl_blender_shaders_priv.cpp
@@ -0,0 +1,398 @@
+/*
+ * gl_blender_shaders_priv.cpp - gl blender shaders private class implementation
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#include "gl_blender_shaders_priv.h"
+
+namespace XCam {
+
+namespace XCamGLShaders {
+
+enum {
+ ShaderGaussScalePyr = 0,
+ ShaderLapTransPyr,
+ ShaderBlendPyr,
+ ShaderReconstructPyr
+};
+
+static const GLShaderInfo shaders_info[] = {
+ {
+ GL_COMPUTE_SHADER,
+ "shader_gauss_scale_pyr",
+#include "shader_gauss_scale_pyr.comp.slx"
+ , 0
+ },
+ {
+ GL_COMPUTE_SHADER,
+ "shader_lap_trans_pyr",
+#include "shader_lap_trans_pyr.comp.slx"
+ , 0
+ },
+ {
+ GL_COMPUTE_SHADER,
+ "shader_blend_pyr",
+#include "shader_blend_pyr.comp.slx"
+ , 0
+ },
+ {
+ GL_COMPUTE_SHADER,
+ "shader_reconstruct_pyr",
+#include "shader_reconstruct_pyr.comp.slx"
+ , 0
+ }
+};
+
+bool
+GLGaussScalePyrShader::check_desc (
+ const GLBufferDesc &in_desc, const GLBufferDesc &out_desc, const Rect &merge_area)
+{
+ XCAM_FAIL_RETURN (
+ ERROR,
+ merge_area.pos_y == 0 && merge_area.height == (int32_t)in_desc.height &&
+ merge_area.pos_x + merge_area.width <= (int32_t)in_desc.width &&
+ merge_area.width == (int32_t)out_desc.width * 2 &&
+ merge_area.height == (int32_t)out_desc.height * 2,
+ false, "invalid buffer size: input:%dx%d, output:%dx%d, merge_area:%dx%d",
+ in_desc.width, in_desc.height, out_desc.width, out_desc.height, merge_area.width, merge_area.height);
+
+ return true;
+}
+
+XCamReturn
+GLGaussScalePyrShader::prepare_arguments (const SmartPtr<Worker::Arguments> &base, GLCmdList &cmds)
+{
+ SmartPtr<GLGaussScalePyrShader::Args> args = base.dynamic_cast_ptr<GLGaussScalePyrShader::Args> ();
+ XCAM_ASSERT (args.ptr () && args->in_glbuf.ptr () && args->out_glbuf.ptr ());
+
+ const GLBufferDesc &in_desc = args->in_glbuf->get_buffer_desc ();
+ const GLBufferDesc &out_desc = args->out_glbuf->get_buffer_desc ();
+ const Rect &merge_area = args->merge_area;
+ XCAM_FAIL_RETURN (
+ ERROR, check_desc (in_desc, out_desc, merge_area), XCAM_RETURN_ERROR_PARAM,
+ "GLGaussScalePyrShader(%s) check buffer description failed, level:%d idx:%d",
+ XCAM_STR (get_name ()), args->level, (int)args->idx);
+
+ cmds.push_back (new GLCmdBindBufRange (args->in_glbuf, 0, NV12PlaneYIdx));
+ cmds.push_back (new GLCmdBindBufRange (args->in_glbuf, 1, NV12PlaneUVIdx));
+ cmds.push_back (new GLCmdBindBufRange (args->out_glbuf, 2, NV12PlaneYIdx));
+ cmds.push_back (new GLCmdBindBufRange (args->out_glbuf, 3, NV12PlaneUVIdx));
+
+ size_t unit_bytes = sizeof (uint32_t);
+ uint32_t in_img_width = XCAM_ALIGN_UP (in_desc.width, unit_bytes) / unit_bytes;
+ uint32_t in_offset_x = XCAM_ALIGN_UP (merge_area.pos_x, unit_bytes) / unit_bytes;
+ uint32_t out_img_width = XCAM_ALIGN_UP (out_desc.width, unit_bytes) / unit_bytes;
+ uint32_t merge_width = XCAM_ALIGN_UP (merge_area.width, unit_bytes) / unit_bytes;
+ cmds.push_back (new GLCmdUniformT<uint32_t> ("in_img_width", in_img_width));
+ cmds.push_back (new GLCmdUniformT<uint32_t> ("in_img_height", in_desc.height));
+ cmds.push_back (new GLCmdUniformT<uint32_t> ("in_offset_x", in_offset_x));
+ cmds.push_back (new GLCmdUniformT<uint32_t> ("out_img_width", out_img_width));
+ cmds.push_back (new GLCmdUniformT<uint32_t> ("merge_width", merge_width));
+
+ GLGroupsSize groups_size;
+ groups_size.x = XCAM_ALIGN_UP (out_img_width, 8) / 8;
+ groups_size.y = XCAM_ALIGN_UP (out_desc.height, 16) / 16;
+ groups_size.z = 1;
+
+ SmartPtr<GLComputeProgram> prog;
+ XCAM_FAIL_RETURN (
+ ERROR, get_compute_program (prog), XCAM_RETURN_ERROR_PARAM,
+ "GLGaussScalePyrShader(%s) get compute program failed", XCAM_STR (get_name ()));
+ prog->set_groups_size (groups_size);
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+bool
+GLLapTransPyrShader::check_desc (
+ const GLBufferDesc &in_desc, const GLBufferDesc &out_desc,
+ const GLBufferDesc &gs_desc, const Rect &merge_area)
+{
+ XCAM_FAIL_RETURN (
+ ERROR,
+ merge_area.pos_y == 0 && merge_area.height == (int32_t)in_desc.height &&
+ merge_area.pos_x + merge_area.width <= (int32_t)in_desc.width &&
+ merge_area.width == (int32_t)out_desc.width && merge_area.height == (int32_t)out_desc.height &&
+ merge_area.width == (int32_t)gs_desc.width * 2 && merge_area.height == (int32_t)gs_desc.height * 2,
+ false,
+ "invalid buffer size: intput:%dx%d, output:%dx%d, gaussscale:%dx%d, in_area:%dx%d",
+ in_desc.width, in_desc.height, out_desc.width, out_desc.height,
+ gs_desc.width, gs_desc.height, merge_area.width, merge_area.height);
+
+ return true;
+}
+
+XCamReturn
+GLLapTransPyrShader::prepare_arguments (const SmartPtr<Worker::Arguments> &base, GLCmdList &cmds)
+{
+ SmartPtr<GLLapTransPyrShader::Args> args = base.dynamic_cast_ptr<GLLapTransPyrShader::Args> ();
+ XCAM_ASSERT (args.ptr () && args->in_glbuf.ptr () && args->gaussscale_glbuf.ptr () && args->out_glbuf.ptr ());
+
+ const GLBufferDesc &in_desc = args->in_glbuf->get_buffer_desc ();
+ const GLBufferDesc &gs_desc = args->gaussscale_glbuf->get_buffer_desc ();
+ const GLBufferDesc &out_desc = args->out_glbuf->get_buffer_desc ();
+ const Rect &merge_area = args->merge_area;
+ XCAM_FAIL_RETURN (
+ ERROR, check_desc (in_desc, out_desc, gs_desc, merge_area), XCAM_RETURN_ERROR_PARAM,
+ "GLLapTransPyrShader(%s) check buffer description failed, level:%d idx:%d",
+ XCAM_STR (get_name ()), args->level, (int)args->idx);
+
+ cmds.push_back (new GLCmdBindBufRange (args->in_glbuf, 0, NV12PlaneYIdx));
+ cmds.push_back (new GLCmdBindBufRange (args->in_glbuf, 1, NV12PlaneUVIdx));
+ cmds.push_back (new GLCmdBindBufRange (args->gaussscale_glbuf, 2, NV12PlaneYIdx));
+ cmds.push_back (new GLCmdBindBufRange (args->gaussscale_glbuf, 3, NV12PlaneUVIdx));
+ cmds.push_back (new GLCmdBindBufRange (args->out_glbuf, 4, NV12PlaneYIdx));
+ cmds.push_back (new GLCmdBindBufRange (args->out_glbuf, 5, NV12PlaneUVIdx));
+
+ size_t unit_bytes = sizeof (uint32_t) * 2;
+ uint32_t in_img_width = XCAM_ALIGN_UP (in_desc.width, unit_bytes) / unit_bytes;
+ uint32_t in_offset_x = XCAM_ALIGN_UP (merge_area.pos_x, unit_bytes) / unit_bytes;
+ uint32_t gaussscale_img_width = XCAM_ALIGN_UP (gs_desc.width, sizeof (uint32_t)) / sizeof (uint32_t);
+ uint32_t merge_width = XCAM_ALIGN_UP (merge_area.width, unit_bytes) / unit_bytes;
+ cmds.push_back (new GLCmdUniformT<uint32_t> ("in_img_width", in_img_width));
+ cmds.push_back (new GLCmdUniformT<uint32_t> ("in_img_height", in_desc.height));
+ cmds.push_back (new GLCmdUniformT<uint32_t> ("in_offset_x", in_offset_x));
+ cmds.push_back (new GLCmdUniformT<uint32_t> ("gaussscale_img_width", gaussscale_img_width));
+ cmds.push_back (new GLCmdUniformT<uint32_t> ("gaussscale_img_height", gs_desc.height));
+ cmds.push_back (new GLCmdUniformT<uint32_t> ("merge_width", merge_width));
+
+ GLGroupsSize groups_size;
+ groups_size.x = XCAM_ALIGN_UP (merge_width, 8) / 8;
+ groups_size.y = XCAM_ALIGN_UP (merge_area.height, 32) / 32;
+ groups_size.z = 1;
+
+ SmartPtr<GLComputeProgram> prog;
+ XCAM_FAIL_RETURN (
+ ERROR, get_compute_program (prog), XCAM_RETURN_ERROR_PARAM,
+ "GLLapTransPyrShader(%s) get compute program failed", XCAM_STR (get_name ()));
+ prog->set_groups_size (groups_size);
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+bool
+GLBlendPyrShader::check_desc (
+ const GLBufferDesc &in0_desc, const GLBufferDesc &in1_desc,
+ const GLBufferDesc &out_desc, const GLBufferDesc &mask_desc)
+{
+ XCAM_FAIL_RETURN (
+ ERROR,
+ in0_desc.width == in1_desc.width && in0_desc.height == in1_desc.height &&
+ in0_desc.width == out_desc.width && in0_desc.height == out_desc.height &&
+ in0_desc.width == mask_desc.width,
+ false,
+ "invalid buffer size: intput0:%dx%d, intput1:%dx%d, output:%dx%d, mask:%dx%d",
+ in0_desc.width, in0_desc.height, in1_desc.width, in1_desc.height,
+ out_desc.width, out_desc.height, mask_desc.width, mask_desc.height);
+
+ XCAM_FAIL_RETURN (
+ ERROR, mask_desc.height == 1, false,
+ "mask buffer only supports one-dimensional array");
+
+ return true;
+}
+
+XCamReturn
+GLBlendPyrShader::prepare_arguments (const SmartPtr<Worker::Arguments> &base, GLCmdList &cmds)
+{
+ SmartPtr<GLBlendPyrShader::Args> args = base.dynamic_cast_ptr<GLBlendPyrShader::Args> ();
+ XCAM_ASSERT (args.ptr () && args->in0_glbuf.ptr () && args->in1_glbuf.ptr () && args->out_glbuf.ptr ());
+ XCAM_ASSERT (args->mask_glbuf.ptr ());
+
+ const GLBufferDesc &in0_desc = args->in0_glbuf->get_buffer_desc ();
+ const GLBufferDesc &in1_desc = args->in1_glbuf->get_buffer_desc ();
+ const GLBufferDesc &out_desc = args->out_glbuf->get_buffer_desc ();
+ const GLBufferDesc &mask_desc = args->mask_glbuf->get_buffer_desc ();
+ XCAM_FAIL_RETURN (
+ ERROR, check_desc (in0_desc, in1_desc, out_desc, mask_desc), XCAM_RETURN_ERROR_PARAM,
+ "GLBlendPyrShader(%s) check buffer description failed", XCAM_STR (get_name ()));
+
+ cmds.push_back (new GLCmdBindBufRange (args->in0_glbuf, 0, NV12PlaneYIdx));
+ cmds.push_back (new GLCmdBindBufRange (args->in0_glbuf, 1, NV12PlaneUVIdx));
+ cmds.push_back (new GLCmdBindBufRange (args->in1_glbuf, 2, NV12PlaneYIdx));
+ cmds.push_back (new GLCmdBindBufRange (args->in1_glbuf, 3, NV12PlaneUVIdx));
+ cmds.push_back (new GLCmdBindBufRange (args->out_glbuf, 4, NV12PlaneYIdx));
+ cmds.push_back (new GLCmdBindBufRange (args->out_glbuf, 5, NV12PlaneUVIdx));
+ cmds.push_back (new GLCmdBindBufBase (args->mask_glbuf, 6));
+
+ size_t unit_bytes = sizeof (uint32_t) * 2;
+ uint32_t in_img_width = XCAM_ALIGN_UP (in0_desc.width, unit_bytes) / unit_bytes;
+ cmds.push_back (new GLCmdUniformT<uint32_t> ("in_img_width", in_img_width));
+
+ GLGroupsSize groups_size;
+ groups_size.x = XCAM_ALIGN_UP (in_img_width, 8) / 8;
+ groups_size.y = XCAM_ALIGN_UP (in0_desc.height, 16) / 16;
+ groups_size.z = 1;
+
+ SmartPtr<GLComputeProgram> prog;
+ XCAM_FAIL_RETURN (
+ ERROR, get_compute_program (prog), XCAM_RETURN_ERROR_PARAM,
+ "GLBlendPyrShader(%s) get compute program failed", XCAM_STR (get_name ()));
+ prog->set_groups_size (groups_size);
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+bool
+GLReconstructPyrShader::check_desc (
+ const GLBufferDesc &lap0_desc, const GLBufferDesc &lap1_desc, const GLBufferDesc &out_desc,
+ const GLBufferDesc &prev_blend_desc, const GLBufferDesc &mask_desc, const Rect &merge_area)
+{
+ XCAM_FAIL_RETURN (
+ ERROR,
+ merge_area.pos_y == 0 && merge_area.height == (int32_t)out_desc.height &&
+ merge_area.pos_x + merge_area.width <= (int32_t)out_desc.width &&
+ merge_area.width == (int32_t)lap0_desc.width && merge_area.height == (int32_t)lap0_desc.height &&
+ lap0_desc.width == lap1_desc.width && lap0_desc.height == lap1_desc.height &&
+ lap0_desc.width == prev_blend_desc.width * 2 && lap0_desc.height == prev_blend_desc.height * 2 &&
+ lap0_desc.width == mask_desc.width,
+ false,
+ "invalid buffer size: lap0:%dx%d, lap1:%dx%d, output:%dx%d, prev_blend:%dx%d, mask:%dx%d, merge_area:%dx%d",
+ lap0_desc.width, lap0_desc.height, lap1_desc.width, lap1_desc.height,
+ out_desc.width, out_desc.height, prev_blend_desc.width, prev_blend_desc.height,
+ mask_desc.width, mask_desc.height, merge_area.width, merge_area.height);
+
+ XCAM_FAIL_RETURN (
+ ERROR, mask_desc.height == 1, false,
+ "mask buffer only supports one-dimensional array");
+
+ return true;
+}
+
+XCamReturn
+GLReconstructPyrShader::prepare_arguments (const SmartPtr<Worker::Arguments> &base, GLCmdList &cmds)
+{
+ SmartPtr<GLReconstructPyrShader::Args> args = base.dynamic_cast_ptr<GLReconstructPyrShader::Args> ();
+ XCAM_ASSERT (args.ptr () && args->lap0_glbuf.ptr () && args->lap1_glbuf.ptr () && args->out_glbuf.ptr ());
+ XCAM_ASSERT (args->mask_glbuf.ptr ());
+
+ const GLBufferDesc &lap0_desc = args->lap0_glbuf->get_buffer_desc ();
+ const GLBufferDesc &lap1_desc = args->lap1_glbuf->get_buffer_desc ();
+ const GLBufferDesc &out_desc = args->out_glbuf->get_buffer_desc ();
+ const GLBufferDesc &prev_blend_desc = args->prev_blend_glbuf->get_buffer_desc ();
+ const GLBufferDesc &mask_desc = args->mask_glbuf->get_buffer_desc ();
+ const Rect &merge_area = args->merge_area;
+ XCAM_FAIL_RETURN (
+ ERROR, check_desc (lap0_desc, lap1_desc, out_desc, prev_blend_desc, mask_desc, merge_area),
+ XCAM_RETURN_ERROR_PARAM,
+ "GLReconstructPyrShader(%s) check buffer description failed, level:%d",
+ XCAM_STR (get_name ()), args->level);
+
+ cmds.push_back (new GLCmdBindBufRange (args->lap0_glbuf, 0, NV12PlaneYIdx));
+ cmds.push_back (new GLCmdBindBufRange (args->lap0_glbuf, 1, NV12PlaneUVIdx));
+ cmds.push_back (new GLCmdBindBufRange (args->lap1_glbuf, 2, NV12PlaneYIdx));
+ cmds.push_back (new GLCmdBindBufRange (args->lap1_glbuf, 3, NV12PlaneUVIdx));
+ cmds.push_back (new GLCmdBindBufRange (args->out_glbuf, 4, NV12PlaneYIdx));
+ cmds.push_back (new GLCmdBindBufRange (args->out_glbuf, 5, NV12PlaneUVIdx));
+ cmds.push_back (new GLCmdBindBufRange (args->prev_blend_glbuf, 6, NV12PlaneYIdx));
+ cmds.push_back (new GLCmdBindBufRange (args->prev_blend_glbuf, 7, NV12PlaneUVIdx));
+ cmds.push_back (new GLCmdBindBufBase (args->mask_glbuf, 8));
+
+ size_t unit_bytes = sizeof (uint32_t) * 2;
+ uint32_t lap_img_width = XCAM_ALIGN_UP (lap0_desc.width, unit_bytes) / unit_bytes;
+ uint32_t out_img_width = XCAM_ALIGN_UP (out_desc.width, unit_bytes) / unit_bytes;
+ uint32_t out_offset_x = XCAM_ALIGN_UP (merge_area.pos_x, unit_bytes) / unit_bytes;
+ uint32_t prev_blend_img_width = XCAM_ALIGN_UP (prev_blend_desc.width, sizeof (uint32_t)) / sizeof (uint32_t);
+ cmds.push_back (new GLCmdUniformT<uint32_t> ("lap_img_width", lap_img_width));
+ cmds.push_back (new GLCmdUniformT<uint32_t> ("lap_img_height", lap0_desc.height));
+ cmds.push_back (new GLCmdUniformT<uint32_t> ("out_img_width", out_img_width));
+ cmds.push_back (new GLCmdUniformT<uint32_t> ("out_offset_x", out_offset_x));
+ cmds.push_back (new GLCmdUniformT<uint32_t> ("prev_blend_img_width", prev_blend_img_width));
+ cmds.push_back (new GLCmdUniformT<uint32_t> ("prev_blend_img_height", prev_blend_desc.height));
+
+ GLGroupsSize groups_size;
+ groups_size.x = XCAM_ALIGN_UP (lap_img_width, 8) / 8;
+ groups_size.y = XCAM_ALIGN_UP (lap0_desc.height, 32) / 32;
+ groups_size.z = 1;
+
+ SmartPtr<GLComputeProgram> prog;
+ XCAM_FAIL_RETURN (
+ ERROR, get_compute_program (prog), XCAM_RETURN_ERROR_PARAM,
+ "GLReconstructPyrShader(%s) get compute program failed", XCAM_STR (get_name ()));
+ prog->set_groups_size (groups_size);
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+SmartPtr<GLGaussScalePyrShader>
+create_gauss_scale_pyr_shader (SmartPtr<Worker::Callback> &cb)
+{
+ XCAM_ASSERT (cb.ptr ());
+
+ SmartPtr<GLGaussScalePyrShader> shader = new GLGaussScalePyrShader (cb);
+ XCAM_ASSERT (shader.ptr ());
+
+ XCamReturn ret = shader->create_compute_program (shaders_info[ShaderGaussScalePyr], "gauss_scale_pyr_program");
+ XCAM_FAIL_RETURN (
+ ERROR, ret == XCAM_RETURN_NO_ERROR, NULL,
+ "create gauss scale pyramid program failed");
+
+ return shader;
+}
+
+SmartPtr<GLLapTransPyrShader>
+create_lap_trans_pyr_shader (SmartPtr<Worker::Callback> &cb)
+{
+ XCAM_ASSERT (cb.ptr ());
+
+ SmartPtr<GLLapTransPyrShader> shader = new GLLapTransPyrShader (cb);
+ XCAM_ASSERT (shader.ptr ());
+
+ XCamReturn ret = shader->create_compute_program (shaders_info[ShaderLapTransPyr], "lap_trans_pyr_program");
+ XCAM_FAIL_RETURN (
+ ERROR, ret == XCAM_RETURN_NO_ERROR, NULL,
+ "create laplace transformation pyramid program failed");
+
+ return shader;
+}
+
+SmartPtr<GLBlendPyrShader>
+create_blend_pyr_shader (SmartPtr<Worker::Callback> &cb)
+{
+ XCAM_ASSERT (cb.ptr ());
+
+ SmartPtr<GLBlendPyrShader> shader = new GLBlendPyrShader (cb);
+ XCAM_ASSERT (shader.ptr ());
+
+ XCamReturn ret = shader->create_compute_program (shaders_info[ShaderBlendPyr], "blend_pyr_program");
+ XCAM_FAIL_RETURN (
+ ERROR, ret == XCAM_RETURN_NO_ERROR, NULL,
+ "create blend pyramid program failed");
+
+ return shader;
+}
+
+SmartPtr<GLReconstructPyrShader>
+create_reconstruct_pyr_shader (SmartPtr<Worker::Callback> &cb)
+{
+ XCAM_ASSERT (cb.ptr ());
+
+ SmartPtr<GLReconstructPyrShader> shader = new GLReconstructPyrShader (cb);
+ XCAM_ASSERT (shader.ptr ());
+
+ XCamReturn ret = shader->create_compute_program (shaders_info[ShaderReconstructPyr], "reconstruct_pyr_program");
+ XCAM_FAIL_RETURN (
+ ERROR, ret == XCAM_RETURN_NO_ERROR, NULL,
+ "create reconstruct pyramid program failed");
+
+ return shader;
+}
+
+}
+
+}
diff --git a/modules/gles/gl_blender_shaders_priv.h b/modules/gles/gl_blender_shaders_priv.h
new file mode 100644
index 0000000..f3e363a
--- /dev/null
+++ b/modules/gles/gl_blender_shaders_priv.h
@@ -0,0 +1,182 @@
+/*
+ * gl_blender_shaders_priv.h - gl blender shaders private class
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#ifndef XCAM_GL_BLENDER_SHADERS_PRIV_H
+#define XCAM_GL_BLENDER_SHADERS_PRIV_H
+
+#include <interface/data_types.h>
+#include <gles/gl_image_shader.h>
+#include <gles/gl_image_handler.h>
+#include <gles/gl_buffer.h>
+#include <gles/gl_blender.h>
+
+#define GL_BLENDER_ALIGN_X 8
+#define GL_BLENDER_ALIGN_Y 4
+
+namespace XCam {
+
+namespace XCamGLShaders {
+
+class GLGaussScalePyrShader
+ : public GLImageShader
+{
+public:
+ struct Args : GLArgs {
+ SmartPtr<GLBuffer> in_glbuf;
+ SmartPtr<GLBuffer> out_glbuf;
+ Rect merge_area;
+
+ const uint32_t level;
+ const GLBlender::BufIdx idx;
+ SmartPtr<VideoBuffer> out_video_buf;
+
+ Args (
+ const SmartPtr<ImageHandler::Parameters> &param,
+ uint32_t l, GLBlender::BufIdx i)
+ : GLArgs (param)
+ , level (l)
+ , idx (i)
+ {}
+ };
+
+public:
+ explicit GLGaussScalePyrShader (const SmartPtr<Worker::Callback> &cb)
+ : GLImageShader ("GLGaussScalePyrShader", cb)
+ {}
+
+private:
+ virtual XCamReturn prepare_arguments (const SmartPtr<Worker::Arguments> &args, GLCmdList &cmds);
+ bool check_desc (const GLBufferDesc &in_desc, const GLBufferDesc &out_desc, const Rect &merge_area);
+};
+
+class GLLapTransPyrShader
+ : public GLImageShader
+{
+public:
+ struct Args : GLArgs {
+ SmartPtr<GLBuffer> in_glbuf;
+ SmartPtr<GLBuffer> out_glbuf;
+ SmartPtr<GLBuffer> gaussscale_glbuf;
+ Rect merge_area;
+
+ const uint32_t level;
+ const GLBlender::BufIdx idx;
+ SmartPtr<VideoBuffer> out_video_buf;
+
+ Args (
+ const SmartPtr<ImageHandler::Parameters> &param,
+ uint32_t l, GLBlender::BufIdx i)
+ : GLArgs (param)
+ , level (l)
+ , idx (i)
+ {}
+ };
+
+public:
+ explicit GLLapTransPyrShader (const SmartPtr<Worker::Callback> &cb)
+ : GLImageShader ("GLLapTransPyrShader", cb)
+ {}
+
+private:
+ virtual XCamReturn prepare_arguments (const SmartPtr<Worker::Arguments> &args, GLCmdList &cmds);
+ bool check_desc (
+ const GLBufferDesc &in_desc, const GLBufferDesc &out_desc,
+ const GLBufferDesc &gs_desc, const Rect &merge_area);
+};
+
+class GLBlendPyrShader
+ : public GLImageShader
+{
+public:
+ struct Args : GLArgs {
+ SmartPtr<GLBuffer> in0_glbuf;
+ SmartPtr<GLBuffer> in1_glbuf;
+ SmartPtr<GLBuffer> out_glbuf;
+ SmartPtr<GLBuffer> mask_glbuf;
+
+ SmartPtr<VideoBuffer> out_video_buf;
+
+ Args (const SmartPtr<ImageHandler::Parameters> &param)
+ : GLArgs (param)
+ {}
+ };
+
+public:
+ explicit GLBlendPyrShader (const SmartPtr<Worker::Callback> &cb)
+ : GLImageShader ("GLBlendPyrShader", cb)
+ {}
+
+private:
+ virtual XCamReturn prepare_arguments (const SmartPtr<Worker::Arguments> &args, GLCmdList &cmds);
+ bool check_desc (
+ const GLBufferDesc &in0_desc, const GLBufferDesc &in1_desc,
+ const GLBufferDesc &out_desc, const GLBufferDesc &mask_desc);
+};
+
+class GLReconstructPyrShader
+ : public GLImageShader
+{
+public:
+ struct Args : GLArgs {
+ SmartPtr<GLBuffer> lap0_glbuf;
+ SmartPtr<GLBuffer> lap1_glbuf;
+ SmartPtr<GLBuffer> out_glbuf;
+ SmartPtr<GLBuffer> prev_blend_glbuf;
+ SmartPtr<GLBuffer> mask_glbuf;
+ Rect merge_area;
+
+ const uint32_t level;
+ SmartPtr<VideoBuffer> out_video_buf;
+
+ Args (const SmartPtr<ImageHandler::Parameters> &param, uint32_t l)
+ : GLArgs (param)
+ , level (l)
+ {}
+ };
+
+public:
+ explicit GLReconstructPyrShader (const SmartPtr<Worker::Callback> &cb)
+ : GLImageShader ("GLReconstructPyrShader", cb)
+ {}
+
+private:
+ virtual XCamReturn prepare_arguments (const SmartPtr<Worker::Arguments> &args, GLCmdList &cmds);
+ bool check_desc (
+ const GLBufferDesc &lap0_desc, const GLBufferDesc &lap1_desc, const GLBufferDesc &out_desc,
+ const GLBufferDesc &prev_blend_desc, const GLBufferDesc &mask_desc, const Rect &merge_area);
+};
+
+SmartPtr<GLGaussScalePyrShader>
+create_gauss_scale_pyr_shader (SmartPtr<Worker::Callback> &cb);
+
+SmartPtr<GLLapTransPyrShader>
+create_lap_trans_pyr_shader (SmartPtr<Worker::Callback> &cb);
+
+SmartPtr<GLBlendPyrShader>
+create_blend_pyr_shader (SmartPtr<Worker::Callback> &cb);
+
+SmartPtr<GLReconstructPyrShader>
+create_reconstruct_pyr_shader (SmartPtr<Worker::Callback> &cb);
+
+}
+
+}
+
+#endif // XCAM_GL_BLENDER_SHADERS_PRIV_H
diff --git a/modules/gles/gl_buffer.cpp b/modules/gles/gl_buffer.cpp
new file mode 100644
index 0000000..7cb8c8e
--- /dev/null
+++ b/modules/gles/gl_buffer.cpp
@@ -0,0 +1,246 @@
+/*
+ * gl_buffer.cpp - GL buffer
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "gl_buffer.h"
+
+namespace XCam {
+
+GLBufferDesc::GLBufferDesc ()
+ : format (V4L2_PIX_FMT_NV12)
+ , width (0)
+ , height (0)
+ , aligned_width (0)
+ , aligned_height (0)
+ , size (0)
+{
+ xcam_mem_clear (strides);
+ xcam_mem_clear (slice_size);
+ xcam_mem_clear (offsets);
+}
+
+GLBuffer::MapRange::MapRange ()
+ : offset (0)
+ , len (0)
+ , flags (0)
+ , ptr (0)
+{
+}
+
+void
+GLBuffer::MapRange::clear ()
+{
+ offset = 0;
+ len = 0;
+ flags = 0;
+ ptr = NULL;
+}
+
+bool
+GLBuffer::MapRange::is_mapped () const
+{
+ return ptr;
+}
+
+GLBuffer::GLBuffer (GLuint id, GLenum target, GLenum usage, uint32_t size)
+ : _target (target)
+ , _usage (usage)
+ , _buf_id (id)
+ , _size (size)
+{
+}
+
+XCamReturn
+GLBuffer::bind ()
+{
+ glBindBuffer (_target, _buf_id);
+ GLenum error = gl_error ();
+ XCAM_FAIL_RETURN (
+ ERROR, error == GL_NO_ERROR, XCAM_RETURN_ERROR_GLES,
+ "GL bind buffer:%d failed, error flag: %s", _buf_id, gl_error_string (error));
+ return XCAM_RETURN_NO_ERROR;
+}
+
+GLBuffer::~GLBuffer ()
+{
+ if (_buf_id) {
+ glDeleteBuffers (1, &_buf_id);
+
+ GLenum error = gl_error ();
+ if (error != GL_NO_ERROR) {
+ XCAM_LOG_WARNING (
+ "GL Buffer delete buffer failed, error flag: %s", gl_error_string (error));
+ }
+ }
+}
+
+SmartPtr<GLBuffer>
+GLBuffer::create_buffer (
+ GLenum target,
+ const GLvoid *data, uint32_t size,
+ GLenum usage)
+{
+ XCAM_ASSERT (size > 0);
+
+ GLuint buf_id = 0;
+ glGenBuffers (1, &buf_id);
+ GLenum error = gl_error ();
+ XCAM_FAIL_RETURN (
+ ERROR, buf_id && (error == GL_NO_ERROR), NULL,
+ "GL buffer creation failed, error flag: %s", gl_error_string (error));
+
+ glBindBuffer (target, buf_id);
+ XCAM_FAIL_RETURN (
+ ERROR, (error = gl_error ()) == GL_NO_ERROR, NULL,
+ "GL buffer creation failed when bind buffer:%d, error flag: %s",
+ buf_id, gl_error_string (error));
+
+ glBufferData (target, size, data, usage);
+ XCAM_FAIL_RETURN (
+ ERROR, (error = gl_error ()) == GL_NO_ERROR, NULL,
+ "GL buffer creation failed in glBufferData, id:%d, error flag: %s",
+ buf_id, gl_error_string (error));
+
+ SmartPtr<GLBuffer> buf_obj =
+ new GLBuffer (buf_id, target, usage, size);
+
+ return buf_obj;
+}
+
+void *
+GLBuffer::map_range (uint32_t offset, uint32_t length, GLbitfield flags)
+{
+ if (length == 0)
+ length = _size;
+
+ if (_mapped_range.is_mapped () &&
+ _mapped_range.flags == flags &&
+ _mapped_range.offset == offset &&
+ _mapped_range.len == length) {
+ return _mapped_range.ptr;
+ }
+ _mapped_range.clear ();
+
+ XCamReturn ret = bind ();
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), NULL,
+ "GL bind buffer failed, buf_id:%d", _buf_id);
+
+ void *ptr = glMapBufferRange (_target, offset, length, flags);
+ GLenum error = gl_error ();
+ XCAM_FAIL_RETURN (
+ ERROR, ptr && (error == GL_NO_ERROR), NULL,
+ "GL buffer map range failed, buf_id:%d, offset:%d, len:%d, flags:%d, error flag: %s",
+ _buf_id, offset, length, flags, gl_error_string (error));
+
+ _mapped_range.offset = offset;
+ _mapped_range.len = length;
+ _mapped_range.flags = flags;
+ _mapped_range.ptr = ptr;
+
+ return ptr;
+}
+
+XCamReturn
+GLBuffer::flush_map ()
+{
+ if (!_mapped_range.is_mapped ())
+ return XCAM_RETURN_ERROR_ORDER;
+
+ XCAM_FAIL_RETURN (
+ ERROR, _mapped_range.flags & GL_MAP_FLUSH_EXPLICIT_BIT,
+ XCAM_RETURN_ERROR_GLES,
+ "GL buffer flush_map buf:%d failed, invalid flags(:%d)",
+ _buf_id, _mapped_range.flags);
+
+ XCamReturn ret = bind ();
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "GL bind buffer failed, buf_id:%d", _buf_id);
+
+ glFlushMappedBufferRange (_target, _mapped_range.offset, _mapped_range.len);
+ GLenum error = gl_error ();
+ XCAM_FAIL_RETURN (
+ ERROR, error == GL_NO_ERROR,
+ XCAM_RETURN_ERROR_GLES,
+ "GL buffer flush_map buf:%d failed, error flag: %s",
+ _buf_id, gl_error_string (error));
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+GLBuffer::unmap ()
+{
+ if (!_mapped_range.is_mapped ())
+ return XCAM_RETURN_ERROR_ORDER;
+
+ XCamReturn ret = bind ();
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "GL bind buffer failed, buf_id:%d", _buf_id);
+
+ XCAM_FAIL_RETURN (
+ ERROR, glUnmapBuffer (_target), XCAM_RETURN_ERROR_GLES,
+ "GL buffer unmap buf:%d failed, error flag: %s",
+ _buf_id, gl_error_string (gl_error ()));
+
+ _mapped_range.clear ();
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+GLBuffer::bind_buffer_base (uint32_t index)
+{
+ XCamReturn ret = bind ();
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "GL bind buffer failed, buf_id:%d", _buf_id);
+
+ glBindBufferBase (_target, index, _buf_id);
+ GLenum error = gl_error ();
+ XCAM_FAIL_RETURN (
+ ERROR, error == GL_NO_ERROR, XCAM_RETURN_ERROR_GLES,
+ "GL bind buffer base failed. buf_id:%d failed, idx:%d, error flag: %s",
+ _buf_id, index, gl_error_string (error));
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+GLBuffer::bind_buffer_range (uint32_t index, uint32_t offset, uint32_t size)
+{
+ XCamReturn ret = bind ();
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "GL bind buffer failed, buf_id:%d", _buf_id);
+
+ glBindBufferRange (_target, index, _buf_id, offset, size);
+ GLenum error = gl_error ();
+ XCAM_FAIL_RETURN (
+ ERROR, error == GL_NO_ERROR, XCAM_RETURN_ERROR_GLES,
+ "GL bind buffer range failed. buf_id:%d failed, idx:%d, error flag: %s",
+ _buf_id, index, gl_error_string (error));
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+}
+
diff --git a/modules/gles/gl_buffer.h b/modules/gles/gl_buffer.h
new file mode 100644
index 0000000..5bd3d48
--- /dev/null
+++ b/modules/gles/gl_buffer.h
@@ -0,0 +1,110 @@
+/*
+ * gl_buffer.h - GL buffer
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_GL_BUFFER_H
+#define XCAM_GL_BUFFER_H
+
+#include <gles/gles_std.h>
+#include <map>
+
+#define XCAM_GL_MAX_COMPONENTS 4
+
+namespace XCam {
+
+struct GLBufferDesc {
+ uint32_t format;
+ uint32_t width;
+ uint32_t height;
+ uint32_t aligned_width;
+ uint32_t aligned_height;
+ uint32_t size;
+ uint32_t strides[XCAM_GL_MAX_COMPONENTS];
+ uint32_t offsets[XCAM_GL_MAX_COMPONENTS];
+ uint32_t slice_size[XCAM_GL_MAX_COMPONENTS];
+
+ GLBufferDesc ();
+};
+
+class GLBuffer
+{
+public:
+ ~GLBuffer ();
+ static SmartPtr<GLBuffer> create_buffer (
+ GLenum target, const GLvoid *data = NULL, uint32_t size = 0, GLenum usage = GL_STATIC_DRAW);
+
+ GLuint get_buffer_id () const {
+ return _buf_id;
+ }
+ GLenum get_target () const {
+ return _target;
+ }
+ GLenum get_usage () const {
+ return _usage;
+ }
+ uint32_t get_size () const {
+ return _size;
+ }
+
+ void set_buffer_desc (const GLBufferDesc &desc) {
+ _desc = desc;
+ }
+ const GLBufferDesc &get_buffer_desc () {
+ return _desc;
+ }
+
+ void *map_range (
+ uint32_t offset = 0, uint32_t length = 0,
+ GLbitfield flags = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
+ XCamReturn flush_map ();
+ XCamReturn unmap ();
+
+ XCamReturn bind ();
+ XCamReturn bind_buffer_base (uint32_t index);
+ XCamReturn bind_buffer_range (uint32_t index, uint32_t offset, uint32_t size);
+
+private:
+ explicit GLBuffer (GLuint id, GLenum type, GLenum usage, uint32_t size);
+
+private:
+ XCAM_DEAD_COPY (GLBuffer);
+
+ struct MapRange {
+ uint32_t offset;
+ uint32_t len;
+ GLbitfield flags;
+ void *ptr;
+
+ MapRange ();
+ void clear ();
+ bool is_mapped () const;
+ };
+
+private:
+ GLenum _target;
+ GLenum _usage;
+ GLuint _buf_id;
+ uint32_t _size;
+ MapRange _mapped_range;
+ GLBufferDesc _desc;
+};
+
+}
+
+#endif //XCAM_GL_BUFFER_H
diff --git a/modules/gles/gl_command.cpp b/modules/gles/gl_command.cpp
new file mode 100644
index 0000000..38b92b0
--- /dev/null
+++ b/modules/gles/gl_command.cpp
@@ -0,0 +1,265 @@
+/*
+ * gl_command.cpp - GL command implementation
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#include "gl_command.h"
+#include "gl_buffer.h"
+
+namespace XCam {
+
+namespace UniformOps {
+
+template <>
+GLenum uniform <GLfloat> (GLint location, GLfloat value)
+{
+ glUniform1f (location, value);
+ return gl_error ();
+}
+
+template <>
+GLenum uniform <GLint> (GLint location, GLint value)
+{
+ glUniform1i (location, value);
+ return gl_error ();
+}
+
+template <>
+GLenum uniform <GLuint> (GLint location, GLuint value)
+{
+ glUniform1ui (location, value);
+ return gl_error ();
+}
+
+template <>
+GLenum uniform_array <GLfloat> (GLint location, const GLfloat *value, GLsizei count)
+{
+ glUniform1fv (location, count, value);
+ return gl_error ();
+}
+
+template <>
+GLenum uniform_array <GLint> (GLint location, const GLint *value, GLsizei count)
+{
+ glUniform1iv (location, count, value);
+ return gl_error ();
+}
+
+template <>
+GLenum uniform_array <GLuint> (GLint location, const GLuint *value, GLsizei count)
+{
+ glUniform1uiv (location, count, value);
+ return gl_error ();
+}
+
+template <>
+GLenum uniform_vect <GLfloat, 2> (GLint location, const GLfloat *value, GLsizei count)
+{
+ glUniform2fv (location, count, value);
+ return gl_error ();
+}
+
+template <>
+GLenum uniform_vect <GLfloat, 3> (GLint location, const GLfloat *value, GLsizei count)
+{
+ glUniform3fv (location, count, value);
+ return gl_error ();
+}
+
+template <>
+GLenum uniform_vect <GLfloat, 4> (GLint location, const GLfloat *value, GLsizei count)
+{
+ glUniform4fv (location, count, value);
+ return gl_error ();
+}
+
+template <>
+GLenum uniform_vect <GLint, 2> (GLint location, const GLint *value, GLsizei count)
+{
+ glUniform2iv (location, count, value);
+ return gl_error ();
+}
+
+template <>
+GLenum uniform_vect <GLint, 3> (GLint location, const GLint *value, GLsizei count)
+{
+ glUniform3iv (location, count, value);
+ return gl_error ();
+}
+
+template <>
+GLenum uniform_vect <GLint, 4> (GLint location, const GLint *value, GLsizei count)
+{
+ glUniform4iv (location, count, value);
+ return gl_error ();
+}
+
+template <>
+GLenum uniform_vect <GLuint, 2> (GLint location, const GLuint *value, GLsizei count)
+{
+ glUniform2uiv (location, count, value);
+ return gl_error ();
+}
+
+template <>
+GLenum uniform_vect <GLuint, 3> (GLint location, const GLuint *value, GLsizei count)
+{
+ glUniform3uiv (location, count, value);
+ return gl_error ();
+}
+
+template <>
+GLenum uniform_vect <GLuint, 4> (GLint location, const GLuint *value, GLsizei count)
+{
+ glUniform4uiv (location, count, value);
+ return gl_error ();
+}
+
+template <>
+GLenum uniform_mat <GLfloat, 2> (GLint location, const GLfloat *value, GLsizei count)
+{
+ glUniformMatrix2fv (location, count, GL_FALSE, value);
+ return gl_error ();
+}
+
+template <>
+GLenum uniform_mat <GLfloat, 3> (GLint location, const GLfloat *value, GLsizei count)
+{
+ glUniformMatrix3fv (location, count, GL_FALSE, value);
+ return gl_error ();
+}
+
+template <>
+GLenum uniform_mat <GLfloat, 4> (GLint location, const GLfloat *value, GLsizei count)
+{
+ glUniformMatrix4fv (location, count, GL_FALSE, value);
+ return gl_error ();
+}
+
+}
+
+GLCmdUniform::GLCmdUniform (const GLchar *name)
+{
+ XCAM_ASSERT (name);
+ strncpy (_name, name, XCAM_GL_NAME_LENGTH - 1);
+}
+
+GLCmdUniform::~GLCmdUniform ()
+{
+}
+
+XCamReturn
+GLCmdUniform::run (GLuint program)
+{
+ GLint location = get_uniform_location (program, _name);
+ XCAM_FAIL_RETURN (ERROR, location >= 0, XCAM_RETURN_ERROR_UNKNOWN, "get_uniform_location failed");
+
+ GLenum error = uniform (location);
+ XCAM_FAIL_RETURN (
+ ERROR, error == GL_NO_ERROR, XCAM_RETURN_ERROR_UNKNOWN,
+ "uniform failed, name:%s, error flag: %s", _name, gl_error_string (error));
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+GLint
+GLCmdUniform::get_uniform_location (GLuint program, const GLchar *name)
+{
+ GLint location = glGetUniformLocation (program, name);
+ GLenum error = gl_error ();
+ XCAM_FAIL_RETURN (
+ ERROR, error == GL_NO_ERROR, -1,
+ "get_uniform_location failed, name:%s, error flag: %s",
+ XCAM_STR (name), gl_error_string (error));
+
+ XCAM_FAIL_RETURN (
+ WARNING, location >= 0, -1,
+ "get_uniform_location invalid or unnecessary parameter, name:%s location:%d",
+ XCAM_STR (name), location);
+
+ return location;
+}
+
+GLCmdBindBufBase::GLCmdBindBufBase (const SmartPtr<GLBuffer> &buf, uint32_t index)
+ : _index (index)
+{
+ XCAM_ASSERT (buf.ptr ());
+ _buf = buf;
+}
+
+GLCmdBindBufBase::~GLCmdBindBufBase ()
+{
+}
+
+XCamReturn
+GLCmdBindBufBase::run (GLuint program)
+{
+ XCAM_UNUSED (program);
+
+ XCamReturn ret = _buf->bind_buffer_base (_index);
+ XCAM_FAIL_RETURN (
+ ERROR, ret == XCAM_RETURN_NO_ERROR, ret,
+ "GLCmdBindBufBase failed, idx:%d", _index);
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+GLCmdBindBufRange::GLCmdBindBufRange (const SmartPtr<GLBuffer> &buf, uint32_t index, uint32_t offset_x)
+ : _index (index)
+ , _offset (offset_x)
+ , _size (0)
+{
+ XCAM_ASSERT (buf.ptr ());
+ _buf = buf;
+
+ const GLBufferDesc &desc = buf->get_buffer_desc ();
+ _size = desc.size - offset_x;
+}
+
+GLCmdBindBufRange::GLCmdBindBufRange (
+ const SmartPtr<GLBuffer> &buf, uint32_t index, NV12PlaneIdx plane, uint32_t offset_in_plane)
+ : _index (index)
+ , _offset (0)
+ , _size (0)
+{
+ XCAM_ASSERT (buf.ptr ());
+ _buf = buf;
+
+ const GLBufferDesc &desc = buf->get_buffer_desc ();
+ _offset = desc.offsets [plane] + offset_in_plane;
+ _size = desc.slice_size [plane] - offset_in_plane;
+}
+
+GLCmdBindBufRange::~GLCmdBindBufRange ()
+{
+}
+
+XCamReturn
+GLCmdBindBufRange::run (GLuint program)
+{
+ XCAM_UNUSED (program);
+
+ XCamReturn ret = _buf->bind_buffer_range (_index, _offset, _size);
+ XCAM_FAIL_RETURN (
+ ERROR, ret == XCAM_RETURN_NO_ERROR, ret,
+ "GLCmdBindBufRange failed, idx:%d", _index);
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+}
diff --git a/modules/gles/gl_command.h b/modules/gles/gl_command.h
new file mode 100644
index 0000000..8906eee
--- /dev/null
+++ b/modules/gles/gl_command.h
@@ -0,0 +1,206 @@
+/*
+ * gl_command.h - GL command class
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#ifndef XCAM_GL_COMMAND_H
+#define XCAM_GL_COMMAND_H
+
+#include <list>
+#include <gles/gles_std.h>
+
+namespace XCam {
+
+namespace UniformOps {
+
+template <typename TType>
+GLenum uniform (GLint location, TType value);
+
+template <typename TType>
+GLenum uniform_array (GLint location, const TType *value, GLsizei count);
+
+template <typename TType, uint32_t TDim>
+GLenum uniform_vect (GLint location, const TType *value, GLsizei count = 1);
+
+template <typename TType, uint32_t TDim>
+GLenum uniform_mat (GLint location, const TType *value, GLsizei count = 1);
+}
+
+class GLCommand
+{
+public:
+ virtual ~GLCommand () {}
+ virtual XCamReturn run (GLuint program) = 0;
+
+protected:
+ explicit GLCommand () {}
+
+private:
+ XCAM_DEAD_COPY (GLCommand);
+};
+typedef std::list<SmartPtr<GLCommand> > GLCmdList;
+
+class GLCmdUniform
+ : public GLCommand
+{
+public:
+ virtual ~GLCmdUniform ();
+ virtual XCamReturn run (GLuint program);
+
+protected:
+ explicit GLCmdUniform (const GLchar *name);
+
+private:
+ GLint get_uniform_location (GLuint program, const GLchar *name);
+ virtual GLenum uniform (GLint location) = 0;
+
+protected:
+ GLchar _name[XCAM_GL_NAME_LENGTH];
+};
+
+/* uniform single variable */
+template <typename TType>
+class GLCmdUniformT
+ : public GLCmdUniform
+{
+public:
+ GLCmdUniformT (const GLchar *name, TType value)
+ : GLCmdUniform (name)
+ , _value (value)
+ {}
+ ~GLCmdUniformT () {}
+
+private:
+ virtual GLenum uniform (GLint location) {
+ return UniformOps::uniform <TType> (location, _value);
+ }
+
+private:
+ TType _value;
+};
+
+/* uniform array: TType array[TCount] */
+template <typename TType, int TCount>
+class GLCmdUniformTArray
+ : public GLCmdUniform
+{
+public:
+ GLCmdUniformTArray (const GLchar *name, const TType *value)
+ : GLCmdUniform (name)
+ {
+ XCAM_ASSERT (value);
+ memcpy (&_value[0], value, sizeof (TType) * TCount);
+ }
+ ~GLCmdUniformTArray () {}
+
+private:
+ virtual GLenum uniform (GLint location) {
+ return UniformOps::uniform_array <TType> (location, _value, TCount);
+ }
+
+private:
+ TType _value[TCount];
+};
+
+/* uniform vectors: TType vec{TDim}[TCount]*/
+template <typename TType, int TDim, int TCount = 1>
+class GLCmdUniformTVect
+ : public GLCmdUniform
+{
+public:
+ GLCmdUniformTVect (const GLchar *name, const TType *value)
+ : GLCmdUniform (name)
+ {
+ XCAM_ASSERT (value);
+ memcpy (&_value[0], value, sizeof (TType) * TDim * TCount);
+ }
+ ~GLCmdUniformTVect () {}
+
+private:
+ virtual GLenum uniform (GLint location) {
+ return UniformOps::uniform_vect <TType, TDim> (location, _value, TCount);
+ }
+
+private:
+ TType _value[TDim * TCount];
+};
+
+/* uniform matrix: TType mat{TColumns}x{TRows}[TCount], only support square matrix */
+template <typename TType, int TColumns, int TRows, int TCount = 1>
+class GLCmdUniformTMat
+ : public GLCmdUniform
+{
+public:
+ GLCmdUniformTMat (const GLchar *name, const TType *value)
+ : GLCmdUniform (name)
+ {
+ XCAM_ASSERT (value);
+ memcpy (&_value[0], value, sizeof (TType) * TColumns * TRows * TCount);
+ }
+ ~GLCmdUniformTMat () {}
+
+private:
+ virtual GLenum uniform (GLint location) {
+ XCAM_FAIL_RETURN (
+ ERROR, TColumns == TRows, -1,
+ "uniform_mat only support square matrix, invalid dimension:%dx%d", TColumns, TRows);
+
+ return UniformOps::uniform_mat <TType, TColumns> (location, _value, TCount);
+ }
+
+private:
+ TType _value[TColumns * TRows * TCount];
+};
+
+class GLBuffer;
+
+class GLCmdBindBufBase
+ : public GLCommand
+{
+public:
+ GLCmdBindBufBase (const SmartPtr<GLBuffer> &buf, uint32_t index);
+ virtual ~GLCmdBindBufBase ();
+
+ virtual XCamReturn run (GLuint program);
+
+private:
+ SmartPtr<GLBuffer> _buf;
+ uint32_t _index;
+};
+
+class GLCmdBindBufRange
+ : public GLCommand
+{
+public:
+ GLCmdBindBufRange (const SmartPtr<GLBuffer> &buf, uint32_t index, uint32_t offset_x = 0);
+ GLCmdBindBufRange (
+ const SmartPtr<GLBuffer> &buf, uint32_t index, NV12PlaneIdx plane, uint32_t offset_in_plane = 0);
+ virtual ~GLCmdBindBufRange ();
+
+ virtual XCamReturn run (GLuint program);
+
+private:
+ SmartPtr<GLBuffer> _buf;
+ uint32_t _index;
+ uint32_t _offset;
+ uint32_t _size;
+};
+
+}
+
+#endif // XCAM_GL_COMMAND_H \ No newline at end of file
diff --git a/modules/gles/gl_compute_program.cpp b/modules/gles/gl_compute_program.cpp
new file mode 100644
index 0000000..13649ad
--- /dev/null
+++ b/modules/gles/gl_compute_program.cpp
@@ -0,0 +1,178 @@
+/*
+ * gl_compute_program.cpp - GL compute program implementation
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#include "gl_compute_program.h"
+
+namespace XCam {
+
+GLGroupsSize GLComputeProgram::_max_groups_size;
+
+GLComputeProgram::GLComputeProgram (GLuint id, const char *name)
+ : GLProgram (id, name)
+ , _barrier (false)
+ , _barrier_bit (GL_SHADER_STORAGE_BARRIER_BIT)
+{
+ if (_max_groups_size.x == 0 && _max_groups_size.y == 0 && _max_groups_size.z == 0) {
+ get_max_groups_size (_max_groups_size);
+ }
+}
+
+GLComputeProgram::~GLComputeProgram ()
+{
+}
+
+SmartPtr<GLComputeProgram>
+GLComputeProgram::create_compute_program (const char *name)
+{
+ GLuint prog_id = glCreateProgram ();
+ XCAM_FAIL_RETURN (
+ ERROR, prog_id, NULL,
+ "create GL program(%s) failed, prog_id: %d, error flag: %s",
+ XCAM_STR (name), prog_id, gl_error_string (gl_error ()));
+
+ SmartPtr<GLComputeProgram> compute_prog = new GLComputeProgram (prog_id, name);
+ XCAM_FAIL_RETURN (
+ ERROR, compute_prog.ptr (), NULL,
+ "create GL compute program(%s) failed", XCAM_STR (name));
+
+ return compute_prog;
+}
+
+bool query_max_groups_size (GLuint idx, GLint &value)
+{
+ glGetIntegeri_v (GL_MAX_COMPUTE_WORK_GROUP_COUNT, idx, &value);
+
+ GLenum error = gl_error ();
+ XCAM_FAIL_RETURN (
+ ERROR, error == GL_NO_ERROR, false,
+ "GLComputeProgram query max groups size failed, idx:%d, error flag: %s",
+ idx, gl_error_string (error));
+
+ return true;
+}
+
+bool
+GLComputeProgram::get_max_groups_size (GLGroupsSize &size)
+{
+ XCAM_FAIL_RETURN (
+ ERROR,
+ query_max_groups_size (0, size.x) &&
+ query_max_groups_size (1, size.y) &&
+ query_max_groups_size (2, size.z),
+ false,
+ "GLComputeProgram(%s) get max groups size failed", XCAM_STR (get_name ()));
+
+ return true;
+}
+
+bool
+GLComputeProgram::check_groups_size (const GLGroupsSize &size)
+{
+ XCAM_FAIL_RETURN (
+ ERROR,
+ size.x > 0 && size.x <= _max_groups_size.x &&
+ size.y > 0 && size.y <= _max_groups_size.y &&
+ size.z > 0 && size.z <= _max_groups_size.z,
+ false,
+ "GLComputeProgram(%s) invalid groups size: %dx%dx%d",
+ XCAM_STR (get_name ()), size.x, size.y, size.z);
+
+ return true;
+}
+
+bool
+GLComputeProgram::set_groups_size (const GLGroupsSize &size)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, check_groups_size (size), false,
+ "GLComputeProgram(%s) set groups size failed, groups size: %dx%dx%d",
+ XCAM_STR (get_name ()), size.x, size.y, size.z);
+
+ _groups_size = size;
+
+ return true;
+}
+
+XCamReturn
+GLComputeProgram::work ()
+{
+ XCamReturn ret = dispatch ();
+ XCAM_FAIL_RETURN (
+ ERROR, ret == XCAM_RETURN_NO_ERROR, ret,
+ "GLComputeProgram(%s) dispatch failed", XCAM_STR (get_name ()));
+
+ if (_barrier) {
+ ret = barrier (_barrier_bit);
+ XCAM_FAIL_RETURN (
+ ERROR, ret == XCAM_RETURN_NO_ERROR, ret,
+ "GLComputeProgram(%s) barrier failed", XCAM_STR (get_name ()));
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+GLComputeProgram::barrier (GLbitfield barrier_bit)
+{
+ glMemoryBarrier (barrier_bit);
+
+ GLenum error = gl_error ();
+ XCAM_FAIL_RETURN (
+ ERROR, error == GL_NO_ERROR, XCAM_RETURN_ERROR_GLES,
+ "GLComputeProgram(%s) barrier failed, barrier bit: %d, error flag: %s",
+ XCAM_STR (get_name ()), barrier_bit, gl_error_string (error));
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+GLComputeProgram::finish ()
+{
+ glFinish ();
+
+ GLenum error = gl_error ();
+ XCAM_FAIL_RETURN (
+ ERROR, error == GL_NO_ERROR, XCAM_RETURN_ERROR_GLES,
+ "GLComputeProgram(%s) finish failed, error flag: %s",
+ XCAM_STR (get_name ()), gl_error_string (error));
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+GLComputeProgram::dispatch ()
+{
+ XCAM_FAIL_RETURN (
+ ERROR, check_groups_size (_groups_size), XCAM_RETURN_ERROR_PARAM,
+ "GLComputeProgram(%s) dispatch invalid groups size: %dx%dx%d",
+ XCAM_STR (get_name ()), _groups_size.x, _groups_size.y, _groups_size.z);
+
+ glDispatchCompute (_groups_size.x, _groups_size.y, _groups_size.z);
+
+ GLenum error = gl_error ();
+ XCAM_FAIL_RETURN (
+ ERROR, error == GL_NO_ERROR, XCAM_RETURN_ERROR_GLES,
+ "GLComputeProgram(%s) dispatch failed, groups size: %dx%dx%d, error flag: %s",
+ XCAM_STR (get_name ()), _groups_size.x, _groups_size.y, _groups_size.z, gl_error_string (error));
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+}
diff --git a/modules/gles/gl_compute_program.h b/modules/gles/gl_compute_program.h
new file mode 100644
index 0000000..66a5c81
--- /dev/null
+++ b/modules/gles/gl_compute_program.h
@@ -0,0 +1,70 @@
+/*
+ * gl_compute_program.h - GL compute program class
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#ifndef XCAM_GL_COMPUTE_PROGRAM_H
+#define XCAM_GL_COMPUTE_PROGRAM_H
+
+#include <gles/gl_program.h>
+
+namespace XCam {
+
+struct GLGroupsSize {
+ GLint x, y, z;
+ GLGroupsSize () : x (0), y (0), z (0) {}
+};
+
+class GLComputeProgram
+ : public GLProgram
+{
+public:
+ static SmartPtr<GLComputeProgram> create_compute_program (const char *name = NULL);
+ ~GLComputeProgram ();
+
+ bool set_groups_size (const GLGroupsSize &size);
+ void set_barrier (bool barrier, GLbitfield barrier_bit = GL_SHADER_STORAGE_BARRIER_BIT) {
+ _barrier = barrier;
+ _barrier_bit = barrier_bit;
+ }
+
+ virtual XCamReturn work ();
+ virtual XCamReturn finish ();
+
+private:
+ explicit GLComputeProgram (GLuint id, const char *name);
+
+ XCamReturn dispatch ();
+ XCamReturn barrier (GLbitfield barrier_bit);
+
+ bool get_max_groups_size (GLGroupsSize &size);
+ bool check_groups_size (const GLGroupsSize &size);
+
+private:
+ XCAM_DEAD_COPY (GLComputeProgram);
+
+private:
+ bool _barrier;
+ GLbitfield _barrier_bit;
+ GLGroupsSize _groups_size;
+ static GLGroupsSize _max_groups_size;
+};
+
+}
+
+#endif // XCAM_GL_COMPUTE_PROGRAM_H
diff --git a/modules/gles/gl_copy_handler.cpp b/modules/gles/gl_copy_handler.cpp
new file mode 100644
index 0000000..a29c23a
--- /dev/null
+++ b/modules/gles/gl_copy_handler.cpp
@@ -0,0 +1,228 @@
+/*
+ * gl_copy_handler.cpp - gl copy handler implementation
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#include "gl_copy_handler.h"
+#include "gl_utils.h"
+
+#define INVALID_INDEX (uint32_t)(-1)
+
+namespace XCam {
+
+DECLARE_WORK_CALLBACK (CbCopyShader, GLCopyHandler, copy_shader_done);
+
+const GLShaderInfo shader_info = {
+ GL_COMPUTE_SHADER,
+ "shader_copy",
+#include "shader_copy.comp.slx"
+ , 0
+};
+
+XCamReturn
+GLCopyShader::prepare_arguments (const SmartPtr<Worker::Arguments> &base, GLCmdList &cmds)
+{
+ SmartPtr<GLCopyShader::Args> args = base.dynamic_cast_ptr<GLCopyShader::Args> ();
+ XCAM_ASSERT (args.ptr () && args->in_buf.ptr () && args->out_buf.ptr ());
+
+ const GLBufferDesc &in_desc = args->in_buf->get_buffer_desc ();
+ const GLBufferDesc &out_desc = args->out_buf->get_buffer_desc ();
+ const Rect &in_area = args->in_area;
+ const Rect &out_area = args->out_area;
+
+ XCAM_ASSERT (in_area.pos_y == 0 && out_area.pos_y == 0);
+ XCAM_ASSERT (in_area.width == out_area.width && in_area.height == out_area.height);
+ XCAM_ASSERT (uint32_t(in_area.height) == in_desc.height && uint32_t(out_area.height) == out_desc.height);
+
+ cmds.push_back (new GLCmdBindBufRange (args->in_buf, 0));
+ cmds.push_back (new GLCmdBindBufRange (args->out_buf, 1));
+
+ size_t unit_bytes = 4 * sizeof (uint32_t);
+ uint32_t in_img_width = XCAM_ALIGN_UP (in_desc.aligned_width, unit_bytes) / unit_bytes;
+ uint32_t in_x_offset = XCAM_ALIGN_UP (in_area.pos_x, unit_bytes) / unit_bytes;
+ uint32_t out_img_width = XCAM_ALIGN_UP (out_desc.aligned_width, unit_bytes) / unit_bytes;
+ uint32_t out_x_offset = XCAM_ALIGN_UP (out_area.pos_x, unit_bytes) / unit_bytes;
+ uint32_t copy_width = XCAM_ALIGN_UP (in_area.width, unit_bytes) / unit_bytes;
+ uint32_t copy_height = XCAM_ALIGN_UP (in_area.height, 2) / 2 * 3;
+
+ cmds.push_back (new GLCmdUniformT<uint32_t> ("in_img_width", in_img_width));
+ cmds.push_back (new GLCmdUniformT<uint32_t> ("in_x_offset", in_x_offset));
+ cmds.push_back (new GLCmdUniformT<uint32_t> ("out_img_width", out_img_width));
+ cmds.push_back (new GLCmdUniformT<uint32_t> ("out_x_offset", out_x_offset));
+ cmds.push_back (new GLCmdUniformT<uint32_t> ("copy_width", copy_width));
+
+ GLGroupsSize groups_size;
+ groups_size.x = XCAM_ALIGN_UP (copy_width, 8) / 8;
+ groups_size.y = XCAM_ALIGN_UP (copy_height, 8) / 8;
+ groups_size.z = 1;
+
+ SmartPtr<GLComputeProgram> prog;
+ XCAM_FAIL_RETURN (
+ ERROR, get_compute_program (prog), XCAM_RETURN_ERROR_PARAM,
+ "GLCopyShader(%s) get compute program (idx:%d) failed", XCAM_STR (get_name ()), args->index);
+ prog->set_groups_size (groups_size);
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+GLCopyHandler::GLCopyHandler (const char *name)
+ : GLImageHandler (name)
+ , _index (INVALID_INDEX)
+{
+}
+
+GLCopyHandler::~GLCopyHandler ()
+{
+}
+
+XCamReturn
+GLCopyHandler::copy (const SmartPtr<VideoBuffer> &in_buf, SmartPtr<VideoBuffer> &out_buf)
+{
+ SmartPtr<ImageHandler::Parameters> param = new ImageHandler::Parameters (in_buf, out_buf);
+ XCAM_ASSERT (param.ptr ());
+
+ XCamReturn ret = execute_buffer (param, false);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "GLCopyHandler(%s) copy failed", XCAM_STR (get_name ()));
+
+ _copy_shader->finish ();
+ if (!out_buf.ptr ()) {
+ out_buf = param->out_buf;
+ }
+
+ return ret;
+}
+
+bool
+GLCopyHandler::set_copy_area (uint32_t idx, const Rect &in_area, const Rect &out_area)
+{
+ XCAM_FAIL_RETURN (
+ ERROR,
+ idx != INVALID_INDEX &&
+ in_area.width == out_area.width && in_area.height == out_area.height,
+ false,
+ "GLCopyHandler(%s): set copy area(idx:%d) failed, input size:%dx%d output size:%dx%d",
+ XCAM_STR (get_name ()), idx, in_area.width, in_area.height, out_area.width, out_area.height);
+
+ _index = idx;
+ _in_area = in_area;
+ _out_area = out_area;
+
+ XCAM_LOG_DEBUG ("GLCopyHandler: copy area (idx:%d) input area(%d, %d, %d, %d) output area(%d, %d, %d, %d)",
+ idx,
+ in_area.pos_x, in_area.pos_y, in_area.width, in_area.height,
+ out_area.pos_x, out_area.pos_y, out_area.width, out_area.height);
+
+ return true;
+}
+
+XCamReturn
+GLCopyHandler::configure_resource (const SmartPtr<Parameters> &param)
+{
+ XCAM_ASSERT (param.ptr () && param->in_buf.ptr ());
+ XCAM_ASSERT (!_copy_shader.ptr ());
+ XCAM_FAIL_RETURN (
+ ERROR,
+ _index != INVALID_INDEX &&
+ _in_area.width && _in_area.height && _out_area.width && _out_area.height,
+ XCAM_RETURN_ERROR_PARAM,
+ "GLCopyHandler(%s) invalid copy area, need set copy area first", XCAM_STR (get_name ()));
+
+ _copy_shader = create_copy_shader ();
+ XCAM_FAIL_RETURN (
+ ERROR, _copy_shader.ptr (), XCAM_RETURN_ERROR_PARAM,
+ "GLCopyHandler(%s) create copy shader (idx:%d) failed", XCAM_STR (get_name ()), _index);
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+GLCopyHandler::start_work (const SmartPtr<ImageHandler::Parameters> &param)
+{
+ XCAM_ASSERT (param.ptr () && param->in_buf.ptr () && param->out_buf.ptr ());
+
+ XCamReturn ret = start_copy_shader (param);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "GLCopyHandler(%s) start work (idx:%d) failed", XCAM_STR (get_name ()), _index);
+
+ param->in_buf.release ();
+
+ return ret;
+};
+
+XCamReturn
+GLCopyHandler::terminate ()
+{
+ if (_copy_shader.ptr ()) {
+ _copy_shader.release ();
+ }
+ return GLImageHandler::terminate ();
+}
+
+SmartPtr<GLCopyShader>
+GLCopyHandler::create_copy_shader ()
+{
+ SmartPtr<Worker::Callback> cb = new CbCopyShader (this);
+ XCAM_ASSERT (cb.ptr ());
+
+ SmartPtr<GLCopyShader> shader = new GLCopyShader (cb);
+ XCAM_ASSERT (shader.ptr ());
+
+ XCamReturn ret = shader->create_compute_program (shader_info, "copy_program");
+ XCAM_FAIL_RETURN (
+ ERROR, ret == XCAM_RETURN_NO_ERROR, NULL,
+ "GLCopyHandler(%s) create compute program failed", XCAM_STR (get_name ()));
+
+ return shader;
+}
+
+XCamReturn
+GLCopyHandler::start_copy_shader (const SmartPtr<ImageHandler::Parameters> &param)
+{
+ XCAM_ASSERT (param.ptr () && param->in_buf.ptr () && param->out_buf.ptr ());
+ XCAM_ASSERT (_copy_shader.ptr ());
+
+ SmartPtr<GLCopyShader::Args> args = new GLCopyShader::Args (param);
+ XCAM_ASSERT (args.ptr ());
+ args->in_buf = get_glbuffer (param->in_buf);
+ args->out_buf = get_glbuffer (param->out_buf);
+ args->index = _index;
+ args->in_area = _in_area;
+ args->out_area = _out_area;
+
+ return _copy_shader->work (args);
+}
+
+void
+GLCopyHandler::copy_shader_done (
+ const SmartPtr<Worker> &worker, const SmartPtr<Worker::Arguments> &base, const XCamReturn error)
+{
+ XCAM_UNUSED (worker);
+ XCAM_ASSERT (worker.ptr () == _copy_shader.ptr ());
+
+ SmartPtr<GLCopyShader::Args> args = base.dynamic_cast_ptr<GLCopyShader::Args> ();
+ XCAM_ASSERT (args.ptr ());
+ const SmartPtr<ImageHandler::Parameters> param = args->get_param ();
+ XCAM_ASSERT (param.ptr ());
+
+ execute_done (param, error);
+}
+
+}
diff --git a/modules/gles/gl_copy_handler.h b/modules/gles/gl_copy_handler.h
new file mode 100644
index 0000000..9235cfb
--- /dev/null
+++ b/modules/gles/gl_copy_handler.h
@@ -0,0 +1,93 @@
+/*
+ * gl_copy_handler.h - gl copy handler class
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#ifndef XCAM_GL_COPY_HANDER_H
+#define XCAM_GL_COPY_HANDER_H
+
+#include <xcam_utils.h>
+#include <gles/gl_image_shader.h>
+#include <gles/gl_image_handler.h>
+
+namespace XCam {
+
+class GLCopyShader
+ : public GLImageShader
+{
+public:
+ struct Args : GLArgs {
+ uint32_t index;
+ Rect in_area, out_area;
+ SmartPtr<GLBuffer> in_buf, out_buf;
+
+ Args (const SmartPtr<ImageHandler::Parameters> &param)
+ : GLArgs (param)
+ , index (0)
+ {}
+ };
+
+public:
+ explicit GLCopyShader (const SmartPtr<Worker::Callback> &cb)
+ : GLImageShader ("GLCopyShader", cb)
+ {}
+
+ ~GLCopyShader () {}
+
+private:
+ virtual XCamReturn prepare_arguments (const SmartPtr<Worker::Arguments> &args, GLCmdList &cmds);
+};
+
+class GLCopyHandler
+ : public GLImageHandler
+{
+ friend class CbCopyShader;
+
+public:
+ GLCopyHandler (const char *name = "GLCopyHandler");
+ ~GLCopyHandler ();
+
+ bool set_copy_area (uint32_t idx, const Rect &in_area, const Rect &out_area);
+ uint32_t get_index () {
+ return _index;
+ }
+ XCamReturn copy (const SmartPtr<VideoBuffer> &in_buf, SmartPtr<VideoBuffer> &out_buf);
+
+ //derived from ImageHandler
+ virtual XCamReturn terminate ();
+
+protected:
+ //derived from GLImageHandler
+ virtual XCamReturn configure_resource (const SmartPtr<Parameters> &param);
+ virtual XCamReturn start_work (const SmartPtr<Parameters> &param);
+
+private:
+ SmartPtr<GLCopyShader> create_copy_shader ();
+ XCamReturn start_copy_shader (const SmartPtr<ImageHandler::Parameters> &param);
+ void copy_shader_done (
+ const SmartPtr<Worker> &worker, const SmartPtr<Worker::Arguments> &args, const XCamReturn error);
+
+private:
+ uint32_t _index;
+ Rect _in_area;
+ Rect _out_area;
+ SmartPtr<GLCopyShader> _copy_shader;
+};
+
+}
+#endif // XCAM_GL_COPY_HANDER_H
diff --git a/modules/gles/gl_geomap_handler.cpp b/modules/gles/gl_geomap_handler.cpp
new file mode 100644
index 0000000..67a06de
--- /dev/null
+++ b/modules/gles/gl_geomap_handler.cpp
@@ -0,0 +1,403 @@
+/*
+ * gl_geomap_handler.cpp - gl geometry map handler implementation
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#include "gl_geomap_handler.h"
+#include "gl_utils.h"
+
+#define XCAM_GL_GEOMAP_ALIGN_X 4
+#define XCAM_GL_GEOMAP_ALIGN_Y 2
+
+namespace XCam {
+
+DECLARE_WORK_CALLBACK (CbGeoMapShader, GLGeoMapHandler, geomap_shader_done);
+
+const GLShaderInfo shader_info = {
+ GL_COMPUTE_SHADER,
+ "shader_geomap",
+#include "shader_geomap.comp.slx"
+ , 0
+};
+
+bool
+GLGeoMapShader::set_std_step (float factor_x, float factor_y)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, !XCAM_DOUBLE_EQUAL_AROUND (factor_x, 0.0f) && !XCAM_DOUBLE_EQUAL_AROUND (factor_y, 0.0f), false,
+ "GLGeoMapShader(%s) invalid standard factors: x:%f, y:%f", XCAM_STR (get_name ()), factor_x, factor_y);
+
+ _lut_std_step[0] = 1.0f / factor_x;
+ _lut_std_step[1] = 1.0f / factor_y;
+
+ return true;
+}
+
+XCamReturn
+GLGeoMapShader::prepare_arguments (const SmartPtr<Worker::Arguments> &base, GLCmdList &cmds)
+{
+ SmartPtr<GLGeoMapShader::Args> args = base.dynamic_cast_ptr<GLGeoMapShader::Args> ();
+ XCAM_ASSERT (args.ptr () && args->in_buf.ptr () && args->out_buf.ptr () && args->lut_buf.ptr ());
+ XCAM_FAIL_RETURN (
+ ERROR,
+ !XCAM_DOUBLE_EQUAL_AROUND (args->factors[0], 0.0f) && !XCAM_DOUBLE_EQUAL_AROUND (args->factors[1], 0.0f) &&
+ !XCAM_DOUBLE_EQUAL_AROUND (args->factors[2], 0.0f) && !XCAM_DOUBLE_EQUAL_AROUND (args->factors[3], 0.0f),
+ XCAM_RETURN_ERROR_PARAM,
+ "GLGeoMapHandler(%s) invalid factors: %f, %f, %f, %f",
+ XCAM_STR (get_name ()), args->factors[0], args->factors[1], args->factors[2], args->factors[3]);
+
+ const GLBufferDesc &in_desc = args->in_buf->get_buffer_desc ();
+ const GLBufferDesc &out_desc = args->out_buf->get_buffer_desc ();
+ const GLBufferDesc &lut_desc = args->lut_buf->get_buffer_desc ();
+
+ cmds.push_back (new GLCmdBindBufRange (args->in_buf, 0, NV12PlaneYIdx));
+ cmds.push_back (new GLCmdBindBufRange (args->in_buf, 1, NV12PlaneUVIdx));
+ cmds.push_back (new GLCmdBindBufRange (args->out_buf, 2, NV12PlaneYIdx));
+ cmds.push_back (new GLCmdBindBufRange (args->out_buf, 3, NV12PlaneUVIdx));
+ cmds.push_back (new GLCmdBindBufBase (args->lut_buf, 4));
+
+ size_t unit_bytes = sizeof (uint32_t);
+ uint32_t in_img_width = XCAM_ALIGN_UP (in_desc.width, unit_bytes) / unit_bytes;
+ uint32_t out_img_width = XCAM_ALIGN_UP (out_desc.width, unit_bytes) / unit_bytes;
+ cmds.push_back (new GLCmdUniformT<uint32_t> ("in_img_width", in_img_width));
+ cmds.push_back (new GLCmdUniformT<uint32_t> ("in_img_height", in_desc.height));
+ cmds.push_back (new GLCmdUniformT<uint32_t> ("out_img_width", out_img_width));
+ cmds.push_back (new GLCmdUniformT<uint32_t> ("out_img_height", out_desc.height));
+
+ cmds.push_back (new GLCmdUniformT<uint32_t> ("lut_width", lut_desc.width));
+ cmds.push_back (new GLCmdUniformT<uint32_t> ("lut_height", lut_desc.height));
+
+ float lut_step[4];
+ lut_step[0] = 1.0f / args->factors[0];
+ lut_step[1] = 1.0f / args->factors[1];
+ lut_step[2] = 1.0f / args->factors[2];
+ lut_step[3] = 1.0f / args->factors[3];
+ cmds.push_back (new GLCmdUniformTVect<float, 4> ("lut_step", lut_step));
+ cmds.push_back (new GLCmdUniformTVect<float, 2> ("lut_std_step", _lut_std_step));
+
+ GLGroupsSize groups_size;
+ groups_size.x = XCAM_ALIGN_UP (out_img_width, 8) / 8;
+ groups_size.y = XCAM_ALIGN_UP (out_desc.height, 16) / 16;
+ groups_size.z = 1;
+
+ SmartPtr<GLComputeProgram> prog;
+ XCAM_FAIL_RETURN (
+ ERROR, get_compute_program (prog), XCAM_RETURN_ERROR_PARAM,
+ "GLGeoMapShader(%s) get compute program failed", XCAM_STR (get_name ()));
+ prog->set_groups_size (groups_size);
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+GLGeoMapHandler::GLGeoMapHandler (const char *name)
+ : GLImageHandler (name)
+{
+}
+
+GLGeoMapHandler::~GLGeoMapHandler ()
+{
+}
+
+XCamReturn
+GLGeoMapHandler::remap (const SmartPtr<VideoBuffer> &in_buf, SmartPtr<VideoBuffer> &out_buf)
+{
+ SmartPtr<ImageHandler::Parameters> param = new ImageHandler::Parameters (in_buf, out_buf);
+ XCAM_ASSERT (param.ptr ());
+
+ XCamReturn ret = execute_buffer (param, false);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "GLGeoMapHandler(%s) remap failed", XCAM_STR (get_name ()));
+
+ _geomap_shader->finish ();
+ if (!out_buf.ptr ()) {
+ out_buf = param->out_buf;
+ }
+
+ return ret;
+}
+
+bool
+GLGeoMapHandler::set_lookup_table (const PointFloat2 *data, uint32_t width, uint32_t height)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, data && width && height, false,
+ "GLGeoMapHandler(%s) set look up table failed, data ptr:%p, width:%d, height:%d",
+ XCAM_STR (get_name ()), data, width, height);
+ XCAM_ASSERT (!_lut_buf.ptr ());
+
+ uint32_t lut_size = width * height * 2 * sizeof (float);
+ SmartPtr<GLBuffer> buf = GLBuffer::create_buffer (GL_SHADER_STORAGE_BUFFER, NULL, lut_size);
+ XCAM_ASSERT (buf.ptr ());
+
+ GLBufferDesc desc;
+ desc.width = width;
+ desc.height = height;
+ desc.size = lut_size;
+ buf->set_buffer_desc (desc);
+
+ float *ptr = (float *) buf->map_range (0, lut_size, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
+ XCAM_FAIL_RETURN (ERROR, ptr, false, "GLGeoMapHandler(%s) map range failed", XCAM_STR (get_name ()));
+ for (uint32_t i = 0; i < height; ++i) {
+ float *ret = &ptr[i * width * 2];
+ const PointFloat2 *line = &data[i * width];
+
+ for (uint32_t j = 0; j < width; ++j) {
+ ret[j * 2] = line[j].x;
+ ret[j * 2 + 1] = line[j].y;
+ }
+ }
+ buf->unmap ();
+ _lut_buf = buf;
+
+ return true;
+}
+
+bool
+GLGeoMapHandler::init_factors ()
+{
+ float factor_x, factor_y;
+ get_factors (factor_x, factor_y);
+
+ if (!XCAM_DOUBLE_EQUAL_AROUND (factor_x, 0.0f) && !XCAM_DOUBLE_EQUAL_AROUND (factor_y, 0.0f))
+ return true;
+
+ const GLBufferDesc &lut_desc = _lut_buf->get_buffer_desc ();
+ return auto_calculate_factors (lut_desc.width, lut_desc.height);
+}
+
+XCamReturn
+GLGeoMapHandler::configure_resource (const SmartPtr<Parameters> &param)
+{
+ XCAM_ASSERT (param.ptr () && param->in_buf.ptr ());
+ XCAM_FAIL_RETURN (
+ ERROR, _lut_buf.ptr (), XCAM_RETURN_ERROR_PARAM,
+ "GLGeoMapHandler(%s) configure failed, look up table is empty", XCAM_STR (get_name ()));
+
+ const VideoBufferInfo &in_info = param->in_buf->get_video_info ();
+ XCAM_FAIL_RETURN (
+ ERROR, in_info.format == V4L2_PIX_FMT_NV12, XCAM_RETURN_ERROR_PARAM,
+ "GLGeoMapHandler(%s) only support NV12 format, but input format is %s",
+ XCAM_STR (get_name ()), xcam_fourcc_to_string (in_info.format));
+
+ uint32_t width, height;
+ get_output_size (width, height);
+ VideoBufferInfo out_info;
+ out_info.init (
+ in_info.format, width, height,
+ XCAM_ALIGN_UP (width, XCAM_GL_GEOMAP_ALIGN_X),
+ XCAM_ALIGN_UP (height, XCAM_GL_GEOMAP_ALIGN_Y));
+ set_out_video_info (out_info);
+
+ init_factors ();
+
+ XCAM_ASSERT (!_geomap_shader.ptr ());
+ _geomap_shader = create_geomap_shader ();
+ XCAM_FAIL_RETURN (
+ ERROR, _geomap_shader.ptr (), XCAM_RETURN_ERROR_PARAM,
+ "GLGeoMapHandler(%s) create geomap shader failed", XCAM_STR (get_name ()));
+
+ float factor_x, factor_y;
+ get_factors (factor_x, factor_y);
+ _geomap_shader->set_std_step (factor_x, factor_y);
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+GLGeoMapHandler::start_work (const SmartPtr<ImageHandler::Parameters> &param)
+{
+ XCAM_ASSERT (param.ptr () && param->in_buf.ptr () && param->out_buf.ptr ());
+
+ XCamReturn ret = start_geomap_shader (param);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "GLGeoMapHandler(%s) start work failed", XCAM_STR (get_name ()));
+
+ param->in_buf.release ();
+
+ return ret;
+};
+
+XCamReturn
+GLGeoMapHandler::terminate ()
+{
+ if (_geomap_shader.ptr ()) {
+ _geomap_shader.release ();
+ }
+
+ return GLImageHandler::terminate ();
+}
+
+SmartPtr<GLGeoMapShader>
+GLGeoMapHandler::create_geomap_shader ()
+{
+ SmartPtr<Worker::Callback> cb = new CbGeoMapShader (this);
+ XCAM_ASSERT (cb.ptr ());
+ SmartPtr<GLGeoMapShader> shader = new GLGeoMapShader (cb);
+ XCAM_ASSERT (shader.ptr ());
+
+ XCamReturn ret = shader->create_compute_program (shader_info, "geomap_program");
+ XCAM_FAIL_RETURN (
+ ERROR, ret == XCAM_RETURN_NO_ERROR, NULL,
+ "GLGeoMapHandler(%s) create compute program failed", XCAM_STR (get_name ()));
+
+ return shader;
+}
+
+XCamReturn
+GLGeoMapHandler::start_geomap_shader (const SmartPtr<ImageHandler::Parameters> &param)
+{
+ XCAM_ASSERT (param.ptr () && param->in_buf.ptr () && param->out_buf.ptr ());
+ XCAM_ASSERT (_geomap_shader.ptr ());
+ XCAM_ASSERT (_lut_buf.ptr ());
+
+ float factor_x, factor_y;
+ get_factors (factor_x, factor_y);
+
+ SmartPtr<GLGeoMapShader::Args> args = new GLGeoMapShader::Args (param);
+ XCAM_ASSERT (args.ptr ());
+ args->in_buf = get_glbuffer (param->in_buf);
+ args->out_buf = get_glbuffer (param->out_buf);
+ args->lut_buf = _lut_buf;
+ args->factors[0] = factor_x;
+ args->factors[1] = factor_y;
+ args->factors[2] = args->factors[0];
+ args->factors[3] = args->factors[1];
+
+ return _geomap_shader->work (args);
+}
+
+void
+GLGeoMapHandler::geomap_shader_done (
+ const SmartPtr<Worker> &worker, const SmartPtr<Worker::Arguments> &base, const XCamReturn error)
+{
+ XCAM_UNUSED (worker);
+ XCAM_ASSERT (worker.ptr () == _geomap_shader.ptr ());
+
+ SmartPtr<GLGeoMapShader::Args> args = base.dynamic_cast_ptr<GLGeoMapShader::Args> ();
+ XCAM_ASSERT (args.ptr ());
+ const SmartPtr<ImageHandler::Parameters> param = args->get_param ();
+ XCAM_ASSERT (param.ptr ());
+
+ execute_done (param, error);
+}
+
+GLDualConstGeoMapHandler::GLDualConstGeoMapHandler (const char *name)
+ : GLGeoMapHandler (name)
+ , _left_factor_x (0.0f)
+ , _left_factor_y (0.0f)
+ , _right_factor_x (0.0f)
+ , _right_factor_y (0.0f)
+{
+}
+
+GLDualConstGeoMapHandler::~GLDualConstGeoMapHandler ()
+{
+}
+
+bool
+GLDualConstGeoMapHandler::set_left_factors (float x, float y)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, !XCAM_DOUBLE_EQUAL_AROUND (x, 0.0f) && !XCAM_DOUBLE_EQUAL_AROUND (y, 0.0f), false,
+ "GLGeoMapHandler(%s) set factors failed: x:%f, y:%f", XCAM_STR (get_name ()), x, y);
+
+ _left_factor_x = x;
+ _left_factor_y = y;
+
+ return true;
+}
+
+bool
+GLDualConstGeoMapHandler::set_right_factors (float x, float y)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, !XCAM_DOUBLE_EQUAL_AROUND (x, 0.0f) && !XCAM_DOUBLE_EQUAL_AROUND (y, 0.0f), false,
+ "GLGeoMapHandler(%s) set factors failed: x:%f, y:%f", XCAM_STR (get_name ()), x, y);
+
+ _right_factor_x = x;
+ _right_factor_y = y;
+
+ return true;
+}
+
+bool
+GLDualConstGeoMapHandler::init_factors ()
+{
+ float factor_x, factor_y;
+ get_factors (factor_x, factor_y);
+
+ if (!XCAM_DOUBLE_EQUAL_AROUND (factor_x, 0.0f) && !XCAM_DOUBLE_EQUAL_AROUND (factor_y, 0.0f))
+ return true;
+
+ const GLBufferDesc &lut_desc = _lut_buf->get_buffer_desc ();
+ XCAM_FAIL_RETURN (
+ ERROR, auto_calculate_factors (lut_desc.width, lut_desc.height), false,
+ "GLGeoMapHandler(%s) auto calculate factors failed");
+
+ get_factors (factor_x, factor_y);
+ _left_factor_x = factor_x;
+ _left_factor_y = factor_y;
+ _right_factor_x = _left_factor_x;
+ _right_factor_y = _left_factor_y;
+
+ return true;
+}
+
+XCamReturn
+GLDualConstGeoMapHandler::start_geomap_shader (const SmartPtr<ImageHandler::Parameters> &param)
+{
+ XCAM_ASSERT (param.ptr () && param->in_buf.ptr () && param->out_buf.ptr ());
+ XCAM_ASSERT (_geomap_shader.ptr ());
+ XCAM_ASSERT (_lut_buf.ptr ());
+
+ SmartPtr<GLGeoMapShader::Args> args = new GLGeoMapShader::Args (param);
+ XCAM_ASSERT (args.ptr ());
+ args->in_buf = get_glbuffer (param->in_buf);
+ args->out_buf = get_glbuffer (param->out_buf);
+ args->lut_buf = _lut_buf;
+
+ float factor_x, factor_y;
+ get_left_factors (factor_x, factor_y);
+ args->factors[0] = factor_x;
+ args->factors[1] = factor_y;
+
+ get_right_factors (factor_x, factor_y);
+ args->factors[2] = factor_x;
+ args->factors[3] = factor_y;
+
+ return _geomap_shader->work (args);
+}
+
+SmartPtr<GLImageHandler> create_gl_geo_mapper ()
+{
+ SmartPtr<GLImageHandler> mapper = new GLGeoMapHandler ();
+ XCAM_ASSERT (mapper.ptr ());
+
+ return mapper;
+}
+
+SmartPtr<GeoMapper>
+GeoMapper::create_gl_geo_mapper ()
+{
+ SmartPtr<GLImageHandler> handler = XCam::create_gl_geo_mapper ();
+ return handler.dynamic_cast_ptr<GeoMapper> ();
+}
+
+}
diff --git a/modules/gles/gl_geomap_handler.h b/modules/gles/gl_geomap_handler.h
new file mode 100644
index 0000000..30ee221
--- /dev/null
+++ b/modules/gles/gl_geomap_handler.h
@@ -0,0 +1,130 @@
+/*
+ * gl_geomap_handler.h - gl geometry map handler class
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#ifndef XCAM_GL_GEOMAP_HANDER_H
+#define XCAM_GL_GEOMAP_HANDER_H
+
+#include <interface/geo_mapper.h>
+#include <gles/gl_image_shader.h>
+#include <gles/gl_image_handler.h>
+
+namespace XCam {
+
+class GLGeoMapShader
+ : public GLImageShader
+{
+public:
+ struct Args : GLArgs {
+ SmartPtr<GLBuffer> in_buf, out_buf;
+ SmartPtr<GLBuffer> lut_buf;
+ float factors[4];
+
+ Args (const SmartPtr<ImageHandler::Parameters> &param)
+ : GLArgs (param)
+ {}
+ };
+
+public:
+ explicit GLGeoMapShader (const SmartPtr<Worker::Callback> &cb)
+ : GLImageShader ("GLGeoMapShader", cb)
+ {
+ xcam_mem_clear (_lut_std_step);
+ }
+
+ ~GLGeoMapShader () {}
+ bool set_std_step (float factor_x, float factor_y);
+
+private:
+ virtual XCamReturn prepare_arguments (const SmartPtr<Worker::Arguments> &args, GLCmdList &cmds);
+ XCAM_DEAD_COPY (GLGeoMapShader);
+
+private:
+ float _lut_std_step[2];
+};
+
+class GLGeoMapHandler
+ : public GLImageHandler, public GeoMapper
+{
+ friend class CbGeoMapShader;
+
+public:
+ GLGeoMapHandler (const char *name = "GLGeoMapHandler");
+ ~GLGeoMapHandler ();
+
+ bool set_lookup_table (const PointFloat2 *data, uint32_t width, uint32_t height);
+
+ XCamReturn remap (const SmartPtr<VideoBuffer> &in_buf, SmartPtr<VideoBuffer> &out_buf);
+
+ //derived from ImageHandler
+ virtual XCamReturn terminate ();
+
+protected:
+ //derived from GLImageHandler
+ virtual XCamReturn configure_resource (const SmartPtr<Parameters> &param);
+ virtual XCamReturn start_work (const SmartPtr<Parameters> &param);
+
+private:
+ virtual bool init_factors ();
+
+ virtual SmartPtr<GLGeoMapShader> create_geomap_shader ();
+ virtual XCamReturn start_geomap_shader (const SmartPtr<ImageHandler::Parameters> &param);
+ virtual void geomap_shader_done (
+ const SmartPtr<Worker> &worker, const SmartPtr<Worker::Arguments> &args, const XCamReturn error);
+
+ XCAM_DEAD_COPY (GLGeoMapHandler);
+
+protected:
+ SmartPtr<GLBuffer> _lut_buf;
+ SmartPtr<GLGeoMapShader> _geomap_shader;
+};
+
+class GLDualConstGeoMapHandler
+ : public GLGeoMapHandler
+{
+public:
+ GLDualConstGeoMapHandler (const char *name = "GLDualConstGeoMapHandler");
+ ~GLDualConstGeoMapHandler ();
+
+ bool set_left_factors (float x, float y);
+ void get_left_factors (float &x, float &y) {
+ x = _left_factor_x;
+ y = _left_factor_y;
+ }
+ bool set_right_factors (float x, float y);
+ void get_right_factors (float &x, float &y) {
+ x = _right_factor_x;
+ y = _right_factor_y;
+ }
+
+private:
+ virtual bool init_factors ();
+ virtual XCamReturn start_geomap_shader (const SmartPtr<ImageHandler::Parameters> &param);
+
+private:
+ float _left_factor_x;
+ float _left_factor_y;
+ float _right_factor_x;
+ float _right_factor_y;
+};
+
+extern SmartPtr<GLImageHandler> create_gl_geo_mapper ();
+
+}
+#endif // XCAM_GL_GEOMAP_HANDER_H
diff --git a/modules/gles/gl_image_handler.cpp b/modules/gles/gl_image_handler.cpp
new file mode 100644
index 0000000..d95b151
--- /dev/null
+++ b/modules/gles/gl_image_handler.cpp
@@ -0,0 +1,41 @@
+/*
+ * gl_image_handler.cpp - GL image handler implementation
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#include "gl_image_handler.h"
+#include "gl_video_buffer.h"
+
+namespace XCam {
+
+GLImageHandler::GLImageHandler (const char* name)
+ : ImageHandler (name)
+{
+}
+
+GLImageHandler::~GLImageHandler ()
+{
+}
+
+SmartPtr<BufferPool>
+GLImageHandler::create_allocator ()
+{
+ return new GLVideoBufferPool;
+}
+
+}
diff --git a/modules/gles/gl_image_handler.h b/modules/gles/gl_image_handler.h
new file mode 100644
index 0000000..db5ee54
--- /dev/null
+++ b/modules/gles/gl_image_handler.h
@@ -0,0 +1,47 @@
+/*
+ * gl_image_handler.h - GL image handler class
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#ifndef XCAM_GL_IMAGE_HANDLER_H
+#define XCAM_GL_IMAGE_HANDLER_H
+
+#include <image_handler.h>
+#include <gles/gles_std.h>
+
+namespace XCam {
+
+class GLImageHandler
+ : public ImageHandler
+{
+public:
+ explicit GLImageHandler (const char* name);
+ ~GLImageHandler ();
+
+private:
+ SmartPtr<BufferPool> create_allocator ();
+
+private:
+ XCAM_DEAD_COPY (GLImageHandler);
+
+private:
+};
+
+}
+
+#endif // XCAM_GL_IMAGE_HANDLER_H
diff --git a/modules/gles/gl_image_shader.cpp b/modules/gles/gl_image_shader.cpp
new file mode 100644
index 0000000..3b1a92f
--- /dev/null
+++ b/modules/gles/gl_image_shader.cpp
@@ -0,0 +1,191 @@
+/*
+ * gl_image_shader.cpp - gl image shader implementation
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#include "gl_image_shader.h"
+
+#define ENABLE_DEBUG_SHADER 0
+
+namespace XCam {
+
+GLImageShader::GLImageShader (const char *name, const SmartPtr<Callback> &cb)
+ : Worker (name, cb)
+{
+ XCAM_OBJ_PROFILING_INIT;
+}
+
+GLImageShader::~GLImageShader ()
+{
+}
+
+XCamReturn
+GLImageShader::finish ()
+{
+ _program->finish ();
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+GLImageShader::stop ()
+{
+ return XCAM_RETURN_NO_ERROR;
+}
+
+bool
+GLImageShader::get_compute_program (SmartPtr<GLComputeProgram> &prog)
+{
+ prog = _program.dynamic_cast_ptr<GLComputeProgram> ();
+ XCAM_FAIL_RETURN (
+ ERROR, prog.ptr (), false,
+ "GLImageShader(%s) convert to GLComputeProgram failed", XCAM_STR (get_name ()));
+
+ return true;
+}
+
+XCamReturn
+GLImageShader::work (const SmartPtr<Worker::Arguments> &args)
+{
+ XCamReturn ret = _program->use ();
+ XCAM_FAIL_RETURN (
+ WARNING, ret == XCAM_RETURN_NO_ERROR, ret,
+ "GLImageShader(%s) use program failed", XCAM_STR (get_name ()));
+
+ ret = pre_work (args);
+ XCAM_FAIL_RETURN (
+ WARNING, ret == XCAM_RETURN_NO_ERROR, ret,
+ "GLImageShader(%s) pre-work failed", XCAM_STR (get_name ()));
+
+#if ENABLE_DEBUG_SHADER
+ XCAM_OBJ_PROFILING_START;
+#endif
+
+ ret = _program->work ();
+ XCAM_FAIL_RETURN (
+ WARNING, ret == XCAM_RETURN_NO_ERROR, ret,
+ "GLImageShader(%s) work failed", XCAM_STR (get_name ()));
+
+#if ENABLE_DEBUG_SHADER
+ ret = _program->finish ();
+ XCAM_FAIL_RETURN (
+ WARNING, ret == XCAM_RETURN_NO_ERROR, ret,
+ "GLImageShader(%s) finish failed", XCAM_STR (get_name ()));
+
+ char name[XCAM_GL_NAME_LENGTH] = {'\0'};
+ snprintf (name, sizeof (name), "%s-%p", XCAM_STR (get_name ()), this);
+ XCAM_OBJ_PROFILING_END (name, XCAM_OBJ_DUR_FRAME_NUM);
+#endif
+
+ ret = _program->disuse ();
+ XCAM_FAIL_RETURN (
+ WARNING, ret == XCAM_RETURN_NO_ERROR, ret,
+ "GLImageShader(%s) disuse program failed", XCAM_STR (get_name ()));
+
+ status_check (args, ret);
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+GLImageShader::pre_work (const SmartPtr<Worker::Arguments> &args)
+{
+ GLCmdList cmds;
+
+ XCamReturn ret = prepare_arguments (args, cmds);
+ XCAM_FAIL_RETURN (
+ WARNING, ret == XCAM_RETURN_NO_ERROR, ret,
+ "GLImageShader(%s) prepare arguments failed", XCAM_STR (get_name ()));
+
+ ret = set_commands (cmds);
+ XCAM_FAIL_RETURN (
+ WARNING, ret == XCAM_RETURN_NO_ERROR, ret,
+ "GLImageShader(%s) set commands failed", XCAM_STR (get_name ()));
+
+ return ret;
+}
+XCamReturn
+GLImageShader::prepare_arguments (const SmartPtr<Worker::Arguments> &args, GLCmdList &cmds)
+{
+ XCAM_UNUSED (args);
+ XCAM_UNUSED (cmds);
+
+ XCAM_LOG_ERROR ("GLImageShader(%s) prepare arguments error", XCAM_STR (get_name ()));
+ return XCAM_RETURN_ERROR_GLES;
+}
+
+XCamReturn
+GLImageShader::set_commands (const GLCmdList &cmds)
+{
+ GLuint prog_id = _program->get_program_id();
+ XCAM_FAIL_RETURN (
+ WARNING, prog_id, XCAM_RETURN_ERROR_PARAM,
+ "GLImageShader(%s) invalid program id:%d", XCAM_STR (get_name ()), prog_id);
+
+ uint32_t i_count = 0;
+ for (GLCmdList::const_iterator iter = cmds.begin (); iter != cmds.end (); ++iter, ++i_count) {
+ const SmartPtr<GLCommand> &cmd = *iter;
+ XCAM_FAIL_RETURN (
+ WARNING, cmd.ptr (), XCAM_RETURN_ERROR_MEM,
+ "GLImageShader(%s) command(idx:%d) is NULL", XCAM_STR (get_name ()), i_count);
+
+ XCamReturn ret = cmd->run (prog_id);
+ XCAM_FAIL_RETURN (
+ WARNING, ret == XCAM_RETURN_NO_ERROR, ret,
+ "GLImageShader(%s) command(idx:%d) run failed", XCAM_STR (get_name ()));
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+GLImageShader::create_compute_program (const GLShaderInfo &info, const char *name)
+{
+ SmartPtr<GLComputeProgram> program = GLComputeProgram::create_compute_program (name);
+ XCAM_FAIL_RETURN (
+ ERROR, program.ptr (), XCAM_RETURN_ERROR_GLES,
+ "GLImageShader(%s) create compute program(%s) failed", XCAM_STR (get_name ()), XCAM_STR (name));
+
+ XCamReturn ret = program->link_shader (info);
+ XCAM_FAIL_RETURN (
+ ERROR, ret == XCAM_RETURN_NO_ERROR, ret,
+ "GLImageShader(%s) program(%s) pour shader failed", XCAM_STR (get_name ()), XCAM_STR (name));
+
+ _program = program;
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+GLImageShader::create_compute_program (const GLShaderInfoList &infos, const char *name)
+{
+ SmartPtr<GLComputeProgram> program = GLComputeProgram::create_compute_program (name);
+ XCAM_FAIL_RETURN (
+ ERROR, program.ptr (), XCAM_RETURN_ERROR_GLES,
+ "GLImageShader(%s) create compute program(%s) failed", XCAM_STR (get_name ()), XCAM_STR (name));
+
+ XCamReturn ret = program->link_shaders (infos);
+ XCAM_FAIL_RETURN (
+ ERROR, ret == XCAM_RETURN_NO_ERROR, ret,
+ "GLImageShader(%s) program(%s) pour shaders failed", XCAM_STR (get_name ()), XCAM_STR (name));
+
+ _program = program;
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+};
diff --git a/modules/gles/gl_image_shader.h b/modules/gles/gl_image_shader.h
new file mode 100644
index 0000000..47666d3
--- /dev/null
+++ b/modules/gles/gl_image_shader.h
@@ -0,0 +1,81 @@
+/*
+ * gl_image_shader.h - gl image shader class
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#ifndef XCAM_GL_IMAGE_SHADER_H
+#define XCAM_GL_IMAGE_SHADER_H
+
+#include <worker.h>
+#include <image_handler.h>
+#include <gles/gles_std.h>
+#include <gles/gl_command.h>
+#include <gles/gl_compute_program.h>
+
+namespace XCam {
+
+struct GLArgs
+ : Worker::Arguments
+{
+private:
+ SmartPtr<ImageHandler::Parameters> _param;
+
+public:
+ explicit GLArgs (const SmartPtr<ImageHandler::Parameters> &param = NULL) : _param (param) {}
+ inline const SmartPtr<ImageHandler::Parameters> &get_param () const {
+ return _param;
+ }
+ inline void set_param (const SmartPtr<ImageHandler::Parameters> &param) {
+ XCAM_ASSERT (param.ptr ());
+ _param = param;
+ }
+};
+
+class GLImageShader
+ : public Worker
+{
+public:
+ explicit GLImageShader (const char *name, const SmartPtr<Callback> &cb = NULL);
+ virtual ~GLImageShader ();
+
+ XCamReturn set_commands (const GLCmdList &cmds);
+ bool get_compute_program (SmartPtr<GLComputeProgram> &prog);
+
+ // derived from Worker
+ virtual XCamReturn work (const SmartPtr<Arguments> &args);
+ virtual XCamReturn finish ();
+ virtual XCamReturn stop ();
+
+ XCamReturn create_compute_program (const GLShaderInfo &info, const char *name = NULL);
+ XCamReturn create_compute_program (const GLShaderInfoList &infos, const char *name = NULL);
+
+private:
+ XCamReturn pre_work (const SmartPtr<Worker::Arguments> &args);
+ virtual XCamReturn prepare_arguments (const SmartPtr<Worker::Arguments> &args, GLCmdList &cmds);
+
+private:
+ XCAM_DEAD_COPY (GLImageShader);
+
+private:
+ SmartPtr<GLProgram> _program;
+
+ XCAM_OBJ_PROFILING_DEFINES;
+};
+
+}
+#endif // XCAM_GL_IMAGE_SHADER_H
diff --git a/modules/gles/gl_program.cpp b/modules/gles/gl_program.cpp
new file mode 100644
index 0000000..f6b9166
--- /dev/null
+++ b/modules/gles/gl_program.cpp
@@ -0,0 +1,247 @@
+/*
+ * gl_program.cpp - GL Program
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "gl_program.h"
+
+namespace XCam {
+
+GLProgram::GLProgram (GLuint id, const char *name)
+ : _program_id (id)
+ , _state (GLProgram::StateIntiated)
+{
+ strncpy (_name, XCAM_STR (name), XCAM_GL_NAME_LENGTH - 1);
+}
+
+GLProgram::~GLProgram ()
+{
+ disuse ();
+ clear_shaders ();
+ if (_program_id) {
+ glDeleteProgram (_program_id);
+
+ GLenum error = gl_error ();
+ if (error != GL_NO_ERROR) {
+ XCAM_LOG_WARNING (
+ "GL Program delete program failed, error flag: %s",
+ gl_error_string (error));
+ }
+ }
+}
+
+SmartPtr<GLProgram>
+GLProgram::create_program (const char *name)
+{
+ GLuint program_id = glCreateProgram ();
+ XCAM_FAIL_RETURN (
+ ERROR, program_id, NULL,
+ "Create GL program(%s) failed, error flag: %s",
+ XCAM_STR (name), gl_error_string (gl_error ()));
+
+ return new GLProgram (program_id, name ? name : "null");
+}
+
+XCamReturn
+GLProgram::attach_shader (const SmartPtr<GLShader> &shader)
+{
+ GLuint shader_id = shader->get_shader_id ();
+ XCAM_ASSERT (shader_id);
+ XCAM_FAIL_RETURN (
+ ERROR, _shaders.find (shader_id) == _shaders.end (),
+ XCAM_RETURN_ERROR_PARAM,
+ "GL program(:%s) already have shader (id:%d), do not attach twice",
+ get_name(), shader_id);
+
+ glAttachShader (_program_id, shader_id);
+ GLenum error = gl_error ();
+ XCAM_FAIL_RETURN (
+ ERROR, error == GL_NO_ERROR, XCAM_RETURN_ERROR_GLES,
+ "GL program(:%s) attach shader (id:%d) failed, error flag: %s",
+ get_name(), shader_id, gl_error_string (error));
+
+ _shaders.insert (ShaderList::value_type (shader_id, shader));
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+GLProgram::detach_shader (const SmartPtr<GLShader> &shader)
+{
+ GLuint shader_id = shader->get_shader_id ();
+ XCAM_ASSERT (shader_id);
+ ShaderList::iterator pos = _shaders.find (shader_id);
+
+ XCAM_FAIL_RETURN (
+ WARNING, pos == _shaders.end (),
+ XCAM_RETURN_ERROR_PARAM,
+ "GL program(:%s) do not need to detach shader (id:%d) which is not exist",
+ get_name(), shader_id);
+
+ glDetachShader (_program_id, shader_id);
+ GLenum error = gl_error ();
+ if (error != GL_NO_ERROR) {
+ XCAM_LOG_WARNING (
+ "GL program(:%s) detach shader (id:%d) failed but continued, error flag: %s",
+ get_name(), shader_id, gl_error_string (error));
+ }
+ _shaders.erase (pos);
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+GLProgram::clear_shaders ()
+{
+ for (ShaderList::iterator i = _shaders.begin (); i != _shaders.end (); ++i) {
+ SmartPtr<GLShader> shader = i->second;
+ glDetachShader (_program_id, shader->get_shader_id ());
+
+ GLenum error = gl_error ();
+ if (error != GL_NO_ERROR) {
+ XCAM_LOG_WARNING (
+ "GL program(:%s) detach shader (id:%d) failed, error flag: %s",
+ get_name(), shader->get_shader_id (), gl_error_string (error));
+ }
+ }
+ _shaders.clear ();
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+GLProgram::link ()
+{
+ XCAM_ASSERT (_program_id);
+
+ glLinkProgram (_program_id);
+ GLenum error = gl_error ();
+
+ GLint status;
+ std::vector<char> link_log;
+ glGetProgramiv (_program_id, GL_LINK_STATUS, &status);
+ if(status == GL_FALSE) {
+ GLint length;
+ glGetProgramiv (_program_id, GL_INFO_LOG_LENGTH, &length);
+ link_log.resize (length + 1);
+ glGetProgramInfoLog (_program_id, length, &length, &link_log[0]);
+ XCAM_LOG_ERROR(
+ "GL program(:%s) link failed, error flag: %s, link log:%s",
+ get_name(), gl_error_string (error), link_log.data());
+ return XCAM_RETURN_ERROR_GLES;
+ }
+
+ _state = StateLinked;
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+GLProgram::use ()
+{
+ XCAM_ASSERT (_program_id);
+ XCAM_FAIL_RETURN (
+ WARNING, _state == StateLinked && !_shaders.empty (), XCAM_RETURN_ERROR_PARAM,
+ "GL program(:%s) use must be called after link", get_name());
+
+ glUseProgram (_program_id);
+ GLenum error = gl_error ();
+ XCAM_FAIL_RETURN (
+ ERROR, error == GL_NO_ERROR, XCAM_RETURN_ERROR_GLES,
+ "GL program(:%s) use failed, error flag: %s",
+ get_name(), gl_error_string (error));
+
+ _state = StateInUse;
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+GLProgram::disuse ()
+{
+ if (_state != StateInUse)
+ return XCAM_RETURN_BYPASS;
+
+ glUseProgram (0);
+ GLenum error = gl_error ();
+ if (error != GL_NO_ERROR) {
+ XCAM_LOG_WARNING (
+ "GL program(:%s) disuse failed, error flag: %s",
+ get_name(), gl_error_string (error));
+ }
+
+ _state = StateLinked;
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+GLProgram::link_shader (const GLShaderInfo &info)
+{
+ SmartPtr<GLShader> shader = GLShader::compile_shader (info);
+ XCAM_FAIL_RETURN (
+ ERROR, shader->get_shader_id (), XCAM_RETURN_ERROR_GLES,
+ "GLProgram(%s) create shader(%s) failed", get_name (), info.name);
+
+ XCamReturn ret = attach_shader (shader);
+ XCAM_FAIL_RETURN (
+ ERROR, ret == XCAM_RETURN_NO_ERROR, ret,
+ "GLProgram(%s) attach shader(%s) failed", get_name (), info.name);
+
+ ret = link ();
+ XCAM_FAIL_RETURN (
+ ERROR, ret == XCAM_RETURN_NO_ERROR, ret,
+ "GLProgram(%s) link program failed", get_name ());
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+GLProgram::link_shaders (const GLShaderInfoList &infos)
+{
+ XCamReturn ret = XCAM_RETURN_NO_ERROR;
+ for (GLShaderInfoList::const_iterator iter = infos.begin (); iter != infos.end (); ++iter) {
+ const GLShaderInfo &info = *(*iter);
+
+ SmartPtr<GLShader> shader = GLShader::compile_shader (info);
+ XCAM_FAIL_RETURN (
+ ERROR, shader->get_shader_id (), XCAM_RETURN_ERROR_GLES,
+ "GLProgram(%s) create shader(%s) failed", get_name (), info.name);
+
+ ret = attach_shader (shader);
+ XCAM_FAIL_RETURN (
+ ERROR, ret == XCAM_RETURN_NO_ERROR, ret,
+ "GLProgram(%s) attach shader(%s) failed", get_name (), info.name);
+ }
+
+ ret = link ();
+ XCAM_FAIL_RETURN (
+ ERROR, ret == XCAM_RETURN_NO_ERROR, ret,
+ "GLProgram(%s) link program(%s) failed", get_name ());
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+GLProgram::work ()
+{
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+GLProgram::finish ()
+{
+ return XCAM_RETURN_NO_ERROR;
+}
+
+}
diff --git a/modules/gles/gl_program.h b/modules/gles/gl_program.h
new file mode 100644
index 0000000..39090c7
--- /dev/null
+++ b/modules/gles/gl_program.h
@@ -0,0 +1,79 @@
+/*
+ * gl_program.h - GL Program
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_GL_PROGRAM_H
+#define XCAM_GL_PROGRAM_H
+
+#include <gles/gles_std.h>
+#include <gles/gl_shader.h>
+#include <map>
+
+namespace XCam {
+
+class GLProgram
+{
+public:
+ typedef std::map<GLuint, SmartPtr<GLShader>> ShaderList;
+ enum State {
+ StateIntiated = 0,
+ StateLinked = 2,
+ StateInUse = 3,
+ };
+
+ virtual ~GLProgram ();
+ static SmartPtr<GLProgram> create_program (const char *name = NULL);
+ GLuint get_program_id () const {
+ return _program_id;
+ }
+ const char *get_name () {
+ return _name;
+ }
+
+ XCamReturn link_shader (const GLShaderInfo &info);
+ XCamReturn link_shaders (const GLShaderInfoList &infos);
+
+ XCamReturn use ();
+ XCamReturn disuse ();
+
+ virtual XCamReturn work ();
+ virtual XCamReturn finish ();
+
+protected:
+ explicit GLProgram (GLuint id, const char *name);
+
+private:
+ XCamReturn attach_shader (const SmartPtr<GLShader> &shader);
+ XCamReturn detach_shader (const SmartPtr<GLShader> &shader);
+ XCamReturn clear_shaders ();
+ XCamReturn link ();
+
+private:
+ XCAM_DEAD_COPY (GLProgram);
+
+private:
+ ShaderList _shaders;
+ GLuint _program_id;
+ State _state;
+ char _name [XCAM_GL_NAME_LENGTH];
+};
+
+}
+
+#endif //XCAM_GL_PROGRAM_H
diff --git a/modules/gles/gl_shader.cpp b/modules/gles/gl_shader.cpp
new file mode 100644
index 0000000..1810c70
--- /dev/null
+++ b/modules/gles/gl_shader.cpp
@@ -0,0 +1,86 @@
+/*
+ * gl_shader.cpp - GL shader
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "gl_shader.h"
+
+namespace XCam {
+
+GLShader::GLShader (GLuint id, GLenum type, const char *name)
+ : _shader_type (type)
+ , _shader_id (id)
+{
+ XCAM_ASSERT (name);
+ strncpy (_name, name, XCAM_GL_NAME_LENGTH - 1);
+}
+
+GLShader::~GLShader ()
+{
+ if (_shader_id) {
+ glDeleteShader (_shader_id);
+
+ GLenum error = gl_error ();
+ if (error != GL_NO_ERROR) {
+ XCAM_LOG_WARNING (
+ "GL Shader delete shader failed, error flag: %s",
+ gl_error_string (error));
+ }
+ }
+}
+
+SmartPtr<GLShader>
+GLShader::compile_shader (const GLShaderInfo &info)
+{
+ GLuint shader_id = glCreateShader (info.type);
+ GLenum error = gl_error ();
+ XCAM_FAIL_RETURN (
+ ERROR, shader_id && (error == GL_NO_ERROR), NULL,
+ "GL create shader(:%s) failed, error flag: %s",
+ XCAM_STR (info.name), gl_error_string (error));
+
+ GLint tmp_len = info.len ? info.len : strlen (info.src);
+ glShaderSource (shader_id, 1, &info.src, &tmp_len);
+ XCAM_FAIL_RETURN (
+ ERROR, (error = gl_error ()) == GL_NO_ERROR, NULL,
+ "GL create shader(:%s) failed in source loading, error flag: %s",
+ XCAM_STR (info.name), gl_error_string (error));
+
+ glCompileShader (shader_id);
+ error = gl_error ();
+
+ GLint status;
+ glGetShaderiv (shader_id, GL_COMPILE_STATUS, &status);
+ if (status == GL_FALSE) {
+ GLint length;
+ std::vector<char> compile_log;
+ glGetShaderiv (shader_id, GL_INFO_LOG_LENGTH, &length);
+ compile_log.resize (length + 1);
+ glGetShaderInfoLog (shader_id, length, &length, &compile_log[0]);
+ XCAM_LOG_ERROR (
+ "GL create sharder(:%s) compile failed, error flag: %s, log: %s",
+ XCAM_STR (info.name), gl_error_string (error), compile_log.data());
+ return NULL;
+ }
+
+ SmartPtr<GLShader> shader =
+ new GLShader (shader_id, info.type, (info.name ? info.name : "null"));
+ return shader;
+}
+
+}
diff --git a/modules/gles/gl_shader.h b/modules/gles/gl_shader.h
new file mode 100644
index 0000000..b379c44
--- /dev/null
+++ b/modules/gles/gl_shader.h
@@ -0,0 +1,78 @@
+/*
+ * gl_shader.h - GL shader
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_GL_SHADER_H
+#define XCAM_GL_SHADER_H
+
+#include <gles/gles_std.h>
+#include <list>
+#include <map>
+
+namespace XCam {
+
+XCAM_BEGIN_DECLARE
+
+typedef struct _GLShaderInfo {
+ GLenum type;
+ const GLchar *name;
+ const GLchar *src;
+ GLint len;
+} GLShaderInfo;
+
+XCAM_END_DECLARE
+
+typedef std::list<const GLShaderInfo *> GLShaderInfoList;
+
+class GLShader
+{
+public:
+ ~GLShader ();
+ static SmartPtr<GLShader> compile_shader (const GLShaderInfo &info);
+
+#if 0
+ static SmartPtr<GLShader> create_binary_shader (
+ GLenum format, const uint8_t *binary, uint32_t length, const char *name = NULL);
+#endif
+
+ GLuint get_shader_id () const {
+ return _shader_id;
+ }
+ const char *get_name () const {
+ return _name;
+ }
+ GLenum get_type () const {
+ return _shader_type;
+ }
+
+private:
+ explicit GLShader (GLuint id, GLenum type, const char *name);
+
+private:
+ XCAM_DEAD_COPY (GLShader);
+
+private:
+ GLenum _shader_type;
+ GLuint _shader_id;
+ char _name [XCAM_GL_NAME_LENGTH];
+};
+
+}
+
+#endif //XCAM_GL_SHADER_H
diff --git a/modules/gles/gl_stitcher.cpp b/modules/gles/gl_stitcher.cpp
new file mode 100644
index 0000000..ff357ce
--- /dev/null
+++ b/modules/gles/gl_stitcher.cpp
@@ -0,0 +1,894 @@
+/*
+ * gl_stitcher.cpp - GL stitcher implementation
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#include "surview_fisheye_dewarp.h"
+#include "gl_video_buffer.h"
+#include "gl_geomap_handler.h"
+#include "gl_blender.h"
+#include "gl_copy_handler.h"
+#include "gl_stitcher.h"
+#include "interface/feature_match.h"
+
+#define GL_STITCHER_ALIGNMENT_X 16
+#define GL_STITCHER_ALIGNMENT_Y 4
+
+#define MAP_FACTOR_X 16
+#define MAP_FACTOR_Y 16
+
+#define DUMP_BUFFER 0
+
+namespace XCam {
+
+#if DUMP_BUFFER
+static void
+dump_buf (const SmartPtr<VideoBuffer> buf, uint32_t idx, const char *prefix)
+{
+ XCAM_ASSERT (buf.ptr ());
+ XCAM_ASSERT (prefix);
+
+ char name[256];
+ snprintf (name, 256, "%s-%d", prefix, idx);
+ dump_buf_perfix_path (buf, name);
+}
+#else
+static void
+dump_buf (const SmartPtr<VideoBuffer> buf, ...) {
+ XCAM_UNUSED (buf);
+}
+#endif
+
+namespace GLSitcherPriv {
+
+DECLARE_HANDLER_CALLBACK (CbGeoMap, GLStitcher, dewarp_done);
+DECLARE_HANDLER_CALLBACK (CbBlender, GLStitcher, blender_done);
+DECLARE_HANDLER_CALLBACK (CbCopier, GLStitcher, copier_done);
+
+struct BlenderParam
+ : GLBlender::BlenderParam
+{
+ SmartPtr<GLStitcher::StitcherParam> stitch_param;
+ uint32_t idx;
+
+ BlenderParam (
+ uint32_t i,
+ const SmartPtr<VideoBuffer> &in0,
+ const SmartPtr<VideoBuffer> &in1,
+ const SmartPtr<VideoBuffer> &out)
+ : GLBlender::BlenderParam (in0, in1, out)
+ , idx (i)
+ {}
+};
+typedef std::map<void*, SmartPtr<BlenderParam>> BlenderParams;
+
+struct HandlerParam
+ : ImageHandler::Parameters
+{
+ SmartPtr<GLStitcher::StitcherParam> stitch_param;
+ uint32_t idx;
+
+ HandlerParam (uint32_t i)
+ : idx (i)
+ {}
+};
+
+struct Factor {
+ float x, y;
+
+ Factor () : x (1.0f), y (1.0f) {}
+ void reset () {
+ x = 1.0f;
+ y = 1.0f;
+ }
+};
+
+struct Overlap {
+ SmartPtr<FeatureMatch> matcher;
+ SmartPtr<GLBlender> blender;
+ BlenderParams param_map;
+
+ SmartPtr<BlenderParam> find_blender_param_in_map (
+ const SmartPtr<GLStitcher::StitcherParam> &key,
+ const uint32_t idx);
+};
+
+struct FisheyeDewarp {
+ SmartPtr<GLGeoMapHandler> dewarp;
+ SmartPtr<BufferPool> buf_pool;
+ Factor left_match_factor;
+ Factor right_match_factor;
+
+ bool set_dewarp_factor ();
+ XCamReturn set_dewarp_geo_table (
+ const SmartPtr<GLGeoMapHandler> &mapper, const CameraInfo &cam_info,
+ const Stitcher::RoundViewSlice &view_slice, const BowlDataConfig &bowl);
+};
+
+typedef std::vector<SmartPtr<GLCopyHandler>> Copiers;
+
+class StitcherImpl {
+ friend class XCam::GLStitcher;
+
+public:
+ StitcherImpl (GLStitcher *handler)
+ : _stitcher (handler)
+ {}
+
+ XCamReturn init_config (uint32_t count);
+ XCamReturn start_dewarps (const SmartPtr<GLStitcher::StitcherParam> &param);
+ XCamReturn start_blenders (
+ const SmartPtr<GLStitcher::StitcherParam> &param,
+ uint32_t idx, const SmartPtr<VideoBuffer> &buf);
+ XCamReturn start_copier (
+ const SmartPtr<GLStitcher::StitcherParam> &param,
+ uint32_t idx, const SmartPtr<VideoBuffer> &buf);
+
+ XCamReturn start_single_blender (uint32_t idx, const SmartPtr<BlenderParam> &param);
+ XCamReturn stop ();
+
+ XCamReturn fisheye_dewarp_to_table ();
+
+ XCamReturn start_feature_match (
+ const SmartPtr<VideoBuffer> &left_buf, const SmartPtr<VideoBuffer> &right_buf, uint32_t idx);
+
+ const SmartPtr<GLComputeProgram> &get_sync_prog ();
+
+private:
+ SmartPtr<GLGeoMapHandler> create_geo_mapper (const Stitcher::RoundViewSlice &view_slice);
+
+ XCamReturn init_fisheye (uint32_t idx);
+ bool init_dewarp_factors (uint32_t idx);
+
+ void calc_dewarp_factors (
+ uint32_t idx, const Factor &last_left_factor, const Factor &last_right_factor,
+ Factor &cur_left, Factor &cur_right);
+
+ void init_feature_match (uint32_t idx);
+ bool get_and_reset_fm_factors (uint32_t idx, Factor &left, Factor &right);
+
+private:
+ FisheyeDewarp _fisheye[XCAM_STITCH_MAX_CAMERAS];
+ Overlap _overlaps[XCAM_STITCH_MAX_CAMERAS];
+ Copiers _copiers;
+
+ GLStitcher *_stitcher;
+ SmartPtr<GLComputeProgram> _sync_prog;
+};
+
+const SmartPtr<GLComputeProgram> &
+StitcherImpl::get_sync_prog ()
+{
+ if (_sync_prog.ptr ())
+ return _sync_prog;
+
+ _sync_prog = GLComputeProgram::create_compute_program ("sync_program");
+ XCAM_FAIL_RETURN (
+ ERROR, _sync_prog.ptr (), _sync_prog,
+ "gl-stitcher(%s) create sync program failed",
+ XCAM_STR (_stitcher->get_name ()));
+
+ return _sync_prog;
+}
+
+bool
+StitcherImpl::get_and_reset_fm_factors (uint32_t idx, Factor &left, Factor &right)
+{
+ uint32_t cam_num = _stitcher->get_camera_num ();
+ XCAM_FAIL_RETURN (
+ ERROR, idx < cam_num, false,
+ "gl-stitcher(%s) invalid camera index, idx(%d) > camera_num(%d)",
+ XCAM_STR (_stitcher->get_name ()), idx, cam_num);
+
+ left = _fisheye[idx].left_match_factor;
+ right = _fisheye[idx].right_match_factor;
+
+ _fisheye[idx].left_match_factor.reset ();
+ _fisheye[idx].right_match_factor.reset ();
+
+ return true;
+}
+
+void
+StitcherImpl::calc_dewarp_factors (
+ uint32_t idx, const Factor &last_left_factor, const Factor &last_right_factor,
+ Factor &cur_left, Factor &cur_right)
+{
+ Factor match_left_factor, match_right_factor;
+ get_and_reset_fm_factors (idx, match_left_factor, match_right_factor);
+
+ cur_left.x = last_left_factor.x * match_left_factor.x;
+ cur_left.y = last_left_factor.y * match_left_factor.y;
+ cur_right.x = last_right_factor.x * match_right_factor.x;
+ cur_right.y = last_right_factor.y * match_right_factor.y;
+}
+
+bool
+StitcherImpl::init_dewarp_factors (uint32_t idx)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, _fisheye[idx].dewarp.ptr (), false,
+ "gl-stitcher(%s) dewarp handler is empty",
+ XCAM_STR (_stitcher->get_name ()));
+
+ Factor last_left_factor, last_right_factor, cur_left, cur_right;
+ if (_stitcher->get_scale_mode () == ScaleSingleConst) {
+ Factor unify_factor;
+ _fisheye[idx].dewarp->get_factors (unify_factor.x, unify_factor.y);
+ if (XCAM_DOUBLE_EQUAL_AROUND (unify_factor.x, 0.0f) ||
+ XCAM_DOUBLE_EQUAL_AROUND (unify_factor.y, 0.0f)) { // not started.
+ return true;
+ }
+ last_left_factor = last_right_factor = unify_factor;
+
+ calc_dewarp_factors (idx, last_left_factor, last_right_factor, cur_left, cur_right);
+ unify_factor.x = (cur_left.x + cur_right.x) / 2.0f;
+ unify_factor.y = (cur_left.y + cur_right.y) / 2.0f;
+
+ _fisheye[idx].dewarp->set_factors (unify_factor.x, unify_factor.y);
+ } else {
+ SmartPtr<GLDualConstGeoMapHandler> dewarp = _fisheye[idx].dewarp.dynamic_cast_ptr<GLDualConstGeoMapHandler> ();
+ XCAM_ASSERT (dewarp.ptr ());
+
+ dewarp->get_left_factors (last_left_factor.x, last_left_factor.y);
+ dewarp->get_right_factors (last_right_factor.x, last_right_factor.y);
+ if (XCAM_DOUBLE_EQUAL_AROUND (last_left_factor.x, 0.0f) ||
+ XCAM_DOUBLE_EQUAL_AROUND (last_left_factor.y, 0.0f) ||
+ XCAM_DOUBLE_EQUAL_AROUND (last_right_factor.y, 0.0f) ||
+ XCAM_DOUBLE_EQUAL_AROUND (last_right_factor.y, 0.0f)) { // not started.
+ return true;
+ }
+
+ calc_dewarp_factors (idx, last_left_factor, last_right_factor, cur_left, cur_right);
+ dewarp->set_left_factors (cur_left.x, cur_left.y);
+ dewarp->set_right_factors (cur_right.x, cur_right.y);
+ }
+
+ return true;
+}
+
+
+XCamReturn
+FisheyeDewarp::set_dewarp_geo_table (
+ const SmartPtr<GLGeoMapHandler> &mapper, const CameraInfo &cam_info,
+ const Stitcher::RoundViewSlice &view_slice, const BowlDataConfig &bowl)
+{
+ PolyFisheyeDewarp fd;
+ fd.set_intrinsic_param (cam_info.calibration.intrinsic);
+ fd.set_extrinsic_param (cam_info.calibration.extrinsic);
+
+ uint32_t table_width, table_height;
+ table_width = view_slice.width / MAP_FACTOR_X;
+ table_height = view_slice.height / MAP_FACTOR_Y;
+
+ SurViewFisheyeDewarp::MapTable map_table(table_width * table_height);
+ fd.fisheye_dewarp (
+ map_table, table_width, table_height,
+ view_slice.width, view_slice.height, bowl);
+
+ XCAM_FAIL_RETURN (
+ ERROR,
+ mapper->set_lookup_table (map_table.data (), table_width, table_height),
+ XCAM_RETURN_ERROR_UNKNOWN,
+ "set fisheye dewarp lookup table failed");
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+SmartPtr<GLGeoMapHandler>
+StitcherImpl::create_geo_mapper (const Stitcher::RoundViewSlice &view_slice)
+{
+ XCAM_UNUSED (view_slice);
+
+ SmartPtr<GLGeoMapHandler> dewarp;
+ GeoMapScaleMode scale_mode = _stitcher->get_scale_mode ();
+ if (scale_mode == ScaleSingleConst)
+ dewarp = new GLGeoMapHandler ("sitcher_singleconst_remapper");
+ else if (scale_mode == ScaleDualConst) {
+ dewarp = new GLDualConstGeoMapHandler ("sitcher_dualconst_remapper");
+ } else {
+ XCAM_LOG_ERROR (
+ "gl-stitcher(%s) unsupported GeoMapScaleMode: %d",
+ XCAM_STR (_stitcher->get_name ()), scale_mode);
+ }
+ XCAM_ASSERT (dewarp.ptr ());
+
+ return dewarp;
+}
+
+XCamReturn
+StitcherImpl::init_fisheye (uint32_t idx)
+{
+ FisheyeDewarp &fisheye = _fisheye[idx];
+ Stitcher::RoundViewSlice view_slice = _stitcher->get_round_view_slice (idx);
+
+ SmartPtr<ImageHandler::Callback> dewarp_cb = new CbGeoMap (_stitcher);
+ fisheye.dewarp = create_geo_mapper (view_slice);
+ fisheye.dewarp->set_callback (dewarp_cb);
+
+ VideoBufferInfo buf_info;
+ buf_info.init (
+ V4L2_PIX_FMT_NV12, view_slice.width, view_slice.height,
+ XCAM_ALIGN_UP (view_slice.width, GL_STITCHER_ALIGNMENT_X),
+ XCAM_ALIGN_UP (view_slice.height, GL_STITCHER_ALIGNMENT_Y));
+
+ SmartPtr<BufferPool> pool = new GLVideoBufferPool (buf_info);
+ XCAM_ASSERT (pool.ptr ());
+ XCAM_FAIL_RETURN (
+ ERROR, pool->reserve (XCAM_GL_RESERVED_BUF_COUNT), XCAM_RETURN_ERROR_MEM,
+ "gl-stitcher(%s) reserve dewarp buffer pool failed, width:%d, height:%d",
+ XCAM_STR (_stitcher->get_name ()), buf_info.width, buf_info.height);
+ fisheye.buf_pool = pool;
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+void
+StitcherImpl::init_feature_match (uint32_t idx)
+{
+#if HAVE_OPENCV
+#ifndef ANDROID
+ FeatureMatchMode fm_mode = _stitcher->get_fm_mode ();
+ if (fm_mode == FMNone)
+ return ;
+ else if (fm_mode == FMDefault)
+ _overlaps[idx].matcher = FeatureMatch::create_default_feature_match ();
+ else if (fm_mode == FMCluster)
+ _overlaps[idx].matcher = FeatureMatch::create_cluster_feature_match ();
+ else if (fm_mode == FMCapi)
+ _overlaps[idx].matcher = FeatureMatch::create_capi_feature_match ();
+ else {
+ XCAM_LOG_ERROR (
+ "gl-stitcher(%s) unsupported FeatureMatchMode: %d",
+ XCAM_STR (_stitcher->get_name ()), fm_mode);
+ }
+#else
+ _overlaps[idx].matcher = FeatureMatch::create_capi_feature_match ();
+#endif
+ XCAM_ASSERT (_overlaps[idx].matcher.ptr ());
+
+ FMConfig config;
+ config.sitch_min_width = 136;
+ config.min_corners = 4;
+ config.offset_factor = 0.8f;
+ config.delta_mean_offset = 120.0f;
+ config.recur_offset_error = 8.0f;
+ config.max_adjusted_offset = 24.0f;
+ config.max_valid_offset_y = 20.0f;
+ config.max_track_error = 28.0f;
+#ifdef ANDROID
+ config.max_track_error = 3600.0f;
+#endif
+ _overlaps[idx].matcher->set_config (config);
+ _overlaps[idx].matcher->set_fm_index (idx);
+
+ const BowlDataConfig bowl = _stitcher->get_bowl_config ();
+ const Stitcher::ImageOverlapInfo &info = _stitcher->get_overlap (idx);
+ Rect left_ovlap = info.left;
+ Rect right_ovlap = info.right;
+ left_ovlap.pos_y = 0;
+ left_ovlap.height = int32_t (bowl.wall_height / (bowl.wall_height + bowl.ground_length) * left_ovlap.height);
+ right_ovlap.pos_y = 0;
+ right_ovlap.height = left_ovlap.height;
+ _overlaps[idx].matcher->set_crop_rect (left_ovlap, right_ovlap);
+#else
+ XCAM_LOG_ERROR ("gl-stitcher(%s) feature match is unsupported", XCAM_STR (_stitcher->get_name ()));
+ XCAM_ASSERT (false);
+#endif
+}
+
+XCamReturn
+StitcherImpl::init_config (uint32_t count)
+{
+ for (uint32_t i = 0; i < count; ++i) {
+ XCamReturn ret = init_fisheye (i);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "gl-stitcher(%s) init fisheye failed, idx:%d.", XCAM_STR (_stitcher->get_name ()), i);
+
+#if HAVE_OPENCV
+ init_feature_match (i);
+#endif
+
+ _overlaps[i].blender = create_gl_blender ().dynamic_cast_ptr<GLBlender>();
+ XCAM_ASSERT (_overlaps[i].blender.ptr ());
+ SmartPtr<ImageHandler::Callback> blender_cb = new CbBlender (_stitcher);
+ XCAM_ASSERT (blender_cb.ptr ());
+ _overlaps[i].blender->set_callback (blender_cb);
+ _overlaps[i].param_map.clear ();
+ }
+
+ Stitcher::CopyAreaArray areas = _stitcher->get_copy_area ();
+ uint32_t size = areas.size ();
+ for (uint32_t i = 0; i < size; ++i) {
+ XCAM_ASSERT (areas[i].in_idx < size);
+
+ SmartPtr<ImageHandler::Callback> copier_cb = new CbCopier (_stitcher);
+ XCAM_ASSERT (copier_cb.ptr ());
+ SmartPtr<GLCopyHandler> copier = new GLCopyHandler ("stitch_copy");
+ XCAM_ASSERT (copier.ptr ());
+
+ copier->enable_allocator (false);
+ copier->set_callback (copier_cb);
+ copier->set_copy_area (areas[i].in_idx, areas[i].in_area, areas[i].out_area);
+ _copiers.push_back (copier);
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+StitcherImpl::fisheye_dewarp_to_table ()
+{
+ uint32_t camera_num = _stitcher->get_camera_num ();
+ for (uint32_t i = 0; i < camera_num; ++i) {
+ CameraInfo cam_info;
+ _stitcher->get_camera_info (i, cam_info);
+ Stitcher::RoundViewSlice view_slice = _stitcher->get_round_view_slice (i);
+
+ BowlDataConfig bowl = _stitcher->get_bowl_config ();
+ bowl.angle_start = view_slice.hori_angle_start;
+ bowl.angle_end = format_angle (view_slice.hori_angle_start + view_slice.hori_angle_range);
+
+ uint32_t out_width, out_height;
+ _stitcher->get_output_size (out_width, out_height);
+
+ XCAM_ASSERT (_fisheye[i].dewarp.ptr ());
+ _fisheye[i].dewarp->set_output_size (view_slice.width, view_slice.height);
+
+ if (bowl.angle_end < bowl.angle_start)
+ bowl.angle_start -= 360.0f;
+
+ XCAM_LOG_DEBUG (
+ "gl-stitcher(%s) camera(idx:%d) info(angle start:%.2f, range:%.2f), bowl info(angle start:%.2f, end:%.2f)",
+ XCAM_STR (_stitcher->get_name ()), i,
+ view_slice.hori_angle_start, view_slice.hori_angle_range,
+ bowl.angle_start, bowl.angle_end);
+
+ XCamReturn ret = _fisheye[i].set_dewarp_geo_table (_fisheye[i].dewarp, cam_info, view_slice, bowl);
+
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "gl-stitcher(%s) set dewarp geo table failed, idx:%d", XCAM_STR (_stitcher->get_name ()), i);
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+StitcherImpl::start_dewarps (const SmartPtr<GLStitcher::StitcherParam> &param)
+{
+ uint32_t camera_num = _stitcher->get_camera_num ();
+
+ for (uint32_t i = 0; i < camera_num; ++i) {
+ SmartPtr<VideoBuffer> out_buf = _fisheye[i].buf_pool->get_buffer ();
+ SmartPtr<HandlerParam> dewarp_params = new HandlerParam (i);
+ dewarp_params->in_buf = param->in_bufs[i];
+ dewarp_params->out_buf = out_buf;
+ dewarp_params->stitch_param = param;
+
+ init_dewarp_factors (i);
+ XCamReturn ret = _fisheye[i].dewarp->execute_buffer (dewarp_params, false);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "gl-stitcher(%s) fisheye dewarp buffer failed, idx:%d",
+ XCAM_STR (_stitcher->get_name ()), i);
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+StitcherImpl::start_feature_match (
+ const SmartPtr<VideoBuffer> &left_buf, const SmartPtr<VideoBuffer> &right_buf, uint32_t idx)
+{
+#if HAVE_OPENCV
+ _overlaps[idx].matcher->reset_offsets ();
+ _overlaps[idx].matcher->feature_match (left_buf, right_buf);
+
+ Rect left_ovlap, right_ovlap;
+ _overlaps[idx].matcher->get_crop_rect (left_ovlap, right_ovlap);
+
+ float left_offsetx = _overlaps[idx].matcher->get_current_left_offset_x ();
+ Factor left_factor, right_factor;
+
+ uint32_t left_idx = idx;
+ float center_x = (float) _stitcher->get_center (left_idx).slice_center_x;
+ float feature_center_x = (float)left_ovlap.pos_x + (left_ovlap.width / 2.0f);
+ float range = feature_center_x - center_x;
+ XCAM_ASSERT (range > 1.0f);
+ right_factor.x = (range + left_offsetx / 2.0f) / range;
+ right_factor.y = 1.0f;
+ XCAM_ASSERT (right_factor.x > 0.0f && right_factor.x < 2.0f);
+
+ uint32_t right_idx = (idx + 1) % _stitcher->get_camera_num ();
+ center_x = (float) _stitcher->get_center (right_idx).slice_center_x;
+ feature_center_x = (float)right_ovlap.pos_x + (right_ovlap.width / 2.0f);
+ range = center_x - feature_center_x;
+ XCAM_ASSERT (range > 1.0f);
+ left_factor.x = (range + left_offsetx / 2.0f) / range;
+ left_factor.y = 1.0f;
+ XCAM_ASSERT (left_factor.x > 0.0f && left_factor.x < 2.0f);
+
+ _fisheye[left_idx].right_match_factor = right_factor;
+ _fisheye[right_idx].left_match_factor = left_factor;
+
+ return XCAM_RETURN_NO_ERROR;
+#else
+ XCAM_LOG_ERROR ("gl-stitcher(%s) feature match is unsupported", XCAM_STR (_stitcher->get_name ()));
+ return XCAM_RETURN_ERROR_PARAM;
+#endif
+}
+
+SmartPtr<BlenderParam>
+Overlap::find_blender_param_in_map (
+ const SmartPtr<GLStitcher::StitcherParam> &key, uint32_t idx)
+{
+ SmartPtr<BlenderParam> param;
+ BlenderParams::iterator i = param_map.find (key.ptr ());
+ if (i == param_map.end ()) {
+ param = new BlenderParam (idx, NULL, NULL, NULL);
+ XCAM_ASSERT (param.ptr ());
+ param->stitch_param = key;
+ param_map.insert (std::make_pair ((void*)key.ptr (), param));
+ } else {
+ param = (*i).second;
+ }
+
+ return param;
+}
+
+XCamReturn
+StitcherImpl::start_single_blender (
+ uint32_t idx, const SmartPtr<BlenderParam> &param)
+{
+ SmartPtr<GLBlender> blender = _overlaps[idx].blender;
+ const Stitcher::ImageOverlapInfo &overlap_info = _stitcher->get_overlap (idx);
+ uint32_t out_width, out_height;
+ _stitcher->get_output_size (out_width, out_height);
+
+ blender->set_output_size (out_width, out_height);
+ blender->set_merge_window (overlap_info.out_area);
+ blender->set_input_valid_area (overlap_info.left, 0);
+ blender->set_input_valid_area (overlap_info.right, 1);
+ blender->set_input_merge_area (overlap_info.left, 0);
+ blender->set_input_merge_area (overlap_info.right, 1);
+
+ return blender->execute_buffer (param, false);
+}
+
+XCamReturn
+StitcherImpl::start_blenders (
+ const SmartPtr<GLStitcher::StitcherParam> &param,
+ uint32_t idx, const SmartPtr<VideoBuffer> &buf)
+{
+ SmartPtr<BlenderParam> cur_param, prev_param;
+ const uint32_t camera_num = _stitcher->get_camera_num ();
+ uint32_t pre_idx = (idx + camera_num - 1) % camera_num;
+
+ SmartPtr<BlenderParam> param_tmp = _overlaps[idx].find_blender_param_in_map (param, idx);
+ param_tmp->in_buf = buf;
+ if (param_tmp->in_buf.ptr () && param_tmp->in1_buf.ptr ()) {
+ cur_param = param_tmp;
+ _overlaps[idx].param_map.erase (param.ptr ());
+ }
+
+ param_tmp = _overlaps[pre_idx].find_blender_param_in_map (param, pre_idx);
+ param_tmp->in1_buf = buf;
+ if (param_tmp->in_buf.ptr () && param_tmp->in1_buf.ptr ()) {
+ prev_param = param_tmp;
+ _overlaps[pre_idx].param_map.erase (param.ptr ());
+ }
+
+ if (cur_param.ptr ()) {
+ cur_param->out_buf = param->out_buf;
+ XCamReturn ret = start_single_blender (idx, cur_param);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "gl-stitcher(%s) blend overlap idx:%d failed", XCAM_STR (_stitcher->get_name ()), idx);
+ }
+
+ if (prev_param.ptr ()) {
+ prev_param->out_buf = param->out_buf;
+ XCamReturn ret = start_single_blender (pre_idx, prev_param);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "gl-stitcher(%s) blend overlap idx:%d failed", XCAM_STR (_stitcher->get_name ()), pre_idx);
+ }
+
+#if HAVE_OPENCV
+ if (_stitcher->get_fm_mode ()) {
+ if (cur_param.ptr ()) {
+ XCamReturn ret = start_feature_match (cur_param->in_buf, cur_param->in1_buf, idx);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "gl-stitcher(%s) feature-match overlap idx:%d failed", XCAM_STR (_stitcher->get_name ()), idx);
+ }
+
+ if (prev_param.ptr ()) {
+ XCamReturn ret = start_feature_match (prev_param->in_buf, prev_param->in1_buf, pre_idx);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "gl-stitcher(%s) feature-match overlap idx:%d failed", XCAM_STR (_stitcher->get_name ()), pre_idx);
+ }
+ }
+#endif
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+StitcherImpl::start_copier (
+ const SmartPtr<GLStitcher::StitcherParam> &param,
+ uint32_t idx, const SmartPtr<VideoBuffer> &buf)
+{
+ XCAM_ASSERT (param.ptr ());
+ XCAM_ASSERT (buf.ptr ());
+
+ uint32_t size = _stitcher->get_copy_area ().size ();
+ XCAM_FAIL_RETURN (
+ ERROR, idx <= size, XCAM_RETURN_ERROR_PARAM,
+ "gl-stitcher(%s) invalid idx:%d", XCAM_STR (_stitcher->get_name ()), idx);
+
+ for (uint32_t i = 0; i < size; ++i) {
+ if(_copiers[i]->get_index () != idx)
+ continue;
+
+ SmartPtr<HandlerParam> copy_params = new HandlerParam (i);
+ copy_params->in_buf = buf;
+ copy_params->out_buf = param->out_buf;
+ copy_params->stitch_param = param;
+
+ XCamReturn ret = _copiers[i]->execute_buffer (copy_params, false);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "gl-stitcher(%s) execute copier failed, i:%d idx:%d",
+ XCAM_STR (_stitcher->get_name ()), i, idx);
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+StitcherImpl::stop ()
+{
+ uint32_t cam_num = _stitcher->get_camera_num ();
+ for (uint32_t i = 0; i < cam_num; ++i) {
+ if (_fisheye[i].dewarp.ptr ()) {
+ _fisheye[i].dewarp->terminate ();
+ _fisheye[i].dewarp.release ();
+ }
+ if (_fisheye[i].buf_pool.ptr ()) {
+ _fisheye[i].buf_pool->stop ();
+ }
+
+ if (_overlaps[i].blender.ptr ()) {
+ _overlaps[i].blender->terminate ();
+ _overlaps[i].blender.release ();
+ }
+ }
+
+ for (Copiers::iterator i_copier = _copiers.begin (); i_copier != _copiers.end (); ++i_copier) {
+ SmartPtr<GLCopyHandler> &copier = *i_copier;
+ if (copier.ptr ()) {
+ copier->terminate ();
+ copier.release ();
+ }
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+};
+
+GLStitcher::GLStitcher (const char *name)
+ : GLImageHandler (name)
+ , Stitcher (GL_STITCHER_ALIGNMENT_X, GL_STITCHER_ALIGNMENT_X)
+{
+ SmartPtr<GLSitcherPriv::StitcherImpl> impl = new GLSitcherPriv::StitcherImpl (this);
+ XCAM_ASSERT (impl.ptr ());
+ _impl = impl;
+}
+
+GLStitcher::~GLStitcher ()
+{
+}
+
+XCamReturn
+GLStitcher::terminate ()
+{
+ _impl->stop ();
+ return GLImageHandler::terminate ();
+}
+
+XCamReturn
+GLStitcher::stitch_buffers (const VideoBufferList &in_bufs, SmartPtr<VideoBuffer> &out_buf)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, !in_bufs.empty (), XCAM_RETURN_ERROR_PARAM,
+ "gl-stitcher(%s) stitch buffer failed, input buffers is empty", XCAM_STR (get_name ()));
+
+ SmartPtr<StitcherParam> param = new StitcherParam;
+ XCAM_ASSERT (param.ptr ());
+ param->out_buf = out_buf;
+
+ uint32_t count = 0;
+ for (VideoBufferList::const_iterator iter = in_bufs.begin(); iter != in_bufs.end (); ++iter) {
+ SmartPtr<VideoBuffer> buf = *iter;
+ XCAM_ASSERT (buf.ptr ());
+ param->in_bufs[count++] = buf;
+ }
+ param->in_buf_num = count;
+
+ XCamReturn ret = execute_buffer (param, false);
+ if (!out_buf.ptr () && xcam_ret_is_ok (ret)) {
+ out_buf = param->out_buf;
+ }
+
+ return ret;
+}
+
+XCamReturn
+GLStitcher::configure_resource (const SmartPtr<Parameters> &param)
+{
+ XCAM_UNUSED (param);
+ XCAM_ASSERT (_impl.ptr ());
+
+ XCamReturn ret = estimate_round_slices ();
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "gl-stitcher(%s) estimate round view slices failed", XCAM_STR (get_name ()));
+
+ ret = estimate_coarse_crops ();
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "gl-stitcher(%s) estimate coarse crops failed", XCAM_STR (get_name ()));
+
+ ret = mark_centers ();
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "gl-stitcher(%s) mark centers failed", XCAM_STR (get_name ()));
+
+ ret = estimate_overlap ();
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "gl-stitcher(%s) estimake coarse overlap failed", XCAM_STR (get_name ()));
+
+ ret = update_copy_areas ();
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "gl-stitcher(%s) update copy areas failed", XCAM_STR (get_name ()));
+
+ uint32_t camera_count = get_camera_num ();
+ ret = _impl->init_config (camera_count);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "gl-stitcher(%s) initialize private config failed", XCAM_STR (get_name ()));
+
+ ret = _impl->fisheye_dewarp_to_table ();
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "gl-stitcher(%s) fisheye_dewarp_to_table failed", XCAM_STR (get_name ()));
+
+ VideoBufferInfo out_info;
+ uint32_t out_width, out_height;
+ get_output_size (out_width, out_height);
+ XCAM_FAIL_RETURN (
+ ERROR, out_width && out_height, XCAM_RETURN_ERROR_PARAM,
+ "gl-stitcher(%s) output size was not set", XCAM_STR (get_name ()));
+
+ out_info.init (
+ V4L2_PIX_FMT_NV12, out_width, out_height,
+ XCAM_ALIGN_UP (out_width, GL_STITCHER_ALIGNMENT_X),
+ XCAM_ALIGN_UP (out_height, GL_STITCHER_ALIGNMENT_Y));
+ set_out_video_info (out_info);
+
+ return ret;
+}
+
+XCamReturn
+GLStitcher::start_work (const SmartPtr<Parameters> &base)
+{
+ XCAM_ASSERT (base.ptr ());
+
+ SmartPtr<StitcherParam> param = base.dynamic_cast_ptr<StitcherParam> ();
+ XCAM_FAIL_RETURN (
+ ERROR, param.ptr () && param->in_buf_num > 0 && param->in_bufs[0].ptr (), XCAM_RETURN_ERROR_PARAM,
+ "gl-stitcher(%s) start work failed, invalid parameters", XCAM_STR (get_name ()));
+
+ XCamReturn ret = _impl->start_dewarps (param);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), XCAM_RETURN_ERROR_PARAM,
+ "gl_stitcher(%s) start dewarps failed", XCAM_STR (get_name ()));
+
+ const SmartPtr<GLComputeProgram> prog = _impl->get_sync_prog ();
+ XCAM_ASSERT (prog.ptr ());
+ ret = prog->finish ();
+
+ return ret;
+}
+
+void
+GLStitcher::dewarp_done (
+ const SmartPtr<ImageHandler> &handler,
+ const SmartPtr<ImageHandler::Parameters> &base, const XCamReturn error)
+{
+ XCAM_UNUSED (handler);
+
+ SmartPtr<GLSitcherPriv::HandlerParam> dewarp_param = base.dynamic_cast_ptr<GLSitcherPriv::HandlerParam> ();
+ XCAM_ASSERT (dewarp_param.ptr ());
+ SmartPtr<GLStitcher::StitcherParam> param = dewarp_param->stitch_param;
+ XCAM_ASSERT (param.ptr ());
+
+ execute_done (param, error);
+
+ XCAM_LOG_DEBUG ("gl-stitcher(%s) camera(idx:%d) dewarp done", XCAM_STR (get_name ()), dewarp_param->idx);
+ dump_buf (dewarp_param->out_buf, dewarp_param->idx, "stitcher-dewarp");
+
+ XCamReturn ret = _impl->start_blenders (param, dewarp_param->idx, dewarp_param->out_buf);
+ if (!xcam_ret_is_ok (ret))
+ XCAM_LOG_ERROR ("start_blenders failed");
+
+ ret = _impl->start_copier (param, dewarp_param->idx, dewarp_param->out_buf);
+ if (!xcam_ret_is_ok (ret))
+ XCAM_LOG_ERROR ("start_copier failed");
+}
+
+void
+GLStitcher::blender_done (
+ const SmartPtr<ImageHandler> &handler,
+ const SmartPtr<ImageHandler::Parameters> &base, const XCamReturn error)
+{
+ XCAM_UNUSED (handler);
+
+ SmartPtr<GLSitcherPriv::BlenderParam> blender_param = base.dynamic_cast_ptr<GLSitcherPriv::BlenderParam> ();
+ XCAM_ASSERT (blender_param.ptr ());
+ SmartPtr<GLStitcher::StitcherParam> param = blender_param->stitch_param;
+ XCAM_ASSERT (param.ptr ());
+
+ execute_done (param, error);
+
+ XCAM_LOG_DEBUG ("gl-stitcher(%s) overlap:%d done", XCAM_STR (handler->get_name ()), blender_param->idx);
+ dump_buf (blender_param->out_buf, blender_param->idx, "stitcher-blend");
+}
+
+void
+GLStitcher::copier_done (
+ const SmartPtr<ImageHandler> &handler,
+ const SmartPtr<ImageHandler::Parameters> &base, const XCamReturn error)
+{
+ XCAM_UNUSED (handler);
+
+ SmartPtr<GLSitcherPriv::HandlerParam> copy_param = base.dynamic_cast_ptr<GLSitcherPriv::HandlerParam> ();
+ XCAM_ASSERT (copy_param.ptr ());
+ SmartPtr<GLStitcher::StitcherParam> param = copy_param->stitch_param;
+ XCAM_ASSERT (param.ptr ());
+
+ execute_done (param, error);
+
+ XCAM_LOG_DEBUG ("gl-stitcher(%s) camera(idx:%d) copy done", XCAM_STR (get_name ()), copy_param->idx);
+}
+
+SmartPtr<Stitcher>
+Stitcher::create_gl_stitcher ()
+{
+ return new GLStitcher;
+}
+
+}
diff --git a/modules/gles/gl_stitcher.h b/modules/gles/gl_stitcher.h
new file mode 100644
index 0000000..08a0406
--- /dev/null
+++ b/modules/gles/gl_stitcher.h
@@ -0,0 +1,91 @@
+/*
+ * gl_stitcher.h - GL stitcher class
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#ifndef XCAM_GL_STITCHER_H
+#define XCAM_GL_STITCHER_H
+
+#include <interface/stitcher.h>
+#include <gles/gles_std.h>
+#include <gles/gl_image_handler.h>
+
+namespace XCam {
+
+namespace GLSitcherPriv {
+class StitcherImpl;
+class CbGeoMap;
+class CbBlender;
+class CbCopier;
+};
+
+class GLStitcher
+ : public GLImageHandler
+ , public Stitcher
+{
+ friend class GLSitcherPriv::StitcherImpl;
+ friend class GLSitcherPriv::CbGeoMap;
+ friend class GLSitcherPriv::CbBlender;
+ friend class GLSitcherPriv::CbCopier;
+
+public:
+ struct StitcherParam
+ : ImageHandler::Parameters
+ {
+ uint32_t in_buf_num;
+ SmartPtr<VideoBuffer> in_bufs[XCAM_STITCH_MAX_CAMERAS];
+
+ StitcherParam ()
+ : Parameters (NULL, NULL)
+ , in_buf_num (0)
+ {}
+ };
+
+public:
+ explicit GLStitcher (const char *name = "GLStitcher");
+ ~GLStitcher ();
+
+ // derived from GLImageHandler
+ virtual XCamReturn terminate ();
+
+protected:
+ // interface derive from Stitcher
+ XCamReturn stitch_buffers (const VideoBufferList &in_bufs, SmartPtr<VideoBuffer> &out_buf);
+
+ // derived from GLImageHandler
+ XCamReturn configure_resource (const SmartPtr<Parameters> &param);
+ XCamReturn start_work (const SmartPtr<Parameters> &param);
+
+private:
+ void dewarp_done (
+ const SmartPtr<ImageHandler> &handler,
+ const SmartPtr<ImageHandler::Parameters> &param, const XCamReturn error);
+ void blender_done (
+ const SmartPtr<ImageHandler> &handler,
+ const SmartPtr<ImageHandler::Parameters> &param, const XCamReturn error);
+ void copier_done (
+ const SmartPtr<ImageHandler> &handler,
+ const SmartPtr<ImageHandler::Parameters> &param, const XCamReturn error);
+
+private:
+ SmartPtr<GLSitcherPriv::StitcherImpl> _impl;
+};
+
+}
+#endif // XCAM_GL_STITCHER_H \ No newline at end of file
diff --git a/modules/gles/gl_utils.cpp b/modules/gles/gl_utils.cpp
new file mode 100644
index 0000000..bafaf10
--- /dev/null
+++ b/modules/gles/gl_utils.cpp
@@ -0,0 +1,41 @@
+/*
+ * gl_utils.h - GL utilities implementation
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#include "gl_utils.h"
+
+namespace XCam {
+
+SmartPtr<GLBuffer> get_glbuffer (const SmartPtr<VideoBuffer> &buf)
+{
+ SmartPtr<GLVideoBuffer> gl_video_buf = buf.dynamic_cast_ptr<GLVideoBuffer> ();
+ XCAM_FAIL_RETURN (
+ ERROR, gl_video_buf.ptr (), NULL,
+ "convert VideoBuffer to GLVideoBuffer failed");
+
+ SmartPtr<GLBuffer> gl_buf = gl_video_buf->get_gl_buffer ();
+ XCAM_ASSERT (gl_buf.ptr ());
+ XCAM_FAIL_RETURN (
+ ERROR, gl_buf.ptr (), NULL,
+ "get GLBuffer from GLVideoBuffer failed");
+
+ return gl_buf;
+}
+
+}
diff --git a/modules/gles/gl_utils.h b/modules/gles/gl_utils.h
new file mode 100644
index 0000000..84ba093
--- /dev/null
+++ b/modules/gles/gl_utils.h
@@ -0,0 +1,32 @@
+/*
+ * gl_utils.h - GL utilities class
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#ifndef XCAM_GL_UTILS_H
+#define XCAM_GL_UTILS_H
+
+#include <gles/gl_video_buffer.h>
+
+namespace XCam {
+
+SmartPtr<GLBuffer> get_glbuffer (const SmartPtr<VideoBuffer> &buf);
+
+}
+
+#endif // XCAM_GL_UTILS_H \ No newline at end of file
diff --git a/modules/gles/gl_video_buffer.cpp b/modules/gles/gl_video_buffer.cpp
new file mode 100644
index 0000000..9029e72
--- /dev/null
+++ b/modules/gles/gl_video_buffer.cpp
@@ -0,0 +1,160 @@
+/*
+ * gl_video_buffer.cpp - GL video buffer implementation
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#include "gl_video_buffer.h"
+
+namespace XCam {
+
+class GLVideoBufferData
+ : public BufferData
+{
+public:
+ explicit GLVideoBufferData (SmartPtr<GLBuffer> &body);
+ ~GLVideoBufferData ();
+
+ virtual uint8_t *map ();
+ virtual bool unmap ();
+
+ SmartPtr<GLBuffer> &get_buf () {
+ return _buf;
+ }
+
+private:
+ uint8_t *_buf_ptr;
+ SmartPtr<GLBuffer> _buf;
+};
+
+GLVideoBufferData::GLVideoBufferData (SmartPtr<GLBuffer> &body)
+ : _buf_ptr (NULL)
+ , _buf (body)
+{
+ XCAM_ASSERT (body.ptr ());
+}
+
+GLVideoBufferData::~GLVideoBufferData ()
+{
+ unmap ();
+ _buf.release ();
+}
+
+uint8_t *
+GLVideoBufferData::map ()
+{
+ if (_buf_ptr)
+ return _buf_ptr;
+
+ uint32_t size = _buf->get_size ();
+ _buf_ptr = (uint8_t *) _buf->map_range (0, size, GL_MAP_READ_BIT | GL_MAP_WRITE_BIT);
+ XCAM_FAIL_RETURN (ERROR, _buf_ptr, NULL, "GLVideoBufferData map data failed");
+
+ return _buf_ptr;
+}
+
+bool
+GLVideoBufferData::unmap ()
+{
+ if (!_buf_ptr)
+ return true;
+
+ XCamReturn ret = _buf->unmap ();
+ XCAM_FAIL_RETURN (
+ ERROR, ret == XCAM_RETURN_NO_ERROR, false,
+ "GLVideoBufferData unmap data failed");
+
+ _buf_ptr = NULL;
+ return true;
+}
+
+GLVideoBuffer::GLVideoBuffer (const VideoBufferInfo &info, const SmartPtr<BufferData> &data)
+ : BufferProxy (info, data)
+{
+}
+
+SmartPtr<GLBuffer>
+GLVideoBuffer::get_gl_buffer ()
+{
+ SmartPtr<BufferData> data = get_buffer_data ();
+ SmartPtr<GLVideoBufferData> gl_data = data.dynamic_cast_ptr<GLVideoBufferData> ();
+ XCAM_FAIL_RETURN (
+ WARNING, gl_data.ptr (), NULL,
+ "GLVideoBuffer get_buffer_data failed with NULL");
+
+ return gl_data->get_buf ();
+}
+
+GLVideoBufferPool::GLVideoBufferPool ()
+ : _target (GL_SHADER_STORAGE_BUFFER)
+{
+}
+
+GLVideoBufferPool::GLVideoBufferPool (const VideoBufferInfo &info, GLenum target)
+ : _target (target)
+{
+ set_video_info (info);
+}
+
+GLVideoBufferPool::~GLVideoBufferPool ()
+{
+}
+
+SmartPtr<BufferData>
+GLVideoBufferPool::allocate_data (const VideoBufferInfo &info)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, info.format == V4L2_PIX_FMT_NV12, NULL,
+ "GLVideoBufferPool unsupported format:%s, try NV12",
+ xcam_fourcc_to_string (info.format));
+
+ SmartPtr<GLBuffer> buf =
+ XCam::GLBuffer::create_buffer (_target, NULL, info.size, GL_STATIC_DRAW);
+ XCAM_ASSERT (buf.ptr ());
+
+ GLBufferDesc desc;
+ desc.format = info.format;
+ desc.width = info.width;
+ desc.height = info.height;
+ desc.aligned_width = info.aligned_width;
+ desc.aligned_height = info.aligned_height;
+ desc.size = info.size;
+ desc.strides[0] = info.strides[0];
+ desc.strides[1] = info.strides[1];
+ desc.offsets[0] = info.offsets[0];
+ desc.offsets[1] = info.offsets[1];
+ desc.slice_size[0] = info.strides [0] * info.aligned_height;
+ desc.slice_size[1] = info.size - info.offsets[1];
+
+ buf->set_buffer_desc (desc);
+
+ return new GLVideoBufferData (buf);
+}
+
+SmartPtr<BufferProxy>
+GLVideoBufferPool::create_buffer_from_data (SmartPtr<BufferData> &data)
+{
+ XCAM_ASSERT (data.ptr ());
+
+ const VideoBufferInfo &info = get_video_info ();
+ SmartPtr<GLVideoBuffer> buf = new GLVideoBuffer (info, data);
+ XCAM_ASSERT (buf.ptr ());
+
+ return buf;
+}
+
+};
diff --git a/modules/gles/gl_video_buffer.h b/modules/gles/gl_video_buffer.h
new file mode 100644
index 0000000..0cc227b
--- /dev/null
+++ b/modules/gles/gl_video_buffer.h
@@ -0,0 +1,63 @@
+/*
+ * gl_video_buffer.h - GL video buffer class
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#ifndef XCAM_GL_VIDEO_BUFFER_H
+#define XCAM_GL_VIDEO_BUFFER_H
+
+#include <buffer_pool.h>
+#include <gles/gl_buffer.h>
+
+namespace XCam {
+
+class GLVideoBuffer
+ : public BufferProxy
+{
+ friend class GLVideoBufferPool;
+
+public:
+ virtual ~GLVideoBuffer () {}
+ SmartPtr<GLBuffer> get_gl_buffer ();
+
+protected:
+ explicit GLVideoBuffer (const VideoBufferInfo &info, const SmartPtr<BufferData> &data);
+};
+
+class GLVideoBufferPool
+ : public BufferPool
+{
+public:
+ explicit GLVideoBufferPool ();
+ explicit GLVideoBufferPool (const VideoBufferInfo &info, GLenum target = GL_SHADER_STORAGE_BUFFER);
+ virtual ~GLVideoBufferPool ();
+
+ void set_binding_target (GLenum target) {
+ _target = target;
+ }
+
+private:
+ virtual SmartPtr<BufferData> allocate_data (const VideoBufferInfo &info);
+ virtual SmartPtr<BufferProxy> create_buffer_from_data (SmartPtr<BufferData> &data);
+
+private:
+ GLenum _target;
+};
+
+};
+#endif // XCAM_GL_VIDEO_BUFFER_H \ No newline at end of file
diff --git a/modules/gles/gles_std.cpp b/modules/gles/gles_std.cpp
new file mode 100644
index 0000000..03ed14a
--- /dev/null
+++ b/modules/gles/gles_std.cpp
@@ -0,0 +1,58 @@
+/*
+ * gles_std.cpp - GLES std
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "gles_std.h"
+
+namespace XCam {
+
+const char *
+gl_error_string (GLenum flag)
+{
+ static char str[XCAM_GL_NAME_LENGTH] = {'\0'};
+
+ switch (flag)
+ {
+ case GL_NO_ERROR:
+ snprintf (str, sizeof (str), "0x%04x:%s", flag, "GL_NO_ERROR");
+ break;
+ case GL_INVALID_ENUM:
+ snprintf (str, sizeof (str), "0x%04x:%s", flag, "GL_INVALID_ENUM");
+ break;
+ case GL_INVALID_VALUE:
+ snprintf (str, sizeof (str), "0x%04x:%s", flag, "GL_INVALID_VALUE");
+ break;
+ case GL_INVALID_OPERATION:
+ snprintf (str, sizeof (str), "0x%04x:%s", flag, "GL_INVALID_OPERATION");
+ break;
+ case GL_INVALID_FRAMEBUFFER_OPERATION:
+ snprintf (str, sizeof (str), "0x%04x:%s", flag, "GL_INVALID_FRAMEBUFFER_OPERATION");
+ break;
+ case GL_OUT_OF_MEMORY:
+ snprintf (str, sizeof (str), "0x%04x:%s", flag, "GL_OUT_OF_MEMORY");
+ break;
+ default:
+ snprintf (str, sizeof (str), "unknown flag:0x%04x", flag);
+ XCAM_LOG_ERROR ("%s", str);
+ }
+
+ return str;
+}
+
+}
diff --git a/modules/gles/gles_std.h b/modules/gles/gles_std.h
new file mode 100644
index 0000000..bad9483
--- /dev/null
+++ b/modules/gles/gles_std.h
@@ -0,0 +1,48 @@
+/*
+ * gles_std.h - GLES std
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_GLES_STD_H
+#define XCAM_GLES_STD_H
+
+#include <xcam_std.h>
+#include <smartptr.h>
+#include <GLES3/gl3.h>
+
+#if HAVE_GLES_32
+#include <GLES3/gl32.h>
+#else
+#include <GLES3/gl31.h>
+#endif
+
+#define XCAM_GL_NAME_LENGTH 64
+#define XCAM_GL_RESERVED_BUF_COUNT 4
+
+namespace XCam {
+
+inline GLenum gl_error ()
+{
+ return glGetError ();
+}
+
+const char *gl_error_string (GLenum flag);
+
+}
+
+#endif // XCAM_GLES_STD_H
diff --git a/modules/isp/Makefile.am b/modules/isp/Makefile.am
index 9ad978c..0cee211 100644
--- a/modules/isp/Makefile.am
+++ b/modules/isp/Makefile.am
@@ -1,81 +1,70 @@
lib_LTLIBRARIES = libxcam_isp.la
-XCAMISP_CXXFLAGS = $(XCAM_CXXFLAGS)
+XCAMISP_CXXFLAGS = \
+ $(XCAM_CXXFLAGS) \
+ $(IA_IMAGING_CFLAGS) \
+ -I$(top_srcdir)/xcore \
+ -I$(top_srcdir)/modules/isp \
+ $(NULL)
+
XCAMISP_LIBS = \
+ $(IA_IMAGING_LIBS) \
+ $(top_builddir)/xcore/libxcam_core.la \
$(NULL)
if USE_LOCAL_ATOMISP
XCAMISP_CXXFLAGS += \
- -I$(top_srcdir)/ext/atomisp \
+ -I$(top_srcdir)/ext/atomisp \
$(NULL)
endif
-if ENABLE_IA_AIQ
-XCAMISP_CXXFLAGS += \
- $(IA_IMAGING_CFLAGS) \
- $(NULL)
-
+if HAVE_LIBDRM
+XCAMISP_CXXFLAGS += $(LIBDRM_CFLAGS)
XCAMISP_LIBS += \
- $(IA_IMAGING_LIBS) \
+ -ldrm_intel \
+ $(LIBDRM_LIBS) \
$(NULL)
endif
xcam_isp_sources = \
- aiq3a_utils.cpp \
- atomisp_device.cpp \
- isp_poll_thread.cpp \
- isp_image_processor.cpp \
- isp_controller.cpp \
- isp_config_translator.cpp \
- x3a_isp_config.cpp \
- sensor_descriptor.cpp \
- iq/x3a_analyze_tuner.cpp \
- iq/x3a_ciq_tuning_handler.cpp \
- iq/x3a_ciq_tnr_tuning_handler.cpp \
- iq/x3a_ciq_bnr_ee_tuning_handler.cpp \
- iq/x3a_ciq_wavelet_tuning_handler.cpp \
- x3a_statistics_queue.cpp \
- libtbd.c \
- xcam_cpf_reader.c \
- $(NULL)
-
-if ENABLE_IA_AIQ
-xcam_isp_sources += \
- aiq_handler.cpp \
- hybrid_analyzer.cpp \
- hybrid_analyzer_loader.cpp \
- x3a_analyzer_aiq.cpp \
+ aiq3a_utils.cpp \
+ atomisp_device.cpp \
+ isp_poll_thread.cpp \
+ isp_image_processor.cpp \
+ isp_controller.cpp \
+ isp_config_translator.cpp \
+ x3a_isp_config.cpp \
+ sensor_descriptor.cpp \
+ iq/x3a_analyze_tuner.cpp \
+ iq/x3a_ciq_tuning_handler.cpp \
+ iq/x3a_ciq_tnr_tuning_handler.cpp \
+ iq/x3a_ciq_bnr_ee_tuning_handler.cpp \
+ iq/x3a_ciq_wavelet_tuning_handler.cpp \
+ x3a_statistics_queue.cpp \
+ aiq_handler.cpp \
+ hybrid_analyzer.cpp \
+ hybrid_analyzer_loader.cpp \
+ x3a_analyzer_aiq.cpp \
+ libtbd.c \
+ xcam_cpf_reader.c \
$(NULL)
-endif
-
-if HAVE_LIBDRM
-XCAMISP_CXXFLAGS += $(LIBDRM_CFLAGS)
-XCAMISP_LIBS += \
- -ldrm_intel \
- $(LIBDRM_LIBS) \
- $(NULL)
-endif
libxcam_isp_la_SOURCES = \
- $(xcam_isp_sources) \
+ $(xcam_isp_sources) \
$(NULL)
libxcam_isp_la_CXXFLAGS = \
- $(XCAMISP_CXXFLAGS) \
- -I$(top_srcdir)/xcore \
- -I$(top_srcdir)/modules/isp \
+ $(XCAMISP_CXXFLAGS) \
$(NULL)
libxcam_isp_la_CFLAGS = $(libxcam_isp_la_CXXFLAGS)
libxcam_isp_la_LIBADD = \
- $(top_builddir)/xcore/libxcam_core.la \
- $(XCAMISP_LIBS) \
+ $(XCAMISP_LIBS) \
$(NULL)
libxcam_isp_la_LDFLAGS = \
- $(XCAM_LT_LDFLAGS) \
- $(PTHREAD_LDFLAGS) \
+ $(XCAM_LT_LDFLAGS) \
$(NULL)
libxcam_isp_la_LIBTOOLFLAGS = --tag=disable-static
diff --git a/modules/isp/aiq_handler.cpp b/modules/isp/aiq_handler.cpp
index 3a4d89b..d186532 100644
--- a/modules/isp/aiq_handler.cpp
+++ b/modules/isp/aiq_handler.cpp
@@ -1526,8 +1526,9 @@ AiqCompositor::limit_nr_levels (struct atomisp_parameters *isp_param)
isp_param->tnr_config->threshold_y = 0;
isp_param->tnr_config->threshold_uv = 0;
}
+
+ XCAM_LOG_DEBUG ("set TNR gain:%u", isp_param->tnr_config->gain);
}
- XCAM_LOG_DEBUG ("set TNR gain:%u", isp_param->tnr_config->gain);
}
return XCAM_RETURN_NO_ERROR;
diff --git a/modules/isp/hybrid_analyzer.cpp b/modules/isp/hybrid_analyzer.cpp
index 9e0a0f6..4a936b3 100644
--- a/modules/isp/hybrid_analyzer.cpp
+++ b/modules/isp/hybrid_analyzer.cpp
@@ -79,8 +79,9 @@ HybridAnalyzer::setup_stats_pool (const XCam3AStats *stats)
grid_info.deci_factor_log2 = log2 (grid_info.bqs_per_grid_cell);
grid_info.elem_bit_depth = stats_info.bit_depth;
- _stats_pool = new X3aStatisticsQueue;
- XCAM_ASSERT (_stats_pool.ptr ());
+ SmartPtr<X3aStatisticsQueue> stats_pool = new X3aStatisticsQueue;
+ XCAM_ASSERT (stats_pool.ptr ());
+ _stats_pool = stats_pool;
_stats_pool->set_grid_info (grid_info);
if (!_stats_pool->reserve (6)) {
diff --git a/modules/isp/isp_poll_thread.cpp b/modules/isp/isp_poll_thread.cpp
index 754452e..722a0b2 100644
--- a/modules/isp/isp_poll_thread.cpp
+++ b/modules/isp/isp_poll_thread.cpp
@@ -50,7 +50,9 @@ IspPollThread::set_isp_controller (SmartPtr<IspController> &isp)
XCamReturn
IspPollThread::start ()
{
- _3a_stats_pool = new X3aStatisticsQueue;
+ SmartPtr<X3aStatsPool> stats_pool = new X3aStatisticsQueue;
+ XCAM_ASSERT (stats_pool.ptr ());
+ _3a_stats_pool = stats_pool;
return PollThread::start ();
}
diff --git a/modules/ocl/Makefile.am b/modules/ocl/Makefile.am
index dc09d6d..5d727e6 100644
--- a/modules/ocl/Makefile.am
+++ b/modules/ocl/Makefile.am
@@ -1,109 +1,99 @@
lib_LTLIBRARIES = libxcam_ocl.la
-XCAMOCL_CXXFLAGS = $(XCAM_CXXFLAGS)
-XCAMOCL_LIBS = -ldl \
- $(NULL)
-
-XCAMOCL_CXXFLAGS += \
+XCAMOCL_CXXFLAGS = \
+ $(XCAM_CXXFLAGS) \
$(LIBCL_CFLAGS) \
-I$(top_srcdir)/xcore \
-I$(top_srcdir)/modules \
- -I$(top_builddir)/clx_kernel \
+ -I$(top_builddir)/shaders/clx \
+ $(NULL)
+
+XCAMOCL_LIBS = \
+ $(LIBCL_LIBS) -ldl \
+ $(top_builddir)/xcore/libxcam_core.la \
$(NULL)
+if HAVE_OPENCV
+XCAMOCL_CXXFLAGS += $(OPENCV_CFLAGS)
XCAMOCL_LIBS += \
- $(LIBCL_LIBS) \
+ $(OPENCV_LIBS) \
+ $(top_builddir)/modules/ocv/libxcam_ocv.la \
$(NULL)
+endif
if HAVE_LIBDRM
XCAMOCL_CXXFLAGS += $(LIBDRM_CFLAGS)
XCAMOCL_LIBS += \
- -ldrm_intel \
- $(LIBDRM_LIBS) \
+ -ldrm_intel \
+ $(LIBDRM_LIBS) \
$(NULL)
endif
-if HAVE_OPENCV
-XCAMOCL_CXXFLAGS += $(OPENCV_CFLAGS)
-XCAMOCL_LIBS += $(OPENCV_LIBS)
-endif
-
xcam_ocl_sources = \
- cl_argument.cpp \
- cl_context.cpp \
- cl_device.cpp \
- cl_kernel.cpp \
- cl_memory.cpp \
- cl_event.cpp \
- cl_utils.cpp \
- cl_image_handler.cpp \
- cl_image_processor.cpp \
- cl_3a_image_processor.cpp \
- cl_post_image_processor.cpp \
- cl_multi_image_handler.cpp \
- cl_csc_image_processor.cpp \
- cl_3a_stats_context.cpp \
- cl_demo_handler.cpp \
- cl_blender.cpp \
- cl_pyramid_blender.cpp \
- cl_geo_map_handler.cpp \
- cl_csc_handler.cpp \
- cl_tnr_handler.cpp \
- cl_defog_dcp_handler.cpp \
- cl_bayer_pipe_handler.cpp \
- cl_bayer_basic_handler.cpp \
- cl_yuv_pipe_handler.cpp \
- cl_rgb_pipe_handler.cpp \
- cl_tonemapping_handler.cpp \
- cl_newtonemapping_handler.cpp \
- cl_fisheye_handler.cpp \
- cl_image_scaler.cpp \
- cl_image_360_stitch.cpp \
- cl_retinex_handler.cpp \
- cl_gauss_handler.cpp \
- cl_wavelet_denoise_handler.cpp \
- cl_newwavelet_denoise_handler.cpp \
- cl_wire_frame_handler.cpp \
- cl_3d_denoise_handler.cpp \
- cl_image_warp_handler.cpp \
- cl_video_stabilizer.cpp \
- cl_video_buffer.cpp \
- priority_buffer_queue.cpp \
+ cl_argument.cpp \
+ cl_context.cpp \
+ cl_device.cpp \
+ cl_kernel.cpp \
+ cl_memory.cpp \
+ cl_event.cpp \
+ cl_utils.cpp \
+ cl_image_handler.cpp \
+ cl_image_processor.cpp \
+ cl_3a_image_processor.cpp \
+ cl_post_image_processor.cpp \
+ cl_multi_image_handler.cpp \
+ cl_csc_image_processor.cpp \
+ cl_3a_stats_context.cpp \
+ cl_demo_handler.cpp \
+ cl_blender.cpp \
+ cl_pyramid_blender.cpp \
+ cl_geo_map_handler.cpp \
+ cl_csc_handler.cpp \
+ cl_tnr_handler.cpp \
+ cl_defog_dcp_handler.cpp \
+ cl_bayer_pipe_handler.cpp \
+ cl_bayer_basic_handler.cpp \
+ cl_yuv_pipe_handler.cpp \
+ cl_rgb_pipe_handler.cpp \
+ cl_tonemapping_handler.cpp \
+ cl_newtonemapping_handler.cpp \
+ cl_fisheye_handler.cpp \
+ cl_image_scaler.cpp \
+ cl_image_360_stitch.cpp \
+ cl_retinex_handler.cpp \
+ cl_gauss_handler.cpp \
+ cl_wavelet_denoise_handler.cpp \
+ cl_newwavelet_denoise_handler.cpp \
+ cl_wire_frame_handler.cpp \
+ cl_3d_denoise_handler.cpp \
+ cl_image_warp_handler.cpp \
+ cl_video_stabilizer.cpp \
+ cl_video_buffer.cpp \
+ priority_buffer_queue.cpp \
$(NULL)
-if HAVE_OPENCV
-xcam_ocl_sources += cv_context.cpp
-xcam_ocl_sources += cv_base_class.cpp
-xcam_ocl_sources += cv_image_process_helper.cpp
-xcam_ocl_sources += cv_image_sharp.cpp
-xcam_ocl_sources += cv_edgetaper.cpp
-xcam_ocl_sources += cv_wiener_filter.cpp
-xcam_ocl_sources += cv_feature_match.cpp
-xcam_ocl_sources += cv_image_deblurring.cpp
-endif
-
if HAVE_LIBDRM
-xcam_ocl_sources += intel/cl_intel_context.cpp
-xcam_ocl_sources += intel/cl_va_memory.cpp
-xcam_ocl_sources += cl_image_bo_buffer.cpp
+xcam_ocl_sources += \
+ intel/cl_intel_context.cpp \
+ intel/cl_va_memory.cpp \
+ cl_image_bo_buffer.cpp \
+ $(NULL)
endif
libxcam_ocl_la_SOURCES = \
- $(xcam_ocl_sources) \
+ $(xcam_ocl_sources) \
$(NULL)
libxcam_ocl_la_CXXFLAGS = \
- $(XCAMOCL_CXXFLAGS) \
+ $(XCAMOCL_CXXFLAGS) \
$(NULL)
libxcam_ocl_la_LIBADD = \
- $(top_builddir)/xcore/libxcam_core.la \
- $(XCAMOCL_LIBS) \
+ $(XCAMOCL_LIBS) \
$(NULL)
libxcam_ocl_la_LDFLAGS = \
$(XCAM_LT_LDFLAGS) \
- $(PTHREAD_LDFLAGS) \
$(NULL)
libxcam_oclincludedir = $(includedir)/xcam/ocl
@@ -150,26 +140,16 @@ nobase_libxcam_oclinclude_HEADERS = \
cl_video_buffer.h \
$(NULL)
-if HAVE_OPENCV
-nobase_libxcam_oclinclude_HEADERS += cv_context.h
-nobase_libxcam_oclinclude_HEADERS += cv_base_class.h
-nobase_libxcam_oclinclude_HEADERS += cv_image_process_helper.h
-nobase_libxcam_oclinclude_HEADERS += cv_image_sharp.h
-nobase_libxcam_oclinclude_HEADERS += cv_edgetaper.h
-nobase_libxcam_oclinclude_HEADERS += cv_wiener_filter.h
-nobase_libxcam_oclinclude_HEADERS += cv_feature_match.h
-nobase_libxcam_oclinclude_HEADERS += cv_image_deblurring.h
-endif
-
if HAVE_LIBDRM
-nobase_libxcam_oclinclude_HEADERS += intel/cl_intel_context.h
-nobase_libxcam_oclinclude_HEADERS += intel/cl_va_memory.h
-nobase_libxcam_oclinclude_HEADERS += cl_image_bo_buffer.h
+nobase_libxcam_oclinclude_HEADERS += \
+ intel/cl_intel_context.h \
+ intel/cl_va_memory.h \
+ cl_image_bo_buffer.h \
+ $(NULL)
endif
-noinst_HEADERS = \
- cl_pyramid_blender.h \
+noinst_HEADERS = \
+ cl_pyramid_blender.h \
$(NULL)
-
libxcam_ocl_la_LIBTOOLFLAGS = --tag=disable-static
diff --git a/modules/ocl/cl_3a_stats_context.cpp b/modules/ocl/cl_3a_stats_context.cpp
index 4d43e6a..fe2a07c 100644
--- a/modules/ocl/cl_3a_stats_context.cpp
+++ b/modules/ocl/cl_3a_stats_context.cpp
@@ -30,7 +30,9 @@ CL3AStatsCalculatorContext::CL3AStatsCalculatorContext (const SmartPtr<CLContext
, _factor_shift (0)
, _data_allocated (false)
{
- _stats_pool = new X3aStatsPool ();
+ SmartPtr<X3aStatsPool> pool = new X3aStatsPool ();
+ XCAM_ASSERT (pool.ptr ());
+ _stats_pool = pool;
}
CL3AStatsCalculatorContext::~CL3AStatsCalculatorContext ()
diff --git a/modules/ocl/cl_bayer_basic_handler.cpp b/modules/ocl/cl_bayer_basic_handler.cpp
index efc2536..7e33fa7 100644
--- a/modules/ocl/cl_bayer_basic_handler.cpp
+++ b/modules/ocl/cl_bayer_basic_handler.cpp
@@ -191,10 +191,13 @@ CLBayerBasicImageHandler::CLBayerBasicImageHandler (
_gamma_table[i] = (float)i / 256.0f;
_gamma_table[XCAM_GAMMA_TABLE_SIZE] = 0.9999f;
- _3a_stats_context = new CL3AStatsCalculatorContext (context);
- XCAM_ASSERT (_3a_stats_context.ptr ());
- _3a_stats_thread = new CLBayer3AStatsThread (this);
- XCAM_ASSERT (_3a_stats_thread.ptr ());
+ SmartPtr<CL3AStatsCalculatorContext> stats_context = new CL3AStatsCalculatorContext (context);
+ XCAM_ASSERT (stats_context.ptr ());
+ _3a_stats_context = stats_context;
+
+ SmartPtr<CLBayer3AStatsThread> stats_thread = new CLBayer3AStatsThread (this);
+ XCAM_ASSERT (stats_thread.ptr ());
+ _3a_stats_thread = stats_thread;
XCAM_OBJ_PROFILING_INIT;
}
diff --git a/modules/ocl/cl_defog_dcp_handler.cpp b/modules/ocl/cl_defog_dcp_handler.cpp
index 7300485..eeb4d78 100644
--- a/modules/ocl/cl_defog_dcp_handler.cpp
+++ b/modules/ocl/cl_defog_dcp_handler.cpp
@@ -387,6 +387,7 @@ create_kernel_dark_channel (const SmartPtr<CLContext> &context, SmartPtr<CLDefog
return kernel;
}
+#if 0
static SmartPtr<CLMinFilterKernel>
create_kernel_min_filter (
const SmartPtr<CLContext> &context,
@@ -410,6 +411,7 @@ create_kernel_min_filter (
return kernel;
}
+#endif
static SmartPtr<CLBiFilterKernel>
create_kernel_bi_filter (
diff --git a/modules/ocl/cl_fisheye_handler.cpp b/modules/ocl/cl_fisheye_handler.cpp
index a7866c5..321ac78 100644
--- a/modules/ocl/cl_fisheye_handler.cpp
+++ b/modules/ocl/cl_fisheye_handler.cpp
@@ -128,7 +128,7 @@ CLFisheye2GPSKernel::prepare_arguments (CLArgList &args, CLWorkSize &work_size)
return XCAM_RETURN_NO_ERROR;
}
-CLFisheyeHandler::CLFisheyeHandler (const SmartPtr<CLContext> &context, SurroundMode surround_mode, bool use_map, bool need_lsc)
+CLFisheyeHandler::CLFisheyeHandler (const SmartPtr<CLContext> &context, SurroundMode surround_mode, bool use_map, bool need_lsc, bool need_scale)
: CLImageHandler (context, "CLFisheyeHandler")
, _output_width (0)
, _output_height (0)
@@ -137,8 +137,12 @@ CLFisheyeHandler::CLFisheyeHandler (const SmartPtr<CLContext> &context, Surround
, _map_factor (DEFAULT_FISHEYE_TABLE_SCALE)
, _use_map (use_map)
, _need_lsc (need_lsc ? 1 : 0)
+ , _need_scale (need_scale ? 1 : 0)
, _lsc_array_size (0)
, _lsc_array (NULL)
+ , _stable_y_start (0.0f)
+ , _left_scale_factor (1.0f, 1.0f)
+ , _right_scale_factor (1.0f, 1.0f)
, _surround_mode (surround_mode)
{
xcam_mem_clear (_gray_threshold);
@@ -203,6 +207,24 @@ CLFisheyeHandler::set_lsc_gray_threshold (float min_threshold, float max_thresho
_gray_threshold[1] = max_threshold;
}
+void
+CLFisheyeHandler::set_stable_y_start (float y_start)
+{
+ _stable_y_start = y_start;
+}
+
+void
+CLFisheyeHandler::set_left_scale_factor (PointFloat2 factor)
+{
+ _left_scale_factor = factor;
+}
+
+void
+CLFisheyeHandler::set_right_scale_factor (PointFloat2 factor)
+{
+ _right_scale_factor = factor;
+}
+
XCamReturn
CLFisheyeHandler::prepare_buffer_pool_video_info (
const VideoBufferInfo &input,
@@ -585,16 +607,16 @@ create_fishey_gps_kernel (const SmartPtr<CLContext> &context, SmartPtr<CLFisheye
}
SmartPtr<CLImageHandler>
-create_fisheye_handler (const SmartPtr<CLContext> &context, SurroundMode surround_mode, bool use_map, bool need_lsc)
+create_fisheye_handler (const SmartPtr<CLContext> &context, SurroundMode surround_mode, bool use_map, bool need_lsc, bool need_scale)
{
SmartPtr<CLFisheyeHandler> handler;
SmartPtr<CLImageKernel> kernel;
- handler = new CLFisheyeHandler (context, surround_mode, use_map, need_lsc);
+ handler = new CLFisheyeHandler (context, surround_mode, use_map, need_lsc, need_scale);
XCAM_ASSERT (handler.ptr ());
if (use_map) {
- kernel = create_geo_map_kernel (context, handler, need_lsc);
+ kernel = create_geo_map_kernel (context, handler, need_lsc, need_scale);
} else {
kernel = create_fishey_gps_kernel (context, handler);
}
diff --git a/modules/ocl/cl_fisheye_handler.h b/modules/ocl/cl_fisheye_handler.h
index be7452f..a8eb7c4 100644
--- a/modules/ocl/cl_fisheye_handler.h
+++ b/modules/ocl/cl_fisheye_handler.h
@@ -49,7 +49,7 @@ class CLFisheyeHandler
{
friend class CLFisheye2GPSKernel;
public:
- explicit CLFisheyeHandler (const SmartPtr<CLContext> &context, SurroundMode surround_mode, bool use_map, bool need_lsc);
+ explicit CLFisheyeHandler (const SmartPtr<CLContext> &context, SurroundMode surround_mode, bool use_map, bool need_lsc, bool need_scale);
virtual ~CLFisheyeHandler();
void set_output_size (uint32_t width, uint32_t height);
@@ -65,9 +65,25 @@ public:
void set_lsc_table (float *table, uint32_t table_size);
void set_lsc_gray_threshold (float min_threshold, float max_threshold);
+ void set_stable_y_start (float y_start);
+ virtual float get_stable_y_start () {
+ return _stable_y_start;
+ }
+
+ void set_left_scale_factor (PointFloat2 factor);
+ void set_right_scale_factor (PointFloat2 factor);
+
+ virtual PointFloat2 get_left_scale_factor () {
+ return _left_scale_factor;
+ }
+ virtual PointFloat2 get_right_scale_factor () {
+ return _right_scale_factor;
+ }
+
void set_bowl_config(const BowlDataConfig bowl_data_config) {
_bowl_data_config = bowl_data_config;
}
+
const BowlDataConfig &get_bowl_config() {
return _bowl_data_config;
}
@@ -137,9 +153,14 @@ private:
float _map_factor;
bool _use_map;
uint32_t _need_lsc;
+ uint32_t _need_scale;
uint32_t _lsc_array_size;
float _gray_threshold[2]; // [min_gray_threshold, max_gray_threshold]
float *_lsc_array;
+ float _stable_y_start;
+
+ PointFloat2 _left_scale_factor;
+ PointFloat2 _right_scale_factor;
BowlDataConfig _bowl_data_config;
@@ -155,7 +176,7 @@ private:
};
SmartPtr<CLImageHandler>
-create_fisheye_handler (const SmartPtr<CLContext> &context, SurroundMode surround_mode = SphereView, bool use_map = false, bool need_lsc = false);
+create_fisheye_handler (const SmartPtr<CLContext> &context, SurroundMode surround_mode = SphereView, bool use_map = false, bool need_lsc = false, bool need_scale = false);
}
diff --git a/modules/ocl/cl_geo_map_handler.cpp b/modules/ocl/cl_geo_map_handler.cpp
index 8151425..abba53f 100644
--- a/modules/ocl/cl_geo_map_handler.cpp
+++ b/modules/ocl/cl_geo_map_handler.cpp
@@ -34,10 +34,11 @@ static const XCamKernelInfo kernel_geo_map_info = {
#define GEO_MAP_CHANNEL 4 /* only use channel_0, channel_1 */
CLGeoMapKernel::CLGeoMapKernel (
- const SmartPtr<CLContext> &context, const SmartPtr<GeoKernelParamCallback> handler, bool need_lsc)
+ const SmartPtr<CLContext> &context, const SmartPtr<GeoKernelParamCallback> handler, bool need_lsc, bool need_scale)
: CLImageKernel (context)
, _handler (handler)
, _need_lsc (need_lsc)
+ , _need_scale (need_scale)
{
XCAM_ASSERT (handler.ptr ());
}
@@ -62,6 +63,16 @@ CLGeoMapKernel::prepare_arguments (CLArgList &args, CLWorkSize &work_size)
args.push_back (new CLMemArgument (geo_image));
args.push_back (new CLArgumentTArray<float, 2> (geo_scale_size));
+ if (_need_scale) {
+ PointFloat2 left_scale_factor = _handler->get_left_scale_factor ();
+ PointFloat2 right_scale_factor = _handler->get_right_scale_factor ();
+ float stable_y_start = _handler->get_stable_y_start ();
+
+ args.push_back (new CLArgumentT<PointFloat2> (left_scale_factor));
+ args.push_back (new CLArgumentT<PointFloat2> (right_scale_factor));
+ args.push_back (new CLArgumentT<float> (stable_y_start));
+ }
+
if (_need_lsc) {
SmartPtr<CLImage> lsc_image = _handler->get_lsc_table ();
float *gray_threshold = _handler->get_lsc_gray_threshold ();
@@ -319,14 +330,14 @@ CLGeoMapHandler::execute_done (SmartPtr<VideoBuffer> &output)
SmartPtr<CLImageKernel>
create_geo_map_kernel (
- const SmartPtr<CLContext> &context, SmartPtr<GeoKernelParamCallback> param_cb, bool need_lsc)
+ const SmartPtr<CLContext> &context, SmartPtr<GeoKernelParamCallback> param_cb, bool need_lsc, bool need_scale)
{
SmartPtr<CLImageKernel> kernel;
- kernel = new CLGeoMapKernel (context, param_cb, need_lsc);
+ kernel = new CLGeoMapKernel (context, param_cb, need_lsc, need_scale);
XCAM_ASSERT (kernel.ptr ());
char build_options[1024];
- snprintf (build_options, sizeof(build_options), "-DENABLE_LSC=%d", need_lsc ? 1 : 0);
+ snprintf (build_options, sizeof(build_options), "-DENABLE_LSC=%d -DENABLE_SCALE=%d", need_lsc ? 1 : 0, need_scale ? 1 : 0);
XCAM_FAIL_RETURN (
ERROR, kernel->build_kernel (kernel_geo_map_info, build_options) == XCAM_RETURN_NO_ERROR,
NULL, "build geo map kernel failed");
@@ -335,7 +346,7 @@ create_geo_map_kernel (
}
SmartPtr<CLImageHandler>
-create_geo_map_handler (const SmartPtr<CLContext> &context, bool need_lsc)
+create_geo_map_handler (const SmartPtr<CLContext> &context, bool need_lsc, bool need_scale)
{
SmartPtr<CLGeoMapHandler> handler;
SmartPtr<CLImageKernel> kernel;
@@ -343,7 +354,7 @@ create_geo_map_handler (const SmartPtr<CLContext> &context, bool need_lsc)
handler = new CLGeoMapHandler (context);
XCAM_ASSERT (handler.ptr ());
- kernel = create_geo_map_kernel (context, handler, need_lsc);
+ kernel = create_geo_map_kernel (context, handler, need_lsc, need_scale);
XCAM_FAIL_RETURN (
ERROR, kernel.ptr (), NULL, "CLMapHandler build geo map kernel failed");
handler->add_kernel (kernel);
diff --git a/modules/ocl/cl_geo_map_handler.h b/modules/ocl/cl_geo_map_handler.h
index a41ad27..4a79545 100644
--- a/modules/ocl/cl_geo_map_handler.h
+++ b/modules/ocl/cl_geo_map_handler.h
@@ -52,6 +52,10 @@ protected:
virtual SmartPtr<CLImage> get_lsc_table () = 0;
virtual float* get_lsc_gray_threshold() = 0;
+ virtual PointFloat2 get_left_scale_factor () = 0;
+ virtual PointFloat2 get_right_scale_factor () = 0;
+
+ virtual float get_stable_y_start () = 0;
private:
XCAM_DEAD_COPY (GeoKernelParamCallback);
};
@@ -64,7 +68,7 @@ public:
explicit CLGeoMapKernel (
const SmartPtr<CLContext> &context,
const SmartPtr<GeoKernelParamCallback> handler,
- bool need_lsc);
+ bool need_lsc, bool need_scale);
protected:
virtual XCamReturn prepare_arguments (CLArgList &args, CLWorkSize &work_size);
@@ -72,6 +76,7 @@ protected:
private:
SmartPtr<GeoKernelParamCallback> _handler;
bool _need_lsc;
+ bool _need_scale;
};
class CLGeoMapHandler
@@ -122,6 +127,22 @@ protected:
return NULL;
}
+ virtual PointFloat2 get_left_scale_factor () {
+ XCAM_ASSERT (false && "CLGeoMapHandler::left_scale_factor is not supported");
+ return PointFloat2 (0.0f, 0.0f);
+ }
+
+ virtual PointFloat2 get_right_scale_factor () {
+ XCAM_ASSERT (false && "CLGeoMapHandler::right_scale_factor is not supported");
+ return PointFloat2 (0.0f, 0.0f);
+ }
+
+ virtual float get_stable_y_start () {
+ XCAM_ASSERT (false && "CLGeoMapHandler::get_stable_y_start is not supported");
+ return 0.0f;
+ }
+
+
protected:
virtual XCamReturn prepare_buffer_pool_video_info (
const VideoBufferInfo &input,
@@ -150,11 +171,11 @@ private:
SmartPtr<CLImageKernel>
create_geo_map_kernel (
- const SmartPtr<CLContext> &context, SmartPtr<GeoKernelParamCallback> param_cb, bool need_lsc);
+ const SmartPtr<CLContext> &context, SmartPtr<GeoKernelParamCallback> param_cb, bool need_lsc, bool need_scale);
SmartPtr<CLImageHandler>
-create_geo_map_handler (const SmartPtr<CLContext> &context, bool need_lsc = false);
+create_geo_map_handler (const SmartPtr<CLContext> &context, bool need_lsc = false, bool need_scale = false);
}
-#endif //XCAM_CL_GEO_MAP_HANDLER_H \ No newline at end of file
+#endif //XCAM_CL_GEO_MAP_HANDLER_H
diff --git a/modules/ocl/cl_image_360_stitch.cpp b/modules/ocl/cl_image_360_stitch.cpp
index ae19b27..242e1b9 100644
--- a/modules/ocl/cl_image_360_stitch.cpp
+++ b/modules/ocl/cl_image_360_stitch.cpp
@@ -19,9 +19,12 @@
*/
#include "cl_utils.h"
+#include "cl_device.h"
#include "cl_image_360_stitch.h"
#if HAVE_OPENCV
-#include "cv_feature_match.h"
+#include "ocv/cv_feature_match.h"
+#include "ocv/cv_feature_match_cluster.h"
+#include <opencv2/core/ocl.hpp>
#endif
#define XCAM_BLENDER_GLOBAL_SCALE_EXT_WIDTH 64
@@ -109,10 +112,10 @@ CLBlenderGlobalScaleKernel::get_output_info (
}
#if HAVE_OPENCV
-static CVFMConfig
-get_fm_default_config (StitchResMode res_mode)
+static FMConfig
+get_fm_sphere_config (StitchResMode res_mode)
{
- CVFMConfig config;
+ FMConfig config;
switch (res_mode) {
case StitchRes1080P: {
@@ -158,6 +161,22 @@ get_fm_default_config (StitchResMode res_mode)
return config;
}
+
+static FMConfig
+get_fm_bowl_config ()
+{
+ FMConfig config;
+ config.sitch_min_width = 136;
+ config.min_corners = 4;
+ config.offset_factor = 0.95f;
+ config.delta_mean_offset = 120.0f;
+ config.recur_offset_error = 8.0f;
+ config.max_adjusted_offset = 24.0f;
+ config.max_valid_offset_y = 20.0f;
+ config.max_track_error = 28.0f;
+
+ return config;
+}
#endif
static StitchInfo
@@ -280,17 +299,25 @@ CLImage360Stitch::CLImage360Stitch (
, _scale_mode (scale_mode)
, _surround_mode (surround_mode)
, _res_mode (res_mode)
+ , _enable_fm (true)
, _is_stitch_inited (false)
, _fisheye_num (fisheye_num)
, _all_in_one_img (all_in_one_img)
{
+#if !HAVE_OPENCV
+ _enable_fm = false;
+#endif
+}
+
+void
+CLImage360Stitch::set_feature_match (bool enable)
+{
#if HAVE_OPENCV
- for (int i = 0; i < fisheye_num; i++) {
- _feature_match[i] = new CVFeatureMatch ();
- XCAM_ASSERT (_feature_match[i].ptr ());
- _feature_match[i]->set_config (get_fm_default_config (res_mode));
- _feature_match[i]->set_fm_index (i);
- }
+ _enable_fm = enable;
+#else
+ if (enable)
+ XCAM_LOG_WARNING ("non-OpenCV mode, feature match is unsupported, disable feature match");
+ _enable_fm = false;
#endif
}
@@ -371,33 +398,6 @@ CLImage360Stitch::set_image_overlap (const int idx, const Rect &overlap0, const
}
void
-CLImage360Stitch::set_feature_match_ocl (bool fm_ocl)
-{
-#if HAVE_OPENCV
- for (int i = 0; i < _fisheye_num; i++) {
- _feature_match[i]->set_ocl (fm_ocl);
- }
-#else
- XCAM_UNUSED (fm_ocl);
- XCAM_LOG_WARNING ("non-OpenCV mode, failed to set ocl for feature match");
-#endif
-}
-
-#if HAVE_OPENCV
-void
-CLImage360Stitch::set_feature_match_config (const int idx, CVFMConfig config)
-{
- _feature_match[idx]->set_config (config);
-}
-
-CVFMConfig
-CLImage360Stitch::get_feature_match_config (const int idx)
-{
- return _feature_match[idx]->get_config ();
-}
-#endif
-
-void
CLImage360Stitch::calc_fisheye_initial_info (SmartPtr<VideoBuffer> &output)
{
const VideoBufferInfo &out_info = output->get_video_info ();
@@ -431,23 +431,15 @@ CLImage360Stitch::calc_fisheye_initial_info (SmartPtr<VideoBuffer> &output)
} else {
_fisheye[0].height = out_info.height + _stitch_info.crop[0].top + _stitch_info.crop[0].bottom;
- float view_angle[XCAM_STITCH_FISHEYE_MAX_NUM];
-
- view_angle[0] = 68.0f;
- _fisheye[0].width = view_angle[0] / 360.0f * out_info.width;
- _fisheye[0].width = XCAM_ALIGN_UP (_fisheye[0].width, 32);
-
- view_angle[1] = 152.0f;
- _fisheye[1].width = view_angle[1] / 360.0f * out_info.width;
- _fisheye[1].width = XCAM_ALIGN_UP (_fisheye[1].width, 32);
+ float view_angle[XCAM_STITCH_FISHEYE_MAX_NUM] = {
+ 64.0f, 158.0f, 60.0f, 158.0f
+ };
- view_angle[2] = 68.0f;
- _fisheye[2].width = view_angle[2] / 360.0f * out_info.width;
- _fisheye[2].width = XCAM_ALIGN_UP (_fisheye[2].width, 32);
-
- view_angle[3] = 152.0f;
- _fisheye[3].width = view_angle[3] / 360.0f * out_info.width;
- _fisheye[3].width = XCAM_ALIGN_UP (_fisheye[3].width, 32);
+ XCAM_ASSERT (_fisheye_num <= XCAM_STITCH_FISHEYE_MAX_NUM);
+ for (int i = 0; i < _fisheye_num; i++) {
+ _fisheye[i].width = view_angle[i] / 360.0f * out_info.width;
+ _fisheye[i].width = XCAM_ALIGN_UP (_fisheye[i].width, 32);
+ }
XCAM_LOG_INFO (
"fisheye correction output size width:%d height:%d",
@@ -465,13 +457,26 @@ CLImage360Stitch::calc_fisheye_initial_info (SmartPtr<VideoBuffer> &output)
bowl_data_config[i].angle_end = angle_center + view_angle[i] / 2;
}
+ float wall_image_height = bowl_data_config[0].wall_height /
+ (float)(bowl_data_config[0].wall_height + bowl_data_config[0].ground_length) *
+ _fisheye[0].height;
+ float stable_y_start = (wall_image_height + _fisheye[0].height ) / 2.0f;
+
+ if (stable_y_start < 0.5f)
+ stable_y_start = 1.0f;
+
for(int i = 0; i < _fisheye_num; i++) {
+ _fisheye[i].handler->set_stable_y_start (stable_y_start);
_fisheye[i].handler->set_bowl_config(bowl_data_config[i]);
_fisheye[i].handler->set_output_size (_fisheye[i].width, _fisheye[i].height);
}
- for(int i = 0; i < _fisheye_num; i++) {
- _stitch_info.merge_width[i] = XCAM_ALIGN_UP((uint32_t)(20.0f / 360.0f * out_info.width), 32);
+ int idx_next;
+ for (int i = 0; i < _fisheye_num; i++) {
+ idx_next = (i == (_fisheye_num - 1)) ? 0 : (i + 1);
+
+ _stitch_info.merge_width[idx_next] = _fisheye[i].width / 2 + _fisheye[idx_next].width / 2 - out_info.width / _fisheye_num;
+ _stitch_info.merge_width[idx_next] = XCAM_ALIGN_UP (_stitch_info.merge_width[idx_next], 32);
}
}
}
@@ -677,13 +682,14 @@ CLImage360Stitch::create_buffer_pool (SmartPtr<BufferPool> &buf_pool, uint32_t w
buf_info.init (V4L2_PIX_FMT_NV12, width, height,
XCAM_ALIGN_UP (width, 16), XCAM_ALIGN_UP (height, 16));
- buf_pool = new CLVideoBufferPool ();
- XCAM_ASSERT (buf_pool.ptr ());
- buf_pool->set_video_info (buf_info);
- if (!buf_pool->reserve (6)) {
+ SmartPtr<BufferPool> pool = new CLVideoBufferPool ();
+ XCAM_ASSERT (pool.ptr ());
+ pool->set_video_info (buf_info);
+ if (!pool->reserve (6)) {
XCAM_LOG_ERROR ("CLImage360Stitch init buffer pool failed");
return false;
}
+ buf_pool = pool;
return true;
}
@@ -710,12 +716,63 @@ CLImage360Stitch::reset_buffer_info (SmartPtr<VideoBuffer> &input)
return XCAM_RETURN_NO_ERROR;
}
+void
+CLImage360Stitch::init_opencv_ocl ()
+{
+#if HAVE_OPENCV
+ if (!cv::ocl::haveOpenCL ()) {
+ XCAM_LOG_ERROR ("OpenCV does not support OpenCL");
+ XCAM_ASSERT (false);
+ }
+
+ char *platform_name = CLDevice::instance()->get_platform_name ();
+ cl_platform_id platform_id = CLDevice::instance()->get_platform_id ();
+ cl_device_id device_id = CLDevice::instance()->get_device_id ();
+ cl_context context_id = _context->get_context_id ();
+ cv::ocl::attachContext (platform_name, platform_id, context_id, device_id);
+ cv::ocl::setUseOpenCL (false);
+#else
+ XCAM_LOG_ERROR ("non-OpenCV mode, failed to initialize opencv ocl");
+#endif
+}
+
+void
+CLImage360Stitch::init_feature_match ()
+{
+#if HAVE_OPENCV
+ bool is_sphere = (_surround_mode == SphereView);
+ const FMConfig &config = is_sphere ? get_fm_sphere_config (_res_mode) : get_fm_bowl_config ();
+
+ for (int i = 0; i < _fisheye_num; i++) {
+ if (is_sphere) {
+ _feature_match[i] = FeatureMatch::create_default_feature_match ();
+ _feature_match[i]->enable_adjust_crop_area ();
+ } else {
+ _feature_match[i] = FeatureMatch::create_cluster_feature_match ();
+ }
+ XCAM_ASSERT (_feature_match[i].ptr ());
+
+ _feature_match[i]->set_fm_index (i);
+ _feature_match[i]->set_config (config);
+ }
+#else
+ XCAM_LOG_ERROR ("non-OpenCV mode, failed to initialize feature match");
+#endif
+}
+
XCamReturn
CLImage360Stitch::prepare_parameters (SmartPtr<VideoBuffer> &input, SmartPtr<VideoBuffer> &output)
{
XCamReturn ret = XCAM_RETURN_NO_ERROR;
- if (!_is_stitch_inited)
+ if (!_is_stitch_inited) {
+#if HAVE_OPENCV
+ if (_enable_fm) {
+ init_opencv_ocl ();
+ init_feature_match ();
+ }
+#endif
set_stitch_info (get_default_stitch_info (_res_mode));
+ }
ret = ensure_fisheye_parameters (input, output);
STITCH_CHECK (ret, "ensure fisheye parameters failed");
@@ -768,44 +825,106 @@ CLImage360Stitch::prepare_parameters (SmartPtr<VideoBuffer> &input, SmartPtr<Vid
XCamReturn
CLImage360Stitch::execute_done (SmartPtr<VideoBuffer> &output)
{
+ get_context ()->finish ();
+ return CLMultiImageHandler::execute_done (output);
+}
+
+void
+CLImage360Stitch::update_scale_factors (uint32_t fm_idx, const Rect &crop_left, const Rect &crop_right)
+{
#if HAVE_OPENCV
- for (int i = 0; i < _fisheye_num; i++) {
- if (!_feature_match[i]->is_ocl_path ()) {
- get_context ()->finish ();
- break;
- }
- }
+ float left_offsetx = _feature_match[fm_idx]->get_current_left_offset_x ();
+ float left_offsety = _feature_match[fm_idx]->get_current_left_offset_y ();
+ PointFloat2 left_factor, right_factor;
+
+ uint32_t left_idx = fm_idx;
+ float center_x = (float) _fisheye[left_idx].width / 2;
+ float feature_center_x = (float)crop_left.pos_x + crop_left.width / 2.0f;
+ float range = feature_center_x - center_x;
+ XCAM_ASSERT (range > 1.0f);
+ right_factor.x = (range + left_offsetx / 2.0f) / range;
+ right_factor.y = (_fisheye[left_idx].handler->get_stable_y_start () - left_offsety / 2.0f) /
+ _fisheye[left_idx].handler->get_stable_y_start ();
+ XCAM_ASSERT (right_factor.x > 0.0f && right_factor.x < 2.0f);
+
+ uint32_t right_idx = (fm_idx + 1) % _fisheye_num;
+ center_x = (float)_fisheye[right_idx].width / 2;
+ feature_center_x = (float)crop_right.pos_x + crop_right.width / 2.0f;
+ range = center_x - feature_center_x;
+ XCAM_ASSERT (range > 1.0f);
+ left_factor.x = (range + left_offsetx / 2.0f) / range;
+ left_factor.y = (_fisheye[left_idx].handler->get_stable_y_start () + left_offsety / 2.0f) /
+ _fisheye[left_idx].handler->get_stable_y_start ();
+ XCAM_ASSERT (left_factor.x > 0.0f && left_factor.x < 2.0f);
+
+ PointFloat2 last_left_factor, last_right_factor;
+ last_left_factor = _fisheye[right_idx].handler->get_left_scale_factor ();
+ last_right_factor = _fisheye[left_idx].handler->get_right_scale_factor ();
+
+ left_factor.x *= last_left_factor.x;
+ left_factor.y *= last_left_factor.y;
+ right_factor.x *= last_right_factor.x;
+ right_factor.y *= last_right_factor.y;
+
+ _fisheye[left_idx].handler->set_right_scale_factor (right_factor);
+ _fisheye[right_idx].handler->set_left_scale_factor (left_factor);
+#else
+ XCAM_LOG_ERROR ("non-OpenCV mode, failed to update scale factors");
#endif
+}
+
+void
+CLImage360Stitch::set_fm_buf_mem (
+ const SmartPtr<VideoBuffer> &buf_left, const SmartPtr<VideoBuffer> &buf_right, int fm_idx)
+{
+#if HAVE_OPENCV
+ SmartPtr<CVFeatureMatch> fm = _feature_match[fm_idx].dynamic_cast_ptr<CVFeatureMatch> ();
+ XCAM_ASSERT (fm.ptr ());
- _scale_global_input.release ();
- _scale_global_output.release ();
+ SmartPtr<CLBuffer> cl_buf_left = convert_to_clbuffer (_context, buf_left);
+ SmartPtr<CLBuffer> cl_buf_right = convert_to_clbuffer (_context, buf_right);
+ XCAM_ASSERT (cl_buf_left.ptr () && cl_buf_left.ptr ());
+ cl_mem mem_left = cl_buf_left->get_mem_id ();
+ cl_mem mem_right = cl_buf_right->get_mem_id ();
- return CLMultiImageHandler::execute_done (output);
+ fm->set_cl_buf_mem (mem_left, CVFeatureMatch::BufIdLeft);
+ fm->set_cl_buf_mem (mem_right, CVFeatureMatch::BufIdRight);
+#else
+ XCAM_LOG_ERROR ("non-OpenCV mode, failed to set feature match buffer memory");
+#endif
}
+#if HAVE_OPENCV
static void
-convert_to_stitch_rect (Rect xcam_rect, Rect &stitch_rect)
+convert_to_stitch_rect (const Rect &xcam_rect, Rect &stitch_rect, SurroundMode surround_mode)
{
stitch_rect.pos_x = xcam_rect.pos_x;
- stitch_rect.pos_y = xcam_rect.pos_y + xcam_rect.height / 3;
stitch_rect.width = xcam_rect.width;
- stitch_rect.height = xcam_rect.height / 3;
+ if (surround_mode == SphereView) {
+ stitch_rect.pos_y = xcam_rect.pos_y + xcam_rect.height / 3;
+ stitch_rect.height = xcam_rect.height / 3;
+ } else {
+ stitch_rect.pos_y = xcam_rect.pos_y + xcam_rect.height / 5;
+ stitch_rect.height = xcam_rect.height / 2;
+ }
}
static void
-convert_to_xcam_rect (Rect stitch_rect, Rect &xcam_rect)
+convert_to_xcam_rect (const Rect &stitch_rect, Rect &xcam_rect)
{
xcam_rect.pos_x = stitch_rect.pos_x;
xcam_rect.width = stitch_rect.width;
}
-
+#endif
XCamReturn
CLImage360Stitch::sub_handler_execute_done (SmartPtr<CLImageHandler> &handler)
{
#if HAVE_OPENCV
- XCAM_ASSERT (handler.ptr ());
+ if (!_enable_fm)
+ return XCAM_RETURN_NO_ERROR;
+ XCAM_ASSERT (handler.ptr ());
if (handler.ptr () == _fisheye[_fisheye_num - 1].handler.ptr ()) {
int idx_next = 1;
Rect crop_left, crop_right;
@@ -813,14 +932,25 @@ CLImage360Stitch::sub_handler_execute_done (SmartPtr<CLImageHandler> &handler)
for (int i = 0; i < _fisheye_num; i++) {
idx_next = (i == (_fisheye_num - 1)) ? 0 : (i + 1);
- convert_to_stitch_rect (_img_merge_info[i].right, crop_left);
- convert_to_stitch_rect (_img_merge_info[idx_next].left, crop_right);
+ set_fm_buf_mem (_fisheye[i].buf, _fisheye[idx_next].buf, i);
- _feature_match[i]->optical_flow_feature_match (
- _fisheye[i].buf, _fisheye[idx_next].buf, crop_left, crop_right, _fisheye[i].width);
+ convert_to_stitch_rect (_img_merge_info[i].right, crop_left, _surround_mode);
+ convert_to_stitch_rect (_img_merge_info[idx_next].left, crop_right, _surround_mode);
+ if (_surround_mode == SphereView) {
+ _feature_match[i]->set_dst_width (_fisheye[i].width);
+ _feature_match[i]->set_crop_rect (crop_left, crop_right);
+ _feature_match[i]->feature_match (_fisheye[i].buf, _fisheye[idx_next].buf);
- convert_to_xcam_rect (crop_left, _img_merge_info[i].right);
- convert_to_xcam_rect (crop_right, _img_merge_info[idx_next].left);
+ _feature_match[i]->get_crop_rect (crop_left, crop_right);
+ convert_to_xcam_rect (crop_left, _img_merge_info[i].right);
+ convert_to_xcam_rect (crop_right, _img_merge_info[idx_next].left);
+ } else {
+ _feature_match[i]->reset_offsets ();
+ _feature_match[i]->set_crop_rect (crop_left, crop_right);
+ _feature_match[i]->feature_match (_fisheye[i].buf, _fisheye[idx_next].buf);
+
+ update_scale_factors (i, crop_left, crop_right);
+ }
}
}
#else
@@ -871,8 +1001,10 @@ create_image_360_stitch (
context, scale_mode, surround_mode, res_mode, fisheye_num, all_in_one_img);
XCAM_ASSERT (stitch.ptr ());
+ bool need_scale = (surround_mode == BowlView) ? true : false;
+
for (int index = 0; index < fisheye_num; ++index) {
- fisheye = create_fisheye_handler (context, surround_mode, fisheye_map, need_lsc).dynamic_cast_ptr<CLFisheyeHandler> ();
+ fisheye = create_fisheye_handler (context, surround_mode, fisheye_map, need_lsc, need_scale).dynamic_cast_ptr<CLFisheyeHandler> ();
XCAM_FAIL_RETURN (ERROR, fisheye.ptr (), NULL, "image_360_stitch create fisheye handler failed");
fisheye->disable_buf_pool (true);
stitch->set_fisheye_handler (fisheye, index);
diff --git a/modules/ocl/cl_image_360_stitch.h b/modules/ocl/cl_image_360_stitch.h
index 2c6babf..c164d4b 100644
--- a/modules/ocl/cl_image_360_stitch.h
+++ b/modules/ocl/cl_image_360_stitch.h
@@ -66,6 +66,8 @@ public:
const SmartPtr<CLContext> &context, CLBlenderScaleMode scale_mode, SurroundMode surround_mode,
StitchResMode res_mode, int fisheye_num, bool all_in_one_img);
+ void set_feature_match (bool enable);
+
bool set_stitch_info (StitchInfo stitch_info);
StitchInfo get_stitch_info ();
void set_output_size (uint32_t width, uint32_t height) {
@@ -94,12 +96,6 @@ public:
return _scale_global_output;
}
- void set_feature_match_ocl (bool use_ocl);
-#if HAVE_OPENCV
- void set_feature_match_config (const int idx, CVFMConfig config);
- CVFMConfig get_feature_match_config (const int idx);
-#endif
-
protected:
virtual XCamReturn prepare_buffer_pool_video_info (const VideoBufferInfo &input, VideoBufferInfo &output);
virtual XCamReturn prepare_parameters (SmartPtr<VideoBuffer> &input, SmartPtr<VideoBuffer> &output);
@@ -121,13 +117,19 @@ protected:
void update_image_overlap ();
private:
+ void init_opencv_ocl ();
+ void init_feature_match ();
+ void update_scale_factors (uint32_t fm_idx, const Rect &crop_left, const Rect &crop_right);
+ void set_fm_buf_mem (
+ const SmartPtr<VideoBuffer> &buf_left, const SmartPtr<VideoBuffer> &buf_right, int fm_idx);
+
+private:
XCAM_DEAD_COPY (CLImage360Stitch);
private:
SmartPtr<CLContext> _context;
CLFisheyeParams _fisheye[XCAM_STITCH_FISHEYE_MAX_NUM];
SmartPtr<CLBlender> _blender[XCAM_STITCH_FISHEYE_MAX_NUM];
- SmartPtr<FeatureMatch> _feature_match[XCAM_STITCH_FISHEYE_MAX_NUM];
uint32_t _output_width;
uint32_t _output_height;
@@ -142,6 +144,9 @@ private:
SurroundMode _surround_mode;
StitchResMode _res_mode;
+ bool _enable_fm;
+ SmartPtr<FeatureMatch> _feature_match[XCAM_STITCH_FISHEYE_MAX_NUM];
+
bool _is_stitch_inited;
int _fisheye_num;
bool _all_in_one_img;
diff --git a/modules/ocl/cl_image_handler.cpp b/modules/ocl/cl_image_handler.cpp
index f9fc56c..2fb87ab 100644
--- a/modules/ocl/cl_image_handler.cpp
+++ b/modules/ocl/cl_image_handler.cpp
@@ -25,6 +25,7 @@
#include "drm_bo_buffer.h"
#endif
#include "cl_device.h"
+#include "cl_video_buffer.h"
#include "swapped_buffer.h"
namespace XCam {
@@ -167,9 +168,9 @@ CLImageHandler::create_buffer_pool (const VideoBufferInfo &video_info)
if (_buf_pool.ptr ())
return XCAM_RETURN_ERROR_PARAM;
- SmartPtr<BufferPool> buffer_pool;
if (_buf_pool_type == CLImageHandler::CLVideoPoolType) {
- buffer_pool = new CLVideoBufferPool ();
+ SmartPtr<BufferPool> pool = new CLVideoBufferPool ();
+ _buf_pool = pool.ptr() ? pool : _buf_pool;
}
#if HAVE_LIBDRM
else {
@@ -181,30 +182,29 @@ CLImageHandler::create_buffer_pool (const VideoBufferInfo &video_info)
"CLImageHandler(%s) failed to get drm dispay", XCAM_STR (_name));
if (_buf_pool_type == CLImageHandler::DrmBoPoolType) {
- buffer_pool = new DrmBoBufferPool (display);
+ SmartPtr<BufferPool> pool = new DrmBoBufferPool (display);
+ _buf_pool = pool.ptr() ? pool : _buf_pool;
} else if (_buf_pool_type == CLImageHandler::CLBoPoolType) {
- buffer_pool = new CLBoBufferPool (display, get_context ());
+ SmartPtr<BufferPool> pool = new CLBoBufferPool (display, get_context ());
+ _buf_pool = pool.ptr() ? pool : _buf_pool;
}
}
#endif
XCAM_FAIL_RETURN(
WARNING,
- buffer_pool.ptr (),
+ _buf_pool.ptr (),
XCAM_RETURN_ERROR_CL,
"CLImageHandler(%s) create buffer pool failed, pool_type:%d",
XCAM_STR (_name), (int32_t)_buf_pool_type);
- XCAM_ASSERT (buffer_pool.ptr ());
// buffer_pool->set_swap_flags (_buf_swap_flags, _buf_swap_init_order);
- buffer_pool->set_video_info (video_info);
-
+ _buf_pool->set_video_info (video_info);
XCAM_FAIL_RETURN(
WARNING,
- buffer_pool->reserve (_buf_pool_size),
+ _buf_pool->reserve (_buf_pool_size),
XCAM_RETURN_ERROR_CL,
"CLImageHandler(%s) failed to init drm buffer pool", XCAM_STR (_name));
- _buf_pool = buffer_pool;
return XCAM_RETURN_NO_ERROR;
}
diff --git a/modules/ocl/cl_image_handler.h b/modules/ocl/cl_image_handler.h
index 45c1b31..dd32da7 100644
--- a/modules/ocl/cl_image_handler.h
+++ b/modules/ocl/cl_image_handler.h
@@ -27,11 +27,11 @@
#include <ocl/cl_kernel.h>
#include <ocl/cl_argument.h>
#include <ocl/cl_memory.h>
-#include <ocl/cl_video_buffer.h>
namespace XCam {
class CLImageHandler;
+class X3aResult;
class CLImageKernel
: public CLKernel
diff --git a/modules/ocl/cl_image_processor.cpp b/modules/ocl/cl_image_processor.cpp
index c0cbd98..a4c178d 100644
--- a/modules/ocl/cl_image_processor.cpp
+++ b/modules/ocl/cl_image_processor.cpp
@@ -83,11 +83,13 @@ CLImageProcessor::CLImageProcessor (const char* name)
_context = CLDevice::instance ()->get_context ();
XCAM_ASSERT (_context.ptr());
- _handler_thread = new CLHandlerThread (this);
- XCAM_ASSERT (_handler_thread.ptr ());
+ SmartPtr<CLHandlerThread> handler_thread = new CLHandlerThread (this);
+ XCAM_ASSERT (handler_thread.ptr ());
+ _handler_thread = handler_thread;
- _done_buf_thread = new CLBufferNotifyThread (this);
- XCAM_ASSERT (_done_buf_thread.ptr ());
+ SmartPtr<CLBufferNotifyThread> done_buf_thread = new CLBufferNotifyThread (this);
+ XCAM_ASSERT (done_buf_thread.ptr ());
+ _done_buf_thread = done_buf_thread;
XCAM_LOG_DEBUG ("CLImageProcessor constructed");
XCAM_OBJ_PROFILING_INIT;
diff --git a/modules/ocl/cl_image_scaler.cpp b/modules/ocl/cl_image_scaler.cpp
index c888b36..171ca30 100644
--- a/modules/ocl/cl_image_scaler.cpp
+++ b/modules/ocl/cl_image_scaler.cpp
@@ -219,10 +219,11 @@ CLImageScaler::prepare_scaler_buf (const VideoBufferInfo &video_info, SmartPtr<V
scaler_video_info.init (video_info.format, new_width, new_height);
- _scaler_buf_pool = new CLVideoBufferPool ();
- XCAM_ASSERT (_scaler_buf_pool.ptr ());
- _scaler_buf_pool->set_video_info (scaler_video_info);
- _scaler_buf_pool->reserve (6);
+ SmartPtr<BufferPool> pool = new CLVideoBufferPool ();
+ XCAM_ASSERT (pool.ptr ());
+ pool->set_video_info (scaler_video_info);
+ pool->reserve (6);
+ _scaler_buf_pool = pool;
}
output = _scaler_buf_pool->get_buffer (_scaler_buf_pool);
diff --git a/modules/ocl/cl_kernel.cpp b/modules/ocl/cl_kernel.cpp
index fdda8ec..47574b6 100644
--- a/modules/ocl/cl_kernel.cpp
+++ b/modules/ocl/cl_kernel.cpp
@@ -34,14 +34,16 @@ namespace XCam {
CLKernel::KernelMap CLKernel::_kernel_map;
Mutex CLKernel::_kernel_map_mutex;
-static char*
+static const char*
default_cache_path () {
- static char path[XCAM_MAX_STR_SIZE] = {0};
- snprintf (
- path, XCAM_MAX_STR_SIZE - 1,
- "%s/%s", std::getenv ("HOME"), ".xcam/");
+ static std::string path = "/tmp";
+ const char *home_dir = std::getenv ("HOME");
+ if (home_dir)
+ path.assign (home_dir, strlen (home_dir));
+
+ path += "/.xcam";
- return path;
+ return path.c_str ();
}
const char* CLKernel::_kernel_cache_path = default_cache_path ();
@@ -134,15 +136,15 @@ CLKernel::build_kernel (const XCamKernelInfo& info, const char* options)
bool load_cache = false;
struct timeval ts;
- const char* cache_path = std::getenv ("XCAM_CL_KERNEL_CACHE_PATH");
- if (NULL == cache_path) {
- cache_path = _kernel_cache_path;
- }
+ std::string cache_path = _kernel_cache_path;
+ const char *env = std::getenv ("XCAM_CL_KERNEL_CACHE_PATH");
+ if (env)
+ cache_path.assign (env, strlen (env));
snprintf (
cache_filename, XCAM_MAX_STR_SIZE - 1,
"%s/%s",
- cache_path, key_str);
+ cache_path.c_str (), key_str);
{
SmartLock locker (_kernel_map_mutex);
@@ -153,8 +155,8 @@ CLKernel::build_kernel (const XCamKernelInfo& info, const char* options)
single_kernel = new CLKernel (context, info.kernel_name);
XCAM_ASSERT (single_kernel.ptr ());
- if (access (cache_path, F_OK) == -1) {
- mkdir (cache_path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
+ if (access (cache_path.c_str (), F_OK) == -1) {
+ mkdir (cache_path.c_str (), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
}
ret = cache_file.open (cache_filename, "r");
diff --git a/modules/ocl/cl_post_image_processor.cpp b/modules/ocl/cl_post_image_processor.cpp
index ebe9319..21d230b 100644
--- a/modules/ocl/cl_post_image_processor.cpp
+++ b/modules/ocl/cl_post_image_processor.cpp
@@ -59,7 +59,6 @@ CLPostImageProcessor::CLPostImageProcessor ()
, _stitch_enable_seam (false)
, _stitch_fisheye_map (false)
, _stitch_lsc (false)
- , _stitch_fm_ocl (false)
, _stitch_scale_mode (CLBlenderScaleLocal)
, _stitch_width (0)
, _stitch_height (0)
@@ -411,9 +410,6 @@ CLPostImageProcessor::create_handlers ()
XCAM_RETURN_ERROR_CL,
"CLPostImageProcessor create image stitch handler failed");
_stitch->set_output_size (_stitch_width, _stitch_height);
-#if HAVE_OPENCV
- _stitch->set_feature_match_ocl (_stitch_fm_ocl);
-#endif
image_handler->set_pool_type (CLImageHandler::CLVideoPoolType);
image_handler->set_pool_size (XCAM_CL_POST_IMAGE_MAX_POOL_SIZE);
image_handler->enable_handler (_enable_stitch);
@@ -512,7 +508,7 @@ CLPostImageProcessor::set_image_warp (bool enable)
bool
CLPostImageProcessor::set_image_stitch (
bool enable_stitch, bool enable_seam, CLBlenderScaleMode scale_mode, bool enable_fisheye_map,
- bool lsc, bool fm_ocl, uint32_t stitch_width, uint32_t stitch_height, uint32_t res_mode)
+ bool lsc, uint32_t stitch_width, uint32_t stitch_height, uint32_t res_mode)
{
XCAM_ASSERT (scale_mode < CLBlenderScaleMax);
@@ -529,12 +525,6 @@ CLPostImageProcessor::set_image_stitch (
_stitch_height = stitch_height;
_stitch_res_mode = res_mode;
-#if HAVE_OPENCV
- _stitch_fm_ocl = fm_ocl;
-#else
- XCAM_UNUSED (fm_ocl);
-#endif
-
STREAM_LOCK;
return true;
diff --git a/modules/ocl/cl_post_image_processor.h b/modules/ocl/cl_post_image_processor.h
index a06e007..43e7052 100644
--- a/modules/ocl/cl_post_image_processor.h
+++ b/modules/ocl/cl_post_image_processor.h
@@ -95,7 +95,7 @@ public:
virtual bool set_image_warp (bool enable);
virtual bool set_image_stitch (
bool enable_stitch, bool enable_seam, CLBlenderScaleMode scale_mode, bool enable_fisheye_map,
- bool lsc, bool fm_ocl, uint32_t stitch_width, uint32_t stitch_height, uint32_t res_mode);
+ bool lsc, uint32_t stitch_width, uint32_t stitch_height, uint32_t res_mode);
protected:
virtual bool can_process_result (SmartPtr<X3aResult> &result);
@@ -141,7 +141,6 @@ private:
bool _stitch_enable_seam;
bool _stitch_fisheye_map;
bool _stitch_lsc;
- bool _stitch_fm_ocl;
CLBlenderScaleMode _stitch_scale_mode;
uint32_t _stitch_width;
uint32_t _stitch_height;
diff --git a/modules/ocl/cl_retinex_handler.cpp b/modules/ocl/cl_retinex_handler.cpp
index 79b5dd1..547d033 100644
--- a/modules/ocl/cl_retinex_handler.cpp
+++ b/modules/ocl/cl_retinex_handler.cpp
@@ -234,10 +234,11 @@ CLRetinexImageHandler::prepare_scaler_buf (const VideoBufferInfo &video_info)
scaler_video_info.init (video_info.format, new_width, new_height);
- _scaler_buf_pool = new CLVideoBufferPool ();
- XCAM_ASSERT (_scaler_buf_pool.ptr ());
- _scaler_buf_pool->set_video_info (scaler_video_info);
- _scaler_buf_pool->reserve (XCAM_RETINEX_MAX_SCALE + 1);
+ SmartPtr<BufferPool> pool = new CLVideoBufferPool ();
+ XCAM_ASSERT (pool.ptr ());
+ pool->set_video_info (scaler_video_info);
+ pool->reserve (XCAM_RETINEX_MAX_SCALE + 1);
+ _scaler_buf_pool = pool;
_scaler_buf1 = _scaler_buf_pool->get_buffer (_scaler_buf_pool);
XCAM_ASSERT (_scaler_buf1.ptr ());
diff --git a/modules/ocl/cl_utils.cpp b/modules/ocl/cl_utils.cpp
index b8ce3a9..831850e 100644
--- a/modules/ocl/cl_utils.cpp
+++ b/modules/ocl/cl_utils.cpp
@@ -317,8 +317,8 @@ generate_rectifiedview_map_table (
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
float plane_point_coords[3];
- plane_point_coords[0] = (center_x - col) * length_per_pixel_x * cos (PI / 2 - degree2radian (angle_center)) + plane_center_coords[0];
- plane_point_coords[1] = (center_x - col) * length_per_pixel_x * sin (PI / 2 - degree2radian (angle_center)) + plane_center_coords[1];
+ plane_point_coords[0] = (center_x - col) * length_per_pixel_x * cos (XCAM_PI / 2 - degree2radian (angle_center)) + plane_center_coords[0];
+ plane_point_coords[1] = (center_x - col) * length_per_pixel_x * sin (XCAM_PI / 2 - degree2radian (angle_center)) + plane_center_coords[1];
plane_point_coords[2] = (center_y - row) * length_per_pixel_y + plane_center_coords[2];
float rate_xz, rate_yz;
diff --git a/modules/ocl/cl_video_buffer.cpp b/modules/ocl/cl_video_buffer.cpp
index 032dd3d..c16d665 100644
--- a/modules/ocl/cl_video_buffer.cpp
+++ b/modules/ocl/cl_video_buffer.cpp
@@ -22,6 +22,7 @@
#include "ocl/cl_memory.h"
#include "ocl/cl_device.h"
#include "ocl/cl_video_buffer.h"
+#include "x3a_stats_pool.h"
namespace XCam {
diff --git a/modules/ocl/cl_video_buffer.h b/modules/ocl/cl_video_buffer.h
index 969bff1..e44e023 100644
--- a/modules/ocl/cl_video_buffer.h
+++ b/modules/ocl/cl_video_buffer.h
@@ -25,13 +25,13 @@
#include <safe_list.h>
#include <xcam_mutex.h>
#include <buffer_pool.h>
-#include <x3a_stats_pool.h>
#include <ocl/cl_context.h>
namespace XCam {
class CLBuffer;
class CLVideoBufferPool;
+class X3aStats;
class CLVideoBufferData
: public BufferData
diff --git a/modules/ocl/cv_base_class.cpp b/modules/ocl/cv_base_class.cpp
deleted file mode 100644
index 7dbecaa..0000000
--- a/modules/ocl/cv_base_class.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * cv_base_class.cpp - base class for all OpenCV related features
- *
- * Copyright (c) 2016-2017 Intel Corporation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Author: Andrey Parfenov <a1994ndrey@gmail.com>
- * Author: Wind Yuan <feng.yuan@intel.com>
- */
-
-#include "cv_base_class.h"
-
-namespace XCam {
-
-CVBaseClass::CVBaseClass ()
-{
- _cv_context = CVContext::instance ();
- XCAM_ASSERT (_cv_context.ptr ());
- _use_ocl = _cv_context->is_ocl_enabled ();
-}
-
-bool
-CVBaseClass::set_ocl (bool use_ocl)
-{
- if (use_ocl && !_cv_context->is_ocl_enabled ()) {
- return false;
- }
- _use_ocl = use_ocl;
- return true;
-}
-
-bool
-CVBaseClass::convert_to_mat (SmartPtr<VideoBuffer> buffer, cv::Mat &image)
-{
-
- VideoBufferInfo info = buffer->get_video_info ();
- XCAM_FAIL_RETURN (WARNING, info.format == V4L2_PIX_FMT_NV12, false, "convert_to_mat only support NV12 format");
-
- uint8_t *ptr = buffer->map ();
- XCAM_FAIL_RETURN (WARNING, ptr, false, "convert_to_mat buffer map failed");
-
- cv::Mat mat = cv::Mat (info.aligned_height * 3 / 2, info.width, CV_8UC1, ptr, info.strides[0]);
- cv::cvtColor (mat, image, cv::COLOR_YUV2BGR_NV12);
- //buffer->unmap ();
-
- return true;
-}
-
-bool
-convert_to_mat (SmartPtr<VideoBuffer> buffer, cv::Mat &image)
-{
- CVBaseClass cv_obj;
- return cv_obj.convert_to_mat (buffer, image);
-}
-
-}
diff --git a/modules/ocl/cv_base_class.h b/modules/ocl/cv_base_class.h
deleted file mode 100644
index 70641c2..0000000
--- a/modules/ocl/cv_base_class.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * cv_base_class.h - base class for all OpenCV related features
- *
- * Copyright (c) 2016-2017 Intel Corporation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Author: Andrey Parfenov <a1994ndrey@gmail.com>
- * Author: Wind Yuan <feng.yuan@intel.com>
- */
-
-#ifndef XCAM_CV_BASE_CLASS_H
-#define XCAM_CV_BASE_CLASS_H
-
-#include <xcam_std.h>
-#include <video_buffer.h>
-#include <ocl/cv_context.h>
-
-namespace XCam {
-
-class CVBaseClass
-{
-public:
- explicit CVBaseClass ();
- bool set_ocl (bool use_ocl);
- bool is_ocl_path () {
- return _use_ocl;
- }
- bool convert_to_mat (SmartPtr<VideoBuffer> buffer, cv::Mat &image);
-
-protected:
- XCAM_DEAD_COPY (CVBaseClass);
- SmartPtr<CVContext> _cv_context;
- bool _use_ocl;
-};
-
-extern bool
-convert_to_mat (SmartPtr<VideoBuffer> buffer, cv::Mat &image);
-
-}
-
-#endif // XCAM_CV_BASE_CLASS_H
diff --git a/modules/ocl/cv_context.cpp b/modules/ocl/cv_context.cpp
deleted file mode 100644
index babf5ef..0000000
--- a/modules/ocl/cv_context.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * cv_context.cpp - used to init_opencv_ocl once
- *
- * Copyright (c) 2016-2017 Intel Corporation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Author: Andrey Parfenov <a1994ndrey@gmail.com>
- * Author: Wind Yuan <feng.yuan@intel.com>
- */
-
-#include "cv_context.h"
-#include "cl_device.h"
-#include "cl_memory.h"
-
-namespace XCam {
-
-Mutex CVContext::_init_mutex;
-SmartPtr<CVContext> CVContext::_instance;
-
-
-SmartPtr<CVContext>
-CVContext::instance ()
-{
- SmartLock locker (_init_mutex);
- if (_instance.ptr())
- return _instance;
-
- _instance = new CVContext ();
- _instance->init_opencv_ocl ();
- return _instance;
-}
-
-void
-CVContext::init_opencv_ocl ()
-{
- _context = CLDevice::instance()->get_context();
- cl_platform_id platform_id = CLDevice::instance()->get_platform_id ();
- char *platform_name = CLDevice::instance()->get_platform_name ();
- cl_device_id device_id = CLDevice::instance()->get_device_id ();
- cl_context _context_id = _context->get_context_id ();
- cv::ocl::attachContext (platform_name, platform_id, _context_id, device_id);
- cv::ocl::setUseOpenCL (cv::ocl::haveOpenCL());
- XCAM_LOG_DEBUG("Use OpenCL is: %s", cv::ocl::haveOpenCL() ? "true" : "false");
-}
-
-bool
-CVContext::enable_ocl (bool flag)
-{
- if (flag && !cv::ocl::haveOpenCL()) {
- return false;
- }
- cv::ocl::setUseOpenCL (flag);
- return true;
-}
-
-bool
-CVContext::is_ocl_enabled () const
-{
- return cv::ocl::useOpenCL ();
-}
-
-CVContext::CVContext ()
-{
-
-}
-
-CVContext::~CVContext () {
-
-}
-
-}
diff --git a/modules/ocl/cv_context.h b/modules/ocl/cv_context.h
deleted file mode 100644
index 17363be..0000000
--- a/modules/ocl/cv_context.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * cv_context.h - used to init_opencv_ocl once
- *
- * Copyright (c) 2016-2017 Intel Corporation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Author: Andrey Parfenov <a1994ndrey@gmail.com>
- * Author: Wind Yuan <feng.yuan@intel.com>
- */
-
-#ifndef XCAM_CV_CONTEXT_H
-#define XCAM_CV_CONTEXT_H
-
-#include <xcam_std.h>
-#include <xcam_obj_debug.h>
-#include <xcam_mutex.h>
-#include <ocl/cl_context.h>
-
-#include <opencv2/opencv.hpp>
-#include <opencv2/core/ocl.hpp>
-
-namespace XCam {
-
-class CVContext
-{
-public:
- static SmartPtr<CVContext> instance ();
-
- SmartPtr<CLContext> get_cl_context () {
- return _context;
- }
- ~CVContext();
- bool enable_ocl (bool flag);
- bool is_ocl_enabled () const;
-
-private:
- CVContext ();
- void init_opencv_ocl ();
-
- static Mutex _init_mutex;
- static SmartPtr<CVContext> _instance;
-
- SmartPtr<CLContext> _context;
-
- XCAM_DEAD_COPY (CVContext);
-
-};
-
-}
-
-#endif // XCAM_CV_CONTEXT_H
diff --git a/modules/ocl/cv_feature_match.h b/modules/ocl/cv_feature_match.h
deleted file mode 100644
index ed53fae..0000000
--- a/modules/ocl/cv_feature_match.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * cv_feature_match.h - optical flow feature match
- *
- * Copyright (c) 2016-2017 Intel Corporation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Author: Wind Yuan <feng.yuan@intel.com>
- * Author: Yinhang Liu <yinhangx.liu@intel.com>
- */
-
-#ifndef XCAM_CV_FEATURE_MATCH_H
-#define XCAM_CV_FEATURE_MATCH_H
-
-#include <xcam_std.h>
-#include <video_buffer.h>
-#include <ocl/cv_base_class.h>
-#include <interface/feature_match.h>
-#include <interface/data_types.h>
-
-#include <ocl/cl_context.h>
-#include <ocl/cl_device.h>
-#include <ocl/cl_memory.h>
-
-namespace XCam {
-
-class CVFeatureMatch
- : public CVBaseClass
- , public FeatureMatch
-{
-public:
- explicit CVFeatureMatch ();
-
- void optical_flow_feature_match (
- const SmartPtr<VideoBuffer> &left_buf, const SmartPtr<VideoBuffer> &right_buf,
- Rect &left_img_crop, Rect &right_img_crop, int dst_width);
-
- void set_ocl (bool use_ocl) {
- CVBaseClass::set_ocl (use_ocl);
- }
- bool is_ocl_path () {
- return CVBaseClass::is_ocl_path ();
- }
-
-protected:
- bool get_crop_image (const SmartPtr<VideoBuffer> &buffer, const Rect &crop_rect, cv::UMat &img);
-
- void add_detected_data (cv::InputArray image, cv::Ptr<cv::Feature2D> detector, std::vector<cv::Point2f> &corners);
- void get_valid_offsets (std::vector<cv::Point2f> &corner0, std::vector<cv::Point2f> &corner1,
- std::vector<uchar> &status, std::vector<float> &error,
- std::vector<float> &offsets, float &sum, int &count,
- cv::InputOutputArray debug_img, cv::Size &img0_size);
-
- void calc_of_match (cv::InputArray image0, cv::InputArray image1,
- std::vector<cv::Point2f> &corner0, std::vector<cv::Point2f> &corner1,
- std::vector<uchar> &status, std::vector<float> &error,
- int &last_count, float &last_mean_offset, float &out_x_offset);
-
- void detect_and_match (cv::InputArray img_left, cv::InputArray img_right, Rect &crop_left, Rect &crop_right,
- int &valid_count, float &mean_offset, float &x_offset, int dst_width);
-
-private:
- XCAM_DEAD_COPY (CVFeatureMatch);
-
-};
-
-}
-
-#endif // XCAM_CV_FEATURE_MATCH_H
diff --git a/modules/ocv/Makefile.am b/modules/ocv/Makefile.am
new file mode 100644
index 0000000..fbbdacb
--- /dev/null
+++ b/modules/ocv/Makefile.am
@@ -0,0 +1,29 @@
+noinst_LTLIBRARIES = libxcam_ocv.la
+
+xcam_ocv_sources = \
+ cv_utils.cpp \
+ cv_image_process_helper.cpp \
+ cv_image_sharp.cpp \
+ cv_edgetaper.cpp \
+ cv_wiener_filter.cpp \
+ cv_image_deblurring.cpp \
+ cv_feature_match.cpp \
+ cv_feature_match_cluster.cpp \
+ cv_capi_feature_match.cpp \
+ $(NULL)
+
+libxcam_ocv_la_SOURCES = \
+ $(xcam_ocv_sources) \
+ $(NULL)
+
+libxcam_ocv_la_CXXFLAGS = \
+ $(XCAM_CXXFLAGS) \
+ $(OPENCV_CFLAGS) \
+ -I$(top_srcdir)/xcore \
+ -I$(top_srcdir)/modules \
+ $(NULL)
+
+libxcam_ocv_la_LIBADD = \
+ $(OPENCV_LIBS) \
+ $(top_builddir)/xcore/libxcam_core.la \
+ $(NULL) \ No newline at end of file
diff --git a/modules/soft/cv_capi_feature_match.cpp b/modules/ocv/cv_capi_feature_match.cpp
index 0e0081c..d478f3c 100644
--- a/modules/soft/cv_capi_feature_match.cpp
+++ b/modules/ocv/cv_capi_feature_match.cpp
@@ -24,19 +24,10 @@
#define XCAM_CV_CAPI_FM_DEBUG 0
-#if XCAM_CV_CAPI_FM_DEBUG
-#include "ocl/cv_base_class.h"
-#endif
-
namespace XCam {
-#if XCAM_CV_CAPI_FM_DEBUG
-static void
-debug_write_image (
- const SmartPtr<VideoBuffer> &buf, const Rect &rect, char *img_name, char *frame_str, char *fm_idx_str);
-#endif
CVCapiFeatureMatch::CVCapiFeatureMatch ()
- : FeatureMatch()
+ : FeatureMatch ()
{
}
@@ -63,8 +54,7 @@ CVCapiFeatureMatch::get_crop_image (
}
void
-CVCapiFeatureMatch::add_detected_data (
- CvArr* image, std::vector<CvPoint2D32f> &corners)
+CVCapiFeatureMatch::add_detected_data (CvArr* image, std::vector<CvPoint2D32f> &corners)
{
std::vector<CvPoint2D32f> keypoints;
@@ -127,10 +117,8 @@ CVCapiFeatureMatch::get_valid_offsets (
void
CVCapiFeatureMatch::calc_of_match (
- CvArr* image0, CvArr* image1,
- std::vector<CvPoint2D32f> &corner0, std::vector<CvPoint2D32f> &corner1,
- std::vector<char> &status, std::vector<float> &error,
- int &last_count, float &last_mean_offset, float &out_x_offset)
+ CvArr* image0, CvArr* image1, std::vector<CvPoint2D32f> &corner0, std::vector<CvPoint2D32f> &corner1,
+ std::vector<char> &status, std::vector<float> &error)
{
CvMat debug_image;
CvSize img0_size = cvSize(((CvMat*)image0)->width, ((CvMat*)image0)->height);
@@ -141,6 +129,7 @@ CVCapiFeatureMatch::calc_of_match (
float offset_sum = 0.0f;
int count = 0;
float mean_offset = 0.0f;
+ float last_mean_offset = _mean_offset;
offsets.reserve (corner0.size ());
#if XCAM_CV_CAPI_FM_DEBUG
@@ -165,21 +154,19 @@ CVCapiFeatureMatch::calc_of_match (
bool ret = get_mean_offset (offsets, offset_sum, count, mean_offset);
if (ret) {
if (fabs (mean_offset - last_mean_offset) < _config.delta_mean_offset) {
- out_x_offset = out_x_offset * _config.offset_factor + mean_offset * (1.0f - _config.offset_factor);
+ _x_offset = _x_offset * _config.offset_factor + mean_offset * (1.0f - _config.offset_factor);
- if (fabs (out_x_offset) > _config.max_adjusted_offset)
- out_x_offset = (out_x_offset > 0.0f) ? _config.max_adjusted_offset : (-_config.max_adjusted_offset);
+ if (fabs (_x_offset) > _config.max_adjusted_offset)
+ _x_offset = (_x_offset > 0.0f) ? _config.max_adjusted_offset : (-_config.max_adjusted_offset);
}
}
- last_count = count;
- last_mean_offset = mean_offset;
+ _valid_count = count;
+ _mean_offset = mean_offset;
}
void
-CVCapiFeatureMatch::detect_and_match (
- CvArr* img_left, CvArr* img_right, Rect &crop_left, Rect &crop_right,
- int &valid_count, float &mean_offset, float &x_offset, int dst_width)
+CVCapiFeatureMatch::detect_and_match (CvArr* img_left, CvArr* img_right)
{
std::vector<float> err;
std::vector<char> status;
@@ -211,31 +198,26 @@ CVCapiFeatureMatch::detect_and_match (
XCAM_LOG_INFO ("FeatureMatch(idx:%d): matched corners:%d", _fm_idx, count);
#endif
- calc_of_match (img_left, img_right, corner_left, corner_right,
- status, err, valid_count, mean_offset, x_offset);
-
- adjust_stitch_area (dst_width, x_offset, crop_left, crop_right);
+ calc_of_match (img_left, img_right, corner_left, corner_right, status, err);
#if XCAM_CV_CAPI_FM_DEBUG
- XCAM_LOG_INFO (
- "FeatureMatch(idx:%d): stiching area: left_area(pos_x:%d, width:%d), right_area(pos_x:%d, width:%d)",
- _fm_idx, crop_left.pos_x, crop_left.width, crop_right.pos_x, crop_right.width);
+ XCAM_LOG_INFO ("FeatureMatch(idx:%d): x_offset:%0.2f", _fm_idx, _x_offset);
#endif
}
void
-CVCapiFeatureMatch::optical_flow_feature_match (
- const SmartPtr<VideoBuffer> &left_buf, const SmartPtr<VideoBuffer> &right_buf,
- Rect &left_crop_rect, Rect &right_crop_rect, int dst_width)
+CVCapiFeatureMatch::feature_match (
+ const SmartPtr<VideoBuffer> &left_buf, const SmartPtr<VideoBuffer> &right_buf)
{
- CvMat left_img, right_img;
+ XCAM_ASSERT (_left_rect.width && _left_rect.height);
+ XCAM_ASSERT (_right_rect.width && _right_rect.height);
- if (!get_crop_image (left_buf, left_crop_rect, _left_crop_image, left_img)
- || !get_crop_image (right_buf, right_crop_rect, _right_crop_image, right_img))
+ CvMat left_img, right_img;
+ if (!get_crop_image (left_buf, _left_rect, _left_crop_image, left_img)
+ || !get_crop_image (right_buf, _right_rect, _right_crop_image, right_img))
return;
- detect_and_match ((CvArr*)(&left_img), (CvArr*)(&right_img), left_crop_rect, right_crop_rect,
- _valid_count, _mean_offset, _x_offset, dst_width);
+ detect_and_match ((CvArr*)(&left_img), (CvArr*)(&right_img));
#if XCAM_CV_CAPI_FM_DEBUG
XCAM_ASSERT (_fm_idx >= 0);
@@ -247,10 +229,9 @@ CVCapiFeatureMatch::optical_flow_feature_match (
char img_name[256] = {'\0'};
std::snprintf (img_name, 256, "fm_in_stitch_area_%d_%d_0.jpg", _frame_num, _fm_idx);
- debug_write_image (left_buf, left_crop_rect, img_name, frame_str, fm_idx_str);
-
+ write_image (left_buf, _left_rect, img_name, frame_str, fm_idx_str);
std::snprintf (img_name, 256, "fm_in_stitch_area_%d_%d_1.jpg", _frame_num, _fm_idx);
- debug_write_image (right_buf, right_crop_rect, img_name, frame_str, fm_idx_str);
+ write_image (right_buf, _right_rect, img_name, frame_str, fm_idx_str);
XCAM_LOG_INFO ("FeatureMatch(idx:%d): frame number:%d done", _fm_idx, _frame_num);
@@ -258,30 +239,13 @@ CVCapiFeatureMatch::optical_flow_feature_match (
#endif
}
-#if XCAM_CV_CAPI_FM_DEBUG
-static void
-debug_write_image (
- const SmartPtr<VideoBuffer> &buf, const Rect &rect, char *img_name, char *frame_str, char *fm_idx_str)
+SmartPtr<FeatureMatch>
+FeatureMatch::create_capi_feature_match ()
{
- cv::Scalar color = cv::Scalar(0, 0, 255);
- VideoBufferInfo info = buf->get_video_info ();
-
- cv::Mat mat;
- CVBaseClass cv_obj;
- cv_obj.convert_to_mat (buf, mat);
+ SmartPtr<CVCapiFeatureMatch> matcher = new CVCapiFeatureMatch ();
+ XCAM_ASSERT (matcher.ptr ());
- cv::putText (mat, frame_str, cv::Point(rect.pos_x, 30), cv::FONT_HERSHEY_COMPLEX, 0.8f, color, 2, 8, false);
- cv::putText (mat, fm_idx_str, cv::Point(rect.pos_x, 70), cv::FONT_HERSHEY_COMPLEX, 0.8f, color, 2, 8, false);
-
- cv::line (mat, cv::Point(rect.pos_x, rect.pos_y), cv::Point(rect.pos_x + rect.width, rect.pos_y), color, 1);
- cv::line (mat, cv::Point(rect.pos_x, rect.pos_y + rect.height),
- cv::Point(rect.pos_x + rect.width, rect.pos_y + rect.height), color, 1);
-
- cv::line (mat, cv::Point(rect.pos_x, 0), cv::Point(rect.pos_x, info.height), color, 2);
- cv::line (mat, cv::Point(rect.pos_x + rect.width, 0), cv::Point(rect.pos_x + rect.width, info.height), color, 2);
-
- cv::imwrite (img_name, mat);
+ return matcher;
}
-#endif
}
diff --git a/modules/ocv/cv_capi_feature_match.h b/modules/ocv/cv_capi_feature_match.h
new file mode 100644
index 0000000..f1f8794
--- /dev/null
+++ b/modules/ocv/cv_capi_feature_match.h
@@ -0,0 +1,74 @@
+/*
+ * cv_capi_feature_match.h - optical flow feature match
+ *
+ * Copyright (c) 2016-2017 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ * Author: Zong Wei <wei.zong@intel.com>
+ */
+
+#ifndef CV_CAPI_FEATURE_MATCH_H
+#define CV_CAPI_FEATURE_MATCH_H
+
+#include <video_buffer.h>
+#include <interface/feature_match.h>
+#include "cv_utils.h"
+
+#ifdef ANDROID
+#include <cv.h>
+#else
+#include <opencv2/imgproc/imgproc_c.h>
+#include <opencv2/video/tracking_c.h>
+#endif
+
+namespace XCam {
+
+class CVCapiFeatureMatch
+ : public FeatureMatch
+{
+public:
+ explicit CVCapiFeatureMatch ();
+
+ virtual void feature_match (
+ const SmartPtr<VideoBuffer> &left_buf, const SmartPtr<VideoBuffer> &right_buf);
+
+private:
+ bool get_crop_image (
+ const SmartPtr<VideoBuffer> &buffer, const Rect &crop_rect, std::vector<char> &crop_image, CvMat &img);
+
+ void detect_and_match (CvArr* img_left, CvArr* img_right);
+ void add_detected_data (CvArr* image, std::vector<CvPoint2D32f> &corners);
+
+ void calc_of_match (
+ CvArr* image0, CvArr* image1, std::vector<CvPoint2D32f> &corner0, std::vector<CvPoint2D32f> &corner1,
+ std::vector<char> &status, std::vector<float> &error);
+
+ void get_valid_offsets (
+ std::vector<CvPoint2D32f> &corner0, std::vector<CvPoint2D32f> &corner1,
+ std::vector<char> &status, std::vector<float> &error,
+ std::vector<float> &offsets, float &sum, int &count,
+ CvArr* out_image, CvSize &img0_size);
+
+private:
+ XCAM_DEAD_COPY (CVCapiFeatureMatch);
+
+ std::vector<char> _left_crop_image;
+ std::vector<char> _right_crop_image;
+};
+
+}
+
+#endif // CV_CAPI_FEATURE_MATCH_H
diff --git a/modules/ocl/cv_edgetaper.cpp b/modules/ocv/cv_edgetaper.cpp
index ab79238..524caa7 100644
--- a/modules/ocl/cv_edgetaper.cpp
+++ b/modules/ocv/cv_edgetaper.cpp
@@ -23,13 +23,6 @@
namespace XCam {
-
-CVEdgetaper::CVEdgetaper ()
- : CVBaseClass ()
-{
-
-}
-
void
CVEdgetaper::create_weights (const cv::Mat &image, const cv::Mat &psf, cv::Mat &coefficients)
{
@@ -37,13 +30,13 @@ CVEdgetaper::create_weights (const cv::Mat &image, const cv::Mat &psf, cv::Mat &
cv::Mat rows_proj_border, cols_proj_border;
cv::Mat rows_cor, cols_cor;
// get psf rows and cols projections
- cv::reduce (psf, rows_proj, 1, CV_REDUCE_SUM, -1);
- cv::reduce (psf, cols_proj, 0, CV_REDUCE_SUM, -1);
+ cv::reduce (psf, rows_proj, 1, cv::REDUCE_SUM, -1);
+ cv::reduce (psf, cols_proj, 0, cv::REDUCE_SUM, -1);
// calculate correlation for psf projections
cv::copyMakeBorder (rows_proj, rows_proj_border, (psf.rows - 1) / 2, (psf.rows - 1) / 2, 0, 0, cv::BORDER_CONSTANT, cv::Scalar::all (0));
cv::copyMakeBorder (cols_proj, cols_proj_border, 0, 0, (psf.cols - 1) / 2, (psf.cols - 1) / 2, cv::BORDER_CONSTANT, cv::Scalar::all (0));
- cv::matchTemplate (rows_proj_border, rows_proj, rows_cor, CV_TM_CCORR);
- cv::matchTemplate (cols_proj_border, cols_proj, cols_cor, CV_TM_CCORR);
+ cv::matchTemplate (rows_proj_border, rows_proj, rows_cor, cv::TM_CCORR);
+ cv::matchTemplate (cols_proj_border, cols_proj, cols_cor, cv::TM_CCORR);
// make it symmetric on both sides
cv::Mat rows_add = cv::Mat_<float>(1, 1) << rows_proj.at<float> (0, 0);
cv::Mat cols_add = cv::Mat_<float>(1, 1) << cols_proj.at<float> (0, 0);
diff --git a/modules/ocl/cv_edgetaper.h b/modules/ocv/cv_edgetaper.h
index 1ead29f..641c266 100644
--- a/modules/ocl/cv_edgetaper.h
+++ b/modules/ocv/cv_edgetaper.h
@@ -22,20 +22,14 @@
#ifndef XCAM_CV_EDGETAPER_H
#define XCAM_CV_EDGETAPER_H
-#include <xcam_std.h>
-#include <ocl/cv_base_class.h>
-
-#include <opencv2/opencv.hpp>
-#include <opencv2/core/ocl.hpp>
+#include "cv_std.h"
namespace XCam {
-
-class CVEdgetaper : public CVBaseClass
+class CVEdgetaper
{
-
public:
- explicit CVEdgetaper ();
+ explicit CVEdgetaper () {}
void edgetaper (const cv::Mat &image, const cv::Mat &psf, cv::Mat &output);
private:
diff --git a/modules/ocl/cv_feature_match.cpp b/modules/ocv/cv_feature_match.cpp
index e4e2ea8..ea04c0e 100644
--- a/modules/ocl/cv_feature_match.cpp
+++ b/modules/ocv/cv_feature_match.cpp
@@ -19,37 +19,63 @@
* Author: Yinhang Liu <yinhangx.liu@intel.com>
*/
-#include "cv_feature_match.h"
#include "xcam_obj_debug.h"
#include "image_file_handle.h"
-#include "cl_utils.h"
+#include "cv_feature_match.h"
+#if HAVE_LIBCL
+#include <opencv2/core/ocl.hpp>
+#endif
#define XCAM_CV_FM_DEBUG 0
#define XCAM_CV_OF_DRAW_SCALE 2
namespace XCam {
-#if XCAM_CV_FM_DEBUG
-static void debug_write_image (
- const SmartPtr<VideoBuffer> &buf, const Rect &rect, char *img_name, char *frame_str, char *fm_idx_str);
-#endif
-
CVFeatureMatch::CVFeatureMatch ()
- : CVBaseClass ()
- , FeatureMatch ()
+ : FeatureMatch ()
+ , _dst_width (0)
+ , _need_adjust (false)
+{
+ xcam_mem_clear (_cl_buf_mem);
+}
+
+CVFeatureMatch::~CVFeatureMatch ()
+{
+ xcam_mem_clear (_cl_buf_mem);
+}
+
+
+void
+CVFeatureMatch::set_dst_width (int width)
{
- XCAM_ASSERT (_cv_context.ptr ());
+ _dst_width = width;
+}
+
+void
+CVFeatureMatch::enable_adjust_crop_area ()
+{
+ _need_adjust = true;
+}
+
+void
+CVFeatureMatch::set_cl_buf_mem (void *mem, BufId id)
+{
+#if HAVE_LIBCL
+ XCAM_ASSERT (mem);
+ _cl_buf_mem[id] = mem;
+#else
+ XCAM_LOG_DEBUG ("non-OpenCL mode, failed to set cl buffer memory");
+#endif
}
bool
-CVFeatureMatch::get_crop_image (
- const SmartPtr<VideoBuffer> &buffer, const Rect &crop_rect, cv::UMat &img)
+CVFeatureMatch::get_crop_image_umat (
+ const SmartPtr<VideoBuffer> &buffer, const Rect &crop_rect, cv::UMat &img, BufId id)
{
- SmartPtr<CLBuffer> cl_buffer = convert_to_clbuffer (_cv_context->get_cl_context (), buffer);
+#if HAVE_LIBCL
VideoBufferInfo info = buffer->get_video_info ();
- cl_mem cl_mem_id = cl_buffer->get_mem_id ();
cv::UMat umat;
- cv::ocl::convertFromBuffer (cl_mem_id, info.strides[0], info.height, info.width, CV_8U, umat);
+ cv::ocl::convertFromBuffer (_cl_buf_mem[id], info.strides[0], info.height, info.width, CV_8U, umat);
if (umat.empty ()) {
XCAM_LOG_ERROR ("FeatureMatch(idx:%d): convert bo buffer to UMat failed", _fm_idx);
return false;
@@ -58,11 +84,15 @@ CVFeatureMatch::get_crop_image (
img = umat (cv::Rect(crop_rect.pos_x, crop_rect.pos_y, crop_rect.width, crop_rect.height));
return true;
+#else
+ XCAM_LOG_ERROR ("FeatureMatch(idx:%d): non-OpenCL mode, failed to get umat", _fm_idx);
+ return false;
+#endif
}
void
CVFeatureMatch::add_detected_data (
- cv::InputArray image, cv::Ptr<cv::Feature2D> detector, std::vector<cv::Point2f> &corners)
+ cv::Mat image, cv::Ptr<cv::Feature2D> detector, std::vector<cv::Point2f> &corners)
{
std::vector<cv::KeyPoint> keypoints;
detector->detect (image, keypoints);
@@ -78,7 +108,7 @@ CVFeatureMatch::get_valid_offsets (
std::vector<cv::Point2f> &corner0, std::vector<cv::Point2f> &corner1,
std::vector<uchar> &status, std::vector<float> &error,
std::vector<float> &offsets, float &sum, int &count,
- cv::InputOutputArray debug_img, cv::Size &img0_size)
+ cv::Mat debug_img, cv::Size &img0_size)
{
count = 0;
sum = 0.0f;
@@ -114,37 +144,24 @@ CVFeatureMatch::get_valid_offsets (
void
CVFeatureMatch::calc_of_match (
- cv::InputArray image0, cv::InputArray image1,
- std::vector<cv::Point2f> &corner0, std::vector<cv::Point2f> &corner1,
- std::vector<uchar> &status, std::vector<float> &error,
- int &last_count, float &last_mean_offset, float &out_x_offset)
+ cv::Mat image0, cv::Mat image1, std::vector<cv::Point2f> &corner0, std::vector<cv::Point2f> &corner1,
+ std::vector<uchar> &status, std::vector<float> &error)
{
- cv::_InputOutputArray debug_img;
+ cv::Mat debug_img;
cv::Size img0_size = image0.size ();
- XCAM_ASSERT (img0_size.height == image1.rows ());
- XCAM_UNUSED (image1);
+ cv::Size img1_size = image1.size ();
+ XCAM_ASSERT (img0_size.height == img1_size.height);
#if XCAM_CV_FM_DEBUG
cv::Mat mat;
- cv::UMat umat;
- cv::Size img1_size = image1.size ();
cv::Size size (img0_size.width + img1_size.width, img0_size.height);
- if (image0.isUMat ()) {
- umat.create (size, image0.type ());
- debug_img = cv::_InputOutputArray (umat);
+ mat.create (size, image0.type ());
+ debug_img = cv::Mat (mat);
- image0.copyTo (umat (cv::Rect(0, 0, img0_size.width, img0_size.height)));
- image1.copyTo (umat (cv::Rect(img0_size.width, 0, img1_size.width, img1_size.height)));
- umat.copyTo (debug_img);
- } else {
- mat.create (size, image0.type ());
- debug_img = cv::_InputOutputArray (mat);
-
- image0.copyTo (mat (cv::Rect(0, 0, img0_size.width, img0_size.height)));
- image1.copyTo (mat (cv::Rect(img0_size.width, 0, img1_size.width, img1_size.height)));
- mat.copyTo (debug_img);
- }
+ image0.copyTo (mat (cv::Rect(0, 0, img0_size.width, img0_size.height)));
+ image1.copyTo (mat (cv::Rect(img0_size.width, 0, img1_size.width, img1_size.height)));
+ mat.copyTo (debug_img);
cv::Size scale_size = size * XCAM_CV_OF_DRAW_SCALE;
cv::resize (debug_img, debug_img, scale_size, 0, 0);
@@ -154,6 +171,7 @@ CVFeatureMatch::calc_of_match (
float offset_sum = 0.0f;
int count = 0;
float mean_offset = 0.0f;
+ float last_mean_offset = _mean_offset;
offsets.reserve (corner0.size ());
get_valid_offsets (corner0, corner1, status, error,
offsets, offset_sum, count, debug_img, img0_size);
@@ -167,21 +185,48 @@ CVFeatureMatch::calc_of_match (
bool ret = get_mean_offset (offsets, offset_sum, count, mean_offset);
if (ret) {
if (fabs (mean_offset - last_mean_offset) < _config.delta_mean_offset) {
- out_x_offset = out_x_offset * _config.offset_factor + mean_offset * (1.0f - _config.offset_factor);
+ _x_offset = _x_offset * _config.offset_factor + mean_offset * (1.0f - _config.offset_factor);
- if (fabs (out_x_offset) > _config.max_adjusted_offset)
- out_x_offset = (out_x_offset > 0.0f) ? _config.max_adjusted_offset : (-_config.max_adjusted_offset);
+ if (fabs (_x_offset) > _config.max_adjusted_offset)
+ _x_offset = (_x_offset > 0.0f) ? _config.max_adjusted_offset : (-_config.max_adjusted_offset);
}
}
- last_count = count;
- last_mean_offset = mean_offset;
+ _valid_count = count;
+ _mean_offset = mean_offset;
+}
+
+void
+CVFeatureMatch::adjust_crop_area ()
+{
+ if (fabs (_x_offset) < 5.0f)
+ return;
+
+ XCAM_ASSERT (_dst_width);
+
+ int last_overlap_width = _right_rect.pos_x + _right_rect.width +
+ (_dst_width - (_left_rect.pos_x + _left_rect.width));
+ // int final_overlap_width = _right_rect.pos_x + _right_rect.width +
+ // (dst_width - (_left_rect.pos_x - x_offset + _left_rect.width));
+ if ((_left_rect.pos_x - _x_offset + _left_rect.width) > _dst_width)
+ _x_offset = _dst_width - (_left_rect.pos_x + _left_rect.width);
+ int final_overlap_width = last_overlap_width + _x_offset;
+ final_overlap_width = XCAM_ALIGN_AROUND (final_overlap_width, 8);
+ XCAM_ASSERT (final_overlap_width >= _config.sitch_min_width);
+ int center = final_overlap_width / 2;
+ XCAM_ASSERT (center >= _config.sitch_min_width / 2);
+
+ _right_rect.pos_x = XCAM_ALIGN_AROUND (center - _config.sitch_min_width / 2, 8);
+ _right_rect.width = _config.sitch_min_width;
+ _left_rect.pos_x = _dst_width - final_overlap_width + _right_rect.pos_x;
+ _left_rect.width = _config.sitch_min_width;
+
+ float delta_offset = final_overlap_width - last_overlap_width;
+ _x_offset -= delta_offset;
}
void
-CVFeatureMatch::detect_and_match (
- cv::InputArray img_left, cv::InputArray img_right, Rect &crop_left, Rect &crop_right,
- int &valid_count, float &mean_offset, float &x_offset, int dst_width)
+CVFeatureMatch::detect_and_match (cv::Mat img_left, cv::Mat img_right)
{
std::vector<float> err;
std::vector<uchar> status;
@@ -189,9 +234,6 @@ CVFeatureMatch::detect_and_match (
cv::Ptr<cv::Feature2D> fast_detector;
cv::Size win_size = cv::Size (5, 5);
- if (img_left.isUMat ())
- win_size = cv::Size (16, 16);
-
fast_detector = cv::FastFeatureDetector::create (20, true);
add_detected_data (img_left, fast_detector, corner_left);
@@ -202,91 +244,82 @@ CVFeatureMatch::detect_and_match (
cv::calcOpticalFlowPyrLK (
img_left, img_right, corner_left, corner_right, status, err, win_size, 3,
cv::TermCriteria (cv::TermCriteria::COUNT + cv::TermCriteria::EPS, 10, 0.01f));
- cv::ocl::finish();
- calc_of_match (img_left, img_right, corner_left, corner_right,
- status, err, valid_count, mean_offset, x_offset);
+ calc_of_match (img_left, img_right, corner_left, corner_right, status, err);
- adjust_stitch_area (dst_width, x_offset, crop_left, crop_right);
+ if (_need_adjust)
+ adjust_crop_area ();
#if XCAM_CV_FM_DEBUG
- XCAM_LOG_INFO (
- "FeatureMatch(idx:%d): stiching area: left_area(pos_x:%d, width:%d), right_area(pos_x:%d, width:%d)",
- _fm_idx, crop_left.pos_x, crop_left.width, crop_right.pos_x, crop_right.width);
+ XCAM_LOG_INFO ("FeatureMatch(idx:%d): x_offset:%0.2f", _fm_idx, _x_offset);
+ if (_need_adjust) {
+ XCAM_LOG_INFO (
+ "FeatureMatch(idx:%d): stiching area: left_area(pos_x:%d, width:%d), right_area(pos_x:%d, width:%d)",
+ _fm_idx, _left_rect.pos_x, _left_rect.width, _right_rect.pos_x, _right_rect.width);
+ }
#endif
}
void
-CVFeatureMatch::optical_flow_feature_match (
- const SmartPtr<VideoBuffer> &left_buf, const SmartPtr<VideoBuffer> &right_buf,
- Rect &left_crop_rect, Rect &right_crop_rect, int dst_width)
+CVFeatureMatch::feature_match (
+ const SmartPtr<VideoBuffer> &left_buf, const SmartPtr<VideoBuffer> &right_buf)
{
+ XCAM_ASSERT (_left_rect.width && _left_rect.height);
+ XCAM_ASSERT (_right_rect.width && _right_rect.height);
+
cv::UMat left_umat, right_umat;
- cv::Mat left_mat, right_mat;
- cv::_InputArray left_img, right_img;
+ cv::Mat left_img, right_img;
- if (!get_crop_image (left_buf, left_crop_rect, left_umat)
- || !get_crop_image (right_buf, right_crop_rect, right_umat))
- return;
+ if (_cl_buf_mem[BufIdLeft] && _cl_buf_mem[BufIdRight]) {
+ if (!get_crop_image_umat (left_buf, _left_rect, left_umat, BufIdLeft)
+ || !get_crop_image_umat (right_buf, _right_rect, right_umat, BufIdRight))
+ return;
- if (_use_ocl) {
- left_img = cv::_InputArray (left_umat);
- right_img = cv::_InputArray (right_umat);
+ left_img = left_umat.getMat (cv::ACCESS_READ);
+ right_img = right_umat.getMat (cv::ACCESS_READ);
} else {
- left_mat = left_umat.getMat (cv::ACCESS_READ);
- right_mat = right_umat.getMat (cv::ACCESS_READ);
-
- left_img = cv::_InputArray (left_mat);
- right_img = cv::_InputArray (right_mat);
+ if (!convert_range_to_mat (left_buf, _left_rect, left_img)
+ || !convert_range_to_mat (right_buf, _right_rect, right_img))
+ return;
}
- detect_and_match (left_img, right_img, left_crop_rect, right_crop_rect,
- _valid_count, _mean_offset, _x_offset, dst_width);
+ detect_and_match (left_img, right_img);
#if XCAM_CV_FM_DEBUG
- XCAM_ASSERT (_fm_idx >= 0);
+ debug_write_image (left_buf, right_buf, _left_rect, _right_rect, _frame_num, _fm_idx);
+ _frame_num++;
+#endif
+}
+
+void
+CVFeatureMatch::debug_write_image (
+ const SmartPtr<VideoBuffer> &left_buf, const SmartPtr<VideoBuffer> &right_buf,
+ const Rect &left_rect, const Rect &right_rect, uint32_t frame_num, int fm_idx)
+{
+ XCAM_ASSERT (fm_idx >= 0);
char frame_str[64] = {'\0'};
- std::snprintf (frame_str, 64, "frame:%d", _frame_num);
+ std::snprintf (frame_str, 64, "frame:%d", frame_num);
char fm_idx_str[64] = {'\0'};
- std::snprintf (fm_idx_str, 64, "fm_idx:%d", _fm_idx);
+ std::snprintf (fm_idx_str, 64, "fm_idx:%d", fm_idx);
char img_name[256] = {'\0'};
- std::snprintf (img_name, 256, "fm_in_stitch_area_%d_%d_0.jpg", _frame_num, _fm_idx);
- debug_write_image (left_buf, left_crop_rect, img_name, frame_str, fm_idx_str);
+ std::snprintf (img_name, 256, "fm_in_stitch_area_%d_%d_0.jpg", frame_num, fm_idx);
+ write_image (left_buf, left_rect, img_name, frame_str, fm_idx_str);
- std::snprintf (img_name, 256, "fm_in_stitch_area_%d_%d_1.jpg", _frame_num, _fm_idx);
- debug_write_image (right_buf, right_crop_rect, img_name, frame_str, fm_idx_str);
+ std::snprintf (img_name, 256, "fm_in_stitch_area_%d_%d_1.jpg", frame_num, fm_idx);
+ write_image (right_buf, right_rect, img_name, frame_str, fm_idx_str);
- XCAM_LOG_INFO ("FeatureMatch(idx:%d): frame number:%d done", _fm_idx, _frame_num);
- _frame_num++;
-#endif
+ XCAM_LOG_INFO ("FeatureMatch(idx:%d): frame number:%d done", fm_idx, frame_num);
}
-#if XCAM_CV_FM_DEBUG
-static void
-debug_write_image (
- const SmartPtr<VideoBuffer> &buf, const Rect &rect, char *img_name, char *frame_str, char *fm_idx_str)
+SmartPtr<FeatureMatch>
+FeatureMatch::create_default_feature_match ()
{
- cv::Scalar color = cv::Scalar(0, 0, 255);
- VideoBufferInfo info = buf->get_video_info ();
-
- cv::Mat mat;
- CVBaseClass cv_obj;
- cv_obj.convert_to_mat (buf, mat);
-
- cv::putText (mat, frame_str, cv::Point(rect.pos_x, 30), cv::FONT_HERSHEY_COMPLEX, 0.8f, color, 2, 8, false);
- cv::putText (mat, fm_idx_str, cv::Point(rect.pos_x, 70), cv::FONT_HERSHEY_COMPLEX, 0.8f, color, 2, 8, false);
+ SmartPtr<CVFeatureMatch> matcher = new CVFeatureMatch ();
+ XCAM_ASSERT (matcher.ptr ());
- cv::line (mat, cv::Point(rect.pos_x, rect.pos_y), cv::Point(rect.pos_x + rect.width, rect.pos_y), color, 1);
- cv::line (mat, cv::Point(rect.pos_x, rect.pos_y + rect.height),
- cv::Point(rect.pos_x + rect.width, rect.pos_y + rect.height), color, 1);
-
- cv::line (mat, cv::Point(rect.pos_x, 0), cv::Point(rect.pos_x, info.height), color, 2);
- cv::line (mat, cv::Point(rect.pos_x + rect.width, 0), cv::Point(rect.pos_x + rect.width, info.height), color, 2);
-
- cv::imwrite (img_name, mat);
+ return matcher;
}
-#endif
}
diff --git a/modules/ocv/cv_feature_match.h b/modules/ocv/cv_feature_match.h
new file mode 100644
index 0000000..5d2fbc7
--- /dev/null
+++ b/modules/ocv/cv_feature_match.h
@@ -0,0 +1,88 @@
+/*
+ * cv_feature_match.h - optical flow feature match
+ *
+ * Copyright (c) 2016-2017 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#ifndef XCAM_CV_FEATURE_MATCH_H
+#define XCAM_CV_FEATURE_MATCH_H
+
+#include <video_buffer.h>
+#include <interface/feature_match.h>
+#include "cv_utils.h"
+
+namespace XCam {
+
+class CVFeatureMatch
+ : public FeatureMatch
+{
+public:
+ enum BufId {
+ BufIdLeft = 0,
+ BufIdRight,
+ BufIdMax
+ };
+
+public:
+ explicit CVFeatureMatch ();
+ virtual ~CVFeatureMatch ();
+
+ virtual void feature_match (
+ const SmartPtr<VideoBuffer> &left_buf, const SmartPtr<VideoBuffer> &right_buf);
+
+ void set_cl_buf_mem (void *mem, BufId id);
+
+protected:
+ bool get_crop_image_umat (const SmartPtr<VideoBuffer> &buffer, const Rect &crop_rect, cv::UMat &img, BufId id);
+ void add_detected_data (cv::Mat image, cv::Ptr<cv::Feature2D> detector, std::vector<cv::Point2f> &corners);
+
+ void debug_write_image (
+ const SmartPtr<VideoBuffer> &left_buf, const SmartPtr<VideoBuffer> &right_buf,
+ const Rect &left_rect, const Rect &right_rect, uint32_t frame_num, int fm_idx);
+
+private:
+ virtual void detect_and_match (cv::Mat img_left, cv::Mat img_right);
+ virtual void calc_of_match (
+ cv::Mat image0, cv::Mat image1, std::vector<cv::Point2f> &corner0, std::vector<cv::Point2f> &corner1,
+ std::vector<uchar> &status, std::vector<float> &error);
+
+ void get_valid_offsets (
+ std::vector<cv::Point2f> &corner0, std::vector<cv::Point2f> &corner1,
+ std::vector<uchar> &status, std::vector<float> &error,
+ std::vector<float> &offsets, float &sum, int &count,
+ cv::Mat debug_img, cv::Size &img0_size);
+
+ void adjust_crop_area ();
+
+ virtual void set_dst_width (int width);
+ virtual void enable_adjust_crop_area ();
+
+private:
+ XCAM_DEAD_COPY (CVFeatureMatch);
+
+protected:
+ void *_cl_buf_mem[BufIdMax];
+
+private:
+ int _dst_width;
+ bool _need_adjust;
+};
+
+}
+
+#endif // XCAM_CV_FEATURE_MATCH_H
diff --git a/modules/ocv/cv_feature_match_cluster.cpp b/modules/ocv/cv_feature_match_cluster.cpp
new file mode 100644
index 0000000..6bc0415
--- /dev/null
+++ b/modules/ocv/cv_feature_match_cluster.cpp
@@ -0,0 +1,316 @@
+/*
+ * cv_feature_match_cluster.cpp - optical flow feature match selected by clustering
+ *
+ * Copyright (c) 2016-2017 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wu Junkai <junkai.wu@intel.com>
+ */
+
+#include "xcam_obj_debug.h"
+#include "image_file_handle.h"
+#include "cv_feature_match_cluster.h"
+
+#define XCAM_CV_FM_DEBUG 0
+#define XCAM_CV_OF_DRAW_SCALE 2
+
+namespace XCam {
+CVFeatureMatchCluster::CVFeatureMatchCluster ()
+ : CVFeatureMatch ()
+{
+}
+
+bool
+CVFeatureMatchCluster::calc_mean_offset (
+ std::vector<cv::Point2f> &corner0, std::vector<cv::Point2f> &corner1,
+ std::vector<uchar> &status, std::vector<float> &error,
+ float &mean_offset_x, float &mean_offset_y,
+ cv::Mat debug_img, cv::Size &img0_size, cv::Size &img1_size)
+{
+ std::vector<std::vector<uint32_t>> clusters;
+ std::vector<std::vector<cv::Point2f>> clusters_offsets;
+ std::vector<uint32_t> valid_seeds (status.size ());
+ std::vector<uint32_t> valid_corners (status.size ());
+
+ for (uint32_t i = 0; i < status.size (); ++i) {
+ if (!status[i] || (error[i] > _config.max_track_error) || corner1[i].x < 0.0f || corner1[i].x > img0_size.width) {
+ valid_corners[i] = 0;
+ valid_seeds[i] = 0;
+ } else {
+ valid_corners[i] = 1;
+ valid_seeds[i] = 1;
+ }
+ }
+
+ float seed_x_offset = 0.0f;
+ float seed_y_offset = 0.0f;
+
+ std::vector<uint32_t> cluster (1);
+ std::vector<cv::Point2f> cluster_offset (1);
+
+ float thres = 8.0f;
+ while (cluster.size() > 0) {
+ cluster.clear ();
+ cluster_offset.clear ();
+
+ for (uint32_t i = 0; i < status.size (); ++i) {
+ if (valid_seeds[i]) {
+ seed_x_offset = corner1[i].x - corner0[i].x;
+ seed_y_offset = corner1[i].y - corner0[i].y;
+ cluster.push_back (i);
+ cluster_offset.push_back (cv::Point2f(seed_x_offset, seed_y_offset));
+ valid_corners[i] = 0;
+ valid_seeds[i] = 0;
+ break;
+ }
+ }
+
+ if (cluster.size() > 0) {
+ for (uint32_t i = 0; i < status.size (); ++i) {
+ if (!valid_corners[i])
+ continue;
+
+ float x_offset = corner1[i].x - corner0[i].x;
+ float y_offset = corner1[i].y - corner0[i].y;
+
+ if (fabs (x_offset - seed_x_offset) > thres || fabs (y_offset - seed_y_offset) > thres / 2.0f)
+ continue;
+
+ cluster.push_back (i);
+ cluster_offset.push_back (cv::Point2f(x_offset, y_offset));
+ valid_seeds[i] = 0;
+ }
+
+ clusters.push_back (cluster);
+ clusters_offsets.push_back (cluster_offset);
+ }
+ }
+
+ if (clusters_offsets.size () == 0)
+ return false;
+
+ uint32_t max_size = 0;
+ uint32_t max_index = 0;
+
+ for (uint32_t i = 0; i < clusters.size (); ++i) {
+ if (clusters[i].size () > max_size) {
+ max_size = clusters[i].size ();
+ max_index = i;
+ }
+ }
+
+ if (clusters_offsets[max_index].size () < (uint32_t)_config.min_corners)
+ return false;
+
+ float sum_x = 0.0f;
+ float sum_y = 0.0f;
+ for (uint32_t i = 0; i < clusters_offsets[max_index].size (); ++i) {
+ sum_x += clusters_offsets[max_index][i].x;
+ sum_y += clusters_offsets[max_index][i].y;
+ }
+
+ mean_offset_x = sum_x / clusters_offsets[max_index].size ();
+ mean_offset_y = sum_y / clusters_offsets[max_index].size ();
+
+#if XCAM_CV_FM_DEBUG
+ for (uint32_t i = 0; i < status.size (); ++i) {
+ if(!status[i])
+ continue;
+
+ cv::Point start = cv::Point(corner0[i]) * XCAM_CV_OF_DRAW_SCALE;
+ cv::circle (debug_img, start, 4, cv::Scalar(0), XCAM_CV_OF_DRAW_SCALE);
+ cv::Point end = (cv::Point(corner1[i]) + cv::Point (img0_size.width, 0)) * XCAM_CV_OF_DRAW_SCALE;
+ cv::line (debug_img, start, end, cv::Scalar(0), XCAM_CV_OF_DRAW_SCALE);
+ }
+
+ for (uint32_t i = 0; i < status.size (); ++i) {
+ if (!status[i])
+ continue;
+
+ cv::Point start = cv::Point(corner0[i]) * XCAM_CV_OF_DRAW_SCALE;
+ cv::circle (debug_img, start, 4, cv::Scalar(0), XCAM_CV_OF_DRAW_SCALE);
+ if (error[i] > _config.max_track_error)
+ continue;
+ if (fabs(corner0[i].y - corner1[i].y) >= _config.max_valid_offset_y)
+ continue;
+ if (corner1[i].x < 0.0f || corner1[i].x > img0_size.width)
+ continue;
+
+ cv::Point end = (cv::Point(corner1[i]) + cv::Point (img0_size.width, 0)) * XCAM_CV_OF_DRAW_SCALE;
+ cv::line (debug_img, start, end, cv::Scalar(255), XCAM_CV_OF_DRAW_SCALE);
+ }
+
+ for (uint32_t i = 0; i < status.size (); ++i) {
+ if(!status[i])
+ continue;
+
+ cv::Point start = (cv::Point(corner0[i]) + cv::Point (img0_size.width + img1_size.width, 0)) * XCAM_CV_OF_DRAW_SCALE;
+ cv::circle (debug_img, start, 4, cv::Scalar(0), XCAM_CV_OF_DRAW_SCALE);
+ cv::Point end = (cv::Point(corner1[i]) + cv::Point (2 * img0_size.width + img1_size.width, 0)) * XCAM_CV_OF_DRAW_SCALE;
+ cv::line (debug_img, start, end, cv::Scalar(0), XCAM_CV_OF_DRAW_SCALE);
+ }
+
+ if (clusters.size () != 0)
+ cluster = clusters[max_index];
+ for (uint32_t i = 0; i < cluster.size (); ++i) {
+ cv::Point start = (cv::Point(corner0[cluster[i]]) + cv::Point(img0_size.width + img1_size.width, 0)) * XCAM_CV_OF_DRAW_SCALE;
+ cv::circle (debug_img, start, 4, cv::Scalar(0), XCAM_CV_OF_DRAW_SCALE);
+ cv::Point end = (cv::Point(corner1[cluster[i]]) + cv::Point (2 * img0_size.width + img1_size.width, 0)) * XCAM_CV_OF_DRAW_SCALE;
+ cv::line (debug_img, start, end, cv::Scalar(255), XCAM_CV_OF_DRAW_SCALE);
+ }
+
+#endif
+
+ XCAM_UNUSED (debug_img);
+ XCAM_UNUSED (img0_size);
+ XCAM_UNUSED (img1_size);
+
+ clusters.clear ();
+ clusters_offsets.clear ();
+
+ return true;
+}
+
+void
+CVFeatureMatchCluster::calc_of_match (
+ cv::Mat image0, cv::Mat image1, std::vector<cv::Point2f> &corner0, std::vector<cv::Point2f> &corner1,
+ std::vector<uchar> &status, std::vector<float> &error)
+{
+ cv::Mat debug_img;
+ cv::Size img0_size = image0.size ();
+ cv::Size img1_size = image1.size ();
+ XCAM_ASSERT (img0_size.height == img1_size.height);
+
+#if XCAM_CV_FM_DEBUG
+ cv::Mat mat;
+ cv::Size size ((img0_size.width + img1_size.width) * 2, img0_size.height);
+
+ mat.create (size, image0.type ());
+ debug_img = cv::Mat (mat);
+
+ image0.copyTo (mat (cv::Rect(0, 0, img0_size.width, img0_size.height)));
+ image1.copyTo (mat (cv::Rect(img0_size.width, 0, img1_size.width, img1_size.height)));
+ image0.copyTo (mat (cv::Rect(img0_size.width + img1_size.width, 0, img0_size.width, img0_size.height)));
+ image1.copyTo (mat (cv::Rect(2 * img0_size.width + img1_size.width, 0, img1_size.width, img1_size.height)));
+
+ mat.copyTo (debug_img);
+
+ cv::Size scale_size = size * XCAM_CV_OF_DRAW_SCALE;
+ cv::resize (debug_img, debug_img, scale_size, 0, 0);
+#endif
+
+ float mean_offset_x = 0.0f;
+ float mean_offset_y = 0.0f;
+ float last_mean_offset_x = _mean_offset;
+ float last_mean_offset_y = _mean_offset_y;
+ bool ret = calc_mean_offset (corner0, corner1, status, error, mean_offset_x, mean_offset_y,
+ debug_img, img0_size, img1_size);
+
+#if XCAM_CV_FM_DEBUG
+ char file_name[256];
+ std::snprintf (file_name, 256, "fm_optical_flow_%d_%d.jpg", _frame_num, _fm_idx);
+ cv::imwrite (file_name, debug_img);
+#endif
+
+ if (ret) {
+ if (fabs (mean_offset_x - last_mean_offset_x) < _config.delta_mean_offset) {
+ _x_offset = _x_offset * _config.offset_factor + mean_offset_x * (1.0f - _config.offset_factor);
+
+ if (fabs (_x_offset) > _config.max_adjusted_offset)
+ _x_offset = (_x_offset > 0.0f) ? _config.max_adjusted_offset : (-_config.max_adjusted_offset);
+ }
+
+ if (fabs (mean_offset_y - last_mean_offset_y) < _config.delta_mean_offset) {
+ _y_offset = _y_offset * _config.offset_factor + mean_offset_y * (1.0f - _config.offset_factor);
+
+ if (fabs (_y_offset) > _config.max_adjusted_offset)
+ _y_offset = (_y_offset > 0.0f) ? _config.max_adjusted_offset : (-_config.max_adjusted_offset);
+ }
+ }
+
+ _mean_offset = mean_offset_x;
+ _mean_offset_y = mean_offset_y;
+}
+
+void
+CVFeatureMatchCluster::detect_and_match (cv::Mat img_left, cv::Mat img_right)
+{
+ std::vector<float> err;
+ std::vector<uchar> status;
+ std::vector<cv::Point2f> corner_left, corner_right;
+ cv::Ptr<cv::Feature2D> fast_detector;
+ cv::Size win_size = cv::Size (21, 21);
+
+ fast_detector = cv::FastFeatureDetector::create (20, true);
+ add_detected_data (img_left, fast_detector, corner_left);
+
+ if (corner_left.empty ()) {
+ return;
+ }
+
+ cv::calcOpticalFlowPyrLK (
+ img_left, img_right, corner_left, corner_right, status, err, win_size, 3,
+ cv::TermCriteria (cv::TermCriteria::COUNT + cv::TermCriteria::EPS, 30, 0.01f));
+
+ calc_of_match (img_left, img_right, corner_left, corner_right, status, err);
+
+#if XCAM_CV_FM_DEBUG
+ XCAM_LOG_INFO ("x_offset:%0.2f", _x_offset);
+ XCAM_LOG_INFO (
+ "FeatureMatch(idx:%d): stiching area: left_area(pos_x:%d, width:%d), right_area(pos_x:%d, width:%d)",
+ _fm_idx, _left_rect.pos_x, _left_rect.width, _right_rect.pos_x, _right_rect.width);
+#endif
+}
+
+void
+CVFeatureMatchCluster::feature_match (
+ const SmartPtr<VideoBuffer> &left_buf, const SmartPtr<VideoBuffer> &right_buf)
+{
+ XCAM_ASSERT (_left_rect.width && _left_rect.height);
+ XCAM_ASSERT (_right_rect.width && _right_rect.height);
+
+ cv::UMat left_umat, right_umat;
+ cv::Mat left_img, right_img;
+
+ if (_cl_buf_mem[BufIdLeft] && _cl_buf_mem[BufIdRight]) {
+ if (!get_crop_image_umat (left_buf, _left_rect, left_umat, BufIdLeft)
+ || !get_crop_image_umat (right_buf, _right_rect, right_umat, BufIdRight))
+ return;
+
+ left_img = left_umat.getMat (cv::ACCESS_READ);
+ right_img = right_umat.getMat (cv::ACCESS_READ);
+ } else {
+ if (!convert_range_to_mat (left_buf, _left_rect, left_img)
+ || !convert_range_to_mat (right_buf, _right_rect, right_img))
+ return;
+ }
+
+ detect_and_match (left_img, right_img);
+
+#if XCAM_CV_FM_DEBUG
+ debug_write_image (left_buf, right_buf, _left_rect, _right_rect, _frame_num, _fm_idx);
+ _frame_num++;
+#endif
+}
+
+SmartPtr<FeatureMatch>
+FeatureMatch::create_cluster_feature_match ()
+{
+ SmartPtr<CVFeatureMatchCluster> matcher = new CVFeatureMatchCluster ();
+ XCAM_ASSERT (matcher.ptr ());
+
+ return matcher;
+}
+
+}
diff --git a/modules/ocv/cv_feature_match_cluster.h b/modules/ocv/cv_feature_match_cluster.h
new file mode 100644
index 0000000..1b1fcdb
--- /dev/null
+++ b/modules/ocv/cv_feature_match_cluster.h
@@ -0,0 +1,55 @@
+/*
+ * cv_feature_match_cluster.h - optical flow feature match selected by clustering
+ *
+ * Copyright (c) 2016-2017 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wu Junkai <junkai.Wu@intel.com>
+ */
+
+#ifndef XCAM_CV_FEATURE_MATCH_CLUSTER_H
+#define XCAM_CV_FEATURE_MATCH_CLUSTER_H
+
+#include "cv_feature_match.h"
+
+namespace XCam {
+
+class CVFeatureMatchCluster
+ : public CVFeatureMatch
+{
+public:
+ explicit CVFeatureMatchCluster ();
+
+ virtual void feature_match (
+ const SmartPtr<VideoBuffer> &left_buf, const SmartPtr<VideoBuffer> &right_buf);
+
+private:
+ virtual void detect_and_match (cv::Mat img_left, cv::Mat img_right);
+ virtual void calc_of_match (
+ cv::Mat image0, cv::Mat image1, std::vector<cv::Point2f> &corner0,
+ std::vector<cv::Point2f> &corner1, std::vector<uchar> &status, std::vector<float> &error);
+
+ bool calc_mean_offset (
+ std::vector<cv::Point2f> &corner0, std::vector<cv::Point2f> &corner1, std::vector<uchar> &status,
+ std::vector<float> &error, float &mean_offset_x, float &mean_offset_y,
+ cv::Mat debug_img, cv::Size &img0_size, cv::Size &img1_size);
+
+private:
+ XCAM_DEAD_COPY (CVFeatureMatchCluster);
+
+};
+
+}
+
+#endif // XCAM_CV_FEATURE_MATCH_CLUSTER_H
diff --git a/modules/ocl/cv_image_deblurring.cpp b/modules/ocv/cv_image_deblurring.cpp
index 730eb42..4c4dbf0 100644
--- a/modules/ocl/cv_image_deblurring.cpp
+++ b/modules/ocv/cv_image_deblurring.cpp
@@ -23,9 +23,7 @@
namespace XCam {
-
CVImageDeblurring::CVImageDeblurring ()
- : CVBaseClass ()
{
_helper = new CVImageProcessHelper ();
_sharp = new CVImageSharp ();
@@ -155,7 +153,7 @@ void
CVImageDeblurring::blind_deblurring (const cv::Mat &blurred, cv::Mat &deblurred, cv::Mat &kernel, int kernel_size, float noise_power, bool use_edgetaper)
{
cv::Mat gray_blurred;
- cv::cvtColor (blurred, gray_blurred, CV_BGR2GRAY);
+ cv::cvtColor (blurred, gray_blurred, cv::COLOR_BGR2GRAY);
if (noise_power < 0)
{
cv::Mat median_blurred;
@@ -196,7 +194,7 @@ CVImageDeblurring::blind_deblurring (const cv::Mat &blurred, cv::Mat &deblurred,
}
cv::merge (deblurred_rgb, result_deblurred);
result_deblurred.convertTo (result_deblurred, CV_8UC3);
- fastNlMeansDenoisingColored (result_deblurred, deblurred, 3, 3, 7, 21);
+ cv::fastNlMeansDenoisingColored (result_deblurred, deblurred, 3, 3, 7, 21);
kernel = result_kernel.clone ();
}
diff --git a/modules/ocl/cv_image_deblurring.h b/modules/ocv/cv_image_deblurring.h
index afac22c..cd28786 100644
--- a/modules/ocl/cv_image_deblurring.h
+++ b/modules/ocv/cv_image_deblurring.h
@@ -22,13 +22,12 @@
#ifndef XCAM_CV_FEATURE_DEBLURRING_H
#define XCAM_CV_FEATURE_DEBLURRING_H
-#include <xcam_std.h>
#include <video_buffer.h>
-#include <ocl/cv_base_class.h>
-#include <ocl/cv_image_process_helper.h>
-#include <ocl/cv_image_sharp.h>
-#include <ocl/cv_edgetaper.h>
-#include <ocl/cv_wiener_filter.h>
+#include "cv_std.h"
+#include "cv_image_process_helper.h"
+#include "cv_image_sharp.h"
+#include "cv_edgetaper.h"
+#include "cv_wiener_filter.h"
namespace XCam {
@@ -41,9 +40,8 @@ struct CVIDConfig {
}
};
-class CVImageDeblurring : public CVBaseClass
+class CVImageDeblurring
{
-
public:
explicit CVImageDeblurring ();
void set_config (CVIDConfig config);
diff --git a/modules/ocl/cv_image_process_helper.cpp b/modules/ocv/cv_image_process_helper.cpp
index 0d08289..33377a9 100644
--- a/modules/ocl/cv_image_process_helper.cpp
+++ b/modules/ocv/cv_image_process_helper.cpp
@@ -23,13 +23,6 @@
namespace XCam {
-
-CVImageProcessHelper::CVImageProcessHelper ()
- : CVBaseClass ()
-{
-
-}
-
cv::Mat
CVImageProcessHelper::erosion (const cv::Mat &image, int erosion_size, int erosion_type)
{
diff --git a/modules/ocl/cv_image_process_helper.h b/modules/ocv/cv_image_process_helper.h
index 137ff6b..cb1cf8a 100644
--- a/modules/ocl/cv_image_process_helper.h
+++ b/modules/ocv/cv_image_process_helper.h
@@ -22,18 +22,15 @@
#ifndef XCAM_CV_IMAGE_PROCESS_HELPER_H
#define XCAM_CV_IMAGE_PROCESS_HELPER_H
-#include <xcam_std.h>
#include <video_buffer.h>
-#include <ocl/cv_base_class.h>
+#include "cv_std.h"
namespace XCam {
-
-class CVImageProcessHelper : public CVBaseClass
+class CVImageProcessHelper
{
-
public:
- explicit CVImageProcessHelper ();
+ explicit CVImageProcessHelper () {}
void compute_dft (const cv::Mat &image, cv::Mat &result);
void compute_idft (cv::Mat *input, cv::Mat &result);
diff --git a/modules/ocl/cv_image_sharp.cpp b/modules/ocv/cv_image_sharp.cpp
index 0a309af..2bf0076 100644
--- a/modules/ocl/cv_image_sharp.cpp
+++ b/modules/ocv/cv_image_sharp.cpp
@@ -23,13 +23,6 @@
namespace XCam {
-
-CVImageSharp::CVImageSharp ()
- : CVBaseClass ()
-{
-
-}
-
cv::Mat
CVImageSharp::sharp_image_gray (const cv::Mat &image, float sigmar)
{
diff --git a/modules/ocl/cv_image_sharp.h b/modules/ocv/cv_image_sharp.h
index 74e0ce4..7a68e23 100644
--- a/modules/ocl/cv_image_sharp.h
+++ b/modules/ocv/cv_image_sharp.h
@@ -22,17 +22,15 @@
#ifndef XCAM_CV_IMAGE_SHARP_H
#define XCAM_CV_IMAGE_SHARP_H
-#include <xcam_std.h>
#include <video_buffer.h>
-#include <ocl/cv_base_class.h>
+#include "cv_std.h"
namespace XCam {
-class CVImageSharp : public CVBaseClass
+class CVImageSharp
{
-
public:
- explicit CVImageSharp ();
+ explicit CVImageSharp () {}
float measure_sharp (const cv::Mat &image);
cv::Mat sharp_image_gray (const cv::Mat &image, float sigmar);
diff --git a/modules/ocv/cv_std.h b/modules/ocv/cv_std.h
new file mode 100644
index 0000000..eba4861
--- /dev/null
+++ b/modules/ocv/cv_std.h
@@ -0,0 +1,27 @@
+/*
+ * cv_std.h - OpenCV std
+ *
+ * Copyright (c) 2019 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#ifndef XCAM_CV_STD_H
+#define XCAM_CV_STD_H
+
+#include <xcam_std.h>
+#include <opencv2/opencv.hpp>
+
+#endif // XCAM_CV_STD_H
diff --git a/modules/ocv/cv_utils.cpp b/modules/ocv/cv_utils.cpp
new file mode 100644
index 0000000..ab70679
--- /dev/null
+++ b/modules/ocv/cv_utils.cpp
@@ -0,0 +1,97 @@
+/*
+ * cv_utils.cpp - OpenCV Utilities
+ *
+ * Copyright (c) 2019 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#include "cv_utils.h"
+
+const static cv::Scalar color = cv::Scalar (0, 0, 255);
+const static int fontFace = cv::FONT_HERSHEY_COMPLEX;
+
+namespace XCam {
+
+bool convert_to_mat (const SmartPtr<VideoBuffer> &buffer, cv::Mat &img)
+{
+ VideoBufferInfo info = buffer->get_video_info ();
+ XCAM_FAIL_RETURN (ERROR, info.format == V4L2_PIX_FMT_NV12, false, "convert_to_mat only support NV12 format");
+
+ uint8_t *mem = buffer->map ();
+ XCAM_FAIL_RETURN (ERROR, mem, false, "convert_to_mat buffer map failed");
+
+ cv::Mat mat = cv::Mat (info.aligned_height * 3 / 2, info.width, CV_8UC1, mem, info.strides[0]);
+ cv::cvtColor (mat, img, cv::COLOR_YUV2BGR_NV12);
+ buffer->unmap ();
+
+ return true;
+}
+
+bool convert_range_to_mat (const SmartPtr<VideoBuffer> &buffer, const Rect &range, cv::Mat &img)
+{
+ VideoBufferInfo info = buffer->get_video_info ();
+
+ uint8_t *mem = buffer->map ();
+ XCAM_FAIL_RETURN (ERROR, mem, false, "convert_range_to_mat buffer map failed");
+
+ uint8_t *start = mem + range.pos_y * info.strides[0] + range.pos_x;
+ img = cv::Mat (range.height, range.width, CV_8UC1, start, info.strides[0]);
+ // buffer->unmap ();
+
+ return true;
+}
+
+void write_image (
+ const SmartPtr<VideoBuffer> &buf, const char *img_name, const char *frame_str, const char *idx_str)
+{
+ XCAM_ASSERT (img_name);
+
+ cv::Mat mat;
+ convert_to_mat (buf, mat);
+
+ if(frame_str)
+ cv::putText (mat, frame_str, cv::Point(20, 50), fontFace, 2.0, color, 2, 8, false);
+ if(idx_str)
+ cv::putText (mat, idx_str, cv::Point(20, 110), fontFace, 2.0, color, 2, 8, false);
+
+ cv::imwrite (img_name, mat);
+}
+
+void write_image (
+ const SmartPtr<VideoBuffer> &buf, const Rect &draw_rect,
+ const char *img_name, const char *frame_str, const char *idx_str)
+{
+ XCAM_ASSERT (img_name && frame_str && idx_str);
+
+ cv::Mat mat;
+ convert_to_mat (buf, mat);
+
+ const Rect &rect = draw_rect;
+ cv::putText (mat, frame_str, cv::Point(rect.pos_x, 30), fontFace, 0.8f, color, 2, 8, false);
+ cv::putText (mat, idx_str, cv::Point(rect.pos_x, 70), fontFace, 0.8f, color, 2, 8, false);
+
+ cv::line (mat, cv::Point(rect.pos_x, rect.pos_y), cv::Point(rect.pos_x + rect.width, rect.pos_y), color, 1);
+ cv::line (mat, cv::Point(rect.pos_x, rect.pos_y + rect.height),
+ cv::Point(rect.pos_x + rect.width, rect.pos_y + rect.height), color, 1);
+
+ VideoBufferInfo info = buf->get_video_info ();
+ cv::line (mat, cv::Point(rect.pos_x, 0), cv::Point(rect.pos_x, info.height), color, 2);
+ cv::line (mat, cv::Point(rect.pos_x + rect.width, 0), cv::Point(rect.pos_x + rect.width, info.height), color, 2);
+
+ cv::imwrite (img_name, mat);
+}
+
+}
diff --git a/modules/ocv/cv_utils.h b/modules/ocv/cv_utils.h
new file mode 100644
index 0000000..8b36b90
--- /dev/null
+++ b/modules/ocv/cv_utils.h
@@ -0,0 +1,41 @@
+/*
+ * cv_utils.h - OpenCV Utilities
+ *
+ * Copyright (c) 2019 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#ifndef XCAM_CV_UTILS_H
+#define XCAM_CV_UTILS_H
+
+#include <interface/data_types.h>
+#include <video_buffer.h>
+#include "cv_std.h"
+
+namespace XCam {
+
+ bool convert_to_mat (const SmartPtr<VideoBuffer> &buffer, cv::Mat &img);
+ bool convert_range_to_mat (const SmartPtr<VideoBuffer> &buffer, const Rect &range, cv::Mat &img);
+
+ void write_image (
+ const SmartPtr<VideoBuffer> &buf, const char *img_name, const char *frame_str, const char *idx_str);
+ void write_image (
+ const SmartPtr<VideoBuffer> &buf, const Rect &draw_rect,
+ const char *img_name, const char *frame_str, const char *idx_str);
+
+}
+
+#endif // XCAM_CV_UTILS_H
diff --git a/modules/ocl/cv_wiener_filter.cpp b/modules/ocv/cv_wiener_filter.cpp
index ff96e5c..cf33649 100644
--- a/modules/ocl/cv_wiener_filter.cpp
+++ b/modules/ocv/cv_wiener_filter.cpp
@@ -23,9 +23,7 @@
namespace XCam {
-
CVWienerFilter::CVWienerFilter ()
- : CVBaseClass ()
{
_helpers = new CVImageProcessHelper ();
}
diff --git a/modules/ocl/cv_wiener_filter.h b/modules/ocv/cv_wiener_filter.h
index fa70812..3720c35 100644
--- a/modules/ocl/cv_wiener_filter.h
+++ b/modules/ocv/cv_wiener_filter.h
@@ -22,16 +22,14 @@
#ifndef XCAM_CV_WIENER_FILTER_H
#define XCAM_CV_WIENER_FILTER_H
-#include <xcam_std.h>
#include <video_buffer.h>
-#include <ocl/cv_base_class.h>
-#include <ocl/cv_image_process_helper.h>
+#include "cv_std.h"
+#include "cv_image_process_helper.h"
namespace XCam {
-class CVWienerFilter : public CVBaseClass
+class CVWienerFilter
{
-
public:
explicit CVWienerFilter ();
diff --git a/modules/render/Makefile.am b/modules/render/Makefile.am
new file mode 100644
index 0000000..2870eaf
--- /dev/null
+++ b/modules/render/Makefile.am
@@ -0,0 +1,52 @@
+lib_LTLIBRARIES = libxcam_render.la
+
+XCAM_RENDER_CXXFLAGS = \
+ $(XCAM_CXXFLAGS) \
+ $(LIBOSG_CFLAGS) \
+ -I$(top_srcdir)/xcore \
+ -I$(top_srcdir)/modules \
+ $(NULL)
+
+XCAM_RENDER_LIBS = \
+ -losgGA \
+ -losgDB \
+ -losgUtil \
+ -losgFX \
+ -losgText \
+ -losgViewer \
+ -losg \
+ $(top_builddir)/xcore/libxcam_core.la \
+ $(NULL)
+
+xcam_render_sources = \
+ render_osg_camera_manipulator.cpp \
+ render_osg_model.cpp \
+ render_osg_viewer.cpp \
+ $(NULL)
+
+libxcam_render_la_SOURCES = \
+ $(xcam_render_sources) \
+ $(NULL)
+
+libxcam_render_la_CXXFLAGS = \
+ $(XCAM_RENDER_CXXFLAGS) \
+ $(NULL)
+
+libxcam_render_la_LIBADD = \
+ $(XCAM_RENDER_LIBS) \
+ $(NULL)
+
+libxcam_render_la_LDFLAGS = \
+ $(XCAM_LT_LDFLAGS) \
+ $(NULL)
+
+libxcam_renderincludedir = $(includedir)/xcam/render
+
+nobase_libxcam_renderinclude_HEADERS = \
+ render_osg_camera_manipulator.h \
+ render_osg_model.h \
+ render_osg_viewer.h \
+ render_osg_shader.h \
+ $(NULL)
+
+libxcam_render_la_LIBTOOLFLAGS = --tag=disable-static
diff --git a/modules/render/render_osg_camera_manipulator.cpp b/modules/render/render_osg_camera_manipulator.cpp
new file mode 100644
index 0000000..ec59fb9
--- /dev/null
+++ b/modules/render/render_osg_camera_manipulator.cpp
@@ -0,0 +1,172 @@
+/*
+ * render_osg_camera_manipulator.cpp - supports 3D interactive manipulators
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Zong Wei <wei.zong@intel.com>
+ */
+
+#include "render_osg_camera_manipulator.h"
+
+namespace XCam {
+
+RenderOsgCameraManipulator::RenderOsgCameraManipulator ()
+ : osgGA::StandardManipulator::StandardManipulator ()
+ , mAngle (osg::PI)
+ , mLookAtOffset (0.0f)
+ , mMaxLookAtOffset (osg::PI_4)
+ , mLength (4.0f)
+ , mWidth (3.0f)
+ , mHeight (1.6f)
+ , mMaxHeight (4.0f)
+ , mMinHeight (0.6)
+ , mEyePosScale (1.0f)
+ , mUp (osg::Vec3d(0.0f, 0.0f, 1.0f))
+{
+ setAllowThrow (false);
+ setAutoComputeHomePosition (false);
+}
+
+RenderOsgCameraManipulator::~RenderOsgCameraManipulator ()
+{
+}
+
+osg::Matrixd
+RenderOsgCameraManipulator::getInverseMatrix () const
+{
+ osg::Vec3d eyePos;
+ getEyePosition (eyePos);
+ osg::Vec3d lookAtPos;
+ getLookAtPosition (lookAtPos);
+ return osg::Matrixd::lookAt (eyePos, lookAtPos, mUp);
+}
+
+osg::Matrixd
+RenderOsgCameraManipulator::getMatrix () const
+{
+ osg::Matrixd matrix = getInverseMatrix ();
+ return osg::Matrixd::inverse (matrix);
+}
+
+void
+RenderOsgCameraManipulator::home (double /*currentTime*/)
+{
+ mAngle = osg::PI;
+ mLookAtOffset = 0.0f;
+ mEyePosScale = 1.0f;
+}
+
+void
+RenderOsgCameraManipulator::rotate (float deltaAngle)
+{
+ if (deltaAngle > 0.) {
+ if (mLookAtOffset < mMaxLookAtOffset) {
+ mLookAtOffset = std::min (mLookAtOffset + deltaAngle, mMaxLookAtOffset);
+ } else {
+ mAngle += deltaAngle;
+ }
+ } else {
+ if (mLookAtOffset > -mMaxLookAtOffset) {
+ mLookAtOffset = std::max (mLookAtOffset + deltaAngle, -mMaxLookAtOffset);
+ } else {
+ mAngle += deltaAngle;
+ }
+ }
+ if (mAngle > 2 * osg::PI) {
+ mAngle -= 2 * osg::PI;
+ } else if (mAngle < 0.0f) {
+ mAngle += 2 * osg::PI;
+ }
+}
+
+void
+RenderOsgCameraManipulator::modifyHeight (float delta)
+{
+ if (delta > 0.0) {
+ mHeight = std::min (mHeight + delta, mMaxHeight);
+ } else {
+ mHeight = std::max (mHeight + delta, mMinHeight);
+ }
+}
+
+void
+RenderOsgCameraManipulator::getEyePosition (osg::Vec3d &eyePos) const
+{
+ float indentFactor = 1.0f - (0.1f * ((mHeight - mMinHeight) / (mMaxHeight - mMinHeight)));
+ eyePos[0] = cos (mAngle) * mLength * indentFactor;
+ eyePos[1] = sin (mAngle) * mWidth * indentFactor;
+ eyePos[2] = mHeight;
+ eyePos *= mEyePosScale;
+}
+
+void
+RenderOsgCameraManipulator::getLookAtPosition (osg::Vec3d &lookAtPos) const
+{
+ float lookAtAngle = mAngle + mLookAtOffset;
+ lookAtPos[0] = cos (lookAtAngle) * mLength * 0.5f;
+ lookAtPos[1] = sin (lookAtAngle) * mWidth * 0.5f;
+ lookAtPos[2] = mHeight * 0.25f;
+}
+
+bool
+RenderOsgCameraManipulator::handleKeyDown (const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &us)
+{
+ (void)us;
+ bool eventHandled = false;
+ int key = ea.getKey ();
+ if (key == osgGA::GUIEventAdapter::KEY_Space) {
+ home (ea.getTime ());
+
+ eventHandled = true;
+ } else if (key == osgGA::GUIEventAdapter::KEY_Left) {
+ rotate (-0.1);
+ eventHandled = true;
+ } else if (key == osgGA::GUIEventAdapter::KEY_Right) {
+ rotate (0.1);
+ eventHandled = true;
+ }
+
+ return eventHandled;
+}
+
+bool
+RenderOsgCameraManipulator::handleMouseWheel (const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &us)
+{
+ (void)us;
+ bool eventHandled = false;
+ osgGA::GUIEventAdapter::ScrollingMotion sm = ea.getScrollingMotion();
+
+ if (sm == osgGA::GUIEventAdapter::SCROLL_DOWN || sm == osgGA::GUIEventAdapter::SCROLL_RIGHT) {
+ rotate (0.1);
+ eventHandled = true;
+ } else if (sm == osgGA::GUIEventAdapter::SCROLL_UP || sm == osgGA::GUIEventAdapter::SCROLL_LEFT) {
+ rotate (-0.1);
+ eventHandled = true;
+ }
+
+ return eventHandled;
+}
+
+bool
+RenderOsgCameraManipulator::performMovementLeftMouseButton (const double eventTimeDelta, const double dx, const double dy)
+{
+ (void)eventTimeDelta;
+
+ rotate (-2.0 * dx);
+ modifyHeight (-dy);
+ return true;
+}
+
+} // namespace XCam
diff --git a/modules/render/render_osg_camera_manipulator.h b/modules/render/render_osg_camera_manipulator.h
new file mode 100644
index 0000000..0653039
--- /dev/null
+++ b/modules/render/render_osg_camera_manipulator.h
@@ -0,0 +1,123 @@
+/*
+ * render_osg_camera_manipulator.h - supports 3D interactive manipulators
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Zong Wei <wei.zong@intel.com>
+ */
+
+#ifndef XCAM_OSG_CAMERA_MANIPULATOR_H
+#define XCAM_OSG_CAMERA_MANIPULATOR_H
+
+#include <osgGA/StandardManipulator>
+
+namespace XCam {
+
+class RenderOsgCameraManipulator
+ : public osgGA::StandardManipulator
+{
+public:
+
+ explicit RenderOsgCameraManipulator ();
+
+ virtual ~RenderOsgCameraManipulator ();
+
+ virtual void setByMatrix (const osg::Matrixd &matrix)
+ {
+ (void)matrix;
+ }
+
+ virtual void setByInverseMatrix (const osg::Matrixd &matrix)
+ {
+ (void)matrix;
+ }
+
+ virtual osg::Matrixd getMatrix () const;
+
+ virtual osg::Matrixd getInverseMatrix () const;
+
+ virtual void home (double currentTime);
+
+ virtual void setTransformation (const osg::Vec3d &eye, const osg::Quat &rotation)
+ {
+ (void)eye;
+ (void)rotation;
+ }
+
+ virtual void setTransformation (const osg::Vec3d &eye, const osg::Vec3d &center, const osg::Vec3d &up)
+ {
+ (void)eye;
+ (void)center;
+ (void)up;
+ }
+
+ virtual void getTransformation (osg::Vec3d &eye, osg::Quat &rotation) const
+ {
+ (void)eye;
+ (void)rotation;
+ }
+
+ virtual void getTransformation (osg::Vec3d &eye, osg::Vec3d &center, osg::Vec3d &up) const
+ {
+ (void)eye;
+ (void)center;
+ (void)up;
+ }
+
+ void setInitialValues (float angle, float length, float width, float height)
+ {
+ mAngle = angle;
+ mLength = length;
+ mWidth = width;
+ mHeight = height;
+ mMinHeight = height / 2.0f;
+
+ mUp = osg::Vec3d(0.0f, 0.0f, 1.0f);
+ }
+
+private:
+ RenderOsgCameraManipulator (RenderOsgCameraManipulator const &other);
+
+ RenderOsgCameraManipulator &operator= (RenderOsgCameraManipulator const &other);
+
+ virtual bool handleKeyDown (const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &us);
+
+ virtual bool handleMouseWheel (const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &us);
+
+ virtual bool performMovementLeftMouseButton (const double eventTimeDelta, const double dx, const double dy);
+
+ void rotate (float deltaAngle);
+
+ void modifyHeight (float delta);
+
+ void getEyePosition (osg::Vec3d &eye) const;
+
+ void getLookAtPosition (osg::Vec3d &center) const;
+
+ float mAngle;
+ float mLookAtOffset;
+ float mMaxLookAtOffset;
+ float mLength;
+ float mWidth;
+ float mHeight;
+ float mMaxHeight;
+ float mMinHeight;
+ float mEyePosScale;
+ osg::Vec3d mUp;
+};
+
+} // namespace XCam
+
+#endif // XCAM_OSG_CAMERA_MANIPULATOR_H
diff --git a/modules/render/render_osg_model.cpp b/modules/render/render_osg_model.cpp
new file mode 100644
index 0000000..4062fed
--- /dev/null
+++ b/modules/render/render_osg_model.cpp
@@ -0,0 +1,342 @@
+/*
+ * render_osg_model.cpp - represents renderable things by model
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Zong Wei <wei.zong@intel.com>
+ */
+
+#include "render_osg_model.h"
+
+#include <iostream>
+#include <string>
+
+#include <osg/MatrixTransform>
+#include <osg/Texture2D>
+#include <osgDB/ReadFile>
+
+namespace XCam {
+
+RenderOsgModel::RenderOsgModel (const char *name, uint32_t width, uint32_t height)
+ : _name (NULL)
+ , _model (NULL)
+ , _geode (NULL)
+ , _program (NULL)
+ , _texture (NULL)
+{
+ XCAM_LOG_DEBUG ("RenderOsgModel width(%d), height(%d) ", width, height);
+ XCAM_ASSERT (name);
+ if (name)
+ _name = strndup (name, XCAM_MAX_STR_SIZE);
+
+ _model = new osg::Group ();
+ _geode = new osg::Geode ();
+
+ _texture = create_texture (width, height);
+ if (_texture.get ()) {
+ add_texture (_texture);
+ }
+}
+
+RenderOsgModel::RenderOsgModel (const char *name, bool from_file)
+ : _name (NULL)
+ , _model (NULL)
+ , _geode (NULL)
+ , _program (NULL)
+ , _texture (NULL)
+{
+ XCAM_LOG_DEBUG ("RenderOsgModel model name (%s) ", name);
+ XCAM_ASSERT (name);
+ if (name)
+ _name = strndup (name, XCAM_MAX_STR_SIZE);
+
+ _model = new osg::Group ();
+ _geode = new osg::Geode ();
+
+ if (from_file && NULL != _geode.get ()) {
+ osg::ref_ptr<osg::Node> node = create_model_from_file (name);
+ _geode->addChild (node);
+ }
+}
+
+RenderOsgModel::~RenderOsgModel ()
+{
+ if (_name)
+ xcam_free (_name);
+}
+
+osg::Node*
+RenderOsgModel::create_model_from_file (const char *name)
+{
+ XCAM_LOG_DEBUG ("Invailide node name %s", name);
+ if (name == NULL) {
+ return NULL;
+ }
+
+ osg::ref_ptr<osg::Node> node = osgDB::readNodeFile (name);
+ if (NULL == node.get ()) {
+ XCAM_LOG_ERROR ("Read node file FAILD!!! node name %s", name);
+ }
+
+ return node.release();
+}
+
+void
+RenderOsgModel::append_model (SmartPtr<RenderOsgModel> &child_model)
+{
+ osg::ref_ptr<osg::Group> model = get_model ();
+
+ if (NULL == model.get () || NULL == child_model.ptr ()) {
+ XCAM_LOG_ERROR ("Append child model ERROR!! NULL model !!");
+ return;
+ }
+
+ model->addChild (child_model->get_model ());
+}
+
+void
+RenderOsgModel::append_geode (SmartPtr<RenderOsgModel> &child_model)
+{
+ osg::ref_ptr<osg::Group> model = get_model ();
+
+ if (NULL == model.get () || NULL == child_model.ptr ()) {
+ XCAM_LOG_ERROR ("Append child geode ERROR!! NULL model !!");
+ return;
+ }
+
+ model->addChild (child_model->get_geode ());
+}
+
+XCamReturn
+RenderOsgModel::setup_shader_program (
+ const char *name,
+ osg::Shader::Type type,
+ const char *source_text)
+{
+ XCAM_LOG_DEBUG ("setup shader program name(%s), type(%d)", name, type);
+ XCamReturn result = XCAM_RETURN_NO_ERROR;
+
+ if (NULL == _program.get ()) {
+ _program = new osg::Program ();
+ _program->setName (name);
+ }
+
+ _program->addShader (new osg::Shader (type, source_text));
+
+ _model->getOrCreateStateSet ()->setAttributeAndModes (_program, osg::StateAttribute::ON);
+ _model->getOrCreateStateSet ()->setMode (GL_DEPTH_TEST, osg::StateAttribute::ON);
+
+ return result;
+}
+
+XCamReturn
+RenderOsgModel::setup_vertex_model (
+ BowlModel::VertexMap &vertices,
+ BowlModel::PointMap &points,
+ BowlModel::IndexVector &indices,
+ float a,
+ float b,
+ float c)
+{
+ XCamReturn result = XCAM_RETURN_NO_ERROR;
+
+ osg::ref_ptr<osg::Group> model = get_model ();
+ osg::ref_ptr<osg::Geode> geode = get_geode ();
+ osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry ();
+
+ geode->addDrawable (geometry);
+ geometry->setUseVertexBufferObjects (true);
+
+ osg::ref_ptr<osg::Vec3Array> vertex_array = new osg::Vec3Array ();
+ osg::ref_ptr<osg::Vec2Array> tex_coord_array = new osg::Vec2Array ();
+ osg::ref_ptr<osg::DrawElementsUInt> index_array = new osg::DrawElementsUInt (GL_TRIANGLE_STRIP, 0);
+
+ osg::ref_ptr<osg::Vec3Array> normal_array = new osg::Vec3Array ();
+ osg::ref_ptr<osg::Vec4Array> color_array = new osg::Vec4Array ();
+
+ normal_array->push_back (osg::Vec3 (0, -1, 0));
+ geometry->setNormalArray (normal_array);
+ geometry->setNormalBinding (osg::Geometry::BIND_OVERALL);
+
+ color_array->push_back (osg::Vec4 (1.0, 0.0, 0.0, 1.0));
+ geometry->setColorArray (color_array);
+ geometry->setColorBinding (osg::Geometry::BIND_OVERALL);
+
+ for (uint32_t idx = 0; idx < vertices.size (); idx++) {
+ vertex_array->push_back (
+ osg::Vec3f (vertices[idx].x * a,
+ vertices[idx].y * b,
+ vertices[idx].z * c));
+ }
+
+ for (uint32_t idx = 0; idx < points.size (); idx++) {
+ tex_coord_array->push_back (osg::Vec2f (points[idx].x, points[idx].y));
+ }
+
+ for (uint32_t idx = 0; idx < indices.size (); idx++) {
+ index_array->push_back (indices[idx]);
+ }
+
+ geometry->setVertexArray (vertex_array.get ());
+
+ if (points.size () > 0) {
+ geometry->setTexCoordArray (0, tex_coord_array.get ());
+ }
+
+ if (indices.size () > 0) {
+ geometry->addPrimitiveSet (index_array.get ());
+ } else {
+ geometry->addPrimitiveSet (new osg::DrawArrays (GL_TRIANGLE_FAN, 0, 4));
+ }
+
+ model->addChild (geode);
+
+ return result;
+}
+
+XCamReturn
+RenderOsgModel::setup_model_matrix (
+ float translation_x,
+ float translation_y,
+ float translation_z,
+ float rotation_x,
+ float rotation_y,
+ float rotation_z,
+ float rotation_degrees)
+{
+ XCamReturn result = XCAM_RETURN_NO_ERROR;
+
+ osg::ref_ptr<osg::Group> model = get_model ();
+ osg::ref_ptr<osg::Geode> geode = get_geode ();
+
+ const osg::Vec3f axis(rotation_x, rotation_y, rotation_z);
+ osg::ref_ptr<osg::MatrixTransform> mat = new osg::MatrixTransform ();
+ mat->setMatrix (osg::Matrix::scale (osg::Vec3 (1.0, 1.0, 1.0)) *
+ osg::Matrix::rotate ((rotation_degrees / 180.f) * osg::PI_2, axis) *
+ osg::Matrix::translate (osg::Vec3 (translation_x, translation_y, translation_z)));
+
+ mat->addChild (geode);
+ model->addChild (mat);
+
+ return result;
+}
+
+XCamReturn
+RenderOsgModel::update_texture (SmartPtr<VideoBuffer> &buffer)
+{
+ XCamReturn result = XCAM_RETURN_NO_ERROR;
+
+ XCAM_LOG_DEBUG ("RenderOsgModel::update_texture ");
+
+ if (NULL == _texture.get ()) {
+ return XCAM_RETURN_ERROR_PARAM;
+ }
+
+ {
+ SmartLock locker (_mutex);
+
+ VideoBufferInfo info = buffer->get_video_info ();
+ uint32_t image_width = info.width;
+ uint32_t image_height = info.height;
+
+ osg::ref_ptr<osg::Image> image_y = new osg::Image ();
+ osg::ref_ptr<osg::Image> image_uv = new osg::Image ();
+
+ uint8_t* image_buffer = buffer->map ();
+ if (NULL == image_buffer) {
+ XCAM_LOG_ERROR ("buffer map return NULL!!");
+ result = XCAM_RETURN_ERROR_MEM;
+ } else {
+ uint8_t* src_y = image_buffer;
+ uint8_t* src_uv = image_buffer + image_width * image_height;
+
+ image_y->setImage (image_width, image_height, 1,
+ GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE,
+ src_y, osg::Image::NO_DELETE);
+
+ image_uv->setImage (image_width / 2, image_height / 2, 1,
+ GL_LUMINANCE, GL_RG, GL_UNSIGNED_BYTE,
+ src_uv, osg::Image::NO_DELETE);
+
+ _texture->_texture_y->setImage (image_y);
+ _texture->_texture_uv->setImage (image_uv);
+ }
+ //buffer->unmap ();
+ }
+
+ return result;
+}
+
+NV12Texture*
+RenderOsgModel::create_texture (uint32_t width, uint32_t height)
+{
+ osg::ref_ptr<NV12Texture> nv12 = new NV12Texture (width, height);
+
+ nv12->_texture_y = new osg::Texture2D ();
+ nv12->_texture_y->setImage (new osg::Image ());
+
+ nv12->_texture_y->setInternalFormat (GL_LUMINANCE);
+ nv12->_texture_y->setResizeNonPowerOfTwoHint (false);
+ nv12->_texture_y->setNumMipmapLevels (0);
+ nv12->_texture_y->setFilter (osg::Texture::MIN_FILTER, osg::Texture::NEAREST);
+ nv12->_texture_y->setFilter (osg::Texture::MAG_FILTER, osg::Texture::NEAREST);
+ nv12->_texture_y->setWrap (osg::Texture::WRAP_S, osg::Texture::CLAMP);
+ nv12->_texture_y->setWrap (osg::Texture::WRAP_T, osg::Texture::CLAMP);
+
+ nv12->_texture_y->setTextureWidth (width);
+ nv12->_texture_y->setTextureHeight (height);
+
+ nv12->_texture_uv = new osg::Texture2D ();
+ nv12->_texture_uv->setImage (new osg::Image ());
+
+ nv12->_texture_uv->setInternalFormat (GL_RG);
+ nv12->_texture_uv->setResizeNonPowerOfTwoHint (false);
+ nv12->_texture_uv->setNumMipmapLevels (0);
+ nv12->_texture_uv->setFilter (osg::Texture::MIN_FILTER, osg::Texture::NEAREST);
+ nv12->_texture_uv->setFilter (osg::Texture::MAG_FILTER, osg::Texture::NEAREST);
+ nv12->_texture_uv->setWrap (osg::Texture::WRAP_S, osg::Texture::CLAMP);
+ nv12->_texture_uv->setWrap (osg::Texture::WRAP_T, osg::Texture::CLAMP);
+
+ nv12->_texture_uv->setTextureWidth (width / 2);
+ nv12->_texture_uv->setTextureHeight (height / 2);
+
+ return nv12.release ();
+}
+
+XCamReturn
+RenderOsgModel::add_texture (osg::ref_ptr<NV12Texture> &texture)
+{
+ XCamReturn result = XCAM_RETURN_NO_ERROR;
+
+ osg::ref_ptr<osg::Group> model = get_model ();
+
+ if (NULL == model.get () || NULL == _texture.get ()) {
+ return XCAM_RETURN_ERROR_PARAM;
+ }
+
+ model->getOrCreateStateSet()->setTextureAttribute(0, texture->_texture_y.get ());
+ texture->_uniform_y = new osg::Uniform (osg::Uniform::SAMPLER_2D, "textureY");
+ texture->_uniform_y->set (0);
+ model->getOrCreateStateSet ()->addUniform (texture->_uniform_y.get ());
+
+ model->getOrCreateStateSet ()->setTextureAttribute (1, texture->_texture_uv.get ());
+ texture->_uniform_uv = new osg::Uniform (osg::Uniform::SAMPLER_2D, "textureUV");
+ texture->_uniform_uv->set (1);
+ model->getOrCreateStateSet ()->addUniform (texture->_uniform_uv.get ());
+
+ return result;
+}
+
+} // namespace XCam
diff --git a/modules/render/render_osg_model.h b/modules/render/render_osg_model.h
new file mode 100644
index 0000000..eaf6302
--- /dev/null
+++ b/modules/render/render_osg_model.h
@@ -0,0 +1,125 @@
+/*
+ * render_osg_model.h - represents renderable things by object
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Zong Wei <wei.zong@intel.com>
+ */
+
+#ifndef XCAM_OSG_RENDER_MODEL_H
+#define XCAM_OSG_RENDER_MODEL_H
+
+#include <osg/Texture2D>
+#include <osg/Group>
+
+#include <interface/data_types.h>
+#include <interface/stitcher.h>
+#include <xcam_mutex.h>
+
+namespace XCam {
+
+class NV12Texture : public osg::Referenced
+{
+public:
+ explicit NV12Texture (uint32_t width, uint32_t height)
+ {
+ _image_width = width;
+ _image_height = height;
+ }
+
+public:
+ uint32_t _image_width;
+ uint32_t _image_height;
+
+ osg::ref_ptr<osg::Texture2D> _texture_y;
+ osg::ref_ptr<osg::Texture2D> _texture_uv;
+
+ osg::ref_ptr<osg::Uniform> _uniform_y;
+ osg::ref_ptr<osg::Uniform> _uniform_uv;
+};
+
+class RenderOsgModel {
+public:
+
+ explicit RenderOsgModel (const char *name, uint32_t width, uint32_t height);
+ explicit RenderOsgModel (const char *name, bool from_file = true);
+
+ virtual ~RenderOsgModel ();
+
+ const char *get_name () const {
+ return _name;
+ }
+
+ osg::Node* create_model_from_file (const char *name);
+
+ osg::Group* get_model () const {
+ return _model;
+ }
+
+ void append_model (SmartPtr<RenderOsgModel> &model);
+
+ void append_geode (SmartPtr<RenderOsgModel> &model);
+
+
+ osg::Geode* get_geode () const {
+ return _geode;
+ }
+
+ XCamReturn setup_shader_program (
+ const char *name,
+ osg::Shader::Type type,
+ const char *source_text);
+
+ XCamReturn setup_vertex_model (
+ BowlModel::VertexMap &vertices,
+ BowlModel::PointMap &points,
+ BowlModel::IndexVector &indices,
+ float a = 1.0f,
+ float b = 1.0f,
+ float c = 1.0f);
+
+ XCamReturn setup_model_matrix (
+ float translation_x,
+ float translation_y,
+ float translation_z,
+ float rotation_x,
+ float rotation_y,
+ float rotation_z,
+ float rotation_degrees);
+
+ XCamReturn update_texture (SmartPtr<VideoBuffer> &buffer);
+
+private:
+
+ XCAM_DEAD_COPY (RenderOsgModel);
+
+ NV12Texture* create_texture (uint32_t width, uint32_t height);
+ XCamReturn add_texture (osg::ref_ptr<NV12Texture> &texture);
+
+private:
+
+ char *_name;
+
+ osg::ref_ptr<osg::Group> _model;
+ osg::ref_ptr<osg::Geode> _geode;
+ osg::ref_ptr<osg::Program> _program;
+ osg::ref_ptr<NV12Texture> _texture;
+
+ Mutex _mutex;
+};
+
+} // namespace XCam
+
+#endif // XCAM_OSG_RENDER_MODEL_H
diff --git a/modules/render/render_osg_shader.h b/modules/render/render_osg_shader.h
new file mode 100644
index 0000000..b2dd52e
--- /dev/null
+++ b/modules/render/render_osg_shader.h
@@ -0,0 +1,93 @@
+/*
+ * render_osg_shader.h - common gl shaders
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Zong Wei <wei.zong@intel.com>
+ */
+
+#ifndef XCAM_OSG_SHADER_H
+#define XCAM_OSG_SHADER_H
+
+namespace XCam {
+
+static const char VtxShaderProjectNV12Texture[] = ""
+ "precision highp float; \n"
+ "attribute vec4 osg_Vertex; \n"
+ "attribute vec2 osg_MultiTexCoord0; \n"
+ "attribute vec4 osg_Color; \n"
+ "uniform mat4 osg_ModelViewProjectionMatrix; \n"
+ "uniform mat4 osg_ModelViewMatrix; \n"
+ "uniform mat4 osg_ViewMatrixInverse; \n"
+ "varying vec2 texcoord; \n"
+ "varying vec4 color; \n"
+ "void main(void) \n"
+ "{ \n"
+ " texcoord = osg_MultiTexCoord0; \n"
+ " gl_Position = osg_ModelViewProjectionMatrix * osg_Vertex; \n"
+ " color = osg_Color; \n"
+ "} \n";
+
+static const char FrgShaderProjectNV12Texture[] = ""
+ "precision highp float; \n"
+ "uniform sampler2D textureY; \n"
+ "uniform sampler2D textureUV; \n"
+ "varying vec2 texcoord; \n"
+ "varying vec4 color; \n"
+ "vec4 getRGBColorNV12(sampler2D u_textureY, sampler2D u_textureUV, vec2 tex) \n"
+ "{ \n"
+ " vec4 resultcolor = vec4 (0.0, 0.0, 0.0, 1.0); \n"
+ " float y, u, v; \n"
+ " y = texture2D(u_textureY, vec2(tex.s, tex.t)).r; \n"
+ " vec2 colorUV = texture2D(u_textureUV, vec2(tex.s, tex.t)).rg; \n"
+ " u = colorUV.x-0.5; \n"
+ " v = colorUV.y-0.5; \n"
+ " y = 1.1643*(y-0.0625); \n"
+ " resultcolor.r = (y+1.5958*(v)); \n"
+ " resultcolor.g = (y-0.39173*(u)-0.81290*(v)); \n"
+ " resultcolor.b = (y+2.017*(u)); \n"
+ " resultcolor.a = 1.0; \n"
+ " return resultcolor; \n"
+ "} \n"
+ "void main() \n"
+ "{ \n"
+ " vec4 textureColor = getRGBColorNV12(textureY, textureUV, texcoord); \n"
+ " gl_FragColor = textureColor; \n"
+ "} \n";
+
+const char VtxShaderSimpleTexture[] = ""
+ "precision highp float; \n"
+ "attribute vec4 osg_Vertex; \n"
+ "attribute vec4 osg_Color; \n"
+ "uniform mat4 osg_ModelViewProjectionMatrix; \n"
+ "varying vec4 color; \n"
+ "void main(void) \n"
+ "{ \n"
+ " gl_Position = osg_ModelViewProjectionMatrix * osg_Vertex; \n"
+ " color = osg_Color; \n"
+ "} \n";
+
+const char FrgShaderSimpleTexture[] = ""
+ "precision highp float; \n"
+ "varying vec4 color; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_FragColor = color; \n"
+ "} \n";
+
+
+} // namespace XCam
+
+#endif // XCAM_OSG_SHADER_H
diff --git a/modules/render/render_osg_viewer.cpp b/modules/render/render_osg_viewer.cpp
new file mode 100644
index 0000000..ff0f394
--- /dev/null
+++ b/modules/render/render_osg_viewer.cpp
@@ -0,0 +1,137 @@
+/*
+ * render_osg_viewer.cpp - renders a single view on to a single scene
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Zong Wei <wei.zong@intel.com>
+ */
+
+#include "render_osg_viewer.h"
+#include "render_osg_model.h"
+#include "render_osg_camera_manipulator.h"
+
+#include <string>
+
+namespace XCam {
+
+RenderOsgViewer::RenderOsgViewer ()
+ : Thread ("RenderOsgViewerThread")
+ , _viewer (NULL)
+ , _model_groups (NULL)
+ , _initialized (false)
+{
+ _viewer = new osgViewer::Viewer ();
+
+ if (!_initialized) {
+ initialize ();
+ }
+}
+
+RenderOsgViewer::~RenderOsgViewer ()
+{
+ _viewer->setDone (true);
+}
+
+XCamReturn
+RenderOsgViewer::initialize ()
+{
+ XCamReturn result = XCAM_RETURN_NO_ERROR;
+
+ osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface();
+ uint32_t win_width = 1920;
+ uint32_t win_height = 1080;
+ if (wsi) {
+ wsi->getScreenResolution (osg::GraphicsContext::ScreenIdentifier (0), win_width, win_height);
+ }
+
+ _viewer->setThreadingModel (osgViewer::Viewer::SingleThreaded);
+
+ _viewer->setLightingMode (osg::View::SKY_LIGHT);
+ _viewer->getLight()->setAmbient (osg::Vec4f(0.f, 0.f, 0.f, 1.f));
+ _viewer->getLight()->setDiffuse (osg::Vec4d(0.4f, 0.4f, 0.4f, 1.f));
+ _viewer->getLight()->setSpecular (osg::Vec4d(0.5f, 0.5f, 0.5f, 1.f));
+
+ osg::ref_ptr<osgViewer::StatsHandler> stats_handler = new osgViewer::StatsHandler ();
+ _viewer->addEventHandler (stats_handler);
+
+ _viewer->setUpViewInWindow (0, 0, win_width, win_height);
+
+ osg::ref_ptr<RenderOsgCameraManipulator> vp_manipulator = new RenderOsgCameraManipulator ();
+ vp_manipulator->setInitialValues (osg::PI, 6.0f, 4.0f, 2.6f);
+ _viewer->setCameraManipulator (vp_manipulator);
+ _viewer->getCamera ()->setClearMask (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ _viewer->getCamera ()->setComputeNearFarMode (osg::Camera::DO_NOT_COMPUTE_NEAR_FAR);
+ _viewer->getCamera ()->setClearColor (osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
+ _viewer->getCamera ()->setViewport (0, 0, win_width, win_height);
+
+ _initialized = true;
+
+ return result;
+}
+
+void
+RenderOsgViewer::start_render ()
+{
+ Thread::start ();
+}
+
+void
+RenderOsgViewer::stop_render ()
+{
+ Thread::stop ();
+}
+
+bool
+RenderOsgViewer::loop ()
+{
+ if (!_viewer->done ())
+ {
+ _viewer->frame ();
+ }
+
+ return true;
+}
+
+void
+RenderOsgViewer::set_camera_manipulator (osg::ref_ptr<osgGA::StandardManipulator> &manipulator)
+{
+ _viewer->setCameraManipulator (manipulator);
+}
+
+void
+RenderOsgViewer::add_model (SmartPtr<RenderOsgModel> &model)
+{
+ if (!model.ptr ()) {
+ return;
+ }
+
+ if (!_model_groups.ptr ()) {
+ _model_groups = model;
+ } else {
+ _model_groups->append_model (model);
+ }
+}
+
+void
+RenderOsgViewer::validate_model_groups ()
+{
+ if (!_model_groups.ptr ()) {
+ return;
+ }
+ _viewer->setSceneData (_model_groups->get_model ());
+}
+
+} // namespace XCam
+
diff --git a/modules/render/render_osg_viewer.h b/modules/render/render_osg_viewer.h
new file mode 100644
index 0000000..335c562
--- /dev/null
+++ b/modules/render/render_osg_viewer.h
@@ -0,0 +1,73 @@
+/*
+ * render_osg_viewer.h - renders a single view on to a single scene
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Zong Wei <wei.zong@intel.com>
+ */
+
+#ifndef XCAM_OSG_RENDER_VIEWER_H
+#define XCAM_OSG_RENDER_VIEWER_H
+
+#include <osgViewer/Viewer>
+#include <osgViewer/ViewerEventHandlers>
+#include <osgGA/StandardManipulator>
+
+#include <interface/data_types.h>
+#include <interface/stitcher.h>
+#include <xcam_mutex.h>
+#include <xcam_thread.h>
+
+namespace XCam {
+
+class RenderOsgModel;
+
+class RenderOsgViewer
+ : public Thread
+{
+public:
+
+ explicit RenderOsgViewer ();
+
+ virtual ~RenderOsgViewer ();
+
+ osgViewer::Viewer *get_viewer () {
+ return _viewer;
+ }
+
+ void set_camera_manipulator (osg::ref_ptr<osgGA::StandardManipulator> &manipulator);
+
+ void add_model (SmartPtr<RenderOsgModel> &model);
+ void validate_model_groups ();
+
+ void start_render ();
+ void stop_render ();
+
+protected:
+ virtual bool loop ();
+
+private:
+ XCAM_DEAD_COPY (RenderOsgViewer);
+ XCamReturn initialize ();
+
+private:
+ osg::ref_ptr<osgViewer::Viewer> _viewer;
+ SmartPtr<RenderOsgModel> _model_groups;
+ bool _initialized;
+};
+
+} // namespace XCam
+
+#endif // XCAM_OSG_RENDER_VIEWER_H
diff --git a/modules/soft/Makefile.am b/modules/soft/Makefile.am
index b1cd92b..83b2721 100644
--- a/modules/soft/Makefile.am
+++ b/modules/soft/Makefile.am
@@ -1,75 +1,63 @@
lib_LTLIBRARIES = libxcam_soft.la
-XCAMSOFT_CXXFLAGS = \
- $(LIBCL_CFLAGS) \
- -I$(top_srcdir)/xcore \
- -I$(top_srcdir)/modules \
+XCAMSOFT_CXXFLAGS = \
+ $(XCAM_CXXFLAGS) \
+ -I$(top_srcdir)/xcore \
+ -I$(top_srcdir)/modules \
$(NULL)
-XCAMSOFT_LIBS =
-
-xcam_soft_sources = \
- soft_handler.cpp \
- soft_video_buf_allocator.cpp \
- soft_worker.cpp \
- soft_blender_tasks_priv.cpp \
- soft_blender.cpp \
- soft_geo_mapper.cpp \
- soft_geo_tasks_priv.cpp \
- soft_copy_task.cpp \
- soft_stitcher.cpp \
- $(NULL)
+XCAMSOFT_LIBS = \
+ $(top_builddir)/xcore/libxcam_core.la \
+ $(NULL)
if HAVE_OPENCV
-XCAMSOFT_CXXFLAGS += $(OPENCV_CFLAGS)
-
-XCAMSOFT_LIBS += $(OPENCV_LIBS)
+XCAMSOFT_LIBS += $(top_builddir)/modules/ocv/libxcam_ocv.la
+endif
-xcam_soft_sources += \
- cv_capi_feature_match.cpp \
+xcam_soft_sources = \
+ soft_handler.cpp \
+ soft_video_buf_allocator.cpp \
+ soft_worker.cpp \
+ soft_blender_tasks_priv.cpp \
+ soft_blender.cpp \
+ soft_geo_mapper.cpp \
+ soft_geo_tasks_priv.cpp \
+ soft_copy_task.cpp \
+ soft_stitcher.cpp \
$(NULL)
-endif
-
-libxcam_soft_la_SOURCES = \
- $(xcam_soft_sources) \
+libxcam_soft_la_SOURCES = \
+ $(xcam_soft_sources) \
$(NULL)
-libxcam_soft_la_CXXFLAGS = \
- $(XCAMSOFT_CXXFLAGS) \
- $(XCAM_CXXFLAGS) \
+libxcam_soft_la_CXXFLAGS = \
+ $(XCAMSOFT_CXXFLAGS) \
$(NULL)
-libxcam_soft_la_LIBADD = \
- $(top_builddir)/xcore/libxcam_core.la \
- $(XCAMSOFT_LIBS) \
+libxcam_soft_la_LIBADD = \
+ $(XCAMSOFT_LIBS) \
$(NULL)
-libxcam_soft_la_LDFLAGS = \
- $(XCAM_LT_LDFLAGS) \
- $(PTHREAD_LDFLAGS) \
+libxcam_soft_la_LDFLAGS = \
+ $(XCAM_LT_LDFLAGS) \
$(NULL)
libxcam_softincludedir = $(includedir)/xcam/soft
-nobase_libxcam_softinclude_HEADERS = \
- soft_handler.h \
- soft_video_buf_allocator.h \
- soft_worker.h \
- soft_image.h \
- soft_blender.h \
- soft_geo_mapper.h \
- soft_copy_task.h \
- soft_stitcher.h \
+nobase_libxcam_softinclude_HEADERS = \
+ soft_handler.h \
+ soft_video_buf_allocator.h \
+ soft_worker.h \
+ soft_image.h \
+ soft_blender.h \
+ soft_geo_mapper.h \
+ soft_copy_task.h \
+ soft_stitcher.h \
$(NULL)
-noinst_HEADERS = \
- soft_blender_tasks_priv.h \
- soft_geo_tasks_priv.h \
+noinst_HEADERS = \
+ soft_blender_tasks_priv.h \
+ soft_geo_tasks_priv.h \
$(NULL)
-if HAVE_OPENCV
-noinst_HEADERS += cv_capi_feature_match.h
-endif
-
libxcam_soft_la_LIBTOOLFLAGS = --tag=disable-static
diff --git a/modules/soft/cv_capi_feature_match.h b/modules/soft/cv_capi_feature_match.h
deleted file mode 100644
index 67a9d4f..0000000
--- a/modules/soft/cv_capi_feature_match.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * cv_capi_feature_match.h - optical flow feature match
- *
- * Copyright (c) 2016-2017 Intel Corporation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Author: Wind Yuan <feng.yuan@intel.com>
- * Author: Yinhang Liu <yinhangx.liu@intel.com>
- * Author: Zong Wei <wei.zong@intel.com>
- */
-
-#ifndef CV_CAPI_FEATURE_MATCH_H
-#define CV_CAPI_FEATURE_MATCH_H
-
-#include <xcam_std.h>
-#include <video_buffer.h>
-#include <interface/feature_match.h>
-
-#ifdef ANDROID
-#include <cv.h>
-#else
-#include <opencv2/opencv.hpp>
-#endif
-
-namespace XCam {
-
-class CVCapiFeatureMatch
- : public FeatureMatch
-{
-public:
- explicit CVCapiFeatureMatch ();
-
- void optical_flow_feature_match (
- const SmartPtr<VideoBuffer> &left_buf, const SmartPtr<VideoBuffer> &right_buf,
- Rect &left_img_crop, Rect &right_img_crop, int dst_width);
-
- void set_ocl (bool use_ocl) {
- XCAM_UNUSED (use_ocl);
- }
- bool is_ocl_path () {
- return false;
- }
-
-protected:
- bool get_crop_image (const SmartPtr<VideoBuffer> &buffer, const Rect &crop_rect,
- std::vector<char> &crop_image, CvMat &img);
-
- void add_detected_data (CvArr* image, std::vector<CvPoint2D32f> &corners);
- void get_valid_offsets (std::vector<CvPoint2D32f> &corner0, std::vector<CvPoint2D32f> &corner1,
- std::vector<char> &status, std::vector<float> &error,
- std::vector<float> &offsets, float &sum, int &count,
- CvArr* out_image, CvSize &img0_size);
-
- void calc_of_match (CvArr* image0, CvArr* image1,
- std::vector<CvPoint2D32f> &corner0, std::vector<CvPoint2D32f> &corner1,
- std::vector<char> &status, std::vector<float> &error,
- int &last_count, float &last_mean_offset, float &out_x_offset);
-
- void detect_and_match (CvArr* img_left, CvArr* img_right, Rect &crop_left, Rect &crop_right,
- int &valid_count, float &mean_offset, float &x_offset, int dst_width);
-
-private:
- XCAM_DEAD_COPY (CVCapiFeatureMatch);
-
- std::vector<char> _left_crop_image;
- std::vector<char> _right_crop_image;
-};
-
-}
-
-#endif // CV_CAPI_FEATURE_MATCH_H
diff --git a/modules/soft/soft_blender.cpp b/modules/soft/soft_blender.cpp
index 7e0c678..056ad37 100644
--- a/modules/soft/soft_blender.cpp
+++ b/modules/soft/soft_blender.cpp
@@ -83,9 +83,11 @@ private:
public:
BlenderPrivConfig (SoftBlender *blender, uint32_t level)
- : pyr_levels (level)
+ : pyr_levels (level - 1)
, _blender (blender)
- {}
+ {
+ XCAM_ASSERT (level >= 2 && level <= XCAM_SOFT_PYRAMID_MAX_LEVEL);
+ }
XCamReturn init_first_masks (uint32_t width, uint32_t height);
XCamReturn scale_down_masks (uint32_t level, uint32_t width, uint32_t height);
@@ -171,8 +173,10 @@ SoftBlender::SoftBlender (const char *name)
: SoftHandler (name)
, Blender (SOFT_BLENDER_ALIGNMENT_X, SOFT_BLENDER_ALIGNMENT_Y)
{
- _priv_config = new SoftBlenderPriv::BlenderPrivConfig (this, XCAM_SOFT_PYRAMID_DEFAULT_LEVEL);
- XCAM_ASSERT (_priv_config.ptr ());
+ SmartPtr<SoftBlenderPriv::BlenderPrivConfig> config =
+ new SoftBlenderPriv::BlenderPrivConfig (this, XCAM_SOFT_PYRAMID_DEFAULT_LEVEL);
+ XCAM_ASSERT (config.ptr ());
+ _priv_config = config;
}
SoftBlender::~SoftBlender ()
@@ -682,7 +686,9 @@ SoftBlender::configure_resource (const SmartPtr<Parameters> &param)
XCAM_ASSERT (merge_size.width % SOFT_BLENDER_ALIGNMENT_X == 0);
overlap_info.init (in0_info.format, merge_size.width, merge_size.height);
- _priv_config->first_lap_pool = new SoftVideoBufAllocator (overlap_info);
+ SmartPtr<BufferPool> first_lap_pool = new SoftVideoBufAllocator (overlap_info);
+ XCAM_ASSERT (first_lap_pool.ptr ());
+ _priv_config->first_lap_pool = first_lap_pool;
XCAM_FAIL_RETURN (
ERROR, _priv_config->first_lap_pool->reserve (LAP_POOL_SIZE), XCAM_RETURN_ERROR_MEM,
"blender:%s reserve lap buffer pool(w:%d,h:%d) failed",
@@ -703,8 +709,9 @@ SoftBlender::configure_resource (const SmartPtr<Parameters> &param)
merge_size.height = XCAM_ALIGN_UP ((merge_size.height + 1) / 2, SOFT_BLENDER_ALIGNMENT_Y);
overlap_info.init (in0_info.format, merge_size.width, merge_size.height);
- _priv_config->pyr_layer[i].overlap_pool = new SoftVideoBufAllocator (overlap_info);
- XCAM_ASSERT (_priv_config->pyr_layer[i].overlap_pool.ptr ());
+ SmartPtr<BufferPool> pool = new SoftVideoBufAllocator (overlap_info);
+ XCAM_ASSERT (pool.ptr ());
+ _priv_config->pyr_layer[i].overlap_pool = pool;
XCAM_FAIL_RETURN (
ERROR, _priv_config->pyr_layer[i].overlap_pool->reserve (OVERLAP_POOL_SIZE), XCAM_RETURN_ERROR_MEM,
"blender:%s reserve buffer pool(w:%d,h:%d) failed",
diff --git a/modules/soft/soft_blender.h b/modules/soft/soft_blender.h
index b83511b..f6466f9 100644
--- a/modules/soft/soft_blender.h
+++ b/modules/soft/soft_blender.h
@@ -26,7 +26,7 @@
#include <soft/soft_handler.h>
#define XCAM_SOFT_PYRAMID_MAX_LEVEL 4
-#define XCAM_SOFT_PYRAMID_DEFAULT_LEVEL 3
+#define XCAM_SOFT_PYRAMID_DEFAULT_LEVEL 2
namespace XCam {
diff --git a/modules/soft/soft_blender_tasks_priv.h b/modules/soft/soft_blender_tasks_priv.h
index a2f2ed8..b754df3 100644
--- a/modules/soft/soft_blender_tasks_priv.h
+++ b/modules/soft/soft_blender_tasks_priv.h
@@ -66,7 +66,7 @@ protected:
out[4] += in[4] * coef;
out[5] += in[5] * coef;
out[6] += in[6] * coef;
- out[7] += in[7] * coef;
+ //out[7] += in[7] * coef;
}
template<typename T>
diff --git a/modules/soft/soft_geo_mapper.cpp b/modules/soft/soft_geo_mapper.cpp
index 478b025..5dac5b7 100644
--- a/modules/soft/soft_geo_mapper.cpp
+++ b/modules/soft/soft_geo_mapper.cpp
@@ -27,6 +27,8 @@
namespace XCam {
DECLARE_WORK_CALLBACK (CbGeoMapTask, SoftGeoMapper, remap_task_done);
+DECLARE_WORK_CALLBACK (CbGeoMapDualConstTask, SoftDualConstGeoMapper, remap_task_done);
+DECLARE_WORK_CALLBACK (CbGeoMapDualCurveTask, SoftDualCurveGeoMapper, remap_task_done);
SoftGeoMapper::SoftGeoMapper (const char *name)
: SoftHandler (name)
@@ -60,6 +62,7 @@ SoftGeoMapper::set_lookup_table (const PointFloat2 *data, uint32_t width, uint32
ret[j].y = line [j].y;
}
}
+
return true;
}
@@ -73,6 +76,7 @@ SoftGeoMapper::remap (
if (xcam_ret_is_ok (ret) && !out_buf.ptr ()) {
out_buf = param->out_buf;
}
+
return ret;
}
@@ -87,16 +91,9 @@ SoftGeoMapper::configure_resource (const SmartPtr<Parameters> &param)
const VideoBufferInfo &in_info = param->in_buf->get_video_info ();
XCAM_FAIL_RETURN (
ERROR, in_info.format == V4L2_PIX_FMT_NV12, XCAM_RETURN_ERROR_PARAM,
- "SoftGeoMapper(:%s) only support format(NV12) but input format is %s",
+ "SoftGeoMapper(%s) only support format(NV12) but input format is %s",
XCAM_STR(get_name ()), xcam_fourcc_to_string (in_info.format));
- Float2 factors;
- get_factors (factors.x, factors.y);
- if (XCAM_DOUBLE_EQUAL_AROUND (factors.x, 0.0f) ||
- XCAM_DOUBLE_EQUAL_AROUND (factors.y, 0.0f)) {
- auto_calculate_factors (_lookup_table->get_width (), _lookup_table->get_height ());
- }
-
uint32_t width, height;
get_output_size (width, height);
VideoBufferInfo out_info;
@@ -106,13 +103,51 @@ SoftGeoMapper::configure_resource (const SmartPtr<Parameters> &param)
XCAM_ALIGN_UP (height, XCAM_GEO_MAP_ALIGNMENT_Y));
set_out_video_info (out_info);
+ init_factors ();
+
XCAM_ASSERT (!_map_task.ptr ());
- _map_task = new XCamSoftTasks::GeoMapTask (new CbGeoMapTask(this));
- XCAM_ASSERT (_map_task.ptr ());
+ _map_task = create_remap_task ();
return XCAM_RETURN_NO_ERROR;
}
+void
+SoftGeoMapper::set_work_size (
+ uint32_t thread_x, uint32_t thread_y,
+ uint32_t luma_width, uint32_t luma_height)
+{
+ WorkSize work_unit = _map_task->get_work_uint ();
+ WorkSize global_size (
+ xcam_ceil (luma_width, work_unit.value[0]) / work_unit.value[0],
+ xcam_ceil (luma_height, work_unit.value[1]) / work_unit.value[1]);
+ WorkSize local_size (
+ xcam_ceil(global_size.value[0], thread_x) / thread_x ,
+ xcam_ceil(global_size.value[1], thread_y) / thread_y);
+
+ _map_task->set_local_size (local_size);
+ _map_task->set_global_size (global_size);
+}
+
+bool
+SoftGeoMapper::init_factors ()
+{
+ Float2 factors;
+ get_factors (factors.x, factors.y);
+ if (!XCAM_DOUBLE_EQUAL_AROUND (factors.x, 0.0f) && !XCAM_DOUBLE_EQUAL_AROUND (factors.y, 0.0f))
+ return true;
+
+ return auto_calculate_factors (_lookup_table->get_width (), _lookup_table->get_height ());
+}
+
+SmartPtr<XCamSoftTasks::GeoMapTask>
+SoftGeoMapper::create_remap_task ()
+{
+ SmartPtr<XCamSoftTasks::GeoMapTask> map_task = new XCamSoftTasks::GeoMapTask (new CbGeoMapTask (this));
+ XCAM_ASSERT (map_task.ptr ());
+
+ return map_task;
+}
+
XCamReturn
SoftGeoMapper::start_remap_task (const SmartPtr<ImageHandler::Parameters> &param)
{
@@ -131,17 +166,7 @@ SoftGeoMapper::start_remap_task (const SmartPtr<ImageHandler::Parameters> &param
args->lookup_table = _lookup_table;
args->factors = factors;
- uint32_t thread_x = 2, thread_y = 2;
- WorkSize work_unit = _map_task->get_work_uint ();
- WorkSize global_size (
- xcam_ceil (args->out_luma->get_width (), work_unit.value[0]) / work_unit.value[0],
- xcam_ceil (args->out_luma->get_height (), work_unit.value[1]) / work_unit.value[1]);
- WorkSize local_size (
- xcam_ceil(global_size.value[0], thread_x) / thread_x ,
- xcam_ceil(global_size.value[1], thread_y) / thread_y);
-
- _map_task->set_local_size (local_size);
- _map_task->set_global_size (global_size);
+ set_work_size (2, 2, args->out_luma->get_width (), args->out_luma->get_height ());
param->in_buf.release ();
return _map_task->work (args);
@@ -157,7 +182,7 @@ SoftGeoMapper::start_work (const SmartPtr<ImageHandler::Parameters> &param)
ret = start_remap_task (param);
XCAM_FAIL_RETURN (
ERROR, xcam_ret_is_ok (ret), ret,
- "geo_mapper:%s start_work failed on idx0", XCAM_STR (get_name ()));
+ "SoftGeoMapper(%s) start_work failed on idx0", XCAM_STR (get_name ()));
param->in_buf.release ();
@@ -180,10 +205,11 @@ SoftGeoMapper::remap_task_done (
{
XCAM_UNUSED (worker);
XCAM_ASSERT (worker.ptr () == _map_task.ptr ());
+
SmartPtr<XCamSoftTasks::GeoMapTask::Args> args = base.dynamic_cast_ptr<XCamSoftTasks::GeoMapTask::Args> ();
XCAM_ASSERT (args.ptr ());
- const SmartPtr<ImageHandler::Parameters> param = args->get_param ();
+ const SmartPtr<ImageHandler::Parameters> param = args->get_param ();
if (!check_work_continue (param, error))
return;
@@ -194,6 +220,7 @@ SmartPtr<SoftHandler> create_soft_geo_mapper ()
{
SmartPtr<SoftHandler> mapper = new SoftGeoMapper ();
XCAM_ASSERT (mapper.ptr ());
+
return mapper;
}
@@ -204,4 +231,216 @@ GeoMapper::create_soft_geo_mapper ()
return handler.dynamic_cast_ptr<GeoMapper> ();
}
+SoftDualConstGeoMapper::SoftDualConstGeoMapper (const char *name)
+ : SoftGeoMapper (name)
+ , _left_factor_x (0.0f)
+ , _left_factor_y (0.0f)
+ , _right_factor_x (0.0f)
+ , _right_factor_y (0.0f)
+{
+}
+
+SoftDualConstGeoMapper::~SoftDualConstGeoMapper ()
+{
+}
+
+bool
+SoftDualConstGeoMapper::set_left_factors (float x, float y)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, !XCAM_DOUBLE_EQUAL_AROUND (x, 0.0f) && !XCAM_DOUBLE_EQUAL_AROUND (y, 0.0f), false,
+ "SoftGeoMapper(%s) set factors failed. (x:%.3f, h:%.3f)", XCAM_STR(get_name ()), x, y);
+ _left_factor_x = x;
+ _left_factor_y = y;
+
+ return true;
+}
+
+bool
+SoftDualConstGeoMapper::set_right_factors (float x, float y)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, !XCAM_DOUBLE_EQUAL_AROUND (x, 0.0f) && !XCAM_DOUBLE_EQUAL_AROUND (y, 0.0f), false,
+ "SoftGeoMapper(%s) set factors failed. (x:%.3f, h:%.3f)", XCAM_STR(get_name ()), x, y);
+ _right_factor_x = x;
+ _right_factor_y = y;
+
+ return true;
+}
+
+bool
+SoftDualConstGeoMapper::auto_calculate_factors (uint32_t lut_w, uint32_t lut_h)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, lut_w > 1 && lut_w > 1, false,
+ "SoftGeoMapper(%s) auto calculate factors failed. lookuptable size need > 1. but set with (w:%d, h:%d)",
+ XCAM_STR(get_name ()), lut_w, lut_h);
+
+ uint32_t width, height;
+ get_output_size (width, height);
+ XCAM_FAIL_RETURN (
+ ERROR, width > 1 && height > 1, false,
+ "SoftGeoMapper(%s) auto calculate factors failed. output size was not set. (w:%d, h:%d)",
+ XCAM_STR(get_name ()), width, height);
+
+ _left_factor_x = (width - 1.0f) / (lut_w - 1.0f);
+ _left_factor_y = (height - 1.0f) / (lut_h - 1.0f);
+
+ _right_factor_x = _left_factor_x;
+ _right_factor_y = _left_factor_y;
+
+ return true;
+}
+
+bool
+SoftDualConstGeoMapper::init_factors ()
+{
+ Float2 left_factors, right_factors;
+ get_left_factors (left_factors.x, left_factors.y);
+ get_right_factors (right_factors.x, right_factors.y);
+ if (!XCAM_DOUBLE_EQUAL_AROUND (left_factors.x, 0.0f) && !XCAM_DOUBLE_EQUAL_AROUND (left_factors.y, 0.0f) &&
+ !XCAM_DOUBLE_EQUAL_AROUND (right_factors.x, 0.0f) && !XCAM_DOUBLE_EQUAL_AROUND (right_factors.y, 0.0f))
+ return true;
+
+ SmartPtr<Float2Image> lookup_table = get_lookup_table ();
+ XCAM_ASSERT (lookup_table.ptr ());
+
+ return auto_calculate_factors (lookup_table->get_width (), lookup_table->get_height ());
+}
+
+SmartPtr<XCamSoftTasks::GeoMapTask>
+SoftDualConstGeoMapper::create_remap_task ()
+{
+ SmartPtr<XCamSoftTasks::GeoMapTask> map_task =
+ new XCamSoftTasks::GeoMapDualConstTask (new CbGeoMapDualConstTask (this));
+ XCAM_ASSERT (map_task.ptr ());
+
+ return map_task;
+}
+
+XCamReturn
+SoftDualConstGeoMapper::prepare_arguments (
+ const SmartPtr<Worker::Arguments> &base,
+ const SmartPtr<ImageHandler::Parameters> &param)
+{
+ SmartPtr<Float2Image> lookup_table = get_lookup_table ();
+ XCAM_ASSERT (lookup_table.ptr ());
+
+ SmartPtr<VideoBuffer> in_buf = param->in_buf, out_buf = param->out_buf;
+ SmartPtr<XCamSoftTasks::GeoMapDualConstTask::Args> args =
+ base.dynamic_cast_ptr<XCamSoftTasks::GeoMapDualConstTask::Args> ();
+ XCAM_ASSERT (args.ptr ());
+
+ Float2 factors;
+ get_left_factors (factors.x, factors.y);
+ args->left_factor = factors;
+ get_right_factors (factors.x, factors.y);
+ args->right_factor = factors;
+ args->in_luma = new UcharImage (in_buf, 0);
+ args->in_uv = new Uchar2Image (in_buf, 1);
+ args->out_luma = new UcharImage (out_buf, 0);
+ args->out_uv = new Uchar2Image (out_buf, 1);
+ args->lookup_table = lookup_table;
+
+ set_work_size (2, 2, args->out_luma->get_width (), args->out_luma->get_height ());
+
+ param->in_buf.release ();
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+SoftDualConstGeoMapper::start_remap_task (const SmartPtr<ImageHandler::Parameters> &param)
+{
+ SmartPtr<XCamSoftTasks::GeoMapTask> map_task = get_map_task ();
+ XCAM_ASSERT (map_task.ptr ());
+
+ SmartPtr<XCamSoftTasks::GeoMapDualConstTask::Args> args =
+ new XCamSoftTasks::GeoMapDualConstTask::Args (param);
+ XCAM_ASSERT (args.ptr ());
+
+ prepare_arguments (args, param);
+
+ return map_task->work (args);
+}
+
+void
+SoftDualConstGeoMapper::remap_task_done (
+ const SmartPtr<Worker> &worker, const SmartPtr<Worker::Arguments> &base, const XCamReturn error)
+{
+ XCAM_UNUSED (worker);
+ XCAM_ASSERT (worker.ptr () == get_map_task().ptr ());
+
+ SmartPtr<XCamSoftTasks::GeoMapDualConstTask::Args> args =
+ base.dynamic_cast_ptr<XCamSoftTasks::GeoMapDualConstTask::Args> ();
+ XCAM_ASSERT (args.ptr ());
+
+ const SmartPtr<ImageHandler::Parameters> param = args->get_param ();
+ if (!check_work_continue (param, error))
+ return;
+
+ work_well_done (param, error);
+}
+
+SoftDualCurveGeoMapper::SoftDualCurveGeoMapper (const char *name)
+ : SoftDualConstGeoMapper (name)
+ , _scaled_height (0.0f)
+{
+}
+
+SoftDualCurveGeoMapper::~SoftDualCurveGeoMapper ()
+{
+}
+
+SmartPtr<XCamSoftTasks::GeoMapTask>
+SoftDualCurveGeoMapper::create_remap_task ()
+{
+ SmartPtr<XCamSoftTasks::GeoMapDualCurveTask> map_task =
+ new XCamSoftTasks::GeoMapDualCurveTask (new CbGeoMapDualCurveTask (this));
+ XCAM_ASSERT (map_task.ptr ());
+
+ map_task->set_scaled_height (_scaled_height);
+
+ float factor_x, factor_y;
+ get_left_factors (factor_x, factor_y);
+ map_task->set_left_std_factor (factor_x, factor_y);
+
+ get_right_factors (factor_x, factor_y);
+ map_task->set_right_std_factor (factor_x, factor_y);
+
+ return map_task;
+}
+
+XCamReturn
+SoftDualCurveGeoMapper::start_remap_task (const SmartPtr<ImageHandler::Parameters> &param)
+{
+ SmartPtr<XCamSoftTasks::GeoMapTask> map_task = get_map_task ();
+ XCAM_ASSERT (map_task.ptr ());
+
+ SmartPtr<XCamSoftTasks::GeoMapDualCurveTask::Args> args =
+ new XCamSoftTasks::GeoMapDualCurveTask::Args (param);
+ XCAM_ASSERT (args.ptr ());
+
+ prepare_arguments (args, param);
+
+ return map_task->work (args);
+}
+
+void
+SoftDualCurveGeoMapper::remap_task_done (
+ const SmartPtr<Worker> &worker, const SmartPtr<Worker::Arguments> &base, const XCamReturn error)
+{
+ XCAM_UNUSED (worker);
+ XCAM_ASSERT (worker.ptr () == get_map_task().ptr ());
+
+ SmartPtr<XCamSoftTasks::GeoMapDualCurveTask::Args> args =
+ base.dynamic_cast_ptr<XCamSoftTasks::GeoMapDualCurveTask::Args> ();
+ XCAM_ASSERT (args.ptr ());
+
+ const SmartPtr<ImageHandler::Parameters> param = args->get_param ();
+ if (!check_work_continue (param, error))
+ return;
+
+ work_well_done (param, error);
+}
+
}
diff --git a/modules/soft/soft_geo_mapper.h b/modules/soft/soft_geo_mapper.h
index c0370d3..ef88f9f 100644
--- a/modules/soft/soft_geo_mapper.h
+++ b/modules/soft/soft_geo_mapper.h
@@ -30,13 +30,15 @@ namespace XCam {
namespace XCamSoftTasks {
class GeoMapTask;
+class GeoMapDualConstTask;
+class GeoMapDualCurveTask;
};
class SoftGeoMapper
: public SoftHandler, public GeoMapper
{
public:
- SoftGeoMapper (const char *name = "SoftGeoMap");
+ SoftGeoMapper (const char *name = "SoftGeoMapper");
~SoftGeoMapper ();
bool set_lookup_table (const PointFloat2 *data, uint32_t width, uint32_t height);
@@ -57,8 +59,18 @@ protected:
XCamReturn configure_resource (const SmartPtr<Parameters> &param);
XCamReturn start_work (const SmartPtr<Parameters> &param);
-private:
- XCamReturn start_remap_task (const SmartPtr<ImageHandler::Parameters> &param);
+ void set_work_size (uint32_t thread_x, uint32_t thread_y, uint32_t luma_width, uint32_t luma_height);
+ SmartPtr<XCamSoftTasks::GeoMapTask> &get_map_task () {
+ return _map_task;
+ }
+ SmartPtr<Float2Image> &get_lookup_table () {
+ return _lookup_table;
+ }
+
+protected:
+ virtual bool init_factors ();
+ virtual SmartPtr<XCamSoftTasks::GeoMapTask> create_remap_task ();
+ virtual XCamReturn start_remap_task (const SmartPtr<ImageHandler::Parameters> &param);
private:
SmartPtr<XCamSoftTasks::GeoMapTask> _map_task;
@@ -66,6 +78,64 @@ private:
};
extern SmartPtr<SoftHandler> create_soft_geo_mapper ();
-}
+class SoftDualConstGeoMapper
+ : public SoftGeoMapper
+{
+public:
+ SoftDualConstGeoMapper (const char *name = "SoftDualConstGeoMapper");
+ ~SoftDualConstGeoMapper ();
+
+ bool set_left_factors (float x, float y);
+ void get_left_factors (float &x, float &y) {
+ x = _left_factor_x;
+ y = _left_factor_y;
+ }
+ bool set_right_factors (float x, float y);
+ void get_right_factors (float &x, float &y) {
+ x = _right_factor_x;
+ y = _right_factor_y;
+ }
+
+ virtual void remap_task_done (
+ const SmartPtr<Worker> &worker, const SmartPtr<Worker::Arguments> &args, const XCamReturn error);
+
+protected:
+ XCamReturn prepare_arguments (const SmartPtr<Worker::Arguments> &args,
+ const SmartPtr<ImageHandler::Parameters> &param);
+ virtual bool auto_calculate_factors (uint32_t lut_w, uint32_t lut_h);
+
+protected:
+ virtual bool init_factors ();
+ virtual SmartPtr<XCamSoftTasks::GeoMapTask> create_remap_task ();
+ virtual XCamReturn start_remap_task (const SmartPtr<ImageHandler::Parameters> &param);
+
+private:
+ float _left_factor_x, _left_factor_y;
+ float _right_factor_x, _right_factor_y;
+};
+
+class SoftDualCurveGeoMapper
+ : public SoftDualConstGeoMapper
+{
+public:
+ SoftDualCurveGeoMapper (const char *name = "SoftDualCurveGeoMapper");
+ ~SoftDualCurveGeoMapper ();
+
+ void set_scaled_height (float scaled_height) {
+ _scaled_height = scaled_height;
+ }
+
+ virtual void remap_task_done (
+ const SmartPtr<Worker> &worker, const SmartPtr<Worker::Arguments> &args, const XCamReturn error);
+
+private:
+ virtual SmartPtr<XCamSoftTasks::GeoMapTask> create_remap_task ();
+ virtual XCamReturn start_remap_task (const SmartPtr<ImageHandler::Parameters> &param);
+
+private:
+ float _scaled_height;
+};
+
+}
#endif //XCAM_SOFT_GEO_MAP_H
diff --git a/modules/soft/soft_geo_tasks_priv.cpp b/modules/soft/soft_geo_tasks_priv.cpp
index 8079352..59e8845 100644
--- a/modules/soft/soft_geo_tasks_priv.cpp
+++ b/modules/soft/soft_geo_tasks_priv.cpp
@@ -24,6 +24,100 @@ namespace XCam {
namespace XCamSoftTasks {
+enum BoundState {
+ BoundInternal = 0,
+ BoundCritical,
+ BoundExternal
+};
+
+inline void check_bound (const uint32_t &img_w, const uint32_t &img_h, Float2 *in_pos,
+ const uint32_t &max_idx, BoundState &bound)
+{
+ if (in_pos[0].x >= 0.0f && in_pos[max_idx].x >= 0.0f && in_pos[0].x < img_w && in_pos[max_idx].x < img_w &&
+ in_pos[0].y >= 0.0f && in_pos[max_idx].y >= 0.0f && in_pos[0].y < img_h && in_pos[max_idx].y < img_h)
+ bound = BoundInternal;
+ else if ((in_pos[0].x < 0.0f && in_pos[max_idx].x < 0.0f) || (in_pos[0].x >= img_w && in_pos[max_idx].x >= img_w) ||
+ (in_pos[0].y < 0.0f && in_pos[max_idx].y < 0.0f) || (in_pos[0].y >= img_h && in_pos[max_idx].y >= img_h))
+ bound = BoundExternal;
+ else
+ bound = BoundCritical;
+}
+
+template <typename TypeT>
+inline void calc_critical_pixels (const uint32_t &img_w, const uint32_t &img_h, Float2 *in_pos,
+ const uint32_t &max_idx, const TypeT &zero_byte, TypeT *luma)
+{
+ for (uint32_t idx = 0; idx < max_idx; ++idx) {
+ if (in_pos[idx].x < 0.0f || in_pos[idx].x >= img_w || in_pos[idx].y < 0.0f || in_pos[idx].y >= img_h)
+ luma[idx] = zero_byte;
+ }
+}
+
+static void map_image (
+ const UcharImage *in_luma, const Uchar2Image *in_uv,
+ UcharImage *out_luma, Uchar2Image *out_uv, const Float2Image *lut,
+ const uint32_t &luma_w, const uint32_t &luma_h, const uint32_t &uv_w, const uint32_t &uv_h,
+ const uint32_t &x_idx, const uint32_t &y_idx, const uint32_t &out_x, const uint32_t &out_y,
+ const Float2 &first, const Float2 &step, const Uchar *zero_luma_byte, const Uchar2 *zero_uv_byte)
+{
+ Float2 lut_pos[8] = {
+ first, Float2(first.x + step.x, first.y),
+ Float2(first.x + step.x * 2, first.y), Float2(first.x + step.x * 3, first.y),
+ Float2(first.x + step.x * 4, first.y), Float2(first.x + step.x * 5, first.y),
+ Float2(first.x + step.x * 6, first.y), Float2(first.x + step.x * 7, first.y)
+ };
+
+ //1st-line luma
+ Float2 in_pos[8];
+ float luma_value[8];
+ Uchar luma_uc[8];
+ BoundState bound = BoundInternal;
+ lut->read_interpolate_array<Float2, 8> (lut_pos, in_pos);
+ check_bound (luma_w, luma_h, in_pos, 7, bound);
+ if (bound == BoundExternal)
+ out_luma->write_array_no_check<8> (out_x, out_y, zero_luma_byte);
+ else {
+ in_luma->read_interpolate_array<float, 8> (in_pos, luma_value);
+ convert_to_uchar_N<float, 8> (luma_value, luma_uc);
+ if (bound == BoundCritical)
+ calc_critical_pixels (luma_w, luma_h, in_pos, 8, zero_luma_byte[0], luma_uc);
+ out_luma->write_array_no_check<8> (out_x, out_y, luma_uc);
+ }
+
+ //4x1 UV
+ Float2 uv_value[4];
+ Uchar2 uv_uc[4];
+ in_pos[0] /= 2.0f;
+ in_pos[1] = in_pos[2] / 2.0f;
+ in_pos[2] = in_pos[4] / 2.0f;
+ in_pos[3] = in_pos[6] / 2.0f;
+ check_bound (uv_w, uv_h, in_pos, 3, bound);
+ if (bound == BoundExternal)
+ out_uv->write_array_no_check<4> (x_idx * 4, y_idx, zero_uv_byte);
+ else {
+ in_uv->read_interpolate_array<Float2, 4> (in_pos, uv_value);
+ convert_to_uchar2_N<Float2, 4> (uv_value, uv_uc);
+ if (bound == BoundCritical)
+ calc_critical_pixels (uv_w, uv_h, in_pos, 4, zero_uv_byte[0], uv_uc);
+ out_uv->write_array_no_check<4> (x_idx * 4, y_idx, uv_uc);
+ }
+
+ //2nd-line luma
+ lut_pos[0].y = lut_pos[1].y = lut_pos[2].y = lut_pos[3].y = lut_pos[4].y = lut_pos[5].y =
+ lut_pos[6].y = lut_pos[7].y = first.y + step.y;
+ lut->read_interpolate_array<Float2, 8> (lut_pos, in_pos);
+ check_bound (luma_w, luma_h, in_pos, 7, bound);
+ if (bound == BoundExternal)
+ out_luma->write_array_no_check<8> (out_x, out_y + 1, zero_luma_byte);
+ else {
+ in_luma->read_interpolate_array<float, 8> (in_pos, luma_value);
+ convert_to_uchar_N<float, 8> (luma_value, luma_uc);
+ if (bound == BoundCritical)
+ calc_critical_pixels (luma_w, luma_h, in_pos, 8, zero_luma_byte[0], luma_uc);
+ out_luma->write_array_no_check<8> (out_x, out_y + 1, luma_uc);
+ }
+}
+
XCamReturn
GeoMapTask::work_range (const SmartPtr<Arguments> &base, const WorkRange &range)
{
@@ -31,6 +125,7 @@ GeoMapTask::work_range (const SmartPtr<Arguments> &base, const WorkRange &range)
static const Uchar2 zero_uv_byte[4] = {{128, 128}, {128, 128}, {128, 128}, {128, 128}};
SmartPtr<GeoMapTask::Args> args = base.dynamic_cast_ptr<GeoMapTask::Args> ();
XCAM_ASSERT (args.ptr ());
+
UcharImage *in_luma = args->in_luma.ptr (), *out_luma = args->out_luma.ptr ();
Uchar2Image *in_uv = args->in_uv.ptr (), *out_uv = args->out_uv.ptr ();
Float2Image *lut = args->lookup_table.ptr ();
@@ -39,78 +134,246 @@ GeoMapTask::work_range (const SmartPtr<Arguments> &base, const WorkRange &range)
XCAM_ASSERT (lut);
Float2 factors = args->factors;
- XCAM_ASSERT (
- !XCAM_DOUBLE_EQUAL_AROUND (factors.x, 0.0f) &&
- !XCAM_DOUBLE_EQUAL_AROUND (factors.y, 0.0f));
+ XCAM_ASSERT (!XCAM_DOUBLE_EQUAL_AROUND (factors.x, 0.0f) && !XCAM_DOUBLE_EQUAL_AROUND (factors.y, 0.0f));
+
+ Float2 step = Float2(1.0f, 1.0f) / factors;
Float2 out_center ((out_luma->get_width () - 1.0f ) / 2.0f, (out_luma->get_height () - 1.0f ) / 2.0f);
Float2 lut_center ((lut->get_width () - 1.0f) / 2.0f, (lut->get_height () - 1.0f) / 2.0f);
- float x_step = 1.0f / factors.x;
- float y_step = 1.0f / factors.y;
-#undef OUT_BOUND
-#define OUT_BOUND(image, first, last) \
- (in_pos[first].x >= image->get_width ()) || \
- (in_pos[first].y >= image->get_height ()) || \
- (in_pos[last].x <= 0.0f) || (in_pos[last].y <= 0.0f)
+ uint32_t luma_w = in_luma->get_width ();
+ uint32_t luma_h = in_luma->get_height ();
+ uint32_t uv_w = in_uv->get_width ();
+ uint32_t uv_h = in_uv->get_height ();
for (uint32_t y = range.pos[1]; y < range.pos[1] + range.pos_len[1]; ++y)
for (uint32_t x = range.pos[0]; x < range.pos[0] + range.pos_len[0]; ++x)
{
- // calculate 8x2 luma, center aligned
- Float2 in_pos[8];
- float luma_value[8];
- Uchar luma_uc[8];
uint32_t out_x = x * 8, out_y = y * 2;
- //1st-line luma
+ // calculate 8x2 luma, center aligned
Float2 out_pos (out_x, out_y);
out_pos -= out_center;
Float2 first = out_pos / factors;
first += lut_center;
- Float2 lut_pos[8] = {
- first, Float2(first.x + x_step, first.y),
- Float2(first.x + x_step * 2, first.y), Float2(first.x + x_step * 3, first.y),
- Float2(first.x + x_step * 4, first.y), Float2(first.x + x_step * 5, first.y),
- Float2(first.x + x_step * 6, first.y), Float2(first.x + x_step * 7, first.y)
- };
- lut->read_interpolate_array<Float2, 8> (lut_pos, in_pos);
- in_luma->read_interpolate_array<float, 8> (in_pos, luma_value);
- convert_to_uchar_N<float, 8> (luma_value, luma_uc);
- if (OUT_BOUND (in_luma, 0, 7))
- out_luma->write_array_no_check<8> (out_x, out_y, zero_luma_byte);
- else
- out_luma->write_array_no_check<8> (out_x, out_y, luma_uc);
-
- //4x1 UV
- Float2 uv_value[4];
- Uchar2 uv_uc[4];
- in_pos[0] /= 2.0f;
- in_pos[1] = in_pos[2] / 2.0f;
- in_pos[2] = in_pos[4] / 2.0f;
- in_pos[3] = in_pos[6] / 2.0f;
- in_uv->read_interpolate_array<Float2, 4> (in_pos, uv_value);
- convert_to_uchar2_N<Float2, 4> (uv_value, uv_uc);
- if (OUT_BOUND (in_uv, 0, 3))
- out_uv->write_array_no_check<4> (x * 4, y, zero_uv_byte);
- else
- out_uv->write_array_no_check<4> (x * 4, y, uv_uc);
-
- //2nd-line luma
- lut_pos[0].y = lut_pos[1].y = lut_pos[2].y = lut_pos[3].y = lut_pos[4].y = lut_pos[5].y =
- lut_pos[6].y = lut_pos[7].y = first.y + y_step;
- lut->read_interpolate_array<Float2, 8> (lut_pos, in_pos);
- in_luma->read_interpolate_array<float, 8> (in_pos, luma_value);
- convert_to_uchar_N<float, 8> (luma_value, luma_uc);
- if (OUT_BOUND (in_luma, 0, 7))
- out_luma->write_array_no_check<8> (out_x, out_y + 1, zero_luma_byte);
- else
- out_luma->write_array_no_check<8> (out_x, out_y + 1, luma_uc);
+
+ map_image (in_luma, in_uv, out_luma, out_uv, lut, luma_w, luma_h, uv_w, uv_h,
+ x, y, out_x, out_y, first, step, zero_luma_byte, zero_uv_byte);
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+GeoMapDualConstTask::work_range (const SmartPtr<Arguments> &base, const WorkRange &range)
+{
+ static const Uchar zero_luma_byte[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+ static const Uchar2 zero_uv_byte[4] = {{128, 128}, {128, 128}, {128, 128}, {128, 128}};
+ SmartPtr<GeoMapDualConstTask::Args> args = base.dynamic_cast_ptr<GeoMapDualConstTask::Args> ();
+ XCAM_ASSERT (args.ptr ());
+
+ UcharImage *in_luma = args->in_luma.ptr (), *out_luma = args->out_luma.ptr ();
+ Uchar2Image *in_uv = args->in_uv.ptr (), *out_uv = args->out_uv.ptr ();
+ Float2Image *lut = args->lookup_table.ptr ();
+ XCAM_ASSERT (in_luma && in_uv);
+ XCAM_ASSERT (out_luma && out_uv);
+ XCAM_ASSERT (lut);
+
+ Float2 left_factor = args->left_factor;
+ Float2 right_factor = args->right_factor;
+ XCAM_ASSERT (
+ !XCAM_DOUBLE_EQUAL_AROUND (left_factor.x, 0.0f) && !XCAM_DOUBLE_EQUAL_AROUND (left_factor.y, 0.0f) &&
+ !XCAM_DOUBLE_EQUAL_AROUND (right_factor.x, 0.0f) && !XCAM_DOUBLE_EQUAL_AROUND (right_factor.y, 0.0f));
+
+ Float2 left_step = Float2(1.0f, 1.0f) / left_factor;
+ Float2 right_step = Float2(1.0f, 1.0f) / right_factor;
+
+ Float2 out_center ((out_luma->get_width () - 1.0f ) / 2.0f, (out_luma->get_height () - 1.0f ) / 2.0f);
+ Float2 lut_center ((lut->get_width () - 1.0f) / 2.0f, (lut->get_height () - 1.0f) / 2.0f);
+
+ uint32_t luma_w = in_luma->get_width ();
+ uint32_t luma_h = in_luma->get_height ();
+ uint32_t uv_w = in_uv->get_width ();
+ uint32_t uv_h = in_uv->get_height ();
+
+ for (uint32_t y = range.pos[1]; y < range.pos[1] + range.pos_len[1]; ++y)
+ for (uint32_t x = range.pos[0]; x < range.pos[0] + range.pos_len[0]; ++x)
+ {
+ uint32_t out_x = x * 8, out_y = y * 2;
+ Float2 &factor = (out_x + 4 < out_center.x) ? left_factor : right_factor;
+ Float2 &step = (out_x + 4 < out_center.x) ? left_step : right_step;
+
+ // calculate 8x2 luma, center aligned
+ Float2 out_pos (out_x, out_y);
+ out_pos -= out_center;
+ Float2 first = out_pos / factor;
+ first += lut_center;
+
+ map_image (in_luma, in_uv, out_luma, out_uv, lut, luma_w, luma_h, uv_w, uv_h,
+ x, y, out_x, out_y, first, step, zero_luma_byte, zero_uv_byte);
}
+
return XCAM_RETURN_NO_ERROR;
}
+GeoMapDualCurveTask::GeoMapDualCurveTask (const SmartPtr<Worker::Callback> &cb)
+ : GeoMapDualConstTask (cb)
+ , _scaled_height (0.0f)
+ , _left_std_factor (0.0f, 0.0f)
+ , _right_std_factor (0.0f, 0.0f)
+ , _left_factors (NULL)
+ , _right_factors (NULL)
+ , _left_steps (NULL)
+ , _right_steps (NULL)
+{
+ set_work_uint (8, 2);
}
+GeoMapDualCurveTask::~GeoMapDualCurveTask () {
+ if (_left_factors) {
+ delete [] _left_factors;
+ _left_factors = NULL;
+ }
+ if (_right_factors) {
+ delete [] _right_factors;
+ _right_factors = NULL;
+ }
+ if (_left_steps) {
+ delete [] _left_steps;
+ _left_steps = NULL;
+ }
+ if (_right_steps) {
+ delete [] _right_steps;
+ _right_steps = NULL;
+ }
}
+void
+GeoMapDualCurveTask::set_left_std_factor (float x, float y) {
+ XCAM_ASSERT (!XCAM_DOUBLE_EQUAL_AROUND (x, 0.0f) && !XCAM_DOUBLE_EQUAL_AROUND (y, 0.0f));
+
+ _left_std_factor.x = x;
+ _left_std_factor.y = y;
+}
+
+void
+GeoMapDualCurveTask::set_right_std_factor (float x, float y) {
+ XCAM_ASSERT (!XCAM_DOUBLE_EQUAL_AROUND (x, 0.0f) && !XCAM_DOUBLE_EQUAL_AROUND (y, 0.0f));
+
+ _right_std_factor.x = x;
+ _right_std_factor.y = y;
+}
+
+static void calc_cur_row_factor (
+ const uint32_t &y, const uint32_t &ym,
+ const Float2 &std_factor, const float &scaled_height,
+ const Float2 &factor, Float2 &cur_row_factor)
+{
+ float a, b, c;
+ a = (std_factor.x - factor.x) / ((scaled_height - ym) * (scaled_height - ym));
+ b = -2 * a * ym;
+ c = std_factor.x - a * scaled_height * scaled_height - b * scaled_height;
+ cur_row_factor.x = (y >= scaled_height) ? std_factor.x : ((y < ym) ? factor.x : (a * y * y + b * y + c));
+
+ cur_row_factor.y = factor.y;
+}
+
+void
+GeoMapDualCurveTask::set_factors (SmartPtr<GeoMapDualCurveTask::Args> args, uint32_t size) {
+ if (_left_factors == NULL) {
+ _left_factors = new Float2[size];
+ XCAM_ASSERT (_left_factors);
+ }
+ if (_right_factors == NULL) {
+ _right_factors = new Float2[size];
+ XCAM_ASSERT (_right_factors);
+ }
+
+ float ym = _scaled_height * 0.5f;
+ for (uint32_t y = 0; y < size; ++y) {
+ calc_cur_row_factor (y, ym, _left_std_factor, _scaled_height, args->left_factor, _left_factors[y]);
+ calc_cur_row_factor (y, ym, _right_std_factor, _scaled_height, args->right_factor, _right_factors[y]);
+ }
+}
+
+bool
+GeoMapDualCurveTask::set_steps (uint32_t size) {
+ if (_left_steps == NULL) {
+ _left_steps = new Float2[size];
+ XCAM_ASSERT (_left_steps);
+ }
+ if (_right_steps == NULL) {
+ _right_steps = new Float2[size];
+ XCAM_ASSERT (_right_steps);
+ }
+
+ for (uint32_t y = 0; y < size; ++y) {
+ XCAM_FAIL_RETURN (
+ ERROR,
+ !XCAM_DOUBLE_EQUAL_AROUND (_left_factors[y].x, 0.0f) &&
+ !XCAM_DOUBLE_EQUAL_AROUND (_left_factors[y].y, 0.0f) &&
+ !XCAM_DOUBLE_EQUAL_AROUND (_right_factors[y].x, 0.0f) &&
+ !XCAM_DOUBLE_EQUAL_AROUND (_right_factors[y].y, 0.0f),
+ false,
+ "GeoMapDualCurveTask invalid factor(row:%d): left_factor(x:%f, y:%f) right_factor(x:%f, y:%f)",
+ y, _left_factors[y].x, _left_factors[y].y, _right_factors[y].x, _right_factors[y].y);
+
+ _left_steps[y] = Float2(1.0f, 1.0f) / _left_factors[y];
+ _right_steps[y] = Float2(1.0f, 1.0f) / _right_factors[y];
+ }
+
+ return true;
+}
+
+XCamReturn
+GeoMapDualCurveTask::work_range (const SmartPtr<Arguments> &base, const WorkRange &range)
+{
+ static const Uchar zero_luma_byte[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+ static const Uchar2 zero_uv_byte[4] = {{128, 128}, {128, 128}, {128, 128}, {128, 128}};
+ SmartPtr<GeoMapDualCurveTask::Args> args = base.dynamic_cast_ptr<GeoMapDualCurveTask::Args> ();
+ XCAM_ASSERT (args.ptr ());
+ XCAM_ASSERT (
+ !XCAM_DOUBLE_EQUAL_AROUND (args->left_factor.x, 0.0f) && !XCAM_DOUBLE_EQUAL_AROUND (args->left_factor.y, 0.0f) &&
+ !XCAM_DOUBLE_EQUAL_AROUND (args->right_factor.x, 0.0f) && !XCAM_DOUBLE_EQUAL_AROUND (args->right_factor.y, 0.0f));
+
+ UcharImage *in_luma = args->in_luma.ptr (), *out_luma = args->out_luma.ptr ();
+ Uchar2Image *in_uv = args->in_uv.ptr (), *out_uv = args->out_uv.ptr ();
+ Float2Image *lut = args->lookup_table.ptr ();
+ XCAM_ASSERT (in_luma && in_uv);
+ XCAM_ASSERT (out_luma && out_uv);
+ XCAM_ASSERT (lut);
+
+ set_factors (args, out_luma->get_height ());
+ set_steps (out_luma->get_height ());
+
+ Float2 out_center ((out_luma->get_width () - 1.0f ) / 2.0f, (out_luma->get_height () - 1.0f ) / 2.0f);
+ Float2 lut_center ((lut->get_width () - 1.0f) / 2.0f, (lut->get_height () - 1.0f) / 2.0f);
+
+ uint32_t luma_w = in_luma->get_width ();
+ uint32_t luma_h = in_luma->get_height ();
+ uint32_t uv_w = in_uv->get_width ();
+ uint32_t uv_h = in_uv->get_height ();
+
+ for (uint32_t y = range.pos[1]; y < range.pos[1] + range.pos_len[1]; ++y)
+ for (uint32_t x = range.pos[0]; x < range.pos[0] + range.pos_len[0]; ++x)
+ {
+ uint32_t out_x = x * 8, out_y = y * 2;
+ Float2 &factor = (out_x + 4 < out_center.x) ? _left_factors[out_y] : _right_factors[out_y];
+ Float2 &step = (out_x + 4 < out_center.x) ? _left_steps[out_y] : _right_steps[out_y];
+
+ // calculate 8x2 luma, center aligned
+ Float2 out_pos (out_x, out_y);
+ out_pos -= out_center;
+ Float2 first = out_pos / factor;
+ first += lut_center;
+
+ map_image (in_luma, in_uv, out_luma, out_uv, lut, luma_w, luma_h, uv_w, uv_h,
+ x, y, out_x, out_y, first, step, zero_luma_byte, zero_uv_byte);
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+}
+
+}
diff --git a/modules/soft/soft_geo_tasks_priv.h b/modules/soft/soft_geo_tasks_priv.h
index 36514b2..e1dc4d3 100644
--- a/modules/soft/soft_geo_tasks_priv.h
+++ b/modules/soft/soft_geo_tasks_priv.h
@@ -18,6 +18,9 @@
* Author: Wind Yuan <feng.yuan@intel.com>
*/
+#ifndef XCAM_SOFT_GEO_TASKS_PRIV_H
+#define XCAM_SOFT_GEO_TASKS_PRIV_H
+
#include <xcam_std.h>
#include <soft/soft_worker.h>
#include <soft/soft_image.h>
@@ -54,6 +57,73 @@ private:
virtual XCamReturn work_range (const SmartPtr<Arguments> &args, const WorkRange &range);
};
+class GeoMapDualConstTask
+ : public GeoMapTask
+{
+public:
+ struct Args : GeoMapTask::Args {
+ Float2 left_factor;
+ Float2 right_factor;
+
+ Args (
+ const SmartPtr<ImageHandler::Parameters> &param)
+ : GeoMapTask::Args (param)
+ {}
+ };
+
+public:
+ explicit GeoMapDualConstTask (const SmartPtr<Worker::Callback> &cb)
+ : GeoMapTask (cb)
+ {
+ set_work_uint (8, 2);
+ }
+
+private:
+ virtual XCamReturn work_range (const SmartPtr<Arguments> &args, const WorkRange &range);
+};
+
+class GeoMapDualCurveTask
+ : public GeoMapDualConstTask
+{
+public:
+ struct Args : GeoMapDualConstTask::Args {
+ Args (
+ const SmartPtr<ImageHandler::Parameters> &param)
+ : GeoMapDualConstTask::Args (param)
+ {}
+ };
+
+public:
+ explicit GeoMapDualCurveTask (const SmartPtr<Worker::Callback> &cb);
+ ~GeoMapDualCurveTask ();
+
+ void set_scaled_height (float scaled_height) {
+ XCAM_ASSERT (!XCAM_DOUBLE_EQUAL_AROUND (scaled_height, 0.0f));
+ _scaled_height = scaled_height;
+ }
+
+ void set_left_std_factor (float x, float y);
+ void set_right_std_factor (float x, float y);
+
+private:
+ void set_factors (SmartPtr<GeoMapDualCurveTask::Args> args, uint32_t size);
+ bool set_steps (uint32_t size);
+
+ virtual XCamReturn work_range (const SmartPtr<Arguments> &args, const WorkRange &range);
+
+ XCAM_DEAD_COPY (GeoMapDualCurveTask);
+
+private:
+ float _scaled_height;
+ Float2 _left_std_factor;
+ Float2 _right_std_factor;
+ Float2 *_left_factors;
+ Float2 *_right_factors;
+ Float2 *_left_steps;
+ Float2 *_right_steps;
+};
+
}
}
+#endif // XCAM_SOFT_GEO_TASKS_PRIV_H
diff --git a/modules/soft/soft_handler.cpp b/modules/soft/soft_handler.cpp
index 6a81472..984fa66 100644
--- a/modules/soft/soft_handler.cpp
+++ b/modules/soft/soft_handler.cpp
@@ -82,8 +82,6 @@ SyncMeta::is_error () const
SoftHandler::SoftHandler (const char* name)
: ImageHandler (name)
- , _need_configure (true)
- , _enable_allocator (true)
, _wip_buf_count (0)
{
}
@@ -99,47 +97,29 @@ SoftHandler::set_threads (const SmartPtr<ThreadPool> &pool)
return true;
}
-bool
-SoftHandler::set_out_video_info (const VideoBufferInfo &info)
+SmartPtr<BufferPool>
+SoftHandler::create_allocator ()
{
- XCAM_ASSERT (info.width && info.height && info.format);
- _out_video_info = info;
- return true;
-}
-
-bool
-SoftHandler::enable_allocator (bool enable)
-{
- _enable_allocator = enable;
- return true;
+ return new SoftVideoBufAllocator;
}
XCamReturn
-SoftHandler::confirm_configured ()
+SoftHandler::configure_rest ()
{
XCamReturn ret = XCAM_RETURN_NO_ERROR;
XCAM_ASSERT (_need_configure);
- if (_enable_allocator) {
- XCAM_FAIL_RETURN (
- ERROR, _out_video_info.is_valid (), XCAM_RETURN_ERROR_PARAM,
- "soft_hander(%s) configure resource failed before reserver buffer since out video info was not set",
- XCAM_STR (get_name ()));
-
- set_allocator (new SoftVideoBufAllocator);
- ret = reserve_buffers (_out_video_info, DEFAULT_SOFT_BUF_COUNT);
- XCAM_FAIL_RETURN (
- ERROR, ret == XCAM_RETURN_NO_ERROR, ret,
- "soft_hander(%s) configure resource failed in reserving buffers", XCAM_STR (get_name ()));
- }
+ ret = ImageHandler::configure_rest ();
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "soft_hander(%s) configure reset failed on ImageHandler::configure_rest", XCAM_STR (get_name ()));
if (_threads.ptr () && !_threads->is_running ()) {
ret = _threads->start ();
XCAM_FAIL_RETURN (
- ERROR, ret == XCAM_RETURN_NO_ERROR, ret,
- "soft_hander(%s) configure resource failed when starting threads", XCAM_STR (get_name ()));
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "soft_hander(%s) configure reset failed when starting threads", XCAM_STR (get_name ()));
}
- _need_configure = false;
return ret;
}
@@ -148,7 +128,6 @@ XCamReturn
SoftHandler::execute_buffer (const SmartPtr<ImageHandler::Parameters> &param, bool sync)
{
XCamReturn ret = XCAM_RETURN_NO_ERROR;
- SmartPtr<SyncMeta> sync_meta;
XCAM_FAIL_RETURN (
ERROR, param.ptr (), XCAM_RETURN_ERROR_PARAM,
@@ -161,10 +140,12 @@ SoftHandler::execute_buffer (const SmartPtr<ImageHandler::Parameters> &param, bo
WARNING, xcam_ret_is_ok (ret), ret,
"soft_hander(%s) configure resource failed", XCAM_STR (get_name ()));
- ret = confirm_configured ();
+ ret = configure_rest ();
XCAM_FAIL_RETURN (
WARNING, xcam_ret_is_ok (ret), ret,
"soft_hander(%s) confirm configure failed", XCAM_STR (get_name ()));
+
+ _need_configure = false;
}
if (!param->out_buf.ptr () && _enable_allocator) {
@@ -176,7 +157,7 @@ SoftHandler::execute_buffer (const SmartPtr<ImageHandler::Parameters> &param, bo
}
XCAM_ASSERT (!param->find_meta<SyncMeta> ().ptr ());
- sync_meta = new SyncMeta ();
+ SmartPtr<SyncMeta> sync_meta = new SyncMeta ();
XCAM_ASSERT (sync_meta.ptr ());
param->add_meta (sync_meta);
diff --git a/modules/soft/soft_handler.h b/modules/soft/soft_handler.h
index e2041bf..460762a 100644
--- a/modules/soft/soft_handler.h
+++ b/modules/soft/soft_handler.h
@@ -57,8 +57,6 @@ public:
~SoftHandler ();
bool set_threads (const SmartPtr<ThreadPool> &pool);
- bool set_out_video_info (const VideoBufferInfo &info);
- bool enable_allocator (bool enable);
// derive from ImageHandler
virtual XCamReturn execute_buffer (const SmartPtr<Parameters> &param, bool sync);
@@ -66,8 +64,10 @@ public:
virtual XCamReturn terminate ();
protected:
- virtual XCamReturn configure_resource (const SmartPtr<Parameters> &param) = 0;
- virtual XCamReturn start_work (const SmartPtr<Parameters> &param) = 0;
+ // derived from ImageHandler
+ virtual SmartPtr<BufferPool> create_allocator ();
+ virtual XCamReturn configure_rest ();
+
//virtual SmartPtr<Worker::Arguments> get_first_worker_args (const SmartPtr<SoftWorker> &worker, SmartPtr<Parameters> &params) = 0;
virtual void work_well_done (const SmartPtr<ImageHandler::Parameters> &param, XCamReturn err);
virtual void work_broken (const SmartPtr<ImageHandler::Parameters> &param, XCamReturn err);
@@ -76,7 +76,6 @@ protected:
bool check_work_continue (const SmartPtr<ImageHandler::Parameters> &param, XCamReturn err);
private:
- XCamReturn confirm_configured ();
void param_ended (SmartPtr<ImageHandler::Parameters> param, XCamReturn err);
static bool is_param_error (const SmartPtr<ImageHandler::Parameters> &param);
@@ -85,10 +84,7 @@ private:
private:
SmartPtr<ThreadPool> _threads;
- VideoBufferInfo _out_video_info;
SmartPtr<SyncMeta> _cur_sync;
- bool _need_configure;
- bool _enable_allocator;
SafeList<Parameters> _params;
mutable std::atomic<int32_t> _wip_buf_count;
};
diff --git a/modules/soft/soft_stitcher.cpp b/modules/soft/soft_stitcher.cpp
index 42f0c93..f5189e1 100644
--- a/modules/soft/soft_stitcher.cpp
+++ b/modules/soft/soft_stitcher.cpp
@@ -31,7 +31,7 @@
#define ENABLE_FEATURE_MATCH HAVE_OPENCV
#if ENABLE_FEATURE_MATCH
-#include "cv_capi_feature_match.h"
+#include "ocv/cv_capi_feature_match.h"
#ifndef ANDROID
#include <opencv2/core/ocl.hpp>
#endif
@@ -181,18 +181,24 @@ public:
XCamReturn stop ();
XCamReturn fisheye_dewarp_to_table ();
- XCamReturn feature_match (
- const SmartPtr<VideoBuffer> &left_buf,
- const SmartPtr<VideoBuffer> &right_buf,
- const uint32_t idx);
+ XCamReturn start_feature_match (
+ const SmartPtr<VideoBuffer> &left_buf, const SmartPtr<VideoBuffer> &right_buf, const uint32_t idx);
bool get_and_reset_feature_match_factors (uint32_t idx, Factor &left, Factor &right);
private:
+ SmartPtr<SoftGeoMapper> create_geo_mapper (const Stitcher::RoundViewSlice &view_slice);
+
XCamReturn init_fisheye (uint32_t idx);
bool init_dewarp_factors (uint32_t idx);
XCamReturn create_copier (Stitcher::CopyArea area);
+ void calc_factors (
+ const uint32_t &idx, const Factor &last_left_factor, const Factor &last_right_factor,
+ Factor &cur_left, Factor &cur_right);
+
+ void init_feature_match (uint32_t idx);
+
private:
FisheyeDewarp _fisheye [XCAM_STITCH_MAX_CAMERAS];
Overlap _overlaps [XCAM_STITCH_MAX_CAMERAS];
@@ -205,6 +211,21 @@ private:
SoftStitcher *_stitcher;
};
+
+void
+StitcherImpl::calc_factors (
+ const uint32_t &idx, const Factor &last_left_factor, const Factor &last_right_factor,
+ Factor &cur_left, Factor &cur_right)
+{
+ Factor match_left_factor, match_right_factor;
+ get_and_reset_feature_match_factors (idx, match_left_factor, match_right_factor);
+
+ cur_left.x = last_left_factor.x * match_left_factor.x;
+ cur_left.y = last_left_factor.y * match_left_factor.y;
+ cur_right.x = last_right_factor.x * match_right_factor.x;
+ cur_right.y = last_right_factor.y * match_right_factor.y;
+}
+
bool
StitcherImpl::init_dewarp_factors (uint32_t idx)
{
@@ -212,26 +233,38 @@ StitcherImpl::init_dewarp_factors (uint32_t idx)
ERROR, _fisheye[idx].dewarp.ptr (), false,
"FisheyeDewarp dewarp handler empty");
- Factor match_left_factor, match_right_factor;
- get_and_reset_feature_match_factors (idx, match_left_factor, match_right_factor);
+ Factor last_left_factor, last_right_factor, cur_left, cur_right;
+ if (_stitcher->get_scale_mode () == ScaleSingleConst) {
+ Factor unify_factor;
+ _fisheye[idx].dewarp->get_factors (unify_factor.x, unify_factor.y);
+ if (XCAM_DOUBLE_EQUAL_AROUND (unify_factor.x, 0.0f) ||
+ XCAM_DOUBLE_EQUAL_AROUND (unify_factor.y, 0.0f)) { // not started.
+ return true;
+ }
+ last_left_factor = last_right_factor = unify_factor;
- Factor unify_factor, last_left_factor, last_right_factor;
- _fisheye[idx].dewarp->get_factors (unify_factor.x, unify_factor.y);
- last_left_factor = last_right_factor = unify_factor;
- if (XCAM_DOUBLE_EQUAL_AROUND (unify_factor.x, 0.0f) ||
- XCAM_DOUBLE_EQUAL_AROUND (unify_factor.y, 0.0f)) { // not started.
- return true;
- }
+ calc_factors (idx, last_left_factor, last_right_factor, cur_left, cur_right);
+ unify_factor.x = (cur_left.x + cur_right.x) / 2.0f;
+ unify_factor.y = (cur_left.y + cur_right.y) / 2.0f;
- Factor cur_left, cur_right;
- cur_left.x = last_left_factor.x * match_left_factor.x;
- cur_left.y = last_left_factor.y * match_left_factor.y;
- cur_right.x = last_right_factor.x * match_right_factor.x;
- cur_right.y = last_right_factor.y * match_right_factor.y;
+ _fisheye[idx].dewarp->set_factors (unify_factor.x, unify_factor.y);
+ } else {
+ SmartPtr<SoftDualConstGeoMapper> dewarp = _fisheye[idx].dewarp.dynamic_cast_ptr<SoftDualConstGeoMapper> ();
+ XCAM_ASSERT (dewarp.ptr ());
+ dewarp->get_left_factors (last_left_factor.x, last_left_factor.y);
+ dewarp->get_right_factors (last_right_factor.x, last_right_factor.y);
+ if (XCAM_DOUBLE_EQUAL_AROUND (last_left_factor.x, 0.0f) ||
+ XCAM_DOUBLE_EQUAL_AROUND (last_left_factor.y, 0.0f) ||
+ XCAM_DOUBLE_EQUAL_AROUND (last_right_factor.y, 0.0f) ||
+ XCAM_DOUBLE_EQUAL_AROUND (last_right_factor.y, 0.0f)) { // not started.
+ return true;
+ }
+
+ calc_factors (idx, last_left_factor, last_right_factor, cur_left, cur_right);
- unify_factor.x = (cur_left.x + cur_right.x) / 2.0f;
- unify_factor.y = (cur_left.y + cur_right.y) / 2.0f;
- _fisheye[idx].dewarp->set_factors (unify_factor.x, unify_factor.y);
+ dewarp->set_left_factors (cur_left.x, cur_left.y);
+ dewarp->set_right_factors (cur_right.x, cur_right.y);
+ }
return true;
}
@@ -280,26 +313,49 @@ StitcherImpl::get_and_reset_feature_match_factors (uint32_t idx, Factor &left, F
return true;
}
+SmartPtr<SoftGeoMapper>
+StitcherImpl::create_geo_mapper (const Stitcher::RoundViewSlice &view_slice)
+{
+ SmartPtr<SoftGeoMapper> dewarp;
+ if (_stitcher->get_scale_mode () == ScaleSingleConst)
+ dewarp = new SoftGeoMapper ("sitcher_remapper");
+ else if (_stitcher->get_scale_mode () == ScaleDualConst)
+ dewarp = new SoftDualConstGeoMapper ("sitcher_dualconst_remapper");
+ else {
+ SmartPtr<SoftDualCurveGeoMapper> geomap = new SoftDualCurveGeoMapper ("sitcher_dualcurve_remapper");
+ XCAM_ASSERT (geomap.ptr ());
+
+ BowlDataConfig bowl = _stitcher->get_bowl_config ();
+ float scaled_height = (bowl.wall_height + bowl.ground_length / 2.0f) /
+ (bowl.wall_height + bowl.ground_length) * view_slice.height;
+
+ geomap->set_scaled_height (scaled_height);
+ dewarp = geomap;
+ }
+
+ XCAM_ASSERT (dewarp.ptr ());
+ return dewarp;
+}
+
XCamReturn
StitcherImpl::init_fisheye (uint32_t idx)
{
FisheyeDewarp &fisheye = _fisheye[idx];
+ Stitcher::RoundViewSlice view_slice = _stitcher->get_round_view_slice (idx);
+
SmartPtr<ImageHandler::Callback> dewarp_cb = new CbGeoMap (_stitcher);
- fisheye.dewarp = new SoftGeoMapper ("sitcher_remapper");
- XCAM_ASSERT (fisheye.dewarp.ptr ());
+ fisheye.dewarp = create_geo_mapper (view_slice);;
fisheye.dewarp->set_callback (dewarp_cb);
- Stitcher::RoundViewSlice view_slice =
- _stitcher->get_round_view_slice (idx);
-
VideoBufferInfo buf_info;
buf_info.init (
V4L2_PIX_FMT_NV12, view_slice.width, view_slice.height,
XCAM_ALIGN_UP (view_slice.width, SOFT_STITCHER_ALIGNMENT_X),
XCAM_ALIGN_UP (view_slice.height, SOFT_STITCHER_ALIGNMENT_Y));
- fisheye.buf_pool = new SoftVideoBufAllocator (buf_info);
- XCAM_ASSERT (fisheye.buf_pool.ptr ());
+ SmartPtr<BufferPool> pool = new SoftVideoBufAllocator (buf_info);
+ XCAM_ASSERT (pool.ptr ());
+ fisheye.buf_pool = pool;
XCAM_FAIL_RETURN (
ERROR, fisheye.buf_pool->reserve (2), XCAM_RETURN_ERROR_MEM,
"stitcher:%s reserve dewarp buffer pool(w:%d,h:%d) failed",
@@ -329,6 +385,61 @@ StitcherImpl::create_copier (Stitcher::CopyArea area)
return XCAM_RETURN_NO_ERROR;
}
+void
+StitcherImpl::init_feature_match (uint32_t idx)
+{
+#if ENABLE_FEATURE_MATCH
+
+#ifndef ANDROID
+ FeatureMatchMode fm_mode = _stitcher->get_fm_mode ();
+ if (fm_mode == FMNone)
+ return ;
+ else if (fm_mode == FMDefault)
+ _overlaps[idx].matcher = FeatureMatch::create_default_feature_match ();
+ else if (fm_mode == FMCluster)
+ _overlaps[idx].matcher = FeatureMatch::create_cluster_feature_match ();
+ else if (fm_mode == FMCapi)
+ _overlaps[idx].matcher = FeatureMatch::create_capi_feature_match ();
+ else {
+ XCAM_LOG_ERROR ("unsupported FeatureMatchMode: %d", fm_mode);
+ XCAM_ASSERT (false);
+ }
+#else
+ _overlaps[idx].matcher = new CVCapiFeatureMatch;
+#endif
+ XCAM_ASSERT (_overlaps[idx].matcher.ptr ());
+
+ FMConfig config;
+ config.sitch_min_width = 136;
+ config.min_corners = 4;
+ config.offset_factor = 0.8f;
+ config.delta_mean_offset = 120.0f;
+ config.recur_offset_error = 8.0f;
+ config.max_adjusted_offset = 24.0f;
+ config.max_valid_offset_y = 20.0f;
+ config.max_track_error = 28.0f;
+#ifdef ANDROID
+ config.max_track_error = 3600.0f;
+#endif
+ _overlaps[idx].matcher->set_config (config);
+ _overlaps[idx].matcher->set_fm_index (idx);
+
+ const BowlDataConfig bowl = _stitcher->get_bowl_config ();
+ const Stitcher::ImageOverlapInfo &info = _stitcher->get_overlap (idx);
+ Rect left_ovlap = info.left;
+ Rect right_ovlap = info.right;
+
+ left_ovlap.pos_y = 0;
+ left_ovlap.height = int32_t (bowl.wall_height / (bowl.wall_height + bowl.ground_length) * left_ovlap.height);
+ right_ovlap.pos_y = 0;
+ right_ovlap.height = left_ovlap.height;
+ _overlaps[idx].matcher->set_crop_rect (left_ovlap, right_ovlap);
+#else
+ XCAM_LOG_ERROR ("FeatureMatch unsupported");
+ XCAM_ASSERT (false);
+#endif
+}
+
XCamReturn
StitcherImpl::init_config (uint32_t count)
{
@@ -342,23 +453,7 @@ StitcherImpl::init_config (uint32_t count)
"stitcher:%s init fisheye failed, idx:%d.", XCAM_STR (_stitcher->get_name ()), i);
#if ENABLE_FEATURE_MATCH
- _overlaps[i].matcher = new CVCapiFeatureMatch;
-
- CVFMConfig config;
- config.sitch_min_width = 136;
- config.min_corners = 4;
- config.offset_factor = 0.8f;
- config.delta_mean_offset = 120.0f;
- config.recur_offset_error = 8.0f;
- config.max_adjusted_offset = 24.0f;
- config.max_valid_offset_y = 20.0f;
-#ifndef ANDROID
- config.max_track_error = 28.0f;
-#else
- config.max_track_error = 3600.0f;
-#endif
- _overlaps[i].matcher->set_config (config);
- _overlaps[i].matcher->set_fm_index (i);
+ init_feature_match (i);
#endif
_overlaps[i].blender = create_soft_blender ().dynamic_cast_ptr<SoftBlender>();
@@ -436,7 +531,7 @@ StitcherImpl::fisheye_dewarp_to_table ()
_fisheye[i].dewarp->set_output_size (view_slice.width, view_slice.height);
if (bowl.angle_end < bowl.angle_start)
bowl.angle_start -= 360.0f;
- XCAM_LOG_INFO (
+ XCAM_LOG_DEBUG (
"soft-stitcher:%s camera(idx:%d) info (angle start:%.2f, range:%.2f), bowl info (angle start%.2f, end:%.2f)",
XCAM_STR (_stitcher->get_name ()), i,
view_slice.hori_angle_start, view_slice.hori_angle_range,
@@ -493,24 +588,37 @@ Overlap::find_blender_param_in_map (
}
XCamReturn
-StitcherImpl::feature_match (
+StitcherImpl::start_single_blender (
+ const uint32_t idx,
+ const SmartPtr<BlenderParam> &param)
+{
+ SmartPtr<SoftBlender> blender = _overlaps[idx].blender;
+ const Stitcher::ImageOverlapInfo &overlap_info = _stitcher->get_overlap (idx);
+ uint32_t out_width, out_height;
+ _stitcher->get_output_size (out_width, out_height);
+
+ blender->set_output_size (out_width, out_height);
+ blender->set_merge_window (overlap_info.out_area);
+ blender->set_input_valid_area (overlap_info.left, 0);
+ blender->set_input_valid_area (overlap_info.right, 1);
+ blender->set_input_merge_area (overlap_info.left, 0);
+ blender->set_input_merge_area (overlap_info.right, 1);
+ return blender->execute_buffer (param, false);
+}
+
+XCamReturn
+StitcherImpl::start_feature_match (
const SmartPtr<VideoBuffer> &left_buf,
const SmartPtr<VideoBuffer> &right_buf,
const uint32_t idx)
{
- const Stitcher::ImageOverlapInfo overlap_info = _stitcher->get_overlap (idx);
- Rect left_ovlap = overlap_info.left;
- Rect right_ovlap = overlap_info.right;
- const VideoBufferInfo left_buf_info = left_buf->get_video_info ();
+#if ENABLE_FEATURE_MATCH
+ _overlaps[idx].matcher->reset_offsets ();
+ _overlaps[idx].matcher->feature_match (left_buf, right_buf);
- left_ovlap.pos_y = left_ovlap.height / 5;
- left_ovlap.height = left_ovlap.height / 2;
- right_ovlap.pos_y = right_ovlap.height / 5;
- right_ovlap.height = right_ovlap.height / 2;
+ Rect left_ovlap, right_ovlap;
+ _overlaps[idx].matcher->get_crop_rect (left_ovlap, right_ovlap);
- _overlaps[idx].matcher->reset_offsets ();
- _overlaps[idx].matcher->optical_flow_feature_match (
- left_buf, right_buf, left_ovlap, right_ovlap, left_buf_info.width);
float left_offsetx = _overlaps[idx].matcher->get_current_left_offset_x ();
Factor left_factor, right_factor;
@@ -520,7 +628,7 @@ StitcherImpl::feature_match (
float range = feature_center_x - center_x;
XCAM_ASSERT (range > 1.0f);
right_factor.x = (range + left_offsetx / 2.0f) / range;
- right_factor.y = 1.0;
+ right_factor.y = 1.0f;
XCAM_ASSERT (right_factor.x > 0.0f && right_factor.x < 2.0f);
uint32_t right_idx = (idx + 1) % _stitcher->get_camera_num ();
@@ -529,7 +637,7 @@ StitcherImpl::feature_match (
range = center_x - feature_center_x;
XCAM_ASSERT (range > 1.0f);
left_factor.x = (range + left_offsetx / 2.0f) / range;
- left_factor.y = 1.0;
+ left_factor.y = 1.0f;
XCAM_ASSERT (left_factor.x > 0.0f && left_factor.x < 2.0f);
{
@@ -539,25 +647,10 @@ StitcherImpl::feature_match (
}
return XCAM_RETURN_NO_ERROR;
-}
-
-XCamReturn
-StitcherImpl::start_single_blender (
- const uint32_t idx,
- const SmartPtr<BlenderParam> &param)
-{
- SmartPtr<SoftBlender> blender = _overlaps[idx].blender;
- const Stitcher::ImageOverlapInfo &overlap_info = _stitcher->get_overlap (idx);
- uint32_t out_width, out_height;
- _stitcher->get_output_size (out_width, out_height);
-
- blender->set_output_size (out_width, out_height);
- blender->set_merge_window (overlap_info.out_area);
- blender->set_input_valid_area (overlap_info.left, 0);
- blender->set_input_valid_area (overlap_info.right, 1);
- blender->set_input_merge_area (overlap_info.left, 0);
- blender->set_input_merge_area (overlap_info.right, 1);
- return blender->execute_buffer (param, false);
+#else
+ XCAM_LOG_ERROR ("FeatureMatch unsupported");
+ return XCAM_RETURN_ERROR_PARAM;
+#endif
}
XCamReturn
@@ -606,20 +699,23 @@ StitcherImpl::start_overlap_tasks (
#if ENABLE_FEATURE_MATCH
//start feature match
- if (cur_param.ptr ()) {
- ret = feature_match (cur_param->in_buf, cur_param->in1_buf, idx);
- XCAM_FAIL_RETURN (
- ERROR, xcam_ret_is_ok (ret), ret,
- "soft-stitcher:%s feature-match overlap idx:%d failed", XCAM_STR (_stitcher->get_name ()), idx);
- }
+ if (_stitcher->get_fm_mode ()) {
+ if (cur_param.ptr ()) {
+ ret = start_feature_match (cur_param->in_buf, cur_param->in1_buf, idx);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "soft-stitcher:%s feature-match overlap idx:%d failed", XCAM_STR (_stitcher->get_name ()), idx);
+ }
- if (prev_param.ptr ()) {
- ret = feature_match (prev_param->in_buf, prev_param->in1_buf, pre_idx);
- XCAM_FAIL_RETURN (
- ERROR, xcam_ret_is_ok (ret), ret,
- "soft-stitcher:%s feature-match overlap idx:%d failed", XCAM_STR (_stitcher->get_name ()), pre_idx);
+ if (prev_param.ptr ()) {
+ ret = start_feature_match (prev_param->in_buf, prev_param->in1_buf, pre_idx);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "soft-stitcher:%s feature-match overlap idx:%d failed", XCAM_STR (_stitcher->get_name ()), pre_idx);
+ }
}
#endif
+
return XCAM_RETURN_NO_ERROR;
}
@@ -718,8 +814,10 @@ SoftStitcher::SoftStitcher (const char *name)
: SoftHandler (name)
, Stitcher (SOFT_STITCHER_ALIGNMENT_X, SOFT_STITCHER_ALIGNMENT_Y)
{
- _impl = new SoftSitcherPriv::StitcherImpl (this);
- XCAM_ASSERT (_impl.ptr ());
+ SmartPtr<SoftSitcherPriv::StitcherImpl> impl = new SoftSitcherPriv::StitcherImpl (this);
+ XCAM_ASSERT (impl.ptr ());
+ _impl = impl;
+
#if ENABLE_FEATURE_MATCH
#ifndef ANDROID
cv::ocl::setUseOpenCL (false);
@@ -801,7 +899,7 @@ SoftStitcher::dewarp_done (
if (!check_work_continue (param, error))
return;
- XCAM_LOG_INFO ("soft-stitcher:%s camera(idx:%d) dewarp done", XCAM_STR (get_name ()), dewarp_param->idx);
+ XCAM_LOG_DEBUG ("soft-stitcher:%s camera(idx:%d) dewarp done", XCAM_STR (get_name ()), dewarp_param->idx);
stitcher_dump_buf (dewarp_param->out_buf, dewarp_param->idx, "stitcher-dewarp");
//start both blender and feature match
@@ -834,7 +932,7 @@ SoftStitcher::blender_done (
}
stitcher_dump_buf (blender_param->out_buf, blender_param->idx, "stitcher-blend");
- XCAM_LOG_INFO ("blender:(%s) overlap:%d done", XCAM_STR (handler->get_name ()), blender_param->idx);
+ XCAM_LOG_DEBUG ("blender:(%s) overlap:%d done", XCAM_STR (handler->get_name ()), blender_param->idx);
if (_impl->dec_task_count (param) == 0) {
work_well_done (param, error);
@@ -859,7 +957,7 @@ SoftStitcher::copy_task_done (
_impl->remove_task_count (param);
return;
}
- XCAM_LOG_INFO ("soft-stitcher:%s camera(idx:%d) copy done", XCAM_STR (get_name ()), args->idx);
+ XCAM_LOG_DEBUG ("soft-stitcher:%s camera(idx:%d) copy done", XCAM_STR (get_name ()), args->idx);
if (_impl->dec_task_count (param) == 0) {
work_well_done (param, error);
diff --git a/modules/soft/soft_worker.cpp b/modules/soft/soft_worker.cpp
index 3a76345..9688155 100644
--- a/modules/soft/soft_worker.cpp
+++ b/modules/soft/soft_worker.cpp
@@ -103,8 +103,6 @@ WorkItem::done (XCamReturn err)
SoftWorker::SoftWorker (const char *name, const SmartPtr<Callback> &cb)
: Worker (name, cb)
- , _global (1, 1, 1)
- , _local (1, 1, 1)
, _work_unit (1, 1, 1)
{
}
@@ -136,30 +134,6 @@ SoftWorker::set_threads (const SmartPtr<ThreadPool> &threads)
return true;
}
-bool
-SoftWorker::set_global_size (const WorkSize &size)
-{
- XCAM_FAIL_RETURN (
- ERROR, size.value[0] && size.value[1] && size.value[2], false,
- "SoftWorker(%s) set global size(x:%d, y:%d, z:%d) failed.",
- XCAM_STR (get_name ()), size.value[0], size.value[1], size.value[2]);
-
- _global = size;
- return true;
-}
-
-bool
-SoftWorker::set_local_size (const WorkSize &size)
-{
- XCAM_FAIL_RETURN (
- ERROR, size.value[0] && size.value[1] && size.value[2], false,
- "SoftWorker(%s) set local size(x:%d, y:%d, z:%d) failed.",
- XCAM_STR (get_name ()), size.value[0], size.value[1], size.value[2]);
-
- _local = size;
- return true;
-}
-
XCamReturn
SoftWorker::stop ()
{
@@ -172,14 +146,17 @@ SoftWorker::work (const SmartPtr<Worker::Arguments> &args)
{
XCamReturn ret = XCAM_RETURN_NO_ERROR;
- XCAM_ASSERT (_local.value[0] * _local.value[1] * _local.value[2]);
- XCAM_ASSERT (_global.value[0] * _global.value[1] * _global.value[2]);
+ const WorkSize &global = get_global_size ();
+ const WorkSize &local = get_local_size ();
+
+ XCAM_ASSERT (local.value[0] && local.value[1] && local.value[2]);
+ XCAM_ASSERT (global.value[0] && global.value[1] && global.value[2]);
WorkSize items;
uint32_t max_items = 1;
- for (uint32_t i = 0; i < SOFT_MAX_DIM; ++i) {
- items.value[i] = xcam_ceil (_global.value[i], _local.value[i]) / _local.value[i];
+ for (uint32_t i = 0; i < WORK_MAX_DIM; ++i) {
+ items.value[i] = xcam_ceil (global.value[i], local.value[i]) / local.value[i];
max_items *= items.value[i];
}
@@ -196,8 +173,10 @@ SoftWorker::work (const SmartPtr<Worker::Arguments> &args)
if (!_threads.ptr ()) {
char thr_name [XCAM_MAX_STR_SIZE];
snprintf (thr_name, XCAM_MAX_STR_SIZE, "%s-thrs", XCAM_STR(get_name ()));
- _threads = new ThreadPool (thr_name);
- XCAM_ASSERT (_threads.ptr ());
+
+ SmartPtr<ThreadPool> threads = new ThreadPool (thr_name);
+ XCAM_ASSERT (threads.ptr ());
+ _threads = threads;
_threads->set_threads (max_items, max_items + 1); //extra thread to process all_items_done
ret = _threads->start ();
XCAM_FAIL_RETURN (
@@ -236,13 +215,16 @@ WorkRange
SoftWorker::get_range (const WorkSize &item)
{
WorkRange range;
- for (uint32_t i = 0; i < SOFT_MAX_DIM; ++i) {
- range.pos[i] = item.value[i] * _local.value[i];
- XCAM_ASSERT (range.pos[i] < _global.value[i]);
- if (range.pos[i] + _local.value[i] > _global.value[i])
- range.pos_len[i] = _global.value[i] - range.pos[i];
+ const WorkSize &global = get_global_size ();
+ const WorkSize &local = get_local_size ();
+
+ for (uint32_t i = 0; i < WORK_MAX_DIM; ++i) {
+ range.pos[i] = item.value[i] * local.value[i];
+ XCAM_ASSERT (range.pos[i] < global.value[i]);
+ if (range.pos[i] + local.value[i] > global.value[i])
+ range.pos_len[i] = global.value[i] - range.pos[i];
else
- range.pos_len[i] = _local.value[i];
+ range.pos_len[i] = local.value[i];
}
return range;
}
diff --git a/modules/soft/soft_worker.h b/modules/soft/soft_worker.h
index a851893..e734328 100644
--- a/modules/soft/soft_worker.h
+++ b/modules/soft/soft_worker.h
@@ -24,15 +24,13 @@
#include <xcam_std.h>
#include <worker.h>
-#define SOFT_MAX_DIM 3
-
namespace XCam {
class ThreadPool;
struct WorkRange {
- uint32_t pos[SOFT_MAX_DIM];
- uint32_t pos_len[SOFT_MAX_DIM];
+ uint32_t pos[WORK_MAX_DIM];
+ uint32_t pos_len[WORK_MAX_DIM];
WorkRange () {
xcam_mem_clear (pos);
@@ -40,15 +38,6 @@ struct WorkRange {
}
};
-struct WorkSize {
- uint32_t value[SOFT_MAX_DIM];
- WorkSize (uint32_t x = 1, uint32_t y = 1, uint32_t z = 1) {
- value[0] = x;
- value[1] = y;
- value[2] = z;
- }
-};
-
//multi-thread worker
class SoftWorker
: public Worker
@@ -65,14 +54,6 @@ public:
}
bool set_threads (const SmartPtr<ThreadPool> &threads);
- bool set_global_size (const WorkSize &size);
- const WorkSize &get_global_size () const {
- return _global;
- }
- bool set_local_size (const WorkSize &size);
- const WorkSize &get_local_size () const {
- return _local;
- }
// derived from Worker
virtual XCamReturn work (const SmartPtr<Arguments> &args);
@@ -91,8 +72,6 @@ private:
private:
SmartPtr<ThreadPool> _threads;
- WorkSize _global;
- WorkSize _local;
WorkSize _work_unit;
};
diff --git a/modules/vulkan/Makefile.am b/modules/vulkan/Makefile.am
new file mode 100644
index 0000000..22763f0
--- /dev/null
+++ b/modules/vulkan/Makefile.am
@@ -0,0 +1,76 @@
+lib_LTLIBRARIES = libxcam_vulkan.la
+
+XCAM_VK_CXXFLAGS = \
+ $(XCAM_CXXFLAGS) \
+ $(LIBVULKAN_CFLAGS) \
+ -I$(top_srcdir)/xcore \
+ -I$(top_srcdir)/modules \
+ -I$(top_builddir)/shaders/spv \
+ $(NULL)
+
+XCAM_VK_LIBS = \
+ $(LIBVULKAN_LIBS) \
+ $(top_builddir)/xcore/libxcam_core.la \
+ $(NULL)
+
+if HAVE_OPENCV
+XCAM_VK_LIBS += $(top_builddir)/modules/ocv/libxcam_ocv.la
+endif
+
+xcam_vulkan_sources = \
+ vk_cmdbuf.cpp \
+ vk_descriptor.cpp \
+ vk_device.cpp \
+ vk_handler.cpp \
+ vk_instance.cpp \
+ vk_memory.cpp \
+ vk_pipeline.cpp \
+ vk_shader.cpp \
+ vk_sync.cpp \
+ vk_video_buf_allocator.cpp \
+ vk_worker.cpp \
+ vulkan_common.cpp \
+ vk_copy_handler.cpp \
+ vk_geomap_handler.cpp \
+ vk_blender.cpp \
+ vk_stitcher.cpp \
+ $(NULL)
+
+libxcam_vulkan_la_SOURCES = \
+ $(xcam_vulkan_sources) \
+ $(NULL)
+
+libxcam_vulkan_la_CXXFLAGS = \
+ $(XCAM_VK_CXXFLAGS) \
+ $(NULL)
+
+libxcam_vulkan_la_LIBADD = \
+ $(XCAM_VK_LIBS) \
+ $(NULL)
+
+libxcam_vulkan_la_LDFLAGS = \
+ $(XCAM_LT_LDFLAGS) \
+ $(NULL)
+
+libxcam_vulkanincludedir = $(includedir)/xcam/vulkan
+
+nobase_libxcam_vulkaninclude_HEADERS = \
+ vk_cmdbuf.h \
+ vk_descriptor.h \
+ vk_device.h \
+ vk_handler.h \
+ vk_instance.h \
+ vk_memory.h \
+ vk_pipeline.h \
+ vk_shader.h \
+ vk_sync.h \
+ vk_video_buf_allocator.h \
+ vk_worker.h \
+ vulkan_common.h \
+ vk_copy_handler.h \
+ vk_geomap_handler.h \
+ vk_blender.h \
+ vk_stitcher.h \
+ $(NULL)
+
+libxcam_vulkan_la_LIBTOOLFLAGS = --tag=disable-static
diff --git a/modules/vulkan/vk_blender.cpp b/modules/vulkan/vk_blender.cpp
new file mode 100644
index 0000000..f880649
--- /dev/null
+++ b/modules/vulkan/vk_blender.cpp
@@ -0,0 +1,1537 @@
+/*
+ * vk_blender.cpp - vulkan blender implementation
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#include "xcam_utils.h"
+
+#include "vk_device.h"
+#include "vk_worker.h"
+#include "vk_blender.h"
+#include "vk_video_buf_allocator.h"
+
+#define DUMP_BUFFER 0
+
+#define GAUSS_RADIUS 2
+#define GAUSS_DIAMETER ((GAUSS_RADIUS)*2+1)
+
+const float gauss_coeffs[GAUSS_DIAMETER] = {0.152f, 0.222f, 0.252f, 0.222f, 0.152f};
+
+#define GS_SHADER_BINDING_COUNT 4
+#define LAP_SHADER_BINDING_COUNT 6
+#define BLEND_SHADER_BINDING_COUNT 7
+#define RECONSTRUCT_SHADER_BINDING_COUNT 9
+
+#define CHECK_RET(ret, format, ...) \
+ if (!xcam_ret_is_ok (ret)) { \
+ XCAM_LOG_ERROR (format, ## __VA_ARGS__); \
+ }
+
+#define DECLARE_VK_PUSH_CONST(PushConstClass, PushConstsProp) \
+ class PushConstClass : public VKConstRange::VKPushConstArg { \
+ private: PushConstsProp _prop; \
+ public: \
+ PushConstClass (const PushConstsProp &prop) : _prop (prop) {} \
+ bool get_const_data (VkPushConstantRange &range, void *& ptr) { \
+ range.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; \
+ range.offset = 0; \
+ range.size = sizeof (_prop); \
+ ptr = &_prop; \
+ return true; } \
+ }
+
+namespace XCam {
+
+#if DUMP_BUFFER
+static void
+dump_vkbuf_with_perfix (const SmartPtr<VKBuffer> &buf, const char *perfix_name)
+{
+ XCAM_ASSERT (buf.ptr ());
+ XCAM_ASSERT (perfix_name);
+
+ const VKBufInfo &info = buf->get_buf_info ();
+ char file_name[XCAM_VK_NAME_LENGTH];
+ snprintf (
+ file_name, XCAM_VK_NAME_LENGTH, "%s-%dx%d.%s",
+ perfix_name, info.width, info.height, xcam_fourcc_to_string (info.format));
+
+ FILE *fp = fopen (file_name, "wb");
+ if (!fp) {
+ XCAM_LOG_ERROR ( "vk-blend open file(%s) failed", file_name);
+ }
+
+ uint8_t *ptr = (uint8_t *)buf->map ();
+ for (uint32_t i = 0; i < info.height * 3 / 2; ++i) {
+ uint8_t *start = ptr + info.aligned_width * i;
+ fwrite (start, info.width, 1, fp);
+ }
+ buf->unmap ();
+ fclose (fp);
+}
+#define dump_vkbuf dump_vkbuf_with_perfix
+
+static void
+dump_level_vkbuf (const SmartPtr<VKBuffer> &buf, const char *name, uint32_t level, uint32_t idx)
+{
+ char file_name[XCAM_VK_NAME_LENGTH];
+ snprintf (file_name, XCAM_VK_NAME_LENGTH, "%s-L%d-Idx%d", name, level, idx);
+
+ dump_vkbuf_with_perfix (buf, file_name);
+}
+#endif
+
+namespace VKBlenderPriv {
+
+enum ShaderID {
+ ShaderGaussScalePyr = 0,
+ ShaderLapTransPyr,
+ ShaderBlendPyr,
+ ShaderReconstructPyr
+};
+
+static const VKShaderInfo shaders_info[] = {
+ VKShaderInfo (
+ "main",
+ std::vector<uint32_t> {
+#include "shader_gauss_scale_pyr.comp.spv"
+ }),
+ VKShaderInfo (
+ "main",
+ std::vector<uint32_t> {
+#include "shader_lap_trans_pyr.comp.spv"
+ }),
+ VKShaderInfo (
+ "main",
+ std::vector<uint32_t> {
+#include "shader_blend_pyr.comp.spv"
+ }),
+ VKShaderInfo (
+ "main",
+ std::vector<uint32_t> {
+#include "shader_reconstruct_pyr.comp.spv"
+ })
+};
+
+struct GaussScalePushConstsProp {
+ uint in_img_width;
+ uint in_img_height;
+ uint in_offset_x;
+ uint out_img_width;
+ uint out_img_height;
+ uint merge_width;
+
+ GaussScalePushConstsProp ()
+ : in_img_width (0)
+ , in_img_height (0)
+ , in_offset_x (0)
+ , out_img_width (0)
+ , out_img_height (0)
+ , merge_width (0)
+ {}
+};
+
+struct LapPushConstsProp {
+ uint in_img_width;
+ uint in_img_height;
+ uint in_offset_x;
+ uint gaussscale_img_width;
+ uint gaussscale_img_height;
+ uint merge_width;
+
+ LapPushConstsProp ()
+ : in_img_width (0)
+ , in_img_height (0)
+ , in_offset_x (0)
+ , gaussscale_img_width (0)
+ , gaussscale_img_height (0)
+ , merge_width (0)
+ {}
+};
+
+struct BlendPushConstsProp {
+ uint in_img_width;
+
+ BlendPushConstsProp ()
+ : in_img_width (0)
+ {}
+};
+
+struct ReconstructPushConstsProp {
+ uint lap_img_width;
+ uint lap_img_height;
+ uint out_img_width;
+ uint out_offset_x;
+ uint prev_blend_img_width;
+ uint prev_blend_img_height;
+
+ ReconstructPushConstsProp ()
+ : lap_img_width (0)
+ , lap_img_height (0)
+ , out_img_width (0)
+ , out_offset_x (0)
+ , prev_blend_img_width (0)
+ , prev_blend_img_height (0)
+ {}
+};
+
+DECLARE_VK_PUSH_CONST (VKGaussScalePushConst, GaussScalePushConstsProp);
+DECLARE_VK_PUSH_CONST (VKLapPushConst, LapPushConstsProp);
+DECLARE_VK_PUSH_CONST (VKBlendPushConst, BlendPushConstsProp);
+DECLARE_VK_PUSH_CONST (VKReconstructPushConst, ReconstructPushConstsProp);
+
+DECLARE_WORK_CALLBACK (CbGaussScalePyr, VKBlender, gauss_scale_done);
+DECLARE_WORK_CALLBACK (CbLapTransPyr, VKBlender, lap_trans_done);
+DECLARE_WORK_CALLBACK (CbBlendPyr, VKBlender, blend_done);
+DECLARE_WORK_CALLBACK (CbReconstructPyr, VKBlender, reconstruct_done);
+
+class BlendArgs
+ : public VKWorker::VKArguments
+{
+public:
+ BlendArgs (uint32_t lv, VKBlender::BufIdx i = VKBlender::BufIdx0);
+
+ uint32_t get_level () {
+ return _level;
+ }
+ VKBlender::BufIdx get_idx () {
+ return _idx;
+ }
+
+private:
+ uint32_t _level;
+ VKBlender::BufIdx _idx;
+};
+
+struct PyrLayer {
+ uint32_t blend_width;
+ uint32_t blend_height;
+
+ SmartPtr<VKBlender::Sync> lap_sync[VKBlender::BufIdxMax];
+ SmartPtr<VKBlender::Sync> blend_sync;
+ SmartPtr<VKBlender::Sync> reconstruct_sync;
+
+ SmartPtr<VKBuffer> gs_buf[VKBlender::BufIdxMax];
+ SmartPtr<VKBuffer> lap_buf[VKBlender::BufIdxMax];
+ SmartPtr<VKBuffer> mask;
+ SmartPtr<VKBuffer> blend_buf;
+ SmartPtr<VKBuffer> reconstruct_buf;
+
+ VKDescriptor::SetBindInfoArray gs_bindings[VKBlender::BufIdxMax];
+ VKDescriptor::SetBindInfoArray lap_bindings[VKBlender::BufIdxMax];
+ VKDescriptor::SetBindInfoArray blend_bindings;
+ VKDescriptor::SetBindInfoArray reconstruct_bindings;
+
+ SmartPtr<VKConstRange::VKPushConstArg> gs_consts[VKBlender::BufIdxMax];
+ SmartPtr<VKConstRange::VKPushConstArg> lap_consts[VKBlender::BufIdxMax];
+ SmartPtr<VKConstRange::VKPushConstArg> blend_consts;
+ SmartPtr<VKConstRange::VKPushConstArg> reconstruct_consts;
+
+ WorkSize gs_global_size[VKBlender::BufIdxMax];
+ WorkSize lap_global_size[VKBlender::BufIdxMax];
+ WorkSize blend_global_size;
+ WorkSize reconstruct_global_size;
+
+ VKWorker *gauss_scale[VKBlender::BufIdxMax];
+ VKWorker *lap_trans[VKBlender::BufIdxMax];
+ VKWorker *blend;
+ VKWorker *reconstruct;
+
+ PyrLayer ();
+};
+
+typedef std::map<ShaderID, SmartPtr<VKWorker>> VKWorkers;
+
+class BlenderImpl {
+public:
+ PyrLayer pyr_layer[XCAM_VK_MAX_LEVEL];
+ uint32_t pyr_layers_num;
+
+private:
+ VKBlender *_blender;
+ VKWorkers _workers;
+
+public:
+ BlenderImpl (VKBlender *blender, uint32_t layers_num)
+ : pyr_layers_num (layers_num)
+ , _blender (blender)
+ {
+ XCAM_ASSERT (layers_num >= 2 && layers_num <= XCAM_VK_MAX_LEVEL);
+ }
+
+ XCamReturn start_gauss_scale (uint32_t level, VKBlender::BufIdx idx);
+ XCamReturn start_lap_trans (uint32_t level, VKBlender::BufIdx idx);
+ XCamReturn start_top_blend ();
+ XCamReturn start_reconstruct (uint32_t level);
+ XCamReturn stop ();
+
+ void init_syncs ();
+ XCamReturn init_layers_bufs (const SmartPtr<ImageHandler::Parameters> &base);
+ XCamReturn bind_io_bufs_to_layer0 (
+ SmartPtr<VideoBuffer> &input0, SmartPtr<VideoBuffer> &input1, SmartPtr<VideoBuffer> &output);
+ XCamReturn bind_io_vkbufs_to_desc ();
+ XCamReturn fix_parameters ();
+ XCamReturn create_workers (const SmartPtr<VKBlender> &blender);
+ XCamReturn redirect_workers ();
+
+private:
+ XCamReturn start_lap_tran (uint32_t level, VKBlender::BufIdx idx);
+
+ XCamReturn layer0_allocate_bufs (SmartPtr<VKDevice> dev);
+ XCamReturn layer0_init_mask (SmartPtr<VKDevice> dev);
+
+ XCamReturn layerx_allocate_bufs (SmartPtr<VKDevice> dev, uint32_t level);
+ XCamReturn allocate_vk_bufs (SmartPtr<VKDevice> dev, uint32_t level);
+ XCamReturn scale_down_mask (SmartPtr<VKDevice> dev, uint32_t level);
+
+ XCamReturn fix_gs_params (uint32_t level, VKBlender::BufIdx idx);
+ XCamReturn fix_lap_trans_params (uint32_t level, VKBlender::BufIdx idx);
+ XCamReturn fix_blend_params ();
+ XCamReturn fix_reconstruct_params (uint32_t level);
+};
+
+BlendArgs::BlendArgs (uint32_t lv, VKBlender::BufIdx i)
+ : _level (lv)
+ , _idx (i)
+{
+ XCAM_ASSERT (lv < XCAM_VK_DEFAULT_LEVEL);
+ XCAM_ASSERT (i < VKBlender::BufIdxMax);
+}
+
+PyrLayer::PyrLayer ()
+ : blend_width (0)
+ , blend_height (0)
+{
+}
+
+void
+BlenderImpl::init_syncs ()
+{
+ for (uint32_t i = 0; i < pyr_layers_num - 1; ++i) {
+ PyrLayer &layer = pyr_layer[i];
+
+ layer.lap_sync[VKBlender::BufIdx0] = new VKBlender::Sync (2);
+ XCAM_ASSERT (layer.lap_sync[VKBlender::BufIdx0].ptr ());
+ layer.lap_sync[VKBlender::BufIdx1] = new VKBlender::Sync (2);
+ XCAM_ASSERT (layer.lap_sync[VKBlender::BufIdx1].ptr ());
+
+ layer.reconstruct_sync = new VKBlender::Sync (3);
+ XCAM_ASSERT (layer.reconstruct_sync.ptr ());
+ }
+
+ pyr_layer[pyr_layers_num - 1].blend_sync = new VKBlender::Sync (2);
+ XCAM_ASSERT (pyr_layer[pyr_layers_num - 1].blend_sync.ptr ());
+}
+
+XCamReturn
+BlenderImpl::bind_io_bufs_to_layer0 (
+ SmartPtr<VideoBuffer> &input0, SmartPtr<VideoBuffer> &input1, SmartPtr<VideoBuffer> &output)
+{
+ XCAM_ASSERT (input0.ptr () && input1.ptr ());
+
+ SmartPtr<VKVideoBuffer> in0_vk = input0.dynamic_cast_ptr<VKVideoBuffer> ();
+ SmartPtr<VKVideoBuffer> in1_vk = input1.dynamic_cast_ptr<VKVideoBuffer> ();
+
+ PyrLayer &layer0 = pyr_layer[0];
+ layer0.gs_buf[VKBlender::BufIdx0] = in0_vk->get_vk_buf ();
+ layer0.gs_buf[VKBlender::BufIdx1] = in1_vk->get_vk_buf ();
+ XCAM_ASSERT (layer0.gs_buf[VKBlender::BufIdx0].ptr () && layer0.gs_buf[VKBlender::BufIdx1].ptr ());
+
+ if (!output.ptr ())
+ return XCAM_RETURN_NO_ERROR;
+
+ SmartPtr<VKVideoBuffer> out_vk = output.dynamic_cast_ptr<VKVideoBuffer> ();
+ XCAM_ASSERT (out_vk.ptr ());
+
+ layer0.reconstruct_buf = out_vk->get_vk_buf ();
+ XCAM_ASSERT (layer0.reconstruct_buf.ptr ());
+ layer0.blend_buf = layer0.reconstruct_buf;
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+BlenderImpl::bind_io_vkbufs_to_desc ()
+{
+ PyrLayer &layer0 = pyr_layer[0];
+ PyrLayer &layer1 = pyr_layer[1];
+ XCAM_ASSERT (layer0.gs_buf[VKBlender::BufIdx0].ptr () && layer0.gs_buf[VKBlender::BufIdx1].ptr ());
+ XCAM_ASSERT (layer0.reconstruct_buf.ptr ());
+
+ VKDescriptor::SetBindInfoArray &gs_bindings0 = layer1.gs_bindings[VKBlender::BufIdx0];
+ VKDescriptor::SetBindInfoArray &gs_bindings1 = layer1.gs_bindings[VKBlender::BufIdx1];
+ gs_bindings0[0].desc = VKBufDesc (layer0.gs_buf[VKBlender::BufIdx0], NV12PlaneYIdx);
+ gs_bindings0[1].desc = VKBufDesc (layer0.gs_buf[VKBlender::BufIdx0], NV12PlaneUVIdx);
+ gs_bindings1[0].desc = VKBufDesc (layer0.gs_buf[VKBlender::BufIdx1], NV12PlaneYIdx);
+ gs_bindings1[1].desc = VKBufDesc (layer0.gs_buf[VKBlender::BufIdx1], NV12PlaneUVIdx);
+
+ VKDescriptor::SetBindInfoArray &lap_bindings0 = layer0.lap_bindings[VKBlender::BufIdx0];
+ VKDescriptor::SetBindInfoArray &lap_bindings1 = layer0.lap_bindings[VKBlender::BufIdx1];
+ lap_bindings0[0].desc = VKBufDesc (layer0.gs_buf[VKBlender::BufIdx0], NV12PlaneYIdx);
+ lap_bindings0[1].desc = VKBufDesc (layer0.gs_buf[VKBlender::BufIdx0], NV12PlaneUVIdx);
+ lap_bindings1[0].desc = VKBufDesc (layer0.gs_buf[VKBlender::BufIdx1], NV12PlaneYIdx);
+ lap_bindings1[1].desc = VKBufDesc (layer0.gs_buf[VKBlender::BufIdx1], NV12PlaneUVIdx);
+
+ layer0.reconstruct_bindings[4].desc = VKBufDesc (layer0.reconstruct_buf, NV12PlaneYIdx);
+ layer0.reconstruct_bindings[5].desc = VKBufDesc (layer0.reconstruct_buf, NV12PlaneUVIdx);
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+static void
+convert_to_vkinfo (const VideoBufferInfo &info, VKBufInfo &vk_info)
+{
+ vk_info.format = info.format;
+ vk_info.width = info.width;
+ vk_info.height = info.height;
+ vk_info.aligned_width = info.aligned_width;
+ vk_info.aligned_height = info.aligned_height;
+ vk_info.size = info.size;
+ vk_info.strides[0] = info.strides[0];
+ vk_info.strides[1] = info.strides[1];
+ vk_info.offsets[0] = info.offsets[0];
+ vk_info.offsets[1] = info.offsets[1];
+ vk_info.slice_size[0] = info.strides[0] * info.aligned_height;
+ vk_info.slice_size[1] = info.size - info.offsets[1];
+}
+
+XCamReturn
+BlenderImpl::layer0_allocate_bufs (SmartPtr<VKDevice> dev)
+{
+ if (pyr_layers_num == 1)
+ return XCAM_RETURN_NO_ERROR;
+
+ PyrLayer &layer0 = pyr_layer[0];
+ XCAM_FAIL_RETURN (
+ ERROR, layer0.blend_width && layer0.blend_height, XCAM_RETURN_ERROR_PARAM,
+ "vk-blend invalid blend size:%dx%d", layer0.blend_width, layer0.blend_height);
+
+ VideoBufferInfo info;
+ info.init (
+ V4L2_PIX_FMT_NV12, layer0.blend_width, layer0.blend_height,
+ XCAM_ALIGN_UP (layer0.blend_width, VK_BLENDER_ALIGN_X),
+ XCAM_ALIGN_UP (layer0.blend_height, VK_BLENDER_ALIGN_X));
+
+ VKBufInfo vk_info;
+ convert_to_vkinfo (info, vk_info);
+
+ for (int idx = 0; idx < VKBlender::BufIdxMax; ++idx) {
+ layer0.lap_buf[idx] = VKBuffer::create_buffer (dev, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, vk_info.size);
+ XCAM_ASSERT (layer0.lap_buf[idx].ptr ());
+ layer0.lap_buf[idx]->set_buf_info (vk_info);
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+BlenderImpl::allocate_vk_bufs (SmartPtr<VKDevice> dev, uint32_t level)
+{
+ XCAM_ASSERT (level >= 1 && level < pyr_layers_num);
+
+ PyrLayer &layer = pyr_layer[level];
+ VideoBufferInfo info;
+ info.init (
+ V4L2_PIX_FMT_NV12, layer.blend_width, layer.blend_height,
+ XCAM_ALIGN_UP (layer.blend_width, VK_BLENDER_ALIGN_X),
+ XCAM_ALIGN_UP (layer.blend_height, VK_BLENDER_ALIGN_X));
+
+ VKBufInfo vk_info;
+ convert_to_vkinfo (info, vk_info);
+
+ bool top_layer = (level == pyr_layers_num - 1);
+ for (int idx = 0; idx < VKBlender::BufIdxMax; ++idx) {
+ layer.gs_buf[idx] = VKBuffer::create_buffer (dev, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, vk_info.size);
+ XCAM_ASSERT (layer.gs_buf[idx].ptr ());
+ layer.gs_buf[idx]->set_buf_info (vk_info);
+
+ if (top_layer)
+ continue;
+
+ layer.lap_buf[idx] = VKBuffer::create_buffer (dev, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, vk_info.size);
+ XCAM_ASSERT (layer.lap_buf[idx].ptr ());
+ layer.lap_buf[idx]->set_buf_info (vk_info);
+ }
+
+ layer.reconstruct_buf = VKBuffer::create_buffer (dev, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, vk_info.size);
+ XCAM_ASSERT (layer.reconstruct_buf.ptr ());
+ layer.reconstruct_buf->set_buf_info (vk_info);
+
+ if (top_layer)
+ layer.blend_buf = layer.reconstruct_buf;
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+BlenderImpl::layer0_init_mask (SmartPtr<VKDevice> dev)
+{
+ PyrLayer &layer = pyr_layer[0];
+ XCAM_ASSERT (layer.blend_width && ((layer.blend_width % VK_BLENDER_ALIGN_X) == 0));
+
+ uint32_t buf_size = layer.blend_width * sizeof (uint8_t);
+ SmartPtr<VKBuffer> buf = VKBuffer::create_buffer (dev, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, buf_size);
+ XCAM_ASSERT (buf.ptr ());
+
+ VKBufInfo info;
+ info.width = layer.blend_width;
+ info.height = 1;
+ info.size = buf_size;
+ buf->set_buf_info (info);
+
+ std::vector<float> gauss_table;
+ uint32_t quater = info.width / 4;
+
+ get_gauss_table (quater, (quater + 1) / 4.0f, gauss_table, false);
+ for (uint32_t i = 0; i < gauss_table.size (); ++i) {
+ float value = ((i < quater) ? (128.0f * (2.0f - gauss_table[i])) : (128.0f * gauss_table[i]));
+ value = XCAM_CLAMP (value, 0.0f, 255.0f);
+ gauss_table[i] = value;
+ }
+
+ uint8_t *mask_ptr = (uint8_t *) buf->map (buf_size, 0);
+ XCAM_FAIL_RETURN (ERROR, mask_ptr, XCAM_RETURN_ERROR_PARAM, "vk-blend map range failed");
+
+ uint32_t gauss_start_pos = (info.width - gauss_table.size ()) / 2;
+ uint32_t idx = 0;
+ for (idx = 0; idx < gauss_start_pos; ++idx) {
+ mask_ptr[idx] = 255;
+ }
+ for (uint32_t i = 0; i < gauss_table.size (); ++idx, ++i) {
+ mask_ptr[idx] = (uint8_t) gauss_table[i];
+ }
+ for (; idx < info.width; ++idx) {
+ mask_ptr[idx] = 0;
+ }
+ buf->unmap ();
+
+ layer.mask = buf;
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+BlenderImpl::scale_down_mask (SmartPtr<VKDevice> dev, uint32_t level)
+{
+ XCAM_ASSERT (level >= 1 && level < pyr_layers_num);
+
+ PyrLayer &layer = pyr_layer[level];
+ PyrLayer &prev_layer = pyr_layer[level - 1];
+
+ XCAM_ASSERT (prev_layer.mask.ptr ());
+ XCAM_ASSERT (layer.blend_width && ((layer.blend_width % VK_BLENDER_ALIGN_X) == 0));
+
+ uint32_t buf_size = layer.blend_width * sizeof (uint8_t);
+ SmartPtr<VKBuffer> buf = VKBuffer::create_buffer (dev, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, buf_size);
+ XCAM_ASSERT (buf.ptr ());
+
+ VKBufInfo info;
+ info.width = layer.blend_width;
+ info.height = 1;
+ info.size = buf_size;
+ buf->set_buf_info (info);
+
+ const VKBufInfo prev_info = prev_layer.mask->get_buf_info ();
+ uint8_t *prev_ptr = (uint8_t *) prev_layer.mask->map (prev_info.size, 0);
+ XCAM_FAIL_RETURN (ERROR, prev_ptr, XCAM_RETURN_ERROR_PARAM, "vk-blend map range failed");
+
+ uint8_t *cur_ptr = (uint8_t *) buf->map (info.size, 0);
+ XCAM_FAIL_RETURN (ERROR, cur_ptr, XCAM_RETURN_ERROR_PARAM, "vk-blend map range failed");
+
+ for (uint32_t i = 0; i < info.width; ++i) {
+ int prev_start = i * 2 - 2;
+ float sum = 0.0f;
+
+ for (int j = 0; j < GAUSS_DIAMETER; ++j) {
+ int prev_idx = XCAM_CLAMP (prev_start + j, 0, (int)prev_info.width);
+ sum += prev_ptr[prev_idx] * gauss_coeffs[j];
+ }
+
+ cur_ptr[i] = XCAM_CLAMP (sum, 0.0f, 255.0f);
+ }
+
+ buf->unmap ();
+ prev_layer.mask->unmap ();
+
+ layer.mask = buf;
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+BlenderImpl::layerx_allocate_bufs (SmartPtr<VKDevice> dev, uint32_t level)
+{
+ XCAM_ASSERT (level >= 1 && level < pyr_layers_num);
+
+ PyrLayer &layer = pyr_layer[level];
+ PyrLayer &prev_layer = pyr_layer[level - 1];
+ XCAM_FAIL_RETURN (
+ ERROR, prev_layer.blend_width && prev_layer.blend_height, XCAM_RETURN_ERROR_PARAM,
+ "vk-blend invalid blend size:%dx%d", prev_layer.blend_width, prev_layer.blend_height);
+
+ layer.blend_width = XCAM_ALIGN_UP ((prev_layer.blend_width + 1) / 2, VK_BLENDER_ALIGN_X);
+ layer.blend_height = XCAM_ALIGN_UP ((prev_layer.blend_height + 1) / 2, VK_BLENDER_ALIGN_Y);
+
+ XCamReturn ret = allocate_vk_bufs (dev, level);
+ XCAM_FAIL_RETURN (ERROR, xcam_ret_is_ok (ret), ret, "vk-blend build vk buffers failed, level:%d", level);
+
+ ret = scale_down_mask (dev, level);
+ XCAM_FAIL_RETURN (ERROR, xcam_ret_is_ok (ret), ret, "vk-blend scale down mask failed, level:%d", level);
+
+ return ret;
+}
+
+static XCamReturn
+check_desc (
+ const VideoBufferInfo &in0_info, const VideoBufferInfo &in1_info,
+ const Rect &merge0_area, const Rect &merge1_area)
+{
+ XCAM_FAIL_RETURN (
+ ERROR,
+ in0_info.width && in0_info.height && in1_info.width &&
+ in0_info.height == in1_info.height,
+ XCAM_RETURN_ERROR_PARAM,
+ "vk-blend invalid buffer size: in0:%dx%d in1:%dx%d out:%dx%d",
+ in0_info.width, in0_info.height, in1_info.width, in1_info.height);
+
+ XCAM_FAIL_RETURN (
+ ERROR,
+ merge0_area.width && merge0_area.width == merge1_area.width &&
+ merge0_area.pos_y == 0 && merge1_area.pos_y == 0 &&
+ merge0_area.height == merge1_area.height && merge0_area.height == (int32_t)in0_info.height,
+ XCAM_RETURN_ERROR_PARAM,
+ "vk-blend invalid merge area: merge0(%d, %d, %d, %d) merge1(%d, %d, %d, %d)",
+ merge0_area.pos_x, merge0_area.pos_y, merge0_area.width, merge0_area.height,
+ merge1_area.pos_x, merge1_area.pos_y, merge1_area.width, merge1_area.height);
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+BlenderImpl::init_layers_bufs (const SmartPtr<ImageHandler::Parameters> &base)
+{
+ XCAM_ASSERT (base.ptr ());
+ SmartPtr<VKBlender::BlenderParam> param = base.dynamic_cast_ptr<VKBlender::BlenderParam> ();
+ XCAM_ASSERT (param.ptr () && param->in_buf.ptr () && param->in1_buf.ptr ());
+
+ const VideoBufferInfo &in0_info = param->in_buf->get_video_info ();
+ const VideoBufferInfo &in1_info = param->in1_buf->get_video_info ();
+ const Rect merge0_area = _blender->get_input_merge_area (VKBlender::BufIdx0);
+ const Rect merge1_area = _blender->get_input_merge_area (VKBlender::BufIdx1);
+
+ XCamReturn ret = check_desc (in0_info, in1_info, merge0_area, merge1_area);
+ XCAM_FAIL_RETURN (ERROR, xcam_ret_is_ok (ret), ret, "vk-blend check desc failed");
+
+ PyrLayer &layer0 = pyr_layer[0];
+ layer0.blend_width = XCAM_ALIGN_UP (merge0_area.width, VK_BLENDER_ALIGN_X);
+ layer0.blend_height = XCAM_ALIGN_UP (merge0_area.height, VK_BLENDER_ALIGN_Y);
+
+ SmartPtr<VKDevice> dev = _blender->get_vk_device ();
+ XCAM_ASSERT (dev.ptr ());
+
+ ret = bind_io_bufs_to_layer0 (param->in_buf, param->in1_buf, param->out_buf);
+ XCAM_FAIL_RETURN (ERROR, xcam_ret_is_ok (ret), ret, "vk-blend bind bufs to layer0 failed");
+ ret = layer0_allocate_bufs (dev);
+ XCAM_FAIL_RETURN (ERROR, xcam_ret_is_ok (ret), ret, "vk-blend layer0 build buffers failed");
+ ret = layer0_init_mask (dev);
+ XCAM_FAIL_RETURN (ERROR, xcam_ret_is_ok (ret), ret, "vk-blend layer0 init mask failed");
+
+ for (uint32_t level = 1; level < pyr_layers_num; ++level) {
+ layerx_allocate_bufs (dev, level);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "vk-blend build buffers failed, level:%d", level);
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+static SmartPtr<VKWorker>
+create_gauss_scale_pyr_shader (const SmartPtr<VKBlender> &blender)
+{
+ SmartPtr<VKDevice> dev = blender->get_vk_device ();
+ XCAM_ASSERT (dev.ptr ());
+
+ GaussScalePushConstsProp prop;
+ VKConstRange::VKPushConstArgs push_consts;
+ push_consts.push_back (new VKGaussScalePushConst (prop));
+
+ VKDescriptor::BindingArray binding_layout;
+ binding_layout.clear ();
+ for (int i = 0; i < GS_SHADER_BINDING_COUNT; ++i) {
+ SmartPtr<VKDescriptor::SetLayoutBinding> binding =
+ new VKDescriptor::ComputeLayoutBinding (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, i);
+ binding_layout.push_back (binding);
+ }
+
+ SmartPtr<VKWorker> worker = new VKWorker (dev, "VKGaussScaleShader", new CbGaussScalePyr (blender));
+ XCAM_ASSERT (worker.ptr ());
+
+ XCamReturn ret = worker->build (shaders_info[ShaderGaussScalePyr], binding_layout, push_consts);
+ XCAM_FAIL_RETURN (ERROR, xcam_ret_is_ok (ret), NULL, "vk-blend build VKGaussScaleShader failed");
+
+ return worker;
+}
+
+static SmartPtr<VKWorker>
+create_lap_trans_pyr_shader (const SmartPtr<VKBlender> &blender)
+{
+ SmartPtr<VKDevice> dev = blender->get_vk_device ();
+ XCAM_ASSERT (dev.ptr ());
+
+ LapPushConstsProp prop;
+ VKConstRange::VKPushConstArgs push_consts;
+ push_consts.push_back (new VKLapPushConst (prop));
+
+ VKDescriptor::BindingArray binding_layout;
+ binding_layout.clear ();
+ for (int i = 0; i < LAP_SHADER_BINDING_COUNT; ++i) {
+ SmartPtr<VKDescriptor::SetLayoutBinding> binding =
+ new VKDescriptor::ComputeLayoutBinding (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, i);
+ binding_layout.push_back (binding);
+ }
+
+ SmartPtr<VKWorker> worker = new VKWorker (dev, "VKLapTransShader", new CbLapTransPyr (blender));
+ XCAM_ASSERT (worker.ptr ());
+
+ XCamReturn ret = worker->build (shaders_info[ShaderLapTransPyr], binding_layout, push_consts);
+ XCAM_FAIL_RETURN (ERROR, xcam_ret_is_ok (ret), NULL, "vk-blend build VKLapTransShader failed");
+
+ return worker;
+}
+
+static SmartPtr<VKWorker>
+create_blend_pyr_shader (const SmartPtr<VKBlender> &blender)
+{
+ SmartPtr<VKDevice> dev = blender->get_vk_device ();
+ XCAM_ASSERT (dev.ptr ());
+
+ BlendPushConstsProp prop;
+ VKConstRange::VKPushConstArgs push_consts;
+ push_consts.push_back (new VKBlendPushConst (prop));
+
+ VKDescriptor::BindingArray binding_layout;
+ binding_layout.clear ();
+ for (int i = 0; i < BLEND_SHADER_BINDING_COUNT; ++i) {
+ SmartPtr<VKDescriptor::SetLayoutBinding> binding =
+ new VKDescriptor::ComputeLayoutBinding (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, i);
+ binding_layout.push_back (binding);
+ }
+
+ SmartPtr<VKWorker> worker = new VKWorker (dev, "VKBlendPyrShader", new CbBlendPyr (blender));
+ XCAM_ASSERT (worker.ptr ());
+
+ XCamReturn ret = worker->build (shaders_info[ShaderBlendPyr], binding_layout, push_consts);
+ XCAM_FAIL_RETURN (ERROR, xcam_ret_is_ok (ret), NULL, "vk-blend build VKBlendPyrShader failed");
+
+ return worker;
+}
+
+static SmartPtr<VKWorker>
+create_reconstruct_pyr_shader (const SmartPtr<VKBlender> &blender)
+{
+ SmartPtr<VKDevice> dev = blender->get_vk_device ();
+ XCAM_ASSERT (dev.ptr ());
+
+ ReconstructPushConstsProp prop;
+ VKConstRange::VKPushConstArgs push_consts;
+ push_consts.push_back (new VKReconstructPushConst (prop));
+
+ VKDescriptor::BindingArray binding_layout;
+ binding_layout.clear ();
+ for (int i = 0; i < RECONSTRUCT_SHADER_BINDING_COUNT; ++i) {
+ SmartPtr<VKDescriptor::SetLayoutBinding> binding =
+ new VKDescriptor::ComputeLayoutBinding (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, i);
+ binding_layout.push_back (binding);
+ }
+
+ SmartPtr<VKWorker> worker = new VKWorker (dev, "VKReconstructShader", new CbReconstructPyr (blender));
+ XCAM_ASSERT (worker.ptr ());
+
+ XCamReturn ret = worker->build (shaders_info[ShaderReconstructPyr], binding_layout, push_consts);
+ XCAM_FAIL_RETURN (ERROR, xcam_ret_is_ok (ret), NULL, "vk-blend build VKReconstructShader failed");
+
+ return worker;
+}
+
+XCamReturn
+BlenderImpl::create_workers (const SmartPtr<VKBlender> &blender)
+{
+ XCAM_ASSERT (blender.ptr ());
+
+ VKWorkers::iterator i = _workers.find (ShaderGaussScalePyr);
+ if (i == _workers.end ()) {
+ SmartPtr<VKWorker> gauss_scale = create_gauss_scale_pyr_shader (blender);
+ XCAM_ASSERT (gauss_scale.ptr ());
+ _workers.insert (std::make_pair (ShaderGaussScalePyr, gauss_scale));
+ }
+
+ i = _workers.find (ShaderLapTransPyr);
+ if (i == _workers.end ()) {
+ SmartPtr<VKWorker> lap_trans = create_lap_trans_pyr_shader (blender);
+ XCAM_ASSERT (lap_trans.ptr ());
+ _workers.insert (std::make_pair (ShaderLapTransPyr, lap_trans));
+ }
+
+ i = _workers.find (ShaderBlendPyr);
+ if (i == _workers.end ()) {
+ SmartPtr<VKWorker> blend = create_blend_pyr_shader (blender);
+ XCAM_ASSERT (blend.ptr ());
+ _workers.insert (std::make_pair (ShaderBlendPyr, blend));
+ }
+
+ i = _workers.find (ShaderReconstructPyr);
+ if (i == _workers.end ()) {
+ SmartPtr<VKWorker> reconstruct = create_reconstruct_pyr_shader (blender);
+ XCAM_ASSERT (reconstruct.ptr ());
+ _workers.insert (std::make_pair (ShaderReconstructPyr, reconstruct));
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+BlenderImpl::redirect_workers ()
+{
+ VKWorkers::iterator i = _workers.find (ShaderGaussScalePyr);
+ XCAM_ASSERT (i != _workers.end ());
+ SmartPtr<VKWorker> gauss_scale = i->second;
+
+ i = _workers.find (ShaderLapTransPyr);
+ XCAM_ASSERT (i != _workers.end ());
+ SmartPtr<VKWorker> lap_trans = i->second;
+
+ i = _workers.find (ShaderBlendPyr);
+ XCAM_ASSERT (i != _workers.end ());
+ SmartPtr<VKWorker> top_blend = i->second;
+
+ i = _workers.find (ShaderReconstructPyr);
+ XCAM_ASSERT (i != _workers.end ());
+ SmartPtr<VKWorker> reconstruct = i->second;
+
+ XCAM_ASSERT (gauss_scale.ptr () && lap_trans.ptr () && reconstruct.ptr () && top_blend.ptr ());
+ for (uint32_t i = 0; i < pyr_layers_num - 1; ++i) {
+ PyrLayer &layer_next = pyr_layer[i + 1];
+ layer_next.gauss_scale[VKBlender::BufIdx0] = gauss_scale.ptr ();
+ layer_next.gauss_scale[VKBlender::BufIdx1] = gauss_scale.ptr ();
+
+ PyrLayer &layer = pyr_layer[i];
+ layer.lap_trans[VKBlender::BufIdx0] = lap_trans.ptr ();
+ layer.lap_trans[VKBlender::BufIdx1] = lap_trans.ptr ();
+ layer.reconstruct = reconstruct.ptr ();
+ }
+
+ PyrLayer &top_layer = pyr_layer[pyr_layers_num - 1];
+ top_layer.blend = top_blend.ptr ();
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+BlenderImpl::fix_parameters ()
+{
+ for (uint32_t i = 0; i < pyr_layers_num - 1; ++i) {
+ fix_gs_params (i + 1, VKBlender::BufIdx0);
+ fix_gs_params (i + 1, VKBlender::BufIdx1);
+
+ fix_lap_trans_params (i, VKBlender::BufIdx0);
+ fix_lap_trans_params (i, VKBlender::BufIdx1);
+
+ fix_reconstruct_params (i);
+ }
+
+ fix_blend_params ();
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+BlenderImpl::fix_gs_params (uint32_t level, VKBlender::BufIdx idx)
+{
+ XCAM_ASSERT (level >= 1);
+
+ uint32_t level_in = level - 1;
+ PyrLayer &layer_in = pyr_layer[level_in];
+ PyrLayer &layer_out = pyr_layer[level];
+ XCAM_ASSERT (layer_out.gs_buf[idx].ptr () && (layer_in.gs_buf[idx].ptr () || level == 1));
+
+ VKDescriptor::BindingArray binding_layout;
+ binding_layout.clear ();
+ for (int i = 0; i < GS_SHADER_BINDING_COUNT; ++i) {
+ SmartPtr<VKDescriptor::SetLayoutBinding> binding =
+ new VKDescriptor::ComputeLayoutBinding (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, i);
+ binding_layout.push_back (binding);
+ }
+
+ VKDescriptor::SetBindInfoArray bindings (GS_SHADER_BINDING_COUNT);
+ bindings[0].layout = binding_layout[0];
+ bindings[1].layout = binding_layout[1];
+ if (layer_in.gs_buf[idx].ptr ()) {
+ bindings[0].desc = VKBufDesc (layer_in.gs_buf[idx], NV12PlaneYIdx);
+ bindings[1].desc = VKBufDesc (layer_in.gs_buf[idx], NV12PlaneUVIdx);
+ }
+ bindings[2].layout = binding_layout[2];
+ bindings[2].desc = VKBufDesc (layer_out.gs_buf[idx], NV12PlaneYIdx);
+ bindings[3].layout = binding_layout[3];
+ bindings[3].desc = VKBufDesc (layer_out.gs_buf[idx], NV12PlaneUVIdx);
+ layer_out.gs_bindings[idx] = bindings;
+
+ const VKBufInfo in_info = layer_in.gs_buf[idx]->get_buf_info ();
+ const VKBufInfo out_info = layer_out.gs_buf[idx]->get_buf_info ();
+
+ size_t unit_bytes = sizeof (uint32_t);
+ GaussScalePushConstsProp prop;
+ prop.in_img_width = XCAM_ALIGN_UP (in_info.width, unit_bytes) / unit_bytes;
+ prop.in_img_height = in_info.height;
+ prop.out_img_width = XCAM_ALIGN_UP (out_info.width, unit_bytes) / unit_bytes;
+ prop.out_img_height = out_info.height;
+ if (level == 1) {
+ const Rect area = _blender->get_input_merge_area (idx);
+ prop.in_offset_x = XCAM_ALIGN_UP (area.pos_x, unit_bytes) / unit_bytes;
+ prop.merge_width = XCAM_ALIGN_UP (area.width, unit_bytes) / unit_bytes;
+ } else {
+ prop.in_offset_x = 0;
+ prop.merge_width = XCAM_ALIGN_UP (in_info.width, unit_bytes) / unit_bytes;
+ }
+ layer_out.gs_consts[idx] = new VKGaussScalePushConst (prop);
+
+ layer_out.gs_global_size[idx] = WorkSize (
+ XCAM_ALIGN_UP (prop.out_img_width, 8) / 8,
+ XCAM_ALIGN_UP (out_info.height, 16) / 16);
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+BlenderImpl::fix_lap_trans_params (uint32_t level, VKBlender::BufIdx idx)
+{
+ XCAM_ASSERT (level < pyr_layers_num - 1);
+
+ PyrLayer &layer = pyr_layer[level];
+ PyrLayer &layer_next = pyr_layer[level + 1];
+ XCAM_ASSERT ((layer.gs_buf[idx].ptr () || level == 0) && layer_next.gs_buf[idx].ptr ());
+ XCAM_ASSERT (layer.lap_buf[idx].ptr ());
+
+ VKDescriptor::BindingArray binding_layout;
+ binding_layout.clear ();
+ for (int i = 0; i < LAP_SHADER_BINDING_COUNT; ++i) {
+ SmartPtr<VKDescriptor::SetLayoutBinding> binding =
+ new VKDescriptor::ComputeLayoutBinding (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, i);
+ binding_layout.push_back (binding);
+ }
+
+ VKDescriptor::SetBindInfoArray bindings (LAP_SHADER_BINDING_COUNT);
+ bindings[0].layout = binding_layout[0];
+ bindings[1].layout = binding_layout[1];
+ if (layer.gs_buf[idx].ptr ()) {
+ bindings[0].desc = VKBufDesc (layer.gs_buf[idx], NV12PlaneYIdx);
+ bindings[1].desc = VKBufDesc (layer.gs_buf[idx], NV12PlaneUVIdx);
+ }
+ bindings[2].layout = binding_layout[2];
+ bindings[2].desc = VKBufDesc (layer_next.gs_buf[idx], NV12PlaneYIdx);
+ bindings[3].layout = binding_layout[3];
+ bindings[3].desc = VKBufDesc (layer_next.gs_buf[idx], NV12PlaneUVIdx);
+ bindings[4].layout = binding_layout[4];
+ bindings[4].desc = VKBufDesc (layer.lap_buf[idx], NV12PlaneYIdx);
+ bindings[5].layout = binding_layout[5];
+ bindings[5].desc = VKBufDesc (layer.lap_buf[idx], NV12PlaneUVIdx);
+ layer.lap_bindings[idx] = bindings;
+
+ const VKBufInfo in_info = layer.gs_buf[idx]->get_buf_info ();
+ const VKBufInfo gs_info = layer_next.gs_buf[idx]->get_buf_info ();
+
+ size_t unit_bytes = sizeof (uint32_t) * 2;
+ LapPushConstsProp prop;
+ prop.in_img_width = XCAM_ALIGN_UP (in_info.width, unit_bytes) / unit_bytes;
+ prop.in_img_height = in_info.height;
+ prop.gaussscale_img_width = XCAM_ALIGN_UP (gs_info.width, sizeof (uint32_t)) / sizeof (uint32_t);
+ prop.gaussscale_img_height = gs_info.height;
+ if (level == 0) {
+ const Rect area = _blender->get_input_merge_area (idx);
+ prop.in_offset_x = XCAM_ALIGN_UP (area.pos_x, unit_bytes) / unit_bytes;
+ prop.merge_width = XCAM_ALIGN_UP (area.width, unit_bytes) / unit_bytes;
+ } else {
+ prop.in_offset_x = 0;
+ prop.merge_width = XCAM_ALIGN_UP (in_info.width, unit_bytes) / unit_bytes;
+ }
+ layer.lap_consts[idx] = new VKLapPushConst (prop);
+
+ layer.lap_global_size[idx] = WorkSize (
+ XCAM_ALIGN_UP (prop.merge_width, 8) / 8,
+ XCAM_ALIGN_UP (in_info.height, 32) / 32);
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+BlenderImpl::fix_blend_params ()
+{
+ PyrLayer &top_layer = pyr_layer[pyr_layers_num - 1];
+ XCAM_ASSERT (top_layer.gs_buf[VKBlender::BufIdx0].ptr () && top_layer.gs_buf[VKBlender::BufIdx1].ptr ());
+ XCAM_ASSERT (top_layer.mask.ptr ());
+ XCAM_ASSERT (top_layer.blend_buf.ptr ());
+
+ VKDescriptor::BindingArray binding_layout;
+ binding_layout.clear ();
+ for (int i = 0; i < BLEND_SHADER_BINDING_COUNT; ++i) {
+ SmartPtr<VKDescriptor::SetLayoutBinding> binding =
+ new VKDescriptor::ComputeLayoutBinding (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, i);
+ binding_layout.push_back (binding);
+ }
+
+ VKDescriptor::SetBindInfoArray bindings (BLEND_SHADER_BINDING_COUNT);
+ bindings[0].layout = binding_layout[0];
+ bindings[0].desc = VKBufDesc (top_layer.gs_buf[VKBlender::BufIdx0], NV12PlaneYIdx);
+ bindings[1].layout = binding_layout[1];
+ bindings[1].desc = VKBufDesc (top_layer.gs_buf[VKBlender::BufIdx0], NV12PlaneUVIdx);
+ bindings[2].layout = binding_layout[2];
+ bindings[2].desc = VKBufDesc (top_layer.gs_buf[VKBlender::BufIdx1], NV12PlaneYIdx);
+ bindings[3].layout = binding_layout[3];
+ bindings[3].desc = VKBufDesc (top_layer.gs_buf[VKBlender::BufIdx1], NV12PlaneUVIdx);
+ bindings[4].layout = binding_layout[4];
+ bindings[4].desc = VKBufDesc (top_layer.blend_buf, NV12PlaneYIdx);
+ bindings[5].layout = binding_layout[5];
+ bindings[5].desc = VKBufDesc (top_layer.blend_buf, NV12PlaneUVIdx);
+ bindings[6].layout = binding_layout[6];
+ bindings[6].desc = VKBufDesc (top_layer.mask);
+ top_layer.blend_bindings = bindings;
+
+ const VKBufInfo in0_info = top_layer.gs_buf[VKBlender::BufIdx0]->get_buf_info ();
+ size_t unit_bytes = sizeof (uint32_t) * 2;
+ BlendPushConstsProp prop;
+ prop.in_img_width = XCAM_ALIGN_UP (in0_info.width, unit_bytes) / unit_bytes;
+ top_layer.blend_consts = new VKBlendPushConst (prop);
+
+ top_layer.blend_global_size = WorkSize (
+ XCAM_ALIGN_UP (prop.in_img_width, 8) / 8,
+ XCAM_ALIGN_UP (in0_info.height, 16) / 16);
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+BlenderImpl::fix_reconstruct_params (uint32_t level)
+{
+ XCAM_ASSERT (level < pyr_layers_num - 1);
+
+ PyrLayer &layer = pyr_layer[level];
+ PyrLayer &prev_layer = pyr_layer[level + 1];
+
+ XCAM_ASSERT (layer.lap_buf[VKBlender::BufIdx0].ptr ());
+ XCAM_ASSERT (layer.lap_buf[VKBlender::BufIdx1].ptr ());
+ XCAM_ASSERT (prev_layer.reconstruct_buf.ptr () && (layer.reconstruct_buf.ptr () || level == 0));
+ XCAM_ASSERT (layer.mask.ptr ());
+
+ VKDescriptor::BindingArray binding_layout;
+ binding_layout.clear ();
+ for (int i = 0; i < RECONSTRUCT_SHADER_BINDING_COUNT; ++i) {
+ SmartPtr<VKDescriptor::SetLayoutBinding> binding =
+ new VKDescriptor::ComputeLayoutBinding (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, i);
+ binding_layout.push_back (binding);
+ }
+
+ VKDescriptor::SetBindInfoArray bindings (RECONSTRUCT_SHADER_BINDING_COUNT);
+ bindings[0].layout = binding_layout[0];
+ bindings[0].desc = VKBufDesc (layer.lap_buf[VKBlender::BufIdx0], NV12PlaneYIdx);
+ bindings[1].layout = binding_layout[1];
+ bindings[1].desc = VKBufDesc (layer.lap_buf[VKBlender::BufIdx0], NV12PlaneUVIdx);
+ bindings[2].layout = binding_layout[2];
+ bindings[2].desc = VKBufDesc (layer.lap_buf[VKBlender::BufIdx1], NV12PlaneYIdx);
+ bindings[3].layout = binding_layout[3];
+ bindings[3].desc = VKBufDesc (layer.lap_buf[VKBlender::BufIdx1], NV12PlaneUVIdx);
+ bindings[4].layout = binding_layout[4];
+ bindings[5].layout = binding_layout[5];
+ if (layer.reconstruct_buf.ptr ()) {
+ bindings[4].desc = VKBufDesc (layer.reconstruct_buf, NV12PlaneYIdx);
+ bindings[5].desc = VKBufDesc (layer.reconstruct_buf, NV12PlaneUVIdx);
+ }
+ bindings[6].layout = binding_layout[6];
+ bindings[6].desc = VKBufDesc (prev_layer.reconstruct_buf, NV12PlaneYIdx);
+ bindings[7].layout = binding_layout[7];
+ bindings[7].desc = VKBufDesc (prev_layer.reconstruct_buf, NV12PlaneUVIdx);
+ bindings[8].layout = binding_layout[8];
+ bindings[8].desc = VKBufDesc (layer.mask);
+ layer.reconstruct_bindings = bindings;
+
+ const VKBufInfo lap0_info = layer.lap_buf[VKBlender::BufIdx0]->get_buf_info ();
+ const VKBufInfo prev_recons_info = prev_layer.reconstruct_buf->get_buf_info ();
+
+ size_t unit_bytes = sizeof (uint32_t) * 2;
+ ReconstructPushConstsProp prop;
+ prop.lap_img_width = XCAM_ALIGN_UP (lap0_info.width, unit_bytes) / unit_bytes;
+ prop.lap_img_height = lap0_info.height;
+ prop.prev_blend_img_width = XCAM_ALIGN_UP (prev_recons_info.width, sizeof (uint32_t)) / sizeof (uint32_t);
+ prop.prev_blend_img_height = prev_recons_info.height;
+ if (level == 0) {
+ const VideoBufferInfo info = _blender->get_out_video_info ();
+ prop.out_img_width = XCAM_ALIGN_UP (info.width, unit_bytes) / unit_bytes;
+
+ const Rect area = _blender->get_merge_window ();
+ prop.out_offset_x = XCAM_ALIGN_UP (area.pos_x, unit_bytes) / unit_bytes;
+ } else {
+ const VKBufInfo info = layer.reconstruct_buf->get_buf_info ();
+ prop.out_img_width = XCAM_ALIGN_UP (info.width, unit_bytes) / unit_bytes;
+ prop.out_offset_x = 0;
+ }
+ layer.reconstruct_consts = new VKReconstructPushConst (prop);
+
+ layer.reconstruct_global_size = WorkSize (
+ XCAM_ALIGN_UP (prop.lap_img_width, 8) / 8,
+ XCAM_ALIGN_UP (lap0_info.height, 32) / 32);
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+BlenderImpl::start_gauss_scale (uint32_t level, VKBlender::BufIdx idx)
+{
+ XCAM_ASSERT (level >= 1 && level < pyr_layers_num);
+
+ PyrLayer &layer = pyr_layer[level];
+ layer.gauss_scale[idx]->set_global_size (layer.gs_global_size[idx]);
+
+ SmartPtr<BlendArgs> args = new BlendArgs (level, idx);
+ args->set_bindings (layer.gs_bindings[idx]);
+ args->add_push_const (layer.gs_consts[idx]);
+
+ return layer.gauss_scale[idx]->work (args);
+}
+
+XCamReturn
+BlenderImpl::start_lap_tran (uint32_t level, VKBlender::BufIdx idx)
+{
+ PyrLayer &layer = pyr_layer[level];
+
+ SmartPtr<VKBlender::Sync> &sync = layer.lap_sync[idx];
+ if (!sync->is_synced ())
+ return XCAM_RETURN_NO_ERROR;
+ sync->reset ();
+
+ layer.lap_trans[idx]->set_global_size (layer.lap_global_size[idx]);
+
+ SmartPtr<BlendArgs> args = new BlendArgs (level, idx);
+ args->set_bindings (layer.lap_bindings[idx]);
+ args->add_push_const (layer.lap_consts[idx]);
+
+ return layer.lap_trans[idx]->work (args);
+}
+
+XCamReturn
+BlenderImpl::start_lap_trans (uint32_t level, VKBlender::BufIdx idx)
+{
+ XCAM_ASSERT (level >= 1 && level < pyr_layers_num);
+
+ uint32_t pre_level = level - 1;
+ pyr_layer[pre_level].lap_sync[idx]->increment ();
+
+ XCamReturn ret = start_lap_tran (pre_level, idx);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "vk-blend start lap tran failed, level:%d idx:%d", pre_level, idx);
+
+ if (level == pyr_layers_num - 1)
+ return XCAM_RETURN_NO_ERROR;
+ pyr_layer[level].lap_sync[idx]->increment ();
+
+ ret = start_lap_tran (level, idx);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "vk-blend start lap tran failed, level:%d idx:%d", level, idx);
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+BlenderImpl::start_top_blend ()
+{
+ uint32_t level = pyr_layers_num - 1;
+ PyrLayer &layer = pyr_layer[level];
+
+ SmartPtr<VKBlender::Sync> &sync = layer.blend_sync;
+ if (!sync->is_synced ())
+ return XCAM_RETURN_NO_ERROR;
+ sync->reset ();
+
+ SmartPtr<VKWorker::VKArguments> args = new VKWorker::VKArguments;
+ args->set_bindings (layer.blend_bindings);
+ args->add_push_const (layer.blend_consts);
+
+ layer.blend->set_global_size (layer.blend_global_size);
+
+ return layer.blend->work (args);
+}
+
+XCamReturn
+BlenderImpl::start_reconstruct (uint32_t level)
+{
+ XCAM_ASSERT (level < pyr_layers_num - 1);
+ PyrLayer &layer = pyr_layer[level];
+
+ SmartPtr<VKBlender::Sync> &sync = layer.reconstruct_sync;
+ if (!sync->is_synced ())
+ return XCAM_RETURN_NO_ERROR;
+ sync->reset ();
+
+ SmartPtr<BlendArgs> args = new BlendArgs (level);
+ args->set_bindings (layer.reconstruct_bindings);
+ args->add_push_const (layer.reconstruct_consts);
+
+ layer.reconstruct->set_global_size (layer.reconstruct_global_size);
+
+ return layer.reconstruct->work (args);
+}
+
+XCamReturn
+BlenderImpl::stop ()
+{
+ for (uint32_t lv = 0; lv < pyr_layers_num; ++lv) {
+ pyr_layer[lv].gs_buf[VKBlender::BufIdx0].release ();
+ pyr_layer[lv].gs_buf[VKBlender::BufIdx1].release ();
+ pyr_layer[lv].lap_buf[VKBlender::BufIdx0].release ();
+ pyr_layer[lv].lap_buf[VKBlender::BufIdx1].release ();
+ pyr_layer[lv].reconstruct_buf.release ();
+ pyr_layer[lv].blend_buf.release ();
+
+ pyr_layer[lv].gs_consts[VKBlender::BufIdx0].release ();
+ pyr_layer[lv].gs_consts[VKBlender::BufIdx1].release ();
+ pyr_layer[lv].lap_consts[VKBlender::BufIdx0].release ();
+ pyr_layer[lv].lap_consts[VKBlender::BufIdx1].release ();
+ pyr_layer[lv].reconstruct_consts.release ();
+ pyr_layer[lv].blend_consts.release ();
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+}
+
+VKBlender::VKBlender (const SmartPtr<VKDevice> dev, const char *name)
+ : VKHandler (dev, name)
+ , Blender (VK_BLENDER_ALIGN_X, VK_BLENDER_ALIGN_Y)
+{
+ SmartPtr<VKBlenderPriv::BlenderImpl> impl =
+ new VKBlenderPriv::BlenderImpl (this, XCAM_VK_DEFAULT_LEVEL);
+ XCAM_ASSERT (impl.ptr ());
+
+ _impl = impl;
+}
+
+VKBlender::~VKBlender ()
+{
+}
+
+XCamReturn
+VKBlender::blend (
+ const SmartPtr<VideoBuffer> &in0, const SmartPtr<VideoBuffer> &in1, SmartPtr<VideoBuffer> &out_buf)
+{
+ XCAM_ASSERT (in0.ptr () && in1.ptr ());
+
+ SmartPtr<BlenderParam> param = new BlenderParam (in0, in1, out_buf);
+ XCAM_ASSERT (param.ptr ());
+
+ XCamReturn ret = execute_buffer (param, true);
+ XCAM_FAIL_RETURN (ERROR, xcam_ret_is_ok (ret), ret, "vk-blend execute buffer failed");
+
+ finish ();
+ if (!out_buf.ptr ()) {
+ out_buf = param->out_buf;
+ }
+
+ return ret;
+}
+
+static XCamReturn
+check_merge_area (const SmartPtr<VKBlender> &blender)
+{
+ Rect in0_area, in1_area, out_area;
+
+ in0_area = blender->get_input_merge_area (VKBlender::BufIdx0);
+ XCAM_FAIL_RETURN (
+ ERROR,
+ in0_area.pos_y == 0 && in0_area.width && in0_area.height &&
+ in0_area.pos_x % VK_BLENDER_ALIGN_X == 0 &&
+ in0_area.width % VK_BLENDER_ALIGN_X == 0 &&
+ in0_area.height % VK_BLENDER_ALIGN_Y == 0,
+ XCAM_RETURN_ERROR_PARAM,
+ "vk-blend invalid input0 merge area, pos_x:%d, pos_y:%d, width:%d, height:%d",
+ in0_area.pos_x, in0_area.pos_y, in0_area.width, in0_area.height);
+
+ in1_area = blender->get_input_merge_area (VKBlender::BufIdx1);
+ XCAM_FAIL_RETURN (
+ ERROR,
+ in1_area.pos_y == 0 && in1_area.width && in1_area.height &&
+ in1_area.pos_x % VK_BLENDER_ALIGN_X == 0 &&
+ in1_area.width % VK_BLENDER_ALIGN_X == 0 &&
+ in1_area.height % VK_BLENDER_ALIGN_Y == 0,
+ XCAM_RETURN_ERROR_PARAM,
+ "vk-blend invalid input1 merge area, pos_x:%d, pos_y:%d, width:%d, height:%d",
+ in1_area.pos_x, in1_area.pos_y, in1_area.width, in1_area.height);
+
+ out_area = blender->get_merge_window ();
+ XCAM_FAIL_RETURN (
+ ERROR,
+ out_area.pos_y == 0 && out_area.width && out_area.height &&
+ out_area.pos_x % VK_BLENDER_ALIGN_X == 0 &&
+ out_area.width % VK_BLENDER_ALIGN_X == 0 &&
+ out_area.height % VK_BLENDER_ALIGN_Y == 0,
+ XCAM_RETURN_ERROR_PARAM,
+ "vk-blend invalid output merge area, pos_x:%d, pos_y:%d, width:%d, height:%d",
+ out_area.pos_x, out_area.pos_y, out_area.width, out_area.height);
+
+ XCAM_FAIL_RETURN (
+ ERROR,
+ in0_area.width == in1_area.width && in0_area.height == in1_area.height &&
+ in0_area.width == out_area.width && in0_area.height == out_area.height,
+ XCAM_RETURN_ERROR_PARAM,
+ "vk-blend invalid input or output overlap area, input0:%dx%d, input1:%dx%d, output:%dx%d",
+ in0_area.width, in0_area.height, in1_area.width, in1_area.height, out_area.width, out_area.height);
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+VKBlender::set_output_info (const SmartPtr<ImageHandler::Parameters> &param)
+{
+ const VideoBufferInfo &in0_info = param->in_buf->get_video_info ();
+ XCAM_FAIL_RETURN (
+ ERROR, in0_info.format == V4L2_PIX_FMT_NV12, XCAM_RETURN_ERROR_PARAM,
+ "vk-blend only support NV12 format, but input format is %s",
+ xcam_fourcc_to_string (in0_info.format));
+
+ uint32_t out_width, out_height;
+ get_output_size (out_width, out_height);
+ XCAM_FAIL_RETURN (
+ ERROR, out_width && out_height, XCAM_RETURN_ERROR_PARAM,
+ "vk-blend invalid output size:%dx%d", out_width, out_height);
+
+ VideoBufferInfo out_info;
+ out_info.init (
+ in0_info.format, out_width, out_height,
+ XCAM_ALIGN_UP (out_width, VK_BLENDER_ALIGN_X),
+ XCAM_ALIGN_UP (out_height, VK_BLENDER_ALIGN_Y));
+ set_out_video_info (out_info);
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+VKBlender::configure_resource (const SmartPtr<Parameters> &param)
+{
+ XCAM_ASSERT (param.ptr ());
+ XCAM_ASSERT (_impl->pyr_layers_num <= XCAM_VK_MAX_LEVEL);
+
+ SmartPtr<BlenderParam> blend_param = param.dynamic_cast_ptr<BlenderParam> ();
+ XCAM_ASSERT (blend_param.ptr () && blend_param->in_buf.ptr () && blend_param->in1_buf.ptr ());
+
+ XCamReturn ret = set_output_info (param);
+ XCAM_FAIL_RETURN (ERROR, xcam_ret_is_ok (ret), ret, "vk-blend set output video info failed");
+
+ ret = check_merge_area (this);
+ XCAM_FAIL_RETURN (ERROR, xcam_ret_is_ok (ret), ret, "vk-blend check merge area failed");
+
+ _impl->init_syncs ();
+
+ ret = _impl->init_layers_bufs (param);
+ XCAM_FAIL_RETURN (ERROR, xcam_ret_is_ok (ret), ret, "vk-blend init buffers failed");
+
+ ret = _impl->fix_parameters ();
+ XCAM_FAIL_RETURN (ERROR, xcam_ret_is_ok (ret), ret, "vk-blend fix parameters failed");
+
+ ret = _impl->create_workers (this);
+ XCAM_FAIL_RETURN (ERROR, xcam_ret_is_ok (ret), ret, "vk-blend create workers failed");
+
+ ret = _impl->redirect_workers ();
+ XCAM_FAIL_RETURN (ERROR, xcam_ret_is_ok (ret), ret, "vk-blend redirect workers failed");
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+VKBlender::start_work (const SmartPtr<ImageHandler::Parameters> &param)
+{
+ SmartPtr<VKBlender::BlenderParam> blend_param = param.dynamic_cast_ptr<BlenderParam> ();
+ XCAM_ASSERT (blend_param.ptr ());
+ XCAM_ASSERT (blend_param->in_buf.ptr () && blend_param->in1_buf.ptr () && blend_param->out_buf.ptr ());
+
+#if DUMP_BUFFER
+ SmartPtr<VKVideoBuffer> in0_vk = blend_param->in_buf.dynamic_cast_ptr<VKVideoBuffer> ();
+ SmartPtr<VKVideoBuffer> in1_vk = blend_param->in1_buf.dynamic_cast_ptr<VKVideoBuffer> ();
+ XCAM_ASSERT (in0_vk.ptr () && in1_vk.ptr ());
+ dump_level_vkbuf (in0_vk->get_vk_buf (), "blend-in", 0, VKBlender::BufIdx0);
+ dump_level_vkbuf (in1_vk->get_vk_buf (), "blend-in", 0, VKBlender::BufIdx1);
+#endif
+
+ _impl->bind_io_bufs_to_layer0 (blend_param->in_buf, blend_param->in1_buf, blend_param->out_buf);
+ _impl->bind_io_vkbufs_to_desc ();
+
+ _impl->pyr_layer[0].lap_sync[BufIdx0]->increment ();
+ _impl->pyr_layer[0].lap_sync[BufIdx1]->increment ();
+
+ XCamReturn ret = XCAM_RETURN_NO_ERROR;
+ ret = _impl->start_gauss_scale (1, BufIdx0);
+ CHECK_RET (ret, "vk-blend start gauss scale failed, level:1 index:0\n");
+
+ ret = _impl->start_gauss_scale (1, BufIdx1);
+ CHECK_RET (ret, "vk-blend start gauss scale failed, level:1 index:1\n");
+
+ execute_done (param, ret);
+
+ return ret;
+}
+
+void
+VKBlender::gauss_scale_done (
+ const SmartPtr<Worker> &worker, const SmartPtr<Worker::Arguments> &base, const XCamReturn error)
+{
+ if (!xcam_ret_is_ok (error)) {
+ XCAM_LOG_ERROR ("vk-blend gauss scale failed");
+ return ;
+ }
+
+ SmartPtr<VKBlenderPriv::BlendArgs> args = base.dynamic_cast_ptr<VKBlenderPriv::BlendArgs> ();
+ XCAM_ASSERT (args.ptr ());
+ uint32_t level = args->get_level ();
+ uint32_t next_level = level + 1;
+ BufIdx idx = args->get_idx ();
+
+ SmartPtr<VKWorker> gs_worker = worker.dynamic_cast_ptr<VKWorker> ();
+ XCAM_ASSERT (gs_worker.ptr ());
+ gs_worker->wait_fence ();
+
+#if DUMP_BUFFER
+ dump_level_vkbuf (_impl->pyr_layer[level].gs_buf[idx], "gauss-scale", level, idx);
+#endif
+
+ XCamReturn ret = _impl->start_lap_trans (level, idx);
+ CHECK_RET (ret, "vk-blend execute laplace transformation failed, level:%d idx:%d", level, idx);
+
+ if (next_level == _impl->pyr_layers_num) {
+ _impl->pyr_layer[level].blend_sync->increment ();
+
+ ret = _impl->start_top_blend ();
+ CHECK_RET (ret, "vk-blend execute top blend failed, level:%d idx:%d", level, idx);
+ } else {
+ ret = _impl->start_gauss_scale (next_level, idx);
+ CHECK_RET (ret, "vk-blend execute gauss scale failed, level:%d idx:%d", next_level, idx);
+ }
+}
+
+void
+VKBlender::lap_trans_done (
+ const SmartPtr<Worker> &worker, const SmartPtr<Worker::Arguments> &base, const XCamReturn error)
+{
+ XCAM_UNUSED (base);
+ if (!xcam_ret_is_ok (error)) {
+ XCAM_LOG_ERROR ("vk-blend laplace transformation failed");
+ return ;
+ }
+
+ SmartPtr<VKBlenderPriv::BlendArgs> args = base.dynamic_cast_ptr<VKBlenderPriv::BlendArgs> ();
+ XCAM_ASSERT (args.ptr ());
+ uint32_t level = args->get_level ();
+
+ SmartPtr<VKWorker> laptrans_worker = worker.dynamic_cast_ptr<VKWorker> ();
+ XCAM_ASSERT (laptrans_worker.ptr ());
+ laptrans_worker->wait_fence ();
+
+#if DUMP_BUFFER
+ BufIdx idx = args->get_idx ();
+ dump_level_vkbuf (_impl->pyr_layer[level].lap_buf[idx], "lap", level, idx);
+#endif
+
+ _impl->pyr_layer[level].reconstruct_sync->increment ();
+
+ XCamReturn ret = _impl->start_reconstruct (level);
+ CHECK_RET (ret, "vk-blend execute reconstruct failed, level:%d", level);
+}
+
+void
+VKBlender::blend_done (
+ const SmartPtr<Worker> &worker, const SmartPtr<Worker::Arguments> &base, const XCamReturn error)
+{
+ XCAM_UNUSED (base);
+ if (!xcam_ret_is_ok (error)) {
+ XCAM_LOG_ERROR ("vk-blend blend failed");
+ return ;
+ }
+
+ SmartPtr<VKWorker> blend_worker = worker.dynamic_cast_ptr<VKWorker> ();
+ XCAM_ASSERT (blend_worker.ptr ());
+ blend_worker->wait_fence ();
+
+#if DUMP_BUFFER
+ dump_vkbuf (_impl->pyr_layer[_impl->pyr_layers_num - 1].blend_buf, "blend-top");
+#endif
+
+ uint32_t pre_level = _impl->pyr_layers_num - 2;
+ _impl->pyr_layer[pre_level].reconstruct_sync->increment ();
+
+ XCamReturn ret = _impl->start_reconstruct (pre_level);
+ CHECK_RET (ret, "vk-blend execute reconstruct failed, level:%d", pre_level);
+}
+
+void
+VKBlender::reconstruct_done (
+ const SmartPtr<Worker> &worker, const SmartPtr<Worker::Arguments> &base, const XCamReturn error)
+{
+ XCAM_UNUSED (base);
+ if (!xcam_ret_is_ok (error)) {
+ XCAM_LOG_ERROR ("vk-blend reconstruct failed");
+ return ;
+ }
+
+ SmartPtr<VKBlenderPriv::BlendArgs> args = base.dynamic_cast_ptr<VKBlenderPriv::BlendArgs> ();
+ XCAM_ASSERT (args.ptr ());
+ uint32_t level = args->get_level ();
+
+ SmartPtr<VKWorker> reconstruct_worker = worker.dynamic_cast_ptr<VKWorker> ();
+ XCAM_ASSERT (reconstruct_worker.ptr ());
+ reconstruct_worker->wait_fence ();
+
+#if DUMP_BUFFER
+ BufIdx idx = args->get_idx ();
+ dump_level_vkbuf (_impl->pyr_layer[level].reconstruct_buf, "reconstruct", level, idx);
+#endif
+
+ if (level == 0) {
+ return;
+ }
+
+ uint32_t pre_level = level - 1;
+ _impl->pyr_layer[pre_level].reconstruct_sync->increment ();
+
+ XCamReturn ret = _impl->start_reconstruct (pre_level);
+ CHECK_RET (ret, "vk-blend execute reconstruct failed, level:%d", pre_level);
+}
+
+SmartPtr<VKHandler>
+create_vk_blender (const SmartPtr<VKDevice> &dev)
+{
+ SmartPtr<VKBlender> blender = new VKBlender (dev);
+ XCAM_ASSERT (blender.ptr ());
+
+ return blender;
+}
+
+SmartPtr<Blender>
+Blender::create_vk_blender (const SmartPtr<VKDevice> &dev)
+{
+ SmartPtr<VKHandler> handler = XCam::create_vk_blender (dev);
+ return handler.dynamic_cast_ptr<Blender> ();
+}
+
+}
diff --git a/modules/vulkan/vk_blender.h b/modules/vulkan/vk_blender.h
new file mode 100644
index 0000000..223b48f
--- /dev/null
+++ b/modules/vulkan/vk_blender.h
@@ -0,0 +1,120 @@
+/*
+ * vk_blender.h - vulkan blender class
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#ifndef XCAM_VK_BLENDER_H
+#define XCAM_VK_BLENDER_H
+
+#include <vulkan/vulkan_std.h>
+#include <vulkan/vk_handler.h>
+#include <interface/blender.h>
+
+#define VK_BLENDER_ALIGN_X 8
+#define VK_BLENDER_ALIGN_Y 4
+
+#define XCAM_VK_MAX_LEVEL 4
+#define XCAM_VK_DEFAULT_LEVEL 2
+
+namespace XCam {
+
+namespace VKBlenderPriv {
+class BlenderImpl;
+}
+
+class VKBlender
+ : public VKHandler, public Blender
+{
+ friend class VKBlenderPriv::BlenderImpl;
+ friend SmartPtr<VKHandler> create_vk_blender (const SmartPtr<VKDevice> &dev);
+
+public:
+ struct BlenderParam : ImageHandler::Parameters {
+ SmartPtr<VideoBuffer> in1_buf;
+
+ BlenderParam (
+ const SmartPtr<VideoBuffer> &in0,
+ const SmartPtr<VideoBuffer> &in1,
+ const SmartPtr<VideoBuffer> &out)
+ : Parameters (in0, out)
+ , in1_buf (in1)
+ {}
+ };
+
+ class Sync
+ {
+ public:
+ Sync (uint32_t threshold)
+ : _count (0), _threshold (threshold)
+ {}
+
+ void increment () {
+ ++_count;
+ }
+ void reset () {
+ _count = 0;
+ }
+ bool is_synced () {
+ return (_threshold == _count);
+ }
+
+ private:
+ uint32_t _count;
+ const uint32_t _threshold;
+ };
+
+ enum BufIdx {
+ BufIdx0 = 0,
+ BufIdx1,
+ BufIdxMax
+ };
+
+public:
+ ~VKBlender ();
+
+ void gauss_scale_done (
+ const SmartPtr<Worker> &worker, const SmartPtr<Worker::Arguments> &base, const XCamReturn error);
+ void lap_trans_done (
+ const SmartPtr<Worker> &worker, const SmartPtr<Worker::Arguments> &base, const XCamReturn error);
+ void blend_done (
+ const SmartPtr<Worker> &worker, const SmartPtr<Worker::Arguments> &base, const XCamReturn error);
+ void reconstruct_done (
+ const SmartPtr<Worker> &worker, const SmartPtr<Worker::Arguments> &base, const XCamReturn error);
+
+protected:
+ explicit VKBlender (const SmartPtr<VKDevice> dev, const char *name = "VKBlender");
+
+ // derived from Blender interface
+ XCamReturn blend (
+ const SmartPtr<VideoBuffer> &in0, const SmartPtr<VideoBuffer> &in1, SmartPtr<VideoBuffer> &out);
+
+ // derived from VKHandler
+ XCamReturn configure_resource (const SmartPtr<Parameters> &param);
+ XCamReturn start_work (const SmartPtr<Parameters> &param);
+
+ XCamReturn set_output_info (const SmartPtr<ImageHandler::Parameters> &param);
+
+private:
+ SmartPtr<VKBlenderPriv::BlenderImpl> _impl;
+};
+
+extern SmartPtr<VKHandler> create_vk_blender (const SmartPtr<VKDevice> &dev);
+
+}
+
+#endif // XCAM_VK_BLENDER_H
diff --git a/modules/vulkan/vk_cmdbuf.cpp b/modules/vulkan/vk_cmdbuf.cpp
new file mode 100644
index 0000000..1bc33be
--- /dev/null
+++ b/modules/vulkan/vk_cmdbuf.cpp
@@ -0,0 +1,172 @@
+/*
+ * vk_cmdbuf.cpp - Vulkan command buffer
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "vk_cmdbuf.h"
+#include "vulkan_common.h"
+#include "vk_pipeline.h"
+
+namespace XCam {
+
+VKCmdBuf::Pool::Pool (const SmartPtr<VKDevice> dev, VkCommandPool id)
+ : _pool_id (id)
+ , _dev (dev)
+{
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (id));
+}
+
+VKCmdBuf::Pool::~Pool ()
+{
+ if (XCAM_IS_VALID_VK_ID (_pool_id))
+ _dev->destroy_cmd_pool (_pool_id);
+}
+
+SmartPtr<VKCmdBuf>
+VKCmdBuf::Pool::allocate_buffer ()
+{
+ //VkCommandBufferAllocateInfo info {};
+ VkCommandBuffer cmd_buf_id = _dev->allocate_cmd_buffer (_pool_id);
+ XCAM_FAIL_RETURN (
+ ERROR, XCAM_IS_VALID_VK_ID (cmd_buf_id), NULL,
+ "VKCmdBuf allocate cmd buffer failed");
+ return new VKCmdBuf (this, cmd_buf_id);
+}
+
+void
+VKCmdBuf::Pool::free_buffer (VkCommandBuffer buf_id)
+{
+ XCAM_ASSERT (_dev.ptr ());
+ _dev->free_cmd_buffer (_pool_id, buf_id);
+}
+
+SmartPtr<VKCmdBuf::Pool>
+VKCmdBuf::create_pool (const SmartPtr<VKDevice> dev, VkFlags queue_flag)
+{
+ VkCommandPool pool_id = dev->create_cmd_pool (queue_flag);
+ XCAM_FAIL_RETURN (
+ ERROR, XCAM_IS_VALID_VK_ID (pool_id), NULL,
+ "VKCmdBuf create_pool failed");
+ SmartPtr<VKCmdBuf::Pool> pool = new VKCmdBuf::Pool (dev, pool_id);
+ return pool;
+}
+
+SmartPtr<VKCmdBuf>
+VKCmdBuf::create_command_buffer (
+ const SmartPtr<VKDevice> dev,
+ const SmartPtr<VKCmdBuf::Pool> pool)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, dev.ptr (), NULL,
+ "VKCmdBuf create command buffer failed");
+
+ SmartPtr<VKCmdBuf::Pool> cmdbuf_pool = pool;
+ if (!pool.ptr()) {
+ cmdbuf_pool = create_pool (dev, VK_QUEUE_COMPUTE_BIT);
+ }
+
+ XCAM_FAIL_RETURN (
+ ERROR, cmdbuf_pool.ptr (), NULL,
+ "VKCmdBuf create command pool failed");
+
+ return cmdbuf_pool->allocate_buffer ();
+}
+
+VKCmdBuf::VKCmdBuf (const SmartPtr<VKCmdBuf::Pool> pool, VkCommandBuffer buf_id)
+ : _cmd_buf_id (buf_id)
+ , _pool (pool)
+{
+}
+
+VKCmdBuf::~VKCmdBuf ()
+{
+ if (_pool.ptr () && XCAM_IS_VALID_VK_ID (_cmd_buf_id))
+ _pool->free_buffer (_cmd_buf_id);
+}
+
+VKCmdBuf::DispatchParam::DispatchParam (const SmartPtr<VKPipeline> &p, uint32_t x, uint32_t y, uint32_t z)
+ : _group_size (x, y, z)
+ , _pipeline (p)
+{
+}
+
+VKCmdBuf::DispatchParam::~DispatchParam ()
+{
+}
+
+bool
+VKCmdBuf::DispatchParam::update_push_consts (VKConstRange::VKPushConstArgs & push_consts)
+{
+ _push_consts = push_consts;
+ return true;
+}
+
+XCamReturn
+VKCmdBuf::DispatchParam::fill_cmd_buf (VKCmdBuf &buf)
+{
+ XCamReturn ret = _pipeline->bind_by (buf);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret),
+ ret, "VKCmdBuf DispatchParam fill command buffer failed when binding pipeline");
+
+ for (size_t i = 0; i < _push_consts.size (); ++i) {
+ XCAM_RETURN_CHECK (
+ ERROR, _pipeline->push_consts_by (buf, _push_consts[i]),
+ "VKCmdBuf DispatchParam fill command buffer failed when push consts (:%d)", i);
+ }
+ return buf.dispatch (_group_size);
+}
+
+XCamReturn
+VKCmdBuf::record (const SmartPtr<DispatchParam> param)
+{
+ VkCommandBufferBeginInfo buf_begin_info = {};
+ buf_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+ buf_begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
+ buf_begin_info.pInheritanceInfo = NULL;
+
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (_cmd_buf_id));
+ XCAM_VK_CHECK_RETURN (
+ ERROR, vkBeginCommandBuffer (_cmd_buf_id, &buf_begin_info),
+ XCAM_RETURN_ERROR_VULKAN, "VKCmdBuf begin command buffer failed");
+
+ XCamReturn ret = param->fill_cmd_buf (*this);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret),
+ ret, "VKCmdBuf dispatch params failed");
+
+ XCAM_VK_CHECK_RETURN (
+ ERROR, vkEndCommandBuffer (_cmd_buf_id),
+ XCAM_RETURN_ERROR_VULKAN, "VKCmdBuf begin command buffer failed");
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+VKCmdBuf::dispatch (const GroupSize &group)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, group.x * group.y * group.z > 0,
+ XCAM_RETURN_ERROR_VULKAN, "VKCmdBuf dispatch params failed");
+
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (_cmd_buf_id));
+ vkCmdDispatch (_cmd_buf_id, group.x, group.y, group.z);
+ return XCAM_RETURN_NO_ERROR;
+}
+
+}
diff --git a/modules/vulkan/vk_cmdbuf.h b/modules/vulkan/vk_cmdbuf.h
new file mode 100644
index 0000000..458bea3
--- /dev/null
+++ b/modules/vulkan/vk_cmdbuf.h
@@ -0,0 +1,106 @@
+/*
+ * vk_cmdbuf.h - Vulkan command buffer
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_VK_CMD_BUF_H
+#define XCAM_VK_CMD_BUF_H
+
+#include <vulkan/vulkan_std.h>
+#include <vulkan/vk_descriptor.h>
+#include <vulkan/vk_device.h>
+
+namespace XCam {
+
+class VKCmdBuf
+{
+public:
+ struct GroupSize {
+ uint32_t x;
+ uint32_t y;
+ uint32_t z;
+ GroupSize (uint32_t x_, uint32_t y_, uint32_t z_)
+ : x (x_)
+ , y (y_)
+ , z (z_)
+ {}
+ };
+
+ class DispatchParam {
+ friend class VKCmdBuf;
+ public:
+ DispatchParam (const SmartPtr<VKPipeline> &p, uint32_t x, uint32_t y = 1, uint32_t z = 1);
+ virtual ~DispatchParam ();
+ bool update_push_consts (VKConstRange::VKPushConstArgs & push_consts);
+ protected:
+ virtual XCamReturn fill_cmd_buf (VKCmdBuf &buf);
+ XCAM_DEAD_COPY (DispatchParam);
+
+ protected:
+ GroupSize _group_size;
+ const SmartPtr<VKPipeline> _pipeline;
+ VKConstRange::VKPushConstArgs _push_consts;
+ };
+
+ class Pool
+ : public RefObj
+ {
+ friend class VKCmdBuf;
+ public:
+ ~Pool ();
+ SmartPtr<VKCmdBuf> allocate_buffer ();
+ void free_buffer (VkCommandBuffer buf_id);
+
+ private:
+ explicit Pool (const SmartPtr<VKDevice> dev, VkCommandPool id);
+ XCAM_DEAD_COPY (Pool);
+ private:
+ VkCommandPool _pool_id;
+ SmartPtr<VKDevice> _dev;
+ };
+
+public:
+ static SmartPtr<VKCmdBuf>
+ create_command_buffer (const SmartPtr<VKDevice> dev, const SmartPtr<Pool> pool = NULL);
+ static SmartPtr<Pool> create_pool (const SmartPtr<VKDevice> dev, VkFlags queue_flag);
+ virtual ~VKCmdBuf ();
+
+ VkCommandBuffer get_cmd_buf_id () const {
+ return _cmd_buf_id;
+ }
+
+ XCamReturn record (const SmartPtr<DispatchParam> param);
+
+ // for fill_cmd_buf
+ XCamReturn dispatch (const GroupSize &group);
+
+protected:
+ explicit VKCmdBuf (const SmartPtr<Pool> pool, VkCommandBuffer buf_id);
+
+private:
+ XCAM_DEAD_COPY (VKCmdBuf);
+
+protected:
+ VkCommandBuffer _cmd_buf_id;
+
+ SmartPtr<Pool> _pool;
+};
+
+}
+
+#endif //XCAM_VK_CMD_BUF_H
diff --git a/modules/vulkan/vk_copy_handler.cpp b/modules/vulkan/vk_copy_handler.cpp
new file mode 100644
index 0000000..4a89446
--- /dev/null
+++ b/modules/vulkan/vk_copy_handler.cpp
@@ -0,0 +1,270 @@
+/*
+ * vk_copy_handler.cpp - vulkan copy handler
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include <vulkan/vulkan_std.h>
+#include "vk_copy_handler.h"
+#include "vk_video_buf_allocator.h"
+#include "vk_shader.h"
+#include "vk_memory.h"
+#include "vk_worker.h"
+#include "vk_device.h"
+
+#define COPY_SHADER_BINDING_COUNT 2
+#define INVALID_INDEX (uint32_t)(-1)
+
+namespace XCam {
+
+namespace {
+
+DECLARE_WORK_CALLBACK (CbCopyShader, VKCopyHandler, copy_done);
+
+class CopyArgs
+ : public VKWorker::VKArguments
+{
+public:
+ explicit CopyArgs (const SmartPtr<ImageHandler::Parameters> &param)
+ : _param (param)
+ {
+ XCAM_ASSERT (param.ptr ());
+ }
+ const SmartPtr<ImageHandler::Parameters> &get_param () const {
+ return _param;
+ }
+
+private:
+ SmartPtr<ImageHandler::Parameters> _param;
+};
+
+class VKCopyPushConst
+ : public VKConstRange::VKPushConstArg
+{
+public:
+ VKCopyPushConst (const VKCopyHandler::PushConstsProp &prop)
+ : _prop (prop)
+ {}
+
+ bool get_const_data (VkPushConstantRange &range, void *& ptr) {
+ range.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
+ range.offset = 0;
+ range.size = sizeof (_prop);
+ ptr = &_prop;
+ return true;
+ }
+
+private:
+ VKCopyHandler::PushConstsProp _prop;
+};
+
+};
+
+static const VKShaderInfo copy_shader_info (
+ "main",
+std::vector<uint32_t> {
+#include "shader_copy.comp.spv"
+});
+
+#if 0
+VKCopyArguments::VKCopyArguments (const SmartPtr<VKBuffer> in, SmartPtr<VKBuffer> out)
+ : _in_buf (in)
+ , _out_buf (out)
+{
+ XCAM_ASSERT (in.ptr());
+ XCAM_ASSERT (out.ptr());
+}
+
+XCamReturn
+VKCopyArguments::prepare_bindings (VKDescriptor::SetBindInfoArray &binding_array)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, _in_buf.ptr () && _out_buf.ptr (), XCAM_RETURN_ERROR_PARAM,
+ "VKCopyArguments input or output buffer is empty.");
+
+ binding_array.resize (2);
+ binding_array[0].layout = new VKDescriptor::ComputeLayoutBinding (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0);
+ binding_array[0].desc = VKBufDesc (_in_buf);
+
+ binding_array[0].layout = new VKDescriptor::ComputeLayoutBinding (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1);
+ binding_array[0].desc = VKBufDesc (_out_buf);
+ return XCAM_RETURN_NO_ERROR;
+}
+#endif
+
+VKCopyHandler::PushConstsProp::PushConstsProp ()
+ : in_img_width (0)
+ , in_x_offset (0)
+ , out_img_width (0)
+ , out_x_offset (0)
+ , copy_width (0)
+{
+}
+
+VKCopyHandler::VKCopyHandler (const SmartPtr<VKDevice> &dev, const char* name)
+ : VKHandler (dev, name)
+ , _index (INVALID_INDEX)
+{
+}
+
+bool
+VKCopyHandler::set_copy_area (uint32_t idx, const Rect &in_area, const Rect &out_area)
+{
+ XCAM_FAIL_RETURN (
+ ERROR,
+ idx != INVALID_INDEX &&
+ in_area.width && in_area.height &&
+ in_area.width == out_area.width && in_area.height == out_area.height,
+ false,
+ "VKCopyHandler(%s): set copy area(idx:%d) failed, input size:%dx%d output size:%dx%d",
+ XCAM_STR (get_name ()), idx, in_area.width, in_area.height, out_area.width, out_area.height);
+
+ _index = idx;
+ _in_area = in_area;
+ _out_area = out_area;
+
+ XCAM_LOG_DEBUG ("VKCopyHandler: copy area(idx:%d) input area(%d, %d, %d, %d) output area(%d, %d, %d, %d)",
+ idx,
+ in_area.pos_x, in_area.pos_y, in_area.width, in_area.height,
+ out_area.pos_x, out_area.pos_y, out_area.width, out_area.height);
+
+ return true;
+}
+
+#define UNIT_BYTES (4*sizeof(uint32_t))
+
+XCamReturn
+VKCopyHandler::configure_resource (const SmartPtr<ImageHandler::Parameters> &param)
+{
+ XCamReturn ret = XCAM_RETURN_NO_ERROR;
+ XCAM_ASSERT (param.ptr ());
+ XCAM_ASSERT (!_worker.ptr ());
+
+ XCAM_FAIL_RETURN (
+ ERROR, param->in_buf.ptr (), XCAM_RETURN_ERROR_VULKAN,
+ "VKCopyHandler(%s) param.in_buf is empty.", XCAM_STR (get_name ()));
+ XCAM_FAIL_RETURN (
+ ERROR, _index != INVALID_INDEX, XCAM_RETURN_ERROR_PARAM,
+ "VKCopyHandler(%s) invalid copy area, need set copy area first", XCAM_STR (get_name ()));
+
+ VideoBufferInfo in_info = param->in_buf->get_video_info ();
+ VideoBufferInfo out_info;
+ if (param->out_buf.ptr ())
+ out_info = param->out_buf->get_video_info ();
+ else
+ out_info = get_out_video_info ();
+ XCAM_FAIL_RETURN (
+ ERROR, out_info.is_valid (), XCAM_RETURN_ERROR_PARAM,
+ "VKCopyHandler(%s) invalid out info.", XCAM_STR (get_name ()));
+
+ _image_prop.in_img_width = in_info.aligned_width / UNIT_BYTES;
+ _image_prop.in_x_offset = _in_area.pos_x / UNIT_BYTES;
+ _image_prop.out_img_width = out_info.aligned_width / UNIT_BYTES;
+ _image_prop.out_x_offset = _out_area.pos_x / UNIT_BYTES;
+ _image_prop.copy_width = _in_area.width / UNIT_BYTES;
+ WorkSize global_size (
+ XCAM_ALIGN_UP (_image_prop.copy_width, 8 ) / 8,
+ XCAM_ALIGN_UP (_in_area.height * 3 / 2, 8 ) / 8);
+
+ _binding_layout.clear ();
+ for (int i = 0; i < COPY_SHADER_BINDING_COUNT; ++i) {
+ SmartPtr<VKDescriptor::SetLayoutBinding> binding =
+ new VKDescriptor::ComputeLayoutBinding (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, i);
+ _binding_layout.push_back (binding);
+ }
+
+ if (!_worker.ptr ()) {
+ _worker = new VKWorker(get_vk_device(), "CbCopyShader", new CbCopyShader (this));
+ XCAM_ASSERT (_worker.ptr());
+
+ _worker->set_global_size (global_size);
+
+ VKConstRange::VKPushConstArgs push_consts;
+ push_consts.push_back (new VKCopyPushConst (_image_prop));
+ ret = _worker->build (copy_shader_info, _binding_layout, push_consts);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), XCAM_RETURN_ERROR_VULKAN,
+ "VKCopyHandler(%s) build copy shader failed.", XCAM_STR (get_name ()));
+ }
+
+ return ret;
+}
+
+XCamReturn
+VKCopyHandler::start_work (const SmartPtr<ImageHandler::Parameters> &param)
+{
+ XCAM_ASSERT (_binding_layout.size () == COPY_SHADER_BINDING_COUNT);
+ SmartPtr<VKVideoBuffer> in_vk = param->in_buf.dynamic_cast_ptr<VKVideoBuffer> ();
+ SmartPtr<VKVideoBuffer> out_vk = param->out_buf.dynamic_cast_ptr<VKVideoBuffer> ();
+
+ XCAM_FAIL_RETURN (
+ ERROR, in_vk.ptr () && out_vk.ptr(), XCAM_RETURN_ERROR_VULKAN,
+ "VKCopyHandler(%s) param.in_buf or param.out_buf is not vk buf.", XCAM_STR (get_name ()));
+
+ VKDescriptor::SetBindInfoArray bindings (_binding_layout.size ());
+ bindings[0].layout = _binding_layout[0];
+ bindings[0].desc = VKBufDesc (in_vk->get_vk_buf ());
+ bindings[1].layout = _binding_layout[1];
+ bindings[1].desc = VKBufDesc (out_vk->get_vk_buf ());
+
+ SmartPtr<CopyArgs> args = new CopyArgs (param);
+ args->set_bindings (bindings);
+ args->add_push_const (new VKCopyPushConst (_image_prop));
+ return _worker->work (args);
+}
+
+void
+VKCopyHandler::copy_done (
+ const SmartPtr<Worker> &worker,
+ const SmartPtr<Worker::Arguments> &base,
+ const XCamReturn error)
+{
+ if (!xcam_ret_is_ok (error)) {
+ XCAM_LOG_ERROR ("VKCopyHandler(%s) copy failed.", XCAM_STR (get_name ()));
+ }
+
+ SmartPtr<VKWorker> vk_worker = worker.dynamic_cast_ptr<VKWorker> ();
+ XCAM_ASSERT (vk_worker.ptr ());
+ vk_worker->wait_fence ();
+
+ SmartPtr<CopyArgs> args = base.dynamic_cast_ptr<CopyArgs> ();
+ XCAM_ASSERT (args.ptr ());
+ const SmartPtr<ImageHandler::Parameters> param = args->get_param ();
+ XCAM_ASSERT (param.ptr ());
+
+ execute_done (param, error);
+}
+
+XCamReturn
+VKCopyHandler::copy (const SmartPtr<VideoBuffer> &in_buf, SmartPtr<VideoBuffer> &out_buf)
+{
+ SmartPtr<ImageHandler::Parameters> param = new ImageHandler::Parameters (in_buf, out_buf);
+ XCAM_ASSERT (param.ptr ());
+
+ XCamReturn ret = execute_buffer (param, false);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "VKCopyHandler(%s) copy failed", XCAM_STR (get_name ()));
+
+ if (!out_buf.ptr ()) {
+ out_buf = param->out_buf;
+ }
+
+ return ret;
+}
+
+};
diff --git a/modules/vulkan/vk_copy_handler.h b/modules/vulkan/vk_copy_handler.h
new file mode 100644
index 0000000..8c71bae
--- /dev/null
+++ b/modules/vulkan/vk_copy_handler.h
@@ -0,0 +1,90 @@
+/*
+ * vk_copy_handler.h - vulkan copy handler
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_VK_COPY_HANDLER_H
+#define XCAM_VK_COPY_HANDLER_H
+
+#include <xcam_utils.h>
+#include <vulkan/vulkan_std.h>
+#include <vulkan/vk_worker.h>
+#include <vulkan/vk_handler.h>
+#include <vulkan/vk_descriptor.h>
+
+namespace XCam {
+
+#if 0
+class VKCopyArguments
+ : public VKWorker::VKArguments
+{
+public:
+ explicit VKCopyArguments (const SmartPtr<VKBuffer> in, SmartPtr<VKBuffer> out);
+
+private:
+ virtual XCamReturn prepare_bindings (VKDescriptor::SetBindInfoArray &binding_array);
+private:
+ SmartPtr<VKBuffer> _in_buf;
+ SmartPtr<VKBuffer> _out_buf;
+};
+#endif
+
+class VKCopyHandler
+ : public VKHandler
+{
+public:
+ struct PushConstsProp {
+ uint in_img_width;
+ uint in_x_offset;
+ uint out_img_width;
+ uint out_x_offset;
+ uint copy_width;
+
+ PushConstsProp ();
+ };
+
+public:
+ explicit VKCopyHandler (const SmartPtr<VKDevice> &dev, const char* name = "vk-copy-handler");
+
+ bool set_copy_area (uint32_t idx, const Rect &in_area, const Rect &out_area);
+ uint32_t get_index () {
+ return _index;
+ }
+
+ XCamReturn copy (const SmartPtr<VideoBuffer> &in_buf, SmartPtr<VideoBuffer> &out_buf);
+ void copy_done (
+ const SmartPtr<Worker> &worker,
+ const SmartPtr<Worker::Arguments> &base,
+ const XCamReturn error);
+
+private:
+ virtual XCamReturn configure_resource (const SmartPtr<Parameters> &param);
+ virtual XCamReturn start_work (const SmartPtr<Parameters> &param);
+
+private:
+ SmartPtr<VKWorker> _worker;
+ PushConstsProp _image_prop;
+ VKDescriptor::BindingArray _binding_layout;
+
+ uint32_t _index;
+ Rect _in_area;
+ Rect _out_area;
+};
+
+}
+#endif //XCAM_VK_COPY_HANDLER_H
diff --git a/modules/vulkan/vk_descriptor.cpp b/modules/vulkan/vk_descriptor.cpp
new file mode 100644
index 0000000..888d3d6
--- /dev/null
+++ b/modules/vulkan/vk_descriptor.cpp
@@ -0,0 +1,220 @@
+/*
+ * vk_descriptor.cpp - Vulkan descriptor
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "vk_descriptor.h"
+#include "vk_device.h"
+
+namespace XCam {
+
+namespace VKDescriptor {
+
+SetLayoutBinding::SetLayoutBinding (
+ VkDescriptorType type, VkShaderStageFlags stage, uint32_t idx, uint32_t count)
+{
+ xcam_mem_clear (_binding);
+ _binding.binding = idx;
+ _binding.descriptorType = type;
+ _binding.descriptorCount = count;
+ _binding.stageFlags = stage;
+ _binding.pImmutableSamplers = NULL;
+}
+
+SetLayoutBinding::~SetLayoutBinding ()
+{
+}
+
+VkBindingArray
+get_vk_layoutbindings (const BindingArray &array)
+{
+ VkBindingArray ret;
+ ret.reserve (array.size ());
+ for (size_t i = 0; i < array.size (); ++i) {
+ ret.push_back(array[i]->get_vk_binding ());
+ }
+ return ret;
+}
+
+Pool::Pool (const SmartPtr<VKDevice> dev)
+ : _pool_id (VK_NULL_HANDLE)
+ , _set_size (0)
+ , _dev (dev)
+{}
+
+Pool::~Pool ()
+{
+ if (XCAM_IS_VALID_VK_ID (_pool_id)) {
+ _dev->destroy_desc_pool (_pool_id);
+ }
+}
+
+void
+Pool::add_binding (const SmartPtr<SetLayoutBinding> &bind)
+{
+ VkDescriptorSetLayoutBinding vk_binding = bind->get_vk_binding ();
+ Pool::TypeTable::iterator i = _types.find (vk_binding.descriptorType);
+ if (i == _types.end ())
+ _types.insert (i, Pool::TypeTable::value_type (vk_binding.descriptorType, vk_binding.descriptorCount));
+ else
+ i->second += vk_binding.descriptorCount;
+}
+
+bool
+Pool::add_set_bindings (const BindingArray &binds)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, !XCAM_IS_VALID_VK_ID (_pool_id), false,
+ "vk desriptor pool was inited, cannot add new binding.");
+
+ for (BindingArray::const_iterator i = binds.begin (); i != binds.end (); ++i) {
+ add_binding (*i);
+ }
+ ++_set_size;
+
+ return true;
+}
+
+XCamReturn
+Pool::create ()
+{
+ XCAM_FAIL_RETURN (
+ ERROR, !_types.empty (), XCAM_RETURN_ERROR_PARAM,
+ "vk desriptor pool cannot create since no types added.");
+
+ XCAM_FAIL_RETURN (
+ ERROR, _dev.ptr (), XCAM_RETURN_ERROR_PARAM,
+ "vk desriptor pool cannot create, device is null");
+
+ std::vector<VkDescriptorPoolSize> pool_sizes;
+ pool_sizes.reserve (_types.size ());
+ for (Pool::TypeTable::iterator i = _types.begin (); i != _types.end(); ++i) {
+ VkDescriptorPoolSize new_size = {};
+ new_size.type = i->first;
+ new_size.descriptorCount = i->second;
+ pool_sizes.push_back (new_size);
+ }
+
+ XCAM_ASSERT (_set_size);
+ VkDescriptorPoolCreateInfo create_info = {};
+ create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
+ create_info.maxSets = _set_size;
+ create_info.poolSizeCount = pool_sizes.size ();
+ create_info.pPoolSizes = pool_sizes.data ();
+
+ _pool_id = _dev->create_desc_pool (create_info);
+
+ XCAM_FAIL_RETURN (
+ ERROR, XCAM_IS_VALID_VK_ID (_pool_id), XCAM_RETURN_ERROR_VULKAN,
+ "vk desriptor pool create pool_id failed");
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+SmartPtr<Set>
+Pool::allocate_set (const SetBindInfoArray &bind_array, VkDescriptorSetLayout layout)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, XCAM_IS_VALID_VK_ID (_pool_id), NULL,
+ "vk desriptor pool allocate set failed, pool was not ready");
+
+#if 0
+ XCAM_FAIL_RETURN (
+ ERROR, bind_array.size () == bufs.size (), NULL,
+ "vk desriptor pool allocate set failed, bindings and bufs sizes are not matched");
+#endif
+
+ XCAM_FAIL_RETURN (
+ ERROR, _set_size > 0, NULL,
+ "vk desriptor pool allocate set failed, bindings and bufs sizes are not matched");
+
+ //TODO remove binds types from _types
+
+ VkDescriptorSetAllocateInfo alloc_info = {};
+ alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
+ alloc_info.descriptorPool = _pool_id;
+ alloc_info.pSetLayouts = &layout;
+ alloc_info.descriptorSetCount = 1;
+
+ VkDescriptorSet desc_set_id = _dev->allocate_desc_set (alloc_info);
+ XCAM_FAIL_RETURN (
+ ERROR, XCAM_IS_VALID_VK_ID (desc_set_id) > 0, NULL,
+ "vk desriptor pool allocate set failed");
+ SmartPtr<Set> new_set = new Set (desc_set_id, this);
+
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (new_set->update_set (bind_array)), NULL,
+ "vk descriptor pool update set failed");
+
+ --_set_size;
+ return new_set;
+}
+
+void
+Pool::destroy_desc_set (VkDescriptorSet set_id)
+{
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (_pool_id));
+ if (xcam_ret_is_ok (_dev->free_desc_set (set_id, _pool_id)))
+ ++_set_size;
+}
+
+Set::Set (VkDescriptorSet set_id, const SmartPtr<Pool> pool)
+ : _set_id (set_id)
+ , _pool (pool)
+{
+}
+
+Set::~Set ()
+{
+ if (XCAM_IS_VALID_VK_ID (_set_id)) {
+ _pool->destroy_desc_set (_set_id);
+ }
+}
+
+XCamReturn
+Set::update_set (const SetBindInfoArray &bind_array)
+{
+ std::vector<VkWriteDescriptorSet> write_desc_info (bind_array.size ());
+ for (uint32_t i = 0; i < bind_array.size (); ++i) {
+ const SetBindInfo &bind_info = bind_array[i];
+ SmartPtr<SetLayoutBinding> bind = bind_info.layout;
+ XCAM_ASSERT (bind.ptr () && bind_info.desc.buf.ptr ());
+
+ VkWriteDescriptorSet &info = write_desc_info[i];
+ xcam_mem_clear (info);
+ info.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+ info.dstSet = _set_id;
+ info.dstBinding = bind->get_index ();
+ info.descriptorCount = 1;
+ info.descriptorType = bind->get_desc_type();
+ info.pBufferInfo = &bind_info.desc.desc_info;
+ }
+ SmartPtr<VKDevice> dev = _pool->get_device ();
+ XCAM_ASSERT (dev.ptr ());
+ XCamReturn ret = dev->update_desc_set (write_desc_info);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "vk descriptor pool update set failed");
+
+ _bind_array = bind_array;
+ return ret;
+}
+
+}
+
+}
diff --git a/modules/vulkan/vk_descriptor.h b/modules/vulkan/vk_descriptor.h
new file mode 100644
index 0000000..63eff6a
--- /dev/null
+++ b/modules/vulkan/vk_descriptor.h
@@ -0,0 +1,163 @@
+/*
+ * vk_descriptor.h - Vulkan descriptor
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_VK_DESCRIPTOR_H
+#define XCAM_VK_DESCRIPTOR_H
+
+#include <vulkan/vulkan_std.h>
+#include <vulkan/vk_memory.h>
+#include <map>
+
+namespace XCam {
+
+class VKDevice;
+
+namespace VKDescriptor {
+
+class SetLayoutBinding
+{
+public:
+ virtual ~SetLayoutBinding ();
+ const VkDescriptorSetLayoutBinding &get_vk_binding () const {
+ return _binding;
+ }
+ VkDescriptorType get_desc_type () const {
+ return _binding.descriptorType;
+ }
+ uint32_t get_index () const {
+ return _binding.binding;
+ }
+
+protected:
+ explicit SetLayoutBinding (
+ VkDescriptorType type, VkShaderStageFlags stage, uint32_t idx, uint32_t count);
+
+private:
+ XCAM_DEAD_COPY (SetLayoutBinding);
+protected:
+ VkDescriptorSetLayoutBinding _binding;
+};
+
+template <VkShaderStageFlags stage>
+class LayoutBinding
+ : public SetLayoutBinding
+{
+public:
+ explicit LayoutBinding (VkDescriptorType type, uint32_t idx)
+ : SetLayoutBinding (type, stage, idx, 1)
+ {}
+};
+
+typedef LayoutBinding<VK_SHADER_STAGE_COMPUTE_BIT> ComputeLayoutBinding;
+typedef LayoutBinding<VK_SHADER_STAGE_VERTEX_BIT> VetexLayoutBinding;
+typedef LayoutBinding<VK_SHADER_STAGE_FRAGMENT_BIT> FragmentLayoutBinding;
+
+typedef std::vector<SmartPtr<SetLayoutBinding>> BindingArray;
+
+typedef std::vector<VkDescriptorSetLayoutBinding> VkBindingArray;
+
+VkBindingArray get_vk_layoutbindings (const BindingArray &array);
+
+struct SetBindInfo {
+ SmartPtr<SetLayoutBinding> layout;
+ VKBufDesc desc;
+};
+
+typedef std::vector<SetBindInfo> SetBindInfoArray;
+
+class Pool;
+class Set {
+public:
+ explicit Set (VkDescriptorSet set_id, const SmartPtr<Pool> pool);
+ ~Set ();
+ XCamReturn update_set (const SetBindInfoArray &bind_array);
+ VkDescriptorSet get_set_id () const {
+ return _set_id;
+ }
+
+private:
+ XCAM_DEAD_COPY (Set);
+
+ VkDescriptorSet _set_id;
+ SetBindInfoArray _bind_array;
+ SmartPtr<Pool> _pool;
+};
+
+class Pool
+ : public RefObj
+{
+ friend class Set;
+public:
+ explicit Pool (const SmartPtr<VKDevice> dev);
+ ~Pool ();
+ bool add_set_bindings (const BindingArray &binds);
+ XCamReturn create ();
+ const SmartPtr<VKDevice> &get_device() const {
+ return _dev;
+ }
+
+ SmartPtr<Set> allocate_set (
+ const SetBindInfoArray &bind_array, VkDescriptorSetLayout layout);
+
+private:
+ XCAM_DEAD_COPY (Pool);
+ void add_binding (const SmartPtr<SetLayoutBinding> &bind);
+ void destroy_desc_set (VkDescriptorSet set_id);
+
+private:
+ typedef std::map<VkDescriptorType, uint32_t> TypeTable;
+
+ VkDescriptorPool _pool_id;
+ uint32_t _set_size;
+ TypeTable _types;
+ const SmartPtr<VKDevice> _dev;
+};
+
+}
+
+namespace VKConstRange {
+
+class VKPushConstArg {
+public:
+ virtual ~VKPushConstArg () {}
+ virtual bool get_const_data (VkPushConstantRange &range, void *& ptr) = 0;
+};
+
+typedef std::vector<SmartPtr<VKPushConstArg>> VKPushConstArgs;
+
+typedef std::vector<VkPushConstantRange> VKConstantArray;
+
+template <VkShaderStageFlags stage>
+VkPushConstantRange
+get_constants (uint32_t size, uint32_t offset)
+{
+ VkPushConstantRange range = {};
+ range.stageFlags = stage;
+ range.offset = offset;
+ range.size = size;
+ return range;
+}
+
+#define get_compute_consts get_constants<VK_SHADER_STAGE_COMPUTE_BIT>
+}
+
+}
+
+#endif //XCAM_VK_DESCRIPTOR_H
diff --git a/modules/vulkan/vk_device.cpp b/modules/vulkan/vk_device.cpp
new file mode 100644
index 0000000..bf5e68e
--- /dev/null
+++ b/modules/vulkan/vk_device.cpp
@@ -0,0 +1,471 @@
+/*
+ * vk_device.cpp - vulkan device
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "vulkan_common.h"
+#include "vk_device.h"
+#include "vk_shader.h"
+#include "vk_instance.h"
+#include "vk_sync.h"
+#include "vk_cmdbuf.h"
+#include "file_handle.h"
+
+namespace XCam {
+
+SmartPtr<VKDevice> VKDevice::_default_dev;
+Mutex VKDevice::_default_mutex;
+
+VKDevice::~VKDevice ()
+{
+ if (_dev_id)
+ vkDestroyDevice (_dev_id, _allocator.ptr ());
+}
+
+VKDevice::VKDevice (VkDevice id, const SmartPtr<VKInstance> &instance)
+ : _dev_id (id)
+ , _instance (instance)
+{
+ XCAM_ASSERT (instance.ptr ());
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (id));
+ _allocator = instance->get_allocator ();
+}
+
+SmartPtr<VKDevice>
+VKDevice::default_device ()
+{
+ SmartLock lock (_default_mutex);
+ if (!_default_dev.ptr()) {
+ _default_dev = create_device ();
+ }
+ XCAM_FAIL_RETURN (
+ ERROR, _default_dev.ptr (), NULL,
+ "VKDevice prepare default device failed.");
+ return _default_dev;
+}
+
+SmartPtr<VKDevice>
+VKDevice::create_device ()
+{
+ SmartPtr<VKInstance> instance = VKInstance::get_instance ();
+ XCAM_FAIL_RETURN (
+ ERROR, instance.ptr (), NULL,
+ "vk create device failed");
+
+ VkPhysicalDevice phy_dev = instance->get_physical_dev ();
+ uint32_t compute_idx = instance->get_compute_queue_family_idx ();
+ SmartPtr<VkAllocationCallbacks> allocator = instance->get_allocator ();
+
+ float priority = 1.0f; //TODO, queue priority change?
+ VkDeviceQueueCreateInfo dev_queue_info = {};
+ dev_queue_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
+ dev_queue_info.queueFamilyIndex = compute_idx; // default use compute idx
+ dev_queue_info.queueCount = 1;
+ dev_queue_info.pQueuePriorities = &priority;
+
+ VkDeviceCreateInfo dev_create_info = {};
+ dev_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
+ //TODO, add graphics queue info
+ dev_create_info.queueCreateInfoCount = 1;
+ dev_create_info.pQueueCreateInfos = &dev_queue_info;
+
+ VkDevice dev_id = 0;
+ XCAM_VK_CHECK_RETURN (
+ ERROR,
+ vkCreateDevice (phy_dev, &dev_create_info, allocator.ptr (), &dev_id),
+ NULL, "create vk device failed");
+
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (dev_id));
+ SmartPtr<VKDevice> device = new VKDevice (dev_id, instance);
+ XCAM_ASSERT (device.ptr ());
+
+ XCamReturn ret = device->prepare_compute_queue ();
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), NULL,
+ "VKDevice prepare compute queue failed.");
+
+ return device;
+}
+
+XCamReturn
+VKDevice::prepare_compute_queue ()
+{
+ uint32_t compute_idx = _instance->get_compute_queue_family_idx ();
+ vkGetDeviceQueue (_dev_id, compute_idx, 0, &_compute_queue);
+ return XCAM_RETURN_NO_ERROR;
+}
+
+SmartPtr<VKShader>
+VKDevice::create_shader (const char *file_name)
+{
+ FileHandle file (file_name, "rb");
+ XCAM_FAIL_RETURN (
+ ERROR, file.is_valid (), NULL,
+ "VKDevice load shader failed when opend shader file:%s.",
+ XCAM_STR (file_name));
+
+ size_t file_size;
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (file.get_file_size (file_size)) || file_size == 0, NULL,
+ "VKDevice load shader failed when read shader file:%s.",
+ XCAM_STR (file_name));
+ std::vector<uint32_t> content (XCAM_ALIGN_UP (file_size, 4) / 4, 0);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (file.read_file ((void *)content.data (), file_size)), NULL,
+ "VKDevice load shader failed when read shader file:%s.",
+ XCAM_STR (file_name));
+ file.close ();
+
+ SmartPtr<VKShader> shader = create_shader (content);
+ if (shader.ptr ())
+ shader->set_name (file_name);
+ return shader;
+}
+
+SmartPtr<VKShader>
+VKDevice::create_shader (const std::vector<uint32_t> &binary)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, XCAM_IS_VALID_VK_ID (_dev_id), NULL,
+ "VKDevice load shader failed with error of null device ready.");
+ XCAM_FAIL_RETURN (
+ ERROR, binary.size () > 5, NULL,
+ "VKDevice load shader failed since binary is corrupt.");
+
+ VkShaderModule shader_id;
+ VkShaderModuleCreateInfo module_create_info = {};
+ module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
+ module_create_info.pNext = NULL;
+ module_create_info.codeSize = binary.size() * sizeof (binary[0]);
+ module_create_info.pCode = binary.data();
+ module_create_info.flags = 0;
+
+ XCAM_VK_CHECK_RETURN (
+ ERROR, vkCreateShaderModule (_dev_id, &module_create_info, NULL, &shader_id),
+ NULL, "VKDevice create shader module failed.");
+
+ XCAM_IS_VALID_VK_ID (shader_id);
+ return new VKShader (this, shader_id);
+}
+
+void
+VKDevice::destroy_shader_id (VkShaderModule shader)
+{
+ if (XCAM_IS_VALID_VK_ID(_dev_id) && XCAM_IS_VALID_VK_ID (shader))
+ vkDestroyShaderModule (_dev_id, shader, _allocator.ptr());
+}
+
+VkDeviceMemory
+VKDevice::allocate_mem_id (VkDeviceSize size, VkMemoryPropertyFlags memory_prop)
+{
+ VkDeviceMemory mem_id;
+ VkMemoryAllocateInfo mem_alloc_info = {};
+ mem_alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+ mem_alloc_info.allocationSize = size;
+ mem_alloc_info.memoryTypeIndex = _instance->get_mem_type_index (memory_prop);
+
+ XCAM_FAIL_RETURN (
+ ERROR, mem_alloc_info.memoryTypeIndex != (uint32_t)(-1), VK_NULL_HANDLE,
+ "VKDevice create mem id failed, can NOT find memory type:0x%08x.", (uint32_t)memory_prop);
+
+ XCAM_VK_CHECK_RETURN (
+ ERROR, vkAllocateMemory (_dev_id, &mem_alloc_info, _allocator.ptr (), &mem_id),
+ VK_NULL_HANDLE, "create vk buffer failed in allocating memory");
+ return mem_id;
+}
+
+void
+VKDevice::free_mem_id (VkDeviceMemory mem)
+{
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (_dev_id));
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (mem));
+
+ vkFreeMemory (_dev_id, mem, _allocator.ptr ());
+}
+
+XCamReturn
+VKDevice::map_mem (VkDeviceMemory mem, VkDeviceSize size, VkDeviceSize offset, void *&ptr)
+{
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (mem));
+ XCAM_VK_CHECK_RETURN (
+ ERROR, vkMapMemory (_dev_id, mem, offset, size, 0, &ptr), XCAM_RETURN_ERROR_VULKAN,
+ "vk device map mem failed. size:%lld", size);
+ return XCAM_RETURN_NO_ERROR;
+}
+
+void
+VKDevice::unmap_mem (VkDeviceMemory mem)
+{
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (mem));
+ vkUnmapMemory (_dev_id, mem);
+}
+
+VkBuffer
+VKDevice::create_buf_id (VkBufferUsageFlags usage, uint32_t size)
+{
+ VkBufferCreateInfo buf_create_info = {};
+ buf_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+ buf_create_info.size = size;
+ buf_create_info.usage = usage;
+ buf_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+
+ VkBuffer buf_id;
+ XCAM_VK_CHECK_RETURN (
+ ERROR, vkCreateBuffer (_dev_id, &buf_create_info, _allocator.ptr (), &buf_id),
+ VK_NULL_HANDLE, "create vk buffer failed");
+
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (buf_id));
+ return buf_id;
+}
+
+void
+VKDevice::destroy_buf_id (VkBuffer buf)
+{
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (buf));
+
+ vkDestroyBuffer (_dev_id, buf, _allocator.ptr ());
+}
+
+XCamReturn
+VKDevice::bind_buffer (VkBuffer buf, VkDeviceMemory mem, VkDeviceSize offset)
+{
+ XCAM_VK_CHECK_RETURN (
+ ERROR, vkBindBufferMemory (_dev_id, buf, mem, offset),
+ XCAM_RETURN_ERROR_VULKAN, "vkdevice bind buffer to mem failed");
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+VkDescriptorPool
+VKDevice::create_desc_pool (const VkDescriptorPoolCreateInfo &info)
+{
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (_dev_id));
+
+ VkDescriptorPool pool_id;
+ XCAM_VK_CHECK_RETURN (
+ ERROR,
+ vkCreateDescriptorPool (_dev_id, &info, _allocator.ptr (), &pool_id),
+ VK_NULL_HANDLE,
+ "vkdevice create desriptor pool failed");
+ return pool_id;
+}
+
+void
+VKDevice::destroy_desc_pool (VkDescriptorPool pool)
+{
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (_dev_id));
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (pool));
+ vkDestroyDescriptorPool (_dev_id, pool, _allocator.ptr ());
+}
+
+VkDescriptorSet
+VKDevice::allocate_desc_set (const VkDescriptorSetAllocateInfo &info)
+{
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (_dev_id));
+
+ VkDescriptorSet set_id;
+ XCAM_VK_CHECK_RETURN (
+ ERROR,
+ vkAllocateDescriptorSets (_dev_id, &info, &set_id),
+ VK_NULL_HANDLE,
+ "vkdevice create desriptor set failed");
+ return set_id;
+
+}
+
+XCamReturn
+VKDevice::free_desc_set (VkDescriptorSet set, VkDescriptorPool pool)
+{
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (_dev_id));
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (set));
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (pool));
+
+ XCAM_VK_CHECK_RETURN (
+ ERROR,
+ vkFreeDescriptorSets (_dev_id, pool, 1, &set),
+ XCAM_RETURN_ERROR_VULKAN,
+ "vkdevice free desriptor set from pool failed");
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+VKDevice::update_desc_set (const std::vector<VkWriteDescriptorSet> &sets)
+{
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (_dev_id));
+ vkUpdateDescriptorSets (_dev_id, sets.size (), sets.data (), 0, NULL);
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+VkCommandPool
+VKDevice::create_cmd_pool (VkFlags queue_flag)
+{
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (_dev_id));
+ XCAM_ASSERT (_instance.ptr ());
+ VkCommandPool pool_id = VK_NULL_HANDLE;
+
+ VkCommandPoolCreateInfo create_pool_info = {};
+ create_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
+ create_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
+
+ if (queue_flag == VK_QUEUE_COMPUTE_BIT)
+ create_pool_info.queueFamilyIndex = _instance->get_compute_queue_family_idx ();
+ else if (queue_flag == VK_QUEUE_GRAPHICS_BIT)
+ create_pool_info.queueFamilyIndex = _instance->get_graphics_queue_family_idx ();
+ else {
+ XCAM_LOG_WARNING ("VKDevice create command pool failed, queue_flag(%d) not supported.", queue_flag);
+ return VK_NULL_HANDLE;
+ }
+
+ XCAM_VK_CHECK_RETURN (
+ ERROR, vkCreateCommandPool (_dev_id, &create_pool_info, _allocator.ptr (), &pool_id),
+ VK_NULL_HANDLE, "VKDevice create command pool failed.");
+ return pool_id;
+}
+
+void
+VKDevice::destroy_cmd_pool (VkCommandPool pool)
+{
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (_dev_id));
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (pool));
+ vkDestroyCommandPool (_dev_id, pool, _allocator.ptr ());
+}
+
+VkCommandBuffer
+VKDevice::allocate_cmd_buffer (VkCommandPool pool)
+{
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (_dev_id));
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (pool));
+
+ VkCommandBufferAllocateInfo allocate_info = {};
+ allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+ allocate_info.commandPool = pool;
+ allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
+ allocate_info.commandBufferCount = 1;
+
+ VkCommandBuffer buf_id = VK_NULL_HANDLE;
+
+ XCAM_VK_CHECK_RETURN (
+ ERROR, vkAllocateCommandBuffers (_dev_id, &allocate_info, &buf_id),
+ VK_NULL_HANDLE, "VKDevice create command buffers failed.");
+ return buf_id;
+}
+
+void
+VKDevice::free_cmd_buffer (VkCommandPool pool, VkCommandBuffer buf)
+{
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (_dev_id));
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (pool));
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (buf));
+
+ vkFreeCommandBuffers (_dev_id, pool, 1, &buf);
+}
+
+SmartPtr<VKFence>
+VKDevice::create_fence (VkFenceCreateFlags flags)
+{
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (_dev_id));
+
+ VkFenceCreateInfo fence_info = {};
+ fence_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
+ fence_info.flags = flags;
+
+ VkFence fence_id = VK_NULL_HANDLE;
+ XCAM_VK_CHECK_RETURN (
+ ERROR, vkCreateFence (_dev_id, &fence_info, _allocator.ptr (), &fence_id),
+ NULL, "VKDevice create fence failed.");
+ return new VKFence (this, fence_id);
+}
+
+void
+VKDevice::destroy_fence (VkFence fence)
+{
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (_dev_id));
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (fence));
+
+ vkDestroyFence (_dev_id, fence, _allocator.ptr ());
+}
+
+XCamReturn
+VKDevice::reset_fence (VkFence fence)
+{
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (_dev_id));
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (fence));
+
+ XCAM_VK_CHECK_RETURN (
+ ERROR, vkResetFences (_dev_id, 1, &fence),
+ XCAM_RETURN_ERROR_VULKAN, "VKDevice reset fence failed.");
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+VKDevice::wait_for_fence (VkFence fence, uint64_t timeout)
+{
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (_dev_id));
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (fence));
+
+ VkResult ret = vkWaitForFences (_dev_id, 1, &fence, VK_TRUE, timeout);
+ if (ret == VK_TIMEOUT) {
+ XCAM_LOG_DEBUG ("VKDevice wait for fence timeout");
+ return XCAM_RETURN_ERROR_TIMEOUT;
+ }
+
+ XCAM_FAIL_RETURN (
+ ERROR, ret == VK_SUCCESS,
+ XCAM_RETURN_ERROR_VULKAN, "VKDevice wait for fence failed.");
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+VKDevice::compute_queue_submit (const SmartPtr<VKCmdBuf> cmd_buf, const SmartPtr<VKFence> fence)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, cmd_buf.ptr (),
+ XCAM_RETURN_ERROR_PARAM, "VKDevice compute queue submit failed, cmd_buf is empty.");
+
+ VkCommandBuffer buf_id = cmd_buf->get_cmd_buf_id ();
+ VkSubmitInfo submit_info = {};
+ submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+ submit_info.commandBufferCount = 1;
+ submit_info.pCommandBuffers = &buf_id;
+
+ VkFence fence_id = VK_NULL_HANDLE;
+ if (fence.ptr ())
+ fence_id = fence->get_fence_id ();
+ XCAM_VK_CHECK_RETURN (
+ ERROR, vkQueueSubmit (_compute_queue, 1, &submit_info, fence_id),
+ XCAM_RETURN_ERROR_VULKAN, "VKDevice compute queue submit failed.");
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+VKDevice::compute_queue_wait_idle ()
+{
+ XCAM_FAIL_RETURN (
+ ERROR, XCAM_IS_VALID_VK_ID (_compute_queue),
+ XCAM_RETURN_ERROR_PARAM, "VKDevice compute queue wait idle failed, queue_id is null");
+
+ XCAM_VK_CHECK_RETURN (
+ ERROR, vkQueueWaitIdle (_compute_queue),
+ XCAM_RETURN_ERROR_VULKAN, "VKDevice compute queue wait idle failed");
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+}
diff --git a/modules/vulkan/vk_device.h b/modules/vulkan/vk_device.h
new file mode 100644
index 0000000..27a07a1
--- /dev/null
+++ b/modules/vulkan/vk_device.h
@@ -0,0 +1,120 @@
+/*
+ * vk_device.h - vulkan device
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_VK_DEVICE_H
+#define XCAM_VK_DEVICE_H
+
+#include <vulkan/vulkan_std.h>
+#include <xcam_mutex.h>
+
+namespace XCam {
+
+class VKPipeline;
+class VKShader;
+class VKFence;
+class VKCmdBuf;
+class VKInstance;
+class VKMemory;
+class VKBuffer;
+
+namespace VKDescriptor {
+class Pool;
+class Set;
+};
+
+class VKDevice
+ : public RefObj
+{
+ friend class VKFence;
+ friend class VKShader;
+ friend class VKPipeline;
+ friend class VKCmdBuf;
+ friend class VKDescriptor::Pool;
+ friend class VKDescriptor::Set;
+ friend class VKMemory;
+ friend class VKBuffer;
+public:
+ ~VKDevice ();
+ static SmartPtr<VKDevice> default_device ();
+ static SmartPtr<VKDevice> create_device ();
+
+ VkDevice get_dev_id () const {
+ return _dev_id;
+ }
+ SmartPtr<VkAllocationCallbacks>
+ get_allocation_cb () const {
+ return _allocator;
+ }
+
+ SmartPtr<VKShader> create_shader (const char *file_name);
+ SmartPtr<VKShader> create_shader (const std::vector<uint32_t> &binary);
+ //SmartPtr<VKPipeline> create_pipeline (const SmartPtr<VKShader> shader);
+ SmartPtr<VKFence> create_fence (VkFenceCreateFlags flags = VK_FENCE_CREATE_SIGNALED_BIT);
+ XCamReturn compute_queue_submit (const SmartPtr<VKCmdBuf> cmd_buf, const SmartPtr<VKFence> fence);
+ XCamReturn compute_queue_wait_idle ();
+
+protected:
+ void destroy_shader_id (VkShaderModule shader);
+ VkDeviceMemory allocate_mem_id (VkDeviceSize size, VkMemoryPropertyFlags memory_prop);
+ void free_mem_id (VkDeviceMemory mem);
+ XCamReturn map_mem (VkDeviceMemory mem, VkDeviceSize size, VkDeviceSize offset, void *&ptr);
+ void unmap_mem (VkDeviceMemory mem);
+ VkBuffer create_buf_id (VkBufferUsageFlags usage, uint32_t size);
+ void destroy_buf_id (VkBuffer buf);
+ XCamReturn bind_buffer (VkBuffer buf, VkDeviceMemory mem, VkDeviceSize offset = 0);
+
+ VkDescriptorPool create_desc_pool (const VkDescriptorPoolCreateInfo &info);
+ void destroy_desc_pool (VkDescriptorPool pool);
+
+ VkDescriptorSet allocate_desc_set (const VkDescriptorSetAllocateInfo &info);
+ XCamReturn free_desc_set (VkDescriptorSet set, VkDescriptorPool pool);
+
+ XCamReturn update_desc_set (const std::vector<VkWriteDescriptorSet> &sets);
+ VkCommandPool create_cmd_pool (VkFlags queue_flag = VK_QUEUE_COMPUTE_BIT);
+ void destroy_cmd_pool (VkCommandPool pool);
+
+ VkCommandBuffer allocate_cmd_buffer (VkCommandPool pool);
+ void free_cmd_buffer (VkCommandPool pool, VkCommandBuffer buf);
+
+ void destroy_fence (VkFence fence);
+ XCamReturn reset_fence (VkFence fence);
+ XCamReturn wait_for_fence (VkFence fence, uint64_t timeout);
+
+protected:
+ explicit VKDevice (VkDevice id, const SmartPtr<VKInstance> &instance);
+ XCamReturn prepare_compute_queue ();
+ //SmartPtr<VKLayout> create_desc_set_layout ();
+
+private:
+ XCAM_DEAD_COPY (VKDevice);
+
+private:
+ static SmartPtr<VKDevice> _default_dev;
+ static Mutex _default_mutex;
+
+ VkDevice _dev_id;
+ VkQueue _compute_queue;
+ SmartPtr<VkAllocationCallbacks> _allocator;
+ SmartPtr<VKInstance> _instance;
+};
+
+}
+
+#endif //XCAM_VK_DEVICE_H
diff --git a/modules/vulkan/vk_geomap_handler.cpp b/modules/vulkan/vk_geomap_handler.cpp
new file mode 100644
index 0000000..4b65a44
--- /dev/null
+++ b/modules/vulkan/vk_geomap_handler.cpp
@@ -0,0 +1,314 @@
+/*
+ * vk_geomap_handler.cpp - vulkan geometry map handler implementation
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#include "vk_geomap_handler.h"
+#include "vk_video_buf_allocator.h"
+#include "vk_device.h"
+
+#define GEOMAP_SHADER_BINDING_COUNT 5
+
+#define XCAM_VK_GEOMAP_ALIGN_X 4
+#define XCAM_VK_GEOMAP_ALIGN_Y 2
+
+namespace XCam {
+
+namespace {
+
+DECLARE_WORK_CALLBACK (CbGeoMapShader, VKGeoMapHandler, geomap_done);
+
+class GeoMapArgs
+ : public VKWorker::VKArguments
+{
+public:
+ explicit GeoMapArgs (const SmartPtr<ImageHandler::Parameters> &param)
+ : _param (param)
+ {
+ XCAM_ASSERT (param.ptr ());
+ }
+ const SmartPtr<ImageHandler::Parameters> &get_param () const {
+ return _param;
+ }
+
+private:
+ SmartPtr<ImageHandler::Parameters> _param;
+};
+
+class VKGeoMapPushConst
+ : public VKConstRange::VKPushConstArg
+{
+public:
+ VKGeoMapPushConst (const VKGeoMapHandler::PushConstsProp &prop)
+ : _prop (prop)
+ {}
+
+ bool get_const_data (VkPushConstantRange &range, void *& ptr) {
+ range.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT;
+ range.offset = 0;
+ range.size = sizeof (_prop);
+ ptr = &_prop;
+ return true;
+ }
+
+private:
+ VKGeoMapHandler::PushConstsProp _prop;
+};
+
+static const VKShaderInfo geomap_shader_info (
+ "main",
+std::vector<uint32_t> {
+#include "shader_geomap.comp.spv"
+});
+
+}
+
+VKGeoMapHandler::PushConstsProp::PushConstsProp ()
+ : in_img_width (0)
+ , in_img_height (0)
+ , out_img_width (0)
+ , out_img_height (0)
+ , lut_width (0)
+ , lut_height (0)
+{
+ xcam_mem_clear (lut_step);
+ xcam_mem_clear (lut_std_step);
+}
+
+VKGeoMapHandler::VKGeoMapHandler (const SmartPtr<VKDevice> &dev, const char* name)
+ : VKHandler (dev, name)
+{
+}
+
+bool
+VKGeoMapHandler::set_lookup_table (const PointFloat2 *data, uint32_t width, uint32_t height)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, data && width && height, false,
+ "VKGeoMapHandler(%s) set look up table failed, data ptr:%p, width:%d, height:%d",
+ XCAM_STR (get_name ()), data, width, height);
+ XCAM_ASSERT (!_lut_buf.ptr ());
+
+ _lut_width = width;
+ _lut_height = height;
+
+ uint32_t lut_size = width * height * 2 * sizeof (float);
+ SmartPtr<VKBuffer> buf = VKBuffer::create_buffer (
+ get_vk_device (), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, lut_size);
+ XCAM_ASSERT (buf.ptr ());
+
+ float *ptr = (float *) buf->map (lut_size, 0);
+ XCAM_FAIL_RETURN (ERROR, ptr, false, "VKGeoMapHandler(%s) map range failed", XCAM_STR (get_name ()));
+ for (uint32_t i = 0; i < height; ++i) {
+ float *ret = &ptr[i * width * 2];
+ const PointFloat2 *line = &data[i * width];
+
+ for (uint32_t j = 0; j < width; ++j) {
+ ret[j * 2] = line[j].x;
+ ret[j * 2 + 1] = line[j].y;
+ }
+ }
+ buf->unmap ();
+ _lut_buf = buf;
+
+ return true;
+}
+
+bool
+VKGeoMapHandler::init_factors ()
+{
+ XCAM_ASSERT (_lut_width && _lut_height);
+
+ float factor_x, factor_y;
+ get_factors (factor_x, factor_y);
+
+ if (!XCAM_DOUBLE_EQUAL_AROUND (factor_x, 0.0f) && !XCAM_DOUBLE_EQUAL_AROUND (factor_y, 0.0f))
+ return true;
+
+ return auto_calculate_factors (_lut_width, _lut_height);
+}
+
+#define UNIT_BYTES (sizeof (uint32_t))
+
+XCamReturn
+VKGeoMapHandler::configure_resource (const SmartPtr<ImageHandler::Parameters> &param)
+{
+ XCAM_ASSERT (param.ptr () && param->in_buf.ptr ());
+ XCAM_FAIL_RETURN (
+ ERROR, _lut_buf.ptr (), XCAM_RETURN_ERROR_PARAM,
+ "VKGeoMapHandler(%s) configure resource failed, look up table is empty", XCAM_STR (get_name ()));
+
+ const VideoBufferInfo &in_info = param->in_buf->get_video_info ();
+ XCAM_FAIL_RETURN (
+ ERROR, in_info.format == V4L2_PIX_FMT_NV12, XCAM_RETURN_ERROR_PARAM,
+ "VKGeoMapHandler(%s) only support NV12 format, but input format is %s",
+ XCAM_STR (get_name ()), xcam_fourcc_to_string (in_info.format));
+
+ uint32_t out_width, out_height;
+ get_output_size (out_width, out_height);
+ VideoBufferInfo out_info;
+ out_info.init (
+ in_info.format, out_width, out_height,
+ XCAM_ALIGN_UP (out_width, XCAM_VK_GEOMAP_ALIGN_X),
+ XCAM_ALIGN_UP (out_height, XCAM_VK_GEOMAP_ALIGN_Y));
+ set_out_video_info (out_info);
+
+ init_factors ();
+
+ float factor_x, factor_y;
+ get_factors (factor_x, factor_y);
+ XCAM_FAIL_RETURN (
+ ERROR,
+ !XCAM_DOUBLE_EQUAL_AROUND (factor_x, 0.0f) &&
+ !XCAM_DOUBLE_EQUAL_AROUND (factor_y, 0.0f),
+ XCAM_RETURN_ERROR_PARAM,
+ "VKGeoMapHandler(%s) invalid standard factors: x:%f, y:%f",
+ XCAM_STR (get_name ()), factor_x, factor_y);
+
+ _image_prop.in_img_width = in_info.aligned_width / UNIT_BYTES;
+ _image_prop.in_img_height = in_info.aligned_height;
+ _image_prop.out_img_width = out_info.aligned_width / UNIT_BYTES;
+ _image_prop.out_img_height = out_info.aligned_height;
+ _image_prop.lut_width = _lut_width;
+ _image_prop.lut_height = _lut_height;
+ _image_prop.lut_std_step[0] = 1.0f / factor_x;
+ _image_prop.lut_std_step[1] = 1.0f / factor_y;
+
+ WorkSize global_size (
+ XCAM_ALIGN_UP (_image_prop.out_img_width, 8) / 8,
+ XCAM_ALIGN_UP (_image_prop.out_img_height, 16) / 16);
+
+ _binding_layout.clear ();
+ for (int i = 0; i < GEOMAP_SHADER_BINDING_COUNT; ++i) {
+ SmartPtr<VKDescriptor::SetLayoutBinding> binding =
+ new VKDescriptor::ComputeLayoutBinding (VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, i);
+ _binding_layout.push_back (binding);
+ }
+
+ XCamReturn ret = XCAM_RETURN_NO_ERROR;
+ if (!_worker.ptr ()) {
+ _worker = new VKWorker (get_vk_device(), "CbGeoMapShader", new CbGeoMapShader (this));
+ XCAM_ASSERT (_worker.ptr ());
+
+ _worker->set_global_size (global_size);
+
+ VKConstRange::VKPushConstArgs push_consts;
+ push_consts.push_back (new VKGeoMapPushConst (_image_prop));
+ ret = _worker->build (geomap_shader_info, _binding_layout, push_consts);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), XCAM_RETURN_ERROR_VULKAN,
+ "VKGeoMapHandler(%s) build geomap shader failed.", XCAM_STR (get_name ()));
+ }
+
+ return ret;
+}
+
+XCamReturn
+VKGeoMapHandler::start_work (const SmartPtr<ImageHandler::Parameters> &param)
+{
+ XCAM_ASSERT (_lut_buf.ptr ());
+ XCAM_ASSERT (param.ptr () && param->in_buf.ptr () && param->out_buf.ptr ());
+ XCAM_ASSERT (_binding_layout.size () == GEOMAP_SHADER_BINDING_COUNT);
+
+ SmartPtr<VKVideoBuffer> in_vk = param->in_buf.dynamic_cast_ptr<VKVideoBuffer> ();
+ SmartPtr<VKVideoBuffer> out_vk = param->out_buf.dynamic_cast_ptr<VKVideoBuffer> ();
+ XCAM_FAIL_RETURN (
+ ERROR, in_vk.ptr () && out_vk.ptr(), XCAM_RETURN_ERROR_VULKAN,
+ "VKGeoMapHandler(%s) param.in_buf or param.out_buf is not vk buffer", XCAM_STR (get_name ()));
+
+ VKDescriptor::SetBindInfoArray bindings (_binding_layout.size ());
+ bindings[0].layout = _binding_layout[0];
+ bindings[0].desc = VKBufDesc (in_vk->get_vk_buf (), NV12PlaneYIdx);
+ bindings[1].layout = _binding_layout[1];
+ bindings[1].desc = VKBufDesc (in_vk->get_vk_buf (), NV12PlaneUVIdx);
+ bindings[2].layout = _binding_layout[2];
+ bindings[2].desc = VKBufDesc (out_vk->get_vk_buf (), NV12PlaneYIdx);
+ bindings[3].layout = _binding_layout[3];
+ bindings[3].desc = VKBufDesc (out_vk->get_vk_buf (), NV12PlaneUVIdx);
+ bindings[4].layout = _binding_layout[4];
+ bindings[4].desc = VKBufDesc (_lut_buf);
+
+ float factor_x, factor_y;
+ get_factors (factor_x, factor_y);
+ _image_prop.lut_step[0] = 1.0f / factor_x;
+ _image_prop.lut_step[1] = 1.0f / factor_y;
+ _image_prop.lut_step[2] = _image_prop.lut_step[0];
+ _image_prop.lut_step[3] = _image_prop.lut_step[1];
+
+ SmartPtr<GeoMapArgs> args = new GeoMapArgs (param);
+ XCAM_ASSERT (args.ptr ());
+ args->set_bindings (bindings);
+ args->add_push_const (new VKGeoMapPushConst (_image_prop));
+
+ return _worker->work (args);
+}
+
+void
+VKGeoMapHandler::geomap_done (
+ const SmartPtr<Worker> &worker, const SmartPtr<Worker::Arguments> &base, const XCamReturn error)
+{
+ if (!xcam_ret_is_ok (error)) {
+ XCAM_LOG_ERROR ("VKGeoMapHandler(%s) geometry map failed.", XCAM_STR (get_name ()));
+ }
+
+ SmartPtr<VKWorker> vk_worker = worker.dynamic_cast_ptr<VKWorker> ();
+ XCAM_ASSERT (vk_worker.ptr ());
+ vk_worker->wait_fence ();
+
+ SmartPtr<GeoMapArgs> args = base.dynamic_cast_ptr<GeoMapArgs> ();
+ XCAM_ASSERT (args.ptr ());
+ const SmartPtr<ImageHandler::Parameters> param = args->get_param ();
+ XCAM_ASSERT (param.ptr ());
+
+ execute_done (param, error);
+}
+
+XCamReturn
+VKGeoMapHandler::remap (const SmartPtr<VideoBuffer> &in_buf, SmartPtr<VideoBuffer> &out_buf)
+{
+ SmartPtr<ImageHandler::Parameters> param = new ImageHandler::Parameters (in_buf, out_buf);
+ XCAM_ASSERT (param.ptr ());
+
+ XCamReturn ret = execute_buffer (param, false);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "VKGeoMapHandler(%s) remap failed", XCAM_STR (get_name ()));
+
+ if (!out_buf.ptr ()) {
+ out_buf = param->out_buf;
+ }
+
+ return ret;
+}
+
+SmartPtr<VKHandler> create_vk_geo_mapper (const SmartPtr<VKDevice> &dev, const char* name)
+{
+ SmartPtr<VKHandler> mapper = new VKGeoMapHandler (dev, name);
+ XCAM_ASSERT (mapper.ptr ());
+
+ return mapper;
+}
+
+SmartPtr<GeoMapper>
+GeoMapper::create_vk_geo_mapper (const SmartPtr<VKDevice> &dev, const char* name)
+{
+ SmartPtr<VKHandler> handler = XCam::create_vk_geo_mapper (dev, name);
+ return handler.dynamic_cast_ptr<GeoMapper> ();
+}
+
+};
diff --git a/modules/vulkan/vk_geomap_handler.h b/modules/vulkan/vk_geomap_handler.h
new file mode 100644
index 0000000..bf8d4d3
--- /dev/null
+++ b/modules/vulkan/vk_geomap_handler.h
@@ -0,0 +1,78 @@
+/*
+ * vk_geomap_handler.h - vulkan geometry map handler class
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#ifndef XCAM_VK_GEOMAP_HANDLER_H
+#define XCAM_VK_GEOMAP_HANDLER_H
+
+#include <xcam_utils.h>
+#include <interface/geo_mapper.h>
+#include <vulkan/vulkan_std.h>
+#include <vulkan/vk_worker.h>
+#include <vulkan/vk_handler.h>
+
+namespace XCam {
+
+class VKGeoMapHandler
+ : public VKHandler, public GeoMapper
+{
+public:
+ struct PushConstsProp {
+ uint in_img_width;
+ uint in_img_height;
+ uint out_img_width;
+ uint out_img_height;
+ uint lut_width;
+ uint lut_height;
+ float lut_step[4];
+ float lut_std_step[2];
+
+ PushConstsProp ();
+ };
+
+public:
+ explicit VKGeoMapHandler (const SmartPtr<VKDevice> &dev, const char* name = "vk-geomap-handler");
+
+ bool set_lookup_table (const PointFloat2 *data, uint32_t width, uint32_t height);
+
+ XCamReturn remap (const SmartPtr<VideoBuffer> &in_buf, SmartPtr<VideoBuffer> &out_buf);
+ void geomap_done (
+ const SmartPtr<Worker> &worker, const SmartPtr<Worker::Arguments> &base, const XCamReturn error);
+
+private:
+ virtual XCamReturn configure_resource (const SmartPtr<Parameters> &param);
+ virtual XCamReturn start_work (const SmartPtr<Parameters> &param);
+
+private:
+ virtual bool init_factors ();
+
+private:
+ SmartPtr<VKWorker> _worker;
+ PushConstsProp _image_prop;
+ VKDescriptor::BindingArray _binding_layout;
+
+ SmartPtr<VKBuffer> _lut_buf;
+ uint32_t _lut_width;
+ uint32_t _lut_height;
+};
+
+extern SmartPtr<VKHandler> create_vk_geo_mapper (const SmartPtr<VKDevice> &dev, const char* name);
+
+}
+#endif // XCAM_VK_GEOMAP_HANDLER_H
diff --git a/modules/vulkan/vk_handler.cpp b/modules/vulkan/vk_handler.cpp
new file mode 100644
index 0000000..6aa1a83
--- /dev/null
+++ b/modules/vulkan/vk_handler.cpp
@@ -0,0 +1,60 @@
+/*
+ * vk_handler.cpp - vulkan image handler class
+ *
+ * Copyright (c) 2017 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "vk_handler.h"
+#include "vk_device.h"
+#include "vk_video_buf_allocator.h"
+
+namespace XCam {
+
+VKHandler::VKHandler (const SmartPtr<VKDevice> &dev, const char* name)
+ : ImageHandler (name)
+ , _device (dev)
+{
+}
+
+VKHandler::~VKHandler ()
+{
+}
+
+
+XCamReturn
+VKHandler::finish ()
+{
+ if (_device.ptr ())
+ _device->compute_queue_wait_idle ();
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+VKHandler::terminate ()
+{
+ finish ();
+ return ImageHandler::terminate ();
+}
+
+SmartPtr<BufferPool>
+VKHandler::create_allocator ()
+{
+ return new VKVideoBufAllocator (_device);
+}
+
+}
diff --git a/modules/vulkan/vk_handler.h b/modules/vulkan/vk_handler.h
new file mode 100644
index 0000000..3d80fa0
--- /dev/null
+++ b/modules/vulkan/vk_handler.h
@@ -0,0 +1,57 @@
+/*
+ * vk_handler.h - vulkan image handler class
+ *
+ * Copyright (c) 2017 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_VK_HANDLER_H
+#define XCAM_VK_HANDLER_H
+
+#include <vulkan/vulkan_std.h>
+#include <image_handler.h>
+
+namespace XCam {
+
+class VKDevice;
+
+class VKHandler
+ : public ImageHandler
+{
+public:
+ explicit VKHandler (const SmartPtr<VKDevice> &dev, const char* name = "vk-handler");
+ ~VKHandler ();
+ const SmartPtr<VKDevice> &get_vk_device () const {
+ return _device;
+ }
+
+ // derive from ImageHandler
+ virtual XCamReturn finish ();
+ virtual XCamReturn terminate ();
+
+protected:
+ SmartPtr<BufferPool> create_allocator ();
+
+private:
+ XCAM_DEAD_COPY (VKHandler);
+
+protected:
+ SmartPtr<VKDevice> _device;
+};
+
+}
+
+#endif //XCAM_VK_HANDLER_H
diff --git a/modules/vulkan/vk_instance.cpp b/modules/vulkan/vk_instance.cpp
new file mode 100644
index 0000000..81b3e6d
--- /dev/null
+++ b/modules/vulkan/vk_instance.cpp
@@ -0,0 +1,230 @@
+/*
+ * vk_instance.cpp - vulkan instance
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "vk_instance.h"
+#include "vulkan_common.h"
+
+#define APP_NAME "xcam"
+#define ENGINE_NAME "xcam"
+
+#define XCAM_INVALID_VK_QUEUE_IDX UINT32_MAX
+
+namespace XCam {
+
+extern void vk_init_error_string ();
+
+SmartPtr<VKInstance> VKInstance::_instance;
+Mutex VKInstance::_instance_mutex;
+
+VKInstance::~VKInstance ()
+{
+ if (XCAM_IS_VALID_VK_ID (_instance_id))
+ vkDestroyInstance (_instance_id, _allocator.ptr ());
+}
+
+VKInstance::VKInstance (VkInstance id, VkAllocationCallbacks *allocator)
+ : _instance_id (id)
+ , _allocator (allocator)
+ , _physical_device (NULL)
+ , _compute_queue_family_idx (XCAM_INVALID_VK_QUEUE_IDX)
+ , _graphics_queue_family_idx (XCAM_INVALID_VK_QUEUE_IDX)
+{
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (id));
+ xcam_mem_clear (_device_properties);
+ xcam_mem_clear (_dev_mem_properties);
+}
+
+SmartPtr<VKInstance>
+VKInstance::get_instance ()
+{
+ SmartLock locker (_instance_mutex);
+ if (!_instance.ptr ()) {
+ vk_init_error_string ();
+ _instance = create_instance ();
+ }
+ return _instance;
+}
+
+SmartPtr<VKInstance>
+VKInstance::create_instance ()
+{
+ VkApplicationInfo app_info = {};
+ app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
+ app_info.pApplicationName = APP_NAME;
+ app_info.applicationVersion = 0;
+ app_info.pEngineName = ENGINE_NAME;
+ app_info.engineVersion = xcam_version ();
+ app_info.apiVersion = VK_API_VERSION_1_0;
+
+ VkInstance id;
+ VkInstanceCreateInfo inst_create_info = {};
+ inst_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
+ inst_create_info.pApplicationInfo = &app_info;
+ inst_create_info.enabledExtensionCount = 0; // TODO, add extensions
+ XCAM_VK_CHECK_RETURN(
+ ERROR, vkCreateInstance (&inst_create_info, NULL, &id),
+ NULL, "create vk instance failed");
+
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (id));
+ SmartPtr<VKInstance> vk_instance = new VKInstance (id, NULL);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (vk_instance->query_physical_info ()), NULL,
+ "vk instance query physical info failed");
+
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (vk_instance->query_queue_info ()), NULL,
+ "vk instance query queue info failed");
+
+ return vk_instance;
+}
+
+static const char *s_device_types[] = {
+ "OTHER_DEVICE",
+ "INTEGRATED_GPU",
+ "DISCRETE_GPU",
+ "VIRTUAL_GPU",
+ "CPU_TYPE",
+};
+
+static const char*
+device_type_to_str(VkPhysicalDeviceType type)
+{
+ size_t number = sizeof (s_device_types) / sizeof (s_device_types[0]);
+ assert (number == 5);
+ if ((size_t)type < number)
+ return s_device_types [type];
+ return "UNKNOWN_TYPE";
+}
+
+XCamReturn
+VKInstance::query_physical_info ()
+{
+#define MAX_DEV_NUM 256
+ VkPhysicalDevice devs[MAX_DEV_NUM];
+ uint32_t dev_num = 0;
+ XCAM_VK_CHECK_RETURN (
+ ERROR, vkEnumeratePhysicalDevices (_instance_id, &dev_num, NULL),
+ XCAM_RETURN_ERROR_VULKAN, "enum vk physical devices failed");
+ XCAM_FAIL_RETURN (
+ ERROR, dev_num, XCAM_RETURN_ERROR_VULKAN,
+ "There is NO vk physical devices");
+
+ dev_num = XCAM_MIN (dev_num, MAX_DEV_NUM);
+ vkEnumeratePhysicalDevices (_instance_id, &dev_num, devs);
+
+ VkPhysicalDevice gpu_dev[VK_PHYSICAL_DEVICE_TYPE_RANGE_SIZE] = {};
+
+ VkPhysicalDeviceProperties dev_prop;
+ for (uint32_t i = 0; i < dev_num; ++i) {
+ vkGetPhysicalDeviceProperties (devs[i], &dev_prop);
+
+ if (dev_prop.deviceType < VK_PHYSICAL_DEVICE_TYPE_BEGIN_RANGE ||
+ dev_prop.deviceType > VK_PHYSICAL_DEVICE_TYPE_END_RANGE) {
+ continue;
+ }
+ if (gpu_dev[dev_prop.deviceType]) {
+ XCAM_LOG_WARNING (
+ "double vk physical dev, type:%d, name:%s",
+ dev_prop.deviceType, dev_prop.deviceName);
+ continue;
+ }
+ gpu_dev[dev_prop.deviceType] = devs[i];
+#if 0
+ printf ("found vk physical dev_id:%d, name:%s, type:%d, API:%d\n",
+ dev_prop.deviceID, dev_prop.deviceName,
+ device_type_to_str (dev_prop.deviceType), dev_prop.apiVersion);
+#endif
+ }
+
+ if (gpu_dev[VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU])
+ _physical_device = gpu_dev[VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU];
+ else if (gpu_dev[VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU])
+ _physical_device = gpu_dev[VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU];
+ else if (gpu_dev[VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU])
+ _physical_device = gpu_dev[VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU];
+ else if (gpu_dev[VK_PHYSICAL_DEVICE_TYPE_CPU]) {
+ _physical_device = gpu_dev[VK_PHYSICAL_DEVICE_TYPE_CPU];
+ XCAM_LOG_WARNING ("vk device select physical CPU, performance may slow down");
+ } else {
+ XCAM_LOG_ERROR ("did NOT find available vk physical device");
+ return XCAM_RETURN_ERROR_VULKAN;
+ }
+
+ vkGetPhysicalDeviceProperties (_physical_device, &dev_prop);
+ XCAM_LOG_INFO ("choose vk physical dev properties dev_id:%d, name:%s, type:%s, API:%d\n",
+ dev_prop.deviceID, dev_prop.deviceName,
+ device_type_to_str (dev_prop.deviceType), dev_prop.apiVersion);
+ _device_properties = dev_prop;
+ vkGetPhysicalDeviceMemoryProperties (_physical_device, &_dev_mem_properties);
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+VKInstance::query_queue_info ()
+{
+ XCAM_ASSERT (_physical_device);
+ // get queue family porperties
+ uint32_t queue_count = 0;
+#define MAX_QUEUE_FAMILY_NUM 256
+ VkQueueFamilyProperties queue_family[MAX_QUEUE_FAMILY_NUM];
+
+ vkGetPhysicalDeviceQueueFamilyProperties (
+ _physical_device, &queue_count, NULL);
+ XCAM_FAIL_RETURN (
+ ERROR, queue_count, XCAM_RETURN_ERROR_VULKAN,
+ "There is NO vk physical devices");
+
+ if (queue_count > MAX_QUEUE_FAMILY_NUM)
+ queue_count = MAX_QUEUE_FAMILY_NUM;
+
+ vkGetPhysicalDeviceQueueFamilyProperties (
+ _physical_device, &queue_count, queue_family);
+
+ for (uint32_t i = 0; i < queue_count; ++i) {
+ if (queue_family[i].queueFlags & VK_QUEUE_COMPUTE_BIT) {
+ _compute_queue_family_idx = i;
+ }
+ if (queue_family[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) {
+ _graphics_queue_family_idx = i;
+ }
+ }
+
+ XCAM_FAIL_RETURN (
+ ERROR,
+ _compute_queue_family_idx != XCAM_INVALID_VK_QUEUE_IDX &&
+ _graphics_queue_family_idx != XCAM_INVALID_VK_QUEUE_IDX,
+ XCAM_RETURN_ERROR_VULKAN,
+ "There is NO vk compute/graphics queue family");
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+uint32_t
+VKInstance::get_mem_type_index (VkMemoryPropertyFlags prop) const
+{
+ for (uint32_t i = 0; i < _dev_mem_properties.memoryTypeCount; ++i) {
+ if (((uint32_t)(_dev_mem_properties.memoryTypes[i].propertyFlags) & prop) == prop)
+ return i;
+ }
+ return (uint32_t)(-1);
+}
+
+}
diff --git a/modules/vulkan/vk_instance.h b/modules/vulkan/vk_instance.h
new file mode 100644
index 0000000..b4b51d4
--- /dev/null
+++ b/modules/vulkan/vk_instance.h
@@ -0,0 +1,77 @@
+/*
+ * vk_instance.h - vulkan instance
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_VK_INSTANCE_H
+#define XCAM_VK_INSTANCE_H
+
+#include <vulkan/vulkan_std.h>
+#include <xcam_mutex.h>
+
+namespace XCam {
+
+class VKInstance
+{
+public:
+ ~VKInstance ();
+ static SmartPtr<VKInstance> get_instance ();
+
+ VkInstance get_id () const {
+ return _instance_id;
+ }
+ VkPhysicalDevice get_physical_dev () const {
+ return _physical_device;
+ }
+ uint32_t get_compute_queue_family_idx () const {
+ return _compute_queue_family_idx;
+ }
+ uint32_t get_graphics_queue_family_idx () const {
+ return _graphics_queue_family_idx;
+ }
+ uint32_t get_mem_type_index (VkMemoryPropertyFlags prop) const;
+
+ SmartPtr<VkAllocationCallbacks> get_allocator () const {
+ return _allocator;
+ }
+
+private:
+ explicit VKInstance (VkInstance id, VkAllocationCallbacks *allocator);
+ static SmartPtr<VKInstance> create_instance ();
+ XCamReturn query_physical_info ();
+ XCamReturn query_queue_info ();
+
+private:
+ XCAM_DEAD_COPY (VKInstance);
+
+private:
+ static SmartPtr<VKInstance> _instance;
+ static Mutex _instance_mutex;
+
+ VkInstance _instance_id;
+ SmartPtr<VkAllocationCallbacks> _allocator;
+ VkPhysicalDevice _physical_device;
+ VkPhysicalDeviceProperties _device_properties;
+ VkPhysicalDeviceMemoryProperties _dev_mem_properties;
+ uint32_t _compute_queue_family_idx;
+ uint32_t _graphics_queue_family_idx;
+};
+
+}
+
+#endif //XCAM_VK_INSTANCE_H
diff --git a/modules/vulkan/vk_memory.cpp b/modules/vulkan/vk_memory.cpp
new file mode 100644
index 0000000..09af690
--- /dev/null
+++ b/modules/vulkan/vk_memory.cpp
@@ -0,0 +1,182 @@
+/*
+ * vk_memory.cpp - Vulkan memory
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "vk_memory.h"
+#include "vk_device.h"
+
+namespace XCam {
+
+VKBufInfo::VKBufInfo ()
+ : format (V4L2_PIX_FMT_NV12)
+ , width (0)
+ , height (0)
+ , aligned_width (0)
+ , aligned_height (0)
+ , size (0)
+{
+ xcam_mem_clear (strides);
+ xcam_mem_clear (offsets);
+ xcam_mem_clear (slice_size);
+}
+
+VKMemory::VKMemory (
+ const SmartPtr<VKDevice> dev,
+ VkDeviceMemory id,
+ uint32_t size,
+ VkMemoryPropertyFlags mem_prop)
+ : _dev (dev)
+ , _mem_id (id)
+ , _mem_prop (mem_prop)
+ , _size (size)
+ , _mapped_ptr (NULL)
+{
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (id));
+}
+
+VKMemory::~VKMemory ()
+{
+ if (XCAM_IS_VALID_VK_ID (_mem_id) && _dev.ptr ()) {
+ _dev->free_mem_id (_mem_id);
+ }
+}
+
+void *
+VKMemory::map (VkDeviceSize size, VkDeviceSize offset)
+{
+ if (_mapped_ptr)
+ return _mapped_ptr;
+
+ XCAM_FAIL_RETURN (
+ ERROR,
+ xcam_ret_is_ok (_dev->map_mem (_mem_id, size, offset, _mapped_ptr)), NULL,
+ "VK memory map failed");
+
+ return _mapped_ptr;
+}
+
+void
+VKMemory::unmap ()
+{
+ if (_mapped_ptr) {
+ _dev->unmap_mem (_mem_id);
+ _mapped_ptr = NULL;
+ }
+}
+
+VKBuffer::VKBuffer (
+ const SmartPtr<VKDevice> dev,
+ VkBuffer buf_id,
+ VkDeviceMemory mem_id,
+ uint32_t size,
+ VkBufferUsageFlags usage,
+ VkMemoryPropertyFlags prop)
+ : VKMemory (dev, mem_id, size, prop)
+ , _buffer_id (buf_id)
+ , _usage_flags (usage)
+ , _prop_flags (prop)
+{
+}
+
+VKBuffer::~VKBuffer ()
+{
+ if (XCAM_IS_VALID_VK_ID (_buffer_id) && _dev.ptr ()) {
+ _dev->destroy_buf_id (_buffer_id);
+ }
+}
+
+XCamReturn
+VKBuffer::bind ()
+{
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (_buffer_id));
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (_mem_id));
+
+ return _dev->bind_buffer (_buffer_id, _mem_id, 0);
+}
+
+SmartPtr<VKBuffer>
+VKBuffer::create_buffer (
+ const SmartPtr<VKDevice> dev,
+ VkBufferUsageFlags usage,
+ uint32_t size, void *data,
+ VkMemoryPropertyFlags mem_prop)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, dev.ptr () && size, NULL,
+ "vk create buffer failed because of dev or size errors");
+
+ VkBuffer buf_id = dev->create_buf_id (usage, size);
+ XCAM_FAIL_RETURN (
+ ERROR, XCAM_IS_VALID_VK_ID (buf_id), NULL,
+ "vk create buffer failed");
+
+ VkDevice dev_id = dev->get_dev_id ();
+ VkMemoryRequirements mem_reqs;
+ vkGetBufferMemoryRequirements (dev_id, buf_id, &mem_reqs);
+ VkDeviceMemory mem_id = dev->allocate_mem_id (mem_reqs.size, mem_prop);
+ XCAM_FAIL_RETURN (
+ ERROR, XCAM_IS_VALID_VK_ID (mem_id), NULL,
+ "vk create buffer failed in mem allocation");
+
+ // size == mem_reqs.size or size?
+ SmartPtr<VKBuffer> buf = new VKBuffer (dev, buf_id, mem_id, size, usage, mem_prop);
+
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (buf->bind ()), NULL,
+ "vk create bufer failed when bind with memory");
+ if (!data)
+ return buf;
+
+ void *ptr = buf->map ();
+ XCAM_FAIL_RETURN (
+ ERROR, ptr, NULL,
+ "vk create bufer failed when map the buf");
+ memcpy (ptr, data, size);
+ buf->unmap ();
+
+ return buf;
+
+}
+
+VKBufDesc::VKBufDesc ()
+{
+ xcam_mem_clear (desc_info);
+}
+
+VKBufDesc::VKBufDesc (const SmartPtr<VKBuffer> &buffer, NV12PlaneIdx plane)
+ : buf (buffer)
+{
+ xcam_mem_clear (desc_info);
+ const VKBufInfo info = buffer->get_buf_info ();
+
+ desc_info.buffer = buffer->get_buf_id ();
+ desc_info.offset = info.offsets[plane];
+ desc_info.range = info.slice_size[plane];
+}
+
+VKBufDesc::VKBufDesc (const SmartPtr<VKBuffer> &buffer, uint32_t offset, size_t size)
+ : buf (buffer)
+{
+ xcam_mem_clear (desc_info);
+ desc_info.buffer = buffer->get_buf_id ();
+ desc_info.offset = offset;
+ desc_info.range = size;
+}
+
+}
diff --git a/modules/vulkan/vk_memory.h b/modules/vulkan/vk_memory.h
new file mode 100644
index 0000000..3eba942
--- /dev/null
+++ b/modules/vulkan/vk_memory.h
@@ -0,0 +1,134 @@
+/*
+ * vk_memory.h - Vulkan memory
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_VK_MEMORY_H
+#define XCAM_VK_MEMORY_H
+
+#include <vulkan/vulkan_std.h>
+
+#define XCAM_VK_MAX_COMPONENTS 4
+
+namespace XCam {
+
+struct VKBufInfo {
+ uint32_t format;
+ uint32_t width;
+ uint32_t height;
+ uint32_t aligned_width;
+ uint32_t aligned_height;
+ uint32_t size;
+ uint32_t strides[XCAM_VK_MAX_COMPONENTS];
+ uint32_t offsets[XCAM_VK_MAX_COMPONENTS];
+ uint32_t slice_size[XCAM_VK_MAX_COMPONENTS];
+
+ VKBufInfo ();
+ bool operator == (const VKBufInfo &info) const;
+};
+
+class VKDevice;
+
+class VKMemory
+{
+public:
+ virtual ~VKMemory ();
+ void *map (VkDeviceSize size = VK_WHOLE_SIZE, VkDeviceSize offset = 0);
+ void unmap ();
+
+protected:
+ explicit VKMemory (
+ const SmartPtr<VKDevice> dev, VkDeviceMemory id,
+ uint32_t size, VkMemoryPropertyFlags mem_prop);
+ VkDeviceMemory get_mem_id () const {
+ return _mem_id;
+ }
+
+private:
+ XCAM_DEAD_COPY (VKMemory);
+
+protected:
+ const SmartPtr<VKDevice> _dev;
+ VkDeviceMemory _mem_id;
+ VkMemoryPropertyFlags _mem_prop;
+ uint32_t _size;
+ void *_mapped_ptr;
+};
+
+class VKBuffer
+ : public VKMemory
+{
+public:
+ ~VKBuffer ();
+
+ // usage can be VK_BUFFER_USAGE_STORAGE_BUFFER_BIT or VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT
+ static SmartPtr<VKBuffer>
+ create_buffer (
+ const SmartPtr<VKDevice> dev,
+ VkBufferUsageFlags usage,
+ uint32_t size, void *data = NULL,
+ VkMemoryPropertyFlags mem_prop = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
+
+ VkBuffer get_buf_id () const {
+ return _buffer_id;
+ }
+ VkBufferUsageFlags get_usage_flags () const {
+ return _usage_flags;
+ }
+ VkMemoryPropertyFlags get_mem_flags () const {
+ return _prop_flags;
+ }
+
+ void set_buf_info (const VKBufInfo &info) {
+ _buf_info = info;
+ }
+ const VKBufInfo &get_buf_info () const {
+ return _buf_info;
+ }
+
+private:
+ explicit VKBuffer (
+ const SmartPtr<VKDevice> dev, VkBuffer buf_id,
+ VkDeviceMemory mem_id, uint32_t size,
+ VkBufferUsageFlags usage, VkMemoryPropertyFlags prop);
+ XCamReturn bind ();
+
+private:
+ XCAM_DEAD_COPY (VKBuffer);
+
+private:
+ VkBuffer _buffer_id;
+ VkBufferUsageFlags _usage_flags;
+ VkMemoryPropertyFlags _prop_flags;
+ VKBufInfo _buf_info;
+};
+
+struct VKBufDesc {
+ SmartPtr<VKBuffer> buf;
+ VkDescriptorBufferInfo desc_info;
+
+ VKBufDesc ();
+ VKBufDesc (const SmartPtr<VKBuffer> &buffer, NV12PlaneIdx plane);
+ VKBufDesc (const SmartPtr<VKBuffer> &buffer, uint32_t offset = 0, size_t size = VK_WHOLE_SIZE);
+};
+
+typedef std::vector<SmartPtr<VKBuffer>> VKBufferArray;
+
+}
+
+#endif //XCAM_VK_MEMORY_H
diff --git a/modules/vulkan/vk_pipeline.cpp b/modules/vulkan/vk_pipeline.cpp
new file mode 100644
index 0000000..5483582
--- /dev/null
+++ b/modules/vulkan/vk_pipeline.cpp
@@ -0,0 +1,293 @@
+/*
+ * vk_pipeline.cpp - Vulkan pipeline
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "vk_pipeline.h"
+#include "vulkan_common.h"
+#include "vk_cmdbuf.h"
+
+namespace XCam {
+
+VKPipeline::VKPipeline (
+ const SmartPtr<VKDevice> dev,
+ const ShaderVec &shaders,
+ const VKDescriptor::BindingArray &bindings,
+ const VKConstRange::VKConstantArray &consts)
+ : _pipe_id (VK_NULL_HANDLE)
+ , _dev (dev)
+ , _shaders (shaders)
+ , _bindings (bindings)
+ , _push_consts (consts)
+{
+ _allocator = _dev->get_allocation_cb ();
+ xcam_mem_clear (_name);
+}
+
+VKPipeline::~VKPipeline ()
+{
+ if (!_dev.ptr ())
+ return;
+
+ VkDevice dev_id = _dev->get_dev_id ();
+ if (XCAM_IS_VALID_VK_ID (_pipe_id))
+ vkDestroyPipeline (dev_id, _pipe_id, _allocator.ptr ());
+}
+
+void
+VKPipeline::set_desc_pool (const SmartPtr<VKDescriptor::Pool> pool)
+{
+ _pool = pool;
+
+ //TODO, check pool status and allocate set, need or not?
+}
+
+VkDescriptorSetLayout
+VKPipeline::create_desc_set_layout (
+ const VKDescriptor::BindingArray &bindings)
+{
+ VKDescriptor::VkBindingArray array = VKDescriptor::get_vk_layoutbindings (bindings);
+
+ VkDescriptorSetLayoutCreateInfo descriptor_layout = {};
+ descriptor_layout.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
+ descriptor_layout.bindingCount = array.size ();
+ descriptor_layout.pBindings = array.data ();
+
+ VkDescriptorSetLayout layout = NULL;
+ XCAM_VK_CHECK_RETURN (
+ ERROR,
+ vkCreateDescriptorSetLayout (
+ _dev->get_dev_id (), &descriptor_layout, _allocator.ptr (), &layout),
+ NULL, "VkPipeline create descriptor set layout failed");
+
+ return layout;
+}
+
+
+VkPipelineLayout
+VKPipeline::create_pipeline_layout (
+ VkDescriptorSetLayout desc_layout,
+ const VKConstRange::VKConstantArray &consts)
+{
+ VkPipelineLayoutCreateInfo pipe_layout_create_info = {};
+ pipe_layout_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
+ pipe_layout_create_info.flags = 0;
+ pipe_layout_create_info.setLayoutCount = 1;
+ pipe_layout_create_info.pSetLayouts = &desc_layout;
+ if (!consts.empty()) {
+ pipe_layout_create_info.pushConstantRangeCount = consts.size ();
+ pipe_layout_create_info.pPushConstantRanges = consts.data ();
+ }
+
+ VkPipelineLayout layout = NULL;
+ XCAM_VK_CHECK_RETURN (
+ ERROR,
+ vkCreatePipelineLayout (
+ _dev->get_dev_id (), &pipe_layout_create_info, NULL, &layout),
+ NULL, "VkPipeline create descriptor set layout failed");
+
+ return layout;
+}
+
+SmartPtr<VKPipeline>
+VKPipeline::create_compute_pipeline (
+ const SmartPtr<VKDevice> dev,
+ const SmartPtr<VKShader> shader,
+ const VKDescriptor::BindingArray &bindings,
+ const VKConstRange::VKConstantArray &consts)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, dev.ptr () && shader.ptr (), NULL,
+ "VKDevice create pipeline with error of null device ready.");
+
+ ShaderVec shaders = {shader};
+ SmartPtr<VKPipeline> pipe = new VKComputePipeline (dev, shaders, bindings, consts);
+
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (pipe->ensure_layouts ()), NULL,
+ "vk pipeline ensure layouts failed");
+
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (pipe->ensure_pipeline ()), NULL,
+ "vk pipeline ensure pipeline failed");
+
+ return pipe;
+}
+
+VKComputePipeline::VKComputePipeline (
+ const SmartPtr<VKDevice> dev,
+ const ShaderVec &shaders,
+ const VKDescriptor::BindingArray &bindings,
+ const VKConstRange::VKConstantArray &consts)
+ : VKPipeline (dev, shaders, bindings, consts)
+ , _pipe_layout (VK_NULL_HANDLE)
+ , _desc_layout (VK_NULL_HANDLE)
+{
+}
+
+VKComputePipeline::~VKComputePipeline ()
+{
+ if (!_dev.ptr ())
+ return;
+
+ VkDevice dev_id = _dev->get_dev_id ();
+ if (XCAM_IS_VALID_VK_ID (_pipe_layout))
+ vkDestroyPipelineLayout (dev_id, _pipe_layout, _allocator.ptr ());
+ if (XCAM_IS_VALID_VK_ID (_desc_layout))
+ vkDestroyDescriptorSetLayout (dev_id, _desc_layout, _allocator.ptr ());
+}
+
+XCamReturn
+VKComputePipeline::ensure_layouts ()
+{
+ if (!XCAM_IS_VALID_VK_ID (_desc_layout)) {
+ _desc_layout = create_desc_set_layout (_bindings);
+ }
+ XCAM_FAIL_RETURN (
+ ERROR, XCAM_IS_VALID_VK_ID(_desc_layout), XCAM_RETURN_ERROR_VULKAN,
+ "vk compute pipeline create desc layout failed");
+
+ if (!XCAM_IS_VALID_VK_ID (_pipe_layout)) {
+ _pipe_layout = create_pipeline_layout (_desc_layout, _push_consts);
+ }
+ XCAM_FAIL_RETURN (
+ ERROR, XCAM_IS_VALID_VK_ID(_pipe_layout), XCAM_RETURN_ERROR_VULKAN,
+ "vk compute pipeline create pipeline layout failed");
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+VKComputePipeline::ensure_pipeline ()
+{
+ XCAM_FAIL_RETURN (
+ ERROR, XCAM_IS_VALID_VK_ID (_desc_layout) && XCAM_IS_VALID_VK_ID (_pipe_layout),
+ XCAM_RETURN_ERROR_PARAM,
+ "vk compute ensure pipeline failed. need ensure desc_layout and pipe_layout first");
+
+ XCAM_FAIL_RETURN (
+ ERROR, !_shaders.empty (), XCAM_RETURN_ERROR_PARAM,
+ "vk compute ensure pipeline failed, shader was empty");
+
+ VkComputePipelineCreateInfo pipeline_create_info =
+ get_compute_create_info (_shaders[0], _pipe_layout);
+
+ VkPipeline pipe_id;
+ XCAM_VK_CHECK_RETURN (
+ ERROR, vkCreateComputePipelines (
+ _dev->get_dev_id (), 0, 1, &pipeline_create_info, 0, &pipe_id),
+ XCAM_RETURN_ERROR_VULKAN, "VK create compute pipeline failed.");
+
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (pipe_id));
+ _pipe_id = pipe_id;
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+VKComputePipeline::update_bindings (const VKDescriptor::SetBindInfoArray &bind_array)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, _pool.ptr () && XCAM_IS_VALID_VK_ID (_desc_layout), XCAM_RETURN_ERROR_PARAM,
+ "vk compute pipeline update bindins failed, pool was not set or desc_layout not ensured");
+
+ if (_desc_set.ptr ())
+ _desc_set.release ();
+
+ _desc_set = _pool->allocate_set (bind_array, _desc_layout);
+ XCAM_FAIL_RETURN (
+ ERROR, _desc_set.ptr (), XCAM_RETURN_ERROR_UNKNOWN,
+ "vk compute pipeline update bindins failed to allocate desc_set or update bindings");
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+VKComputePipeline::bind_by (VKCmdBuf &cmd_buf)
+{
+
+ VkCommandBuffer buf_id = cmd_buf.get_cmd_buf_id ();
+ VkPipeline pipe_id = get_pipeline_id ();
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (buf_id));
+ XCAM_FAIL_RETURN (
+ ERROR,
+ XCAM_IS_VALID_VK_ID (pipe_id) && XCAM_IS_VALID_VK_ID (_pipe_layout) && _desc_set.ptr (),
+ XCAM_RETURN_ERROR_PARAM,
+ "vk compute pipeline bind command buffer failed, please check pipe_id, pipe_layout and desc_layout.");
+
+ // // bind pipeline sets
+ vkCmdBindPipeline (buf_id, VK_PIPELINE_BIND_POINT_COMPUTE, pipe_id);
+
+ // bind descriptor sets
+ VkDescriptorSet desc_set_id = _desc_set->get_set_id ();
+ vkCmdBindDescriptorSets (
+ buf_id, VK_PIPELINE_BIND_POINT_COMPUTE, _pipe_layout,
+ 0, 1, &desc_set_id, 0, NULL);
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+VKComputePipeline::push_consts_by (
+ VKCmdBuf &cmd_buf, const SmartPtr<VKConstRange::VKPushConstArg> &push_const)
+{
+ VkCommandBuffer cmd_buf_id = cmd_buf.get_cmd_buf_id ();
+ XCAM_FAIL_RETURN (
+ ERROR,
+ XCAM_IS_VALID_VK_ID (cmd_buf_id) && XCAM_IS_VALID_VK_ID (_pipe_layout),
+ XCAM_RETURN_ERROR_PARAM,
+ "vk compute pipeline push_consts by cmdbuf failed, please check pipe_layout and cmd_buf_id.");
+
+ XCAM_ASSERT (push_const.ptr ());
+ VkPushConstantRange const_range;
+ xcam_mem_clear (const_range);
+ void *ptr = NULL;
+ push_const->get_const_data (const_range, ptr);
+
+ XCAM_FAIL_RETURN (
+ ERROR,
+ const_range.stageFlags == VK_SHADER_STAGE_COMPUTE_BIT,
+ XCAM_RETURN_ERROR_PARAM,
+ "vk compute pipeline push_consts by cmdbuf failed, please check pipe_layout and cmd_buf_id.");
+
+ vkCmdPushConstants(
+ cmd_buf_id, _pipe_layout, VK_SHADER_STAGE_COMPUTE_BIT, const_range.offset, const_range.size, ptr);
+ return XCAM_RETURN_NO_ERROR;
+}
+
+VkComputePipelineCreateInfo
+VKComputePipeline::get_compute_create_info (
+ const SmartPtr<VKShader> &shader,
+ VkPipelineLayout &layout)
+{
+ VkPipelineShaderStageCreateInfo shader_stage_create_info = {};
+ shader_stage_create_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
+ shader_stage_create_info.flags = 0;
+ shader_stage_create_info.stage = shader->get_shader_stage_flags ();
+ shader_stage_create_info.module = shader->get_shader_id ();
+ shader_stage_create_info.pName = shader->get_func_name ();
+
+ VkComputePipelineCreateInfo pipeline_create_info = { };
+ pipeline_create_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
+ pipeline_create_info.pNext = NULL;
+ pipeline_create_info.flags = 0;
+ pipeline_create_info.stage = shader_stage_create_info;
+ pipeline_create_info.layout = layout;
+
+ return pipeline_create_info;
+}
+
+}
diff --git a/modules/vulkan/vk_pipeline.h b/modules/vulkan/vk_pipeline.h
new file mode 100644
index 0000000..cecb99b
--- /dev/null
+++ b/modules/vulkan/vk_pipeline.h
@@ -0,0 +1,127 @@
+/*
+ * vk_pipeline.h - Vulkan pipeline
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_VK_PIPELINE_H
+#define XCAM_VK_PIPELINE_H
+
+#include <vulkan/vulkan_std.h>
+#include <vulkan/vk_descriptor.h>
+#include <vulkan/vk_device.h>
+#include <vulkan/vk_shader.h>
+
+namespace XCam {
+
+class VKPipeline
+{
+public:
+ static SmartPtr<VKPipeline>
+ create_compute_pipeline (
+ const SmartPtr<VKDevice> dev,
+ const SmartPtr<VKShader> shader,
+ const VKDescriptor::BindingArray &bindings,
+ const VKConstRange::VKConstantArray &consts);
+
+ virtual ~VKPipeline ();
+
+ VkPipeline get_pipeline_id () const {
+ return _pipe_id;
+ }
+ const char *get_name () const {
+ return _name;
+ }
+ void set_desc_pool (const SmartPtr<VKDescriptor::Pool> pool);
+ //interface
+ virtual XCamReturn update_bindings (const VKDescriptor::SetBindInfoArray &bind_array) = 0;
+
+ // inter-functions, called by VKCmdBuf
+ virtual XCamReturn bind_by (VKCmdBuf &cmd_buf) = 0;
+ virtual XCamReturn push_consts_by (
+ VKCmdBuf &cmd_buf, const SmartPtr<VKConstRange::VKPushConstArg> &push_const) = 0;
+
+protected:
+ explicit VKPipeline (
+ const SmartPtr<VKDevice> dev,
+ const ShaderVec &shaders,
+ const VKDescriptor::BindingArray &bindings,
+ const VKConstRange::VKConstantArray &consts);
+
+ VkDescriptorSetLayout create_desc_set_layout (
+ const VKDescriptor::BindingArray &bindings);
+
+ VkPipelineLayout create_pipeline_layout (
+ VkDescriptorSetLayout desc_layout,
+ const VKConstRange::VKConstantArray &consts);
+
+ // intra virtual functions
+ virtual XCamReturn ensure_layouts () = 0;
+ virtual XCamReturn ensure_pipeline () = 0;
+
+private:
+ XCAM_DEAD_COPY (VKPipeline);
+
+protected:
+ VkPipeline _pipe_id;
+ char _name [XCAM_VK_NAME_LENGTH];
+
+ SmartPtr<VKDevice> _dev;
+ SmartPtr<VkAllocationCallbacks> _allocator;
+ ShaderVec _shaders;
+ VKDescriptor::BindingArray _bindings;
+ VKConstRange::VKConstantArray _push_consts;
+ SmartPtr<VKDescriptor::Pool> _pool;
+};
+
+class VKComputePipeline
+ : public VKPipeline
+{
+ friend class VKPipeline;
+
+public:
+ static VkComputePipelineCreateInfo
+ get_compute_create_info (const SmartPtr<VKShader> &shader, VkPipelineLayout &layout);
+
+ ~VKComputePipeline ();
+
+ //inherit from VKPipeline
+ XCamReturn update_bindings (const VKDescriptor::SetBindInfoArray &bind_array);
+
+protected:
+ explicit VKComputePipeline (
+ const SmartPtr<VKDevice> dev,
+ const ShaderVec &shaders,
+ const VKDescriptor::BindingArray &bindings,
+ const VKConstRange::VKConstantArray &consts);
+
+ //virtual functions from VKPipeline
+ XCamReturn ensure_layouts ();
+ XCamReturn ensure_pipeline ();
+ XCamReturn bind_by (VKCmdBuf &cmd_buf);
+ XCamReturn push_consts_by (
+ VKCmdBuf &cmd_buf, const SmartPtr<VKConstRange::VKPushConstArg> &push_const);
+
+private:
+ VkPipelineLayout _pipe_layout;
+ VkDescriptorSetLayout _desc_layout;
+ SmartPtr<VKDescriptor::Set> _desc_set;
+};
+
+}
+
+#endif //XCAM_VK_PIPELINE_H
diff --git a/modules/vulkan/vk_shader.cpp b/modules/vulkan/vk_shader.cpp
new file mode 100644
index 0000000..96e0427
--- /dev/null
+++ b/modules/vulkan/vk_shader.cpp
@@ -0,0 +1,60 @@
+/*
+ * vk_shader.cpp - vulkan shader module
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "vk_shader.h"
+#include "vk_device.h"
+#include "file_handle.h"
+
+namespace XCam {
+
+VKShader::VKShader (SmartPtr<VKDevice> dev, VkShaderModule id, const char *name)
+ : _device (dev)
+ , _shader_id (id)
+ , _shader_stage (VK_SHADER_STAGE_COMPUTE_BIT)
+{
+ XCAM_IS_VALID_VK_ID (id);
+ xcam_mem_clear (_name);
+ if (name)
+ strncpy (_name, name, XCAM_VK_NAME_LENGTH - 1);
+ strncpy (_func_name, "main", XCAM_VK_NAME_LENGTH - 1);
+}
+
+VKShader::~VKShader ()
+{
+ if (XCAM_IS_VALID_VK_ID (_shader_id))
+ _device->destroy_shader_id (_shader_id);
+}
+
+void
+VKShader::set_func_name (const char *name)
+{
+ XCAM_ASSERT (name);
+ strncpy (_func_name, name, XCAM_VK_NAME_LENGTH - 1);
+}
+
+void
+VKShader::set_name (const char *name)
+{
+ XCAM_ASSERT (name);
+ strncpy (_name, name, XCAM_VK_NAME_LENGTH - 1);
+}
+
+
+}
diff --git a/modules/vulkan/vk_shader.h b/modules/vulkan/vk_shader.h
new file mode 100644
index 0000000..fd243bb
--- /dev/null
+++ b/modules/vulkan/vk_shader.h
@@ -0,0 +1,71 @@
+/*
+ * vk_shader.h - Vulkan shader module
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_VK_SHADER_H
+#define XCAM_VK_SHADER_H
+
+#include <vulkan/vulkan_std.h>
+
+namespace XCam {
+
+class VKDevice;
+
+class VKShader
+{
+ friend class VKDevice;
+public:
+ ~VKShader ();
+
+ VkShaderModule get_shader_id () const {
+ return _shader_id;
+ }
+ VkShaderStageFlagBits get_shader_stage_flags () const {
+ return _shader_stage;
+ }
+ void set_func_name (const char *name);
+ void set_name (const char *name);
+ const char *get_func_name () const {
+ return _func_name;
+ }
+ const char *get_name () const {
+ return _name;
+ }
+
+private:
+ explicit VKShader (SmartPtr<VKDevice> dev, VkShaderModule id, const char *name = "null");
+
+private:
+ XCAM_DEAD_COPY (VKShader);
+
+private:
+ //static ShaderTable _shader_cache;
+ //static Mutex _cache_mutex;
+ SmartPtr<VKDevice> _device;
+ VkShaderModule _shader_id;
+ VkShaderStageFlagBits _shader_stage;
+ char _func_name [XCAM_VK_NAME_LENGTH];
+ char _name [XCAM_VK_NAME_LENGTH];
+};
+
+typedef std::vector<SmartPtr<VKShader>> ShaderVec;
+
+}
+
+#endif //XCAM_VK_SHADER_H
diff --git a/modules/vulkan/vk_stitcher.cpp b/modules/vulkan/vk_stitcher.cpp
new file mode 100644
index 0000000..f074e48
--- /dev/null
+++ b/modules/vulkan/vk_stitcher.cpp
@@ -0,0 +1,824 @@
+/*
+ * vk_stitcher.cpp - Vulkan stitcher implementation
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#include "surview_fisheye_dewarp.h"
+#include "vk_video_buf_allocator.h"
+#include "vk_geomap_handler.h"
+#include "vk_blender.h"
+#include "vk_copy_handler.h"
+#include "vk_stitcher.h"
+#include "interface/feature_match.h"
+
+#define DUMP_BUFFER 0
+
+#define GEOMAP_POOL_SIZE 1
+
+#define VK_STITCHER_ALIGNMENT_X 16
+#define VK_STITCHER_ALIGNMENT_Y 4
+
+#define MAP_FACTOR_X 16
+#define MAP_FACTOR_Y 16
+
+#define CHECK_RET(ret, format, ...) \
+ if (!xcam_ret_is_ok (ret)) { \
+ XCAM_LOG_ERROR (format, ## __VA_ARGS__); \
+ }
+
+namespace XCam {
+
+#if DUMP_BUFFER
+static void
+dump_buf (const SmartPtr<VideoBuffer> &buf, uint32_t idx, const char *prefix)
+{
+ XCAM_ASSERT (buf.ptr () && prefix);
+
+ char name[256];
+ snprintf (name, 256, "%s-%d", prefix, idx);
+ dump_buf_perfix_path (buf, name);
+}
+#endif
+
+namespace VKSitcherPriv {
+
+DECLARE_HANDLER_CALLBACK (CbGeoMap, VKStitcher, geomap_done);
+
+struct GeoMapParam
+ : ImageHandler::Parameters
+{
+ SmartPtr<VKStitcher::StitcherParam> stitch_param;
+ uint32_t idx;
+
+ GeoMapParam (uint32_t i)
+ : idx (i)
+ {}
+};
+
+struct Factor {
+ float x, y;
+
+ Factor () : x (1.0f), y (1.0f) {}
+ void reset () {
+ x = 1.0f;
+ y = 1.0f;
+ }
+};
+
+struct GeoMapFactors {
+ Factor left;
+ Factor right;
+};
+
+typedef std::vector<SmartPtr<VKCopyHandler>> Copiers;
+
+struct StitcherResource {
+ SmartPtr<VKBlender::Sync> blender_sync[XCAM_STITCH_MAX_CAMERAS];
+ SmartPtr<BufferPool> mapper_pool[XCAM_STITCH_MAX_CAMERAS];
+
+ SmartPtr<GeoMapParam> mapper_param[XCAM_STITCH_MAX_CAMERAS];
+ SmartPtr<VKBlender::BlenderParam> blender_param[XCAM_STITCH_MAX_CAMERAS];
+ SmartPtr<ImageHandler::Parameters> copier_param[XCAM_STITCH_MAX_CAMERAS];
+
+ SmartPtr<VKGeoMapHandler> mapper[XCAM_STITCH_MAX_CAMERAS];
+ SmartPtr<VKBlender> blender[XCAM_STITCH_MAX_CAMERAS];
+ Copiers copiers;
+
+ SmartPtr<FeatureMatch> matcher[XCAM_STITCH_MAX_CAMERAS];
+ GeoMapFactors mapper_factors[XCAM_STITCH_MAX_CAMERAS];
+
+ StitcherResource ();
+};
+
+class StitcherImpl {
+ friend class XCam::VKStitcher;
+
+public:
+ StitcherImpl (VKStitcher *handler)
+ : _stitcher (handler)
+ {}
+
+ XCamReturn init_resource ();
+
+ XCamReturn start_geo_mappers (const SmartPtr<VKStitcher::StitcherParam> &param);
+ XCamReturn start_blenders (const SmartPtr<VKStitcher::StitcherParam> &param, uint32_t idx);
+ XCamReturn start_copier (const SmartPtr<VKStitcher::StitcherParam> &param, uint32_t idx);
+ XCamReturn start_feature_match (
+ const SmartPtr<VideoBuffer> &left_buf, const SmartPtr<VideoBuffer> &right_buf, uint32_t idx);
+
+ XCamReturn stop ();
+
+private:
+ SmartPtr<VKGeoMapHandler> create_geo_mapper (
+ const SmartPtr<VKDevice> &dev, const Stitcher::RoundViewSlice &view_slice);
+
+ XCamReturn init_geo_mappers (const SmartPtr<VKDevice> &dev);
+ XCamReturn init_blenders (const SmartPtr<VKDevice> &dev);
+ XCamReturn init_copiers (const SmartPtr<VKDevice> &dev);
+ void init_feature_matchers ();
+
+ void calc_geomap_factors (
+ uint32_t idx, const Factor &last_left_factor, const Factor &last_right_factor,
+ Factor &cur_left, Factor &cur_right);
+ bool update_geomap_factors (uint32_t idx);
+ XCamReturn create_geomap_pool (const SmartPtr<VKDevice> &dev, uint32_t idx);
+ XCamReturn set_geomap_table (
+ const SmartPtr<VKGeoMapHandler> &mapper, const CameraInfo &cam_info,
+ const Stitcher::RoundViewSlice &view_slice, const BowlDataConfig &bowl);
+ XCamReturn generate_geomap_table (const SmartPtr<VKGeoMapHandler> &mapper, uint32_t idx);
+
+ void update_blender_sync (uint32_t idx);
+ XCamReturn start_blender (const SmartPtr<VKStitcher::StitcherParam> &param, uint32_t idx);
+
+private:
+ StitcherResource _res;
+ VKStitcher *_stitcher;
+};
+
+StitcherResource::StitcherResource ()
+{
+}
+
+SmartPtr<VKGeoMapHandler>
+StitcherImpl::create_geo_mapper (
+ const SmartPtr<VKDevice> &dev, const Stitcher::RoundViewSlice &view_slice)
+{
+ XCAM_UNUSED (view_slice);
+
+ SmartPtr<VKGeoMapHandler> mapper;
+ if (_stitcher->get_scale_mode () == ScaleSingleConst) {
+ mapper = new VKGeoMapHandler (dev, "sitcher_singleconst_remapper");
+ } else {
+ XCAM_LOG_ERROR (
+ "vk-stitcher(%s) unsupported scale mode:%d",
+ XCAM_STR (_stitcher->get_name ()), _stitcher->get_scale_mode ());
+ }
+ XCAM_ASSERT (mapper.ptr ());
+
+ return mapper;
+}
+
+void
+StitcherImpl::update_blender_sync (uint32_t idx)
+{
+ uint32_t cam_num = _stitcher->get_camera_num ();
+ uint32_t pre_idx = (idx + cam_num - 1) % cam_num;
+
+ _res.blender_sync[pre_idx]->increment ();
+ _res.blender_sync[idx]->increment ();
+}
+
+void
+StitcherImpl::calc_geomap_factors (
+ uint32_t idx, const Factor &last_left_factor, const Factor &last_right_factor,
+ Factor &cur_left, Factor &cur_right)
+{
+ const Factor &fm_left_factor = _res.mapper_factors[idx].left;
+ const Factor &fm_right_factor = _res.mapper_factors[idx].right;
+
+ cur_left.x = last_left_factor.x * fm_left_factor.x;
+ cur_left.y = last_left_factor.y * fm_left_factor.y;
+ cur_right.x = last_right_factor.x * fm_right_factor.x;
+ cur_right.y = last_right_factor.y * fm_right_factor.y;
+
+ _res.mapper_factors[idx].left.reset ();
+ _res.mapper_factors[idx].right.reset ();
+}
+
+bool
+StitcherImpl::update_geomap_factors (uint32_t idx)
+{
+ SmartPtr<VKGeoMapHandler> &mapper = _res.mapper[idx];
+ XCAM_FAIL_RETURN (
+ ERROR, mapper.ptr (), false,
+ "vk-stitcher(%s) geomap handler is empty, idx:%d", XCAM_STR (_stitcher->get_name ()), idx);
+
+ if (_stitcher->get_scale_mode () == ScaleSingleConst) {
+ Factor unify_factor, cur_left, cur_right;
+
+ mapper->get_factors (unify_factor.x, unify_factor.y);
+ if (XCAM_DOUBLE_EQUAL_AROUND (unify_factor.x, 0.0f) ||
+ XCAM_DOUBLE_EQUAL_AROUND (unify_factor.y, 0.0f)) { // not started.
+ return true;
+ }
+
+ calc_geomap_factors (idx, unify_factor, unify_factor, cur_left, cur_right);
+ unify_factor.x = (cur_left.x + cur_right.x) / 2.0f;
+ unify_factor.y = (cur_left.y + cur_right.y) / 2.0f;
+
+ mapper->set_factors (unify_factor.x, unify_factor.y);
+ } else {
+ XCAM_LOG_ERROR (
+ "vk-stitcher(%s) unsupported scale mode:%d",
+ XCAM_STR (_stitcher->get_name ()), _stitcher->get_scale_mode ());
+ return false;
+ }
+
+ return true;
+}
+
+XCamReturn
+StitcherImpl::create_geomap_pool (const SmartPtr<VKDevice> &dev, uint32_t idx)
+{
+ uint32_t output_width, output_height;
+ _res.mapper[idx]->get_output_size (output_width, output_height);
+
+ VideoBufferInfo out_info;
+ out_info.init (
+ V4L2_PIX_FMT_NV12, output_width, output_height,
+ XCAM_ALIGN_UP (output_width, VK_STITCHER_ALIGNMENT_X),
+ XCAM_ALIGN_UP (output_height, VK_STITCHER_ALIGNMENT_Y));
+
+ SmartPtr<BufferPool> pool = create_vk_buffer_pool (dev);
+ XCAM_ASSERT (pool.ptr ());
+ XCAM_FAIL_RETURN (
+ ERROR, pool->set_video_info (out_info) && pool->reserve (GEOMAP_POOL_SIZE),
+ XCAM_RETURN_ERROR_MEM,
+ "vk-stitcher(%s) create buffer pool failed, buffer size:%dx%d, idx:%d",
+ XCAM_STR (_stitcher->get_name ()), out_info.width, out_info.height, idx);
+
+ _res.mapper_pool[idx] = pool;
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+StitcherImpl::set_geomap_table (
+ const SmartPtr<VKGeoMapHandler> &mapper, const CameraInfo &cam_info,
+ const Stitcher::RoundViewSlice &view_slice, const BowlDataConfig &bowl)
+{
+ PolyFisheyeDewarp fd;
+ fd.set_intrinsic_param (cam_info.calibration.intrinsic);
+ fd.set_extrinsic_param (cam_info.calibration.extrinsic);
+
+ uint32_t table_width, table_height;
+ table_width = view_slice.width / MAP_FACTOR_X;
+ table_height = view_slice.height / MAP_FACTOR_Y;
+
+ SurViewFisheyeDewarp::MapTable map_table (table_width * table_height);
+ fd.fisheye_dewarp (
+ map_table, table_width, table_height,
+ view_slice.width, view_slice.height, bowl);
+
+ bool ret = mapper->set_lookup_table (map_table.data (), table_width, table_height);
+ XCAM_FAIL_RETURN (
+ ERROR, ret, XCAM_RETURN_ERROR_UNKNOWN,
+ "vk-stitcher(%s) set geomap lookup table failed", XCAM_STR (_stitcher->get_name ()));
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+StitcherImpl::generate_geomap_table (
+ const SmartPtr<VKGeoMapHandler> &mapper, uint32_t idx)
+{
+ CameraInfo cam_info;
+ _stitcher->get_camera_info (idx, cam_info);
+ Stitcher::RoundViewSlice view_slice = _stitcher->get_round_view_slice (idx);
+
+ BowlDataConfig bowl = _stitcher->get_bowl_config ();
+ bowl.angle_start = view_slice.hori_angle_start;
+ bowl.angle_end = format_angle (view_slice.hori_angle_start + view_slice.hori_angle_range);
+ if (bowl.angle_end < bowl.angle_start)
+ bowl.angle_start -= 360.0f;
+
+ XCAM_LOG_DEBUG (
+ "vk-stitcher(%s) camera(idx:%d) info(angle start:%.2f, range:%.2f), bowl info(angle start:%.2f, end:%.2f)",
+ XCAM_STR (_stitcher->get_name ()), idx,
+ view_slice.hori_angle_start, view_slice.hori_angle_range,
+ bowl.angle_start, bowl.angle_end);
+
+ XCamReturn ret = set_geomap_table (mapper, cam_info, view_slice, bowl);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "vk-stitcher(%s) set geometry map table failed, idx:%d", XCAM_STR (_stitcher->get_name ()), idx);
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+StitcherImpl::init_geo_mappers (const SmartPtr<VKDevice> &dev)
+{
+ uint32_t cam_num = _stitcher->get_camera_num ();
+ SmartPtr<ImageHandler::Callback> cb = new CbGeoMap (_stitcher);
+
+ for (uint32_t idx = 0; idx < cam_num; ++idx) {
+ Stitcher::RoundViewSlice view_slice = _stitcher->get_round_view_slice (idx);
+
+ SmartPtr<VKGeoMapHandler> &mapper = _res.mapper[idx];
+ mapper = create_geo_mapper (dev, view_slice);
+ mapper->set_callback (cb);
+ mapper->set_output_size (view_slice.width, view_slice.height);
+
+ create_geomap_pool (dev, idx);
+
+ SmartPtr<GeoMapParam> &mapper_param = _res.mapper_param[idx];
+ mapper_param = new GeoMapParam (idx);
+ XCAM_ASSERT (mapper_param.ptr ());
+
+ mapper_param->out_buf = _res.mapper_pool[idx]->get_buffer ();
+ XCAM_ASSERT (mapper_param->out_buf.ptr ());
+
+ XCamReturn ret = generate_geomap_table (mapper, idx);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "vk-stitcher(%s) generate geomap table failed", XCAM_STR (_stitcher->get_name ()));
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+StitcherImpl::init_blenders (const SmartPtr<VKDevice> &dev)
+{
+ uint32_t out_width, out_height;
+ _stitcher->get_output_size (out_width, out_height);
+ uint32_t cam_num = _stitcher->get_camera_num ();
+
+ for (uint32_t idx = 0; idx < cam_num; ++idx) {
+ SmartPtr<VKBlender> &blender = _res.blender[idx];
+ blender = create_vk_blender (dev).dynamic_cast_ptr<VKBlender> ();
+ XCAM_ASSERT (blender.ptr ());
+
+ const Stitcher::ImageOverlapInfo &overlap = _stitcher->get_overlap (idx);
+ blender->set_output_size (out_width, out_height);
+ blender->set_merge_window (overlap.out_area);
+ blender->set_input_valid_area (overlap.left, 0);
+ blender->set_input_valid_area (overlap.right, 1);
+ blender->set_input_merge_area (overlap.left, 0);
+ blender->set_input_merge_area (overlap.right, 1);
+
+ SmartPtr<VKBlender::BlenderParam> &blender_param = _res.blender_param[idx];
+ blender_param = new VKBlender::BlenderParam (NULL, NULL, NULL);
+ XCAM_ASSERT (blender_param.ptr ());
+
+ uint32_t next_idx = (idx + 1) % cam_num;
+ blender_param->in_buf = _res.mapper_param[idx]->out_buf;
+ blender_param->in1_buf = _res.mapper_param[next_idx]->out_buf;
+ XCAM_ASSERT (blender_param->in_buf.ptr () && blender_param->in1_buf.ptr ());
+
+ _res.blender_sync[idx] = new VKBlender::Sync (2);
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+StitcherImpl::init_copiers (const SmartPtr<VKDevice> &dev)
+{
+ uint32_t cam_num = _stitcher->get_camera_num ();
+ for (uint32_t idx = 0; idx < cam_num; ++idx) {
+ SmartPtr<ImageHandler::Parameters> &copier_param = _res.copier_param[idx];
+ copier_param = new ImageHandler::Parameters ();
+ XCAM_ASSERT (copier_param.ptr ());
+
+ copier_param->in_buf = _res.mapper_param[idx]->out_buf;
+ XCAM_ASSERT (copier_param->in_buf.ptr ());
+ }
+
+ Stitcher::CopyAreaArray areas = _stitcher->get_copy_area ();
+ uint32_t size = areas.size ();
+ for (uint32_t idx = 0; idx < size; ++idx) {
+ XCAM_ASSERT (areas[idx].in_idx < size);
+
+ SmartPtr<VKCopyHandler> copier = new VKCopyHandler (dev);
+ XCAM_ASSERT (copier.ptr ());
+ copier->enable_allocator (false);
+ copier->set_copy_area (areas[idx].in_idx, areas[idx].in_area, areas[idx].out_area);
+
+ _res.copiers.push_back (copier);
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+void
+StitcherImpl::init_feature_matchers ()
+{
+#if HAVE_OPENCV
+ FeatureMatchMode fm_mode = _stitcher->get_fm_mode ();
+ if (fm_mode == FMNone)
+ return ;
+
+ uint32_t cam_num = _stitcher->get_camera_num ();
+ for (uint32_t idx = 0; idx < cam_num; ++idx) {
+ SmartPtr<FeatureMatch> &matcher = _res.matcher[idx];
+#ifndef ANDROID
+ if (fm_mode == FMDefault)
+ matcher = FeatureMatch::create_default_feature_match ();
+ else if (fm_mode == FMCluster)
+ matcher = FeatureMatch::create_cluster_feature_match ();
+ else if (fm_mode == FMCapi)
+ matcher = FeatureMatch::create_capi_feature_match ();
+ else {
+ XCAM_LOG_ERROR (
+ "vk-stitcher(%s) unsupported FeatureMatchMode: %d",
+ XCAM_STR (_stitcher->get_name ()), fm_mode);
+ }
+#else
+ matcher = FeatureMatch::create_capi_feature_match ();
+#endif
+ XCAM_ASSERT (matcher.ptr ());
+
+ FMConfig config;
+ config.sitch_min_width = 136;
+ config.min_corners = 4;
+ config.offset_factor = 0.8f;
+ config.delta_mean_offset = 120.0f;
+ config.recur_offset_error = 8.0f;
+ config.max_adjusted_offset = 24.0f;
+ config.max_valid_offset_y = 20.0f;
+ config.max_track_error = 28.0f;
+#ifdef ANDROID
+ config.max_track_error = 3600.0f;
+#endif
+ matcher->set_config (config);
+ matcher->set_fm_index (idx);
+
+ const BowlDataConfig bowl = _stitcher->get_bowl_config ();
+ const Stitcher::ImageOverlapInfo &info = _stitcher->get_overlap (idx);
+ Rect left_ovlap = info.left;
+ Rect right_ovlap = info.right;
+ left_ovlap.pos_y = 0;
+ left_ovlap.height = int32_t (bowl.wall_height / (bowl.wall_height + bowl.ground_length) * left_ovlap.height);
+ right_ovlap.pos_y = 0;
+ right_ovlap.height = left_ovlap.height;
+ matcher->set_crop_rect (left_ovlap, right_ovlap);
+ }
+#else
+ XCAM_LOG_ERROR ("vk-stitcher(%s) feature match is unsupported", XCAM_STR (_stitcher->get_name ()));
+ XCAM_ASSERT (false);
+#endif
+}
+
+XCamReturn
+StitcherImpl::init_resource ()
+{
+ const SmartPtr<VKDevice> &dev = _stitcher->get_vk_device ();
+ XCAM_ASSERT (dev.ptr ());
+
+ XCamReturn ret = init_geo_mappers (dev);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "vk-stitcher(%s) init dewarps failed", XCAM_STR (_stitcher->get_name ()));
+
+#if HAVE_OPENCV
+ init_feature_matchers ();
+#endif
+
+ ret = init_blenders (dev);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "vk-stitcher(%s) init blenders failed", XCAM_STR (_stitcher->get_name ()));
+
+ ret = init_copiers (dev);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "vk-stitcher(%s) init copiers failed", XCAM_STR (_stitcher->get_name ()));
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+StitcherImpl::start_geo_mappers (const SmartPtr<VKStitcher::StitcherParam> &param)
+{
+ uint32_t cam_num = _stitcher->get_camera_num ();
+
+ for (uint32_t idx = 0; idx < cam_num; ++idx) {
+ if (_stitcher->get_fm_mode ())
+ update_geomap_factors (idx);
+
+ SmartPtr<GeoMapParam> &mapper_param = _res.mapper_param[idx];
+ mapper_param->in_buf = param->in_bufs[idx];
+ mapper_param->stitch_param = param;
+
+ XCamReturn ret = _res.mapper[idx]->execute_buffer (mapper_param, false);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "vk-stitcher(%s) execute geo mapper failed, idx:%d",
+ XCAM_STR (_stitcher->get_name ()), idx);
+
+#if DUMP_BUFFER
+ dump_buf (mapper_param->out_buf, idx, "stitcher-geomap");
+#endif
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+StitcherImpl::start_feature_match (
+ const SmartPtr<VideoBuffer> &left_buf, const SmartPtr<VideoBuffer> &right_buf, uint32_t idx)
+{
+#if HAVE_OPENCV
+ _res.matcher[idx]->reset_offsets ();
+ _res.matcher[idx]->feature_match (left_buf, right_buf);
+
+ Rect left_ovlap, right_ovlap;
+ _res.matcher[idx]->get_crop_rect (left_ovlap, right_ovlap);
+ float left_offsetx = _res.matcher[idx]->get_current_left_offset_x ();
+
+ uint32_t left_idx = idx;
+ Factor left_factor, right_factor;
+ float center_x = (float) _stitcher->get_center (left_idx).slice_center_x;
+ float feature_center_x = (float)left_ovlap.pos_x + (left_ovlap.width / 2.0f);
+ float range = feature_center_x - center_x;
+ XCAM_ASSERT (range > 1.0f);
+ right_factor.x = (range + left_offsetx / 2.0f) / range;
+ right_factor.y = 1.0f;
+ XCAM_ASSERT (right_factor.x > 0.0f && right_factor.x < 2.0f);
+
+ uint32_t right_idx = (idx + 1) % _stitcher->get_camera_num ();
+ center_x = (float) _stitcher->get_center (right_idx).slice_center_x;
+ feature_center_x = (float)right_ovlap.pos_x + (right_ovlap.width / 2.0f);
+ range = center_x - feature_center_x;
+ XCAM_ASSERT (range > 1.0f);
+ left_factor.x = (range + left_offsetx / 2.0f) / range;
+ left_factor.y = 1.0f;
+ XCAM_ASSERT (left_factor.x > 0.0f && left_factor.x < 2.0f);
+
+ _res.mapper_factors[left_idx].right = right_factor;
+ _res.mapper_factors[right_idx].left = left_factor;
+
+ return XCAM_RETURN_NO_ERROR;
+#else
+ XCAM_LOG_ERROR ("vk-stitcher(%s) feature match is unsupported", XCAM_STR (_stitcher->get_name ()));
+ return XCAM_RETURN_ERROR_PARAM;
+#endif
+}
+
+XCamReturn
+StitcherImpl::start_blender (
+ const SmartPtr<VKStitcher::StitcherParam> &param, uint32_t idx)
+{
+ SmartPtr<VKBlender::Sync> &sync = _res.blender_sync[idx];
+ if (!sync->is_synced ())
+ return XCAM_RETURN_NO_ERROR;
+ sync->reset ();
+
+ SmartPtr<VKBlender::BlenderParam> &blend_param = _res.blender_param[idx];
+ blend_param->out_buf = param->out_buf;
+
+ XCamReturn ret = _res.blender[idx]->execute_buffer (blend_param, false);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "vk-stitcher(%s) execute blender failed, idx:%d", XCAM_STR (_stitcher->get_name ()), idx);
+
+#if DUMP_BUFFER
+ dump_buf (param->out_buf, idx, "stitcher-blend");
+#endif
+
+#if HAVE_OPENCV
+ if (_stitcher->get_fm_mode ()) {
+ ret = start_feature_match (blend_param->in_buf, blend_param->in1_buf, idx);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "vk-stitcher(%s) start feature match failed, idx:%d", XCAM_STR (_stitcher->get_name ()), idx);
+ }
+#endif
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+StitcherImpl::start_blenders (const SmartPtr<VKStitcher::StitcherParam> &param, uint32_t idx)
+{
+ uint32_t cam_num = _stitcher->get_camera_num ();
+ uint32_t pre_idx = (idx + cam_num - 1) % cam_num;
+
+ XCamReturn ret = start_blender (param, pre_idx);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "vk-stitcher(%s) start blender failed, idx:%d", XCAM_STR (_stitcher->get_name ()), pre_idx);
+
+ ret = start_blender (param, idx);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "vk-stitcher(%s) start blender failed, idx:%d", XCAM_STR (_stitcher->get_name ()), idx);
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+StitcherImpl::start_copier (
+ const SmartPtr<VKStitcher::StitcherParam> &param, uint32_t idx)
+{
+ uint32_t size = _stitcher->get_copy_area ().size ();
+
+ for (uint32_t i = 0; i < size; ++i) {
+ if(_res.copiers[i]->get_index () != idx)
+ continue;
+
+ SmartPtr<ImageHandler::Parameters> &copy_param = _res.copier_param[idx];
+ copy_param->out_buf = param->out_buf;
+
+ XCamReturn ret = _res.copiers[i]->execute_buffer (copy_param, false);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "vk-stitcher(%s) execute copier failed, i:%d idx:%d",
+ XCAM_STR (_stitcher->get_name ()), i, idx);
+
+#if DUMP_BUFFER
+ dump_buf (copy_param->out_buf, i, "stitcher-copy");
+#endif
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+StitcherImpl::stop ()
+{
+ uint32_t cam_num = _stitcher->get_camera_num ();
+ for (uint32_t i = 0; i < cam_num; ++i) {
+ if (_res.mapper[i].ptr ()) {
+ _res.mapper[i]->terminate ();
+ _res.mapper[i].release ();
+ }
+ if (_res.mapper_pool[i].ptr ()) {
+ _res.mapper_pool[i]->stop ();
+ }
+
+ if (_res.blender[i].ptr ()) {
+ _res.blender[i]->terminate ();
+ _res.blender[i].release ();
+ }
+ }
+
+ for (Copiers::iterator i = _res.copiers.begin (); i != _res.copiers.end (); ++i) {
+ SmartPtr<VKCopyHandler> &copier = *i;
+ if (copier.ptr ()) {
+ copier->terminate ();
+ copier.release ();
+ }
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+};
+
+VKStitcher::VKStitcher (const SmartPtr<VKDevice> &dev, const char *name)
+ : VKHandler (dev, name)
+ , Stitcher (VK_STITCHER_ALIGNMENT_X, VK_STITCHER_ALIGNMENT_X)
+{
+ SmartPtr<VKSitcherPriv::StitcherImpl> impl = new VKSitcherPriv::StitcherImpl (this);
+ XCAM_ASSERT (impl.ptr ());
+ _impl = impl;
+}
+
+VKStitcher::~VKStitcher ()
+{
+ _impl.release ();
+}
+
+XCamReturn
+VKStitcher::terminate ()
+{
+ _impl->stop ();
+ return VKHandler::terminate ();
+}
+
+XCamReturn
+VKStitcher::stitch_buffers (const VideoBufferList &in_bufs, SmartPtr<VideoBuffer> &out_buf)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, !in_bufs.empty (), XCAM_RETURN_ERROR_PARAM,
+ "vk-stitcher(%s) input buffers is empty", XCAM_STR (get_name ()));
+
+ SmartPtr<StitcherParam> param = new StitcherParam ();
+ XCAM_ASSERT (param.ptr ());
+
+ uint32_t buf_num = 0;
+ for (VideoBufferList::const_iterator iter = in_bufs.begin(); iter != in_bufs.end (); ++iter) {
+ XCAM_ASSERT ((*iter).ptr ());
+ param->in_bufs[buf_num++] = *iter;
+ }
+ param->in_buf_num = buf_num;
+ param->out_buf = out_buf;
+
+ XCamReturn ret = execute_buffer (param, false);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "vk-stitcher(%s) execute buffer failed", XCAM_STR (get_name ()));
+
+ finish ();
+ if (!out_buf.ptr ()) {
+ out_buf = param->out_buf;
+ }
+
+ return ret;
+}
+
+XCamReturn
+VKStitcher::configure_resource (const SmartPtr<Parameters> &param)
+{
+ XCAM_UNUSED (param);
+ XCAM_ASSERT (_impl.ptr ());
+
+ XCamReturn ret = estimate_round_slices ();
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "vk-stitcher(%s) estimate round view slices failed", XCAM_STR (get_name ()));
+
+ ret = estimate_coarse_crops ();
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "vk-stitcher(%s) estimate coarse crops failed", XCAM_STR (get_name ()));
+
+ ret = mark_centers ();
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "vk-stitcher(%s) mark centers failed", XCAM_STR (get_name ()));
+
+ ret = estimate_overlap ();
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "vk-stitcher(%s) estimake coarse overlap failed", XCAM_STR (get_name ()));
+
+ ret = update_copy_areas ();
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "vk-stitcher(%s) update copy areas failed", XCAM_STR (get_name ()));
+
+ ret = _impl->init_resource ();
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "vk-stitcher(%s) initialize private config failed", XCAM_STR (get_name ()));
+
+ VideoBufferInfo out_info;
+ uint32_t out_width, out_height;
+ get_output_size (out_width, out_height);
+ XCAM_FAIL_RETURN (
+ ERROR, out_width && out_height, XCAM_RETURN_ERROR_PARAM,
+ "vk-stitcher(%s) output size was not set", XCAM_STR (get_name ()));
+
+ out_info.init (
+ V4L2_PIX_FMT_NV12, out_width, out_height,
+ XCAM_ALIGN_UP (out_width, VK_STITCHER_ALIGNMENT_X),
+ XCAM_ALIGN_UP (out_height, VK_STITCHER_ALIGNMENT_Y));
+ set_out_video_info (out_info);
+
+ return ret;
+}
+
+XCamReturn
+VKStitcher::start_work (const SmartPtr<Parameters> &base)
+{
+ XCAM_ASSERT (base.ptr ());
+
+ SmartPtr<StitcherParam> param = base.dynamic_cast_ptr<StitcherParam> ();
+ XCAM_ASSERT (param.ptr () && param->in_buf_num > 0);
+
+ XCamReturn ret = _impl->start_geo_mappers (param);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), XCAM_RETURN_ERROR_PARAM,
+ "vk_stitcher(%s) start geometry map failed", XCAM_STR (get_name ()));
+
+ return ret;
+}
+
+void
+VKStitcher::geomap_done (
+ const SmartPtr<ImageHandler> &handler,
+ const SmartPtr<ImageHandler::Parameters> &base, const XCamReturn error)
+{
+ XCAM_UNUSED (handler);
+ XCAM_UNUSED (error);
+
+ SmartPtr<VKSitcherPriv::GeoMapParam> param = base.dynamic_cast_ptr<VKSitcherPriv::GeoMapParam> ();
+ XCAM_ASSERT (param.ptr ());
+ SmartPtr<VKStitcher::StitcherParam> &stitch_param = param->stitch_param;
+ XCAM_ASSERT (stitch_param.ptr ());
+
+ _impl->update_blender_sync (param->idx);
+
+ XCamReturn ret = _impl->start_blenders (stitch_param, param->idx);
+ CHECK_RET (ret, "vk-stitcher(%s) start blenders failed, idx:%d", XCAM_STR (get_name ()), param->idx);
+
+ ret = _impl->start_copier (stitch_param, param->idx);
+ CHECK_RET (ret, "vk-stitcher(%s) start copier failed, idx:%d", XCAM_STR (get_name ()), param->idx);
+}
+
+SmartPtr<Stitcher>
+Stitcher::create_vk_stitcher (const SmartPtr<VKDevice> dev)
+{
+ return new VKStitcher (dev);
+}
+
+}
diff --git a/modules/vulkan/vk_stitcher.h b/modules/vulkan/vk_stitcher.h
new file mode 100644
index 0000000..c59f013
--- /dev/null
+++ b/modules/vulkan/vk_stitcher.h
@@ -0,0 +1,80 @@
+/*
+ * vk_stitcher.h - Vulkan stitcher class
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#ifndef XCAM_VK_STITCHER_H
+#define XCAM_VK_STITCHER_H
+
+#include <interface/stitcher.h>
+#include <vulkan/vulkan_std.h>
+#include <vulkan/vk_handler.h>
+
+namespace XCam {
+
+namespace VKSitcherPriv {
+class StitcherImpl;
+class CbGeoMap;
+};
+
+class VKStitcher
+ : public VKHandler
+ , public Stitcher
+{
+ friend class VKSitcherPriv::StitcherImpl;
+ friend class VKSitcherPriv::CbGeoMap;
+
+public:
+ struct StitcherParam
+ : ImageHandler::Parameters
+ {
+ uint32_t in_buf_num;
+ SmartPtr<VideoBuffer> in_bufs[XCAM_STITCH_MAX_CAMERAS];
+
+ StitcherParam ()
+ : Parameters (NULL, NULL)
+ , in_buf_num (0)
+ {}
+ };
+
+public:
+ explicit VKStitcher (const SmartPtr<VKDevice> &dev, const char *name = "VKStitcher");
+ ~VKStitcher ();
+
+ // derived from VKHandler
+ virtual XCamReturn terminate ();
+
+protected:
+ // interface derive from Stitcher
+ XCamReturn stitch_buffers (const VideoBufferList &in_bufs, SmartPtr<VideoBuffer> &out_buf);
+
+ // derived from VKHandler
+ XCamReturn configure_resource (const SmartPtr<Parameters> &param);
+ XCamReturn start_work (const SmartPtr<Parameters> &param);
+
+private:
+ void geomap_done (
+ const SmartPtr<ImageHandler> &handler,
+ const SmartPtr<ImageHandler::Parameters> &param, const XCamReturn error);
+
+private:
+ SmartPtr<VKSitcherPriv::StitcherImpl> _impl;
+};
+
+}
+#endif // XCAM_VK_STITCHER_H
diff --git a/modules/vulkan/vk_sync.cpp b/modules/vulkan/vk_sync.cpp
new file mode 100644
index 0000000..f5ea6c6
--- /dev/null
+++ b/modules/vulkan/vk_sync.cpp
@@ -0,0 +1,55 @@
+/*
+ * vk_sync.cpp - Vulkan sync
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "vk_sync.h"
+#include "vk_device.h"
+
+namespace XCam {
+
+VKFence::~VKFence ()
+{
+ if (_dev.ptr () && XCAM_IS_VALID_VK_ID (_fence_id))
+ _dev->destroy_fence (_fence_id);
+}
+
+VKFence::VKFence (const SmartPtr<VKDevice> dev, VkFence id)
+ : _fence_id (id)
+ , _dev (dev)
+{
+}
+
+XCamReturn
+VKFence::reset ()
+{
+ XCAM_ASSERT (_dev.ptr ());
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (_fence_id));
+
+ return _dev->reset_fence (_fence_id);
+}
+
+XCamReturn
+VKFence::wait (uint64_t timeout)
+{
+ XCAM_ASSERT (_dev.ptr ());
+ XCAM_ASSERT (XCAM_IS_VALID_VK_ID (_fence_id));
+ return _dev->wait_for_fence (_fence_id, timeout);
+}
+
+}
diff --git a/modules/vulkan/vk_sync.h b/modules/vulkan/vk_sync.h
new file mode 100644
index 0000000..e2a7d34
--- /dev/null
+++ b/modules/vulkan/vk_sync.h
@@ -0,0 +1,56 @@
+/*
+ * vk_sync.h - Vulkan sync
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_VK_SYNC_H
+#define XCAM_VK_SYNC_H
+
+#include <vulkan/vulkan_std.h>
+
+namespace XCam {
+
+class VKDevice;
+
+class VKFence
+{
+ friend class VKDevice;
+public:
+ virtual ~VKFence ();
+
+ XCamReturn reset ();
+ XCamReturn wait (uint64_t timeout = UINT64_MAX);
+
+ VkFence get_fence_id () const {
+ return _fence_id;
+ }
+
+protected:
+ explicit VKFence (const SmartPtr<VKDevice> dev, VkFence id);
+
+private:
+ XCAM_DEAD_COPY (VKFence);
+
+protected:
+ VkFence _fence_id;
+ SmartPtr<VKDevice> _dev;
+};
+
+}
+
+#endif //XCAM_VK_SYNC_H
diff --git a/modules/vulkan/vk_video_buf_allocator.cpp b/modules/vulkan/vk_video_buf_allocator.cpp
new file mode 100644
index 0000000..c60476a
--- /dev/null
+++ b/modules/vulkan/vk_video_buf_allocator.cpp
@@ -0,0 +1,164 @@
+/*
+ * vk_video_buf_allocator.cpp - vulkan video buffer allocator implementation
+ *
+ * Copyright (c) 2017 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "vk_video_buf_allocator.h"
+#include "vk_memory.h"
+#include "vk_device.h"
+
+namespace XCam {
+
+class VKVideoData
+ : public BufferData
+{
+ friend class VKVideoBuffer;
+public:
+ explicit VKVideoData (const SmartPtr<VKBuffer> vk_buf);
+ virtual ~VKVideoData ();
+
+ //derive from BufferData
+ virtual uint8_t *map ();
+ virtual bool unmap ();
+
+ bool is_valid ();
+
+private:
+ uint8_t *_mem_ptr;
+ SmartPtr<VKBuffer> _vk_buf;
+};
+
+VKVideoData::VKVideoData (const SmartPtr<VKBuffer> vk_buf)
+ : _mem_ptr (NULL)
+ , _vk_buf (vk_buf)
+{
+ XCAM_ASSERT (vk_buf.ptr ());
+}
+
+VKVideoData::~VKVideoData ()
+{
+}
+
+bool
+VKVideoData::is_valid ()
+{
+ return _vk_buf.ptr () && XCAM_IS_VALID_VK_ID (_vk_buf->get_buf_id ());
+}
+
+uint8_t *
+VKVideoData::map ()
+{
+ if (!_mem_ptr) {
+ _mem_ptr = (uint8_t *)_vk_buf->map ();
+ }
+ return _mem_ptr;
+}
+
+bool
+VKVideoData::unmap ()
+{
+ if (!_mem_ptr)
+ return false;
+
+ _mem_ptr = NULL;
+ _vk_buf->unmap ();
+ return true;
+}
+
+VKVideoBufAllocator::VKVideoBufAllocator (const SmartPtr<VKDevice> dev)
+ : _dev (dev)
+{
+}
+
+VKVideoBufAllocator::~VKVideoBufAllocator ()
+{
+}
+
+SmartPtr<BufferData>
+VKVideoBufAllocator::allocate_data (const VideoBufferInfo &buffer_info)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, buffer_info.size, NULL,
+ "VKVideoBufAllocator allocate data failed. buf_size is zero");
+
+ SmartPtr<VKBuffer> vk_buf =
+ VKBuffer::create_buffer (_dev, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, buffer_info.size);
+
+ XCAM_FAIL_RETURN (
+ ERROR, vk_buf.ptr (), NULL,
+ "VKVideoBufAllocator create vk memory failed. buf_size :%d", buffer_info.size);
+
+ VKBufInfo info;
+ info.format = buffer_info.format;
+ info.width = buffer_info.width;
+ info.height = buffer_info.height;
+ info.aligned_width = buffer_info.aligned_width;
+ info.aligned_height = buffer_info.aligned_height;
+ info.size = buffer_info.size;
+ info.strides[0] = buffer_info.strides[0];
+ info.strides[1] = buffer_info.strides[1];
+ info.offsets[0] = buffer_info.offsets[0];
+ info.offsets[1] = buffer_info.offsets[1];
+ info.slice_size[0] = buffer_info.strides[0] * buffer_info.aligned_height;
+ info.slice_size[1] = buffer_info.size - buffer_info.offsets[1];
+ vk_buf->set_buf_info (info);
+
+ SmartPtr<VKVideoData> data = new VKVideoData (vk_buf);
+ XCAM_FAIL_RETURN (
+ ERROR, data.ptr () && data->is_valid (), NULL,
+ "VKVideoBufAllocator allocate data failed. buf_size:%d", buffer_info.size);
+
+ return data;
+}
+
+SmartPtr<BufferProxy>
+VKVideoBufAllocator::create_buffer_from_data (SmartPtr<BufferData> &data)
+{
+ const VideoBufferInfo &info = get_video_info ();
+
+ XCAM_ASSERT (data.ptr ());
+ return new VKVideoBuffer (info, data);
+}
+
+VKVideoBuffer::VKVideoBuffer (const VideoBufferInfo &info, const SmartPtr<BufferData> &data)
+ : BufferProxy (info, data)
+{
+}
+
+SmartPtr<VKBuffer>
+VKVideoBuffer::get_vk_buf ()
+{
+ SmartPtr<BufferData> data = get_buffer_data ();
+ SmartPtr<VKVideoData> vk_data = data.dynamic_cast_ptr<VKVideoData> ();
+ XCAM_FAIL_RETURN (
+ ERROR, vk_data.ptr () && vk_data->_vk_buf.ptr (), VK_NULL_HANDLE,
+ "VKVideoBuffer get buf_id failed, data is empty");
+
+ return vk_data->_vk_buf;
+}
+
+SmartPtr<BufferPool>
+create_vk_buffer_pool (const SmartPtr<VKDevice> &dev)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, dev.ptr () && XCAM_IS_VALID_VK_ID(dev->get_dev_id()), NULL,
+ "create_vk_buffer_pool failed since vk device is invalid");
+ return new VKVideoBufAllocator (dev);
+}
+
+}
diff --git a/modules/vulkan/vk_video_buf_allocator.h b/modules/vulkan/vk_video_buf_allocator.h
new file mode 100644
index 0000000..af56f94
--- /dev/null
+++ b/modules/vulkan/vk_video_buf_allocator.h
@@ -0,0 +1,58 @@
+/*
+ * vk_video_buf_allocator.h - vulkan video buffer allocator class
+ *
+ * Copyright (c) 2017 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_VK_VIDEO_BUF_ALLOCATOR_H
+#define XCAM_VK_VIDEO_BUF_ALLOCATOR_H
+
+#include <buffer_pool.h>
+
+namespace XCam {
+
+class VKDevice;
+class VKBuffer;
+
+class VKVideoBufAllocator
+ : public BufferPool
+{
+public:
+ explicit VKVideoBufAllocator (const SmartPtr<VKDevice> dev);
+ virtual ~VKVideoBufAllocator ();
+
+private:
+ //derive from BufferPool
+ virtual SmartPtr<BufferData> allocate_data (const VideoBufferInfo &buffer_info);
+ virtual SmartPtr<BufferProxy> create_buffer_from_data (SmartPtr<BufferData> &data);
+
+private:
+ SmartPtr<VKDevice> _dev;
+};
+
+class VKVideoBuffer
+ : public BufferProxy
+{
+public:
+ explicit VKVideoBuffer (const VideoBufferInfo &info, const SmartPtr<BufferData> &data);
+ SmartPtr<VKBuffer> get_vk_buf ();
+};
+
+}
+
+#endif //XCAM_VK_VIDEO_BUF_ALLOCATOR_H
+
diff --git a/modules/vulkan/vk_worker.cpp b/modules/vulkan/vk_worker.cpp
new file mode 100644
index 0000000..f40a81a
--- /dev/null
+++ b/modules/vulkan/vk_worker.cpp
@@ -0,0 +1,218 @@
+/*
+ * vk_worker.cpp - vulkan worker class
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "vk_worker.h"
+#include "vk_sync.h"
+#include "vk_pipeline.h"
+#include "vk_cmdbuf.h"
+#include "vk_device.h"
+#include "vulkan_common.h"
+
+namespace XCam {
+
+XCamReturn
+VKWorker::VKArguments::prepare_bindings (
+ VKDescriptor::SetBindInfoArray &binding_array,
+ VKConstRange::VKPushConstArgs &push_consts)
+{
+ XCAM_ASSERT (_binding_bufs.size ());
+ XCAM_FAIL_RETURN (
+ ERROR, _binding_bufs.size (), XCAM_RETURN_ERROR_PARAM,
+ "VKArguments found bindings empty, please check settings or derive interface prepare_bindings");
+
+ binding_array = _binding_bufs;
+ push_consts = _push_consts;
+ return XCAM_RETURN_NO_ERROR;
+}
+
+bool
+VKWorker::VKArguments::set_bindings (const VKDescriptor::SetBindInfoArray &arr)
+{
+ _binding_bufs = arr;
+ return true;
+}
+
+bool
+VKWorker::VKArguments::add_binding (const VKDescriptor::SetBindInfo &info)
+{
+ _binding_bufs.push_back (info);
+ return true;
+}
+
+bool
+VKWorker::VKArguments::add_push_const (const SmartPtr<VKConstRange::VKPushConstArg> &push_const)
+{
+ _push_consts.push_back (push_const);
+ return true;
+}
+
+VKWorker::VKWorker (SmartPtr<VKDevice> dev, const char *name, const SmartPtr<Callback> &cb)
+ : Worker (name, cb)
+ , _device (dev)
+{
+}
+
+VKWorker::~VKWorker ()
+{
+}
+
+XCamReturn
+VKWorker::build (
+ const VKShaderInfo &info,
+ const VKDescriptor::BindingArray &bindings,
+ const VKConstRange::VKPushConstArgs &consts)
+{
+ XCamReturn ret = XCAM_RETURN_NO_ERROR;
+ XCAM_FAIL_RETURN (
+ ERROR, _device.ptr (), XCAM_RETURN_ERROR_VULKAN,
+ "vk woker(%s) build failed since vk_device is null.", XCAM_STR (get_name ()));
+
+ SmartPtr<VKShader> shader;
+ if (info.type == VKSahderInfoSpirVPath) {
+ const char *dir_env = std::getenv (XCAM_VK_SHADER_PATH);
+ std::string vk_dir (dir_env, (dir_env ? strlen (dir_env) : 0));
+ if (vk_dir.empty () || !vk_dir.length())
+ vk_dir = XCAM_DEFAULT_VK_SHADER_PATH;
+ std::string spirv_path = vk_dir + "/" + info.spirv_path;
+ shader = _device->create_shader (spirv_path.c_str ());
+ } else if (info.type == VKSahderInfoSpirVBinary) {
+ shader = _device->create_shader (info.spirv_bin);
+ }
+ XCAM_FAIL_RETURN (
+ ERROR, shader.ptr (), XCAM_RETURN_ERROR_VULKAN,
+ "vk woker(%s) build failed when creating shader.", XCAM_STR (get_name ()));
+ shader->set_func_name (info.func_name.c_str ());
+
+ _desc_pool = new VKDescriptor::Pool (_device);
+ XCAM_ASSERT (_desc_pool.ptr ());
+ XCAM_FAIL_RETURN (
+ ERROR, _desc_pool->add_set_bindings (bindings), XCAM_RETURN_ERROR_VULKAN,
+ "vk woker(%s) build failed to add bindings to desc_pool", XCAM_STR (get_name ()));
+ ret = _desc_pool->create ();
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "vk woker(%s) build failed to craete bindings in desc_pool", XCAM_STR (get_name ()));
+
+ VKConstRange::VKConstantArray const_array;
+ for (size_t i = 0; i < consts.size(); ++i) {
+ VkPushConstantRange data_const = {0, 0, 0};
+ void *ptr = NULL;
+ consts[i]->get_const_data (data_const, ptr);
+ const_array.push_back (data_const);
+ }
+ _pipeline = VKPipeline::create_compute_pipeline (_device, shader, bindings, const_array);
+ XCAM_FAIL_RETURN (
+ ERROR, _pipeline.ptr (), XCAM_RETURN_ERROR_VULKAN,
+ "vk woker(%s) build failed when creating pipelines.", XCAM_STR (get_name ()));
+
+ _pipeline->set_desc_pool (_desc_pool);
+
+ _cmdbuf = VKCmdBuf::create_command_buffer (_device);
+ XCAM_FAIL_RETURN (
+ ERROR, _cmdbuf.ptr (), XCAM_RETURN_ERROR_VULKAN,
+ "vk woker(%s) build failed when creating command buffers.", XCAM_STR (get_name ()));
+
+ _fence = _device->create_fence (VK_FENCE_CREATE_SIGNALED_BIT);
+ XCAM_FAIL_RETURN (
+ ERROR, _fence.ptr (), XCAM_RETURN_ERROR_VULKAN,
+ "vk woker(%s) build failed when creating fence.", XCAM_STR (get_name ()));
+ return XCAM_RETURN_NO_ERROR;
+}
+
+// derived from Worker
+XCamReturn
+VKWorker::work (const SmartPtr<Worker::Arguments> &args)
+{
+ SmartPtr<VKArguments> vk_args = args.dynamic_cast_ptr<VKArguments>();
+ XCAM_FAIL_RETURN (
+ ERROR, vk_args.ptr(), XCAM_RETURN_ERROR_PARAM,
+ "vk woker(%s) work argements error.", XCAM_STR (get_name ()));
+
+ VKDescriptor::SetBindInfoArray binding_array;
+ VKConstRange::VKPushConstArgs push_consts;
+ XCamReturn ret = vk_args->prepare_bindings (binding_array, push_consts);
+
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "vk woker(%s) prepare argements failed.", XCAM_STR (get_name ()));
+
+ XCAM_FAIL_RETURN (
+ ERROR, !binding_array.empty (), XCAM_RETURN_ERROR_PARAM,
+ "vk woker(%s) binding_array is empty.", XCAM_STR (get_name ()));
+
+ ret = _pipeline->update_bindings (binding_array);
+
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "vk woker(%s) update binding argements failed.", XCAM_STR (get_name ()));
+
+ const WorkSize global = get_global_size ();
+ SmartPtr<VKCmdBuf::DispatchParam> dispatch =
+ new VKCmdBuf::DispatchParam (_pipeline, global.value[0], global.value[1], global.value[2]);
+ if (!push_consts.empty()) {
+ XCAM_FAIL_RETURN (
+ ERROR, dispatch->update_push_consts (push_consts), XCAM_RETURN_ERROR_PARAM,
+ "vk woker(%s) update push-consts failed.", XCAM_STR (get_name ()));
+ }
+
+ ret = _cmdbuf->record (dispatch);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "vk woker(%s) record cmdbuf failed.", XCAM_STR (get_name ()));
+
+ ret = _device->compute_queue_submit (_cmdbuf, _fence);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "vk woker(%s) submit compute queue failed.", XCAM_STR (get_name ()));
+
+ status_check (args, ret);
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+VKWorker::stop ()
+{
+ if (_pipeline.ptr () && _device.ptr ()) {
+ if (_fence.ptr ()) {
+ _fence->wait ();
+ _fence->reset ();
+ }
+ _device->compute_queue_wait_idle ();
+ }
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+VKWorker::wait_fence ()
+{
+ XCamReturn ret = XCAM_RETURN_NO_ERROR;
+ if (_fence.ptr ()) {
+ ret = _fence->wait ();
+ if (!xcam_ret_is_ok (ret)) {
+ XCAM_LOG_ERROR ("vk woker(%s) wait fence failed.", XCAM_STR (get_name ()));
+ }
+ _fence->reset ();
+ }
+
+ return ret;
+}
+
+}
diff --git a/modules/vulkan/vk_worker.h b/modules/vulkan/vk_worker.h
new file mode 100644
index 0000000..c23bd4d
--- /dev/null
+++ b/modules/vulkan/vk_worker.h
@@ -0,0 +1,112 @@
+/*
+ * vk_worker.h - vulkan worker class
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_VK_WORKER_H
+#define XCAM_VK_WORKER_H
+
+#include <vulkan/vulkan_std.h>
+#include <vulkan/vk_descriptor.h>
+#include <worker.h>
+#include <string>
+
+namespace XCam {
+
+class VKPipeline;
+class VKDevice;
+class VKFence;
+class VKCmdBuf;
+
+enum VKSahderInfoType {
+ VKSahderInfoSpirVBinary = 0,
+ VKSahderInfoSpirVPath = 1,
+};
+
+struct VKShaderInfo {
+ VKSahderInfoType type;
+ std::string func_name;
+ std::string spirv_path;
+ std::vector<uint32_t> spirv_bin;
+
+ VKShaderInfo () {}
+ VKShaderInfo (const char *func, const char *path)
+ : type (VKSahderInfoSpirVPath)
+ , func_name (func)
+ , spirv_path (path)
+ {}
+ VKShaderInfo (const char *func, const std::vector<uint32_t> &binary)
+ : type (VKSahderInfoSpirVBinary)
+ , func_name (func)
+ , spirv_bin (binary)
+ {}
+};
+
+class VKWorker
+ : public Worker
+{
+public:
+ class VKArguments:
+ public Worker::Arguments
+ {
+ friend class VKWorker;
+ public:
+ VKArguments () {}
+ VKArguments (VKDescriptor::SetBindInfoArray &arr)
+ : _binding_bufs (arr)
+ {}
+ bool set_bindings (const VKDescriptor::SetBindInfoArray &arr);
+ bool add_binding (const VKDescriptor::SetBindInfo &info);
+ bool add_push_const (const SmartPtr<VKConstRange::VKPushConstArg> &push_const);
+
+ protected:
+ virtual XCamReturn prepare_bindings (
+ VKDescriptor::SetBindInfoArray &binding_array,
+ VKConstRange::VKPushConstArgs &push_consts);
+ private:
+ VKDescriptor::SetBindInfoArray _binding_bufs;
+ VKConstRange::VKPushConstArgs _push_consts;
+ };
+
+public:
+ explicit VKWorker (SmartPtr<VKDevice> dev, const char *name, const SmartPtr<Callback> &cb = NULL);
+ virtual ~VKWorker ();
+
+ XCamReturn build (
+ const VKShaderInfo &info,
+ const VKDescriptor::BindingArray &bindings,
+ const VKConstRange::VKPushConstArgs &consts);
+
+ // derived from Worker
+ virtual XCamReturn work (const SmartPtr<Arguments> &args);
+ virtual XCamReturn stop ();
+ XCamReturn wait_fence ();
+
+private:
+ XCAM_DEAD_COPY (VKWorker);
+
+private:
+ SmartPtr<VKDevice> _device;
+ SmartPtr<VKDescriptor::Pool> _desc_pool;
+ SmartPtr<VKPipeline> _pipeline;
+ SmartPtr<VKFence> _fence;
+ SmartPtr<VKCmdBuf> _cmdbuf;
+};
+
+}
+#endif //XCAM_VK_WORKER_H
diff --git a/modules/vulkan/vulkan_common.cpp b/modules/vulkan/vulkan_common.cpp
new file mode 100644
index 0000000..6e7ec66
--- /dev/null
+++ b/modules/vulkan/vulkan_common.cpp
@@ -0,0 +1,77 @@
+/*
+ * vulkan_common.cpp - vulkan common
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "vulkan_common.h"
+#include <map>
+
+#define VK_STR_INSERT(ERR) \
+ vk_errors.insert (VkErrorMap::value_type(VK_ ##ERR, #ERR))
+
+namespace XCam {
+
+typedef std::map <uint32_t, const char*> VkErrorMap;
+
+static VkErrorMap vk_errors;
+
+void vk_init_error_string ()
+{
+ if (!vk_errors.empty ())
+ return;
+
+ VK_STR_INSERT (SUCCESS);
+ VK_STR_INSERT (NOT_READY);
+ VK_STR_INSERT (TIMEOUT);
+ VK_STR_INSERT (EVENT_SET);
+ VK_STR_INSERT (EVENT_RESET);
+ VK_STR_INSERT (INCOMPLETE);
+ VK_STR_INSERT (ERROR_OUT_OF_HOST_MEMORY);
+ VK_STR_INSERT (ERROR_OUT_OF_DEVICE_MEMORY);
+ VK_STR_INSERT (ERROR_INITIALIZATION_FAILED);
+ VK_STR_INSERT (ERROR_DEVICE_LOST);
+ VK_STR_INSERT (ERROR_MEMORY_MAP_FAILED);
+ VK_STR_INSERT (ERROR_LAYER_NOT_PRESENT);
+ VK_STR_INSERT (ERROR_FEATURE_NOT_PRESENT);
+ VK_STR_INSERT (ERROR_INCOMPATIBLE_DRIVER);
+ VK_STR_INSERT (ERROR_TOO_MANY_OBJECTS);
+ VK_STR_INSERT (ERROR_FORMAT_NOT_SUPPORTED);
+ VK_STR_INSERT (ERROR_FRAGMENTED_POOL);
+}
+
+const char*
+vk_error_str(VkResult id)
+{
+ VkErrorMap::iterator i = vk_errors.find (id);
+ if (i == vk_errors.end ())
+ return "VkUnKnown";
+ return i->second;
+}
+
+const std::string
+xcam_default_shader_path ()
+{
+ std::string home = "~";
+ const char *env = std::getenv ("HOME");
+ if (env)
+ home.assign (env, strlen (env));
+
+ return home + "/.xcam/vk";
+}
+
+}
diff --git a/modules/vulkan/vulkan_common.h b/modules/vulkan/vulkan_common.h
new file mode 100644
index 0000000..8093029
--- /dev/null
+++ b/modules/vulkan/vulkan_common.h
@@ -0,0 +1,33 @@
+/*
+ * vulkan_common.h - vulkan common
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_VK_COMMON_H
+#define XCAM_VK_COMMON_H
+
+#include <vulkan/vulkan_std.h>
+#include <string>
+
+namespace XCam {
+
+const char* vk_error_str(VkResult id);
+const std::string xcam_default_shader_path ();
+}
+
+#endif
diff --git a/modules/vulkan/vulkan_std.h b/modules/vulkan/vulkan_std.h
new file mode 100644
index 0000000..952645e
--- /dev/null
+++ b/modules/vulkan/vulkan_std.h
@@ -0,0 +1,43 @@
+/*
+ * vulkan_std.h - vulkan common
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#ifndef XCAM_VK_STD_H
+#define XCAM_VK_STD_H
+
+#include <xcam_std.h>
+#include <vulkan/vulkan.h>
+
+#define XCAM_VK_CHECK_RETURN(LEVEL, vk_exp, failed_value, format, ...) \
+ do { \
+ VkResult err = vk_exp; \
+ XCAM_FAIL_RETURN (LEVEL, err == VK_SUCCESS, failed_value, \
+ format ", vk_error(%d:%s)", ## __VA_ARGS__, \
+ (int)err, vk_error_str(err)); \
+ } while (0)
+
+
+#define XCAM_VK_NAME_LENGTH 256
+
+#define XCAM_IS_VALID_VK_ID(id) (VK_NULL_HANDLE != (id))
+
+#define XCAM_VK_SHADER_PATH "XCAM_VK_SHADER_PATH"
+#define XCAM_DEFAULT_VK_SHADER_PATH xcam_default_shader_path()
+
+#endif
diff --git a/plugins/3a/Makefile.am b/plugins/3a/Makefile.am
index 63c148a..4dbfcba 100644
--- a/plugins/3a/Makefile.am
+++ b/plugins/3a/Makefile.am
@@ -1,15 +1,5 @@
-if ENABLE_IA_AIQ
-AIQ_DIR = aiq
-else
-AIQ_DIR =
-endif
-
-if ENABLE_IA_AIQ
if HAVE_LIBCL
HYBRID_DIR = hybrid
-else
-HYBRID_DIR =
-endif
endif
-SUBDIRS = $(AIQ_DIR) $(HYBRID_DIR)
+SUBDIRS = aiq $(HYBRID_DIR)
diff --git a/plugins/3a/aiq/Makefile.am b/plugins/3a/aiq/Makefile.am
index c1ca926..b22febb 100644
--- a/plugins/3a/aiq/Makefile.am
+++ b/plugins/3a/aiq/Makefile.am
@@ -1,43 +1,44 @@
plugin_LTLIBRARIES = libxcam_3a_aiq.la
-XCAMAIQ_CXXFLAGS = $(XCAM_CXXFLAGS)
-XCAMAIQ_LIBS = \
+XCAM_AIQ_CXXFLAGS = \
+ $(XCAM_CXXFLAGS) \
+ -I$(top_srcdir)/xcore \
+ -I$(top_srcdir)/modules/isp \
+ -I$(top_srcdir)/plugins/3a/aiq \
+ $(NULL)
+
+XCAM_AIQ_LIBS = \
+ $(top_builddir)/xcore/libxcam_core.la \
+ $(top_builddir)/modules/isp/libxcam_isp.la \
$(NULL)
if HAVE_LIBDRM
-XCAMAIQ_CXXFLAGS += $(LIBDRM_CFLAGS)
-XCAMAIQ_LIBS += $(LIBDRM_LIBS)
+XCAM_AIQ_CXXFLAGS += $(LIBDRM_CFLAGS)
+XCAM_AIQ_LIBS += $(LIBDRM_LIBS)
endif
if USE_LOCAL_ATOMISP
-XCAMAIQ_CXXFLAGS += \
- -I$(top_srcdir)/ext/atomisp \
+XCAM_AIQ_CXXFLAGS += \
+ -I$(top_srcdir)/ext/atomisp \
$(NULL)
endif
plugindir="$(libdir)/xcam/plugins/3a"
libxcam_3a_aiq_la_SOURCES = \
- aiq_wrapper.cpp \
+ aiq_wrapper.cpp \
$(NULL)
libxcam_3a_aiq_la_CXXFLAGS = \
- $(GST_CFLAGS) $(XCAMAIQ_CXXFLAGS) \
- -I$(top_srcdir)/xcore \
- -I$(top_srcdir)/modules/isp \
- -I$(top_srcdir)/plugins/3a/aiq \
+ $(XCAM_AIQ_CXXFLAGS) \
$(NULL)
libxcam_3a_aiq_la_LIBADD = \
- $(XCAMAIQ_LIBS) \
- $(top_builddir)/modules/isp/libxcam_isp.la \
- $(top_builddir)/xcore/libxcam_core.la \
+ $(XCAM_AIQ_LIBS) \
$(NULL)
libxcam_3a_aiq_la_LDFLAGS = \
- -module -avoid-version \
- $(top_builddir)/xcore/libxcam_core.la \
- $(PTHREAD_LDFLAGS) \
+ -module -avoid-version \
$(NULL)
libxcam_3a_aiq_la_LIBTOOLFLAGS = --tag=disable-static
diff --git a/plugins/3a/aiq/aiq_wrapper.cpp b/plugins/3a/aiq/aiq_wrapper.cpp
index e6feb20..c09d9df 100644
--- a/plugins/3a/aiq/aiq_wrapper.cpp
+++ b/plugins/3a/aiq/aiq_wrapper.cpp
@@ -24,7 +24,7 @@
#include "x3a_statistics_queue.h"
#include "aiq3a_utils.h"
#include "x3a_result_factory.h"
-#include "x3a_analyze_tuner.h"
+#include "iq/x3a_analyze_tuner.h"
#define DEFAULT_AIQ_CPF_FILE "/etc/atomisp/imx185.cpf"
@@ -112,22 +112,22 @@ XCam3AAiqContext::setup_stats_pool (uint32_t bit_depth)
VideoBufferInfo info;
info.init (XCAM_PIX_FMT_SGRBG16, _video_width, _video_height);
- _stats_pool = new X3aStatisticsQueue;
- XCAM_ASSERT (_stats_pool.ptr ());
+ SmartPtr<X3aStatisticsQueue> pool = new X3aStatisticsQueue;
+ XCAM_ASSERT (pool.ptr ());
- _stats_pool->set_bit_depth (bit_depth);
+ pool->set_bit_depth (bit_depth);
XCAM_FAIL_RETURN (
WARNING,
- _stats_pool->set_video_info (info),
+ pool->set_video_info (info),
false,
"3a stats set video info failed");
-
- if (!_stats_pool->reserve (6)) {
+ if (!pool->reserve (6)) {
XCAM_LOG_WARNING ("init_3a_stats_pool failed to reserve stats buffer.");
return false;
}
+ _stats_pool = pool;
return true;
}
diff --git a/plugins/3a/hybrid/Makefile.am b/plugins/3a/hybrid/Makefile.am
index df23f61..e09aa57 100644
--- a/plugins/3a/hybrid/Makefile.am
+++ b/plugins/3a/hybrid/Makefile.am
@@ -1,30 +1,31 @@
plugin_LTLIBRARIES = libxcam_3a_hybrid.la
-XCAMSRC_CXXFLAGS = $(XCAM_CXXFLAGS)
-XCAMSRC_LIBS = \
+XCAM_HYBRID_CXXFLAGS = \
+ $(XCAM_CXXFLAGS) \
+ -I$(top_srcdir)/xcore \
+ -I$(top_srcdir)/plugins/3a/hybrid \
+ $(NULL)
+
+XCAM_HYBRID_LIBS = \
+ $(top_builddir)/xcore/libxcam_core.la \
$(NULL)
plugindir="$(libdir)/xcam/plugins/3a"
libxcam_3a_hybrid_la_SOURCES = \
- sample.cpp \
+ sample.cpp \
$(NULL)
libxcam_3a_hybrid_la_CXXFLAGS = \
- $(GST_CFLAGS) $(XCAMSRC_CXXFLAGS) \
- -I$(top_srcdir)/xcore \
- -I$(top_srcdir)/plugins/3a/hybrid \
+ $(XCAM_HYBRID_CXXFLAGS) \
$(NULL)
libxcam_3a_hybrid_la_LIBADD = \
- $(XCAMSRC_LIBS) \
- $(top_builddir)/xcore/libxcam_core.la \
+ $(XCAM_HYBRID_LIBS) \
$(NULL)
libxcam_3a_hybrid_la_LDFLAGS = \
- -module -avoid-version \
- $(top_builddir)/xcore/libxcam_core.la \
- $(PTHREAD_LDFLAGS) \
+ -module -avoid-version \
$(NULL)
libxcam_3a_hybrid_la_LIBTOOLFLAGS = --tag=disable-static
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index e3e20f4..f46513e 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -1,13 +1,9 @@
if ENABLE_3ALIB
X3ALIB_DIR = 3a
-else
-X3ALIB_DIR =
endif
if ENABLE_SMART_LIB
SMARTLIB_DIR = smart
-else
-SMARTLIB_DIR =
endif
SUBDIRS = $(X3ALIB_DIR) $(SMARTLIB_DIR)
diff --git a/plugins/smart/Makefile.am b/plugins/smart/Makefile.am
index 49cf033..ef1348d 100644
--- a/plugins/smart/Makefile.am
+++ b/plugins/smart/Makefile.am
@@ -1,13 +1,11 @@
-
if ENABLE_DVS
if HAVE_LIBCL
DVS_DIR = dvs
-else
-DVS_DIR =
endif
-else
-DVS_DIR =
endif
-SUBDIRS = $(DVS_DIR) sample
+if ENABLE_IA_AIQ
+SAMPLE_DIR = sample
+endif
+SUBDIRS = $(DVS_DIR) $(SAMPLE_DIR) \ No newline at end of file
diff --git a/plugins/smart/dvs/Makefile.am b/plugins/smart/dvs/Makefile.am
index 2675621..7b72a89 100644
--- a/plugins/smart/dvs/Makefile.am
+++ b/plugins/smart/dvs/Makefile.am
@@ -2,46 +2,41 @@ SUBDIRS = libdvs
noinst_LTLIBRARIES = libxcam_plugin_dvs.la
-XCAM_PLUGIN_DVS_CXXFLAGS = $(XCAM_CXXFLAGS) \
- -I$(top_srcdir)/xcore \
- -I$(top_srcdir)/modules \
- -I$(top_srcdir)/plugins/smart/dvs/libdvs \
- $(NULL)
-
-if HAVE_LIBDRM
-XCAM_PLUGIN_DVS_CXXFLAGS += $(LIBDRM_CFLAGS)
-endif
+XCAM_PLUGIN_DVS_CXXFLAGS = \
+ $(XCAM_CXXFLAGS) \
+ -I$(top_srcdir)/xcore \
+ -I$(top_srcdir)/modules \
+ -I$(top_srcdir)/plugins/smart/dvs/libdvs \
+ $(NULL)
-XCAM_PLUGIN_DVS_LIBS = \
- $(top_builddir)/plugins/smart/dvs/libdvs/libxcam_dvs.a \
- $(NULL)
+XCAM_PLUGIN_DVS_LIBS = \
+ $(OPENCV_LIBS) \
+ $(top_builddir)/xcore/libxcam_core.la \
+ $(top_builddir)/modules/ocl/libxcam_ocl.la \
+ $(top_builddir)/plugins/smart/dvs/libdvs/libxcam_dvs.a \
+ $(NULL)
if HAVE_LIBDRM
+XCAM_PLUGIN_DVS_CXXFLAGS += $(LIBDRM_CFLAGS)
XCAM_PLUGIN_DVS_LIBS += $(LIBDRM_LIBS)
endif
plugindir="$(libdir)/xcam/plugins/smart"
-libxcam_plugin_dvs_la_SOURCES = \
- xcam_plugin_dvs.cpp \
- $(NULL)
+libxcam_plugin_dvs_la_SOURCES = \
+ xcam_plugin_dvs.cpp \
+ $(NULL)
-libxcam_plugin_dvs_la_CXXFLAGS = \
- $(GST_CFLAGS) $(XCAM_PLUGIN_DVS_CXXFLAGS) \
- $(NULL)
+libxcam_plugin_dvs_la_CXXFLAGS = \
+ $(XCAM_PLUGIN_DVS_CXXFLAGS) \
+ $(NULL)
-libxcam_plugin_dvs_la_LIBADD = \
- $(XCAM_PLUGIN_DVS_LIBS) \
- $(top_builddir)/modules/ocl/libxcam_ocl.la \
- $(top_builddir)/xcore/libxcam_core.la \
- $(OPENCV_LIBS) \
+libxcam_plugin_dvs_la_LIBADD = \
+ $(XCAM_PLUGIN_DVS_LIBS) \
$(NULL)
-libxcam_plugin_dvs_la_LDFLAGS = \
- -module -avoid-version \
- $(top_builddir)/xcore/libxcam_core.la \
- $(PTHREAD_LDFLAGS) \
- $(OPENCV_LIBS) \
+libxcam_plugin_dvs_la_LDFLAGS = \
+ -module -avoid-version \
$(NULL)
libxcam_plugin_dvs_la_LIBTOOLFLAGS = --tag=disable-static
diff --git a/plugins/smart/dvs/libdvs/Makefile.am b/plugins/smart/dvs/libdvs/Makefile.am
index 6fba743..8ffcb8c 100644
--- a/plugins/smart/dvs/libdvs/Makefile.am
+++ b/plugins/smart/dvs/libdvs/Makefile.am
@@ -1,45 +1,32 @@
-noinst_LIBRARIES = \
- libxcam_dvs.a \
- $(NULL)
-
-XCAM_DVS_LIB_CXXFLAGS = \
- $(XCAM_CXXFLAGS) \
- $(OPENCV_CFLAGS) \
- $(NULL)
-
-XCAM_DVS_LIBS = \
- $(OPENCV_LIBS) \
- $(NULL)
+noinst_LIBRARIES = libxcam_dvs.a
libxcam_dvs_a_SOURCES = \
- libdvs.cpp \
- stabilizer.cpp \
- $(NULL)
-
-libxcam_dvs_a_CXXFLAGS = \
- $(GST_CFLAGS) $(XCAM_DVS_LIB_CXXFLAGS) \
- -I$(top_srcdir)/xcore \
- $(NULL)
+ libdvs.cpp \
+ stabilizer.cpp \
+ $(NULL)
-libxcam_dvs_a_LIBADD = \
- $(top_builddir)/xcore/libxcam_core.la \
+libxcam_dvs_a_CXXFLAGS = \
+ $(XCAM_CXXFLAGS) \
+ $(OPENCV_CFLAGS) \
+ -I$(top_srcdir)/xcore \
$(NULL)
-noinst_PROGRAMS = \
- test_image_stabilization \
+libxcam_dvs_a_LIBADD = \
+ $(top_builddir)/xcore/libxcam_core.la \
$(NULL)
+noinst_PROGRAMS = test_image_stabilization
+
test_image_stabilization_SOURCES = \
test-image-stabilization.cpp \
$(NULL)
test_image_stabilization_CXXFLAGS = \
- $(XCAM_CXXFLAGS) \
+ $(XCAM_CXXFLAGS) \
-I$(top_srcdir)/xcore \
$(NULL)
test_image_stabilization_LDADD = \
- libxcam_dvs.a \
+ libxcam_dvs.a \
$(OPENCV_LIBS) \
$(NULL)
-
diff --git a/plugins/smart/dvs/libdvs/stabilizer.cpp b/plugins/smart/dvs/libdvs/stabilizer.cpp
index 1dd4f66..ba660f9 100644
--- a/plugins/smart/dvs/libdvs/stabilizer.cpp
+++ b/plugins/smart/dvs/libdvs/stabilizer.cpp
@@ -377,13 +377,23 @@ VideoStabilizer::setFrameSize(Size frameSize)
Mat
VideoStabilizer::nextFrame()
{
+ Mat frame;
+
if (isTwoPass_) {
Ptr<TwoPassVideoStabilizer> stab = stabilizer_.dynamicCast<TwoPassVideoStabilizer>();
- return stab->nextFrame();
+ if(!stab.empty())
+ frame = stab->nextFrame();
+ else
+ CV_Error (Error::StsNullPtr, "VideoStabilizer: cast stabilizer failed");
} else {
Ptr<OnePassVideoStabilizer> stab = stabilizer_.dynamicCast<OnePassVideoStabilizer>();
- return stab->nextFrame();
+ if(!stab.empty())
+ frame = stab->nextFrame();
+ else
+ CV_Error (Error::StsNullPtr, "VideoStabilizer: cast stabilizer failed");
}
+
+ return frame;
}
Mat
@@ -393,10 +403,16 @@ VideoStabilizer::nextStabilizedMotion(DvsData* frame, int& stablizedPos)
if (isTwoPass_) {
Ptr<TwoPassVideoStabilizer> stab = stabilizer_.dynamicCast<TwoPassVideoStabilizer>();
- HMatrix = stab->nextStabilizedMotion(frame, stablizedPos);
+ if(!stab.empty())
+ HMatrix = stab->nextStabilizedMotion(frame, stablizedPos);
+ else
+ CV_Error (Error::StsNullPtr, "VideoStabilizer: cast stabilizer failed");
} else {
Ptr<OnePassVideoStabilizer> stab = stabilizer_.dynamicCast<OnePassVideoStabilizer>();
- HMatrix = stab->nextStabilizedMotion(frame, stablizedPos);
+ if(!stab.empty())
+ HMatrix = stab->nextStabilizedMotion(frame, stablizedPos);
+ else
+ CV_Error (Error::StsNullPtr, "VideoStabilizer: cast stabilizer failed");
}
return HMatrix;
diff --git a/plugins/smart/dvs/libdvs/test-image-stabilization.cpp b/plugins/smart/dvs/libdvs/test-image-stabilization.cpp
index 944ef12..c2549e5 100644
--- a/plugins/smart/dvs/libdvs/test-image-stabilization.cpp
+++ b/plugins/smart/dvs/libdvs/test-image-stabilization.cpp
@@ -86,7 +86,7 @@ int main(int argc, char *argv[])
break;
case 'e':
usage (argv[0]);
- return -1;
+ return 0;
default:
printf ("getopt_long return unknown value:%c \n", opt);
usage (argv[0]);
diff --git a/plugins/smart/dvs/xcam_plugin_dvs.cpp b/plugins/smart/dvs/xcam_plugin_dvs.cpp
index d8e2365..c6f154a 100644
--- a/plugins/smart/dvs/xcam_plugin_dvs.cpp
+++ b/plugins/smart/dvs/xcam_plugin_dvs.cpp
@@ -136,7 +136,6 @@ XCamReturn dvs_analyze(XCamSmartAnalysisContext *context, XCamVideoBuffer *buffe
DvsBuffer* dvs_buf = new DvsBuffer(buffer, frame);
//set default config
DvsConfig config;
- memset(&config, 0, sizeof(DvsConfig));
config.use_ocl = true;
config.frame_width = buffer->info.width;
config.frame_height = buffer->info.height;
@@ -158,6 +157,14 @@ XCamReturn dvs_analyze(XCamSmartAnalysisContext *context, XCamVideoBuffer *buffe
XCAM_LOG_WARNING ("dvs_analyze not ready! ");
} else {
XCamDVSResult *dvs_result = (XCamDVSResult *)malloc(sizeof(XCamDVSResult));
+ if (!dvs_result) {
+ XCAM_LOG_ERROR ("dvs_result: malloc failed!");
+ results[0] = NULL;
+ *res_count = 0;
+
+ return XCAM_RETURN_ERROR_MEM;
+ }
+
memset(dvs_result, 0, sizeof(XCamDVSResult));
dvs_result->head.type = XCAM_3A_RESULT_DVS;
diff --git a/plugins/smart/sample/Makefile.am b/plugins/smart/sample/Makefile.am
index 407d2dd3..2dc4b51 100644
--- a/plugins/smart/sample/Makefile.am
+++ b/plugins/smart/sample/Makefile.am
@@ -1,46 +1,38 @@
-noinst_LTLIBRARIES = \
- $(NULL)
+noinst_LTLIBRARIES = libxcam_sample_smart.la
-if ENABLE_IA_AIQ
-noinst_LTLIBRARIES += \
- libxcam_sample_smart.la \
+XCAM_SAMPLE_CXXFLAGS = \
+ $(XCAM_CXXFLAGS) \
+ -I$(top_srcdir)/xcore \
+ -I$(top_srcdir)/modules/isp \
+ -I$(top_srcdir)/plugins/smart \
$(NULL)
-endif
-XCAMSMART_CXXFLAGS = $(XCAM_CXXFLAGS)
-XCAMSMART_LIBS = \
+XCAM_SAMPLE_LIBS = \
+ $(top_builddir)/xcore/libxcam_core.la \
$(NULL)
if USE_LOCAL_ATOMISP
-XCAMSMART_CXXFLAGS += \
- -I$(top_srcdir)/ext/atomisp \
+XCAM_SAMPLE_CXXFLAGS += \
+ -I$(top_srcdir)/ext/atomisp \
$(NULL)
endif
plugindir="$(libdir)/xcam/plugins/smart"
-if ENABLE_IA_AIQ
libxcam_sample_smart_la_SOURCES = \
- sample_smart_analysis.cpp \
+ sample_smart_analysis.cpp \
$(NULL)
libxcam_sample_smart_la_CXXFLAGS = \
- $(GST_CFLAGS) $(XCAMSMART_CXXFLAGS) \
- -I$(top_srcdir)/xcore \
- -I$(top_srcdir)/modules/isp \
- -I$(top_srcdir)/plugins/smart \
+ $(XCAM_SAMPLE_CXXFLAGS) \
$(NULL)
libxcam_sample_smart_la_LIBADD = \
- $(XCAMSMART_LIBS) \
- $(top_builddir)/xcore/libxcam_core.la \
+ $(XCAM_SAMPLE_LIBS) \
$(NULL)
libxcam_sample_smart_la_LDFLAGS = \
- -module -avoid-version \
- $(top_builddir)/xcore/libxcam_core.la \
- $(PTHREAD_LDFLAGS) \
+ -module -avoid-version \
$(NULL)
-endif
libxcam_sample_smart_la_LIBTOOLFLAGS = --tag=disable-static
diff --git a/plugins/smart/sample/sample_smart_analysis.cpp b/plugins/smart/sample/sample_smart_analysis.cpp
index a144946..defcca4 100644
--- a/plugins/smart/sample/sample_smart_analysis.cpp
+++ b/plugins/smart/sample/sample_smart_analysis.cpp
@@ -228,10 +228,11 @@ SampleHandler::update_params (const XCamSmartAnalysisParam *params)
XCamReturn
SampleHandler::analyze (XCamVideoBuffer *buffer)
{
- XCAM_LOG_DEBUG ("Smart SampleHandler::analyze on ts:" XCAM_TIMESTAMP_FORMAT, XCAM_TIMESTAMP_ARGS (buffer->timestamp));
if (NULL == buffer) {
return XCAM_RETURN_ERROR_PARAM;
}
+ XCAM_LOG_DEBUG ("Smart SampleHandler::analyze on ts:" XCAM_TIMESTAMP_FORMAT, XCAM_TIMESTAMP_ARGS (buffer->timestamp));
+
XCamReturn ret = XCAM_RETURN_NO_ERROR;
XCAM_LOG_DEBUG ("format(0x%x), color_bits(%d)", buffer->info.format, buffer->info.color_bits);
diff --git a/shaders/Makefile.am b/shaders/Makefile.am
new file mode 100644
index 0000000..4e540d5
--- /dev/null
+++ b/shaders/Makefile.am
@@ -0,0 +1,9 @@
+if HAVE_LIBCL
+CLX_DIR = clx
+endif
+
+if HAVE_GLES
+GLSLX_DIR = glslx
+endif
+
+SUBDIRS = $(CLX_DIR) $(GLSLX_DIR)
diff --git a/cl_kernel/kernel_3d_denoise.cl b/shaders/cl/kernel_3d_denoise.cl
index c94c1d7..c94c1d7 100644
--- a/cl_kernel/kernel_3d_denoise.cl
+++ b/shaders/cl/kernel_3d_denoise.cl
diff --git a/cl_kernel/kernel_3d_denoise_slm.cl b/shaders/cl/kernel_3d_denoise_slm.cl
index 55eef62..55eef62 100644
--- a/cl_kernel/kernel_3d_denoise_slm.cl
+++ b/shaders/cl/kernel_3d_denoise_slm.cl
diff --git a/cl_kernel/kernel_bayer_basic.cl b/shaders/cl/kernel_bayer_basic.cl
index e6c19dd..e6c19dd 100644
--- a/cl_kernel/kernel_bayer_basic.cl
+++ b/shaders/cl/kernel_bayer_basic.cl
diff --git a/cl_kernel/kernel_bayer_pipe.cl b/shaders/cl/kernel_bayer_pipe.cl
index 91dd362..91dd362 100644
--- a/cl_kernel/kernel_bayer_pipe.cl
+++ b/shaders/cl/kernel_bayer_pipe.cl
diff --git a/cl_kernel/kernel_bi_filter.cl b/shaders/cl/kernel_bi_filter.cl
index 4023c12..4023c12 100644
--- a/cl_kernel/kernel_bi_filter.cl
+++ b/shaders/cl/kernel_bi_filter.cl
diff --git a/cl_kernel/kernel_csc.cl b/shaders/cl/kernel_csc.cl
index 1a6739a..1a6739a 100644
--- a/cl_kernel/kernel_csc.cl
+++ b/shaders/cl/kernel_csc.cl
diff --git a/cl_kernel/kernel_defog_dcp.cl b/shaders/cl/kernel_defog_dcp.cl
index 3903da6..3903da6 100644
--- a/cl_kernel/kernel_defog_dcp.cl
+++ b/shaders/cl/kernel_defog_dcp.cl
diff --git a/cl_kernel/kernel_demo.cl b/shaders/cl/kernel_demo.cl
index 161e6e6..161e6e6 100644
--- a/cl_kernel/kernel_demo.cl
+++ b/shaders/cl/kernel_demo.cl
diff --git a/cl_kernel/kernel_fisheye.cl b/shaders/cl/kernel_fisheye.cl
index 3b3f5b5..3b3f5b5 100644
--- a/cl_kernel/kernel_fisheye.cl
+++ b/shaders/cl/kernel_fisheye.cl
diff --git a/cl_kernel/kernel_gauss.cl b/shaders/cl/kernel_gauss.cl
index 4e66d48..4e66d48 100644
--- a/cl_kernel/kernel_gauss.cl
+++ b/shaders/cl/kernel_gauss.cl
diff --git a/cl_kernel/kernel_gauss_lap_pyramid.cl b/shaders/cl/kernel_gauss_lap_pyramid.cl
index b983b57..b983b57 100644
--- a/cl_kernel/kernel_gauss_lap_pyramid.cl
+++ b/shaders/cl/kernel_gauss_lap_pyramid.cl
diff --git a/cl_kernel/kernel_geo_map.cl b/shaders/cl/kernel_geo_map.cl
index b696a40..40b191a 100644
--- a/cl_kernel/kernel_geo_map.cl
+++ b/shaders/cl/kernel_geo_map.cl
@@ -14,6 +14,10 @@
#define ENABLE_LSC 0
#endif
+#ifndef ENABLE_SCALE
+#define ENABLE_SCALE 0
+#endif
+
#define CONST_DATA_Y 0.0f
#define CONST_DATA_UV (float2)(0.5f, 0.5f)
@@ -66,6 +70,10 @@ __kernel void
kernel_geo_map (
__read_only image2d_t input_y, __read_only image2d_t input_uv,
__read_only image2d_t geo_table, float2 table_scale_size,
+#if ENABLE_SCALE
+ float2 left_scale_factor, float2 right_scale_factor,
+ float stable_y_start,
+#endif
#if ENABLE_LSC
__read_only image2d_t lsc_table, float2 gray_threshold,
#endif
@@ -79,11 +87,33 @@ kernel_geo_map (
bool out_of_bound[8];
float2 input_pos[8];
// map to [-0.5, 0.5)
- float2 table_scale_step = 1.0f / table_scale_size;
+ float2 scale = 1.0f;
+
+#if ENABLE_SCALE
+ float a, b, c;
+ float y_m = stable_y_start * 0.5f;
+
+ float2 scale_factor = (g_x * PIXEL_RES_STEP_X < out_size.x / 2.0f) ? left_scale_factor : right_scale_factor;
+ a = (1 - scale_factor.x) / ((stable_y_start - y_m) * (stable_y_start - y_m));
+ b = -2 * a * y_m;
+ c = 1 - a * stable_y_start * stable_y_start - b * stable_y_start;
+
+ scale.y = (g_y >= stable_y_start) ? 1.0f : ((right_scale_factor.y - left_scale_factor.y) /
+ (out_size.x - PIXEL_RES_STEP_X) * g_x * PIXEL_RES_STEP_X + left_scale_factor.y);
+ float y_scale = ((float)g_y - stable_y_start) * scale.y + stable_y_start;
+ scale.x = (y_scale >= stable_y_start) ? 1.0f : ((y_scale < y_m) ? scale_factor.x : (a * y_scale * y_scale + b * y_scale + c));
+#endif
+
+ float2 table_scale_step = 1.0f / (table_scale_size * scale);
float2 out_map_pos;
sampler_t sampler = CLK_NORMALIZED_COORDS_TRUE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_LINEAR;
+#if ENABLE_SCALE
+ out_map_pos.x = (g_x * PIXEL_RES_STEP_X - out_size.x / 2.0f) * table_scale_step.x + 0.5f;
+ out_map_pos.y = ((float)g_y - stable_y_start) * table_scale_step.y + stable_y_start / out_size.y;
+#else
out_map_pos = (convert_float2((int2)(g_x * PIXEL_RES_STEP_X, g_y)) - out_size / 2.0f) * table_scale_step + 0.5f;
+#endif
get_geo_mapped_y (input_y, geo_table, out_map_pos, table_scale_step.x, out_of_bound, input_pos, &output_data);
@@ -100,7 +130,21 @@ kernel_geo_map (
output_data.s67 = out_of_bound[6] ? CONST_DATA_UV : read_imagef (input_uv, sampler, input_pos[6]).xy;
write_imageui (output_uv, (int2)(g_x, g_y_uv), convert_uint4(as_ushort4(convert_uchar8(output_data * 255.0f))));
+#if ENABLE_SCALE
+ scale.y = (g_y + 1 >= stable_y_start) ? 1.0f : ((right_scale_factor.y - left_scale_factor.y) /
+ (out_size.x - PIXEL_RES_STEP_X) * g_x * PIXEL_RES_STEP_X + left_scale_factor.y);
+ y_scale = (g_y + 1 - stable_y_start) * scale.y + stable_y_start;
+ scale.x = (y_scale >= stable_y_start) ? 1.0f :
+ ((y_scale < y_m) ? scale_factor.x : (a * y_scale * y_scale + b * y_scale + c));
+
+ table_scale_step = 1.0f / (table_scale_size * scale);
+
+ out_map_pos.x = (g_x * PIXEL_RES_STEP_X - out_size.x / 2.0f) * table_scale_step.x + 0.5f;
+ out_map_pos.y = ((float)g_y + 1 - stable_y_start) * table_scale_step.y + stable_y_start / out_size.y;
+#else
out_map_pos.y += table_scale_step.y;
+#endif
+
get_geo_mapped_y (input_y, geo_table, out_map_pos, table_scale_step.x, out_of_bound, input_pos, &output_data);
#if ENABLE_LSC
diff --git a/cl_kernel/kernel_image_scaler.cl b/shaders/cl/kernel_image_scaler.cl
index c6c1ca3..c6c1ca3 100644
--- a/cl_kernel/kernel_image_scaler.cl
+++ b/shaders/cl/kernel_image_scaler.cl
diff --git a/cl_kernel/kernel_image_warp.cl b/shaders/cl/kernel_image_warp.cl
index 22acd39..22acd39 100644
--- a/cl_kernel/kernel_image_warp.cl
+++ b/shaders/cl/kernel_image_warp.cl
diff --git a/cl_kernel/kernel_min_filter.cl b/shaders/cl/kernel_min_filter.cl
index 6a30f20..6a30f20 100644
--- a/cl_kernel/kernel_min_filter.cl
+++ b/shaders/cl/kernel_min_filter.cl
diff --git a/cl_kernel/kernel_newtonemapping.cl b/shaders/cl/kernel_newtonemapping.cl
index c66bab4..c66bab4 100755
--- a/cl_kernel/kernel_newtonemapping.cl
+++ b/shaders/cl/kernel_newtonemapping.cl
diff --git a/cl_kernel/kernel_retinex.cl b/shaders/cl/kernel_retinex.cl
index 9df3a58..9df3a58 100644
--- a/cl_kernel/kernel_retinex.cl
+++ b/shaders/cl/kernel_retinex.cl
diff --git a/cl_kernel/kernel_rgb_pipe.cl b/shaders/cl/kernel_rgb_pipe.cl
index 277d9d4..277d9d4 100644
--- a/cl_kernel/kernel_rgb_pipe.cl
+++ b/shaders/cl/kernel_rgb_pipe.cl
diff --git a/cl_kernel/kernel_tnr.cl b/shaders/cl/kernel_tnr.cl
index e5c1c36..e5c1c36 100644
--- a/cl_kernel/kernel_tnr.cl
+++ b/shaders/cl/kernel_tnr.cl
diff --git a/cl_kernel/kernel_tonemapping.cl b/shaders/cl/kernel_tonemapping.cl
index 2f239ca..2f239ca 100644
--- a/cl_kernel/kernel_tonemapping.cl
+++ b/shaders/cl/kernel_tonemapping.cl
diff --git a/cl_kernel/kernel_wavelet_coeff.cl b/shaders/cl/kernel_wavelet_coeff.cl
index 51c3b5f..51c3b5f 100644
--- a/cl_kernel/kernel_wavelet_coeff.cl
+++ b/shaders/cl/kernel_wavelet_coeff.cl
diff --git a/cl_kernel/kernel_wavelet_denoise.cl b/shaders/cl/kernel_wavelet_denoise.cl
index b0353a1..b0353a1 100644
--- a/cl_kernel/kernel_wavelet_denoise.cl
+++ b/shaders/cl/kernel_wavelet_denoise.cl
diff --git a/cl_kernel/kernel_wavelet_haar.cl b/shaders/cl/kernel_wavelet_haar.cl
index bdecd68..bdecd68 100644
--- a/cl_kernel/kernel_wavelet_haar.cl
+++ b/shaders/cl/kernel_wavelet_haar.cl
diff --git a/cl_kernel/kernel_wire_frame.cl b/shaders/cl/kernel_wire_frame.cl
index 5862dd5..5862dd5 100644
--- a/cl_kernel/kernel_wire_frame.cl
+++ b/shaders/cl/kernel_wire_frame.cl
diff --git a/cl_kernel/kernel_yuv_pipe.cl b/shaders/cl/kernel_yuv_pipe.cl
index 681fa62..681fa62 100644
--- a/cl_kernel/kernel_yuv_pipe.cl
+++ b/shaders/cl/kernel_yuv_pipe.cl
diff --git a/clx_kernel/.gitignore b/shaders/clx/.gitignore
index 74cd98e..74cd98e 100644
--- a/clx_kernel/.gitignore
+++ b/shaders/clx/.gitignore
diff --git a/shaders/clx/Makefile.am b/shaders/clx/Makefile.am
new file mode 100644
index 0000000..b122b1b
--- /dev/null
+++ b/shaders/clx/Makefile.am
@@ -0,0 +1,39 @@
+clx_sources = \
+ kernel_csc.clx \
+ kernel_demo.clx \
+ kernel_defog_dcp.clx \
+ kernel_min_filter.clx \
+ kernel_bi_filter.clx \
+ kernel_tnr.clx \
+ kernel_bayer_pipe.clx \
+ kernel_bayer_basic.clx \
+ kernel_fisheye.clx \
+ kernel_rgb_pipe.clx \
+ kernel_yuv_pipe.clx \
+ kernel_tonemapping.clx \
+ kernel_newtonemapping.clx \
+ kernel_image_scaler.clx \
+ kernel_retinex.clx \
+ kernel_gauss.clx \
+ kernel_gauss_lap_pyramid.clx \
+ kernel_geo_map.clx \
+ kernel_wavelet_denoise.clx \
+ kernel_wavelet_haar.clx \
+ kernel_wavelet_coeff.clx \
+ kernel_wire_frame.clx \
+ kernel_3d_denoise.clx \
+ kernel_3d_denoise_slm.clx \
+ kernel_image_warp.clx \
+ $(NULL)
+
+add_quotation_marks_sh = \
+ $(top_srcdir)/tools/add-quotation-marks.sh
+
+cl_dir = $(top_srcdir)/shaders/cl
+
+all-local: $(clx_sources)
+
+$(clx_sources): %.clx: $(cl_dir)/%.cl
+ @$(add_quotation_marks_sh) $< $@
+
+CLEANFILES = $(clx_sources)
diff --git a/shaders/glsl/shader_blend_pyr.comp.sl b/shaders/glsl/shader_blend_pyr.comp.sl
new file mode 100644
index 0000000..dd1fb0f
--- /dev/null
+++ b/shaders/glsl/shader_blend_pyr.comp.sl
@@ -0,0 +1,91 @@
+#version 310 es
+
+layout (local_size_x = 8, local_size_y = 8) in;
+
+layout (binding = 0) readonly buffer In0BufY {
+ uvec2 data[];
+} in0_buf_y;
+
+layout (binding = 1) readonly buffer In0BufUV {
+ uvec2 data[];
+} in0_buf_uv;
+
+layout (binding = 2) readonly buffer In1BufY {
+ uvec2 data[];
+} in1_buf_y;
+
+layout (binding = 3) readonly buffer In1BufUV {
+ uvec2 data[];
+} in1_buf_uv;
+
+layout (binding = 4) writeonly buffer OutBufY {
+ uvec2 data[];
+} out_buf_y;
+
+layout (binding = 5) writeonly buffer OutBufUV {
+ uvec2 data[];
+} out_buf_uv;
+
+layout (binding = 6) readonly buffer MaskBuf {
+ uvec2 data[];
+} mask_buf;
+
+uniform uint in_img_width;
+
+void main ()
+{
+ uvec2 g_id = gl_GlobalInvocationID.xy;
+ g_id.x = clamp (g_id.x, 0u, in_img_width - 1u);
+
+ uvec2 mask = mask_buf.data[g_id.x];
+ vec4 mask0 = unpackUnorm4x8 (mask.x);
+ vec4 mask1 = unpackUnorm4x8 (mask.y);
+
+ uint y_idx = g_id.y * 2u * in_img_width + g_id.x;
+ uvec2 in0_y = in0_buf_y.data[y_idx];
+ vec4 in0_y0 = unpackUnorm4x8 (in0_y.x);
+ vec4 in0_y1 = unpackUnorm4x8 (in0_y.y);
+
+ uvec2 in1_y = in1_buf_y.data[y_idx];
+ vec4 in1_y0 = unpackUnorm4x8 (in1_y.x);
+ vec4 in1_y1 = unpackUnorm4x8 (in1_y.y);
+
+ vec4 out_y0 = (in0_y0 - in1_y0) * mask0 + in1_y0;
+ vec4 out_y1 = (in0_y1 - in1_y1) * mask1 + in1_y1;
+ out_y0 = clamp (out_y0, 0.0f, 1.0f);
+ out_y1 = clamp (out_y1, 0.0f, 1.0f);
+ out_buf_y.data[y_idx] = uvec2 (packUnorm4x8 (out_y0), packUnorm4x8 (out_y1));
+
+ y_idx += in_img_width;
+ in0_y = in0_buf_y.data[y_idx];
+ in0_y0 = unpackUnorm4x8 (in0_y.x);
+ in0_y1 = unpackUnorm4x8 (in0_y.y);
+
+ in1_y = in1_buf_y.data[y_idx];
+ in1_y0 = unpackUnorm4x8 (in1_y.x);
+ in1_y1 = unpackUnorm4x8 (in1_y.y);
+
+ out_y0 = (in0_y0 - in1_y0) * mask0 + in1_y0;
+ out_y1 = (in0_y1 - in1_y1) * mask1 + in1_y1;
+ out_y0 = clamp (out_y0, 0.0f, 1.0f);
+ out_y1 = clamp (out_y1, 0.0f, 1.0f);
+ out_buf_y.data[y_idx] = uvec2 (packUnorm4x8 (out_y0), packUnorm4x8 (out_y1));
+
+ uint uv_idx = g_id.y * in_img_width + g_id.x;
+ uvec2 in0_uv = in0_buf_uv.data[uv_idx];
+ vec4 in0_uv0 = unpackUnorm4x8 (in0_uv.x);
+ vec4 in0_uv1 = unpackUnorm4x8 (in0_uv.y);
+
+ uvec2 in1_uv = in1_buf_uv.data[uv_idx];
+ vec4 in1_uv0 = unpackUnorm4x8 (in1_uv.x);
+ vec4 in1_uv1 = unpackUnorm4x8 (in1_uv.y);
+
+ mask0.yw = mask0.xz;
+ mask1.yw = mask1.xz;
+ vec4 out_uv0 = (in0_uv0 - in1_uv0) * mask0 + in1_uv0;
+ vec4 out_uv1 = (in0_uv1 - in1_uv1) * mask1 + in1_uv1;
+
+ out_uv0 = clamp (out_uv0, 0.0f, 1.0f);
+ out_uv1 = clamp (out_uv1, 0.0f, 1.0f);
+ out_buf_uv.data[uv_idx] = uvec2 (packUnorm4x8 (out_uv0), packUnorm4x8 (out_uv1));
+}
diff --git a/shaders/glsl/shader_copy.comp.sl b/shaders/glsl/shader_copy.comp.sl
new file mode 100644
index 0000000..ced6c91
--- /dev/null
+++ b/shaders/glsl/shader_copy.comp.sl
@@ -0,0 +1,28 @@
+#version 310 es
+
+layout (local_size_x = 8, local_size_y = 8) in;
+
+layout (binding = 0) readonly buffer InBuf {
+ uvec4 data[];
+} in_buf;
+
+layout (binding = 1) writeonly buffer OutBuf {
+ uvec4 data[];
+} out_buf;
+
+uniform uint in_img_width;
+uniform uint in_x_offset;
+
+uniform uint out_img_width;
+uniform uint out_x_offset;
+
+uniform uint copy_width;
+
+void main ()
+{
+ uvec2 g_id = gl_GlobalInvocationID.xy;
+ g_id.x = min (g_id.x, copy_width - 1u);
+
+ out_buf.data[g_id.y * out_img_width + out_x_offset + g_id.x] =
+ in_buf.data[g_id.y * in_img_width + in_x_offset + g_id.x];
+}
diff --git a/shaders/glsl/shader_gauss_scale_pyr.comp.sl b/shaders/glsl/shader_gauss_scale_pyr.comp.sl
new file mode 100644
index 0000000..1fbdd8f
--- /dev/null
+++ b/shaders/glsl/shader_gauss_scale_pyr.comp.sl
@@ -0,0 +1,174 @@
+#version 310 es
+
+layout (local_size_x = 8, local_size_y = 8) in;
+
+layout (binding = 0) readonly buffer InBufY {
+ uint data[];
+} in_buf_y;
+
+layout (binding = 1) readonly buffer InBufUV {
+ uint data[];
+} in_buf_uv;
+
+layout (binding = 2) writeonly buffer OutBufY {
+ uint data[];
+} out_buf_y;
+
+layout (binding = 3) writeonly buffer OutBufUV {
+ uint data[];
+} out_buf_uv;
+
+uniform uint in_img_width;
+uniform uint in_img_height;
+uniform uint in_offset_x;
+
+uniform uint out_img_width;
+
+uniform uint merge_width;
+
+const float coeffs[5] = float[] (0.152f, 0.222f, 0.252f, 0.222f, 0.152f);
+
+#define unpack_unorm(buf, pixel, idx) \
+ { \
+ pixel[0] = unpackUnorm4x8 (buf.data[idx]); \
+ pixel[1] = unpackUnorm4x8 (buf.data[idx + 1u]); \
+ pixel[2] = unpackUnorm4x8 (buf.data[idx + 2u]); \
+ pixel[3] = unpackUnorm4x8 (buf.data[idx + 3u]); \
+ }
+
+#define multiply_coeff(sum, pixel, idx) \
+ { \
+ sum[0] += pixel[0] * coeffs[idx]; \
+ sum[1] += pixel[1] * coeffs[idx]; \
+ sum[2] += pixel[2] * coeffs[idx]; \
+ sum[3] += pixel[3] * coeffs[idx]; \
+ }
+
+void gauss_scale_y (uvec2 y_id);
+void gauss_scale_uv (uvec2 uv_id);
+
+void main ()
+{
+ uvec2 g_id = gl_GlobalInvocationID.xy;
+ g_id.x = clamp (g_id.x, 0u, merge_width - 1u);
+
+ uvec2 y_id = g_id * uvec2 (1u, 2u);
+ gauss_scale_y (y_id);
+
+ gauss_scale_uv (g_id);
+}
+
+void gauss_scale_y (uvec2 y_id)
+{
+ uvec2 in_id = y_id * 2u;
+ uvec2 gauss_start = in_id - uvec2 (1u, 2u);
+ gauss_start.y = clamp (gauss_start.y, 0u, in_img_height - 7u);
+
+ vec4 sum0[4] = vec4[] (vec4 (0.0f), vec4 (0.0f), vec4 (0.0f), vec4 (0.0f));
+ vec4 sum1[4] = vec4[] (vec4 (0.0f), vec4 (0.0f), vec4 (0.0f), vec4 (0.0f));
+
+ vec4 pixel_y[4];
+ uint in_idx = (in_id.y == 0u) ? (in_id.x - 1u) : (gauss_start.y * in_img_width + gauss_start.x);
+ in_idx += in_offset_x;
+ unpack_unorm (in_buf_y, pixel_y, in_idx);
+ multiply_coeff (sum0, pixel_y, 0u);
+
+ in_idx = (in_id.y == 0u) ? in_idx : (in_idx + in_img_width);
+ unpack_unorm (in_buf_y, pixel_y, in_idx);
+ multiply_coeff (sum0, pixel_y, 1u);
+
+ in_idx = (in_id.y == 0u) ? in_idx : (in_idx + in_img_width);
+ unpack_unorm (in_buf_y, pixel_y, in_idx);
+ multiply_coeff (sum0, pixel_y, 2u);
+ multiply_coeff (sum1, pixel_y, 0u);
+
+ in_idx += in_img_width;
+ unpack_unorm (in_buf_y, pixel_y, in_idx);
+ multiply_coeff (sum0, pixel_y, 3u);
+ multiply_coeff (sum1, pixel_y, 1u);
+
+ in_idx += in_img_width;
+ unpack_unorm (in_buf_y, pixel_y, in_idx);
+ multiply_coeff (sum0, pixel_y, 4u);
+ multiply_coeff (sum1, pixel_y, 2u);
+
+ in_idx += in_img_width;
+ unpack_unorm (in_buf_y, pixel_y, in_idx);
+ multiply_coeff (sum1, pixel_y, 3u);
+
+ in_idx += in_img_width;
+ unpack_unorm (in_buf_y, pixel_y, in_idx);
+ multiply_coeff (sum1, pixel_y, 4u);
+
+ sum0[0] = (in_id.x == 0u) ? vec4 (sum0[1].x) : sum0[0];
+ sum1[0] = (in_id.x == 0u) ? vec4 (sum1[1].x) : sum1[0];
+ sum0[3] = (in_id.x == merge_width - 2u) ? vec4 (sum0[2].w) : sum0[3];
+ sum1[3] = (in_id.x == merge_width - 2u) ? vec4 (sum1[2].w) : sum1[3];
+
+ vec4 out_data0 =
+ vec4 (sum0[0].z, sum0[1].x, sum0[1].z, sum0[2].x) * coeffs[0] +
+ vec4 (sum0[0].w, sum0[1].y, sum0[1].w, sum0[2].y) * coeffs[1] +
+ vec4 (sum0[1].x, sum0[1].z, sum0[2].x, sum0[2].z) * coeffs[2] +
+ vec4 (sum0[1].y, sum0[1].w, sum0[2].y, sum0[2].w) * coeffs[3] +
+ vec4 (sum0[1].z, sum0[2].x, sum0[2].z, sum0[3].x) * coeffs[4];
+
+ vec4 out_data1 =
+ vec4 (sum1[0].z, sum1[1].x, sum1[1].z, sum1[2].x) * coeffs[0] +
+ vec4 (sum1[0].w, sum1[1].y, sum1[1].w, sum1[2].y) * coeffs[1] +
+ vec4 (sum1[1].x, sum1[1].z, sum1[2].x, sum1[2].z) * coeffs[2] +
+ vec4 (sum1[1].y, sum1[1].w, sum1[2].y, sum1[2].w) * coeffs[3] +
+ vec4 (sum1[1].z, sum1[2].x, sum1[2].z, sum1[3].x) * coeffs[4];
+
+ out_data0 = clamp (out_data0, 0.0f, 1.0f);
+ out_data1 = clamp (out_data1, 0.0f, 1.0f);
+
+ y_id.x = clamp (y_id.x, 0u, out_img_width - 1u);
+ uint out_idx = y_id.y * out_img_width + y_id.x;
+ out_buf_y.data[out_idx] = packUnorm4x8 (out_data0);
+ out_buf_y.data[out_idx + out_img_width] = packUnorm4x8 (out_data1);
+}
+
+void gauss_scale_uv (uvec2 uv_id)
+{
+ uvec2 in_id = uv_id * 2u;
+ uvec2 gauss_start = in_id - uvec2 (1u, 2u);
+ gauss_start.y = clamp (gauss_start.y, 0u, in_img_height / 2u - 5u);
+
+ vec4 sum[4] = vec4[] (vec4 (0.0f), vec4 (0.0f), vec4 (0.0f), vec4 (0.0f));
+ uint in_idx = (in_id.y == 0u) ? (in_id.x - 1u) : (gauss_start.y * in_img_width + gauss_start.x);
+ in_idx += in_offset_x;
+
+ vec4 pixel_uv[4];
+ unpack_unorm (in_buf_uv, pixel_uv, in_idx);
+ multiply_coeff (sum, pixel_uv, 0u);
+
+ in_idx = (in_id.y == 0u) ? in_idx : (in_idx + in_img_width);
+ unpack_unorm (in_buf_uv, pixel_uv, in_idx);
+ multiply_coeff (sum, pixel_uv, 1u);
+
+ in_idx = (in_id.y == 0u) ? in_idx : (in_idx + in_img_width);
+ unpack_unorm (in_buf_uv, pixel_uv, in_idx);
+ multiply_coeff (sum, pixel_uv, 2u);
+
+ in_idx += in_img_width;
+ unpack_unorm (in_buf_uv, pixel_uv, in_idx);
+ multiply_coeff (sum, pixel_uv, 3u);
+
+ in_idx += in_img_width;
+ unpack_unorm (in_buf_uv, pixel_uv, in_idx);
+ multiply_coeff (sum, pixel_uv, 4u);
+
+ sum[0] = (in_id.x == 0u) ? vec4 (sum[1]) : sum[0];
+ sum[3] = (in_id.x == merge_width - 2u) ? vec4 (sum[2]) : sum[3];
+
+ vec4 out_data =
+ vec4 (sum[0].x, sum[0].y, sum[1].x, sum[1].y) * coeffs[0] +
+ vec4 (sum[0].z, sum[0].w, sum[1].z, sum[1].w) * coeffs[1] +
+ vec4 (sum[1].x, sum[1].y, sum[2].x, sum[2].y) * coeffs[2] +
+ vec4 (sum[1].z, sum[1].w, sum[2].z, sum[2].w) * coeffs[3] +
+ vec4 (sum[2].x, sum[2].y, sum[3].x, sum[3].y) * coeffs[4];
+
+ out_data = clamp (out_data, 0.0f, 1.0f);
+ uv_id.x = clamp (uv_id.x, 0u, out_img_width - 1u);
+ out_buf_uv.data[uv_id.y * out_img_width + uv_id.x] = packUnorm4x8 (out_data);
+}
diff --git a/shaders/glsl/shader_geomap.comp.sl b/shaders/glsl/shader_geomap.comp.sl
new file mode 100644
index 0000000..d2b5b70
--- /dev/null
+++ b/shaders/glsl/shader_geomap.comp.sl
@@ -0,0 +1,238 @@
+#version 310 es
+
+layout (local_size_x = 8, local_size_y = 8) in;
+
+layout (binding = 0) readonly buffer InBufY {
+ uint data[];
+} in_buf_y;
+
+layout (binding = 1) readonly buffer InBufUV {
+ uint data[];
+} in_buf_uv;
+
+layout (binding = 2) writeonly buffer OutBufY {
+ uint data[];
+} out_buf_y;
+
+layout (binding = 3) writeonly buffer OutBufUV {
+ uint data[];
+} out_buf_uv;
+
+layout (binding = 4) readonly buffer GeoMapTable {
+ vec2 data[];
+} lut;
+
+uniform uint in_img_width;
+uniform uint in_img_height;
+
+uniform uint out_img_width;
+uniform uint out_img_height;
+
+uniform uint lut_width;
+uniform uint lut_height;
+
+uniform vec4 lut_step;
+uniform vec2 lut_std_step;
+
+#define UNIT_SIZE 4u
+
+#define unpack_unorm_y(index) \
+ { \
+ vec4 value = unpackUnorm4x8 (in_buf_y.data[index00[index]]); \
+ out_y00[index] = value[x00_fract[index]]; \
+ value = unpackUnorm4x8 (in_buf_y.data[index01[index]]); \
+ out_y01[index] = value[x01_fract[index]]; \
+ value = unpackUnorm4x8 (in_buf_y.data[index10[index]]); \
+ out_y10[index] = value[x10_fract[index]]; \
+ value = unpackUnorm4x8 (in_buf_y.data[index11[index]]); \
+ out_y11[index] = value[x11_fract[index]]; \
+ }
+
+void geomap_y (vec4 lut_x, vec4 lut_y, out vec4 in_img_x, out vec4 in_img_y, out bvec4 out_bound, out uint out_data);
+void geomap_uv (vec2 in_uv_x, vec2 in_uv_y, bvec4 out_bound_uv, out uint out_data);
+
+void main ()
+{
+ uint g_x = gl_GlobalInvocationID.x;
+ uint g_y = gl_GlobalInvocationID.y * 2u;
+
+ vec2 cent = (vec2 (out_img_width, out_img_height) - 1.0f) / 2.0f;
+ vec2 step = g_x < uint (cent.x) ? lut_step.xy : lut_step.zw;
+
+ vec2 start = (vec2 (g_x, g_y) - cent) * step + cent * lut_std_step;
+ vec4 lut_x = start.x * float (UNIT_SIZE) + vec4 (0.0f, step.x, step.x * 2.0f, step.x * 3.0f);
+ vec4 lut_y = start.yyyy;
+ lut_x = clamp (lut_x, 0.0f, float (lut_width) - 1.0f);
+ lut_y = clamp (lut_y, 0.0f, float (lut_height) - 1.0f - step.y);
+
+ uint out_data;
+ vec4 in_img_x, in_img_y;
+ bvec4 out_bound;
+ geomap_y (lut_x, lut_y, in_img_x, in_img_y, out_bound, out_data);
+ out_buf_y.data[g_y * out_img_width + g_x] = out_data;
+
+ bvec4 out_bound_uv = out_bound.xxzz;
+ if (all (out_bound_uv)) {
+ out_data = packUnorm4x8 (vec4 (0.5f));
+ } else {
+ vec2 in_uv_x = in_img_x.xz;
+ vec2 in_uv_y = in_img_y.xz / 2.0f;
+ in_uv_y = clamp (in_uv_y, 0.0f, float (in_img_height / 2u - 1u));
+ geomap_uv (in_uv_x, in_uv_y, out_bound_uv, out_data);
+ }
+ out_buf_uv.data[g_y / 2u * out_img_width + g_x] = out_data;
+
+ lut_y += step.y;
+ geomap_y (lut_x, lut_y, in_img_x, in_img_y, out_bound, out_data);
+ out_buf_y.data[(g_y + 1u) * out_img_width + g_x] = out_data;
+}
+
+void geomap_y (vec4 lut_x, vec4 lut_y, out vec4 in_img_x, out vec4 in_img_y, out bvec4 out_bound, out uint out_data)
+{
+ uvec4 x00 = uvec4 (lut_x);
+ uvec4 y00 = uvec4 (lut_y);
+ uvec4 x01 = x00 + 1u;
+ uvec4 y01 = y00;
+ uvec4 x10 = x00;
+ uvec4 y10 = y00 + 1u;
+ uvec4 x11 = x01;
+ uvec4 y11 = y10;
+
+ vec4 fract_x = fract (lut_x);
+ vec4 fract_y = fract (lut_y);
+ vec4 weight00 = (1.0f - fract_x) * (1.0f - fract_y);
+ vec4 weight01 = fract_x * (1.0f - fract_y);
+ vec4 weight10 = (1.0f - fract_x) * fract_y;
+ vec4 weight11 = fract_x * fract_y;
+
+ uvec4 index00 = y00 * lut_width + x00;
+ uvec4 index01 = y01 * lut_width + x01;
+ uvec4 index10 = y10 * lut_width + x10;
+ uvec4 index11 = y11 * lut_width + x11;
+
+ vec4 in_img_x00, in_img_x01, in_img_x10, in_img_x11;
+ vec4 in_img_y00, in_img_y01, in_img_y10, in_img_y11;
+ for (uint i = 0u; i < UNIT_SIZE; ++i) {
+ vec2 value = lut.data[index00[i]];
+ in_img_x00[i] = value.x;
+ in_img_y00[i] = value.y;
+ value = lut.data[index01[i]];
+ in_img_x01[i] = value.x;
+ in_img_y01[i] = value.y;
+ value = lut.data[index10[i]];
+ in_img_x10[i] = value.x;
+ in_img_y10[i] = value.y;
+ value = lut.data[index11[i]];
+ in_img_x11[i] = value.x;
+ in_img_y11[i] = value.y;
+ }
+ in_img_x = in_img_x00 * weight00 + in_img_x01 * weight01 + in_img_x10 * weight10 + in_img_x11 * weight11;
+ in_img_y = in_img_y00 * weight00 + in_img_y01 * weight01 + in_img_y10 * weight10 + in_img_y11 * weight11;
+
+ for (uint i = 0u; i < UNIT_SIZE; ++i) {
+ out_bound[i] = in_img_x[i] < 0.0f || in_img_x[i] > float (in_img_width * UNIT_SIZE - 1u) ||
+ in_img_y[i] < 0.0f || in_img_y[i] > float (in_img_height - 1u);
+ }
+ if (all (out_bound)) {
+ out_data = 0u;
+ return;
+ }
+
+ x00 = uvec4 (in_img_x);
+ y00 = uvec4 (in_img_y);
+ x01 = x00 + 1u;
+ y01 = y00;
+ x10 = x00;
+ y10 = y00 + 1u;
+ x11 = x01;
+ y11 = y10;
+
+ fract_x = fract (in_img_x);
+ fract_y = fract (in_img_y);
+ weight00 = (1.0f - fract_x) * (1.0f - fract_y);
+ weight01 = fract_x * (1.0f - fract_y);
+ weight10 = (1.0f - fract_x) * fract_y;
+ weight11 = fract_x * fract_y;
+
+ uvec4 x00_floor = x00 / UNIT_SIZE;
+ uvec4 x01_floor = x01 / UNIT_SIZE;
+ uvec4 x10_floor = x10 / UNIT_SIZE;
+ uvec4 x11_floor = x11 / UNIT_SIZE;
+ uvec4 x00_fract = x00 % UNIT_SIZE;
+ uvec4 x01_fract = x01 % UNIT_SIZE;
+ uvec4 x10_fract = x10 % UNIT_SIZE;
+ uvec4 x11_fract = x11 % UNIT_SIZE;
+
+ index00 = y00 * in_img_width + x00_floor;
+ index01 = y01 * in_img_width + x01_floor;
+ index10 = y10 * in_img_width + x10_floor;
+ index11 = y11 * in_img_width + x11_floor;
+
+ // pixel Y-value
+ vec4 out_y00, out_y01, out_y10, out_y11;
+ unpack_unorm_y (0);
+ unpack_unorm_y (1);
+ unpack_unorm_y (2);
+ unpack_unorm_y (3);
+
+ vec4 inter_y = out_y00 * weight00 + out_y01 * weight01 + out_y10 * weight10 + out_y11 * weight11;
+ out_data = packUnorm4x8 (inter_y * vec4 (not (out_bound)));
+}
+
+void geomap_uv (vec2 in_uv_x, vec2 in_uv_y, bvec4 out_bound_uv, out uint out_data)
+{
+ uvec2 x00 = uvec2 (in_uv_x);
+ uvec2 y00 = uvec2 (in_uv_y);
+ uvec2 x01 = x00 + 1u;
+ uvec2 y01 = y00;
+ uvec2 x10 = x00;
+ uvec2 y10 = y00 + 1u;
+ uvec2 x11 = x01;
+ uvec2 y11 = y10;
+
+ vec2 fract_x = fract (in_uv_x);
+ vec2 fract_y = fract (in_uv_y);
+ vec2 weight00 = (1.0f - fract_x) * (1.0f - fract_y);
+ vec2 weight01 = fract_x * (1.0f - fract_y);
+ vec2 weight10 = (1.0f - fract_x) * fract_y;
+ vec2 weight11 = fract_x * fract_y;
+
+ uvec2 x00_floor = x00 / UNIT_SIZE;
+ uvec2 x01_floor = x01 / UNIT_SIZE;
+ uvec2 x10_floor = x10 / UNIT_SIZE;
+ uvec2 x11_floor = x11 / UNIT_SIZE;
+ uvec2 x00_fract = (x00 % UNIT_SIZE) / 2u;
+ uvec2 x01_fract = (x01 % UNIT_SIZE) / 2u;
+ uvec2 x10_fract = (x10 % UNIT_SIZE) / 2u;
+ uvec2 x11_fract = (x11 % UNIT_SIZE) / 2u;
+
+ uvec2 index00 = y00 * in_img_width + x00_floor;
+ uvec2 index01 = y01 * in_img_width + x01_floor;
+ uvec2 index10 = y10 * in_img_width + x10_floor;
+ uvec2 index11 = y11 * in_img_width + x11_floor;
+
+ // pixel UV-value
+ vec4 out_uv00, out_uv01, out_uv10, out_uv11;
+ vec4 value = unpackUnorm4x8 (in_buf_uv.data[index00.x]);
+ out_uv00.xy = x00_fract.x == 0u ? value.xy : value.zw;
+ value = unpackUnorm4x8 (in_buf_uv.data[index01.x]);
+ out_uv01.xy = x01_fract.x == 0u ? value.xy : value.zw;
+ value = unpackUnorm4x8 (in_buf_uv.data[index10.x]);
+ out_uv10.xy = x10_fract.x == 0u ? value.xy : value.zw;
+ value = unpackUnorm4x8 (in_buf_uv.data[index11.x]);
+ out_uv11.xy = x11_fract.x == 0u ? value.xy : value.zw;
+
+ value = unpackUnorm4x8 (in_buf_uv.data[index00.y]);
+ out_uv00.zw = x00_fract.y == 0u ? value.xy : value.zw;
+ value = unpackUnorm4x8 (in_buf_uv.data[index01.y]);
+ out_uv01.zw = x01_fract.y == 0u ? value.xy : value.zw;
+ value = unpackUnorm4x8 (in_buf_uv.data[index10.y]);
+ out_uv10.zw = x10_fract.y == 0u ? value.xy : value.zw;
+ value = unpackUnorm4x8 (in_buf_uv.data[index11.y]);
+ out_uv11.zw = x11_fract.y == 0u ? value.xy : value.zw;
+
+ vec4 inter_uv = out_uv00 * weight00.xxyy + out_uv01 * weight01.xxyy +
+ out_uv10 * weight10.xxyy + out_uv11 * weight11.xxyy;
+ inter_uv = inter_uv * vec4 (not (out_bound_uv)) + vec4 (out_bound_uv) * 0.5f;
+ out_data = packUnorm4x8 (inter_uv);
+}
diff --git a/shaders/glsl/shader_lap_trans_pyr.comp.sl b/shaders/glsl/shader_lap_trans_pyr.comp.sl
new file mode 100644
index 0000000..128a3a2
--- /dev/null
+++ b/shaders/glsl/shader_lap_trans_pyr.comp.sl
@@ -0,0 +1,162 @@
+#version 310 es
+
+layout (local_size_x = 8, local_size_y = 8) in;
+
+layout (binding = 0) readonly buffer InBufY {
+ uvec2 data[];
+} in_buf_y;
+
+layout (binding = 1) readonly buffer InBufUV {
+ uvec2 data[];
+} in_buf_uv;
+
+layout (binding = 2) readonly buffer GaussScaleBufY {
+ uint data[];
+} gaussscale_buf_y;
+
+layout (binding = 3) readonly buffer GaussScaleBufUV {
+ uint data[];
+} gaussscale_buf_uv;
+
+layout (binding = 4) writeonly buffer OutBufY {
+ uvec2 data[];
+} out_buf_y;
+
+layout (binding = 5) writeonly buffer OutBufUV {
+ uvec2 data[];
+} out_buf_uv;
+
+uniform uint in_img_width;
+uniform uint in_img_height;
+uniform uint in_offset_x;
+
+uniform uint gaussscale_img_width;
+uniform uint gaussscale_img_height;
+
+uniform uint merge_width;
+
+// normalization of half gray level
+const float norm_half_gl = 128.0f / 255.0f;
+
+void lap_trans_y (uvec2 y_id, uvec2 gs_id);
+void lap_trans_uv (uvec2 uv_id, uvec2 gs_id);
+
+void main ()
+{
+ uvec2 g_id = gl_GlobalInvocationID.xy;
+
+ uvec2 y_id = uvec2 (g_id.x, g_id.y * 4u);
+ y_id.x = clamp (y_id.x, 0u, merge_width - 1u);
+
+ uvec2 gs_id = uvec2 (g_id.x, g_id.y * 2u);
+ gs_id.x = clamp (gs_id.x, 0u, gaussscale_img_width - 1u);
+ lap_trans_y (y_id, gs_id);
+
+ y_id.y += 2u;
+ gs_id.y += 1u;
+ lap_trans_y (y_id, gs_id);
+
+ uvec2 uv_id = uvec2 (y_id.x, g_id.y * 2u);
+ gs_id.y = g_id.y;
+ lap_trans_uv (uv_id, gs_id);
+}
+
+void lap_trans_y (uvec2 y_id, uvec2 gs_id)
+{
+ y_id.y = clamp (y_id.y, 0u, in_img_height - 1u);
+ gs_id.y = clamp (gs_id.y, 0u, gaussscale_img_height - 1u);
+
+ uint y_idx = y_id.y * in_img_width + in_offset_x + y_id.x;
+ uvec2 in_pack = in_buf_y.data[y_idx];
+ vec4 in0 = unpackUnorm4x8 (in_pack.x);
+ vec4 in1 = unpackUnorm4x8 (in_pack.y);
+
+ uint gs_idx = gs_id.y * gaussscale_img_width + gs_id.x;
+ vec4 gs0 = unpackUnorm4x8 (gaussscale_buf_y.data[gs_idx]);
+ vec4 gs1 = unpackUnorm4x8 (gaussscale_buf_y.data[gs_idx + 1u]);
+ gs1 = (gs_id.x == gaussscale_img_width - 1u) ? gs0.wwww : gs1;
+
+ vec4 inter = (gs0 + vec4 (gs0.yzw, gs1.x)) * 0.5f;
+ vec4 inter00 = vec4 (gs0.x, inter.x, gs0.y, inter.y);
+ vec4 inter01 = vec4 (gs0.z, inter.z, gs0.w, inter.w);
+
+ vec4 lap0 = (in0 - inter00) * 0.5f + norm_half_gl;
+ vec4 lap1 = (in1 - inter01) * 0.5f + norm_half_gl;
+ lap0 = clamp (lap0, 0.0f, 1.0f);
+ lap1 = clamp (lap1, 0.0f, 1.0f);
+
+ uint out_idx = y_id.y * merge_width + y_id.x;
+ out_buf_y.data[out_idx] = uvec2 (packUnorm4x8 (lap0), packUnorm4x8 (lap1));
+
+ y_idx = (y_id.y >= in_img_height - 1u) ? y_idx : y_idx + in_img_width;
+ in_pack = in_buf_y.data[y_idx];
+ in0 = unpackUnorm4x8 (in_pack.x);
+ in1 = unpackUnorm4x8 (in_pack.y);
+
+ gs_idx = (gs_id.y >= gaussscale_img_height - 1u) ? gs_idx : gs_idx + gaussscale_img_width;
+ gs0 = unpackUnorm4x8 (gaussscale_buf_y.data[gs_idx]);
+ gs1 = unpackUnorm4x8 (gaussscale_buf_y.data[gs_idx + 1u]);
+ gs1 = (gs_id.x == gaussscale_img_width - 1u) ? gs0.wwww : gs1;
+
+ inter = (gs0 + vec4 (gs0.yzw, gs1.x)) * 0.5f;
+ vec4 inter10 = (inter00 + vec4 (gs0.x, inter.x, gs0.y, inter.y)) * 0.5f;
+ vec4 inter11 = (inter01 + vec4 (gs0.z, inter.z, gs0.w, inter.w)) * 0.5f;
+
+ lap0 = (in0 - inter10) * 0.5f + norm_half_gl;
+ lap1 = (in1 - inter11) * 0.5f + norm_half_gl;
+ lap0 = clamp (lap0, 0.0f, 1.0f);
+ lap1 = clamp (lap1, 0.0f, 1.0f);
+
+ out_idx += merge_width;
+ out_buf_y.data[out_idx] = uvec2 (packUnorm4x8 (lap0), packUnorm4x8 (lap1));
+}
+
+void lap_trans_uv (uvec2 uv_id, uvec2 gs_id)
+{
+ uv_id.y = clamp (uv_id.y, 0u, in_img_height / 2u - 1u);
+ gs_id.y = clamp (gs_id.y, 0u, gaussscale_img_height / 2u - 1u);
+
+ uint uv_idx = uv_id.y * in_img_width + in_offset_x + uv_id.x;
+ uvec2 in_pack = in_buf_uv.data[uv_idx];
+ vec4 in0 = unpackUnorm4x8 (in_pack.x);
+ vec4 in1 = unpackUnorm4x8 (in_pack.y);
+
+ uint gs_idx = gs_id.y * gaussscale_img_width + gs_id.x;
+ vec4 gs0 = unpackUnorm4x8 (gaussscale_buf_uv.data[gs_idx]);
+ vec4 gs1 = unpackUnorm4x8 (gaussscale_buf_uv.data[gs_idx + 1u]);
+ gs1 = (gs_id.x == gaussscale_img_width - 1u) ? gs0.zwzw : gs1;
+
+ vec4 inter = (gs0 + vec4 (gs0.zw, gs1.xy)) * 0.5f;
+ vec4 inter00 = vec4 (gs0.xy, inter.xy);
+ vec4 inter01 = vec4 (gs0.zw, inter.zw);
+
+ vec4 lap0 = (in0 - inter00) * 0.5f + norm_half_gl;
+ vec4 lap1 = (in1 - inter01) * 0.5f + norm_half_gl;
+ lap0 = clamp (lap0, 0.0f, 1.0f);
+ lap1 = clamp (lap1, 0.0f, 1.0f);
+
+ uint out_idx = uv_id.y * merge_width + uv_id.x;
+ out_buf_uv.data[out_idx] = uvec2 (packUnorm4x8 (lap0), packUnorm4x8 (lap1));
+
+ uv_idx = (uv_id.y >= (in_img_height / 2u - 1u)) ? uv_idx : uv_idx + in_img_width;
+ in_pack = in_buf_uv.data[uv_idx];
+ in0 = unpackUnorm4x8 (in_pack.x);
+ in1 = unpackUnorm4x8 (in_pack.y);
+
+ gs_idx = (gs_id.y >= (gaussscale_img_height / 2u - 1u)) ? gs_idx : gs_idx + gaussscale_img_width;
+ gs0 = unpackUnorm4x8 (gaussscale_buf_uv.data[gs_idx]);
+ gs1 = unpackUnorm4x8 (gaussscale_buf_uv.data[gs_idx + 1u]);
+ gs1 = (gs_id.x == gaussscale_img_width - 1u) ? gs0.zwzw : gs1;
+
+ inter = (gs0 + vec4 (gs0.zw, gs1.xy)) * 0.5f;
+ vec4 inter10 = (inter00 + vec4 (gs0.xy, inter.xy)) * 0.5f;
+ vec4 inter11 = (inter01 + vec4 (gs0.zw, inter.zw)) * 0.5f;
+
+ lap0 = (in0 - inter10) * 0.5f + norm_half_gl;
+ lap1 = (in1 - inter11) * 0.5f + norm_half_gl;
+ lap0 = clamp (lap0, 0.0f, 1.0f);
+ lap1 = clamp (lap1, 0.0f, 1.0f);
+
+ out_idx += merge_width;
+ out_buf_uv.data[out_idx] = uvec2 (packUnorm4x8 (lap0), packUnorm4x8 (lap1));
+}
diff --git a/shaders/glsl/shader_reconstruct_pyr.comp.sl b/shaders/glsl/shader_reconstruct_pyr.comp.sl
new file mode 100644
index 0000000..d5537b9
--- /dev/null
+++ b/shaders/glsl/shader_reconstruct_pyr.comp.sl
@@ -0,0 +1,219 @@
+#version 310 es
+
+layout (local_size_x = 8, local_size_y = 8) in;
+
+layout (binding = 0) readonly buffer Lap0BufY {
+ uvec2 data[];
+} lap0_buf_y;
+
+layout (binding = 1) readonly buffer Lap0BufUV {
+ uvec2 data[];
+} lap0_buf_uv;
+
+layout (binding = 2) readonly buffer Lap1BufY {
+ uvec2 data[];
+} lap1_buf_y;
+
+layout (binding = 3) readonly buffer Lap1BufUV {
+ uvec2 data[];
+} lap1_buf_uv;
+
+layout (binding = 4) writeonly buffer OutBufY {
+ uvec2 data[];
+} out_buf_y;
+
+layout (binding = 5) writeonly buffer OutBufUV {
+ uvec2 data[];
+} out_buf_uv;
+
+layout (binding = 6) readonly buffer PrevBlendBufY {
+ uint data[];
+} prev_blend_y;
+
+layout (binding = 7) readonly buffer PrevBlendBufUV {
+ uint data[];
+} prev_blend_uv;
+
+layout (binding = 8) readonly buffer MaskBuf {
+ uvec2 data[];
+} mask_buf;
+
+uniform uint lap_img_width;
+uniform uint lap_img_height;
+
+uniform uint out_img_width;
+uniform uint out_offset_x;
+
+uniform uint prev_blend_img_width;
+uniform uint prev_blend_img_height;
+
+// normalization of gray level
+const float norm_gl = 256.0f / 255.0f;
+
+void reconstruct_y (uvec2 y_id, uvec2 blend_id);
+void reconstruct_uv (uvec2 uv_id, uvec2 blend_id);
+
+void main ()
+{
+ uvec2 g_id = gl_GlobalInvocationID.xy;
+
+ uvec2 y_id = uvec2 (g_id.x, g_id.y * 4u);
+ y_id.x = clamp (y_id.x, 0u, lap_img_width - 1u);
+
+ uvec2 blend_id = uvec2 (g_id.x, g_id.y * 2u);
+ blend_id.x = clamp (blend_id.x, 0u, prev_blend_img_width - 1u);
+ reconstruct_y (y_id, blend_id);
+
+ y_id.y += 2u;
+ blend_id.y += 1u;
+ reconstruct_y (y_id, blend_id);
+
+ uvec2 uv_id = uvec2 (g_id.x, g_id.y * 2u);
+ uv_id.x = clamp (uv_id.x, 0u, lap_img_width - 1u);
+ blend_id = g_id;
+ blend_id.x = clamp (blend_id.x, 0u, prev_blend_img_width - 1u);
+ reconstruct_uv (uv_id, blend_id);
+}
+
+void reconstruct_y (uvec2 y_id, uvec2 blend_id)
+{
+ y_id.y = clamp (y_id.y, 0u, lap_img_height - 1u);
+ blend_id.y = clamp (blend_id.y, 0u, prev_blend_img_height - 1u);
+
+ uvec2 mask = mask_buf.data[y_id.x];
+ vec4 mask0 = unpackUnorm4x8 (mask.x);
+ vec4 mask1 = unpackUnorm4x8 (mask.y);
+
+ uint idx = y_id.y * lap_img_width + y_id.x;
+ uvec2 lap = lap0_buf_y.data[idx];
+ vec4 lap00 = unpackUnorm4x8 (lap.x);
+ vec4 lap01 = unpackUnorm4x8 (lap.y);
+
+ lap = lap1_buf_y.data[idx];
+ vec4 lap10 = unpackUnorm4x8 (lap.x);
+ vec4 lap11 = unpackUnorm4x8 (lap.y);
+
+ vec4 lap_blend0 = (lap00 - lap10) * mask0 + lap10;
+ vec4 lap_blend1 = (lap01 - lap11) * mask1 + lap11;
+
+ uint prev_blend_idx = blend_id.y * prev_blend_img_width + blend_id.x;
+ vec4 prev_blend0 = unpackUnorm4x8 (prev_blend_y.data[prev_blend_idx]);
+ vec4 prev_blend1 = unpackUnorm4x8 (prev_blend_y.data[prev_blend_idx + 1u]);
+ prev_blend1 = (blend_id.x == prev_blend_img_width - 1u) ? prev_blend0.wwww : prev_blend1;
+
+ vec4 inter = (prev_blend0 + vec4 (prev_blend0.yzw, prev_blend1.x)) * 0.5f;
+ vec4 prev_blend_inter00 = vec4 (prev_blend0.x, inter.x, prev_blend0.y, inter.y);
+ vec4 prev_blend_inter01 = vec4 (prev_blend0.z, inter.z, prev_blend0.w, inter.w);
+
+ vec4 out0 = prev_blend_inter00 + lap_blend0 * 2.0f - norm_gl;
+ vec4 out1 = prev_blend_inter01 + lap_blend1 * 2.0f - norm_gl;
+ out0 = clamp (out0, 0.0f, 1.0f);
+ out1 = clamp (out1, 0.0f, 1.0f);
+
+ uint out_idx = y_id.y * out_img_width + out_offset_x + y_id.x;
+ out_buf_y.data[out_idx] = uvec2 (packUnorm4x8 (out0), packUnorm4x8 (out1));
+
+ idx = (y_id.y >= lap_img_height - 1u) ? idx : idx + lap_img_width;
+ lap = lap0_buf_y.data[idx];
+ lap00 = unpackUnorm4x8 (lap.x);
+ lap01 = unpackUnorm4x8 (lap.y);
+
+ lap = lap1_buf_y.data[idx];
+ lap10 = unpackUnorm4x8 (lap.x);
+ lap11 = unpackUnorm4x8 (lap.y);
+
+ lap_blend0 = (lap00 - lap10) * mask0 + lap10;
+ lap_blend1 = (lap01 - lap11) * mask1 + lap11;
+
+ prev_blend_idx = (blend_id.y >= prev_blend_img_height - 1u) ? prev_blend_idx : prev_blend_idx + prev_blend_img_width;
+ prev_blend0 = unpackUnorm4x8 (prev_blend_y.data[prev_blend_idx]);
+ prev_blend1 = unpackUnorm4x8 (prev_blend_y.data[prev_blend_idx + 1u]);
+ prev_blend1 = (blend_id.x == prev_blend_img_width - 1u) ? prev_blend0.wwww : prev_blend1;
+
+ inter = (prev_blend0 + vec4 (prev_blend0.yzw, prev_blend1.x)) * 0.5f;
+ vec4 prev_blend_inter10 = vec4 (prev_blend0.x, inter.x, prev_blend0.y, inter.y);
+ vec4 prev_blend_inter11 = vec4 (prev_blend0.z, inter.z, prev_blend0.w, inter.w);
+ prev_blend_inter10 = (prev_blend_inter00 + prev_blend_inter10) * 0.5f;
+ prev_blend_inter11 = (prev_blend_inter01 + prev_blend_inter11) * 0.5f;
+
+ out0 = prev_blend_inter10 + lap_blend0 * 2.0f - norm_gl;
+ out1 = prev_blend_inter11 + lap_blend1 * 2.0f - norm_gl;
+ out0 = clamp (out0, 0.0f, 1.0f);
+ out1 = clamp (out1, 0.0f, 1.0f);
+
+ out_idx += out_img_width;
+ out_buf_y.data[out_idx] = uvec2 (packUnorm4x8 (out0), packUnorm4x8 (out1));
+}
+
+void reconstruct_uv (uvec2 uv_id, uvec2 blend_id)
+{
+ uv_id.y = clamp (uv_id.y, 0u, lap_img_height / 2u - 1u);
+ blend_id.y = clamp (blend_id.y, 0u, prev_blend_img_height / 2u - 1u);
+
+ uvec2 mask = mask_buf.data[uv_id.x];
+ vec4 mask0 = unpackUnorm4x8 (mask.x);
+ vec4 mask1 = unpackUnorm4x8 (mask.y);
+
+ uint idx = uv_id.y * lap_img_width + uv_id.x;
+ uvec2 lap = lap0_buf_uv.data[idx];
+ vec4 lap00 = unpackUnorm4x8 (lap.x);
+ vec4 lap01 = unpackUnorm4x8 (lap.y);
+
+ lap = lap1_buf_uv.data[idx];
+ vec4 lap10 = unpackUnorm4x8 (lap.x);
+ vec4 lap11 = unpackUnorm4x8 (lap.y);
+
+ mask0.yw = mask0.xz;
+ mask1.yw = mask1.xz;
+ vec4 lap_blend0 = (lap00 - lap10) * mask0 + lap10;
+ vec4 lap_blend1 = (lap01 - lap11) * mask1 + lap11;
+
+ uint prev_blend_idx = blend_id.y * prev_blend_img_width + blend_id.x;
+ vec4 prev_blend0 = unpackUnorm4x8 (prev_blend_uv.data[prev_blend_idx]);
+ vec4 prev_blend1 = unpackUnorm4x8 (prev_blend_uv.data[prev_blend_idx + 1u]);
+ prev_blend1 = (blend_id.x == prev_blend_img_width - 1u) ? prev_blend0.zwzw : prev_blend1;
+
+ vec4 inter = (prev_blend0 + vec4 (prev_blend0.zw, prev_blend1.xy)) * 0.5f;
+ vec4 prev_blend_inter00 = vec4 (prev_blend0.xy, inter.xy);
+ vec4 prev_blend_inter01 = vec4 (prev_blend0.zw, inter.zw);
+
+ vec4 out0 = prev_blend_inter00 + lap_blend0 * 2.0f - norm_gl;
+ vec4 out1 = prev_blend_inter01 + lap_blend1 * 2.0f - norm_gl;
+ out0 = clamp (out0, 0.0f, 1.0f);
+ out1 = clamp (out1, 0.0f, 1.0f);
+
+ uint out_idx = uv_id.y * out_img_width + out_offset_x + uv_id.x;
+ out_buf_uv.data[out_idx] = uvec2 (packUnorm4x8 (out0), packUnorm4x8 (out1));
+
+ idx = (uv_id.y >= (lap_img_height / 2u - 1u)) ? idx : idx + lap_img_width;
+ lap = lap0_buf_uv.data[idx];
+ lap00 = unpackUnorm4x8 (lap.x);
+ lap01 = unpackUnorm4x8 (lap.y);
+
+ lap = lap1_buf_uv.data[idx];
+ lap10 = unpackUnorm4x8 (lap.x);
+ lap11 = unpackUnorm4x8 (lap.y);
+
+ lap_blend0 = (lap00 - lap10) * mask0 + lap10;
+ lap_blend1 = (lap01 - lap11) * mask1 + lap11;
+
+ prev_blend_idx = (blend_id.y >= (prev_blend_img_height / 2u - 1u)) ?
+ prev_blend_idx : prev_blend_idx + prev_blend_img_width;
+ prev_blend0 = unpackUnorm4x8 (prev_blend_uv.data[prev_blend_idx]);
+ prev_blend1 = unpackUnorm4x8 (prev_blend_uv.data[prev_blend_idx + 1u]);
+ prev_blend1 = (blend_id.x == prev_blend_img_width - 1u) ? prev_blend0.zwzw : prev_blend1;
+
+ inter = (prev_blend0 + vec4 (prev_blend0.zw, prev_blend1.xy)) * 0.5f;
+ vec4 prev_blend_inter10 = vec4 (prev_blend0.xy, inter.xy);
+ vec4 prev_blend_inter11 = vec4 (prev_blend0.zw, inter.zw);
+ prev_blend_inter10 = (prev_blend_inter00 + prev_blend_inter10) * 0.5f;
+ prev_blend_inter11 = (prev_blend_inter01 + prev_blend_inter11) * 0.5f;
+
+ out0 = prev_blend_inter10 + lap_blend0 * 2.0f - norm_gl;
+ out1 = prev_blend_inter11 + lap_blend1 * 2.0f - norm_gl;
+ out0 = clamp (out0, 0.0f, 1.0f);
+ out1 = clamp (out1, 0.0f, 1.0f);
+
+ out_idx += out_img_width;
+ out_buf_uv.data[out_idx] = uvec2 (packUnorm4x8 (out0), packUnorm4x8 (out1));
+}
diff --git a/shaders/glslx/.gitignore b/shaders/glslx/.gitignore
new file mode 100644
index 0000000..c161cb9
--- /dev/null
+++ b/shaders/glslx/.gitignore
@@ -0,0 +1 @@
+*.slx
diff --git a/shaders/glslx/Makefile.am b/shaders/glslx/Makefile.am
new file mode 100644
index 0000000..9be760e
--- /dev/null
+++ b/shaders/glslx/Makefile.am
@@ -0,0 +1,20 @@
+glslx_sources = \
+ shader_copy.comp.slx \
+ shader_geomap.comp.slx \
+ shader_gauss_scale_pyr.comp.slx \
+ shader_lap_trans_pyr.comp.slx \
+ shader_blend_pyr.comp.slx \
+ shader_reconstruct_pyr.comp.slx \
+ $(NULL)
+
+add_quotation_marks_sh = \
+ $(top_srcdir)/tools/add-quotation-marks.sh
+
+glsl_dir = $(top_srcdir)/shaders/glsl
+
+all-local: $(glslx_sources)
+
+$(glslx_sources): %.slx: $(glsl_dir)/%.sl
+ @$(add_quotation_marks_sh) $< $@
+
+CLEANFILES = $(glslx_sources)
diff --git a/shaders/spv/shader_blend_pyr.comp b/shaders/spv/shader_blend_pyr.comp
new file mode 100644
index 0000000..77ff1a9
--- /dev/null
+++ b/shaders/spv/shader_blend_pyr.comp
@@ -0,0 +1,93 @@
+#version 310 es
+
+layout (local_size_x = 8, local_size_y = 8) in;
+
+layout (binding = 0) readonly buffer In0BufY {
+ uvec2 data[];
+} in0_buf_y;
+
+layout (binding = 1) readonly buffer In0BufUV {
+ uvec2 data[];
+} in0_buf_uv;
+
+layout (binding = 2) readonly buffer In1BufY {
+ uvec2 data[];
+} in1_buf_y;
+
+layout (binding = 3) readonly buffer In1BufUV {
+ uvec2 data[];
+} in1_buf_uv;
+
+layout (binding = 4) writeonly buffer OutBufY {
+ uvec2 data[];
+} out_buf_y;
+
+layout (binding = 5) writeonly buffer OutBufUV {
+ uvec2 data[];
+} out_buf_uv;
+
+layout (binding = 6) readonly buffer MaskBuf {
+ uvec2 data[];
+} mask_buf;
+
+layout (push_constant) uniform PushConsts {
+ uint in_img_width;
+} prop;
+
+void main ()
+{
+ uvec2 g_id = gl_GlobalInvocationID.xy;
+ g_id.x = clamp (g_id.x, 0u, prop.in_img_width - 1u);
+
+ uvec2 mask = mask_buf.data[g_id.x];
+ vec4 mask0 = unpackUnorm4x8 (mask.x);
+ vec4 mask1 = unpackUnorm4x8 (mask.y);
+
+ uint y_idx = g_id.y * 2u * prop.in_img_width + g_id.x;
+ uvec2 in0_y = in0_buf_y.data[y_idx];
+ vec4 in0_y0 = unpackUnorm4x8 (in0_y.x);
+ vec4 in0_y1 = unpackUnorm4x8 (in0_y.y);
+
+ uvec2 in1_y = in1_buf_y.data[y_idx];
+ vec4 in1_y0 = unpackUnorm4x8 (in1_y.x);
+ vec4 in1_y1 = unpackUnorm4x8 (in1_y.y);
+
+ vec4 out_y0 = (in0_y0 - in1_y0) * mask0 + in1_y0;
+ vec4 out_y1 = (in0_y1 - in1_y1) * mask1 + in1_y1;
+ out_y0 = clamp (out_y0, 0.0f, 1.0f);
+ out_y1 = clamp (out_y1, 0.0f, 1.0f);
+ out_buf_y.data[y_idx] = uvec2 (packUnorm4x8 (out_y0), packUnorm4x8 (out_y1));
+
+ y_idx += prop.in_img_width;
+ in0_y = in0_buf_y.data[y_idx];
+ in0_y0 = unpackUnorm4x8 (in0_y.x);
+ in0_y1 = unpackUnorm4x8 (in0_y.y);
+
+ in1_y = in1_buf_y.data[y_idx];
+ in1_y0 = unpackUnorm4x8 (in1_y.x);
+ in1_y1 = unpackUnorm4x8 (in1_y.y);
+
+ out_y0 = (in0_y0 - in1_y0) * mask0 + in1_y0;
+ out_y1 = (in0_y1 - in1_y1) * mask1 + in1_y1;
+ out_y0 = clamp (out_y0, 0.0f, 1.0f);
+ out_y1 = clamp (out_y1, 0.0f, 1.0f);
+ out_buf_y.data[y_idx] = uvec2 (packUnorm4x8 (out_y0), packUnorm4x8 (out_y1));
+
+ uint uv_idx = g_id.y * prop.in_img_width + g_id.x;
+ uvec2 in0_uv = in0_buf_uv.data[uv_idx];
+ vec4 in0_uv0 = unpackUnorm4x8 (in0_uv.x);
+ vec4 in0_uv1 = unpackUnorm4x8 (in0_uv.y);
+
+ uvec2 in1_uv = in1_buf_uv.data[uv_idx];
+ vec4 in1_uv0 = unpackUnorm4x8 (in1_uv.x);
+ vec4 in1_uv1 = unpackUnorm4x8 (in1_uv.y);
+
+ mask0.yw = mask0.xz;
+ mask1.yw = mask1.xz;
+ vec4 out_uv0 = (in0_uv0 - in1_uv0) * mask0 + in1_uv0;
+ vec4 out_uv1 = (in0_uv1 - in1_uv1) * mask1 + in1_uv1;
+
+ out_uv0 = clamp (out_uv0, 0.0f, 1.0f);
+ out_uv1 = clamp (out_uv1, 0.0f, 1.0f);
+ out_buf_uv.data[uv_idx] = uvec2 (packUnorm4x8 (out_uv0), packUnorm4x8 (out_uv1));
+}
diff --git a/shaders/spv/shader_blend_pyr.comp.spv b/shaders/spv/shader_blend_pyr.comp.spv
new file mode 100644
index 0000000..9f1d33a
--- /dev/null
+++ b/shaders/spv/shader_blend_pyr.comp.spv
@@ -0,0 +1,228 @@
+ // 7.8.2870
+ 0x07230203,0x00010000,0x00080007,0x0000010e,0x00000000,0x00020011,0x00000001,0x0006000b,
+ 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,
+ 0x0006000f,0x00000005,0x00000004,0x6e69616d,0x00000000,0x0000000c,0x00060010,0x00000004,
+ 0x00000011,0x00000008,0x00000008,0x00000001,0x00030003,0x00000001,0x00000136,0x00040005,
+ 0x00000004,0x6e69616d,0x00000000,0x00040005,0x00000009,0x64695f67,0x00000000,0x00080005,
+ 0x0000000c,0x475f6c67,0x61626f6c,0x766e496c,0x7461636f,0x496e6f69,0x00000044,0x00050005,
+ 0x00000013,0x68737550,0x736e6f43,0x00007374,0x00070006,0x00000013,0x00000000,0x695f6e69,
+ 0x775f676d,0x68746469,0x00000000,0x00040005,0x00000015,0x706f7270,0x00000000,0x00040005,
+ 0x0000001f,0x6b73616d,0x00000000,0x00040005,0x00000021,0x6b73614d,0x00667542,0x00050006,
+ 0x00000021,0x00000000,0x61746164,0x00000000,0x00050005,0x00000023,0x6b73616d,0x6675625f,
+ 0x00000000,0x00040005,0x0000002c,0x6b73616d,0x00000030,0x00040005,0x00000030,0x6b73616d,
+ 0x00000031,0x00040005,0x00000034,0x64695f79,0x00000078,0x00040005,0x0000003f,0x5f306e69,
+ 0x00000079,0x00040005,0x00000041,0x42306e49,0x00596675,0x00050006,0x00000041,0x00000000,
+ 0x61746164,0x00000000,0x00050005,0x00000043,0x5f306e69,0x5f667562,0x00000079,0x00040005,
+ 0x00000047,0x5f306e69,0x00003079,0x00040005,0x0000004b,0x5f306e69,0x00003179,0x00040005,
+ 0x0000004f,0x5f316e69,0x00000079,0x00040005,0x00000051,0x42316e49,0x00596675,0x00050006,
+ 0x00000051,0x00000000,0x61746164,0x00000000,0x00050005,0x00000053,0x5f316e69,0x5f667562,
+ 0x00000079,0x00040005,0x00000057,0x5f316e69,0x00003079,0x00040005,0x0000005b,0x5f316e69,
+ 0x00003179,0x00040005,0x0000005f,0x5f74756f,0x00003079,0x00040005,0x00000067,0x5f74756f,
+ 0x00003179,0x00040005,0x0000007a,0x4274754f,0x00596675,0x00050006,0x0000007a,0x00000000,
+ 0x61746164,0x00000000,0x00050005,0x0000007c,0x5f74756f,0x5f667562,0x00000079,0x00040005,
+ 0x000000b7,0x695f7675,0x00007864,0x00040005,0x000000c0,0x5f306e69,0x00007675,0x00050005,
+ 0x000000c2,0x42306e49,0x56556675,0x00000000,0x00050006,0x000000c2,0x00000000,0x61746164,
+ 0x00000000,0x00050005,0x000000c4,0x5f306e69,0x5f667562,0x00007675,0x00040005,0x000000c8,
+ 0x5f306e69,0x00307675,0x00040005,0x000000cc,0x5f306e69,0x00317675,0x00040005,0x000000d0,
+ 0x5f316e69,0x00007675,0x00050005,0x000000d2,0x42316e49,0x56556675,0x00000000,0x00050006,
+ 0x000000d2,0x00000000,0x61746164,0x00000000,0x00050005,0x000000d4,0x5f316e69,0x5f667562,
+ 0x00007675,0x00040005,0x000000d8,0x5f316e69,0x00307675,0x00040005,0x000000dc,0x5f316e69,
+ 0x00317675,0x00040005,0x000000e9,0x5f74756f,0x00307675,0x00040005,0x000000f1,0x5f74756f,
+ 0x00317675,0x00050005,0x00000102,0x4274754f,0x56556675,0x00000000,0x00050006,0x00000102,
+ 0x00000000,0x61746164,0x00000000,0x00050005,0x00000104,0x5f74756f,0x5f667562,0x00007675,
+ 0x00040047,0x0000000c,0x0000000b,0x0000001c,0x00050048,0x00000013,0x00000000,0x00000023,
+ 0x00000000,0x00030047,0x00000013,0x00000002,0x00040047,0x00000020,0x00000006,0x00000008,
+ 0x00040048,0x00000021,0x00000000,0x00000018,0x00050048,0x00000021,0x00000000,0x00000023,
+ 0x00000000,0x00030047,0x00000021,0x00000003,0x00040047,0x00000023,0x00000022,0x00000000,
+ 0x00040047,0x00000023,0x00000021,0x00000006,0x00040047,0x00000040,0x00000006,0x00000008,
+ 0x00040048,0x00000041,0x00000000,0x00000018,0x00050048,0x00000041,0x00000000,0x00000023,
+ 0x00000000,0x00030047,0x00000041,0x00000003,0x00040047,0x00000043,0x00000022,0x00000000,
+ 0x00040047,0x00000043,0x00000021,0x00000000,0x00040047,0x00000050,0x00000006,0x00000008,
+ 0x00040048,0x00000051,0x00000000,0x00000018,0x00050048,0x00000051,0x00000000,0x00000023,
+ 0x00000000,0x00030047,0x00000051,0x00000003,0x00040047,0x00000053,0x00000022,0x00000000,
+ 0x00040047,0x00000053,0x00000021,0x00000002,0x00040047,0x00000079,0x00000006,0x00000008,
+ 0x00040048,0x0000007a,0x00000000,0x00000019,0x00050048,0x0000007a,0x00000000,0x00000023,
+ 0x00000000,0x00030047,0x0000007a,0x00000003,0x00040047,0x0000007c,0x00000022,0x00000000,
+ 0x00040047,0x0000007c,0x00000021,0x00000004,0x00040047,0x000000c1,0x00000006,0x00000008,
+ 0x00040048,0x000000c2,0x00000000,0x00000018,0x00050048,0x000000c2,0x00000000,0x00000023,
+ 0x00000000,0x00030047,0x000000c2,0x00000003,0x00040047,0x000000c4,0x00000022,0x00000000,
+ 0x00040047,0x000000c4,0x00000021,0x00000001,0x00040047,0x000000d1,0x00000006,0x00000008,
+ 0x00040048,0x000000d2,0x00000000,0x00000018,0x00050048,0x000000d2,0x00000000,0x00000023,
+ 0x00000000,0x00030047,0x000000d2,0x00000003,0x00040047,0x000000d4,0x00000022,0x00000000,
+ 0x00040047,0x000000d4,0x00000021,0x00000003,0x00040047,0x00000101,0x00000006,0x00000008,
+ 0x00040048,0x00000102,0x00000000,0x00000019,0x00050048,0x00000102,0x00000000,0x00000023,
+ 0x00000000,0x00030047,0x00000102,0x00000003,0x00040047,0x00000104,0x00000022,0x00000000,
+ 0x00040047,0x00000104,0x00000021,0x00000005,0x00040047,0x0000010d,0x0000000b,0x00000019,
+ 0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00040015,0x00000006,0x00000020,
+ 0x00000000,0x00040017,0x00000007,0x00000006,0x00000002,0x00040020,0x00000008,0x00000007,
+ 0x00000007,0x00040017,0x0000000a,0x00000006,0x00000003,0x00040020,0x0000000b,0x00000001,
+ 0x0000000a,0x0004003b,0x0000000b,0x0000000c,0x00000001,0x0004002b,0x00000006,0x0000000f,
+ 0x00000000,0x00040020,0x00000010,0x00000007,0x00000006,0x0003001e,0x00000013,0x00000006,
+ 0x00040020,0x00000014,0x00000009,0x00000013,0x0004003b,0x00000014,0x00000015,0x00000009,
+ 0x00040015,0x00000016,0x00000020,0x00000001,0x0004002b,0x00000016,0x00000017,0x00000000,
+ 0x00040020,0x00000018,0x00000009,0x00000006,0x0004002b,0x00000006,0x0000001b,0x00000001,
+ 0x0003001d,0x00000020,0x00000007,0x0003001e,0x00000021,0x00000020,0x00040020,0x00000022,
+ 0x00000002,0x00000021,0x0004003b,0x00000022,0x00000023,0x00000002,0x00040020,0x00000026,
+ 0x00000002,0x00000007,0x00030016,0x00000029,0x00000020,0x00040017,0x0000002a,0x00000029,
+ 0x00000004,0x00040020,0x0000002b,0x00000007,0x0000002a,0x0004002b,0x00000006,0x00000037,
+ 0x00000002,0x0003001d,0x00000040,0x00000007,0x0003001e,0x00000041,0x00000040,0x00040020,
+ 0x00000042,0x00000002,0x00000041,0x0004003b,0x00000042,0x00000043,0x00000002,0x0003001d,
+ 0x00000050,0x00000007,0x0003001e,0x00000051,0x00000050,0x00040020,0x00000052,0x00000002,
+ 0x00000051,0x0004003b,0x00000052,0x00000053,0x00000002,0x0004002b,0x00000029,0x00000070,
+ 0x00000000,0x0004002b,0x00000029,0x00000071,0x3f800000,0x0003001d,0x00000079,0x00000007,
+ 0x0003001e,0x0000007a,0x00000079,0x00040020,0x0000007b,0x00000002,0x0000007a,0x0004003b,
+ 0x0000007b,0x0000007c,0x00000002,0x0003001d,0x000000c1,0x00000007,0x0003001e,0x000000c2,
+ 0x000000c1,0x00040020,0x000000c3,0x00000002,0x000000c2,0x0004003b,0x000000c3,0x000000c4,
+ 0x00000002,0x0003001d,0x000000d1,0x00000007,0x0003001e,0x000000d2,0x000000d1,0x00040020,
+ 0x000000d3,0x00000002,0x000000d2,0x0004003b,0x000000d3,0x000000d4,0x00000002,0x00040017,
+ 0x000000e0,0x00000029,0x00000002,0x0003001d,0x00000101,0x00000007,0x0003001e,0x00000102,
+ 0x00000101,0x00040020,0x00000103,0x00000002,0x00000102,0x0004003b,0x00000103,0x00000104,
+ 0x00000002,0x0004002b,0x00000006,0x0000010c,0x00000008,0x0006002c,0x0000000a,0x0000010d,
+ 0x0000010c,0x0000010c,0x0000001b,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,
+ 0x000200f8,0x00000005,0x0004003b,0x00000008,0x00000009,0x00000007,0x0004003b,0x00000008,
+ 0x0000001f,0x00000007,0x0004003b,0x0000002b,0x0000002c,0x00000007,0x0004003b,0x0000002b,
+ 0x00000030,0x00000007,0x0004003b,0x00000010,0x00000034,0x00000007,0x0004003b,0x00000008,
+ 0x0000003f,0x00000007,0x0004003b,0x0000002b,0x00000047,0x00000007,0x0004003b,0x0000002b,
+ 0x0000004b,0x00000007,0x0004003b,0x00000008,0x0000004f,0x00000007,0x0004003b,0x0000002b,
+ 0x00000057,0x00000007,0x0004003b,0x0000002b,0x0000005b,0x00000007,0x0004003b,0x0000002b,
+ 0x0000005f,0x00000007,0x0004003b,0x0000002b,0x00000067,0x00000007,0x0004003b,0x00000010,
+ 0x000000b7,0x00000007,0x0004003b,0x00000008,0x000000c0,0x00000007,0x0004003b,0x0000002b,
+ 0x000000c8,0x00000007,0x0004003b,0x0000002b,0x000000cc,0x00000007,0x0004003b,0x00000008,
+ 0x000000d0,0x00000007,0x0004003b,0x0000002b,0x000000d8,0x00000007,0x0004003b,0x0000002b,
+ 0x000000dc,0x00000007,0x0004003b,0x0000002b,0x000000e9,0x00000007,0x0004003b,0x0000002b,
+ 0x000000f1,0x00000007,0x0004003d,0x0000000a,0x0000000d,0x0000000c,0x0007004f,0x00000007,
+ 0x0000000e,0x0000000d,0x0000000d,0x00000000,0x00000001,0x0003003e,0x00000009,0x0000000e,
+ 0x00050041,0x00000010,0x00000011,0x00000009,0x0000000f,0x0004003d,0x00000006,0x00000012,
+ 0x00000011,0x00050041,0x00000018,0x00000019,0x00000015,0x00000017,0x0004003d,0x00000006,
+ 0x0000001a,0x00000019,0x00050082,0x00000006,0x0000001c,0x0000001a,0x0000001b,0x0008000c,
+ 0x00000006,0x0000001d,0x00000001,0x0000002c,0x00000012,0x0000000f,0x0000001c,0x00050041,
+ 0x00000010,0x0000001e,0x00000009,0x0000000f,0x0003003e,0x0000001e,0x0000001d,0x00050041,
+ 0x00000010,0x00000024,0x00000009,0x0000000f,0x0004003d,0x00000006,0x00000025,0x00000024,
+ 0x00060041,0x00000026,0x00000027,0x00000023,0x00000017,0x00000025,0x0004003d,0x00000007,
+ 0x00000028,0x00000027,0x0003003e,0x0000001f,0x00000028,0x00050041,0x00000010,0x0000002d,
+ 0x0000001f,0x0000000f,0x0004003d,0x00000006,0x0000002e,0x0000002d,0x0006000c,0x0000002a,
+ 0x0000002f,0x00000001,0x00000040,0x0000002e,0x0003003e,0x0000002c,0x0000002f,0x00050041,
+ 0x00000010,0x00000031,0x0000001f,0x0000001b,0x0004003d,0x00000006,0x00000032,0x00000031,
+ 0x0006000c,0x0000002a,0x00000033,0x00000001,0x00000040,0x00000032,0x0003003e,0x00000030,
+ 0x00000033,0x00050041,0x00000010,0x00000035,0x00000009,0x0000001b,0x0004003d,0x00000006,
+ 0x00000036,0x00000035,0x00050084,0x00000006,0x00000038,0x00000036,0x00000037,0x00050041,
+ 0x00000018,0x00000039,0x00000015,0x00000017,0x0004003d,0x00000006,0x0000003a,0x00000039,
+ 0x00050084,0x00000006,0x0000003b,0x00000038,0x0000003a,0x00050041,0x00000010,0x0000003c,
+ 0x00000009,0x0000000f,0x0004003d,0x00000006,0x0000003d,0x0000003c,0x00050080,0x00000006,
+ 0x0000003e,0x0000003b,0x0000003d,0x0003003e,0x00000034,0x0000003e,0x0004003d,0x00000006,
+ 0x00000044,0x00000034,0x00060041,0x00000026,0x00000045,0x00000043,0x00000017,0x00000044,
+ 0x0004003d,0x00000007,0x00000046,0x00000045,0x0003003e,0x0000003f,0x00000046,0x00050041,
+ 0x00000010,0x00000048,0x0000003f,0x0000000f,0x0004003d,0x00000006,0x00000049,0x00000048,
+ 0x0006000c,0x0000002a,0x0000004a,0x00000001,0x00000040,0x00000049,0x0003003e,0x00000047,
+ 0x0000004a,0x00050041,0x00000010,0x0000004c,0x0000003f,0x0000001b,0x0004003d,0x00000006,
+ 0x0000004d,0x0000004c,0x0006000c,0x0000002a,0x0000004e,0x00000001,0x00000040,0x0000004d,
+ 0x0003003e,0x0000004b,0x0000004e,0x0004003d,0x00000006,0x00000054,0x00000034,0x00060041,
+ 0x00000026,0x00000055,0x00000053,0x00000017,0x00000054,0x0004003d,0x00000007,0x00000056,
+ 0x00000055,0x0003003e,0x0000004f,0x00000056,0x00050041,0x00000010,0x00000058,0x0000004f,
+ 0x0000000f,0x0004003d,0x00000006,0x00000059,0x00000058,0x0006000c,0x0000002a,0x0000005a,
+ 0x00000001,0x00000040,0x00000059,0x0003003e,0x00000057,0x0000005a,0x00050041,0x00000010,
+ 0x0000005c,0x0000004f,0x0000001b,0x0004003d,0x00000006,0x0000005d,0x0000005c,0x0006000c,
+ 0x0000002a,0x0000005e,0x00000001,0x00000040,0x0000005d,0x0003003e,0x0000005b,0x0000005e,
+ 0x0004003d,0x0000002a,0x00000060,0x00000047,0x0004003d,0x0000002a,0x00000061,0x00000057,
+ 0x00050083,0x0000002a,0x00000062,0x00000060,0x00000061,0x0004003d,0x0000002a,0x00000063,
+ 0x0000002c,0x00050085,0x0000002a,0x00000064,0x00000062,0x00000063,0x0004003d,0x0000002a,
+ 0x00000065,0x00000057,0x00050081,0x0000002a,0x00000066,0x00000064,0x00000065,0x0003003e,
+ 0x0000005f,0x00000066,0x0004003d,0x0000002a,0x00000068,0x0000004b,0x0004003d,0x0000002a,
+ 0x00000069,0x0000005b,0x00050083,0x0000002a,0x0000006a,0x00000068,0x00000069,0x0004003d,
+ 0x0000002a,0x0000006b,0x00000030,0x00050085,0x0000002a,0x0000006c,0x0000006a,0x0000006b,
+ 0x0004003d,0x0000002a,0x0000006d,0x0000005b,0x00050081,0x0000002a,0x0000006e,0x0000006c,
+ 0x0000006d,0x0003003e,0x00000067,0x0000006e,0x0004003d,0x0000002a,0x0000006f,0x0000005f,
+ 0x00070050,0x0000002a,0x00000072,0x00000070,0x00000070,0x00000070,0x00000070,0x00070050,
+ 0x0000002a,0x00000073,0x00000071,0x00000071,0x00000071,0x00000071,0x0008000c,0x0000002a,
+ 0x00000074,0x00000001,0x0000002b,0x0000006f,0x00000072,0x00000073,0x0003003e,0x0000005f,
+ 0x00000074,0x0004003d,0x0000002a,0x00000075,0x00000067,0x00070050,0x0000002a,0x00000076,
+ 0x00000070,0x00000070,0x00000070,0x00000070,0x00070050,0x0000002a,0x00000077,0x00000071,
+ 0x00000071,0x00000071,0x00000071,0x0008000c,0x0000002a,0x00000078,0x00000001,0x0000002b,
+ 0x00000075,0x00000076,0x00000077,0x0003003e,0x00000067,0x00000078,0x0004003d,0x00000006,
+ 0x0000007d,0x00000034,0x0004003d,0x0000002a,0x0000007e,0x0000005f,0x0006000c,0x00000006,
+ 0x0000007f,0x00000001,0x00000037,0x0000007e,0x0004003d,0x0000002a,0x00000080,0x00000067,
+ 0x0006000c,0x00000006,0x00000081,0x00000001,0x00000037,0x00000080,0x00050050,0x00000007,
+ 0x00000082,0x0000007f,0x00000081,0x00060041,0x00000026,0x00000083,0x0000007c,0x00000017,
+ 0x0000007d,0x0003003e,0x00000083,0x00000082,0x00050041,0x00000018,0x00000084,0x00000015,
+ 0x00000017,0x0004003d,0x00000006,0x00000085,0x00000084,0x0004003d,0x00000006,0x00000086,
+ 0x00000034,0x00050080,0x00000006,0x00000087,0x00000086,0x00000085,0x0003003e,0x00000034,
+ 0x00000087,0x0004003d,0x00000006,0x00000088,0x00000034,0x00060041,0x00000026,0x00000089,
+ 0x00000043,0x00000017,0x00000088,0x0004003d,0x00000007,0x0000008a,0x00000089,0x0003003e,
+ 0x0000003f,0x0000008a,0x00050041,0x00000010,0x0000008b,0x0000003f,0x0000000f,0x0004003d,
+ 0x00000006,0x0000008c,0x0000008b,0x0006000c,0x0000002a,0x0000008d,0x00000001,0x00000040,
+ 0x0000008c,0x0003003e,0x00000047,0x0000008d,0x00050041,0x00000010,0x0000008e,0x0000003f,
+ 0x0000001b,0x0004003d,0x00000006,0x0000008f,0x0000008e,0x0006000c,0x0000002a,0x00000090,
+ 0x00000001,0x00000040,0x0000008f,0x0003003e,0x0000004b,0x00000090,0x0004003d,0x00000006,
+ 0x00000091,0x00000034,0x00060041,0x00000026,0x00000092,0x00000053,0x00000017,0x00000091,
+ 0x0004003d,0x00000007,0x00000093,0x00000092,0x0003003e,0x0000004f,0x00000093,0x00050041,
+ 0x00000010,0x00000094,0x0000004f,0x0000000f,0x0004003d,0x00000006,0x00000095,0x00000094,
+ 0x0006000c,0x0000002a,0x00000096,0x00000001,0x00000040,0x00000095,0x0003003e,0x00000057,
+ 0x00000096,0x00050041,0x00000010,0x00000097,0x0000004f,0x0000001b,0x0004003d,0x00000006,
+ 0x00000098,0x00000097,0x0006000c,0x0000002a,0x00000099,0x00000001,0x00000040,0x00000098,
+ 0x0003003e,0x0000005b,0x00000099,0x0004003d,0x0000002a,0x0000009a,0x00000047,0x0004003d,
+ 0x0000002a,0x0000009b,0x00000057,0x00050083,0x0000002a,0x0000009c,0x0000009a,0x0000009b,
+ 0x0004003d,0x0000002a,0x0000009d,0x0000002c,0x00050085,0x0000002a,0x0000009e,0x0000009c,
+ 0x0000009d,0x0004003d,0x0000002a,0x0000009f,0x00000057,0x00050081,0x0000002a,0x000000a0,
+ 0x0000009e,0x0000009f,0x0003003e,0x0000005f,0x000000a0,0x0004003d,0x0000002a,0x000000a1,
+ 0x0000004b,0x0004003d,0x0000002a,0x000000a2,0x0000005b,0x00050083,0x0000002a,0x000000a3,
+ 0x000000a1,0x000000a2,0x0004003d,0x0000002a,0x000000a4,0x00000030,0x00050085,0x0000002a,
+ 0x000000a5,0x000000a3,0x000000a4,0x0004003d,0x0000002a,0x000000a6,0x0000005b,0x00050081,
+ 0x0000002a,0x000000a7,0x000000a5,0x000000a6,0x0003003e,0x00000067,0x000000a7,0x0004003d,
+ 0x0000002a,0x000000a8,0x0000005f,0x00070050,0x0000002a,0x000000a9,0x00000070,0x00000070,
+ 0x00000070,0x00000070,0x00070050,0x0000002a,0x000000aa,0x00000071,0x00000071,0x00000071,
+ 0x00000071,0x0008000c,0x0000002a,0x000000ab,0x00000001,0x0000002b,0x000000a8,0x000000a9,
+ 0x000000aa,0x0003003e,0x0000005f,0x000000ab,0x0004003d,0x0000002a,0x000000ac,0x00000067,
+ 0x00070050,0x0000002a,0x000000ad,0x00000070,0x00000070,0x00000070,0x00000070,0x00070050,
+ 0x0000002a,0x000000ae,0x00000071,0x00000071,0x00000071,0x00000071,0x0008000c,0x0000002a,
+ 0x000000af,0x00000001,0x0000002b,0x000000ac,0x000000ad,0x000000ae,0x0003003e,0x00000067,
+ 0x000000af,0x0004003d,0x00000006,0x000000b0,0x00000034,0x0004003d,0x0000002a,0x000000b1,
+ 0x0000005f,0x0006000c,0x00000006,0x000000b2,0x00000001,0x00000037,0x000000b1,0x0004003d,
+ 0x0000002a,0x000000b3,0x00000067,0x0006000c,0x00000006,0x000000b4,0x00000001,0x00000037,
+ 0x000000b3,0x00050050,0x00000007,0x000000b5,0x000000b2,0x000000b4,0x00060041,0x00000026,
+ 0x000000b6,0x0000007c,0x00000017,0x000000b0,0x0003003e,0x000000b6,0x000000b5,0x00050041,
+ 0x00000010,0x000000b8,0x00000009,0x0000001b,0x0004003d,0x00000006,0x000000b9,0x000000b8,
+ 0x00050041,0x00000018,0x000000ba,0x00000015,0x00000017,0x0004003d,0x00000006,0x000000bb,
+ 0x000000ba,0x00050084,0x00000006,0x000000bc,0x000000b9,0x000000bb,0x00050041,0x00000010,
+ 0x000000bd,0x00000009,0x0000000f,0x0004003d,0x00000006,0x000000be,0x000000bd,0x00050080,
+ 0x00000006,0x000000bf,0x000000bc,0x000000be,0x0003003e,0x000000b7,0x000000bf,0x0004003d,
+ 0x00000006,0x000000c5,0x000000b7,0x00060041,0x00000026,0x000000c6,0x000000c4,0x00000017,
+ 0x000000c5,0x0004003d,0x00000007,0x000000c7,0x000000c6,0x0003003e,0x000000c0,0x000000c7,
+ 0x00050041,0x00000010,0x000000c9,0x000000c0,0x0000000f,0x0004003d,0x00000006,0x000000ca,
+ 0x000000c9,0x0006000c,0x0000002a,0x000000cb,0x00000001,0x00000040,0x000000ca,0x0003003e,
+ 0x000000c8,0x000000cb,0x00050041,0x00000010,0x000000cd,0x000000c0,0x0000001b,0x0004003d,
+ 0x00000006,0x000000ce,0x000000cd,0x0006000c,0x0000002a,0x000000cf,0x00000001,0x00000040,
+ 0x000000ce,0x0003003e,0x000000cc,0x000000cf,0x0004003d,0x00000006,0x000000d5,0x000000b7,
+ 0x00060041,0x00000026,0x000000d6,0x000000d4,0x00000017,0x000000d5,0x0004003d,0x00000007,
+ 0x000000d7,0x000000d6,0x0003003e,0x000000d0,0x000000d7,0x00050041,0x00000010,0x000000d9,
+ 0x000000d0,0x0000000f,0x0004003d,0x00000006,0x000000da,0x000000d9,0x0006000c,0x0000002a,
+ 0x000000db,0x00000001,0x00000040,0x000000da,0x0003003e,0x000000d8,0x000000db,0x00050041,
+ 0x00000010,0x000000dd,0x000000d0,0x0000001b,0x0004003d,0x00000006,0x000000de,0x000000dd,
+ 0x0006000c,0x0000002a,0x000000df,0x00000001,0x00000040,0x000000de,0x0003003e,0x000000dc,
+ 0x000000df,0x0004003d,0x0000002a,0x000000e1,0x0000002c,0x0007004f,0x000000e0,0x000000e2,
+ 0x000000e1,0x000000e1,0x00000000,0x00000002,0x0004003d,0x0000002a,0x000000e3,0x0000002c,
+ 0x0009004f,0x0000002a,0x000000e4,0x000000e3,0x000000e2,0x00000000,0x00000004,0x00000002,
+ 0x00000005,0x0003003e,0x0000002c,0x000000e4,0x0004003d,0x0000002a,0x000000e5,0x00000030,
+ 0x0007004f,0x000000e0,0x000000e6,0x000000e5,0x000000e5,0x00000000,0x00000002,0x0004003d,
+ 0x0000002a,0x000000e7,0x00000030,0x0009004f,0x0000002a,0x000000e8,0x000000e7,0x000000e6,
+ 0x00000000,0x00000004,0x00000002,0x00000005,0x0003003e,0x00000030,0x000000e8,0x0004003d,
+ 0x0000002a,0x000000ea,0x000000c8,0x0004003d,0x0000002a,0x000000eb,0x000000d8,0x00050083,
+ 0x0000002a,0x000000ec,0x000000ea,0x000000eb,0x0004003d,0x0000002a,0x000000ed,0x0000002c,
+ 0x00050085,0x0000002a,0x000000ee,0x000000ec,0x000000ed,0x0004003d,0x0000002a,0x000000ef,
+ 0x000000d8,0x00050081,0x0000002a,0x000000f0,0x000000ee,0x000000ef,0x0003003e,0x000000e9,
+ 0x000000f0,0x0004003d,0x0000002a,0x000000f2,0x000000cc,0x0004003d,0x0000002a,0x000000f3,
+ 0x000000dc,0x00050083,0x0000002a,0x000000f4,0x000000f2,0x000000f3,0x0004003d,0x0000002a,
+ 0x000000f5,0x00000030,0x00050085,0x0000002a,0x000000f6,0x000000f4,0x000000f5,0x0004003d,
+ 0x0000002a,0x000000f7,0x000000dc,0x00050081,0x0000002a,0x000000f8,0x000000f6,0x000000f7,
+ 0x0003003e,0x000000f1,0x000000f8,0x0004003d,0x0000002a,0x000000f9,0x000000e9,0x00070050,
+ 0x0000002a,0x000000fa,0x00000070,0x00000070,0x00000070,0x00000070,0x00070050,0x0000002a,
+ 0x000000fb,0x00000071,0x00000071,0x00000071,0x00000071,0x0008000c,0x0000002a,0x000000fc,
+ 0x00000001,0x0000002b,0x000000f9,0x000000fa,0x000000fb,0x0003003e,0x000000e9,0x000000fc,
+ 0x0004003d,0x0000002a,0x000000fd,0x000000f1,0x00070050,0x0000002a,0x000000fe,0x00000070,
+ 0x00000070,0x00000070,0x00000070,0x00070050,0x0000002a,0x000000ff,0x00000071,0x00000071,
+ 0x00000071,0x00000071,0x0008000c,0x0000002a,0x00000100,0x00000001,0x0000002b,0x000000fd,
+ 0x000000fe,0x000000ff,0x0003003e,0x000000f1,0x00000100,0x0004003d,0x00000006,0x00000105,
+ 0x000000b7,0x0004003d,0x0000002a,0x00000106,0x000000e9,0x0006000c,0x00000006,0x00000107,
+ 0x00000001,0x00000037,0x00000106,0x0004003d,0x0000002a,0x00000108,0x000000f1,0x0006000c,
+ 0x00000006,0x00000109,0x00000001,0x00000037,0x00000108,0x00050050,0x00000007,0x0000010a,
+ 0x00000107,0x00000109,0x00060041,0x00000026,0x0000010b,0x00000104,0x00000017,0x00000105,
+ 0x0003003e,0x0000010b,0x0000010a,0x000100fd,0x00010038
diff --git a/shaders/spv/shader_copy.comp b/shaders/spv/shader_copy.comp
new file mode 100644
index 0000000..876bdf7
--- /dev/null
+++ b/shaders/spv/shader_copy.comp
@@ -0,0 +1,28 @@
+#version 310 es
+
+layout (local_size_x = 8, local_size_y = 8) in;
+
+layout (binding = 0) readonly buffer InBuf {
+ uvec4 data[];
+} in_buf;
+
+layout (binding = 1) writeonly buffer OutBuf {
+ uvec4 data[];
+} out_buf;
+
+layout (push_constant) uniform PushConsts {
+ uint in_img_width;
+ uint in_x_offset;
+ uint out_img_width;
+ uint out_x_offset;
+ uint copy_width;
+} prop;
+
+void main ()
+{
+ uvec2 g_id = gl_GlobalInvocationID.xy;
+ g_id.x = min (g_id.x, prop.copy_width - 1u);
+
+ out_buf.data[g_id.y * prop.out_img_width + prop.out_x_offset + g_id.x] =
+ in_buf.data[g_id.y * prop.in_img_width + prop.in_x_offset + g_id.x];
+}
diff --git a/shaders/spv/shader_copy.comp.spv b/shaders/spv/shader_copy.comp.spv
new file mode 100644
index 0000000..240daab
--- /dev/null
+++ b/shaders/spv/shader_copy.comp.spv
@@ -0,0 +1,66 @@
+ // 7.8.2870
+ 0x07230203,0x00010000,0x00080007,0x00000048,0x00000000,0x00020011,0x00000001,0x0006000b,
+ 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,
+ 0x0006000f,0x00000005,0x00000004,0x6e69616d,0x00000000,0x0000000c,0x00060010,0x00000004,
+ 0x00000011,0x00000008,0x00000008,0x00000001,0x00030003,0x00000001,0x00000136,0x00040005,
+ 0x00000004,0x6e69616d,0x00000000,0x00040005,0x00000009,0x64695f67,0x00000000,0x00080005,
+ 0x0000000c,0x475f6c67,0x61626f6c,0x766e496c,0x7461636f,0x496e6f69,0x00000044,0x00050005,
+ 0x00000013,0x68737550,0x736e6f43,0x00007374,0x00070006,0x00000013,0x00000000,0x695f6e69,
+ 0x775f676d,0x68746469,0x00000000,0x00060006,0x00000013,0x00000001,0x785f6e69,0x66666f5f,
+ 0x00746573,0x00070006,0x00000013,0x00000002,0x5f74756f,0x5f676d69,0x74646977,0x00000068,
+ 0x00070006,0x00000013,0x00000003,0x5f74756f,0x666f5f78,0x74657366,0x00000000,0x00060006,
+ 0x00000013,0x00000004,0x79706f63,0x6469775f,0x00006874,0x00040005,0x00000015,0x706f7270,
+ 0x00000000,0x00040005,0x00000021,0x4274754f,0x00006675,0x00050006,0x00000021,0x00000000,
+ 0x61746164,0x00000000,0x00040005,0x00000023,0x5f74756f,0x00667562,0x00040005,0x00000033,
+ 0x75426e49,0x00000066,0x00050006,0x00000033,0x00000000,0x61746164,0x00000000,0x00040005,
+ 0x00000035,0x625f6e69,0x00006675,0x00040047,0x0000000c,0x0000000b,0x0000001c,0x00050048,
+ 0x00000013,0x00000000,0x00000023,0x00000000,0x00050048,0x00000013,0x00000001,0x00000023,
+ 0x00000004,0x00050048,0x00000013,0x00000002,0x00000023,0x00000008,0x00050048,0x00000013,
+ 0x00000003,0x00000023,0x0000000c,0x00050048,0x00000013,0x00000004,0x00000023,0x00000010,
+ 0x00030047,0x00000013,0x00000002,0x00040047,0x00000020,0x00000006,0x00000010,0x00040048,
+ 0x00000021,0x00000000,0x00000019,0x00050048,0x00000021,0x00000000,0x00000023,0x00000000,
+ 0x00030047,0x00000021,0x00000003,0x00040047,0x00000023,0x00000022,0x00000000,0x00040047,
+ 0x00000023,0x00000021,0x00000001,0x00040047,0x00000032,0x00000006,0x00000010,0x00040048,
+ 0x00000033,0x00000000,0x00000018,0x00050048,0x00000033,0x00000000,0x00000023,0x00000000,
+ 0x00030047,0x00000033,0x00000003,0x00040047,0x00000035,0x00000022,0x00000000,0x00040047,
+ 0x00000035,0x00000021,0x00000000,0x00040047,0x00000047,0x0000000b,0x00000019,0x00020013,
+ 0x00000002,0x00030021,0x00000003,0x00000002,0x00040015,0x00000006,0x00000020,0x00000000,
+ 0x00040017,0x00000007,0x00000006,0x00000002,0x00040020,0x00000008,0x00000007,0x00000007,
+ 0x00040017,0x0000000a,0x00000006,0x00000003,0x00040020,0x0000000b,0x00000001,0x0000000a,
+ 0x0004003b,0x0000000b,0x0000000c,0x00000001,0x0004002b,0x00000006,0x0000000f,0x00000000,
+ 0x00040020,0x00000010,0x00000007,0x00000006,0x0007001e,0x00000013,0x00000006,0x00000006,
+ 0x00000006,0x00000006,0x00000006,0x00040020,0x00000014,0x00000009,0x00000013,0x0004003b,
+ 0x00000014,0x00000015,0x00000009,0x00040015,0x00000016,0x00000020,0x00000001,0x0004002b,
+ 0x00000016,0x00000017,0x00000004,0x00040020,0x00000018,0x00000009,0x00000006,0x0004002b,
+ 0x00000006,0x0000001b,0x00000001,0x00040017,0x0000001f,0x00000006,0x00000004,0x0003001d,
+ 0x00000020,0x0000001f,0x0003001e,0x00000021,0x00000020,0x00040020,0x00000022,0x00000002,
+ 0x00000021,0x0004003b,0x00000022,0x00000023,0x00000002,0x0004002b,0x00000016,0x00000024,
+ 0x00000000,0x0004002b,0x00000016,0x00000027,0x00000002,0x0004002b,0x00000016,0x0000002b,
+ 0x00000003,0x0003001d,0x00000032,0x0000001f,0x0003001e,0x00000033,0x00000032,0x00040020,
+ 0x00000034,0x00000002,0x00000033,0x0004003b,0x00000034,0x00000035,0x00000002,0x0004002b,
+ 0x00000016,0x0000003b,0x00000001,0x00040020,0x00000042,0x00000002,0x0000001f,0x0004002b,
+ 0x00000006,0x00000046,0x00000008,0x0006002c,0x0000000a,0x00000047,0x00000046,0x00000046,
+ 0x0000001b,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,
+ 0x0004003b,0x00000008,0x00000009,0x00000007,0x0004003d,0x0000000a,0x0000000d,0x0000000c,
+ 0x0007004f,0x00000007,0x0000000e,0x0000000d,0x0000000d,0x00000000,0x00000001,0x0003003e,
+ 0x00000009,0x0000000e,0x00050041,0x00000010,0x00000011,0x00000009,0x0000000f,0x0004003d,
+ 0x00000006,0x00000012,0x00000011,0x00050041,0x00000018,0x00000019,0x00000015,0x00000017,
+ 0x0004003d,0x00000006,0x0000001a,0x00000019,0x00050082,0x00000006,0x0000001c,0x0000001a,
+ 0x0000001b,0x0007000c,0x00000006,0x0000001d,0x00000001,0x00000026,0x00000012,0x0000001c,
+ 0x00050041,0x00000010,0x0000001e,0x00000009,0x0000000f,0x0003003e,0x0000001e,0x0000001d,
+ 0x00050041,0x00000010,0x00000025,0x00000009,0x0000001b,0x0004003d,0x00000006,0x00000026,
+ 0x00000025,0x00050041,0x00000018,0x00000028,0x00000015,0x00000027,0x0004003d,0x00000006,
+ 0x00000029,0x00000028,0x00050084,0x00000006,0x0000002a,0x00000026,0x00000029,0x00050041,
+ 0x00000018,0x0000002c,0x00000015,0x0000002b,0x0004003d,0x00000006,0x0000002d,0x0000002c,
+ 0x00050080,0x00000006,0x0000002e,0x0000002a,0x0000002d,0x00050041,0x00000010,0x0000002f,
+ 0x00000009,0x0000000f,0x0004003d,0x00000006,0x00000030,0x0000002f,0x00050080,0x00000006,
+ 0x00000031,0x0000002e,0x00000030,0x00050041,0x00000010,0x00000036,0x00000009,0x0000001b,
+ 0x0004003d,0x00000006,0x00000037,0x00000036,0x00050041,0x00000018,0x00000038,0x00000015,
+ 0x00000024,0x0004003d,0x00000006,0x00000039,0x00000038,0x00050084,0x00000006,0x0000003a,
+ 0x00000037,0x00000039,0x00050041,0x00000018,0x0000003c,0x00000015,0x0000003b,0x0004003d,
+ 0x00000006,0x0000003d,0x0000003c,0x00050080,0x00000006,0x0000003e,0x0000003a,0x0000003d,
+ 0x00050041,0x00000010,0x0000003f,0x00000009,0x0000000f,0x0004003d,0x00000006,0x00000040,
+ 0x0000003f,0x00050080,0x00000006,0x00000041,0x0000003e,0x00000040,0x00060041,0x00000042,
+ 0x00000043,0x00000035,0x00000024,0x00000041,0x0004003d,0x0000001f,0x00000044,0x00000043,
+ 0x00060041,0x00000042,0x00000045,0x00000023,0x00000024,0x00000031,0x0003003e,0x00000045,
+ 0x00000044,0x000100fd,0x00010038
diff --git a/shaders/spv/shader_gauss_scale_pyr.comp b/shaders/spv/shader_gauss_scale_pyr.comp
new file mode 100644
index 0000000..fa9f49d
--- /dev/null
+++ b/shaders/spv/shader_gauss_scale_pyr.comp
@@ -0,0 +1,176 @@
+#version 310 es
+
+layout (local_size_x = 8, local_size_y = 8) in;
+
+layout (binding = 0) readonly buffer InBufY {
+ uint data[];
+} in_buf_y;
+
+layout (binding = 1) readonly buffer InBufUV {
+ uint data[];
+} in_buf_uv;
+
+layout (binding = 2) writeonly buffer OutBufY {
+ uint data[];
+} out_buf_y;
+
+layout (binding = 3) writeonly buffer OutBufUV {
+ uint data[];
+} out_buf_uv;
+
+layout (push_constant) uniform PushConsts {
+ uint in_img_width;
+ uint in_img_height;
+ uint in_offset_x;
+ uint out_img_width;
+ uint out_img_height;
+ uint merge_width;
+} prop;
+
+const float coeffs[5] = float[] (0.152f, 0.222f, 0.252f, 0.222f, 0.152f);
+
+#define unpack_unorm(buf, pixel, idx) \
+ { \
+ pixel[0] = unpackUnorm4x8 (buf.data[idx]); \
+ pixel[1] = unpackUnorm4x8 (buf.data[idx + 1u]); \
+ pixel[2] = unpackUnorm4x8 (buf.data[idx + 2u]); \
+ pixel[3] = unpackUnorm4x8 (buf.data[idx + 3u]); \
+ }
+
+#define multiply_coeff(sum, pixel, idx) \
+ { \
+ sum[0] += pixel[0] * coeffs[idx]; \
+ sum[1] += pixel[1] * coeffs[idx]; \
+ sum[2] += pixel[2] * coeffs[idx]; \
+ sum[3] += pixel[3] * coeffs[idx]; \
+ }
+
+void gauss_scale_y (uvec2 y_id, uvec2 g_id);
+void gauss_scale_uv (uvec2 uv_id);
+
+void main ()
+{
+ uvec2 g_id = gl_GlobalInvocationID.xy;
+ g_id.x = clamp (g_id.x, 0u, prop.merge_width - 1u);
+
+ uvec2 y_id = g_id * uvec2 (1u, 2u);
+ gauss_scale_y (y_id, g_id);
+
+ gauss_scale_uv (g_id);
+}
+
+void gauss_scale_y (uvec2 y_id, uvec2 g_id)
+{
+ uvec2 in_id = y_id * 2u;
+ uvec2 gauss_start = in_id - uvec2 (1u, 2u);
+ gauss_start.y = clamp (gauss_start.y, 0u, prop.in_img_height - 7u);
+
+ vec4 sum0[4] = vec4[] (vec4 (0.0f), vec4 (0.0f), vec4 (0.0f), vec4 (0.0f));
+ vec4 sum1[4] = vec4[] (vec4 (0.0f), vec4 (0.0f), vec4 (0.0f), vec4 (0.0f));
+
+ vec4 pixel_y[4];
+ uint in_idx = (in_id.y == 0u) ? (in_id.x - 1u) : (gauss_start.y * prop.in_img_width + gauss_start.x);
+ in_idx += prop.in_offset_x;
+ unpack_unorm (in_buf_y, pixel_y, in_idx);
+ multiply_coeff (sum0, pixel_y, 0u);
+
+ in_idx = (in_id.y == 0u) ? in_idx : (in_idx + prop.in_img_width);
+ unpack_unorm (in_buf_y, pixel_y, in_idx);
+ multiply_coeff (sum0, pixel_y, 1u);
+
+ in_idx = (in_id.y == 0u) ? in_idx : (in_idx + prop.in_img_width);
+ unpack_unorm (in_buf_y, pixel_y, in_idx);
+ multiply_coeff (sum0, pixel_y, 2u);
+ multiply_coeff (sum1, pixel_y, 0u);
+
+ in_idx += prop.in_img_width;
+ unpack_unorm (in_buf_y, pixel_y, in_idx);
+ multiply_coeff (sum0, pixel_y, 3u);
+ multiply_coeff (sum1, pixel_y, 1u);
+
+ in_idx += prop.in_img_width;
+ unpack_unorm (in_buf_y, pixel_y, in_idx);
+ multiply_coeff (sum0, pixel_y, 4u);
+ multiply_coeff (sum1, pixel_y, 2u);
+
+ in_idx += prop.in_img_width;
+ unpack_unorm (in_buf_y, pixel_y, in_idx);
+ multiply_coeff (sum1, pixel_y, 3u);
+
+ in_idx += prop.in_img_width;
+ unpack_unorm (in_buf_y, pixel_y, in_idx);
+ multiply_coeff (sum1, pixel_y, 4u);
+
+ sum0[0] = (in_id.x == 0u) ? vec4 (sum0[1].x) : sum0[0];
+ sum1[0] = (in_id.x == 0u) ? vec4 (sum1[1].x) : sum1[0];
+ sum0[3] = (in_id.x == prop.merge_width - 2u) ? vec4 (sum0[2].w) : sum0[3];
+ sum1[3] = (in_id.x == prop.merge_width - 2u) ? vec4 (sum1[2].w) : sum1[3];
+
+ vec4 out_data0 =
+ vec4 (sum0[0].z, sum0[1].x, sum0[1].z, sum0[2].x) * coeffs[0] +
+ vec4 (sum0[0].w, sum0[1].y, sum0[1].w, sum0[2].y) * coeffs[1] +
+ vec4 (sum0[1].x, sum0[1].z, sum0[2].x, sum0[2].z) * coeffs[2] +
+ vec4 (sum0[1].y, sum0[1].w, sum0[2].y, sum0[2].w) * coeffs[3] +
+ vec4 (sum0[1].z, sum0[2].x, sum0[2].z, sum0[3].x) * coeffs[4];
+
+ vec4 out_data1 =
+ vec4 (sum1[0].z, sum1[1].x, sum1[1].z, sum1[2].x) * coeffs[0] +
+ vec4 (sum1[0].w, sum1[1].y, sum1[1].w, sum1[2].y) * coeffs[1] +
+ vec4 (sum1[1].x, sum1[1].z, sum1[2].x, sum1[2].z) * coeffs[2] +
+ vec4 (sum1[1].y, sum1[1].w, sum1[2].y, sum1[2].w) * coeffs[3] +
+ vec4 (sum1[1].z, sum1[2].x, sum1[2].z, sum1[3].x) * coeffs[4];
+
+ out_data0 = clamp (out_data0, 0.0f, 1.0f);
+ out_data1 = clamp (out_data1, 0.0f, 1.0f);
+
+ y_id.x = clamp (y_id.x, 0u, prop.out_img_width - 1u);
+ y_id.y = clamp (y_id.y, 0u, prop.out_img_height - 2u);
+ uint out_idx = y_id.y * prop.out_img_width + y_id.x;
+ out_buf_y.data[out_idx] = packUnorm4x8 (out_data0);
+ out_buf_y.data[out_idx + prop.out_img_width] = packUnorm4x8 (out_data1);
+}
+
+void gauss_scale_uv (uvec2 uv_id)
+{
+ uvec2 in_id = uv_id * 2u;
+ uvec2 gauss_start = in_id - uvec2 (1u, 2u);
+ gauss_start.y = clamp (gauss_start.y, 0u, prop.in_img_height / 2u - 5u);
+
+ vec4 sum[4] = vec4[] (vec4 (0.0f), vec4 (0.0f), vec4 (0.0f), vec4 (0.0f));
+ uint in_idx = (in_id.y == 0u) ? (in_id.x - 1u) : (gauss_start.y * prop.in_img_width + gauss_start.x);
+ in_idx += prop.in_offset_x;
+
+ vec4 pixel_uv[4];
+ unpack_unorm (in_buf_uv, pixel_uv, in_idx);
+ multiply_coeff (sum, pixel_uv, 0u);
+
+ in_idx = (in_id.y == 0u) ? in_idx : (in_idx + prop.in_img_width);
+ unpack_unorm (in_buf_uv, pixel_uv, in_idx);
+ multiply_coeff (sum, pixel_uv, 1u);
+
+ in_idx = (in_id.y == 0u) ? in_idx : (in_idx + prop.in_img_width);
+ unpack_unorm (in_buf_uv, pixel_uv, in_idx);
+ multiply_coeff (sum, pixel_uv, 2u);
+
+ in_idx += prop.in_img_width;
+ unpack_unorm (in_buf_uv, pixel_uv, in_idx);
+ multiply_coeff (sum, pixel_uv, 3u);
+
+ in_idx += prop.in_img_width;
+ unpack_unorm (in_buf_uv, pixel_uv, in_idx);
+ multiply_coeff (sum, pixel_uv, 4u);
+
+ sum[0] = (in_id.x == 0u) ? vec4 (sum[1]) : sum[0];
+ sum[3] = (in_id.x == prop.merge_width - 2u) ? vec4 (sum[2]) : sum[3];
+
+ vec4 out_data =
+ vec4 (sum[0].x, sum[0].y, sum[1].x, sum[1].y) * coeffs[0] +
+ vec4 (sum[0].z, sum[0].w, sum[1].z, sum[1].w) * coeffs[1] +
+ vec4 (sum[1].x, sum[1].y, sum[2].x, sum[2].y) * coeffs[2] +
+ vec4 (sum[1].z, sum[1].w, sum[2].z, sum[2].w) * coeffs[3] +
+ vec4 (sum[2].x, sum[2].y, sum[3].x, sum[3].y) * coeffs[4];
+
+ out_data = clamp (out_data, 0.0f, 1.0f);
+ uv_id.x = clamp (uv_id.x, 0u, prop.out_img_width - 1u);
+ out_buf_uv.data[uv_id.y * prop.out_img_width + uv_id.x] = packUnorm4x8 (out_data);
+}
diff --git a/shaders/spv/shader_gauss_scale_pyr.comp.spv b/shaders/spv/shader_gauss_scale_pyr.comp.spv
new file mode 100644
index 0000000..16235d3
--- /dev/null
+++ b/shaders/spv/shader_gauss_scale_pyr.comp.spv
@@ -0,0 +1,891 @@
+ // 7.8.2870
+ 0x07230203,0x00010000,0x00080007,0x00000501,0x00000000,0x00020011,0x00000001,0x0006000b,
+ 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,
+ 0x0006000f,0x00000005,0x00000004,0x6e69616d,0x00000000,0x00000015,0x00060010,0x00000004,
+ 0x00000011,0x00000008,0x00000008,0x00000001,0x00030003,0x00000001,0x00000136,0x00040005,
+ 0x00000004,0x6e69616d,0x00000000,0x00080005,0x0000000c,0x73756167,0x63735f73,0x5f656c61,
+ 0x75762879,0x75763b32,0x00003b32,0x00040005,0x0000000a,0x64695f79,0x00000000,0x00040005,
+ 0x0000000b,0x64695f67,0x00000000,0x00070005,0x00000010,0x73756167,0x63735f73,0x5f656c61,
+ 0x76287675,0x003b3275,0x00040005,0x0000000f,0x695f7675,0x00000064,0x00040005,0x00000012,
+ 0x64695f67,0x00000000,0x00080005,0x00000015,0x475f6c67,0x61626f6c,0x766e496c,0x7461636f,
+ 0x496e6f69,0x00000044,0x00050005,0x0000001c,0x68737550,0x736e6f43,0x00007374,0x00070006,
+ 0x0000001c,0x00000000,0x695f6e69,0x775f676d,0x68746469,0x00000000,0x00070006,0x0000001c,
+ 0x00000001,0x695f6e69,0x685f676d,0x68676965,0x00000074,0x00060006,0x0000001c,0x00000002,
+ 0x6f5f6e69,0x65736666,0x00785f74,0x00070006,0x0000001c,0x00000003,0x5f74756f,0x5f676d69,
+ 0x74646977,0x00000068,0x00070006,0x0000001c,0x00000004,0x5f74756f,0x5f676d69,0x67696568,
+ 0x00007468,0x00060006,0x0000001c,0x00000005,0x6772656d,0x69775f65,0x00687464,0x00040005,
+ 0x0000001e,0x706f7270,0x00000000,0x00040005,0x00000028,0x64695f79,0x00000000,0x00040005,
+ 0x0000002d,0x61726170,0x0000006d,0x00040005,0x0000002f,0x61726170,0x0000006d,0x00040005,
+ 0x00000032,0x61726170,0x0000006d,0x00040005,0x00000035,0x695f6e69,0x00000064,0x00050005,
+ 0x00000039,0x73756167,0x74735f73,0x00747261,0x00040005,0x0000004a,0x306d7573,0x00000000,
+ 0x00040005,0x0000004e,0x316d7573,0x00000000,0x00040005,0x0000004f,0x695f6e69,0x00007864,
+ 0x00040005,0x0000006a,0x65786970,0x00795f6c,0x00040005,0x0000006c,0x75426e49,0x00005966,
+ 0x00050006,0x0000006c,0x00000000,0x61746164,0x00000000,0x00050005,0x0000006e,0x625f6e69,
+ 0x795f6675,0x00000000,0x00050005,0x00000298,0x5f74756f,0x61746164,0x00000030,0x00050005,
+ 0x000002cf,0x5f74756f,0x61746164,0x00000031,0x00040005,0x0000031e,0x5f74756f,0x00786469,
+ 0x00040005,0x00000328,0x4274754f,0x00596675,0x00050006,0x00000328,0x00000000,0x61746164,
+ 0x00000000,0x00050005,0x0000032a,0x5f74756f,0x5f667562,0x00000079,0x00040005,0x00000336,
+ 0x695f6e69,0x00000064,0x00050005,0x0000033a,0x73756167,0x74735f73,0x00747261,0x00030005,
+ 0x00000346,0x006d7573,0x00040005,0x00000347,0x695f6e69,0x00007864,0x00050005,0x0000035f,
+ 0x65786970,0x76755f6c,0x00000000,0x00040005,0x00000361,0x75426e49,0x00565566,0x00050006,
+ 0x00000361,0x00000000,0x61746164,0x00000000,0x00050005,0x00000363,0x625f6e69,0x755f6675,
+ 0x00000076,0x00050005,0x000004ac,0x5f74756f,0x61746164,0x00000000,0x00050005,0x000004ef,
+ 0x4274754f,0x56556675,0x00000000,0x00050006,0x000004ef,0x00000000,0x61746164,0x00000000,
+ 0x00050005,0x000004f1,0x5f74756f,0x5f667562,0x00007675,0x00040047,0x00000015,0x0000000b,
+ 0x0000001c,0x00050048,0x0000001c,0x00000000,0x00000023,0x00000000,0x00050048,0x0000001c,
+ 0x00000001,0x00000023,0x00000004,0x00050048,0x0000001c,0x00000002,0x00000023,0x00000008,
+ 0x00050048,0x0000001c,0x00000003,0x00000023,0x0000000c,0x00050048,0x0000001c,0x00000004,
+ 0x00000023,0x00000010,0x00050048,0x0000001c,0x00000005,0x00000023,0x00000014,0x00030047,
+ 0x0000001c,0x00000002,0x00040047,0x0000006b,0x00000006,0x00000004,0x00040048,0x0000006c,
+ 0x00000000,0x00000018,0x00050048,0x0000006c,0x00000000,0x00000023,0x00000000,0x00030047,
+ 0x0000006c,0x00000003,0x00040047,0x0000006e,0x00000022,0x00000000,0x00040047,0x0000006e,
+ 0x00000021,0x00000000,0x00040047,0x00000327,0x00000006,0x00000004,0x00040048,0x00000328,
+ 0x00000000,0x00000019,0x00050048,0x00000328,0x00000000,0x00000023,0x00000000,0x00030047,
+ 0x00000328,0x00000003,0x00040047,0x0000032a,0x00000022,0x00000000,0x00040047,0x0000032a,
+ 0x00000021,0x00000002,0x00040047,0x00000360,0x00000006,0x00000004,0x00040048,0x00000361,
+ 0x00000000,0x00000018,0x00050048,0x00000361,0x00000000,0x00000023,0x00000000,0x00030047,
+ 0x00000361,0x00000003,0x00040047,0x00000363,0x00000022,0x00000000,0x00040047,0x00000363,
+ 0x00000021,0x00000001,0x00040047,0x000004ee,0x00000006,0x00000004,0x00040048,0x000004ef,
+ 0x00000000,0x00000019,0x00050048,0x000004ef,0x00000000,0x00000023,0x00000000,0x00030047,
+ 0x000004ef,0x00000003,0x00040047,0x000004f1,0x00000022,0x00000000,0x00040047,0x000004f1,
+ 0x00000021,0x00000003,0x00040047,0x000004fe,0x0000000b,0x00000019,0x00020013,0x00000002,
+ 0x00030021,0x00000003,0x00000002,0x00040015,0x00000006,0x00000020,0x00000000,0x00040017,
+ 0x00000007,0x00000006,0x00000002,0x00040020,0x00000008,0x00000007,0x00000007,0x00050021,
+ 0x00000009,0x00000002,0x00000008,0x00000008,0x00040021,0x0000000e,0x00000002,0x00000008,
+ 0x00040017,0x00000013,0x00000006,0x00000003,0x00040020,0x00000014,0x00000001,0x00000013,
+ 0x0004003b,0x00000014,0x00000015,0x00000001,0x0004002b,0x00000006,0x00000018,0x00000000,
+ 0x00040020,0x00000019,0x00000007,0x00000006,0x0008001e,0x0000001c,0x00000006,0x00000006,
+ 0x00000006,0x00000006,0x00000006,0x00000006,0x00040020,0x0000001d,0x00000009,0x0000001c,
+ 0x0004003b,0x0000001d,0x0000001e,0x00000009,0x00040015,0x0000001f,0x00000020,0x00000001,
+ 0x0004002b,0x0000001f,0x00000020,0x00000005,0x00040020,0x00000021,0x00000009,0x00000006,
+ 0x0004002b,0x00000006,0x00000024,0x00000001,0x0004002b,0x00000006,0x0000002a,0x00000002,
+ 0x0005002c,0x00000007,0x0000002b,0x00000024,0x0000002a,0x0004002b,0x0000001f,0x0000003e,
+ 0x00000001,0x0004002b,0x00000006,0x00000041,0x00000007,0x00030016,0x00000045,0x00000020,
+ 0x00040017,0x00000046,0x00000045,0x00000004,0x0004002b,0x00000006,0x00000047,0x00000004,
+ 0x0004001c,0x00000048,0x00000046,0x00000047,0x00040020,0x00000049,0x00000007,0x00000048,
+ 0x0004002b,0x00000045,0x0000004b,0x00000000,0x0007002c,0x00000046,0x0000004c,0x0000004b,
+ 0x0000004b,0x0000004b,0x0000004b,0x0007002c,0x00000048,0x0000004d,0x0000004c,0x0000004c,
+ 0x0000004c,0x0000004c,0x00020014,0x00000052,0x0004002b,0x0000001f,0x0000005d,0x00000000,
+ 0x0004002b,0x0000001f,0x00000065,0x00000002,0x0003001d,0x0000006b,0x00000006,0x0003001e,
+ 0x0000006c,0x0000006b,0x00040020,0x0000006d,0x00000002,0x0000006c,0x0004003b,0x0000006d,
+ 0x0000006e,0x00000002,0x00040020,0x00000070,0x00000002,0x00000006,0x00040020,0x00000074,
+ 0x00000007,0x00000046,0x0004002b,0x0000001f,0x00000082,0x00000003,0x0004002b,0x00000006,
+ 0x00000084,0x00000003,0x0004002b,0x00000045,0x0000008c,0x3e1ba5e3,0x0004002b,0x00000045,
+ 0x000000cd,0x3e6353f8,0x0004002b,0x00000045,0x0000010e,0x3e810625,0x00040020,0x0000025f,
+ 0x00000007,0x00000045,0x0004002b,0x00000045,0x00000307,0x3f800000,0x0004002b,0x0000001f,
+ 0x00000318,0x00000004,0x0003001d,0x00000327,0x00000006,0x0003001e,0x00000328,0x00000327,
+ 0x00040020,0x00000329,0x00000002,0x00000328,0x0004003b,0x00000329,0x0000032a,0x00000002,
+ 0x0004002b,0x00000006,0x00000342,0x00000005,0x0003001d,0x00000360,0x00000006,0x0003001e,
+ 0x00000361,0x00000360,0x00040020,0x00000362,0x00000002,0x00000361,0x0004003b,0x00000362,
+ 0x00000363,0x00000002,0x0003001d,0x000004ee,0x00000006,0x0003001e,0x000004ef,0x000004ee,
+ 0x00040020,0x000004f0,0x00000002,0x000004ef,0x0004003b,0x000004f0,0x000004f1,0x00000002,
+ 0x0004002b,0x00000006,0x000004fd,0x00000008,0x0006002c,0x00000013,0x000004fe,0x000004fd,
+ 0x000004fd,0x00000024,0x0004001c,0x000004ff,0x00000045,0x00000342,0x0008002c,0x000004ff,
+ 0x00000500,0x0000008c,0x000000cd,0x0000010e,0x000000cd,0x0000008c,0x00050036,0x00000002,
+ 0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003b,0x00000008,0x00000012,
+ 0x00000007,0x0004003b,0x00000008,0x00000028,0x00000007,0x0004003b,0x00000008,0x0000002d,
+ 0x00000007,0x0004003b,0x00000008,0x0000002f,0x00000007,0x0004003b,0x00000008,0x00000032,
+ 0x00000007,0x0004003d,0x00000013,0x00000016,0x00000015,0x0007004f,0x00000007,0x00000017,
+ 0x00000016,0x00000016,0x00000000,0x00000001,0x0003003e,0x00000012,0x00000017,0x00050041,
+ 0x00000019,0x0000001a,0x00000012,0x00000018,0x0004003d,0x00000006,0x0000001b,0x0000001a,
+ 0x00050041,0x00000021,0x00000022,0x0000001e,0x00000020,0x0004003d,0x00000006,0x00000023,
+ 0x00000022,0x00050082,0x00000006,0x00000025,0x00000023,0x00000024,0x0008000c,0x00000006,
+ 0x00000026,0x00000001,0x0000002c,0x0000001b,0x00000018,0x00000025,0x00050041,0x00000019,
+ 0x00000027,0x00000012,0x00000018,0x0003003e,0x00000027,0x00000026,0x0004003d,0x00000007,
+ 0x00000029,0x00000012,0x00050084,0x00000007,0x0000002c,0x00000029,0x0000002b,0x0003003e,
+ 0x00000028,0x0000002c,0x0004003d,0x00000007,0x0000002e,0x00000028,0x0003003e,0x0000002d,
+ 0x0000002e,0x0004003d,0x00000007,0x00000030,0x00000012,0x0003003e,0x0000002f,0x00000030,
+ 0x00060039,0x00000002,0x00000031,0x0000000c,0x0000002d,0x0000002f,0x0004003d,0x00000007,
+ 0x00000033,0x00000012,0x0003003e,0x00000032,0x00000033,0x00050039,0x00000002,0x00000034,
+ 0x00000010,0x00000032,0x000100fd,0x00010038,0x00050036,0x00000002,0x0000000c,0x00000000,
+ 0x00000009,0x00030037,0x00000008,0x0000000a,0x00030037,0x00000008,0x0000000b,0x000200f8,
+ 0x0000000d,0x0004003b,0x00000008,0x00000035,0x00000007,0x0004003b,0x00000008,0x00000039,
+ 0x00000007,0x0004003b,0x00000049,0x0000004a,0x00000007,0x0004003b,0x00000049,0x0000004e,
+ 0x00000007,0x0004003b,0x00000019,0x0000004f,0x00000007,0x0004003b,0x00000019,0x00000054,
+ 0x00000007,0x0004003b,0x00000049,0x0000006a,0x00000007,0x0004003b,0x00000019,0x000000aa,
+ 0x00000007,0x0004003b,0x00000019,0x000000eb,0x00000007,0x0004003b,0x00000074,0x0000025c,
+ 0x00000007,0x0004003b,0x00000074,0x0000026b,0x00000007,0x0004003b,0x00000074,0x0000027c,
+ 0x00000007,0x0004003b,0x00000074,0x0000028d,0x00000007,0x0004003b,0x00000074,0x00000298,
+ 0x00000007,0x0004003b,0x00000074,0x000002cf,0x00000007,0x0004003b,0x00000019,0x0000031e,
+ 0x00000007,0x0004003d,0x00000007,0x00000036,0x0000000a,0x00050050,0x00000007,0x00000037,
+ 0x0000002a,0x0000002a,0x00050084,0x00000007,0x00000038,0x00000036,0x00000037,0x0003003e,
+ 0x00000035,0x00000038,0x0004003d,0x00000007,0x0000003a,0x00000035,0x00050082,0x00000007,
+ 0x0000003b,0x0000003a,0x0000002b,0x0003003e,0x00000039,0x0000003b,0x00050041,0x00000019,
+ 0x0000003c,0x00000039,0x00000024,0x0004003d,0x00000006,0x0000003d,0x0000003c,0x00050041,
+ 0x00000021,0x0000003f,0x0000001e,0x0000003e,0x0004003d,0x00000006,0x00000040,0x0000003f,
+ 0x00050082,0x00000006,0x00000042,0x00000040,0x00000041,0x0008000c,0x00000006,0x00000043,
+ 0x00000001,0x0000002c,0x0000003d,0x00000018,0x00000042,0x00050041,0x00000019,0x00000044,
+ 0x00000039,0x00000024,0x0003003e,0x00000044,0x00000043,0x0003003e,0x0000004a,0x0000004d,
+ 0x0003003e,0x0000004e,0x0000004d,0x00050041,0x00000019,0x00000050,0x00000035,0x00000024,
+ 0x0004003d,0x00000006,0x00000051,0x00000050,0x000500aa,0x00000052,0x00000053,0x00000051,
+ 0x00000018,0x000300f7,0x00000056,0x00000000,0x000400fa,0x00000053,0x00000055,0x0000005a,
+ 0x000200f8,0x00000055,0x00050041,0x00000019,0x00000057,0x00000035,0x00000018,0x0004003d,
+ 0x00000006,0x00000058,0x00000057,0x00050082,0x00000006,0x00000059,0x00000058,0x00000024,
+ 0x0003003e,0x00000054,0x00000059,0x000200f9,0x00000056,0x000200f8,0x0000005a,0x00050041,
+ 0x00000019,0x0000005b,0x00000039,0x00000024,0x0004003d,0x00000006,0x0000005c,0x0000005b,
+ 0x00050041,0x00000021,0x0000005e,0x0000001e,0x0000005d,0x0004003d,0x00000006,0x0000005f,
+ 0x0000005e,0x00050084,0x00000006,0x00000060,0x0000005c,0x0000005f,0x00050041,0x00000019,
+ 0x00000061,0x00000039,0x00000018,0x0004003d,0x00000006,0x00000062,0x00000061,0x00050080,
+ 0x00000006,0x00000063,0x00000060,0x00000062,0x0003003e,0x00000054,0x00000063,0x000200f9,
+ 0x00000056,0x000200f8,0x00000056,0x0004003d,0x00000006,0x00000064,0x00000054,0x0003003e,
+ 0x0000004f,0x00000064,0x00050041,0x00000021,0x00000066,0x0000001e,0x00000065,0x0004003d,
+ 0x00000006,0x00000067,0x00000066,0x0004003d,0x00000006,0x00000068,0x0000004f,0x00050080,
+ 0x00000006,0x00000069,0x00000068,0x00000067,0x0003003e,0x0000004f,0x00000069,0x0004003d,
+ 0x00000006,0x0000006f,0x0000004f,0x00060041,0x00000070,0x00000071,0x0000006e,0x0000005d,
+ 0x0000006f,0x0004003d,0x00000006,0x00000072,0x00000071,0x0006000c,0x00000046,0x00000073,
+ 0x00000001,0x00000040,0x00000072,0x00050041,0x00000074,0x00000075,0x0000006a,0x0000005d,
+ 0x0003003e,0x00000075,0x00000073,0x0004003d,0x00000006,0x00000076,0x0000004f,0x00050080,
+ 0x00000006,0x00000077,0x00000076,0x00000024,0x00060041,0x00000070,0x00000078,0x0000006e,
+ 0x0000005d,0x00000077,0x0004003d,0x00000006,0x00000079,0x00000078,0x0006000c,0x00000046,
+ 0x0000007a,0x00000001,0x00000040,0x00000079,0x00050041,0x00000074,0x0000007b,0x0000006a,
+ 0x0000003e,0x0003003e,0x0000007b,0x0000007a,0x0004003d,0x00000006,0x0000007c,0x0000004f,
+ 0x00050080,0x00000006,0x0000007d,0x0000007c,0x0000002a,0x00060041,0x00000070,0x0000007e,
+ 0x0000006e,0x0000005d,0x0000007d,0x0004003d,0x00000006,0x0000007f,0x0000007e,0x0006000c,
+ 0x00000046,0x00000080,0x00000001,0x00000040,0x0000007f,0x00050041,0x00000074,0x00000081,
+ 0x0000006a,0x00000065,0x0003003e,0x00000081,0x00000080,0x0004003d,0x00000006,0x00000083,
+ 0x0000004f,0x00050080,0x00000006,0x00000085,0x00000083,0x00000084,0x00060041,0x00000070,
+ 0x00000086,0x0000006e,0x0000005d,0x00000085,0x0004003d,0x00000006,0x00000087,0x00000086,
+ 0x0006000c,0x00000046,0x00000088,0x00000001,0x00000040,0x00000087,0x00050041,0x00000074,
+ 0x00000089,0x0000006a,0x00000082,0x0003003e,0x00000089,0x00000088,0x00050041,0x00000074,
+ 0x0000008a,0x0000006a,0x0000005d,0x0004003d,0x00000046,0x0000008b,0x0000008a,0x0005008e,
+ 0x00000046,0x0000008d,0x0000008b,0x0000008c,0x00050041,0x00000074,0x0000008e,0x0000004a,
+ 0x0000005d,0x0004003d,0x00000046,0x0000008f,0x0000008e,0x00050081,0x00000046,0x00000090,
+ 0x0000008f,0x0000008d,0x00050041,0x00000074,0x00000091,0x0000004a,0x0000005d,0x0003003e,
+ 0x00000091,0x00000090,0x00050041,0x00000074,0x00000092,0x0000006a,0x0000003e,0x0004003d,
+ 0x00000046,0x00000093,0x00000092,0x0005008e,0x00000046,0x00000094,0x00000093,0x0000008c,
+ 0x00050041,0x00000074,0x00000095,0x0000004a,0x0000003e,0x0004003d,0x00000046,0x00000096,
+ 0x00000095,0x00050081,0x00000046,0x00000097,0x00000096,0x00000094,0x00050041,0x00000074,
+ 0x00000098,0x0000004a,0x0000003e,0x0003003e,0x00000098,0x00000097,0x00050041,0x00000074,
+ 0x00000099,0x0000006a,0x00000065,0x0004003d,0x00000046,0x0000009a,0x00000099,0x0005008e,
+ 0x00000046,0x0000009b,0x0000009a,0x0000008c,0x00050041,0x00000074,0x0000009c,0x0000004a,
+ 0x00000065,0x0004003d,0x00000046,0x0000009d,0x0000009c,0x00050081,0x00000046,0x0000009e,
+ 0x0000009d,0x0000009b,0x00050041,0x00000074,0x0000009f,0x0000004a,0x00000065,0x0003003e,
+ 0x0000009f,0x0000009e,0x00050041,0x00000074,0x000000a0,0x0000006a,0x00000082,0x0004003d,
+ 0x00000046,0x000000a1,0x000000a0,0x0005008e,0x00000046,0x000000a2,0x000000a1,0x0000008c,
+ 0x00050041,0x00000074,0x000000a3,0x0000004a,0x00000082,0x0004003d,0x00000046,0x000000a4,
+ 0x000000a3,0x00050081,0x00000046,0x000000a5,0x000000a4,0x000000a2,0x00050041,0x00000074,
+ 0x000000a6,0x0000004a,0x00000082,0x0003003e,0x000000a6,0x000000a5,0x00050041,0x00000019,
+ 0x000000a7,0x00000035,0x00000024,0x0004003d,0x00000006,0x000000a8,0x000000a7,0x000500aa,
+ 0x00000052,0x000000a9,0x000000a8,0x00000018,0x000300f7,0x000000ac,0x00000000,0x000400fa,
+ 0x000000a9,0x000000ab,0x000000ae,0x000200f8,0x000000ab,0x0004003d,0x00000006,0x000000ad,
+ 0x0000004f,0x0003003e,0x000000aa,0x000000ad,0x000200f9,0x000000ac,0x000200f8,0x000000ae,
+ 0x0004003d,0x00000006,0x000000af,0x0000004f,0x00050041,0x00000021,0x000000b0,0x0000001e,
+ 0x0000005d,0x0004003d,0x00000006,0x000000b1,0x000000b0,0x00050080,0x00000006,0x000000b2,
+ 0x000000af,0x000000b1,0x0003003e,0x000000aa,0x000000b2,0x000200f9,0x000000ac,0x000200f8,
+ 0x000000ac,0x0004003d,0x00000006,0x000000b3,0x000000aa,0x0003003e,0x0000004f,0x000000b3,
+ 0x0004003d,0x00000006,0x000000b4,0x0000004f,0x00060041,0x00000070,0x000000b5,0x0000006e,
+ 0x0000005d,0x000000b4,0x0004003d,0x00000006,0x000000b6,0x000000b5,0x0006000c,0x00000046,
+ 0x000000b7,0x00000001,0x00000040,0x000000b6,0x00050041,0x00000074,0x000000b8,0x0000006a,
+ 0x0000005d,0x0003003e,0x000000b8,0x000000b7,0x0004003d,0x00000006,0x000000b9,0x0000004f,
+ 0x00050080,0x00000006,0x000000ba,0x000000b9,0x00000024,0x00060041,0x00000070,0x000000bb,
+ 0x0000006e,0x0000005d,0x000000ba,0x0004003d,0x00000006,0x000000bc,0x000000bb,0x0006000c,
+ 0x00000046,0x000000bd,0x00000001,0x00000040,0x000000bc,0x00050041,0x00000074,0x000000be,
+ 0x0000006a,0x0000003e,0x0003003e,0x000000be,0x000000bd,0x0004003d,0x00000006,0x000000bf,
+ 0x0000004f,0x00050080,0x00000006,0x000000c0,0x000000bf,0x0000002a,0x00060041,0x00000070,
+ 0x000000c1,0x0000006e,0x0000005d,0x000000c0,0x0004003d,0x00000006,0x000000c2,0x000000c1,
+ 0x0006000c,0x00000046,0x000000c3,0x00000001,0x00000040,0x000000c2,0x00050041,0x00000074,
+ 0x000000c4,0x0000006a,0x00000065,0x0003003e,0x000000c4,0x000000c3,0x0004003d,0x00000006,
+ 0x000000c5,0x0000004f,0x00050080,0x00000006,0x000000c6,0x000000c5,0x00000084,0x00060041,
+ 0x00000070,0x000000c7,0x0000006e,0x0000005d,0x000000c6,0x0004003d,0x00000006,0x000000c8,
+ 0x000000c7,0x0006000c,0x00000046,0x000000c9,0x00000001,0x00000040,0x000000c8,0x00050041,
+ 0x00000074,0x000000ca,0x0000006a,0x00000082,0x0003003e,0x000000ca,0x000000c9,0x00050041,
+ 0x00000074,0x000000cb,0x0000006a,0x0000005d,0x0004003d,0x00000046,0x000000cc,0x000000cb,
+ 0x0005008e,0x00000046,0x000000ce,0x000000cc,0x000000cd,0x00050041,0x00000074,0x000000cf,
+ 0x0000004a,0x0000005d,0x0004003d,0x00000046,0x000000d0,0x000000cf,0x00050081,0x00000046,
+ 0x000000d1,0x000000d0,0x000000ce,0x00050041,0x00000074,0x000000d2,0x0000004a,0x0000005d,
+ 0x0003003e,0x000000d2,0x000000d1,0x00050041,0x00000074,0x000000d3,0x0000006a,0x0000003e,
+ 0x0004003d,0x00000046,0x000000d4,0x000000d3,0x0005008e,0x00000046,0x000000d5,0x000000d4,
+ 0x000000cd,0x00050041,0x00000074,0x000000d6,0x0000004a,0x0000003e,0x0004003d,0x00000046,
+ 0x000000d7,0x000000d6,0x00050081,0x00000046,0x000000d8,0x000000d7,0x000000d5,0x00050041,
+ 0x00000074,0x000000d9,0x0000004a,0x0000003e,0x0003003e,0x000000d9,0x000000d8,0x00050041,
+ 0x00000074,0x000000da,0x0000006a,0x00000065,0x0004003d,0x00000046,0x000000db,0x000000da,
+ 0x0005008e,0x00000046,0x000000dc,0x000000db,0x000000cd,0x00050041,0x00000074,0x000000dd,
+ 0x0000004a,0x00000065,0x0004003d,0x00000046,0x000000de,0x000000dd,0x00050081,0x00000046,
+ 0x000000df,0x000000de,0x000000dc,0x00050041,0x00000074,0x000000e0,0x0000004a,0x00000065,
+ 0x0003003e,0x000000e0,0x000000df,0x00050041,0x00000074,0x000000e1,0x0000006a,0x00000082,
+ 0x0004003d,0x00000046,0x000000e2,0x000000e1,0x0005008e,0x00000046,0x000000e3,0x000000e2,
+ 0x000000cd,0x00050041,0x00000074,0x000000e4,0x0000004a,0x00000082,0x0004003d,0x00000046,
+ 0x000000e5,0x000000e4,0x00050081,0x00000046,0x000000e6,0x000000e5,0x000000e3,0x00050041,
+ 0x00000074,0x000000e7,0x0000004a,0x00000082,0x0003003e,0x000000e7,0x000000e6,0x00050041,
+ 0x00000019,0x000000e8,0x00000035,0x00000024,0x0004003d,0x00000006,0x000000e9,0x000000e8,
+ 0x000500aa,0x00000052,0x000000ea,0x000000e9,0x00000018,0x000300f7,0x000000ed,0x00000000,
+ 0x000400fa,0x000000ea,0x000000ec,0x000000ef,0x000200f8,0x000000ec,0x0004003d,0x00000006,
+ 0x000000ee,0x0000004f,0x0003003e,0x000000eb,0x000000ee,0x000200f9,0x000000ed,0x000200f8,
+ 0x000000ef,0x0004003d,0x00000006,0x000000f0,0x0000004f,0x00050041,0x00000021,0x000000f1,
+ 0x0000001e,0x0000005d,0x0004003d,0x00000006,0x000000f2,0x000000f1,0x00050080,0x00000006,
+ 0x000000f3,0x000000f0,0x000000f2,0x0003003e,0x000000eb,0x000000f3,0x000200f9,0x000000ed,
+ 0x000200f8,0x000000ed,0x0004003d,0x00000006,0x000000f4,0x000000eb,0x0003003e,0x0000004f,
+ 0x000000f4,0x0004003d,0x00000006,0x000000f5,0x0000004f,0x00060041,0x00000070,0x000000f6,
+ 0x0000006e,0x0000005d,0x000000f5,0x0004003d,0x00000006,0x000000f7,0x000000f6,0x0006000c,
+ 0x00000046,0x000000f8,0x00000001,0x00000040,0x000000f7,0x00050041,0x00000074,0x000000f9,
+ 0x0000006a,0x0000005d,0x0003003e,0x000000f9,0x000000f8,0x0004003d,0x00000006,0x000000fa,
+ 0x0000004f,0x00050080,0x00000006,0x000000fb,0x000000fa,0x00000024,0x00060041,0x00000070,
+ 0x000000fc,0x0000006e,0x0000005d,0x000000fb,0x0004003d,0x00000006,0x000000fd,0x000000fc,
+ 0x0006000c,0x00000046,0x000000fe,0x00000001,0x00000040,0x000000fd,0x00050041,0x00000074,
+ 0x000000ff,0x0000006a,0x0000003e,0x0003003e,0x000000ff,0x000000fe,0x0004003d,0x00000006,
+ 0x00000100,0x0000004f,0x00050080,0x00000006,0x00000101,0x00000100,0x0000002a,0x00060041,
+ 0x00000070,0x00000102,0x0000006e,0x0000005d,0x00000101,0x0004003d,0x00000006,0x00000103,
+ 0x00000102,0x0006000c,0x00000046,0x00000104,0x00000001,0x00000040,0x00000103,0x00050041,
+ 0x00000074,0x00000105,0x0000006a,0x00000065,0x0003003e,0x00000105,0x00000104,0x0004003d,
+ 0x00000006,0x00000106,0x0000004f,0x00050080,0x00000006,0x00000107,0x00000106,0x00000084,
+ 0x00060041,0x00000070,0x00000108,0x0000006e,0x0000005d,0x00000107,0x0004003d,0x00000006,
+ 0x00000109,0x00000108,0x0006000c,0x00000046,0x0000010a,0x00000001,0x00000040,0x00000109,
+ 0x00050041,0x00000074,0x0000010b,0x0000006a,0x00000082,0x0003003e,0x0000010b,0x0000010a,
+ 0x00050041,0x00000074,0x0000010c,0x0000006a,0x0000005d,0x0004003d,0x00000046,0x0000010d,
+ 0x0000010c,0x0005008e,0x00000046,0x0000010f,0x0000010d,0x0000010e,0x00050041,0x00000074,
+ 0x00000110,0x0000004a,0x0000005d,0x0004003d,0x00000046,0x00000111,0x00000110,0x00050081,
+ 0x00000046,0x00000112,0x00000111,0x0000010f,0x00050041,0x00000074,0x00000113,0x0000004a,
+ 0x0000005d,0x0003003e,0x00000113,0x00000112,0x00050041,0x00000074,0x00000114,0x0000006a,
+ 0x0000003e,0x0004003d,0x00000046,0x00000115,0x00000114,0x0005008e,0x00000046,0x00000116,
+ 0x00000115,0x0000010e,0x00050041,0x00000074,0x00000117,0x0000004a,0x0000003e,0x0004003d,
+ 0x00000046,0x00000118,0x00000117,0x00050081,0x00000046,0x00000119,0x00000118,0x00000116,
+ 0x00050041,0x00000074,0x0000011a,0x0000004a,0x0000003e,0x0003003e,0x0000011a,0x00000119,
+ 0x00050041,0x00000074,0x0000011b,0x0000006a,0x00000065,0x0004003d,0x00000046,0x0000011c,
+ 0x0000011b,0x0005008e,0x00000046,0x0000011d,0x0000011c,0x0000010e,0x00050041,0x00000074,
+ 0x0000011e,0x0000004a,0x00000065,0x0004003d,0x00000046,0x0000011f,0x0000011e,0x00050081,
+ 0x00000046,0x00000120,0x0000011f,0x0000011d,0x00050041,0x00000074,0x00000121,0x0000004a,
+ 0x00000065,0x0003003e,0x00000121,0x00000120,0x00050041,0x00000074,0x00000122,0x0000006a,
+ 0x00000082,0x0004003d,0x00000046,0x00000123,0x00000122,0x0005008e,0x00000046,0x00000124,
+ 0x00000123,0x0000010e,0x00050041,0x00000074,0x00000125,0x0000004a,0x00000082,0x0004003d,
+ 0x00000046,0x00000126,0x00000125,0x00050081,0x00000046,0x00000127,0x00000126,0x00000124,
+ 0x00050041,0x00000074,0x00000128,0x0000004a,0x00000082,0x0003003e,0x00000128,0x00000127,
+ 0x00050041,0x00000074,0x00000129,0x0000006a,0x0000005d,0x0004003d,0x00000046,0x0000012a,
+ 0x00000129,0x0005008e,0x00000046,0x0000012b,0x0000012a,0x0000008c,0x00050041,0x00000074,
+ 0x0000012c,0x0000004e,0x0000005d,0x0004003d,0x00000046,0x0000012d,0x0000012c,0x00050081,
+ 0x00000046,0x0000012e,0x0000012d,0x0000012b,0x00050041,0x00000074,0x0000012f,0x0000004e,
+ 0x0000005d,0x0003003e,0x0000012f,0x0000012e,0x00050041,0x00000074,0x00000130,0x0000006a,
+ 0x0000003e,0x0004003d,0x00000046,0x00000131,0x00000130,0x0005008e,0x00000046,0x00000132,
+ 0x00000131,0x0000008c,0x00050041,0x00000074,0x00000133,0x0000004e,0x0000003e,0x0004003d,
+ 0x00000046,0x00000134,0x00000133,0x00050081,0x00000046,0x00000135,0x00000134,0x00000132,
+ 0x00050041,0x00000074,0x00000136,0x0000004e,0x0000003e,0x0003003e,0x00000136,0x00000135,
+ 0x00050041,0x00000074,0x00000137,0x0000006a,0x00000065,0x0004003d,0x00000046,0x00000138,
+ 0x00000137,0x0005008e,0x00000046,0x00000139,0x00000138,0x0000008c,0x00050041,0x00000074,
+ 0x0000013a,0x0000004e,0x00000065,0x0004003d,0x00000046,0x0000013b,0x0000013a,0x00050081,
+ 0x00000046,0x0000013c,0x0000013b,0x00000139,0x00050041,0x00000074,0x0000013d,0x0000004e,
+ 0x00000065,0x0003003e,0x0000013d,0x0000013c,0x00050041,0x00000074,0x0000013e,0x0000006a,
+ 0x00000082,0x0004003d,0x00000046,0x0000013f,0x0000013e,0x0005008e,0x00000046,0x00000140,
+ 0x0000013f,0x0000008c,0x00050041,0x00000074,0x00000141,0x0000004e,0x00000082,0x0004003d,
+ 0x00000046,0x00000142,0x00000141,0x00050081,0x00000046,0x00000143,0x00000142,0x00000140,
+ 0x00050041,0x00000074,0x00000144,0x0000004e,0x00000082,0x0003003e,0x00000144,0x00000143,
+ 0x00050041,0x00000021,0x00000145,0x0000001e,0x0000005d,0x0004003d,0x00000006,0x00000146,
+ 0x00000145,0x0004003d,0x00000006,0x00000147,0x0000004f,0x00050080,0x00000006,0x00000148,
+ 0x00000147,0x00000146,0x0003003e,0x0000004f,0x00000148,0x0004003d,0x00000006,0x00000149,
+ 0x0000004f,0x00060041,0x00000070,0x0000014a,0x0000006e,0x0000005d,0x00000149,0x0004003d,
+ 0x00000006,0x0000014b,0x0000014a,0x0006000c,0x00000046,0x0000014c,0x00000001,0x00000040,
+ 0x0000014b,0x00050041,0x00000074,0x0000014d,0x0000006a,0x0000005d,0x0003003e,0x0000014d,
+ 0x0000014c,0x0004003d,0x00000006,0x0000014e,0x0000004f,0x00050080,0x00000006,0x0000014f,
+ 0x0000014e,0x00000024,0x00060041,0x00000070,0x00000150,0x0000006e,0x0000005d,0x0000014f,
+ 0x0004003d,0x00000006,0x00000151,0x00000150,0x0006000c,0x00000046,0x00000152,0x00000001,
+ 0x00000040,0x00000151,0x00050041,0x00000074,0x00000153,0x0000006a,0x0000003e,0x0003003e,
+ 0x00000153,0x00000152,0x0004003d,0x00000006,0x00000154,0x0000004f,0x00050080,0x00000006,
+ 0x00000155,0x00000154,0x0000002a,0x00060041,0x00000070,0x00000156,0x0000006e,0x0000005d,
+ 0x00000155,0x0004003d,0x00000006,0x00000157,0x00000156,0x0006000c,0x00000046,0x00000158,
+ 0x00000001,0x00000040,0x00000157,0x00050041,0x00000074,0x00000159,0x0000006a,0x00000065,
+ 0x0003003e,0x00000159,0x00000158,0x0004003d,0x00000006,0x0000015a,0x0000004f,0x00050080,
+ 0x00000006,0x0000015b,0x0000015a,0x00000084,0x00060041,0x00000070,0x0000015c,0x0000006e,
+ 0x0000005d,0x0000015b,0x0004003d,0x00000006,0x0000015d,0x0000015c,0x0006000c,0x00000046,
+ 0x0000015e,0x00000001,0x00000040,0x0000015d,0x00050041,0x00000074,0x0000015f,0x0000006a,
+ 0x00000082,0x0003003e,0x0000015f,0x0000015e,0x00050041,0x00000074,0x00000160,0x0000006a,
+ 0x0000005d,0x0004003d,0x00000046,0x00000161,0x00000160,0x0005008e,0x00000046,0x00000162,
+ 0x00000161,0x000000cd,0x00050041,0x00000074,0x00000163,0x0000004a,0x0000005d,0x0004003d,
+ 0x00000046,0x00000164,0x00000163,0x00050081,0x00000046,0x00000165,0x00000164,0x00000162,
+ 0x00050041,0x00000074,0x00000166,0x0000004a,0x0000005d,0x0003003e,0x00000166,0x00000165,
+ 0x00050041,0x00000074,0x00000167,0x0000006a,0x0000003e,0x0004003d,0x00000046,0x00000168,
+ 0x00000167,0x0005008e,0x00000046,0x00000169,0x00000168,0x000000cd,0x00050041,0x00000074,
+ 0x0000016a,0x0000004a,0x0000003e,0x0004003d,0x00000046,0x0000016b,0x0000016a,0x00050081,
+ 0x00000046,0x0000016c,0x0000016b,0x00000169,0x00050041,0x00000074,0x0000016d,0x0000004a,
+ 0x0000003e,0x0003003e,0x0000016d,0x0000016c,0x00050041,0x00000074,0x0000016e,0x0000006a,
+ 0x00000065,0x0004003d,0x00000046,0x0000016f,0x0000016e,0x0005008e,0x00000046,0x00000170,
+ 0x0000016f,0x000000cd,0x00050041,0x00000074,0x00000171,0x0000004a,0x00000065,0x0004003d,
+ 0x00000046,0x00000172,0x00000171,0x00050081,0x00000046,0x00000173,0x00000172,0x00000170,
+ 0x00050041,0x00000074,0x00000174,0x0000004a,0x00000065,0x0003003e,0x00000174,0x00000173,
+ 0x00050041,0x00000074,0x00000175,0x0000006a,0x00000082,0x0004003d,0x00000046,0x00000176,
+ 0x00000175,0x0005008e,0x00000046,0x00000177,0x00000176,0x000000cd,0x00050041,0x00000074,
+ 0x00000178,0x0000004a,0x00000082,0x0004003d,0x00000046,0x00000179,0x00000178,0x00050081,
+ 0x00000046,0x0000017a,0x00000179,0x00000177,0x00050041,0x00000074,0x0000017b,0x0000004a,
+ 0x00000082,0x0003003e,0x0000017b,0x0000017a,0x00050041,0x00000074,0x0000017c,0x0000006a,
+ 0x0000005d,0x0004003d,0x00000046,0x0000017d,0x0000017c,0x0005008e,0x00000046,0x0000017e,
+ 0x0000017d,0x000000cd,0x00050041,0x00000074,0x0000017f,0x0000004e,0x0000005d,0x0004003d,
+ 0x00000046,0x00000180,0x0000017f,0x00050081,0x00000046,0x00000181,0x00000180,0x0000017e,
+ 0x00050041,0x00000074,0x00000182,0x0000004e,0x0000005d,0x0003003e,0x00000182,0x00000181,
+ 0x00050041,0x00000074,0x00000183,0x0000006a,0x0000003e,0x0004003d,0x00000046,0x00000184,
+ 0x00000183,0x0005008e,0x00000046,0x00000185,0x00000184,0x000000cd,0x00050041,0x00000074,
+ 0x00000186,0x0000004e,0x0000003e,0x0004003d,0x00000046,0x00000187,0x00000186,0x00050081,
+ 0x00000046,0x00000188,0x00000187,0x00000185,0x00050041,0x00000074,0x00000189,0x0000004e,
+ 0x0000003e,0x0003003e,0x00000189,0x00000188,0x00050041,0x00000074,0x0000018a,0x0000006a,
+ 0x00000065,0x0004003d,0x00000046,0x0000018b,0x0000018a,0x0005008e,0x00000046,0x0000018c,
+ 0x0000018b,0x000000cd,0x00050041,0x00000074,0x0000018d,0x0000004e,0x00000065,0x0004003d,
+ 0x00000046,0x0000018e,0x0000018d,0x00050081,0x00000046,0x0000018f,0x0000018e,0x0000018c,
+ 0x00050041,0x00000074,0x00000190,0x0000004e,0x00000065,0x0003003e,0x00000190,0x0000018f,
+ 0x00050041,0x00000074,0x00000191,0x0000006a,0x00000082,0x0004003d,0x00000046,0x00000192,
+ 0x00000191,0x0005008e,0x00000046,0x00000193,0x00000192,0x000000cd,0x00050041,0x00000074,
+ 0x00000194,0x0000004e,0x00000082,0x0004003d,0x00000046,0x00000195,0x00000194,0x00050081,
+ 0x00000046,0x00000196,0x00000195,0x00000193,0x00050041,0x00000074,0x00000197,0x0000004e,
+ 0x00000082,0x0003003e,0x00000197,0x00000196,0x00050041,0x00000021,0x00000198,0x0000001e,
+ 0x0000005d,0x0004003d,0x00000006,0x00000199,0x00000198,0x0004003d,0x00000006,0x0000019a,
+ 0x0000004f,0x00050080,0x00000006,0x0000019b,0x0000019a,0x00000199,0x0003003e,0x0000004f,
+ 0x0000019b,0x0004003d,0x00000006,0x0000019c,0x0000004f,0x00060041,0x00000070,0x0000019d,
+ 0x0000006e,0x0000005d,0x0000019c,0x0004003d,0x00000006,0x0000019e,0x0000019d,0x0006000c,
+ 0x00000046,0x0000019f,0x00000001,0x00000040,0x0000019e,0x00050041,0x00000074,0x000001a0,
+ 0x0000006a,0x0000005d,0x0003003e,0x000001a0,0x0000019f,0x0004003d,0x00000006,0x000001a1,
+ 0x0000004f,0x00050080,0x00000006,0x000001a2,0x000001a1,0x00000024,0x00060041,0x00000070,
+ 0x000001a3,0x0000006e,0x0000005d,0x000001a2,0x0004003d,0x00000006,0x000001a4,0x000001a3,
+ 0x0006000c,0x00000046,0x000001a5,0x00000001,0x00000040,0x000001a4,0x00050041,0x00000074,
+ 0x000001a6,0x0000006a,0x0000003e,0x0003003e,0x000001a6,0x000001a5,0x0004003d,0x00000006,
+ 0x000001a7,0x0000004f,0x00050080,0x00000006,0x000001a8,0x000001a7,0x0000002a,0x00060041,
+ 0x00000070,0x000001a9,0x0000006e,0x0000005d,0x000001a8,0x0004003d,0x00000006,0x000001aa,
+ 0x000001a9,0x0006000c,0x00000046,0x000001ab,0x00000001,0x00000040,0x000001aa,0x00050041,
+ 0x00000074,0x000001ac,0x0000006a,0x00000065,0x0003003e,0x000001ac,0x000001ab,0x0004003d,
+ 0x00000006,0x000001ad,0x0000004f,0x00050080,0x00000006,0x000001ae,0x000001ad,0x00000084,
+ 0x00060041,0x00000070,0x000001af,0x0000006e,0x0000005d,0x000001ae,0x0004003d,0x00000006,
+ 0x000001b0,0x000001af,0x0006000c,0x00000046,0x000001b1,0x00000001,0x00000040,0x000001b0,
+ 0x00050041,0x00000074,0x000001b2,0x0000006a,0x00000082,0x0003003e,0x000001b2,0x000001b1,
+ 0x00050041,0x00000074,0x000001b3,0x0000006a,0x0000005d,0x0004003d,0x00000046,0x000001b4,
+ 0x000001b3,0x0005008e,0x00000046,0x000001b5,0x000001b4,0x0000008c,0x00050041,0x00000074,
+ 0x000001b6,0x0000004a,0x0000005d,0x0004003d,0x00000046,0x000001b7,0x000001b6,0x00050081,
+ 0x00000046,0x000001b8,0x000001b7,0x000001b5,0x00050041,0x00000074,0x000001b9,0x0000004a,
+ 0x0000005d,0x0003003e,0x000001b9,0x000001b8,0x00050041,0x00000074,0x000001ba,0x0000006a,
+ 0x0000003e,0x0004003d,0x00000046,0x000001bb,0x000001ba,0x0005008e,0x00000046,0x000001bc,
+ 0x000001bb,0x0000008c,0x00050041,0x00000074,0x000001bd,0x0000004a,0x0000003e,0x0004003d,
+ 0x00000046,0x000001be,0x000001bd,0x00050081,0x00000046,0x000001bf,0x000001be,0x000001bc,
+ 0x00050041,0x00000074,0x000001c0,0x0000004a,0x0000003e,0x0003003e,0x000001c0,0x000001bf,
+ 0x00050041,0x00000074,0x000001c1,0x0000006a,0x00000065,0x0004003d,0x00000046,0x000001c2,
+ 0x000001c1,0x0005008e,0x00000046,0x000001c3,0x000001c2,0x0000008c,0x00050041,0x00000074,
+ 0x000001c4,0x0000004a,0x00000065,0x0004003d,0x00000046,0x000001c5,0x000001c4,0x00050081,
+ 0x00000046,0x000001c6,0x000001c5,0x000001c3,0x00050041,0x00000074,0x000001c7,0x0000004a,
+ 0x00000065,0x0003003e,0x000001c7,0x000001c6,0x00050041,0x00000074,0x000001c8,0x0000006a,
+ 0x00000082,0x0004003d,0x00000046,0x000001c9,0x000001c8,0x0005008e,0x00000046,0x000001ca,
+ 0x000001c9,0x0000008c,0x00050041,0x00000074,0x000001cb,0x0000004a,0x00000082,0x0004003d,
+ 0x00000046,0x000001cc,0x000001cb,0x00050081,0x00000046,0x000001cd,0x000001cc,0x000001ca,
+ 0x00050041,0x00000074,0x000001ce,0x0000004a,0x00000082,0x0003003e,0x000001ce,0x000001cd,
+ 0x00050041,0x00000074,0x000001cf,0x0000006a,0x0000005d,0x0004003d,0x00000046,0x000001d0,
+ 0x000001cf,0x0005008e,0x00000046,0x000001d1,0x000001d0,0x0000010e,0x00050041,0x00000074,
+ 0x000001d2,0x0000004e,0x0000005d,0x0004003d,0x00000046,0x000001d3,0x000001d2,0x00050081,
+ 0x00000046,0x000001d4,0x000001d3,0x000001d1,0x00050041,0x00000074,0x000001d5,0x0000004e,
+ 0x0000005d,0x0003003e,0x000001d5,0x000001d4,0x00050041,0x00000074,0x000001d6,0x0000006a,
+ 0x0000003e,0x0004003d,0x00000046,0x000001d7,0x000001d6,0x0005008e,0x00000046,0x000001d8,
+ 0x000001d7,0x0000010e,0x00050041,0x00000074,0x000001d9,0x0000004e,0x0000003e,0x0004003d,
+ 0x00000046,0x000001da,0x000001d9,0x00050081,0x00000046,0x000001db,0x000001da,0x000001d8,
+ 0x00050041,0x00000074,0x000001dc,0x0000004e,0x0000003e,0x0003003e,0x000001dc,0x000001db,
+ 0x00050041,0x00000074,0x000001dd,0x0000006a,0x00000065,0x0004003d,0x00000046,0x000001de,
+ 0x000001dd,0x0005008e,0x00000046,0x000001df,0x000001de,0x0000010e,0x00050041,0x00000074,
+ 0x000001e0,0x0000004e,0x00000065,0x0004003d,0x00000046,0x000001e1,0x000001e0,0x00050081,
+ 0x00000046,0x000001e2,0x000001e1,0x000001df,0x00050041,0x00000074,0x000001e3,0x0000004e,
+ 0x00000065,0x0003003e,0x000001e3,0x000001e2,0x00050041,0x00000074,0x000001e4,0x0000006a,
+ 0x00000082,0x0004003d,0x00000046,0x000001e5,0x000001e4,0x0005008e,0x00000046,0x000001e6,
+ 0x000001e5,0x0000010e,0x00050041,0x00000074,0x000001e7,0x0000004e,0x00000082,0x0004003d,
+ 0x00000046,0x000001e8,0x000001e7,0x00050081,0x00000046,0x000001e9,0x000001e8,0x000001e6,
+ 0x00050041,0x00000074,0x000001ea,0x0000004e,0x00000082,0x0003003e,0x000001ea,0x000001e9,
+ 0x00050041,0x00000021,0x000001eb,0x0000001e,0x0000005d,0x0004003d,0x00000006,0x000001ec,
+ 0x000001eb,0x0004003d,0x00000006,0x000001ed,0x0000004f,0x00050080,0x00000006,0x000001ee,
+ 0x000001ed,0x000001ec,0x0003003e,0x0000004f,0x000001ee,0x0004003d,0x00000006,0x000001ef,
+ 0x0000004f,0x00060041,0x00000070,0x000001f0,0x0000006e,0x0000005d,0x000001ef,0x0004003d,
+ 0x00000006,0x000001f1,0x000001f0,0x0006000c,0x00000046,0x000001f2,0x00000001,0x00000040,
+ 0x000001f1,0x00050041,0x00000074,0x000001f3,0x0000006a,0x0000005d,0x0003003e,0x000001f3,
+ 0x000001f2,0x0004003d,0x00000006,0x000001f4,0x0000004f,0x00050080,0x00000006,0x000001f5,
+ 0x000001f4,0x00000024,0x00060041,0x00000070,0x000001f6,0x0000006e,0x0000005d,0x000001f5,
+ 0x0004003d,0x00000006,0x000001f7,0x000001f6,0x0006000c,0x00000046,0x000001f8,0x00000001,
+ 0x00000040,0x000001f7,0x00050041,0x00000074,0x000001f9,0x0000006a,0x0000003e,0x0003003e,
+ 0x000001f9,0x000001f8,0x0004003d,0x00000006,0x000001fa,0x0000004f,0x00050080,0x00000006,
+ 0x000001fb,0x000001fa,0x0000002a,0x00060041,0x00000070,0x000001fc,0x0000006e,0x0000005d,
+ 0x000001fb,0x0004003d,0x00000006,0x000001fd,0x000001fc,0x0006000c,0x00000046,0x000001fe,
+ 0x00000001,0x00000040,0x000001fd,0x00050041,0x00000074,0x000001ff,0x0000006a,0x00000065,
+ 0x0003003e,0x000001ff,0x000001fe,0x0004003d,0x00000006,0x00000200,0x0000004f,0x00050080,
+ 0x00000006,0x00000201,0x00000200,0x00000084,0x00060041,0x00000070,0x00000202,0x0000006e,
+ 0x0000005d,0x00000201,0x0004003d,0x00000006,0x00000203,0x00000202,0x0006000c,0x00000046,
+ 0x00000204,0x00000001,0x00000040,0x00000203,0x00050041,0x00000074,0x00000205,0x0000006a,
+ 0x00000082,0x0003003e,0x00000205,0x00000204,0x00050041,0x00000074,0x00000206,0x0000006a,
+ 0x0000005d,0x0004003d,0x00000046,0x00000207,0x00000206,0x0005008e,0x00000046,0x00000208,
+ 0x00000207,0x000000cd,0x00050041,0x00000074,0x00000209,0x0000004e,0x0000005d,0x0004003d,
+ 0x00000046,0x0000020a,0x00000209,0x00050081,0x00000046,0x0000020b,0x0000020a,0x00000208,
+ 0x00050041,0x00000074,0x0000020c,0x0000004e,0x0000005d,0x0003003e,0x0000020c,0x0000020b,
+ 0x00050041,0x00000074,0x0000020d,0x0000006a,0x0000003e,0x0004003d,0x00000046,0x0000020e,
+ 0x0000020d,0x0005008e,0x00000046,0x0000020f,0x0000020e,0x000000cd,0x00050041,0x00000074,
+ 0x00000210,0x0000004e,0x0000003e,0x0004003d,0x00000046,0x00000211,0x00000210,0x00050081,
+ 0x00000046,0x00000212,0x00000211,0x0000020f,0x00050041,0x00000074,0x00000213,0x0000004e,
+ 0x0000003e,0x0003003e,0x00000213,0x00000212,0x00050041,0x00000074,0x00000214,0x0000006a,
+ 0x00000065,0x0004003d,0x00000046,0x00000215,0x00000214,0x0005008e,0x00000046,0x00000216,
+ 0x00000215,0x000000cd,0x00050041,0x00000074,0x00000217,0x0000004e,0x00000065,0x0004003d,
+ 0x00000046,0x00000218,0x00000217,0x00050081,0x00000046,0x00000219,0x00000218,0x00000216,
+ 0x00050041,0x00000074,0x0000021a,0x0000004e,0x00000065,0x0003003e,0x0000021a,0x00000219,
+ 0x00050041,0x00000074,0x0000021b,0x0000006a,0x00000082,0x0004003d,0x00000046,0x0000021c,
+ 0x0000021b,0x0005008e,0x00000046,0x0000021d,0x0000021c,0x000000cd,0x00050041,0x00000074,
+ 0x0000021e,0x0000004e,0x00000082,0x0004003d,0x00000046,0x0000021f,0x0000021e,0x00050081,
+ 0x00000046,0x00000220,0x0000021f,0x0000021d,0x00050041,0x00000074,0x00000221,0x0000004e,
+ 0x00000082,0x0003003e,0x00000221,0x00000220,0x00050041,0x00000021,0x00000222,0x0000001e,
+ 0x0000005d,0x0004003d,0x00000006,0x00000223,0x00000222,0x0004003d,0x00000006,0x00000224,
+ 0x0000004f,0x00050080,0x00000006,0x00000225,0x00000224,0x00000223,0x0003003e,0x0000004f,
+ 0x00000225,0x0004003d,0x00000006,0x00000226,0x0000004f,0x00060041,0x00000070,0x00000227,
+ 0x0000006e,0x0000005d,0x00000226,0x0004003d,0x00000006,0x00000228,0x00000227,0x0006000c,
+ 0x00000046,0x00000229,0x00000001,0x00000040,0x00000228,0x00050041,0x00000074,0x0000022a,
+ 0x0000006a,0x0000005d,0x0003003e,0x0000022a,0x00000229,0x0004003d,0x00000006,0x0000022b,
+ 0x0000004f,0x00050080,0x00000006,0x0000022c,0x0000022b,0x00000024,0x00060041,0x00000070,
+ 0x0000022d,0x0000006e,0x0000005d,0x0000022c,0x0004003d,0x00000006,0x0000022e,0x0000022d,
+ 0x0006000c,0x00000046,0x0000022f,0x00000001,0x00000040,0x0000022e,0x00050041,0x00000074,
+ 0x00000230,0x0000006a,0x0000003e,0x0003003e,0x00000230,0x0000022f,0x0004003d,0x00000006,
+ 0x00000231,0x0000004f,0x00050080,0x00000006,0x00000232,0x00000231,0x0000002a,0x00060041,
+ 0x00000070,0x00000233,0x0000006e,0x0000005d,0x00000232,0x0004003d,0x00000006,0x00000234,
+ 0x00000233,0x0006000c,0x00000046,0x00000235,0x00000001,0x00000040,0x00000234,0x00050041,
+ 0x00000074,0x00000236,0x0000006a,0x00000065,0x0003003e,0x00000236,0x00000235,0x0004003d,
+ 0x00000006,0x00000237,0x0000004f,0x00050080,0x00000006,0x00000238,0x00000237,0x00000084,
+ 0x00060041,0x00000070,0x00000239,0x0000006e,0x0000005d,0x00000238,0x0004003d,0x00000006,
+ 0x0000023a,0x00000239,0x0006000c,0x00000046,0x0000023b,0x00000001,0x00000040,0x0000023a,
+ 0x00050041,0x00000074,0x0000023c,0x0000006a,0x00000082,0x0003003e,0x0000023c,0x0000023b,
+ 0x00050041,0x00000074,0x0000023d,0x0000006a,0x0000005d,0x0004003d,0x00000046,0x0000023e,
+ 0x0000023d,0x0005008e,0x00000046,0x0000023f,0x0000023e,0x0000008c,0x00050041,0x00000074,
+ 0x00000240,0x0000004e,0x0000005d,0x0004003d,0x00000046,0x00000241,0x00000240,0x00050081,
+ 0x00000046,0x00000242,0x00000241,0x0000023f,0x00050041,0x00000074,0x00000243,0x0000004e,
+ 0x0000005d,0x0003003e,0x00000243,0x00000242,0x00050041,0x00000074,0x00000244,0x0000006a,
+ 0x0000003e,0x0004003d,0x00000046,0x00000245,0x00000244,0x0005008e,0x00000046,0x00000246,
+ 0x00000245,0x0000008c,0x00050041,0x00000074,0x00000247,0x0000004e,0x0000003e,0x0004003d,
+ 0x00000046,0x00000248,0x00000247,0x00050081,0x00000046,0x00000249,0x00000248,0x00000246,
+ 0x00050041,0x00000074,0x0000024a,0x0000004e,0x0000003e,0x0003003e,0x0000024a,0x00000249,
+ 0x00050041,0x00000074,0x0000024b,0x0000006a,0x00000065,0x0004003d,0x00000046,0x0000024c,
+ 0x0000024b,0x0005008e,0x00000046,0x0000024d,0x0000024c,0x0000008c,0x00050041,0x00000074,
+ 0x0000024e,0x0000004e,0x00000065,0x0004003d,0x00000046,0x0000024f,0x0000024e,0x00050081,
+ 0x00000046,0x00000250,0x0000024f,0x0000024d,0x00050041,0x00000074,0x00000251,0x0000004e,
+ 0x00000065,0x0003003e,0x00000251,0x00000250,0x00050041,0x00000074,0x00000252,0x0000006a,
+ 0x00000082,0x0004003d,0x00000046,0x00000253,0x00000252,0x0005008e,0x00000046,0x00000254,
+ 0x00000253,0x0000008c,0x00050041,0x00000074,0x00000255,0x0000004e,0x00000082,0x0004003d,
+ 0x00000046,0x00000256,0x00000255,0x00050081,0x00000046,0x00000257,0x00000256,0x00000254,
+ 0x00050041,0x00000074,0x00000258,0x0000004e,0x00000082,0x0003003e,0x00000258,0x00000257,
+ 0x00050041,0x00000019,0x00000259,0x00000035,0x00000018,0x0004003d,0x00000006,0x0000025a,
+ 0x00000259,0x000500aa,0x00000052,0x0000025b,0x0000025a,0x00000018,0x000300f7,0x0000025e,
+ 0x00000000,0x000400fa,0x0000025b,0x0000025d,0x00000263,0x000200f8,0x0000025d,0x00060041,
+ 0x0000025f,0x00000260,0x0000004a,0x0000003e,0x00000018,0x0004003d,0x00000045,0x00000261,
+ 0x00000260,0x00070050,0x00000046,0x00000262,0x00000261,0x00000261,0x00000261,0x00000261,
+ 0x0003003e,0x0000025c,0x00000262,0x000200f9,0x0000025e,0x000200f8,0x00000263,0x00050041,
+ 0x00000074,0x00000264,0x0000004a,0x0000005d,0x0004003d,0x00000046,0x00000265,0x00000264,
+ 0x0003003e,0x0000025c,0x00000265,0x000200f9,0x0000025e,0x000200f8,0x0000025e,0x0004003d,
+ 0x00000046,0x00000266,0x0000025c,0x00050041,0x00000074,0x00000267,0x0000004a,0x0000005d,
+ 0x0003003e,0x00000267,0x00000266,0x00050041,0x00000019,0x00000268,0x00000035,0x00000018,
+ 0x0004003d,0x00000006,0x00000269,0x00000268,0x000500aa,0x00000052,0x0000026a,0x00000269,
+ 0x00000018,0x000300f7,0x0000026d,0x00000000,0x000400fa,0x0000026a,0x0000026c,0x00000271,
+ 0x000200f8,0x0000026c,0x00060041,0x0000025f,0x0000026e,0x0000004e,0x0000003e,0x00000018,
+ 0x0004003d,0x00000045,0x0000026f,0x0000026e,0x00070050,0x00000046,0x00000270,0x0000026f,
+ 0x0000026f,0x0000026f,0x0000026f,0x0003003e,0x0000026b,0x00000270,0x000200f9,0x0000026d,
+ 0x000200f8,0x00000271,0x00050041,0x00000074,0x00000272,0x0000004e,0x0000005d,0x0004003d,
+ 0x00000046,0x00000273,0x00000272,0x0003003e,0x0000026b,0x00000273,0x000200f9,0x0000026d,
+ 0x000200f8,0x0000026d,0x0004003d,0x00000046,0x00000274,0x0000026b,0x00050041,0x00000074,
+ 0x00000275,0x0000004e,0x0000005d,0x0003003e,0x00000275,0x00000274,0x00050041,0x00000019,
+ 0x00000276,0x00000035,0x00000018,0x0004003d,0x00000006,0x00000277,0x00000276,0x00050041,
+ 0x00000021,0x00000278,0x0000001e,0x00000020,0x0004003d,0x00000006,0x00000279,0x00000278,
+ 0x00050082,0x00000006,0x0000027a,0x00000279,0x0000002a,0x000500aa,0x00000052,0x0000027b,
+ 0x00000277,0x0000027a,0x000300f7,0x0000027e,0x00000000,0x000400fa,0x0000027b,0x0000027d,
+ 0x00000282,0x000200f8,0x0000027d,0x00060041,0x0000025f,0x0000027f,0x0000004a,0x00000065,
+ 0x00000084,0x0004003d,0x00000045,0x00000280,0x0000027f,0x00070050,0x00000046,0x00000281,
+ 0x00000280,0x00000280,0x00000280,0x00000280,0x0003003e,0x0000027c,0x00000281,0x000200f9,
+ 0x0000027e,0x000200f8,0x00000282,0x00050041,0x00000074,0x00000283,0x0000004a,0x00000082,
+ 0x0004003d,0x00000046,0x00000284,0x00000283,0x0003003e,0x0000027c,0x00000284,0x000200f9,
+ 0x0000027e,0x000200f8,0x0000027e,0x0004003d,0x00000046,0x00000285,0x0000027c,0x00050041,
+ 0x00000074,0x00000286,0x0000004a,0x00000082,0x0003003e,0x00000286,0x00000285,0x00050041,
+ 0x00000019,0x00000287,0x00000035,0x00000018,0x0004003d,0x00000006,0x00000288,0x00000287,
+ 0x00050041,0x00000021,0x00000289,0x0000001e,0x00000020,0x0004003d,0x00000006,0x0000028a,
+ 0x00000289,0x00050082,0x00000006,0x0000028b,0x0000028a,0x0000002a,0x000500aa,0x00000052,
+ 0x0000028c,0x00000288,0x0000028b,0x000300f7,0x0000028f,0x00000000,0x000400fa,0x0000028c,
+ 0x0000028e,0x00000293,0x000200f8,0x0000028e,0x00060041,0x0000025f,0x00000290,0x0000004e,
+ 0x00000065,0x00000084,0x0004003d,0x00000045,0x00000291,0x00000290,0x00070050,0x00000046,
+ 0x00000292,0x00000291,0x00000291,0x00000291,0x00000291,0x0003003e,0x0000028d,0x00000292,
+ 0x000200f9,0x0000028f,0x000200f8,0x00000293,0x00050041,0x00000074,0x00000294,0x0000004e,
+ 0x00000082,0x0004003d,0x00000046,0x00000295,0x00000294,0x0003003e,0x0000028d,0x00000295,
+ 0x000200f9,0x0000028f,0x000200f8,0x0000028f,0x0004003d,0x00000046,0x00000296,0x0000028d,
+ 0x00050041,0x00000074,0x00000297,0x0000004e,0x00000082,0x0003003e,0x00000297,0x00000296,
+ 0x00060041,0x0000025f,0x00000299,0x0000004a,0x0000005d,0x0000002a,0x0004003d,0x00000045,
+ 0x0000029a,0x00000299,0x00060041,0x0000025f,0x0000029b,0x0000004a,0x0000003e,0x00000018,
+ 0x0004003d,0x00000045,0x0000029c,0x0000029b,0x00060041,0x0000025f,0x0000029d,0x0000004a,
+ 0x0000003e,0x0000002a,0x0004003d,0x00000045,0x0000029e,0x0000029d,0x00060041,0x0000025f,
+ 0x0000029f,0x0000004a,0x00000065,0x00000018,0x0004003d,0x00000045,0x000002a0,0x0000029f,
+ 0x00070050,0x00000046,0x000002a1,0x0000029a,0x0000029c,0x0000029e,0x000002a0,0x0005008e,
+ 0x00000046,0x000002a2,0x000002a1,0x0000008c,0x00060041,0x0000025f,0x000002a3,0x0000004a,
+ 0x0000005d,0x00000084,0x0004003d,0x00000045,0x000002a4,0x000002a3,0x00060041,0x0000025f,
+ 0x000002a5,0x0000004a,0x0000003e,0x00000024,0x0004003d,0x00000045,0x000002a6,0x000002a5,
+ 0x00060041,0x0000025f,0x000002a7,0x0000004a,0x0000003e,0x00000084,0x0004003d,0x00000045,
+ 0x000002a8,0x000002a7,0x00060041,0x0000025f,0x000002a9,0x0000004a,0x00000065,0x00000024,
+ 0x0004003d,0x00000045,0x000002aa,0x000002a9,0x00070050,0x00000046,0x000002ab,0x000002a4,
+ 0x000002a6,0x000002a8,0x000002aa,0x0005008e,0x00000046,0x000002ac,0x000002ab,0x000000cd,
+ 0x00050081,0x00000046,0x000002ad,0x000002a2,0x000002ac,0x00060041,0x0000025f,0x000002ae,
+ 0x0000004a,0x0000003e,0x00000018,0x0004003d,0x00000045,0x000002af,0x000002ae,0x00060041,
+ 0x0000025f,0x000002b0,0x0000004a,0x0000003e,0x0000002a,0x0004003d,0x00000045,0x000002b1,
+ 0x000002b0,0x00060041,0x0000025f,0x000002b2,0x0000004a,0x00000065,0x00000018,0x0004003d,
+ 0x00000045,0x000002b3,0x000002b2,0x00060041,0x0000025f,0x000002b4,0x0000004a,0x00000065,
+ 0x0000002a,0x0004003d,0x00000045,0x000002b5,0x000002b4,0x00070050,0x00000046,0x000002b6,
+ 0x000002af,0x000002b1,0x000002b3,0x000002b5,0x0005008e,0x00000046,0x000002b7,0x000002b6,
+ 0x0000010e,0x00050081,0x00000046,0x000002b8,0x000002ad,0x000002b7,0x00060041,0x0000025f,
+ 0x000002b9,0x0000004a,0x0000003e,0x00000024,0x0004003d,0x00000045,0x000002ba,0x000002b9,
+ 0x00060041,0x0000025f,0x000002bb,0x0000004a,0x0000003e,0x00000084,0x0004003d,0x00000045,
+ 0x000002bc,0x000002bb,0x00060041,0x0000025f,0x000002bd,0x0000004a,0x00000065,0x00000024,
+ 0x0004003d,0x00000045,0x000002be,0x000002bd,0x00060041,0x0000025f,0x000002bf,0x0000004a,
+ 0x00000065,0x00000084,0x0004003d,0x00000045,0x000002c0,0x000002bf,0x00070050,0x00000046,
+ 0x000002c1,0x000002ba,0x000002bc,0x000002be,0x000002c0,0x0005008e,0x00000046,0x000002c2,
+ 0x000002c1,0x000000cd,0x00050081,0x00000046,0x000002c3,0x000002b8,0x000002c2,0x00060041,
+ 0x0000025f,0x000002c4,0x0000004a,0x0000003e,0x0000002a,0x0004003d,0x00000045,0x000002c5,
+ 0x000002c4,0x00060041,0x0000025f,0x000002c6,0x0000004a,0x00000065,0x00000018,0x0004003d,
+ 0x00000045,0x000002c7,0x000002c6,0x00060041,0x0000025f,0x000002c8,0x0000004a,0x00000065,
+ 0x0000002a,0x0004003d,0x00000045,0x000002c9,0x000002c8,0x00060041,0x0000025f,0x000002ca,
+ 0x0000004a,0x00000082,0x00000018,0x0004003d,0x00000045,0x000002cb,0x000002ca,0x00070050,
+ 0x00000046,0x000002cc,0x000002c5,0x000002c7,0x000002c9,0x000002cb,0x0005008e,0x00000046,
+ 0x000002cd,0x000002cc,0x0000008c,0x00050081,0x00000046,0x000002ce,0x000002c3,0x000002cd,
+ 0x0003003e,0x00000298,0x000002ce,0x00060041,0x0000025f,0x000002d0,0x0000004e,0x0000005d,
+ 0x0000002a,0x0004003d,0x00000045,0x000002d1,0x000002d0,0x00060041,0x0000025f,0x000002d2,
+ 0x0000004e,0x0000003e,0x00000018,0x0004003d,0x00000045,0x000002d3,0x000002d2,0x00060041,
+ 0x0000025f,0x000002d4,0x0000004e,0x0000003e,0x0000002a,0x0004003d,0x00000045,0x000002d5,
+ 0x000002d4,0x00060041,0x0000025f,0x000002d6,0x0000004e,0x00000065,0x00000018,0x0004003d,
+ 0x00000045,0x000002d7,0x000002d6,0x00070050,0x00000046,0x000002d8,0x000002d1,0x000002d3,
+ 0x000002d5,0x000002d7,0x0005008e,0x00000046,0x000002d9,0x000002d8,0x0000008c,0x00060041,
+ 0x0000025f,0x000002da,0x0000004e,0x0000005d,0x00000084,0x0004003d,0x00000045,0x000002db,
+ 0x000002da,0x00060041,0x0000025f,0x000002dc,0x0000004e,0x0000003e,0x00000024,0x0004003d,
+ 0x00000045,0x000002dd,0x000002dc,0x00060041,0x0000025f,0x000002de,0x0000004e,0x0000003e,
+ 0x00000084,0x0004003d,0x00000045,0x000002df,0x000002de,0x00060041,0x0000025f,0x000002e0,
+ 0x0000004e,0x00000065,0x00000024,0x0004003d,0x00000045,0x000002e1,0x000002e0,0x00070050,
+ 0x00000046,0x000002e2,0x000002db,0x000002dd,0x000002df,0x000002e1,0x0005008e,0x00000046,
+ 0x000002e3,0x000002e2,0x000000cd,0x00050081,0x00000046,0x000002e4,0x000002d9,0x000002e3,
+ 0x00060041,0x0000025f,0x000002e5,0x0000004e,0x0000003e,0x00000018,0x0004003d,0x00000045,
+ 0x000002e6,0x000002e5,0x00060041,0x0000025f,0x000002e7,0x0000004e,0x0000003e,0x0000002a,
+ 0x0004003d,0x00000045,0x000002e8,0x000002e7,0x00060041,0x0000025f,0x000002e9,0x0000004e,
+ 0x00000065,0x00000018,0x0004003d,0x00000045,0x000002ea,0x000002e9,0x00060041,0x0000025f,
+ 0x000002eb,0x0000004e,0x00000065,0x0000002a,0x0004003d,0x00000045,0x000002ec,0x000002eb,
+ 0x00070050,0x00000046,0x000002ed,0x000002e6,0x000002e8,0x000002ea,0x000002ec,0x0005008e,
+ 0x00000046,0x000002ee,0x000002ed,0x0000010e,0x00050081,0x00000046,0x000002ef,0x000002e4,
+ 0x000002ee,0x00060041,0x0000025f,0x000002f0,0x0000004e,0x0000003e,0x00000024,0x0004003d,
+ 0x00000045,0x000002f1,0x000002f0,0x00060041,0x0000025f,0x000002f2,0x0000004e,0x0000003e,
+ 0x00000084,0x0004003d,0x00000045,0x000002f3,0x000002f2,0x00060041,0x0000025f,0x000002f4,
+ 0x0000004e,0x00000065,0x00000024,0x0004003d,0x00000045,0x000002f5,0x000002f4,0x00060041,
+ 0x0000025f,0x000002f6,0x0000004e,0x00000065,0x00000084,0x0004003d,0x00000045,0x000002f7,
+ 0x000002f6,0x00070050,0x00000046,0x000002f8,0x000002f1,0x000002f3,0x000002f5,0x000002f7,
+ 0x0005008e,0x00000046,0x000002f9,0x000002f8,0x000000cd,0x00050081,0x00000046,0x000002fa,
+ 0x000002ef,0x000002f9,0x00060041,0x0000025f,0x000002fb,0x0000004e,0x0000003e,0x0000002a,
+ 0x0004003d,0x00000045,0x000002fc,0x000002fb,0x00060041,0x0000025f,0x000002fd,0x0000004e,
+ 0x00000065,0x00000018,0x0004003d,0x00000045,0x000002fe,0x000002fd,0x00060041,0x0000025f,
+ 0x000002ff,0x0000004e,0x00000065,0x0000002a,0x0004003d,0x00000045,0x00000300,0x000002ff,
+ 0x00060041,0x0000025f,0x00000301,0x0000004e,0x00000082,0x00000018,0x0004003d,0x00000045,
+ 0x00000302,0x00000301,0x00070050,0x00000046,0x00000303,0x000002fc,0x000002fe,0x00000300,
+ 0x00000302,0x0005008e,0x00000046,0x00000304,0x00000303,0x0000008c,0x00050081,0x00000046,
+ 0x00000305,0x000002fa,0x00000304,0x0003003e,0x000002cf,0x00000305,0x0004003d,0x00000046,
+ 0x00000306,0x00000298,0x00070050,0x00000046,0x00000308,0x0000004b,0x0000004b,0x0000004b,
+ 0x0000004b,0x00070050,0x00000046,0x00000309,0x00000307,0x00000307,0x00000307,0x00000307,
+ 0x0008000c,0x00000046,0x0000030a,0x00000001,0x0000002b,0x00000306,0x00000308,0x00000309,
+ 0x0003003e,0x00000298,0x0000030a,0x0004003d,0x00000046,0x0000030b,0x000002cf,0x00070050,
+ 0x00000046,0x0000030c,0x0000004b,0x0000004b,0x0000004b,0x0000004b,0x00070050,0x00000046,
+ 0x0000030d,0x00000307,0x00000307,0x00000307,0x00000307,0x0008000c,0x00000046,0x0000030e,
+ 0x00000001,0x0000002b,0x0000030b,0x0000030c,0x0000030d,0x0003003e,0x000002cf,0x0000030e,
+ 0x00050041,0x00000019,0x0000030f,0x0000000a,0x00000018,0x0004003d,0x00000006,0x00000310,
+ 0x0000030f,0x00050041,0x00000021,0x00000311,0x0000001e,0x00000082,0x0004003d,0x00000006,
+ 0x00000312,0x00000311,0x00050082,0x00000006,0x00000313,0x00000312,0x00000024,0x0008000c,
+ 0x00000006,0x00000314,0x00000001,0x0000002c,0x00000310,0x00000018,0x00000313,0x00050041,
+ 0x00000019,0x00000315,0x0000000a,0x00000018,0x0003003e,0x00000315,0x00000314,0x00050041,
+ 0x00000019,0x00000316,0x0000000a,0x00000024,0x0004003d,0x00000006,0x00000317,0x00000316,
+ 0x00050041,0x00000021,0x00000319,0x0000001e,0x00000318,0x0004003d,0x00000006,0x0000031a,
+ 0x00000319,0x00050082,0x00000006,0x0000031b,0x0000031a,0x0000002a,0x0008000c,0x00000006,
+ 0x0000031c,0x00000001,0x0000002c,0x00000317,0x00000018,0x0000031b,0x00050041,0x00000019,
+ 0x0000031d,0x0000000a,0x00000024,0x0003003e,0x0000031d,0x0000031c,0x00050041,0x00000019,
+ 0x0000031f,0x0000000a,0x00000024,0x0004003d,0x00000006,0x00000320,0x0000031f,0x00050041,
+ 0x00000021,0x00000321,0x0000001e,0x00000082,0x0004003d,0x00000006,0x00000322,0x00000321,
+ 0x00050084,0x00000006,0x00000323,0x00000320,0x00000322,0x00050041,0x00000019,0x00000324,
+ 0x0000000a,0x00000018,0x0004003d,0x00000006,0x00000325,0x00000324,0x00050080,0x00000006,
+ 0x00000326,0x00000323,0x00000325,0x0003003e,0x0000031e,0x00000326,0x0004003d,0x00000006,
+ 0x0000032b,0x0000031e,0x0004003d,0x00000046,0x0000032c,0x00000298,0x0006000c,0x00000006,
+ 0x0000032d,0x00000001,0x00000037,0x0000032c,0x00060041,0x00000070,0x0000032e,0x0000032a,
+ 0x0000005d,0x0000032b,0x0003003e,0x0000032e,0x0000032d,0x0004003d,0x00000006,0x0000032f,
+ 0x0000031e,0x00050041,0x00000021,0x00000330,0x0000001e,0x00000082,0x0004003d,0x00000006,
+ 0x00000331,0x00000330,0x00050080,0x00000006,0x00000332,0x0000032f,0x00000331,0x0004003d,
+ 0x00000046,0x00000333,0x000002cf,0x0006000c,0x00000006,0x00000334,0x00000001,0x00000037,
+ 0x00000333,0x00060041,0x00000070,0x00000335,0x0000032a,0x0000005d,0x00000332,0x0003003e,
+ 0x00000335,0x00000334,0x000100fd,0x00010038,0x00050036,0x00000002,0x00000010,0x00000000,
+ 0x0000000e,0x00030037,0x00000008,0x0000000f,0x000200f8,0x00000011,0x0004003b,0x00000008,
+ 0x00000336,0x00000007,0x0004003b,0x00000008,0x0000033a,0x00000007,0x0004003b,0x00000049,
+ 0x00000346,0x00000007,0x0004003b,0x00000019,0x00000347,0x00000007,0x0004003b,0x00000019,
+ 0x0000034b,0x00000007,0x0004003b,0x00000049,0x0000035f,0x00000007,0x0004003b,0x00000019,
+ 0x0000039a,0x00000007,0x0004003b,0x00000019,0x000003da,0x00000007,0x0004003b,0x00000074,
+ 0x00000488,0x00000007,0x0004003b,0x00000074,0x0000049d,0x00000007,0x0004003b,0x00000074,
+ 0x000004ac,0x00000007,0x0004003d,0x00000007,0x00000337,0x0000000f,0x00050050,0x00000007,
+ 0x00000338,0x0000002a,0x0000002a,0x00050084,0x00000007,0x00000339,0x00000337,0x00000338,
+ 0x0003003e,0x00000336,0x00000339,0x0004003d,0x00000007,0x0000033b,0x00000336,0x00050082,
+ 0x00000007,0x0000033c,0x0000033b,0x0000002b,0x0003003e,0x0000033a,0x0000033c,0x00050041,
+ 0x00000019,0x0000033d,0x0000033a,0x00000024,0x0004003d,0x00000006,0x0000033e,0x0000033d,
+ 0x00050041,0x00000021,0x0000033f,0x0000001e,0x0000003e,0x0004003d,0x00000006,0x00000340,
+ 0x0000033f,0x00050086,0x00000006,0x00000341,0x00000340,0x0000002a,0x00050082,0x00000006,
+ 0x00000343,0x00000341,0x00000342,0x0008000c,0x00000006,0x00000344,0x00000001,0x0000002c,
+ 0x0000033e,0x00000018,0x00000343,0x00050041,0x00000019,0x00000345,0x0000033a,0x00000024,
+ 0x0003003e,0x00000345,0x00000344,0x0003003e,0x00000346,0x0000004d,0x00050041,0x00000019,
+ 0x00000348,0x00000336,0x00000024,0x0004003d,0x00000006,0x00000349,0x00000348,0x000500aa,
+ 0x00000052,0x0000034a,0x00000349,0x00000018,0x000300f7,0x0000034d,0x00000000,0x000400fa,
+ 0x0000034a,0x0000034c,0x00000351,0x000200f8,0x0000034c,0x00050041,0x00000019,0x0000034e,
+ 0x00000336,0x00000018,0x0004003d,0x00000006,0x0000034f,0x0000034e,0x00050082,0x00000006,
+ 0x00000350,0x0000034f,0x00000024,0x0003003e,0x0000034b,0x00000350,0x000200f9,0x0000034d,
+ 0x000200f8,0x00000351,0x00050041,0x00000019,0x00000352,0x0000033a,0x00000024,0x0004003d,
+ 0x00000006,0x00000353,0x00000352,0x00050041,0x00000021,0x00000354,0x0000001e,0x0000005d,
+ 0x0004003d,0x00000006,0x00000355,0x00000354,0x00050084,0x00000006,0x00000356,0x00000353,
+ 0x00000355,0x00050041,0x00000019,0x00000357,0x0000033a,0x00000018,0x0004003d,0x00000006,
+ 0x00000358,0x00000357,0x00050080,0x00000006,0x00000359,0x00000356,0x00000358,0x0003003e,
+ 0x0000034b,0x00000359,0x000200f9,0x0000034d,0x000200f8,0x0000034d,0x0004003d,0x00000006,
+ 0x0000035a,0x0000034b,0x0003003e,0x00000347,0x0000035a,0x00050041,0x00000021,0x0000035b,
+ 0x0000001e,0x00000065,0x0004003d,0x00000006,0x0000035c,0x0000035b,0x0004003d,0x00000006,
+ 0x0000035d,0x00000347,0x00050080,0x00000006,0x0000035e,0x0000035d,0x0000035c,0x0003003e,
+ 0x00000347,0x0000035e,0x0004003d,0x00000006,0x00000364,0x00000347,0x00060041,0x00000070,
+ 0x00000365,0x00000363,0x0000005d,0x00000364,0x0004003d,0x00000006,0x00000366,0x00000365,
+ 0x0006000c,0x00000046,0x00000367,0x00000001,0x00000040,0x00000366,0x00050041,0x00000074,
+ 0x00000368,0x0000035f,0x0000005d,0x0003003e,0x00000368,0x00000367,0x0004003d,0x00000006,
+ 0x00000369,0x00000347,0x00050080,0x00000006,0x0000036a,0x00000369,0x00000024,0x00060041,
+ 0x00000070,0x0000036b,0x00000363,0x0000005d,0x0000036a,0x0004003d,0x00000006,0x0000036c,
+ 0x0000036b,0x0006000c,0x00000046,0x0000036d,0x00000001,0x00000040,0x0000036c,0x00050041,
+ 0x00000074,0x0000036e,0x0000035f,0x0000003e,0x0003003e,0x0000036e,0x0000036d,0x0004003d,
+ 0x00000006,0x0000036f,0x00000347,0x00050080,0x00000006,0x00000370,0x0000036f,0x0000002a,
+ 0x00060041,0x00000070,0x00000371,0x00000363,0x0000005d,0x00000370,0x0004003d,0x00000006,
+ 0x00000372,0x00000371,0x0006000c,0x00000046,0x00000373,0x00000001,0x00000040,0x00000372,
+ 0x00050041,0x00000074,0x00000374,0x0000035f,0x00000065,0x0003003e,0x00000374,0x00000373,
+ 0x0004003d,0x00000006,0x00000375,0x00000347,0x00050080,0x00000006,0x00000376,0x00000375,
+ 0x00000084,0x00060041,0x00000070,0x00000377,0x00000363,0x0000005d,0x00000376,0x0004003d,
+ 0x00000006,0x00000378,0x00000377,0x0006000c,0x00000046,0x00000379,0x00000001,0x00000040,
+ 0x00000378,0x00050041,0x00000074,0x0000037a,0x0000035f,0x00000082,0x0003003e,0x0000037a,
+ 0x00000379,0x00050041,0x00000074,0x0000037b,0x0000035f,0x0000005d,0x0004003d,0x00000046,
+ 0x0000037c,0x0000037b,0x0005008e,0x00000046,0x0000037d,0x0000037c,0x0000008c,0x00050041,
+ 0x00000074,0x0000037e,0x00000346,0x0000005d,0x0004003d,0x00000046,0x0000037f,0x0000037e,
+ 0x00050081,0x00000046,0x00000380,0x0000037f,0x0000037d,0x00050041,0x00000074,0x00000381,
+ 0x00000346,0x0000005d,0x0003003e,0x00000381,0x00000380,0x00050041,0x00000074,0x00000382,
+ 0x0000035f,0x0000003e,0x0004003d,0x00000046,0x00000383,0x00000382,0x0005008e,0x00000046,
+ 0x00000384,0x00000383,0x0000008c,0x00050041,0x00000074,0x00000385,0x00000346,0x0000003e,
+ 0x0004003d,0x00000046,0x00000386,0x00000385,0x00050081,0x00000046,0x00000387,0x00000386,
+ 0x00000384,0x00050041,0x00000074,0x00000388,0x00000346,0x0000003e,0x0003003e,0x00000388,
+ 0x00000387,0x00050041,0x00000074,0x00000389,0x0000035f,0x00000065,0x0004003d,0x00000046,
+ 0x0000038a,0x00000389,0x0005008e,0x00000046,0x0000038b,0x0000038a,0x0000008c,0x00050041,
+ 0x00000074,0x0000038c,0x00000346,0x00000065,0x0004003d,0x00000046,0x0000038d,0x0000038c,
+ 0x00050081,0x00000046,0x0000038e,0x0000038d,0x0000038b,0x00050041,0x00000074,0x0000038f,
+ 0x00000346,0x00000065,0x0003003e,0x0000038f,0x0000038e,0x00050041,0x00000074,0x00000390,
+ 0x0000035f,0x00000082,0x0004003d,0x00000046,0x00000391,0x00000390,0x0005008e,0x00000046,
+ 0x00000392,0x00000391,0x0000008c,0x00050041,0x00000074,0x00000393,0x00000346,0x00000082,
+ 0x0004003d,0x00000046,0x00000394,0x00000393,0x00050081,0x00000046,0x00000395,0x00000394,
+ 0x00000392,0x00050041,0x00000074,0x00000396,0x00000346,0x00000082,0x0003003e,0x00000396,
+ 0x00000395,0x00050041,0x00000019,0x00000397,0x00000336,0x00000024,0x0004003d,0x00000006,
+ 0x00000398,0x00000397,0x000500aa,0x00000052,0x00000399,0x00000398,0x00000018,0x000300f7,
+ 0x0000039c,0x00000000,0x000400fa,0x00000399,0x0000039b,0x0000039e,0x000200f8,0x0000039b,
+ 0x0004003d,0x00000006,0x0000039d,0x00000347,0x0003003e,0x0000039a,0x0000039d,0x000200f9,
+ 0x0000039c,0x000200f8,0x0000039e,0x0004003d,0x00000006,0x0000039f,0x00000347,0x00050041,
+ 0x00000021,0x000003a0,0x0000001e,0x0000005d,0x0004003d,0x00000006,0x000003a1,0x000003a0,
+ 0x00050080,0x00000006,0x000003a2,0x0000039f,0x000003a1,0x0003003e,0x0000039a,0x000003a2,
+ 0x000200f9,0x0000039c,0x000200f8,0x0000039c,0x0004003d,0x00000006,0x000003a3,0x0000039a,
+ 0x0003003e,0x00000347,0x000003a3,0x0004003d,0x00000006,0x000003a4,0x00000347,0x00060041,
+ 0x00000070,0x000003a5,0x00000363,0x0000005d,0x000003a4,0x0004003d,0x00000006,0x000003a6,
+ 0x000003a5,0x0006000c,0x00000046,0x000003a7,0x00000001,0x00000040,0x000003a6,0x00050041,
+ 0x00000074,0x000003a8,0x0000035f,0x0000005d,0x0003003e,0x000003a8,0x000003a7,0x0004003d,
+ 0x00000006,0x000003a9,0x00000347,0x00050080,0x00000006,0x000003aa,0x000003a9,0x00000024,
+ 0x00060041,0x00000070,0x000003ab,0x00000363,0x0000005d,0x000003aa,0x0004003d,0x00000006,
+ 0x000003ac,0x000003ab,0x0006000c,0x00000046,0x000003ad,0x00000001,0x00000040,0x000003ac,
+ 0x00050041,0x00000074,0x000003ae,0x0000035f,0x0000003e,0x0003003e,0x000003ae,0x000003ad,
+ 0x0004003d,0x00000006,0x000003af,0x00000347,0x00050080,0x00000006,0x000003b0,0x000003af,
+ 0x0000002a,0x00060041,0x00000070,0x000003b1,0x00000363,0x0000005d,0x000003b0,0x0004003d,
+ 0x00000006,0x000003b2,0x000003b1,0x0006000c,0x00000046,0x000003b3,0x00000001,0x00000040,
+ 0x000003b2,0x00050041,0x00000074,0x000003b4,0x0000035f,0x00000065,0x0003003e,0x000003b4,
+ 0x000003b3,0x0004003d,0x00000006,0x000003b5,0x00000347,0x00050080,0x00000006,0x000003b6,
+ 0x000003b5,0x00000084,0x00060041,0x00000070,0x000003b7,0x00000363,0x0000005d,0x000003b6,
+ 0x0004003d,0x00000006,0x000003b8,0x000003b7,0x0006000c,0x00000046,0x000003b9,0x00000001,
+ 0x00000040,0x000003b8,0x00050041,0x00000074,0x000003ba,0x0000035f,0x00000082,0x0003003e,
+ 0x000003ba,0x000003b9,0x00050041,0x00000074,0x000003bb,0x0000035f,0x0000005d,0x0004003d,
+ 0x00000046,0x000003bc,0x000003bb,0x0005008e,0x00000046,0x000003bd,0x000003bc,0x000000cd,
+ 0x00050041,0x00000074,0x000003be,0x00000346,0x0000005d,0x0004003d,0x00000046,0x000003bf,
+ 0x000003be,0x00050081,0x00000046,0x000003c0,0x000003bf,0x000003bd,0x00050041,0x00000074,
+ 0x000003c1,0x00000346,0x0000005d,0x0003003e,0x000003c1,0x000003c0,0x00050041,0x00000074,
+ 0x000003c2,0x0000035f,0x0000003e,0x0004003d,0x00000046,0x000003c3,0x000003c2,0x0005008e,
+ 0x00000046,0x000003c4,0x000003c3,0x000000cd,0x00050041,0x00000074,0x000003c5,0x00000346,
+ 0x0000003e,0x0004003d,0x00000046,0x000003c6,0x000003c5,0x00050081,0x00000046,0x000003c7,
+ 0x000003c6,0x000003c4,0x00050041,0x00000074,0x000003c8,0x00000346,0x0000003e,0x0003003e,
+ 0x000003c8,0x000003c7,0x00050041,0x00000074,0x000003c9,0x0000035f,0x00000065,0x0004003d,
+ 0x00000046,0x000003ca,0x000003c9,0x0005008e,0x00000046,0x000003cb,0x000003ca,0x000000cd,
+ 0x00050041,0x00000074,0x000003cc,0x00000346,0x00000065,0x0004003d,0x00000046,0x000003cd,
+ 0x000003cc,0x00050081,0x00000046,0x000003ce,0x000003cd,0x000003cb,0x00050041,0x00000074,
+ 0x000003cf,0x00000346,0x00000065,0x0003003e,0x000003cf,0x000003ce,0x00050041,0x00000074,
+ 0x000003d0,0x0000035f,0x00000082,0x0004003d,0x00000046,0x000003d1,0x000003d0,0x0005008e,
+ 0x00000046,0x000003d2,0x000003d1,0x000000cd,0x00050041,0x00000074,0x000003d3,0x00000346,
+ 0x00000082,0x0004003d,0x00000046,0x000003d4,0x000003d3,0x00050081,0x00000046,0x000003d5,
+ 0x000003d4,0x000003d2,0x00050041,0x00000074,0x000003d6,0x00000346,0x00000082,0x0003003e,
+ 0x000003d6,0x000003d5,0x00050041,0x00000019,0x000003d7,0x00000336,0x00000024,0x0004003d,
+ 0x00000006,0x000003d8,0x000003d7,0x000500aa,0x00000052,0x000003d9,0x000003d8,0x00000018,
+ 0x000300f7,0x000003dc,0x00000000,0x000400fa,0x000003d9,0x000003db,0x000003de,0x000200f8,
+ 0x000003db,0x0004003d,0x00000006,0x000003dd,0x00000347,0x0003003e,0x000003da,0x000003dd,
+ 0x000200f9,0x000003dc,0x000200f8,0x000003de,0x0004003d,0x00000006,0x000003df,0x00000347,
+ 0x00050041,0x00000021,0x000003e0,0x0000001e,0x0000005d,0x0004003d,0x00000006,0x000003e1,
+ 0x000003e0,0x00050080,0x00000006,0x000003e2,0x000003df,0x000003e1,0x0003003e,0x000003da,
+ 0x000003e2,0x000200f9,0x000003dc,0x000200f8,0x000003dc,0x0004003d,0x00000006,0x000003e3,
+ 0x000003da,0x0003003e,0x00000347,0x000003e3,0x0004003d,0x00000006,0x000003e4,0x00000347,
+ 0x00060041,0x00000070,0x000003e5,0x00000363,0x0000005d,0x000003e4,0x0004003d,0x00000006,
+ 0x000003e6,0x000003e5,0x0006000c,0x00000046,0x000003e7,0x00000001,0x00000040,0x000003e6,
+ 0x00050041,0x00000074,0x000003e8,0x0000035f,0x0000005d,0x0003003e,0x000003e8,0x000003e7,
+ 0x0004003d,0x00000006,0x000003e9,0x00000347,0x00050080,0x00000006,0x000003ea,0x000003e9,
+ 0x00000024,0x00060041,0x00000070,0x000003eb,0x00000363,0x0000005d,0x000003ea,0x0004003d,
+ 0x00000006,0x000003ec,0x000003eb,0x0006000c,0x00000046,0x000003ed,0x00000001,0x00000040,
+ 0x000003ec,0x00050041,0x00000074,0x000003ee,0x0000035f,0x0000003e,0x0003003e,0x000003ee,
+ 0x000003ed,0x0004003d,0x00000006,0x000003ef,0x00000347,0x00050080,0x00000006,0x000003f0,
+ 0x000003ef,0x0000002a,0x00060041,0x00000070,0x000003f1,0x00000363,0x0000005d,0x000003f0,
+ 0x0004003d,0x00000006,0x000003f2,0x000003f1,0x0006000c,0x00000046,0x000003f3,0x00000001,
+ 0x00000040,0x000003f2,0x00050041,0x00000074,0x000003f4,0x0000035f,0x00000065,0x0003003e,
+ 0x000003f4,0x000003f3,0x0004003d,0x00000006,0x000003f5,0x00000347,0x00050080,0x00000006,
+ 0x000003f6,0x000003f5,0x00000084,0x00060041,0x00000070,0x000003f7,0x00000363,0x0000005d,
+ 0x000003f6,0x0004003d,0x00000006,0x000003f8,0x000003f7,0x0006000c,0x00000046,0x000003f9,
+ 0x00000001,0x00000040,0x000003f8,0x00050041,0x00000074,0x000003fa,0x0000035f,0x00000082,
+ 0x0003003e,0x000003fa,0x000003f9,0x00050041,0x00000074,0x000003fb,0x0000035f,0x0000005d,
+ 0x0004003d,0x00000046,0x000003fc,0x000003fb,0x0005008e,0x00000046,0x000003fd,0x000003fc,
+ 0x0000010e,0x00050041,0x00000074,0x000003fe,0x00000346,0x0000005d,0x0004003d,0x00000046,
+ 0x000003ff,0x000003fe,0x00050081,0x00000046,0x00000400,0x000003ff,0x000003fd,0x00050041,
+ 0x00000074,0x00000401,0x00000346,0x0000005d,0x0003003e,0x00000401,0x00000400,0x00050041,
+ 0x00000074,0x00000402,0x0000035f,0x0000003e,0x0004003d,0x00000046,0x00000403,0x00000402,
+ 0x0005008e,0x00000046,0x00000404,0x00000403,0x0000010e,0x00050041,0x00000074,0x00000405,
+ 0x00000346,0x0000003e,0x0004003d,0x00000046,0x00000406,0x00000405,0x00050081,0x00000046,
+ 0x00000407,0x00000406,0x00000404,0x00050041,0x00000074,0x00000408,0x00000346,0x0000003e,
+ 0x0003003e,0x00000408,0x00000407,0x00050041,0x00000074,0x00000409,0x0000035f,0x00000065,
+ 0x0004003d,0x00000046,0x0000040a,0x00000409,0x0005008e,0x00000046,0x0000040b,0x0000040a,
+ 0x0000010e,0x00050041,0x00000074,0x0000040c,0x00000346,0x00000065,0x0004003d,0x00000046,
+ 0x0000040d,0x0000040c,0x00050081,0x00000046,0x0000040e,0x0000040d,0x0000040b,0x00050041,
+ 0x00000074,0x0000040f,0x00000346,0x00000065,0x0003003e,0x0000040f,0x0000040e,0x00050041,
+ 0x00000074,0x00000410,0x0000035f,0x00000082,0x0004003d,0x00000046,0x00000411,0x00000410,
+ 0x0005008e,0x00000046,0x00000412,0x00000411,0x0000010e,0x00050041,0x00000074,0x00000413,
+ 0x00000346,0x00000082,0x0004003d,0x00000046,0x00000414,0x00000413,0x00050081,0x00000046,
+ 0x00000415,0x00000414,0x00000412,0x00050041,0x00000074,0x00000416,0x00000346,0x00000082,
+ 0x0003003e,0x00000416,0x00000415,0x00050041,0x00000021,0x00000417,0x0000001e,0x0000005d,
+ 0x0004003d,0x00000006,0x00000418,0x00000417,0x0004003d,0x00000006,0x00000419,0x00000347,
+ 0x00050080,0x00000006,0x0000041a,0x00000419,0x00000418,0x0003003e,0x00000347,0x0000041a,
+ 0x0004003d,0x00000006,0x0000041b,0x00000347,0x00060041,0x00000070,0x0000041c,0x00000363,
+ 0x0000005d,0x0000041b,0x0004003d,0x00000006,0x0000041d,0x0000041c,0x0006000c,0x00000046,
+ 0x0000041e,0x00000001,0x00000040,0x0000041d,0x00050041,0x00000074,0x0000041f,0x0000035f,
+ 0x0000005d,0x0003003e,0x0000041f,0x0000041e,0x0004003d,0x00000006,0x00000420,0x00000347,
+ 0x00050080,0x00000006,0x00000421,0x00000420,0x00000024,0x00060041,0x00000070,0x00000422,
+ 0x00000363,0x0000005d,0x00000421,0x0004003d,0x00000006,0x00000423,0x00000422,0x0006000c,
+ 0x00000046,0x00000424,0x00000001,0x00000040,0x00000423,0x00050041,0x00000074,0x00000425,
+ 0x0000035f,0x0000003e,0x0003003e,0x00000425,0x00000424,0x0004003d,0x00000006,0x00000426,
+ 0x00000347,0x00050080,0x00000006,0x00000427,0x00000426,0x0000002a,0x00060041,0x00000070,
+ 0x00000428,0x00000363,0x0000005d,0x00000427,0x0004003d,0x00000006,0x00000429,0x00000428,
+ 0x0006000c,0x00000046,0x0000042a,0x00000001,0x00000040,0x00000429,0x00050041,0x00000074,
+ 0x0000042b,0x0000035f,0x00000065,0x0003003e,0x0000042b,0x0000042a,0x0004003d,0x00000006,
+ 0x0000042c,0x00000347,0x00050080,0x00000006,0x0000042d,0x0000042c,0x00000084,0x00060041,
+ 0x00000070,0x0000042e,0x00000363,0x0000005d,0x0000042d,0x0004003d,0x00000006,0x0000042f,
+ 0x0000042e,0x0006000c,0x00000046,0x00000430,0x00000001,0x00000040,0x0000042f,0x00050041,
+ 0x00000074,0x00000431,0x0000035f,0x00000082,0x0003003e,0x00000431,0x00000430,0x00050041,
+ 0x00000074,0x00000432,0x0000035f,0x0000005d,0x0004003d,0x00000046,0x00000433,0x00000432,
+ 0x0005008e,0x00000046,0x00000434,0x00000433,0x000000cd,0x00050041,0x00000074,0x00000435,
+ 0x00000346,0x0000005d,0x0004003d,0x00000046,0x00000436,0x00000435,0x00050081,0x00000046,
+ 0x00000437,0x00000436,0x00000434,0x00050041,0x00000074,0x00000438,0x00000346,0x0000005d,
+ 0x0003003e,0x00000438,0x00000437,0x00050041,0x00000074,0x00000439,0x0000035f,0x0000003e,
+ 0x0004003d,0x00000046,0x0000043a,0x00000439,0x0005008e,0x00000046,0x0000043b,0x0000043a,
+ 0x000000cd,0x00050041,0x00000074,0x0000043c,0x00000346,0x0000003e,0x0004003d,0x00000046,
+ 0x0000043d,0x0000043c,0x00050081,0x00000046,0x0000043e,0x0000043d,0x0000043b,0x00050041,
+ 0x00000074,0x0000043f,0x00000346,0x0000003e,0x0003003e,0x0000043f,0x0000043e,0x00050041,
+ 0x00000074,0x00000440,0x0000035f,0x00000065,0x0004003d,0x00000046,0x00000441,0x00000440,
+ 0x0005008e,0x00000046,0x00000442,0x00000441,0x000000cd,0x00050041,0x00000074,0x00000443,
+ 0x00000346,0x00000065,0x0004003d,0x00000046,0x00000444,0x00000443,0x00050081,0x00000046,
+ 0x00000445,0x00000444,0x00000442,0x00050041,0x00000074,0x00000446,0x00000346,0x00000065,
+ 0x0003003e,0x00000446,0x00000445,0x00050041,0x00000074,0x00000447,0x0000035f,0x00000082,
+ 0x0004003d,0x00000046,0x00000448,0x00000447,0x0005008e,0x00000046,0x00000449,0x00000448,
+ 0x000000cd,0x00050041,0x00000074,0x0000044a,0x00000346,0x00000082,0x0004003d,0x00000046,
+ 0x0000044b,0x0000044a,0x00050081,0x00000046,0x0000044c,0x0000044b,0x00000449,0x00050041,
+ 0x00000074,0x0000044d,0x00000346,0x00000082,0x0003003e,0x0000044d,0x0000044c,0x00050041,
+ 0x00000021,0x0000044e,0x0000001e,0x0000005d,0x0004003d,0x00000006,0x0000044f,0x0000044e,
+ 0x0004003d,0x00000006,0x00000450,0x00000347,0x00050080,0x00000006,0x00000451,0x00000450,
+ 0x0000044f,0x0003003e,0x00000347,0x00000451,0x0004003d,0x00000006,0x00000452,0x00000347,
+ 0x00060041,0x00000070,0x00000453,0x00000363,0x0000005d,0x00000452,0x0004003d,0x00000006,
+ 0x00000454,0x00000453,0x0006000c,0x00000046,0x00000455,0x00000001,0x00000040,0x00000454,
+ 0x00050041,0x00000074,0x00000456,0x0000035f,0x0000005d,0x0003003e,0x00000456,0x00000455,
+ 0x0004003d,0x00000006,0x00000457,0x00000347,0x00050080,0x00000006,0x00000458,0x00000457,
+ 0x00000024,0x00060041,0x00000070,0x00000459,0x00000363,0x0000005d,0x00000458,0x0004003d,
+ 0x00000006,0x0000045a,0x00000459,0x0006000c,0x00000046,0x0000045b,0x00000001,0x00000040,
+ 0x0000045a,0x00050041,0x00000074,0x0000045c,0x0000035f,0x0000003e,0x0003003e,0x0000045c,
+ 0x0000045b,0x0004003d,0x00000006,0x0000045d,0x00000347,0x00050080,0x00000006,0x0000045e,
+ 0x0000045d,0x0000002a,0x00060041,0x00000070,0x0000045f,0x00000363,0x0000005d,0x0000045e,
+ 0x0004003d,0x00000006,0x00000460,0x0000045f,0x0006000c,0x00000046,0x00000461,0x00000001,
+ 0x00000040,0x00000460,0x00050041,0x00000074,0x00000462,0x0000035f,0x00000065,0x0003003e,
+ 0x00000462,0x00000461,0x0004003d,0x00000006,0x00000463,0x00000347,0x00050080,0x00000006,
+ 0x00000464,0x00000463,0x00000084,0x00060041,0x00000070,0x00000465,0x00000363,0x0000005d,
+ 0x00000464,0x0004003d,0x00000006,0x00000466,0x00000465,0x0006000c,0x00000046,0x00000467,
+ 0x00000001,0x00000040,0x00000466,0x00050041,0x00000074,0x00000468,0x0000035f,0x00000082,
+ 0x0003003e,0x00000468,0x00000467,0x00050041,0x00000074,0x00000469,0x0000035f,0x0000005d,
+ 0x0004003d,0x00000046,0x0000046a,0x00000469,0x0005008e,0x00000046,0x0000046b,0x0000046a,
+ 0x0000008c,0x00050041,0x00000074,0x0000046c,0x00000346,0x0000005d,0x0004003d,0x00000046,
+ 0x0000046d,0x0000046c,0x00050081,0x00000046,0x0000046e,0x0000046d,0x0000046b,0x00050041,
+ 0x00000074,0x0000046f,0x00000346,0x0000005d,0x0003003e,0x0000046f,0x0000046e,0x00050041,
+ 0x00000074,0x00000470,0x0000035f,0x0000003e,0x0004003d,0x00000046,0x00000471,0x00000470,
+ 0x0005008e,0x00000046,0x00000472,0x00000471,0x0000008c,0x00050041,0x00000074,0x00000473,
+ 0x00000346,0x0000003e,0x0004003d,0x00000046,0x00000474,0x00000473,0x00050081,0x00000046,
+ 0x00000475,0x00000474,0x00000472,0x00050041,0x00000074,0x00000476,0x00000346,0x0000003e,
+ 0x0003003e,0x00000476,0x00000475,0x00050041,0x00000074,0x00000477,0x0000035f,0x00000065,
+ 0x0004003d,0x00000046,0x00000478,0x00000477,0x0005008e,0x00000046,0x00000479,0x00000478,
+ 0x0000008c,0x00050041,0x00000074,0x0000047a,0x00000346,0x00000065,0x0004003d,0x00000046,
+ 0x0000047b,0x0000047a,0x00050081,0x00000046,0x0000047c,0x0000047b,0x00000479,0x00050041,
+ 0x00000074,0x0000047d,0x00000346,0x00000065,0x0003003e,0x0000047d,0x0000047c,0x00050041,
+ 0x00000074,0x0000047e,0x0000035f,0x00000082,0x0004003d,0x00000046,0x0000047f,0x0000047e,
+ 0x0005008e,0x00000046,0x00000480,0x0000047f,0x0000008c,0x00050041,0x00000074,0x00000481,
+ 0x00000346,0x00000082,0x0004003d,0x00000046,0x00000482,0x00000481,0x00050081,0x00000046,
+ 0x00000483,0x00000482,0x00000480,0x00050041,0x00000074,0x00000484,0x00000346,0x00000082,
+ 0x0003003e,0x00000484,0x00000483,0x00050041,0x00000019,0x00000485,0x00000336,0x00000018,
+ 0x0004003d,0x00000006,0x00000486,0x00000485,0x000500aa,0x00000052,0x00000487,0x00000486,
+ 0x00000018,0x000300f7,0x0000048a,0x00000000,0x000400fa,0x00000487,0x00000489,0x00000492,
+ 0x000200f8,0x00000489,0x00050041,0x00000074,0x0000048b,0x00000346,0x0000003e,0x0004003d,
+ 0x00000046,0x0000048c,0x0000048b,0x00050051,0x00000045,0x0000048d,0x0000048c,0x00000000,
+ 0x00050051,0x00000045,0x0000048e,0x0000048c,0x00000001,0x00050051,0x00000045,0x0000048f,
+ 0x0000048c,0x00000002,0x00050051,0x00000045,0x00000490,0x0000048c,0x00000003,0x00070050,
+ 0x00000046,0x00000491,0x0000048d,0x0000048e,0x0000048f,0x00000490,0x0003003e,0x00000488,
+ 0x00000491,0x000200f9,0x0000048a,0x000200f8,0x00000492,0x00050041,0x00000074,0x00000493,
+ 0x00000346,0x0000005d,0x0004003d,0x00000046,0x00000494,0x00000493,0x0003003e,0x00000488,
+ 0x00000494,0x000200f9,0x0000048a,0x000200f8,0x0000048a,0x0004003d,0x00000046,0x00000495,
+ 0x00000488,0x00050041,0x00000074,0x00000496,0x00000346,0x0000005d,0x0003003e,0x00000496,
+ 0x00000495,0x00050041,0x00000019,0x00000497,0x00000336,0x00000018,0x0004003d,0x00000006,
+ 0x00000498,0x00000497,0x00050041,0x00000021,0x00000499,0x0000001e,0x00000020,0x0004003d,
+ 0x00000006,0x0000049a,0x00000499,0x00050082,0x00000006,0x0000049b,0x0000049a,0x0000002a,
+ 0x000500aa,0x00000052,0x0000049c,0x00000498,0x0000049b,0x000300f7,0x0000049f,0x00000000,
+ 0x000400fa,0x0000049c,0x0000049e,0x000004a7,0x000200f8,0x0000049e,0x00050041,0x00000074,
+ 0x000004a0,0x00000346,0x00000065,0x0004003d,0x00000046,0x000004a1,0x000004a0,0x00050051,
+ 0x00000045,0x000004a2,0x000004a1,0x00000000,0x00050051,0x00000045,0x000004a3,0x000004a1,
+ 0x00000001,0x00050051,0x00000045,0x000004a4,0x000004a1,0x00000002,0x00050051,0x00000045,
+ 0x000004a5,0x000004a1,0x00000003,0x00070050,0x00000046,0x000004a6,0x000004a2,0x000004a3,
+ 0x000004a4,0x000004a5,0x0003003e,0x0000049d,0x000004a6,0x000200f9,0x0000049f,0x000200f8,
+ 0x000004a7,0x00050041,0x00000074,0x000004a8,0x00000346,0x00000082,0x0004003d,0x00000046,
+ 0x000004a9,0x000004a8,0x0003003e,0x0000049d,0x000004a9,0x000200f9,0x0000049f,0x000200f8,
+ 0x0000049f,0x0004003d,0x00000046,0x000004aa,0x0000049d,0x00050041,0x00000074,0x000004ab,
+ 0x00000346,0x00000082,0x0003003e,0x000004ab,0x000004aa,0x00060041,0x0000025f,0x000004ad,
+ 0x00000346,0x0000005d,0x00000018,0x0004003d,0x00000045,0x000004ae,0x000004ad,0x00060041,
+ 0x0000025f,0x000004af,0x00000346,0x0000005d,0x00000024,0x0004003d,0x00000045,0x000004b0,
+ 0x000004af,0x00060041,0x0000025f,0x000004b1,0x00000346,0x0000003e,0x00000018,0x0004003d,
+ 0x00000045,0x000004b2,0x000004b1,0x00060041,0x0000025f,0x000004b3,0x00000346,0x0000003e,
+ 0x00000024,0x0004003d,0x00000045,0x000004b4,0x000004b3,0x00070050,0x00000046,0x000004b5,
+ 0x000004ae,0x000004b0,0x000004b2,0x000004b4,0x0005008e,0x00000046,0x000004b6,0x000004b5,
+ 0x0000008c,0x00060041,0x0000025f,0x000004b7,0x00000346,0x0000005d,0x0000002a,0x0004003d,
+ 0x00000045,0x000004b8,0x000004b7,0x00060041,0x0000025f,0x000004b9,0x00000346,0x0000005d,
+ 0x00000084,0x0004003d,0x00000045,0x000004ba,0x000004b9,0x00060041,0x0000025f,0x000004bb,
+ 0x00000346,0x0000003e,0x0000002a,0x0004003d,0x00000045,0x000004bc,0x000004bb,0x00060041,
+ 0x0000025f,0x000004bd,0x00000346,0x0000003e,0x00000084,0x0004003d,0x00000045,0x000004be,
+ 0x000004bd,0x00070050,0x00000046,0x000004bf,0x000004b8,0x000004ba,0x000004bc,0x000004be,
+ 0x0005008e,0x00000046,0x000004c0,0x000004bf,0x000000cd,0x00050081,0x00000046,0x000004c1,
+ 0x000004b6,0x000004c0,0x00060041,0x0000025f,0x000004c2,0x00000346,0x0000003e,0x00000018,
+ 0x0004003d,0x00000045,0x000004c3,0x000004c2,0x00060041,0x0000025f,0x000004c4,0x00000346,
+ 0x0000003e,0x00000024,0x0004003d,0x00000045,0x000004c5,0x000004c4,0x00060041,0x0000025f,
+ 0x000004c6,0x00000346,0x00000065,0x00000018,0x0004003d,0x00000045,0x000004c7,0x000004c6,
+ 0x00060041,0x0000025f,0x000004c8,0x00000346,0x00000065,0x00000024,0x0004003d,0x00000045,
+ 0x000004c9,0x000004c8,0x00070050,0x00000046,0x000004ca,0x000004c3,0x000004c5,0x000004c7,
+ 0x000004c9,0x0005008e,0x00000046,0x000004cb,0x000004ca,0x0000010e,0x00050081,0x00000046,
+ 0x000004cc,0x000004c1,0x000004cb,0x00060041,0x0000025f,0x000004cd,0x00000346,0x0000003e,
+ 0x0000002a,0x0004003d,0x00000045,0x000004ce,0x000004cd,0x00060041,0x0000025f,0x000004cf,
+ 0x00000346,0x0000003e,0x00000084,0x0004003d,0x00000045,0x000004d0,0x000004cf,0x00060041,
+ 0x0000025f,0x000004d1,0x00000346,0x00000065,0x0000002a,0x0004003d,0x00000045,0x000004d2,
+ 0x000004d1,0x00060041,0x0000025f,0x000004d3,0x00000346,0x00000065,0x00000084,0x0004003d,
+ 0x00000045,0x000004d4,0x000004d3,0x00070050,0x00000046,0x000004d5,0x000004ce,0x000004d0,
+ 0x000004d2,0x000004d4,0x0005008e,0x00000046,0x000004d6,0x000004d5,0x000000cd,0x00050081,
+ 0x00000046,0x000004d7,0x000004cc,0x000004d6,0x00060041,0x0000025f,0x000004d8,0x00000346,
+ 0x00000065,0x00000018,0x0004003d,0x00000045,0x000004d9,0x000004d8,0x00060041,0x0000025f,
+ 0x000004da,0x00000346,0x00000065,0x00000024,0x0004003d,0x00000045,0x000004db,0x000004da,
+ 0x00060041,0x0000025f,0x000004dc,0x00000346,0x00000082,0x00000018,0x0004003d,0x00000045,
+ 0x000004dd,0x000004dc,0x00060041,0x0000025f,0x000004de,0x00000346,0x00000082,0x00000024,
+ 0x0004003d,0x00000045,0x000004df,0x000004de,0x00070050,0x00000046,0x000004e0,0x000004d9,
+ 0x000004db,0x000004dd,0x000004df,0x0005008e,0x00000046,0x000004e1,0x000004e0,0x0000008c,
+ 0x00050081,0x00000046,0x000004e2,0x000004d7,0x000004e1,0x0003003e,0x000004ac,0x000004e2,
+ 0x0004003d,0x00000046,0x000004e3,0x000004ac,0x00070050,0x00000046,0x000004e4,0x0000004b,
+ 0x0000004b,0x0000004b,0x0000004b,0x00070050,0x00000046,0x000004e5,0x00000307,0x00000307,
+ 0x00000307,0x00000307,0x0008000c,0x00000046,0x000004e6,0x00000001,0x0000002b,0x000004e3,
+ 0x000004e4,0x000004e5,0x0003003e,0x000004ac,0x000004e6,0x00050041,0x00000019,0x000004e7,
+ 0x0000000f,0x00000018,0x0004003d,0x00000006,0x000004e8,0x000004e7,0x00050041,0x00000021,
+ 0x000004e9,0x0000001e,0x00000082,0x0004003d,0x00000006,0x000004ea,0x000004e9,0x00050082,
+ 0x00000006,0x000004eb,0x000004ea,0x00000024,0x0008000c,0x00000006,0x000004ec,0x00000001,
+ 0x0000002c,0x000004e8,0x00000018,0x000004eb,0x00050041,0x00000019,0x000004ed,0x0000000f,
+ 0x00000018,0x0003003e,0x000004ed,0x000004ec,0x00050041,0x00000019,0x000004f2,0x0000000f,
+ 0x00000024,0x0004003d,0x00000006,0x000004f3,0x000004f2,0x00050041,0x00000021,0x000004f4,
+ 0x0000001e,0x00000082,0x0004003d,0x00000006,0x000004f5,0x000004f4,0x00050084,0x00000006,
+ 0x000004f6,0x000004f3,0x000004f5,0x00050041,0x00000019,0x000004f7,0x0000000f,0x00000018,
+ 0x0004003d,0x00000006,0x000004f8,0x000004f7,0x00050080,0x00000006,0x000004f9,0x000004f6,
+ 0x000004f8,0x0004003d,0x00000046,0x000004fa,0x000004ac,0x0006000c,0x00000006,0x000004fb,
+ 0x00000001,0x00000037,0x000004fa,0x00060041,0x00000070,0x000004fc,0x000004f1,0x0000005d,
+ 0x000004f9,0x0003003e,0x000004fc,0x000004fb,0x000100fd,0x00010038
diff --git a/shaders/spv/shader_geomap.comp b/shaders/spv/shader_geomap.comp
new file mode 100644
index 0000000..f92dcb4
--- /dev/null
+++ b/shaders/spv/shader_geomap.comp
@@ -0,0 +1,238 @@
+#version 310 es
+
+layout (local_size_x = 8, local_size_y = 8) in;
+
+layout (binding = 0) readonly buffer InBufY {
+ uint data[];
+} in_buf_y;
+
+layout (binding = 1) readonly buffer InBufUV {
+ uint data[];
+} in_buf_uv;
+
+layout (binding = 2) writeonly buffer OutBufY {
+ uint data[];
+} out_buf_y;
+
+layout (binding = 3) writeonly buffer OutBufUV {
+ uint data[];
+} out_buf_uv;
+
+layout (binding = 4) readonly buffer GeoMapTable {
+ vec2 data[];
+} lut;
+
+layout (push_constant) uniform PushConsts {
+ uint in_img_width;
+ uint in_img_height;
+ uint out_img_width;
+ uint out_img_height;
+ uint lut_width;
+ uint lut_height;
+ float lut_step[4];
+ float lut_std_step[2];
+} prop;
+
+#define UNIT_SIZE 4u
+
+#define unpack_unorm_y(index) \
+ { \
+ vec4 value = unpackUnorm4x8 (in_buf_y.data[index00[index]]); \
+ out_y00[index] = value[x00_fract[index]]; \
+ value = unpackUnorm4x8 (in_buf_y.data[index01[index]]); \
+ out_y01[index] = value[x01_fract[index]]; \
+ value = unpackUnorm4x8 (in_buf_y.data[index10[index]]); \
+ out_y10[index] = value[x10_fract[index]]; \
+ value = unpackUnorm4x8 (in_buf_y.data[index11[index]]); \
+ out_y11[index] = value[x11_fract[index]]; \
+ }
+
+void geomap_y (vec4 lut_x, vec4 lut_y, out vec4 in_img_x, out vec4 in_img_y, out bvec4 out_bound, out uint out_data);
+void geomap_uv (vec2 in_uv_x, vec2 in_uv_y, bvec4 out_bound_uv, out uint out_data);
+
+void main ()
+{
+ uint g_x = gl_GlobalInvocationID.x;
+ uint g_y = gl_GlobalInvocationID.y * 2u;
+
+ vec2 cent = (vec2 (prop.out_img_width, prop.out_img_height) - 1.0f) / 2.0f;
+ vec2 step = g_x < uint (cent.x) ? vec2 (prop.lut_step[0], prop.lut_step[1]) :
+ vec2 (prop.lut_step[2], prop.lut_step[3]);
+
+ vec2 start = (vec2 (g_x, g_y) - cent) * step + cent * vec2 (prop.lut_std_step[0], prop.lut_std_step[1]);
+ vec4 lut_x = start.x * float (UNIT_SIZE) + vec4 (0.0f, step.x, step.x * 2.0f, step.x * 3.0f);
+ vec4 lut_y = start.yyyy;
+ lut_x = clamp (lut_x, 0.0f, float (prop.lut_width) - 1.0f);
+ lut_y = clamp (lut_y, 0.0f, float (prop.lut_height) - 1.0f - step.y);
+
+ uint out_data;
+ vec4 in_img_x, in_img_y;
+ bvec4 out_bound;
+ geomap_y (lut_x, lut_y, in_img_x, in_img_y, out_bound, out_data);
+ out_buf_y.data[g_y * prop.out_img_width + g_x] = out_data;
+
+ bvec4 out_bound_uv = out_bound.xxzz;
+ if (all (out_bound_uv)) {
+ out_data = packUnorm4x8 (vec4 (0.5f));
+ } else {
+ vec2 in_uv_x = in_img_x.xz;
+ vec2 in_uv_y = in_img_y.xz / 2.0f;
+ in_uv_y = clamp (in_uv_y, 0.0f, float (prop.in_img_height / 2u - 1u));
+ geomap_uv (in_uv_x, in_uv_y, out_bound_uv, out_data);
+ }
+ out_buf_uv.data[g_y / 2u * prop.out_img_width + g_x] = out_data;
+
+ lut_y += step.y;
+ geomap_y (lut_x, lut_y, in_img_x, in_img_y, out_bound, out_data);
+ out_buf_y.data[(g_y + 1u) * prop.out_img_width + g_x] = out_data;
+}
+
+void geomap_y (vec4 lut_x, vec4 lut_y, out vec4 in_img_x, out vec4 in_img_y, out bvec4 out_bound, out uint out_data)
+{
+ uvec4 x00 = uvec4 (lut_x);
+ uvec4 y00 = uvec4 (lut_y);
+ uvec4 x01 = x00 + 1u;
+ uvec4 y01 = y00;
+ uvec4 x10 = x00;
+ uvec4 y10 = y00 + 1u;
+ uvec4 x11 = x01;
+ uvec4 y11 = y10;
+
+ vec4 fract_x = fract (lut_x);
+ vec4 fract_y = fract (lut_y);
+ vec4 weight00 = (1.0f - fract_x) * (1.0f - fract_y);
+ vec4 weight01 = fract_x * (1.0f - fract_y);
+ vec4 weight10 = (1.0f - fract_x) * fract_y;
+ vec4 weight11 = fract_x * fract_y;
+
+ uvec4 index00 = y00 * prop.lut_width + x00;
+ uvec4 index01 = y01 * prop.lut_width + x01;
+ uvec4 index10 = y10 * prop.lut_width + x10;
+ uvec4 index11 = y11 * prop.lut_width + x11;
+
+ vec4 in_img_x00, in_img_x01, in_img_x10, in_img_x11;
+ vec4 in_img_y00, in_img_y01, in_img_y10, in_img_y11;
+ for (uint i = 0u; i < UNIT_SIZE; ++i) {
+ vec2 value = lut.data[index00[i]];
+ in_img_x00[i] = value.x;
+ in_img_y00[i] = value.y;
+ value = lut.data[index01[i]];
+ in_img_x01[i] = value.x;
+ in_img_y01[i] = value.y;
+ value = lut.data[index10[i]];
+ in_img_x10[i] = value.x;
+ in_img_y10[i] = value.y;
+ value = lut.data[index11[i]];
+ in_img_x11[i] = value.x;
+ in_img_y11[i] = value.y;
+ }
+ in_img_x = in_img_x00 * weight00 + in_img_x01 * weight01 + in_img_x10 * weight10 + in_img_x11 * weight11;
+ in_img_y = in_img_y00 * weight00 + in_img_y01 * weight01 + in_img_y10 * weight10 + in_img_y11 * weight11;
+
+ for (uint i = 0u; i < UNIT_SIZE; ++i) {
+ out_bound[i] = in_img_x[i] < 0.0f || in_img_x[i] > float (prop.in_img_width * UNIT_SIZE - 1u) ||
+ in_img_y[i] < 0.0f || in_img_y[i] > float (prop.in_img_height - 1u);
+ }
+ if (all (out_bound)) {
+ out_data = 0u;
+ return;
+ }
+
+ x00 = uvec4 (in_img_x);
+ y00 = uvec4 (in_img_y);
+ x01 = x00 + 1u;
+ y01 = y00;
+ x10 = x00;
+ y10 = y00 + 1u;
+ x11 = x01;
+ y11 = y10;
+
+ fract_x = fract (in_img_x);
+ fract_y = fract (in_img_y);
+ weight00 = (1.0f - fract_x) * (1.0f - fract_y);
+ weight01 = fract_x * (1.0f - fract_y);
+ weight10 = (1.0f - fract_x) * fract_y;
+ weight11 = fract_x * fract_y;
+
+ uvec4 x00_floor = x00 / UNIT_SIZE;
+ uvec4 x01_floor = x01 / UNIT_SIZE;
+ uvec4 x10_floor = x10 / UNIT_SIZE;
+ uvec4 x11_floor = x11 / UNIT_SIZE;
+ uvec4 x00_fract = x00 % UNIT_SIZE;
+ uvec4 x01_fract = x01 % UNIT_SIZE;
+ uvec4 x10_fract = x10 % UNIT_SIZE;
+ uvec4 x11_fract = x11 % UNIT_SIZE;
+
+ index00 = y00 * prop.in_img_width + x00_floor;
+ index01 = y01 * prop.in_img_width + x01_floor;
+ index10 = y10 * prop.in_img_width + x10_floor;
+ index11 = y11 * prop.in_img_width + x11_floor;
+
+ // pixel Y-value
+ vec4 out_y00, out_y01, out_y10, out_y11;
+ unpack_unorm_y (0);
+ unpack_unorm_y (1);
+ unpack_unorm_y (2);
+ unpack_unorm_y (3);
+
+ vec4 inter_y = out_y00 * weight00 + out_y01 * weight01 + out_y10 * weight10 + out_y11 * weight11;
+ out_data = packUnorm4x8 (inter_y * vec4 (not (out_bound)));
+}
+
+void geomap_uv (vec2 in_uv_x, vec2 in_uv_y, bvec4 out_bound_uv, out uint out_data)
+{
+ uvec2 x00 = uvec2 (in_uv_x);
+ uvec2 y00 = uvec2 (in_uv_y);
+ uvec2 x01 = x00 + 1u;
+ uvec2 y01 = y00;
+ uvec2 x10 = x00;
+ uvec2 y10 = y00 + 1u;
+ uvec2 x11 = x01;
+ uvec2 y11 = y10;
+
+ vec2 fract_x = fract (in_uv_x);
+ vec2 fract_y = fract (in_uv_y);
+ vec2 weight00 = (1.0f - fract_x) * (1.0f - fract_y);
+ vec2 weight01 = fract_x * (1.0f - fract_y);
+ vec2 weight10 = (1.0f - fract_x) * fract_y;
+ vec2 weight11 = fract_x * fract_y;
+
+ uvec2 x00_floor = x00 / UNIT_SIZE;
+ uvec2 x01_floor = x01 / UNIT_SIZE;
+ uvec2 x10_floor = x10 / UNIT_SIZE;
+ uvec2 x11_floor = x11 / UNIT_SIZE;
+ uvec2 x00_fract = (x00 % UNIT_SIZE) / 2u;
+ uvec2 x01_fract = (x01 % UNIT_SIZE) / 2u;
+ uvec2 x10_fract = (x10 % UNIT_SIZE) / 2u;
+ uvec2 x11_fract = (x11 % UNIT_SIZE) / 2u;
+
+ uvec2 index00 = y00 * prop.in_img_width + x00_floor;
+ uvec2 index01 = y01 * prop.in_img_width + x01_floor;
+ uvec2 index10 = y10 * prop.in_img_width + x10_floor;
+ uvec2 index11 = y11 * prop.in_img_width + x11_floor;
+
+ // pixel UV-value
+ vec4 out_uv00, out_uv01, out_uv10, out_uv11;
+ vec4 value = unpackUnorm4x8 (in_buf_uv.data[index00.x]);
+ out_uv00.xy = x00_fract.x == 0u ? value.xy : value.zw;
+ value = unpackUnorm4x8 (in_buf_uv.data[index01.x]);
+ out_uv01.xy = x01_fract.x == 0u ? value.xy : value.zw;
+ value = unpackUnorm4x8 (in_buf_uv.data[index10.x]);
+ out_uv10.xy = x10_fract.x == 0u ? value.xy : value.zw;
+ value = unpackUnorm4x8 (in_buf_uv.data[index11.x]);
+ out_uv11.xy = x11_fract.x == 0u ? value.xy : value.zw;
+
+ value = unpackUnorm4x8 (in_buf_uv.data[index00.y]);
+ out_uv00.zw = x00_fract.y == 0u ? value.xy : value.zw;
+ value = unpackUnorm4x8 (in_buf_uv.data[index01.y]);
+ out_uv01.zw = x01_fract.y == 0u ? value.xy : value.zw;
+ value = unpackUnorm4x8 (in_buf_uv.data[index10.y]);
+ out_uv10.zw = x10_fract.y == 0u ? value.xy : value.zw;
+ value = unpackUnorm4x8 (in_buf_uv.data[index11.y]);
+ out_uv11.zw = x11_fract.y == 0u ? value.xy : value.zw;
+
+ vec4 inter_uv = out_uv00 * weight00.xxyy + out_uv01 * weight01.xxyy +
+ out_uv10 * weight10.xxyy + out_uv11 * weight11.xxyy;
+ inter_uv = inter_uv * vec4 (not (out_bound_uv)) + vec4 (out_bound_uv) * 0.5f;
+ out_data = packUnorm4x8 (inter_uv);
+}
diff --git a/shaders/spv/shader_geomap.comp.spv b/shaders/spv/shader_geomap.comp.spv
new file mode 100644
index 0000000..6f822b8
--- /dev/null
+++ b/shaders/spv/shader_geomap.comp.spv
@@ -0,0 +1,847 @@
+ // 7.8.2870
+ 0x07230203,0x00010000,0x00080007,0x00000466,0x00000000,0x00020011,0x00000001,0x0006000b,
+ 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,
+ 0x0006000f,0x00000005,0x00000004,0x6e69616d,0x00000000,0x00000023,0x00060010,0x00000004,
+ 0x00000011,0x00000008,0x00000008,0x00000001,0x00030003,0x00000001,0x00000136,0x00040005,
+ 0x00000004,0x6e69616d,0x00000000,0x000b0005,0x00000015,0x6d6f6567,0x795f7061,0x34667628,
+ 0x3466763b,0x3466763b,0x3466763b,0x3462763b,0x3b31753b,0x00000000,0x00040005,0x0000000f,
+ 0x5f74756c,0x00000078,0x00040005,0x00000010,0x5f74756c,0x00000079,0x00050005,0x00000011,
+ 0x695f6e69,0x785f676d,0x00000000,0x00050005,0x00000012,0x695f6e69,0x795f676d,0x00000000,
+ 0x00050005,0x00000013,0x5f74756f,0x6e756f62,0x00000064,0x00050005,0x00000014,0x5f74756f,
+ 0x61746164,0x00000000,0x00090005,0x0000001e,0x6d6f6567,0x755f7061,0x66762876,0x66763b32,
+ 0x62763b32,0x31753b34,0x0000003b,0x00040005,0x0000001a,0x755f6e69,0x00785f76,0x00040005,
+ 0x0000001b,0x755f6e69,0x00795f76,0x00060005,0x0000001c,0x5f74756f,0x6e756f62,0x76755f64,
+ 0x00000000,0x00050005,0x0000001d,0x5f74756f,0x61746164,0x00000000,0x00030005,0x00000020,
+ 0x00785f67,0x00080005,0x00000023,0x475f6c67,0x61626f6c,0x766e496c,0x7461636f,0x496e6f69,
+ 0x00000044,0x00030005,0x00000028,0x00795f67,0x00040005,0x0000002e,0x746e6563,0x00000000,
+ 0x00050005,0x00000032,0x68737550,0x736e6f43,0x00007374,0x00070006,0x00000032,0x00000000,
+ 0x695f6e69,0x775f676d,0x68746469,0x00000000,0x00070006,0x00000032,0x00000001,0x695f6e69,
+ 0x685f676d,0x68676965,0x00000074,0x00070006,0x00000032,0x00000002,0x5f74756f,0x5f676d69,
+ 0x74646977,0x00000068,0x00070006,0x00000032,0x00000003,0x5f74756f,0x5f676d69,0x67696568,
+ 0x00007468,0x00060006,0x00000032,0x00000004,0x5f74756c,0x74646977,0x00000068,0x00060006,
+ 0x00000032,0x00000005,0x5f74756c,0x67696568,0x00007468,0x00060006,0x00000032,0x00000006,
+ 0x5f74756c,0x70657473,0x00000000,0x00070006,0x00000032,0x00000007,0x5f74756c,0x5f647473,
+ 0x70657473,0x00000000,0x00040005,0x00000034,0x706f7270,0x00000000,0x00040005,0x00000046,
+ 0x70657473,0x00000000,0x00040005,0x00000060,0x72617473,0x00000074,0x00040005,0x00000073,
+ 0x5f74756c,0x00000078,0x00040005,0x00000085,0x5f74756c,0x00000079,0x00050005,0x0000009d,
+ 0x695f6e69,0x785f676d,0x00000000,0x00050005,0x0000009e,0x695f6e69,0x795f676d,0x00000000,
+ 0x00050005,0x0000009f,0x5f74756f,0x6e756f62,0x00000064,0x00050005,0x000000a0,0x5f74756f,
+ 0x61746164,0x00000000,0x00040005,0x000000a1,0x61726170,0x0000006d,0x00040005,0x000000a3,
+ 0x61726170,0x0000006d,0x00040005,0x000000a5,0x61726170,0x0000006d,0x00040005,0x000000a6,
+ 0x61726170,0x0000006d,0x00040005,0x000000a7,0x61726170,0x0000006d,0x00040005,0x000000a8,
+ 0x61726170,0x0000006d,0x00040005,0x000000af,0x4274754f,0x00596675,0x00050006,0x000000af,
+ 0x00000000,0x61746164,0x00000000,0x00050005,0x000000b1,0x5f74756f,0x5f667562,0x00000079,
+ 0x00060005,0x000000bb,0x5f74756f,0x6e756f62,0x76755f64,0x00000000,0x00040005,0x000000c6,
+ 0x755f6e69,0x00785f76,0x00040005,0x000000c9,0x755f6e69,0x00795f76,0x00040005,0x000000d7,
+ 0x61726170,0x0000006d,0x00040005,0x000000d9,0x61726170,0x0000006d,0x00040005,0x000000db,
+ 0x61726170,0x0000006d,0x00040005,0x000000dd,0x61726170,0x0000006d,0x00050005,0x000000e1,
+ 0x4274754f,0x56556675,0x00000000,0x00050006,0x000000e1,0x00000000,0x61746164,0x00000000,
+ 0x00050005,0x000000e3,0x5f74756f,0x5f667562,0x00007675,0x00040005,0x000000f2,0x61726170,
+ 0x0000006d,0x00040005,0x000000f4,0x61726170,0x0000006d,0x00040005,0x000000f6,0x61726170,
+ 0x0000006d,0x00040005,0x000000f7,0x61726170,0x0000006d,0x00040005,0x000000f8,0x61726170,
+ 0x0000006d,0x00040005,0x000000f9,0x61726170,0x0000006d,0x00030005,0x0000010a,0x00303078,
+ 0x00030005,0x0000010d,0x00303079,0x00030005,0x00000110,0x00313078,0x00030005,0x00000114,
+ 0x00313079,0x00030005,0x00000116,0x00303178,0x00030005,0x00000118,0x00303179,0x00030005,
+ 0x0000011c,0x00313178,0x00030005,0x0000011e,0x00313179,0x00040005,0x00000120,0x63617266,
+ 0x00785f74,0x00040005,0x00000123,0x63617266,0x00795f74,0x00050005,0x00000126,0x67696577,
+ 0x30307468,0x00000000,0x00050005,0x0000012e,0x67696577,0x31307468,0x00000000,0x00050005,
+ 0x00000134,0x67696577,0x30317468,0x00000000,0x00050005,0x0000013a,0x67696577,0x31317468,
+ 0x00000000,0x00040005,0x0000013e,0x65646e69,0x00303078,0x00040005,0x00000146,0x65646e69,
+ 0x00313078,0x00040005,0x0000014e,0x65646e69,0x00303178,0x00040005,0x00000156,0x65646e69,
+ 0x00313178,0x00030005,0x0000015e,0x00000069,0x00040005,0x00000166,0x756c6176,0x00000065,
+ 0x00050005,0x00000168,0x4d6f6547,0x61547061,0x00656c62,0x00050006,0x00000168,0x00000000,
+ 0x61746164,0x00000000,0x00030005,0x0000016a,0x0074756c,0x00050005,0x00000171,0x695f6e69,
+ 0x785f676d,0x00003030,0x00050005,0x00000176,0x695f6e69,0x795f676d,0x00003030,0x00050005,
+ 0x00000180,0x695f6e69,0x785f676d,0x00003130,0x00050005,0x00000185,0x695f6e69,0x795f676d,
+ 0x00003130,0x00050005,0x0000018f,0x695f6e69,0x785f676d,0x00003031,0x00050005,0x00000194,
+ 0x695f6e69,0x795f676d,0x00003031,0x00050005,0x0000019e,0x695f6e69,0x785f676d,0x00003131,
+ 0x00050005,0x000001a3,0x695f6e69,0x795f676d,0x00003131,0x00030005,0x000001c8,0x00000069,
+ 0x00050005,0x00000225,0x5f303078,0x6f6f6c66,0x00000072,0x00050005,0x00000229,0x5f313078,
+ 0x6f6f6c66,0x00000072,0x00050005,0x0000022d,0x5f303178,0x6f6f6c66,0x00000072,0x00050005,
+ 0x00000231,0x5f313178,0x6f6f6c66,0x00000072,0x00050005,0x00000235,0x5f303078,0x63617266,
+ 0x00000074,0x00050005,0x00000239,0x5f313078,0x63617266,0x00000074,0x00050005,0x0000023d,
+ 0x5f303178,0x63617266,0x00000074,0x00050005,0x00000241,0x5f313178,0x63617266,0x00000074,
+ 0x00040005,0x00000261,0x756c6176,0x00000065,0x00040005,0x00000263,0x75426e49,0x00005966,
+ 0x00050006,0x00000263,0x00000000,0x61746164,0x00000000,0x00050005,0x00000265,0x625f6e69,
+ 0x795f6675,0x00000000,0x00040005,0x0000026b,0x5f74756f,0x00303079,0x00040005,0x00000276,
+ 0x5f74756f,0x00313079,0x00040005,0x00000281,0x5f74756f,0x00303179,0x00040005,0x0000028c,
+ 0x5f74756f,0x00313179,0x00040005,0x00000292,0x756c6176,0x00000065,0x00040005,0x000002bb,
+ 0x756c6176,0x00000065,0x00040005,0x000002e4,0x756c6176,0x00000065,0x00040005,0x0000030e,
+ 0x65746e69,0x00795f72,0x00030005,0x00000328,0x00303078,0x00030005,0x0000032b,0x00303079,
+ 0x00030005,0x0000032e,0x00313078,0x00030005,0x00000332,0x00313079,0x00030005,0x00000334,
+ 0x00303178,0x00030005,0x00000336,0x00303179,0x00030005,0x0000033a,0x00313178,0x00030005,
+ 0x0000033c,0x00313179,0x00040005,0x0000033e,0x63617266,0x00785f74,0x00040005,0x00000341,
+ 0x63617266,0x00795f74,0x00050005,0x00000344,0x67696577,0x30307468,0x00000000,0x00050005,
+ 0x0000034c,0x67696577,0x31307468,0x00000000,0x00050005,0x00000352,0x67696577,0x30317468,
+ 0x00000000,0x00050005,0x00000358,0x67696577,0x31317468,0x00000000,0x00050005,0x0000035c,
+ 0x5f303078,0x6f6f6c66,0x00000072,0x00050005,0x00000360,0x5f313078,0x6f6f6c66,0x00000072,
+ 0x00050005,0x00000364,0x5f303178,0x6f6f6c66,0x00000072,0x00050005,0x00000368,0x5f313178,
+ 0x6f6f6c66,0x00000072,0x00050005,0x0000036c,0x5f303078,0x63617266,0x00000074,0x00050005,
+ 0x00000372,0x5f313078,0x63617266,0x00000074,0x00050005,0x00000378,0x5f303178,0x63617266,
+ 0x00000074,0x00050005,0x0000037e,0x5f313178,0x63617266,0x00000074,0x00040005,0x00000384,
+ 0x65646e69,0x00303078,0x00040005,0x0000038c,0x65646e69,0x00313078,0x00040005,0x00000394,
+ 0x65646e69,0x00303178,0x00040005,0x0000039c,0x65646e69,0x00313178,0x00040005,0x000003a4,
+ 0x756c6176,0x00000065,0x00040005,0x000003a6,0x75426e49,0x00565566,0x00050006,0x000003a6,
+ 0x00000000,0x61746164,0x00000000,0x00050005,0x000003a8,0x625f6e69,0x755f6675,0x00000076,
+ 0x00050005,0x000003ae,0x5f74756f,0x30307675,0x00000000,0x00050005,0x000003c2,0x5f74756f,
+ 0x31307675,0x00000000,0x00050005,0x000003d6,0x5f74756f,0x30317675,0x00000000,0x00050005,
+ 0x000003ea,0x5f74756f,0x31317675,0x00000000,0x00050005,0x00000445,0x65746e69,0x76755f72,
+ 0x00000000,0x00040047,0x00000023,0x0000000b,0x0000001c,0x00040047,0x00000030,0x00000006,
+ 0x00000004,0x00040047,0x00000031,0x00000006,0x00000004,0x00050048,0x00000032,0x00000000,
+ 0x00000023,0x00000000,0x00050048,0x00000032,0x00000001,0x00000023,0x00000004,0x00050048,
+ 0x00000032,0x00000002,0x00000023,0x00000008,0x00050048,0x00000032,0x00000003,0x00000023,
+ 0x0000000c,0x00050048,0x00000032,0x00000004,0x00000023,0x00000010,0x00050048,0x00000032,
+ 0x00000005,0x00000023,0x00000014,0x00050048,0x00000032,0x00000006,0x00000023,0x00000018,
+ 0x00050048,0x00000032,0x00000007,0x00000023,0x00000028,0x00030047,0x00000032,0x00000002,
+ 0x00040047,0x000000ae,0x00000006,0x00000004,0x00040048,0x000000af,0x00000000,0x00000019,
+ 0x00050048,0x000000af,0x00000000,0x00000023,0x00000000,0x00030047,0x000000af,0x00000003,
+ 0x00040047,0x000000b1,0x00000022,0x00000000,0x00040047,0x000000b1,0x00000021,0x00000002,
+ 0x00040047,0x000000e0,0x00000006,0x00000004,0x00040048,0x000000e1,0x00000000,0x00000019,
+ 0x00050048,0x000000e1,0x00000000,0x00000023,0x00000000,0x00030047,0x000000e1,0x00000003,
+ 0x00040047,0x000000e3,0x00000022,0x00000000,0x00040047,0x000000e3,0x00000021,0x00000003,
+ 0x00040047,0x00000167,0x00000006,0x00000008,0x00040048,0x00000168,0x00000000,0x00000018,
+ 0x00050048,0x00000168,0x00000000,0x00000023,0x00000000,0x00030047,0x00000168,0x00000003,
+ 0x00040047,0x0000016a,0x00000022,0x00000000,0x00040047,0x0000016a,0x00000021,0x00000004,
+ 0x00040047,0x00000262,0x00000006,0x00000004,0x00040048,0x00000263,0x00000000,0x00000018,
+ 0x00050048,0x00000263,0x00000000,0x00000023,0x00000000,0x00030047,0x00000263,0x00000003,
+ 0x00040047,0x00000265,0x00000022,0x00000000,0x00040047,0x00000265,0x00000021,0x00000000,
+ 0x00040047,0x000003a5,0x00000006,0x00000004,0x00040048,0x000003a6,0x00000000,0x00000018,
+ 0x00050048,0x000003a6,0x00000000,0x00000023,0x00000000,0x00030047,0x000003a6,0x00000003,
+ 0x00040047,0x000003a8,0x00000022,0x00000000,0x00040047,0x000003a8,0x00000021,0x00000001,
+ 0x00040047,0x00000465,0x0000000b,0x00000019,0x00020013,0x00000002,0x00030021,0x00000003,
+ 0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000004,
+ 0x00040020,0x00000008,0x00000007,0x00000007,0x00020014,0x00000009,0x00040017,0x0000000a,
+ 0x00000009,0x00000004,0x00040020,0x0000000b,0x00000007,0x0000000a,0x00040015,0x0000000c,
+ 0x00000020,0x00000000,0x00040020,0x0000000d,0x00000007,0x0000000c,0x00090021,0x0000000e,
+ 0x00000002,0x00000008,0x00000008,0x00000008,0x00000008,0x0000000b,0x0000000d,0x00040017,
+ 0x00000017,0x00000006,0x00000002,0x00040020,0x00000018,0x00000007,0x00000017,0x00070021,
+ 0x00000019,0x00000002,0x00000018,0x00000018,0x0000000b,0x0000000d,0x00040017,0x00000021,
+ 0x0000000c,0x00000003,0x00040020,0x00000022,0x00000001,0x00000021,0x0004003b,0x00000022,
+ 0x00000023,0x00000001,0x0004002b,0x0000000c,0x00000024,0x00000000,0x00040020,0x00000025,
+ 0x00000001,0x0000000c,0x0004002b,0x0000000c,0x00000029,0x00000001,0x0004002b,0x0000000c,
+ 0x0000002c,0x00000002,0x0004002b,0x0000000c,0x0000002f,0x00000004,0x0004001c,0x00000030,
+ 0x00000006,0x0000002f,0x0004001c,0x00000031,0x00000006,0x0000002c,0x000a001e,0x00000032,
+ 0x0000000c,0x0000000c,0x0000000c,0x0000000c,0x0000000c,0x0000000c,0x00000030,0x00000031,
+ 0x00040020,0x00000033,0x00000009,0x00000032,0x0004003b,0x00000033,0x00000034,0x00000009,
+ 0x00040015,0x00000035,0x00000020,0x00000001,0x0004002b,0x00000035,0x00000036,0x00000002,
+ 0x00040020,0x00000037,0x00000009,0x0000000c,0x0004002b,0x00000035,0x0000003b,0x00000003,
+ 0x0004002b,0x00000006,0x00000040,0x3f800000,0x0004002b,0x00000006,0x00000043,0x40000000,
+ 0x00040020,0x00000048,0x00000007,0x00000006,0x0004002b,0x00000035,0x00000050,0x00000006,
+ 0x0004002b,0x00000035,0x00000051,0x00000000,0x00040020,0x00000052,0x00000009,0x00000006,
+ 0x0004002b,0x00000035,0x00000055,0x00000001,0x0004002b,0x00000035,0x0000006b,0x00000007,
+ 0x0004002b,0x00000006,0x00000076,0x40800000,0x0004002b,0x00000006,0x00000078,0x00000000,
+ 0x0004002b,0x00000006,0x00000080,0x40400000,0x0004002b,0x00000035,0x00000089,0x00000004,
+ 0x0004002b,0x00000035,0x00000092,0x00000005,0x0003001d,0x000000ae,0x0000000c,0x0003001e,
+ 0x000000af,0x000000ae,0x00040020,0x000000b0,0x00000002,0x000000af,0x0004003b,0x000000b0,
+ 0x000000b1,0x00000002,0x00040020,0x000000b9,0x00000002,0x0000000c,0x0004002b,0x00000006,
+ 0x000000c2,0x3f000000,0x0007002c,0x00000007,0x000000c3,0x000000c2,0x000000c2,0x000000c2,
+ 0x000000c2,0x0003001d,0x000000e0,0x0000000c,0x0003001e,0x000000e1,0x000000e0,0x00040020,
+ 0x000000e2,0x00000002,0x000000e1,0x0004003b,0x000000e2,0x000000e3,0x00000002,0x00040017,
+ 0x00000108,0x0000000c,0x00000004,0x00040020,0x00000109,0x00000007,0x00000108,0x0003001d,
+ 0x00000167,0x00000017,0x0003001e,0x00000168,0x00000167,0x00040020,0x00000169,0x00000002,
+ 0x00000168,0x0004003b,0x00000169,0x0000016a,0x00000002,0x00040020,0x0000016e,0x00000002,
+ 0x00000017,0x00040020,0x000001f6,0x00000007,0x00000009,0x0003001d,0x00000262,0x0000000c,
+ 0x0003001e,0x00000263,0x00000262,0x00040020,0x00000264,0x00000002,0x00000263,0x0004003b,
+ 0x00000264,0x00000265,0x00000002,0x0004002b,0x0000000c,0x000002e5,0x00000003,0x0007002c,
+ 0x00000007,0x00000321,0x00000078,0x00000078,0x00000078,0x00000078,0x0007002c,0x00000007,
+ 0x00000322,0x00000040,0x00000040,0x00000040,0x00000040,0x00040017,0x00000326,0x0000000c,
+ 0x00000002,0x00040020,0x00000327,0x00000007,0x00000326,0x0003001d,0x000003a5,0x0000000c,
+ 0x0003001e,0x000003a6,0x000003a5,0x00040020,0x000003a7,0x00000002,0x000003a6,0x0004003b,
+ 0x000003a7,0x000003a8,0x00000002,0x0004002b,0x0000000c,0x00000464,0x00000008,0x0006002c,
+ 0x00000021,0x00000465,0x00000464,0x00000464,0x00000029,0x00050036,0x00000002,0x00000004,
+ 0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003b,0x0000000d,0x00000020,0x00000007,
+ 0x0004003b,0x0000000d,0x00000028,0x00000007,0x0004003b,0x00000018,0x0000002e,0x00000007,
+ 0x0004003b,0x00000018,0x00000046,0x00000007,0x0004003b,0x00000018,0x0000004d,0x00000007,
+ 0x0004003b,0x00000018,0x00000060,0x00000007,0x0004003b,0x00000008,0x00000073,0x00000007,
+ 0x0004003b,0x00000008,0x00000085,0x00000007,0x0004003b,0x00000008,0x0000009d,0x00000007,
+ 0x0004003b,0x00000008,0x0000009e,0x00000007,0x0004003b,0x0000000b,0x0000009f,0x00000007,
+ 0x0004003b,0x0000000d,0x000000a0,0x00000007,0x0004003b,0x00000008,0x000000a1,0x00000007,
+ 0x0004003b,0x00000008,0x000000a3,0x00000007,0x0004003b,0x00000008,0x000000a5,0x00000007,
+ 0x0004003b,0x00000008,0x000000a6,0x00000007,0x0004003b,0x0000000b,0x000000a7,0x00000007,
+ 0x0004003b,0x0000000d,0x000000a8,0x00000007,0x0004003b,0x0000000b,0x000000bb,0x00000007,
+ 0x0004003b,0x00000018,0x000000c6,0x00000007,0x0004003b,0x00000018,0x000000c9,0x00000007,
+ 0x0004003b,0x00000018,0x000000d7,0x00000007,0x0004003b,0x00000018,0x000000d9,0x00000007,
+ 0x0004003b,0x0000000b,0x000000db,0x00000007,0x0004003b,0x0000000d,0x000000dd,0x00000007,
+ 0x0004003b,0x00000008,0x000000f2,0x00000007,0x0004003b,0x00000008,0x000000f4,0x00000007,
+ 0x0004003b,0x00000008,0x000000f6,0x00000007,0x0004003b,0x00000008,0x000000f7,0x00000007,
+ 0x0004003b,0x0000000b,0x000000f8,0x00000007,0x0004003b,0x0000000d,0x000000f9,0x00000007,
+ 0x00050041,0x00000025,0x00000026,0x00000023,0x00000024,0x0004003d,0x0000000c,0x00000027,
+ 0x00000026,0x0003003e,0x00000020,0x00000027,0x00050041,0x00000025,0x0000002a,0x00000023,
+ 0x00000029,0x0004003d,0x0000000c,0x0000002b,0x0000002a,0x00050084,0x0000000c,0x0000002d,
+ 0x0000002b,0x0000002c,0x0003003e,0x00000028,0x0000002d,0x00050041,0x00000037,0x00000038,
+ 0x00000034,0x00000036,0x0004003d,0x0000000c,0x00000039,0x00000038,0x00040070,0x00000006,
+ 0x0000003a,0x00000039,0x00050041,0x00000037,0x0000003c,0x00000034,0x0000003b,0x0004003d,
+ 0x0000000c,0x0000003d,0x0000003c,0x00040070,0x00000006,0x0000003e,0x0000003d,0x00050050,
+ 0x00000017,0x0000003f,0x0000003a,0x0000003e,0x00050050,0x00000017,0x00000041,0x00000040,
+ 0x00000040,0x00050083,0x00000017,0x00000042,0x0000003f,0x00000041,0x00050050,0x00000017,
+ 0x00000044,0x00000043,0x00000043,0x00050088,0x00000017,0x00000045,0x00000042,0x00000044,
+ 0x0003003e,0x0000002e,0x00000045,0x0004003d,0x0000000c,0x00000047,0x00000020,0x00050041,
+ 0x00000048,0x00000049,0x0000002e,0x00000024,0x0004003d,0x00000006,0x0000004a,0x00000049,
+ 0x0004006d,0x0000000c,0x0000004b,0x0000004a,0x000500b0,0x00000009,0x0000004c,0x00000047,
+ 0x0000004b,0x000300f7,0x0000004f,0x00000000,0x000400fa,0x0000004c,0x0000004e,0x00000059,
+ 0x000200f8,0x0000004e,0x00060041,0x00000052,0x00000053,0x00000034,0x00000050,0x00000051,
+ 0x0004003d,0x00000006,0x00000054,0x00000053,0x00060041,0x00000052,0x00000056,0x00000034,
+ 0x00000050,0x00000055,0x0004003d,0x00000006,0x00000057,0x00000056,0x00050050,0x00000017,
+ 0x00000058,0x00000054,0x00000057,0x0003003e,0x0000004d,0x00000058,0x000200f9,0x0000004f,
+ 0x000200f8,0x00000059,0x00060041,0x00000052,0x0000005a,0x00000034,0x00000050,0x00000036,
+ 0x0004003d,0x00000006,0x0000005b,0x0000005a,0x00060041,0x00000052,0x0000005c,0x00000034,
+ 0x00000050,0x0000003b,0x0004003d,0x00000006,0x0000005d,0x0000005c,0x00050050,0x00000017,
+ 0x0000005e,0x0000005b,0x0000005d,0x0003003e,0x0000004d,0x0000005e,0x000200f9,0x0000004f,
+ 0x000200f8,0x0000004f,0x0004003d,0x00000017,0x0000005f,0x0000004d,0x0003003e,0x00000046,
+ 0x0000005f,0x0004003d,0x0000000c,0x00000061,0x00000020,0x00040070,0x00000006,0x00000062,
+ 0x00000061,0x0004003d,0x0000000c,0x00000063,0x00000028,0x00040070,0x00000006,0x00000064,
+ 0x00000063,0x00050050,0x00000017,0x00000065,0x00000062,0x00000064,0x0004003d,0x00000017,
+ 0x00000066,0x0000002e,0x00050083,0x00000017,0x00000067,0x00000065,0x00000066,0x0004003d,
+ 0x00000017,0x00000068,0x00000046,0x00050085,0x00000017,0x00000069,0x00000067,0x00000068,
+ 0x0004003d,0x00000017,0x0000006a,0x0000002e,0x00060041,0x00000052,0x0000006c,0x00000034,
+ 0x0000006b,0x00000051,0x0004003d,0x00000006,0x0000006d,0x0000006c,0x00060041,0x00000052,
+ 0x0000006e,0x00000034,0x0000006b,0x00000055,0x0004003d,0x00000006,0x0000006f,0x0000006e,
+ 0x00050050,0x00000017,0x00000070,0x0000006d,0x0000006f,0x00050085,0x00000017,0x00000071,
+ 0x0000006a,0x00000070,0x00050081,0x00000017,0x00000072,0x00000069,0x00000071,0x0003003e,
+ 0x00000060,0x00000072,0x00050041,0x00000048,0x00000074,0x00000060,0x00000024,0x0004003d,
+ 0x00000006,0x00000075,0x00000074,0x00050085,0x00000006,0x00000077,0x00000075,0x00000076,
+ 0x00050041,0x00000048,0x00000079,0x00000046,0x00000024,0x0004003d,0x00000006,0x0000007a,
+ 0x00000079,0x00050041,0x00000048,0x0000007b,0x00000046,0x00000024,0x0004003d,0x00000006,
+ 0x0000007c,0x0000007b,0x00050085,0x00000006,0x0000007d,0x0000007c,0x00000043,0x00050041,
+ 0x00000048,0x0000007e,0x00000046,0x00000024,0x0004003d,0x00000006,0x0000007f,0x0000007e,
+ 0x00050085,0x00000006,0x00000081,0x0000007f,0x00000080,0x00070050,0x00000007,0x00000082,
+ 0x00000078,0x0000007a,0x0000007d,0x00000081,0x00070050,0x00000007,0x00000083,0x00000077,
+ 0x00000077,0x00000077,0x00000077,0x00050081,0x00000007,0x00000084,0x00000083,0x00000082,
+ 0x0003003e,0x00000073,0x00000084,0x0004003d,0x00000017,0x00000086,0x00000060,0x0009004f,
+ 0x00000007,0x00000087,0x00000086,0x00000086,0x00000001,0x00000001,0x00000001,0x00000001,
+ 0x0003003e,0x00000085,0x00000087,0x0004003d,0x00000007,0x00000088,0x00000073,0x00050041,
+ 0x00000037,0x0000008a,0x00000034,0x00000089,0x0004003d,0x0000000c,0x0000008b,0x0000008a,
+ 0x00040070,0x00000006,0x0000008c,0x0000008b,0x00050083,0x00000006,0x0000008d,0x0000008c,
+ 0x00000040,0x00070050,0x00000007,0x0000008e,0x00000078,0x00000078,0x00000078,0x00000078,
+ 0x00070050,0x00000007,0x0000008f,0x0000008d,0x0000008d,0x0000008d,0x0000008d,0x0008000c,
+ 0x00000007,0x00000090,0x00000001,0x0000002b,0x00000088,0x0000008e,0x0000008f,0x0003003e,
+ 0x00000073,0x00000090,0x0004003d,0x00000007,0x00000091,0x00000085,0x00050041,0x00000037,
+ 0x00000093,0x00000034,0x00000092,0x0004003d,0x0000000c,0x00000094,0x00000093,0x00040070,
+ 0x00000006,0x00000095,0x00000094,0x00050083,0x00000006,0x00000096,0x00000095,0x00000040,
+ 0x00050041,0x00000048,0x00000097,0x00000046,0x00000029,0x0004003d,0x00000006,0x00000098,
+ 0x00000097,0x00050083,0x00000006,0x00000099,0x00000096,0x00000098,0x00070050,0x00000007,
+ 0x0000009a,0x00000078,0x00000078,0x00000078,0x00000078,0x00070050,0x00000007,0x0000009b,
+ 0x00000099,0x00000099,0x00000099,0x00000099,0x0008000c,0x00000007,0x0000009c,0x00000001,
+ 0x0000002b,0x00000091,0x0000009a,0x0000009b,0x0003003e,0x00000085,0x0000009c,0x0004003d,
+ 0x00000007,0x000000a2,0x00000073,0x0003003e,0x000000a1,0x000000a2,0x0004003d,0x00000007,
+ 0x000000a4,0x00000085,0x0003003e,0x000000a3,0x000000a4,0x000a0039,0x00000002,0x000000a9,
+ 0x00000015,0x000000a1,0x000000a3,0x000000a5,0x000000a6,0x000000a7,0x000000a8,0x0004003d,
+ 0x00000007,0x000000aa,0x000000a5,0x0003003e,0x0000009d,0x000000aa,0x0004003d,0x00000007,
+ 0x000000ab,0x000000a6,0x0003003e,0x0000009e,0x000000ab,0x0004003d,0x0000000a,0x000000ac,
+ 0x000000a7,0x0003003e,0x0000009f,0x000000ac,0x0004003d,0x0000000c,0x000000ad,0x000000a8,
+ 0x0003003e,0x000000a0,0x000000ad,0x0004003d,0x0000000c,0x000000b2,0x00000028,0x00050041,
+ 0x00000037,0x000000b3,0x00000034,0x00000036,0x0004003d,0x0000000c,0x000000b4,0x000000b3,
+ 0x00050084,0x0000000c,0x000000b5,0x000000b2,0x000000b4,0x0004003d,0x0000000c,0x000000b6,
+ 0x00000020,0x00050080,0x0000000c,0x000000b7,0x000000b5,0x000000b6,0x0004003d,0x0000000c,
+ 0x000000b8,0x000000a0,0x00060041,0x000000b9,0x000000ba,0x000000b1,0x00000051,0x000000b7,
+ 0x0003003e,0x000000ba,0x000000b8,0x0004003d,0x0000000a,0x000000bc,0x0000009f,0x0009004f,
+ 0x0000000a,0x000000bd,0x000000bc,0x000000bc,0x00000000,0x00000000,0x00000002,0x00000002,
+ 0x0003003e,0x000000bb,0x000000bd,0x0004003d,0x0000000a,0x000000be,0x000000bb,0x0004009b,
+ 0x00000009,0x000000bf,0x000000be,0x000300f7,0x000000c1,0x00000000,0x000400fa,0x000000bf,
+ 0x000000c0,0x000000c5,0x000200f8,0x000000c0,0x0006000c,0x0000000c,0x000000c4,0x00000001,
+ 0x00000037,0x000000c3,0x0003003e,0x000000a0,0x000000c4,0x000200f9,0x000000c1,0x000200f8,
+ 0x000000c5,0x0004003d,0x00000007,0x000000c7,0x0000009d,0x0007004f,0x00000017,0x000000c8,
+ 0x000000c7,0x000000c7,0x00000000,0x00000002,0x0003003e,0x000000c6,0x000000c8,0x0004003d,
+ 0x00000007,0x000000ca,0x0000009e,0x0007004f,0x00000017,0x000000cb,0x000000ca,0x000000ca,
+ 0x00000000,0x00000002,0x00050050,0x00000017,0x000000cc,0x00000043,0x00000043,0x00050088,
+ 0x00000017,0x000000cd,0x000000cb,0x000000cc,0x0003003e,0x000000c9,0x000000cd,0x0004003d,
+ 0x00000017,0x000000ce,0x000000c9,0x00050041,0x00000037,0x000000cf,0x00000034,0x00000055,
+ 0x0004003d,0x0000000c,0x000000d0,0x000000cf,0x00050086,0x0000000c,0x000000d1,0x000000d0,
+ 0x0000002c,0x00050082,0x0000000c,0x000000d2,0x000000d1,0x00000029,0x00040070,0x00000006,
+ 0x000000d3,0x000000d2,0x00050050,0x00000017,0x000000d4,0x00000078,0x00000078,0x00050050,
+ 0x00000017,0x000000d5,0x000000d3,0x000000d3,0x0008000c,0x00000017,0x000000d6,0x00000001,
+ 0x0000002b,0x000000ce,0x000000d4,0x000000d5,0x0003003e,0x000000c9,0x000000d6,0x0004003d,
+ 0x00000017,0x000000d8,0x000000c6,0x0003003e,0x000000d7,0x000000d8,0x0004003d,0x00000017,
+ 0x000000da,0x000000c9,0x0003003e,0x000000d9,0x000000da,0x0004003d,0x0000000a,0x000000dc,
+ 0x000000bb,0x0003003e,0x000000db,0x000000dc,0x00080039,0x00000002,0x000000de,0x0000001e,
+ 0x000000d7,0x000000d9,0x000000db,0x000000dd,0x0004003d,0x0000000c,0x000000df,0x000000dd,
+ 0x0003003e,0x000000a0,0x000000df,0x000200f9,0x000000c1,0x000200f8,0x000000c1,0x0004003d,
+ 0x0000000c,0x000000e4,0x00000028,0x00050086,0x0000000c,0x000000e5,0x000000e4,0x0000002c,
+ 0x00050041,0x00000037,0x000000e6,0x00000034,0x00000036,0x0004003d,0x0000000c,0x000000e7,
+ 0x000000e6,0x00050084,0x0000000c,0x000000e8,0x000000e5,0x000000e7,0x0004003d,0x0000000c,
+ 0x000000e9,0x00000020,0x00050080,0x0000000c,0x000000ea,0x000000e8,0x000000e9,0x0004003d,
+ 0x0000000c,0x000000eb,0x000000a0,0x00060041,0x000000b9,0x000000ec,0x000000e3,0x00000051,
+ 0x000000ea,0x0003003e,0x000000ec,0x000000eb,0x00050041,0x00000048,0x000000ed,0x00000046,
+ 0x00000029,0x0004003d,0x00000006,0x000000ee,0x000000ed,0x0004003d,0x00000007,0x000000ef,
+ 0x00000085,0x00070050,0x00000007,0x000000f0,0x000000ee,0x000000ee,0x000000ee,0x000000ee,
+ 0x00050081,0x00000007,0x000000f1,0x000000ef,0x000000f0,0x0003003e,0x00000085,0x000000f1,
+ 0x0004003d,0x00000007,0x000000f3,0x00000073,0x0003003e,0x000000f2,0x000000f3,0x0004003d,
+ 0x00000007,0x000000f5,0x00000085,0x0003003e,0x000000f4,0x000000f5,0x000a0039,0x00000002,
+ 0x000000fa,0x00000015,0x000000f2,0x000000f4,0x000000f6,0x000000f7,0x000000f8,0x000000f9,
+ 0x0004003d,0x00000007,0x000000fb,0x000000f6,0x0003003e,0x0000009d,0x000000fb,0x0004003d,
+ 0x00000007,0x000000fc,0x000000f7,0x0003003e,0x0000009e,0x000000fc,0x0004003d,0x0000000a,
+ 0x000000fd,0x000000f8,0x0003003e,0x0000009f,0x000000fd,0x0004003d,0x0000000c,0x000000fe,
+ 0x000000f9,0x0003003e,0x000000a0,0x000000fe,0x0004003d,0x0000000c,0x000000ff,0x00000028,
+ 0x00050080,0x0000000c,0x00000100,0x000000ff,0x00000029,0x00050041,0x00000037,0x00000101,
+ 0x00000034,0x00000036,0x0004003d,0x0000000c,0x00000102,0x00000101,0x00050084,0x0000000c,
+ 0x00000103,0x00000100,0x00000102,0x0004003d,0x0000000c,0x00000104,0x00000020,0x00050080,
+ 0x0000000c,0x00000105,0x00000103,0x00000104,0x0004003d,0x0000000c,0x00000106,0x000000a0,
+ 0x00060041,0x000000b9,0x00000107,0x000000b1,0x00000051,0x00000105,0x0003003e,0x00000107,
+ 0x00000106,0x000100fd,0x00010038,0x00050036,0x00000002,0x00000015,0x00000000,0x0000000e,
+ 0x00030037,0x00000008,0x0000000f,0x00030037,0x00000008,0x00000010,0x00030037,0x00000008,
+ 0x00000011,0x00030037,0x00000008,0x00000012,0x00030037,0x0000000b,0x00000013,0x00030037,
+ 0x0000000d,0x00000014,0x000200f8,0x00000016,0x0004003b,0x00000109,0x0000010a,0x00000007,
+ 0x0004003b,0x00000109,0x0000010d,0x00000007,0x0004003b,0x00000109,0x00000110,0x00000007,
+ 0x0004003b,0x00000109,0x00000114,0x00000007,0x0004003b,0x00000109,0x00000116,0x00000007,
+ 0x0004003b,0x00000109,0x00000118,0x00000007,0x0004003b,0x00000109,0x0000011c,0x00000007,
+ 0x0004003b,0x00000109,0x0000011e,0x00000007,0x0004003b,0x00000008,0x00000120,0x00000007,
+ 0x0004003b,0x00000008,0x00000123,0x00000007,0x0004003b,0x00000008,0x00000126,0x00000007,
+ 0x0004003b,0x00000008,0x0000012e,0x00000007,0x0004003b,0x00000008,0x00000134,0x00000007,
+ 0x0004003b,0x00000008,0x0000013a,0x00000007,0x0004003b,0x00000109,0x0000013e,0x00000007,
+ 0x0004003b,0x00000109,0x00000146,0x00000007,0x0004003b,0x00000109,0x0000014e,0x00000007,
+ 0x0004003b,0x00000109,0x00000156,0x00000007,0x0004003b,0x0000000d,0x0000015e,0x00000007,
+ 0x0004003b,0x00000018,0x00000166,0x00000007,0x0004003b,0x00000008,0x00000171,0x00000007,
+ 0x0004003b,0x00000008,0x00000176,0x00000007,0x0004003b,0x00000008,0x00000180,0x00000007,
+ 0x0004003b,0x00000008,0x00000185,0x00000007,0x0004003b,0x00000008,0x0000018f,0x00000007,
+ 0x0004003b,0x00000008,0x00000194,0x00000007,0x0004003b,0x00000008,0x0000019e,0x00000007,
+ 0x0004003b,0x00000008,0x000001a3,0x00000007,0x0004003b,0x0000000d,0x000001c8,0x00000007,
+ 0x0004003b,0x00000109,0x00000225,0x00000007,0x0004003b,0x00000109,0x00000229,0x00000007,
+ 0x0004003b,0x00000109,0x0000022d,0x00000007,0x0004003b,0x00000109,0x00000231,0x00000007,
+ 0x0004003b,0x00000109,0x00000235,0x00000007,0x0004003b,0x00000109,0x00000239,0x00000007,
+ 0x0004003b,0x00000109,0x0000023d,0x00000007,0x0004003b,0x00000109,0x00000241,0x00000007,
+ 0x0004003b,0x00000008,0x00000261,0x00000007,0x0004003b,0x00000008,0x0000026b,0x00000007,
+ 0x0004003b,0x00000008,0x00000276,0x00000007,0x0004003b,0x00000008,0x00000281,0x00000007,
+ 0x0004003b,0x00000008,0x0000028c,0x00000007,0x0004003b,0x00000008,0x00000292,0x00000007,
+ 0x0004003b,0x00000008,0x000002bb,0x00000007,0x0004003b,0x00000008,0x000002e4,0x00000007,
+ 0x0004003b,0x00000008,0x0000030e,0x00000007,0x0004003d,0x00000007,0x0000010b,0x0000000f,
+ 0x0004006d,0x00000108,0x0000010c,0x0000010b,0x0003003e,0x0000010a,0x0000010c,0x0004003d,
+ 0x00000007,0x0000010e,0x00000010,0x0004006d,0x00000108,0x0000010f,0x0000010e,0x0003003e,
+ 0x0000010d,0x0000010f,0x0004003d,0x00000108,0x00000111,0x0000010a,0x00070050,0x00000108,
+ 0x00000112,0x00000029,0x00000029,0x00000029,0x00000029,0x00050080,0x00000108,0x00000113,
+ 0x00000111,0x00000112,0x0003003e,0x00000110,0x00000113,0x0004003d,0x00000108,0x00000115,
+ 0x0000010d,0x0003003e,0x00000114,0x00000115,0x0004003d,0x00000108,0x00000117,0x0000010a,
+ 0x0003003e,0x00000116,0x00000117,0x0004003d,0x00000108,0x00000119,0x0000010d,0x00070050,
+ 0x00000108,0x0000011a,0x00000029,0x00000029,0x00000029,0x00000029,0x00050080,0x00000108,
+ 0x0000011b,0x00000119,0x0000011a,0x0003003e,0x00000118,0x0000011b,0x0004003d,0x00000108,
+ 0x0000011d,0x00000110,0x0003003e,0x0000011c,0x0000011d,0x0004003d,0x00000108,0x0000011f,
+ 0x00000118,0x0003003e,0x0000011e,0x0000011f,0x0004003d,0x00000007,0x00000121,0x0000000f,
+ 0x0006000c,0x00000007,0x00000122,0x00000001,0x0000000a,0x00000121,0x0003003e,0x00000120,
+ 0x00000122,0x0004003d,0x00000007,0x00000124,0x00000010,0x0006000c,0x00000007,0x00000125,
+ 0x00000001,0x0000000a,0x00000124,0x0003003e,0x00000123,0x00000125,0x0004003d,0x00000007,
+ 0x00000127,0x00000120,0x00070050,0x00000007,0x00000128,0x00000040,0x00000040,0x00000040,
+ 0x00000040,0x00050083,0x00000007,0x00000129,0x00000128,0x00000127,0x0004003d,0x00000007,
+ 0x0000012a,0x00000123,0x00070050,0x00000007,0x0000012b,0x00000040,0x00000040,0x00000040,
+ 0x00000040,0x00050083,0x00000007,0x0000012c,0x0000012b,0x0000012a,0x00050085,0x00000007,
+ 0x0000012d,0x00000129,0x0000012c,0x0003003e,0x00000126,0x0000012d,0x0004003d,0x00000007,
+ 0x0000012f,0x00000120,0x0004003d,0x00000007,0x00000130,0x00000123,0x00070050,0x00000007,
+ 0x00000131,0x00000040,0x00000040,0x00000040,0x00000040,0x00050083,0x00000007,0x00000132,
+ 0x00000131,0x00000130,0x00050085,0x00000007,0x00000133,0x0000012f,0x00000132,0x0003003e,
+ 0x0000012e,0x00000133,0x0004003d,0x00000007,0x00000135,0x00000120,0x00070050,0x00000007,
+ 0x00000136,0x00000040,0x00000040,0x00000040,0x00000040,0x00050083,0x00000007,0x00000137,
+ 0x00000136,0x00000135,0x0004003d,0x00000007,0x00000138,0x00000123,0x00050085,0x00000007,
+ 0x00000139,0x00000137,0x00000138,0x0003003e,0x00000134,0x00000139,0x0004003d,0x00000007,
+ 0x0000013b,0x00000120,0x0004003d,0x00000007,0x0000013c,0x00000123,0x00050085,0x00000007,
+ 0x0000013d,0x0000013b,0x0000013c,0x0003003e,0x0000013a,0x0000013d,0x0004003d,0x00000108,
+ 0x0000013f,0x0000010d,0x00050041,0x00000037,0x00000140,0x00000034,0x00000089,0x0004003d,
+ 0x0000000c,0x00000141,0x00000140,0x00070050,0x00000108,0x00000142,0x00000141,0x00000141,
+ 0x00000141,0x00000141,0x00050084,0x00000108,0x00000143,0x0000013f,0x00000142,0x0004003d,
+ 0x00000108,0x00000144,0x0000010a,0x00050080,0x00000108,0x00000145,0x00000143,0x00000144,
+ 0x0003003e,0x0000013e,0x00000145,0x0004003d,0x00000108,0x00000147,0x00000114,0x00050041,
+ 0x00000037,0x00000148,0x00000034,0x00000089,0x0004003d,0x0000000c,0x00000149,0x00000148,
+ 0x00070050,0x00000108,0x0000014a,0x00000149,0x00000149,0x00000149,0x00000149,0x00050084,
+ 0x00000108,0x0000014b,0x00000147,0x0000014a,0x0004003d,0x00000108,0x0000014c,0x00000110,
+ 0x00050080,0x00000108,0x0000014d,0x0000014b,0x0000014c,0x0003003e,0x00000146,0x0000014d,
+ 0x0004003d,0x00000108,0x0000014f,0x00000118,0x00050041,0x00000037,0x00000150,0x00000034,
+ 0x00000089,0x0004003d,0x0000000c,0x00000151,0x00000150,0x00070050,0x00000108,0x00000152,
+ 0x00000151,0x00000151,0x00000151,0x00000151,0x00050084,0x00000108,0x00000153,0x0000014f,
+ 0x00000152,0x0004003d,0x00000108,0x00000154,0x00000116,0x00050080,0x00000108,0x00000155,
+ 0x00000153,0x00000154,0x0003003e,0x0000014e,0x00000155,0x0004003d,0x00000108,0x00000157,
+ 0x0000011e,0x00050041,0x00000037,0x00000158,0x00000034,0x00000089,0x0004003d,0x0000000c,
+ 0x00000159,0x00000158,0x00070050,0x00000108,0x0000015a,0x00000159,0x00000159,0x00000159,
+ 0x00000159,0x00050084,0x00000108,0x0000015b,0x00000157,0x0000015a,0x0004003d,0x00000108,
+ 0x0000015c,0x0000011c,0x00050080,0x00000108,0x0000015d,0x0000015b,0x0000015c,0x0003003e,
+ 0x00000156,0x0000015d,0x0003003e,0x0000015e,0x00000024,0x000200f9,0x0000015f,0x000200f8,
+ 0x0000015f,0x000400f6,0x00000161,0x00000162,0x00000000,0x000200f9,0x00000163,0x000200f8,
+ 0x00000163,0x0004003d,0x0000000c,0x00000164,0x0000015e,0x000500b0,0x00000009,0x00000165,
+ 0x00000164,0x0000002f,0x000400fa,0x00000165,0x00000160,0x00000161,0x000200f8,0x00000160,
+ 0x0004003d,0x0000000c,0x0000016b,0x0000015e,0x00050041,0x0000000d,0x0000016c,0x0000013e,
+ 0x0000016b,0x0004003d,0x0000000c,0x0000016d,0x0000016c,0x00060041,0x0000016e,0x0000016f,
+ 0x0000016a,0x00000051,0x0000016d,0x0004003d,0x00000017,0x00000170,0x0000016f,0x0003003e,
+ 0x00000166,0x00000170,0x0004003d,0x0000000c,0x00000172,0x0000015e,0x00050041,0x00000048,
+ 0x00000173,0x00000166,0x00000024,0x0004003d,0x00000006,0x00000174,0x00000173,0x00050041,
+ 0x00000048,0x00000175,0x00000171,0x00000172,0x0003003e,0x00000175,0x00000174,0x0004003d,
+ 0x0000000c,0x00000177,0x0000015e,0x00050041,0x00000048,0x00000178,0x00000166,0x00000029,
+ 0x0004003d,0x00000006,0x00000179,0x00000178,0x00050041,0x00000048,0x0000017a,0x00000176,
+ 0x00000177,0x0003003e,0x0000017a,0x00000179,0x0004003d,0x0000000c,0x0000017b,0x0000015e,
+ 0x00050041,0x0000000d,0x0000017c,0x00000146,0x0000017b,0x0004003d,0x0000000c,0x0000017d,
+ 0x0000017c,0x00060041,0x0000016e,0x0000017e,0x0000016a,0x00000051,0x0000017d,0x0004003d,
+ 0x00000017,0x0000017f,0x0000017e,0x0003003e,0x00000166,0x0000017f,0x0004003d,0x0000000c,
+ 0x00000181,0x0000015e,0x00050041,0x00000048,0x00000182,0x00000166,0x00000024,0x0004003d,
+ 0x00000006,0x00000183,0x00000182,0x00050041,0x00000048,0x00000184,0x00000180,0x00000181,
+ 0x0003003e,0x00000184,0x00000183,0x0004003d,0x0000000c,0x00000186,0x0000015e,0x00050041,
+ 0x00000048,0x00000187,0x00000166,0x00000029,0x0004003d,0x00000006,0x00000188,0x00000187,
+ 0x00050041,0x00000048,0x00000189,0x00000185,0x00000186,0x0003003e,0x00000189,0x00000188,
+ 0x0004003d,0x0000000c,0x0000018a,0x0000015e,0x00050041,0x0000000d,0x0000018b,0x0000014e,
+ 0x0000018a,0x0004003d,0x0000000c,0x0000018c,0x0000018b,0x00060041,0x0000016e,0x0000018d,
+ 0x0000016a,0x00000051,0x0000018c,0x0004003d,0x00000017,0x0000018e,0x0000018d,0x0003003e,
+ 0x00000166,0x0000018e,0x0004003d,0x0000000c,0x00000190,0x0000015e,0x00050041,0x00000048,
+ 0x00000191,0x00000166,0x00000024,0x0004003d,0x00000006,0x00000192,0x00000191,0x00050041,
+ 0x00000048,0x00000193,0x0000018f,0x00000190,0x0003003e,0x00000193,0x00000192,0x0004003d,
+ 0x0000000c,0x00000195,0x0000015e,0x00050041,0x00000048,0x00000196,0x00000166,0x00000029,
+ 0x0004003d,0x00000006,0x00000197,0x00000196,0x00050041,0x00000048,0x00000198,0x00000194,
+ 0x00000195,0x0003003e,0x00000198,0x00000197,0x0004003d,0x0000000c,0x00000199,0x0000015e,
+ 0x00050041,0x0000000d,0x0000019a,0x00000156,0x00000199,0x0004003d,0x0000000c,0x0000019b,
+ 0x0000019a,0x00060041,0x0000016e,0x0000019c,0x0000016a,0x00000051,0x0000019b,0x0004003d,
+ 0x00000017,0x0000019d,0x0000019c,0x0003003e,0x00000166,0x0000019d,0x0004003d,0x0000000c,
+ 0x0000019f,0x0000015e,0x00050041,0x00000048,0x000001a0,0x00000166,0x00000024,0x0004003d,
+ 0x00000006,0x000001a1,0x000001a0,0x00050041,0x00000048,0x000001a2,0x0000019e,0x0000019f,
+ 0x0003003e,0x000001a2,0x000001a1,0x0004003d,0x0000000c,0x000001a4,0x0000015e,0x00050041,
+ 0x00000048,0x000001a5,0x00000166,0x00000029,0x0004003d,0x00000006,0x000001a6,0x000001a5,
+ 0x00050041,0x00000048,0x000001a7,0x000001a3,0x000001a4,0x0003003e,0x000001a7,0x000001a6,
+ 0x000200f9,0x00000162,0x000200f8,0x00000162,0x0004003d,0x0000000c,0x000001a8,0x0000015e,
+ 0x00050080,0x0000000c,0x000001a9,0x000001a8,0x00000055,0x0003003e,0x0000015e,0x000001a9,
+ 0x000200f9,0x0000015f,0x000200f8,0x00000161,0x0004003d,0x00000007,0x000001aa,0x00000171,
+ 0x0004003d,0x00000007,0x000001ab,0x00000126,0x00050085,0x00000007,0x000001ac,0x000001aa,
+ 0x000001ab,0x0004003d,0x00000007,0x000001ad,0x00000180,0x0004003d,0x00000007,0x000001ae,
+ 0x0000012e,0x00050085,0x00000007,0x000001af,0x000001ad,0x000001ae,0x00050081,0x00000007,
+ 0x000001b0,0x000001ac,0x000001af,0x0004003d,0x00000007,0x000001b1,0x0000018f,0x0004003d,
+ 0x00000007,0x000001b2,0x00000134,0x00050085,0x00000007,0x000001b3,0x000001b1,0x000001b2,
+ 0x00050081,0x00000007,0x000001b4,0x000001b0,0x000001b3,0x0004003d,0x00000007,0x000001b5,
+ 0x0000019e,0x0004003d,0x00000007,0x000001b6,0x0000013a,0x00050085,0x00000007,0x000001b7,
+ 0x000001b5,0x000001b6,0x00050081,0x00000007,0x000001b8,0x000001b4,0x000001b7,0x0003003e,
+ 0x00000011,0x000001b8,0x0004003d,0x00000007,0x000001b9,0x00000176,0x0004003d,0x00000007,
+ 0x000001ba,0x00000126,0x00050085,0x00000007,0x000001bb,0x000001b9,0x000001ba,0x0004003d,
+ 0x00000007,0x000001bc,0x00000185,0x0004003d,0x00000007,0x000001bd,0x0000012e,0x00050085,
+ 0x00000007,0x000001be,0x000001bc,0x000001bd,0x00050081,0x00000007,0x000001bf,0x000001bb,
+ 0x000001be,0x0004003d,0x00000007,0x000001c0,0x00000194,0x0004003d,0x00000007,0x000001c1,
+ 0x00000134,0x00050085,0x00000007,0x000001c2,0x000001c0,0x000001c1,0x00050081,0x00000007,
+ 0x000001c3,0x000001bf,0x000001c2,0x0004003d,0x00000007,0x000001c4,0x000001a3,0x0004003d,
+ 0x00000007,0x000001c5,0x0000013a,0x00050085,0x00000007,0x000001c6,0x000001c4,0x000001c5,
+ 0x00050081,0x00000007,0x000001c7,0x000001c3,0x000001c6,0x0003003e,0x00000012,0x000001c7,
+ 0x0003003e,0x000001c8,0x00000024,0x000200f9,0x000001c9,0x000200f8,0x000001c9,0x000400f6,
+ 0x000001cb,0x000001cc,0x00000000,0x000200f9,0x000001cd,0x000200f8,0x000001cd,0x0004003d,
+ 0x0000000c,0x000001ce,0x000001c8,0x000500b0,0x00000009,0x000001cf,0x000001ce,0x0000002f,
+ 0x000400fa,0x000001cf,0x000001ca,0x000001cb,0x000200f8,0x000001ca,0x0004003d,0x0000000c,
+ 0x000001d0,0x000001c8,0x0004003d,0x0000000c,0x000001d1,0x000001c8,0x00050041,0x00000048,
+ 0x000001d2,0x00000011,0x000001d1,0x0004003d,0x00000006,0x000001d3,0x000001d2,0x000500b8,
+ 0x00000009,0x000001d4,0x000001d3,0x00000078,0x000400a8,0x00000009,0x000001d5,0x000001d4,
+ 0x000300f7,0x000001d7,0x00000000,0x000400fa,0x000001d5,0x000001d6,0x000001d7,0x000200f8,
+ 0x000001d6,0x0004003d,0x0000000c,0x000001d8,0x000001c8,0x00050041,0x00000048,0x000001d9,
+ 0x00000011,0x000001d8,0x0004003d,0x00000006,0x000001da,0x000001d9,0x00050041,0x00000037,
+ 0x000001db,0x00000034,0x00000051,0x0004003d,0x0000000c,0x000001dc,0x000001db,0x00050084,
+ 0x0000000c,0x000001dd,0x000001dc,0x0000002f,0x00050082,0x0000000c,0x000001de,0x000001dd,
+ 0x00000029,0x00040070,0x00000006,0x000001df,0x000001de,0x000500ba,0x00000009,0x000001e0,
+ 0x000001da,0x000001df,0x000200f9,0x000001d7,0x000200f8,0x000001d7,0x000700f5,0x00000009,
+ 0x000001e1,0x000001d4,0x000001ca,0x000001e0,0x000001d6,0x000400a8,0x00000009,0x000001e2,
+ 0x000001e1,0x000300f7,0x000001e4,0x00000000,0x000400fa,0x000001e2,0x000001e3,0x000001e4,
+ 0x000200f8,0x000001e3,0x0004003d,0x0000000c,0x000001e5,0x000001c8,0x00050041,0x00000048,
+ 0x000001e6,0x00000012,0x000001e5,0x0004003d,0x00000006,0x000001e7,0x000001e6,0x000500b8,
+ 0x00000009,0x000001e8,0x000001e7,0x00000078,0x000200f9,0x000001e4,0x000200f8,0x000001e4,
+ 0x000700f5,0x00000009,0x000001e9,0x000001e1,0x000001d7,0x000001e8,0x000001e3,0x000400a8,
+ 0x00000009,0x000001ea,0x000001e9,0x000300f7,0x000001ec,0x00000000,0x000400fa,0x000001ea,
+ 0x000001eb,0x000001ec,0x000200f8,0x000001eb,0x0004003d,0x0000000c,0x000001ed,0x000001c8,
+ 0x00050041,0x00000048,0x000001ee,0x00000012,0x000001ed,0x0004003d,0x00000006,0x000001ef,
+ 0x000001ee,0x00050041,0x00000037,0x000001f0,0x00000034,0x00000055,0x0004003d,0x0000000c,
+ 0x000001f1,0x000001f0,0x00050082,0x0000000c,0x000001f2,0x000001f1,0x00000029,0x00040070,
+ 0x00000006,0x000001f3,0x000001f2,0x000500ba,0x00000009,0x000001f4,0x000001ef,0x000001f3,
+ 0x000200f9,0x000001ec,0x000200f8,0x000001ec,0x000700f5,0x00000009,0x000001f5,0x000001e9,
+ 0x000001e4,0x000001f4,0x000001eb,0x00050041,0x000001f6,0x000001f7,0x00000013,0x000001d0,
+ 0x0003003e,0x000001f7,0x000001f5,0x000200f9,0x000001cc,0x000200f8,0x000001cc,0x0004003d,
+ 0x0000000c,0x000001f8,0x000001c8,0x00050080,0x0000000c,0x000001f9,0x000001f8,0x00000055,
+ 0x0003003e,0x000001c8,0x000001f9,0x000200f9,0x000001c9,0x000200f8,0x000001cb,0x0004003d,
+ 0x0000000a,0x000001fa,0x00000013,0x0004009b,0x00000009,0x000001fb,0x000001fa,0x000300f7,
+ 0x000001fd,0x00000000,0x000400fa,0x000001fb,0x000001fc,0x000001fd,0x000200f8,0x000001fc,
+ 0x0003003e,0x00000014,0x00000024,0x000100fd,0x000200f8,0x000001fd,0x0004003d,0x00000007,
+ 0x000001ff,0x00000011,0x0004006d,0x00000108,0x00000200,0x000001ff,0x0003003e,0x0000010a,
+ 0x00000200,0x0004003d,0x00000007,0x00000201,0x00000012,0x0004006d,0x00000108,0x00000202,
+ 0x00000201,0x0003003e,0x0000010d,0x00000202,0x0004003d,0x00000108,0x00000203,0x0000010a,
+ 0x00070050,0x00000108,0x00000204,0x00000029,0x00000029,0x00000029,0x00000029,0x00050080,
+ 0x00000108,0x00000205,0x00000203,0x00000204,0x0003003e,0x00000110,0x00000205,0x0004003d,
+ 0x00000108,0x00000206,0x0000010d,0x0003003e,0x00000114,0x00000206,0x0004003d,0x00000108,
+ 0x00000207,0x0000010a,0x0003003e,0x00000116,0x00000207,0x0004003d,0x00000108,0x00000208,
+ 0x0000010d,0x00070050,0x00000108,0x00000209,0x00000029,0x00000029,0x00000029,0x00000029,
+ 0x00050080,0x00000108,0x0000020a,0x00000208,0x00000209,0x0003003e,0x00000118,0x0000020a,
+ 0x0004003d,0x00000108,0x0000020b,0x00000110,0x0003003e,0x0000011c,0x0000020b,0x0004003d,
+ 0x00000108,0x0000020c,0x00000118,0x0003003e,0x0000011e,0x0000020c,0x0004003d,0x00000007,
+ 0x0000020d,0x00000011,0x0006000c,0x00000007,0x0000020e,0x00000001,0x0000000a,0x0000020d,
+ 0x0003003e,0x00000120,0x0000020e,0x0004003d,0x00000007,0x0000020f,0x00000012,0x0006000c,
+ 0x00000007,0x00000210,0x00000001,0x0000000a,0x0000020f,0x0003003e,0x00000123,0x00000210,
+ 0x0004003d,0x00000007,0x00000211,0x00000120,0x00070050,0x00000007,0x00000212,0x00000040,
+ 0x00000040,0x00000040,0x00000040,0x00050083,0x00000007,0x00000213,0x00000212,0x00000211,
+ 0x0004003d,0x00000007,0x00000214,0x00000123,0x00070050,0x00000007,0x00000215,0x00000040,
+ 0x00000040,0x00000040,0x00000040,0x00050083,0x00000007,0x00000216,0x00000215,0x00000214,
+ 0x00050085,0x00000007,0x00000217,0x00000213,0x00000216,0x0003003e,0x00000126,0x00000217,
+ 0x0004003d,0x00000007,0x00000218,0x00000120,0x0004003d,0x00000007,0x00000219,0x00000123,
+ 0x00070050,0x00000007,0x0000021a,0x00000040,0x00000040,0x00000040,0x00000040,0x00050083,
+ 0x00000007,0x0000021b,0x0000021a,0x00000219,0x00050085,0x00000007,0x0000021c,0x00000218,
+ 0x0000021b,0x0003003e,0x0000012e,0x0000021c,0x0004003d,0x00000007,0x0000021d,0x00000120,
+ 0x00070050,0x00000007,0x0000021e,0x00000040,0x00000040,0x00000040,0x00000040,0x00050083,
+ 0x00000007,0x0000021f,0x0000021e,0x0000021d,0x0004003d,0x00000007,0x00000220,0x00000123,
+ 0x00050085,0x00000007,0x00000221,0x0000021f,0x00000220,0x0003003e,0x00000134,0x00000221,
+ 0x0004003d,0x00000007,0x00000222,0x00000120,0x0004003d,0x00000007,0x00000223,0x00000123,
+ 0x00050085,0x00000007,0x00000224,0x00000222,0x00000223,0x0003003e,0x0000013a,0x00000224,
+ 0x0004003d,0x00000108,0x00000226,0x0000010a,0x00070050,0x00000108,0x00000227,0x0000002f,
+ 0x0000002f,0x0000002f,0x0000002f,0x00050086,0x00000108,0x00000228,0x00000226,0x00000227,
+ 0x0003003e,0x00000225,0x00000228,0x0004003d,0x00000108,0x0000022a,0x00000110,0x00070050,
+ 0x00000108,0x0000022b,0x0000002f,0x0000002f,0x0000002f,0x0000002f,0x00050086,0x00000108,
+ 0x0000022c,0x0000022a,0x0000022b,0x0003003e,0x00000229,0x0000022c,0x0004003d,0x00000108,
+ 0x0000022e,0x00000116,0x00070050,0x00000108,0x0000022f,0x0000002f,0x0000002f,0x0000002f,
+ 0x0000002f,0x00050086,0x00000108,0x00000230,0x0000022e,0x0000022f,0x0003003e,0x0000022d,
+ 0x00000230,0x0004003d,0x00000108,0x00000232,0x0000011c,0x00070050,0x00000108,0x00000233,
+ 0x0000002f,0x0000002f,0x0000002f,0x0000002f,0x00050086,0x00000108,0x00000234,0x00000232,
+ 0x00000233,0x0003003e,0x00000231,0x00000234,0x0004003d,0x00000108,0x00000236,0x0000010a,
+ 0x00070050,0x00000108,0x00000237,0x0000002f,0x0000002f,0x0000002f,0x0000002f,0x00050089,
+ 0x00000108,0x00000238,0x00000236,0x00000237,0x0003003e,0x00000235,0x00000238,0x0004003d,
+ 0x00000108,0x0000023a,0x00000110,0x00070050,0x00000108,0x0000023b,0x0000002f,0x0000002f,
+ 0x0000002f,0x0000002f,0x00050089,0x00000108,0x0000023c,0x0000023a,0x0000023b,0x0003003e,
+ 0x00000239,0x0000023c,0x0004003d,0x00000108,0x0000023e,0x00000116,0x00070050,0x00000108,
+ 0x0000023f,0x0000002f,0x0000002f,0x0000002f,0x0000002f,0x00050089,0x00000108,0x00000240,
+ 0x0000023e,0x0000023f,0x0003003e,0x0000023d,0x00000240,0x0004003d,0x00000108,0x00000242,
+ 0x0000011c,0x00070050,0x00000108,0x00000243,0x0000002f,0x0000002f,0x0000002f,0x0000002f,
+ 0x00050089,0x00000108,0x00000244,0x00000242,0x00000243,0x0003003e,0x00000241,0x00000244,
+ 0x0004003d,0x00000108,0x00000245,0x0000010d,0x00050041,0x00000037,0x00000246,0x00000034,
+ 0x00000051,0x0004003d,0x0000000c,0x00000247,0x00000246,0x00070050,0x00000108,0x00000248,
+ 0x00000247,0x00000247,0x00000247,0x00000247,0x00050084,0x00000108,0x00000249,0x00000245,
+ 0x00000248,0x0004003d,0x00000108,0x0000024a,0x00000225,0x00050080,0x00000108,0x0000024b,
+ 0x00000249,0x0000024a,0x0003003e,0x0000013e,0x0000024b,0x0004003d,0x00000108,0x0000024c,
+ 0x00000114,0x00050041,0x00000037,0x0000024d,0x00000034,0x00000051,0x0004003d,0x0000000c,
+ 0x0000024e,0x0000024d,0x00070050,0x00000108,0x0000024f,0x0000024e,0x0000024e,0x0000024e,
+ 0x0000024e,0x00050084,0x00000108,0x00000250,0x0000024c,0x0000024f,0x0004003d,0x00000108,
+ 0x00000251,0x00000229,0x00050080,0x00000108,0x00000252,0x00000250,0x00000251,0x0003003e,
+ 0x00000146,0x00000252,0x0004003d,0x00000108,0x00000253,0x00000118,0x00050041,0x00000037,
+ 0x00000254,0x00000034,0x00000051,0x0004003d,0x0000000c,0x00000255,0x00000254,0x00070050,
+ 0x00000108,0x00000256,0x00000255,0x00000255,0x00000255,0x00000255,0x00050084,0x00000108,
+ 0x00000257,0x00000253,0x00000256,0x0004003d,0x00000108,0x00000258,0x0000022d,0x00050080,
+ 0x00000108,0x00000259,0x00000257,0x00000258,0x0003003e,0x0000014e,0x00000259,0x0004003d,
+ 0x00000108,0x0000025a,0x0000011e,0x00050041,0x00000037,0x0000025b,0x00000034,0x00000051,
+ 0x0004003d,0x0000000c,0x0000025c,0x0000025b,0x00070050,0x00000108,0x0000025d,0x0000025c,
+ 0x0000025c,0x0000025c,0x0000025c,0x00050084,0x00000108,0x0000025e,0x0000025a,0x0000025d,
+ 0x0004003d,0x00000108,0x0000025f,0x00000231,0x00050080,0x00000108,0x00000260,0x0000025e,
+ 0x0000025f,0x0003003e,0x00000156,0x00000260,0x00050041,0x0000000d,0x00000266,0x0000013e,
+ 0x00000024,0x0004003d,0x0000000c,0x00000267,0x00000266,0x00060041,0x000000b9,0x00000268,
+ 0x00000265,0x00000051,0x00000267,0x0004003d,0x0000000c,0x00000269,0x00000268,0x0006000c,
+ 0x00000007,0x0000026a,0x00000001,0x00000040,0x00000269,0x0003003e,0x00000261,0x0000026a,
+ 0x00050041,0x0000000d,0x0000026c,0x00000235,0x00000024,0x0004003d,0x0000000c,0x0000026d,
+ 0x0000026c,0x00050041,0x00000048,0x0000026e,0x00000261,0x0000026d,0x0004003d,0x00000006,
+ 0x0000026f,0x0000026e,0x00050041,0x00000048,0x00000270,0x0000026b,0x00000024,0x0003003e,
+ 0x00000270,0x0000026f,0x00050041,0x0000000d,0x00000271,0x00000146,0x00000024,0x0004003d,
+ 0x0000000c,0x00000272,0x00000271,0x00060041,0x000000b9,0x00000273,0x00000265,0x00000051,
+ 0x00000272,0x0004003d,0x0000000c,0x00000274,0x00000273,0x0006000c,0x00000007,0x00000275,
+ 0x00000001,0x00000040,0x00000274,0x0003003e,0x00000261,0x00000275,0x00050041,0x0000000d,
+ 0x00000277,0x00000239,0x00000024,0x0004003d,0x0000000c,0x00000278,0x00000277,0x00050041,
+ 0x00000048,0x00000279,0x00000261,0x00000278,0x0004003d,0x00000006,0x0000027a,0x00000279,
+ 0x00050041,0x00000048,0x0000027b,0x00000276,0x00000024,0x0003003e,0x0000027b,0x0000027a,
+ 0x00050041,0x0000000d,0x0000027c,0x0000014e,0x00000024,0x0004003d,0x0000000c,0x0000027d,
+ 0x0000027c,0x00060041,0x000000b9,0x0000027e,0x00000265,0x00000051,0x0000027d,0x0004003d,
+ 0x0000000c,0x0000027f,0x0000027e,0x0006000c,0x00000007,0x00000280,0x00000001,0x00000040,
+ 0x0000027f,0x0003003e,0x00000261,0x00000280,0x00050041,0x0000000d,0x00000282,0x0000023d,
+ 0x00000024,0x0004003d,0x0000000c,0x00000283,0x00000282,0x00050041,0x00000048,0x00000284,
+ 0x00000261,0x00000283,0x0004003d,0x00000006,0x00000285,0x00000284,0x00050041,0x00000048,
+ 0x00000286,0x00000281,0x00000024,0x0003003e,0x00000286,0x00000285,0x00050041,0x0000000d,
+ 0x00000287,0x00000156,0x00000024,0x0004003d,0x0000000c,0x00000288,0x00000287,0x00060041,
+ 0x000000b9,0x00000289,0x00000265,0x00000051,0x00000288,0x0004003d,0x0000000c,0x0000028a,
+ 0x00000289,0x0006000c,0x00000007,0x0000028b,0x00000001,0x00000040,0x0000028a,0x0003003e,
+ 0x00000261,0x0000028b,0x00050041,0x0000000d,0x0000028d,0x00000241,0x00000024,0x0004003d,
+ 0x0000000c,0x0000028e,0x0000028d,0x00050041,0x00000048,0x0000028f,0x00000261,0x0000028e,
+ 0x0004003d,0x00000006,0x00000290,0x0000028f,0x00050041,0x00000048,0x00000291,0x0000028c,
+ 0x00000024,0x0003003e,0x00000291,0x00000290,0x00050041,0x0000000d,0x00000293,0x0000013e,
+ 0x00000029,0x0004003d,0x0000000c,0x00000294,0x00000293,0x00060041,0x000000b9,0x00000295,
+ 0x00000265,0x00000051,0x00000294,0x0004003d,0x0000000c,0x00000296,0x00000295,0x0006000c,
+ 0x00000007,0x00000297,0x00000001,0x00000040,0x00000296,0x0003003e,0x00000292,0x00000297,
+ 0x00050041,0x0000000d,0x00000298,0x00000235,0x00000029,0x0004003d,0x0000000c,0x00000299,
+ 0x00000298,0x00050041,0x00000048,0x0000029a,0x00000292,0x00000299,0x0004003d,0x00000006,
+ 0x0000029b,0x0000029a,0x00050041,0x00000048,0x0000029c,0x0000026b,0x00000029,0x0003003e,
+ 0x0000029c,0x0000029b,0x00050041,0x0000000d,0x0000029d,0x00000146,0x00000029,0x0004003d,
+ 0x0000000c,0x0000029e,0x0000029d,0x00060041,0x000000b9,0x0000029f,0x00000265,0x00000051,
+ 0x0000029e,0x0004003d,0x0000000c,0x000002a0,0x0000029f,0x0006000c,0x00000007,0x000002a1,
+ 0x00000001,0x00000040,0x000002a0,0x0003003e,0x00000292,0x000002a1,0x00050041,0x0000000d,
+ 0x000002a2,0x00000239,0x00000029,0x0004003d,0x0000000c,0x000002a3,0x000002a2,0x00050041,
+ 0x00000048,0x000002a4,0x00000292,0x000002a3,0x0004003d,0x00000006,0x000002a5,0x000002a4,
+ 0x00050041,0x00000048,0x000002a6,0x00000276,0x00000029,0x0003003e,0x000002a6,0x000002a5,
+ 0x00050041,0x0000000d,0x000002a7,0x0000014e,0x00000029,0x0004003d,0x0000000c,0x000002a8,
+ 0x000002a7,0x00060041,0x000000b9,0x000002a9,0x00000265,0x00000051,0x000002a8,0x0004003d,
+ 0x0000000c,0x000002aa,0x000002a9,0x0006000c,0x00000007,0x000002ab,0x00000001,0x00000040,
+ 0x000002aa,0x0003003e,0x00000292,0x000002ab,0x00050041,0x0000000d,0x000002ac,0x0000023d,
+ 0x00000029,0x0004003d,0x0000000c,0x000002ad,0x000002ac,0x00050041,0x00000048,0x000002ae,
+ 0x00000292,0x000002ad,0x0004003d,0x00000006,0x000002af,0x000002ae,0x00050041,0x00000048,
+ 0x000002b0,0x00000281,0x00000029,0x0003003e,0x000002b0,0x000002af,0x00050041,0x0000000d,
+ 0x000002b1,0x00000156,0x00000029,0x0004003d,0x0000000c,0x000002b2,0x000002b1,0x00060041,
+ 0x000000b9,0x000002b3,0x00000265,0x00000051,0x000002b2,0x0004003d,0x0000000c,0x000002b4,
+ 0x000002b3,0x0006000c,0x00000007,0x000002b5,0x00000001,0x00000040,0x000002b4,0x0003003e,
+ 0x00000292,0x000002b5,0x00050041,0x0000000d,0x000002b6,0x00000241,0x00000029,0x0004003d,
+ 0x0000000c,0x000002b7,0x000002b6,0x00050041,0x00000048,0x000002b8,0x00000292,0x000002b7,
+ 0x0004003d,0x00000006,0x000002b9,0x000002b8,0x00050041,0x00000048,0x000002ba,0x0000028c,
+ 0x00000029,0x0003003e,0x000002ba,0x000002b9,0x00050041,0x0000000d,0x000002bc,0x0000013e,
+ 0x0000002c,0x0004003d,0x0000000c,0x000002bd,0x000002bc,0x00060041,0x000000b9,0x000002be,
+ 0x00000265,0x00000051,0x000002bd,0x0004003d,0x0000000c,0x000002bf,0x000002be,0x0006000c,
+ 0x00000007,0x000002c0,0x00000001,0x00000040,0x000002bf,0x0003003e,0x000002bb,0x000002c0,
+ 0x00050041,0x0000000d,0x000002c1,0x00000235,0x0000002c,0x0004003d,0x0000000c,0x000002c2,
+ 0x000002c1,0x00050041,0x00000048,0x000002c3,0x000002bb,0x000002c2,0x0004003d,0x00000006,
+ 0x000002c4,0x000002c3,0x00050041,0x00000048,0x000002c5,0x0000026b,0x0000002c,0x0003003e,
+ 0x000002c5,0x000002c4,0x00050041,0x0000000d,0x000002c6,0x00000146,0x0000002c,0x0004003d,
+ 0x0000000c,0x000002c7,0x000002c6,0x00060041,0x000000b9,0x000002c8,0x00000265,0x00000051,
+ 0x000002c7,0x0004003d,0x0000000c,0x000002c9,0x000002c8,0x0006000c,0x00000007,0x000002ca,
+ 0x00000001,0x00000040,0x000002c9,0x0003003e,0x000002bb,0x000002ca,0x00050041,0x0000000d,
+ 0x000002cb,0x00000239,0x0000002c,0x0004003d,0x0000000c,0x000002cc,0x000002cb,0x00050041,
+ 0x00000048,0x000002cd,0x000002bb,0x000002cc,0x0004003d,0x00000006,0x000002ce,0x000002cd,
+ 0x00050041,0x00000048,0x000002cf,0x00000276,0x0000002c,0x0003003e,0x000002cf,0x000002ce,
+ 0x00050041,0x0000000d,0x000002d0,0x0000014e,0x0000002c,0x0004003d,0x0000000c,0x000002d1,
+ 0x000002d0,0x00060041,0x000000b9,0x000002d2,0x00000265,0x00000051,0x000002d1,0x0004003d,
+ 0x0000000c,0x000002d3,0x000002d2,0x0006000c,0x00000007,0x000002d4,0x00000001,0x00000040,
+ 0x000002d3,0x0003003e,0x000002bb,0x000002d4,0x00050041,0x0000000d,0x000002d5,0x0000023d,
+ 0x0000002c,0x0004003d,0x0000000c,0x000002d6,0x000002d5,0x00050041,0x00000048,0x000002d7,
+ 0x000002bb,0x000002d6,0x0004003d,0x00000006,0x000002d8,0x000002d7,0x00050041,0x00000048,
+ 0x000002d9,0x00000281,0x0000002c,0x0003003e,0x000002d9,0x000002d8,0x00050041,0x0000000d,
+ 0x000002da,0x00000156,0x0000002c,0x0004003d,0x0000000c,0x000002db,0x000002da,0x00060041,
+ 0x000000b9,0x000002dc,0x00000265,0x00000051,0x000002db,0x0004003d,0x0000000c,0x000002dd,
+ 0x000002dc,0x0006000c,0x00000007,0x000002de,0x00000001,0x00000040,0x000002dd,0x0003003e,
+ 0x000002bb,0x000002de,0x00050041,0x0000000d,0x000002df,0x00000241,0x0000002c,0x0004003d,
+ 0x0000000c,0x000002e0,0x000002df,0x00050041,0x00000048,0x000002e1,0x000002bb,0x000002e0,
+ 0x0004003d,0x00000006,0x000002e2,0x000002e1,0x00050041,0x00000048,0x000002e3,0x0000028c,
+ 0x0000002c,0x0003003e,0x000002e3,0x000002e2,0x00050041,0x0000000d,0x000002e6,0x0000013e,
+ 0x000002e5,0x0004003d,0x0000000c,0x000002e7,0x000002e6,0x00060041,0x000000b9,0x000002e8,
+ 0x00000265,0x00000051,0x000002e7,0x0004003d,0x0000000c,0x000002e9,0x000002e8,0x0006000c,
+ 0x00000007,0x000002ea,0x00000001,0x00000040,0x000002e9,0x0003003e,0x000002e4,0x000002ea,
+ 0x00050041,0x0000000d,0x000002eb,0x00000235,0x000002e5,0x0004003d,0x0000000c,0x000002ec,
+ 0x000002eb,0x00050041,0x00000048,0x000002ed,0x000002e4,0x000002ec,0x0004003d,0x00000006,
+ 0x000002ee,0x000002ed,0x00050041,0x00000048,0x000002ef,0x0000026b,0x000002e5,0x0003003e,
+ 0x000002ef,0x000002ee,0x00050041,0x0000000d,0x000002f0,0x00000146,0x000002e5,0x0004003d,
+ 0x0000000c,0x000002f1,0x000002f0,0x00060041,0x000000b9,0x000002f2,0x00000265,0x00000051,
+ 0x000002f1,0x0004003d,0x0000000c,0x000002f3,0x000002f2,0x0006000c,0x00000007,0x000002f4,
+ 0x00000001,0x00000040,0x000002f3,0x0003003e,0x000002e4,0x000002f4,0x00050041,0x0000000d,
+ 0x000002f5,0x00000239,0x000002e5,0x0004003d,0x0000000c,0x000002f6,0x000002f5,0x00050041,
+ 0x00000048,0x000002f7,0x000002e4,0x000002f6,0x0004003d,0x00000006,0x000002f8,0x000002f7,
+ 0x00050041,0x00000048,0x000002f9,0x00000276,0x000002e5,0x0003003e,0x000002f9,0x000002f8,
+ 0x00050041,0x0000000d,0x000002fa,0x0000014e,0x000002e5,0x0004003d,0x0000000c,0x000002fb,
+ 0x000002fa,0x00060041,0x000000b9,0x000002fc,0x00000265,0x00000051,0x000002fb,0x0004003d,
+ 0x0000000c,0x000002fd,0x000002fc,0x0006000c,0x00000007,0x000002fe,0x00000001,0x00000040,
+ 0x000002fd,0x0003003e,0x000002e4,0x000002fe,0x00050041,0x0000000d,0x000002ff,0x0000023d,
+ 0x000002e5,0x0004003d,0x0000000c,0x00000300,0x000002ff,0x00050041,0x00000048,0x00000301,
+ 0x000002e4,0x00000300,0x0004003d,0x00000006,0x00000302,0x00000301,0x00050041,0x00000048,
+ 0x00000303,0x00000281,0x000002e5,0x0003003e,0x00000303,0x00000302,0x00050041,0x0000000d,
+ 0x00000304,0x00000156,0x000002e5,0x0004003d,0x0000000c,0x00000305,0x00000304,0x00060041,
+ 0x000000b9,0x00000306,0x00000265,0x00000051,0x00000305,0x0004003d,0x0000000c,0x00000307,
+ 0x00000306,0x0006000c,0x00000007,0x00000308,0x00000001,0x00000040,0x00000307,0x0003003e,
+ 0x000002e4,0x00000308,0x00050041,0x0000000d,0x00000309,0x00000241,0x000002e5,0x0004003d,
+ 0x0000000c,0x0000030a,0x00000309,0x00050041,0x00000048,0x0000030b,0x000002e4,0x0000030a,
+ 0x0004003d,0x00000006,0x0000030c,0x0000030b,0x00050041,0x00000048,0x0000030d,0x0000028c,
+ 0x000002e5,0x0003003e,0x0000030d,0x0000030c,0x0004003d,0x00000007,0x0000030f,0x0000026b,
+ 0x0004003d,0x00000007,0x00000310,0x00000126,0x00050085,0x00000007,0x00000311,0x0000030f,
+ 0x00000310,0x0004003d,0x00000007,0x00000312,0x00000276,0x0004003d,0x00000007,0x00000313,
+ 0x0000012e,0x00050085,0x00000007,0x00000314,0x00000312,0x00000313,0x00050081,0x00000007,
+ 0x00000315,0x00000311,0x00000314,0x0004003d,0x00000007,0x00000316,0x00000281,0x0004003d,
+ 0x00000007,0x00000317,0x00000134,0x00050085,0x00000007,0x00000318,0x00000316,0x00000317,
+ 0x00050081,0x00000007,0x00000319,0x00000315,0x00000318,0x0004003d,0x00000007,0x0000031a,
+ 0x0000028c,0x0004003d,0x00000007,0x0000031b,0x0000013a,0x00050085,0x00000007,0x0000031c,
+ 0x0000031a,0x0000031b,0x00050081,0x00000007,0x0000031d,0x00000319,0x0000031c,0x0003003e,
+ 0x0000030e,0x0000031d,0x0004003d,0x00000007,0x0000031e,0x0000030e,0x0004003d,0x0000000a,
+ 0x0000031f,0x00000013,0x000400a8,0x0000000a,0x00000320,0x0000031f,0x000600a9,0x00000007,
+ 0x00000323,0x00000320,0x00000322,0x00000321,0x00050085,0x00000007,0x00000324,0x0000031e,
+ 0x00000323,0x0006000c,0x0000000c,0x00000325,0x00000001,0x00000037,0x00000324,0x0003003e,
+ 0x00000014,0x00000325,0x000100fd,0x00010038,0x00050036,0x00000002,0x0000001e,0x00000000,
+ 0x00000019,0x00030037,0x00000018,0x0000001a,0x00030037,0x00000018,0x0000001b,0x00030037,
+ 0x0000000b,0x0000001c,0x00030037,0x0000000d,0x0000001d,0x000200f8,0x0000001f,0x0004003b,
+ 0x00000327,0x00000328,0x00000007,0x0004003b,0x00000327,0x0000032b,0x00000007,0x0004003b,
+ 0x00000327,0x0000032e,0x00000007,0x0004003b,0x00000327,0x00000332,0x00000007,0x0004003b,
+ 0x00000327,0x00000334,0x00000007,0x0004003b,0x00000327,0x00000336,0x00000007,0x0004003b,
+ 0x00000327,0x0000033a,0x00000007,0x0004003b,0x00000327,0x0000033c,0x00000007,0x0004003b,
+ 0x00000018,0x0000033e,0x00000007,0x0004003b,0x00000018,0x00000341,0x00000007,0x0004003b,
+ 0x00000018,0x00000344,0x00000007,0x0004003b,0x00000018,0x0000034c,0x00000007,0x0004003b,
+ 0x00000018,0x00000352,0x00000007,0x0004003b,0x00000018,0x00000358,0x00000007,0x0004003b,
+ 0x00000327,0x0000035c,0x00000007,0x0004003b,0x00000327,0x00000360,0x00000007,0x0004003b,
+ 0x00000327,0x00000364,0x00000007,0x0004003b,0x00000327,0x00000368,0x00000007,0x0004003b,
+ 0x00000327,0x0000036c,0x00000007,0x0004003b,0x00000327,0x00000372,0x00000007,0x0004003b,
+ 0x00000327,0x00000378,0x00000007,0x0004003b,0x00000327,0x0000037e,0x00000007,0x0004003b,
+ 0x00000327,0x00000384,0x00000007,0x0004003b,0x00000327,0x0000038c,0x00000007,0x0004003b,
+ 0x00000327,0x00000394,0x00000007,0x0004003b,0x00000327,0x0000039c,0x00000007,0x0004003b,
+ 0x00000008,0x000003a4,0x00000007,0x0004003b,0x00000008,0x000003ae,0x00000007,0x0004003b,
+ 0x00000018,0x000003b2,0x00000007,0x0004003b,0x00000008,0x000003c2,0x00000007,0x0004003b,
+ 0x00000018,0x000003c6,0x00000007,0x0004003b,0x00000008,0x000003d6,0x00000007,0x0004003b,
+ 0x00000018,0x000003da,0x00000007,0x0004003b,0x00000008,0x000003ea,0x00000007,0x0004003b,
+ 0x00000018,0x000003ee,0x00000007,0x0004003b,0x00000018,0x00000401,0x00000007,0x0004003b,
+ 0x00000018,0x00000414,0x00000007,0x0004003b,0x00000018,0x00000427,0x00000007,0x0004003b,
+ 0x00000018,0x0000043a,0x00000007,0x0004003b,0x00000008,0x00000445,0x00000007,0x0004003d,
+ 0x00000017,0x00000329,0x0000001a,0x0004006d,0x00000326,0x0000032a,0x00000329,0x0003003e,
+ 0x00000328,0x0000032a,0x0004003d,0x00000017,0x0000032c,0x0000001b,0x0004006d,0x00000326,
+ 0x0000032d,0x0000032c,0x0003003e,0x0000032b,0x0000032d,0x0004003d,0x00000326,0x0000032f,
+ 0x00000328,0x00050050,0x00000326,0x00000330,0x00000029,0x00000029,0x00050080,0x00000326,
+ 0x00000331,0x0000032f,0x00000330,0x0003003e,0x0000032e,0x00000331,0x0004003d,0x00000326,
+ 0x00000333,0x0000032b,0x0003003e,0x00000332,0x00000333,0x0004003d,0x00000326,0x00000335,
+ 0x00000328,0x0003003e,0x00000334,0x00000335,0x0004003d,0x00000326,0x00000337,0x0000032b,
+ 0x00050050,0x00000326,0x00000338,0x00000029,0x00000029,0x00050080,0x00000326,0x00000339,
+ 0x00000337,0x00000338,0x0003003e,0x00000336,0x00000339,0x0004003d,0x00000326,0x0000033b,
+ 0x0000032e,0x0003003e,0x0000033a,0x0000033b,0x0004003d,0x00000326,0x0000033d,0x00000336,
+ 0x0003003e,0x0000033c,0x0000033d,0x0004003d,0x00000017,0x0000033f,0x0000001a,0x0006000c,
+ 0x00000017,0x00000340,0x00000001,0x0000000a,0x0000033f,0x0003003e,0x0000033e,0x00000340,
+ 0x0004003d,0x00000017,0x00000342,0x0000001b,0x0006000c,0x00000017,0x00000343,0x00000001,
+ 0x0000000a,0x00000342,0x0003003e,0x00000341,0x00000343,0x0004003d,0x00000017,0x00000345,
+ 0x0000033e,0x00050050,0x00000017,0x00000346,0x00000040,0x00000040,0x00050083,0x00000017,
+ 0x00000347,0x00000346,0x00000345,0x0004003d,0x00000017,0x00000348,0x00000341,0x00050050,
+ 0x00000017,0x00000349,0x00000040,0x00000040,0x00050083,0x00000017,0x0000034a,0x00000349,
+ 0x00000348,0x00050085,0x00000017,0x0000034b,0x00000347,0x0000034a,0x0003003e,0x00000344,
+ 0x0000034b,0x0004003d,0x00000017,0x0000034d,0x0000033e,0x0004003d,0x00000017,0x0000034e,
+ 0x00000341,0x00050050,0x00000017,0x0000034f,0x00000040,0x00000040,0x00050083,0x00000017,
+ 0x00000350,0x0000034f,0x0000034e,0x00050085,0x00000017,0x00000351,0x0000034d,0x00000350,
+ 0x0003003e,0x0000034c,0x00000351,0x0004003d,0x00000017,0x00000353,0x0000033e,0x00050050,
+ 0x00000017,0x00000354,0x00000040,0x00000040,0x00050083,0x00000017,0x00000355,0x00000354,
+ 0x00000353,0x0004003d,0x00000017,0x00000356,0x00000341,0x00050085,0x00000017,0x00000357,
+ 0x00000355,0x00000356,0x0003003e,0x00000352,0x00000357,0x0004003d,0x00000017,0x00000359,
+ 0x0000033e,0x0004003d,0x00000017,0x0000035a,0x00000341,0x00050085,0x00000017,0x0000035b,
+ 0x00000359,0x0000035a,0x0003003e,0x00000358,0x0000035b,0x0004003d,0x00000326,0x0000035d,
+ 0x00000328,0x00050050,0x00000326,0x0000035e,0x0000002f,0x0000002f,0x00050086,0x00000326,
+ 0x0000035f,0x0000035d,0x0000035e,0x0003003e,0x0000035c,0x0000035f,0x0004003d,0x00000326,
+ 0x00000361,0x0000032e,0x00050050,0x00000326,0x00000362,0x0000002f,0x0000002f,0x00050086,
+ 0x00000326,0x00000363,0x00000361,0x00000362,0x0003003e,0x00000360,0x00000363,0x0004003d,
+ 0x00000326,0x00000365,0x00000334,0x00050050,0x00000326,0x00000366,0x0000002f,0x0000002f,
+ 0x00050086,0x00000326,0x00000367,0x00000365,0x00000366,0x0003003e,0x00000364,0x00000367,
+ 0x0004003d,0x00000326,0x00000369,0x0000033a,0x00050050,0x00000326,0x0000036a,0x0000002f,
+ 0x0000002f,0x00050086,0x00000326,0x0000036b,0x00000369,0x0000036a,0x0003003e,0x00000368,
+ 0x0000036b,0x0004003d,0x00000326,0x0000036d,0x00000328,0x00050050,0x00000326,0x0000036e,
+ 0x0000002f,0x0000002f,0x00050089,0x00000326,0x0000036f,0x0000036d,0x0000036e,0x00050050,
+ 0x00000326,0x00000370,0x0000002c,0x0000002c,0x00050086,0x00000326,0x00000371,0x0000036f,
+ 0x00000370,0x0003003e,0x0000036c,0x00000371,0x0004003d,0x00000326,0x00000373,0x0000032e,
+ 0x00050050,0x00000326,0x00000374,0x0000002f,0x0000002f,0x00050089,0x00000326,0x00000375,
+ 0x00000373,0x00000374,0x00050050,0x00000326,0x00000376,0x0000002c,0x0000002c,0x00050086,
+ 0x00000326,0x00000377,0x00000375,0x00000376,0x0003003e,0x00000372,0x00000377,0x0004003d,
+ 0x00000326,0x00000379,0x00000334,0x00050050,0x00000326,0x0000037a,0x0000002f,0x0000002f,
+ 0x00050089,0x00000326,0x0000037b,0x00000379,0x0000037a,0x00050050,0x00000326,0x0000037c,
+ 0x0000002c,0x0000002c,0x00050086,0x00000326,0x0000037d,0x0000037b,0x0000037c,0x0003003e,
+ 0x00000378,0x0000037d,0x0004003d,0x00000326,0x0000037f,0x0000033a,0x00050050,0x00000326,
+ 0x00000380,0x0000002f,0x0000002f,0x00050089,0x00000326,0x00000381,0x0000037f,0x00000380,
+ 0x00050050,0x00000326,0x00000382,0x0000002c,0x0000002c,0x00050086,0x00000326,0x00000383,
+ 0x00000381,0x00000382,0x0003003e,0x0000037e,0x00000383,0x0004003d,0x00000326,0x00000385,
+ 0x0000032b,0x00050041,0x00000037,0x00000386,0x00000034,0x00000051,0x0004003d,0x0000000c,
+ 0x00000387,0x00000386,0x00050050,0x00000326,0x00000388,0x00000387,0x00000387,0x00050084,
+ 0x00000326,0x00000389,0x00000385,0x00000388,0x0004003d,0x00000326,0x0000038a,0x0000035c,
+ 0x00050080,0x00000326,0x0000038b,0x00000389,0x0000038a,0x0003003e,0x00000384,0x0000038b,
+ 0x0004003d,0x00000326,0x0000038d,0x00000332,0x00050041,0x00000037,0x0000038e,0x00000034,
+ 0x00000051,0x0004003d,0x0000000c,0x0000038f,0x0000038e,0x00050050,0x00000326,0x00000390,
+ 0x0000038f,0x0000038f,0x00050084,0x00000326,0x00000391,0x0000038d,0x00000390,0x0004003d,
+ 0x00000326,0x00000392,0x00000360,0x00050080,0x00000326,0x00000393,0x00000391,0x00000392,
+ 0x0003003e,0x0000038c,0x00000393,0x0004003d,0x00000326,0x00000395,0x00000336,0x00050041,
+ 0x00000037,0x00000396,0x00000034,0x00000051,0x0004003d,0x0000000c,0x00000397,0x00000396,
+ 0x00050050,0x00000326,0x00000398,0x00000397,0x00000397,0x00050084,0x00000326,0x00000399,
+ 0x00000395,0x00000398,0x0004003d,0x00000326,0x0000039a,0x00000364,0x00050080,0x00000326,
+ 0x0000039b,0x00000399,0x0000039a,0x0003003e,0x00000394,0x0000039b,0x0004003d,0x00000326,
+ 0x0000039d,0x0000033c,0x00050041,0x00000037,0x0000039e,0x00000034,0x00000051,0x0004003d,
+ 0x0000000c,0x0000039f,0x0000039e,0x00050050,0x00000326,0x000003a0,0x0000039f,0x0000039f,
+ 0x00050084,0x00000326,0x000003a1,0x0000039d,0x000003a0,0x0004003d,0x00000326,0x000003a2,
+ 0x00000368,0x00050080,0x00000326,0x000003a3,0x000003a1,0x000003a2,0x0003003e,0x0000039c,
+ 0x000003a3,0x00050041,0x0000000d,0x000003a9,0x00000384,0x00000024,0x0004003d,0x0000000c,
+ 0x000003aa,0x000003a9,0x00060041,0x000000b9,0x000003ab,0x000003a8,0x00000051,0x000003aa,
+ 0x0004003d,0x0000000c,0x000003ac,0x000003ab,0x0006000c,0x00000007,0x000003ad,0x00000001,
+ 0x00000040,0x000003ac,0x0003003e,0x000003a4,0x000003ad,0x00050041,0x0000000d,0x000003af,
+ 0x0000036c,0x00000024,0x0004003d,0x0000000c,0x000003b0,0x000003af,0x000500aa,0x00000009,
+ 0x000003b1,0x000003b0,0x00000024,0x000300f7,0x000003b4,0x00000000,0x000400fa,0x000003b1,
+ 0x000003b3,0x000003b7,0x000200f8,0x000003b3,0x0004003d,0x00000007,0x000003b5,0x000003a4,
+ 0x0007004f,0x00000017,0x000003b6,0x000003b5,0x000003b5,0x00000000,0x00000001,0x0003003e,
+ 0x000003b2,0x000003b6,0x000200f9,0x000003b4,0x000200f8,0x000003b7,0x0004003d,0x00000007,
+ 0x000003b8,0x000003a4,0x0007004f,0x00000017,0x000003b9,0x000003b8,0x000003b8,0x00000002,
+ 0x00000003,0x0003003e,0x000003b2,0x000003b9,0x000200f9,0x000003b4,0x000200f8,0x000003b4,
+ 0x0004003d,0x00000017,0x000003ba,0x000003b2,0x0004003d,0x00000007,0x000003bb,0x000003ae,
+ 0x0009004f,0x00000007,0x000003bc,0x000003bb,0x000003ba,0x00000004,0x00000005,0x00000002,
+ 0x00000003,0x0003003e,0x000003ae,0x000003bc,0x00050041,0x0000000d,0x000003bd,0x0000038c,
+ 0x00000024,0x0004003d,0x0000000c,0x000003be,0x000003bd,0x00060041,0x000000b9,0x000003bf,
+ 0x000003a8,0x00000051,0x000003be,0x0004003d,0x0000000c,0x000003c0,0x000003bf,0x0006000c,
+ 0x00000007,0x000003c1,0x00000001,0x00000040,0x000003c0,0x0003003e,0x000003a4,0x000003c1,
+ 0x00050041,0x0000000d,0x000003c3,0x00000372,0x00000024,0x0004003d,0x0000000c,0x000003c4,
+ 0x000003c3,0x000500aa,0x00000009,0x000003c5,0x000003c4,0x00000024,0x000300f7,0x000003c8,
+ 0x00000000,0x000400fa,0x000003c5,0x000003c7,0x000003cb,0x000200f8,0x000003c7,0x0004003d,
+ 0x00000007,0x000003c9,0x000003a4,0x0007004f,0x00000017,0x000003ca,0x000003c9,0x000003c9,
+ 0x00000000,0x00000001,0x0003003e,0x000003c6,0x000003ca,0x000200f9,0x000003c8,0x000200f8,
+ 0x000003cb,0x0004003d,0x00000007,0x000003cc,0x000003a4,0x0007004f,0x00000017,0x000003cd,
+ 0x000003cc,0x000003cc,0x00000002,0x00000003,0x0003003e,0x000003c6,0x000003cd,0x000200f9,
+ 0x000003c8,0x000200f8,0x000003c8,0x0004003d,0x00000017,0x000003ce,0x000003c6,0x0004003d,
+ 0x00000007,0x000003cf,0x000003c2,0x0009004f,0x00000007,0x000003d0,0x000003cf,0x000003ce,
+ 0x00000004,0x00000005,0x00000002,0x00000003,0x0003003e,0x000003c2,0x000003d0,0x00050041,
+ 0x0000000d,0x000003d1,0x00000394,0x00000024,0x0004003d,0x0000000c,0x000003d2,0x000003d1,
+ 0x00060041,0x000000b9,0x000003d3,0x000003a8,0x00000051,0x000003d2,0x0004003d,0x0000000c,
+ 0x000003d4,0x000003d3,0x0006000c,0x00000007,0x000003d5,0x00000001,0x00000040,0x000003d4,
+ 0x0003003e,0x000003a4,0x000003d5,0x00050041,0x0000000d,0x000003d7,0x00000378,0x00000024,
+ 0x0004003d,0x0000000c,0x000003d8,0x000003d7,0x000500aa,0x00000009,0x000003d9,0x000003d8,
+ 0x00000024,0x000300f7,0x000003dc,0x00000000,0x000400fa,0x000003d9,0x000003db,0x000003df,
+ 0x000200f8,0x000003db,0x0004003d,0x00000007,0x000003dd,0x000003a4,0x0007004f,0x00000017,
+ 0x000003de,0x000003dd,0x000003dd,0x00000000,0x00000001,0x0003003e,0x000003da,0x000003de,
+ 0x000200f9,0x000003dc,0x000200f8,0x000003df,0x0004003d,0x00000007,0x000003e0,0x000003a4,
+ 0x0007004f,0x00000017,0x000003e1,0x000003e0,0x000003e0,0x00000002,0x00000003,0x0003003e,
+ 0x000003da,0x000003e1,0x000200f9,0x000003dc,0x000200f8,0x000003dc,0x0004003d,0x00000017,
+ 0x000003e2,0x000003da,0x0004003d,0x00000007,0x000003e3,0x000003d6,0x0009004f,0x00000007,
+ 0x000003e4,0x000003e3,0x000003e2,0x00000004,0x00000005,0x00000002,0x00000003,0x0003003e,
+ 0x000003d6,0x000003e4,0x00050041,0x0000000d,0x000003e5,0x0000039c,0x00000024,0x0004003d,
+ 0x0000000c,0x000003e6,0x000003e5,0x00060041,0x000000b9,0x000003e7,0x000003a8,0x00000051,
+ 0x000003e6,0x0004003d,0x0000000c,0x000003e8,0x000003e7,0x0006000c,0x00000007,0x000003e9,
+ 0x00000001,0x00000040,0x000003e8,0x0003003e,0x000003a4,0x000003e9,0x00050041,0x0000000d,
+ 0x000003eb,0x0000037e,0x00000024,0x0004003d,0x0000000c,0x000003ec,0x000003eb,0x000500aa,
+ 0x00000009,0x000003ed,0x000003ec,0x00000024,0x000300f7,0x000003f0,0x00000000,0x000400fa,
+ 0x000003ed,0x000003ef,0x000003f3,0x000200f8,0x000003ef,0x0004003d,0x00000007,0x000003f1,
+ 0x000003a4,0x0007004f,0x00000017,0x000003f2,0x000003f1,0x000003f1,0x00000000,0x00000001,
+ 0x0003003e,0x000003ee,0x000003f2,0x000200f9,0x000003f0,0x000200f8,0x000003f3,0x0004003d,
+ 0x00000007,0x000003f4,0x000003a4,0x0007004f,0x00000017,0x000003f5,0x000003f4,0x000003f4,
+ 0x00000002,0x00000003,0x0003003e,0x000003ee,0x000003f5,0x000200f9,0x000003f0,0x000200f8,
+ 0x000003f0,0x0004003d,0x00000017,0x000003f6,0x000003ee,0x0004003d,0x00000007,0x000003f7,
+ 0x000003ea,0x0009004f,0x00000007,0x000003f8,0x000003f7,0x000003f6,0x00000004,0x00000005,
+ 0x00000002,0x00000003,0x0003003e,0x000003ea,0x000003f8,0x00050041,0x0000000d,0x000003f9,
+ 0x00000384,0x00000029,0x0004003d,0x0000000c,0x000003fa,0x000003f9,0x00060041,0x000000b9,
+ 0x000003fb,0x000003a8,0x00000051,0x000003fa,0x0004003d,0x0000000c,0x000003fc,0x000003fb,
+ 0x0006000c,0x00000007,0x000003fd,0x00000001,0x00000040,0x000003fc,0x0003003e,0x000003a4,
+ 0x000003fd,0x00050041,0x0000000d,0x000003fe,0x0000036c,0x00000029,0x0004003d,0x0000000c,
+ 0x000003ff,0x000003fe,0x000500aa,0x00000009,0x00000400,0x000003ff,0x00000024,0x000300f7,
+ 0x00000403,0x00000000,0x000400fa,0x00000400,0x00000402,0x00000406,0x000200f8,0x00000402,
+ 0x0004003d,0x00000007,0x00000404,0x000003a4,0x0007004f,0x00000017,0x00000405,0x00000404,
+ 0x00000404,0x00000000,0x00000001,0x0003003e,0x00000401,0x00000405,0x000200f9,0x00000403,
+ 0x000200f8,0x00000406,0x0004003d,0x00000007,0x00000407,0x000003a4,0x0007004f,0x00000017,
+ 0x00000408,0x00000407,0x00000407,0x00000002,0x00000003,0x0003003e,0x00000401,0x00000408,
+ 0x000200f9,0x00000403,0x000200f8,0x00000403,0x0004003d,0x00000017,0x00000409,0x00000401,
+ 0x0004003d,0x00000007,0x0000040a,0x000003ae,0x0009004f,0x00000007,0x0000040b,0x0000040a,
+ 0x00000409,0x00000000,0x00000001,0x00000004,0x00000005,0x0003003e,0x000003ae,0x0000040b,
+ 0x00050041,0x0000000d,0x0000040c,0x0000038c,0x00000029,0x0004003d,0x0000000c,0x0000040d,
+ 0x0000040c,0x00060041,0x000000b9,0x0000040e,0x000003a8,0x00000051,0x0000040d,0x0004003d,
+ 0x0000000c,0x0000040f,0x0000040e,0x0006000c,0x00000007,0x00000410,0x00000001,0x00000040,
+ 0x0000040f,0x0003003e,0x000003a4,0x00000410,0x00050041,0x0000000d,0x00000411,0x00000372,
+ 0x00000029,0x0004003d,0x0000000c,0x00000412,0x00000411,0x000500aa,0x00000009,0x00000413,
+ 0x00000412,0x00000024,0x000300f7,0x00000416,0x00000000,0x000400fa,0x00000413,0x00000415,
+ 0x00000419,0x000200f8,0x00000415,0x0004003d,0x00000007,0x00000417,0x000003a4,0x0007004f,
+ 0x00000017,0x00000418,0x00000417,0x00000417,0x00000000,0x00000001,0x0003003e,0x00000414,
+ 0x00000418,0x000200f9,0x00000416,0x000200f8,0x00000419,0x0004003d,0x00000007,0x0000041a,
+ 0x000003a4,0x0007004f,0x00000017,0x0000041b,0x0000041a,0x0000041a,0x00000002,0x00000003,
+ 0x0003003e,0x00000414,0x0000041b,0x000200f9,0x00000416,0x000200f8,0x00000416,0x0004003d,
+ 0x00000017,0x0000041c,0x00000414,0x0004003d,0x00000007,0x0000041d,0x000003c2,0x0009004f,
+ 0x00000007,0x0000041e,0x0000041d,0x0000041c,0x00000000,0x00000001,0x00000004,0x00000005,
+ 0x0003003e,0x000003c2,0x0000041e,0x00050041,0x0000000d,0x0000041f,0x00000394,0x00000029,
+ 0x0004003d,0x0000000c,0x00000420,0x0000041f,0x00060041,0x000000b9,0x00000421,0x000003a8,
+ 0x00000051,0x00000420,0x0004003d,0x0000000c,0x00000422,0x00000421,0x0006000c,0x00000007,
+ 0x00000423,0x00000001,0x00000040,0x00000422,0x0003003e,0x000003a4,0x00000423,0x00050041,
+ 0x0000000d,0x00000424,0x00000378,0x00000029,0x0004003d,0x0000000c,0x00000425,0x00000424,
+ 0x000500aa,0x00000009,0x00000426,0x00000425,0x00000024,0x000300f7,0x00000429,0x00000000,
+ 0x000400fa,0x00000426,0x00000428,0x0000042c,0x000200f8,0x00000428,0x0004003d,0x00000007,
+ 0x0000042a,0x000003a4,0x0007004f,0x00000017,0x0000042b,0x0000042a,0x0000042a,0x00000000,
+ 0x00000001,0x0003003e,0x00000427,0x0000042b,0x000200f9,0x00000429,0x000200f8,0x0000042c,
+ 0x0004003d,0x00000007,0x0000042d,0x000003a4,0x0007004f,0x00000017,0x0000042e,0x0000042d,
+ 0x0000042d,0x00000002,0x00000003,0x0003003e,0x00000427,0x0000042e,0x000200f9,0x00000429,
+ 0x000200f8,0x00000429,0x0004003d,0x00000017,0x0000042f,0x00000427,0x0004003d,0x00000007,
+ 0x00000430,0x000003d6,0x0009004f,0x00000007,0x00000431,0x00000430,0x0000042f,0x00000000,
+ 0x00000001,0x00000004,0x00000005,0x0003003e,0x000003d6,0x00000431,0x00050041,0x0000000d,
+ 0x00000432,0x0000039c,0x00000029,0x0004003d,0x0000000c,0x00000433,0x00000432,0x00060041,
+ 0x000000b9,0x00000434,0x000003a8,0x00000051,0x00000433,0x0004003d,0x0000000c,0x00000435,
+ 0x00000434,0x0006000c,0x00000007,0x00000436,0x00000001,0x00000040,0x00000435,0x0003003e,
+ 0x000003a4,0x00000436,0x00050041,0x0000000d,0x00000437,0x0000037e,0x00000029,0x0004003d,
+ 0x0000000c,0x00000438,0x00000437,0x000500aa,0x00000009,0x00000439,0x00000438,0x00000024,
+ 0x000300f7,0x0000043c,0x00000000,0x000400fa,0x00000439,0x0000043b,0x0000043f,0x000200f8,
+ 0x0000043b,0x0004003d,0x00000007,0x0000043d,0x000003a4,0x0007004f,0x00000017,0x0000043e,
+ 0x0000043d,0x0000043d,0x00000000,0x00000001,0x0003003e,0x0000043a,0x0000043e,0x000200f9,
+ 0x0000043c,0x000200f8,0x0000043f,0x0004003d,0x00000007,0x00000440,0x000003a4,0x0007004f,
+ 0x00000017,0x00000441,0x00000440,0x00000440,0x00000002,0x00000003,0x0003003e,0x0000043a,
+ 0x00000441,0x000200f9,0x0000043c,0x000200f8,0x0000043c,0x0004003d,0x00000017,0x00000442,
+ 0x0000043a,0x0004003d,0x00000007,0x00000443,0x000003ea,0x0009004f,0x00000007,0x00000444,
+ 0x00000443,0x00000442,0x00000000,0x00000001,0x00000004,0x00000005,0x0003003e,0x000003ea,
+ 0x00000444,0x0004003d,0x00000007,0x00000446,0x000003ae,0x0004003d,0x00000017,0x00000447,
+ 0x00000344,0x0009004f,0x00000007,0x00000448,0x00000447,0x00000447,0x00000000,0x00000000,
+ 0x00000001,0x00000001,0x00050085,0x00000007,0x00000449,0x00000446,0x00000448,0x0004003d,
+ 0x00000007,0x0000044a,0x000003c2,0x0004003d,0x00000017,0x0000044b,0x0000034c,0x0009004f,
+ 0x00000007,0x0000044c,0x0000044b,0x0000044b,0x00000000,0x00000000,0x00000001,0x00000001,
+ 0x00050085,0x00000007,0x0000044d,0x0000044a,0x0000044c,0x00050081,0x00000007,0x0000044e,
+ 0x00000449,0x0000044d,0x0004003d,0x00000007,0x0000044f,0x000003d6,0x0004003d,0x00000017,
+ 0x00000450,0x00000352,0x0009004f,0x00000007,0x00000451,0x00000450,0x00000450,0x00000000,
+ 0x00000000,0x00000001,0x00000001,0x00050085,0x00000007,0x00000452,0x0000044f,0x00000451,
+ 0x00050081,0x00000007,0x00000453,0x0000044e,0x00000452,0x0004003d,0x00000007,0x00000454,
+ 0x000003ea,0x0004003d,0x00000017,0x00000455,0x00000358,0x0009004f,0x00000007,0x00000456,
+ 0x00000455,0x00000455,0x00000000,0x00000000,0x00000001,0x00000001,0x00050085,0x00000007,
+ 0x00000457,0x00000454,0x00000456,0x00050081,0x00000007,0x00000458,0x00000453,0x00000457,
+ 0x0003003e,0x00000445,0x00000458,0x0004003d,0x00000007,0x00000459,0x00000445,0x0004003d,
+ 0x0000000a,0x0000045a,0x0000001c,0x000400a8,0x0000000a,0x0000045b,0x0000045a,0x000600a9,
+ 0x00000007,0x0000045c,0x0000045b,0x00000322,0x00000321,0x00050085,0x00000007,0x0000045d,
+ 0x00000459,0x0000045c,0x0004003d,0x0000000a,0x0000045e,0x0000001c,0x000600a9,0x00000007,
+ 0x0000045f,0x0000045e,0x00000322,0x00000321,0x0005008e,0x00000007,0x00000460,0x0000045f,
+ 0x000000c2,0x00050081,0x00000007,0x00000461,0x0000045d,0x00000460,0x0003003e,0x00000445,
+ 0x00000461,0x0004003d,0x00000007,0x00000462,0x00000445,0x0006000c,0x0000000c,0x00000463,
+ 0x00000001,0x00000037,0x00000462,0x0003003e,0x0000001d,0x00000463,0x000100fd,0x00010038
diff --git a/shaders/spv/shader_lap_trans_pyr.comp b/shaders/spv/shader_lap_trans_pyr.comp
new file mode 100644
index 0000000..a1f29ee
--- /dev/null
+++ b/shaders/spv/shader_lap_trans_pyr.comp
@@ -0,0 +1,162 @@
+#version 310 es
+
+layout (local_size_x = 8, local_size_y = 8) in;
+
+layout (binding = 0) readonly buffer InBufY {
+ uvec2 data[];
+} in_buf_y;
+
+layout (binding = 1) readonly buffer InBufUV {
+ uvec2 data[];
+} in_buf_uv;
+
+layout (binding = 2) readonly buffer GaussScaleBufY {
+ uint data[];
+} gaussscale_buf_y;
+
+layout (binding = 3) readonly buffer GaussScaleBufUV {
+ uint data[];
+} gaussscale_buf_uv;
+
+layout (binding = 4) writeonly buffer OutBufY {
+ uvec2 data[];
+} out_buf_y;
+
+layout (binding = 5) writeonly buffer OutBufUV {
+ uvec2 data[];
+} out_buf_uv;
+
+layout (push_constant) uniform PushConsts {
+ uint in_img_width;
+ uint in_img_height;
+ uint in_offset_x;
+ uint gaussscale_img_width;
+ uint gaussscale_img_height;
+ uint merge_width;
+} prop;
+
+// normalization of half gray level
+const float norm_half_gl = 128.0f / 255.0f;
+
+void lap_trans_y (uvec2 y_id, uvec2 gs_id);
+void lap_trans_uv (uvec2 uv_id, uvec2 gs_id);
+
+void main ()
+{
+ uvec2 g_id = gl_GlobalInvocationID.xy;
+
+ uvec2 y_id = uvec2 (g_id.x, g_id.y * 4u);
+ y_id.x = clamp (y_id.x, 0u, prop.merge_width - 1u);
+
+ uvec2 gs_id = uvec2 (g_id.x, g_id.y * 2u);
+ gs_id.x = clamp (gs_id.x, 0u, prop.gaussscale_img_width - 1u);
+ lap_trans_y (y_id, gs_id);
+
+ y_id.y += 2u;
+ gs_id.y += 1u;
+ lap_trans_y (y_id, gs_id);
+
+ uvec2 uv_id = uvec2 (y_id.x, g_id.y * 2u);
+ gs_id.y = g_id.y;
+ lap_trans_uv (uv_id, gs_id);
+}
+
+void lap_trans_y (uvec2 y_id, uvec2 gs_id)
+{
+ y_id.y = clamp (y_id.y, 0u, prop.in_img_height - 1u);
+ gs_id.y = clamp (gs_id.y, 0u, prop.gaussscale_img_height - 1u);
+
+ uint y_idx = y_id.y * prop.in_img_width + prop.in_offset_x + y_id.x;
+ uvec2 in_pack = in_buf_y.data[y_idx];
+ vec4 in0 = unpackUnorm4x8 (in_pack.x);
+ vec4 in1 = unpackUnorm4x8 (in_pack.y);
+
+ uint gs_idx = gs_id.y * prop.gaussscale_img_width + gs_id.x;
+ vec4 gs0 = unpackUnorm4x8 (gaussscale_buf_y.data[gs_idx]);
+ vec4 gs1 = unpackUnorm4x8 (gaussscale_buf_y.data[gs_idx + 1u]);
+ gs1 = (gs_id.x == prop.gaussscale_img_width - 1u) ? gs0.wwww : gs1;
+
+ vec4 inter = (gs0 + vec4 (gs0.yzw, gs1.x)) * 0.5f;
+ vec4 inter00 = vec4 (gs0.x, inter.x, gs0.y, inter.y);
+ vec4 inter01 = vec4 (gs0.z, inter.z, gs0.w, inter.w);
+
+ vec4 lap0 = (in0 - inter00) * 0.5f + norm_half_gl;
+ vec4 lap1 = (in1 - inter01) * 0.5f + norm_half_gl;
+ lap0 = clamp (lap0, 0.0f, 1.0f);
+ lap1 = clamp (lap1, 0.0f, 1.0f);
+
+ uint out_idx = y_id.y * prop.merge_width + y_id.x;
+ out_buf_y.data[out_idx] = uvec2 (packUnorm4x8 (lap0), packUnorm4x8 (lap1));
+
+ y_idx = (y_id.y >= prop.in_img_height - 1u) ? y_idx : y_idx + prop.in_img_width;
+ in_pack = in_buf_y.data[y_idx];
+ in0 = unpackUnorm4x8 (in_pack.x);
+ in1 = unpackUnorm4x8 (in_pack.y);
+
+ gs_idx = (gs_id.y >= prop.gaussscale_img_height - 1u) ? gs_idx : gs_idx + prop.gaussscale_img_width;
+ gs0 = unpackUnorm4x8 (gaussscale_buf_y.data[gs_idx]);
+ gs1 = unpackUnorm4x8 (gaussscale_buf_y.data[gs_idx + 1u]);
+ gs1 = (gs_id.x == prop.gaussscale_img_width - 1u) ? gs0.wwww : gs1;
+
+ inter = (gs0 + vec4 (gs0.yzw, gs1.x)) * 0.5f;
+ vec4 inter10 = (inter00 + vec4 (gs0.x, inter.x, gs0.y, inter.y)) * 0.5f;
+ vec4 inter11 = (inter01 + vec4 (gs0.z, inter.z, gs0.w, inter.w)) * 0.5f;
+
+ lap0 = (in0 - inter10) * 0.5f + norm_half_gl;
+ lap1 = (in1 - inter11) * 0.5f + norm_half_gl;
+ lap0 = clamp (lap0, 0.0f, 1.0f);
+ lap1 = clamp (lap1, 0.0f, 1.0f);
+
+ out_idx = (y_id.y >= prop.in_img_height - 1u) ? out_idx : out_idx + prop.merge_width;
+ out_buf_y.data[out_idx] = uvec2 (packUnorm4x8 (lap0), packUnorm4x8 (lap1));
+}
+
+void lap_trans_uv (uvec2 uv_id, uvec2 gs_id)
+{
+ uv_id.y = clamp (uv_id.y, 0u, prop.in_img_height / 2u - 1u);
+ gs_id.y = clamp (gs_id.y, 0u, prop.gaussscale_img_height / 2u - 1u);
+
+ uint uv_idx = uv_id.y * prop.in_img_width + prop.in_offset_x + uv_id.x;
+ uvec2 in_pack = in_buf_uv.data[uv_idx];
+ vec4 in0 = unpackUnorm4x8 (in_pack.x);
+ vec4 in1 = unpackUnorm4x8 (in_pack.y);
+
+ uint gs_idx = gs_id.y * prop.gaussscale_img_width + gs_id.x;
+ vec4 gs0 = unpackUnorm4x8 (gaussscale_buf_uv.data[gs_idx]);
+ vec4 gs1 = unpackUnorm4x8 (gaussscale_buf_uv.data[gs_idx + 1u]);
+ gs1 = (gs_id.x == prop.gaussscale_img_width - 1u) ? gs0.zwzw : gs1;
+
+ vec4 inter = (gs0 + vec4 (gs0.zw, gs1.xy)) * 0.5f;
+ vec4 inter00 = vec4 (gs0.xy, inter.xy);
+ vec4 inter01 = vec4 (gs0.zw, inter.zw);
+
+ vec4 lap0 = (in0 - inter00) * 0.5f + norm_half_gl;
+ vec4 lap1 = (in1 - inter01) * 0.5f + norm_half_gl;
+ lap0 = clamp (lap0, 0.0f, 1.0f);
+ lap1 = clamp (lap1, 0.0f, 1.0f);
+
+ uint out_idx = uv_id.y * prop.merge_width + uv_id.x;
+ out_buf_uv.data[out_idx] = uvec2 (packUnorm4x8 (lap0), packUnorm4x8 (lap1));
+
+ uv_idx = (uv_id.y >= (prop.in_img_height / 2u - 1u)) ? uv_idx : uv_idx + prop.in_img_width;
+ in_pack = in_buf_uv.data[uv_idx];
+ in0 = unpackUnorm4x8 (in_pack.x);
+ in1 = unpackUnorm4x8 (in_pack.y);
+
+ gs_idx = (gs_id.y >= (prop.gaussscale_img_height / 2u - 1u)) ? gs_idx : gs_idx + prop.gaussscale_img_width;
+ gs0 = unpackUnorm4x8 (gaussscale_buf_uv.data[gs_idx]);
+ gs1 = unpackUnorm4x8 (gaussscale_buf_uv.data[gs_idx + 1u]);
+ gs1 = (gs_id.x == prop.gaussscale_img_width - 1u) ? gs0.zwzw : gs1;
+
+ inter = (gs0 + vec4 (gs0.zw, gs1.xy)) * 0.5f;
+ vec4 inter10 = (inter00 + vec4 (gs0.xy, inter.xy)) * 0.5f;
+ vec4 inter11 = (inter01 + vec4 (gs0.zw, inter.zw)) * 0.5f;
+
+ lap0 = (in0 - inter10) * 0.5f + norm_half_gl;
+ lap1 = (in1 - inter11) * 0.5f + norm_half_gl;
+ lap0 = clamp (lap0, 0.0f, 1.0f);
+ lap1 = clamp (lap1, 0.0f, 1.0f);
+
+ out_idx += prop.merge_width;
+ out_buf_uv.data[out_idx] = uvec2 (packUnorm4x8 (lap0), packUnorm4x8 (lap1));
+}
diff --git a/shaders/spv/shader_lap_trans_pyr.comp.spv b/shaders/spv/shader_lap_trans_pyr.comp.spv
new file mode 100644
index 0000000..d137ab2
--- /dev/null
+++ b/shaders/spv/shader_lap_trans_pyr.comp.spv
@@ -0,0 +1,536 @@
+ // 7.8.2870
+ 0x07230203,0x00010000,0x00080007,0x000002c3,0x00000000,0x00020011,0x00000001,0x0006000b,
+ 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,
+ 0x0006000f,0x00000005,0x00000004,0x6e69616d,0x00000000,0x00000015,0x00060010,0x00000004,
+ 0x00000011,0x00000008,0x00000008,0x00000001,0x00030003,0x00000001,0x00000136,0x00040005,
+ 0x00000004,0x6e69616d,0x00000000,0x00080005,0x0000000c,0x5f70616c,0x6e617274,0x28795f73,
+ 0x3b327576,0x3b327576,0x00000000,0x00040005,0x0000000a,0x64695f79,0x00000000,0x00040005,
+ 0x0000000b,0x695f7367,0x00000064,0x00080005,0x00000010,0x5f70616c,0x6e617274,0x76755f73,
+ 0x32757628,0x3275763b,0x0000003b,0x00040005,0x0000000e,0x695f7675,0x00000064,0x00040005,
+ 0x0000000f,0x695f7367,0x00000064,0x00040005,0x00000012,0x64695f67,0x00000000,0x00080005,
+ 0x00000015,0x475f6c67,0x61626f6c,0x766e496c,0x7461636f,0x496e6f69,0x00000044,0x00040005,
+ 0x00000018,0x64695f79,0x00000000,0x00050005,0x00000025,0x68737550,0x736e6f43,0x00007374,
+ 0x00070006,0x00000025,0x00000000,0x695f6e69,0x775f676d,0x68746469,0x00000000,0x00070006,
+ 0x00000025,0x00000001,0x695f6e69,0x685f676d,0x68676965,0x00000074,0x00060006,0x00000025,
+ 0x00000002,0x6f5f6e69,0x65736666,0x00785f74,0x00090006,0x00000025,0x00000003,0x73756167,
+ 0x61637373,0x695f656c,0x775f676d,0x68746469,0x00000000,0x00090006,0x00000025,0x00000004,
+ 0x73756167,0x61637373,0x695f656c,0x685f676d,0x68676965,0x00000074,0x00060006,0x00000025,
+ 0x00000005,0x6772656d,0x69775f65,0x00687464,0x00040005,0x00000027,0x706f7270,0x00000000,
+ 0x00040005,0x00000030,0x695f7367,0x00000064,0x00040005,0x00000040,0x61726170,0x0000006d,
+ 0x00040005,0x00000042,0x61726170,0x0000006d,0x00040005,0x0000004d,0x61726170,0x0000006d,
+ 0x00040005,0x0000004f,0x61726170,0x0000006d,0x00040005,0x00000052,0x695f7675,0x00000064,
+ 0x00040005,0x0000005c,0x61726170,0x0000006d,0x00040005,0x0000005e,0x61726170,0x0000006d,
+ 0x00040005,0x00000071,0x64695f79,0x00000078,0x00040005,0x0000007f,0x705f6e69,0x006b6361,
+ 0x00040005,0x00000081,0x75426e49,0x00005966,0x00050006,0x00000081,0x00000000,0x61746164,
+ 0x00000000,0x00050005,0x00000083,0x625f6e69,0x795f6675,0x00000000,0x00030005,0x0000008b,
+ 0x00306e69,0x00030005,0x0000008f,0x00316e69,0x00040005,0x00000093,0x695f7367,0x00007864,
+ 0x00030005,0x0000009c,0x00307367,0x00060005,0x0000009e,0x73756147,0x61635373,0x7542656c,
+ 0x00005966,0x00050006,0x0000009e,0x00000000,0x61746164,0x00000000,0x00070005,0x000000a0,
+ 0x73756167,0x61637373,0x625f656c,0x795f6675,0x00000000,0x00030005,0x000000a6,0x00317367,
+ 0x00040005,0x000000bb,0x65746e69,0x00000072,0x00040005,0x000000ca,0x65746e69,0x00303072,
+ 0x00040005,0x000000d4,0x65746e69,0x00313072,0x00040005,0x000000df,0x3070616c,0x00000000,
+ 0x00040005,0x000000e7,0x3170616c,0x00000000,0x00040005,0x000000f8,0x5f74756f,0x00786469,
+ 0x00040005,0x00000102,0x4274754f,0x00596675,0x00050006,0x00000102,0x00000000,0x61746164,
+ 0x00000000,0x00050005,0x00000104,0x5f74756f,0x5f667562,0x00000079,0x00040005,0x00000157,
+ 0x65746e69,0x00303172,0x00040005,0x00000164,0x65746e69,0x00313172,0x00040005,0x000001ac,
+ 0x695f7675,0x00007864,0x00040005,0x000001b8,0x705f6e69,0x006b6361,0x00040005,0x000001ba,
+ 0x75426e49,0x00565566,0x00050006,0x000001ba,0x00000000,0x61746164,0x00000000,0x00050005,
+ 0x000001bc,0x625f6e69,0x755f6675,0x00000076,0x00030005,0x000001c0,0x00306e69,0x00030005,
+ 0x000001c4,0x00316e69,0x00040005,0x000001c8,0x695f7367,0x00007864,0x00030005,0x000001d1,
+ 0x00307367,0x00060005,0x000001d3,0x73756147,0x61635373,0x7542656c,0x00565566,0x00050006,
+ 0x000001d3,0x00000000,0x61746164,0x00000000,0x00070005,0x000001d5,0x73756167,0x61637373,
+ 0x625f656c,0x755f6675,0x00000076,0x00030005,0x000001da,0x00317367,0x00040005,0x000001ee,
+ 0x65746e69,0x00000072,0x00040005,0x000001fc,0x65746e69,0x00303072,0x00040005,0x00000206,
+ 0x65746e69,0x00313072,0x00040005,0x00000210,0x3070616c,0x00000000,0x00040005,0x00000217,
+ 0x3170616c,0x00000000,0x00040005,0x00000226,0x5f74756f,0x00786469,0x00050005,0x00000230,
+ 0x4274754f,0x56556675,0x00000000,0x00050006,0x00000230,0x00000000,0x61746164,0x00000000,
+ 0x00050005,0x00000232,0x5f74756f,0x5f667562,0x00007675,0x00040005,0x00000288,0x65746e69,
+ 0x00303172,0x00040005,0x00000295,0x65746e69,0x00313172,0x00040047,0x00000015,0x0000000b,
+ 0x0000001c,0x00050048,0x00000025,0x00000000,0x00000023,0x00000000,0x00050048,0x00000025,
+ 0x00000001,0x00000023,0x00000004,0x00050048,0x00000025,0x00000002,0x00000023,0x00000008,
+ 0x00050048,0x00000025,0x00000003,0x00000023,0x0000000c,0x00050048,0x00000025,0x00000004,
+ 0x00000023,0x00000010,0x00050048,0x00000025,0x00000005,0x00000023,0x00000014,0x00030047,
+ 0x00000025,0x00000002,0x00040047,0x00000080,0x00000006,0x00000008,0x00040048,0x00000081,
+ 0x00000000,0x00000018,0x00050048,0x00000081,0x00000000,0x00000023,0x00000000,0x00030047,
+ 0x00000081,0x00000003,0x00040047,0x00000083,0x00000022,0x00000000,0x00040047,0x00000083,
+ 0x00000021,0x00000000,0x00040047,0x0000009d,0x00000006,0x00000004,0x00040048,0x0000009e,
+ 0x00000000,0x00000018,0x00050048,0x0000009e,0x00000000,0x00000023,0x00000000,0x00030047,
+ 0x0000009e,0x00000003,0x00040047,0x000000a0,0x00000022,0x00000000,0x00040047,0x000000a0,
+ 0x00000021,0x00000002,0x00040047,0x00000101,0x00000006,0x00000008,0x00040048,0x00000102,
+ 0x00000000,0x00000019,0x00050048,0x00000102,0x00000000,0x00000023,0x00000000,0x00030047,
+ 0x00000102,0x00000003,0x00040047,0x00000104,0x00000022,0x00000000,0x00040047,0x00000104,
+ 0x00000021,0x00000004,0x00040047,0x000001b9,0x00000006,0x00000008,0x00040048,0x000001ba,
+ 0x00000000,0x00000018,0x00050048,0x000001ba,0x00000000,0x00000023,0x00000000,0x00030047,
+ 0x000001ba,0x00000003,0x00040047,0x000001bc,0x00000022,0x00000000,0x00040047,0x000001bc,
+ 0x00000021,0x00000001,0x00040047,0x000001d2,0x00000006,0x00000004,0x00040048,0x000001d3,
+ 0x00000000,0x00000018,0x00050048,0x000001d3,0x00000000,0x00000023,0x00000000,0x00030047,
+ 0x000001d3,0x00000003,0x00040047,0x000001d5,0x00000022,0x00000000,0x00040047,0x000001d5,
+ 0x00000021,0x00000003,0x00040047,0x0000022f,0x00000006,0x00000008,0x00040048,0x00000230,
+ 0x00000000,0x00000019,0x00050048,0x00000230,0x00000000,0x00000023,0x00000000,0x00030047,
+ 0x00000230,0x00000003,0x00040047,0x00000232,0x00000022,0x00000000,0x00040047,0x00000232,
+ 0x00000021,0x00000005,0x00040047,0x000002c2,0x0000000b,0x00000019,0x00020013,0x00000002,
+ 0x00030021,0x00000003,0x00000002,0x00040015,0x00000006,0x00000020,0x00000000,0x00040017,
+ 0x00000007,0x00000006,0x00000002,0x00040020,0x00000008,0x00000007,0x00000007,0x00050021,
+ 0x00000009,0x00000002,0x00000008,0x00000008,0x00040017,0x00000013,0x00000006,0x00000003,
+ 0x00040020,0x00000014,0x00000001,0x00000013,0x0004003b,0x00000014,0x00000015,0x00000001,
+ 0x0004002b,0x00000006,0x00000019,0x00000000,0x00040020,0x0000001a,0x00000007,0x00000006,
+ 0x0004002b,0x00000006,0x0000001d,0x00000001,0x0004002b,0x00000006,0x00000020,0x00000004,
+ 0x0008001e,0x00000025,0x00000006,0x00000006,0x00000006,0x00000006,0x00000006,0x00000006,
+ 0x00040020,0x00000026,0x00000009,0x00000025,0x0004003b,0x00000026,0x00000027,0x00000009,
+ 0x00040015,0x00000028,0x00000020,0x00000001,0x0004002b,0x00000028,0x00000029,0x00000005,
+ 0x00040020,0x0000002a,0x00000009,0x00000006,0x0004002b,0x00000006,0x00000035,0x00000002,
+ 0x0004002b,0x00000028,0x0000003a,0x00000003,0x0004002b,0x00000028,0x00000063,0x00000001,
+ 0x0004002b,0x00000028,0x0000006b,0x00000004,0x0004002b,0x00000028,0x00000074,0x00000000,
+ 0x0004002b,0x00000028,0x00000078,0x00000002,0x0003001d,0x00000080,0x00000007,0x0003001e,
+ 0x00000081,0x00000080,0x00040020,0x00000082,0x00000002,0x00000081,0x0004003b,0x00000082,
+ 0x00000083,0x00000002,0x00040020,0x00000085,0x00000002,0x00000007,0x00030016,0x00000088,
+ 0x00000020,0x00040017,0x00000089,0x00000088,0x00000004,0x00040020,0x0000008a,0x00000007,
+ 0x00000089,0x0003001d,0x0000009d,0x00000006,0x0003001e,0x0000009e,0x0000009d,0x00040020,
+ 0x0000009f,0x00000002,0x0000009e,0x0004003b,0x0000009f,0x000000a0,0x00000002,0x00040020,
+ 0x000000a2,0x00000002,0x00000006,0x00020014,0x000000b1,0x00040017,0x000000bd,0x00000088,
+ 0x00000003,0x00040020,0x000000c0,0x00000007,0x00000088,0x0004002b,0x00000088,0x000000c8,
+ 0x3f000000,0x0004002b,0x00000006,0x000000d9,0x00000003,0x0004002b,0x00000088,0x000000e4,
+ 0x3f008081,0x0004002b,0x00000088,0x000000ef,0x00000000,0x0004002b,0x00000088,0x000000f0,
+ 0x3f800000,0x0003001d,0x00000101,0x00000007,0x0003001e,0x00000102,0x00000101,0x00040020,
+ 0x00000103,0x00000002,0x00000102,0x0004003b,0x00000103,0x00000104,0x00000002,0x0003001d,
+ 0x000001b9,0x00000007,0x0003001e,0x000001ba,0x000001b9,0x00040020,0x000001bb,0x00000002,
+ 0x000001ba,0x0004003b,0x000001bb,0x000001bc,0x00000002,0x0003001d,0x000001d2,0x00000006,
+ 0x0003001e,0x000001d3,0x000001d2,0x00040020,0x000001d4,0x00000002,0x000001d3,0x0004003b,
+ 0x000001d4,0x000001d5,0x00000002,0x00040017,0x000001f0,0x00000088,0x00000002,0x0003001d,
+ 0x0000022f,0x00000007,0x0003001e,0x00000230,0x0000022f,0x00040020,0x00000231,0x00000002,
+ 0x00000230,0x0004003b,0x00000231,0x00000232,0x00000002,0x0004002b,0x00000006,0x000002c1,
+ 0x00000008,0x0006002c,0x00000013,0x000002c2,0x000002c1,0x000002c1,0x0000001d,0x00050036,
+ 0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003b,0x00000008,
+ 0x00000012,0x00000007,0x0004003b,0x00000008,0x00000018,0x00000007,0x0004003b,0x00000008,
+ 0x00000030,0x00000007,0x0004003b,0x00000008,0x00000040,0x00000007,0x0004003b,0x00000008,
+ 0x00000042,0x00000007,0x0004003b,0x00000008,0x0000004d,0x00000007,0x0004003b,0x00000008,
+ 0x0000004f,0x00000007,0x0004003b,0x00000008,0x00000052,0x00000007,0x0004003b,0x00000008,
+ 0x0000005c,0x00000007,0x0004003b,0x00000008,0x0000005e,0x00000007,0x0004003d,0x00000013,
+ 0x00000016,0x00000015,0x0007004f,0x00000007,0x00000017,0x00000016,0x00000016,0x00000000,
+ 0x00000001,0x0003003e,0x00000012,0x00000017,0x00050041,0x0000001a,0x0000001b,0x00000012,
+ 0x00000019,0x0004003d,0x00000006,0x0000001c,0x0000001b,0x00050041,0x0000001a,0x0000001e,
+ 0x00000012,0x0000001d,0x0004003d,0x00000006,0x0000001f,0x0000001e,0x00050084,0x00000006,
+ 0x00000021,0x0000001f,0x00000020,0x00050050,0x00000007,0x00000022,0x0000001c,0x00000021,
+ 0x0003003e,0x00000018,0x00000022,0x00050041,0x0000001a,0x00000023,0x00000018,0x00000019,
+ 0x0004003d,0x00000006,0x00000024,0x00000023,0x00050041,0x0000002a,0x0000002b,0x00000027,
+ 0x00000029,0x0004003d,0x00000006,0x0000002c,0x0000002b,0x00050082,0x00000006,0x0000002d,
+ 0x0000002c,0x0000001d,0x0008000c,0x00000006,0x0000002e,0x00000001,0x0000002c,0x00000024,
+ 0x00000019,0x0000002d,0x00050041,0x0000001a,0x0000002f,0x00000018,0x00000019,0x0003003e,
+ 0x0000002f,0x0000002e,0x00050041,0x0000001a,0x00000031,0x00000012,0x00000019,0x0004003d,
+ 0x00000006,0x00000032,0x00000031,0x00050041,0x0000001a,0x00000033,0x00000012,0x0000001d,
+ 0x0004003d,0x00000006,0x00000034,0x00000033,0x00050084,0x00000006,0x00000036,0x00000034,
+ 0x00000035,0x00050050,0x00000007,0x00000037,0x00000032,0x00000036,0x0003003e,0x00000030,
+ 0x00000037,0x00050041,0x0000001a,0x00000038,0x00000030,0x00000019,0x0004003d,0x00000006,
+ 0x00000039,0x00000038,0x00050041,0x0000002a,0x0000003b,0x00000027,0x0000003a,0x0004003d,
+ 0x00000006,0x0000003c,0x0000003b,0x00050082,0x00000006,0x0000003d,0x0000003c,0x0000001d,
+ 0x0008000c,0x00000006,0x0000003e,0x00000001,0x0000002c,0x00000039,0x00000019,0x0000003d,
+ 0x00050041,0x0000001a,0x0000003f,0x00000030,0x00000019,0x0003003e,0x0000003f,0x0000003e,
+ 0x0004003d,0x00000007,0x00000041,0x00000018,0x0003003e,0x00000040,0x00000041,0x0004003d,
+ 0x00000007,0x00000043,0x00000030,0x0003003e,0x00000042,0x00000043,0x00060039,0x00000002,
+ 0x00000044,0x0000000c,0x00000040,0x00000042,0x00050041,0x0000001a,0x00000045,0x00000018,
+ 0x0000001d,0x0004003d,0x00000006,0x00000046,0x00000045,0x00050080,0x00000006,0x00000047,
+ 0x00000046,0x00000035,0x00050041,0x0000001a,0x00000048,0x00000018,0x0000001d,0x0003003e,
+ 0x00000048,0x00000047,0x00050041,0x0000001a,0x00000049,0x00000030,0x0000001d,0x0004003d,
+ 0x00000006,0x0000004a,0x00000049,0x00050080,0x00000006,0x0000004b,0x0000004a,0x0000001d,
+ 0x00050041,0x0000001a,0x0000004c,0x00000030,0x0000001d,0x0003003e,0x0000004c,0x0000004b,
+ 0x0004003d,0x00000007,0x0000004e,0x00000018,0x0003003e,0x0000004d,0x0000004e,0x0004003d,
+ 0x00000007,0x00000050,0x00000030,0x0003003e,0x0000004f,0x00000050,0x00060039,0x00000002,
+ 0x00000051,0x0000000c,0x0000004d,0x0000004f,0x00050041,0x0000001a,0x00000053,0x00000018,
+ 0x00000019,0x0004003d,0x00000006,0x00000054,0x00000053,0x00050041,0x0000001a,0x00000055,
+ 0x00000012,0x0000001d,0x0004003d,0x00000006,0x00000056,0x00000055,0x00050084,0x00000006,
+ 0x00000057,0x00000056,0x00000035,0x00050050,0x00000007,0x00000058,0x00000054,0x00000057,
+ 0x0003003e,0x00000052,0x00000058,0x00050041,0x0000001a,0x00000059,0x00000012,0x0000001d,
+ 0x0004003d,0x00000006,0x0000005a,0x00000059,0x00050041,0x0000001a,0x0000005b,0x00000030,
+ 0x0000001d,0x0003003e,0x0000005b,0x0000005a,0x0004003d,0x00000007,0x0000005d,0x00000052,
+ 0x0003003e,0x0000005c,0x0000005d,0x0004003d,0x00000007,0x0000005f,0x00000030,0x0003003e,
+ 0x0000005e,0x0000005f,0x00060039,0x00000002,0x00000060,0x00000010,0x0000005c,0x0000005e,
+ 0x000100fd,0x00010038,0x00050036,0x00000002,0x0000000c,0x00000000,0x00000009,0x00030037,
+ 0x00000008,0x0000000a,0x00030037,0x00000008,0x0000000b,0x000200f8,0x0000000d,0x0004003b,
+ 0x0000001a,0x00000071,0x00000007,0x0004003b,0x00000008,0x0000007f,0x00000007,0x0004003b,
+ 0x0000008a,0x0000008b,0x00000007,0x0004003b,0x0000008a,0x0000008f,0x00000007,0x0004003b,
+ 0x0000001a,0x00000093,0x00000007,0x0004003b,0x0000008a,0x0000009c,0x00000007,0x0004003b,
+ 0x0000008a,0x000000a6,0x00000007,0x0004003b,0x0000008a,0x000000b3,0x00000007,0x0004003b,
+ 0x0000008a,0x000000bb,0x00000007,0x0004003b,0x0000008a,0x000000ca,0x00000007,0x0004003b,
+ 0x0000008a,0x000000d4,0x00000007,0x0004003b,0x0000008a,0x000000df,0x00000007,0x0004003b,
+ 0x0000008a,0x000000e7,0x00000007,0x0004003b,0x0000001a,0x000000f8,0x00000007,0x0004003b,
+ 0x0000001a,0x00000112,0x00000007,0x0004003b,0x0000001a,0x0000012b,0x00000007,0x0004003b,
+ 0x0000008a,0x00000144,0x00000007,0x0004003b,0x0000008a,0x00000157,0x00000007,0x0004003b,
+ 0x0000008a,0x00000164,0x00000007,0x0004003b,0x0000001a,0x0000018b,0x00000007,0x00050041,
+ 0x0000001a,0x00000061,0x0000000a,0x0000001d,0x0004003d,0x00000006,0x00000062,0x00000061,
+ 0x00050041,0x0000002a,0x00000064,0x00000027,0x00000063,0x0004003d,0x00000006,0x00000065,
+ 0x00000064,0x00050082,0x00000006,0x00000066,0x00000065,0x0000001d,0x0008000c,0x00000006,
+ 0x00000067,0x00000001,0x0000002c,0x00000062,0x00000019,0x00000066,0x00050041,0x0000001a,
+ 0x00000068,0x0000000a,0x0000001d,0x0003003e,0x00000068,0x00000067,0x00050041,0x0000001a,
+ 0x00000069,0x0000000b,0x0000001d,0x0004003d,0x00000006,0x0000006a,0x00000069,0x00050041,
+ 0x0000002a,0x0000006c,0x00000027,0x0000006b,0x0004003d,0x00000006,0x0000006d,0x0000006c,
+ 0x00050082,0x00000006,0x0000006e,0x0000006d,0x0000001d,0x0008000c,0x00000006,0x0000006f,
+ 0x00000001,0x0000002c,0x0000006a,0x00000019,0x0000006e,0x00050041,0x0000001a,0x00000070,
+ 0x0000000b,0x0000001d,0x0003003e,0x00000070,0x0000006f,0x00050041,0x0000001a,0x00000072,
+ 0x0000000a,0x0000001d,0x0004003d,0x00000006,0x00000073,0x00000072,0x00050041,0x0000002a,
+ 0x00000075,0x00000027,0x00000074,0x0004003d,0x00000006,0x00000076,0x00000075,0x00050084,
+ 0x00000006,0x00000077,0x00000073,0x00000076,0x00050041,0x0000002a,0x00000079,0x00000027,
+ 0x00000078,0x0004003d,0x00000006,0x0000007a,0x00000079,0x00050080,0x00000006,0x0000007b,
+ 0x00000077,0x0000007a,0x00050041,0x0000001a,0x0000007c,0x0000000a,0x00000019,0x0004003d,
+ 0x00000006,0x0000007d,0x0000007c,0x00050080,0x00000006,0x0000007e,0x0000007b,0x0000007d,
+ 0x0003003e,0x00000071,0x0000007e,0x0004003d,0x00000006,0x00000084,0x00000071,0x00060041,
+ 0x00000085,0x00000086,0x00000083,0x00000074,0x00000084,0x0004003d,0x00000007,0x00000087,
+ 0x00000086,0x0003003e,0x0000007f,0x00000087,0x00050041,0x0000001a,0x0000008c,0x0000007f,
+ 0x00000019,0x0004003d,0x00000006,0x0000008d,0x0000008c,0x0006000c,0x00000089,0x0000008e,
+ 0x00000001,0x00000040,0x0000008d,0x0003003e,0x0000008b,0x0000008e,0x00050041,0x0000001a,
+ 0x00000090,0x0000007f,0x0000001d,0x0004003d,0x00000006,0x00000091,0x00000090,0x0006000c,
+ 0x00000089,0x00000092,0x00000001,0x00000040,0x00000091,0x0003003e,0x0000008f,0x00000092,
+ 0x00050041,0x0000001a,0x00000094,0x0000000b,0x0000001d,0x0004003d,0x00000006,0x00000095,
+ 0x00000094,0x00050041,0x0000002a,0x00000096,0x00000027,0x0000003a,0x0004003d,0x00000006,
+ 0x00000097,0x00000096,0x00050084,0x00000006,0x00000098,0x00000095,0x00000097,0x00050041,
+ 0x0000001a,0x00000099,0x0000000b,0x00000019,0x0004003d,0x00000006,0x0000009a,0x00000099,
+ 0x00050080,0x00000006,0x0000009b,0x00000098,0x0000009a,0x0003003e,0x00000093,0x0000009b,
+ 0x0004003d,0x00000006,0x000000a1,0x00000093,0x00060041,0x000000a2,0x000000a3,0x000000a0,
+ 0x00000074,0x000000a1,0x0004003d,0x00000006,0x000000a4,0x000000a3,0x0006000c,0x00000089,
+ 0x000000a5,0x00000001,0x00000040,0x000000a4,0x0003003e,0x0000009c,0x000000a5,0x0004003d,
+ 0x00000006,0x000000a7,0x00000093,0x00050080,0x00000006,0x000000a8,0x000000a7,0x0000001d,
+ 0x00060041,0x000000a2,0x000000a9,0x000000a0,0x00000074,0x000000a8,0x0004003d,0x00000006,
+ 0x000000aa,0x000000a9,0x0006000c,0x00000089,0x000000ab,0x00000001,0x00000040,0x000000aa,
+ 0x0003003e,0x000000a6,0x000000ab,0x00050041,0x0000001a,0x000000ac,0x0000000b,0x00000019,
+ 0x0004003d,0x00000006,0x000000ad,0x000000ac,0x00050041,0x0000002a,0x000000ae,0x00000027,
+ 0x0000003a,0x0004003d,0x00000006,0x000000af,0x000000ae,0x00050082,0x00000006,0x000000b0,
+ 0x000000af,0x0000001d,0x000500aa,0x000000b1,0x000000b2,0x000000ad,0x000000b0,0x000300f7,
+ 0x000000b5,0x00000000,0x000400fa,0x000000b2,0x000000b4,0x000000b8,0x000200f8,0x000000b4,
+ 0x0004003d,0x00000089,0x000000b6,0x0000009c,0x0009004f,0x00000089,0x000000b7,0x000000b6,
+ 0x000000b6,0x00000003,0x00000003,0x00000003,0x00000003,0x0003003e,0x000000b3,0x000000b7,
+ 0x000200f9,0x000000b5,0x000200f8,0x000000b8,0x0004003d,0x00000089,0x000000b9,0x000000a6,
+ 0x0003003e,0x000000b3,0x000000b9,0x000200f9,0x000000b5,0x000200f8,0x000000b5,0x0004003d,
+ 0x00000089,0x000000ba,0x000000b3,0x0003003e,0x000000a6,0x000000ba,0x0004003d,0x00000089,
+ 0x000000bc,0x0000009c,0x0004003d,0x00000089,0x000000be,0x0000009c,0x0008004f,0x000000bd,
+ 0x000000bf,0x000000be,0x000000be,0x00000001,0x00000002,0x00000003,0x00050041,0x000000c0,
+ 0x000000c1,0x000000a6,0x00000019,0x0004003d,0x00000088,0x000000c2,0x000000c1,0x00050051,
+ 0x00000088,0x000000c3,0x000000bf,0x00000000,0x00050051,0x00000088,0x000000c4,0x000000bf,
+ 0x00000001,0x00050051,0x00000088,0x000000c5,0x000000bf,0x00000002,0x00070050,0x00000089,
+ 0x000000c6,0x000000c3,0x000000c4,0x000000c5,0x000000c2,0x00050081,0x00000089,0x000000c7,
+ 0x000000bc,0x000000c6,0x0005008e,0x00000089,0x000000c9,0x000000c7,0x000000c8,0x0003003e,
+ 0x000000bb,0x000000c9,0x00050041,0x000000c0,0x000000cb,0x0000009c,0x00000019,0x0004003d,
+ 0x00000088,0x000000cc,0x000000cb,0x00050041,0x000000c0,0x000000cd,0x000000bb,0x00000019,
+ 0x0004003d,0x00000088,0x000000ce,0x000000cd,0x00050041,0x000000c0,0x000000cf,0x0000009c,
+ 0x0000001d,0x0004003d,0x00000088,0x000000d0,0x000000cf,0x00050041,0x000000c0,0x000000d1,
+ 0x000000bb,0x0000001d,0x0004003d,0x00000088,0x000000d2,0x000000d1,0x00070050,0x00000089,
+ 0x000000d3,0x000000cc,0x000000ce,0x000000d0,0x000000d2,0x0003003e,0x000000ca,0x000000d3,
+ 0x00050041,0x000000c0,0x000000d5,0x0000009c,0x00000035,0x0004003d,0x00000088,0x000000d6,
+ 0x000000d5,0x00050041,0x000000c0,0x000000d7,0x000000bb,0x00000035,0x0004003d,0x00000088,
+ 0x000000d8,0x000000d7,0x00050041,0x000000c0,0x000000da,0x0000009c,0x000000d9,0x0004003d,
+ 0x00000088,0x000000db,0x000000da,0x00050041,0x000000c0,0x000000dc,0x000000bb,0x000000d9,
+ 0x0004003d,0x00000088,0x000000dd,0x000000dc,0x00070050,0x00000089,0x000000de,0x000000d6,
+ 0x000000d8,0x000000db,0x000000dd,0x0003003e,0x000000d4,0x000000de,0x0004003d,0x00000089,
+ 0x000000e0,0x0000008b,0x0004003d,0x00000089,0x000000e1,0x000000ca,0x00050083,0x00000089,
+ 0x000000e2,0x000000e0,0x000000e1,0x0005008e,0x00000089,0x000000e3,0x000000e2,0x000000c8,
+ 0x00070050,0x00000089,0x000000e5,0x000000e4,0x000000e4,0x000000e4,0x000000e4,0x00050081,
+ 0x00000089,0x000000e6,0x000000e3,0x000000e5,0x0003003e,0x000000df,0x000000e6,0x0004003d,
+ 0x00000089,0x000000e8,0x0000008f,0x0004003d,0x00000089,0x000000e9,0x000000d4,0x00050083,
+ 0x00000089,0x000000ea,0x000000e8,0x000000e9,0x0005008e,0x00000089,0x000000eb,0x000000ea,
+ 0x000000c8,0x00070050,0x00000089,0x000000ec,0x000000e4,0x000000e4,0x000000e4,0x000000e4,
+ 0x00050081,0x00000089,0x000000ed,0x000000eb,0x000000ec,0x0003003e,0x000000e7,0x000000ed,
+ 0x0004003d,0x00000089,0x000000ee,0x000000df,0x00070050,0x00000089,0x000000f1,0x000000ef,
+ 0x000000ef,0x000000ef,0x000000ef,0x00070050,0x00000089,0x000000f2,0x000000f0,0x000000f0,
+ 0x000000f0,0x000000f0,0x0008000c,0x00000089,0x000000f3,0x00000001,0x0000002b,0x000000ee,
+ 0x000000f1,0x000000f2,0x0003003e,0x000000df,0x000000f3,0x0004003d,0x00000089,0x000000f4,
+ 0x000000e7,0x00070050,0x00000089,0x000000f5,0x000000ef,0x000000ef,0x000000ef,0x000000ef,
+ 0x00070050,0x00000089,0x000000f6,0x000000f0,0x000000f0,0x000000f0,0x000000f0,0x0008000c,
+ 0x00000089,0x000000f7,0x00000001,0x0000002b,0x000000f4,0x000000f5,0x000000f6,0x0003003e,
+ 0x000000e7,0x000000f7,0x00050041,0x0000001a,0x000000f9,0x0000000a,0x0000001d,0x0004003d,
+ 0x00000006,0x000000fa,0x000000f9,0x00050041,0x0000002a,0x000000fb,0x00000027,0x00000029,
+ 0x0004003d,0x00000006,0x000000fc,0x000000fb,0x00050084,0x00000006,0x000000fd,0x000000fa,
+ 0x000000fc,0x00050041,0x0000001a,0x000000fe,0x0000000a,0x00000019,0x0004003d,0x00000006,
+ 0x000000ff,0x000000fe,0x00050080,0x00000006,0x00000100,0x000000fd,0x000000ff,0x0003003e,
+ 0x000000f8,0x00000100,0x0004003d,0x00000006,0x00000105,0x000000f8,0x0004003d,0x00000089,
+ 0x00000106,0x000000df,0x0006000c,0x00000006,0x00000107,0x00000001,0x00000037,0x00000106,
+ 0x0004003d,0x00000089,0x00000108,0x000000e7,0x0006000c,0x00000006,0x00000109,0x00000001,
+ 0x00000037,0x00000108,0x00050050,0x00000007,0x0000010a,0x00000107,0x00000109,0x00060041,
+ 0x00000085,0x0000010b,0x00000104,0x00000074,0x00000105,0x0003003e,0x0000010b,0x0000010a,
+ 0x00050041,0x0000001a,0x0000010c,0x0000000a,0x0000001d,0x0004003d,0x00000006,0x0000010d,
+ 0x0000010c,0x00050041,0x0000002a,0x0000010e,0x00000027,0x00000063,0x0004003d,0x00000006,
+ 0x0000010f,0x0000010e,0x00050082,0x00000006,0x00000110,0x0000010f,0x0000001d,0x000500ae,
+ 0x000000b1,0x00000111,0x0000010d,0x00000110,0x000300f7,0x00000114,0x00000000,0x000400fa,
+ 0x00000111,0x00000113,0x00000116,0x000200f8,0x00000113,0x0004003d,0x00000006,0x00000115,
+ 0x00000071,0x0003003e,0x00000112,0x00000115,0x000200f9,0x00000114,0x000200f8,0x00000116,
+ 0x0004003d,0x00000006,0x00000117,0x00000071,0x00050041,0x0000002a,0x00000118,0x00000027,
+ 0x00000074,0x0004003d,0x00000006,0x00000119,0x00000118,0x00050080,0x00000006,0x0000011a,
+ 0x00000117,0x00000119,0x0003003e,0x00000112,0x0000011a,0x000200f9,0x00000114,0x000200f8,
+ 0x00000114,0x0004003d,0x00000006,0x0000011b,0x00000112,0x0003003e,0x00000071,0x0000011b,
+ 0x0004003d,0x00000006,0x0000011c,0x00000071,0x00060041,0x00000085,0x0000011d,0x00000083,
+ 0x00000074,0x0000011c,0x0004003d,0x00000007,0x0000011e,0x0000011d,0x0003003e,0x0000007f,
+ 0x0000011e,0x00050041,0x0000001a,0x0000011f,0x0000007f,0x00000019,0x0004003d,0x00000006,
+ 0x00000120,0x0000011f,0x0006000c,0x00000089,0x00000121,0x00000001,0x00000040,0x00000120,
+ 0x0003003e,0x0000008b,0x00000121,0x00050041,0x0000001a,0x00000122,0x0000007f,0x0000001d,
+ 0x0004003d,0x00000006,0x00000123,0x00000122,0x0006000c,0x00000089,0x00000124,0x00000001,
+ 0x00000040,0x00000123,0x0003003e,0x0000008f,0x00000124,0x00050041,0x0000001a,0x00000125,
+ 0x0000000b,0x0000001d,0x0004003d,0x00000006,0x00000126,0x00000125,0x00050041,0x0000002a,
+ 0x00000127,0x00000027,0x0000006b,0x0004003d,0x00000006,0x00000128,0x00000127,0x00050082,
+ 0x00000006,0x00000129,0x00000128,0x0000001d,0x000500ae,0x000000b1,0x0000012a,0x00000126,
+ 0x00000129,0x000300f7,0x0000012d,0x00000000,0x000400fa,0x0000012a,0x0000012c,0x0000012f,
+ 0x000200f8,0x0000012c,0x0004003d,0x00000006,0x0000012e,0x00000093,0x0003003e,0x0000012b,
+ 0x0000012e,0x000200f9,0x0000012d,0x000200f8,0x0000012f,0x0004003d,0x00000006,0x00000130,
+ 0x00000093,0x00050041,0x0000002a,0x00000131,0x00000027,0x0000003a,0x0004003d,0x00000006,
+ 0x00000132,0x00000131,0x00050080,0x00000006,0x00000133,0x00000130,0x00000132,0x0003003e,
+ 0x0000012b,0x00000133,0x000200f9,0x0000012d,0x000200f8,0x0000012d,0x0004003d,0x00000006,
+ 0x00000134,0x0000012b,0x0003003e,0x00000093,0x00000134,0x0004003d,0x00000006,0x00000135,
+ 0x00000093,0x00060041,0x000000a2,0x00000136,0x000000a0,0x00000074,0x00000135,0x0004003d,
+ 0x00000006,0x00000137,0x00000136,0x0006000c,0x00000089,0x00000138,0x00000001,0x00000040,
+ 0x00000137,0x0003003e,0x0000009c,0x00000138,0x0004003d,0x00000006,0x00000139,0x00000093,
+ 0x00050080,0x00000006,0x0000013a,0x00000139,0x0000001d,0x00060041,0x000000a2,0x0000013b,
+ 0x000000a0,0x00000074,0x0000013a,0x0004003d,0x00000006,0x0000013c,0x0000013b,0x0006000c,
+ 0x00000089,0x0000013d,0x00000001,0x00000040,0x0000013c,0x0003003e,0x000000a6,0x0000013d,
+ 0x00050041,0x0000001a,0x0000013e,0x0000000b,0x00000019,0x0004003d,0x00000006,0x0000013f,
+ 0x0000013e,0x00050041,0x0000002a,0x00000140,0x00000027,0x0000003a,0x0004003d,0x00000006,
+ 0x00000141,0x00000140,0x00050082,0x00000006,0x00000142,0x00000141,0x0000001d,0x000500aa,
+ 0x000000b1,0x00000143,0x0000013f,0x00000142,0x000300f7,0x00000146,0x00000000,0x000400fa,
+ 0x00000143,0x00000145,0x00000149,0x000200f8,0x00000145,0x0004003d,0x00000089,0x00000147,
+ 0x0000009c,0x0009004f,0x00000089,0x00000148,0x00000147,0x00000147,0x00000003,0x00000003,
+ 0x00000003,0x00000003,0x0003003e,0x00000144,0x00000148,0x000200f9,0x00000146,0x000200f8,
+ 0x00000149,0x0004003d,0x00000089,0x0000014a,0x000000a6,0x0003003e,0x00000144,0x0000014a,
+ 0x000200f9,0x00000146,0x000200f8,0x00000146,0x0004003d,0x00000089,0x0000014b,0x00000144,
+ 0x0003003e,0x000000a6,0x0000014b,0x0004003d,0x00000089,0x0000014c,0x0000009c,0x0004003d,
+ 0x00000089,0x0000014d,0x0000009c,0x0008004f,0x000000bd,0x0000014e,0x0000014d,0x0000014d,
+ 0x00000001,0x00000002,0x00000003,0x00050041,0x000000c0,0x0000014f,0x000000a6,0x00000019,
+ 0x0004003d,0x00000088,0x00000150,0x0000014f,0x00050051,0x00000088,0x00000151,0x0000014e,
+ 0x00000000,0x00050051,0x00000088,0x00000152,0x0000014e,0x00000001,0x00050051,0x00000088,
+ 0x00000153,0x0000014e,0x00000002,0x00070050,0x00000089,0x00000154,0x00000151,0x00000152,
+ 0x00000153,0x00000150,0x00050081,0x00000089,0x00000155,0x0000014c,0x00000154,0x0005008e,
+ 0x00000089,0x00000156,0x00000155,0x000000c8,0x0003003e,0x000000bb,0x00000156,0x0004003d,
+ 0x00000089,0x00000158,0x000000ca,0x00050041,0x000000c0,0x00000159,0x0000009c,0x00000019,
+ 0x0004003d,0x00000088,0x0000015a,0x00000159,0x00050041,0x000000c0,0x0000015b,0x000000bb,
+ 0x00000019,0x0004003d,0x00000088,0x0000015c,0x0000015b,0x00050041,0x000000c0,0x0000015d,
+ 0x0000009c,0x0000001d,0x0004003d,0x00000088,0x0000015e,0x0000015d,0x00050041,0x000000c0,
+ 0x0000015f,0x000000bb,0x0000001d,0x0004003d,0x00000088,0x00000160,0x0000015f,0x00070050,
+ 0x00000089,0x00000161,0x0000015a,0x0000015c,0x0000015e,0x00000160,0x00050081,0x00000089,
+ 0x00000162,0x00000158,0x00000161,0x0005008e,0x00000089,0x00000163,0x00000162,0x000000c8,
+ 0x0003003e,0x00000157,0x00000163,0x0004003d,0x00000089,0x00000165,0x000000d4,0x00050041,
+ 0x000000c0,0x00000166,0x0000009c,0x00000035,0x0004003d,0x00000088,0x00000167,0x00000166,
+ 0x00050041,0x000000c0,0x00000168,0x000000bb,0x00000035,0x0004003d,0x00000088,0x00000169,
+ 0x00000168,0x00050041,0x000000c0,0x0000016a,0x0000009c,0x000000d9,0x0004003d,0x00000088,
+ 0x0000016b,0x0000016a,0x00050041,0x000000c0,0x0000016c,0x000000bb,0x000000d9,0x0004003d,
+ 0x00000088,0x0000016d,0x0000016c,0x00070050,0x00000089,0x0000016e,0x00000167,0x00000169,
+ 0x0000016b,0x0000016d,0x00050081,0x00000089,0x0000016f,0x00000165,0x0000016e,0x0005008e,
+ 0x00000089,0x00000170,0x0000016f,0x000000c8,0x0003003e,0x00000164,0x00000170,0x0004003d,
+ 0x00000089,0x00000171,0x0000008b,0x0004003d,0x00000089,0x00000172,0x00000157,0x00050083,
+ 0x00000089,0x00000173,0x00000171,0x00000172,0x0005008e,0x00000089,0x00000174,0x00000173,
+ 0x000000c8,0x00070050,0x00000089,0x00000175,0x000000e4,0x000000e4,0x000000e4,0x000000e4,
+ 0x00050081,0x00000089,0x00000176,0x00000174,0x00000175,0x0003003e,0x000000df,0x00000176,
+ 0x0004003d,0x00000089,0x00000177,0x0000008f,0x0004003d,0x00000089,0x00000178,0x00000164,
+ 0x00050083,0x00000089,0x00000179,0x00000177,0x00000178,0x0005008e,0x00000089,0x0000017a,
+ 0x00000179,0x000000c8,0x00070050,0x00000089,0x0000017b,0x000000e4,0x000000e4,0x000000e4,
+ 0x000000e4,0x00050081,0x00000089,0x0000017c,0x0000017a,0x0000017b,0x0003003e,0x000000e7,
+ 0x0000017c,0x0004003d,0x00000089,0x0000017d,0x000000df,0x00070050,0x00000089,0x0000017e,
+ 0x000000ef,0x000000ef,0x000000ef,0x000000ef,0x00070050,0x00000089,0x0000017f,0x000000f0,
+ 0x000000f0,0x000000f0,0x000000f0,0x0008000c,0x00000089,0x00000180,0x00000001,0x0000002b,
+ 0x0000017d,0x0000017e,0x0000017f,0x0003003e,0x000000df,0x00000180,0x0004003d,0x00000089,
+ 0x00000181,0x000000e7,0x00070050,0x00000089,0x00000182,0x000000ef,0x000000ef,0x000000ef,
+ 0x000000ef,0x00070050,0x00000089,0x00000183,0x000000f0,0x000000f0,0x000000f0,0x000000f0,
+ 0x0008000c,0x00000089,0x00000184,0x00000001,0x0000002b,0x00000181,0x00000182,0x00000183,
+ 0x0003003e,0x000000e7,0x00000184,0x00050041,0x0000001a,0x00000185,0x0000000a,0x0000001d,
+ 0x0004003d,0x00000006,0x00000186,0x00000185,0x00050041,0x0000002a,0x00000187,0x00000027,
+ 0x00000063,0x0004003d,0x00000006,0x00000188,0x00000187,0x00050082,0x00000006,0x00000189,
+ 0x00000188,0x0000001d,0x000500ae,0x000000b1,0x0000018a,0x00000186,0x00000189,0x000300f7,
+ 0x0000018d,0x00000000,0x000400fa,0x0000018a,0x0000018c,0x0000018f,0x000200f8,0x0000018c,
+ 0x0004003d,0x00000006,0x0000018e,0x000000f8,0x0003003e,0x0000018b,0x0000018e,0x000200f9,
+ 0x0000018d,0x000200f8,0x0000018f,0x0004003d,0x00000006,0x00000190,0x000000f8,0x00050041,
+ 0x0000002a,0x00000191,0x00000027,0x00000029,0x0004003d,0x00000006,0x00000192,0x00000191,
+ 0x00050080,0x00000006,0x00000193,0x00000190,0x00000192,0x0003003e,0x0000018b,0x00000193,
+ 0x000200f9,0x0000018d,0x000200f8,0x0000018d,0x0004003d,0x00000006,0x00000194,0x0000018b,
+ 0x0003003e,0x000000f8,0x00000194,0x0004003d,0x00000006,0x00000195,0x000000f8,0x0004003d,
+ 0x00000089,0x00000196,0x000000df,0x0006000c,0x00000006,0x00000197,0x00000001,0x00000037,
+ 0x00000196,0x0004003d,0x00000089,0x00000198,0x000000e7,0x0006000c,0x00000006,0x00000199,
+ 0x00000001,0x00000037,0x00000198,0x00050050,0x00000007,0x0000019a,0x00000197,0x00000199,
+ 0x00060041,0x00000085,0x0000019b,0x00000104,0x00000074,0x00000195,0x0003003e,0x0000019b,
+ 0x0000019a,0x000100fd,0x00010038,0x00050036,0x00000002,0x00000010,0x00000000,0x00000009,
+ 0x00030037,0x00000008,0x0000000e,0x00030037,0x00000008,0x0000000f,0x000200f8,0x00000011,
+ 0x0004003b,0x0000001a,0x000001ac,0x00000007,0x0004003b,0x00000008,0x000001b8,0x00000007,
+ 0x0004003b,0x0000008a,0x000001c0,0x00000007,0x0004003b,0x0000008a,0x000001c4,0x00000007,
+ 0x0004003b,0x0000001a,0x000001c8,0x00000007,0x0004003b,0x0000008a,0x000001d1,0x00000007,
+ 0x0004003b,0x0000008a,0x000001da,0x00000007,0x0004003b,0x0000008a,0x000001e6,0x00000007,
+ 0x0004003b,0x0000008a,0x000001ee,0x00000007,0x0004003b,0x0000008a,0x000001fc,0x00000007,
+ 0x0004003b,0x0000008a,0x00000206,0x00000007,0x0004003b,0x0000008a,0x00000210,0x00000007,
+ 0x0004003b,0x0000008a,0x00000217,0x00000007,0x0004003b,0x0000001a,0x00000226,0x00000007,
+ 0x0004003b,0x0000001a,0x00000241,0x00000007,0x0004003b,0x0000001a,0x0000025b,0x00000007,
+ 0x0004003b,0x0000008a,0x00000274,0x00000007,0x0004003b,0x0000008a,0x00000288,0x00000007,
+ 0x0004003b,0x0000008a,0x00000295,0x00000007,0x00050041,0x0000001a,0x0000019c,0x0000000e,
+ 0x0000001d,0x0004003d,0x00000006,0x0000019d,0x0000019c,0x00050041,0x0000002a,0x0000019e,
+ 0x00000027,0x00000063,0x0004003d,0x00000006,0x0000019f,0x0000019e,0x00050086,0x00000006,
+ 0x000001a0,0x0000019f,0x00000035,0x00050082,0x00000006,0x000001a1,0x000001a0,0x0000001d,
+ 0x0008000c,0x00000006,0x000001a2,0x00000001,0x0000002c,0x0000019d,0x00000019,0x000001a1,
+ 0x00050041,0x0000001a,0x000001a3,0x0000000e,0x0000001d,0x0003003e,0x000001a3,0x000001a2,
+ 0x00050041,0x0000001a,0x000001a4,0x0000000f,0x0000001d,0x0004003d,0x00000006,0x000001a5,
+ 0x000001a4,0x00050041,0x0000002a,0x000001a6,0x00000027,0x0000006b,0x0004003d,0x00000006,
+ 0x000001a7,0x000001a6,0x00050086,0x00000006,0x000001a8,0x000001a7,0x00000035,0x00050082,
+ 0x00000006,0x000001a9,0x000001a8,0x0000001d,0x0008000c,0x00000006,0x000001aa,0x00000001,
+ 0x0000002c,0x000001a5,0x00000019,0x000001a9,0x00050041,0x0000001a,0x000001ab,0x0000000f,
+ 0x0000001d,0x0003003e,0x000001ab,0x000001aa,0x00050041,0x0000001a,0x000001ad,0x0000000e,
+ 0x0000001d,0x0004003d,0x00000006,0x000001ae,0x000001ad,0x00050041,0x0000002a,0x000001af,
+ 0x00000027,0x00000074,0x0004003d,0x00000006,0x000001b0,0x000001af,0x00050084,0x00000006,
+ 0x000001b1,0x000001ae,0x000001b0,0x00050041,0x0000002a,0x000001b2,0x00000027,0x00000078,
+ 0x0004003d,0x00000006,0x000001b3,0x000001b2,0x00050080,0x00000006,0x000001b4,0x000001b1,
+ 0x000001b3,0x00050041,0x0000001a,0x000001b5,0x0000000e,0x00000019,0x0004003d,0x00000006,
+ 0x000001b6,0x000001b5,0x00050080,0x00000006,0x000001b7,0x000001b4,0x000001b6,0x0003003e,
+ 0x000001ac,0x000001b7,0x0004003d,0x00000006,0x000001bd,0x000001ac,0x00060041,0x00000085,
+ 0x000001be,0x000001bc,0x00000074,0x000001bd,0x0004003d,0x00000007,0x000001bf,0x000001be,
+ 0x0003003e,0x000001b8,0x000001bf,0x00050041,0x0000001a,0x000001c1,0x000001b8,0x00000019,
+ 0x0004003d,0x00000006,0x000001c2,0x000001c1,0x0006000c,0x00000089,0x000001c3,0x00000001,
+ 0x00000040,0x000001c2,0x0003003e,0x000001c0,0x000001c3,0x00050041,0x0000001a,0x000001c5,
+ 0x000001b8,0x0000001d,0x0004003d,0x00000006,0x000001c6,0x000001c5,0x0006000c,0x00000089,
+ 0x000001c7,0x00000001,0x00000040,0x000001c6,0x0003003e,0x000001c4,0x000001c7,0x00050041,
+ 0x0000001a,0x000001c9,0x0000000f,0x0000001d,0x0004003d,0x00000006,0x000001ca,0x000001c9,
+ 0x00050041,0x0000002a,0x000001cb,0x00000027,0x0000003a,0x0004003d,0x00000006,0x000001cc,
+ 0x000001cb,0x00050084,0x00000006,0x000001cd,0x000001ca,0x000001cc,0x00050041,0x0000001a,
+ 0x000001ce,0x0000000f,0x00000019,0x0004003d,0x00000006,0x000001cf,0x000001ce,0x00050080,
+ 0x00000006,0x000001d0,0x000001cd,0x000001cf,0x0003003e,0x000001c8,0x000001d0,0x0004003d,
+ 0x00000006,0x000001d6,0x000001c8,0x00060041,0x000000a2,0x000001d7,0x000001d5,0x00000074,
+ 0x000001d6,0x0004003d,0x00000006,0x000001d8,0x000001d7,0x0006000c,0x00000089,0x000001d9,
+ 0x00000001,0x00000040,0x000001d8,0x0003003e,0x000001d1,0x000001d9,0x0004003d,0x00000006,
+ 0x000001db,0x000001c8,0x00050080,0x00000006,0x000001dc,0x000001db,0x0000001d,0x00060041,
+ 0x000000a2,0x000001dd,0x000001d5,0x00000074,0x000001dc,0x0004003d,0x00000006,0x000001de,
+ 0x000001dd,0x0006000c,0x00000089,0x000001df,0x00000001,0x00000040,0x000001de,0x0003003e,
+ 0x000001da,0x000001df,0x00050041,0x0000001a,0x000001e0,0x0000000f,0x00000019,0x0004003d,
+ 0x00000006,0x000001e1,0x000001e0,0x00050041,0x0000002a,0x000001e2,0x00000027,0x0000003a,
+ 0x0004003d,0x00000006,0x000001e3,0x000001e2,0x00050082,0x00000006,0x000001e4,0x000001e3,
+ 0x0000001d,0x000500aa,0x000000b1,0x000001e5,0x000001e1,0x000001e4,0x000300f7,0x000001e8,
+ 0x00000000,0x000400fa,0x000001e5,0x000001e7,0x000001eb,0x000200f8,0x000001e7,0x0004003d,
+ 0x00000089,0x000001e9,0x000001d1,0x0009004f,0x00000089,0x000001ea,0x000001e9,0x000001e9,
+ 0x00000002,0x00000003,0x00000002,0x00000003,0x0003003e,0x000001e6,0x000001ea,0x000200f9,
+ 0x000001e8,0x000200f8,0x000001eb,0x0004003d,0x00000089,0x000001ec,0x000001da,0x0003003e,
+ 0x000001e6,0x000001ec,0x000200f9,0x000001e8,0x000200f8,0x000001e8,0x0004003d,0x00000089,
+ 0x000001ed,0x000001e6,0x0003003e,0x000001da,0x000001ed,0x0004003d,0x00000089,0x000001ef,
+ 0x000001d1,0x0004003d,0x00000089,0x000001f1,0x000001d1,0x0007004f,0x000001f0,0x000001f2,
+ 0x000001f1,0x000001f1,0x00000002,0x00000003,0x0004003d,0x00000089,0x000001f3,0x000001da,
+ 0x0007004f,0x000001f0,0x000001f4,0x000001f3,0x000001f3,0x00000000,0x00000001,0x00050051,
+ 0x00000088,0x000001f5,0x000001f2,0x00000000,0x00050051,0x00000088,0x000001f6,0x000001f2,
+ 0x00000001,0x00050051,0x00000088,0x000001f7,0x000001f4,0x00000000,0x00050051,0x00000088,
+ 0x000001f8,0x000001f4,0x00000001,0x00070050,0x00000089,0x000001f9,0x000001f5,0x000001f6,
+ 0x000001f7,0x000001f8,0x00050081,0x00000089,0x000001fa,0x000001ef,0x000001f9,0x0005008e,
+ 0x00000089,0x000001fb,0x000001fa,0x000000c8,0x0003003e,0x000001ee,0x000001fb,0x0004003d,
+ 0x00000089,0x000001fd,0x000001d1,0x0007004f,0x000001f0,0x000001fe,0x000001fd,0x000001fd,
+ 0x00000000,0x00000001,0x0004003d,0x00000089,0x000001ff,0x000001ee,0x0007004f,0x000001f0,
+ 0x00000200,0x000001ff,0x000001ff,0x00000000,0x00000001,0x00050051,0x00000088,0x00000201,
+ 0x000001fe,0x00000000,0x00050051,0x00000088,0x00000202,0x000001fe,0x00000001,0x00050051,
+ 0x00000088,0x00000203,0x00000200,0x00000000,0x00050051,0x00000088,0x00000204,0x00000200,
+ 0x00000001,0x00070050,0x00000089,0x00000205,0x00000201,0x00000202,0x00000203,0x00000204,
+ 0x0003003e,0x000001fc,0x00000205,0x0004003d,0x00000089,0x00000207,0x000001d1,0x0007004f,
+ 0x000001f0,0x00000208,0x00000207,0x00000207,0x00000002,0x00000003,0x0004003d,0x00000089,
+ 0x00000209,0x000001ee,0x0007004f,0x000001f0,0x0000020a,0x00000209,0x00000209,0x00000002,
+ 0x00000003,0x00050051,0x00000088,0x0000020b,0x00000208,0x00000000,0x00050051,0x00000088,
+ 0x0000020c,0x00000208,0x00000001,0x00050051,0x00000088,0x0000020d,0x0000020a,0x00000000,
+ 0x00050051,0x00000088,0x0000020e,0x0000020a,0x00000001,0x00070050,0x00000089,0x0000020f,
+ 0x0000020b,0x0000020c,0x0000020d,0x0000020e,0x0003003e,0x00000206,0x0000020f,0x0004003d,
+ 0x00000089,0x00000211,0x000001c0,0x0004003d,0x00000089,0x00000212,0x000001fc,0x00050083,
+ 0x00000089,0x00000213,0x00000211,0x00000212,0x0005008e,0x00000089,0x00000214,0x00000213,
+ 0x000000c8,0x00070050,0x00000089,0x00000215,0x000000e4,0x000000e4,0x000000e4,0x000000e4,
+ 0x00050081,0x00000089,0x00000216,0x00000214,0x00000215,0x0003003e,0x00000210,0x00000216,
+ 0x0004003d,0x00000089,0x00000218,0x000001c4,0x0004003d,0x00000089,0x00000219,0x00000206,
+ 0x00050083,0x00000089,0x0000021a,0x00000218,0x00000219,0x0005008e,0x00000089,0x0000021b,
+ 0x0000021a,0x000000c8,0x00070050,0x00000089,0x0000021c,0x000000e4,0x000000e4,0x000000e4,
+ 0x000000e4,0x00050081,0x00000089,0x0000021d,0x0000021b,0x0000021c,0x0003003e,0x00000217,
+ 0x0000021d,0x0004003d,0x00000089,0x0000021e,0x00000210,0x00070050,0x00000089,0x0000021f,
+ 0x000000ef,0x000000ef,0x000000ef,0x000000ef,0x00070050,0x00000089,0x00000220,0x000000f0,
+ 0x000000f0,0x000000f0,0x000000f0,0x0008000c,0x00000089,0x00000221,0x00000001,0x0000002b,
+ 0x0000021e,0x0000021f,0x00000220,0x0003003e,0x00000210,0x00000221,0x0004003d,0x00000089,
+ 0x00000222,0x00000217,0x00070050,0x00000089,0x00000223,0x000000ef,0x000000ef,0x000000ef,
+ 0x000000ef,0x00070050,0x00000089,0x00000224,0x000000f0,0x000000f0,0x000000f0,0x000000f0,
+ 0x0008000c,0x00000089,0x00000225,0x00000001,0x0000002b,0x00000222,0x00000223,0x00000224,
+ 0x0003003e,0x00000217,0x00000225,0x00050041,0x0000001a,0x00000227,0x0000000e,0x0000001d,
+ 0x0004003d,0x00000006,0x00000228,0x00000227,0x00050041,0x0000002a,0x00000229,0x00000027,
+ 0x00000029,0x0004003d,0x00000006,0x0000022a,0x00000229,0x00050084,0x00000006,0x0000022b,
+ 0x00000228,0x0000022a,0x00050041,0x0000001a,0x0000022c,0x0000000e,0x00000019,0x0004003d,
+ 0x00000006,0x0000022d,0x0000022c,0x00050080,0x00000006,0x0000022e,0x0000022b,0x0000022d,
+ 0x0003003e,0x00000226,0x0000022e,0x0004003d,0x00000006,0x00000233,0x00000226,0x0004003d,
+ 0x00000089,0x00000234,0x00000210,0x0006000c,0x00000006,0x00000235,0x00000001,0x00000037,
+ 0x00000234,0x0004003d,0x00000089,0x00000236,0x00000217,0x0006000c,0x00000006,0x00000237,
+ 0x00000001,0x00000037,0x00000236,0x00050050,0x00000007,0x00000238,0x00000235,0x00000237,
+ 0x00060041,0x00000085,0x00000239,0x00000232,0x00000074,0x00000233,0x0003003e,0x00000239,
+ 0x00000238,0x00050041,0x0000001a,0x0000023a,0x0000000e,0x0000001d,0x0004003d,0x00000006,
+ 0x0000023b,0x0000023a,0x00050041,0x0000002a,0x0000023c,0x00000027,0x00000063,0x0004003d,
+ 0x00000006,0x0000023d,0x0000023c,0x00050086,0x00000006,0x0000023e,0x0000023d,0x00000035,
+ 0x00050082,0x00000006,0x0000023f,0x0000023e,0x0000001d,0x000500ae,0x000000b1,0x00000240,
+ 0x0000023b,0x0000023f,0x000300f7,0x00000243,0x00000000,0x000400fa,0x00000240,0x00000242,
+ 0x00000245,0x000200f8,0x00000242,0x0004003d,0x00000006,0x00000244,0x000001ac,0x0003003e,
+ 0x00000241,0x00000244,0x000200f9,0x00000243,0x000200f8,0x00000245,0x0004003d,0x00000006,
+ 0x00000246,0x000001ac,0x00050041,0x0000002a,0x00000247,0x00000027,0x00000074,0x0004003d,
+ 0x00000006,0x00000248,0x00000247,0x00050080,0x00000006,0x00000249,0x00000246,0x00000248,
+ 0x0003003e,0x00000241,0x00000249,0x000200f9,0x00000243,0x000200f8,0x00000243,0x0004003d,
+ 0x00000006,0x0000024a,0x00000241,0x0003003e,0x000001ac,0x0000024a,0x0004003d,0x00000006,
+ 0x0000024b,0x000001ac,0x00060041,0x00000085,0x0000024c,0x000001bc,0x00000074,0x0000024b,
+ 0x0004003d,0x00000007,0x0000024d,0x0000024c,0x0003003e,0x000001b8,0x0000024d,0x00050041,
+ 0x0000001a,0x0000024e,0x000001b8,0x00000019,0x0004003d,0x00000006,0x0000024f,0x0000024e,
+ 0x0006000c,0x00000089,0x00000250,0x00000001,0x00000040,0x0000024f,0x0003003e,0x000001c0,
+ 0x00000250,0x00050041,0x0000001a,0x00000251,0x000001b8,0x0000001d,0x0004003d,0x00000006,
+ 0x00000252,0x00000251,0x0006000c,0x00000089,0x00000253,0x00000001,0x00000040,0x00000252,
+ 0x0003003e,0x000001c4,0x00000253,0x00050041,0x0000001a,0x00000254,0x0000000f,0x0000001d,
+ 0x0004003d,0x00000006,0x00000255,0x00000254,0x00050041,0x0000002a,0x00000256,0x00000027,
+ 0x0000006b,0x0004003d,0x00000006,0x00000257,0x00000256,0x00050086,0x00000006,0x00000258,
+ 0x00000257,0x00000035,0x00050082,0x00000006,0x00000259,0x00000258,0x0000001d,0x000500ae,
+ 0x000000b1,0x0000025a,0x00000255,0x00000259,0x000300f7,0x0000025d,0x00000000,0x000400fa,
+ 0x0000025a,0x0000025c,0x0000025f,0x000200f8,0x0000025c,0x0004003d,0x00000006,0x0000025e,
+ 0x000001c8,0x0003003e,0x0000025b,0x0000025e,0x000200f9,0x0000025d,0x000200f8,0x0000025f,
+ 0x0004003d,0x00000006,0x00000260,0x000001c8,0x00050041,0x0000002a,0x00000261,0x00000027,
+ 0x0000003a,0x0004003d,0x00000006,0x00000262,0x00000261,0x00050080,0x00000006,0x00000263,
+ 0x00000260,0x00000262,0x0003003e,0x0000025b,0x00000263,0x000200f9,0x0000025d,0x000200f8,
+ 0x0000025d,0x0004003d,0x00000006,0x00000264,0x0000025b,0x0003003e,0x000001c8,0x00000264,
+ 0x0004003d,0x00000006,0x00000265,0x000001c8,0x00060041,0x000000a2,0x00000266,0x000001d5,
+ 0x00000074,0x00000265,0x0004003d,0x00000006,0x00000267,0x00000266,0x0006000c,0x00000089,
+ 0x00000268,0x00000001,0x00000040,0x00000267,0x0003003e,0x000001d1,0x00000268,0x0004003d,
+ 0x00000006,0x00000269,0x000001c8,0x00050080,0x00000006,0x0000026a,0x00000269,0x0000001d,
+ 0x00060041,0x000000a2,0x0000026b,0x000001d5,0x00000074,0x0000026a,0x0004003d,0x00000006,
+ 0x0000026c,0x0000026b,0x0006000c,0x00000089,0x0000026d,0x00000001,0x00000040,0x0000026c,
+ 0x0003003e,0x000001da,0x0000026d,0x00050041,0x0000001a,0x0000026e,0x0000000f,0x00000019,
+ 0x0004003d,0x00000006,0x0000026f,0x0000026e,0x00050041,0x0000002a,0x00000270,0x00000027,
+ 0x0000003a,0x0004003d,0x00000006,0x00000271,0x00000270,0x00050082,0x00000006,0x00000272,
+ 0x00000271,0x0000001d,0x000500aa,0x000000b1,0x00000273,0x0000026f,0x00000272,0x000300f7,
+ 0x00000276,0x00000000,0x000400fa,0x00000273,0x00000275,0x00000279,0x000200f8,0x00000275,
+ 0x0004003d,0x00000089,0x00000277,0x000001d1,0x0009004f,0x00000089,0x00000278,0x00000277,
+ 0x00000277,0x00000002,0x00000003,0x00000002,0x00000003,0x0003003e,0x00000274,0x00000278,
+ 0x000200f9,0x00000276,0x000200f8,0x00000279,0x0004003d,0x00000089,0x0000027a,0x000001da,
+ 0x0003003e,0x00000274,0x0000027a,0x000200f9,0x00000276,0x000200f8,0x00000276,0x0004003d,
+ 0x00000089,0x0000027b,0x00000274,0x0003003e,0x000001da,0x0000027b,0x0004003d,0x00000089,
+ 0x0000027c,0x000001d1,0x0004003d,0x00000089,0x0000027d,0x000001d1,0x0007004f,0x000001f0,
+ 0x0000027e,0x0000027d,0x0000027d,0x00000002,0x00000003,0x0004003d,0x00000089,0x0000027f,
+ 0x000001da,0x0007004f,0x000001f0,0x00000280,0x0000027f,0x0000027f,0x00000000,0x00000001,
+ 0x00050051,0x00000088,0x00000281,0x0000027e,0x00000000,0x00050051,0x00000088,0x00000282,
+ 0x0000027e,0x00000001,0x00050051,0x00000088,0x00000283,0x00000280,0x00000000,0x00050051,
+ 0x00000088,0x00000284,0x00000280,0x00000001,0x00070050,0x00000089,0x00000285,0x00000281,
+ 0x00000282,0x00000283,0x00000284,0x00050081,0x00000089,0x00000286,0x0000027c,0x00000285,
+ 0x0005008e,0x00000089,0x00000287,0x00000286,0x000000c8,0x0003003e,0x000001ee,0x00000287,
+ 0x0004003d,0x00000089,0x00000289,0x000001fc,0x0004003d,0x00000089,0x0000028a,0x000001d1,
+ 0x0007004f,0x000001f0,0x0000028b,0x0000028a,0x0000028a,0x00000000,0x00000001,0x0004003d,
+ 0x00000089,0x0000028c,0x000001ee,0x0007004f,0x000001f0,0x0000028d,0x0000028c,0x0000028c,
+ 0x00000000,0x00000001,0x00050051,0x00000088,0x0000028e,0x0000028b,0x00000000,0x00050051,
+ 0x00000088,0x0000028f,0x0000028b,0x00000001,0x00050051,0x00000088,0x00000290,0x0000028d,
+ 0x00000000,0x00050051,0x00000088,0x00000291,0x0000028d,0x00000001,0x00070050,0x00000089,
+ 0x00000292,0x0000028e,0x0000028f,0x00000290,0x00000291,0x00050081,0x00000089,0x00000293,
+ 0x00000289,0x00000292,0x0005008e,0x00000089,0x00000294,0x00000293,0x000000c8,0x0003003e,
+ 0x00000288,0x00000294,0x0004003d,0x00000089,0x00000296,0x00000206,0x0004003d,0x00000089,
+ 0x00000297,0x000001d1,0x0007004f,0x000001f0,0x00000298,0x00000297,0x00000297,0x00000002,
+ 0x00000003,0x0004003d,0x00000089,0x00000299,0x000001ee,0x0007004f,0x000001f0,0x0000029a,
+ 0x00000299,0x00000299,0x00000002,0x00000003,0x00050051,0x00000088,0x0000029b,0x00000298,
+ 0x00000000,0x00050051,0x00000088,0x0000029c,0x00000298,0x00000001,0x00050051,0x00000088,
+ 0x0000029d,0x0000029a,0x00000000,0x00050051,0x00000088,0x0000029e,0x0000029a,0x00000001,
+ 0x00070050,0x00000089,0x0000029f,0x0000029b,0x0000029c,0x0000029d,0x0000029e,0x00050081,
+ 0x00000089,0x000002a0,0x00000296,0x0000029f,0x0005008e,0x00000089,0x000002a1,0x000002a0,
+ 0x000000c8,0x0003003e,0x00000295,0x000002a1,0x0004003d,0x00000089,0x000002a2,0x000001c0,
+ 0x0004003d,0x00000089,0x000002a3,0x00000288,0x00050083,0x00000089,0x000002a4,0x000002a2,
+ 0x000002a3,0x0005008e,0x00000089,0x000002a5,0x000002a4,0x000000c8,0x00070050,0x00000089,
+ 0x000002a6,0x000000e4,0x000000e4,0x000000e4,0x000000e4,0x00050081,0x00000089,0x000002a7,
+ 0x000002a5,0x000002a6,0x0003003e,0x00000210,0x000002a7,0x0004003d,0x00000089,0x000002a8,
+ 0x000001c4,0x0004003d,0x00000089,0x000002a9,0x00000295,0x00050083,0x00000089,0x000002aa,
+ 0x000002a8,0x000002a9,0x0005008e,0x00000089,0x000002ab,0x000002aa,0x000000c8,0x00070050,
+ 0x00000089,0x000002ac,0x000000e4,0x000000e4,0x000000e4,0x000000e4,0x00050081,0x00000089,
+ 0x000002ad,0x000002ab,0x000002ac,0x0003003e,0x00000217,0x000002ad,0x0004003d,0x00000089,
+ 0x000002ae,0x00000210,0x00070050,0x00000089,0x000002af,0x000000ef,0x000000ef,0x000000ef,
+ 0x000000ef,0x00070050,0x00000089,0x000002b0,0x000000f0,0x000000f0,0x000000f0,0x000000f0,
+ 0x0008000c,0x00000089,0x000002b1,0x00000001,0x0000002b,0x000002ae,0x000002af,0x000002b0,
+ 0x0003003e,0x00000210,0x000002b1,0x0004003d,0x00000089,0x000002b2,0x00000217,0x00070050,
+ 0x00000089,0x000002b3,0x000000ef,0x000000ef,0x000000ef,0x000000ef,0x00070050,0x00000089,
+ 0x000002b4,0x000000f0,0x000000f0,0x000000f0,0x000000f0,0x0008000c,0x00000089,0x000002b5,
+ 0x00000001,0x0000002b,0x000002b2,0x000002b3,0x000002b4,0x0003003e,0x00000217,0x000002b5,
+ 0x00050041,0x0000002a,0x000002b6,0x00000027,0x00000029,0x0004003d,0x00000006,0x000002b7,
+ 0x000002b6,0x0004003d,0x00000006,0x000002b8,0x00000226,0x00050080,0x00000006,0x000002b9,
+ 0x000002b8,0x000002b7,0x0003003e,0x00000226,0x000002b9,0x0004003d,0x00000006,0x000002ba,
+ 0x00000226,0x0004003d,0x00000089,0x000002bb,0x00000210,0x0006000c,0x00000006,0x000002bc,
+ 0x00000001,0x00000037,0x000002bb,0x0004003d,0x00000089,0x000002bd,0x00000217,0x0006000c,
+ 0x00000006,0x000002be,0x00000001,0x00000037,0x000002bd,0x00050050,0x00000007,0x000002bf,
+ 0x000002bc,0x000002be,0x00060041,0x00000085,0x000002c0,0x00000232,0x00000074,0x000002ba,
+ 0x0003003e,0x000002c0,0x000002bf,0x000100fd,0x00010038
diff --git a/shaders/spv/shader_reconstruct_pyr.comp b/shaders/spv/shader_reconstruct_pyr.comp
new file mode 100644
index 0000000..7929989
--- /dev/null
+++ b/shaders/spv/shader_reconstruct_pyr.comp
@@ -0,0 +1,220 @@
+#version 310 es
+
+layout (local_size_x = 8, local_size_y = 8) in;
+
+layout (binding = 0) readonly buffer Lap0BufY {
+ uvec2 data[];
+} lap0_buf_y;
+
+layout (binding = 1) readonly buffer Lap0BufUV {
+ uvec2 data[];
+} lap0_buf_uv;
+
+layout (binding = 2) readonly buffer Lap1BufY {
+ uvec2 data[];
+} lap1_buf_y;
+
+layout (binding = 3) readonly buffer Lap1BufUV {
+ uvec2 data[];
+} lap1_buf_uv;
+
+layout (binding = 4) writeonly buffer OutBufY {
+ uvec2 data[];
+} out_buf_y;
+
+layout (binding = 5) writeonly buffer OutBufUV {
+ uvec2 data[];
+} out_buf_uv;
+
+layout (binding = 6) readonly buffer PrevBlendBufY {
+ uint data[];
+} prev_blend_y;
+
+layout (binding = 7) readonly buffer PrevBlendBufUV {
+ uint data[];
+} prev_blend_uv;
+
+layout (binding = 8) readonly buffer MaskBuf {
+ uvec2 data[];
+} mask_buf;
+
+layout (push_constant) uniform PushConsts {
+ uint lap_img_width;
+ uint lap_img_height;
+ uint out_img_width;
+ uint out_offset_x;
+ uint prev_blend_img_width;
+ uint prev_blend_img_height;
+} prop;
+
+// normalization of gray level
+const float norm_gl = 256.0f / 255.0f;
+
+void reconstruct_y (uvec2 y_id, uvec2 blend_id);
+void reconstruct_uv (uvec2 uv_id, uvec2 blend_id);
+
+void main ()
+{
+ uvec2 g_id = gl_GlobalInvocationID.xy;
+
+ uvec2 y_id = uvec2 (g_id.x, g_id.y * 4u);
+ y_id.x = clamp (y_id.x, 0u, prop.lap_img_width - 1u);
+
+ uvec2 blend_id = uvec2 (g_id.x, g_id.y * 2u);
+ blend_id.x = clamp (blend_id.x, 0u, prop.prev_blend_img_width - 1u);
+ reconstruct_y (y_id, blend_id);
+
+ y_id.y += 2u;
+ blend_id.y += 1u;
+ reconstruct_y (y_id, blend_id);
+
+ uvec2 uv_id = uvec2 (g_id.x, g_id.y * 2u);
+ uv_id.x = clamp (uv_id.x, 0u, prop.lap_img_width - 1u);
+ blend_id = g_id;
+ blend_id.x = clamp (blend_id.x, 0u, prop.prev_blend_img_width - 1u);
+ reconstruct_uv (uv_id, blend_id);
+}
+
+void reconstruct_y (uvec2 y_id, uvec2 blend_id)
+{
+ y_id.y = clamp (y_id.y, 0u, prop.lap_img_height - 1u);
+ blend_id.y = clamp (blend_id.y, 0u, prop.prev_blend_img_height - 2u);
+
+ uvec2 mask = mask_buf.data[y_id.x];
+ vec4 mask0 = unpackUnorm4x8 (mask.x);
+ vec4 mask1 = unpackUnorm4x8 (mask.y);
+
+ uint idx = y_id.y * prop.lap_img_width + y_id.x;
+ uvec2 lap = lap0_buf_y.data[idx];
+ vec4 lap00 = unpackUnorm4x8 (lap.x);
+ vec4 lap01 = unpackUnorm4x8 (lap.y);
+
+ lap = lap1_buf_y.data[idx];
+ vec4 lap10 = unpackUnorm4x8 (lap.x);
+ vec4 lap11 = unpackUnorm4x8 (lap.y);
+
+ vec4 lap_blend0 = (lap00 - lap10) * mask0 + lap10;
+ vec4 lap_blend1 = (lap01 - lap11) * mask1 + lap11;
+
+ uint prev_blend_idx = blend_id.y * prop.prev_blend_img_width + blend_id.x;
+ vec4 prev_blend0 = unpackUnorm4x8 (prev_blend_y.data[prev_blend_idx]);
+ vec4 prev_blend1 = unpackUnorm4x8 (prev_blend_y.data[prev_blend_idx + 1u]);
+ prev_blend1 = (blend_id.x == prop.prev_blend_img_width - 1u) ? prev_blend0.wwww : prev_blend1;
+
+ vec4 inter = (prev_blend0 + vec4 (prev_blend0.yzw, prev_blend1.x)) * 0.5f;
+ vec4 prev_blend_inter00 = vec4 (prev_blend0.x, inter.x, prev_blend0.y, inter.y);
+ vec4 prev_blend_inter01 = vec4 (prev_blend0.z, inter.z, prev_blend0.w, inter.w);
+
+ vec4 out0 = prev_blend_inter00 + lap_blend0 * 2.0f - norm_gl;
+ vec4 out1 = prev_blend_inter01 + lap_blend1 * 2.0f - norm_gl;
+ out0 = clamp (out0, 0.0f, 1.0f);
+ out1 = clamp (out1, 0.0f, 1.0f);
+
+ uint out_idx = y_id.y * prop.out_img_width + prop.out_offset_x + y_id.x;
+ out_buf_y.data[out_idx] = uvec2 (packUnorm4x8 (out0), packUnorm4x8 (out1));
+
+ idx = (y_id.y >= prop.lap_img_height - 1u) ? idx : idx + prop.lap_img_width;
+ lap = lap0_buf_y.data[idx];
+ lap00 = unpackUnorm4x8 (lap.x);
+ lap01 = unpackUnorm4x8 (lap.y);
+
+ lap = lap1_buf_y.data[idx];
+ lap10 = unpackUnorm4x8 (lap.x);
+ lap11 = unpackUnorm4x8 (lap.y);
+
+ lap_blend0 = (lap00 - lap10) * mask0 + lap10;
+ lap_blend1 = (lap01 - lap11) * mask1 + lap11;
+
+ prev_blend_idx = (blend_id.y >= prop.prev_blend_img_height - 1u) ?
+ prev_blend_idx : prev_blend_idx + prop.prev_blend_img_width;
+ prev_blend0 = unpackUnorm4x8 (prev_blend_y.data[prev_blend_idx]);
+ prev_blend1 = unpackUnorm4x8 (prev_blend_y.data[prev_blend_idx + 1u]);
+ prev_blend1 = (blend_id.x == prop.prev_blend_img_width - 1u) ? prev_blend0.wwww : prev_blend1;
+
+ inter = (prev_blend0 + vec4 (prev_blend0.yzw, prev_blend1.x)) * 0.5f;
+ vec4 prev_blend_inter10 = vec4 (prev_blend0.x, inter.x, prev_blend0.y, inter.y);
+ vec4 prev_blend_inter11 = vec4 (prev_blend0.z, inter.z, prev_blend0.w, inter.w);
+ prev_blend_inter10 = (prev_blend_inter00 + prev_blend_inter10) * 0.5f;
+ prev_blend_inter11 = (prev_blend_inter01 + prev_blend_inter11) * 0.5f;
+
+ out0 = prev_blend_inter10 + lap_blend0 * 2.0f - norm_gl;
+ out1 = prev_blend_inter11 + lap_blend1 * 2.0f - norm_gl;
+ out0 = clamp (out0, 0.0f, 1.0f);
+ out1 = clamp (out1, 0.0f, 1.0f);
+
+ out_idx = (y_id.y >= prop.lap_img_height - 1u) ? out_idx : out_idx + prop.out_img_width;
+ out_buf_y.data[out_idx] = uvec2 (packUnorm4x8 (out0), packUnorm4x8 (out1));
+}
+
+void reconstruct_uv (uvec2 uv_id, uvec2 blend_id)
+{
+ uv_id.y = clamp (uv_id.y, 0u, prop.lap_img_height / 2u - 2u);
+ blend_id.y = clamp (blend_id.y, 0u, prop.prev_blend_img_height / 2u - 1u);
+
+ uvec2 mask = mask_buf.data[uv_id.x];
+ vec4 mask0 = unpackUnorm4x8 (mask.x);
+ vec4 mask1 = unpackUnorm4x8 (mask.y);
+
+ uint idx = uv_id.y * prop.lap_img_width + uv_id.x;
+ uvec2 lap = lap0_buf_uv.data[idx];
+ vec4 lap00 = unpackUnorm4x8 (lap.x);
+ vec4 lap01 = unpackUnorm4x8 (lap.y);
+
+ lap = lap1_buf_uv.data[idx];
+ vec4 lap10 = unpackUnorm4x8 (lap.x);
+ vec4 lap11 = unpackUnorm4x8 (lap.y);
+
+ mask0.yw = mask0.xz;
+ mask1.yw = mask1.xz;
+ vec4 lap_blend0 = (lap00 - lap10) * mask0 + lap10;
+ vec4 lap_blend1 = (lap01 - lap11) * mask1 + lap11;
+
+ uint prev_blend_idx = blend_id.y * prop.prev_blend_img_width + blend_id.x;
+ vec4 prev_blend0 = unpackUnorm4x8 (prev_blend_uv.data[prev_blend_idx]);
+ vec4 prev_blend1 = unpackUnorm4x8 (prev_blend_uv.data[prev_blend_idx + 1u]);
+ prev_blend1 = (blend_id.x == prop.prev_blend_img_width - 1u) ? prev_blend0.zwzw : prev_blend1;
+
+ vec4 inter = (prev_blend0 + vec4 (prev_blend0.zw, prev_blend1.xy)) * 0.5f;
+ vec4 prev_blend_inter00 = vec4 (prev_blend0.xy, inter.xy);
+ vec4 prev_blend_inter01 = vec4 (prev_blend0.zw, inter.zw);
+
+ vec4 out0 = prev_blend_inter00 + lap_blend0 * 2.0f - norm_gl;
+ vec4 out1 = prev_blend_inter01 + lap_blend1 * 2.0f - norm_gl;
+ out0 = clamp (out0, 0.0f, 1.0f);
+ out1 = clamp (out1, 0.0f, 1.0f);
+
+ uint out_idx = uv_id.y * prop.out_img_width + prop.out_offset_x + uv_id.x;
+ out_buf_uv.data[out_idx] = uvec2 (packUnorm4x8 (out0), packUnorm4x8 (out1));
+
+ idx = (uv_id.y >= (prop.lap_img_height / 2u - 1u)) ? idx : idx + prop.lap_img_width;
+ lap = lap0_buf_uv.data[idx];
+ lap00 = unpackUnorm4x8 (lap.x);
+ lap01 = unpackUnorm4x8 (lap.y);
+
+ lap = lap1_buf_uv.data[idx];
+ lap10 = unpackUnorm4x8 (lap.x);
+ lap11 = unpackUnorm4x8 (lap.y);
+
+ lap_blend0 = (lap00 - lap10) * mask0 + lap10;
+ lap_blend1 = (lap01 - lap11) * mask1 + lap11;
+
+ prev_blend_idx = (blend_id.y >= (prop.prev_blend_img_height / 2u - 1u)) ?
+ prev_blend_idx : prev_blend_idx + prop.prev_blend_img_width;
+ prev_blend0 = unpackUnorm4x8 (prev_blend_uv.data[prev_blend_idx]);
+ prev_blend1 = unpackUnorm4x8 (prev_blend_uv.data[prev_blend_idx + 1u]);
+ prev_blend1 = (blend_id.x == prop.prev_blend_img_width - 1u) ? prev_blend0.zwzw : prev_blend1;
+
+ inter = (prev_blend0 + vec4 (prev_blend0.zw, prev_blend1.xy)) * 0.5f;
+ vec4 prev_blend_inter10 = vec4 (prev_blend0.xy, inter.xy);
+ vec4 prev_blend_inter11 = vec4 (prev_blend0.zw, inter.zw);
+ prev_blend_inter10 = (prev_blend_inter00 + prev_blend_inter10) * 0.5f;
+ prev_blend_inter11 = (prev_blend_inter01 + prev_blend_inter11) * 0.5f;
+
+ out0 = prev_blend_inter10 + lap_blend0 * 2.0f - norm_gl;
+ out1 = prev_blend_inter11 + lap_blend1 * 2.0f - norm_gl;
+ out0 = clamp (out0, 0.0f, 1.0f);
+ out1 = clamp (out1, 0.0f, 1.0f);
+
+ out_idx += prop.out_img_width;
+ out_buf_uv.data[out_idx] = uvec2 (packUnorm4x8 (out0), packUnorm4x8 (out1));
+}
diff --git a/shaders/spv/shader_reconstruct_pyr.comp.spv b/shaders/spv/shader_reconstruct_pyr.comp.spv
new file mode 100644
index 0000000..00ccea9
--- /dev/null
+++ b/shaders/spv/shader_reconstruct_pyr.comp.spv
@@ -0,0 +1,670 @@
+ // 7.8.2870
+ 0x07230203,0x00010000,0x00080007,0x00000366,0x00000000,0x00020011,0x00000001,0x0006000b,
+ 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,
+ 0x0006000f,0x00000005,0x00000004,0x6e69616d,0x00000000,0x00000015,0x00060010,0x00000004,
+ 0x00000011,0x00000008,0x00000008,0x00000001,0x00030003,0x00000001,0x00000136,0x00040005,
+ 0x00000004,0x6e69616d,0x00000000,0x00080005,0x0000000c,0x6f636572,0x7274736e,0x5f746375,
+ 0x75762879,0x75763b32,0x00003b32,0x00040005,0x0000000a,0x64695f79,0x00000000,0x00050005,
+ 0x0000000b,0x6e656c62,0x64695f64,0x00000000,0x00080005,0x00000010,0x6f636572,0x7274736e,
+ 0x5f746375,0x76287675,0x763b3275,0x003b3275,0x00040005,0x0000000e,0x695f7675,0x00000064,
+ 0x00050005,0x0000000f,0x6e656c62,0x64695f64,0x00000000,0x00040005,0x00000012,0x64695f67,
+ 0x00000000,0x00080005,0x00000015,0x475f6c67,0x61626f6c,0x766e496c,0x7461636f,0x496e6f69,
+ 0x00000044,0x00040005,0x00000018,0x64695f79,0x00000000,0x00050005,0x00000025,0x68737550,
+ 0x736e6f43,0x00007374,0x00070006,0x00000025,0x00000000,0x5f70616c,0x5f676d69,0x74646977,
+ 0x00000068,0x00070006,0x00000025,0x00000001,0x5f70616c,0x5f676d69,0x67696568,0x00007468,
+ 0x00070006,0x00000025,0x00000002,0x5f74756f,0x5f676d69,0x74646977,0x00000068,0x00070006,
+ 0x00000025,0x00000003,0x5f74756f,0x7366666f,0x785f7465,0x00000000,0x00090006,0x00000025,
+ 0x00000004,0x76657270,0x656c625f,0x695f646e,0x775f676d,0x68746469,0x00000000,0x00090006,
+ 0x00000025,0x00000005,0x76657270,0x656c625f,0x695f646e,0x685f676d,0x68676965,0x00000074,
+ 0x00040005,0x00000027,0x706f7270,0x00000000,0x00050005,0x00000030,0x6e656c62,0x64695f64,
+ 0x00000000,0x00040005,0x00000040,0x61726170,0x0000006d,0x00040005,0x00000042,0x61726170,
+ 0x0000006d,0x00040005,0x0000004d,0x61726170,0x0000006d,0x00040005,0x0000004f,0x61726170,
+ 0x0000006d,0x00040005,0x00000052,0x695f7675,0x00000064,0x00040005,0x00000068,0x61726170,
+ 0x0000006d,0x00040005,0x0000006a,0x61726170,0x0000006d,0x00040005,0x0000007d,0x6b73616d,
+ 0x00000000,0x00040005,0x0000007f,0x6b73614d,0x00667542,0x00050006,0x0000007f,0x00000000,
+ 0x61746164,0x00000000,0x00050005,0x00000081,0x6b73616d,0x6675625f,0x00000000,0x00040005,
+ 0x0000008a,0x6b73616d,0x00000030,0x00040005,0x0000008e,0x6b73616d,0x00000031,0x00030005,
+ 0x00000092,0x00786469,0x00030005,0x0000009b,0x0070616c,0x00050005,0x0000009d,0x3070614c,
+ 0x59667542,0x00000000,0x00050006,0x0000009d,0x00000000,0x61746164,0x00000000,0x00050005,
+ 0x0000009f,0x3070616c,0x6675625f,0x0000795f,0x00040005,0x000000a3,0x3070616c,0x00000030,
+ 0x00040005,0x000000a7,0x3070616c,0x00000031,0x00050005,0x000000ac,0x3170614c,0x59667542,
+ 0x00000000,0x00050006,0x000000ac,0x00000000,0x61746164,0x00000000,0x00050005,0x000000ae,
+ 0x3170616c,0x6675625f,0x0000795f,0x00040005,0x000000b2,0x3170616c,0x00000030,0x00040005,
+ 0x000000b6,0x3170616c,0x00000031,0x00050005,0x000000ba,0x5f70616c,0x6e656c62,0x00003064,
+ 0x00050005,0x000000c2,0x5f70616c,0x6e656c62,0x00003164,0x00060005,0x000000ca,0x76657270,
+ 0x656c625f,0x695f646e,0x00007864,0x00050005,0x000000d3,0x76657270,0x656c625f,0x0030646e,
+ 0x00060005,0x000000d5,0x76657250,0x6e656c42,0x66754264,0x00000059,0x00050006,0x000000d5,
+ 0x00000000,0x61746164,0x00000000,0x00060005,0x000000d7,0x76657270,0x656c625f,0x795f646e,
+ 0x00000000,0x00050005,0x000000dd,0x76657270,0x656c625f,0x0031646e,0x00040005,0x000000f2,
+ 0x65746e69,0x00000072,0x00070005,0x00000101,0x76657270,0x656c625f,0x695f646e,0x7265746e,
+ 0x00003030,0x00070005,0x0000010b,0x76657270,0x656c625f,0x695f646e,0x7265746e,0x00003130,
+ 0x00040005,0x00000116,0x3074756f,0x00000000,0x00040005,0x0000011f,0x3174756f,0x00000000,
+ 0x00040005,0x00000130,0x5f74756f,0x00786469,0x00040005,0x0000013f,0x4274754f,0x00596675,
+ 0x00050006,0x0000013f,0x00000000,0x61746164,0x00000000,0x00050005,0x00000141,0x5f74756f,
+ 0x5f667562,0x00000079,0x00070005,0x000001ab,0x76657270,0x656c625f,0x695f646e,0x7265746e,
+ 0x00003031,0x00070005,0x000001b5,0x76657270,0x656c625f,0x695f646e,0x7265746e,0x00003131,
+ 0x00040005,0x00000202,0x6b73616d,0x00000000,0x00040005,0x00000207,0x6b73616d,0x00000030,
+ 0x00040005,0x0000020b,0x6b73616d,0x00000031,0x00030005,0x0000020f,0x00786469,0x00030005,
+ 0x00000218,0x0070616c,0x00050005,0x0000021a,0x3070614c,0x55667542,0x00000056,0x00050006,
+ 0x0000021a,0x00000000,0x61746164,0x00000000,0x00050005,0x0000021c,0x3070616c,0x6675625f,
+ 0x0076755f,0x00040005,0x00000220,0x3070616c,0x00000030,0x00040005,0x00000224,0x3070616c,
+ 0x00000031,0x00050005,0x00000229,0x3170614c,0x55667542,0x00000056,0x00050006,0x00000229,
+ 0x00000000,0x61746164,0x00000000,0x00050005,0x0000022b,0x3170616c,0x6675625f,0x0076755f,
+ 0x00040005,0x0000022f,0x3170616c,0x00000030,0x00040005,0x00000233,0x3170616c,0x00000031,
+ 0x00050005,0x00000240,0x5f70616c,0x6e656c62,0x00003064,0x00050005,0x00000248,0x5f70616c,
+ 0x6e656c62,0x00003164,0x00060005,0x00000250,0x76657270,0x656c625f,0x695f646e,0x00007864,
+ 0x00050005,0x00000259,0x76657270,0x656c625f,0x0030646e,0x00060005,0x0000025b,0x76657250,
+ 0x6e656c42,0x66754264,0x00005655,0x00050006,0x0000025b,0x00000000,0x61746164,0x00000000,
+ 0x00060005,0x0000025d,0x76657270,0x656c625f,0x755f646e,0x00000076,0x00050005,0x00000262,
+ 0x76657270,0x656c625f,0x0031646e,0x00040005,0x00000276,0x65746e69,0x00000072,0x00070005,
+ 0x00000283,0x76657270,0x656c625f,0x695f646e,0x7265746e,0x00003030,0x00070005,0x0000028d,
+ 0x76657270,0x656c625f,0x695f646e,0x7265746e,0x00003130,0x00040005,0x00000297,0x3074756f,
+ 0x00000000,0x00040005,0x0000029e,0x3174756f,0x00000000,0x00040005,0x000002ad,0x5f74756f,
+ 0x00786469,0x00050005,0x000002ba,0x4274754f,0x56556675,0x00000000,0x00050006,0x000002ba,
+ 0x00000000,0x61746164,0x00000000,0x00050005,0x000002bc,0x5f74756f,0x5f667562,0x00007675,
+ 0x00070005,0x00000329,0x76657270,0x656c625f,0x695f646e,0x7265746e,0x00003031,0x00070005,
+ 0x00000333,0x76657270,0x656c625f,0x695f646e,0x7265746e,0x00003131,0x00040047,0x00000015,
+ 0x0000000b,0x0000001c,0x00050048,0x00000025,0x00000000,0x00000023,0x00000000,0x00050048,
+ 0x00000025,0x00000001,0x00000023,0x00000004,0x00050048,0x00000025,0x00000002,0x00000023,
+ 0x00000008,0x00050048,0x00000025,0x00000003,0x00000023,0x0000000c,0x00050048,0x00000025,
+ 0x00000004,0x00000023,0x00000010,0x00050048,0x00000025,0x00000005,0x00000023,0x00000014,
+ 0x00030047,0x00000025,0x00000002,0x00040047,0x0000007e,0x00000006,0x00000008,0x00040048,
+ 0x0000007f,0x00000000,0x00000018,0x00050048,0x0000007f,0x00000000,0x00000023,0x00000000,
+ 0x00030047,0x0000007f,0x00000003,0x00040047,0x00000081,0x00000022,0x00000000,0x00040047,
+ 0x00000081,0x00000021,0x00000008,0x00040047,0x0000009c,0x00000006,0x00000008,0x00040048,
+ 0x0000009d,0x00000000,0x00000018,0x00050048,0x0000009d,0x00000000,0x00000023,0x00000000,
+ 0x00030047,0x0000009d,0x00000003,0x00040047,0x0000009f,0x00000022,0x00000000,0x00040047,
+ 0x0000009f,0x00000021,0x00000000,0x00040047,0x000000ab,0x00000006,0x00000008,0x00040048,
+ 0x000000ac,0x00000000,0x00000018,0x00050048,0x000000ac,0x00000000,0x00000023,0x00000000,
+ 0x00030047,0x000000ac,0x00000003,0x00040047,0x000000ae,0x00000022,0x00000000,0x00040047,
+ 0x000000ae,0x00000021,0x00000002,0x00040047,0x000000d4,0x00000006,0x00000004,0x00040048,
+ 0x000000d5,0x00000000,0x00000018,0x00050048,0x000000d5,0x00000000,0x00000023,0x00000000,
+ 0x00030047,0x000000d5,0x00000003,0x00040047,0x000000d7,0x00000022,0x00000000,0x00040047,
+ 0x000000d7,0x00000021,0x00000006,0x00040047,0x0000013e,0x00000006,0x00000008,0x00040048,
+ 0x0000013f,0x00000000,0x00000019,0x00050048,0x0000013f,0x00000000,0x00000023,0x00000000,
+ 0x00030047,0x0000013f,0x00000003,0x00040047,0x00000141,0x00000022,0x00000000,0x00040047,
+ 0x00000141,0x00000021,0x00000004,0x00040047,0x00000219,0x00000006,0x00000008,0x00040048,
+ 0x0000021a,0x00000000,0x00000018,0x00050048,0x0000021a,0x00000000,0x00000023,0x00000000,
+ 0x00030047,0x0000021a,0x00000003,0x00040047,0x0000021c,0x00000022,0x00000000,0x00040047,
+ 0x0000021c,0x00000021,0x00000001,0x00040047,0x00000228,0x00000006,0x00000008,0x00040048,
+ 0x00000229,0x00000000,0x00000018,0x00050048,0x00000229,0x00000000,0x00000023,0x00000000,
+ 0x00030047,0x00000229,0x00000003,0x00040047,0x0000022b,0x00000022,0x00000000,0x00040047,
+ 0x0000022b,0x00000021,0x00000003,0x00040047,0x0000025a,0x00000006,0x00000004,0x00040048,
+ 0x0000025b,0x00000000,0x00000018,0x00050048,0x0000025b,0x00000000,0x00000023,0x00000000,
+ 0x00030047,0x0000025b,0x00000003,0x00040047,0x0000025d,0x00000022,0x00000000,0x00040047,
+ 0x0000025d,0x00000021,0x00000007,0x00040047,0x000002b9,0x00000006,0x00000008,0x00040048,
+ 0x000002ba,0x00000000,0x00000019,0x00050048,0x000002ba,0x00000000,0x00000023,0x00000000,
+ 0x00030047,0x000002ba,0x00000003,0x00040047,0x000002bc,0x00000022,0x00000000,0x00040047,
+ 0x000002bc,0x00000021,0x00000005,0x00040047,0x00000365,0x0000000b,0x00000019,0x00020013,
+ 0x00000002,0x00030021,0x00000003,0x00000002,0x00040015,0x00000006,0x00000020,0x00000000,
+ 0x00040017,0x00000007,0x00000006,0x00000002,0x00040020,0x00000008,0x00000007,0x00000007,
+ 0x00050021,0x00000009,0x00000002,0x00000008,0x00000008,0x00040017,0x00000013,0x00000006,
+ 0x00000003,0x00040020,0x00000014,0x00000001,0x00000013,0x0004003b,0x00000014,0x00000015,
+ 0x00000001,0x0004002b,0x00000006,0x00000019,0x00000000,0x00040020,0x0000001a,0x00000007,
+ 0x00000006,0x0004002b,0x00000006,0x0000001d,0x00000001,0x0004002b,0x00000006,0x00000020,
+ 0x00000004,0x0008001e,0x00000025,0x00000006,0x00000006,0x00000006,0x00000006,0x00000006,
+ 0x00000006,0x00040020,0x00000026,0x00000009,0x00000025,0x0004003b,0x00000026,0x00000027,
+ 0x00000009,0x00040015,0x00000028,0x00000020,0x00000001,0x0004002b,0x00000028,0x00000029,
+ 0x00000000,0x00040020,0x0000002a,0x00000009,0x00000006,0x0004002b,0x00000006,0x00000035,
+ 0x00000002,0x0004002b,0x00000028,0x0000003a,0x00000004,0x0004002b,0x00000028,0x0000006f,
+ 0x00000001,0x0004002b,0x00000028,0x00000077,0x00000005,0x0003001d,0x0000007e,0x00000007,
+ 0x0003001e,0x0000007f,0x0000007e,0x00040020,0x00000080,0x00000002,0x0000007f,0x0004003b,
+ 0x00000080,0x00000081,0x00000002,0x00040020,0x00000084,0x00000002,0x00000007,0x00030016,
+ 0x00000087,0x00000020,0x00040017,0x00000088,0x00000087,0x00000004,0x00040020,0x00000089,
+ 0x00000007,0x00000088,0x0003001d,0x0000009c,0x00000007,0x0003001e,0x0000009d,0x0000009c,
+ 0x00040020,0x0000009e,0x00000002,0x0000009d,0x0004003b,0x0000009e,0x0000009f,0x00000002,
+ 0x0003001d,0x000000ab,0x00000007,0x0003001e,0x000000ac,0x000000ab,0x00040020,0x000000ad,
+ 0x00000002,0x000000ac,0x0004003b,0x000000ad,0x000000ae,0x00000002,0x0003001d,0x000000d4,
+ 0x00000006,0x0003001e,0x000000d5,0x000000d4,0x00040020,0x000000d6,0x00000002,0x000000d5,
+ 0x0004003b,0x000000d6,0x000000d7,0x00000002,0x00040020,0x000000d9,0x00000002,0x00000006,
+ 0x00020014,0x000000e8,0x00040017,0x000000f4,0x00000087,0x00000003,0x00040020,0x000000f7,
+ 0x00000007,0x00000087,0x0004002b,0x00000087,0x000000ff,0x3f000000,0x0004002b,0x00000006,
+ 0x00000110,0x00000003,0x0004002b,0x00000087,0x00000119,0x40000000,0x0004002b,0x00000087,
+ 0x0000011c,0x3f808081,0x0004002b,0x00000087,0x00000127,0x00000000,0x0004002b,0x00000087,
+ 0x00000128,0x3f800000,0x0004002b,0x00000028,0x00000133,0x00000002,0x0004002b,0x00000028,
+ 0x00000137,0x00000003,0x0003001d,0x0000013e,0x00000007,0x0003001e,0x0000013f,0x0000013e,
+ 0x00040020,0x00000140,0x00000002,0x0000013f,0x0004003b,0x00000140,0x00000141,0x00000002,
+ 0x0003001d,0x00000219,0x00000007,0x0003001e,0x0000021a,0x00000219,0x00040020,0x0000021b,
+ 0x00000002,0x0000021a,0x0004003b,0x0000021b,0x0000021c,0x00000002,0x0003001d,0x00000228,
+ 0x00000007,0x0003001e,0x00000229,0x00000228,0x00040020,0x0000022a,0x00000002,0x00000229,
+ 0x0004003b,0x0000022a,0x0000022b,0x00000002,0x00040017,0x00000237,0x00000087,0x00000002,
+ 0x0003001d,0x0000025a,0x00000006,0x0003001e,0x0000025b,0x0000025a,0x00040020,0x0000025c,
+ 0x00000002,0x0000025b,0x0004003b,0x0000025c,0x0000025d,0x00000002,0x0003001d,0x000002b9,
+ 0x00000007,0x0003001e,0x000002ba,0x000002b9,0x00040020,0x000002bb,0x00000002,0x000002ba,
+ 0x0004003b,0x000002bb,0x000002bc,0x00000002,0x0004002b,0x00000006,0x00000364,0x00000008,
+ 0x0006002c,0x00000013,0x00000365,0x00000364,0x00000364,0x0000001d,0x00050036,0x00000002,
+ 0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003b,0x00000008,0x00000012,
+ 0x00000007,0x0004003b,0x00000008,0x00000018,0x00000007,0x0004003b,0x00000008,0x00000030,
+ 0x00000007,0x0004003b,0x00000008,0x00000040,0x00000007,0x0004003b,0x00000008,0x00000042,
+ 0x00000007,0x0004003b,0x00000008,0x0000004d,0x00000007,0x0004003b,0x00000008,0x0000004f,
+ 0x00000007,0x0004003b,0x00000008,0x00000052,0x00000007,0x0004003b,0x00000008,0x00000068,
+ 0x00000007,0x0004003b,0x00000008,0x0000006a,0x00000007,0x0004003d,0x00000013,0x00000016,
+ 0x00000015,0x0007004f,0x00000007,0x00000017,0x00000016,0x00000016,0x00000000,0x00000001,
+ 0x0003003e,0x00000012,0x00000017,0x00050041,0x0000001a,0x0000001b,0x00000012,0x00000019,
+ 0x0004003d,0x00000006,0x0000001c,0x0000001b,0x00050041,0x0000001a,0x0000001e,0x00000012,
+ 0x0000001d,0x0004003d,0x00000006,0x0000001f,0x0000001e,0x00050084,0x00000006,0x00000021,
+ 0x0000001f,0x00000020,0x00050050,0x00000007,0x00000022,0x0000001c,0x00000021,0x0003003e,
+ 0x00000018,0x00000022,0x00050041,0x0000001a,0x00000023,0x00000018,0x00000019,0x0004003d,
+ 0x00000006,0x00000024,0x00000023,0x00050041,0x0000002a,0x0000002b,0x00000027,0x00000029,
+ 0x0004003d,0x00000006,0x0000002c,0x0000002b,0x00050082,0x00000006,0x0000002d,0x0000002c,
+ 0x0000001d,0x0008000c,0x00000006,0x0000002e,0x00000001,0x0000002c,0x00000024,0x00000019,
+ 0x0000002d,0x00050041,0x0000001a,0x0000002f,0x00000018,0x00000019,0x0003003e,0x0000002f,
+ 0x0000002e,0x00050041,0x0000001a,0x00000031,0x00000012,0x00000019,0x0004003d,0x00000006,
+ 0x00000032,0x00000031,0x00050041,0x0000001a,0x00000033,0x00000012,0x0000001d,0x0004003d,
+ 0x00000006,0x00000034,0x00000033,0x00050084,0x00000006,0x00000036,0x00000034,0x00000035,
+ 0x00050050,0x00000007,0x00000037,0x00000032,0x00000036,0x0003003e,0x00000030,0x00000037,
+ 0x00050041,0x0000001a,0x00000038,0x00000030,0x00000019,0x0004003d,0x00000006,0x00000039,
+ 0x00000038,0x00050041,0x0000002a,0x0000003b,0x00000027,0x0000003a,0x0004003d,0x00000006,
+ 0x0000003c,0x0000003b,0x00050082,0x00000006,0x0000003d,0x0000003c,0x0000001d,0x0008000c,
+ 0x00000006,0x0000003e,0x00000001,0x0000002c,0x00000039,0x00000019,0x0000003d,0x00050041,
+ 0x0000001a,0x0000003f,0x00000030,0x00000019,0x0003003e,0x0000003f,0x0000003e,0x0004003d,
+ 0x00000007,0x00000041,0x00000018,0x0003003e,0x00000040,0x00000041,0x0004003d,0x00000007,
+ 0x00000043,0x00000030,0x0003003e,0x00000042,0x00000043,0x00060039,0x00000002,0x00000044,
+ 0x0000000c,0x00000040,0x00000042,0x00050041,0x0000001a,0x00000045,0x00000018,0x0000001d,
+ 0x0004003d,0x00000006,0x00000046,0x00000045,0x00050080,0x00000006,0x00000047,0x00000046,
+ 0x00000035,0x00050041,0x0000001a,0x00000048,0x00000018,0x0000001d,0x0003003e,0x00000048,
+ 0x00000047,0x00050041,0x0000001a,0x00000049,0x00000030,0x0000001d,0x0004003d,0x00000006,
+ 0x0000004a,0x00000049,0x00050080,0x00000006,0x0000004b,0x0000004a,0x0000001d,0x00050041,
+ 0x0000001a,0x0000004c,0x00000030,0x0000001d,0x0003003e,0x0000004c,0x0000004b,0x0004003d,
+ 0x00000007,0x0000004e,0x00000018,0x0003003e,0x0000004d,0x0000004e,0x0004003d,0x00000007,
+ 0x00000050,0x00000030,0x0003003e,0x0000004f,0x00000050,0x00060039,0x00000002,0x00000051,
+ 0x0000000c,0x0000004d,0x0000004f,0x00050041,0x0000001a,0x00000053,0x00000012,0x00000019,
+ 0x0004003d,0x00000006,0x00000054,0x00000053,0x00050041,0x0000001a,0x00000055,0x00000012,
+ 0x0000001d,0x0004003d,0x00000006,0x00000056,0x00000055,0x00050084,0x00000006,0x00000057,
+ 0x00000056,0x00000035,0x00050050,0x00000007,0x00000058,0x00000054,0x00000057,0x0003003e,
+ 0x00000052,0x00000058,0x00050041,0x0000001a,0x00000059,0x00000052,0x00000019,0x0004003d,
+ 0x00000006,0x0000005a,0x00000059,0x00050041,0x0000002a,0x0000005b,0x00000027,0x00000029,
+ 0x0004003d,0x00000006,0x0000005c,0x0000005b,0x00050082,0x00000006,0x0000005d,0x0000005c,
+ 0x0000001d,0x0008000c,0x00000006,0x0000005e,0x00000001,0x0000002c,0x0000005a,0x00000019,
+ 0x0000005d,0x00050041,0x0000001a,0x0000005f,0x00000052,0x00000019,0x0003003e,0x0000005f,
+ 0x0000005e,0x0004003d,0x00000007,0x00000060,0x00000012,0x0003003e,0x00000030,0x00000060,
+ 0x00050041,0x0000001a,0x00000061,0x00000030,0x00000019,0x0004003d,0x00000006,0x00000062,
+ 0x00000061,0x00050041,0x0000002a,0x00000063,0x00000027,0x0000003a,0x0004003d,0x00000006,
+ 0x00000064,0x00000063,0x00050082,0x00000006,0x00000065,0x00000064,0x0000001d,0x0008000c,
+ 0x00000006,0x00000066,0x00000001,0x0000002c,0x00000062,0x00000019,0x00000065,0x00050041,
+ 0x0000001a,0x00000067,0x00000030,0x00000019,0x0003003e,0x00000067,0x00000066,0x0004003d,
+ 0x00000007,0x00000069,0x00000052,0x0003003e,0x00000068,0x00000069,0x0004003d,0x00000007,
+ 0x0000006b,0x00000030,0x0003003e,0x0000006a,0x0000006b,0x00060039,0x00000002,0x0000006c,
+ 0x00000010,0x00000068,0x0000006a,0x000100fd,0x00010038,0x00050036,0x00000002,0x0000000c,
+ 0x00000000,0x00000009,0x00030037,0x00000008,0x0000000a,0x00030037,0x00000008,0x0000000b,
+ 0x000200f8,0x0000000d,0x0004003b,0x00000008,0x0000007d,0x00000007,0x0004003b,0x00000089,
+ 0x0000008a,0x00000007,0x0004003b,0x00000089,0x0000008e,0x00000007,0x0004003b,0x0000001a,
+ 0x00000092,0x00000007,0x0004003b,0x00000008,0x0000009b,0x00000007,0x0004003b,0x00000089,
+ 0x000000a3,0x00000007,0x0004003b,0x00000089,0x000000a7,0x00000007,0x0004003b,0x00000089,
+ 0x000000b2,0x00000007,0x0004003b,0x00000089,0x000000b6,0x00000007,0x0004003b,0x00000089,
+ 0x000000ba,0x00000007,0x0004003b,0x00000089,0x000000c2,0x00000007,0x0004003b,0x0000001a,
+ 0x000000ca,0x00000007,0x0004003b,0x00000089,0x000000d3,0x00000007,0x0004003b,0x00000089,
+ 0x000000dd,0x00000007,0x0004003b,0x00000089,0x000000ea,0x00000007,0x0004003b,0x00000089,
+ 0x000000f2,0x00000007,0x0004003b,0x00000089,0x00000101,0x00000007,0x0004003b,0x00000089,
+ 0x0000010b,0x00000007,0x0004003b,0x00000089,0x00000116,0x00000007,0x0004003b,0x00000089,
+ 0x0000011f,0x00000007,0x0004003b,0x0000001a,0x00000130,0x00000007,0x0004003b,0x0000001a,
+ 0x0000014f,0x00000007,0x0004003b,0x0000001a,0x0000017f,0x00000007,0x0004003b,0x00000089,
+ 0x00000198,0x00000007,0x0004003b,0x00000089,0x000001ab,0x00000007,0x0004003b,0x00000089,
+ 0x000001b5,0x00000007,0x0004003b,0x0000001a,0x000001e1,0x00000007,0x00050041,0x0000001a,
+ 0x0000006d,0x0000000a,0x0000001d,0x0004003d,0x00000006,0x0000006e,0x0000006d,0x00050041,
+ 0x0000002a,0x00000070,0x00000027,0x0000006f,0x0004003d,0x00000006,0x00000071,0x00000070,
+ 0x00050082,0x00000006,0x00000072,0x00000071,0x0000001d,0x0008000c,0x00000006,0x00000073,
+ 0x00000001,0x0000002c,0x0000006e,0x00000019,0x00000072,0x00050041,0x0000001a,0x00000074,
+ 0x0000000a,0x0000001d,0x0003003e,0x00000074,0x00000073,0x00050041,0x0000001a,0x00000075,
+ 0x0000000b,0x0000001d,0x0004003d,0x00000006,0x00000076,0x00000075,0x00050041,0x0000002a,
+ 0x00000078,0x00000027,0x00000077,0x0004003d,0x00000006,0x00000079,0x00000078,0x00050082,
+ 0x00000006,0x0000007a,0x00000079,0x00000035,0x0008000c,0x00000006,0x0000007b,0x00000001,
+ 0x0000002c,0x00000076,0x00000019,0x0000007a,0x00050041,0x0000001a,0x0000007c,0x0000000b,
+ 0x0000001d,0x0003003e,0x0000007c,0x0000007b,0x00050041,0x0000001a,0x00000082,0x0000000a,
+ 0x00000019,0x0004003d,0x00000006,0x00000083,0x00000082,0x00060041,0x00000084,0x00000085,
+ 0x00000081,0x00000029,0x00000083,0x0004003d,0x00000007,0x00000086,0x00000085,0x0003003e,
+ 0x0000007d,0x00000086,0x00050041,0x0000001a,0x0000008b,0x0000007d,0x00000019,0x0004003d,
+ 0x00000006,0x0000008c,0x0000008b,0x0006000c,0x00000088,0x0000008d,0x00000001,0x00000040,
+ 0x0000008c,0x0003003e,0x0000008a,0x0000008d,0x00050041,0x0000001a,0x0000008f,0x0000007d,
+ 0x0000001d,0x0004003d,0x00000006,0x00000090,0x0000008f,0x0006000c,0x00000088,0x00000091,
+ 0x00000001,0x00000040,0x00000090,0x0003003e,0x0000008e,0x00000091,0x00050041,0x0000001a,
+ 0x00000093,0x0000000a,0x0000001d,0x0004003d,0x00000006,0x00000094,0x00000093,0x00050041,
+ 0x0000002a,0x00000095,0x00000027,0x00000029,0x0004003d,0x00000006,0x00000096,0x00000095,
+ 0x00050084,0x00000006,0x00000097,0x00000094,0x00000096,0x00050041,0x0000001a,0x00000098,
+ 0x0000000a,0x00000019,0x0004003d,0x00000006,0x00000099,0x00000098,0x00050080,0x00000006,
+ 0x0000009a,0x00000097,0x00000099,0x0003003e,0x00000092,0x0000009a,0x0004003d,0x00000006,
+ 0x000000a0,0x00000092,0x00060041,0x00000084,0x000000a1,0x0000009f,0x00000029,0x000000a0,
+ 0x0004003d,0x00000007,0x000000a2,0x000000a1,0x0003003e,0x0000009b,0x000000a2,0x00050041,
+ 0x0000001a,0x000000a4,0x0000009b,0x00000019,0x0004003d,0x00000006,0x000000a5,0x000000a4,
+ 0x0006000c,0x00000088,0x000000a6,0x00000001,0x00000040,0x000000a5,0x0003003e,0x000000a3,
+ 0x000000a6,0x00050041,0x0000001a,0x000000a8,0x0000009b,0x0000001d,0x0004003d,0x00000006,
+ 0x000000a9,0x000000a8,0x0006000c,0x00000088,0x000000aa,0x00000001,0x00000040,0x000000a9,
+ 0x0003003e,0x000000a7,0x000000aa,0x0004003d,0x00000006,0x000000af,0x00000092,0x00060041,
+ 0x00000084,0x000000b0,0x000000ae,0x00000029,0x000000af,0x0004003d,0x00000007,0x000000b1,
+ 0x000000b0,0x0003003e,0x0000009b,0x000000b1,0x00050041,0x0000001a,0x000000b3,0x0000009b,
+ 0x00000019,0x0004003d,0x00000006,0x000000b4,0x000000b3,0x0006000c,0x00000088,0x000000b5,
+ 0x00000001,0x00000040,0x000000b4,0x0003003e,0x000000b2,0x000000b5,0x00050041,0x0000001a,
+ 0x000000b7,0x0000009b,0x0000001d,0x0004003d,0x00000006,0x000000b8,0x000000b7,0x0006000c,
+ 0x00000088,0x000000b9,0x00000001,0x00000040,0x000000b8,0x0003003e,0x000000b6,0x000000b9,
+ 0x0004003d,0x00000088,0x000000bb,0x000000a3,0x0004003d,0x00000088,0x000000bc,0x000000b2,
+ 0x00050083,0x00000088,0x000000bd,0x000000bb,0x000000bc,0x0004003d,0x00000088,0x000000be,
+ 0x0000008a,0x00050085,0x00000088,0x000000bf,0x000000bd,0x000000be,0x0004003d,0x00000088,
+ 0x000000c0,0x000000b2,0x00050081,0x00000088,0x000000c1,0x000000bf,0x000000c0,0x0003003e,
+ 0x000000ba,0x000000c1,0x0004003d,0x00000088,0x000000c3,0x000000a7,0x0004003d,0x00000088,
+ 0x000000c4,0x000000b6,0x00050083,0x00000088,0x000000c5,0x000000c3,0x000000c4,0x0004003d,
+ 0x00000088,0x000000c6,0x0000008e,0x00050085,0x00000088,0x000000c7,0x000000c5,0x000000c6,
+ 0x0004003d,0x00000088,0x000000c8,0x000000b6,0x00050081,0x00000088,0x000000c9,0x000000c7,
+ 0x000000c8,0x0003003e,0x000000c2,0x000000c9,0x00050041,0x0000001a,0x000000cb,0x0000000b,
+ 0x0000001d,0x0004003d,0x00000006,0x000000cc,0x000000cb,0x00050041,0x0000002a,0x000000cd,
+ 0x00000027,0x0000003a,0x0004003d,0x00000006,0x000000ce,0x000000cd,0x00050084,0x00000006,
+ 0x000000cf,0x000000cc,0x000000ce,0x00050041,0x0000001a,0x000000d0,0x0000000b,0x00000019,
+ 0x0004003d,0x00000006,0x000000d1,0x000000d0,0x00050080,0x00000006,0x000000d2,0x000000cf,
+ 0x000000d1,0x0003003e,0x000000ca,0x000000d2,0x0004003d,0x00000006,0x000000d8,0x000000ca,
+ 0x00060041,0x000000d9,0x000000da,0x000000d7,0x00000029,0x000000d8,0x0004003d,0x00000006,
+ 0x000000db,0x000000da,0x0006000c,0x00000088,0x000000dc,0x00000001,0x00000040,0x000000db,
+ 0x0003003e,0x000000d3,0x000000dc,0x0004003d,0x00000006,0x000000de,0x000000ca,0x00050080,
+ 0x00000006,0x000000df,0x000000de,0x0000001d,0x00060041,0x000000d9,0x000000e0,0x000000d7,
+ 0x00000029,0x000000df,0x0004003d,0x00000006,0x000000e1,0x000000e0,0x0006000c,0x00000088,
+ 0x000000e2,0x00000001,0x00000040,0x000000e1,0x0003003e,0x000000dd,0x000000e2,0x00050041,
+ 0x0000001a,0x000000e3,0x0000000b,0x00000019,0x0004003d,0x00000006,0x000000e4,0x000000e3,
+ 0x00050041,0x0000002a,0x000000e5,0x00000027,0x0000003a,0x0004003d,0x00000006,0x000000e6,
+ 0x000000e5,0x00050082,0x00000006,0x000000e7,0x000000e6,0x0000001d,0x000500aa,0x000000e8,
+ 0x000000e9,0x000000e4,0x000000e7,0x000300f7,0x000000ec,0x00000000,0x000400fa,0x000000e9,
+ 0x000000eb,0x000000ef,0x000200f8,0x000000eb,0x0004003d,0x00000088,0x000000ed,0x000000d3,
+ 0x0009004f,0x00000088,0x000000ee,0x000000ed,0x000000ed,0x00000003,0x00000003,0x00000003,
+ 0x00000003,0x0003003e,0x000000ea,0x000000ee,0x000200f9,0x000000ec,0x000200f8,0x000000ef,
+ 0x0004003d,0x00000088,0x000000f0,0x000000dd,0x0003003e,0x000000ea,0x000000f0,0x000200f9,
+ 0x000000ec,0x000200f8,0x000000ec,0x0004003d,0x00000088,0x000000f1,0x000000ea,0x0003003e,
+ 0x000000dd,0x000000f1,0x0004003d,0x00000088,0x000000f3,0x000000d3,0x0004003d,0x00000088,
+ 0x000000f5,0x000000d3,0x0008004f,0x000000f4,0x000000f6,0x000000f5,0x000000f5,0x00000001,
+ 0x00000002,0x00000003,0x00050041,0x000000f7,0x000000f8,0x000000dd,0x00000019,0x0004003d,
+ 0x00000087,0x000000f9,0x000000f8,0x00050051,0x00000087,0x000000fa,0x000000f6,0x00000000,
+ 0x00050051,0x00000087,0x000000fb,0x000000f6,0x00000001,0x00050051,0x00000087,0x000000fc,
+ 0x000000f6,0x00000002,0x00070050,0x00000088,0x000000fd,0x000000fa,0x000000fb,0x000000fc,
+ 0x000000f9,0x00050081,0x00000088,0x000000fe,0x000000f3,0x000000fd,0x0005008e,0x00000088,
+ 0x00000100,0x000000fe,0x000000ff,0x0003003e,0x000000f2,0x00000100,0x00050041,0x000000f7,
+ 0x00000102,0x000000d3,0x00000019,0x0004003d,0x00000087,0x00000103,0x00000102,0x00050041,
+ 0x000000f7,0x00000104,0x000000f2,0x00000019,0x0004003d,0x00000087,0x00000105,0x00000104,
+ 0x00050041,0x000000f7,0x00000106,0x000000d3,0x0000001d,0x0004003d,0x00000087,0x00000107,
+ 0x00000106,0x00050041,0x000000f7,0x00000108,0x000000f2,0x0000001d,0x0004003d,0x00000087,
+ 0x00000109,0x00000108,0x00070050,0x00000088,0x0000010a,0x00000103,0x00000105,0x00000107,
+ 0x00000109,0x0003003e,0x00000101,0x0000010a,0x00050041,0x000000f7,0x0000010c,0x000000d3,
+ 0x00000035,0x0004003d,0x00000087,0x0000010d,0x0000010c,0x00050041,0x000000f7,0x0000010e,
+ 0x000000f2,0x00000035,0x0004003d,0x00000087,0x0000010f,0x0000010e,0x00050041,0x000000f7,
+ 0x00000111,0x000000d3,0x00000110,0x0004003d,0x00000087,0x00000112,0x00000111,0x00050041,
+ 0x000000f7,0x00000113,0x000000f2,0x00000110,0x0004003d,0x00000087,0x00000114,0x00000113,
+ 0x00070050,0x00000088,0x00000115,0x0000010d,0x0000010f,0x00000112,0x00000114,0x0003003e,
+ 0x0000010b,0x00000115,0x0004003d,0x00000088,0x00000117,0x00000101,0x0004003d,0x00000088,
+ 0x00000118,0x000000ba,0x0005008e,0x00000088,0x0000011a,0x00000118,0x00000119,0x00050081,
+ 0x00000088,0x0000011b,0x00000117,0x0000011a,0x00070050,0x00000088,0x0000011d,0x0000011c,
+ 0x0000011c,0x0000011c,0x0000011c,0x00050083,0x00000088,0x0000011e,0x0000011b,0x0000011d,
+ 0x0003003e,0x00000116,0x0000011e,0x0004003d,0x00000088,0x00000120,0x0000010b,0x0004003d,
+ 0x00000088,0x00000121,0x000000c2,0x0005008e,0x00000088,0x00000122,0x00000121,0x00000119,
+ 0x00050081,0x00000088,0x00000123,0x00000120,0x00000122,0x00070050,0x00000088,0x00000124,
+ 0x0000011c,0x0000011c,0x0000011c,0x0000011c,0x00050083,0x00000088,0x00000125,0x00000123,
+ 0x00000124,0x0003003e,0x0000011f,0x00000125,0x0004003d,0x00000088,0x00000126,0x00000116,
+ 0x00070050,0x00000088,0x00000129,0x00000127,0x00000127,0x00000127,0x00000127,0x00070050,
+ 0x00000088,0x0000012a,0x00000128,0x00000128,0x00000128,0x00000128,0x0008000c,0x00000088,
+ 0x0000012b,0x00000001,0x0000002b,0x00000126,0x00000129,0x0000012a,0x0003003e,0x00000116,
+ 0x0000012b,0x0004003d,0x00000088,0x0000012c,0x0000011f,0x00070050,0x00000088,0x0000012d,
+ 0x00000127,0x00000127,0x00000127,0x00000127,0x00070050,0x00000088,0x0000012e,0x00000128,
+ 0x00000128,0x00000128,0x00000128,0x0008000c,0x00000088,0x0000012f,0x00000001,0x0000002b,
+ 0x0000012c,0x0000012d,0x0000012e,0x0003003e,0x0000011f,0x0000012f,0x00050041,0x0000001a,
+ 0x00000131,0x0000000a,0x0000001d,0x0004003d,0x00000006,0x00000132,0x00000131,0x00050041,
+ 0x0000002a,0x00000134,0x00000027,0x00000133,0x0004003d,0x00000006,0x00000135,0x00000134,
+ 0x00050084,0x00000006,0x00000136,0x00000132,0x00000135,0x00050041,0x0000002a,0x00000138,
+ 0x00000027,0x00000137,0x0004003d,0x00000006,0x00000139,0x00000138,0x00050080,0x00000006,
+ 0x0000013a,0x00000136,0x00000139,0x00050041,0x0000001a,0x0000013b,0x0000000a,0x00000019,
+ 0x0004003d,0x00000006,0x0000013c,0x0000013b,0x00050080,0x00000006,0x0000013d,0x0000013a,
+ 0x0000013c,0x0003003e,0x00000130,0x0000013d,0x0004003d,0x00000006,0x00000142,0x00000130,
+ 0x0004003d,0x00000088,0x00000143,0x00000116,0x0006000c,0x00000006,0x00000144,0x00000001,
+ 0x00000037,0x00000143,0x0004003d,0x00000088,0x00000145,0x0000011f,0x0006000c,0x00000006,
+ 0x00000146,0x00000001,0x00000037,0x00000145,0x00050050,0x00000007,0x00000147,0x00000144,
+ 0x00000146,0x00060041,0x00000084,0x00000148,0x00000141,0x00000029,0x00000142,0x0003003e,
+ 0x00000148,0x00000147,0x00050041,0x0000001a,0x00000149,0x0000000a,0x0000001d,0x0004003d,
+ 0x00000006,0x0000014a,0x00000149,0x00050041,0x0000002a,0x0000014b,0x00000027,0x0000006f,
+ 0x0004003d,0x00000006,0x0000014c,0x0000014b,0x00050082,0x00000006,0x0000014d,0x0000014c,
+ 0x0000001d,0x000500ae,0x000000e8,0x0000014e,0x0000014a,0x0000014d,0x000300f7,0x00000151,
+ 0x00000000,0x000400fa,0x0000014e,0x00000150,0x00000153,0x000200f8,0x00000150,0x0004003d,
+ 0x00000006,0x00000152,0x00000092,0x0003003e,0x0000014f,0x00000152,0x000200f9,0x00000151,
+ 0x000200f8,0x00000153,0x0004003d,0x00000006,0x00000154,0x00000092,0x00050041,0x0000002a,
+ 0x00000155,0x00000027,0x00000029,0x0004003d,0x00000006,0x00000156,0x00000155,0x00050080,
+ 0x00000006,0x00000157,0x00000154,0x00000156,0x0003003e,0x0000014f,0x00000157,0x000200f9,
+ 0x00000151,0x000200f8,0x00000151,0x0004003d,0x00000006,0x00000158,0x0000014f,0x0003003e,
+ 0x00000092,0x00000158,0x0004003d,0x00000006,0x00000159,0x00000092,0x00060041,0x00000084,
+ 0x0000015a,0x0000009f,0x00000029,0x00000159,0x0004003d,0x00000007,0x0000015b,0x0000015a,
+ 0x0003003e,0x0000009b,0x0000015b,0x00050041,0x0000001a,0x0000015c,0x0000009b,0x00000019,
+ 0x0004003d,0x00000006,0x0000015d,0x0000015c,0x0006000c,0x00000088,0x0000015e,0x00000001,
+ 0x00000040,0x0000015d,0x0003003e,0x000000a3,0x0000015e,0x00050041,0x0000001a,0x0000015f,
+ 0x0000009b,0x0000001d,0x0004003d,0x00000006,0x00000160,0x0000015f,0x0006000c,0x00000088,
+ 0x00000161,0x00000001,0x00000040,0x00000160,0x0003003e,0x000000a7,0x00000161,0x0004003d,
+ 0x00000006,0x00000162,0x00000092,0x00060041,0x00000084,0x00000163,0x000000ae,0x00000029,
+ 0x00000162,0x0004003d,0x00000007,0x00000164,0x00000163,0x0003003e,0x0000009b,0x00000164,
+ 0x00050041,0x0000001a,0x00000165,0x0000009b,0x00000019,0x0004003d,0x00000006,0x00000166,
+ 0x00000165,0x0006000c,0x00000088,0x00000167,0x00000001,0x00000040,0x00000166,0x0003003e,
+ 0x000000b2,0x00000167,0x00050041,0x0000001a,0x00000168,0x0000009b,0x0000001d,0x0004003d,
+ 0x00000006,0x00000169,0x00000168,0x0006000c,0x00000088,0x0000016a,0x00000001,0x00000040,
+ 0x00000169,0x0003003e,0x000000b6,0x0000016a,0x0004003d,0x00000088,0x0000016b,0x000000a3,
+ 0x0004003d,0x00000088,0x0000016c,0x000000b2,0x00050083,0x00000088,0x0000016d,0x0000016b,
+ 0x0000016c,0x0004003d,0x00000088,0x0000016e,0x0000008a,0x00050085,0x00000088,0x0000016f,
+ 0x0000016d,0x0000016e,0x0004003d,0x00000088,0x00000170,0x000000b2,0x00050081,0x00000088,
+ 0x00000171,0x0000016f,0x00000170,0x0003003e,0x000000ba,0x00000171,0x0004003d,0x00000088,
+ 0x00000172,0x000000a7,0x0004003d,0x00000088,0x00000173,0x000000b6,0x00050083,0x00000088,
+ 0x00000174,0x00000172,0x00000173,0x0004003d,0x00000088,0x00000175,0x0000008e,0x00050085,
+ 0x00000088,0x00000176,0x00000174,0x00000175,0x0004003d,0x00000088,0x00000177,0x000000b6,
+ 0x00050081,0x00000088,0x00000178,0x00000176,0x00000177,0x0003003e,0x000000c2,0x00000178,
+ 0x00050041,0x0000001a,0x00000179,0x0000000b,0x0000001d,0x0004003d,0x00000006,0x0000017a,
+ 0x00000179,0x00050041,0x0000002a,0x0000017b,0x00000027,0x00000077,0x0004003d,0x00000006,
+ 0x0000017c,0x0000017b,0x00050082,0x00000006,0x0000017d,0x0000017c,0x0000001d,0x000500ae,
+ 0x000000e8,0x0000017e,0x0000017a,0x0000017d,0x000300f7,0x00000181,0x00000000,0x000400fa,
+ 0x0000017e,0x00000180,0x00000183,0x000200f8,0x00000180,0x0004003d,0x00000006,0x00000182,
+ 0x000000ca,0x0003003e,0x0000017f,0x00000182,0x000200f9,0x00000181,0x000200f8,0x00000183,
+ 0x0004003d,0x00000006,0x00000184,0x000000ca,0x00050041,0x0000002a,0x00000185,0x00000027,
+ 0x0000003a,0x0004003d,0x00000006,0x00000186,0x00000185,0x00050080,0x00000006,0x00000187,
+ 0x00000184,0x00000186,0x0003003e,0x0000017f,0x00000187,0x000200f9,0x00000181,0x000200f8,
+ 0x00000181,0x0004003d,0x00000006,0x00000188,0x0000017f,0x0003003e,0x000000ca,0x00000188,
+ 0x0004003d,0x00000006,0x00000189,0x000000ca,0x00060041,0x000000d9,0x0000018a,0x000000d7,
+ 0x00000029,0x00000189,0x0004003d,0x00000006,0x0000018b,0x0000018a,0x0006000c,0x00000088,
+ 0x0000018c,0x00000001,0x00000040,0x0000018b,0x0003003e,0x000000d3,0x0000018c,0x0004003d,
+ 0x00000006,0x0000018d,0x000000ca,0x00050080,0x00000006,0x0000018e,0x0000018d,0x0000001d,
+ 0x00060041,0x000000d9,0x0000018f,0x000000d7,0x00000029,0x0000018e,0x0004003d,0x00000006,
+ 0x00000190,0x0000018f,0x0006000c,0x00000088,0x00000191,0x00000001,0x00000040,0x00000190,
+ 0x0003003e,0x000000dd,0x00000191,0x00050041,0x0000001a,0x00000192,0x0000000b,0x00000019,
+ 0x0004003d,0x00000006,0x00000193,0x00000192,0x00050041,0x0000002a,0x00000194,0x00000027,
+ 0x0000003a,0x0004003d,0x00000006,0x00000195,0x00000194,0x00050082,0x00000006,0x00000196,
+ 0x00000195,0x0000001d,0x000500aa,0x000000e8,0x00000197,0x00000193,0x00000196,0x000300f7,
+ 0x0000019a,0x00000000,0x000400fa,0x00000197,0x00000199,0x0000019d,0x000200f8,0x00000199,
+ 0x0004003d,0x00000088,0x0000019b,0x000000d3,0x0009004f,0x00000088,0x0000019c,0x0000019b,
+ 0x0000019b,0x00000003,0x00000003,0x00000003,0x00000003,0x0003003e,0x00000198,0x0000019c,
+ 0x000200f9,0x0000019a,0x000200f8,0x0000019d,0x0004003d,0x00000088,0x0000019e,0x000000dd,
+ 0x0003003e,0x00000198,0x0000019e,0x000200f9,0x0000019a,0x000200f8,0x0000019a,0x0004003d,
+ 0x00000088,0x0000019f,0x00000198,0x0003003e,0x000000dd,0x0000019f,0x0004003d,0x00000088,
+ 0x000001a0,0x000000d3,0x0004003d,0x00000088,0x000001a1,0x000000d3,0x0008004f,0x000000f4,
+ 0x000001a2,0x000001a1,0x000001a1,0x00000001,0x00000002,0x00000003,0x00050041,0x000000f7,
+ 0x000001a3,0x000000dd,0x00000019,0x0004003d,0x00000087,0x000001a4,0x000001a3,0x00050051,
+ 0x00000087,0x000001a5,0x000001a2,0x00000000,0x00050051,0x00000087,0x000001a6,0x000001a2,
+ 0x00000001,0x00050051,0x00000087,0x000001a7,0x000001a2,0x00000002,0x00070050,0x00000088,
+ 0x000001a8,0x000001a5,0x000001a6,0x000001a7,0x000001a4,0x00050081,0x00000088,0x000001a9,
+ 0x000001a0,0x000001a8,0x0005008e,0x00000088,0x000001aa,0x000001a9,0x000000ff,0x0003003e,
+ 0x000000f2,0x000001aa,0x00050041,0x000000f7,0x000001ac,0x000000d3,0x00000019,0x0004003d,
+ 0x00000087,0x000001ad,0x000001ac,0x00050041,0x000000f7,0x000001ae,0x000000f2,0x00000019,
+ 0x0004003d,0x00000087,0x000001af,0x000001ae,0x00050041,0x000000f7,0x000001b0,0x000000d3,
+ 0x0000001d,0x0004003d,0x00000087,0x000001b1,0x000001b0,0x00050041,0x000000f7,0x000001b2,
+ 0x000000f2,0x0000001d,0x0004003d,0x00000087,0x000001b3,0x000001b2,0x00070050,0x00000088,
+ 0x000001b4,0x000001ad,0x000001af,0x000001b1,0x000001b3,0x0003003e,0x000001ab,0x000001b4,
+ 0x00050041,0x000000f7,0x000001b6,0x000000d3,0x00000035,0x0004003d,0x00000087,0x000001b7,
+ 0x000001b6,0x00050041,0x000000f7,0x000001b8,0x000000f2,0x00000035,0x0004003d,0x00000087,
+ 0x000001b9,0x000001b8,0x00050041,0x000000f7,0x000001ba,0x000000d3,0x00000110,0x0004003d,
+ 0x00000087,0x000001bb,0x000001ba,0x00050041,0x000000f7,0x000001bc,0x000000f2,0x00000110,
+ 0x0004003d,0x00000087,0x000001bd,0x000001bc,0x00070050,0x00000088,0x000001be,0x000001b7,
+ 0x000001b9,0x000001bb,0x000001bd,0x0003003e,0x000001b5,0x000001be,0x0004003d,0x00000088,
+ 0x000001bf,0x00000101,0x0004003d,0x00000088,0x000001c0,0x000001ab,0x00050081,0x00000088,
+ 0x000001c1,0x000001bf,0x000001c0,0x0005008e,0x00000088,0x000001c2,0x000001c1,0x000000ff,
+ 0x0003003e,0x000001ab,0x000001c2,0x0004003d,0x00000088,0x000001c3,0x0000010b,0x0004003d,
+ 0x00000088,0x000001c4,0x000001b5,0x00050081,0x00000088,0x000001c5,0x000001c3,0x000001c4,
+ 0x0005008e,0x00000088,0x000001c6,0x000001c5,0x000000ff,0x0003003e,0x000001b5,0x000001c6,
+ 0x0004003d,0x00000088,0x000001c7,0x000001ab,0x0004003d,0x00000088,0x000001c8,0x000000ba,
+ 0x0005008e,0x00000088,0x000001c9,0x000001c8,0x00000119,0x00050081,0x00000088,0x000001ca,
+ 0x000001c7,0x000001c9,0x00070050,0x00000088,0x000001cb,0x0000011c,0x0000011c,0x0000011c,
+ 0x0000011c,0x00050083,0x00000088,0x000001cc,0x000001ca,0x000001cb,0x0003003e,0x00000116,
+ 0x000001cc,0x0004003d,0x00000088,0x000001cd,0x000001b5,0x0004003d,0x00000088,0x000001ce,
+ 0x000000c2,0x0005008e,0x00000088,0x000001cf,0x000001ce,0x00000119,0x00050081,0x00000088,
+ 0x000001d0,0x000001cd,0x000001cf,0x00070050,0x00000088,0x000001d1,0x0000011c,0x0000011c,
+ 0x0000011c,0x0000011c,0x00050083,0x00000088,0x000001d2,0x000001d0,0x000001d1,0x0003003e,
+ 0x0000011f,0x000001d2,0x0004003d,0x00000088,0x000001d3,0x00000116,0x00070050,0x00000088,
+ 0x000001d4,0x00000127,0x00000127,0x00000127,0x00000127,0x00070050,0x00000088,0x000001d5,
+ 0x00000128,0x00000128,0x00000128,0x00000128,0x0008000c,0x00000088,0x000001d6,0x00000001,
+ 0x0000002b,0x000001d3,0x000001d4,0x000001d5,0x0003003e,0x00000116,0x000001d6,0x0004003d,
+ 0x00000088,0x000001d7,0x0000011f,0x00070050,0x00000088,0x000001d8,0x00000127,0x00000127,
+ 0x00000127,0x00000127,0x00070050,0x00000088,0x000001d9,0x00000128,0x00000128,0x00000128,
+ 0x00000128,0x0008000c,0x00000088,0x000001da,0x00000001,0x0000002b,0x000001d7,0x000001d8,
+ 0x000001d9,0x0003003e,0x0000011f,0x000001da,0x00050041,0x0000001a,0x000001db,0x0000000a,
+ 0x0000001d,0x0004003d,0x00000006,0x000001dc,0x000001db,0x00050041,0x0000002a,0x000001dd,
+ 0x00000027,0x0000006f,0x0004003d,0x00000006,0x000001de,0x000001dd,0x00050082,0x00000006,
+ 0x000001df,0x000001de,0x0000001d,0x000500ae,0x000000e8,0x000001e0,0x000001dc,0x000001df,
+ 0x000300f7,0x000001e3,0x00000000,0x000400fa,0x000001e0,0x000001e2,0x000001e5,0x000200f8,
+ 0x000001e2,0x0004003d,0x00000006,0x000001e4,0x00000130,0x0003003e,0x000001e1,0x000001e4,
+ 0x000200f9,0x000001e3,0x000200f8,0x000001e5,0x0004003d,0x00000006,0x000001e6,0x00000130,
+ 0x00050041,0x0000002a,0x000001e7,0x00000027,0x00000133,0x0004003d,0x00000006,0x000001e8,
+ 0x000001e7,0x00050080,0x00000006,0x000001e9,0x000001e6,0x000001e8,0x0003003e,0x000001e1,
+ 0x000001e9,0x000200f9,0x000001e3,0x000200f8,0x000001e3,0x0004003d,0x00000006,0x000001ea,
+ 0x000001e1,0x0003003e,0x00000130,0x000001ea,0x0004003d,0x00000006,0x000001eb,0x00000130,
+ 0x0004003d,0x00000088,0x000001ec,0x00000116,0x0006000c,0x00000006,0x000001ed,0x00000001,
+ 0x00000037,0x000001ec,0x0004003d,0x00000088,0x000001ee,0x0000011f,0x0006000c,0x00000006,
+ 0x000001ef,0x00000001,0x00000037,0x000001ee,0x00050050,0x00000007,0x000001f0,0x000001ed,
+ 0x000001ef,0x00060041,0x00000084,0x000001f1,0x00000141,0x00000029,0x000001eb,0x0003003e,
+ 0x000001f1,0x000001f0,0x000100fd,0x00010038,0x00050036,0x00000002,0x00000010,0x00000000,
+ 0x00000009,0x00030037,0x00000008,0x0000000e,0x00030037,0x00000008,0x0000000f,0x000200f8,
+ 0x00000011,0x0004003b,0x00000008,0x00000202,0x00000007,0x0004003b,0x00000089,0x00000207,
+ 0x00000007,0x0004003b,0x00000089,0x0000020b,0x00000007,0x0004003b,0x0000001a,0x0000020f,
+ 0x00000007,0x0004003b,0x00000008,0x00000218,0x00000007,0x0004003b,0x00000089,0x00000220,
+ 0x00000007,0x0004003b,0x00000089,0x00000224,0x00000007,0x0004003b,0x00000089,0x0000022f,
+ 0x00000007,0x0004003b,0x00000089,0x00000233,0x00000007,0x0004003b,0x00000089,0x00000240,
+ 0x00000007,0x0004003b,0x00000089,0x00000248,0x00000007,0x0004003b,0x0000001a,0x00000250,
+ 0x00000007,0x0004003b,0x00000089,0x00000259,0x00000007,0x0004003b,0x00000089,0x00000262,
+ 0x00000007,0x0004003b,0x00000089,0x0000026e,0x00000007,0x0004003b,0x00000089,0x00000276,
+ 0x00000007,0x0004003b,0x00000089,0x00000283,0x00000007,0x0004003b,0x00000089,0x0000028d,
+ 0x00000007,0x0004003b,0x00000089,0x00000297,0x00000007,0x0004003b,0x00000089,0x0000029e,
+ 0x00000007,0x0004003b,0x0000001a,0x000002ad,0x00000007,0x0004003b,0x0000001a,0x000002cb,
+ 0x00000007,0x0004003b,0x0000001a,0x000002fc,0x00000007,0x0004003b,0x00000089,0x00000315,
+ 0x00000007,0x0004003b,0x00000089,0x00000329,0x00000007,0x0004003b,0x00000089,0x00000333,
+ 0x00000007,0x00050041,0x0000001a,0x000001f2,0x0000000e,0x0000001d,0x0004003d,0x00000006,
+ 0x000001f3,0x000001f2,0x00050041,0x0000002a,0x000001f4,0x00000027,0x0000006f,0x0004003d,
+ 0x00000006,0x000001f5,0x000001f4,0x00050086,0x00000006,0x000001f6,0x000001f5,0x00000035,
+ 0x00050082,0x00000006,0x000001f7,0x000001f6,0x00000035,0x0008000c,0x00000006,0x000001f8,
+ 0x00000001,0x0000002c,0x000001f3,0x00000019,0x000001f7,0x00050041,0x0000001a,0x000001f9,
+ 0x0000000e,0x0000001d,0x0003003e,0x000001f9,0x000001f8,0x00050041,0x0000001a,0x000001fa,
+ 0x0000000f,0x0000001d,0x0004003d,0x00000006,0x000001fb,0x000001fa,0x00050041,0x0000002a,
+ 0x000001fc,0x00000027,0x00000077,0x0004003d,0x00000006,0x000001fd,0x000001fc,0x00050086,
+ 0x00000006,0x000001fe,0x000001fd,0x00000035,0x00050082,0x00000006,0x000001ff,0x000001fe,
+ 0x0000001d,0x0008000c,0x00000006,0x00000200,0x00000001,0x0000002c,0x000001fb,0x00000019,
+ 0x000001ff,0x00050041,0x0000001a,0x00000201,0x0000000f,0x0000001d,0x0003003e,0x00000201,
+ 0x00000200,0x00050041,0x0000001a,0x00000203,0x0000000e,0x00000019,0x0004003d,0x00000006,
+ 0x00000204,0x00000203,0x00060041,0x00000084,0x00000205,0x00000081,0x00000029,0x00000204,
+ 0x0004003d,0x00000007,0x00000206,0x00000205,0x0003003e,0x00000202,0x00000206,0x00050041,
+ 0x0000001a,0x00000208,0x00000202,0x00000019,0x0004003d,0x00000006,0x00000209,0x00000208,
+ 0x0006000c,0x00000088,0x0000020a,0x00000001,0x00000040,0x00000209,0x0003003e,0x00000207,
+ 0x0000020a,0x00050041,0x0000001a,0x0000020c,0x00000202,0x0000001d,0x0004003d,0x00000006,
+ 0x0000020d,0x0000020c,0x0006000c,0x00000088,0x0000020e,0x00000001,0x00000040,0x0000020d,
+ 0x0003003e,0x0000020b,0x0000020e,0x00050041,0x0000001a,0x00000210,0x0000000e,0x0000001d,
+ 0x0004003d,0x00000006,0x00000211,0x00000210,0x00050041,0x0000002a,0x00000212,0x00000027,
+ 0x00000029,0x0004003d,0x00000006,0x00000213,0x00000212,0x00050084,0x00000006,0x00000214,
+ 0x00000211,0x00000213,0x00050041,0x0000001a,0x00000215,0x0000000e,0x00000019,0x0004003d,
+ 0x00000006,0x00000216,0x00000215,0x00050080,0x00000006,0x00000217,0x00000214,0x00000216,
+ 0x0003003e,0x0000020f,0x00000217,0x0004003d,0x00000006,0x0000021d,0x0000020f,0x00060041,
+ 0x00000084,0x0000021e,0x0000021c,0x00000029,0x0000021d,0x0004003d,0x00000007,0x0000021f,
+ 0x0000021e,0x0003003e,0x00000218,0x0000021f,0x00050041,0x0000001a,0x00000221,0x00000218,
+ 0x00000019,0x0004003d,0x00000006,0x00000222,0x00000221,0x0006000c,0x00000088,0x00000223,
+ 0x00000001,0x00000040,0x00000222,0x0003003e,0x00000220,0x00000223,0x00050041,0x0000001a,
+ 0x00000225,0x00000218,0x0000001d,0x0004003d,0x00000006,0x00000226,0x00000225,0x0006000c,
+ 0x00000088,0x00000227,0x00000001,0x00000040,0x00000226,0x0003003e,0x00000224,0x00000227,
+ 0x0004003d,0x00000006,0x0000022c,0x0000020f,0x00060041,0x00000084,0x0000022d,0x0000022b,
+ 0x00000029,0x0000022c,0x0004003d,0x00000007,0x0000022e,0x0000022d,0x0003003e,0x00000218,
+ 0x0000022e,0x00050041,0x0000001a,0x00000230,0x00000218,0x00000019,0x0004003d,0x00000006,
+ 0x00000231,0x00000230,0x0006000c,0x00000088,0x00000232,0x00000001,0x00000040,0x00000231,
+ 0x0003003e,0x0000022f,0x00000232,0x00050041,0x0000001a,0x00000234,0x00000218,0x0000001d,
+ 0x0004003d,0x00000006,0x00000235,0x00000234,0x0006000c,0x00000088,0x00000236,0x00000001,
+ 0x00000040,0x00000235,0x0003003e,0x00000233,0x00000236,0x0004003d,0x00000088,0x00000238,
+ 0x00000207,0x0007004f,0x00000237,0x00000239,0x00000238,0x00000238,0x00000000,0x00000002,
+ 0x0004003d,0x00000088,0x0000023a,0x00000207,0x0009004f,0x00000088,0x0000023b,0x0000023a,
+ 0x00000239,0x00000000,0x00000004,0x00000002,0x00000005,0x0003003e,0x00000207,0x0000023b,
+ 0x0004003d,0x00000088,0x0000023c,0x0000020b,0x0007004f,0x00000237,0x0000023d,0x0000023c,
+ 0x0000023c,0x00000000,0x00000002,0x0004003d,0x00000088,0x0000023e,0x0000020b,0x0009004f,
+ 0x00000088,0x0000023f,0x0000023e,0x0000023d,0x00000000,0x00000004,0x00000002,0x00000005,
+ 0x0003003e,0x0000020b,0x0000023f,0x0004003d,0x00000088,0x00000241,0x00000220,0x0004003d,
+ 0x00000088,0x00000242,0x0000022f,0x00050083,0x00000088,0x00000243,0x00000241,0x00000242,
+ 0x0004003d,0x00000088,0x00000244,0x00000207,0x00050085,0x00000088,0x00000245,0x00000243,
+ 0x00000244,0x0004003d,0x00000088,0x00000246,0x0000022f,0x00050081,0x00000088,0x00000247,
+ 0x00000245,0x00000246,0x0003003e,0x00000240,0x00000247,0x0004003d,0x00000088,0x00000249,
+ 0x00000224,0x0004003d,0x00000088,0x0000024a,0x00000233,0x00050083,0x00000088,0x0000024b,
+ 0x00000249,0x0000024a,0x0004003d,0x00000088,0x0000024c,0x0000020b,0x00050085,0x00000088,
+ 0x0000024d,0x0000024b,0x0000024c,0x0004003d,0x00000088,0x0000024e,0x00000233,0x00050081,
+ 0x00000088,0x0000024f,0x0000024d,0x0000024e,0x0003003e,0x00000248,0x0000024f,0x00050041,
+ 0x0000001a,0x00000251,0x0000000f,0x0000001d,0x0004003d,0x00000006,0x00000252,0x00000251,
+ 0x00050041,0x0000002a,0x00000253,0x00000027,0x0000003a,0x0004003d,0x00000006,0x00000254,
+ 0x00000253,0x00050084,0x00000006,0x00000255,0x00000252,0x00000254,0x00050041,0x0000001a,
+ 0x00000256,0x0000000f,0x00000019,0x0004003d,0x00000006,0x00000257,0x00000256,0x00050080,
+ 0x00000006,0x00000258,0x00000255,0x00000257,0x0003003e,0x00000250,0x00000258,0x0004003d,
+ 0x00000006,0x0000025e,0x00000250,0x00060041,0x000000d9,0x0000025f,0x0000025d,0x00000029,
+ 0x0000025e,0x0004003d,0x00000006,0x00000260,0x0000025f,0x0006000c,0x00000088,0x00000261,
+ 0x00000001,0x00000040,0x00000260,0x0003003e,0x00000259,0x00000261,0x0004003d,0x00000006,
+ 0x00000263,0x00000250,0x00050080,0x00000006,0x00000264,0x00000263,0x0000001d,0x00060041,
+ 0x000000d9,0x00000265,0x0000025d,0x00000029,0x00000264,0x0004003d,0x00000006,0x00000266,
+ 0x00000265,0x0006000c,0x00000088,0x00000267,0x00000001,0x00000040,0x00000266,0x0003003e,
+ 0x00000262,0x00000267,0x00050041,0x0000001a,0x00000268,0x0000000f,0x00000019,0x0004003d,
+ 0x00000006,0x00000269,0x00000268,0x00050041,0x0000002a,0x0000026a,0x00000027,0x0000003a,
+ 0x0004003d,0x00000006,0x0000026b,0x0000026a,0x00050082,0x00000006,0x0000026c,0x0000026b,
+ 0x0000001d,0x000500aa,0x000000e8,0x0000026d,0x00000269,0x0000026c,0x000300f7,0x00000270,
+ 0x00000000,0x000400fa,0x0000026d,0x0000026f,0x00000273,0x000200f8,0x0000026f,0x0004003d,
+ 0x00000088,0x00000271,0x00000259,0x0009004f,0x00000088,0x00000272,0x00000271,0x00000271,
+ 0x00000002,0x00000003,0x00000002,0x00000003,0x0003003e,0x0000026e,0x00000272,0x000200f9,
+ 0x00000270,0x000200f8,0x00000273,0x0004003d,0x00000088,0x00000274,0x00000262,0x0003003e,
+ 0x0000026e,0x00000274,0x000200f9,0x00000270,0x000200f8,0x00000270,0x0004003d,0x00000088,
+ 0x00000275,0x0000026e,0x0003003e,0x00000262,0x00000275,0x0004003d,0x00000088,0x00000277,
+ 0x00000259,0x0004003d,0x00000088,0x00000278,0x00000259,0x0007004f,0x00000237,0x00000279,
+ 0x00000278,0x00000278,0x00000002,0x00000003,0x0004003d,0x00000088,0x0000027a,0x00000262,
+ 0x0007004f,0x00000237,0x0000027b,0x0000027a,0x0000027a,0x00000000,0x00000001,0x00050051,
+ 0x00000087,0x0000027c,0x00000279,0x00000000,0x00050051,0x00000087,0x0000027d,0x00000279,
+ 0x00000001,0x00050051,0x00000087,0x0000027e,0x0000027b,0x00000000,0x00050051,0x00000087,
+ 0x0000027f,0x0000027b,0x00000001,0x00070050,0x00000088,0x00000280,0x0000027c,0x0000027d,
+ 0x0000027e,0x0000027f,0x00050081,0x00000088,0x00000281,0x00000277,0x00000280,0x0005008e,
+ 0x00000088,0x00000282,0x00000281,0x000000ff,0x0003003e,0x00000276,0x00000282,0x0004003d,
+ 0x00000088,0x00000284,0x00000259,0x0007004f,0x00000237,0x00000285,0x00000284,0x00000284,
+ 0x00000000,0x00000001,0x0004003d,0x00000088,0x00000286,0x00000276,0x0007004f,0x00000237,
+ 0x00000287,0x00000286,0x00000286,0x00000000,0x00000001,0x00050051,0x00000087,0x00000288,
+ 0x00000285,0x00000000,0x00050051,0x00000087,0x00000289,0x00000285,0x00000001,0x00050051,
+ 0x00000087,0x0000028a,0x00000287,0x00000000,0x00050051,0x00000087,0x0000028b,0x00000287,
+ 0x00000001,0x00070050,0x00000088,0x0000028c,0x00000288,0x00000289,0x0000028a,0x0000028b,
+ 0x0003003e,0x00000283,0x0000028c,0x0004003d,0x00000088,0x0000028e,0x00000259,0x0007004f,
+ 0x00000237,0x0000028f,0x0000028e,0x0000028e,0x00000002,0x00000003,0x0004003d,0x00000088,
+ 0x00000290,0x00000276,0x0007004f,0x00000237,0x00000291,0x00000290,0x00000290,0x00000002,
+ 0x00000003,0x00050051,0x00000087,0x00000292,0x0000028f,0x00000000,0x00050051,0x00000087,
+ 0x00000293,0x0000028f,0x00000001,0x00050051,0x00000087,0x00000294,0x00000291,0x00000000,
+ 0x00050051,0x00000087,0x00000295,0x00000291,0x00000001,0x00070050,0x00000088,0x00000296,
+ 0x00000292,0x00000293,0x00000294,0x00000295,0x0003003e,0x0000028d,0x00000296,0x0004003d,
+ 0x00000088,0x00000298,0x00000283,0x0004003d,0x00000088,0x00000299,0x00000240,0x0005008e,
+ 0x00000088,0x0000029a,0x00000299,0x00000119,0x00050081,0x00000088,0x0000029b,0x00000298,
+ 0x0000029a,0x00070050,0x00000088,0x0000029c,0x0000011c,0x0000011c,0x0000011c,0x0000011c,
+ 0x00050083,0x00000088,0x0000029d,0x0000029b,0x0000029c,0x0003003e,0x00000297,0x0000029d,
+ 0x0004003d,0x00000088,0x0000029f,0x0000028d,0x0004003d,0x00000088,0x000002a0,0x00000248,
+ 0x0005008e,0x00000088,0x000002a1,0x000002a0,0x00000119,0x00050081,0x00000088,0x000002a2,
+ 0x0000029f,0x000002a1,0x00070050,0x00000088,0x000002a3,0x0000011c,0x0000011c,0x0000011c,
+ 0x0000011c,0x00050083,0x00000088,0x000002a4,0x000002a2,0x000002a3,0x0003003e,0x0000029e,
+ 0x000002a4,0x0004003d,0x00000088,0x000002a5,0x00000297,0x00070050,0x00000088,0x000002a6,
+ 0x00000127,0x00000127,0x00000127,0x00000127,0x00070050,0x00000088,0x000002a7,0x00000128,
+ 0x00000128,0x00000128,0x00000128,0x0008000c,0x00000088,0x000002a8,0x00000001,0x0000002b,
+ 0x000002a5,0x000002a6,0x000002a7,0x0003003e,0x00000297,0x000002a8,0x0004003d,0x00000088,
+ 0x000002a9,0x0000029e,0x00070050,0x00000088,0x000002aa,0x00000127,0x00000127,0x00000127,
+ 0x00000127,0x00070050,0x00000088,0x000002ab,0x00000128,0x00000128,0x00000128,0x00000128,
+ 0x0008000c,0x00000088,0x000002ac,0x00000001,0x0000002b,0x000002a9,0x000002aa,0x000002ab,
+ 0x0003003e,0x0000029e,0x000002ac,0x00050041,0x0000001a,0x000002ae,0x0000000e,0x0000001d,
+ 0x0004003d,0x00000006,0x000002af,0x000002ae,0x00050041,0x0000002a,0x000002b0,0x00000027,
+ 0x00000133,0x0004003d,0x00000006,0x000002b1,0x000002b0,0x00050084,0x00000006,0x000002b2,
+ 0x000002af,0x000002b1,0x00050041,0x0000002a,0x000002b3,0x00000027,0x00000137,0x0004003d,
+ 0x00000006,0x000002b4,0x000002b3,0x00050080,0x00000006,0x000002b5,0x000002b2,0x000002b4,
+ 0x00050041,0x0000001a,0x000002b6,0x0000000e,0x00000019,0x0004003d,0x00000006,0x000002b7,
+ 0x000002b6,0x00050080,0x00000006,0x000002b8,0x000002b5,0x000002b7,0x0003003e,0x000002ad,
+ 0x000002b8,0x0004003d,0x00000006,0x000002bd,0x000002ad,0x0004003d,0x00000088,0x000002be,
+ 0x00000297,0x0006000c,0x00000006,0x000002bf,0x00000001,0x00000037,0x000002be,0x0004003d,
+ 0x00000088,0x000002c0,0x0000029e,0x0006000c,0x00000006,0x000002c1,0x00000001,0x00000037,
+ 0x000002c0,0x00050050,0x00000007,0x000002c2,0x000002bf,0x000002c1,0x00060041,0x00000084,
+ 0x000002c3,0x000002bc,0x00000029,0x000002bd,0x0003003e,0x000002c3,0x000002c2,0x00050041,
+ 0x0000001a,0x000002c4,0x0000000e,0x0000001d,0x0004003d,0x00000006,0x000002c5,0x000002c4,
+ 0x00050041,0x0000002a,0x000002c6,0x00000027,0x0000006f,0x0004003d,0x00000006,0x000002c7,
+ 0x000002c6,0x00050086,0x00000006,0x000002c8,0x000002c7,0x00000035,0x00050082,0x00000006,
+ 0x000002c9,0x000002c8,0x0000001d,0x000500ae,0x000000e8,0x000002ca,0x000002c5,0x000002c9,
+ 0x000300f7,0x000002cd,0x00000000,0x000400fa,0x000002ca,0x000002cc,0x000002cf,0x000200f8,
+ 0x000002cc,0x0004003d,0x00000006,0x000002ce,0x0000020f,0x0003003e,0x000002cb,0x000002ce,
+ 0x000200f9,0x000002cd,0x000200f8,0x000002cf,0x0004003d,0x00000006,0x000002d0,0x0000020f,
+ 0x00050041,0x0000002a,0x000002d1,0x00000027,0x00000029,0x0004003d,0x00000006,0x000002d2,
+ 0x000002d1,0x00050080,0x00000006,0x000002d3,0x000002d0,0x000002d2,0x0003003e,0x000002cb,
+ 0x000002d3,0x000200f9,0x000002cd,0x000200f8,0x000002cd,0x0004003d,0x00000006,0x000002d4,
+ 0x000002cb,0x0003003e,0x0000020f,0x000002d4,0x0004003d,0x00000006,0x000002d5,0x0000020f,
+ 0x00060041,0x00000084,0x000002d6,0x0000021c,0x00000029,0x000002d5,0x0004003d,0x00000007,
+ 0x000002d7,0x000002d6,0x0003003e,0x00000218,0x000002d7,0x00050041,0x0000001a,0x000002d8,
+ 0x00000218,0x00000019,0x0004003d,0x00000006,0x000002d9,0x000002d8,0x0006000c,0x00000088,
+ 0x000002da,0x00000001,0x00000040,0x000002d9,0x0003003e,0x00000220,0x000002da,0x00050041,
+ 0x0000001a,0x000002db,0x00000218,0x0000001d,0x0004003d,0x00000006,0x000002dc,0x000002db,
+ 0x0006000c,0x00000088,0x000002dd,0x00000001,0x00000040,0x000002dc,0x0003003e,0x00000224,
+ 0x000002dd,0x0004003d,0x00000006,0x000002de,0x0000020f,0x00060041,0x00000084,0x000002df,
+ 0x0000022b,0x00000029,0x000002de,0x0004003d,0x00000007,0x000002e0,0x000002df,0x0003003e,
+ 0x00000218,0x000002e0,0x00050041,0x0000001a,0x000002e1,0x00000218,0x00000019,0x0004003d,
+ 0x00000006,0x000002e2,0x000002e1,0x0006000c,0x00000088,0x000002e3,0x00000001,0x00000040,
+ 0x000002e2,0x0003003e,0x0000022f,0x000002e3,0x00050041,0x0000001a,0x000002e4,0x00000218,
+ 0x0000001d,0x0004003d,0x00000006,0x000002e5,0x000002e4,0x0006000c,0x00000088,0x000002e6,
+ 0x00000001,0x00000040,0x000002e5,0x0003003e,0x00000233,0x000002e6,0x0004003d,0x00000088,
+ 0x000002e7,0x00000220,0x0004003d,0x00000088,0x000002e8,0x0000022f,0x00050083,0x00000088,
+ 0x000002e9,0x000002e7,0x000002e8,0x0004003d,0x00000088,0x000002ea,0x00000207,0x00050085,
+ 0x00000088,0x000002eb,0x000002e9,0x000002ea,0x0004003d,0x00000088,0x000002ec,0x0000022f,
+ 0x00050081,0x00000088,0x000002ed,0x000002eb,0x000002ec,0x0003003e,0x00000240,0x000002ed,
+ 0x0004003d,0x00000088,0x000002ee,0x00000224,0x0004003d,0x00000088,0x000002ef,0x00000233,
+ 0x00050083,0x00000088,0x000002f0,0x000002ee,0x000002ef,0x0004003d,0x00000088,0x000002f1,
+ 0x0000020b,0x00050085,0x00000088,0x000002f2,0x000002f0,0x000002f1,0x0004003d,0x00000088,
+ 0x000002f3,0x00000233,0x00050081,0x00000088,0x000002f4,0x000002f2,0x000002f3,0x0003003e,
+ 0x00000248,0x000002f4,0x00050041,0x0000001a,0x000002f5,0x0000000f,0x0000001d,0x0004003d,
+ 0x00000006,0x000002f6,0x000002f5,0x00050041,0x0000002a,0x000002f7,0x00000027,0x00000077,
+ 0x0004003d,0x00000006,0x000002f8,0x000002f7,0x00050086,0x00000006,0x000002f9,0x000002f8,
+ 0x00000035,0x00050082,0x00000006,0x000002fa,0x000002f9,0x0000001d,0x000500ae,0x000000e8,
+ 0x000002fb,0x000002f6,0x000002fa,0x000300f7,0x000002fe,0x00000000,0x000400fa,0x000002fb,
+ 0x000002fd,0x00000300,0x000200f8,0x000002fd,0x0004003d,0x00000006,0x000002ff,0x00000250,
+ 0x0003003e,0x000002fc,0x000002ff,0x000200f9,0x000002fe,0x000200f8,0x00000300,0x0004003d,
+ 0x00000006,0x00000301,0x00000250,0x00050041,0x0000002a,0x00000302,0x00000027,0x0000003a,
+ 0x0004003d,0x00000006,0x00000303,0x00000302,0x00050080,0x00000006,0x00000304,0x00000301,
+ 0x00000303,0x0003003e,0x000002fc,0x00000304,0x000200f9,0x000002fe,0x000200f8,0x000002fe,
+ 0x0004003d,0x00000006,0x00000305,0x000002fc,0x0003003e,0x00000250,0x00000305,0x0004003d,
+ 0x00000006,0x00000306,0x00000250,0x00060041,0x000000d9,0x00000307,0x0000025d,0x00000029,
+ 0x00000306,0x0004003d,0x00000006,0x00000308,0x00000307,0x0006000c,0x00000088,0x00000309,
+ 0x00000001,0x00000040,0x00000308,0x0003003e,0x00000259,0x00000309,0x0004003d,0x00000006,
+ 0x0000030a,0x00000250,0x00050080,0x00000006,0x0000030b,0x0000030a,0x0000001d,0x00060041,
+ 0x000000d9,0x0000030c,0x0000025d,0x00000029,0x0000030b,0x0004003d,0x00000006,0x0000030d,
+ 0x0000030c,0x0006000c,0x00000088,0x0000030e,0x00000001,0x00000040,0x0000030d,0x0003003e,
+ 0x00000262,0x0000030e,0x00050041,0x0000001a,0x0000030f,0x0000000f,0x00000019,0x0004003d,
+ 0x00000006,0x00000310,0x0000030f,0x00050041,0x0000002a,0x00000311,0x00000027,0x0000003a,
+ 0x0004003d,0x00000006,0x00000312,0x00000311,0x00050082,0x00000006,0x00000313,0x00000312,
+ 0x0000001d,0x000500aa,0x000000e8,0x00000314,0x00000310,0x00000313,0x000300f7,0x00000317,
+ 0x00000000,0x000400fa,0x00000314,0x00000316,0x0000031a,0x000200f8,0x00000316,0x0004003d,
+ 0x00000088,0x00000318,0x00000259,0x0009004f,0x00000088,0x00000319,0x00000318,0x00000318,
+ 0x00000002,0x00000003,0x00000002,0x00000003,0x0003003e,0x00000315,0x00000319,0x000200f9,
+ 0x00000317,0x000200f8,0x0000031a,0x0004003d,0x00000088,0x0000031b,0x00000262,0x0003003e,
+ 0x00000315,0x0000031b,0x000200f9,0x00000317,0x000200f8,0x00000317,0x0004003d,0x00000088,
+ 0x0000031c,0x00000315,0x0003003e,0x00000262,0x0000031c,0x0004003d,0x00000088,0x0000031d,
+ 0x00000259,0x0004003d,0x00000088,0x0000031e,0x00000259,0x0007004f,0x00000237,0x0000031f,
+ 0x0000031e,0x0000031e,0x00000002,0x00000003,0x0004003d,0x00000088,0x00000320,0x00000262,
+ 0x0007004f,0x00000237,0x00000321,0x00000320,0x00000320,0x00000000,0x00000001,0x00050051,
+ 0x00000087,0x00000322,0x0000031f,0x00000000,0x00050051,0x00000087,0x00000323,0x0000031f,
+ 0x00000001,0x00050051,0x00000087,0x00000324,0x00000321,0x00000000,0x00050051,0x00000087,
+ 0x00000325,0x00000321,0x00000001,0x00070050,0x00000088,0x00000326,0x00000322,0x00000323,
+ 0x00000324,0x00000325,0x00050081,0x00000088,0x00000327,0x0000031d,0x00000326,0x0005008e,
+ 0x00000088,0x00000328,0x00000327,0x000000ff,0x0003003e,0x00000276,0x00000328,0x0004003d,
+ 0x00000088,0x0000032a,0x00000259,0x0007004f,0x00000237,0x0000032b,0x0000032a,0x0000032a,
+ 0x00000000,0x00000001,0x0004003d,0x00000088,0x0000032c,0x00000276,0x0007004f,0x00000237,
+ 0x0000032d,0x0000032c,0x0000032c,0x00000000,0x00000001,0x00050051,0x00000087,0x0000032e,
+ 0x0000032b,0x00000000,0x00050051,0x00000087,0x0000032f,0x0000032b,0x00000001,0x00050051,
+ 0x00000087,0x00000330,0x0000032d,0x00000000,0x00050051,0x00000087,0x00000331,0x0000032d,
+ 0x00000001,0x00070050,0x00000088,0x00000332,0x0000032e,0x0000032f,0x00000330,0x00000331,
+ 0x0003003e,0x00000329,0x00000332,0x0004003d,0x00000088,0x00000334,0x00000259,0x0007004f,
+ 0x00000237,0x00000335,0x00000334,0x00000334,0x00000002,0x00000003,0x0004003d,0x00000088,
+ 0x00000336,0x00000276,0x0007004f,0x00000237,0x00000337,0x00000336,0x00000336,0x00000002,
+ 0x00000003,0x00050051,0x00000087,0x00000338,0x00000335,0x00000000,0x00050051,0x00000087,
+ 0x00000339,0x00000335,0x00000001,0x00050051,0x00000087,0x0000033a,0x00000337,0x00000000,
+ 0x00050051,0x00000087,0x0000033b,0x00000337,0x00000001,0x00070050,0x00000088,0x0000033c,
+ 0x00000338,0x00000339,0x0000033a,0x0000033b,0x0003003e,0x00000333,0x0000033c,0x0004003d,
+ 0x00000088,0x0000033d,0x00000283,0x0004003d,0x00000088,0x0000033e,0x00000329,0x00050081,
+ 0x00000088,0x0000033f,0x0000033d,0x0000033e,0x0005008e,0x00000088,0x00000340,0x0000033f,
+ 0x000000ff,0x0003003e,0x00000329,0x00000340,0x0004003d,0x00000088,0x00000341,0x0000028d,
+ 0x0004003d,0x00000088,0x00000342,0x00000333,0x00050081,0x00000088,0x00000343,0x00000341,
+ 0x00000342,0x0005008e,0x00000088,0x00000344,0x00000343,0x000000ff,0x0003003e,0x00000333,
+ 0x00000344,0x0004003d,0x00000088,0x00000345,0x00000329,0x0004003d,0x00000088,0x00000346,
+ 0x00000240,0x0005008e,0x00000088,0x00000347,0x00000346,0x00000119,0x00050081,0x00000088,
+ 0x00000348,0x00000345,0x00000347,0x00070050,0x00000088,0x00000349,0x0000011c,0x0000011c,
+ 0x0000011c,0x0000011c,0x00050083,0x00000088,0x0000034a,0x00000348,0x00000349,0x0003003e,
+ 0x00000297,0x0000034a,0x0004003d,0x00000088,0x0000034b,0x00000333,0x0004003d,0x00000088,
+ 0x0000034c,0x00000248,0x0005008e,0x00000088,0x0000034d,0x0000034c,0x00000119,0x00050081,
+ 0x00000088,0x0000034e,0x0000034b,0x0000034d,0x00070050,0x00000088,0x0000034f,0x0000011c,
+ 0x0000011c,0x0000011c,0x0000011c,0x00050083,0x00000088,0x00000350,0x0000034e,0x0000034f,
+ 0x0003003e,0x0000029e,0x00000350,0x0004003d,0x00000088,0x00000351,0x00000297,0x00070050,
+ 0x00000088,0x00000352,0x00000127,0x00000127,0x00000127,0x00000127,0x00070050,0x00000088,
+ 0x00000353,0x00000128,0x00000128,0x00000128,0x00000128,0x0008000c,0x00000088,0x00000354,
+ 0x00000001,0x0000002b,0x00000351,0x00000352,0x00000353,0x0003003e,0x00000297,0x00000354,
+ 0x0004003d,0x00000088,0x00000355,0x0000029e,0x00070050,0x00000088,0x00000356,0x00000127,
+ 0x00000127,0x00000127,0x00000127,0x00070050,0x00000088,0x00000357,0x00000128,0x00000128,
+ 0x00000128,0x00000128,0x0008000c,0x00000088,0x00000358,0x00000001,0x0000002b,0x00000355,
+ 0x00000356,0x00000357,0x0003003e,0x0000029e,0x00000358,0x00050041,0x0000002a,0x00000359,
+ 0x00000027,0x00000133,0x0004003d,0x00000006,0x0000035a,0x00000359,0x0004003d,0x00000006,
+ 0x0000035b,0x000002ad,0x00050080,0x00000006,0x0000035c,0x0000035b,0x0000035a,0x0003003e,
+ 0x000002ad,0x0000035c,0x0004003d,0x00000006,0x0000035d,0x000002ad,0x0004003d,0x00000088,
+ 0x0000035e,0x00000297,0x0006000c,0x00000006,0x0000035f,0x00000001,0x00000037,0x0000035e,
+ 0x0004003d,0x00000088,0x00000360,0x0000029e,0x0006000c,0x00000006,0x00000361,0x00000001,
+ 0x00000037,0x00000360,0x00050050,0x00000007,0x00000362,0x0000035f,0x00000361,0x00060041,
+ 0x00000084,0x00000363,0x000002bc,0x00000029,0x0000035d,0x0003003e,0x00000363,0x00000362,
+ 0x000100fd,0x00010038
diff --git a/tests/.gitignore b/tests/.gitignore
index 61440c7..0c8a72d 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -7,3 +7,7 @@ test-image-stitching
test-pipe-manager
test-video-stabilization
test-soft-image
+test-gles-handler
+test-render-surround-view
+test-surround-view
+test-vk-handler
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 6e68880..eb27a9e 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,126 +1,253 @@
-XCORE_DIR = $(top_srcdir)/xcore
-MODULES_DIR = $(top_srcdir)/modules
+noinst_PROGRAMS = \
+ test-soft-image \
+ test-surround-view \
+ test-device-manager \
+ $(NULL)
-TEST_BASE_CXXFLAGS = $(XCAM_CXXFLAGS)
-if HAVE_LIBDRM
-TEST_BASE_CXXFLAGS += $(LIBDRM_CFLAGS) $(LIBDRM_LIBS)
+if HAVE_LIBCL
+noinst_PROGRAMS += \
+ test-cl-image \
+ test-image-blend \
+ test-pipe-manager \
+ test-binary-kernel \
+ test-image-stitching \
+ test-video-stabilization \
+ $(NULL)
endif
-if USE_LOCAL_ATOMISP
-TEST_BASE_CXXFLAGS += -I$(top_srcdir)/ext/atomisp
+if HAVE_GLES
+noinst_PROGRAMS += \
+ test-gles-handler \
+ $(NULL)
endif
-TEST_BASE_CXXFLAGS += \
- -I$(XCORE_DIR) \
- -I$(MODULES_DIR) \
- $(NULL)
-
-TEST_BASE_LA = \
- $(NULL)
-
-noinst_PROGRAMS = \
- test-device-manager \
- test-soft-image \
- $(NULL)
-
-if ENABLE_IA_AIQ
+if HAVE_VULKAN
noinst_PROGRAMS += \
- test-poll-thread \
- $(NULL)
+ test-vk-handler \
+ $(NULL)
endif
-if HAVE_LIBCL
+if ENABLE_RENDER
noinst_PROGRAMS += \
- test-cl-image \
- test-binary-kernel \
- test-pipe-manager \
- test-image-blend \
- test-image-stitching \
- test-video-stabilization \
- $(NULL)
+ test-render-surround-view \
+ $(NULL)
+endif
-TEST_BASE_LA += $(top_builddir)/modules/ocl/libxcam_ocl.la
+if ENABLE_DNN
+noinst_PROGRAMS += \
+ test-dnn-inference \
+ $(NULL)
+endif
if HAVE_OPENCV
noinst_PROGRAMS += \
- test-image-deblurring \
- $(NULL)
-
-TEST_BASE_CXXFLAGS += $(OPENCV_CFLAGS)
-TEST_BASE_LA += $(OPENCV_LIBS)
-endif
+ test-image-deblurring \
+ $(NULL)
endif
-TEST_BASE_LA += \
- $(top_builddir)/xcore/libxcam_core.la \
- $(NULL)
+TEST_BASE_CXXFLAGS = \
+ $(XCAM_CXXFLAGS) \
+ -I$(top_srcdir)/xcore \
+ -I$(top_srcdir)/modules \
+ $(NULL)
-test_device_manager_SOURCES = test-device-manager.cpp
-test_device_manager_CXXFLAGS = $(TEST_BASE_CXXFLAGS)
-test_device_manager_LDADD = $(TEST_BASE_LA)
+TEST_BASE_LA = \
+ $(top_builddir)/xcore/libxcam_core.la \
+ $(NULL)
-if ENABLE_IA_AIQ
-ISP_LA = $(top_builddir)/modules/isp/libxcam_isp.la
+if HAVE_OPENCV
+XCAM_OCV_CFLAGS = $(OPENCV_CFLAGS)
+XCAM_OCV_LIBS = $(OPENCV_LIBS)
+XCAM_OCV_LA = $(top_builddir)/modules/ocv/libxcam_ocv.la
+endif
-test_device_manager_LDADD += $(ISP_LA)
+if HAVE_LIBDRM
+TEST_DRM_CFLAGS = $(LIBDRM_CFLAGS)
+TEST_DRM_LIBS = \
+ -ldrm_intel \
+ $(LIBDRM_LIBS) \
+ $(NULL)
+endif
-test_poll_thread_SOURCES = test-poll-thread.cpp
-test_poll_thread_CXXFLAGS = $(TEST_BASE_CXXFLAGS)
-test_poll_thread_LDADD = \
- $(TEST_BASE_LA) $(ISP_LA) \
- $(NULL)
+test_device_manager_SOURCES = test-device-manager.cpp
+test_device_manager_CXXFLAGS = \
+ $(TEST_BASE_CXXFLAGS) \
+ $(TEST_DRM_CFLAGS) \
+ $(NULL)
+test_device_manager_LDADD = \
+ $(TEST_BASE_LA) \
+ $(TEST_DRM_LIBS) \
+ $(NULL)
+if USE_LOCAL_ATOMISP
+test_device_manager_CXXFLAGS += -I$(top_srcdir)/ext/atomisp
+endif
+if ENABLE_IA_AIQ
+test_device_manager_LDADD += $(top_builddir)/modules/isp/libxcam_isp.la
endif
if HAVE_LIBCL
+test_device_manager_LDADD += $(top_builddir)/modules/ocl/libxcam_ocl.la
+
+TEST_OCL_CXXFLAGS = \
+ $(TEST_BASE_CXXFLAGS) \
+ $(TEST_DRM_CFLAGS) \
+ $(NULL)
+
+TEST_OCL_LDADD = \
+ $(TEST_BASE_LA) \
+ $(TEST_DRM_LIBS) \
+ $(top_builddir)/modules/ocl/libxcam_ocl.la \
+ $(NULL)
+
test_cl_image_SOURCES = test-cl-image.cpp
-test_cl_image_CXXFLAGS = $(TEST_BASE_CXXFLAGS)
-test_cl_image_LDADD = \
- $(TEST_BASE_LA) \
- $(NULL)
+test_cl_image_CXXFLAGS = $(TEST_OCL_CXXFLAGS)
+test_cl_image_LDADD = $(TEST_OCL_LDADD)
test_binary_kernel_SOURCES = test-binary-kernel.cpp
-test_binary_kernel_CXXFLAGS = $(TEST_BASE_CXXFLAGS)
-test_binary_kernel_LDADD = \
- $(TEST_BASE_LA) \
- $(NULL)
+test_binary_kernel_CXXFLAGS = $(TEST_OCL_CXXFLAGS)
+test_binary_kernel_LDADD = $(TEST_OCL_LDADD)
test_pipe_manager_SOURCES = test-pipe-manager.cpp
-test_pipe_manager_CXXFLAGS = $(TEST_BASE_CXXFLAGS)
-test_pipe_manager_LDADD = \
- $(TEST_BASE_LA) \
- $(NULL)
+test_pipe_manager_CXXFLAGS = $(TEST_OCL_CXXFLAGS)
+test_pipe_manager_LDADD = $(TEST_OCL_LDADD)
test_image_blend_SOURCES = test-image-blend.cpp
-test_image_blend_CXXFLAGS = $(TEST_BASE_CXXFLAGS)
-test_image_blend_LDADD = \
- $(TEST_BASE_LA) \
- $(NULL)
+test_image_blend_CXXFLAGS = $(TEST_OCL_CXXFLAGS)
+test_image_blend_LDADD = $(TEST_OCL_LDADD)
test_image_stitching_SOURCES = test-image-stitching.cpp
-test_image_stitching_CXXFLAGS = $(TEST_BASE_CXXFLAGS)
+test_image_stitching_CXXFLAGS = \
+ $(TEST_OCL_CXXFLAGS) \
+ $(XCAM_OCV_CFLAGS) \
+ $(NULL)
test_image_stitching_LDADD = \
- $(TEST_BASE_LA) \
- $(NULL)
+ $(TEST_OCL_LDADD) \
+ $(XCAM_OCV_LIBS) \
+ $(XCAM_OCV_LA) \
+ $(NULL)
test_video_stabilization_SOURCES = test-video-stabilization.cpp
-test_video_stabilization_CXXFLAGS = $(TEST_BASE_CXXFLAGS)
+test_video_stabilization_CXXFLAGS = \
+ $(TEST_OCL_CXXFLAGS) \
+ $(XCAM_OCV_CFLAGS) \
+ $(NULL)
test_video_stabilization_LDADD = \
- $(TEST_BASE_LA) \
- $(NULL)
+ $(TEST_OCL_LDADD) \
+ $(XCAM_OCV_LIBS) \
+ $(XCAM_OCV_LA) \
+ $(NULL)
+endif
if HAVE_OPENCV
test_image_deblurring_SOURCES = test-image-deblurring.cpp
-test_image_deblurring_CXXFLAGS = $(TEST_BASE_CXXFLAGS)
- $(NULL)
+test_image_deblurring_CXXFLAGS = \
+ $(TEST_BASE_CXXFLAGS) \
+ $(XCAM_OCV_CFLAGS) \
+ $(NULL)
test_image_deblurring_LDADD = \
- $(TEST_BASE_LA) \
- $(NULL)
-endif
+ $(TEST_BASE_LA) \
+ $(XCAM_OCV_LIBS) \
+ $(XCAM_OCV_LA) \
+ $(NULL)
endif
+TEST_SOFT_LA = $(top_builddir)/modules/soft/libxcam_soft.la
+
test_soft_image_SOURCES = test-soft-image.cpp
-test_soft_image_CXXFLAGS = $(TEST_BASE_CXXFLAGS)
-test_soft_image_LDADD = \
- $(top_builddir)/modules/soft/libxcam_soft.la \
- $(TEST_BASE_LA) \
- $(NULL)
+test_soft_image_CXXFLAGS = \
+ $(TEST_BASE_CXXFLAGS) \
+ $(XCAM_OCV_CFLAGS) \
+ $(NULL)
+test_soft_image_LDADD = \
+ $(TEST_BASE_LA) \
+ $(XCAM_OCV_LIBS) \
+ $(XCAM_OCV_LA) \
+ $(TEST_SOFT_LA) \
+ $(NULL)
+
+if HAVE_GLES
+TEST_GLES_LA = $(top_builddir)/modules/gles/libxcam_gles.la
+endif
+if HAVE_VULKAN
+TEST_VK_LA = $(top_builddir)/modules/vulkan/libxcam_vulkan.la
+endif
+
+test_surround_view_SOURCES = test-surround-view.cpp
+test_surround_view_CXXFLAGS = \
+ $(TEST_BASE_CXXFLAGS) \
+ $(XCAM_OCV_CFLAGS) \
+ $(NULL)
+test_surround_view_LDADD = \
+ $(TEST_BASE_LA) \
+ $(XCAM_OCV_LIBS) \
+ $(XCAM_OCV_LA) \
+ $(TEST_SOFT_LA) \
+ $(TEST_GLES_LA) \
+ $(TEST_VK_LA) \
+ $(NULL)
+
+if HAVE_VULKAN
+test_vk_handler_SOURCES = test-vk-handler.cpp
+test_vk_handler_CXXFLAGS = \
+ $(TEST_BASE_CXXFLAGS) \
+ $(LIBVULKAN_CFLAGS) \
+ $(XCAM_OCV_CFLAGS) \
+ $(NULL)
+test_vk_handler_LDADD = \
+ $(TEST_BASE_LA) \
+ $(LIBVULKAN_LIBS) \
+ $(XCAM_OCV_LIBS) \
+ $(XCAM_OCV_LA) \
+ $(TEST_VK_LA) \
+ $(NULL)
+endif
+
+if HAVE_GLES
+test_gles_handler_SOURCES = test-gles-handler.cpp
+test_gles_handler_CXXFLAGS = \
+ $(TEST_BASE_CXXFLAGS) \
+ $(XCAM_OCV_CFLAGS) \
+ $(NULL)
+test_gles_handler_LDADD = \
+ $(TEST_BASE_LA) \
+ $(XCAM_OCV_LIBS) \
+ $(XCAM_OCV_LA) \
+ $(TEST_GLES_LA) \
+ $(NULL)
+endif
+
+if ENABLE_RENDER
+TEST_RENDER_LA = $(top_builddir)/modules/render/libxcam_render.la
+
+test_render_surround_view_SOURCES = test-render-surround-view.cpp
+test_render_surround_view_CXXFLAGS = \
+ $(TEST_BASE_CXXFLAGS) \
+ $(XCAM_OCV_CFLAGS) \
+ $(NULL)
+test_render_surround_view_LDADD = \
+ $(TEST_BASE_LA) \
+ $(XCAM_OCV_LIBS) \
+ $(XCAM_OCV_LA) \
+ $(TEST_SOFT_LA) \
+ $(TEST_GLES_LA) \
+ $(TEST_VK_LA) \
+ $(TEST_RENDER_LA) \
+ $(NULL)
+endif
+
+if ENABLE_DNN
+TEST_DNN_INFERENCE_LA = $(top_builddir)/modules/dnn/libxcam_dnn.la
+
+test_dnn_inference_SOURCES = test-dnn-inference.cpp
+test_dnn_inference_CXXFLAGS = \
+ $(TEST_BASE_CXXFLAGS) \
+ -I$(OPENVINO_IE_INC_PATH)/include \
+ -I$(OPENVINO_IE_INC_PATH)/src/extension \
+ $(NULL)
+
+test_dnn_inference_LDADD = \
+ $(TEST_BASE_LA) \
+ $(TEST_DNN_INFERENCE_LA) \
+ $(NULL)
+endif
+
diff --git a/tests/test-cl-image.cpp b/tests/test-cl-image.cpp
index 19000b5..a986d5d 100644
--- a/tests/test-cl-image.cpp
+++ b/tests/test-cl-image.cpp
@@ -175,7 +175,6 @@ int main (int argc, char *argv[])
SmartPtr<CLImageHandler> image_handler;
VideoBufferInfo input_buf_info;
SmartPtr<CLContext> context;
- SmartPtr<BufferPool> buf_pool;
int opt = 0;
CLCscType csc_type = CL_CSC_TYPE_RGBATONV12;
bool enable_bnr = false;
@@ -409,6 +408,7 @@ int main (int argc, char *argv[])
SmartPtr<CLNewWaveletDenoiseImageHandler> wavelet = image_handler.dynamic_cast_ptr<CLNewWaveletDenoiseImageHandler> ();
XCAM_ASSERT (wavelet.ptr ());
XCam3aResultWaveletNoiseReduction wavelet_config;
+ xcam_mem_clear (wavelet_config);
wavelet_config.threshold[0] = 0.2;
wavelet_config.threshold[1] = 0.5;
wavelet_config.decomposition_levels = 4;
@@ -497,7 +497,8 @@ int main (int argc, char *argv[])
input_buf_info.init (input_format, width, height);
- buf_pool = new CLVideoBufferPool ();
+ SmartPtr<BufferPool> buf_pool = new CLVideoBufferPool ();
+ XCAM_ASSERT (buf_pool.ptr ());
image_handler->set_pool_type (CLImageHandler::CLVideoPoolType);
buf_pool->set_video_info (input_buf_info);
if (!buf_pool->reserve (6)) {
@@ -541,14 +542,6 @@ int main (int argc, char *argv[])
XCAM_LOG_INFO ("processed %d buffers successfully", buf_count);
if (enable_psnr) {
- buf_pool = new CLVideoBufferPool ();
- XCAM_ASSERT (buf_pool.ptr ());
- buf_pool->set_video_info (input_buf_info);
- if (!buf_pool->reserve (6)) {
- XCAM_LOG_ERROR ("init buffer pool failed");
- return -1;
- }
-
psnr_ref = buf_pool->get_buffer (buf_pool);
XCAM_ASSERT (psnr_ref.ptr ());
diff --git a/tests/test-device-manager.cpp b/tests/test-device-manager.cpp
index f299d46..1be70f5 100644
--- a/tests/test-device-manager.cpp
+++ b/tests/test-device-manager.cpp
@@ -32,7 +32,7 @@
#include "isp/isp_image_processor.h"
#include "isp/isp_poll_thread.h"
#include "isp/x3a_analyzer_aiq.h"
-#include "x3a_analyze_tuner.h"
+#include "isp/iq/x3a_analyze_tuner.h"
#include "dynamic_analyzer_loader.h"
#include "isp/hybrid_analyzer_loader.h"
#endif
@@ -328,8 +328,6 @@ int main (int argc, char *argv[])
bool have_cl_processor = false;
SmartPtr<SmartAnalyzer> smart_analyzer;
bool have_cl_post_processor = true;
- SmartPtr<CL3aImageProcessor> cl_processor;
- SmartPtr<CLPostImageProcessor> cl_post_processor;
uint32_t tnr_type = CL_TNR_DISABLE;
uint32_t denoise_type = 0;
uint8_t tnr_level = 0;
@@ -817,7 +815,7 @@ int main (int argc, char *argv[])
#endif
#if HAVE_LIBCL
if (have_cl_processor) {
- cl_processor = new CL3aImageProcessor ();
+ SmartPtr<CL3aImageProcessor> cl_processor = new CL3aImageProcessor ();
cl_processor->set_stats_callback(device_manager);
cl_processor->set_denoise (denoise_type);
cl_processor->set_capture_stage (capture_stage);
@@ -837,7 +835,7 @@ int main (int argc, char *argv[])
}
if (have_cl_post_processor) {
- cl_post_processor = new CLPostImageProcessor ();
+ SmartPtr<CLPostImageProcessor> cl_post_processor = new CLPostImageProcessor ();
cl_post_processor->set_stats_callback (device_manager);
cl_post_processor->set_defog_mode ((CLPostImageProcessor::CLDefogMode)defog_type);
diff --git a/tests/test-dnn-inference.cpp b/tests/test-dnn-inference.cpp
new file mode 100644
index 0000000..d07e27c
--- /dev/null
+++ b/tests/test-dnn-inference.cpp
@@ -0,0 +1,497 @@
+/*
+ * test-dnn-inference.cpp - test dnn inference sample
+ *
+ * Copyright (c) 2019 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Zong Wei <wei.zong@intel.com>
+ *
+ */
+
+#include <fstream>
+#include <random>
+#include <string>
+#include <vector>
+#include <time.h>
+
+#include <xcam_std.h>
+#include "test_common.h"
+
+#include <dnn/dnn_inference_engine.h>
+#include <dnn/dnn_object_detection.h>
+
+using namespace XCam;
+using namespace InferenceEngine;
+
+class Color {
+
+public:
+ Color (uint8_t r, uint8_t g, uint8_t b) {
+ _red = r;
+ _green = g;
+ _blue = b;
+ }
+
+public:
+ uint8_t _red;
+ uint8_t _green;
+ uint8_t _blue;
+};
+
+static void add_rectangles (
+ uint8_t *data, uint32_t width, uint32_t height,
+ std::vector<int> rectangles, std::vector<int> classes, int thickness = 1)
+{
+ std::vector<Color> colors = {
+ // colors to be used for bounding boxes
+ Color ( 128, 64, 128 ),
+ Color ( 232, 35, 244 ),
+ Color ( 70, 70, 70 ),
+ Color ( 156, 102, 102 ),
+ Color ( 153, 153, 190 ),
+ Color ( 153, 153, 153 ),
+ Color ( 30, 170, 250 ),
+ Color ( 0, 220, 220 ),
+ Color ( 35, 142, 107 ),
+ Color ( 152, 251, 152 ),
+ Color ( 180, 130, 70 ),
+ Color ( 60, 20, 220 ),
+ Color ( 0, 0, 255 ),
+ Color ( 142, 0, 0 ),
+ Color ( 70, 0, 0 ),
+ Color ( 100, 60, 0 ),
+ Color ( 90, 0, 0 ),
+ Color ( 230, 0, 0 ),
+ Color ( 32, 11, 119 ),
+ Color ( 0, 74, 111 ),
+ Color ( 81, 0, 81 )
+ };
+ if (rectangles.size() % 4 != 0 || rectangles.size() / 4 != classes.size()) {
+ return;
+ }
+
+ for (size_t i = 0; i < classes.size(); i++) {
+ int x = rectangles.at(i * 4);
+ int y = rectangles.at(i * 4 + 1);
+ int w = rectangles.at(i * 4 + 2);
+ int h = rectangles.at(i * 4 + 3);
+
+ int cls = classes.at(i) % colors.size(); // color of a bounding box line
+
+ if (x < 0) x = 0;
+ if (y < 0) y = 0;
+ if (w < 0) w = 0;
+ if (h < 0) h = 0;
+
+ if (static_cast<std::size_t>(x) >= width) {
+ x = width - 1;
+ w = 0;
+ thickness = 1;
+ }
+ if (static_cast<std::size_t>(y) >= height) {
+ y = height - 1;
+ h = 0;
+ thickness = 1;
+ }
+
+ if (static_cast<std::size_t>(x + w) >= width) {
+ w = width - x - 1;
+ }
+ if (static_cast<std::size_t>(y + h) >= height) {
+ h = height - y - 1;
+ }
+
+ thickness = std::min(std::min(thickness, w / 2 + 1), h / 2 + 1);
+
+ size_t shift_first;
+ size_t shift_second;
+ for (int t = 0; t < thickness; t++) {
+ shift_first = (y + t) * width * 3;
+ shift_second = (y + h - t) * width * 3;
+ for (int ii = x; ii < x + w + 1; ii++) {
+ data[shift_first + ii * 3] = colors.at(cls)._red;
+ data[shift_first + ii * 3 + 1] = colors.at(cls)._green;
+ data[shift_first + ii * 3 + 2] = colors.at(cls)._blue;
+ data[shift_second + ii * 3] = colors.at(cls)._red;
+ data[shift_second + ii * 3 + 1] = colors.at(cls)._green;
+ data[shift_second + ii * 3 + 2] = colors.at(cls)._blue;
+ }
+ }
+
+ for (int t = 0; t < thickness; t++) {
+ shift_first = (x + t) * 3;
+ shift_second = (x + w - t) * 3;
+ for (int ii = y; ii < y + h + 1; ii++) {
+ data[shift_first + ii * width * 3] = colors.at(cls)._red;
+ data[shift_first + ii * width * 3 + 1] = colors.at(cls)._green;
+ data[shift_first + ii * width * 3 + 2] = colors.at(cls)._blue;
+ data[shift_second + ii * width * 3] = colors.at(cls)._red;
+ data[shift_second + ii * width * 3 + 1] = colors.at(cls)._green;
+ data[shift_second + ii * width * 3 + 2] = colors.at(cls)._blue;
+ }
+ }
+ }
+}
+
+static bool write_output_bmp (std::string name, unsigned char *data, uint32_t width, uint32_t height)
+{
+ std::ofstream out_file;
+ out_file.open (name, std::ofstream::binary);
+ if (!out_file.is_open ()) {
+ return false;
+ }
+
+ unsigned char file[14] = {
+ 'B', 'M', // magic
+ 0, 0, 0, 0, // size in bytes
+ 0, 0, // app data
+ 0, 0, // app data
+ 40 + 14, 0, 0, 0 // start of data offset
+ };
+ unsigned char info[40] = {
+ 40, 0, 0, 0, // info hd size
+ 0, 0, 0, 0, // width
+ 0, 0, 0, 0, // height
+ 1, 0, // number color planes
+ 24, 0, // bits per pixel
+ 0, 0, 0, 0, // compression is none
+ 0, 0, 0, 0, // image bits size
+ 0x13, 0x0B, 0, 0, // horz resolution in pixel / m
+ 0x13, 0x0B, 0, 0, // vert resolution (0x03C3 = 96 dpi, 0x0B13 = 72 dpi)
+ 0, 0, 0, 0, // #colors in palette
+ 0, 0, 0, 0, // #important colors
+ };
+
+ if (height > (size_t)std::numeric_limits<int32_t>::max ||
+ width > (size_t)std::numeric_limits<int32_t>::max) {
+ XCAM_LOG_ERROR ("File size is too big: %dx%d", height, width);
+ return false;
+ }
+
+ int pad_size = static_cast<int>(4 - (width * 3) % 4) % 4;
+ int size_data = static_cast<int>(width * height * 3 + height * pad_size);
+ int size_all = size_data + sizeof(file) + sizeof(info);
+
+ file[2] = (unsigned char)(size_all);
+ file[3] = (unsigned char)(size_all >> 8);
+ file[4] = (unsigned char)(size_all >> 16);
+ file[5] = (unsigned char)(size_all >> 24);
+
+ info[4] = (unsigned char)(width);
+ info[5] = (unsigned char)(width >> 8);
+ info[6] = (unsigned char)(width >> 16);
+ info[7] = (unsigned char)(width >> 24);
+
+ int32_t negative_height = -(int32_t)height;
+ info[8] = (unsigned char)(negative_height);
+ info[9] = (unsigned char)(negative_height >> 8);
+ info[10] = (unsigned char)(negative_height >> 16);
+ info[11] = (unsigned char)(negative_height >> 24);
+
+ info[20] = (unsigned char)(size_data);
+ info[21] = (unsigned char)(size_data >> 8);
+ info[22] = (unsigned char)(size_data >> 16);
+ info[23] = (unsigned char)(size_data >> 24);
+
+ out_file.write(reinterpret_cast<char *>(file), sizeof(file));
+ out_file.write(reinterpret_cast<char *>(info), sizeof(info));
+
+ unsigned char pad[3] = { 0, 0, 0 };
+
+ for (size_t y = 0; y < height; y++) {
+ for (size_t x = 0; x < width; x++) {
+ unsigned char pixel[3];
+ pixel[0] = data[y * width * 3 + x * 3];
+ pixel[1] = data[y * width * 3 + x * 3 + 1];
+ pixel[2] = data[y * width * 3 + x * 3 + 2];
+
+ out_file.write(reinterpret_cast<char *>(pixel), 3);
+ }
+ out_file.write(reinterpret_cast<char *>(pad), pad_size);
+ }
+ return true;
+}
+
+static void usage (const char* arg0)
+{
+ printf ("Usage:\n"
+ "%s --plugin PATH --input filename --model-name xx.xml ...\n"
+ "\t--plugin plugin path\n"
+ "\t--target-dev target device, default: DnnInferDeviceCPU\n"
+ "\t--ext-path extension path\n"
+ "\t--model-file model file name\n"
+ "\t--input input image \n"
+ "\t--save save output image \n"
+ "\t--help usage\n",
+ arg0);
+}
+
+int main (int argc, char *argv[])
+{
+ const struct option long_opts[] = {
+ {"plugin", required_argument, NULL, 'p'},
+ {"target-dev", required_argument, NULL, 'd'},
+ {"ext-path", required_argument, NULL, 'x'},
+ {"model-file", required_argument, NULL, 'm'},
+ {"input", required_argument, NULL, 'i'},
+ {"save", required_argument, NULL, 's'},
+ {"help", no_argument, NULL, 'h'},
+ {NULL, 0, NULL, 0},
+ };
+
+ // --------------------------- 0. Get inference engine configurations -----------------------------------------------------------
+ XCAM_LOG_DEBUG ("0. Get inference engine configurations");
+
+ DnnInferConfig infer_config;
+ infer_config.target_id = DnnInferDeviceCPU;
+
+ char* ext_path = NULL;
+ char* input_image = NULL;
+ bool save_output = true;
+
+ int opt = -1;
+ while ((opt = getopt_long (argc, argv, "", long_opts, NULL)) != -1) {
+ switch (opt) {
+ case 'p':
+ XCAM_ASSERT (optarg);
+ infer_config.plugin_path = optarg;
+ break;
+ case 'd':
+ XCAM_ASSERT (optarg);
+ infer_config.target_id = (DnnInferTargetDeviceType)(atoi (optarg));
+ if (!strcasecmp (optarg, "CPU")) {
+ infer_config.target_id = DnnInferDeviceCPU;
+ } else if (!strcasecmp (optarg, "GPU")) {
+ infer_config.target_id = DnnInferDeviceGPU;
+ } else if (!strcasecmp (optarg, "FPGA")) {
+ infer_config.target_id = DnnInferDeviceFPGA;
+ } else if (!strcasecmp (optarg, "Myriad")) {
+ infer_config.target_id = DnnInferDeviceMyriad;
+ } else {
+ XCAM_LOG_ERROR ("target device unknown type: %s", optarg);
+ usage (argv[0]);
+ return -1;
+ }
+ break;
+ case 'x':
+ XCAM_ASSERT (optarg);
+ ext_path = optarg;
+ break;
+ case 'm':
+ XCAM_ASSERT (optarg);
+ infer_config.model_filename = optarg;
+ break;
+ case 'i':
+ XCAM_ASSERT (optarg);
+ input_image = optarg;
+ break;
+ case 's':
+ XCAM_ASSERT (optarg);
+ save_output = (strcasecmp (optarg, "false") == 0 ? false : true);
+ break;
+ case 'h':
+ usage (argv[0]);
+ return 0;
+ default:
+ XCAM_LOG_ERROR ("getopt_long return unknown value: %c", opt);
+ usage (argv[0]);
+ return -1;
+ }
+ }
+
+ XCAM_LOG_DEBUG ("targetDevice: %d", infer_config.target_id );
+ if (DnnInferDeviceCPU == infer_config.target_id) {
+ infer_config.cpu_ext_path = ext_path;
+ XCAM_LOG_DEBUG ("CPU Extension loaded: %s", infer_config.cpu_ext_path);
+ } else if (DnnInferDeviceGPU == infer_config.target_id) {
+ infer_config.cldnn_ext_path = ext_path;
+ XCAM_LOG_DEBUG ("GPU Extension loaded: %s", infer_config.cldnn_ext_path);
+ }
+
+ if (optind < argc || argc < 2) {
+ XCAM_LOG_ERROR ("unknown option %s", argv[optind]);
+ usage (argv[0]);
+ return -1;
+ }
+
+ printf ("plugin path:\t\t%s\n", (infer_config.plugin_path != NULL) ? infer_config.plugin_path : "NULL");
+ printf ("target device id:\t\t%d\n", infer_config.target_id);
+ printf ("extention path:\t\t%s\n", (ext_path != NULL) ? ext_path : "NULL");
+ printf ("input image:\t\t%s\n", (input_image != NULL) ? input_image : "NULL");
+ printf ("model file name:\t\t%s\n", (infer_config.model_filename != NULL) ? infer_config.model_filename : "NULL");
+
+ // --------------------------- 1. Set input image file names -----------------------------------------------------------
+ XCAM_LOG_DEBUG ("1. Set input image file names");
+ std::vector<std::string> images;
+ if (NULL != input_image) {
+ images.push_back (input_image);
+ }
+
+ if (images.empty()) {
+ XCAM_LOG_ERROR ("No suitable images were found!");
+ return -1;
+ }
+
+ // --------------------------- 2. create inference engine --------------------------------------------------
+ XCAM_LOG_DEBUG ("2. Create inference engine");
+ infer_config.perf_counter = 0;
+
+ SmartPtr<DnnInferenceEngine> infer_engine = new DnnObjectDetection (infer_config);
+
+ DnnInferenceEngineInfo infer_info;
+ CHECK (
+ infer_engine->get_info (infer_info, DnnInferInfoEngine),
+ "get inference engine info failed!");
+ XCAM_LOG_DEBUG ("Inference Engine version: %d.%d", infer_info.major, infer_info.minor);
+
+ CHECK (
+ infer_engine->get_info (infer_info, DnnInferInfoPlugin),
+ "get inference engine info failed!");
+ XCAM_LOG_DEBUG ("Inference Engine plugin discription: %s", infer_info.desc);
+ XCAM_LOG_DEBUG ("Inference Engine plugin version: %d.%d", infer_info.major, infer_info.minor);
+
+ CHECK (
+ infer_engine->get_info (infer_info, DnnInferInfoNetwork),
+ "get inference engine info failed!");
+ XCAM_LOG_DEBUG ("Inference Engine network name: %s", infer_info.name);
+ XCAM_LOG_DEBUG ("Inference Engine network discription: %s", infer_info.desc);
+ XCAM_LOG_DEBUG ("Inference Engine network version: %d.%d", infer_info.major, infer_info.minor);
+
+ // --------------------------- 3. Get model input infos --------------------------------------------------
+ XCAM_LOG_DEBUG ("3. Get/Set model input infos");
+ CHECK (
+ infer_engine->get_model_input_info (infer_config.input_infos),
+ "get model input info failed!");
+
+ XCAM_LOG_DEBUG ("Input info :");
+ for (uint32_t i = 0; i < infer_config.input_infos.numbers; i++) {
+ infer_config.input_infos.data_type[i] = DnnInferDataTypeImage;
+ CHECK (
+ infer_engine->set_input_presion (i, DnnInferPrecisionU8),
+ "set input presion failed!");
+ XCAM_LOG_DEBUG ("Idx %d : [%d X %d X %d] , [%d %d %d], batch size = %d", i,
+ infer_config.input_infos.width[i], infer_config.input_infos.height[i], infer_config.input_infos.channels[i],
+ infer_config.input_infos.precision[i], infer_config.input_infos.layout[i], infer_config.input_infos.data_type[i],
+ infer_config.input_infos.batch_size);
+ }
+
+ // --------------------------- 4. Get model output infos -------------------------------------------------
+ XCAM_LOG_DEBUG ("4. Get/Set model output infos");
+ CHECK (
+ infer_engine->get_model_output_info (infer_config.output_infos),
+ "get model output info failed!");
+ XCAM_LOG_DEBUG ("Output info (numbers %d) :", infer_config.output_infos.numbers);
+
+ for (uint32_t i = 0; i < infer_config.output_infos.numbers; i++) {
+ CHECK (
+ infer_engine->set_output_presion (i, DnnInferPrecisionFP32),
+ "set output presion failed!");
+ XCAM_LOG_DEBUG ("Idx %d : [%d X %d X %d] , [%d %d %d], batch size = %d", i,
+ infer_config.output_infos.width[i], infer_config.output_infos.height[i], infer_config.output_infos.channels[i],
+ infer_config.output_infos.precision[i], infer_config.output_infos.layout[i], infer_config.output_infos.data_type[i],
+ infer_config.output_infos.batch_size);
+ }
+
+ // --------------------------- 5. load inference model -------------------------------------------------
+ XCAM_LOG_DEBUG ("5. load inference model");
+ CHECK (
+ infer_engine->load_model (infer_config),
+ "load model failed!");
+
+ // --------------------------- 6. Set inference data --------------------------------------------------------
+ XCAM_LOG_DEBUG ("6. Set inference data");
+ CHECK (
+ infer_engine->set_inference_data (images),
+ "set inference data failed!");
+
+ // --------------------------- 7. Do inference ---------------------------------------------------------
+ XCAM_LOG_DEBUG ("7. Start inference iterations");
+ if (infer_engine->ready_to_start ()) {
+ CHECK (
+ infer_engine->start (),
+ "inference failed!");
+ }
+
+ FPS_CALCULATION (inference_engine, XCAM_OBJ_DUR_FRAME_NUM);
+
+ // --------------------------- 8. Process inference results -------------------------------------------------------
+ XCAM_LOG_DEBUG ("Processing inference results");
+
+ size_t batch_size = infer_engine->get_output_size ();
+ if (batch_size != images.size ()) {
+ XCAM_LOG_DEBUG ( "Number of images: %d ", images.size ());
+ batch_size = std::min(batch_size, images.size ());
+ XCAM_LOG_DEBUG ( "Number of images to be processed is: %d ", batch_size);
+ }
+
+ uint32_t blob_size = 0;
+ float* result_ptr = NULL;
+ std::vector<std::vector<int> > boxes(batch_size);
+ std::vector<std::vector<int> > classes(batch_size);
+
+ for (uint32_t batch_idx = 0; batch_idx < batch_size; batch_idx ++) {
+ result_ptr = (float*)infer_engine->get_inference_results (batch_idx, blob_size);
+ if (NULL == result_ptr) {
+ continue;
+ }
+
+ int image_width = infer_engine->get_input_image_width ();
+ int image_height = infer_engine->get_input_image_height ();
+ int max_proposal_count = infer_config.output_infos.channels[batch_idx];
+ int object_size = infer_config.output_infos.object_size[batch_idx];
+
+ for (int32_t cur_proposal = 0; cur_proposal < max_proposal_count; cur_proposal++) {
+ float image_id = result_ptr[cur_proposal * object_size + 0];
+ if (image_id < 0) {
+ break;
+ }
+
+ float label = result_ptr[cur_proposal * object_size + 1];
+ float confidence = result_ptr[cur_proposal * object_size + 2];
+ float xmin = result_ptr[cur_proposal * object_size + 3] * image_width;
+ float ymin = result_ptr[cur_proposal * object_size + 4] * image_height;
+ float xmax = result_ptr[cur_proposal * object_size + 5] * image_width;
+ float ymax = result_ptr[cur_proposal * object_size + 6] * image_height;
+
+ if (confidence > 0.5) {
+ classes[image_id].push_back(static_cast<int>(label));
+ boxes[image_id].push_back(static_cast<int>(xmin));
+ boxes[image_id].push_back(static_cast<int>(ymin));
+ boxes[image_id].push_back(static_cast<int>(xmax - xmin));
+ boxes[image_id].push_back(static_cast<int>(ymax - ymin));
+
+ XCAM_LOG_DEBUG ("Proposal:%d label:%d confidence:%f", cur_proposal, (int)label, confidence);
+ XCAM_LOG_DEBUG ("Boxes[%f] {%d, %d, %d, %d}",
+ image_id, (int)xmin, (int)ymin, (int)xmax, (int)ymax);
+ }
+ }
+
+ if (save_output) {
+ std::shared_ptr<unsigned char> orig_image = infer_engine->read_inference_image (images[batch_idx]);
+ add_rectangles (orig_image.get (),
+ image_width, image_height,
+ boxes[batch_idx], classes[batch_idx]);
+
+ const std::string image_path = images[batch_idx] + "_out_" + std::to_string (batch_idx) + ".bmp";
+ if (write_output_bmp (image_path, orig_image.get (), image_width, image_height)) {
+ XCAM_LOG_DEBUG ("Image %s created!", image_path.c_str ());
+ } else {
+ XCAM_LOG_ERROR ("Can't create image file: %s", image_path.c_str ());
+ }
+ }
+ }
+
+ XCAM_LOG_DEBUG ("Execution successful");
+ return 0;
+}
diff --git a/tests/test-gles-handler.cpp b/tests/test-gles-handler.cpp
new file mode 100644
index 0000000..acafa00
--- /dev/null
+++ b/tests/test-gles-handler.cpp
@@ -0,0 +1,313 @@
+/*
+ * test-gles-handler.cpp - test gles handler
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#include "test_common.h"
+#include "test_stream.h"
+
+#include <gles/gl_video_buffer.h>
+#include <gles/egl/egl_base.h>
+#include <gles/gl_copy_handler.h>
+#include <gles/gl_geomap_handler.h>
+#include <interface/blender.h>
+
+using namespace XCam;
+
+enum GLType {
+ GLTypeNone = 0,
+ GLTypeCopy,
+ GLTypeRemap,
+ GLTypeBlender
+};
+
+class GLStream
+ : public Stream
+{
+public:
+ explicit GLStream (const char *file_name = NULL, uint32_t width = 0, uint32_t height = 0);
+ virtual ~GLStream () {}
+
+ virtual XCamReturn create_buf_pool (const VideoBufferInfo &info, uint32_t count);
+};
+
+typedef std::vector<SmartPtr<GLStream>> GLStreams;
+
+GLStream::GLStream (const char *file_name, uint32_t width, uint32_t height)
+ : Stream (file_name, width, height)
+{
+}
+
+XCamReturn
+GLStream::create_buf_pool (const VideoBufferInfo &info, uint32_t count)
+{
+ SmartPtr<GLVideoBufferPool> pool = new GLVideoBufferPool (info);
+ XCAM_ASSERT (pool.ptr ());
+
+ if (!pool->reserve (count)) {
+ XCAM_LOG_ERROR ("create buffer pool failed");
+ return XCAM_RETURN_ERROR_MEM;
+ }
+
+ set_buf_pool (pool);
+ return XCAM_RETURN_NO_ERROR;
+}
+
+static void
+calc_hor_flip_table (uint32_t width, uint32_t height, PointFloat2 *&map_table)
+{
+ XCAM_ASSERT (map_table);
+
+ float lut_size[2] = {8, 8};
+ for (uint32_t i = 0; i < height; ++i) {
+ PointFloat2 *line = &map_table[i * width];
+ for (uint32_t j = 0; j < width; j++) {
+ line[j].x = (width - j) * lut_size[0];
+ line[j].y = i * lut_size[1];
+ }
+ }
+}
+
+static void usage (const char *arg0)
+{
+ printf ("Usage:\n"
+ "%s --type TYPE --input0 input.nv12 --input1 input1.nv12 --output output.nv12 ...\n"
+ "\t--type processing type, selected from: copy, remap, blend\n"
+ "\t--input0 input image(NV12)\n"
+ "\t--input1 input image(NV12)\n"
+ "\t--output output image(NV12/MP4)\n"
+ "\t--in-w optional, input width, default: 1280\n"
+ "\t--in-h optional, input height, default: 800\n"
+ "\t--out-w optional, output width, default: 1280\n"
+ "\t--out-h optional, output height, default: 800\n"
+ "\t--save optional, save file or not, select from [true/false], default: true\n"
+ "\t--loop optional, how many loops need to run, default: 1\n"
+ "\t--help usage\n",
+ arg0);
+}
+
+int main (int argc, char **argv)
+{
+ uint32_t input_width = 1280;
+ uint32_t input_height = 800;
+ uint32_t output_width = 1280;
+ uint32_t output_height = 800;
+
+ GLStreams ins;
+ GLStreams outs;
+ GLType type = GLTypeNone;
+
+ int loop = 1;
+ bool save_output = true;
+
+ const struct option long_opts[] = {
+ {"type", required_argument, NULL, 't'},
+ {"input0", required_argument, NULL, 'i'},
+ {"input1", required_argument, NULL, 'j'},
+ {"output", required_argument, NULL, 'o'},
+ {"in-w", required_argument, NULL, 'w'},
+ {"in-h", required_argument, NULL, 'h'},
+ {"out-w", required_argument, NULL, 'W'},
+ {"out-h", required_argument, NULL, 'H'},
+ {"save", required_argument, NULL, 's'},
+ {"loop", required_argument, NULL, 'l'},
+ {"help", no_argument, NULL, 'e'},
+ {NULL, 0, NULL, 0},
+ };
+
+ int opt = -1;
+ while ((opt = getopt_long(argc, argv, "", long_opts, NULL)) != -1) {
+ switch (opt) {
+ case 't':
+ XCAM_ASSERT (optarg);
+ if (!strcasecmp (optarg, "copy"))
+ type = GLTypeCopy;
+ else if (!strcasecmp (optarg, "remap"))
+ type = GLTypeRemap;
+ else if (!strcasecmp (optarg, "blend"))
+ type = GLTypeBlender;
+ else {
+ XCAM_LOG_ERROR ("unknown type:%s", optarg);
+ usage (argv[0]);
+ return -1;
+ }
+ break;
+ case 'i':
+ XCAM_ASSERT (optarg);
+ PUSH_STREAM (GLStream, ins, optarg);
+ break;
+ case 'j':
+ XCAM_ASSERT (optarg);
+ PUSH_STREAM (GLStream, ins, optarg);
+ break;
+ case 'o':
+ XCAM_ASSERT (optarg);
+ PUSH_STREAM (GLStream, outs, optarg);
+ break;
+ case 'w':
+ input_width = atoi(optarg);
+ break;
+ case 'h':
+ input_height = atoi(optarg);
+ break;
+ case 'W':
+ output_width = atoi(optarg);
+ break;
+ case 'H':
+ output_height = atoi(optarg);
+ break;
+ case 's':
+ save_output = (strcasecmp (optarg, "false") == 0 ? false : true);
+ break;
+ case 'l':
+ loop = atoi(optarg);
+ break;
+ case 'e':
+ usage (argv[0]);
+ return 0;
+ default:
+ XCAM_LOG_ERROR ("getopt_long return unknown value:%c", opt);
+ usage (argv[0]);
+ return -1;
+ }
+ }
+
+ if (optind < argc || argc < 2) {
+ XCAM_LOG_ERROR ("unknown option %s", argv[optind]);
+ usage (argv[0]);
+ return -1;
+ }
+
+ if (ins.empty () || outs.empty ()) {
+ XCAM_LOG_ERROR ("input or output stream is empty");
+ usage (argv[0]);
+ return -1;
+ }
+
+ for (uint32_t i = 0; i < ins.size (); ++i) {
+ printf ("input%d file:\t\t%s\n", i, ins[i]->get_file_name ());
+ }
+ printf ("output file:\t\t%s\n", outs[0]->get_file_name ());
+ printf ("input width:\t\t%d\n", input_width);
+ printf ("input height:\t\t%d\n", input_height);
+ printf ("output width:\t\t%d\n", output_width);
+ printf ("output height:\t\t%d\n", output_height);
+ printf ("save output:\t\t%s\n", save_output ? "true" : "false");
+ printf ("loop count:\t\t%d\n", loop);
+
+ SmartPtr<EGLBase> egl = new EGLBase ();
+ XCAM_FAIL_RETURN (ERROR, egl->init (), -1, "init EGL failed");
+
+ VideoBufferInfo in_info;
+ in_info.init (V4L2_PIX_FMT_NV12, input_width, input_height);
+ for (uint32_t i = 0; i < ins.size (); ++i) {
+ ins[i]->set_buf_size (input_width, input_height);
+ CHECK (ins[i]->create_buf_pool (in_info, XCAM_GL_RESERVED_BUF_COUNT), "create buffer pool failed");
+ CHECK (ins[i]->open_reader ("rb"), "open input file(%s) failed", ins[i]->get_file_name ());
+ }
+
+ VideoBufferInfo out_info;
+ out_info.init (V4L2_PIX_FMT_NV12, output_width, output_height);
+ outs[0]->set_buf_size (output_width, output_height);
+ if (save_output) {
+ CHECK (outs[0]->estimate_file_format (), "%s: estimate file format failed", outs[0]->get_file_name ());
+ CHECK (outs[0]->open_writer ("wb"), "open output file(%s) failed", outs[0]->get_file_name ());
+ }
+
+ switch (type) {
+ case GLTypeCopy: {
+ SmartPtr<GLCopyHandler> copyer = new GLCopyHandler ();
+ XCAM_ASSERT (copyer.ptr ());
+
+ Rect in_area = Rect (0, 0, output_width, output_height);
+ Rect out_area = in_area;
+ copyer->set_copy_area (0, in_area, out_area);
+ copyer->set_out_video_info (out_info);
+
+ CHECK (ins[0]->read_buf(), "read buffer from file(%s) failed.", ins[0]->get_file_name ());
+ for (int i = 0; i < loop; ++i) {
+ CHECK (copyer->copy (ins[0]->get_buf (), outs[0]->get_buf ()), "copy buffer failed");
+ if (save_output)
+ outs[0]->write_buf ();
+ FPS_CALCULATION (gl-copy, XCAM_OBJ_DUR_FRAME_NUM);
+ }
+ break;
+ }
+ case GLTypeRemap: {
+ SmartPtr<GLGeoMapHandler> mapper = new GLGeoMapHandler ();
+ XCAM_ASSERT (mapper.ptr ());
+ mapper->set_output_size (output_width, output_height);
+
+ uint32_t lut_width = XCAM_ALIGN_UP (output_width, 8) / 8;
+ uint32_t lut_height = XCAM_ALIGN_UP (output_height, 8) / 8;
+ PointFloat2 *map_table = new PointFloat2[lut_width * lut_height];
+ calc_hor_flip_table (lut_width, lut_height, map_table);
+ mapper->set_lookup_table (map_table, lut_width, lut_height);
+ delete [] map_table;
+
+ CHECK (ins[0]->read_buf(), "read buffer from file(%s) failed.", ins[0]->get_file_name ());
+ for (int i = 0; i < loop; ++i) {
+ CHECK (mapper->remap (ins[0]->get_buf (), outs[0]->get_buf ()), "remap buffer failed");
+ if (save_output)
+ outs[0]->write_buf ();
+ FPS_CALCULATION (gl-remap, XCAM_OBJ_DUR_FRAME_NUM);
+ }
+ break;
+ }
+ case GLTypeBlender: {
+ CHECK_EXP (ins.size () == 2, "Error: blender needs 2 input files.");
+ SmartPtr<Blender> blender = Blender::create_gl_blender ();
+ XCAM_ASSERT (blender.ptr ());
+ blender->set_output_size (output_width, output_height);
+
+ Rect area;
+ area.pos_x = 0;
+ area.pos_y = 0;
+ area.width = output_width;
+ area.height = output_height;
+ blender->set_merge_window (area);
+ area.pos_x = 0;
+ area.pos_y = 0;
+ area.width = input_width;
+ area.height = input_height;
+ blender->set_input_merge_area (area, 0);
+ area.pos_x = 0;
+ area.pos_y = 0;
+ area.width = input_width;
+ area.height = input_height;
+ blender->set_input_merge_area (area, 1);
+
+ CHECK (ins[0]->read_buf(), "read buffer from file(%s) failed.", ins[0]->get_file_name ());
+ CHECK (ins[1]->read_buf(), "read buffer from file(%s) failed.", ins[1]->get_file_name ());
+ for (int i = 0; i < loop; ++i) {
+ CHECK (blender->blend (ins[0]->get_buf (), ins[1]->get_buf (), outs[0]->get_buf ()), "blend buffer failed");
+ if (save_output)
+ outs[0]->write_buf ();
+ FPS_CALCULATION (gl-blend, XCAM_OBJ_DUR_FRAME_NUM);
+ }
+ break;
+ }
+ default: {
+ XCAM_LOG_ERROR ("unsupported type:%d", type);
+ usage (argv[0]);
+ return -1;
+ }
+ }
+
+ return 0;
+}
diff --git a/tests/test-image-blend.cpp b/tests/test-image-blend.cpp
index a00236f..c355a49 100644
--- a/tests/test-image-blend.cpp
+++ b/tests/test-image-blend.cpp
@@ -27,6 +27,7 @@
#include <ocl/cl_blender.h>
#include <image_file_handle.h>
#include <ocl/cl_geo_map_handler.h>
+#include <ocl/cl_video_buffer.h>
#if HAVE_LIBDRM
#include <drm_display.h>
#endif
@@ -165,7 +166,6 @@ int main (int argc, char *argv[])
SmartPtr<CLBlender> blender;
VideoBufferInfo input_buf_info0, input_buf_info1, output_buf_info;
SmartPtr<CLContext> context;
- SmartPtr<BufferPool> buf_pool0, buf_pool1;
ImageFileHandle file_in0, file_in1, file_out;
SmartPtr<VideoBuffer> input0, input1;
SmartPtr<VideoBuffer> output_buf;
@@ -227,7 +227,7 @@ int main (int argc, char *argv[])
break;
case 'h':
usage (argv[0]);
- return -1;
+ return 0;
default:
printf ("getopt_long return unknown value:%c\n", opt);
usage (argv[0]);
@@ -259,13 +259,14 @@ int main (int argc, char *argv[])
input_buf_info0.init (input_format, input_width0, input_height);
input_buf_info1.init (input_format, input_width1, input_height);
output_buf_info.init (input_format, output_width, output_height);
+
#if (ENABLE_DMA_TEST) && (HAVE_LIBDRM)
SmartPtr<DrmDisplay> display = DrmDisplay::instance ();
- buf_pool0 = new DrmBoBufferPool (display);
- buf_pool1 = new DrmBoBufferPool (display);
+ SmartPtr<BufferPool> buf_pool0 = new DrmBoBufferPool (display);
+ SmartPtr<BufferPool> buf_pool1 = new DrmBoBufferPool (display);
#else
- buf_pool0 = new CLVideoBufferPool ();
- buf_pool1 = new CLVideoBufferPool ();
+ SmartPtr<BufferPool> buf_pool0 = new CLVideoBufferPool ();
+ SmartPtr<BufferPool> buf_pool1 = new CLVideoBufferPool ();
#endif
XCAM_ASSERT (buf_pool0.ptr () && buf_pool1.ptr ());
buf_pool0->set_video_info (input_buf_info0);
diff --git a/tests/test-image-deblurring.cpp b/tests/test-image-deblurring.cpp
index bc681b2..bfc9d88 100644
--- a/tests/test-image-deblurring.cpp
+++ b/tests/test-image-deblurring.cpp
@@ -25,9 +25,9 @@
#include <unistd.h>
#include <getopt.h>
#include <image_file_handle.h>
-#include <ocl/cv_image_sharp.h>
-#include <ocl/cv_wiener_filter.h>
-#include <ocl/cv_image_deblurring.h>
+#include "ocv/cv_image_sharp.h"
+#include "ocv/cv_wiener_filter.h"
+#include "ocv/cv_image_deblurring.h"
#include <opencv2/opencv.hpp>
#include <opencv2/core/ocl.hpp>
@@ -58,7 +58,7 @@ static void
non_blind_deblurring (cv::Mat &input_image, cv::Mat &output_image)
{
SmartPtr<CVWienerFilter> wiener_filter = new CVWienerFilter ();
- cv::cvtColor (input_image, input_image, CV_BGR2GRAY);
+ cv::cvtColor (input_image, input_image, cv::COLOR_BGR2GRAY);
// use simple motion blur kernel
int kernel_size = 13;
cv::Mat kernel = cv::Mat::zeros (kernel_size, kernel_size, CV_32FC1);
@@ -115,7 +115,7 @@ int main (int argc, char *argv[])
break;
case 'H':
usage (argv[0]);
- return -1;
+ return 0;
default:
printf ("getopt_long return unknown value:%c\n", opt);
usage (argv[0]);
@@ -144,12 +144,12 @@ int main (int argc, char *argv[])
printf ("----------------------\n");
SmartPtr<CVImageSharp> sharp = new CVImageSharp ();
- cv::Mat input_image = cv::imread (file_in_name, CV_LOAD_IMAGE_COLOR);
+ cv::Mat input_image = cv::imread (file_in_name, cv::IMREAD_COLOR);
cv::Mat output_image;
if (input_image.empty ())
{
XCAM_LOG_ERROR ("input file read error");
- return 0;
+ return -1;
}
if (blind)
{
@@ -166,5 +166,7 @@ int main (int argc, char *argv[])
cv::imwrite (file_out_name, output_image);
}
XCAM_ASSERT (output_sharp > input_sharp);
+
+ return 0;
}
diff --git a/tests/test-image-stitching.cpp b/tests/test-image-stitching.cpp
index ddd765f..0062f90 100644
--- a/tests/test-image-stitching.cpp
+++ b/tests/test-image-stitching.cpp
@@ -31,12 +31,16 @@
#include <ocl/cl_image_360_stitch.h>
#include <ocl/cl_utils.h>
#if HAVE_OPENCV
-#include <ocl/cv_base_class.h>
+#include "ocv/cv_utils.h"
#endif
#define XCAM_TEST_STITCH_DEBUG 0
#define XCAM_ALIGNED_WIDTH 16
+#if HAVE_OPENCV
+#define FOURCC_X264 cv::VideoWriter::fourcc ('X', '2', '6', '4')
+#endif
+
#define CHECK_ACCESS(fliename) \
if (access (fliename, F_OK) != 0) { \
XCAM_LOG_ERROR ("%s not found", fliename); \
@@ -59,31 +63,28 @@ parse_calibration_params (
ExtrinsicParameter extrinsic_param[],
int fisheye_num)
{
+ static const char *instrinsic_names[] = {
+ "intrinsic_camera_front.txt", "intrinsic_camera_right.txt",
+ "intrinsic_camera_rear.txt", "intrinsic_camera_left.txt"
+ };
+ static const char *exstrinsic_names[] = {
+ "extrinsic_camera_front.txt", "extrinsic_camera_right.txt",
+ "extrinsic_camera_rear.txt", "extrinsic_camera_left.txt"
+ };
+
+ std::string fisheye_config_path = FISHEYE_CONFIG_PATH;
+ const char *env = std::getenv (FISHEYE_CONFIG_ENV_VAR);
+ if (env)
+ fisheye_config_path.assign (env, strlen (env));
+ XCAM_LOG_INFO ("calibration config path:%s", fisheye_config_path.c_str ());
+
CalibrationParser calib_parser;
+ XCAM_ASSERT (fisheye_num <= 4);
char intrinsic_path[1024], extrinsic_path[1024];
for(int index = 0; index < fisheye_num; index++) {
- switch (index) {
- case 0:
- strncpy (intrinsic_path, "./calib_params/intrinsic_camera_front.txt", 1023);
- strncpy (extrinsic_path, "./calib_params/extrinsic_camera_front.txt", 1023);
- break;
- case 1:
- strncpy (intrinsic_path, "./calib_params/intrinsic_camera_right.txt", 1023);
- strncpy (extrinsic_path, "./calib_params/extrinsic_camera_right.txt", 1023);
- break;
- case 2:
- strncpy (intrinsic_path, "./calib_params/intrinsic_camera_rear.txt", 1023);
- strncpy (extrinsic_path, "./calib_params/extrinsic_camera_rear.txt", 1023);
- break;
- case 3:
- strncpy (intrinsic_path, "./calib_params/intrinsic_camera_left.txt", 1023);
- strncpy (extrinsic_path, "./calib_params/extrinsic_camera_left.txt", 1023);
- break;
- default:
- XCAM_LOG_ERROR ("bowl view only support 4-camera mode");
- return false;
- }
+ snprintf (intrinsic_path, 1023, "%s/%s", fisheye_config_path.c_str (), instrinsic_names[index]);
+ snprintf (extrinsic_path, 1023, "%s/%s", fisheye_config_path.c_str (), exstrinsic_names[index]);
CHECK_ACCESS (intrinsic_path);
CHECK_ACCESS (extrinsic_path);
@@ -148,11 +149,13 @@ void usage(const char* arg0)
"\t--enable-fisheyemap optional, enable fisheye map, default: no\n"
"\t--enable-lsc optional, enable lens shading correction, default: no\n"
#if HAVE_OPENCV
- "\t--fm-ocl optional, enable ocl for feature match, select from [true/false], default: false\n"
+ "\t--fm optional, enable or disable feature match, default: true\n"
#endif
"\t--fisheye-num optional, the number of fisheye lens, default: 2\n"
"\t--all-in-one optional, all fisheye in one image, select from [true/false], default: true\n"
"\t--save optional, save file or not, select from [true/false], default: true\n"
+ "\t--save-top-view optional, save top view videos. default: no\n"
+ "\t--save-free-view optional, save rectified(free) view videos. default: no\n"
"\t--framerate optional, framerate of saved video, default: 30.0\n"
"\t--loop optional, how many loops need to run for performance test, default: 1\n"
"\t--help usage\n",
@@ -186,19 +189,21 @@ int main (int argc, char *argv[])
bool enable_seam = false;
bool enable_fisheye_map = false;
bool enable_lsc = false;
+#if HAVE_OPENCV
+ bool need_fm = true;
+#endif
CLBlenderScaleMode scale_mode = CLBlenderScaleLocal;
StitchResMode res_mode = StitchRes1080P;
- SurroundMode surround_mode = BowlView;
+ SurroundMode surround_mode = SphereView;
IntrinsicParameter intrinsic_param[XCAM_STITCH_FISHEYE_MAX_NUM];
ExtrinsicParameter extrinsic_param[XCAM_STITCH_FISHEYE_MAX_NUM];
-#if HAVE_OPENCV
- bool fm_ocl = false;
-#endif
int fisheye_num = 2;
bool all_in_one = true;
bool need_save_output = true;
+ bool save_top_view = false;
+ bool save_free_view = false;
double framerate = 30.0;
const char *file_in_name[XCAM_STITCH_FISHEYE_MAX_NUM] = {NULL};
@@ -222,11 +227,13 @@ int main (int argc, char *argv[])
{"enable-fisheyemap", no_argument, NULL, 'F'},
{"enable-lsc", no_argument, NULL, 'L'},
#if HAVE_OPENCV
- {"fm-ocl", required_argument, NULL, 'O'},
+ {"fm", required_argument, NULL, 'm'},
#endif
{"fisheye-num", required_argument, NULL, 'N'},
{"all-in-one", required_argument, NULL, 'A'},
{"save", required_argument, NULL, 's'},
+ {"save-top-view", no_argument, NULL, 't'},
+ {"save-free-view", no_argument, NULL, 'v'},
{"framerate", required_argument, NULL, 'f'},
{"loop", required_argument, NULL, 'l'},
{"help", no_argument, NULL, 'e'},
@@ -299,8 +306,8 @@ int main (int argc, char *argv[])
enable_lsc = true;
break;
#if HAVE_OPENCV
- case 'O':
- fm_ocl = (strcasecmp (optarg, "true") == 0 ? true : false);
+ case 'm':
+ need_fm = (strcasecmp (optarg, "false") == 0 ? false : true);
break;
#endif
case 'N':
@@ -316,6 +323,12 @@ int main (int argc, char *argv[])
case 's':
need_save_output = (strcasecmp (optarg, "false") == 0 ? false : true);
break;
+ case 't':
+ save_top_view = true;
+ break;
+ case 'v':
+ save_free_view = true;
+ break;
case 'f':
framerate = atof(optarg);
break;
@@ -324,7 +337,7 @@ int main (int argc, char *argv[])
break;
case 'e':
usage (argv[0]);
- return -1;
+ return 0;
default:
XCAM_LOG_ERROR ("getopt_long return unknown value:%c", opt);
usage (argv[0]);
@@ -351,8 +364,8 @@ int main (int argc, char *argv[])
}
}
- if (!file_out_name) {
- XCAM_LOG_ERROR ("output path is NULL");
+ if (!file_out_name && need_save_output) {
+ XCAM_LOG_ERROR ("output path is NULL, video can't be saved");
return -1;
}
@@ -365,7 +378,7 @@ int main (int argc, char *argv[])
#if !HAVE_OPENCV
if (need_save_output) {
- XCAM_LOG_WARNING ("non-OpenCV mode, can't save video");
+ XCAM_LOG_WARNING ("non-OpenCV mode, can't save video to file:%s", XCAM_STR (file_out_name));
need_save_output = false;
}
#endif
@@ -377,7 +390,7 @@ int main (int argc, char *argv[])
for (int i = 0; i < input_count; i++)
printf ("input file %d:\t\t%s\n", i, file_in_name[i]);
}
- printf ("output file:\t\t%s\n", file_out_name);
+ printf ("output file:\t\t%s\n", XCAM_STR (file_out_name));
printf ("input width:\t\t%d\n", input_width);
printf ("input height:\t\t%d\n", input_height);
printf ("output width:\t\t%d\n", output_width);
@@ -391,11 +404,13 @@ int main (int argc, char *argv[])
printf ("fisheye map:\t\t%s\n", enable_fisheye_map ? "true" : "false");
printf ("shading correction:\t%s\n", enable_lsc ? "true" : "false");
#if HAVE_OPENCV
- printf ("feature match ocl:\t%s\n", fm_ocl ? "true" : "false");
+ printf ("feature match:\t\t%s\n", need_fm ? "true" : "false");
#endif
printf ("fisheye number:\t\t%d\n", fisheye_num);
printf ("all in one:\t\t%s\n", all_in_one ? "true" : "false");
printf ("save file:\t\t%s\n", need_save_output ? "true" : "false");
+ printf ("save top-view file:\t%s\n", save_top_view ? top_view_filename : "NO");
+ printf ("save free-view file:\t%s\n", save_free_view ? rectified_view_filename : "NO");
printf ("framerate:\t\t%.3lf\n", framerate);
printf ("loop count:\t\t%d\n", loop);
printf ("-----------------------------------\n");
@@ -407,13 +422,16 @@ int main (int argc, char *argv[])
res_mode, fisheye_num, all_in_one).dynamic_cast_ptr<CLImage360Stitch> ();
XCAM_ASSERT (image_360.ptr ());
image_360->set_output_size (output_width, output_height);
+ image_360->set_pool_type (CLImageHandler::CLVideoPoolType);
#if HAVE_OPENCV
- image_360->set_feature_match_ocl (fm_ocl);
+ image_360->set_feature_match (need_fm);
#endif
- image_360->set_pool_type (CLImageHandler::CLVideoPoolType);
if (surround_mode == BowlView) {
- parse_calibration_params (intrinsic_param, extrinsic_param, fisheye_num);
+ if (!parse_calibration_params (intrinsic_param, extrinsic_param, fisheye_num)) {
+ XCAM_LOG_ERROR ("parse calibration data failed in surround view.");
+ return -1;
+ }
for (int i = 0; i < fisheye_num; i++) {
image_360->set_fisheye_intrinsic (intrinsic_param[i], i);
@@ -426,13 +444,15 @@ int main (int argc, char *argv[])
top_view_buf_info.init (input_format, top_view_width, top_view_height);
rectified_view_buf_info.init (input_format, rectified_view_width, rectified_view_height);
for (int i = 0; i < input_count; i++) {
- buf_pool[i] = new CLVideoBufferPool ();
- XCAM_ASSERT (buf_pool[i].ptr ());
- buf_pool[i]->set_video_info (input_buf_info);
- if (!buf_pool[i]->reserve (6)) {
+ SmartPtr<BufferPool> pool = new CLVideoBufferPool ();
+ XCAM_ASSERT (pool.ptr ());
+ pool->set_video_info (input_buf_info);
+ if (!pool->reserve (6)) {
XCAM_LOG_ERROR ("init buffer pool failed");
return -1;
}
+
+ buf_pool[i] = pool;
}
SmartPtr<BufferPool> top_view_pool = new CLVideoBufferPool ();
@@ -464,19 +484,21 @@ int main (int argc, char *argv[])
cv::VideoWriter rectified_view_writer;
if (need_save_output) {
cv::Size dst_size = cv::Size (output_width, output_height);
- if (!writer.open (file_out_name, CV_FOURCC('X', '2', '6', '4'), framerate, dst_size)) {
+ if (!writer.open (file_out_name, FOURCC_X264, framerate, dst_size)) {
XCAM_LOG_ERROR ("open file %s failed", file_out_name);
return -1;
}
-
- dst_size = cv::Size (top_view_width, top_view_height);
- if (!top_view_writer.open (top_view_filename, CV_FOURCC('X', '2', '6', '4'), framerate, dst_size)) {
+ }
+ if (save_top_view) {
+ cv::Size dst_size = cv::Size (top_view_width, top_view_height);
+ if (!top_view_writer.open (top_view_filename, FOURCC_X264, framerate, dst_size)) {
XCAM_LOG_ERROR ("open file %s failed", top_view_filename);
return -1;
}
-
- dst_size = cv::Size (rectified_view_width, rectified_view_height);
- if (!rectified_view_writer.open (rectified_view_filename, CV_FOURCC('X', '2', '6', '4'), framerate, dst_size)) {
+ }
+ if (save_free_view) {
+ cv::Size dst_size = cv::Size (rectified_view_width, rectified_view_height);
+ if (!rectified_view_writer.open (rectified_view_filename, FOURCC_X264, framerate, dst_size)) {
XCAM_LOG_ERROR ("open file %s failed", rectified_view_filename);
return -1;
}
@@ -484,13 +506,15 @@ int main (int argc, char *argv[])
#endif
SmartPtr<VideoBuffer> pre_buf, cur_buf;
-#if (HAVE_OPENCV) && (XCAM_TEST_STITCH_DEBUG)
+ int frame_id = 0;
+#if (HAVE_OPENCV)
+#if XCAM_TEST_STITCH_DEBUG
SmartPtr<VideoBuffer> input_bufs[XCAM_STITCH_FISHEYE_MAX_NUM];
#endif
- int frame_id = 0;
std::vector<PointFloat2> top_view_map_table;
std::vector<PointFloat2> rectified_view_map_table;
float rectified_start_angle = -45.0f, rectified_end_angle = 45.0f;
+#endif
while (loop--) {
for (int i = 0; i < input_count; i++) {
@@ -532,24 +556,29 @@ int main (int argc, char *argv[])
cv::Mat out_mat;
convert_to_mat (output_buf, out_mat);
writer.write (out_mat);
+ }
- BowlDataConfig config = image_360->get_fisheye_bowl_config ();
+ BowlDataConfig config = image_360->get_fisheye_bowl_config ();
+ if (save_top_view) {
cv::Mat top_view_mat;
sample_generate_top_view (output_buf, top_view_buf, config, top_view_map_table);
convert_to_mat (top_view_buf, top_view_mat);
top_view_writer.write (top_view_mat);
-
+ }
+ if (save_free_view) {
cv::Mat rectified_view_mat;
sample_generate_rectified_view (output_buf, rectified_view_buf, config, rectified_start_angle,
rectified_end_angle, rectified_view_map_table);
convert_to_mat (rectified_view_buf, rectified_view_mat);
rectified_view_writer.write (rectified_view_mat);
+ }
#if XCAM_TEST_STITCH_DEBUG
- dbg_write_image (context, image_360, input_bufs, output_buf, top_view_buf, rectified_view_buf,
- all_in_one, fisheye_num, input_count);
+ dbg_write_image (context, image_360, input_bufs, output_buf, top_view_buf, rectified_view_buf,
+ all_in_one, fisheye_num, input_count);
#endif
- } else
+
+ if (!(need_save_output || save_top_view || save_free_view))
#endif
ensure_gpu_buffer_done (output_buf);
diff --git a/tests/test-pipe-manager.cpp b/tests/test-pipe-manager.cpp
index 280bfdc..1389699 100644
--- a/tests/test-pipe-manager.cpp
+++ b/tests/test-pipe-manager.cpp
@@ -199,8 +199,6 @@ int main (int argc, char *argv[])
VideoBufferInfo buf_info;
SmartPtr<VideoBuffer> video_buf;
SmartPtr<SmartAnalyzer> smart_analyzer;
- SmartPtr<CLPostImageProcessor> cl_post_processor;
- SmartPtr<BufferPool> buf_pool;
uint32_t pixel_format = V4L2_PIX_FMT_NV12;
uint32_t image_width = 1920;
@@ -400,7 +398,7 @@ int main (int argc, char *argv[])
pipe_manager->set_smart_analyzer (smart_analyzer);
}
- cl_post_processor = new CLPostImageProcessor ();
+ SmartPtr<CLPostImageProcessor> cl_post_processor = new CLPostImageProcessor ();
cl_post_processor->set_stats_callback (pipe_manager);
cl_post_processor->set_defog_mode ((CLPostImageProcessor::CLDefogMode) defog_mode);
cl_post_processor->set_wavelet (wavelet_mode, wavelet_channel, wavelet_bayes_shrink);
@@ -416,7 +414,7 @@ int main (int argc, char *argv[])
pipe_manager->add_image_processor (cl_post_processor);
buf_info.init (pixel_format, image_width, image_height);
- buf_pool = new CLVideoBufferPool ();
+ SmartPtr<BufferPool> buf_pool = new CLVideoBufferPool ();
XCAM_ASSERT (buf_pool.ptr ());
if (!buf_pool->set_video_info (buf_info) || !buf_pool->reserve (DEFAULT_FPT_BUF_COUNT)) {
XCAM_LOG_ERROR ("init buffer pool failed");
diff --git a/tests/test-render-surround-view.cpp b/tests/test-render-surround-view.cpp
new file mode 100644
index 0000000..9142d4d
--- /dev/null
+++ b/tests/test-render-surround-view.cpp
@@ -0,0 +1,688 @@
+/*
+ * test-render-surround-view.cpp - test render surround view
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Zong Wei <wei.zong@intel.com>
+ */
+
+#include "test_common.h"
+#include "test_stream.h"
+#include <interface/geo_mapper.h>
+#include <interface/stitcher.h>
+#include <calibration_parser.h>
+#include <soft/soft_video_buf_allocator.h>
+#if HAVE_GLES
+#include <gles/gl_video_buffer.h>
+#include <gles/egl/egl_base.h>
+#endif
+#if HAVE_VULKAN
+#include <vulkan/vk_device.h>
+#endif
+
+#include <render/render_osg_viewer.h>
+#include <render/render_osg_model.h>
+#include <render/render_osg_shader.h>
+
+using namespace XCam;
+
+#define CAR_MODEL_NAME "Suv.osgb"
+
+enum SVModule {
+ SVModuleNone = 0,
+ SVModuleSoft,
+ SVModuleGLES,
+ SVModuleVulkan
+};
+
+static const char *instrinsic_names[] = {
+ "intrinsic_camera_front.txt",
+ "intrinsic_camera_right.txt",
+ "intrinsic_camera_rear.txt",
+ "intrinsic_camera_left.txt"
+};
+
+static const char *exstrinsic_names[] = {
+ "extrinsic_camera_front.txt",
+ "extrinsic_camera_right.txt",
+ "extrinsic_camera_rear.txt",
+ "extrinsic_camera_left.txt"
+};
+
+static const float viewpoints_range[] = {64.0f, 160.0f, 64.0f, 160.0f};
+
+static const char VtxShaderCar[] = ""
+ "precision highp float; \n"
+ "uniform mat4 osg_ModelViewProjectionMatrix; \n"
+ "uniform mat4 osg_ModelViewMatrix; \n"
+ "uniform mat3 osg_NormalMatrix; \n"
+ "attribute vec3 osg_Normal; \n"
+ "attribute vec4 osg_Color; \n"
+ "attribute vec4 osg_Vertex; \n"
+ "varying vec4 v_color; \n"
+ "varying float diffuseLight; \n"
+ "varying float specLight; \n"
+ "attribute vec2 osg_MultiTexCoord0; \n"
+ "varying vec2 texCoord0; \n"
+ "void main() \n"
+ "{ \n"
+ " vec4 light = vec4(0.0,100.0, 100.0, 1.0); \n"
+ " vec4 lightColorSpec = vec4(1.0, 1.0, 1.0, 1.0); \n"
+ " vec4 lightColorDiffuse = vec4(1.0, 1.0, 1.0, 1.0); \n"
+ " vec4 lightColorAmbient = vec4(0.3, 0.3, .3, 1.0); \n"
+ " vec4 carColorAmbient = vec4(0.0, 0.0, 1.0, 1.0); \n"
+ " vec4 carColorDiffuse = vec4(0.0, 0.0, 1.0, 1.0); \n"
+ " vec4 carColorSpec = vec4(1.0, 1.0, 1.0, 1.0); \n"
+ " vec3 tnorm = normalize(osg_NormalMatrix * osg_Normal); \n"
+ " vec4 eye = osg_ModelViewMatrix * osg_Vertex; \n"
+ " vec3 s = normalize(vec3(light - eye)); \n"
+ " vec3 v = normalize(-eye.xyz); \n"
+ " vec3 r = reflect(-s, tnorm); \n"
+ " diffuseLight = max(0.0, dot( s, tnorm)); \n"
+ " specLight = 0.0; \n"
+ " if(diffuseLight > 0.0) \n"
+ " { \n"
+ " specLight = pow(max(0.0, dot(r,v)), 10.0); \n"
+ " } \n"
+ " texCoord0 = osg_MultiTexCoord0; \n"
+ " v_color = (specLight * lightColorSpec * carColorSpec) + (carColorDiffuse * lightColorDiffuse * diffuseLight) + lightColorAmbient * carColorAmbient; \n"
+ " gl_Position = osg_ModelViewProjectionMatrix * osg_Vertex; \n"
+ "} \n";
+
+static const char FrgShaderCar[] = ""
+ "precision highp float; \n"
+ "varying vec4 v_color; \n"
+ "varying float diffuseLight; \n"
+ "varying float specLight; \n"
+ "uniform sampler2D textureWheel; \n"
+ "varying vec2 texCoord0; \n"
+ "void main() \n"
+ "{ \n"
+ " vec4 lightColorSpec = vec4(1.0, 1.0, 1.0, 1.0); \n"
+ " vec4 lightColorDiffuse = vec4(1.0, 1.0, 1.0, 1.0); \n"
+ " vec4 lightColorAmbient = vec4(0.3, 0.3, .3, 1.0); \n"
+ " vec4 base = texture2D(textureWheel, texCoord0.st); \n"
+ " gl_FragColor = (specLight * lightColorSpec * base) + (base * lightColorDiffuse * diffuseLight) + lightColorAmbient * base ; \n"
+ "} \n";
+
+class SVStream
+ : public Stream
+{
+public:
+ explicit SVStream (const char *file_name = NULL, uint32_t width = 0, uint32_t height = 0);
+ virtual ~SVStream () {}
+
+ void set_module (SVModule module) {
+ XCAM_ASSERT (module != SVModuleNone);
+ _module = module;
+ }
+
+#if HAVE_VULKAN
+ void set_vk_device (SmartPtr<VKDevice> &device) {
+ XCAM_ASSERT (device.ptr ());
+ _vk_dev = device;
+ }
+ SmartPtr<VKDevice> &get_vk_device () {
+ return _vk_dev;
+ }
+#endif
+
+ virtual XCamReturn create_buf_pool (const VideoBufferInfo &info, uint32_t count);
+
+private:
+ XCAM_DEAD_COPY (SVStream);
+
+private:
+ SVModule _module;
+#if HAVE_VULKAN
+ SmartPtr<VKDevice> _vk_dev;
+#endif
+};
+typedef std::vector<SmartPtr<SVStream>> SVStreams;
+
+SVStream::SVStream (const char *file_name, uint32_t width, uint32_t height)
+ : Stream (file_name, width, height)
+ , _module (SVModuleNone)
+{
+}
+
+XCamReturn
+SVStream::create_buf_pool (const VideoBufferInfo &info, uint32_t count)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, _module != SVModuleNone, XCAM_RETURN_ERROR_PARAM,
+ "invalid module, please set module first");
+
+ SmartPtr<BufferPool> pool;
+ if (_module == SVModuleSoft) {
+ pool = new SoftVideoBufAllocator (info);
+ } else if (_module == SVModuleGLES) {
+#if HAVE_GLES
+ pool = new GLVideoBufferPool (info);
+#endif
+ } else if (_module == SVModuleVulkan) {
+#if HAVE_VULKAN
+ XCAM_ASSERT (_vk_dev.ptr ());
+ pool = create_vk_buffer_pool (_vk_dev);
+ XCAM_ASSERT (pool.ptr ());
+ pool->set_video_info (info);
+#endif
+ }
+ XCAM_ASSERT (pool.ptr ());
+
+ if (!pool->reserve (count)) {
+ XCAM_LOG_ERROR ("create buffer pool failed");
+ pool.release ();
+ return XCAM_RETURN_ERROR_MEM;
+ }
+
+ set_buf_pool (pool);
+ return XCAM_RETURN_NO_ERROR;
+}
+
+static SmartPtr<Stitcher>
+create_stitcher (const SmartPtr<SVStream> &stitch, SVModule module)
+{
+ SmartPtr<Stitcher> stitcher;
+
+ if (module == SVModuleSoft) {
+ stitcher = Stitcher::create_soft_stitcher ();
+ } else if (module == SVModuleGLES) {
+#if HAVE_GLES
+ stitcher = Stitcher::create_gl_stitcher ();
+#endif
+ } else if (module == SVModuleVulkan) {
+#if HAVE_VULKAN
+ SmartPtr<VKDevice> dev = stitch->get_vk_device ();
+ XCAM_ASSERT (dev.ptr ());
+ stitcher = Stitcher::create_vk_stitcher (dev);
+#else
+ XCAM_UNUSED (stitch);
+#endif
+ }
+ XCAM_ASSERT (stitcher.ptr ());
+
+ return stitcher;
+}
+
+static int
+parse_camera_info (const char *path, uint32_t idx, CameraInfo &info, uint32_t camera_count)
+{
+ XCAM_ASSERT (path);
+
+ char intrinsic_path[XCAM_TEST_MAX_STR_SIZE] = {'\0'};
+ char extrinsic_path[XCAM_TEST_MAX_STR_SIZE] = {'\0'};
+ snprintf (intrinsic_path, XCAM_TEST_MAX_STR_SIZE, "%s/%s", path, instrinsic_names[idx]);
+ snprintf (extrinsic_path, XCAM_TEST_MAX_STR_SIZE, "%s/%s", path, exstrinsic_names[idx]);
+
+ CalibrationParser parser;
+ CHECK (
+ parser.parse_intrinsic_file (intrinsic_path, info.calibration.intrinsic),
+ "parse intrinsic params(%s) failed.", intrinsic_path);
+
+ CHECK (
+ parser.parse_extrinsic_file (extrinsic_path, info.calibration.extrinsic),
+ "parse extrinsic params(%s) failed.", extrinsic_path);
+ info.calibration.extrinsic.trans_x += TEST_CAMERA_POSITION_OFFSET_X;
+
+ info.angle_range = viewpoints_range[idx];
+ info.round_angle_start = (idx * 360.0f / camera_count) - info.angle_range / 2.0f;
+ return 0;
+}
+
+void
+get_bowl_model (
+ const SmartPtr<Stitcher> &stitcher,
+ BowlModel::VertexMap &vertices,
+ BowlModel::PointMap &points,
+ BowlModel::IndexVector &indices,
+ float &a,
+ float &b,
+ float &c,
+ float resRatio,
+ uint32_t image_width,
+ uint32_t image_height)
+{
+ uint32_t res_width = image_width * resRatio;
+ uint32_t res_height = image_height * resRatio;
+
+ BowlDataConfig bowl = stitcher->get_bowl_config();
+ bowl.angle_start = 0.0f;
+ bowl.angle_end = 360.0f;
+
+ a = bowl.a;
+ b = bowl.b;
+ c = bowl.c;
+
+ BowlModel bowl_model(bowl, image_width, image_height);
+
+ bowl_model.get_bowlview_vertex_model(
+ vertices,
+ points,
+ indices,
+ res_width,
+ res_height);
+}
+
+static SmartPtr<RenderOsgModel>
+create_surround_view_model (
+ const SmartPtr<Stitcher> &stitcher,
+ uint32_t texture_width,
+ uint32_t texture_height)
+{
+ SmartPtr<RenderOsgModel> svm_model = new RenderOsgModel ("svm model", texture_width, texture_height);
+
+ svm_model->setup_shader_program ("SVM", osg::Shader::VERTEX, VtxShaderProjectNV12Texture);
+ svm_model->setup_shader_program ("SVM", osg::Shader::FRAGMENT, FrgShaderProjectNV12Texture);
+
+ BowlModel::VertexMap vertices;
+ BowlModel::PointMap points;
+ BowlModel::IndexVector indices;
+
+ float a = 0;
+ float b = 0;
+ float c = 0;
+ float res_ratio = 0.3;
+ float scaling = 1000.0f;
+
+ get_bowl_model (stitcher, vertices, points, indices,
+ a, b, c, res_ratio, texture_width, texture_height );
+
+ svm_model->setup_vertex_model (vertices, points, indices, a / scaling, b / scaling, c / scaling);
+
+ return svm_model;
+}
+
+static SmartPtr<RenderOsgModel>
+create_car_model (const char *name)
+{
+ std::string car_name;
+ if (NULL != name) {
+ car_name = std::string (name);
+ } else {
+ car_name = std::string (CAR_MODEL_NAME);
+ }
+ std::string car_model_path = FISHEYE_CONFIG_PATH + car_name;
+
+ const char *env_path = std::getenv (FISHEYE_CONFIG_ENV_VAR);
+ if (env_path) {
+ car_model_path.clear ();
+ car_model_path = std::string (env_path) + car_name;
+ }
+
+ SmartPtr<RenderOsgModel> car_model = new RenderOsgModel (car_model_path.c_str(), true);
+
+ car_model->setup_shader_program ("Car", osg::Shader::VERTEX, VtxShaderCar);
+ car_model->setup_shader_program ("Car", osg::Shader::FRAGMENT, FrgShaderCar);
+
+ float translation_x = -0.3f;
+ float translation_y = 0.0f;
+ float translation_z = 0.0f;
+ float rotation_x = 0.0f;
+ float rotation_y = 0.0f;
+ float rotation_z = 1.0f;
+ float rotation_degrees = -180.0;
+
+ car_model->setup_model_matrix (
+ translation_x,
+ translation_y,
+ translation_z,
+ rotation_x,
+ rotation_y,
+ rotation_z,
+ rotation_degrees);
+
+ return car_model;
+}
+
+static int
+run_stitcher (
+ const SmartPtr<Stitcher> &stitcher,
+ const SmartPtr<RenderOsgModel> &model,
+ const SVStreams &ins,
+ const SVStreams &outs)
+{
+ XCamReturn ret = XCAM_RETURN_NO_ERROR;
+
+ Mutex mutex;
+
+ VideoBufferList in_buffers;
+ for (uint32_t i = 0; i < ins.size (); ++i) {
+ CHECK (ins[i]->rewind (), "rewind buffer from file(%s) failed", ins[i]->get_file_name ());
+ }
+
+ do {
+ in_buffers.clear ();
+
+ for (uint32_t i = 0; i < ins.size (); ++i) {
+ ret = ins[i]->read_buf();
+ if (ret == XCAM_RETURN_BYPASS)
+ break;
+ CHECK (ret, "read buffer from file(%s) failed.", ins[i]->get_file_name ());
+ in_buffers.push_back (ins[i]->get_buf ());
+ }
+ if (ret == XCAM_RETURN_BYPASS) {
+ XCAM_LOG_DEBUG ("XCAM_RETURN_BYPASS \n");
+ break;
+ }
+
+ {
+ SmartLock locker (mutex);
+ CHECK (
+ stitcher->stitch_buffers (in_buffers, outs[0]->get_buf ()),
+ "stitch buffer failed.");
+ }
+
+ model->update_texture (outs[0]->get_buf ());
+
+ FPS_CALCULATION (render surround view, XCAM_OBJ_DUR_FRAME_NUM);
+ } while (true);
+
+ return 0;
+}
+
+static void usage(const char* arg0)
+{
+ printf ("Usage:\n"
+ "%s --module MODULE --input0 input.nv12 --input1 input1.nv12 --input2 input2.nv12 ...\n"
+ "\t--module processing module, selected from: soft, gles, vulkan\n"
+ "\t-- read calibration files from exported path $FISHEYE_CONFIG_PATH\n"
+ "\t--input0 input image(NV12)\n"
+ "\t--input1 input image(NV12)\n"
+ "\t--input2 input image(NV12)\n"
+ "\t--input3 input image(NV12)\n"
+ "\t--in-w optional, input width, default: 1280\n"
+ "\t--in-h optional, input height, default: 800\n"
+ "\t--out-w optional, output width, default: 1920\n"
+ "\t--out-h optional, output height, default: 640\n"
+ "\t--scale-mode optional, scaling mode for geometric mapping,\n"
+ "\t select from [singleconst/dualconst/dualcurve], default: singleconst\n"
+ "\t--fm-mode optional, feature match mode,\n"
+#if HAVE_OPENCV
+ "\t select from [none/default/cluster/capi], default: none\n"
+#else
+ "\t select from [none], default: none\n"
+#endif
+ "\t--car optional, car model name\n"
+ "\t--loop optional, how many loops need to run, default: 1\n"
+ "\t--help usage\n",
+ arg0);
+}
+
+int main (int argc, char *argv[])
+{
+ uint32_t input_width = 1280;
+ uint32_t input_height = 800;
+ uint32_t output_width = 1920;
+ uint32_t output_height = 640;
+
+ SVStreams ins;
+ SVStreams outs;
+ PUSH_STREAM (SVStream, outs, NULL);
+
+ const char *car_name = NULL;
+
+ SVModule module = SVModuleGLES;
+ GeoMapScaleMode scale_mode = ScaleSingleConst;
+ FeatureMatchMode fm_mode = FMNone;
+
+ int loop = 1;
+
+ const struct option long_opts[] = {
+ {"module", required_argument, NULL, 'm'},
+ {"input0", required_argument, NULL, 'i'},
+ {"input1", required_argument, NULL, 'j'},
+ {"input2", required_argument, NULL, 'k'},
+ {"input3", required_argument, NULL, 'l'},
+ {"in-w", required_argument, NULL, 'w'},
+ {"in-h", required_argument, NULL, 'h'},
+ {"out-w", required_argument, NULL, 'W'},
+ {"out-h", required_argument, NULL, 'H'},
+ {"scale-mode", required_argument, NULL, 'S'},
+ {"fm-mode", required_argument, NULL, 'F'},
+ {"car", required_argument, NULL, 'c'},
+ {"loop", required_argument, NULL, 'L'},
+ {"help", no_argument, NULL, 'e'},
+ {NULL, 0, NULL, 0},
+ };
+
+ int opt = -1;
+ while ((opt = getopt_long(argc, argv, "", long_opts, NULL)) != -1) {
+ switch (opt) {
+ case 'm':
+ XCAM_ASSERT (optarg);
+ if (!strcasecmp (optarg, "soft")) {
+ module = SVModuleSoft;
+ } else if (!strcasecmp (optarg, "gles")) {
+ module = SVModuleGLES;
+ } else if (!strcasecmp (optarg, "vulkan")) {
+ module = SVModuleVulkan;
+ }
+ break;
+ case 'i':
+ XCAM_ASSERT (optarg);
+ PUSH_STREAM (SVStream, ins, optarg);
+ break;
+ case 'j':
+ XCAM_ASSERT (optarg);
+ PUSH_STREAM (SVStream, ins, optarg);
+ break;
+ case 'k':
+ XCAM_ASSERT (optarg);
+ PUSH_STREAM (SVStream, ins, optarg);
+ break;
+ case 'l':
+ XCAM_ASSERT (optarg);
+ PUSH_STREAM (SVStream, ins, optarg);
+ break;
+ case 'w':
+ XCAM_ASSERT (optarg);
+ input_width = (uint32_t)atoi(optarg);
+ break;
+ case 'h':
+ XCAM_ASSERT (optarg);
+ input_height = (uint32_t)atoi(optarg);
+ break;
+ case 'W':
+ XCAM_ASSERT (optarg);
+ output_width = (uint32_t)atoi(optarg);
+ break;
+ case 'H':
+ XCAM_ASSERT (optarg);
+ output_height = (uint32_t)atoi(optarg);
+ break;
+ case 'S':
+ XCAM_ASSERT (optarg);
+ if (!strcasecmp (optarg, "singleconst"))
+ scale_mode = ScaleSingleConst;
+ else if (!strcasecmp (optarg, "dualconst"))
+ scale_mode = ScaleDualConst;
+ else if (!strcasecmp (optarg, "dualcurve"))
+ scale_mode = ScaleDualCurve;
+ else {
+ XCAM_LOG_ERROR ("GeoMapScaleMode unknown mode: %s", optarg);
+ usage (argv[0]);
+ return -1;
+ }
+ break;
+ case 'F':
+ XCAM_ASSERT (optarg);
+ if (!strcasecmp (optarg, "none"))
+ fm_mode = FMNone;
+#if HAVE_OPENCV
+ else if (!strcasecmp (optarg, "default"))
+ fm_mode = FMDefault;
+ else if (!strcasecmp (optarg, "cluster"))
+ fm_mode = FMCluster;
+ else if (!strcasecmp (optarg, "capi"))
+ fm_mode = FMCapi;
+#endif
+ else {
+ XCAM_LOG_ERROR ("unsupported feature match mode: %s", optarg);
+ usage (argv[0]);
+ return -1;
+ }
+ break;
+ case 'c':
+ XCAM_ASSERT (optarg);
+ car_name = optarg;
+ break;
+ case 'L':
+ loop = atoi(optarg);
+ break;
+ case 'e':
+ usage (argv[0]);
+ return 0;
+ default:
+ XCAM_LOG_ERROR ("getopt_long return unknown value: %c", opt);
+ usage (argv[0]);
+ return -1;
+ }
+ }
+
+ if (optind < argc || argc < 2) {
+ XCAM_LOG_ERROR ("unknown option %s", argv[optind]);
+ usage (argv[0]);
+ return -1;
+ }
+
+ CHECK_EXP (ins.size () == 4, "surrond view needs 4 input streams");
+ for (uint32_t i = 0; i < ins.size (); ++i) {
+ CHECK_EXP (ins[i].ptr (), "input stream is NULL, index:%d", i);
+ CHECK_EXP (strlen (ins[i]->get_file_name ()), "input file name was not set, index:%d", i);
+ }
+
+ CHECK_EXP (outs.size () == 1 && outs[0].ptr (), "surrond view needs 1 output stream");
+
+ for (uint32_t i = 0; i < ins.size (); ++i) {
+ printf ("input%d file:\t\t%s\n", i, ins[i]->get_file_name ());
+ }
+ printf ("input width:\t\t%d\n", input_width);
+ printf ("input height:\t\t%d\n", input_height);
+ printf ("output width:\t\t%d\n", output_width);
+ printf ("output height:\t\t%d\n", output_height);
+ printf ("scaling mode:\t\t%s\n", (scale_mode == ScaleSingleConst) ? "singleconst" :
+ ((scale_mode == ScaleDualConst) ? "dualconst" : "dualcurve"));
+ printf ("feature match:\t\t%s\n", (fm_mode == FMNone) ? "none" :
+ ((fm_mode == FMDefault ) ? "default" : ((fm_mode == FMCluster) ? "cluster" : "capi")));
+ printf ("car model name:\t\t%s\n", car_name != NULL ? car_name : "Not specified, use default model");
+ printf ("loop count:\t\t%d\n", loop);
+
+#if HAVE_GLES
+ SmartPtr<EGLBase> egl;
+ if (module == SVModuleGLES) {
+ egl = new EGLBase ();
+ XCAM_ASSERT (egl.ptr ());
+ XCAM_FAIL_RETURN (ERROR, egl->init (), -1, "init EGL failed");
+ }
+#else
+ if (module == SVModuleGLES) {
+ XCAM_LOG_ERROR ("GLES module is unsupported");
+ return -1;
+ }
+#endif
+
+ if (module == SVModuleVulkan) {
+#if HAVE_VULKAN
+ scale_mode = ScaleSingleConst;
+ if (scale_mode != ScaleSingleConst) {
+ XCAM_LOG_ERROR ("vulkan module only support singleconst scale mode currently");
+ return -1;
+ }
+
+ SmartPtr<VKDevice> vk_dev = VKDevice::default_device ();
+ for (uint32_t i = 0; i < ins.size (); ++i) {
+ ins[i]->set_vk_device (vk_dev);
+ }
+ XCAM_ASSERT (outs[0].ptr ());
+ outs[0]->set_vk_device (vk_dev);
+#else
+ XCAM_LOG_ERROR ("vulkan module is unsupported");
+ return -1;
+#endif
+ }
+
+ VideoBufferInfo in_info;
+ in_info.init (V4L2_PIX_FMT_NV12, input_width, input_height);
+ for (uint32_t i = 0; i < ins.size (); ++i) {
+ ins[i]->set_module (module);
+ ins[i]->set_buf_size (input_width, input_height);
+ CHECK (ins[i]->create_buf_pool (in_info, 6), "create buffer pool failed");
+ CHECK (ins[i]->open_reader ("rb"), "open input file(%s) failed", ins[i]->get_file_name ());
+ }
+
+ outs[0]->set_buf_size (output_width, output_height);
+
+ SmartPtr<Stitcher> stitcher = create_stitcher (outs[0], module);
+ XCAM_ASSERT (stitcher.ptr ());
+
+ CameraInfo cam_info[4];
+ std::string fisheye_config_path = FISHEYE_CONFIG_PATH;
+ const char *env = std::getenv (FISHEYE_CONFIG_ENV_VAR);
+ if (env)
+ fisheye_config_path.assign (env, strlen (env));
+ XCAM_LOG_INFO ("calibration config path:%s", fisheye_config_path.c_str ());
+
+ uint32_t camera_count = ins.size ();
+ for (uint32_t i = 0; i < camera_count; ++i) {
+ if (parse_camera_info (fisheye_config_path.c_str (), i, cam_info[i], camera_count) != 0) {
+ XCAM_LOG_ERROR ("parse fisheye dewarp info(idx:%d) failed.", i);
+ return -1;
+ }
+ }
+
+ PointFloat3 bowl_coord_offset;
+ centralize_bowl_coord_from_cameras (
+ cam_info[0].calibration.extrinsic, cam_info[1].calibration.extrinsic,
+ cam_info[2].calibration.extrinsic, cam_info[3].calibration.extrinsic,
+ bowl_coord_offset);
+
+ stitcher->set_camera_num (camera_count);
+ for (uint32_t i = 0; i < camera_count; ++i) {
+ stitcher->set_camera_info (i, cam_info[i]);
+ }
+
+ BowlDataConfig bowl;
+ bowl.wall_height = 1800.0f;
+ bowl.ground_length = 3000.0f;
+ bowl.angle_start = 0.0f;
+ bowl.angle_end = 360.0f;
+ stitcher->set_bowl_config (bowl);
+ stitcher->set_output_size (output_width, output_height);
+ stitcher->set_scale_mode (scale_mode);
+ stitcher->set_fm_mode (fm_mode);
+
+ SmartPtr<RenderOsgViewer> render = new RenderOsgViewer ();
+
+ SmartPtr<RenderOsgModel> sv_model = create_surround_view_model (stitcher, output_width, output_height);
+ render->add_model (sv_model);
+
+ SmartPtr<RenderOsgModel> car_model = create_car_model (car_name);
+ render->add_model (car_model);
+
+ render->validate_model_groups ();
+
+ render->start_render ();
+
+ while (loop--) {
+ CHECK_EXP (
+ run_stitcher (stitcher, sv_model, ins, outs) == 0,
+ "run stitcher failed");
+ }
+
+ render->stop_render ();
+
+ return 0;
+}
diff --git a/tests/test-soft-image.cpp b/tests/test-soft-image.cpp
index 578de8e..d9d9493 100644
--- a/tests/test-soft-image.cpp
+++ b/tests/test-soft-image.cpp
@@ -20,31 +20,10 @@
#include "test_common.h"
#include "test_inline.h"
-#include <buffer_pool.h>
-#include <image_handler.h>
-#include <image_file_handle.h>
+#include "test_stream.h"
#include <soft/soft_video_buf_allocator.h>
#include <interface/blender.h>
#include <interface/geo_mapper.h>
-#include <interface/stitcher.h>
-#include <calibration_parser.h>
-#include <string>
-
-#if (!defined(ANDROID) && (HAVE_OPENCV))
-#include <ocl/cv_base_class.h>
-#endif
-
-#define XCAM_TEST_SOFT_IMAGE_DEBUG 0
-
-#if (!defined(ANDROID) && (HAVE_OPENCV))
-#define XCAM_TEST_OPENCV 1
-#else
-#define XCAM_TEST_OPENCV 0
-#endif
-
-#define XCAM_TEST_MAX_STR_SIZE 1024
-
-#define FISHEYE_CONFIG_PATH "./"
#define MAP_WIDTH 3
#define MAP_HEIGHT 4
@@ -59,484 +38,58 @@ static PointFloat2 map_table[MAP_HEIGHT * MAP_WIDTH] = {
using namespace XCam;
enum SoftType {
- SoftTypeNone = 0,
+ SoftTypeNone = 0,
SoftTypeBlender,
- SoftTypeRemap,
- SoftTypeStitch,
+ SoftTypeRemap
};
-#define RUN_N(statement, loop, msg, ...) \
- for (int i = 0; i < loop; ++i) { \
- CHECK (statement, msg, ## __VA_ARGS__); \
- FPS_CALCULATION (soft-image, XCAM_OBJ_DUR_FRAME_NUM); \
- }
-
-#define ADD_ENELEMT(elements, file_name) \
- { \
- SmartPtr<SoftElement> element = new SoftElement (file_name); \
- elements.push_back (element); \
- }
-
-#if XCAM_TEST_OPENCV
-const static cv::Scalar color = cv::Scalar (0, 0, 255);
-const static int fontFace = cv::FONT_HERSHEY_COMPLEX;
-#endif
-
-class SoftElement {
+class SoftStream
+ : public Stream
+{
public:
- explicit SoftElement (const char *file_name = NULL, uint32_t width = 0, uint32_t height = 0);
- ~SoftElement ();
+ explicit SoftStream (const char *file_name = NULL, uint32_t width = 0, uint32_t height = 0);
+ virtual ~SoftStream () {}
- void set_buf_size (uint32_t width, uint32_t height);
- uint32_t get_width () const {
- return _width;
- }
- uint32_t get_height () const {
- return _height;
- }
-
- const char *get_file_name () const {
- return _file_name;
- }
-
- SmartPtr<VideoBuffer> &get_buf () {
- return _buf;
- }
-
- XCamReturn open_file (const char *option);
- XCamReturn close_file ();
- XCamReturn rewind_file ();
-
- XCamReturn read_buf ();
- XCamReturn write_buf ();
-
- XCamReturn create_buf_pool (const VideoBufferInfo &info, uint32_t count);
-
-#if XCAM_TEST_OPENCV
- XCamReturn cv_open_writer ();
- void cv_write_image (char *img_name, char *frame_str, char *idx_str = NULL);
-#endif
+ virtual XCamReturn create_buf_pool (const VideoBufferInfo &info, uint32_t count);
private:
- char *_file_name;
- uint32_t _width;
- uint32_t _height;
- SmartPtr<VideoBuffer> _buf;
-
- ImageFileHandle _file;
- SmartPtr<BufferPool> _pool;
-#if XCAM_TEST_OPENCV
- cv::VideoWriter _writer;
-#endif
+ XCAM_DEAD_COPY (SoftStream);
};
+typedef std::vector<SmartPtr<SoftStream>> SoftStreams;
-typedef std::vector<SmartPtr<SoftElement>> SoftElements;
-
-SoftElement::SoftElement (const char *file_name, uint32_t width, uint32_t height)
- : _file_name (NULL)
- , _width (width)
- , _height (height)
+SoftStream::SoftStream (const char *file_name, uint32_t width, uint32_t height)
+ : Stream (file_name, width, height)
{
- if (file_name)
- _file_name = strndup (file_name, XCAM_TEST_MAX_STR_SIZE);
-}
-
-SoftElement::~SoftElement ()
-{
- _file.close ();
-
- if (_file_name)
- xcam_free (_file_name);
-}
-
-void
-SoftElement::set_buf_size (uint32_t width, uint32_t height)
-{
- _width = width;
- _height = height;
-}
-
-XCamReturn
-SoftElement::open_file (const char *option)
-{
- if (_file.open (_file_name, option) != XCAM_RETURN_NO_ERROR) {
- XCAM_LOG_ERROR ("open %s failed.", _file_name);
- return XCAM_RETURN_ERROR_FILE;
- }
-
- return XCAM_RETURN_NO_ERROR;
}
XCamReturn
-SoftElement::close_file ()
+SoftStream::create_buf_pool (const VideoBufferInfo &info, uint32_t count)
{
- return _file.close ();
-}
-
-XCamReturn
-SoftElement::rewind_file ()
-{
- return _file.rewind ();
-}
+ SmartPtr<BufferPool> pool = new SoftVideoBufAllocator ();
+ XCAM_ASSERT (pool.ptr ());
-XCamReturn
-SoftElement::create_buf_pool (const VideoBufferInfo &info, uint32_t count)
-{
- _pool = new SoftVideoBufAllocator ();
- _pool->set_video_info (info);
- if (!_pool->reserve (count)) {
+ pool->set_video_info (info);
+ if (!pool->reserve (count)) {
XCAM_LOG_ERROR ("create buffer pool failed");
return XCAM_RETURN_ERROR_MEM;
}
+ set_buf_pool (pool);
return XCAM_RETURN_NO_ERROR;
}
-XCamReturn
-SoftElement::read_buf ()
-{
- _buf = _pool->get_buffer (_pool);
- XCAM_ASSERT (_buf.ptr ());
-
- return _file.read_buf (_buf);
-}
-
-XCamReturn
-SoftElement::write_buf () {
- return _file.write_buf (_buf);
-}
-
-#if XCAM_TEST_OPENCV
-XCamReturn
-SoftElement::cv_open_writer ()
-{
- XCAM_FAIL_RETURN (
- ERROR,
- _width && _height,
- XCAM_RETURN_ERROR_PARAM,
- "invalid size width:%d height:%d", _width, _height);
-
- cv::Size frame_size = cv::Size (_width, _height);
- if (!_writer.open (_file_name, CV_FOURCC('X', '2', '6', '4'), 30, frame_size)) {
- XCAM_LOG_ERROR ("open file %s failed", _file_name);
- return XCAM_RETURN_ERROR_FILE;
- }
-
- return XCAM_RETURN_NO_ERROR;
-}
-
-void
-SoftElement::cv_write_image (char *img_name, char *frame_str, char *idx_str)
-{
- cv::Mat mat;
-
-#if XCAM_TEST_SOFT_IMAGE_DEBUG
- convert_to_mat (_buf, mat);
-
- cv::putText (mat, frame_str, cv::Point(20, 50), fontFace, 2.0, color, 2, 8, false);
- if(idx_str)
- cv::putText (mat, idx_str, cv::Point(20, 110), fontFace, 2.0, color, 2, 8, false);
-
- cv::imwrite (img_name, mat);
-#else
- XCAM_UNUSED (img_name);
- XCAM_UNUSED (frame_str);
- XCAM_UNUSED (idx_str);
-#endif
-
- if (_writer.isOpened ()) {
- if (mat.empty())
- convert_to_mat (_buf, mat);
-
- _writer.write (mat);
- }
-}
-#endif
-
-static int
-parse_camera_info (const char *path, uint32_t idx, CameraInfo &info, uint32_t camera_count)
-{
- static const char *instrinsic_names[] = {
- "intrinsic_camera_front.txt", "intrinsic_camera_right.txt",
- "intrinsic_camera_rear.txt", "intrinsic_camera_left.txt"
- };
- static const char *exstrinsic_names[] = {
- "extrinsic_camera_front.txt", "extrinsic_camera_right.txt",
- "extrinsic_camera_rear.txt", "extrinsic_camera_left.txt"
- };
- static const float viewpoints_range[] = {64.0f, 160.0f, 64.0f, 160.0f};
-
- char intrinsic_path[XCAM_TEST_MAX_STR_SIZE] = {'\0'};
- char extrinsic_path[XCAM_TEST_MAX_STR_SIZE] = {'\0'};
- snprintf (intrinsic_path, XCAM_TEST_MAX_STR_SIZE, "%s/%s", path, instrinsic_names[idx]);
- snprintf (extrinsic_path, XCAM_TEST_MAX_STR_SIZE, "%s/%s", path, exstrinsic_names[idx]);
-
- CalibrationParser parser;
- CHECK (
- parser.parse_intrinsic_file (intrinsic_path, info.calibration.intrinsic),
- "parse intrinsic params (%s)failed.", intrinsic_path);
-
- CHECK (
- parser.parse_extrinsic_file (extrinsic_path, info.calibration.extrinsic),
- "parse extrinsic params (%s)failed.", extrinsic_path);
- info.calibration.extrinsic.trans_x += TEST_CAMERA_POSITION_OFFSET_X;
-
- info.angle_range = viewpoints_range[idx];
- info.round_angle_start = (idx * 360.0f / camera_count) - info.angle_range / 2.0f;
- return 0;
-}
-
-static void
-combine_name (const char *orig_name, const char *embedded_str, char *new_name)
-{
- const char *dir_delimiter = std::strrchr (orig_name, '/');
-
- if (dir_delimiter) {
- std::string path (orig_name, dir_delimiter - orig_name + 1);
- XCAM_ASSERT (path.c_str ());
- snprintf (new_name, XCAM_TEST_MAX_STR_SIZE, "%s%s_%s", path.c_str (), embedded_str, dir_delimiter + 1);
- } else {
- snprintf (new_name, XCAM_TEST_MAX_STR_SIZE, "%s_%s", embedded_str, orig_name);
- }
-}
-
-static void
-add_element (SoftElements &elements, const char *element_name, uint32_t width, uint32_t height)
-{
- char file_name[XCAM_TEST_MAX_STR_SIZE] = {'\0'};
- combine_name (elements[0]->get_file_name (), element_name, file_name);
-
- SmartPtr<SoftElement> element = new SoftElement (file_name, width, height);
- elements.push_back (element);
-}
-
-static XCamReturn
-elements_open_file (const SoftElements &elements, const char *option, const bool &nv12_output)
-{
- XCamReturn ret = XCAM_RETURN_NO_ERROR;
-
- for (uint32_t i = 0; i < elements.size (); ++i) {
- if (nv12_output)
- ret = elements[i]->open_file (option);
-#if XCAM_TEST_OPENCV
- else
- ret = elements[i]->cv_open_writer ();
-#endif
-
- if (ret != XCAM_RETURN_NO_ERROR) {
- XCAM_LOG_ERROR ("open file(%s) failed", elements[i]->get_file_name ());
- break;
- }
- }
-
- return ret;
-}
-
-static XCamReturn
-remap_topview_buf (
- BowlModel &model,
- const SmartPtr<VideoBuffer> &buf,
- SmartPtr<VideoBuffer> &topview_buf,
- uint32_t topview_width, uint32_t topview_height)
-{
- BowlModel::PointMap points;
-
- uint32_t lut_w = topview_width / 4, lut_h = topview_height / 4;
- float length_mm = 0.0f, width_mm = 0.0f;
-
- model.get_max_topview_area_mm (length_mm, width_mm);
- XCAM_LOG_INFO ("Max Topview Area (L%.2fmm, W%.2fmm)", length_mm, width_mm);
-
- model.get_topview_rect_map (points, lut_w, lut_h);
- SmartPtr<GeoMapper> mapper = GeoMapper::create_soft_geo_mapper ();
- XCAM_ASSERT (mapper.ptr ());
- mapper->set_output_size (topview_width, topview_height);
- mapper->set_lookup_table (points.data (), lut_w, lut_h);
-
- XCamReturn ret = mapper->remap (buf, topview_buf);
- if (ret != XCAM_RETURN_NO_ERROR) {
- XCAM_LOG_ERROR ("remap stitched image to topview failed.");
- return ret;
- }
-
-#if 0
- BowlModel::VertexMap bowl_vertices;
- BowlModel::PointMap bowl_points;
- uint32_t bowl_lut_w = 15, bowl_lut_h = 10;
- model.get_bowlview_vertex_map (bowl_vertices, bowl_points, bowl_lut_w, bowl_lut_h);
- for (uint32_t i = 0; i < bowl_lut_h; ++i) {
- for (uint32_t j = 0; j < bowl_lut_w; ++j)
- {
- PointFloat3 &vetex = bowl_vertices[i * bowl_lut_w + j];
- printf ("(%4.0f, %4.0f, %4.0f), ", vetex.x, vetex.y, vetex.z );
- }
- printf ("\n");
- }
-#endif
-
- return XCAM_RETURN_NO_ERROR;
-}
-
-static void
-write_image (const SoftElements &ins, const SoftElements &outs, const bool &nv12_output) {
- if (nv12_output) {
- for (uint32_t i = 0; i < outs.size (); ++i)
- outs[i]->write_buf ();
- }
-#if XCAM_TEST_OPENCV
- else {
- static uint32_t frame_num = 0;
- char img_name[XCAM_TEST_MAX_STR_SIZE] = {'\0'};
- char frame_str[XCAM_TEST_MAX_STR_SIZE] = {'\0'};
- std::snprintf (frame_str, XCAM_TEST_MAX_STR_SIZE, "frame:%d", frame_num);
-
- char idx_str[XCAM_TEST_MAX_STR_SIZE] = {'\0'};
- for (uint32_t i = 0; i < ins.size (); ++i) {
- std::snprintf (idx_str, XCAM_TEST_MAX_STR_SIZE, "idx:%d", i);
- std::snprintf (img_name, XCAM_TEST_MAX_STR_SIZE, "orig_fisheye_%d_%d.jpg", frame_num, i);
- ins[i]->cv_write_image (img_name, frame_str, idx_str);
- }
-
- for (uint32_t i = 0; i < outs.size (); ++i) {
- std::snprintf (img_name, XCAM_TEST_MAX_STR_SIZE, "%s_%d.jpg", outs[i]->get_file_name (), frame_num);
- outs[i]->cv_write_image (img_name, frame_str);
- }
- frame_num++;
- }
-#endif
-}
-
-static XCamReturn
-ensure_output_format (const char *file_name, const SoftType &type, bool &nv12_output)
-{
- char suffix[XCAM_TEST_MAX_STR_SIZE] = {'\0'};
- const char *ptr = std::strrchr (file_name, '.');
- std::snprintf (suffix, XCAM_TEST_MAX_STR_SIZE, "%s", ptr + 1);
- if (!strcasecmp (suffix, "mp4")) {
-#if XCAM_TEST_OPENCV
- if (type != SoftTypeStitch) {
- XCAM_LOG_ERROR ("only stitch type supports MP4 output format");
- return XCAM_RETURN_ERROR_PARAM;
- }
- nv12_output = false;
-#else
- XCAM_LOG_ERROR ("only supports NV12 output format");
- return XCAM_RETURN_ERROR_PARAM;
-#endif
- }
-
- return XCAM_RETURN_NO_ERROR;
-}
-
-static bool
-check_element (const SoftElements &elements, const uint32_t &idx)
-{
- if (idx >= elements.size ())
- return false;
-
- if (!elements[idx].ptr()) {
- XCAM_LOG_ERROR ("SoftElement(idx:%d) ptr is NULL", idx);
- return false;
- }
-
- XCAM_FAIL_RETURN (
- ERROR,
- elements[idx]->get_width () && elements[idx]->get_height (),
- false,
- "SoftElement(idx:%d): invalid parameters width:%d height:%d",
- idx, elements[idx]->get_width (), elements[idx]->get_height ());
-
- return true;
-}
-
-static XCamReturn
-check_elements (const SoftElements &elements)
-{
- for (uint32_t i = 0; i < elements.size (); ++i) {
- XCAM_FAIL_RETURN (
- ERROR,
- check_element (elements, i),
- XCAM_RETURN_ERROR_PARAM,
- "invalid SoftElement index:%d\n", i);
- }
-
- return XCAM_RETURN_NO_ERROR;
-}
-
-static XCamReturn
-run_topview (const SmartPtr<Stitcher> &stitcher, const SoftElements &outs)
-{
- BowlModel bowl_model (stitcher->get_bowl_config (), outs[0]->get_width (), outs[0]->get_height ());
- return remap_topview_buf (bowl_model, outs[0]->get_buf (), outs[1]->get_buf (),
- outs[1]->get_width (), outs[1]->get_height ());
-}
-
-static int
-run_stitcher (
- const SmartPtr<Stitcher> &stitcher,
- const SoftElements &ins, const SoftElements &outs,
- bool nv12_output, bool save_output, int loop)
-{
- XCamReturn ret = XCAM_RETURN_NO_ERROR;
- CHECK (check_elements (ins), "invalid input elements");
- CHECK (check_elements (outs), "invalid output elements");
-
- VideoBufferList in_buffers;
- while (loop--) {
- for (uint32_t i = 0; i < ins.size (); ++i) {
- CHECK (ins[i]->rewind_file (), "rewind buffer from file(%s) failed", ins[i]->get_file_name ());
- }
-
- do {
- in_buffers.clear ();
-
- for (uint32_t i = 0; i < ins.size (); ++i) {
- ret = ins[i]->read_buf();
- if (ret == XCAM_RETURN_BYPASS)
- break;
- CHECK (ret, "read buffer from file(%s) failed.", ins[i]->get_file_name ());
-
- in_buffers.push_back (ins[i]->get_buf ());
- }
- if (ret == XCAM_RETURN_BYPASS)
- break;
-
- CHECK (
- stitcher->stitch_buffers (in_buffers, outs[0]->get_buf ()),
- "stitch buffer failed.");
-
- if (save_output) {
- if (check_element (outs, 1)) {
- CHECK (run_topview (stitcher, outs), "run topview failed");
- }
-
- write_image (ins, outs, nv12_output);
- }
-
- FPS_CALCULATION (soft - stitcher, XCAM_OBJ_DUR_FRAME_NUM);
- } while (true);
- }
-
- return 0;
-}
-
static void usage(const char* arg0)
{
printf ("Usage:\n"
- "%s --type TYPE--input0 file0 --input1 file1 --output file\n"
- "\t--type processing type, selected from: blend, remap, stitch, ...\n"
- "\t-- [stitch]: read calibration files from exported path $FISHEYE_CONFIG_PATH\n"
+ "%s --type TYPE --input0 input.nv12 --input1 input1.nv12 --output output.nv12 ...\n"
+ "\t--type processing type, selected from: blend, remap\n"
"\t--input0 input image(NV12)\n"
"\t--input1 input image(NV12)\n"
- "\t--input2 input image(NV12)\n"
- "\t--input3 input image(NV12)\n"
- "\t--output output image(NV12)\n"
- "\t--in-w optional, input width, default: 1920\n"
- "\t--in-h optional, input height, default: 1080\n"
- "\t--out-w optional, output width, default: 1920\n"
- "\t--out-h optional, output height, default: 960\n"
- "\t--topview-w optional, output width, default: 1280\n"
- "\t--topview-h optional, output height, default: 720\n"
+ "\t--output output image(NV12/MP4)\n"
+ "\t--in-w optional, input width, default: 1280\n"
+ "\t--in-h optional, input height, default: 800\n"
+ "\t--out-w optional, output width, default: 1280\n"
+ "\t--out-h optional, output height, default: 800\n"
"\t--save optional, save file or not, select from [true/false], default: true\n"
"\t--loop optional, how many loops need to run, default: 1\n"
"\t--help usage\n",
@@ -545,36 +98,29 @@ static void usage(const char* arg0)
int main (int argc, char *argv[])
{
- uint32_t input_width = 1920;
- uint32_t input_height = 1080;
- uint32_t output_width = 1920; //output_height * 2;
- uint32_t output_height = 960; //960;
- uint32_t topview_width = 1280;
- uint32_t topview_height = 720;
- SoftType type = SoftTypeNone;
+ uint32_t input_width = 1280;
+ uint32_t input_height = 800;
+ uint32_t output_width = 1280;
+ uint32_t output_height = 800;
- SoftElements ins;
- SoftElements outs;
+ SoftStreams ins;
+ SoftStreams outs;
+ SoftType type = SoftTypeNone;
int loop = 1;
bool save_output = true;
- bool nv12_output = true;
const struct option long_opts[] = {
{"type", required_argument, NULL, 't'},
{"input0", required_argument, NULL, 'i'},
{"input1", required_argument, NULL, 'j'},
- {"input2", required_argument, NULL, 'k'},
- {"input3", required_argument, NULL, 'l'},
{"output", required_argument, NULL, 'o'},
{"in-w", required_argument, NULL, 'w'},
{"in-h", required_argument, NULL, 'h'},
{"out-w", required_argument, NULL, 'W'},
{"out-h", required_argument, NULL, 'H'},
- {"topview-w", required_argument, NULL, 'P'},
- {"topview-h", required_argument, NULL, 'V'},
{"save", required_argument, NULL, 's'},
- {"loop", required_argument, NULL, 'L'},
+ {"loop", required_argument, NULL, 'l'},
{"help", no_argument, NULL, 'e'},
{NULL, 0, NULL, 0},
};
@@ -588,34 +134,23 @@ int main (int argc, char *argv[])
type = SoftTypeBlender;
else if (!strcasecmp (optarg, "remap"))
type = SoftTypeRemap;
- else if (!strcasecmp (optarg, "stitch"))
- type = SoftTypeStitch;
else {
XCAM_LOG_ERROR ("unknown type:%s", optarg);
usage (argv[0]);
return -1;
}
break;
-
case 'i':
XCAM_ASSERT (optarg);
- ADD_ENELEMT(ins, optarg);
+ PUSH_STREAM (SoftStream, ins, optarg);
break;
case 'j':
XCAM_ASSERT (optarg);
- ADD_ENELEMT(ins, optarg);
- break;
- case 'k':
- XCAM_ASSERT (optarg);
- ADD_ENELEMT(ins, optarg);
- break;
- case 'l':
- XCAM_ASSERT (optarg);
- ADD_ENELEMT(ins, optarg);
+ PUSH_STREAM (SoftStream, ins, optarg);
break;
case 'o':
XCAM_ASSERT (optarg);
- ADD_ENELEMT(outs, optarg);
+ PUSH_STREAM (SoftStream, outs, optarg);
break;
case 'w':
input_width = atoi(optarg);
@@ -629,18 +164,15 @@ int main (int argc, char *argv[])
case 'H':
output_height = atoi(optarg);
break;
- case 'P':
- topview_width = atoi(optarg);
- break;
- case 'V':
- topview_height = atoi(optarg);
- break;
case 's':
save_output = (strcasecmp (optarg, "false") == 0 ? false : true);
break;
- case 'L':
+ case 'l':
loop = atoi(optarg);
break;
+ case 'e':
+ usage (argv[0]);
+ return 0;
default:
XCAM_LOG_ERROR ("getopt_long return unknown value:%c", opt);
usage (argv[0]);
@@ -654,12 +186,6 @@ int main (int argc, char *argv[])
return -1;
}
- if (SoftTypeNone == type) {
- XCAM_LOG_ERROR ("Type was not set");
- usage (argv[0]);
- return -1;
- }
-
if (ins.empty () || outs.empty () ||
!strlen (ins[0]->get_file_name ()) || !strlen (outs[0]->get_file_name ())) {
XCAM_LOG_ERROR ("input or output file name was not set");
@@ -675,47 +201,55 @@ int main (int argc, char *argv[])
printf ("input height:\t\t%d\n", input_height);
printf ("output width:\t\t%d\n", output_width);
printf ("output height:\t\t%d\n", output_height);
- printf ("topview width:\t\t%d\n", topview_width);
- printf ("topview height:\t\t%d\n", topview_height);
printf ("save output:\t\t%s\n", save_output ? "true" : "false");
printf ("loop count:\t\t%d\n", loop);
- VideoBufferInfo in_info, out_info;
+ VideoBufferInfo in_info;
in_info.init (V4L2_PIX_FMT_NV12, input_width, input_height);
- out_info.init (V4L2_PIX_FMT_NV12, output_width, output_height);
-
for (uint32_t i = 0; i < ins.size (); ++i) {
ins[i]->set_buf_size (input_width, input_height);
CHECK (ins[i]->create_buf_pool (in_info, 6), "create buffer pool failed");
- CHECK (ins[i]->open_file ("rb"), "open file(%s) failed", ins[i]->get_file_name ());
+ CHECK (ins[i]->open_reader ("rb"), "open input file(%s) failed", ins[i]->get_file_name ());
}
outs[0]->set_buf_size (output_width, output_height);
if (save_output) {
- CHECK (ensure_output_format (outs[0]->get_file_name (), type, nv12_output), "unsupported output format");
- if (nv12_output) {
- CHECK (outs[0]->open_file ("wb"), "open file(%s) failed", outs[0]->get_file_name ());
- }
+ CHECK (outs[0]->estimate_file_format (), "%s: estimate file format failed", outs[0]->get_file_name ());
+ CHECK (outs[0]->open_writer ("wb"), "open output file(%s) failed", outs[0]->get_file_name ());
}
switch (type) {
case SoftTypeBlender: {
- CHECK_EXP (ins.size () >= 2, "blender need 2 input files.");
+ CHECK_EXP (ins.size () == 2, "blender needs 2 input files.");
SmartPtr<Blender> blender = Blender::create_soft_blender ();
XCAM_ASSERT (blender.ptr ());
blender->set_output_size (output_width, output_height);
- Rect merge_window;
- merge_window.pos_x = 0;
- merge_window.pos_y = 0;
- merge_window.width = out_info.width;
- merge_window.height = out_info.height;
- blender->set_merge_window (merge_window);
+
+ Rect area;
+ area.pos_x = 0;
+ area.pos_y = 0;
+ area.width = output_width;
+ area.height = output_height;
+ blender->set_merge_window (area);
+ area.pos_x = 0;
+ area.pos_y = 0;
+ area.width = input_width;
+ area.height = input_height;
+ blender->set_input_merge_area (area, 0);
+ area.pos_x = 0;
+ area.pos_y = 0;
+ area.width = input_width;
+ area.height = input_height;
+ blender->set_input_merge_area (area, 1);
CHECK (ins[0]->read_buf(), "read buffer from file(%s) failed.", ins[0]->get_file_name ());
CHECK (ins[1]->read_buf(), "read buffer from file(%s) failed.", ins[1]->get_file_name ());
- RUN_N (blender->blend (ins[0]->get_buf (), ins[1]->get_buf (), outs[0]->get_buf ()), loop, "blend buffer failed.");
- if (save_output)
- outs[0]->write_buf ();
+ for (int i = 0; i < loop; ++i) {
+ CHECK (blender->blend (ins[0]->get_buf (), ins[1]->get_buf (), outs[0]->get_buf ()), "blend buffer failed");
+ if (save_output)
+ outs[0]->write_buf ();
+ FPS_CALCULATION (soft-blend, XCAM_OBJ_DUR_FRAME_NUM);
+ }
break;
}
case SoftTypeRemap: {
@@ -726,64 +260,14 @@ int main (int argc, char *argv[])
//mapper->set_factors ((output_width - 1.0f) / (MAP_WIDTH - 1.0f), (output_height - 1.0f) / (MAP_HEIGHT - 1.0f));
CHECK (ins[0]->read_buf(), "read buffer from file(%s) failed.", ins[0]->get_file_name ());
- RUN_N (mapper->remap (ins[0]->get_buf (), outs[0]->get_buf ()), loop, "remap buffer failed.");
- if (save_output)
- outs[0]->write_buf ();
- break;
- }
- case SoftTypeStitch: {
- CHECK_EXP (ins.size () >= 2 && ins.size () <= 4, "stitcher need at 2~4 input files.");
-
- uint32_t camera_count = ins.size ();
- SmartPtr<Stitcher> stitcher = Stitcher::create_soft_stitcher ();
- XCAM_ASSERT (stitcher.ptr ());
-
- CameraInfo cam_info[4];
- const char *fisheye_config_path = getenv ("FISHEYE_CONFIG_PATH");
- if (!fisheye_config_path)
- fisheye_config_path = FISHEYE_CONFIG_PATH;
-
- for (uint32_t i = 0; i < camera_count; ++i) {
- if (parse_camera_info (fisheye_config_path, i, cam_info[i], camera_count) != 0) {
- XCAM_LOG_ERROR ("parse fisheye dewarp info(idx:%d) failed.", i);
- return -1;
- }
- }
-
- PointFloat3 bowl_coord_offset;
- if (camera_count == 4) {
- centralize_bowl_coord_from_cameras (
- cam_info[0].calibration.extrinsic, cam_info[1].calibration.extrinsic,
- cam_info[2].calibration.extrinsic, cam_info[3].calibration.extrinsic,
- bowl_coord_offset);
+ for (int i = 0; i < loop; ++i) {
+ CHECK (mapper->remap (ins[0]->get_buf (), outs[0]->get_buf ()), "remap buffer failed");
+ if (save_output)
+ outs[0]->write_buf ();
+ FPS_CALCULATION (soft-remap, XCAM_OBJ_DUR_FRAME_NUM);
}
-
- stitcher->set_camera_num (camera_count);
- for (uint32_t i = 0; i < camera_count; ++i) {
- stitcher->set_camera_info (i, cam_info[i]);
- }
-
- BowlDataConfig bowl;
- bowl.wall_height = 3000.0f;
- bowl.ground_length = 2000.0f;
- //bowl.a = 5000.0f;
- //bowl.b = 3600.0f;
- //bowl.c = 3000.0f;
- bowl.angle_start = 0.0f;
- bowl.angle_end = 360.0f;
- stitcher->set_bowl_config (bowl);
- stitcher->set_output_size (output_width, output_height);
-
- if (save_output) {
- add_element (outs, "topview", topview_width, topview_height);
- elements_open_file (outs, "wb", nv12_output);
- }
- CHECK_EXP (
- run_stitcher (stitcher, ins, outs, nv12_output, save_output, loop) == 0,
- "run stitcher failed.");
break;
}
-
default: {
XCAM_LOG_ERROR ("unsupported type:%d", type);
usage (argv[0]);
diff --git a/tests/test-surround-view.cpp b/tests/test-surround-view.cpp
new file mode 100644
index 0000000..6d627c3
--- /dev/null
+++ b/tests/test-surround-view.cpp
@@ -0,0 +1,769 @@
+/*
+ * test-surround-view.cpp - test surround view
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#include "test_common.h"
+#include "test_stream.h"
+#include <interface/geo_mapper.h>
+#include <interface/stitcher.h>
+#include <calibration_parser.h>
+#include <soft/soft_video_buf_allocator.h>
+#if HAVE_GLES
+#include <gles/gl_video_buffer.h>
+#include <gles/egl/egl_base.h>
+#endif
+#if HAVE_VULKAN
+#include <vulkan/vk_device.h>
+#endif
+
+using namespace XCam;
+
+enum FrameMode {
+ FrameSingle = 0,
+ FrameMulti
+};
+
+enum SVModule {
+ SVModuleNone = 0,
+ SVModuleSoft,
+ SVModuleGLES,
+ SVModuleVulkan
+};
+
+enum SVOutIdx {
+ IdxStitch = 0,
+ IdxTopView,
+ IdxCount
+};
+
+static const char *instrinsic_names[] = {
+ "intrinsic_camera_front.txt",
+ "intrinsic_camera_right.txt",
+ "intrinsic_camera_rear.txt",
+ "intrinsic_camera_left.txt"
+};
+
+static const char *exstrinsic_names[] = {
+ "extrinsic_camera_front.txt",
+ "extrinsic_camera_right.txt",
+ "extrinsic_camera_rear.txt",
+ "extrinsic_camera_left.txt"
+};
+
+static const float viewpoints_range[] = {64.0f, 160.0f, 64.0f, 160.0f};
+
+class SVStream
+ : public Stream
+{
+public:
+ explicit SVStream (const char *file_name = NULL, uint32_t width = 0, uint32_t height = 0);
+ virtual ~SVStream () {}
+
+ void set_module (SVModule module) {
+ XCAM_ASSERT (module != SVModuleNone);
+ _module = module;
+ }
+
+ void set_mapper (const SmartPtr<GeoMapper> &mapper) {
+ XCAM_ASSERT (mapper.ptr ());
+ _mapper = mapper;
+ }
+ const SmartPtr<GeoMapper> &get_mapper () {
+ return _mapper;
+ }
+
+#if HAVE_VULKAN
+ void set_vk_device (SmartPtr<VKDevice> &device) {
+ XCAM_ASSERT (device.ptr ());
+ _vk_dev = device;
+ }
+ SmartPtr<VKDevice> &get_vk_device () {
+ return _vk_dev;
+ }
+#endif
+
+ virtual XCamReturn create_buf_pool (const VideoBufferInfo &info, uint32_t count);
+
+private:
+ XCAM_DEAD_COPY (SVStream);
+
+private:
+ SVModule _module;
+ SmartPtr<GeoMapper> _mapper;
+#if HAVE_VULKAN
+ SmartPtr<VKDevice> _vk_dev;
+#endif
+};
+typedef std::vector<SmartPtr<SVStream>> SVStreams;
+
+SVStream::SVStream (const char *file_name, uint32_t width, uint32_t height)
+ : Stream (file_name, width, height)
+ , _module (SVModuleNone)
+{
+}
+
+XCamReturn
+SVStream::create_buf_pool (const VideoBufferInfo &info, uint32_t count)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, _module != SVModuleNone, XCAM_RETURN_ERROR_PARAM,
+ "invalid module, please set module first");
+
+ SmartPtr<BufferPool> pool;
+ if (_module == SVModuleSoft) {
+ pool = new SoftVideoBufAllocator (info);
+ } else if (_module == SVModuleGLES) {
+#if HAVE_GLES
+ pool = new GLVideoBufferPool (info);
+#endif
+ } else if (_module == SVModuleVulkan) {
+#if HAVE_VULKAN
+ XCAM_ASSERT (_vk_dev.ptr ());
+ pool = create_vk_buffer_pool (_vk_dev);
+ XCAM_ASSERT (pool.ptr ());
+ pool->set_video_info (info);
+#endif
+ }
+ XCAM_ASSERT (pool.ptr ());
+
+ if (!pool->reserve (count)) {
+ XCAM_LOG_ERROR ("create buffer pool failed");
+ return XCAM_RETURN_ERROR_MEM;
+ }
+
+ set_buf_pool (pool);
+ return XCAM_RETURN_NO_ERROR;
+}
+
+static SmartPtr<Stitcher>
+create_stitcher (const SmartPtr<SVStream> &stitch, SVModule module)
+{
+ SmartPtr<Stitcher> stitcher;
+
+ if (module == SVModuleSoft) {
+ stitcher = Stitcher::create_soft_stitcher ();
+ } else if (module == SVModuleGLES) {
+#if HAVE_GLES
+ stitcher = Stitcher::create_gl_stitcher ();
+#endif
+ } else if (module == SVModuleVulkan) {
+#if HAVE_VULKAN
+ SmartPtr<VKDevice> dev = stitch->get_vk_device ();
+ XCAM_ASSERT (dev.ptr ());
+ stitcher = Stitcher::create_vk_stitcher (dev);
+#else
+ XCAM_UNUSED (stitch);
+#endif
+ }
+ XCAM_ASSERT (stitcher.ptr ());
+
+ return stitcher;
+}
+
+static int
+parse_camera_info (const char *path, uint32_t idx, CameraInfo &info, uint32_t camera_count)
+{
+ XCAM_ASSERT (path);
+
+ char intrinsic_path[XCAM_TEST_MAX_STR_SIZE] = {'\0'};
+ char extrinsic_path[XCAM_TEST_MAX_STR_SIZE] = {'\0'};
+ snprintf (intrinsic_path, XCAM_TEST_MAX_STR_SIZE, "%s/%s", path, instrinsic_names[idx]);
+ snprintf (extrinsic_path, XCAM_TEST_MAX_STR_SIZE, "%s/%s", path, exstrinsic_names[idx]);
+
+ CalibrationParser parser;
+ CHECK (
+ parser.parse_intrinsic_file (intrinsic_path, info.calibration.intrinsic),
+ "parse intrinsic params(%s) failed.", intrinsic_path);
+
+ CHECK (
+ parser.parse_extrinsic_file (extrinsic_path, info.calibration.extrinsic),
+ "parse extrinsic params(%s) failed.", extrinsic_path);
+ info.calibration.extrinsic.trans_x += TEST_CAMERA_POSITION_OFFSET_X;
+
+ info.angle_range = viewpoints_range[idx];
+ info.round_angle_start = (idx * 360.0f / camera_count) - info.angle_range / 2.0f;
+ return 0;
+}
+
+static void
+combine_name (const char *orig_name, const char *embedded_str, char *new_name)
+{
+ const char *dir_delimiter = strrchr (orig_name, '/');
+
+ if (dir_delimiter) {
+ std::string path (orig_name, dir_delimiter - orig_name + 1);
+ XCAM_ASSERT (path.c_str ());
+ snprintf (new_name, XCAM_TEST_MAX_STR_SIZE, "%s%s_%s", path.c_str (), embedded_str, dir_delimiter + 1);
+ } else {
+ snprintf (new_name, XCAM_TEST_MAX_STR_SIZE, "%s_%s", embedded_str, orig_name);
+ }
+}
+
+static void
+add_stream (SVStreams &streams, const char *stream_name, uint32_t width, uint32_t height)
+{
+ char file_name[XCAM_TEST_MAX_STR_SIZE] = {'\0'};
+ combine_name (streams[0]->get_file_name (), stream_name, file_name);
+
+ SmartPtr<SVStream> stream = new SVStream (file_name, width, height);
+ XCAM_ASSERT (stream.ptr ());
+ streams.push_back (stream);
+}
+
+static void
+write_in_image (const SVStreams &ins, uint32_t frame_num)
+{
+#if (XCAM_TEST_STREAM_DEBUG) && (XCAM_TEST_OPENCV)
+ char frame_str[XCAM_TEST_MAX_STR_SIZE] = {'\0'};
+ std::snprintf (frame_str, XCAM_TEST_MAX_STR_SIZE, "frame:%d", frame_num);
+
+ char img_name[XCAM_TEST_MAX_STR_SIZE] = {'\0'};
+ char idx_str[XCAM_TEST_MAX_STR_SIZE] = {'\0'};
+ for (uint32_t i = 0; i < ins.size (); ++i) {
+ std::snprintf (idx_str, XCAM_TEST_MAX_STR_SIZE, "idx:%d", i);
+ std::snprintf (img_name, XCAM_TEST_MAX_STR_SIZE, "orig_fisheye_%d_%d.jpg", frame_num, i);
+ ins[i]->debug_write_image (img_name, frame_str, idx_str);
+ }
+#else
+ XCAM_UNUSED (ins);
+ XCAM_UNUSED (frame_num);
+#endif
+}
+
+static void
+write_out_image (const SmartPtr<SVStream> &out, uint32_t frame_num)
+{
+#if !XCAM_TEST_STREAM_DEBUG
+ XCAM_UNUSED (frame_num);
+ out->write_buf ();
+#else
+ char frame_str[XCAM_TEST_MAX_STR_SIZE] = {'\0'};
+ std::snprintf (frame_str, XCAM_TEST_MAX_STR_SIZE, "frame:%d", frame_num);
+ out->write_buf (frame_str);
+
+#if XCAM_TEST_OPENCV
+ char img_name[XCAM_TEST_MAX_STR_SIZE] = {'\0'};
+ std::snprintf (img_name, XCAM_TEST_MAX_STR_SIZE, "%s_%d.jpg", out->get_file_name (), frame_num);
+ out->debug_write_image (img_name, frame_str);
+#endif
+#endif
+}
+
+static XCamReturn
+create_topview_mapper (
+ const SmartPtr<Stitcher> &stitcher, const SmartPtr<SVStream> &stitch,
+ const SmartPtr<SVStream> &topview, SVModule module)
+{
+ BowlModel bowl_model (stitcher->get_bowl_config (), stitch->get_width (), stitch->get_height ());
+ BowlModel::PointMap points;
+
+ float length_mm = 0.0f, width_mm = 0.0f;
+ bowl_model.get_max_topview_area_mm (length_mm, width_mm);
+ XCAM_LOG_INFO ("Max Topview Area (L%.2fmm, W%.2fmm)", length_mm, width_mm);
+
+ bowl_model.get_topview_rect_map (points, topview->get_width (), topview->get_height (), length_mm, width_mm);
+ SmartPtr<GeoMapper> mapper;
+ if (module == SVModuleSoft) {
+ mapper = GeoMapper::create_soft_geo_mapper ();
+ } else if (module == SVModuleGLES) {
+#if HAVE_GLES
+ mapper = GeoMapper::create_gl_geo_mapper ();
+#endif
+ } else if (module == SVModuleVulkan) {
+#if HAVE_VULKAN
+ SmartPtr<VKDevice> dev = stitch->get_vk_device ();
+ XCAM_ASSERT (dev.ptr ());
+ mapper = GeoMapper::create_vk_geo_mapper (dev, "topview-map");
+#endif
+ }
+ XCAM_ASSERT (mapper.ptr ());
+
+ mapper->set_output_size (topview->get_width (), topview->get_height ());
+ mapper->set_lookup_table (points.data (), topview->get_width (), topview->get_height ());
+ topview->set_mapper (mapper);
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+static XCamReturn
+remap_topview_buf (const SmartPtr<SVStream> &stitch, const SmartPtr<SVStream> &topview)
+{
+ const SmartPtr<GeoMapper> mapper = topview->get_mapper();
+ XCAM_ASSERT (mapper.ptr ());
+
+ XCamReturn ret = mapper->remap (stitch->get_buf (), topview->get_buf ());
+ if (ret != XCAM_RETURN_NO_ERROR) {
+ XCAM_LOG_ERROR ("remap stitched image to topview failed.");
+ return ret;
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+static void
+write_image (
+ const SVStreams &ins, const SVStreams &outs, bool save_output, bool save_topview)
+{
+ static uint32_t frame_num = 0;
+
+ write_in_image (ins, frame_num);
+
+ if (save_output)
+ write_out_image (outs[IdxStitch], frame_num);
+
+ if (save_topview) {
+ remap_topview_buf (outs[IdxStitch], outs[IdxTopView]);
+ write_out_image (outs[IdxTopView], frame_num);
+ }
+
+ frame_num++;
+}
+
+static int
+single_frame (
+ const SmartPtr<Stitcher> &stitcher,
+ const SVStreams &ins, const SVStreams &outs,
+ bool save_output, bool save_topview, int loop)
+{
+ for (uint32_t i = 0; i < ins.size (); ++i) {
+ CHECK (ins[i]->rewind (), "rewind buffer from file(%s) failed", ins[i]->get_file_name ());
+ }
+
+ VideoBufferList in_buffers;
+ for (uint32_t i = 0; i < ins.size (); ++i) {
+ XCamReturn ret = ins[i]->read_buf ();
+ CHECK_EXP (ret == XCAM_RETURN_NO_ERROR, "read buffer from file(%s) failed.", ins[i]->get_file_name ());
+
+ XCAM_ASSERT (ins[i]->get_buf ().ptr ());
+ in_buffers.push_back (ins[i]->get_buf ());
+ }
+
+ while (loop--) {
+ CHECK (stitcher->stitch_buffers (in_buffers, outs[IdxStitch]->get_buf ()), "stitch buffer failed.");
+
+ if (save_output || save_topview)
+ write_image (ins, outs, save_output, save_topview);
+
+ FPS_CALCULATION (surround-view, XCAM_OBJ_DUR_FRAME_NUM);
+ }
+
+ return 0;
+}
+
+static int
+multi_frame (
+ const SmartPtr<Stitcher> &stitcher,
+ const SVStreams &ins, const SVStreams &outs,
+ bool save_output, bool save_topview, int loop)
+{
+ XCamReturn ret = XCAM_RETURN_NO_ERROR;
+
+ VideoBufferList in_buffers;
+ while (loop--) {
+ for (uint32_t i = 0; i < ins.size (); ++i) {
+ CHECK (ins[i]->rewind (), "rewind buffer from file(%s) failed", ins[i]->get_file_name ());
+ }
+
+ do {
+ in_buffers.clear ();
+
+ for (uint32_t i = 0; i < ins.size (); ++i) {
+ ret = ins[i]->read_buf();
+ if (ret == XCAM_RETURN_BYPASS)
+ break;
+ CHECK (ret, "read buffer from file(%s) failed.", ins[i]->get_file_name ());
+
+ in_buffers.push_back (ins[i]->get_buf ());
+ }
+ if (ret == XCAM_RETURN_BYPASS)
+ break;
+
+ CHECK (
+ stitcher->stitch_buffers (in_buffers, outs[IdxStitch]->get_buf ()),
+ "stitch buffer failed.");
+
+ if (save_output || save_topview)
+ write_image (ins, outs, save_output, save_topview);
+
+ FPS_CALCULATION (surround-view, XCAM_OBJ_DUR_FRAME_NUM);
+ } while (true);
+ }
+
+ return 0;
+}
+
+static int
+run_stitcher (
+ const SmartPtr<Stitcher> &stitcher,
+ const SVStreams &ins, const SVStreams &outs,
+ FrameMode frame_mode, bool save_output, bool save_topview, int loop)
+{
+ CHECK (check_streams<SVStreams> (ins), "invalid input streams");
+ CHECK (check_streams<SVStreams> (outs), "invalid output streams");
+
+ int ret = -1;
+ if (frame_mode == FrameSingle)
+ ret = single_frame (stitcher, ins, outs, save_output, save_topview, loop);
+ else if (frame_mode == FrameMulti)
+ ret = multi_frame (stitcher, ins, outs, save_output, save_topview, loop);
+ else
+ XCAM_LOG_ERROR ("invalid frame mode: %d", frame_mode);
+
+ return ret;
+}
+
+static void usage(const char* arg0)
+{
+ printf ("Usage:\n"
+ "%s --module MODULE --input0 input.nv12 --input1 input1.nv12 --input2 input2.nv12 ...\n"
+ "\t--module processing module, selected from: soft, gles, vulkan\n"
+ "\t-- read calibration files from exported path $FISHEYE_CONFIG_PATH\n"
+ "\t--input0 input image(NV12)\n"
+ "\t--input1 input image(NV12)\n"
+ "\t--input2 input image(NV12)\n"
+ "\t--input3 input image(NV12)\n"
+ "\t--output output image(NV12/MP4)\n"
+ "\t--in-w optional, input width, default: 1280\n"
+ "\t--in-h optional, input height, default: 800\n"
+ "\t--out-w optional, output width, default: 1920\n"
+ "\t--out-h optional, output height, default: 640\n"
+ "\t--topview-w optional, output width, default: 1280\n"
+ "\t--topview-h optional, output height, default: 720\n"
+ "\t--scale-mode optional, scaling mode for geometric mapping,\n"
+ "\t select from [singleconst/dualconst/dualcurve], default: singleconst\n"
+ "\t--fm-mode optional, feature match mode,\n"
+#if HAVE_OPENCV
+ "\t select from [none/default/cluster/capi], default: none\n"
+#else
+ "\t select from [none], default: none\n"
+#endif
+ "\t--frame-mode optional, times of buffer reading, select from [single/multi], default: multi\n"
+ "\t--save optional, save file or not, select from [true/false], default: true\n"
+ "\t--save-topview optional, save top view video, select from [true/false], default: false\n"
+ "\t--loop optional, how many loops need to run, default: 1\n"
+ "\t--help usage\n",
+ arg0);
+}
+
+int main (int argc, char *argv[])
+{
+ uint32_t input_width = 1280;
+ uint32_t input_height = 800;
+ uint32_t output_width = 1920;
+ uint32_t output_height = 640;
+ uint32_t topview_width = 1280;
+ uint32_t topview_height = 720;
+
+ SVStreams ins;
+ SVStreams outs;
+
+ FrameMode frame_mode = FrameMulti;
+ SVModule module = SVModuleNone;
+ GeoMapScaleMode scale_mode = ScaleSingleConst;
+ FeatureMatchMode fm_mode = FMNone;
+
+ int loop = 1;
+ bool save_output = true;
+ bool save_topview = false;
+
+ const struct option long_opts[] = {
+ {"module", required_argument, NULL, 'm'},
+ {"input0", required_argument, NULL, 'i'},
+ {"input1", required_argument, NULL, 'j'},
+ {"input2", required_argument, NULL, 'k'},
+ {"input3", required_argument, NULL, 'l'},
+ {"output", required_argument, NULL, 'o'},
+ {"in-w", required_argument, NULL, 'w'},
+ {"in-h", required_argument, NULL, 'h'},
+ {"out-w", required_argument, NULL, 'W'},
+ {"out-h", required_argument, NULL, 'H'},
+ {"topview-w", required_argument, NULL, 'P'},
+ {"topview-h", required_argument, NULL, 'V'},
+ {"scale-mode", required_argument, NULL, 'S'},
+ {"fm-mode", required_argument, NULL, 'F'},
+ {"frame-mode", required_argument, NULL, 'f'},
+ {"save", required_argument, NULL, 's'},
+ {"save-topview", required_argument, NULL, 't'},
+ {"loop", required_argument, NULL, 'L'},
+ {"help", no_argument, NULL, 'e'},
+ {NULL, 0, NULL, 0},
+ };
+
+ int opt = -1;
+ while ((opt = getopt_long(argc, argv, "", long_opts, NULL)) != -1) {
+ switch (opt) {
+ case 'm':
+ XCAM_ASSERT (optarg);
+ if (!strcasecmp (optarg, "soft"))
+ module = SVModuleSoft;
+ else if (!strcasecmp (optarg, "gles")) {
+ module = SVModuleGLES;
+ } else if (!strcasecmp (optarg, "vulkan")) {
+ module = SVModuleVulkan;
+ } else {
+ XCAM_LOG_ERROR ("unknown module:%s", optarg);
+ usage (argv[0]);
+ return -1;
+ }
+ break;
+ case 'i':
+ XCAM_ASSERT (optarg);
+ PUSH_STREAM (SVStream, ins, optarg);
+ break;
+ case 'j':
+ XCAM_ASSERT (optarg);
+ PUSH_STREAM (SVStream, ins, optarg);
+ break;
+ case 'k':
+ XCAM_ASSERT (optarg);
+ PUSH_STREAM (SVStream, ins, optarg);
+ break;
+ case 'l':
+ XCAM_ASSERT (optarg);
+ PUSH_STREAM (SVStream, ins, optarg);
+ break;
+ case 'o':
+ XCAM_ASSERT (optarg);
+ PUSH_STREAM (SVStream, outs, optarg);
+ break;
+ case 'w':
+ input_width = atoi(optarg);
+ break;
+ case 'h':
+ input_height = atoi(optarg);
+ break;
+ case 'W':
+ output_width = atoi(optarg);
+ break;
+ case 'H':
+ output_height = atoi(optarg);
+ break;
+ case 'P':
+ topview_width = atoi(optarg);
+ break;
+ case 'V':
+ topview_height = atoi(optarg);
+ break;
+ case 'S':
+ XCAM_ASSERT (optarg);
+ if (!strcasecmp (optarg, "singleconst"))
+ scale_mode = ScaleSingleConst;
+ else if (!strcasecmp (optarg, "dualconst"))
+ scale_mode = ScaleDualConst;
+ else if (!strcasecmp (optarg, "dualcurve"))
+ scale_mode = ScaleDualCurve;
+ else {
+ XCAM_LOG_ERROR ("GeoMapScaleMode unknown mode: %s", optarg);
+ usage (argv[0]);
+ return -1;
+ }
+ break;
+ case 'F':
+ XCAM_ASSERT (optarg);
+ if (!strcasecmp (optarg, "none"))
+ fm_mode = FMNone;
+#if HAVE_OPENCV
+ else if (!strcasecmp (optarg, "default"))
+ fm_mode = FMDefault;
+ else if (!strcasecmp (optarg, "cluster"))
+ fm_mode = FMCluster;
+ else if (!strcasecmp (optarg, "capi"))
+ fm_mode = FMCapi;
+#endif
+ else {
+ XCAM_LOG_ERROR ("surround view unsupported feature match mode: %s", optarg);
+ usage (argv[0]);
+ return -1;
+ }
+ break;
+ case 'f':
+ XCAM_ASSERT (optarg);
+ if (!strcasecmp (optarg, "single"))
+ frame_mode = FrameSingle;
+ else if (!strcasecmp (optarg, "multi"))
+ frame_mode = FrameMulti;
+ else {
+ XCAM_LOG_ERROR ("FrameMode unknown mode: %s", optarg);
+ usage (argv[0]);
+ return -1;
+ }
+ break;
+ case 's':
+ save_output = (strcasecmp (optarg, "false") == 0 ? false : true);
+ break;
+ case 't':
+ save_topview = (strcasecmp (optarg, "false") == 0 ? false : true);
+ break;
+ case 'L':
+ loop = atoi(optarg);
+ break;
+ case 'e':
+ usage (argv[0]);
+ return 0;
+ default:
+ XCAM_LOG_ERROR ("getopt_long return unknown value: %c", opt);
+ usage (argv[0]);
+ return -1;
+ }
+ }
+
+ if (optind < argc || argc < 2) {
+ XCAM_LOG_ERROR ("unknown option %s", argv[optind]);
+ usage (argv[0]);
+ return -1;
+ }
+
+ CHECK_EXP (ins.size () == 4, "surrond view needs 4 input streams");
+ for (uint32_t i = 0; i < ins.size (); ++i) {
+ CHECK_EXP (ins[i].ptr (), "input stream is NULL, index:%d", i);
+ CHECK_EXP (strlen (ins[i]->get_file_name ()), "input file name was not set, index:%d", i);
+ }
+
+ CHECK_EXP (outs.size () == 1 && outs[IdxStitch].ptr (), "surrond view needs 1 output stream");
+ CHECK_EXP (strlen (outs[IdxStitch]->get_file_name ()), "output file name was not set");
+
+ for (uint32_t i = 0; i < ins.size (); ++i) {
+ printf ("input%d file:\t\t%s\n", i, ins[i]->get_file_name ());
+ }
+ printf ("output file:\t\t%s\n", outs[IdxStitch]->get_file_name ());
+ printf ("input width:\t\t%d\n", input_width);
+ printf ("input height:\t\t%d\n", input_height);
+ printf ("output width:\t\t%d\n", output_width);
+ printf ("output height:\t\t%d\n", output_height);
+ printf ("topview width:\t\t%d\n", topview_width);
+ printf ("topview height:\t\t%d\n", topview_height);
+ printf ("scaling mode:\t\t%s\n", (scale_mode == ScaleSingleConst) ? "singleconst" :
+ ((scale_mode == ScaleDualConst) ? "dualconst" : "dualcurve"));
+ printf ("feature match:\t\t%s\n", (fm_mode == FMNone) ? "none" :
+ ((fm_mode == FMDefault ) ? "default" : ((fm_mode == FMCluster) ? "cluster" : "capi")));
+ printf ("frame mode:\t\t%s\n", (frame_mode == FrameSingle) ? "singleframe" : "multiframe");
+ printf ("save output:\t\t%s\n", save_output ? "true" : "false");
+ printf ("save topview:\t\t%s\n", save_topview ? "true" : "false");
+ printf ("loop count:\t\t%d\n", loop);
+
+#if HAVE_GLES
+ SmartPtr<EGLBase> egl;
+ if (module == SVModuleGLES) {
+ if (scale_mode == ScaleDualCurve) {
+ XCAM_LOG_ERROR ("GLES module does not support dualcurve scale mode currently");
+ return -1;
+ }
+
+ egl = new EGLBase ();
+ XCAM_ASSERT (egl.ptr ());
+ XCAM_FAIL_RETURN (ERROR, egl->init (), -1, "init EGL failed");
+ }
+#else
+ if (module == SVModuleGLES) {
+ XCAM_LOG_ERROR ("GLES module is unsupported");
+ return -1;
+ }
+#endif
+
+ if (module == SVModuleVulkan) {
+#if HAVE_VULKAN
+ if (scale_mode != ScaleSingleConst) {
+ XCAM_LOG_ERROR ("vulkan module only support singleconst scale mode currently");
+ return -1;
+ }
+
+ SmartPtr<VKDevice> vk_dev = VKDevice::default_device ();
+ for (uint32_t i = 0; i < ins.size (); ++i) {
+ ins[i]->set_vk_device (vk_dev);
+ }
+ XCAM_ASSERT (outs[IdxStitch].ptr ());
+ outs[IdxStitch]->set_vk_device (vk_dev);
+#else
+ XCAM_LOG_ERROR ("vulkan module is unsupported");
+ return -1;
+#endif
+ }
+
+ VideoBufferInfo in_info;
+ in_info.init (V4L2_PIX_FMT_NV12, input_width, input_height);
+ for (uint32_t i = 0; i < ins.size (); ++i) {
+ ins[i]->set_module (module);
+ ins[i]->set_buf_size (input_width, input_height);
+ CHECK (ins[i]->create_buf_pool (in_info, 6), "create buffer pool failed");
+ CHECK (ins[i]->open_reader ("rb"), "open input file(%s) failed", ins[i]->get_file_name ());
+ }
+
+ outs[IdxStitch]->set_buf_size (output_width, output_height);
+ if (save_output) {
+ CHECK (outs[IdxStitch]->estimate_file_format (),
+ "%s: estimate file format failed", outs[IdxStitch]->get_file_name ());
+ CHECK (outs[IdxStitch]->open_writer ("wb"), "open output file(%s) failed", outs[IdxStitch]->get_file_name ());
+ }
+
+ SmartPtr<Stitcher> stitcher = create_stitcher (outs[IdxStitch], module);
+ XCAM_ASSERT (stitcher.ptr ());
+
+ CameraInfo cam_info[4];
+ std::string fisheye_config_path = FISHEYE_CONFIG_PATH;
+ const char *env = std::getenv (FISHEYE_CONFIG_ENV_VAR);
+ if (env)
+ fisheye_config_path.assign (env, strlen (env));
+ XCAM_LOG_INFO ("calibration config path:%s", fisheye_config_path.c_str ());
+
+ uint32_t camera_count = ins.size ();
+ for (uint32_t i = 0; i < camera_count; ++i) {
+ if (parse_camera_info (fisheye_config_path.c_str (), i, cam_info[i], camera_count) != 0) {
+ XCAM_LOG_ERROR ("parse fisheye dewarp info(idx:%d) failed.", i);
+ return -1;
+ }
+ }
+
+ PointFloat3 bowl_coord_offset;
+ centralize_bowl_coord_from_cameras (
+ cam_info[0].calibration.extrinsic, cam_info[1].calibration.extrinsic,
+ cam_info[2].calibration.extrinsic, cam_info[3].calibration.extrinsic,
+ bowl_coord_offset);
+
+ stitcher->set_camera_num (camera_count);
+ for (uint32_t i = 0; i < camera_count; ++i) {
+ stitcher->set_camera_info (i, cam_info[i]);
+ }
+
+ BowlDataConfig bowl;
+ bowl.wall_height = 1800.0f;
+ bowl.ground_length = 3000.0f;
+ bowl.angle_start = 0.0f;
+ bowl.angle_end = 360.0f;
+ stitcher->set_bowl_config (bowl);
+ stitcher->set_output_size (output_width, output_height);
+ stitcher->set_scale_mode (scale_mode);
+ stitcher->set_fm_mode (fm_mode);
+
+ if (save_topview) {
+ add_stream (outs, "topview", topview_width, topview_height);
+ XCAM_ASSERT (outs.size () >= IdxCount);
+
+ CHECK (outs[IdxTopView]->estimate_file_format (),
+ "%s: estimate file format failed", outs[IdxTopView]->get_file_name ());
+ CHECK (outs[IdxTopView]->open_writer ("wb"), "open output file(%s) failed", outs[IdxTopView]->get_file_name ());
+
+ create_topview_mapper (stitcher, outs[IdxStitch], outs[IdxTopView], module);
+ }
+
+ CHECK_EXP (
+ run_stitcher (stitcher, ins, outs, frame_mode, save_output, save_topview, loop) == 0,
+ "run stitcher failed");
+
+ return 0;
+}
diff --git a/tests/test-video-stabilization.cpp b/tests/test-video-stabilization.cpp
index 5280467..7885462 100644
--- a/tests/test-video-stabilization.cpp
+++ b/tests/test-video-stabilization.cpp
@@ -33,7 +33,7 @@
#if HAVE_OPENCV
#include <opencv2/opencv.hpp>
#include <opencv2/core/ocl.hpp>
-#include <ocl/cv_base_class.h>
+#include "ocv/cv_utils.h"
#endif
using namespace XCam;
@@ -62,10 +62,7 @@ int main (int argc, char *argv[])
XCamReturn ret = XCAM_RETURN_NO_ERROR;
SmartPtr<CLVideoStabilizer> video_stab;
-
SmartPtr<CLContext> context;
- SmartPtr<BufferPool> buf_pool;
-
VideoBufferInfo input_buf_info;
VideoBufferInfo output_buf_info;
SmartPtr<VideoBuffer> input_buf;
@@ -84,7 +81,6 @@ int main (int argc, char *argv[])
const char *gyro_data = "gyro_data.csv";
bool need_save_output = true;
- double framerate = 30.0;
int loop = 1;
const struct option long_opts[] = {
@@ -127,7 +123,7 @@ int main (int argc, char *argv[])
break;
case 'H':
usage (argv[0]);
- return -1;
+ return 0;
default:
printf ("getopt_long return unknown value:%c\n", opt);
usage (argv[0]);
@@ -201,7 +197,7 @@ int main (int argc, char *argv[])
input_buf_info.init (input_format, input_width, input_height);
output_buf_info.init (input_format, output_width, output_height);
- buf_pool = new CLVideoBufferPool ();
+ SmartPtr<BufferPool> buf_pool = new CLVideoBufferPool ();
XCAM_ASSERT (buf_pool.ptr ());
buf_pool->set_video_info (input_buf_info);
if (!buf_pool->reserve (36)) {
@@ -216,7 +212,7 @@ int main (int argc, char *argv[])
cv::VideoWriter writer;
if (need_save_output) {
cv::Size dst_size = cv::Size (output_width, output_height);
- if (!writer.open (file_out_name, CV_FOURCC('X', '2', '6', '4'), framerate, dst_size)) {
+ if (!writer.open (file_out_name, cv::VideoWriter::fourcc ('X', '2', '6', '4'), 30, dst_size)) {
XCAM_LOG_ERROR ("open file %s failed", file_out_name);
return -1;
}
diff --git a/tests/test-vk-handler.cpp b/tests/test-vk-handler.cpp
new file mode 100644
index 0000000..30941fc
--- /dev/null
+++ b/tests/test-vk-handler.cpp
@@ -0,0 +1,340 @@
+/*
+ * test_vk_handler.cpp - test vulkan handler
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Wind Yuan <feng.yuan@intel.com>
+ */
+
+#include "test_common.h"
+#include "test_stream.h"
+
+#include <vulkan/vk_device.h>
+#include <vulkan/vk_copy_handler.h>
+#include <vulkan/vk_geomap_handler.h>
+#include <interface/blender.h>
+
+using namespace XCam;
+
+enum VKType {
+ VKTypeNone = 0,
+ VKTypeCopy,
+ VKTypeRemap,
+ VKTypeBlender
+};
+
+class VKStream
+ : public Stream
+{
+public:
+ explicit VKStream (const char *file_name = NULL, uint32_t width = 0, uint32_t height = 0);
+ virtual ~VKStream () {}
+
+ void set_vk_device (SmartPtr<VKDevice> &device) {
+ XCAM_ASSERT (device.ptr ());
+ _device = device;
+ }
+
+ virtual XCamReturn create_buf_pool (const VideoBufferInfo &info, uint32_t count);
+
+private:
+ SmartPtr<VKDevice> _device;
+};
+
+typedef std::vector<SmartPtr<VKStream>> VKStreams;
+
+VKStream::VKStream (const char *file_name, uint32_t width, uint32_t height)
+ : Stream (file_name, width, height)
+{
+}
+
+XCamReturn
+VKStream::create_buf_pool (const VideoBufferInfo &info, uint32_t count)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, _device.ptr(), XCAM_RETURN_ERROR_PARAM,
+ "vulkan device id NULL, please set device first");
+
+ SmartPtr<BufferPool> pool = create_vk_buffer_pool (_device);
+ XCAM_ASSERT (pool.ptr ());
+
+ if (!pool->set_video_info (info)) {
+ XCAM_LOG_ERROR ("set video info failed");
+ return XCAM_RETURN_ERROR_UNKNOWN;
+ }
+
+ if (!pool->reserve (count)) {
+ XCAM_LOG_ERROR ("create buffer pool failed");
+ return XCAM_RETURN_ERROR_MEM;
+ }
+
+ set_buf_pool (pool);
+ return XCAM_RETURN_NO_ERROR;
+}
+
+static void
+calc_hor_flip_table (uint32_t width, uint32_t height, PointFloat2 *&map_table)
+{
+ XCAM_ASSERT (map_table);
+
+ float lut_size[2] = {8, 8};
+ for (uint32_t i = 0; i < height; ++i) {
+ PointFloat2 *line = &map_table[i * width];
+ for (uint32_t j = 0; j < width; j++) {
+ line[j].x = (width - j) * lut_size[0];
+ line[j].y = i * lut_size[1];
+ }
+ }
+}
+
+static void
+print_help (const char *arg0)
+{
+ printf ("Usage:\n"
+ "%s --type TYPE --input0 input.nv12 --input1 input1.nv12 --output output.nv12 ...\n"
+ "\t--type processing type, selected from: copy, remap, blend\n"
+ "\t--input0 input image(NV12)\n"
+ "\t--input1 input image(NV12)\n"
+ "\t--output output image(NV12/MP4)\n"
+ "\t--in-w optional, input width, default: 1280\n"
+ "\t--in-h optional, input height, default: 800\n"
+ "\t--out-w optional, output width, default: 1280\n"
+ "\t--out-h optional, output height, default: 800\n"
+ "\t--save optional, save file or not, select from [true/false], default: true\n"
+ "\t--loop optional, how many loops need to run, default: 1\n"
+ "\t--help usage\n",
+ arg0);
+
+ printf ("Note:\n"
+ "Spirv path Setup Env: $" XCAM_VK_SHADER_PATH "\n"
+ "Generate spirv kernel:\n"
+ "glslangValidator -V -x -o sample.comp.spv sample.comp.sl\n"
+ );
+}
+
+int main (int argc, char **argv)
+{
+ uint32_t input_width = 1280;
+ uint32_t input_height = 800;
+ uint32_t output_width = 1280;
+ uint32_t output_height = 800;
+
+ VKStreams ins;
+ VKStreams outs;
+ VKType type = VKTypeNone;
+
+ int loop = 1;
+ bool save_output = true;
+
+ const struct option long_opts[] = {
+ {"type", required_argument, NULL, 't'},
+ {"input0", required_argument, NULL, 'i'},
+ {"input1", required_argument, NULL, 'j'},
+ {"output", required_argument, NULL, 'o'},
+ {"in-w", required_argument, NULL, 'w'},
+ {"in-h", required_argument, NULL, 'h'},
+ {"out-w", required_argument, NULL, 'W'},
+ {"out-h", required_argument, NULL, 'H'},
+ {"save", required_argument, NULL, 's'},
+ {"loop", required_argument, NULL, 'l'},
+ {"help", no_argument, NULL, 'e'},
+ {NULL, 0, NULL, 0},
+ };
+
+ int opt = -1;
+ while ((opt = getopt_long (argc, argv, "", long_opts, NULL)) != -1) {
+ switch (opt) {
+ case 't':
+ XCAM_ASSERT (optarg);
+ if (!strcasecmp (optarg, "copy"))
+ type = VKTypeCopy;
+ else if (!strcasecmp (optarg, "remap"))
+ type = VKTypeRemap;
+ else if (!strcasecmp (optarg, "blend"))
+ type = VKTypeBlender;
+ else {
+ XCAM_LOG_ERROR ("unknown type:%s", optarg);
+ print_help (argv[0]);
+ return -1;
+ }
+ break;
+ case 'i':
+ XCAM_ASSERT (optarg);
+ PUSH_STREAM (VKStream, ins, optarg);
+ break;
+ case 'j':
+ XCAM_ASSERT (optarg);
+ PUSH_STREAM (VKStream, ins, optarg);
+ break;
+ case 'o':
+ XCAM_ASSERT (optarg);
+ PUSH_STREAM (VKStream, outs, optarg);
+ break;
+ case 'w':
+ input_width = atoi(optarg);
+ break;
+ case 'h':
+ input_height = atoi(optarg);
+ break;
+ case 'W':
+ output_width = atoi(optarg);
+ break;
+ case 'H':
+ output_height = atoi(optarg);
+ break;
+ case 's':
+ save_output = (strcasecmp (optarg, "false") == 0 ? false : true);
+ break;
+ case 'l':
+ loop = atoi(optarg);
+ break;
+ case 'e':
+ print_help (argv[0]);
+ return 0;
+ default:
+ XCAM_LOG_ERROR ("getopt_long return unknown value:%c", opt);
+ print_help (argv[0]);
+ return -1;
+ }
+ }
+
+ if (optind < argc || argc < 2) {
+ XCAM_LOG_ERROR ("unknown option %s", argv[optind]);
+ print_help (argv[0]);
+ return -1;
+ }
+
+ if (ins.empty () || outs.empty ()) {
+ XCAM_LOG_ERROR ("input or output stream is empty");
+ print_help (argv[0]);
+ return -1;
+ }
+
+ for (uint32_t i = 0; i < ins.size (); ++i) {
+ printf ("input%d file:\t\t%s\n", i, ins[i]->get_file_name ());
+ }
+ printf ("output file:\t\t%s\n", outs[0]->get_file_name ());
+ printf ("input width:\t\t%d\n", input_width);
+ printf ("input height:\t\t%d\n", input_height);
+ printf ("output width:\t\t%d\n", output_width);
+ printf ("output height:\t\t%d\n", output_height);
+ printf ("save output:\t\t%s\n", save_output ? "true" : "false");
+ printf ("loop count:\t\t%d\n", loop);
+
+ SmartPtr<VKDevice> vk_device = VKDevice::default_device ();
+ XCAM_FAIL_RETURN (
+ ERROR, vk_device.ptr(), -1,
+ "Get default VKDevice failed, please check vulkan environment");
+
+ VideoBufferInfo in_info;
+ in_info.init (V4L2_PIX_FMT_NV12, input_width, input_height);
+ for (uint32_t i = 0; i < ins.size (); ++i) {
+ ins[i]->set_buf_size (input_width, input_height);
+ ins[i]->set_vk_device (vk_device);
+ CHECK (ins[i]->create_buf_pool (in_info, 4), "create buffer pool failed");
+ CHECK (ins[i]->open_reader ("rb"), "open input file(%s) failed", ins[i]->get_file_name ());
+ }
+
+ VideoBufferInfo out_info;
+ out_info.init (V4L2_PIX_FMT_NV12, output_width, output_height);
+ outs[0]->set_buf_size (output_width, output_height);
+ if (save_output) {
+ CHECK (outs[0]->estimate_file_format (), "%s: estimate file format failed", outs[0]->get_file_name ());
+ CHECK (outs[0]->open_writer ("wb"), "open output file(%s) failed", outs[0]->get_file_name ());
+ }
+
+ switch (type) {
+ case VKTypeCopy: {
+ SmartPtr<VKCopyHandler> copyer = new VKCopyHandler (vk_device, "vk-copy");
+ XCAM_ASSERT (copyer.ptr ());
+
+ Rect in_area = Rect (0, 0, input_width, input_height);
+ Rect out_area = Rect (0, 0, output_width, output_height);
+ XCAM_ASSERT (in_area.width == out_area.width && in_area.height == out_area.height);
+ copyer->set_copy_area (0, in_area, out_area);
+ copyer->set_out_video_info (out_info);
+
+ CHECK (ins[0]->read_buf(), "read buffer from file(%s) failed", ins[0]->get_file_name ());
+ for (int i = 0; i < loop; ++i) {
+ CHECK (copyer->copy (ins[0]->get_buf (), outs[0]->get_buf ()), "copy buffer failed");
+ if (save_output)
+ outs[0]->write_buf ();
+ FPS_CALCULATION (vk-copy, XCAM_OBJ_DUR_FRAME_NUM);
+ }
+ break;
+ }
+ case VKTypeRemap: {
+ SmartPtr<VKGeoMapHandler> mapper = new VKGeoMapHandler (vk_device, "vk-remap");
+ XCAM_ASSERT (mapper.ptr ());
+ mapper->set_output_size (output_width, output_height);
+
+ uint32_t lut_width = XCAM_ALIGN_UP (output_width, 8) / 8;
+ uint32_t lut_height = XCAM_ALIGN_UP (output_height, 8) / 8;
+ PointFloat2 *map_table = new PointFloat2[lut_width * lut_height];
+ calc_hor_flip_table (lut_width, lut_height, map_table);
+ mapper->set_lookup_table (map_table, lut_width, lut_height);
+ delete [] map_table;
+
+ CHECK (ins[0]->read_buf(), "read buffer from file(%s) failed", ins[0]->get_file_name ());
+ for (int i = 0; i < loop; ++i) {
+ CHECK (mapper->remap (ins[0]->get_buf (), outs[0]->get_buf ()), "remap buffer failed");
+ if (save_output)
+ outs[0]->write_buf ();
+ FPS_CALCULATION (vk-remap, XCAM_OBJ_DUR_FRAME_NUM);
+ }
+ break;
+ }
+ case VKTypeBlender: {
+ CHECK_EXP (ins.size () == 2, "Error: blender needs 2 input files.");
+ SmartPtr<Blender> blender = Blender::create_vk_blender (vk_device);
+ XCAM_ASSERT (blender.ptr ());
+ blender->set_output_size (output_width, output_height);
+
+ Rect area;
+ area.pos_x = 0;
+ area.pos_y = 0;
+ area.width = output_width;
+ area.height = output_height;
+ blender->set_merge_window (area);
+ area.pos_x = 0;
+ area.pos_y = 0;
+ area.width = input_width;
+ area.height = input_height;
+ blender->set_input_merge_area (area, 0);
+ area.pos_x = 0;
+ area.pos_y = 0;
+ area.width = input_width;
+ area.height = input_height;
+ blender->set_input_merge_area (area, 1);
+
+ CHECK (ins[0]->read_buf(), "read buffer from file(%s) failed.", ins[0]->get_file_name ());
+ CHECK (ins[1]->read_buf(), "read buffer from file(%s) failed.", ins[1]->get_file_name ());
+ for (int i = 0; i < loop; ++i) {
+ CHECK (blender->blend (ins[0]->get_buf (), ins[1]->get_buf (), outs[0]->get_buf ()), "blend buffer failed");
+ if (save_output)
+ outs[0]->write_buf ();
+ FPS_CALCULATION (vk-blend, XCAM_OBJ_DUR_FRAME_NUM);
+ }
+ break;
+ }
+ default: {
+ XCAM_LOG_ERROR ("unsupported type:%d", type);
+ print_help (argv[0]);
+ return -1;
+ }
+ }
+
+ return 0;
+}
diff --git a/tests/test_common.h b/tests/test_common.h
index 9ca75e3..3052a60 100644
--- a/tests/test_common.h
+++ b/tests/test_common.h
@@ -24,6 +24,7 @@
#include <unistd.h>
#include <getopt.h>
+#include <string>
#define TEST_CAMERA_POSITION_OFFSET_X 2000
@@ -60,6 +61,8 @@
#define DEFAULT_HYBRID_3A_LIB "/usr/lib/xcam/plugins/3a/libxcam_3a_hybrid.so"
#define DEFAULT_SMART_ANALYSIS_LIB_DIR "/usr/lib/xcam/plugins/smart"
+#define FISHEYE_CONFIG_PATH "./calib_params/"
+#define FISHEYE_CONFIG_ENV_VAR "FISHEYE_CONFIG_PATH"
#define FPS_CALCULATION(objname, count) XCAM_STATIC_FPS_CALCULATION(objname, count)
diff --git a/tests/test_stream.h b/tests/test_stream.h
new file mode 100644
index 0000000..6bbaf8a
--- /dev/null
+++ b/tests/test_stream.h
@@ -0,0 +1,333 @@
+/*
+ * test_stream.h - test stream class
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Yinhang Liu <yinhangx.liu@intel.com>
+ */
+
+#ifndef XCAM_TEST_STREAM_H
+#define XCAM_TEST_STREAM_H
+
+#include <buffer_pool.h>
+#include <image_file_handle.h>
+#if (!defined(ANDROID) && (HAVE_OPENCV))
+#include "ocv/cv_utils.h"
+#endif
+
+#define XCAM_TEST_STREAM_DEBUG 0
+
+#define XCAM_TEST_MAX_STR_SIZE 256
+
+#if (!defined(ANDROID) && (HAVE_OPENCV))
+#define XCAM_TEST_OPENCV 1
+#else
+#define XCAM_TEST_OPENCV 0
+#endif
+
+#if XCAM_TEST_OPENCV
+const static cv::Scalar color = cv::Scalar (0, 0, 255);
+const static int fontFace = cv::FONT_HERSHEY_COMPLEX;
+#endif
+
+namespace XCam {
+
+enum TestFileFormat {
+ FileNone,
+ FileNV12,
+ FileMP4
+};
+
+#define PUSH_STREAM(Type, streams, file_name) \
+ { \
+ SmartPtr<Type> stream = new Type (file_name); \
+ XCAM_ASSERT (stream.ptr ()); \
+ streams.push_back (stream); \
+ }
+
+template <typename TType>
+XCamReturn check_streams (const TType &streams)
+{
+ for (uint32_t i = 0; i < streams.size (); ++i) {
+ if (!streams[i].ptr()) {
+ XCAM_LOG_ERROR ("streams[%d] ptr is NULL", i);
+ return XCAM_RETURN_ERROR_PARAM;
+ }
+
+ XCAM_FAIL_RETURN (
+ ERROR, streams[i]->get_width () && streams[i]->get_height (), XCAM_RETURN_ERROR_PARAM,
+ "streams[%d]: invalid parameters width:%d height:%d, please set buffer size first",
+ i, streams[i]->get_width (), streams[i]->get_height ());
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+class Stream {
+public:
+ explicit Stream (const char *file_name = NULL, uint32_t width = 0, uint32_t height = 0);
+ virtual ~Stream ();
+
+ void set_buf_size (uint32_t width, uint32_t height);
+ uint32_t get_width () const {
+ return _width;
+ }
+ uint32_t get_height () const {
+ return _height;
+ }
+ SmartPtr<VideoBuffer> &get_buf () {
+ return _buf;
+ }
+ const char *get_file_name () const {
+ return _file_name;
+ }
+ XCamReturn estimate_file_format ();
+
+ XCamReturn open_reader (const char *option);
+ XCamReturn open_writer (const char *option);
+ XCamReturn close ();
+ XCamReturn rewind ();
+
+ XCamReturn read_buf ();
+ XCamReturn write_buf (char *frame_str = NULL);
+ virtual XCamReturn create_buf_pool (const VideoBufferInfo &info, uint32_t count) = 0;
+
+#if XCAM_TEST_OPENCV
+ void debug_write_image (char *img_name, char *frame_str = NULL, char *idx_str = NULL);
+#endif
+
+protected:
+ void set_buf_pool (const SmartPtr<BufferPool> &pool) {
+ _pool = pool;
+ }
+
+private:
+#if XCAM_TEST_OPENCV
+ XCamReturn cv_open_writer ();
+ void cv_write_buf (char *frame_str = NULL);
+#endif
+
+private:
+ XCAM_DEAD_COPY (Stream);
+
+private:
+ char *_file_name;
+ uint32_t _width;
+ uint32_t _height;
+
+ SmartPtr<VideoBuffer> _buf;
+ SmartPtr<BufferPool> _pool;
+
+ ImageFileHandle _file;
+#if XCAM_TEST_OPENCV
+ cv::VideoWriter _writer;
+#endif
+ TestFileFormat _format;
+};
+
+Stream::Stream (const char *file_name, uint32_t width, uint32_t height)
+ : _file_name (NULL)
+ , _width (width)
+ , _height (height)
+ , _format (FileNV12)
+{
+ if (file_name)
+ _file_name = strndup (file_name, XCAM_TEST_MAX_STR_SIZE);
+}
+
+Stream::~Stream ()
+{
+ _file.close ();
+
+ if (_file_name) {
+ xcam_free (_file_name);
+ _file_name = NULL;
+ }
+}
+
+void
+Stream::set_buf_size (uint32_t width, uint32_t height)
+{
+ _width = width;
+ _height = height;
+}
+
+XCamReturn
+Stream::open_reader (const char *option)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, _format == FileNV12, XCAM_RETURN_ERROR_PARAM,
+ "stream(%s) only support NV12 input format", _file_name);
+
+ if (_file.open (_file_name, option) != XCAM_RETURN_NO_ERROR) {
+ XCAM_LOG_ERROR ("stream(%s) open failed", _file_name);
+ return XCAM_RETURN_ERROR_FILE;
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+Stream::open_writer (const char *option)
+{
+ XCAM_ASSERT (_format != FileNone);
+
+ if (_format == FileNV12) {
+ if (_file.open (_file_name, option) != XCAM_RETURN_NO_ERROR) {
+ XCAM_LOG_ERROR ("stream(%s) open failed", _file_name);
+ return XCAM_RETURN_ERROR_FILE;
+ }
+ } else if (_format == FileMP4) {
+#if XCAM_TEST_OPENCV
+ XCamReturn ret = cv_open_writer ();
+ XCAM_FAIL_RETURN (
+ ERROR, ret == XCAM_RETURN_NO_ERROR, ret, "stream(%s) cv open writer failed", _file_name);
+#else
+ XCAM_LOG_ERROR ("stream(%s) unsupported MP4 format without opencv", _file_name);
+ return XCAM_RETURN_ERROR_PARAM;
+#endif
+ } else {
+ XCAM_LOG_ERROR ("stream(%s) invalid file format: %d", _file_name, (int)_format);
+ return XCAM_RETURN_ERROR_PARAM;
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+Stream::close ()
+{
+ return _file.close ();
+}
+
+XCamReturn
+Stream::rewind ()
+{
+ return _file.rewind ();
+}
+
+XCamReturn
+Stream::read_buf ()
+{
+ XCAM_ASSERT (_pool.ptr ());
+
+ _buf = _pool->get_buffer (_pool);
+ XCAM_ASSERT (_buf.ptr ());
+
+ return _file.read_buf (_buf);
+}
+
+XCamReturn
+Stream::write_buf (char *frame_str) {
+ if (_format == FileNV12) {
+ _file.write_buf (_buf);
+ } else if (_format == FileMP4) {
+#if XCAM_TEST_OPENCV
+ cv_write_buf (frame_str);
+#else
+ XCAM_UNUSED (frame_str);
+ XCAM_LOG_ERROR ("stream(%s) unsupported MP4 format without opencv", _file_name);
+ return XCAM_RETURN_ERROR_PARAM;
+#endif
+ } else {
+ XCAM_LOG_ERROR ("stream(%s) invalid file format: %d", _file_name, (int)_format);
+ return XCAM_RETURN_ERROR_PARAM;
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+XCamReturn
+Stream::estimate_file_format ()
+{
+ XCAM_ASSERT (get_file_name ());
+
+ char suffix[XCAM_TEST_MAX_STR_SIZE] = {'\0'};
+ const char *ptr = strrchr (get_file_name (), '.');
+ snprintf (suffix, XCAM_TEST_MAX_STR_SIZE, "%s", ptr + 1);
+
+ if (!strcasecmp (suffix, "nv12")) {
+ _format = FileNV12;
+ } else if (!strcasecmp (suffix, "mp4")) {
+#if XCAM_TEST_OPENCV
+ _format = FileMP4;
+#else
+ XCAM_LOG_ERROR ("stream(%s) unsupported MP4 format without opencv", _file_name);
+ return XCAM_RETURN_ERROR_PARAM;
+#endif
+ } else {
+ XCAM_LOG_ERROR ("stream(%s) invalid file format: %s", _file_name, suffix);
+ return XCAM_RETURN_ERROR_PARAM;
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+#if XCAM_TEST_OPENCV
+XCamReturn
+Stream::cv_open_writer ()
+{
+ XCAM_FAIL_RETURN (
+ ERROR, _width && _height, XCAM_RETURN_ERROR_PARAM,
+ "stream(%s) invalid size width:%d height:%d", _file_name, _width, _height);
+
+ cv::Size frame_size = cv::Size (_width, _height);
+ if (!_writer.open (_file_name, cv::VideoWriter::fourcc ('X', '2', '6', '4'), 30, frame_size)) {
+ XCAM_LOG_ERROR ("stream(%s) open file failed", _file_name);
+ return XCAM_RETURN_ERROR_FILE;
+ }
+
+ return XCAM_RETURN_NO_ERROR;
+}
+
+void
+Stream::cv_write_buf (char *frame_str)
+{
+ cv::Mat mat;
+
+#if XCAM_TEST_STREAM_DEBUG
+ convert_to_mat (_buf, mat);
+ cv::putText (mat, frame_str, cv::Point(20, 50), fontFace, 2.0, color, 2, 8, false);
+#else
+ XCAM_UNUSED (frame_str);
+#endif
+
+ if (_writer.isOpened ()) {
+ if (mat.empty())
+ convert_to_mat (_buf, mat);
+
+ _writer.write (mat);
+ }
+}
+
+void
+Stream::debug_write_image (char *img_name, char *frame_str, char *idx_str)
+{
+ XCAM_ASSERT (img_name);
+
+ cv::Mat mat;
+ convert_to_mat (_buf, mat);
+
+ if(frame_str)
+ cv::putText (mat, frame_str, cv::Point(20, 50), fontFace, 2.0, color, 2, 8, false);
+ if(idx_str)
+ cv::putText (mat, idx_str, cv::Point(20, 110), fontFace, 2.0, color, 2, 8, false);
+
+ cv::imwrite (img_name, mat);
+}
+#endif
+
+}
+#endif // XCAM_TEST_STREAM_H
diff --git a/tools/cl-double-quotation.sh b/tools/add-quotation-marks.sh
index 5a77a67..3c669f5 100755
--- a/tools/cl-double-quotation.sh
+++ b/tools/add-quotation-marks.sh
@@ -1,12 +1,12 @@
#! /bin/sh
-# Add double quotation marks on cl file, this script will
-# be called in top_srcdir/clx_kernel/Makefile.am
+# Add double quotation marks on source file
+# Usage: add-quotation-marks.sh <src_file> <dst_file>
-CL_FILE=$1
-CLX_FILE=$2
+SRC_FILE=$1
+DST_FILE=$2
if [ $# -ne 2 ]; then
- echo "Usage: $0 <cl_file> <clx_file>"
+ echo "Usage: $0 <src_file> <dst_file>"
exit 1
fi
@@ -32,15 +32,15 @@ gawk '
}
}
}
- ' $CL_FILE > $CLX_FILE.tmp
+ ' $SRC_FILE > $DST_FILE.tmp
ret=$?
if [ $ret != 0 ]; then
- rm -rf $CLX_FILE.tmp
- echo "Add double quotation marks on $CL_FILE failed"
+ rm -rf $DST_FILE.tmp
+ echo "Add double quotation marks on $SRC_FILE failed"
exit 1
fi
-mv $CLX_FILE.tmp $CLX_FILE
+mv $DST_FILE.tmp $DST_FILE
-echo "Add double quotation marks on $CL_FILE done"
+echo "Add double quotation marks on $SRC_FILE done"
diff --git a/wrapper/Makefile.am b/wrapper/Makefile.am
index 63dbffd..cac6ded 100644
--- a/wrapper/Makefile.am
+++ b/wrapper/Makefile.am
@@ -1,8 +1,5 @@
-
if ENABLE_GST
GST_DIR = gstreamer
-else
-GST_DIR =
endif
SUBDIRS = $(GST_DIR)
diff --git a/wrapper/gstreamer/Makefile.am b/wrapper/gstreamer/Makefile.am
index 8a47a6f..cc0f7d8 100644
--- a/wrapper/gstreamer/Makefile.am
+++ b/wrapper/gstreamer/Makefile.am
@@ -2,135 +2,117 @@ if ENABLE_IA_AIQ
SUBDIRS = interface
endif
-plugin_LTLIBRARIES = \
- libgstxcamsrc.la \
- $(NULL)
+plugin_LTLIBRARIES = libgstxcamsrc.la
if HAVE_LIBCL
-plugin_LTLIBRARIES += \
- libgstxcamfilter.la \
- $(NULL)
+plugin_LTLIBRARIES += libgstxcamfilter.la
endif
-XCORE_DIR = $(top_srcdir)/xcore
-MODULES_DIR = $(top_srcdir)/modules
-
-XCORE_LA = $(top_builddir)/xcore/libxcam_core.la
-
-if ENABLE_IA_AIQ
-XCAM_INTERFACE_DIR = -I$(top_srcdir)/wrapper/gstreamer/interface
-XCAM_INTERFACE_LA = $(top_builddir)/wrapper/gstreamer/interface/libgstxcaminterface.la
-else
-XCAM_INTERFACE_DIR =
-XCAM_INTERFACE_LA =
-endif
+XCAM_GST_CXXFLAGS = \
+ $(XCAM_CXXFLAGS) \
+ $(GST_CFLAGS) \
+ -I$(top_srcdir)/xcore \
+ -I$(top_srcdir)/modules \
+ -I$(top_srcdir)/wrapper/gstreamer \
+ $(NULL)
-XCAMGST_CXXFLAGS = $(XCAM_CXXFLAGS)
-XCAMGST_LIBS = \
+XCAM_GST_LIBS = \
+ $(GST_LIBS) \
+ $(GST_VIDEO_LIBS) \
+ $(GST_ALLOCATOR_LIBS) \
+ $(top_builddir)/xcore/libxcam_core.la \
$(NULL)
-if HAVE_LIBDRM
-XCAMGST_CXXFLAGS += $(LIBDRM_CFLAGS)
-XCAMGST_LIBS += $(LIBDRM_LIBS)
+if HAVE_LIBCL
+XCAM_GST_LIBS += $(top_builddir)/modules/ocl/libxcam_ocl.la
endif
-if USE_LOCAL_ATOMISP
-XCAMGST_CXXFLAGS += -I$(top_srcdir)/ext/atomisp
+if HAVE_LIBDRM
+XCAM_GST_CXXFLAGS += $(LIBDRM_CFLAGS)
+XCAM_GST_LIBS += $(LIBDRM_LIBS)
endif
-XCAMGST_CXXFLAGS += \
- -I$(XCORE_DIR) \
- -I$(MODULES_DIR) \
- $(NULL)
-
# Note: plugindir is set in configure
plugindir="$(libdir)/gstreamer-1.0"
# sources used to compile this plug-in
libgstxcamsrc_la_SOURCES = \
- gstxcambuffermeta.cpp \
- gstxcambufferpool.cpp \
- main_dev_manager.cpp \
- gstxcamsrc.cpp \
+ gstxcambuffermeta.cpp \
+ gstxcambufferpool.cpp \
+ main_dev_manager.cpp \
+ gstxcamsrc.cpp \
$(NULL)
# compiler and linker flags used to compile this plugin, set in configure.ac
+XCAM_SRC_CXXFLAGS = \
+ $(XCAM_GST_CXXFLAGS) \
+ $(NULL)
+
+XCAM_SRC_LIBS = \
+ $(XCAM_GST_LIBS) \
+ $(NULL)
+
+if USE_LOCAL_ATOMISP
+XCAM_SRC_CXXFLAGS += -I$(top_srcdir)/ext/atomisp
+endif
+
+if ENABLE_IA_AIQ
+XCAM_SRC_CXXFLAGS += -I$(top_srcdir)/wrapper/gstreamer/interface
+XCAM_SRC_LIBS += \
+ $(top_builddir)/modules/isp/libxcam_isp.la \
+ $(top_builddir)/wrapper/gstreamer/interface/libgstxcaminterface.la \
+ $(NULL)
+endif
+
libgstxcamsrc_la_CXXFLAGS = \
- $(GST_CFLAGS) $(XCAMGST_CXXFLAGS) \
- -I$(top_srcdir)/wrapper/gstreamer \
- $(XCAM_INTERFACE_DIR) \
+ $(XCAM_SRC_CXXFLAGS) \
$(NULL)
-libgstxcamsrc_la_LIBADD = $(XCAMGST_LIBS) \
- $(XCAM_INTERFACE_LA) \
- $(XCORE_LA) $(GST_ALLOCATOR_LIBS) \
- $(GST_VIDEO_LIBS) $(GST_LIBS) \
+libgstxcamsrc_la_LIBADD = \
+ $(XCAM_SRC_LIBS) \
$(NULL)
libgstxcamsrc_la_LDFLAGS = \
- -module -avoid-version \
- $(PTHREAD_LDFLAGS) $(XCORE_LA) \
+ -module -avoid-version \
$(NULL)
libgstxcamsrc_la_LIBTOOLFLAGS = --tag=disable-static
-if ENABLE_IA_AIQ
-ISP_LA = $(top_builddir)/modules/isp/libxcam_isp.la
-libgstxcamsrc_la_LIBADD += $(ISP_LA)
-libgstxcamsrc_la_LDFLAGS += $(ISP_LA)
-endif
-
if HAVE_LIBCL
-OCL_LA = $(top_builddir)/modules/ocl/libxcam_ocl.la
-
-libgstxcamsrc_la_LIBADD += $(OCL_LA)
-libgstxcamsrc_la_LDFLAGS += $(OCL_LA)
-
libgstxcamfilter_la_SOURCES = \
- gstxcambuffermeta.cpp \
- main_pipe_manager.cpp \
- gstxcamfilter.cpp \
+ gstxcambuffermeta.cpp \
+ main_pipe_manager.cpp \
+ gstxcamfilter.cpp \
$(NULL)
libgstxcamfilter_la_CXXFLAGS = \
- $(GST_CFLAGS) $(XCAMGST_CXXFLAGS) \
- -I$(top_srcdir)/wrapper/gstreamer \
+ $(XCAM_GST_CXXFLAGS) \
$(NULL)
libgstxcamfilter_la_LIBADD = \
- $(XCAMGST_LIBS) \
- $(XCORE_LA) $(OCL_LA) \
- $(GST_ALLOCATOR_LIBS) \
- $(GST_VIDEO_LIBS) \
- $(GST_LIBS) \
+ $(XCAM_GST_LIBS) \
$(NULL)
libgstxcamfilter_la_LDFLAGS = \
- -module -avoid-version \
- $(XCORE_LA) $(OCL_LA) \
+ -module -avoid-version \
$(NULL)
libgstxcamfilter_la_LIBTOOLFLAGS = --tag=disable-static
endif
-# headers we need but don't want installed
+# headers we need but do not want installed
noinst_HEADERS = \
- gst_xcam_utils.h \
+ gst_xcam_utils.h \
+ gstxcambufferpool.h \
+ gstxcambuffermeta.h \
+ main_dev_manager.h \
+ gstxcamsrc.h \
$(NULL)
-if ENABLE_IA_AIQ
-noinst_HEADERS += \
- gstxcambufferpool.h \
- gstxcambuffermeta.h \
- main_dev_manager.h \
- gstxcamsrc.h \
- $(NULL)
-endif
-
if HAVE_LIBCL
noinst_HEADERS += \
- gstxcambuffermeta.h \
- main_pipe_manager.h \
- gstxcamfilter.h \
+ gstxcambuffermeta.h \
+ main_pipe_manager.h \
+ gstxcamfilter.h \
$(NULL)
endif
diff --git a/wrapper/gstreamer/gstxcamfilter.cpp b/wrapper/gstreamer/gstxcamfilter.cpp
index 21b38d8..a8cd595 100644
--- a/wrapper/gstreamer/gstxcamfilter.cpp
+++ b/wrapper/gstreamer/gstxcamfilter.cpp
@@ -42,7 +42,6 @@ using namespace GstXCam;
#define DEFAULT_PROP_STITCH_SCALE_MODE CLBlenderScaleLocal
#define DEFAULT_PROP_STITCH_FISHEYE_MAP FALSE
#define DEFAULT_PROP_STITCH_LSC FALSE
-#define DEFAULT_PROP_STITCH_FM_OCL FALSE
#define DEFAULT_PROP_STITCH_RES_MODE StitchRes1080P
XCAM_BEGIN_DECLARE
@@ -61,7 +60,6 @@ enum {
PROP_STITCH_SCALE_MODE,
PROP_STITCH_FISHEYE_MAP,
PROP_STITCH_LSC,
- PROP_STITCH_FM_OCL,
PROP_STITCH_RES_MODE
};
@@ -307,13 +305,6 @@ gst_xcam_filter_class_init (GstXCamFilterClass *class_self)
g_param_spec_boolean ("stitch-lsc", "stitch enable lens shading correction", "Enable Lens Shading Correction",
DEFAULT_PROP_STITCH_LSC, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-#if HAVE_OPENCV
- g_object_class_install_property (
- gobject_class, PROP_STITCH_FM_OCL,
- g_param_spec_boolean ("stitch-fm-ocl", "stitch enable ocl for feature match", "Enable ocl for feature match",
- DEFAULT_PROP_STITCH_FM_OCL, (GParamFlags)(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
-#endif
-
g_object_class_install_property (
gobject_class, PROP_STITCH_RES_MODE,
g_param_spec_enum ("stitch-res-mode", "stitch resolution mode", "Stitch Resolution Mode",
@@ -355,7 +346,6 @@ gst_xcam_filter_init (GstXCamFilter *xcamfilter)
xcamfilter->stitch_enable_seam = DEFAULT_PROP_STITCH_ENABLE_SEAM;
xcamfilter->stitch_fisheye_map = DEFAULT_PROP_STITCH_FISHEYE_MAP;
xcamfilter->stitch_lsc = DEFAULT_PROP_STITCH_LSC;
- xcamfilter->stitch_fm_ocl = DEFAULT_PROP_STITCH_FM_OCL;
xcamfilter->stitch_scale_mode = DEFAULT_PROP_STITCH_SCALE_MODE;
xcamfilter->stitch_res_mode = DEFAULT_PROP_STITCH_RES_MODE;
@@ -363,8 +353,9 @@ gst_xcam_filter_init (GstXCamFilter *xcamfilter)
xcamfilter->cached_buf_num = 0;
XCAM_CONSTRUCTOR (xcamfilter->pipe_manager, SmartPtr<MainPipeManager>);
- xcamfilter->pipe_manager = new MainPipeManager;
- XCAM_ASSERT (xcamfilter->pipe_manager.ptr ());
+ SmartPtr<MainPipeManager> pipe_manager = new MainPipeManager;
+ XCAM_ASSERT (pipe_manager.ptr ());
+ xcamfilter->pipe_manager = pipe_manager;
}
static void
@@ -423,11 +414,6 @@ gst_xcam_filter_set_property (GObject *object, guint prop_id, const GValue *valu
case PROP_STITCH_LSC:
xcamfilter->stitch_lsc = g_value_get_boolean (value);
break;
-#if HAVE_OPENCV
- case PROP_STITCH_FM_OCL:
- xcamfilter->stitch_fm_ocl = g_value_get_boolean (value);
- break;
-#endif
case PROP_STITCH_RES_MODE:
xcamfilter->stitch_res_mode = (StitchResMode) g_value_get_enum (value);
break;
@@ -479,11 +465,6 @@ gst_xcam_filter_get_property (GObject *object, guint prop_id, GValue *value, GPa
case PROP_STITCH_LSC:
g_value_set_boolean (value, xcamfilter->stitch_lsc);
break;
-#if HAVE_OPENCV
- case PROP_STITCH_FM_OCL:
- g_value_set_boolean (value, xcamfilter->stitch_fm_ocl);
- break;
-#endif
case PROP_STITCH_RES_MODE:
g_value_set_enum (value, xcamfilter->stitch_res_mode);
break;
@@ -508,7 +489,6 @@ gst_xcam_filter_start (GstBaseTransform *trans)
SmartPtr<MainPipeManager> pipe_manager = xcamfilter->pipe_manager;
SmartPtr<SmartAnalyzer> smart_analyzer;
- SmartPtr<CLPostImageProcessor> image_processor;
SmartHandlerList smart_handlers = SmartAnalyzerLoader::load_smart_handlers (DEFAULT_SMART_ANALYSIS_LIB_DIR);
if (!smart_handlers.empty ()) {
@@ -530,7 +510,7 @@ gst_xcam_filter_start (GstBaseTransform *trans)
}
}
- image_processor = new CLPostImageProcessor ();
+ SmartPtr<CLPostImageProcessor> image_processor = new CLPostImageProcessor ();
XCAM_ASSERT (image_processor.ptr ());
image_processor->set_stats_callback (pipe_manager);
image_processor->set_defog_mode ((CLPostImageProcessor::CLDefogMode) xcamfilter->defog_mode);
@@ -571,8 +551,10 @@ gst_xcam_filter_start (GstBaseTransform *trans)
pipe_manager->add_image_processor (image_processor);
pipe_manager->set_image_processor (image_processor);
- xcamfilter->buf_pool = new CLVideoBufferPool ();
- XCAM_ASSERT (xcamfilter->buf_pool.ptr ());
+ SmartPtr<BufferPool> pool = new CLVideoBufferPool ();
+ XCAM_ASSERT (pool.ptr ());
+ xcamfilter->buf_pool = pool;
+
if (xcamfilter->copy_mode == COPY_MODE_DMA) {
XCAM_LOG_WARNING ("CLVideoBuffer doesn't support DMA copy mode, switch to CPU copy mode");
xcamfilter->copy_mode = COPY_MODE_CPU;
@@ -735,8 +717,8 @@ gst_xcam_filter_set_caps (GstBaseTransform *trans, GstCaps *incaps, GstCaps *out
if (xcamfilter->enable_stitch) {
processor->set_image_stitch (
xcamfilter->enable_stitch, xcamfilter->stitch_enable_seam, xcamfilter->stitch_scale_mode,
- xcamfilter->stitch_fisheye_map, xcamfilter->stitch_lsc, xcamfilter->stitch_fm_ocl,
- GST_VIDEO_INFO_WIDTH (&out_info), GST_VIDEO_INFO_HEIGHT (&out_info), (uint32_t) xcamfilter->stitch_res_mode);
+ xcamfilter->stitch_fisheye_map, xcamfilter->stitch_lsc, GST_VIDEO_INFO_WIDTH (&out_info),
+ GST_VIDEO_INFO_HEIGHT (&out_info), (uint32_t) xcamfilter->stitch_res_mode);
XCAM_LOG_INFO ("xcamfilter stitch output size width:%d height:%d",
GST_VIDEO_INFO_WIDTH (&out_info), GST_VIDEO_INFO_HEIGHT (&out_info));
}
@@ -1001,5 +983,5 @@ GST_PLUGIN_DEFINE (
VERSION,
GST_LICENSE_UNKNOWN,
"libxcamfilter",
- "https://github.com/01org/libxcam"
+ "https://github.com/intel/libxcam"
)
diff --git a/wrapper/gstreamer/gstxcamfilter.h b/wrapper/gstreamer/gstxcamfilter.h
index fddfed2..bd26aa9 100644
--- a/wrapper/gstreamer/gstxcamfilter.h
+++ b/wrapper/gstreamer/gstxcamfilter.h
@@ -84,7 +84,6 @@ struct _GstXCamFilter
gboolean enable_stitch;
gboolean stitch_enable_seam;
gboolean stitch_fisheye_map;
- gboolean stitch_fm_ocl;
gboolean stitch_lsc;
XCam::CLBlenderScaleMode stitch_scale_mode;
StitchResMode stitch_res_mode;
diff --git a/wrapper/gstreamer/gstxcamsrc.cpp b/wrapper/gstreamer/gstxcamsrc.cpp
index cb3a6f4..0292c26 100644
--- a/wrapper/gstreamer/gstxcamsrc.cpp
+++ b/wrapper/gstreamer/gstxcamsrc.cpp
@@ -41,7 +41,7 @@
#include "gstxcaminterface.h"
#include "dynamic_analyzer_loader.h"
#include "isp/hybrid_analyzer_loader.h"
-#include "x3a_analyze_tuner.h"
+#include "isp/iq/x3a_analyze_tuner.h"
#include "isp/isp_poll_thread.h"
#endif
#if HAVE_LIBCL
@@ -83,6 +83,8 @@ using namespace GstXCam;
#define DEFAULT_PROP_IMAGE_PROCESSOR ISP_IMAGE_PROCESSOR
#elif HAVE_LIBCL
#define DEFAULT_PROP_IMAGE_PROCESSOR CL_IMAGE_PROCESSOR
+#else
+#define DEFAULT_PROP_IMAGE_PROCESSOR NONE_IMAGE_PROCESSOR
#endif
#if HAVE_LIBCL
#define DEFAULT_PROP_WDR_MODE NONE_WDR
@@ -633,8 +635,11 @@ gst_xcam_src_init (GstXCamSrc *xcamsrc)
xcamsrc->xcam_video_info.init (DEFAULT_PROP_PIXELFORMAT, DEFAULT_VIDEO_WIDTH, DEFAULT_VIDEO_HEIGHT);
xcamsrc->image_processor_type = DEFAULT_PROP_IMAGE_PROCESSOR;
xcamsrc->analyzer_type = DEFAULT_PROP_ANALYZER;
+
XCAM_CONSTRUCTOR (xcamsrc->device_manager, SmartPtr<MainDeviceManager>);
- xcamsrc->device_manager = new MainDeviceManager;
+ SmartPtr<MainDeviceManager> device_manager = new MainDeviceManager;
+ XCAM_ASSERT (device_manager.ptr ());
+ xcamsrc->device_manager = device_manager;
}
static void
@@ -913,11 +918,6 @@ gst_xcam_src_start (GstBaseSrc *src)
SmartPtr<ImageProcessor> isp_processor;
SmartPtr<IspController> isp_controller;
#endif
-#if HAVE_LIBCL
- SmartPtr<SmartAnalyzer> smart_analyzer;
- SmartPtr<CL3aImageProcessor> cl_processor;
- SmartPtr<CLPostImageProcessor> cl_post_processor;
-#endif
SmartPtr<V4l2Device> capture_device;
SmartPtr<V4l2SubDevice> event_device;
SmartPtr<PollThread> poll_thread;
@@ -980,13 +980,15 @@ gst_xcam_src_start (GstBaseSrc *src)
XCAM_ASSERT (isp_processor.ptr ());
device_manager->add_image_processor (isp_processor);
#endif
- cl_processor = new CL3aImageProcessor ();
+
+ SmartPtr<CL3aImageProcessor> cl_processor = new CL3aImageProcessor ();
+ XCAM_ASSERT (cl_processor.ptr ());
cl_processor->set_stats_callback (device_manager);
if(xcamsrc->wdr_mode_type != NONE_WDR)
{
cl_processor->set_gamma (false);
xcamsrc->in_format = V4L2_PIX_FMT_SGRBG12;
- cl_processor->set_3a_stats_bits(12);
+ cl_processor->set_3a_stats_bits (12);
setenv ("AIQ_CPF_PATH", "/etc/atomisp/imx185_wdr.cpf", 1);
if(xcamsrc->wdr_mode_type == GAUSSIAN_WDR)
@@ -1018,7 +1020,8 @@ gst_xcam_src_start (GstBaseSrc *src)
}
#if HAVE_LIBCL
- cl_post_processor = new CLPostImageProcessor ();
+ SmartPtr<CLPostImageProcessor> cl_post_processor = new CLPostImageProcessor ();
+ XCAM_ASSERT (cl_post_processor.ptr ());
cl_post_processor->set_stats_callback (device_manager);
cl_post_processor->set_defog_mode ((CLPostImageProcessor::CLDefogMode) xcamsrc->defog_mode);
@@ -1110,6 +1113,7 @@ gst_xcam_src_start (GstBaseSrc *src)
device_manager->set_3a_analyzer (analyzer);
#if HAVE_LIBCL
+ SmartPtr<SmartAnalyzer> smart_analyzer;
SmartHandlerList smart_handlers = SmartAnalyzerLoader::load_smart_handlers (DEFAULT_SMART_ANALYSIS_LIB_DIR);
if (!smart_handlers.empty ()) {
smart_analyzer = new SmartAnalyzer ();
@@ -1219,7 +1223,7 @@ translate_format_to_xcam (GstVideoFormat format)
case GST_VIDEO_FORMAT_Y42B:
return V4L2_PIX_FMT_YUV422P;
- //RGB
+ //RGB
case GST_VIDEO_FORMAT_RGBx:
return V4L2_PIX_FMT_RGB32;
case GST_VIDEO_FORMAT_BGRx:
@@ -1733,5 +1737,5 @@ GST_PLUGIN_DEFINE (
VERSION,
GST_LICENSE_UNKNOWN,
"libxcamsrc",
- "https://github.com/01org/libxcam"
+ "https://github.com/intel/libxcam"
)
diff --git a/wrapper/gstreamer/gstxcamsrc.h b/wrapper/gstreamer/gstxcamsrc.h
index 8e87e88..4af1926 100644
--- a/wrapper/gstreamer/gstxcamsrc.h
+++ b/wrapper/gstreamer/gstxcamsrc.h
@@ -42,6 +42,7 @@ XCAM_BEGIN_DECLARE
typedef enum {
ISP_IMAGE_PROCESSOR = 0,
CL_IMAGE_PROCESSOR,
+ NONE_IMAGE_PROCESSOR,
} ImageProcessorType;
typedef enum {
diff --git a/wrapper/gstreamer/interface/Makefile.am b/wrapper/gstreamer/interface/Makefile.am
index 5170426..3b056e0 100644
--- a/wrapper/gstreamer/interface/Makefile.am
+++ b/wrapper/gstreamer/interface/Makefile.am
@@ -2,20 +2,22 @@ lib_LTLIBRARIES = libgstxcaminterface.la
libgstxcaminterface_la_SOURCES = gstxcaminterface.c
-libgstxcaminterface_la_CFLAGS = \
- $(GST_CFLAGS) \
- -I$(top_srcdir)/xcore \
- -I$(top_srcdir)/xcore/base \
- $(XCAM_CFLAGS) \
- $(NULL)
+libgstxcaminterface_la_CFLAGS = \
+ $(XCAM_CFLAGS) \
+ $(GST_CFLAGS) \
+ -I$(top_srcdir)/xcore \
+ -I$(top_srcdir)/xcore/base \
+ $(NULL)
libgstxcaminterface_la_LIBADD = \
- $(GST_LIBS) \
- $(NULL)
+ $(GST_LIBS) \
+ $(top_builddir)/xcore/libxcam_core.la \
+ $(NULL)
libgstxcaminterfaceincludedir = \
- $(includedir)/gstreamer-1.0/gst
+ $(includedir)/gstreamer-1.0/gst \
+ $(NULL)
libgstxcaminterfaceinclude_HEADERS = \
- gstxcaminterface.h
-
+ gstxcaminterface.h \
+ $(NULL)
diff --git a/xcore/Makefile.am b/xcore/Makefile.am
index bcadd7c..f901e75 100644
--- a/xcore/Makefile.am
+++ b/xcore/Makefile.am
@@ -1,146 +1,150 @@
lib_LTLIBRARIES = libxcam_core.la
-XCAM_CORE_CXXFLAGS = $(XCAM_CXXFLAGS)
+XCAM_CORE_CXXFLAGS = \
+ $(XCAM_CXXFLAGS) \
+ -pthread \
+ $(NULL)
+
XCAM_CORE_LIBS = \
- -ldl \
- -lpthread \
+ -ldl \
$(NULL)
xcam_sources = \
- analyzer_loader.cpp \
- smart_analyzer_loader.cpp \
- buffer_pool.cpp \
- calibration_parser.cpp \
- device_manager.cpp \
- pipe_manager.cpp \
- dma_video_buffer.cpp \
- dynamic_analyzer.cpp \
- dynamic_analyzer_loader.cpp \
- smart_analyzer.cpp \
- smart_analysis_handler.cpp \
- smart_buffer_priv.cpp \
- fake_poll_thread.cpp \
- file_handle.cpp \
- handler_interface.cpp \
- image_handler.cpp \
- image_processor.cpp \
- image_projector.cpp \
- image_file_handle.cpp \
- poll_thread.cpp \
- surview_fisheye_dewarp.cpp \
- swapped_buffer.cpp \
- thread_pool.cpp \
- uvc_device.cpp \
- v4l2_buffer_proxy.cpp \
- v4l2_device.cpp \
- video_buffer.cpp \
- worker.cpp \
- xcam_analyzer.cpp \
- x3a_analyzer.cpp \
- x3a_analyzer_manager.cpp \
- x3a_analyzer_simple.cpp \
- x3a_image_process_center.cpp \
- x3a_stats_pool.cpp \
- x3a_result.cpp \
- x3a_result_factory.cpp \
- xcam_common.cpp \
- xcam_buffer.cpp \
- xcam_thread.cpp \
- xcam_utils.cpp \
- interface/feature_match.cpp \
- interface/blender.cpp \
- interface/geo_mapper.cpp \
- interface/stitcher.cpp \
+ analyzer_loader.cpp \
+ smart_analyzer_loader.cpp \
+ buffer_pool.cpp \
+ calibration_parser.cpp \
+ device_manager.cpp \
+ pipe_manager.cpp \
+ dma_video_buffer.cpp \
+ dynamic_analyzer.cpp \
+ dynamic_analyzer_loader.cpp \
+ smart_analyzer.cpp \
+ smart_analysis_handler.cpp \
+ smart_buffer_priv.cpp \
+ fake_poll_thread.cpp \
+ file_handle.cpp \
+ handler_interface.cpp \
+ image_handler.cpp \
+ image_processor.cpp \
+ image_projector.cpp \
+ image_file_handle.cpp \
+ poll_thread.cpp \
+ surview_fisheye_dewarp.cpp \
+ swapped_buffer.cpp \
+ thread_pool.cpp \
+ uvc_device.cpp \
+ v4l2_buffer_proxy.cpp \
+ v4l2_device.cpp \
+ video_buffer.cpp \
+ once_map_video_buffer_priv.cpp \
+ worker.cpp \
+ xcam_analyzer.cpp \
+ x3a_analyzer.cpp \
+ x3a_analyzer_manager.cpp \
+ x3a_analyzer_simple.cpp \
+ x3a_image_process_center.cpp \
+ x3a_stats_pool.cpp \
+ x3a_result.cpp \
+ x3a_result_factory.cpp \
+ xcam_common.cpp \
+ xcam_buffer.cpp \
+ xcam_thread.cpp \
+ xcam_utils.cpp \
+ interface/feature_match.cpp \
+ interface/blender.cpp \
+ interface/geo_mapper.cpp \
+ interface/stitcher.cpp \
$(NULL)
if HAVE_LIBDRM
XCAM_CORE_CXXFLAGS += $(LIBDRM_CFLAGS)
XCAM_CORE_LIBS += \
- -ldrm_intel \
- $(LIBDRM_LIBS) \
+ -ldrm_intel \
+ $(LIBDRM_LIBS) \
$(NULL)
xcam_sources += \
- drm_bo_buffer.cpp \
- drm_display.cpp \
- drm_v4l2_buffer.cpp \
+ drm_bo_buffer.cpp \
+ drm_display.cpp \
+ drm_v4l2_buffer.cpp \
$(NULL)
endif
libxcam_core_la_CXXFLAGS = \
- $(XCAM_CORE_CXXFLAGS) \
+ $(XCAM_CORE_CXXFLAGS) \
$(NULL)
libxcam_core_la_SOURCES = \
- $(xcam_sources) \
+ $(xcam_sources) \
$(NULL)
-libxcam_core_la_LDFLAGS = \
- -no-undefined \
- $(XCAM_LT_LDFLAGS) \
- $(PTHREAD_LDFLAGS) \
+libxcam_core_la_LIBADD = \
+ $(XCAM_CORE_LIBS) \
$(NULL)
-libxcam_core_la_LIBADD = \
- $(XCAM_CORE_LIBS) \
+libxcam_core_la_LDFLAGS = \
+ -no-undefined \
+ -pthread \
+ $(XCAM_LT_LDFLAGS) \
$(NULL)
libxcam_coreincludedir = $(includedir)/xcam
nobase_libxcam_coreinclude_HEADERS = \
- base/xcam_3a_result.h \
- base/xcam_3a_types.h \
- base/xcam_3a_description.h \
- base/xcam_buffer.h \
- base/xcam_params.h \
- base/xcam_common.h \
- base/xcam_defs.h \
- base/xcam_smart_description.h \
- base/xcam_smart_result.h \
- calibration_parser.h \
- device_manager.h \
- dma_video_buffer.h \
- file_handle.h \
- pipe_manager.h \
- handler_interface.h \
- image_handler.h \
- image_processor.h \
- image_projector.h \
- image_file_handle.h \
- safe_list.h \
- smartptr.h \
- surview_fisheye_dewarp.h \
- swapped_buffer.h \
- thread_pool.h \
- v4l2_buffer_proxy.h \
- v4l2_device.h \
- video_buffer.h \
- worker.h \
- xcam_analyzer.h \
- x3a_analyzer.h \
- x3a_analyzer_manager.h \
- x3a_event.h \
- x3a_image_process_center.h \
- x3a_result.h \
- xcam_mutex.h \
- xcam_thread.h \
- xcam_std.h \
- xcam_utils.h \
- xcam_obj_debug.h \
- buffer_pool.h \
- meta_data.h \
- vec_mat.h \
- interface/data_types.h \
- interface/feature_match.h \
- interface/blender.h \
- interface/geo_mapper.h \
- interface/stitcher.h \
+ base/xcam_3a_result.h \
+ base/xcam_3a_types.h \
+ base/xcam_3a_description.h \
+ base/xcam_buffer.h \
+ base/xcam_params.h \
+ base/xcam_common.h \
+ base/xcam_defs.h \
+ base/xcam_smart_description.h \
+ base/xcam_smart_result.h \
+ calibration_parser.h \
+ device_manager.h \
+ dma_video_buffer.h \
+ file_handle.h \
+ pipe_manager.h \
+ handler_interface.h \
+ image_handler.h \
+ image_processor.h \
+ image_projector.h \
+ image_file_handle.h \
+ safe_list.h \
+ smartptr.h \
+ surview_fisheye_dewarp.h \
+ swapped_buffer.h \
+ thread_pool.h \
+ v4l2_buffer_proxy.h \
+ v4l2_device.h \
+ video_buffer.h \
+ worker.h \
+ xcam_analyzer.h \
+ x3a_analyzer.h \
+ x3a_analyzer_manager.h \
+ x3a_event.h \
+ x3a_image_process_center.h \
+ x3a_result.h \
+ xcam_mutex.h \
+ xcam_thread.h \
+ xcam_std.h \
+ xcam_utils.h \
+ xcam_obj_debug.h \
+ buffer_pool.h \
+ meta_data.h \
+ vec_mat.h \
+ interface/data_types.h \
+ interface/feature_match.h \
+ interface/blender.h \
+ interface/geo_mapper.h \
+ interface/stitcher.h \
$(NULL)
if HAVE_LIBDRM
nobase_libxcam_coreinclude_HEADERS += \
- drm_bo_buffer.h \
- drm_display.h \
- drm_v4l2_buffer.h \
+ drm_bo_buffer.h \
+ drm_display.h \
+ drm_v4l2_buffer.h \
$(NULL)
endif
diff --git a/xcore/base/xcam_common.h b/xcore/base/xcam_common.h
index 46cc6fd..1f16e1e 100644
--- a/xcore/base/xcam_common.h
+++ b/xcore/base/xcam_common.h
@@ -49,6 +49,8 @@ typedef enum {
XCAM_RETURN_ERROR_IOCTL = -8,
XCAM_RETURN_ERROR_CL = -9,
XCAM_RETURN_ERROR_ORDER = -10,
+ XCAM_RETURN_ERROR_GLES = -11,
+ XCAM_RETURN_ERROR_VULKAN = -12,
XCAM_RETURN_ERROR_TIMEOUT = -20,
diff --git a/xcore/base/xcam_defs.h b/xcore/base/xcam_defs.h
index 276644f..77b74a5 100644
--- a/xcore/base/xcam_defs.h
+++ b/xcore/base/xcam_defs.h
@@ -72,9 +72,17 @@
#define XCAM_FAIL_RETURN(LEVEL, exp, ret, msg, ...) \
if (!(exp)) { \
XCAM_LOG_##LEVEL (msg, ## __VA_ARGS__); \
- return (ret); \
+ return ret; \
}
+#define XCAM_RETURN_CHECK(LEVEL, exp, msg, ...) \
+ do { \
+ XCamReturn err_ret = (exp); \
+ XCAM_FAIL_RETURN(LEVEL, xcam_ret_is_ok(err_ret), \
+ err_ret, msg, ## __VA_ARGS__); \
+ } while (0)
+
+
#define XCAM_DEAD_COPY(ClassObj) \
ClassObj (const ClassObj&); \
ClassObj & operator= (const ClassObj&) \
@@ -119,7 +127,10 @@
#define PRIuS "u"
#endif
-#define PI 3.1415926f
-#define degree2radian(degree) ((degree) * PI / 180.0f)
+#ifndef XCAM_PI
+#define XCAM_PI 3.1415926f
+#endif
+
+#define degree2radian(degree) ((degree) * XCAM_PI / 180.0f)
#endif //XCAM_DEFS_H
diff --git a/xcore/buffer_pool.h b/xcore/buffer_pool.h
index 899cbf0..09bb1da 100644
--- a/xcore/buffer_pool.h
+++ b/xcore/buffer_pool.h
@@ -67,6 +67,9 @@ protected:
SmartPtr<BufferData> &get_buffer_data () {
return _data;
}
+ const SmartPtr<BufferData> &get_buffer_data () const {
+ return _data;
+ }
private:
XCAM_DEAD_COPY (BufferProxy);
@@ -126,6 +129,9 @@ private:
bool _started;
};
+class VKDevice;
+SmartPtr<BufferPool> create_vk_buffer_pool (const SmartPtr<VKDevice> &dev);
+
};
#endif //XCAM_BUFFER_POOL_H
diff --git a/xcore/drm_bo_buffer.h b/xcore/drm_bo_buffer.h
index fa661d3..2a76a43 100644
--- a/xcore/drm_bo_buffer.h
+++ b/xcore/drm_bo_buffer.h
@@ -94,7 +94,7 @@ class DrmBoBufferPool
public:
explicit DrmBoBufferPool (SmartPtr<DrmDisplay> &display);
- ~DrmBoBufferPool ();
+ virtual ~DrmBoBufferPool ();
// **** MUST be set before set_video_info ****
void set_swap_flags (uint32_t flags, uint32_t init_order) {
diff --git a/xcore/drm_display.cpp b/xcore/drm_display.cpp
index a5c89db..7e41efa 100644
--- a/xcore/drm_display.cpp
+++ b/xcore/drm_display.cpp
@@ -54,7 +54,11 @@ DrmDisplay::instance ()
SmartLock lock(_mutex);
if (_instance.ptr())
return _instance;
- _instance = new DrmDisplay ();
+
+ SmartPtr<DrmDisplay> instance = new DrmDisplay ();
+ XCAM_ASSERT (instance.ptr ());
+ _instance = instance;
+
return _instance;
}
diff --git a/xcore/dynamic_analyzer.cpp b/xcore/dynamic_analyzer.cpp
index 4ca553a..b0932d1 100644
--- a/xcore/dynamic_analyzer.cpp
+++ b/xcore/dynamic_analyzer.cpp
@@ -104,7 +104,10 @@ DynamicAnalyzer::create_common_handler ()
if (_common_handler.ptr())
return _common_handler;
- _common_handler = new DynamicCommonHandler (this);
+ SmartPtr<DynamicCommonHandler> handler = new DynamicCommonHandler (this);
+ XCAM_ASSERT (handler.ptr ());
+ _common_handler = handler;
+
return _common_handler;
}
diff --git a/xcore/fake_poll_thread.cpp b/xcore/fake_poll_thread.cpp
index 612a697..c15df13 100644
--- a/xcore/fake_poll_thread.cpp
+++ b/xcore/fake_poll_thread.cpp
@@ -146,8 +146,9 @@ FakePollThread::init_buffer_pool ()
format.fmt.pix.height, 0, 0, 0);
#if HAVE_LIBDRM
SmartPtr<DrmDisplay> drm_disp = DrmDisplay::instance ();
- _buf_pool = new DrmBoBufferPool (drm_disp);
- XCAM_ASSERT (_buf_pool.ptr ());
+ SmartPtr<BufferPool> pool = new DrmBoBufferPool (drm_disp);
+ XCAM_ASSERT (pool.ptr ());
+ _buf_pool = pool;
if (_buf_pool->set_video_info (info) && _buf_pool->reserve (DEFAULT_FPT_BUF_COUNT))
return XCAM_RETURN_NO_ERROR;
diff --git a/xcore/image_file_handle.cpp b/xcore/image_file_handle.cpp
index a901b1f..6a9ce68 100644
--- a/xcore/image_file_handle.cpp
+++ b/xcore/image_file_handle.cpp
@@ -48,6 +48,12 @@ ImageFileHandle::read_buf (const SmartPtr<VideoBuffer> &buf)
XCAM_ASSERT (is_valid ());
memory = buf->map ();
+
+ if (NULL == memory) {
+ XCAM_LOG_ERROR ("ImageFileHandle::read_buf map buffer memory(%p) \n", memory);
+ buf->unmap ();
+ return ret;
+ }
for (uint32_t index = 0; index < info.components; index++) {
info.get_planar_info (planar, index);
uint32_t line_bytes = planar.width * planar.pixel_bytes;
diff --git a/xcore/image_handler.cpp b/xcore/image_handler.cpp
index 6e47a62..2dabc97 100644
--- a/xcore/image_handler.cpp
+++ b/xcore/image_handler.cpp
@@ -23,7 +23,10 @@
namespace XCam {
ImageHandler::ImageHandler (const char* name)
- : _name (NULL)
+ : _need_configure (true)
+ , _enable_allocator (true)
+ , _buf_capacity (XCAM_DEFAULT_HANDLER_BUF_CAP)
+ , _name (NULL)
{
if (name)
_name = strndup (name, XCAM_MAX_STR_SIZE);
@@ -35,21 +38,127 @@ ImageHandler::~ImageHandler()
}
bool
+ImageHandler::set_out_video_info (const VideoBufferInfo &info)
+{
+ XCAM_ASSERT (info.width && info.height && info.format);
+ _out_video_info = info;
+ return true;
+}
+
+bool
+ImageHandler::enable_allocator (bool enable, uint32_t buf_count)
+{
+
+ if (enable && !buf_count) {
+ XCAM_LOG_ERROR (
+ "ImageHandler(%s) enable allocator must with buf_count>0", XCAM_STR(get_name ()));
+ return false;
+ }
+
+ _enable_allocator = enable;
+ if (enable)
+ _buf_capacity = buf_count;
+
+ return true;
+}
+
+bool
ImageHandler::set_allocator (const SmartPtr<BufferPool> &allocator)
{
XCAM_FAIL_RETURN (
ERROR, allocator.ptr (), false,
- "softhandler(%s) set allocator(is NULL)", XCAM_STR(get_name ()));
+ "ImageHandler(%s) set allocator(is NULL)", XCAM_STR(get_name ()));
_allocator = allocator;
return true;
}
XCamReturn
-ImageHandler::finish ()
+ImageHandler::configure_rest ()
{
+ if (_enable_allocator) {
+ XCAM_FAIL_RETURN (
+ ERROR, _out_video_info.is_valid (), XCAM_RETURN_ERROR_PARAM,
+ "image_hander(%s) configure reset failed before reserver buffer since out_video_info was not set",
+ XCAM_STR (get_name ()));
+
+ SmartPtr<BufferPool> allocator = create_allocator ();
+ XCAM_FAIL_RETURN (
+ ERROR, allocator.ptr (), XCAM_RETURN_ERROR_PARAM,
+ "image_hander(%s) configure reset failed since allocator not created", XCAM_STR (get_name ()));
+ _allocator = allocator;
+ XCamReturn ret = reserve_buffers (_out_video_info, _buf_capacity);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "soft_hander(%s) configure resource failed in reserving buffers", XCAM_STR (get_name ()));
+ }
return XCAM_RETURN_NO_ERROR;
}
+XCamReturn
+ImageHandler::execute_buffer (const SmartPtr<ImageHandler::Parameters> &param, bool sync)
+{
+ XCAM_UNUSED (sync);
+
+ XCamReturn ret = XCAM_RETURN_NO_ERROR;
+
+ XCAM_FAIL_RETURN (
+ ERROR, param.ptr (), XCAM_RETURN_ERROR_PARAM,
+ "image_handler(%s) execute buffer failed, params is null",
+ XCAM_STR (get_name ()));
+
+ if (_need_configure) {
+ ret = configure_resource (param);
+ XCAM_FAIL_RETURN (
+ WARNING, xcam_ret_is_ok (ret), ret,
+ "image_handler(%s) configure resource failed", XCAM_STR (get_name ()));
+
+ ret = configure_rest ();
+ XCAM_FAIL_RETURN (
+ WARNING, xcam_ret_is_ok (ret), ret,
+ "image_handler(%s) configure rest failed", XCAM_STR (get_name ()));
+ _need_configure = false;
+ }
+
+ if (!param->out_buf.ptr () && _enable_allocator) {
+ param->out_buf = get_free_buf ();
+ XCAM_FAIL_RETURN (
+ ERROR, param->out_buf.ptr (), XCAM_RETURN_ERROR_PARAM,
+ "image_handler:%s execute buffer failed, output buffer failed in allocation.",
+ XCAM_STR (get_name ()));
+ }
+
+ ret = start_work (param);
+ XCAM_FAIL_RETURN (
+ ERROR, xcam_ret_is_ok (ret), ret,
+ "image_handler(%s) execute buffer failed in starting workers", XCAM_STR (get_name ()));
+
+ return ret;
+}
+
+void
+ImageHandler::execute_done (const SmartPtr<ImageHandler::Parameters> &param, XCamReturn err)
+{
+ XCAM_ASSERT (param.ptr ());
+
+ if (err < XCAM_RETURN_NO_ERROR) {
+ XCAM_LOG_WARNING (
+ "image_handler(%s) broken with errno %d", XCAM_STR (get_name ()), (int)err);
+ return ;
+ }
+
+ if (err > XCAM_RETURN_NO_ERROR) {
+ XCAM_LOG_WARNING (
+ "image_handler(%s) continued with errno %d", XCAM_STR (get_name ()), (int)err);
+ }
+
+ execute_status_check (param, err);
+}
+
+XCamReturn
+ImageHandler::finish ()
+{
+ return XCAM_RETURN_NO_ERROR;
+}
XCamReturn
ImageHandler::terminate ()
@@ -72,13 +181,13 @@ ImageHandler::reserve_buffers (const VideoBufferInfo &info, uint32_t count)
{
XCAM_FAIL_RETURN (
ERROR, _allocator.ptr (), XCAM_RETURN_ERROR_PARAM,
- "softhandler(%s) reserve buffers failed, alloctor was not set", XCAM_STR(get_name ()));
+ "ImageHandler(%s) reserve buffers failed, alloctor was not set", XCAM_STR(get_name ()));
_allocator->set_video_info (info);
XCAM_FAIL_RETURN (
ERROR, _allocator->reserve (count), XCAM_RETURN_ERROR_MEM,
- "softhandler(%s) reserve buffers(%d) failed", XCAM_STR(get_name ()), count);
+ "ImageHandler(%s) reserve buffers(%d) failed", XCAM_STR(get_name ()), count);
return XCAM_RETURN_NO_ERROR;
}
@@ -88,7 +197,7 @@ ImageHandler::get_free_buf ()
{
XCAM_FAIL_RETURN (
ERROR, _allocator.ptr (), NULL,
- "softhandler(%s) get free buffer failed since allocator was not initilized", XCAM_STR(get_name ()));
+ "ImageHandler(%s) get free buffer failed since allocator was not initilized", XCAM_STR(get_name ()));
return _allocator->get_buffer (_allocator);
}
diff --git a/xcore/image_handler.h b/xcore/image_handler.h
index 2c3fba8..80c64f5 100644
--- a/xcore/image_handler.h
+++ b/xcore/image_handler.h
@@ -37,6 +37,8 @@
_h->mem_func (handler, params, error); } \
}
+#define XCAM_DEFAULT_HANDLER_BUF_CAP 4
+
namespace XCam {
class ImageHandler;
@@ -85,14 +87,22 @@ public:
const char *get_name () const {
return _name;
}
+ bool set_out_video_info (const VideoBufferInfo &info);
+ bool enable_allocator (bool enable, uint32_t buf_count = XCAM_DEFAULT_HANDLER_BUF_CAP);
// virtual functions
// execute_buffer params should NOT be const
- virtual XCamReturn execute_buffer (const SmartPtr<Parameters> &params, bool sync) = 0;
+ virtual XCamReturn execute_buffer (const SmartPtr<Parameters> &params, bool sync);
+ virtual void execute_done (const SmartPtr<ImageHandler::Parameters> &param, XCamReturn err);
virtual XCamReturn finish ();
virtual XCamReturn terminate ();
protected:
+ virtual XCamReturn configure_resource (const SmartPtr<Parameters> &param) = 0;
+ virtual SmartPtr<BufferPool> create_allocator () = 0;
+ virtual XCamReturn configure_rest ();
+ virtual XCamReturn start_work (const SmartPtr<Parameters> &param) = 0;
+
virtual void execute_status_check (const SmartPtr<Parameters> &params, const XCamReturn error);
bool set_allocator (const SmartPtr<BufferPool> &allocator);
@@ -102,12 +112,22 @@ protected:
XCamReturn reserve_buffers (const VideoBufferInfo &info, uint32_t count);
SmartPtr<VideoBuffer> get_free_buf ();
+ const VideoBufferInfo &get_out_video_info () {
+ return _out_video_info;
+ }
+
private:
XCAM_DEAD_COPY (ImageHandler);
+protected:
+ bool _need_configure;
+ bool _enable_allocator;
+
private:
SmartPtr<Callback> _callback;
+ VideoBufferInfo _out_video_info;
SmartPtr<BufferPool> _allocator;
+ uint32_t _buf_capacity;
char *_name;
};
diff --git a/xcore/image_processor.cpp b/xcore/image_processor.cpp
index 928cbcc..f2cdc2d 100644
--- a/xcore/image_processor.cpp
+++ b/xcore/image_processor.cpp
@@ -144,8 +144,13 @@ ImageProcessor::ImageProcessor (const char* name)
if (name)
_name = strndup (name, XCAM_MAX_STR_SIZE);
- _processor_thread = new ImageProcessorThread (this);
- _results_thread = new X3aResultsProcessThread (this);
+ SmartPtr<ImageProcessorThread> processor_thread = new ImageProcessorThread (this);
+ XCAM_ASSERT (processor_thread.ptr ());
+ _processor_thread = processor_thread;
+
+ SmartPtr<X3aResultsProcessThread> results_thread = new X3aResultsProcessThread (this);
+ XCAM_ASSERT (results_thread.ptr ());
+ _results_thread = results_thread;
}
ImageProcessor::~ImageProcessor ()
diff --git a/xcore/interface/blender.h b/xcore/interface/blender.h
index 93b5fbe..2d56614 100644
--- a/xcore/interface/blender.h
+++ b/xcore/interface/blender.h
@@ -30,6 +30,7 @@
namespace XCam {
class Blender;
+class VKDevice;
class Blender
{
@@ -38,6 +39,8 @@ public:
virtual ~Blender ();
static SmartPtr<Blender> create_ocl_blender ();
static SmartPtr<Blender> create_soft_blender ();
+ static SmartPtr<Blender> create_gl_blender ();
+ static SmartPtr<Blender> create_vk_blender (const SmartPtr<VKDevice> &dev);
void set_output_size (uint32_t width, uint32_t height);
void get_output_size (uint32_t &width, uint32_t &height) const {
diff --git a/xcore/interface/data_types.h b/xcore/interface/data_types.h
index a4d6f4e..589ec29 100644
--- a/xcore/interface/data_types.h
+++ b/xcore/interface/data_types.h
@@ -31,6 +31,19 @@ enum SurroundMode {
BowlView = 1
};
+enum FeatureMatchMode {
+ FMNone = 0,
+ FMDefault,
+ FMCluster,
+ FMCapi
+};
+
+enum GeoMapScaleMode {
+ ScaleSingleConst = 0,
+ ScaleDualConst,
+ ScaleDualCurve
+};
+
struct Rect {
int32_t pos_x, pos_y;
int32_t width, height;
diff --git a/xcore/interface/feature_match.cpp b/xcore/interface/feature_match.cpp
index 4a6a428..1ed625f 100644
--- a/xcore/interface/feature_match.cpp
+++ b/xcore/interface/feature_match.cpp
@@ -27,7 +27,9 @@ namespace XCam {
FeatureMatch::FeatureMatch ()
: _x_offset (0.0f)
+ , _y_offset (0.0f)
, _mean_offset (0.0f)
+ , _mean_offset_y (0.0f)
, _valid_count (0)
, _fm_idx (-1)
, _frame_num (0)
@@ -35,34 +37,73 @@ FeatureMatch::FeatureMatch ()
}
void
-FeatureMatch::set_config (CVFMConfig config)
+FeatureMatch::set_fm_index (int idx)
+{
+ _fm_idx = idx;
+}
+
+void
+FeatureMatch::set_config (const FMConfig &config)
{
_config = config;
}
-CVFMConfig
-FeatureMatch::get_config ()
+void
+FeatureMatch::set_crop_rect (const Rect &left_rect, const Rect &right_rect)
{
- return _config;
+ _left_rect = left_rect;
+ _right_rect = right_rect;
}
void
-FeatureMatch::set_fm_index (int idx)
+FeatureMatch::get_crop_rect (Rect &left_rect, Rect &right_rect)
{
- _fm_idx = idx;
+ left_rect = _left_rect;
+ right_rect = _right_rect;
}
void
FeatureMatch::reset_offsets ()
{
_x_offset = 0.0f;
+ _y_offset = 0.0f;
_mean_offset = 0.0f;
+ _mean_offset_y = 0.0f;
+}
+
+float
+FeatureMatch::get_current_left_offset_x ()
+{
+ return _x_offset;
+}
+
+float
+FeatureMatch::get_current_left_offset_y ()
+{
+ return _y_offset;
+}
+
+void
+FeatureMatch::set_dst_width (int width)
+{
+ XCAM_UNUSED (width);
+
+ XCAM_LOG_ERROR ("dst width is not supported");
+ XCAM_ASSERT (false);
+}
+
+void
+FeatureMatch::enable_adjust_crop_area ()
+{
+ XCAM_LOG_ERROR ("adjust crop area is not supported");
+ XCAM_ASSERT (false);
}
bool
-FeatureMatch::get_mean_offset (std::vector<float> &offsets, float sum, int &count, float &mean_offset)
+FeatureMatch::get_mean_offset (
+ const std::vector<float> &offsets, float sum, int &count, float &mean_offset)
{
- if (count < _config.min_corners)
+ if (count < _config.min_corners || count <= 0)
return false;
mean_offset = sum / count;
@@ -87,7 +128,7 @@ FeatureMatch::get_mean_offset (std::vector<float> &offsets, float sum, int &coun
++recur_count;
}
- if (recur_count < _config.min_corners) {
+ if (recur_count < _config.min_corners || recur_count <= 0) {
ret = false;
break;
}
@@ -115,29 +156,4 @@ FeatureMatch::get_mean_offset (std::vector<float> &offsets, float sum, int &coun
return ret;
}
-void
-FeatureMatch::adjust_stitch_area (int dst_width, float &x_offset, Rect &stitch0, Rect &stitch1)
-{
- if (fabs (x_offset) < 5.0f)
- return;
-
- int last_overlap_width = stitch1.pos_x + stitch1.width + (dst_width - (stitch0.pos_x + stitch0.width));
- // int final_overlap_width = stitch1.pos_x + stitch1.width + (dst_width - (stitch0.pos_x - x_offset + stitch0.width));
- if ((stitch0.pos_x - x_offset + stitch0.width) > dst_width)
- x_offset = dst_width - (stitch0.pos_x + stitch0.width);
- int final_overlap_width = last_overlap_width + x_offset;
- final_overlap_width = XCAM_ALIGN_AROUND (final_overlap_width, 8);
- XCAM_ASSERT (final_overlap_width >= _config.sitch_min_width);
- int center = final_overlap_width / 2;
- XCAM_ASSERT (center >= _config.sitch_min_width / 2);
-
- stitch1.pos_x = XCAM_ALIGN_AROUND (center - _config.sitch_min_width / 2, 8);
- stitch1.width = _config.sitch_min_width;
- stitch0.pos_x = dst_width - final_overlap_width + stitch1.pos_x;
- stitch0.width = _config.sitch_min_width;
-
- float delta_offset = final_overlap_width - last_overlap_width;
- x_offset -= delta_offset;
-}
-
}
diff --git a/xcore/interface/feature_match.h b/xcore/interface/feature_match.h
index 06c0b7b..a8dd72b 100644
--- a/xcore/interface/feature_match.h
+++ b/xcore/interface/feature_match.h
@@ -28,7 +28,7 @@
namespace XCam {
-struct CVFMConfig {
+struct FMConfig {
int sitch_min_width;
int min_corners; // number of minimum efficient corners
float offset_factor; // last_offset * offset_factor + cur_offset * (1.0f - offset_factor)
@@ -38,7 +38,7 @@ struct CVFMConfig {
float max_valid_offset_y; // valid maximum offset in vertical direction
float max_track_error; // maximum track error
- CVFMConfig ()
+ FMConfig ()
: sitch_min_width (56)
, min_corners (8)
, offset_factor (0.8f)
@@ -56,41 +56,46 @@ public:
explicit FeatureMatch ();
virtual ~FeatureMatch () {};
- void set_config (CVFMConfig config);
- CVFMConfig get_config ();
+ static SmartPtr<FeatureMatch> create_default_feature_match ();
+ static SmartPtr<FeatureMatch> create_cluster_feature_match ();
+ static SmartPtr<FeatureMatch> create_capi_feature_match ();
- void set_fm_index (int idx);
+ virtual void feature_match (
+ const SmartPtr<VideoBuffer> &left_buf, const SmartPtr<VideoBuffer> &right_buf) = 0;
- void reset_offsets ();
+ void set_fm_index (int idx);
+ void set_config (const FMConfig &config);
- virtual void optical_flow_feature_match (
- const SmartPtr<VideoBuffer> &left_buf, const SmartPtr<VideoBuffer> &right_buf,
- Rect &left_crop_rect, Rect &right_crop_rect, int dst_width) = 0;
+ void set_crop_rect (const Rect &left_rect, const Rect &right_rect);
+ void get_crop_rect (Rect &left_rect, Rect &right_rect);
- float get_current_left_offset_x () const {
- return _x_offset;
- }
+ void reset_offsets ();
+ float get_current_left_offset_x ();
+ float get_current_left_offset_y ();
- virtual void set_ocl (bool use_ocl) = 0;
- virtual bool is_ocl_path () = 0;
+ virtual void set_dst_width (int width);
+ virtual void enable_adjust_crop_area ();
protected:
- bool get_mean_offset (std::vector<float> &offsets, float sum, int &count, float &mean_offset);
-
- void adjust_stitch_area (int dst_width, float &x_offset, Rect &stitch0, Rect &stitch1);
+ bool get_mean_offset (const std::vector<float> &offsets, float sum, int &count, float &mean_offset);
private:
XCAM_DEAD_COPY (FeatureMatch);
protected:
float _x_offset;
+ float _y_offset;
float _mean_offset;
+ float _mean_offset_y;
int _valid_count;
- CVFMConfig _config;
+ FMConfig _config;
+
+ Rect _left_rect;
+ Rect _right_rect;
// debug parameters
int _fm_idx;
- uint _frame_num;
+ uint32_t _frame_num;
};
}
diff --git a/xcore/interface/geo_mapper.h b/xcore/interface/geo_mapper.h
index 0ddd495..8a779af 100644
--- a/xcore/interface/geo_mapper.h
+++ b/xcore/interface/geo_mapper.h
@@ -27,6 +27,8 @@
namespace XCam {
+class VKDevice;
+
class GeoMapper
{
public:
@@ -34,6 +36,8 @@ public:
virtual ~GeoMapper ();
static SmartPtr<GeoMapper> create_ocl_geo_mapper ();
static SmartPtr<GeoMapper> create_soft_geo_mapper ();
+ static SmartPtr<GeoMapper> create_gl_geo_mapper ();
+ static SmartPtr<GeoMapper> create_vk_geo_mapper (const SmartPtr<VKDevice> &dev, const char* name);
//2D table
virtual bool set_lookup_table (const PointFloat2 *data, uint32_t width, uint32_t height) = 0;
@@ -53,7 +57,7 @@ public:
SmartPtr<VideoBuffer> &out_buf) = 0;
protected:
- bool auto_calculate_factors (uint32_t lut_w, uint32_t lut_h);
+ virtual bool auto_calculate_factors (uint32_t lut_w, uint32_t lut_h);
private:
uint32_t _out_width, _out_height;
diff --git a/xcore/interface/stitcher.cpp b/xcore/interface/stitcher.cpp
index 70da11f..3b0ed6d 100644
--- a/xcore/interface/stitcher.cpp
+++ b/xcore/interface/stitcher.cpp
@@ -77,8 +77,7 @@ split_area_by_out (
}
Stitcher::Stitcher (uint32_t align_x, uint32_t align_y)
- : _is_crop_set (false)
- , _alignment_x (align_x)
+ : _alignment_x (align_x)
, _alignment_y (align_y)
, _output_width (0)
, _output_height (0)
@@ -86,7 +85,10 @@ Stitcher::Stitcher (uint32_t align_x, uint32_t align_y)
, _camera_num (0)
, _is_round_view_set (false)
, _is_overlap_set (false)
+ , _is_crop_set (false)
, _is_center_marked (false)
+ , _scale_mode (ScaleSingleConst)
+ , _fm_mode (FMNone)
{
XCAM_ASSERT (align_x >= 1);
XCAM_ASSERT (align_y >= 1);
@@ -629,7 +631,7 @@ BowlModel::get_stitch_image_vertex_model (
vertices.push_back (PointFloat3(world_pos0.x / _config.a, world_pos0.y / _config.b, world_pos0.z / _config.c));
indeices.push_back (indicator++);
- texture_points.push_back (PointFloat2(texture_pos0.x / _bowl_img_width, (_bowl_img_height - texture_pos0.y) / _bowl_img_height));
+ texture_points.push_back (PointFloat2(texture_pos0.x / _bowl_img_width, texture_pos0.y / _bowl_img_height));
PointFloat3 world_pos1 =
bowl_view_image_to_world (
@@ -637,7 +639,7 @@ BowlModel::get_stitch_image_vertex_model (
vertices.push_back (PointFloat3(world_pos1.x / _config.a, world_pos1.y / _config.b, world_pos1.z / _config.c));
indeices.push_back (indicator++);
- texture_points.push_back (PointFloat2(texture_pos1.x / _bowl_img_width, (_bowl_img_height - texture_pos1.y) / _bowl_img_height));
+ texture_points.push_back (PointFloat2(texture_pos1.x / _bowl_img_width, texture_pos1.y / _bowl_img_height));
}
}
return true;
diff --git a/xcore/interface/stitcher.h b/xcore/interface/stitcher.h
index e38a98e..8987507 100644
--- a/xcore/interface/stitcher.h
+++ b/xcore/interface/stitcher.h
@@ -70,6 +70,8 @@ struct CameraInfo {
float angle_range;;
};
+class VKDevice;
+
class Stitcher
{
public:
@@ -126,6 +128,8 @@ public:
virtual ~Stitcher ();
static SmartPtr<Stitcher> create_ocl_stitcher ();
static SmartPtr<Stitcher> create_soft_stitcher ();
+ static SmartPtr<Stitcher> create_gl_stitcher ();
+ static SmartPtr<Stitcher> create_vk_stitcher (const SmartPtr<VKDevice> dev);
bool set_bowl_config (const BowlDataConfig &config);
const BowlDataConfig &get_bowl_config () {
@@ -153,11 +157,25 @@ public:
_output_width = width; //XCAM_ALIGN_UP (width, XCAM_BLENDER_ALIGNED_WIDTH);
_output_height = height;
}
-
void get_output_size (uint32_t &width, uint32_t &height) const {
width = _output_width;
height = _output_height;
}
+
+ void set_scale_mode (GeoMapScaleMode scale_mode) {
+ _scale_mode = scale_mode;
+ }
+ GeoMapScaleMode get_scale_mode () {
+ return _scale_mode;
+ }
+
+ void set_fm_mode (FeatureMatchMode fm_mode) {
+ _fm_mode = fm_mode;
+ }
+ FeatureMatchMode get_fm_mode () {
+ return _fm_mode;
+ }
+
virtual XCamReturn stitch_buffers (const VideoBufferList &in_bufs, SmartPtr<VideoBuffer> &out_buf) = 0;
protected:
@@ -186,12 +204,6 @@ protected:
private:
XCAM_DEAD_COPY (Stitcher);
-protected:
- ImageCropInfo _crop_info[XCAM_STITCH_MAX_CAMERAS];
- bool _is_crop_set;
- //update after each feature match
- ScaleFactor _scale_factors[XCAM_STITCH_MAX_CAMERAS];
-
private:
uint32_t _alignment_x, _alignment_y;
uint32_t _output_width, _output_height;
@@ -205,10 +217,19 @@ private:
BowlDataConfig _bowl_config;
bool _is_overlap_set;
+ ImageCropInfo _crop_info[XCAM_STITCH_MAX_CAMERAS];
+ bool _is_crop_set;
+
//auto calculation
CenterMark _center_marks[XCAM_STITCH_MAX_CAMERAS];
bool _is_center_marked;
CopyAreaArray _copy_areas;
+
+ GeoMapScaleMode _scale_mode;
+ //update after each feature match
+ ScaleFactor _scale_factors[XCAM_STITCH_MAX_CAMERAS];
+
+ FeatureMatchMode _fm_mode;
};
class BowlModel {
diff --git a/xcore/once_map_video_buffer_priv.cpp b/xcore/once_map_video_buffer_priv.cpp
new file mode 100644
index 0000000..1d4793c
--- /dev/null
+++ b/xcore/once_map_video_buffer_priv.cpp
@@ -0,0 +1,97 @@
+/*
+ * once_map_video_buffer_priv.cpp
+ *
+ * Copyright (c) 2017 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Zong Wei <wei.zong@intel.com>
+ */
+
+#include <xcam_std.h>
+#include <video_buffer.h>
+
+namespace XCam {
+
+class OnceMapVideoBuffer
+ : public VideoBuffer
+{
+public:
+ OnceMapVideoBuffer (const VideoBufferInfo &info, uint8_t* buffer);
+
+ virtual ~OnceMapVideoBuffer ();
+
+ virtual uint8_t *map ();
+ virtual bool unmap ();
+ virtual int get_fd ();
+
+private:
+
+ XCAM_DEAD_COPY (OnceMapVideoBuffer);
+
+private:
+ uint8_t* _buffer;
+};
+
+OnceMapVideoBuffer::OnceMapVideoBuffer (const VideoBufferInfo &info, uint8_t* buffer)
+ : VideoBuffer (info)
+ , _buffer (buffer)
+{
+ XCAM_ASSERT (buffer != NULL);
+}
+
+OnceMapVideoBuffer::~OnceMapVideoBuffer ()
+{
+}
+
+uint8_t *
+OnceMapVideoBuffer::map ()
+{
+ return _buffer;
+}
+
+bool
+OnceMapVideoBuffer::unmap ()
+{
+ return true;
+}
+
+int
+OnceMapVideoBuffer::get_fd ()
+{
+ XCAM_ASSERT (false && "OnceMapVideoBuffer::get_fd not supported");
+ return -1;
+}
+
+SmartPtr<VideoBuffer>
+external_buf_to_once_map_buf (
+ uint8_t* buf, uint32_t format,
+ uint32_t width, uint32_t height,
+ uint32_t aligned_width, uint32_t aligned_height,
+ uint32_t size)
+{
+ VideoBufferInfo buf_info;
+ SmartPtr<OnceMapVideoBuffer> video_buffer;
+
+ XCAM_FAIL_RETURN (
+ ERROR, buf, NULL,
+ "external_buf_to_map_buf failed since buf is NULL");
+
+ buf_info.init (format, width, height,
+ aligned_width, aligned_height, size);
+ video_buffer = new OnceMapVideoBuffer (buf_info, buf);
+ XCAM_ASSERT (video_buffer.ptr ());
+ return video_buffer;
+}
+
+}
diff --git a/xcore/poll_thread.cpp b/xcore/poll_thread.cpp
index dcb778b..013a543 100644
--- a/xcore/poll_thread.cpp
+++ b/xcore/poll_thread.cpp
@@ -83,8 +83,13 @@ PollThread::PollThread ()
: _poll_callback (NULL)
, _stats_callback (NULL)
{
- _event_loop = new EventPollThread(this);
- _capture_loop = new CapturePollThread (this);
+ SmartPtr<EventPollThread> event_loop = new EventPollThread(this);
+ XCAM_ASSERT (event_loop.ptr ());
+ _event_loop = event_loop;
+
+ SmartPtr<CapturePollThread> capture_loop = new CapturePollThread (this);
+ XCAM_ASSERT (capture_loop.ptr ());
+ _capture_loop = capture_loop;
XCAM_LOG_DEBUG ("PollThread constructed");
}
diff --git a/xcore/surview_fisheye_dewarp.cpp b/xcore/surview_fisheye_dewarp.cpp
index 6c0830c..7e45eac 100644
--- a/xcore/surview_fisheye_dewarp.cpp
+++ b/xcore/surview_fisheye_dewarp.cpp
@@ -60,18 +60,19 @@ SurViewFisheyeDewarp::get_extrinsic_param()
}
void
-SurViewFisheyeDewarp::fisheye_dewarp(MapTable &map_table, uint32_t table_w, uint32_t table_h, uint32_t image_w, uint32_t image_h, const BowlDataConfig &bowl_config)
+SurViewFisheyeDewarp::fisheye_dewarp(MapTable &map_table, uint32_t table_w, uint32_t table_h,
+ uint32_t image_w, uint32_t image_h, const BowlDataConfig &bowl_config)
{
PointFloat3 world_coord;
PointFloat3 cam_coord;
PointFloat3 cam_world_coord;
PointFloat2 image_coord;
- XCAM_LOG_DEBUG ("fisheye-dewarp:\n table(%dx%d), out_size(%dx%d)"
- "bowl(start:%.1f, end:%.1f, ground:%.2f, wall:%.2f, a:%.2f, b:%.2f, c:%.2f, center_z:%.2f )",
+ XCAM_LOG_DEBUG ("fisheye-dewarp:\n table(%dx%d) out_size(%dx%d) "
+ "bowl(start:%.1f, end:%.1f, ground:%.2f, wall:%.2f, a:%.2f, b:%.2f, c:%.2f, center_z:%.2f)",
table_w, table_h, image_w, image_h,
bowl_config.angle_start, bowl_config.angle_end,
- bowl_config.wall_height, bowl_config.ground_length,
+ bowl_config.ground_length, bowl_config.wall_height,
bowl_config.a, bowl_config.b, bowl_config.c, bowl_config.center_z);
float scale_factor_w = (float)image_w / table_w;
diff --git a/xcore/surview_fisheye_dewarp.h b/xcore/surview_fisheye_dewarp.h
index 571b02a..3754942 100644
--- a/xcore/surview_fisheye_dewarp.h
+++ b/xcore/surview_fisheye_dewarp.h
@@ -36,7 +36,8 @@ public:
explicit SurViewFisheyeDewarp ();
virtual ~SurViewFisheyeDewarp ();
- void fisheye_dewarp(MapTable &map_table, uint32_t table_w, uint32_t table_h, uint32_t image_w, uint32_t image_h, const BowlDataConfig &bowl_config);
+ void fisheye_dewarp(MapTable &map_table, uint32_t table_w, uint32_t table_h,
+ uint32_t image_w, uint32_t image_h, const BowlDataConfig &bowl_config);
void set_intrinsic_param(const IntrinsicParameter &intrinsic_param);
void set_extrinsic_param(const ExtrinsicParameter &extrinsic_param);
diff --git a/xcore/vec_mat.h b/xcore/vec_mat.h
index 51add21..eccb52e 100644
--- a/xcore/vec_mat.h
+++ b/xcore/vec_mat.h
@@ -27,10 +27,6 @@
namespace XCam {
-#ifndef PI
-#define PI 3.14159265358979323846
-#endif
-
#ifndef FLT_EPSILON
#define FLT_EPSILON 1.19209290e-07F // float
#endif
@@ -40,11 +36,11 @@ namespace XCam {
#endif
#ifndef DEGREE_2_RADIANS
-#define DEGREE_2_RADIANS(x) (((x) * PI) / 180.0)
+#define DEGREE_2_RADIANS(x) (((x) * XCAM_PI) / 180.0)
#endif
#ifndef RADIANS_2_DEGREE
-#define RADIANS_2_DEGREE(x) (((x) * 180.0) / PI)
+#define RADIANS_2_DEGREE(x) (((x) * 180.0) / XCAM_PI)
#endif
#define XCAM_VECT2_OPERATOR_VECT2(op) \
@@ -157,11 +153,11 @@ public:
inline bool operator == (const VectorN<T, N>& rhs) const;
inline T& operator [] (uint32_t index) {
- XCAM_ASSERT(index >= 0 && index < N);
+ XCAM_ASSERT(index < N);
return data[index];
}
inline const T& operator [] (uint32_t index) const {
- XCAM_ASSERT(index >= 0 && index < N);
+ XCAM_ASSERT(index < N);
return data[index];
}
@@ -521,15 +517,11 @@ public:
inline void eye ();
inline T& at (uint32_t row, uint32_t col) {
- XCAM_ASSERT(row >= 0 && row < N);
- XCAM_ASSERT(col >= 0 && col < N);
-
+ XCAM_ASSERT(row < N && col < N);
return data[row * N + col];
};
inline const T& at (uint32_t row, uint32_t col) const {
- XCAM_ASSERT(row >= 0 && row < N);
- XCAM_ASSERT(col >= 0 && col < N);
-
+ XCAM_ASSERT(row < N && col < N);
return data[row * N + col];
};
diff --git a/xcore/worker.cpp b/xcore/worker.cpp
index 6d8a7ab..c4b52d0 100644
--- a/xcore/worker.cpp
+++ b/xcore/worker.cpp
@@ -25,6 +25,8 @@ namespace XCam {
Worker::Worker (const char *name, const SmartPtr<Callback> &cb)
: _name (NULL)
, _callback (cb)
+ , _global (1, 1, 1)
+ , _local (1, 1, 1)
{
if (name)
_name = strndup (name, XCAM_MAX_STR_SIZE);
@@ -69,6 +71,31 @@ Worker::status_check (const SmartPtr<Worker::Arguments> &args, const XCamReturn
_callback->work_status (this, args, error);
}
+bool
+Worker::set_global_size (const WorkSize &size)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, size.value[0] && size.value[1] && size.value[2], false,
+ "Worker(%s) set global size(x:%d, y:%d, z:%d) failed.",
+ XCAM_STR (get_name ()), size.value[0], size.value[1], size.value[2]);
+
+ _global = size;
+ return true;
+}
+
+bool
+Worker::set_local_size (const WorkSize &size)
+{
+ XCAM_FAIL_RETURN (
+ ERROR, size.value[0] && size.value[1] && size.value[2], false,
+ "Worker(%s) set local size(x:%d, y:%d, z:%d) failed.",
+ XCAM_STR (get_name ()), size.value[0], size.value[1], size.value[2]);
+
+ _local = size;
+ return true;
+}
+
+
#if ENABLE_FUNC_OBJ
bool
Worker::set_func_obj (const SmartPtr<FuncObj> &obj)
diff --git a/xcore/worker.h b/xcore/worker.h
index 16807c1..9a4eec0 100644
--- a/xcore/worker.h
+++ b/xcore/worker.h
@@ -23,6 +23,8 @@
#include <xcam_std.h>
+#define WORK_MAX_DIM 3
+
#define ENABLE_FUNC_OBJ 0
#define DECLARE_WORK_CALLBACK(CbClass, Handler, mem_func) \
@@ -38,6 +40,15 @@
namespace XCam {
+struct WorkSize {
+ uint32_t value[WORK_MAX_DIM];
+ WorkSize (uint32_t x = 1, uint32_t y = 1, uint32_t z = 1) {
+ value[0] = x;
+ value[1] = y;
+ value[2] = z;
+ }
+};
+
class Worker
: public RefObj
{
@@ -82,6 +93,15 @@ public:
const char *get_name () const {
return _name;
}
+ bool set_global_size (const WorkSize &size);
+ const WorkSize &get_global_size () const {
+ return _global;
+ }
+ bool set_local_size (const WorkSize &size);
+ const WorkSize &get_local_size () const {
+ return _local;
+ }
+
#if ENABLE_FUNC_OBJ
bool set_func_obj (const SmartPtr<FuncObj> &obj);
#endif
@@ -99,6 +119,9 @@ private:
private:
char *_name;
SmartPtr<Callback> _callback;
+ WorkSize _global;
+ WorkSize _local;
+
#if ENABLE_FUNC_OBJ
SmartPtr<FuncObj> _func_obj;
#endif
diff --git a/xcore/xcam_analyzer.cpp b/xcore/xcam_analyzer.cpp
index 8191a79..13ee457 100644
--- a/xcore/xcam_analyzer.cpp
+++ b/xcore/xcam_analyzer.cpp
@@ -118,7 +118,9 @@ XAnalyzer::XAnalyzer (const char *name)
if (name)
_name = strndup (name, XCAM_MAX_STR_SIZE);
- _analyzer_thread = new AnalyzerThread (this);
+ SmartPtr<AnalyzerThread> thread= new AnalyzerThread (this);
+ XCAM_ASSERT (thread.ptr ());
+ _analyzer_thread = thread;
}
XAnalyzer::~XAnalyzer()
diff --git a/xcore/xcam_utils.cpp b/xcore/xcam_utils.cpp
index 4393961..246be93 100644
--- a/xcore/xcam_utils.cpp
+++ b/xcore/xcam_utils.cpp
@@ -32,11 +32,11 @@ transform_bowl_coord_to_image_x (
const float bowl_x, const float bowl_y,
const uint32_t img_width)
{
- float offset_radian = (bowl_x < 0.0f) ? PI : ((bowl_y >= 0.0f) ? 2.0f * PI : 0.0f);
- float arctan_radian = (bowl_x != 0.0f) ? atan (-bowl_y / bowl_x) : ((bowl_y >= 0.0f) ? -PI / 2.0f : PI / 2.0f);
+ float offset_radian = (bowl_x < 0.0f) ? XCAM_PI : ((bowl_y >= 0.0f) ? 2.0f * XCAM_PI : 0.0f);
+ float arctan_radian = (bowl_x != 0.0f) ? atan (-bowl_y / bowl_x) : ((bowl_y >= 0.0f) ? -XCAM_PI / 2.0f : XCAM_PI / 2.0f);
float img_x = arctan_radian + offset_radian;
- img_x *= img_width / (2.0f * PI);
+ img_x *= img_width / (2.0f * XCAM_PI);
return XCAM_CLAMP (img_x, 0.0f, img_width - 1.0f);
}
@@ -95,10 +95,10 @@ PointFloat3 bowl_view_image_to_world (
float b = config.b;
float c = config.c;
- float wall_image_height = config.wall_height / (float)(config.wall_height + config.ground_length) * (float)img_height;
- float ground_image_height = (float)img_height - wall_image_height;
+ float wall_image_height = config.wall_height / (config.wall_height + config.ground_length) * img_height;
+ float ground_image_height = img_height - wall_image_height;
- float z_step = (float)config.wall_height / wall_image_height;
+ float z_step = config.wall_height / wall_image_height;
float angle_step = fabs(config.angle_end - config.angle_start) / img_width;
if(img_pos.y < wall_image_height) {
@@ -106,13 +106,13 @@ PointFloat3 bowl_view_image_to_world (
angle = degree2radian (config.angle_start + img_pos.x * angle_step);
float r2 = 1 - (world.z - config.center_z) * (world.z - config.center_z) / (c * c);
- if(XCAM_DOUBLE_EQUAL_AROUND (angle, PI / 2)) {
+ if(XCAM_DOUBLE_EQUAL_AROUND (angle, XCAM_PI / 2)) {
world.x = 0.0f;
world.y = -sqrt(r2 * b * b);
- } else if (XCAM_DOUBLE_EQUAL_AROUND (angle, PI * 3 / 2)) {
+ } else if (XCAM_DOUBLE_EQUAL_AROUND (angle, XCAM_PI * 3 / 2)) {
world.x = 0.0f;
world.y = sqrt(r2 * b * b);
- } else if((angle < PI / 2) || (angle > PI * 3 / 2)) {
+ } else if((angle < XCAM_PI / 2) || (angle > XCAM_PI * 3 / 2)) {
world.x = sqrt(r2 * a * a * b * b / (b * b + a * a * tan(angle) * tan(angle)));
world.y = -world.x * tan(angle);
} else {
@@ -124,7 +124,6 @@ PointFloat3 bowl_view_image_to_world (
b = b * sqrt(1 - config.center_z * config.center_z / (c * c));
float ratio_ab = b / a;
-
float step_b = config.ground_length / ground_image_height;
b = b - (img_pos.y - wall_image_height) * step_b;
@@ -132,13 +131,13 @@ PointFloat3 bowl_view_image_to_world (
angle = degree2radian (config.angle_start + img_pos.x * angle_step);
- if(XCAM_DOUBLE_EQUAL_AROUND (angle, PI / 2)) {
+ if(XCAM_DOUBLE_EQUAL_AROUND (angle, XCAM_PI / 2)) {
world.x = 0.0f;
world.y = -b;
- } else if (XCAM_DOUBLE_EQUAL_AROUND (angle, PI * 3 / 2)) {
+ } else if (XCAM_DOUBLE_EQUAL_AROUND (angle, XCAM_PI * 3 / 2)) {
world.x = 0.0f;
world.y = b;
- } else if((angle < PI / 2) || (angle > PI * 3 / 2)) {
+ } else if((angle < XCAM_PI / 2) || (angle > XCAM_PI * 3 / 2)) {
world.x = a * b / sqrt(b * b + a * a * tan(angle) * tan(angle));
world.y = -world.x * tan(angle);
} else {
@@ -193,13 +192,13 @@ linear_interpolate_p2 (
if (dist_start == 0) {
weight_start = 10000000.0;
} else {
- weight_start = ((double)dist_sum / dist_start);
+ weight_start = (dist_sum / dist_start);
}
if (dist_end == 0) {
weight_end = 10000000.0;
} else {
- weight_end = ((double)dist_sum / dist_end);
+ weight_end = (dist_sum / dist_end);
}
value = (value_start * weight_start + value_end * weight_end) / (weight_start + weight_end);
@@ -227,36 +226,35 @@ linear_interpolate_p4(
double dist_sum = 0;
double value = 0;
- dist_lt = (double)abs(ref_curr_x - ref_lt_x) + (double)abs(ref_curr_y - ref_lt_y);
- dist_rt = (double)abs(ref_curr_x - ref_rt_x) + (double)abs(ref_curr_y - ref_rt_y);
- dist_lb = (double)abs(ref_curr_x - ref_lb_x) + (double)abs(ref_curr_y - ref_lb_y);
- dist_rb = (double)abs(ref_curr_x - ref_rb_x) + (double)abs(ref_curr_y - ref_rb_y);
+ dist_lt = abs(ref_curr_x - ref_lt_x) + abs(ref_curr_y - ref_lt_y);
+ dist_rt = abs(ref_curr_x - ref_rt_x) + abs(ref_curr_y - ref_rt_y);
+ dist_lb = abs(ref_curr_x - ref_lb_x) + abs(ref_curr_y - ref_lb_y);
+ dist_rb = abs(ref_curr_x - ref_rb_x) + abs(ref_curr_y - ref_rb_y);
dist_sum = dist_lt + dist_rt + dist_lb + dist_rb;
if (dist_lt == 0) {
weight_lt = 10000000.0;
} else {
- weight_lt = ((float)dist_sum / dist_lt);
+ weight_lt = (dist_sum / dist_lt);
}
if (dist_rt == 0) {
weight_rt = 10000000.0;
} else {
- weight_rt = ((float)dist_sum / dist_rt);
+ weight_rt = (dist_sum / dist_rt);
}
if (dist_lb == 0) {
weight_lb = 10000000.0;
} else {
- weight_lb = ((float)dist_sum / dist_lb);
+ weight_lb = (dist_sum / dist_lb);
}
if (dist_rb == 0) {
weight_rb = 10000000.0;
} else {
- weight_rb = ((float)dist_sum / dist_rt);
+ weight_rb = (dist_sum / dist_rt);
}
- value = (double)floor ( (value_lt * weight_lt + value_rt * weight_rt +
- value_lb * weight_lb + value_rb * weight_rb) /
- (weight_lt + weight_rt + weight_lb + weight_rb) + 0.5 );
+ value = floor ((value_lt * weight_lt + value_rt * weight_rt + value_lb * weight_lb + value_rb * weight_rb) /
+ (weight_lt + weight_rt + weight_lb + weight_rb) + 0.5);
return value;
}
@@ -272,7 +270,7 @@ get_gauss_table (uint32_t radius, float sigma, std::vector<float> &table, bool n
table[radius] = 1.0f;
for (i = 0; i < radius; i++) {
- dis = ((float)i - radius) * ((float)i - radius);
+ dis = (i - radius) * (i - radius);
table[i] = table[scale - i - 1] = exp(-dis / (2.0f * sigma * sigma));
sum += table[i] * 2.0f;
}
diff --git a/xcore/xcam_utils.h b/xcore/xcam_utils.h
index 492744a..f72efa0 100644
--- a/xcore/xcam_utils.h
+++ b/xcore/xcam_utils.h
@@ -64,6 +64,13 @@ class VideoBuffer;
void dump_buf_perfix_path (const SmartPtr<VideoBuffer> buf, const char *prefix_name);
bool dump_video_buf (const SmartPtr<VideoBuffer> buf, const char *file_name);
+SmartPtr<VideoBuffer>
+external_buf_to_once_map_buf (
+ uint8_t* buf, uint32_t format,
+ uint32_t width, uint32_t height,
+ uint32_t aligned_width, uint32_t aligned_height,
+ uint32_t size);
+
};
#endif //XCAM_UTILS_H